aboutsummaryrefslogtreecommitdiff
path: root/examples/stm32f411_rtc_interrupt/src/main.rs
blob: 71ce96f8ae04ee1d441745bf40d2f2d625424446 (plain) (blame)
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        
    }
}