- Added function to read out the display_buffer via USB-Serial - Added basic structure and files for later complete firmware (still in progress) - Added Doc folder with schematic in it - Added Python script and batch file to read out the display buffer and open the image in gimp
116 lines
3.1 KiB
C
116 lines
3.1 KiB
C
/*
|
|
* ADC.c
|
|
*
|
|
* Created: Tue Sep 13 2022 19:51:36
|
|
* Author Chris
|
|
*/
|
|
// ============================================================================================
|
|
// Includes
|
|
#include "Core1_ADC.h"
|
|
|
|
#include "hardware/adc.h"
|
|
#include "hardware/irq.h"
|
|
#include "hardware/divider.h"
|
|
|
|
|
|
// ============================================================================================
|
|
// Defines
|
|
#define YES true
|
|
#define NO false
|
|
|
|
#define ANALOG_REFERENCE_mV 3300ul
|
|
#define ADC_INPUT_PIN 29
|
|
|
|
|
|
// ============================================================================================
|
|
// Variables
|
|
static uint32_t _ADC_Result_Value;
|
|
static uint32_t _ADC_Result_mV;
|
|
|
|
const uint32_t _ADC_Result_Num = 11;
|
|
const uint32_t _ADC_Result_Denum = 1;
|
|
const bool _ADC_Result_LowPass = NO;
|
|
|
|
|
|
// ============================================================================================
|
|
// Function Declarations
|
|
void Core1_ADC_Select_Next_MUX_Channel();
|
|
void Core1_ADC_Set_Mux(uint channel);
|
|
void Core1_ADC_Store_ADC_Result(uint16_t adc_value);
|
|
uint32_t Core1_ADC_Low_Pass_Filter(int current_value, int new_value);
|
|
|
|
|
|
/*******************************************************************
|
|
Interrupt Service Routines
|
|
*******************************************************************/
|
|
bool ISR_ADC()
|
|
{
|
|
Core1_ADC_Store_ADC_Result(adc_fifo_get());
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
Functions
|
|
*******************************************************************/
|
|
void Core1_ADC_Init()
|
|
{
|
|
_ADC_Result_Value = 0;
|
|
_ADC_Result_mV = 0;
|
|
|
|
adc_gpio_init(ADC_INPUT_PIN);
|
|
adc_init();
|
|
adc_select_input(3);
|
|
adc_fifo_setup(
|
|
true, // Write each completed conversion to the sample FIFO
|
|
false, // Enable DMA data request (DREQ)
|
|
1, // DREQ (and IRQ) asserted when at least 1 sample present
|
|
false, // We won't see the ERR bit because of 8 bit reads; disable.
|
|
false // Shift each sample to 8 bits when pushing to FIFO
|
|
);
|
|
adc_set_clkdiv(5999); // One measurement every 0.125ms -> 8 measurements per 1 ms
|
|
adc_irq_set_enabled(true);
|
|
|
|
irq_set_exclusive_handler(ADC_IRQ_FIFO, (void *)ISR_ADC);
|
|
irq_set_enabled(ADC_IRQ_FIFO, true);
|
|
|
|
adc_run(true);
|
|
}
|
|
|
|
uint16_t Core1_ADC_Get_Result_Value(uint channel)
|
|
{
|
|
return _ADC_Result_Value;
|
|
}
|
|
|
|
uint16_t Core1_ADC_Get_Result_mV(uint channel)
|
|
{
|
|
return _ADC_Result_mV;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
Internal Functions
|
|
*******************************************************************/
|
|
void Core1_ADC_Store_ADC_Result(uint16_t adc_value)
|
|
{
|
|
if(_ADC_Result_LowPass == YES) {
|
|
_ADC_Result_Value = (uint16_t)Core1_ADC_Low_Pass_Filter((float)_ADC_Result_Value, (float)adc_value);
|
|
} else {
|
|
_ADC_Result_Value = (uint32_t)adc_value;
|
|
}
|
|
|
|
_ADC_Result_mV = ((_ADC_Result_Value * ANALOG_REFERENCE_mV * _ADC_Result_Num) / 4096) / _ADC_Result_Denum;
|
|
}
|
|
|
|
uint32_t Core1_ADC_Low_Pass_Filter(int current_value, int new_value)
|
|
{
|
|
// Link: https://kiritchatterjee.wordpress.com/2014/11/10/a-simple-digital-low-pass-filter-in-c/
|
|
|
|
const int Beta = 6;
|
|
|
|
current_value = (current_value << Beta) - current_value;
|
|
current_value += new_value;
|
|
current_value >>= Beta;
|
|
|
|
return (uint32_t)current_value;
|
|
}
|