mirror of
https://gitlab.com/hyperglitch/jellyfish.git
synced 2025-12-29 15:36:30 +00:00
91 lines
3.1 KiB
C
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;
|
|
}
|