Compare commits
No commits in common. "bd15878cb5a77d97248f7644ad8a0a36e9ac39a7" and "edb59d7e6b8f65b3920f6a27d4fdf4dd8ad4eef2" have entirely different histories.
bd15878cb5
...
edb59d7e6b
79
drv/bkp.c
79
drv/bkp.c
@ -18,14 +18,12 @@
|
|||||||
|
|
||||||
//--local definitions-----------------------------------------------------------
|
//--local definitions-----------------------------------------------------------
|
||||||
|
|
||||||
static uint32_t compute_prescaler(uint32_t period_ms,
|
uint32_t compute_prescaler(uint32_t period_ms, enum BkpRtcClockSrc clock_src);
|
||||||
enum BkpRtcClockSrc clock_src);
|
|
||||||
static void lsi_calib_callback(enum TimIRQSource src);
|
|
||||||
|
|
||||||
|
|
||||||
//--local variables-------------------------------------------------------------
|
//--local variables-------------------------------------------------------------
|
||||||
|
|
||||||
static volatile struct BKP* bkp_regs = (struct BKP*)BKP_BASE_ADDRESS;
|
//static volatile struct BKP* bkp_regs = (struct BKP*)BKP_BASE_ADDRESS;
|
||||||
static volatile struct RCC* rcc_regs = (struct RCC*)RCC_BASE_ADDRESS;
|
static volatile struct RCC* rcc_regs = (struct RCC*)RCC_BASE_ADDRESS;
|
||||||
static volatile struct RTC* rtc_regs = (struct RTC*)RTC_BASE_ADDRESS;
|
static volatile struct RTC* rtc_regs = (struct RTC*)RTC_BASE_ADDRESS;
|
||||||
|
|
||||||
@ -105,62 +103,12 @@ uint32_t bkp_read_rtc(void)
|
|||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t bkp_read_rtc_div(void)
|
|
||||||
{
|
|
||||||
//wait for core registers to be synchronized, immediate most of the time
|
|
||||||
while (rtc_regs->CRL.RSF != 1) {}
|
|
||||||
|
|
||||||
uint32_t div = rtc_regs->DIVH.RTC_DIV << 16;
|
|
||||||
div |= rtc_regs->DIVL.RTC_DIV << 0;
|
|
||||||
|
|
||||||
return div;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bkp_reset(void)
|
void bkp_reset(void)
|
||||||
{
|
{
|
||||||
rcc_regs->BDCR.BDRST = 1;
|
rcc_regs->BDCR.BDRST = 1;
|
||||||
rcc_regs->BDCR.BDRST = 0;
|
rcc_regs->BDCR.BDRST = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bkp_write_data(enum BkpData data_index, uint16_t data)
|
|
||||||
{
|
|
||||||
bkp_regs->DR[data_index].D = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t bkp_read_data(enum BkpData data_index)
|
|
||||||
{
|
|
||||||
return bkp_regs->DR[data_index].D;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bkp_calibrate_lsi(enum TimPeriph timer)
|
|
||||||
{
|
|
||||||
rcc_enable(RCC_AHB_NONE, RCC_APB1_BKP, RCC_APB2_NONE);
|
|
||||||
|
|
||||||
//do not calibrate if already calibrated
|
|
||||||
if (bkp_read_data(BKP_DATA_LSI_CALIB) != 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//configure timer to count 1s exactly
|
|
||||||
struct RccClocks clocks;
|
|
||||||
rcc_get_clocks(&clocks);
|
|
||||||
|
|
||||||
tim_set_prescaler(timer, (clocks.tim_freq / 10000)); //10000 to avoid
|
|
||||||
//prescaler overflow
|
|
||||||
tim_set_auto_reload(timer, 10000);
|
|
||||||
tim_configure_master(timer, TIM_CONFIG_ONE_SHOT
|
|
||||||
| TIM_CONFIG_DIR_UP, TIM_MASTER_CONFIG_MODE_RESET,
|
|
||||||
lsi_calib_callback);
|
|
||||||
|
|
||||||
//configure rtc to tick every 2s so the div value isn't reset during the
|
|
||||||
//timer's delay if the clock is too fast
|
|
||||||
bkp_configure_rtc(2000, BKP_RTC_CLOCK_SRC_LSI, BKP_RTC_IRQ_NONE, nullptr);
|
|
||||||
tim_start(timer);
|
|
||||||
|
|
||||||
while (bkp_read_data(BKP_DATA_LSI_CALIB) == 0) {}
|
|
||||||
|
|
||||||
//TODO reset timer
|
|
||||||
}
|
|
||||||
|
|
||||||
//--local functions-------------------------------------------------------------
|
//--local functions-------------------------------------------------------------
|
||||||
|
|
||||||
@ -168,38 +116,25 @@ void bkp_calibrate_lsi(enum TimPeriph timer)
|
|||||||
* Computes the prescaler value based on the clock source and the required
|
* Computes the prescaler value based on the clock source and the required
|
||||||
* period
|
* period
|
||||||
*/
|
*/
|
||||||
static uint32_t compute_prescaler(uint32_t period_ms,
|
uint32_t compute_prescaler(uint32_t period_ms, enum BkpRtcClockSrc clock_src)
|
||||||
enum BkpRtcClockSrc clock_src)
|
|
||||||
{
|
{
|
||||||
uint32_t prescaler;
|
uint32_t prescaler;
|
||||||
|
|
||||||
switch (clock_src) {
|
switch (clock_src) {
|
||||||
case BKP_RTC_CLOCK_SRC_LSE:
|
case BKP_RTC_CLOCK_SRC_LSE:
|
||||||
prescaler = 32768; //32.768kHz
|
prescaler = 32768000; //32.768kHz
|
||||||
break;
|
break;
|
||||||
case BKP_RTC_CLOCK_SRC_LSI:
|
case BKP_RTC_CLOCK_SRC_LSI:
|
||||||
prescaler = bkp_read_data(BKP_DATA_LSI_CALIB);
|
prescaler = 40000000; //40khz
|
||||||
if (prescaler == 0) {
|
|
||||||
prescaler = 40000; //40khz
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case BKP_RTC_CLOCK_SRC_HSE:
|
case BKP_RTC_CLOCK_SRC_HSE:
|
||||||
prescaler = 62500; //8Mhz / 128
|
prescaler = 62500000; //8Mhz / 128
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (period_ms * prescaler) / 1000;
|
return prescaler / period_ms;
|
||||||
}
|
|
||||||
|
|
||||||
static void lsi_calib_callback(enum TimIRQSource src)
|
|
||||||
{
|
|
||||||
if (src == TIM_IRQ_SOURCE_UPDATE) {
|
|
||||||
//div is decremented from 40kHz * programmed delay (in s)
|
|
||||||
uint32_t lsi_freq = (40000 * 2) - bkp_read_rtc_div();
|
|
||||||
bkp_write_data(BKP_DATA_LSI_CALIB, lsi_freq);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
21
drv/bkp.h
21
drv/bkp.h
@ -14,7 +14,6 @@
|
|||||||
//--includes--------------------------------------------------------------------
|
//--includes--------------------------------------------------------------------
|
||||||
|
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
#include "tim.h"
|
|
||||||
|
|
||||||
|
|
||||||
//--type definitions------------------------------------------------------------
|
//--type definitions------------------------------------------------------------
|
||||||
@ -40,19 +39,6 @@ enum BkpRtcIrq {
|
|||||||
BKP_RTC_IRQ_OVERFLOW = 0x1 << 2,
|
BKP_RTC_IRQ_OVERFLOW = 0x1 << 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BkpData {
|
|
||||||
BKP_DATA_LSI_CALIB,
|
|
||||||
BKP_DATA_1,
|
|
||||||
BKP_DATA_2,
|
|
||||||
BKP_DATA_3,
|
|
||||||
BKP_DATA_4,
|
|
||||||
BKP_DATA_5,
|
|
||||||
BKP_DATA_6,
|
|
||||||
BKP_DATA_7,
|
|
||||||
BKP_DATA_8,
|
|
||||||
BKP_DATA_9,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prototype of the IRQ callbacks that the applicative code can provide
|
* Prototype of the IRQ callbacks that the applicative code can provide
|
||||||
*/
|
*/
|
||||||
@ -99,7 +85,6 @@ void bkp_set_rtc_alam(uint32_t offset);
|
|||||||
* Returns the current counter value of the RTC
|
* Returns the current counter value of the RTC
|
||||||
*/
|
*/
|
||||||
uint32_t bkp_read_rtc(void);
|
uint32_t bkp_read_rtc(void);
|
||||||
uint32_t bkp_read_rtc_div(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the entire backup domain, composed of everything configured through
|
* Resets the entire backup domain, composed of everything configured through
|
||||||
@ -107,13 +92,9 @@ uint32_t bkp_read_rtc_div(void);
|
|||||||
*/
|
*/
|
||||||
void bkp_reset(void);
|
void bkp_reset(void);
|
||||||
|
|
||||||
void bkp_write_data(enum BkpData data_index, uint16_t data);
|
|
||||||
uint16_t bkp_read_data(enum BkpData data_index);
|
|
||||||
|
|
||||||
void bkp_calibrate_lsi(enum TimPeriph timer);
|
|
||||||
|
|
||||||
//unimplemented functions
|
//unimplemented functions
|
||||||
void bkp_configure_tamper();
|
void bkp_configure_tamper();
|
||||||
|
void bkp_calibrate_lsi(void);
|
||||||
void bkp_configure_lse(bool enable);
|
void bkp_configure_lse(bool enable);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -62,7 +62,6 @@ union BKP_CSR {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct BKP {
|
struct BKP {
|
||||||
uint32_t reserved1;
|
|
||||||
union BKP_DR DR[20];
|
union BKP_DR DR[20];
|
||||||
union BKP_RTCCR RTCCR;
|
union BKP_RTCCR RTCCR;
|
||||||
union BKP_CR CR;
|
union BKP_CR CR;
|
||||||
|
|||||||
@ -96,7 +96,7 @@ enum DmaIRQSource {
|
|||||||
/**
|
/**
|
||||||
* Prototype of the IRQ callbacks that the applicative code can provide
|
* Prototype of the IRQ callbacks that the applicative code can provide
|
||||||
*/
|
*/
|
||||||
typedef void (*DmaCallback)(enum DmaIRQSource src, volatile void* param);
|
typedef void (*DmaCallback)(enum DmaIRQSource, volatile void* param);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic struct used to share DAM configs between peripheral drivers and
|
* Generic struct used to share DAM configs between peripheral drivers and
|
||||||
|
|||||||
@ -94,20 +94,17 @@ void rcc_reset(enum RccApb1 apb1_mask, enum RccApb2 apb2_mask)
|
|||||||
|
|
||||||
void rcc_get_clocks(struct RccClocks* clocks)
|
void rcc_get_clocks(struct RccClocks* clocks)
|
||||||
{
|
{
|
||||||
clocks->ahb_freq = 0;
|
|
||||||
switch (current_preset)
|
switch (current_preset)
|
||||||
{
|
{
|
||||||
case RCC_PRESET_DEFAULT:
|
case RCC_PRESET_DEFAULT:
|
||||||
clocks->ahb_freq = 8000000;
|
clocks->ahb_freq = 8000000;
|
||||||
clocks->apb1_freq = 8000000;
|
clocks->apb1_freq = 8000000;
|
||||||
clocks->apb2_freq = 8000000;
|
clocks->apb2_freq = 8000000;
|
||||||
clocks->tim_freq = 8000000;
|
|
||||||
break;
|
break;
|
||||||
case RCC_PRESET_SPEED:
|
case RCC_PRESET_SPEED:
|
||||||
clocks->ahb_freq = 72000000;
|
clocks->ahb_freq = 72000000;
|
||||||
clocks->apb1_freq = 36000000;
|
clocks->apb1_freq = 36000000;
|
||||||
clocks->apb2_freq = 72000000;
|
clocks->apb2_freq = 72000000;
|
||||||
clocks->tim_freq = 72000000;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
//TODO hardfault
|
//TODO hardfault
|
||||||
|
|||||||
@ -106,7 +106,6 @@ struct RccClocks {
|
|||||||
uint32_t ahb_freq;
|
uint32_t ahb_freq;
|
||||||
uint32_t apb1_freq;
|
uint32_t apb1_freq;
|
||||||
uint32_t apb2_freq;
|
uint32_t apb2_freq;
|
||||||
uint32_t tim_freq;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
49
drv/tim.c
49
drv/tim.c
@ -47,12 +47,13 @@ void tim_configure_master(enum TimPeriph periph, enum TimConfig config_mask,
|
|||||||
callbacks[periph] = callback;
|
callbacks[periph] = callback;
|
||||||
|
|
||||||
regs[periph]->dier.TIE = 1;
|
regs[periph]->dier.TIE = 1;
|
||||||
regs[periph]->dier.UIE = 0;
|
regs[periph]->dier.UIE = 1;
|
||||||
|
|
||||||
enum NvicIrq irq = 0;
|
enum NvicIrq irq = 0;
|
||||||
switch (periph) {
|
switch (periph) {
|
||||||
case TIM_PERIPH_1:
|
case TIM_PERIPH_1:
|
||||||
irq = NVIC_IRQ_TIM1_UP;
|
irq = NVIC_IRQ_TIM1_BRK | NVIC_IRQ_TIM1_UP
|
||||||
|
| NVIC_IRQ_TIM1_TRG_COM | NVIC_IRQ_TIM1_CC;
|
||||||
break;
|
break;
|
||||||
case TIM_PERIPH_2:
|
case TIM_PERIPH_2:
|
||||||
irq = NVIC_IRQ_TIM2;
|
irq = NVIC_IRQ_TIM2;
|
||||||
@ -70,12 +71,6 @@ void tim_configure_master(enum TimPeriph periph, enum TimConfig config_mask,
|
|||||||
|
|
||||||
//trigger update to force application of the config
|
//trigger update to force application of the config
|
||||||
regs[periph]->egr.UG = 1;
|
regs[periph]->egr.UG = 1;
|
||||||
while (regs[periph]->sr.UIF == 0) {}
|
|
||||||
regs[periph]->sr.UIF = 0;
|
|
||||||
|
|
||||||
if (callback != nullptr) {
|
|
||||||
regs[periph]->dier.UIE = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -149,12 +144,48 @@ static enum TimIRQSource computeIRQSource(enum TimPeriph periph)
|
|||||||
|
|
||||||
//--ISRs------------------------------------------------------------------------
|
//--ISRs------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void hdr_tim1_brk(void)
|
||||||
|
{
|
||||||
|
nvic_clear_pending(NVIC_IRQ_TIM1_BRK);
|
||||||
|
|
||||||
|
enum TimIRQSource src = computeIRQSource(TIM_PERIPH_1);
|
||||||
|
|
||||||
|
if (callbacks[TIM_PERIPH_1] != nullptr) {
|
||||||
|
callbacks[TIM_PERIPH_1](src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void hdr_tim1_up(void)
|
void hdr_tim1_up(void)
|
||||||
{
|
{
|
||||||
nvic_clear_pending(NVIC_IRQ_TIM1_UP);
|
nvic_clear_pending(NVIC_IRQ_TIM1_UP);
|
||||||
|
|
||||||
enum TimIRQSource src = computeIRQSource(TIM_PERIPH_1);
|
enum TimIRQSource src = computeIRQSource(TIM_PERIPH_1);
|
||||||
callbacks[TIM_PERIPH_1](src);
|
|
||||||
|
if (callbacks[TIM_PERIPH_1] != nullptr) {
|
||||||
|
callbacks[TIM_PERIPH_1](src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hdr_tim1_trg_com(void)
|
||||||
|
{
|
||||||
|
nvic_clear_pending(NVIC_IRQ_TIM1_TRG_COM);
|
||||||
|
|
||||||
|
enum TimIRQSource src = computeIRQSource(TIM_PERIPH_1);
|
||||||
|
|
||||||
|
if (callbacks[TIM_PERIPH_1] != nullptr) {
|
||||||
|
callbacks[TIM_PERIPH_1](src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hdr_tim1_cc(void)
|
||||||
|
{
|
||||||
|
nvic_clear_pending(NVIC_IRQ_TIM1_CC);
|
||||||
|
|
||||||
|
enum TimIRQSource src = computeIRQSource(TIM_PERIPH_1);
|
||||||
|
|
||||||
|
if (callbacks[TIM_PERIPH_1] != nullptr) {
|
||||||
|
callbacks[TIM_PERIPH_1](src);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hdr_tim2(void)
|
void hdr_tim2(void)
|
||||||
|
|||||||
10
srv/debug.c
10
srv/debug.c
@ -38,11 +38,11 @@ void _debug_init(enum UsartPeriph usart, enum GpioPort tx_port,
|
|||||||
dma_mbuf_configure(&mbuf,usart_configure_tx_dma(usart),
|
dma_mbuf_configure(&mbuf,usart_configure_tx_dma(usart),
|
||||||
DMA_CONFIG_PRIO_LOW, tx_buffer, BUFFER_SIZE);
|
DMA_CONFIG_PRIO_LOW, tx_buffer, BUFFER_SIZE);
|
||||||
|
|
||||||
debug_trace("");
|
debug_trace("\n");
|
||||||
debug_trace("------------------------------------------------------------------------------");
|
debug_trace("------------------------------------------------------------------------------\n");
|
||||||
debug_trace("starting debug software");
|
debug_trace("starting debug software\n");
|
||||||
debug_trace("compiled on " __DATE__ " at " __TIME__);
|
debug_trace("compiled on " __DATE__ " at " __TIME__ "\n");
|
||||||
debug_trace("------------------------------------------------------------------------------");
|
debug_trace("------------------------------------------------------------------------------\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void _debug_print(const char* restrict header,
|
void _debug_print(const char* restrict header,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user