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 */
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  */
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  {
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 */
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 |
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 |
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 */
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;
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 
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 {
510 
511  while (!rtc_wakeup_triggered)
512  {
513  // Turn off interrupts
515 
517  {
518  __WFI();
519  }
520 
521  // Enable interrupt again, the ISR will execute directly after this
523  }
524 
525  rtc_wakeup_triggered = false;
526 
528 }
529 
530 
531 void acc_integration_set_periodic_wakeup(uint32_t time_msec)
532 {
533  periodic_sleep_time_ms = time_msec;
535 }
536 
537 
539 {
540  HAL_RCC_GetOscConfig(&prepare_saved_rcc_oscinitstruct);
541  HAL_RCC_GetClockConfig(&prepare_saved_rcc_clkinitstruct, &prepare_saved_flatency);
542 
544  HAL_I2C_DeInit(&MODULE_I2C_HANDLE);
545  HAL_SPI_DeInit(&A121_SPI_HANDLE);
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 
557 {
558  HAL_ResumeTick();
559 
560  HAL_RCC_OscConfig(&prepare_saved_rcc_oscinitstruct);
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 
591 {
592  // The periodic timer must be set prior to invoking this function
593  if (periodic_sleep_time_ms != 0)
594  {
596 
597  uint32_t rtc_ticks_pre_sleep = get_rtc_tick();
598 
599  while (!rtc_alarm_triggered)
600  {
601  // Turn off 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
611  }
612 
613  rtc_alarm_triggered = false;
614 
615  update_system_tick(rtc_ticks_pre_sleep, get_rtc_tick());
616 
618  }
619  else
620  {
621  printf("acc_integration_set_periodic_wakeup must be called prior to calling this function\n");
622  }
623 }
624 
625 
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 
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