Compare commits

..

No commits in common. "a4ca0d30c3cfc1668943adbebdf947d95de99848" and "80c027370b4102f876ae0a07cdcd8d2cb1a0dee4" have entirely different histories.

6 changed files with 110 additions and 122 deletions

View File

@ -1,11 +1,6 @@
/** @file bkp.c
* Module handling the Backup (BKP) domain functionalities.
*
* This module includes management of the Real Time Clock (RTC), Tamper
* protection system and a limited space (20 bytes) for persistent data storage
*
* All features present in this module stay running in standby mode / when
* no-longer powered, so long as VBAT is maintained
*/
//--includes--------------------------------------------------------------------
@ -33,7 +28,7 @@ static BkpRtcCallback rtc_callback;
//--public functions------------------------------------------------------------
void bkp_configure_rtc(uint32_t period_ms, enum BkpRtcClockSrc clock_src,
enum BkpRtcIrq irq_mask, BkpRtcCallback callback)
enum BkpRtcIrq irq_mask, uint32_t alarm_tick, BkpRtcCallback callback)
{
rcc_enable(RCC_AHB_NONE, RCC_APB1_BKP, RCC_APB2_NONE);
@ -55,6 +50,8 @@ void bkp_configure_rtc(uint32_t period_ms, enum BkpRtcClockSrc clock_src,
//configure core registers
rtc_regs->PRLH.PRL = prescaler >> 16;
rtc_regs->PRLL.PRL = prescaler;
rtc_regs->ALRH.RTC_ALR = alarm_tick >> 16;
rtc_regs->ALRL.RTC_ALR = alarm_tick;
//apply irq config
rtc_regs->CRH.word |= irq_mask & 0x7;
@ -71,27 +68,6 @@ void bkp_configure_rtc(uint32_t period_ms, enum BkpRtcClockSrc clock_src,
}
}
void bkp_set_rtc_alam(uint32_t offset)
{
uint32_t alarm = bkp_read_rtc() + offset;
//wait for last operation to finish
while (rtc_regs->CRL.RTOFF != 1) {}
//enable core configuration
rtc_regs->CRL.CNF = 1;
//write alarm value
rtc_regs->ALRH.RTC_ALR = alarm >> 16;
rtc_regs->ALRL.RTC_ALR = alarm;
//disable/apply core configuration
rtc_regs->CRL.CNF = 0;
//wait for last operation to finish
while (rtc_regs->CRL.RTOFF != 1) {}
}
uint32_t bkp_read_rtc(void)
{
//wait for core registers to be synchronized, immediate most of the time

View File

@ -1,11 +1,6 @@
/** @file bkp.h
* Module handling the Backup (BKP) domain functionalities.
*
* This module includes management of the Real Time Clock (RTC), Tamper
* protection system and a limited space (20 bytes) for persistent data storage
*
* All features present in this module stay running in standby mode / when
* no-longer powered, so long as VBAT is maintained
*/
#ifndef _BKP_H_
@ -63,23 +58,11 @@ typedef void (*BkpRtcCallback)(enum BkpRtcIrq src);
* Clocks must be enabled prior to calling this function
*
* Mulitple IRQs can be enabled and redirected to single callback. The alarm
* IRQ, triggered at the tick value specified by bkp_set_rtc_alam() can be
* rerouted to an exti line for wakeup from stop and standby, in wich case it
* doesn't need to be enabled here.
*
* Ensure backup domain writes are enabled (see pwr_configure_bkp_write()) while
* calling this function
* IRQ, triggered at the specified tick value can be rerouted to an exti line
* for wakeup from stanby, in wich case it doesn't need to be enabled here.
*/
void bkp_configure_rtc(uint32_t period_ms, enum BkpRtcClockSrc clock_src,
enum BkpRtcIrq irq_mask, BkpRtcCallback callback);
/**
* Configure the alarm to trigger after the specified time in ticks, which can
* be viewed as an offset to the current time value. This offset is only precise
* to the tick and thus if the tick changes right after this function is
* called, the observed offset will be close to 1 tick short
*/
void bkp_set_rtc_alam(uint32_t offset);
enum BkpRtcIrq irq_mask, uint32_t alarm_tick, BkpRtcCallback callback);
/**
* Returns the current counter value of the RTC

View File

@ -11,6 +11,7 @@
#include "exti_regs.h"
#include "nvic.h"
#include "afio.h"
//--local definitions-----------------------------------------------------------
@ -23,11 +24,13 @@ static ExtiCallback callbacks[19];
//--public functions------------------------------------------------------------
void exti_configure(enum ExtiLine line_mask, enum ExtiConfig config_mask,
ExtiCallback callback)
void exti_configure(enum ExtiLine line_mask, enum GpioPort port,
enum ExtiConfig config_mask, ExtiCallback callback)
{
exti_reset(line_mask);
afio_map_exti(line_mask, port);
//configure edge detections
if (config_mask & EXTI_CONFIG_RISING_EDGE) {
regs->RTSR.word |= line_mask;
@ -45,7 +48,7 @@ void exti_configure(enum ExtiLine line_mask, enum ExtiConfig config_mask,
regs->EMR.word |= line_mask;
if (callback) {
//register callbacks for each line selected
for (uint8_t i = 0; i < 19; ++i) {
for (uint8_t i = 0; i < 16; ++i) {
if (line_mask & (0x1 << i)) {
callbacks[i] = callback;
}
@ -63,15 +66,6 @@ void exti_configure(enum ExtiLine line_mask, enum ExtiConfig config_mask,
if (line_mask & 0x7c00) {
nvic_enable(NVIC_IRQ_EXTI15_10);
}
if (line_mask & EXTI_LINE_PVD) {
nvic_enable(NVIC_IRQ_PVD);
}
if (line_mask & EXTI_LINE_RTC) {
nvic_enable(NVIC_IRQ_RTC_ALARM);
}
if (line_mask & EXTI_LINE_USB) {
nvic_enable(NVIC_IRQ_USB_WAKEUP);
}
//enable irqs in last to avoid triggers during config
regs->IMR.word |= line_mask;
@ -100,6 +94,56 @@ void exti_reset(enum ExtiLine line_mask)
nvic_disable(NVIC_IRQ_EXTI15_10);
}
afio_map_exti(0xFFFF, 0x0);
}
void exti_configure_specific(enum ExtiLineSpecific line_mask,
enum ExtiConfig config_mask, ExtiCallback callback)
{
//reset is identical to normal lines
exti_reset_specific(line_mask);
//configure edge detections
if (config_mask & EXTI_CONFIG_RISING_EDGE) {
regs->RTSR.word |= line_mask;
} else {
regs->RTSR.word &= ~line_mask;
}
if (config_mask & EXTI_CONFIG_FALLING_EDGE) {
regs->FTSR.word |= line_mask;
} else {
regs->FTSR.word &= ~line_mask;
}
//reconfigure events/irqs
regs->EMR.word |= line_mask;
if (callback) {
//register callbacks for each line selected
for (uint8_t i = 0; i < 16; ++i) {
if (line_mask & (0x1 << i)) {
callbacks[i] = callback;
}
}
//enable interrupts lines in nvic
if (line_mask & EXTI_LINE_PVD) {
nvic_enable(NVIC_IRQ_PVD);
}
if (line_mask & EXTI_LINE_RTC) {
nvic_enable(NVIC_IRQ_RTC_ALARM);
}
if (line_mask & EXTI_LINE_USB) {
nvic_enable(NVIC_IRQ_USB_WAKEUP);
}
//enable irqs in last to avoid triggers during config
regs->IMR.word |= line_mask;
}
}
void exti_reset_specific(enum ExtiLineSpecific line_mask)
{
//disable events/irqs
regs->IMR.word &= ~line_mask;
regs->EMR.word &= ~line_mask;
@ -119,7 +163,6 @@ void exti_reset(enum ExtiLine line_mask)
}
}
void exti_reset_peripheral(void)
{
//reset peripheral config
@ -139,6 +182,8 @@ void exti_reset_peripheral(void)
nvic_disable(NVIC_IRQ_PVD);
nvic_disable(NVIC_IRQ_RTC_ALARM);
nvic_disable(NVIC_IRQ_USB_WAKEUP);
afio_map_exti(0xFFFF, 0x0);
}
//--local functions-------------------------------------------------------------

View File

@ -10,11 +10,16 @@
//--includes--------------------------------------------------------------------
#include "stdint.h"
#include "stdbool.h"
#include "gpio.h"
//--type definitions------------------------------------------------------------
/**
* Available exti lines. The numbered lines correspond to gpios while the
* remaining are directly mapped to peripherals
* Available exti lines. These lines correspond to gpios
*/
enum ExtiLine {
EXTI_LINE_0 = (0x1 << 0),
@ -33,6 +38,12 @@ enum ExtiLine {
EXTI_LINE_13 = (0x1 << 13),
EXTI_LINE_14 = (0x1 << 14),
EXTI_LINE_15 = (0x1 << 15),
};
/**
* Available exti lines. These lines correspond to specific peripherals
*/
enum ExtiLineSpecific {
EXTI_LINE_PVD = (0x1 << 16),
EXTI_LINE_RTC = (0x1 << 17),
EXTI_LINE_USB = (0x1 << 18),
@ -53,31 +64,43 @@ typedef void (*ExtiCallback)(void);
//--functions-------------------------------------------------------------------
/**
* Configure lines to call a single callback. The ExtiLine enum can be used as a
* mask to configure multiple lines at the same time.
* Configure lines on a single GPIO port. The ExtiLine enum can be used as a
* mask to configure multiple lines at the same time. Every line can only be
* configured for a single port, reconfiguring it will override the previous
* configuration. Each line is linked to the pins of the same id (ex : pin 1 for
* exti 1). When possible, it is recommanded to use the lowest id possible for
* better performance. The ExtiConfig enum can be used as mask. If no callback
* is specified, the interrupt won't be enabled, but an event will still be sent
* to wake the cpu up.
*
* Every numbered line must be linked to a gpio port using afio_map_exti(). Each
* line is linked to the pins of the same id (ex : pin 1 for exti 1). When
* possible, it is recommended to use the lowest id possible for better
* performance. Each pin must be configured independently through the gpio
* driver module
*
* The remaining lines are linked to specific peripherals which must be
* configured independently through the corresponding driver module.
*
* The ExtiConfig enum can be used as mask. If no callback is specified, the
* interrupt won't be enabled, but an event will still be sent to wake the cpu
* up.
* Note: wich port is linked to a line can be changed atfer the fact using
* afio_map_exti()
*/
void exti_configure(enum ExtiLine line_mask, enum ExtiConfig config_mask,
ExtiCallback callback);
void exti_configure(enum ExtiLine line_mask, enum GpioPort port,
enum ExtiConfig config_mask, ExtiCallback callback);
/**
* Resets lines. The ExtiLine enum can be used as a mask to reset multiple lines
* at the same time
* Resets lines. The ExtiLine enum can be used as a mask to configure multiple
* lines at the same time
*/
void exti_reset(enum ExtiLine line_mask);
/**
* Configure lines for specific, non-gpio peripherals. The ExtiLineSpecific enum
* can be used as a mask to configure multiple lines at the same time. The
* ExtiConfig enum can be used as mask. If no callback is specified, the
* interrupt won't be enabled, but an event will still be sent to wake the cpu
* up
*/
void exti_configure_specific(enum ExtiLineSpecific line_mask,
enum ExtiConfig config_mask, ExtiCallback callback);
/**
* Resets lines for specific, non-gpio peripherals. The ExtiLineSpecific enum
* can be used as a mask to configure multiple lines at the same time.
*/
void exti_reset_specific(enum ExtiLineSpecific line_mask);
/**
* Resets all lines. The exti peripheral is returned to its reset configuration
*/

View File

@ -1,25 +0,0 @@
# using a STM32f103CB wich has 128kB of flash instead of the more common 64KB
set CHIPNAME stm32f103CB
set FLASH_SIZE 0x20000
# load default configurations
source [find interface/stlink.cfg]
source [find target/stm32f1x.cfg]
# override examine-end event
$CHIPNAME.cpu configure -event examine-end {
# write DBGMCU_CR, disable all peripherals (timers, dmas, watchdogs while
# halted by debug. Trace is not affected
mmw 0xE0042004 0x7E3FFF07 0
}
reset_config srst_only srst_nogate connect_assert_srst
# inits debugging, from that point, commands can be used
init
# resets the target and halt it immediately afterward. Stops debug from being
# inacessible due to low-power states
reset halt

View File

@ -26,10 +26,6 @@
#include "task.h"
#include "error.h"
#include "../drv/stk.h"
#include "../drv/pwr.h"
#include "../drv/rcc.h"
#include "../drv/bkp.h"
#include "../drv/exti.h"
//--local definitions-----------------------------------------------------------
@ -55,13 +51,7 @@ static volatile uint32_t timestamp;
void task_start_scheduler(void)
{
stk_configure(1000, callback_stk);
rcc_configure_lsi(true);
pwr_configure_bkp_write(true);
bkp_reset();
bkp_configure_rtc(1000, BKP_RTC_CLOCK_SRC_LSI, BKP_RTC_IRQ_NONE, nullptr);
pwr_configure_bkp_write(false);
exti_configure(EXTI_LINE_RTC, EXTI_CONFIG_RISING_EDGE, callback_rtc);
//TODO: configure RTC
while (true) {
uint8_t triggers = stk_irq << 0 | rtc_irq << 1;
@ -75,13 +65,10 @@ void task_start_scheduler(void)
if (stk_needed) {
stk_start();
pwr_sleep();
__asm("wfi");
} else {
pwr_configure_bkp_write(true);
bkp_set_rtc_alam(1);
pwr_configure_bkp_write(false);
stk_stop();
pwr_sleep();
//TODO: enter deep sleep
}
}
}
@ -171,5 +158,4 @@ static void callback_stk(void)
static void callback_rtc(void)
{
rtc_irq = true;
timestamp = bkp_read_rtc() * 1000;
}