Working termal probe

+ created basic library for ADCs, to be improved
This commit is contained in:
Steins7 2020-01-22 19:39:27 +01:00
parent 55de91c274
commit 7730b983e3
7 changed files with 101 additions and 26 deletions

42
src/drivers/adc.c Normal file
View File

@ -0,0 +1,42 @@
#include "adc.h"
extern Clock_t sysclks;
int adc_init(ADC_TypeDef* adc) {
// enable adc clock
if(adc == ADC1) RCC->APB2ENR |= 0x1 << 9;
else if(adc == ADC2) RCC->APB2ENR |= 0x1 << 10;
else return -1; //no such adc
// enable adc
adc->CR2 |= 0x1;
// configure regular channels
adc->CR1 = 0; //reset value
adc->CR1 |= 0x1 << 23; //enable analog watchdog
adc->CR1 |= 0x1 << 11; //discontinuous mode
// set trigger to manual
adc->CR1 |= 0x7 << 3;
adc->SMPR2 |= 0x7;
// calibrate
adc->CR2 |= 0x1 << 2;
while((adc->CR2 >> 2) & 0x1);
return 0;
}
uint16_t adc_read(ADC_TypeDef* adc, uint8_t channel) {
adc->SQR1 &= ~(0xF << 20); //one conversion only
adc->SQR3 = (adc->SQR3 & ~(0x1F)) | channel; //set channel
//adc->CR2 |= 0x1 << 22; //start convertion
adc->CR2 |= 0x1;
while(!((adc->SR >> 1) & 0x1)); //waiting for convertion
return adc->DR & 0xFFFF;
}

15
src/drivers/adc.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef ADC_H
#define ADC_H
#include "../target/stm32f103xb.h"
#include "../config.h"
#include "rcc.h"
int adc_init(ADC_TypeDef* adc);
uint16_t adc_read(ADC_TypeDef* adc, uint8_t channel);
#endif

View File

