Guest User

Untitled

a guest
Dec 18th, 2017
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.10 KB | None | 0 0
  1. typedef struct
  2. {
  3. I2C_HandleTypeDef* instance;
  4. uint16_t sdaPin;
  5. GPIO_TypeDef* sdaPort;
  6. uint16_t sclPin;
  7. GPIO_TypeDef* sclPort;
  8. } I2C_Module_t;
  9.  
  10. static uint8_t wait_for_gpio_state_timeout(GPIO_TypeDef *port, uint16_t pin, GPIO_PinState state, uint32_t timeout)
  11. {
  12. uint32_t Tickstart = HAL_GetTick();
  13. uint8_t ret = TRUE;
  14. /* Wait until flag is set */
  15. for(;(state != HAL_GPIO_ReadPin(port, pin)) && (TRUE == ret);)
  16. {
  17. /* Check for the timeout */
  18. if (timeout != HAL_MAX_DELAY)
  19. {
  20. if ((timeout == 0U) || ((HAL_GetTick() - Tickstart) > timeout))
  21. {
  22. ret = FALSE;
  23. }
  24. else
  25. {
  26. }
  27. }
  28. asm("nop");
  29. }
  30. return ret;
  31. }
  32.  
  33. static void I2C_ClearBusyFlagErratum(I2C_Module_t* i2c, uint32_t timeout)
  34. {
  35. GPIO_InitTypeDef GPIO_InitStructure;
  36.  
  37. I2C_HandleTypeDef* handler = NULL;
  38.  
  39. handler = i2c->instance;
  40.  
  41. // 1. Clear PE bit.
  42. CLEAR_BIT(handler->Instance->CR1, I2C_CR1_PE);
  43.  
  44. // 2. Configure the SCL and SDA I/Os as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR).
  45. HAL_I2C_DeInit(handler);
  46.  
  47. GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
  48. GPIO_InitStructure.Pull = GPIO_NOPULL;
  49.  
  50. GPIO_InitStructure.Pin = i2c->sclPin;
  51. HAL_GPIO_Init(i2c->sclPort, &GPIO_InitStructure);
  52.  
  53. GPIO_InitStructure.Pin = i2c->sdaPin;
  54. HAL_GPIO_Init(i2c->sdaPort, &GPIO_InitStructure);
  55.  
  56. // 3. Check SCL and SDA High level in GPIOx_IDR.
  57. HAL_GPIO_WritePin(i2c->sdaPort, i2c->sdaPin, GPIO_PIN_SET);
  58. HAL_GPIO_WritePin(i2c->sclPort, i2c->sclPin, GPIO_PIN_SET);
  59.  
  60. wait_for_gpio_state_timeout(i2c->sclPort, i2c->sclPin, GPIO_PIN_SET, timeout);
  61. wait_for_gpio_state_timeout(i2c->sdaPort, i2c->sdaPin, GPIO_PIN_SET, timeout);
  62.  
  63. // 4. Configure the SDA I/O as General Purpose Output Open-Drain, Low level (Write 0 to GPIOx_ODR).
  64. HAL_GPIO_WritePin(i2c->sdaPort, i2c->sdaPin, GPIO_PIN_RESET);
  65.  
  66. // 5. Check SDA Low level in GPIOx_IDR.
  67. wait_for_gpio_state_timeout(i2c->sdaPort, i2c->sdaPin, GPIO_PIN_RESET, timeout);
  68.  
  69. // 6. Configure the SCL I/O as General Purpose Output Open-Drain, Low level (Write 0 to GPIOx_ODR).
  70. HAL_GPIO_WritePin(i2c->sclPort, i2c->sclPin, GPIO_PIN_RESET);
  71.  
  72. // 7. Check SCL Low level in GPIOx_IDR.
  73. wait_for_gpio_state_timeout(i2c->sclPort, i2c->sclPin, GPIO_PIN_RESET, timeout);
  74.  
  75. // 8. Configure the SCL I/O as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR).
  76. HAL_GPIO_WritePin(i2c->sclPort, i2c->sclPin, GPIO_PIN_SET);
  77.  
  78. // 9. Check SCL High level in GPIOx_IDR.
  79. wait_for_gpio_state_timeout(i2c->sclPort, i2c->sclPin, GPIO_PIN_SET, timeout);
  80.  
  81. // 10. Configure the SDA I/O as General Purpose Output Open-Drain , High level (Write 1 to GPIOx_ODR).
  82. HAL_GPIO_WritePin(i2c->sdaPort, i2c->sdaPin, GPIO_PIN_SET);
  83.  
  84. // 11. Check SDA High level in GPIOx_IDR.
  85. wait_for_gpio_state_timeout(i2c->sdaPort, i2c->sdaPin, GPIO_PIN_SET, timeout);
  86.  
  87. // 12. Configure the SCL and SDA I/Os as Alternate function Open-Drain.
  88. GPIO_InitStructure.Mode = GPIO_MODE_AF_OD;
  89. GPIO_InitStructure.Alternate = GPIO_AF4_I2C2;
  90.  
  91. GPIO_InitStructure.Pin = i2c->sclPin;
  92. HAL_GPIO_Init(i2c->sclPort, &GPIO_InitStructure);
  93.  
  94. GPIO_InitStructure.Pin = i2c->sdaPin;
  95. HAL_GPIO_Init(i2c->sdaPort, &GPIO_InitStructure);
  96.  
  97. // 13. Set SWRST bit in I2Cx_CR1 register.
  98. SET_BIT(handler->Instance->CR1, I2C_CR1_SWRST);
  99. asm("nop");
  100.  
  101. /* 14. Clear SWRST bit in I2Cx_CR1 register. */
  102. CLEAR_BIT(handler->Instance->CR1, I2C_CR1_SWRST);
  103. asm("nop");
  104.  
  105. /* 15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register */
  106. SET_BIT(handler->Instance->CR1, I2C_CR1_PE);
  107. asm("nop");
  108.  
  109. // Call initialization function.
  110. HAL_I2C_Init(handler);
  111. }
  112.  
  113. /* HAL Write */
  114. status = HAL_I2C_Mem_Write(eeprom_handler.instance, (uint16_t)device_address, mem_addr_masked, I2C_MEMADD_SIZE_8BIT, src, bytes_to_write, 1000);
  115. if (HAL_OK == status)
  116. {
  117. bytes_written = bytes_to_write;
  118. }
  119. else if (HAL_BUSY == status)
  120. {
  121. I2C_ClearBusyFlagErratum(&eeprom_handler, 1000);
  122. }
Add Comment
Please, Sign In to add comment