Working termal probe
+ created basic library for ADCs, to be improved
This commit is contained in:
parent
55de91c274
commit
7730b983e3
42
src/drivers/adc.c
Normal file
42
src/drivers/adc.c
Normal 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
15
src/drivers/adc.h
Normal 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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -263,8 +263,6 @@ void timer_start(TIM_TypeDef *tmr) {
|
||||
|
||||
// enable counting
|
||||
tmr->CR1 |= 1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void timer_stop(TIM_TypeDef *tmr) {
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
14
src/main.c
14
src/main.c
@ -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;
|
||||
|
||||
Reference in New Issue
Block a user