i2c_application_system_stm32.c
Go to the documentation of this file.
1 // Copyright (c) Acconeer AB, 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 <stdbool.h>
8 #include <stddef.h>
9
10 #include "main.h"
11
12 #include "acc_integration.h"
13 #include "acc_reg_protocol.h"
14 #include "i2c_application_system.h"
15
16 #define I2C_SLAVE_BUFFER_SIZE 4
17 #define WAIT_FOR_IDLE_RETRIES 10U
18 #define WAIT_FOR_IDLE_RETRY_INTERNAL_MS 10U
19 #define GPIO_BANK_COUNT 3U
20
21 typedef struct
22 {
23 uint32_t MODER; /*!< GPIO port mode register */
24 uint32_t OTYPER; /*!< GPIO port output type register */
25 uint32_t OSPEEDR; /*!< GPIO port output speed register */
26 uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register */
27 uint32_t AFR[2]; /*!< GPIO alternate function registers */
28 uint32_t ASCR; /*!< GPIO analog switch control register */
29 uint32_t RCC_GPIO_CLK_ENABLE; /*!< GPIO Port Clock Enable */
30 } gpio_config_t;
31
32 extern SPI_HandleTypeDef A121_SPI_HANDLE;
33 extern I2C_HandleTypeDef MODULE_I2C_HANDLE;
34 extern UART_HandleTypeDef MODULE_UART1_HANDLE;
35 extern UART_HandleTypeDef MODULE_UART2_HANDLE;
36 extern RTC_HandleTypeDef MODULE_RTC_HANDLE;
37 static RCC_OscInitTypeDef low_power_saved_rcc_oscinitstruct;
38 static RCC_ClkInitTypeDef low_power_saved_rcc_clkinitstruct;
39 static uint32_t low_power_saved_flatency;
40 static gpio_config_t low_power_saved_gpio_bank[GPIO_BANK_COUNT] = { 0 };
41 static GPIO_TypeDef *gpio_banks[GPIO_BANK_COUNT] = { GPIOA, GPIOB, GPIOH };
42
43 static uint8_t i2c_slave_buffer[I2C_SLAVE_BUFFER_SIZE];
44 static volatile bool i2c_idle = true;
45
46 static uint32_t rtc_period_time_ms = 0;
47 static volatile bool rtc_wakeup_triggered = false;
48
49 /**
50 * @brief Disable interrupts
51 */
52 static inline void disable_interrupts(void);
53
54
55 /**
56 * @brief Enable interrupts
57 */
58 static inline void enable_interrupts(void);
59
60
61 /**
62 * @brief Prepare power down state
63 */
64 static inline void prepare_power_down(void);
65
66
67 /**
68 * @brief Resume power down state
69 */
70 static inline void resume_power_down(void);
71
72
73 /**
74 * @brief Get RTC ticks based on current RTC time
75 *
76 * @return The current RTC ticks in ms
77 */
78 static uint32_t get_rtc_tick(void);
79
80
81 /**
82 * @brief Convert RTC ticks to RTC time
83 *
84 * @param[in] tick rtc ticks in ms
85 * @param[out] time RTC time
86 */
87 static void rtc_tick_to_time(uint32_t tick, RTC_TimeTypeDef *time);
88
89
90 /**
91 * @brief Function for setting the next wakeup time from the RTC interrupt.
92 */
93 static void rtc_set_next_wakeup_time(void);
94
95
96 /**
97 * @brief Wait for I2C interface to be idle
98 */
99 static void wait_for_i2c_idle(void);
100
101
102 /**
103 * @brief Helper function to prepare transmit of register data
104 *
105 * @param[in] hi2c The I2C handle
106 */
107 static void prepare_register_data(I2C_HandleTypeDef *hi2c);
108
109
110 void i2c_application_system_init(void)
111 {
112 /* Disable unused functionality in MCU */
113 HAL_UART_DeInit(&MODULE_UART1_HANDLE);
114
115 /* Start I2C */
116 if (HAL_I2C_EnableListen_IT(&MODULE_I2C_HANDLE) != HAL_OK)
117 {
118 /**
119 * Calling this function with wrong parameters will return HAL_ERROR
120 * Calling this function when the i2c module is in the wrong state return HAL_BUSY
121 */
122 Error_Handler();
123 }
124
125 i2c_application_system_set_ready_pin(true);
126 }
127
128
129 void i2c_application_system_reset(void)
130 {
131 /**
132 * Wait for the i2c interface to be idle,
133 * if not idle after retries, reset anyway!
134 */
135 wait_for_i2c_idle();
136
137 NVIC_SystemReset();
138 }
139
140
141 void i2c_application_system_wait_for_interrupt(void)
142 {
143 __WFI();
144 }
145
146
147 bool i2c_application_system_test_wakeup_pin(void)
148 {
149 GPIO_PinState pin_state = HAL_GPIO_ReadPin(WAKE_UP_GPIO_Port, WAKE_UP_Pin);
150
151 return pin_state == GPIO_PIN_SET;
152 }
153
154
155 void i2c_application_system_set_ready_pin(bool enable)
156 {
157 GPIO_PinState pin_state = enable ? GPIO_PIN_SET : GPIO_PIN_RESET;
158
159 HAL_GPIO_WritePin(MCU_INT_GPIO_Port, MCU_INT_Pin, pin_state);
160 }
161
162
163 void i2c_application_system_setup_generic_gpio_pin(bool enable)
164 {
165 /* Setup generic gpio pin (MISC_GPIO0) */
166 GPIO_InitTypeDef GPIO_InitStruct;
167
168 GPIO_InitStruct.Pin = MISC_GPIO0_Pin;
169 GPIO_InitStruct.Pull = GPIO_NOPULL;
170
171 if (enable)
172 {
173 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
174 }
175 else
176 {
177 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
178 }
179
180 HAL_GPIO_Init(MISC_GPIO0_GPIO_Port, &GPIO_InitStruct);
181 }
182
183
184 void i2c_application_system_set_generic_gpio_pin(bool enable)
185 {
186 GPIO_PinState pin_state = enable ? GPIO_PIN_SET : GPIO_PIN_RESET;
187
188 HAL_GPIO_WritePin(MISC_GPIO0_GPIO_Port, MISC_GPIO0_Pin, pin_state);
189 }
190
191
192 void i2c_application_enter_low_power_state(void)
193 {
194 /**
195 * Wait for the i2c interface to be idle,
196 * if not idle after retries, power down anyway!
197 */
198 wait_for_i2c_idle();
199
200 prepare_power_down();
201
202 disable_interrupts();
203
204 /* Do a final test of the wakeup pin and rtc wakeup before going to sleep */
205 if (!i2c_application_system_test_wakeup_pin() && !rtc_wakeup_triggered)
206 {
207 HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
208 }
209
210 enable_interrupts();
211
212 resume_power_down();
213 }
214
215
216 void i2c_application_set_periodic_wakeup(uint32_t period_ms)
217 {
218 rtc_period_time_ms = period_ms;
219 rtc_set_next_wakeup_time();
220 }
221
222
223 bool i2c_application_is_periodic_wakeup(void)
224 {
225 acc_integration_critical_section_enter();
226 bool periodic_wakeup = rtc_wakeup_triggered;
227 rtc_wakeup_triggered = false;
228 acc_integration_critical_section_exit();
229
230 return periodic_wakeup;
231 }
232
233
234 /**
235 * @brief IRQ Handler for RTC B Alarm
236 */
237 void HAL_RTCEx_AlarmBEventCallback(RTC_HandleTypeDef *rtc)
238 {
239 (void)rtc;
240 rtc_set_next_wakeup_time();
241 rtc_wakeup_triggered = true;
242 }
243
244
245 static inline void disable_interrupts(void)
246 {
247 __disable_irq();
248 __DSB();
249 __ISB();
250 }
251
252
253 static inline void enable_interrupts(void)
254 {
255 __enable_irq();
256 __DSB();
257 __ISB();
258 }
259
260
261 static inline void prepare_power_down(void)
262 {
263 HAL_RCC_GetOscConfig(&low_power_saved_rcc_oscinitstruct);
264 HAL_RCC_GetClockConfig(&low_power_saved_rcc_clkinitstruct, &low_power_saved_flatency);
265
266 HAL_I2C_DeInit(&MODULE_I2C_HANDLE);
267 HAL_SPI_DeInit(&A121_SPI_HANDLE);
268 HAL_UART_DeInit(&MODULE_UART1_HANDLE);
269
270 /* Save GPIO bank state */
271 for (size_t idx = 0; idx < GPIO_BANK_COUNT; idx++)
272 {
273 GPIO_TypeDef *gpio_bank = gpio_banks[idx];
274 gpio_config_t *gpio_config = &low_power_saved_gpio_bank[idx];
275 gpio_config->MODER = READ_REG(gpio_bank->MODER);
276 gpio_config->OTYPER = READ_REG(gpio_bank->OTYPER);
277 gpio_config->OSPEEDR = READ_REG(gpio_bank->OSPEEDR);
278 gpio_config->PUPDR = READ_REG(gpio_bank->PUPDR);
279 gpio_config->AFR[0] = READ_REG(gpio_bank->AFR[0]);
280 gpio_config->AFR[1] = READ_REG(gpio_bank->AFR[1]);
281 }
282
283 /* Turn GPIO off */
284 GPIO_InitTypeDef GPIO_InitStructOff;
285
286 /* Set all unused GPIO pins in the lowest power consuming state according to AN4899*/
287 GPIO_InitStructOff.Mode = GPIO_MODE_ANALOG;
288 GPIO_InitStructOff.Pull = GPIO_NOPULL;
289
290 /* GPIO A */
291 GPIO_InitStructOff.Pin = GPIO_PIN_All;
292 GPIO_InitStructOff.Pin &= (uint16_t) ~(WAKE_UP_Pin | SPI_SCK_Pin | SPI_MISO_Pin | SPI_MOSI_Pin);
293 HAL_GPIO_Init(GPIOA, &GPIO_InitStructOff);
294
295 /* GPIO B */
296 GPIO_InitStructOff.Pin = GPIO_PIN_All;
297 GPIO_InitStructOff.Pin &= (uint16_t) ~(MCU_INT_Pin | ENABLE_Pin | SPI_SS_Pin | MISC_GPIO0_Pin);
298 HAL_GPIO_Init(GPIOB, &GPIO_InitStructOff);
299
300 /* GPIO H */
301 GPIO_InitStructOff.Pin = GPIO_PIN_All;
302 HAL_GPIO_Init(GPIOH, &GPIO_InitStructOff);
303
304 /* Disable Clocks */
305 __HAL_RCC_GPIOA_CLK_DISABLE();
306 __HAL_RCC_GPIOB_CLK_DISABLE();
307 __HAL_RCC_GPIOH_CLK_DISABLE();
308
309 HAL_SuspendTick();
310 }
311
312
313 static inline void resume_power_down(void)
314 {
315 HAL_ResumeTick();
316
317 HAL_RCC_OscConfig(&low_power_saved_rcc_oscinitstruct);
318 HAL_RCC_ClockConfig(&low_power_saved_rcc_clkinitstruct, low_power_saved_flatency);
319
320 __HAL_RCC_GPIOA_CLK_ENABLE();
321 __HAL_RCC_GPIOB_CLK_ENABLE();
322 __HAL_RCC_GPIOH_CLK_ENABLE();
323
324 /* Save GPIO bank state */
325 for (size_t idx = 0; idx < GPIO_BANK_COUNT; idx++)
326 {
327 GPIO_TypeDef *gpio_bank = gpio_banks[idx];
328 gpio_config_t *gpio_config = &low_power_saved_gpio_bank[idx];
329
330 WRITE_REG(gpio_bank->MODER, gpio_config->MODER);
331 WRITE_REG(gpio_bank->OTYPER, gpio_config->OTYPER);
332 WRITE_REG(gpio_bank->OSPEEDR, gpio_config->OSPEEDR);
333 WRITE_REG(gpio_bank->PUPDR, gpio_config->PUPDR);
334 WRITE_REG(gpio_bank->AFR[0], gpio_config->AFR[0]);
335 WRITE_REG(gpio_bank->AFR[1], gpio_config->AFR[1]);
336 }
337
338 HAL_I2C_Init(&MODULE_I2C_HANDLE);
339 HAL_SPI_Init(&A121_SPI_HANDLE);
340 HAL_UART_Init(&MODULE_UART2_HANDLE);
341
342 /* Start I2C */
343 if (HAL_I2C_EnableListen_IT(&MODULE_I2C_HANDLE) != HAL_OK)
344 {
345 /**
346 * Calling this function with wrong parameters will return HAL_ERROR
347 * Calling this function when the i2c module is in the wrong state return HAL_BUSY
348 */
349 Error_Handler();
350 }
351 }
352
353
354 static uint32_t get_rtc_tick(void)
355 {
356 RTC_DateTypeDef rtc_date = { 0 };
357 RTC_TimeTypeDef rtc_time = { 0 };
358
359 /* Wait until any pending shift operation is completed */
360 while ((MODULE_RTC_HANDLE.Instance->ISR & RTC_ISR_SHPF) != RESET)
361 {
362 ;
363 }
364
365 if (HAL_RTC_GetTime(&MODULE_RTC_HANDLE, &rtc_time, RTC_FORMAT_BIN) != HAL_OK)
366 {
367 Error_Handler();
368 }
369
370 if (HAL_RTC_GetDate(&MODULE_RTC_HANDLE, &rtc_date, RTC_FORMAT_BIN) != HAL_OK)
371 {
372 Error_Handler();
373 }
374
375 uint32_t rtc_ticks_ms = 0;
376
377 if (rtc_time.Hours)
378 {
379 rtc_ticks_ms += rtc_time.Hours * 60 * 60 * 1000;
380 }
381
382 if (rtc_time.Minutes)
383 {
384 rtc_ticks_ms += rtc_time.Minutes * 60 * 1000;
385 }
386
387 if (rtc_time.Seconds)
388 {
389 rtc_ticks_ms += rtc_time.Seconds * 1000;
390 }
391
392 rtc_ticks_ms += ((rtc_time.SecondFraction - rtc_time.SubSeconds) * 1000) / (rtc_time.SecondFraction + 1);
393
394 return rtc_ticks_ms;
395 }
396
397
398 static void rtc_tick_to_time(uint32_t tick, RTC_TimeTypeDef *time)
399 {
400 uint32_t rtc_ticks_ms = tick;
401
402 time->SecondFraction = MODULE_RTC_HANDLE.Init.SynchPrediv;
403
404 time->Hours = (rtc_ticks_ms / (60 * 60 * 1000)) % 24;
405
406 rtc_ticks_ms = rtc_ticks_ms % (60 * 60 * 1000);
407
408 time->Minutes = (rtc_ticks_ms / (60 * 1000)) % 60;
409
410 rtc_ticks_ms = rtc_ticks_ms % (60 * 1000);
411
412 time->Seconds = (rtc_ticks_ms / 1000) % 60;
413
414 rtc_ticks_ms = rtc_ticks_ms % 1000;
415
416 time->SubSeconds = time->SecondFraction - (rtc_ticks_ms * (time->SecondFraction + 1)) / 1000;
417 }
418
419
420 static void rtc_set_next_wakeup_time(void)
421 {
422 RTC_AlarmTypeDef alarm = { {0}, 0, 0, 0, 0, 0, 0};
423
424 if (rtc_period_time_ms > 0)
425 {
426 rtc_tick_to_time(get_rtc_tick() + rtc_period_time_ms, &alarm.AlarmTime);
427
428 alarm.Alarm = RTC_ALARM_B;
429 alarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
430 alarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_SS14;
431
432 if (HAL_RTC_DeactivateAlarm(&MODULE_RTC_HANDLE, RTC_ALARM_B) != HAL_OK)
433 {
434 Error_Handler();
435 }
436
437 if (HAL_RTC_SetAlarm_IT(&MODULE_RTC_HANDLE, &alarm, RTC_FORMAT_BIN) != HAL_OK)
438 {
439 Error_Handler();
440 }
441 }
442 else
443 {
444 if (HAL_RTC_DeactivateAlarm(&MODULE_RTC_HANDLE, RTC_ALARM_B) != HAL_OK)
445 {
446 Error_Handler();
447 }
448 }
449 }
450
451
452 static void wait_for_i2c_idle(void)
453 {
454 for (size_t idx = 0U; idx < WAIT_FOR_IDLE_RETRIES; idx++)
455 {
456 /* Make sure we do not have a race for i2c_idle */
457 acc_integration_critical_section_enter();
458 bool idle = i2c_idle;
459 acc_integration_critical_section_exit();
460
461 if (idle)
462 {
463 break;
464 }
465
466 /* Wait before next retry */
467 HAL_Delay(WAIT_FOR_IDLE_RETRY_INTERNAL_MS);
468 }
469 }
470
471
472 static void prepare_register_data(I2C_HandleTypeDef *hi2c)
473 {
474 /* Read register and put in buffer */
475 acc_reg_protocol_data_out(i2c_slave_buffer, ACC_REG_PROTOCOL_REGDATA_LENGTH);
476
477 /* Prepare buffer for transmit */
478 if (HAL_I2C_Slave_Seq_Transmit_IT(hi2c,
479 i2c_slave_buffer,
480 ACC_REG_PROTOCOL_REGDATA_LENGTH,
481 I2C_NEXT_FRAME) != HAL_OK)
482 {
483 /**
484 * Calling this function with wrong parameters will return HAL_ERROR
485 * Calling this function when the i2c module is in the wrong state return HAL_BUSY
486 */
487 Error_Handler();
488 }
489 }
490
491
492 /*
493 * STM32 I2C Interrupt callbacks
494 */
495
496
497 void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
498 {
499 (void)AddrMatchCode;
500
501 i2c_idle = false;
502
503 /* Our i2c address was detected, transmit or receive? */
504 if (TransferDirection == I2C_DIRECTION_TRANSMIT)
505 {
506 /* Reset protocol before receiving new bytes from master */
507 acc_reg_protocol_reset();
508
509 /* Always start by getting register address, 2 bytes */
510 if (HAL_I2C_Slave_Seq_Receive_IT(hi2c,
511 i2c_slave_buffer,
512 ACC_REG_PROTOCOL_ADDRESS_LENGTH,
513 I2C_NEXT_FRAME) != HAL_OK)
514 {
515 /**
516 * Calling this function with wrong parameters will return HAL_ERROR
517 * Calling this function when the i2c module is in the wrong state return HAL_BUSY
518 */
519 Error_Handler();
520 }
521 }
522 else
523 {
524 /* Prepare register data to be read by master */
525 prepare_register_data(hi2c);
526 }
527 }
528
529
530 void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c)
531 {
532 /* Prepare register data to be read by master */
533 prepare_register_data(hi2c);
534 }
535
536
537 void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
538 {
539 /* Get number of received bytes */
540 uint16_t input_length = (uint16_t)((uintptr_t)hi2c->pBuffPtr - (uintptr_t)i2c_slave_buffer);
541
542 if (input_length == ACC_REG_PROTOCOL_ADDRESS_LENGTH)
543 {
544 /* Handle receive register address */
545 acc_reg_protocol_data_in(i2c_slave_buffer, input_length);
546 }
547 else if (input_length == ACC_REG_PROTOCOL_REGDATA_LENGTH)
548 {
549 /* Handle receive register data (write register) */
550 acc_reg_protocol_data_in(i2c_slave_buffer, input_length);
551 }
552
553 /* NACK next write if an error has occured */
554 if (acc_reg_protocol_data_nack())
555 {
556 __HAL_I2C_GENERATE_NACK(hi2c);
557 }
558
559 /* Prepare to receive register data (4 bytes) */
560 if (HAL_I2C_Slave_Seq_Receive_IT(hi2c,
561 i2c_slave_buffer,
562 ACC_REG_PROTOCOL_REGDATA_LENGTH,
563 I2C_NEXT_FRAME) != HAL_OK)
564 {
565 /**
566 * Calling this function with wrong parameters will return HAL_ERROR
567 * Calling this function when the i2c module is in the wrong state return HAL_BUSY
568 */
569 Error_Handler();
570 }
571 }
572
573
574 void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c)
575 {
576 i2c_idle = true;
577
578 /* I2C transaction done, start listening for new */
579 if (HAL_I2C_EnableListen_IT(hi2c) != HAL_OK)
580 {
581 /**
582 * Calling this function with wrong parameters will return HAL_ERROR
583 * Calling this function when the i2c module is in the wrong state return HAL_BUSY
584 */
585 Error_Handler();
586 }
587 }
588
589
590 void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
591 {
592 /* Has an I2C error occured? */
593 if (HAL_I2C_GetError(hi2c) != HAL_I2C_ERROR_AF)
594 {
595 /**
596 * The data NACK is the only valid error code
597 */
598 Error_Handler();
599 }
600 }
acc_reg_protocol_data_in
void acc_reg_protocol_data_in(uint8_t *buffer, size_t data_in_length)
Handle data input to the register protocol.
Definition: acc_reg_protocol.c:230
rtc_period_time_ms
static uint32_t rtc_period_time_ms
Definition: i2c_application_system_stm32.c:46
SPI_MISO_Pin
#define SPI_MISO_Pin
Definition: main.h:90
low_power_saved_rcc_oscinitstruct
static RCC_OscInitTypeDef low_power_saved_rcc_oscinitstruct
Definition: i2c_application_system_stm32.c:37
ACC_REG_PROTOCOL_ADDRESS_LENGTH
#define ACC_REG_PROTOCOL_ADDRESS_LENGTH
Definition: acc_reg_protocol.h:11
MISC_GPIO0_GPIO_Port
#define MISC_GPIO0_GPIO_Port
Definition: main.h:97
MCU_INT_GPIO_Port
#define MCU_INT_GPIO_Port
Definition: main.h:73
WAKE_UP_Pin
#define WAKE_UP_Pin
Definition: main.h:67
MODULE_I2C_HANDLE
I2C_HandleTypeDef MODULE_I2C_HANDLE
SPI_SCK_Pin
#define SPI_SCK_Pin
Definition: main.h:92
low_power_saved_gpio_bank
static gpio_config_t low_power_saved_gpio_bank[3U]
Definition: i2c_application_system_stm32.c:40
SPI_MOSI_Pin
#define SPI_MOSI_Pin
Definition: main.h:88
acc_integration_critical_section_exit
void acc_integration_critical_section_exit(void)
Definition: acc_integration_cortex.c:18
resume_power_down
static void resume_power_down(void)
Resume power down state.
Definition: i2c_application_system_stm32.c:313
MODULE_RTC_HANDLE
RTC_HandleTypeDef MODULE_RTC_HANDLE
i2c_application_system_reset
void i2c_application_system_reset(void)
Reset the system.
Definition: i2c_application_system_stm32.c:129
i2c_application_system_init
void i2c_application_system_init(void)
Init the system.
Definition: i2c_application_system_stm32.c:110
acc_integration.h
ACC_REG_PROTOCOL_REGDATA_LENGTH
#define ACC_REG_PROTOCOL_REGDATA_LENGTH
Definition: acc_reg_protocol.h:12
MCU_INT_Pin
#define MCU_INT_Pin
Definition: main.h:72
HAL_I2C_AddrCallback
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
Definition: i2c_application_system_stm32.c:497
WAIT_FOR_IDLE_RETRIES
#define WAIT_FOR_IDLE_RETRIES
Definition: i2c_application_system_stm32.c:17
MODULE_UART1_HANDLE
UART_HandleTypeDef MODULE_UART1_HANDLE
prepare_register_data
static void prepare_register_data(I2C_HandleTypeDef *hi2c)
Helper function to prepare transmit of register data.
Definition: i2c_application_system_stm32.c:472
HAL_I2C_SlaveTxCpltCallback
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c)
Definition: i2c_application_system_stm32.c:530
rtc_tick_to_time
static void rtc_tick_to_time(uint32_t tick, RTC_TimeTypeDef *time)
Convert RTC ticks to RTC time.
Definition: i2c_application_system_stm32.c:398
A121_SPI_HANDLE
SPI_HandleTypeDef A121_SPI_HANDLE
i2c_application_set_periodic_wakeup
void i2c_application_set_periodic_wakeup(uint32_t period_ms)
Set up a periodic timer used to wake up the system from sleep.
Definition: i2c_application_system_stm32.c:216
acc_reg_protocol_data_nack
bool acc_reg_protocol_data_nack(void)
Should protocol NACK the next data.
Definition: acc_reg_protocol.c:218
gpio_config_t::PUPDR
uint32_t PUPDR
Definition: i2c_application_system_stm32.c:26
I2C_SLAVE_BUFFER_SIZE
#define I2C_SLAVE_BUFFER_SIZE
Definition: i2c_application_system_stm32.c:16
gpio_config_t::OTYPER
uint32_t OTYPER
Definition: i2c_application_system_stm32.c:24
i2c_application_system.h
get_rtc_tick
static uint32_t get_rtc_tick(void)
Get RTC ticks based on current RTC time.
Definition: i2c_application_system_stm32.c:354
i2c_application_is_periodic_wakeup
bool i2c_application_is_periodic_wakeup(void)
Test if a periodic wake up has occurred.
Definition: i2c_application_system_stm32.c:223
SPI_SS_Pin
#define SPI_SS_Pin
Definition: main.h:98
disable_interrupts
static void disable_interrupts(void)
Disable interrupts.
Definition: i2c_application_system_stm32.c:245
i2c_application_system_setup_generic_gpio_pin
void i2c_application_system_setup_generic_gpio_pin(bool enable)
Setup the generic gpio pin.
Definition: i2c_application_system_stm32.c:163
gpio_config_t::RCC_GPIO_CLK_ENABLE
uint32_t RCC_GPIO_CLK_ENABLE
Definition: i2c_application_system_stm32.c:29
MODULE_UART2_HANDLE
UART_HandleTypeDef MODULE_UART2_HANDLE
low_power_saved_flatency
static uint32_t low_power_saved_flatency
Definition: i2c_application_system_stm32.c:39
i2c_application_system_wait_for_interrupt
void i2c_application_system_wait_for_interrupt(void)
Wait for interrupt to occur.
Definition: i2c_application_system_stm32.c:141
WAKE_UP_GPIO_Port
#define WAKE_UP_GPIO_Port
Definition: main.h:68
gpio_config_t::AFR
uint32_t AFR[2]
Definition: i2c_application_system_stm32.c:27
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: i2c_application_system_stm32.c:420
GPIO_BANK_COUNT
#define GPIO_BANK_COUNT
Definition: i2c_application_system_stm32.c:19
low_power_saved_rcc_clkinitstruct
static RCC_ClkInitTypeDef low_power_saved_rcc_clkinitstruct
Definition: i2c_application_system_stm32.c:38
wait_for_i2c_idle
static void wait_for_i2c_idle(void)
Wait for I2C interface to be idle.
Definition: i2c_application_system_stm32.c:452
rtc_wakeup_triggered
static volatile bool rtc_wakeup_triggered
Definition: i2c_application_system_stm32.c:47
i2c_application_enter_low_power_state
void i2c_application_enter_low_power_state(void)
Make the MCU enter its low power state.
Definition: i2c_application_system_stm32.c:192
ENABLE_Pin
#define ENABLE_Pin
Definition: main.h:84
prepare_power_down
static void prepare_power_down(void)
Prepare power down state.
Definition: i2c_application_system_stm32.c:261
gpio_banks
static GPIO_TypeDef * gpio_banks[3U]
Definition: i2c_application_system_stm32.c:41
i2c_slave_buffer
static uint8_t i2c_slave_buffer[4]
Definition: i2c_application_system_stm32.c:43
HAL_I2C_ListenCpltCallback
void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c)
Definition: i2c_application_system_stm32.c:574
main.h
: Header for main.c file. This file contains the common defines of the application.
Error_Handler
void Error_Handler(void)
gpio_config_t
GPIO config status, maps directly to the GPIO registers.
Definition: i2c_application_system_stm32.c:21
WAIT_FOR_IDLE_RETRY_INTERNAL_MS
#define WAIT_FOR_IDLE_RETRY_INTERNAL_MS
Definition: i2c_application_system_stm32.c:18
acc_reg_protocol.h
acc_reg_protocol_data_out
void acc_reg_protocol_data_out(uint8_t *buffer, size_t data_out_length)
Handle data input from the register protocol.
Definition: acc_reg_protocol.c:294
acc_integration_critical_section_enter
void acc_integration_critical_section_enter(void)
Definition: acc_integration_cortex.c:10
HAL_I2C_SlaveRxCpltCallback
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
Definition: i2c_application_system_stm32.c:537
acc_reg_protocol_reset
void acc_reg_protocol_reset(void)
Reset register protocol.
Definition: acc_reg_protocol.c:211
HAL_I2C_ErrorCallback
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
Definition: i2c_application_system_stm32.c:590
i2c_application_system_set_ready_pin
void i2c_application_system_set_ready_pin(bool enable)
Set the ready pin state.
Definition: i2c_application_system_stm32.c:155
MISC_GPIO0_Pin
#define MISC_GPIO0_Pin
Definition: main.h:96
HAL_RTCEx_AlarmBEventCallback
void HAL_RTCEx_AlarmBEventCallback(RTC_HandleTypeDef *rtc)
IRQ Handler for RTC B Alarm.
Definition: i2c_application_system_stm32.c:237
i2c_application_system_test_wakeup_pin
bool i2c_application_system_test_wakeup_pin(void)
Check if wakeup pin is high.
Definition: i2c_application_system_stm32.c:147
enable_interrupts
static void enable_interrupts(void)
Enable interrupts.
Definition: i2c_application_system_stm32.c:253
gpio_config_t::OSPEEDR
uint32_t OSPEEDR
Definition: i2c_application_system_stm32.c:25
i2c_application_system_set_generic_gpio_pin
void i2c_application_system_set_generic_gpio_pin(bool enable)
Set the generic gpio pin output state.
Definition: i2c_application_system_stm32.c:184
gpio_config_t::MODER
uint32_t MODER
Definition: i2c_application_system_stm32.c:23
gpio_config_t::ASCR
uint32_t ASCR
Definition: i2c_application_system_stm32.c:28
i2c_idle
static volatile bool i2c_idle
Definition: i2c_application_system_stm32.c:44