1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
#![deny(unsafe_code)]
#![deny(warnings)]
#![no_main]
#![no_std]
#![feature(type_alias_impl_trait)]
use panic_halt as _;
#[rtic::app(device = stm32f4xx_hal::pac, peripherals = true)]
mod app {
use stm32f4xx_hal::{
gpio::{self, Edge, Input, Output, PushPull},
pac::TIM1,
prelude::*,
rtc::{Rtc, Event},
timer,
};
use defmt_rtt as _;
// Resources shared between tasks
#[shared]
struct Shared {
delayval: u32,
rtc: Rtc,
}
// Local resources to specific tasks (cannot be shared)
#[local]
struct Local {
button: gpio::PA0<Input>,
led: gpio::PC13<Output<PushPull>>,
delay: timer::DelayMs<TIM1>,
}
#[init]
fn init(ctx: init::Context) -> (Shared, Local) {
let mut dp = ctx.device;
// Configure and obtain handle for delay abstraction
// 1) Promote RCC structure to HAL to be able to configure clocks
let rcc = dp.RCC.constrain();
// 2) Configure the system clocks
// 25 MHz must be used for HSE on the Blackpill-STM32F411CE board according to manual
let clocks = rcc.cfgr.use_hse(25.MHz()).freeze();
//Configure RTC
let mut rtc = Rtc::new(dp.RTC, &mut dp.PWR);
//Set date and time
let _ = rtc.set_year(2023);
let _ = rtc.set_month(11);
let _ = rtc.set_day(25);
let _ = rtc.set_hours(22);
let _ = rtc.set_minutes(46);
let _ = rtc.set_seconds(00);
//Start listening to WAKE UP INTERRUPTS
rtc.enable_wakeup(10.secs());
rtc.listen(&mut dp.EXTI, Event::Wakeup);
// 3) Create delay handle
let delay = dp.TIM1.delay_ms(&clocks);
// Configure the LED pin as a push pull ouput and obtain handle
// On the Blackpill STM32F411CEU6 there is an on-board LED connected to pin PC13
// 1) Promote the GPIOC PAC struct
let gpioc = dp.GPIOC.split();
// 2) Configure PORTC OUTPUT Pins and Obtain Handle
let led = gpioc.pc13.into_push_pull_output();
// Configure the button pin as input and obtain handle
// On the Blackpill STM32F411CEU6 there is a button connected to pin PA0
// 1) Promote the GPIOA PAC struct
let gpioa: gpio::gpioa::Parts = dp.GPIOA.split();
// 2) Configure Pin and Obtain Handle
let mut button = gpioa.pa0.into_pull_up_input();
// Configure Button Pin for Interrupts
// 1) Promote SYSCFG structure to HAL to be able to configure interrupts
let mut syscfg = dp.SYSCFG.constrain();
// 2) Make button an interrupt source
button.make_interrupt_source(&mut syscfg);
// 3) Configure the interruption to be triggered on a rising edge
button.trigger_on_edge(&mut dp.EXTI, Edge::Rising);
// 4) Enable gpio interrupt for button
button.enable_interrupt(&mut dp.EXTI);
(
// Initialization of shared resources
Shared { delayval: 2000_u32, rtc},
// Initialization of task local resources
Local { button, led, delay},
)
}
// Background task, runs whenever no other tasks are running
#[idle(local = [led, delay], shared = [delayval])]
fn idle(mut ctx: idle::Context) -> ! {
let led = ctx.local.led;
let delay = ctx.local.delay;
loop {
// Turn On LED
led.set_high();
// Obtain shared delay variable and delay
delay.delay_ms(ctx.shared.delayval.lock(|del| *del));
// Turn off LED
led.set_low();
// Obtain shared delay variable and delay
delay.delay_ms(ctx.shared.delayval.lock(|del| *del));
}
}
#[task(binds = EXTI0, local = [button], shared=[delayval, rtc])]
fn gpio_interrupt_handler(mut ctx: gpio_interrupt_handler::Context) {
ctx.shared.delayval.lock(|del| {
*del = *del - 100_u32;
if *del < 200_u32 {
*del = 2000_u32;
}
*del
});
ctx.shared.rtc.lock(|rtc|{
let current_time = rtc.get_datetime();
defmt::info!("CURRENT TIME {:?}", current_time.as_hms());
rtc.disable_wakeup();
});
ctx.local.button.clear_interrupt_pending_bit();
}
#[task(binds = RTC_WKUP, shared = [rtc])]
fn rtc_wakeup(mut ctx: rtc_wakeup::Context) {
defmt::warn!("RTC INTERRUPT!!!!");
ctx.shared.rtc.lock(|rtc|{
let current_time = rtc.get_datetime();
rtc.clear_interrupt(Event::Wakeup);
defmt::info!("Current time {:?}", current_time.as_hms() );
});
// Your RTC wakeup interrupt handling code here
}
}
|