From e8606bcea8795b0074d0ed51b516f6dc6f7d44f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Sat, 3 Apr 2021 22:48:53 +0200 Subject: [PATCH] Add ADC code to measure temperature. Supervisor not yet implemented --- firmware/Makefile | 3 +- firmware/include/cmsis/core_cm0.h | 4 +- firmware/include/ring-light/temp-adc.h | 10 +++ firmware/include/stm32f030x6.h | 6 +- firmware/main.c | 9 ++- firmware/temp-adc.c | 102 +++++++++++++++++++++++++ 6 files changed, 125 insertions(+), 9 deletions(-) create mode 100644 firmware/include/ring-light/temp-adc.h create mode 100644 firmware/temp-adc.c diff --git a/firmware/Makefile b/firmware/Makefile index 4e927e5..8c1d6c5 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -12,6 +12,7 @@ endif #Add Files and Folders below######################################################### CFILES = main.c syscalls/syscalls.c setup/system_init.c startup/startup_stm32f0xx.c +CFILES += temp-adc.c ASFILES = sk6812.S INCLUDEPATH = -Iinclude -Iinclude/cmsis @@ -39,7 +40,7 @@ LFLAGS += -mfloat-abi=soft --disable-newlib-supplied-syscalls -nostartfiles LFLAGS += -Tstartup/stm32f030.ld -Wl,-Map=$(mapfile).map -Wl,--gc-sections -g CFLAGS = -c -fmessage-length=0 -mlittle-endian -mthumb -mcpu=cortex-m0 -mthumb-interwork -CFLAGS += -mfloat-abi=soft -nostartfiles -Wall -g -O3 +CFLAGS += -mfloat-abi=soft -nostartfiles -Wall -g3 -O0 #################################################################################### diff --git a/firmware/include/cmsis/core_cm0.h b/firmware/include/cmsis/core_cm0.h index cf2b5d6..b684366 100644 --- a/firmware/include/cmsis/core_cm0.h +++ b/firmware/include/cmsis/core_cm0.h @@ -145,8 +145,8 @@ #endif #include /* standard types definitions */ -#include /* Core Instruction Access */ -#include /* Core Function Access */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ #ifdef __cplusplus } diff --git a/firmware/include/ring-light/temp-adc.h b/firmware/include/ring-light/temp-adc.h new file mode 100644 index 0000000..3cd62ce --- /dev/null +++ b/firmware/include/ring-light/temp-adc.h @@ -0,0 +1,10 @@ +#ifndef _TEMP_ADC_H_ +#define _TEMP_ADC_H_ + +#include + +void temperature_adc_init(void); + +int32_t temperature_adc_get_temp(void); + +#endif /* _TEMP_ADC_H_ */ diff --git a/firmware/include/stm32f030x6.h b/firmware/include/stm32f030x6.h index c06fe71..90aa877 100644 --- a/firmware/include/stm32f030x6.h +++ b/firmware/include/stm32f030x6.h @@ -9,7 +9,7 @@ * This file contains: * - Data structures and the address mapping for all peripherals * - Peripheral's registers declarations and bits definition - * - Macros to access peripheral’s registers hardware + * - Macros to access peripheral�s registers hardware * ****************************************************************************** * @attention @@ -114,8 +114,8 @@ typedef enum * @} */ -#include "core_cm0.h" /* Cortex-M0 processor and core peripherals */ -#include "system_stm32f0xx.h" /* STM32F0xx System Header */ +#include /* Cortex-M0 processor and core peripherals */ +#include /* STM32F0xx System Header */ #include /** @addtogroup Peripheral_registers_structures diff --git a/firmware/main.c b/firmware/main.c index 9c1a859..f849edc 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -1,6 +1,7 @@ #include #include #include +#include #define RING_MAX_LED 30u @@ -16,8 +17,7 @@ enum ring_modes { RING_MODE_MAX }; -unsigned int i = 0x12345678; -unsigned char c = 2; +volatile int32_t temperature; extern void sk6812_send_led(uint32_t rgbw); @@ -33,6 +33,7 @@ int main(void) { uint32_t led_val = 0x00UL; uint32_t led_calc_val[RING_MAX_LED] = {0x00UL}; + bool button_pressed = false; enum ring_modes mode = RING_MODE_ALL; @@ -55,9 +56,11 @@ int main(void) TIM3->PSC = 0; TIM3->CR1 = TIM_CR1_CEN; + temperature_adc_init(); + SysTick_Config(800000); while(1) { - + temperature = temperature_adc_get_temp(); switch (mode) { case RING_MODE_ALL: diff --git a/firmware/temp-adc.c b/firmware/temp-adc.c new file mode 100644 index 0000000..13d5258 --- /dev/null +++ b/firmware/temp-adc.c @@ -0,0 +1,102 @@ +#include +#include + +#define FLOAT_TO_S23_8(x) (int32_t)((x) * 1024.0f) + +static volatile uint16_t adc_results[16]; +static volatile int32_t vdd_lf_s23_8 = FLOAT_TO_S23_8(0); +static volatile int32_t temp_lf_s23_8 = FLOAT_TO_S23_8(0); + +void temperature_adc_init(void) +{ + RCC->AHBENR |= RCC_AHBENR_DMAEN; + RCC->APB2ENR |= RCC_APB2ENR_ADCEN; + + /* ADC is mapped to DMA Channel 1 */ + SYSCFG->CFGR1 &= ~SYSCFG_CFGR1_DMA_RMP; + + DMA1_Channel1->CNDTR = 16; + DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR; + DMA1_Channel1->CMAR = (uint32_t)&adc_results[0]; + DMA1_Channel1->CCR = DMA_CCR_PL_1 | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0 | DMA_CCR_MINC | DMA_CCR_CIRC | DMA_CCR_TCIE | DMA_CCR_EN; + + NVIC_EnableIRQ(DMA1_Channel1_IRQn); + + /* Calibrate the ADC */ + ADC1->CR = ADC_CR_ADCAL; + while (ADC1->CR & ADC_CR_ADCAL); + + /* Dummy read the offset calibration value */ + ADC1->DR; + ADC1->CR = 0; + ADC1->CFGR1 = ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG | ADC_CFGR1_CONT; + ADC1->CFGR2 = ADC_CFGR2_CKMODE_1; + ADC1->SMPR = 7u; + ADC->CCR |= ADC_CCR_TSEN | ADC_CCR_VREFEN; + ADC1->CHSELR = (1<<17) | (1<<16); + ADC1->CR = ADC_CR_ADEN | ADC_CR_ADSTART; +} + +static uint32_t get_temp_sensor_cal(void) +{ + const volatile uint16_t *cal; + + cal = (const volatile uint16_t *)0x1FFFF7B8UL; + return (uint32_t)*cal; +} + +int32_t temperature_adc_get_temp(void) +{ + int32_t temp; + const int32_t slope = FLOAT_TO_S23_8(5.336f); + + + temp = ((temp_lf_s23_8 / 16) * vdd_lf_s23_8 / FLOAT_TO_S23_8(3.3)) * 16; + temp = (get_temp_sensor_cal() << 10) - temp; + temp = (temp * 10 / slope) + 300; +} + +static uint32_t get_vrefint_cal(void) +{ + const volatile uint16_t *cal; + + cal = (const volatile uint16_t *)0x1FFFF7BAUL; + return (uint32_t)*cal; +} + +static void process_adc_samples(void) +{ + int i; + uint32_t temp_val = 0; + uint32_t vref_val = 0; + int32_t vdd_s23_8; + int32_t temp_s23_8; + const uint32_t ref_cal = get_vrefint_cal(); + + for (i = 0; i < 8; i++) { + temp_val += adc_results[2 * i]; + vref_val += adc_results[(2 * i) + 1]; + } + + vref_val >>= 3; + temp_val >>= 3; + + vdd_s23_8 = (FLOAT_TO_S23_8(3.3f) * ref_cal) / vref_val; + temp_s23_8 = temp_val << 10; + + /* Moving average filter */ + vdd_lf_s23_8 = (vdd_lf_s23_8 * FLOAT_TO_S23_8(0.78125f) + vdd_s23_8 * FLOAT_TO_S23_8(0.21875f)) >> 10; + temp_lf_s23_8 = (int32_t)((((int64_t)temp_lf_s23_8 * (int64_t)FLOAT_TO_S23_8(0.78125f)) + temp_s23_8 * FLOAT_TO_S23_8(0.21875f)) / 1024); +} + +void DMA_CH1_IRQHandler(void) +{ + uint32_t isr; + + isr = DMA1->ISR; + DMA1->IFCR = isr; + + if (isr & DMA_ISR_TCIF1) { + process_adc_samples(); + } +} \ No newline at end of file