@ -27,8 +27,8 @@ derived from the System clock (I2S, RTC, ADC, USB OTG FS/SDIO/RNG)
==============================================================================
[..]
A delay between an RCC peripheral clock enable and the effective peripheral
enabling should be taken into account in order to manage the peripheral read/write
from/to registers.
enabling should be taken into account in order to manage the peripheral
read/write from/to registers.
(+) This delay depends on the peripheral mapping.
(+) If peripheral is mapped on AHB: the delay is 2 AHB clock cycle
after the clock enable bit is set on the hardware register
@ -66,6 +66,12 @@ register is required.
/* PPLMUL: PPL multiplier */
#define RCC_CFGR_PLLMUL(fac) (fac + 2)
/* ADC: ADCPRE prescalers */
#define RCC_CFGR_ADCPRE_DIV_2 0x0
#define RCC_CFGR_ADCPRE_DIV_4 0x1
#define RCC_CFGR_ADCPRE_DIV_6 0x2
#define RCC_CFGR_ADCPRE_DIV_8 0x3
enum rcc_osc {
RCC_HSI,
RCC_HSE,
@ -81,6 +87,7 @@ struct ClockConfig_t {
uint8_t hpre;
uint8_t ppre1;
uint8_t ppre2;
uint8_t adcpre;
uint32_t flash_cfg;
uint32_t ahb_freq;
uint32_t apb1_freq;
@ -91,10 +98,11 @@ static struct ClockConfig_t _clock_config[] = {
{/* Performance Mode */
.type = RCC_PLL,
.pll_src = RCC_HSE, //8MHz
.pllmul = RCC_CFGR_PLLMUL(9), //freq should noot exceed 72MHz
.pllmul = RCC_CFGR_PLLMUL(9), //freq should noot exceed 72MHz
.hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_2, //freq should not exceed 36MHz
.ppre1 = RCC_CFGR_PPRE_DIV_2, //freq should not exceed 36MHz
.ppre2 = RCC_CFGR_PPRE_DIV_NONE,
.adcpre = RCC_CFGR_ADCPRE_DIV_6, //freq should not exceed 14MHz
.flash_cfg = FLASH_ACR_LATENCY_2,
.ahb_freq = 72000000,
.apb1_freq = 36000000,
@ -106,6 +114,7 @@ static struct ClockConfig_t _clock_config[] = {
.hpre = RCC_CFGR_HPRE_DIV_16,
.ppre1 = RCC_CFGR_PPRE_DIV_16,
.ppre2 = RCC_CFGR_PPRE_DIV_16,
.adcpre = RCC_CFGR_ADCPRE_DIV_2,
.flash_cfg = FLASH_ACR_LATENCY_0,
.ahb_freq = 500000,
.apb1_freq = 500000,
@ -206,10 +215,11 @@ void rcc_config_clock(uint32_t config, Clock_t *sysclks)
// AHB: AHBCLK > 25MHz
// APB1: APB1CLK <= 36MHz
// APB2: APB2CLK <= 72MHz
RCC->CFGR = ( RCC->CFGR & ~((0x3F<<8) | (0xF<<4)) ) |
RCC->CFGR = ( RCC->CFGR & ~((0x3F<<8) | (0xF<<4) | (0x3<<14)) ) |
((clk->hpre & 0xF) << 4) |
((clk->ppre1 & 0x7) << 8) |
((clk->ppre2 & 0x7) << 11);
((clk->ppre2 & 0x7) << 11)|
(clk->adcpre << 14);
// configure PLL
RCC->CFGR &= !(0xF<<18);
@ -241,7 +251,8 @@ void rcc_config_clock(uint32_t config, Clock_t *sysclks)
sysclks->ahb_freq = clk->ahb_freq;
sysclks->apb1_freq = clk->apb1_freq;
sysclks->apb2_freq = clk->apb2_freq;
//TODO check timer frequencies
sysclks->apb1_timer_freq = clk->ppre1==RCC_CFGR_PPRE_DIV_NONE ? clk->apb1_freq : 2*clk->apb1_freq;
sysclks->apb2_timer_freq = clk->ppre2==RCC_CFGR_PPRE_DIV_NONE ? clk->apb2_freq : 2*clk->apb2_freq;
sysclks->apb1_timer_freq =
clk->ppre1==RCC_CFGR_PPRE_DIV_NONE ? clk->apb1_freq : 2*clk->apb1_freq;
sysclks->apb2_timer_freq =
clk->ppre2==RCC_CFGR_PPRE_DIV_NONE ? clk->apb2_freq : 2*clk->apb2_freq;
}

View File

@ -5,6 +5,8 @@
!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/
!_TAG_PROGRAM_URL https://ctags.io/ /official site/
!_TAG_PROGRAM_VERSION 0.0.0 /3fdf28bc/
ADC_Data adc.h /^} ADC_Data;$/;" t typeref:struct:__anon0f12ca630108
ADC_H adc.h /^#define ADC_H$/;" d
CLOCK_CONFIG_END rcc.h /^ CLOCK_CONFIG_END$/;" e enum:Clock_config
CLOCK_CONFIG_PERFORMANCE rcc.h /^ CLOCK_CONFIG_PERFORMANCE,$/;" e enum:Clock_config
CLOCK_CONFIG_POWERSAVE rcc.h /^ CLOCK_CONFIG_POWERSAVE,$/;" e enum:Clock_config
@ -49,6 +51,10 @@ PIN_7 io.h /^ PIN_7 = (1 << 7),$/;" e enum:io_pin
PIN_8 io.h /^ PIN_8 = (1 << 8),$/;" e enum:io_pin
PIN_9 io.h /^ PIN_9 = (1 << 9),$/;" e enum:io_pin
PIN_ALL io.h /^ PIN_ALL = 0xFFFF$/;" e enum:io_pin
RCC_CFGR_ADCPRE_DIV_2 rcc.c /^#define RCC_CFGR_ADCPRE_DIV_2 /;" d file:
RCC_CFGR_ADCPRE_DIV_4 rcc.c /^#define RCC_CFGR_ADCPRE_DIV_4 /;" d file:
RCC_CFGR_ADCPRE_DIV_6 rcc.c /^#define RCC_CFGR_ADCPRE_DIV_6 /;" d file:
RCC_CFGR_ADCPRE_DIV_8 rcc.c /^#define RCC_CFGR_ADCPRE_DIV_8 /;" d file:
RCC_CFGR_HPRE_DIV_128 rcc.c /^#define RCC_CFGR_HPRE_DIV_128 /;" d file:
RCC_CFGR_HPRE_DIV_16 rcc.c /^#define RCC_CFGR_HPRE_DIV_16 /;" d file:
RCC_CFGR_HPRE_DIV_256 rcc.c /^#define RCC_CFGR_HPRE_DIV_256 /;" d file:
@ -79,11 +85,15 @@ TIM1_UP_IRQHandler timer.c /^void TIM1_UP_IRQHandler(void) {$/;" f typeref:typen
TIM2_IRQHandler timer.c /^void TIM2_IRQHandler(void) {$/;" f typeref:typename:void
TIM3_IRQHandler timer.c /^void TIM3_IRQHandler(void) {$/;" f typeref:typename:void
TIM4_IRQHandler timer.c /^void TIM4_IRQHandler(void) {$/;" f typeref:typename:void
TIMER_H timer.h /^#define TIMER_H$/;" d
_Clock_t rcc.h /^typedef struct _Clock_t {$/;" s
_IO_H_ io.h /^#define _IO_H_$/;" d
_RCC_H_ rcc.h /^#define _RCC_H_$/;" d
_TIMER_H_ timer.h /^#define _TIMER_H_$/;" d
__anon0f12ca630108 adc.h /^typedef struct {$/;" s
_clock_config rcc.c /^static struct ClockConfig_t _clock_config[] = {$/;" v typeref:struct:ClockConfig_t[] file:
adc_init adc.c /^int adc_init(ADC_TypeDef* adc) {$/;" f typeref:typename:int
adc_read adc.c /^int adc_read(void) {$/;" f typeref:typename:int
adcpre rcc.c /^ uint8_t adcpre;$/;" m struct:ClockConfig_t typeref:typename:uint8_t file:
ahb_freq rcc.c /^ uint32_t ahb_freq;$/;" m struct:ClockConfig_t typeref:typename:uint32_t file:
ahb_freq rcc.h /^ uint32_t ahb_freq;$/;" m struct:_Clock_t typeref:typename:uint32_t
apb1_freq rcc.c /^ uint32_t apb1_freq;$/;" m struct:ClockConfig_t typeref:typename:uint32_t file:
@ -117,7 +127,7 @@ rcc_osc_off rcc.c /^static void rcc_osc_off(enum rcc_osc osc)$/;" f typeref:type
rcc_osc_on rcc.c /^static void rcc_osc_on(enum rcc_osc osc)$/;" f typeref:typename:void file:
rcc_osc rcc.c /^enum rcc_osc {$/;" g file:
rcc_set_sysclk rcc.c /^static void rcc_set_sysclk(enum rcc_osc osc)$/;" f typeref:typename:void file:
timer_config_cb timer.c /^int timer_config_cb(TIM_TypeDef* tmr, OnTick cb) {$/;" f typeref:typename:int
timer_config_cb timer.c /^int timer_config_cb(TIM_TypeDef* tmr, uint32_t* clk, OnTick cb) {$/;" f typeref:typename:int
timer_set_period timer.c /^int timer_set_period(TIM_TypeDef *tmr, uint16_t tick) {$/;" f typeref:typename:int
timer_start timer.c /^void timer_start(TIM_TypeDef *tmr) {$/;" f typeref:typename:void
timer_stop timer.c /^void timer_stop(TIM_TypeDef *tmr) {$/;" f typeref:typename:void

View File

@ -263,8 +263,6 @@ void timer_start(TIM_TypeDef *tmr) {
// enable counting
tmr->CR1 |= 1;
}
void timer_stop(TIM_TypeDef *tmr) {

View File

@ -1,14 +1,10 @@
#ifndef _TIMER_H_
#define _TIMER_H_
#ifndef TIMER_H
#define TIMER_H
#include "../target/stm32f103xb.h"
#include "../config.h"
#include "rcc.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*OnTick)(void);
//------------------------------------------------------------------------------
@ -81,8 +77,5 @@ void timer_stop(TIM_TypeDef *tmr);
// */
//#define pwm_stop(pwm) timer_stop(pwm)
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,11 +1,13 @@
#include "drivers/rcc.h"
#include "drivers/io.h"
#include "drivers/adc.h"
Clock_t sysclks;
#include "drivers/timer.h"
int val = 0;
uint16_t data = 0;
static void timeout_cb(void) {
io_write(GPIOC, val, PIN_13);
@ -20,12 +22,16 @@ int main(void) {
return 0;
io_write(GPIOC, 1, PIN_13);
//timer_tick_init(TIM2, 1000, timeout_cb);
//timer_start(TIM2);
timer_tick_init(TIM2, 1000, timeout_cb);
timer_start(TIM2);
if(io_configure(GPIOA, PIN_4 | PIN_5, IO_MODE_INPUT | IO_IN_ANALOG, 0))
return 0;
if(adc_init(ADC1)) return 0;
for(;;){
timer_wait_ms(TIM1, 500, 0);
timer_wait_ms(TIM2, 500, timeout_cb);
data = adc_read(ADC1, 5);
data -= adc_read(ADC1, 4);
}
return 0;