145 lines
3.0 KiB
C
145 lines
3.0 KiB
C
/*
|
|
* Created on: Jul 27, 2024
|
|
*
|
|
* because the ambient light sensor is facing toward the bottom, and
|
|
* this badge has an "ADJUST" knob that is intended for brightness,
|
|
* the light sensor code is incomplete.
|
|
*
|
|
* if you want to use it, copy code from another badge, where it's also
|
|
* likely incomplete lol
|
|
*/
|
|
|
|
#include <ch32v00x.h>
|
|
|
|
|
|
|
|
// deadzone fudge factors for potentionmeter. test on actual badge
|
|
// and see if necessary, or if pot hardware + adc periph is good enough
|
|
#define POT_LO 40
|
|
#define POT_HI (1024-POT_LO)
|
|
|
|
|
|
|
|
uint16_t adc_val[16];
|
|
uint16_t adc_val_idx;
|
|
uint16_t adc_avg;
|
|
|
|
uint16_t lsens_val;
|
|
|
|
|
|
|
|
void adc_init()
|
|
{
|
|
ADC_InitTypeDef adc = {0};
|
|
GPIO_InitTypeDef gpio = {0};
|
|
|
|
|
|
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
|
|
|
|
gpio.GPIO_Pin = GPIO_Pin_3;
|
|
gpio.GPIO_Mode = GPIO_Mode_AIN;
|
|
GPIO_Init(GPIOD, &gpio);
|
|
|
|
ADC_DeInit(ADC1);
|
|
adc.ADC_Mode = ADC_Mode_Independent;
|
|
adc.ADC_ScanConvMode = DISABLE;
|
|
adc.ADC_ContinuousConvMode = DISABLE;
|
|
adc.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
|
|
adc.ADC_DataAlign = ADC_DataAlign_Right;
|
|
adc.ADC_NbrOfChannel = 1;
|
|
ADC_Init(ADC1, &adc);
|
|
|
|
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_241Cycles);
|
|
ADC_InjectedChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_73Cycles);
|
|
ADC_Calibration_Vol(ADC1, ADC_CALVOL_50PERCENT);
|
|
ADC_Cmd(ADC1, ENABLE);
|
|
|
|
ADC_ResetCalibration(ADC1);
|
|
while(ADC_GetResetCalibrationStatus(ADC1));
|
|
ADC_StartCalibration(ADC1);
|
|
while(ADC_GetCalibrationStatus(ADC1));
|
|
}
|
|
|
|
void adc_calc_avg()
|
|
{
|
|
uint8_t i;
|
|
uint16_t sum = 0;
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
sum += adc_val[i];
|
|
}
|
|
|
|
sum >>= 4;
|
|
|
|
adc_avg = sum;
|
|
}
|
|
|
|
void adc_convert()
|
|
{
|
|
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
|
|
}
|
|
|
|
void adc_read()
|
|
{
|
|
if (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)) {
|
|
adc_val[adc_val_idx++] = ADC_GetConversionValue(ADC1);
|
|
adc_val_idx &= 0x0f;
|
|
if (!adc_val_idx) adc_calc_avg();
|
|
|
|
if (ADC1->CTLR1 & ADC_JAUTO) {
|
|
if (ADC_GetFlagStatus(ADC1, ADC_FLAG_JEOC)) {
|
|
lsens_val = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_1);
|
|
|
|
// reset LSENS
|
|
ADC_AutoInjectedConvCmd(ADC1, DISABLE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void adc_use_lsens()
|
|
{
|
|
GPIO_InitTypeDef gpio = {0};
|
|
|
|
// configure GPIO
|
|
gpio.GPIO_Pin = GPIO_Pin_2;
|
|
gpio.GPIO_Mode = GPIO_Mode_AIN;
|
|
GPIO_Init(GPIOA, &gpio);
|
|
|
|
// enable injected channel
|
|
ADC_AutoInjectedConvCmd(ADC1, ENABLE);
|
|
}
|
|
|
|
void adc_stop_lsens()
|
|
{
|
|
GPIO_InitTypeDef gpio = {0};
|
|
|
|
// configure GPIO
|
|
gpio.GPIO_Pin = GPIO_Pin_2;
|
|
gpio.GPIO_Mode = GPIO_Mode_Out_PP;
|
|
GPIO_Init(GPIOA, &gpio);
|
|
}
|
|
|
|
uint8_t adc_get_pot()
|
|
{
|
|
uint32_t pot;
|
|
|
|
// set lower bound
|
|
pot = adc_avg;
|
|
if (pot < POT_LO) pot = 0; else pot -= POT_LO;
|
|
|
|
// scale to upper bound
|
|
pot <<= 10;
|
|
pot /= POT_HI;
|
|
|
|
// 8 bits is good enough for us
|
|
pot >>= 2;
|
|
|
|
return 255 - (pot & 0xff);
|
|
}
|
|
|
|
uint16_t adc_get_lsens()
|
|
{
|
|
return lsens_val;
|
|
}
|