acc_integration_stm32.c
Go to the documentation of this file.
1 // Copyright (c) Acconeer AB, 2019-2023
2 // All rights reserved
3 // This file is subject to the terms and conditions defined in the file
4 // 'LICENSES/license_acconeer.txt', (BSD 3-Clause License) which is part
5 // of this source code package.
6
7 #include <stdint.h>
8 #include <stdio.h>
9 #include <string.h>
10
11 #include "main.h"
12
13 #include "acc_integration.h"
14
15
16 /**
17 * @brief Maximum RTC time before wrapping occurs
18 */
19 #define RTC_MAX_TIME_MS (24*60*60*1000)
20
21
22 /**
23 * @brief Set to true when RTC alarm interrupt has triggered
24 */
25 volatile bool rtc_alarm_triggered = false;
26
27
28 /**
29 * @brief Set to true when RTC wakeup interrupt has triggered
30 */
31 volatile bool rtc_wakeup_triggered = false;
32
33
34 /**
35 * @brief Variable that holds the periodic wakeup time
36 */
37 static uint32_t periodic_sleep_time_ms = 0;
38
39
40 /**
41 * @brief GPIO config status, maps directly to the GPIO registers
42 */
43 typedef struct
44 {
45 uint32_t MODER; /*!< GPIO port mode register */
46 uint32_t OTYPER; /*!< GPIO port output type register */
47 uint32_t OSPEEDR; /*!< GPIO port output speed register */
48 uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register */
49 uint32_t AFR[2]; /*!< GPIO alternate function registers */
50 uint32_t ASCR; /*!< GPIO analog switch control register */
51 uint32_t RCC_GPIO_CLK_ENABLE; /*!< GPIO Port Clock Enable */
52 } gpio_config_t;
53
54
55 static inline void disable_interrupts(void)
56 {
57 __disable_irq();
58 __DSB();
59 __ISB();
60 }
61
62
63 static inline void enable_interrupts(void)
64 {
65 __enable_irq();
66 __DSB();
67 __ISB();
68 }
69
70
71 /**
72 * @brief GPIO status of the system before going to sleep
73 */
74 static gpio_config_t saved_gpio_status[3];
75
76
77 /**
78 * @brief Handles for the blocks to control
79 */
80 extern RTC_HandleTypeDef MODULE_RTC_HANDLE;
81 extern SPI_HandleTypeDef A121_SPI_HANDLE;
82 extern I2C_HandleTypeDef MODULE_I2C_HANDLE;
83 extern UART_HandleTypeDef MODULE_UART1_HANDLE;
84 extern UART_HandleTypeDef MODULE_UART2_HANDLE;
85
86 extern __IO uint32_t uwTick;
87
88 static RCC_OscInitTypeDef prepare_saved_rcc_oscinitstruct;
89 static RCC_ClkInitTypeDef prepare_saved_rcc_clkinitstruct;
90 static uint32_t prepare_saved_flatency;
91
92 static HAL_UART_StateTypeDef prepare_saved_uart1_rx_state;
93 static HAL_I2C_StateTypeDef prepare_saved_i2c_state;
94
95
96 /**
97 * @brief Convert RTC time to RTC ticks
98 *
99 * @param[in] time RTC time
100 * @return rtc ticks in ms
101 */
102 static uint32_t rtc_time_to_tick(RTC_TimeTypeDef *time)
103 {
104 uint32_t rtc_ticks_ms = 0;
105
106 if (time->Hours)
107 {
108 rtc_ticks_ms += time->Hours * 60 * 60 * 1000;
109 }
110
111 if (time->Minutes)
112 {
113 rtc_ticks_ms += time->Minutes * 60 * 1000;
114 }
115
116 if (time->Seconds)
117 {
118 rtc_ticks_ms += time->Seconds * 1000;
119 }
120
121 rtc_ticks_ms += ((time->SecondFraction - time->SubSeconds) * 1000) / (time->SecondFraction + 1);
122
123 return rtc_ticks_ms;
124 }
125
126
127 /**
128 * @brief Convert RTC ticks to RTC time
129 *
130 * @param[in] tick rtc ticks in ms
131 * @param[out] time RTC time
132 */
133 static void rtc_tick_to_time(uint32_t tick, RTC_TimeTypeDef *time)
134 {
135 uint32_t rtc_ticks_ms = tick;
136
137 time->SecondFraction = MODULE_RTC_HANDLE.Init.SynchPrediv;
138
139 time->Hours = (rtc_ticks_ms / (60 * 60 * 1000)) % 24;
140
141 rtc_ticks_ms = rtc_ticks_ms % (60 * 60 * 1000);
142
143 time->Minutes = (rtc_ticks_ms / (60 * 1000)) % 60;
144
145 rtc_ticks_ms = rtc_ticks_ms % (60 * 1000);
146
147 time->Seconds = (rtc_ticks_ms / 1000) % 60;
148
149 rtc_ticks_ms = rtc_ticks_ms % 1000;
150
151 time->SubSeconds = time->SecondFraction - (rtc_ticks_ms * (time->SecondFraction + 1)) / 1000;
152 }
153
154
155 /**
156 * @brief Get RTC ticks based on current RTC time
157 *
158 * @return The current RTC ticks in ms
159 */
160 static uint32_t get_rtc_tick(void)
161 {
162 RTC_DateTypeDef rtc_date = { 0 };
163 RTC_TimeTypeDef rtc_time = { 0 };
164
165 /* Wait until any pending shift operation is completed */
166 while ((MODULE_RTC_HANDLE.Instance->ISR & RTC_ISR_SHPF) != RESET)
167 {
168 ;
169 }
170
171 if (HAL_RTC_GetTime(&MODULE_RTC_HANDLE, &rtc_time, RTC_FORMAT_BIN) != HAL_OK)
172 {
173 Error_Handler();
174 }
175
176 if (HAL_RTC_GetDate(&MODULE_RTC_HANDLE, &rtc_date, RTC_FORMAT_BIN) != HAL_OK)
177 {
178 Error_Handler();
179 }
180
181 return rtc_time_to_tick(&rtc_time);
182 }
183
184
185 /**
186 * @brief Update system tick based on RTC ticks during sleep
187 *
188 * @param[in] rtc_ticks_pre_sleep rtc ticks before sleep was entered
189 * @param[in] rtc_ticks_post_sleep rtc ticks after sleep was exited
190 */
191 static void update_system_tick(uint32_t rtc_ticks_pre_sleep, uint32_t rtc_ticks_post_sleep)
192 {
193 // Take care of wrapping which will occur every 24h
194 int32_t elapsed_ticks = (int32_t)rtc_ticks_post_sleep - rtc_ticks_pre_sleep;
195
196 if (elapsed_ticks < 0)
197 {
198 elapsed_ticks = RTC_MAX_TIME_MS + elapsed_ticks;
199 }
200
201 uwTick += (uint32_t)elapsed_ticks;
202 }
203
204
205 /**
206 * @brief Function for setting the next wakeup time from the RTC interrupt.
207 */
208 static void rtc_set_next_wakeup_time(void)
209 {
210 RTC_AlarmTypeDef alarm = { {0}, 0, 0, 0, 0, 0, 0};
211
212 if (periodic_sleep_time_ms != 0)
213 {
214 rtc_tick_to_time(get_rtc_tick() + periodic_sleep_time_ms, &alarm.AlarmTime);
215
216 alarm.Alarm = RTC_ALARM_A;
217 alarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
218 alarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_SS14;
219
220 if (HAL_RTC_DeactivateAlarm(&MODULE_RTC_HANDLE, RTC_ALARM_A) != HAL_OK)
221 {
222 Error_Handler();
223 }
224
225 if (HAL_RTC_SetAlarm_IT(&MODULE_RTC_HANDLE, &alarm, RTC_FORMAT_BIN) != HAL_OK)
226 {
227 Error_Handler();
228 }
229 }
230 else
231 {
232 if (HAL_RTC_DeactivateAlarm(&MODULE_RTC_HANDLE, RTC_ALARM_A) != HAL_OK)
233 {
234 Error_Handler();
235 }
236
237 rtc_alarm_triggered = false;
238 }
239 }
240
241
242 /**
243 * @brief Set the port clock status for a given GPIO bank
244 *
245 * @param[in] gpio_bank GPIO port clock to set
246 * @param[in] enable True to enable clock, False to disable
247 */
248 static void enable_gpio_port_clock(GPIO_TypeDef *gpio_bank, bool enable)
249 {
250 if (gpio_bank == GPIOA)
251 {
252 if (enable)
253 {
254 __HAL_RCC_GPIOA_CLK_ENABLE();
255 }
256 else
257 {
258 __HAL_RCC_GPIOA_CLK_DISABLE();
259 }
260 }
261 else if (gpio_bank == GPIOB)
262 {
263 if (enable)
264 {
265 __HAL_RCC_GPIOB_CLK_ENABLE();
266 }
267 else
268 {
269 __HAL_RCC_GPIOB_CLK_DISABLE();
270 }
271 }
272 else if (gpio_bank == GPIOH)
273 {
274 if (enable)
275 {
276 __HAL_RCC_GPIOH_CLK_ENABLE();
277 }
278 else
279 {
280 __HAL_RCC_GPIOH_CLK_DISABLE();
281 }
282 }
283 }
284
285
286 /**
287 * @brief Get the port clock status for a given GPIO bank
288 *
289 * @param[in] gpio_bank GPIO bank to save
290 * @return True if the GPIO port clock is enabled
291 */
292 static bool get_gpio_port_clock(GPIO_TypeDef *gpio_bank)
293 {
294 if (gpio_bank == GPIOA)
295 {
296 return __HAL_RCC_GPIOA_IS_CLK_ENABLED();
297 }
298 else if (gpio_bank == GPIOB)
299 {
300 return __HAL_RCC_GPIOB_IS_CLK_ENABLED();
301 }
302 else if (gpio_bank == GPIOH)
303 {
304 return __HAL_RCC_GPIOH_IS_CLK_ENABLED();
305 }
306
307 /* We should never end up here */
308 Error_Handler();
309 return false;
310 }
311
312
313 /**
314 * @brief Save all registers for a given GPIO bank including the original GPIO port clock
315 *
316 * The GPIO port clock needs to be enabled before calling this function
317 *
318 * @param[in] gpio_bank GPIO bank to save
319 * @param[out] config Variable for storing the GPIO bank registers
320 */
321 static void save_gpio_bank(GPIO_TypeDef *gpio_bank, gpio_config_t *config)
322 {
323 config->MODER = READ_REG(gpio_bank->MODER);
324 config->OTYPER = READ_REG(gpio_bank->OTYPER);
325 config->OSPEEDR = READ_REG(gpio_bank->OSPEEDR);
326 config->PUPDR = READ_REG(gpio_bank->PUPDR);
327 config->AFR[0] = READ_REG(gpio_bank->AFR[0]);
328 config->AFR[1] = READ_REG(gpio_bank->AFR[1]);
329 }
330
331
332 /**
333 * @brief Restore all registers for a given GPIO bank
334 *
335 * @param[in] gpio_bank GPIO bank to restore
336 * @param[in] config Variable that contains all the saved GPIO bank registers
337 */
338 static void restore_gpio_bank(GPIO_TypeDef *gpio_bank, gpio_config_t *config)
339 {
340 /* Enable GPIO port clock to be able to change the configuration */
341 enable_gpio_port_clock(gpio_bank, true);
342
343 WRITE_REG(gpio_bank->MODER, config->MODER);
344 WRITE_REG(gpio_bank->OTYPER, config->OTYPER);
345 WRITE_REG(gpio_bank->OSPEEDR, config->OSPEEDR);
346 WRITE_REG(gpio_bank->PUPDR, config->PUPDR);
347 WRITE_REG(gpio_bank->AFR[0], config->AFR[0]);
348 WRITE_REG(gpio_bank->AFR[1], config->AFR[1]);
349
350 /* Restore GPIO port clock to what it was prior to suspending */
351 enable_gpio_port_clock(gpio_bank, config->RCC_GPIO_CLK_ENABLE);
352 }
353
354
355 /**
356 * @brief Suspend GPIO driver
357 *
358 * Set all GPIO pins in the lowest power consuming state according to AN4899
359 * and disable all the port clocks.
360 *
361 */
362 static void gpio_suspend(void)
363 {
364 GPIO_InitTypeDef GPIO_InitStructOff;
365
366 /* Save Clocks */
367 saved_gpio_status[0].RCC_GPIO_CLK_ENABLE = get_gpio_port_clock(GPIOA);
368 saved_gpio_status[1].RCC_GPIO_CLK_ENABLE = get_gpio_port_clock(GPIOB);
369 saved_gpio_status[2].RCC_GPIO_CLK_ENABLE = get_gpio_port_clock(GPIOH);
370
371 /* Enable all GPIO port clocks now when we have saved the status */
372 __HAL_RCC_GPIOA_CLK_ENABLE();
373 __HAL_RCC_GPIOB_CLK_ENABLE();
374 __HAL_RCC_GPIOH_CLK_ENABLE();
375
376 /* Save all GPIO banks */
377 save_gpio_bank(GPIOA, &saved_gpio_status[0]);
378 save_gpio_bank(GPIOB, &saved_gpio_status[1]);
379 save_gpio_bank(GPIOH, &saved_gpio_status[2]);
380
381 /* Set all unused GPIO pins in the lowest power consuming state according to AN4899*/
382 GPIO_InitStructOff.Mode = GPIO_MODE_ANALOG;
383 GPIO_InitStructOff.Pull = GPIO_NOPULL;
384
385 GPIO_InitStructOff.Pin = GPIO_PIN_All;
386
387 /* Leave the following pins on bank A unchanged */
388 GPIO_InitStructOff.Pin &= (uint16_t) ~(SPI_SCK_Pin |
389 SPI_MISO_Pin |
390 SPI_MOSI_Pin);
391
392 HAL_GPIO_Init(GPIOA, &GPIO_InitStructOff);
393
394 GPIO_InitStructOff.Pin = GPIO_PIN_All;
395
396 /* Leave the following pins on bank B unchanged */
397 GPIO_InitStructOff.Pin &= (uint16_t) ~(INTERRUPT_Pin |
398 ENABLE_Pin |
399 MISC_GPIO1_Pin |
400 MISC_GPIO0_Pin);
401
402 HAL_GPIO_Init(GPIOB, &GPIO_InitStructOff);
403
404 GPIO_InitStructOff.Pin = GPIO_PIN_All;
405
406 /* Leave the following pins on bank H unchanged */
407 GPIO_InitStructOff.Pin &= (uint16_t) ~(I2C_ADDRESS_Pin |
408 MISC_GPIO2_Pin);
409
410 HAL_GPIO_Init(GPIOH, &GPIO_InitStructOff);
411
412 /* Disable all GPIO port clocks */
413 __HAL_RCC_GPIOA_CLK_DISABLE();
414 __HAL_RCC_GPIOB_CLK_DISABLE();
415 __HAL_RCC_GPIOH_CLK_DISABLE();
416 }
417
418
419 /**
420 * @brief Resume GPIO driver
421 *
422 * @return Status
423 */
424 static void gpio_resume(void)
425 {
426 /* Restore all GPIOS */
427 restore_gpio_bank(GPIOA, &saved_gpio_status[0]);
428 restore_gpio_bank(GPIOB, &saved_gpio_status[1]);
429 restore_gpio_bank(GPIOH, &saved_gpio_status[2]);
430 }
431
432
433 /**
434 * @brief IRQ Handler for RTC Alarm
435 */
436 void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *rtc)
437 {
438 (void)rtc;
439
440 rtc_alarm_triggered = true;
441 rtc_set_next_wakeup_time();
442 }
443
444
445 /**
446 * @brief IRQ Handler for RTC Wakeup
447 */
448 void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *rtc)
449 {
450 (void)rtc;
451
452 rtc_wakeup_triggered = true;
453 }
454
455
456 static void acc_integration_enable_wake_up(uint32_t time_usec)
457 {
458 uint32_t wakeup_clock;
459 uint32_t wakeup_counter;
460
461 rtc_wakeup_triggered = false;
462
463 // Calculate proper clock source and counter values from sleep time
464 // RTC_WAKEUPCLOCK_RTCCLK_DIV16 gives 1÷32000×16 = 500 us resolution and max 32s
465 // RTC_WAKEUPCLOCK_RTCCLK_DIV8 gives 1÷32000×8 = 250 us resolution and max 16s
466 // RTC_WAKEUPCLOCK_RTCCLK_DIV4 gives 1÷32000×4 = 125 us resolution and max 8s
467 // RTC_WAKEUPCLOCK_RTCCLK_DIV2 gives 1÷32000×2 = 62.5 us resolution and max 4s
468 // RTC_WAKEUPCLOCK_CK_SPRE_16BITS gives 1000 ms resolution and max 18h
469 if (time_usec > 30000000)
470 {
471 wakeup_clock = RTC_WAKEUPCLOCK_CK_SPRE_16BITS;
472 wakeup_counter = (time_usec / 1000000) - 1;
473 }
474 else if (time_usec > 100000)
475 {
476 wakeup_clock = RTC_WAKEUPCLOCK_RTCCLK_DIV16;
477 wakeup_counter = (time_usec * 2 / 1000) - 1;
478 }
479 else
480 {
481 wakeup_clock = RTC_WAKEUPCLOCK_RTCCLK_DIV2;
482 wakeup_counter = (time_usec * 16 / 1000) - 1;
483 }
484
485 if (HAL_RTCEx_SetWakeUpTimer_IT(&MODULE_RTC_HANDLE, wakeup_counter, wakeup_clock) != HAL_OK)
486 {
487 Error_Handler();
488 }
489 }
490
491
492 static void acc_integration_disable_wake_up(void)
493 {
494 if (HAL_RTCEx_DeactivateWakeUpTimer(&MODULE_RTC_HANDLE) != HAL_OK)
495 {
496 Error_Handler();
497 }
498 }
499
500
501 void acc_integration_sleep_ms(uint32_t time_msec)
502 {
503 acc_integration_sleep_us(time_msec * 1000);
504 }
505
506
507 void acc_integration_sleep_us(uint32_t time_usec)
508 {
509 acc_integration_enable_wake_up(time_usec);
510
511 while (!rtc_wakeup_triggered)
512 {
513 // Turn off interrupts
514 disable_interrupts();
515
516 if (!rtc_wakeup_triggered)
517 {
518 __WFI();
519 }
520
521 // Enable interrupt again, the ISR will execute directly after this
522 enable_interrupts();
523 }
524
525 rtc_wakeup_triggered = false;
526
527 acc_integration_disable_wake_up();
528 }
529
530
531 void acc_integration_set_periodic_wakeup(uint32_t time_msec)
532 {
533 periodic_sleep_time_ms = time_msec;
534 rtc_set_next_wakeup_time();
535 }
536
537
538 static void acc_integration_prepare_stop_1(void)
539 {
540 HAL_RCC_GetOscConfig(&prepare_saved_rcc_oscinitstruct);
541 HAL_RCC_GetClockConfig(&prepare_saved_rcc_clkinitstruct, &prepare_saved_flatency);
542
543 prepare_saved_i2c_state = MODULE_I2C_HANDLE.State;
544 HAL_I2C_DeInit(&MODULE_I2C_HANDLE);
545 HAL_SPI_DeInit(&A121_SPI_HANDLE);
546 prepare_saved_uart1_rx_state = MODULE_UART1_HANDLE.RxState;
547 HAL_UART_DeInit(&MODULE_UART1_HANDLE);
548 HAL_UART_DeInit(&MODULE_UART2_HANDLE);
549
550 gpio_suspend();
551
552 HAL_SuspendTick();
553 }
554
555
556 static void acc_integration_resume_stop_1(void)
557 {
558 HAL_ResumeTick();
559
560 HAL_RCC_OscConfig(&prepare_saved_rcc_oscinitstruct);
561 HAL_RCC_ClockConfig(&prepare_saved_rcc_clkinitstruct, prepare_saved_flatency);
562
563 gpio_resume();
564
565 HAL_I2C_Init(&MODULE_I2C_HANDLE);
566 if (prepare_saved_i2c_state == HAL_I2C_STATE_LISTEN)
567 {
568 HAL_I2C_EnableListen_IT(&MODULE_I2C_HANDLE);
569 }
570
571 HAL_SPI_Init(&A121_SPI_HANDLE);
572 HAL_UART_Init(&MODULE_UART1_HANDLE);
573
574 if (prepare_saved_uart1_rx_state == HAL_UART_STATE_BUSY_RX)
575 {
576 if (MODULE_UART1_HANDLE.hdmarx != NULL)
577 {
578 HAL_UART_Receive_DMA(&MODULE_UART1_HANDLE, MODULE_UART1_HANDLE.pRxBuffPtr, MODULE_UART1_HANDLE.RxXferSize);
579 }
580 else
581 {
582 HAL_UART_Receive_IT(&MODULE_UART1_HANDLE, MODULE_UART1_HANDLE.pRxBuffPtr, MODULE_UART1_HANDLE.RxXferSize);
583 }
584 }
585
586 HAL_UART_Init(&MODULE_UART2_HANDLE);
587 }
588
589
590 void acc_integration_sleep_until_periodic_wakeup(void)
591 {
592 // The periodic timer must be set prior to invoking this function
593 if (periodic_sleep_time_ms != 0)
594 {
595 acc_integration_prepare_stop_1();
596
597 uint32_t rtc_ticks_pre_sleep = get_rtc_tick();
598
599 while (!rtc_alarm_triggered)
600 {
601 // Turn off interrupts
602 disable_interrupts();
603
604 if (!rtc_alarm_triggered)
605 {
606 HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
607 }
608
609 // Enable interrupt again, the ISR will execute directly after this
610 enable_interrupts();
611 }
612
613 rtc_alarm_triggered = false;
614
615 update_system_tick(rtc_ticks_pre_sleep, get_rtc_tick());
616
617 acc_integration_resume_stop_1();
618 }
619 else
620 {
621 printf("acc_integration_set_periodic_wakeup must be called prior to calling this function\n");
622 }
623 }
624
625
626 uint32_t acc_integration_get_time(void)
627 {
628 return HAL_GetTick();
629 }
630
631
632 void *acc_integration_mem_alloc(size_t size)
633 {
634 return malloc(size);
635 }
636
637
638 void *acc_integration_mem_calloc(size_t nmemb, size_t size)
639 {
640 return calloc(nmemb, size);
641 }
642
643
644 void acc_integration_mem_free(void *ptr)
645 {
646 free(ptr);
647 }
prepare_saved_flatency
static uint32_t prepare_saved_flatency
Definition: acc_integration_stm32.c:90
HAL_RTCEx_WakeUpTimerEventCallback
void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *rtc)
IRQ Handler for RTC Wakeup.
Definition: acc_integration_stm32.c:448
MODULE_UART2_HANDLE
UART_HandleTypeDef MODULE_UART2_HANDLE
SPI_MISO_Pin
#define SPI_MISO_Pin
Definition: main.h:90
prepare_saved_uart1_rx_state
static HAL_UART_StateTypeDef prepare_saved_uart1_rx_state
Definition: acc_integration_stm32.c:92
MISC_GPIO1_Pin
#define MISC_GPIO1_Pin
Definition: main.h:100
A121_SPI_HANDLE
SPI_HandleTypeDef A121_SPI_HANDLE
enable_gpio_port_clock
static void enable_gpio_port_clock(GPIO_TypeDef *gpio_bank, bool enable)
Set the port clock status for a given GPIO bank.
Definition: acc_integration_stm32.c:248
rtc_alarm_triggered
volatile bool rtc_alarm_triggered
Set to true when RTC alarm interrupt has triggered.
Definition: acc_integration_stm32.c:25
SPI_SCK_Pin
#define SPI_SCK_Pin
Definition: main.h:92
gpio_resume
static void gpio_resume(void)
Resume GPIO driver.
Definition: acc_integration_stm32.c:424
prepare_saved_rcc_oscinitstruct
static RCC_OscInitTypeDef prepare_saved_rcc_oscinitstruct
Definition: acc_integration_stm32.c:88
update_system_tick
static void update_system_tick(uint32_t rtc_ticks_pre_sleep, uint32_t rtc_ticks_post_sleep)
Update system tick based on RTC ticks during sleep.
Definition: acc_integration_stm32.c:191
SPI_MOSI_Pin
#define SPI_MOSI_Pin
Definition: main.h:88
I2C_ADDRESS_Pin
#define I2C_ADDRESS_Pin
Definition: main.h:76
gpio_suspend
static void gpio_suspend(void)
Suspend GPIO driver.
Definition: acc_integration_stm32.c:362
acc_integration.h
acc_integration_get_time
uint32_t acc_integration_get_time(void)
Get current time.
Definition: acc_integration_stm32.c:626
MISC_GPIO2_Pin
#define MISC_GPIO2_Pin
Definition: main.h:65
get_rtc_tick
static uint32_t get_rtc_tick(void)
Get RTC ticks based on current RTC time.
Definition: acc_integration_stm32.c:160
acc_integration_sleep_ms
void acc_integration_sleep_ms(uint32_t time_msec)
Sleep for a specified number of milliseconds.
Definition: acc_integration_stm32.c:501
rtc_time_to_tick
static uint32_t rtc_time_to_tick(RTC_TimeTypeDef *time)
Convert RTC time to RTC ticks.
Definition: acc_integration_stm32.c:102
gpio_config_t::PUPDR
uint32_t PUPDR
Definition: i2c_application_system_stm32.c:26
gpio_config_t::OTYPER
uint32_t OTYPER
Definition: i2c_application_system_stm32.c:24
acc_integration_disable_wake_up
static void acc_integration_disable_wake_up(void)
Definition: acc_integration_stm32.c:492
get_gpio_port_clock
static bool get_gpio_port_clock(GPIO_TypeDef *gpio_bank)
Get the port clock status for a given GPIO bank.
Definition: acc_integration_stm32.c:292
printf
#define printf
Definition: printf.h:60
acc_integration_set_periodic_wakeup
void acc_integration_set_periodic_wakeup(uint32_t time_msec)
Set up a periodic timer used to wake up the system from sleep.
Definition: acc_integration_stm32.c:531
gpio_config_t::RCC_GPIO_CLK_ENABLE
uint32_t RCC_GPIO_CLK_ENABLE
Definition: i2c_application_system_stm32.c:29
acc_integration_prepare_stop_1
static void acc_integration_prepare_stop_1(void)
Definition: acc_integration_stm32.c:538
acc_integration_mem_free
void acc_integration_mem_free(void *ptr)
Free dynamic memory.
Definition: acc_integration_stm32.c:644
gpio_config_t::AFR
uint32_t AFR[2]
Definition: i2c_application_system_stm32.c:27
MODULE_RTC_HANDLE
RTC_HandleTypeDef MODULE_RTC_HANDLE
Handles for the blocks to control.
disable_interrupts
static void disable_interrupts(void)
Definition: acc_integration_stm32.c:55
acc_integration_mem_alloc
void * acc_integration_mem_alloc(size_t size)
Allocate dynamic memory.
Definition: acc_integration_stm32.c:632
enable_interrupts
static void enable_interrupts(void)
Definition: acc_integration_stm32.c:63
ENABLE_Pin
#define ENABLE_Pin
Definition: main.h:84
RTC_MAX_TIME_MS
#define RTC_MAX_TIME_MS
Maximum RTC time before wrapping occurs.
Definition: acc_integration_stm32.c:19
main.h
: Header for main.c file. This file contains the common defines of the application.
Error_Handler
void Error_Handler(void)
acc_integration_sleep_us
void acc_integration_sleep_us(uint32_t time_usec)
Sleep for a specified number of microseconds.
Definition: acc_integration_stm32.c:507
gpio_config_t
GPIO config status, maps directly to the GPIO registers.
Definition: i2c_application_system_stm32.c:21
acc_integration_resume_stop_1
static void acc_integration_resume_stop_1(void)
Definition: acc_integration_stm32.c:556
acc_integration_enable_wake_up
static void acc_integration_enable_wake_up(uint32_t time_usec)
Definition: acc_integration_stm32.c:456
acc_integration_sleep_until_periodic_wakeup
void acc_integration_sleep_until_periodic_wakeup(void)
Put the system in sleep until the periodic timer triggers.
Definition: acc_integration_stm32.c:590
rtc_wakeup_triggered
volatile bool rtc_wakeup_triggered
Set to true when RTC wakeup interrupt has triggered.
Definition: acc_integration_stm32.c:31
rtc_set_next_wakeup_time
static void rtc_set_next_wakeup_time(void)
Function for setting the next wakeup time from the RTC interrupt.
Definition: acc_integration_stm32.c:208
save_gpio_bank
static void save_gpio_bank(GPIO_TypeDef *gpio_bank, gpio_config_t *config)
Save all registers for a given GPIO bank including the original GPIO port clock.
Definition: acc_integration_stm32.c:321
uwTick
__IO uint32_t uwTick
MISC_GPIO0_Pin
#define MISC_GPIO0_Pin
Definition: main.h:96
INTERRUPT_Pin
#define INTERRUPT_Pin
Definition: main.h:62
saved_gpio_status
static gpio_config_t saved_gpio_status[3]
GPIO status of the system before going to sleep.
Definition: acc_integration_stm32.c:74
rtc_tick_to_time
static void rtc_tick_to_time(uint32_t tick, RTC_TimeTypeDef *time)
Convert RTC ticks to RTC time.
Definition: acc_integration_stm32.c:133
MODULE_UART1_HANDLE
UART_HandleTypeDef MODULE_UART1_HANDLE
prepare_saved_i2c_state
static HAL_I2C_StateTypeDef prepare_saved_i2c_state
Definition: acc_integration_stm32.c:93
restore_gpio_bank
static void restore_gpio_bank(GPIO_TypeDef *gpio_bank, gpio_config_t *config)
Restore all registers for a given GPIO bank.
Definition: acc_integration_stm32.c:338
gpio_config_t::OSPEEDR
uint32_t OSPEEDR
Definition: i2c_application_system_stm32.c:25
acc_integration_mem_calloc
void * acc_integration_mem_calloc(size_t nmemb, size_t size)
Allocate dynamic memory.
Definition: acc_integration_stm32.c:638
prepare_saved_rcc_clkinitstruct
static RCC_ClkInitTypeDef prepare_saved_rcc_clkinitstruct
Definition: acc_integration_stm32.c:89
periodic_sleep_time_ms
static uint32_t periodic_sleep_time_ms
Variable that holds the periodic wakeup time.
Definition: acc_integration_stm32.c:37
gpio_config_t::MODER
uint32_t MODER
Definition: i2c_application_system_stm32.c:23
HAL_RTC_AlarmAEventCallback
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *rtc)
IRQ Handler for RTC Alarm.
Definition: acc_integration_stm32.c:436
MODULE_I2C_HANDLE
I2C_HandleTypeDef MODULE_I2C_HANDLE