Compare commits
9 Commits
edb59d7e6b
...
bd15878cb5
| Author | SHA1 | Date | |
|---|---|---|---|
| bd15878cb5 | |||
| 5ddcf4b15e | |||
| 05e3397d95 | |||
| ae9cdc3582 | |||
| a0dadf166d | |||
| a1028b29b8 | |||
| 449ec77f9f | |||
| 92085aabb0 | |||
| 6ab59f1545 |
79
drv/bkp.c
79
drv/bkp.c
@ -18,12 +18,14 @@
|
||||
|
||||
//--local definitions-----------------------------------------------------------
|
||||
|
||||
uint32_t compute_prescaler(uint32_t period_ms, enum BkpRtcClockSrc clock_src);
|
||||
static uint32_t compute_prescaler(uint32_t period_ms,
|
||||
enum BkpRtcClockSrc clock_src);
|
||||
static void lsi_calib_callback(enum TimIRQSource src);
|
||||
|
||||
|
||||
//--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 RTC* rtc_regs = (struct RTC*)RTC_BASE_ADDRESS;
|
||||
|
||||
@ -103,12 +105,62 @@ uint32_t bkp_read_rtc(void)
|
||||
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)
|
||||
{
|
||||
rcc_regs->BDCR.BDRST = 1;
|
||||
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-------------------------------------------------------------
|
||||
|
||||
@ -116,25 +168,38 @@ void bkp_reset(void)
|
||||
* Computes the prescaler value based on the clock source and the required
|
||||
* period
|
||||
*/
|
||||
uint32_t compute_prescaler(uint32_t period_ms, enum BkpRtcClockSrc clock_src)
|
||||
static uint32_t compute_prescaler(uint32_t period_ms,
|
||||
enum BkpRtcClockSrc clock_src)
|
||||
{
|
||||
uint32_t prescaler;
|
||||
|
||||
switch (clock_src) {
|
||||
case BKP_RTC_CLOCK_SRC_LSE:
|
||||
prescaler = 32768000; //32.768kHz
|
||||
prescaler = 32768; //32.768kHz
|
||||
break;
|
||||
case BKP_RTC_CLOCK_SRC_LSI:
|
||||
prescaler = 40000000; //40khz
|
||||
prescaler = bkp_read_data(BKP_DATA_LSI_CALIB);
|
||||
if (prescaler == 0) {
|
||||
prescaler = 40000; //40khz
|
||||
}
|
||||
break;
|
||||
case BKP_RTC_CLOCK_SRC_HSE:
|
||||
prescaler = 62500000; //8Mhz / 128
|
||||
prescaler = 62500; //8Mhz / 128
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return prescaler / period_ms;
|
||||
return (period_ms * prescaler) / 1000;
|
||||
}
|
||||
|
||||
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,6 +14,7 @@
|
||||
//--includes--------------------------------------------------------------------
|
||||
|
||||
#include "stdint.h"
|
||||
#include "tim.h"
|
||||
|
||||
|
||||
//--type definitions------------------------------------------------------------
|
||||
@ -39,6 +40,19 @@ enum BkpRtcIrq {
|
||||
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
|
||||
*/
|
||||
@ -85,6 +99,7 @@ void bkp_set_rtc_alam(uint32_t offset);
|
||||
* Returns the current counter value of the RTC
|
||||
*/
|
||||
uint32_t bkp_read_rtc(void);
|
||||
uint32_t bkp_read_rtc_div(void);
|
||||
|
||||
/**
|
||||
* Resets the entire backup domain, composed of everything configured through
|
||||
@ -92,9 +107,13 @@ uint32_t bkp_read_rtc(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
|
||||
void bkp_configure_tamper();
|
||||
void bkp_calibrate_lsi(void);
|
||||
void bkp_configure_lse(bool enable);
|
||||
|
||||
|
||||
|
||||
@ -62,6 +62,7 @@ union BKP_CSR {
|
||||
};
|
||||
|
||||
struct BKP {
|
||||
uint32_t reserved1;
|
||||
union BKP_DR DR[20];
|
||||
union BKP_RTCCR RTCCR;
|
||||
union BKP_CR CR;
|
||||
|
||||
@ -96,7 +96,7 @@ enum DmaIRQSource {
|
||||
/**
|
||||
* Prototype of the IRQ callbacks that the applicative code can provide
|
||||
*/
|
||||
typedef void (*DmaCallback)(enum DmaIRQSource, volatile void* param);
|
||||
typedef void (*DmaCallback)(enum DmaIRQSource src, volatile void* param);
|
||||
|
||||
/**
|
||||
* Generic struct used to share DAM configs between peripheral drivers and
|
||||
|
||||
@ -94,17 +94,20 @@ void rcc_reset(enum RccApb1 apb1_mask, enum RccApb2 apb2_mask)
|
||||
|
||||
void rcc_get_clocks(struct RccClocks* clocks)
|
||||
{
|
||||
clocks->ahb_freq = 0;
|
||||
switch (current_preset)
|
||||
{
|
||||
case RCC_PRESET_DEFAULT:
|
||||
clocks->ahb_freq = 8000000;
|
||||
clocks->apb1_freq = 8000000;
|
||||
clocks->apb2_freq = 8000000;
|
||||
clocks->tim_freq = 8000000;
|
||||
break;
|
||||
case RCC_PRESET_SPEED:
|
||||
clocks->ahb_freq = 72000000;
|
||||
clocks->apb1_freq = 36000000;
|
||||
clocks->apb2_freq = 72000000;
|
||||
clocks->tim_freq = 72000000;
|
||||
break;
|
||||
default:
|
||||
//TODO hardfault
|
||||
|
||||
@ -106,6 +106,7 @@ struct RccClocks {
|
||||
uint32_t ahb_freq;
|
||||
uint32_t apb1_freq;
|
||||
uint32_t apb2_freq;
|
||||
uint32_t tim_freq;
|
||||
};
|
||||
|
||||
|
||||
|
||||
47
drv/tim.c
47
drv/tim.c
@ -47,13 +47,12 @@ void tim_configure_master(enum TimPeriph periph, enum TimConfig config_mask,
|
||||
callbacks[periph] = callback;
|
||||
|
||||
regs[periph]->dier.TIE = 1;
|
||||
regs[periph]->dier.UIE = 1;
|
||||
regs[periph]->dier.UIE = 0;
|
||||
|
||||
enum NvicIrq irq = 0;
|
||||
switch (periph) {
|
||||
case TIM_PERIPH_1:
|
||||
irq = NVIC_IRQ_TIM1_BRK | NVIC_IRQ_TIM1_UP
|
||||
| NVIC_IRQ_TIM1_TRG_COM | NVIC_IRQ_TIM1_CC;
|
||||
irq = NVIC_IRQ_TIM1_UP;
|
||||
break;
|
||||
case TIM_PERIPH_2:
|
||||
irq = NVIC_IRQ_TIM2;
|
||||
@ -71,6 +70,12 @@ void tim_configure_master(enum TimPeriph periph, enum TimConfig config_mask,
|
||||
|
||||
//trigger update to force application of the config
|
||||
regs[periph]->egr.UG = 1;
|
||||
while (regs[periph]->sr.UIF == 0) {}
|
||||
regs[periph]->sr.UIF = 0;
|
||||
|
||||
if (callback != nullptr) {
|
||||
regs[periph]->dier.UIE = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -144,49 +149,13 @@ static enum TimIRQSource computeIRQSource(enum TimPeriph periph)
|
||||
|
||||
//--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)
|
||||
{
|
||||
nvic_clear_pending(NVIC_IRQ_TIM1_UP);
|
||||
|
||||
enum TimIRQSource src = computeIRQSource(TIM_PERIPH_1);
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
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_CONFIG_PRIO_LOW, tx_buffer, BUFFER_SIZE);
|
||||
|
||||
debug_trace("\n");
|
||||
debug_trace("------------------------------------------------------------------------------\n");
|
||||
debug_trace("starting debug software\n");
|
||||
debug_trace("compiled on " __DATE__ " at " __TIME__ "\n");
|
||||
debug_trace("------------------------------------------------------------------------------\n");
|
||||
debug_trace("");
|
||||
debug_trace("------------------------------------------------------------------------------");
|
||||
debug_trace("starting debug software");
|
||||
debug_trace("compiled on " __DATE__ " at " __TIME__);
|
||||
debug_trace("------------------------------------------------------------------------------");
|
||||
}
|
||||
|
||||
void _debug_print(const char* restrict header,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user