0
mirror of https://gitlab.com/hyperglitch/jellyfish.git synced 2025-12-29 15:36:30 +00:00
2025-06-12 10:31:43 +02:00

91 lines
3.1 KiB
C

/*
* SPDX-FileCopyrightText: 2025 Igor Brkic <igor@hyperglitch.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <math.h>
#include "jf_adc.h"
#include "main.h"
#include "jf_common.h"
#include "stm32f4xx_ll_adc.h"
uint32_t adc_buff[JF_ADC_CHANNEL_COUNT] = {0}; // ADC buffer
int32_t adc_values[JF_ADC_CHANNEL_COUNT] = {0}; // ADC values
jf_adc_callback_t adc_callbacks[JF_ADC_CHANNEL_COUNT] = {NULL};
// NOTE: if changing make sure to also update the label array in jf_adc.h
const char jf_adc_channel_labels[JF_ADC_CHANNEL_COUNT][13] = {
"VSENSE_DC",
"VSENSE_USB0",
"VSENSE_USB1",
"NTC1",
"NTC2",
"AUX_ISENSE",
"AUX_VSENSE",
"TEMPERATURE",
"VREFINT",
};
bool jf_adc_register_callback(jf_adc_channel_t channel, jf_adc_callback_t callback) {
if(channel>=JF_ADC_CHANNEL_COUNT) return false;
if (callback==NULL) return false;
adc_callbacks[channel] = callback;
return true;
}
void jf_adc_process(const uint32_t *adc_buff){
if(adc_buff[JF_ADC_VREFINT]==0) return; // no measurements yet
int32_t adc_calc[JF_ADC_CHANNEL_COUNT] = {0};
// convert ADC values to voltages
const float vdda = VREFINT_CAL_VREF * (float)*VREFINT_CAL_ADDR / (float)adc_buff[JF_ADC_VREFINT] / 1000.0;
for(int i=0; i<JF_ADC_CHANNEL_COUNT; i++){
if(i==JF_ADC_TEMPERATURE){
// temperature is calculated from VrefInt
continue;
}
// convert to millivolts
//adc_calc[i] = (int32_t)((adc_buff[i] / 4095.0 * vdda)*1000);
adc_calc[i] = ((int32_t)adc_buff[i]*1000) / 1168; // 1168 <= calculated from measurement
}
// calculate internal temperature now that we have Vref in mV
//adc_calc[JF_ADC_TEMPERATURE] = __LL_ADC_CALC_TEMPERATURE(adc_calc[JF_ADC_VREFINT], adc_buff[JF_ADC_TEMPERATURE], LL_ADC_RESOLUTION_12B);
// calculate NTC temperatures (FIXME: convert to fixed point)
//const float ntc_beta = 3435.0;
const float r_ntc1 = 10000.0 * (float)adc_calc[JF_ADC_NTC1] / (3300.0-(float)adc_calc[JF_ADC_NTC1]);
const float r_ntc2 = 10000.0 * (float)adc_calc[JF_ADC_NTC2] / (3300.0-(float)adc_calc[JF_ADC_NTC2]);
//float ntc1_temp_k = 1.0 / (1.0/298.15)+(1.0/ntc_beta) * log(r_ntc1/10000.0);
//float ntc2_temp_k = 1.0 / (1.0/298.15)+(1.0/ntc_beta) * log(r_ntc2/10000.0);
//adc_calc[JF_ADC_NTC1] = (int16_t)((ntc1_temp_k-273.15)*100);
//adc_calc[JF_ADC_NTC2] = (int16_t)((ntc2_temp_k-273.15)*100);
adc_calc[JF_ADC_NTC1] = (int16_t)r_ntc1;
adc_calc[JF_ADC_NTC2] = (int16_t)r_ntc2;
// calculate input VSENSE voltages (should be calibrated based on actual resistor values)
adc_calc[JF_ADC_VSENSE_DC] = ((int32_t)adc_calc[JF_ADC_VSENSE_DC] * 1121) / 121; // 100k/12.1k voltage divider
adc_calc[JF_ADC_VSENSE_USB0] = ((int32_t)adc_calc[JF_ADC_VSENSE_USB0] * 1121) / 121; // 100k/12.1k voltage divider
adc_calc[JF_ADC_VSENSE_USB1] = ((int32_t)adc_calc[JF_ADC_VSENSE_USB1] * 1121) / 121; // 100k/12.1k voltage divider
// process the data if needed and copy it for sharing
for(int i=0; i<JF_ADC_CHANNEL_COUNT; i++){
if(adc_callbacks[i]!=NULL) {
adc_values[i] = adc_callbacks[i](adc_calc[i]);
}
else {
adc_values[i] = adc_calc[i];
}
}
}
const int32_t* jf_adc_get_values(){
return adc_values;
}