Files
RP2350_MIDI_Lighter/Firmware/Core1_ADC.c
Chris 128d42c586 - Fixed drawing of round objects (Circles, Rounded Rects) using a lookup table
- 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
2025-09-07 08:55:39 +02:00

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;
}