Add ADC code to measure temperature. Supervisor not yet implemented

This commit is contained in:
Mario Hüttel 2021-04-03 22:48:53 +02:00
parent f47631b2cf
commit e8606bcea8
6 changed files with 125 additions and 9 deletions

View File

@ -12,6 +12,7 @@ endif
#Add Files and Folders below######################################################### #Add Files and Folders below#########################################################
CFILES = main.c syscalls/syscalls.c setup/system_init.c startup/startup_stm32f0xx.c CFILES = main.c syscalls/syscalls.c setup/system_init.c startup/startup_stm32f0xx.c
CFILES += temp-adc.c
ASFILES = sk6812.S ASFILES = sk6812.S
INCLUDEPATH = -Iinclude -Iinclude/cmsis 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 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 = -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
#################################################################################### ####################################################################################

View File

@ -145,8 +145,8 @@
#endif #endif
#include <stdint.h> /* standard types definitions */ #include <stdint.h> /* standard types definitions */
#include <core_cmInstr.h> /* Core Instruction Access */ #include <cmsis/core_cmInstr.h> /* Core Instruction Access */
#include <core_cmFunc.h> /* Core Function Access */ #include <cmsis/core_cmFunc.h> /* Core Function Access */
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -0,0 +1,10 @@
#ifndef _TEMP_ADC_H_
#define _TEMP_ADC_H_
#include <stdint.h>
void temperature_adc_init(void);
int32_t temperature_adc_get_temp(void);
#endif /* _TEMP_ADC_H_ */

View File

@ -9,7 +9,7 @@
* This file contains: * This file contains:
* - Data structures and the address mapping for all peripherals * - Data structures and the address mapping for all peripherals
* - Peripheral's registers declarations and bits definition * - Peripheral's registers declarations and bits definition
* - Macros to access peripherals registers hardware * - Macros to access peripheral<EFBFBD>s registers hardware
* *
****************************************************************************** ******************************************************************************
* @attention * @attention
@ -114,8 +114,8 @@ typedef enum
* @} * @}
*/ */
#include "core_cm0.h" /* Cortex-M0 processor and core peripherals */ #include <cmsis/core_cm0.h> /* Cortex-M0 processor and core peripherals */
#include "system_stm32f0xx.h" /* STM32F0xx System Header */ #include <system_stm32f0xx.h> /* STM32F0xx System Header */
#include <stdint.h> #include <stdint.h>
/** @addtogroup Peripheral_registers_structures /** @addtogroup Peripheral_registers_structures

View File

@ -1,6 +1,7 @@
#include <stm32f0xx.h> #include <stm32f0xx.h>
#include <cmsis/core_cm0.h> #include <cmsis/core_cm0.h>
#include <stdbool.h> #include <stdbool.h>
#include <ring-light/temp-adc.h>
#define RING_MAX_LED 30u #define RING_MAX_LED 30u
@ -16,8 +17,7 @@ enum ring_modes {
RING_MODE_MAX RING_MODE_MAX
}; };
unsigned int i = 0x12345678; volatile int32_t temperature;
unsigned char c = 2;
extern void sk6812_send_led(uint32_t rgbw); extern void sk6812_send_led(uint32_t rgbw);
@ -33,6 +33,7 @@ int main(void)
{ {
uint32_t led_val = 0x00UL; uint32_t led_val = 0x00UL;
uint32_t led_calc_val[RING_MAX_LED] = {0x00UL}; uint32_t led_calc_val[RING_MAX_LED] = {0x00UL};
bool button_pressed = false; bool button_pressed = false;
enum ring_modes mode = RING_MODE_ALL; enum ring_modes mode = RING_MODE_ALL;
@ -55,9 +56,11 @@ int main(void)
TIM3->PSC = 0; TIM3->PSC = 0;
TIM3->CR1 = TIM_CR1_CEN; TIM3->CR1 = TIM_CR1_CEN;
temperature_adc_init();
SysTick_Config(800000); SysTick_Config(800000);
while(1) { while(1) {
temperature = temperature_adc_get_temp();
switch (mode) switch (mode)
{ {
case RING_MODE_ALL: case RING_MODE_ALL:

102
firmware/temp-adc.c Normal file
View File

@ -0,0 +1,102 @@
#include <ring-light/temp-adc.h>
#include <stm32f0xx.h>
#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();
}
}