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