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