furi_hal_i2c_config.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include "furi_hal_i2c_config.h"
  2. #include <furi_hal_resources.h>
  3. #include <furi_hal_version.h>
  4. #include <stm32wbxx_ll_rcc.h>
  5. #include <stm32wbxx_ll_bus.h>
  6. /** Timing register value is computed with the STM32CubeMX Tool,
  7. * Standard Mode @100kHz with I2CCLK = 64 MHz,
  8. * rise time = 0ns, fall time = 0ns
  9. */
  10. #define FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100 0x10707DBC
  11. /** Timing register value is computed with the STM32CubeMX Tool,
  12. * Fast Mode @400kHz with I2CCLK = 64 MHz,
  13. * rise time = 0ns, fall time = 0ns
  14. */
  15. #define FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_400 0x00602173
  16. static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) {
  17. if(event == FuriHalI2cBusEventInit) {
  18. LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
  19. LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1);
  20. LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1);
  21. bus->current_handle = NULL;
  22. } else if(event == FuriHalI2cBusEventDeinit) {
  23. } else if(event == FuriHalI2cBusEventLock) {
  24. } else if(event == FuriHalI2cBusEventUnlock) {
  25. } else if(event == FuriHalI2cBusEventActivate) {
  26. LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1);
  27. } else if(event == FuriHalI2cBusEventDeactivate) {
  28. LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1);
  29. }
  30. }
  31. FuriHalI2cBus furi_hal_i2c_bus_power = {
  32. .i2c = I2C1,
  33. .current_handle = NULL,
  34. .callback = furi_hal_i2c_bus_power_event,
  35. };
  36. static void furi_hal_i2c_bus_external_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) {
  37. if(event == FuriHalI2cBusEventActivate) {
  38. LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C3);
  39. LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1);
  40. LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3);
  41. } else if(event == FuriHalI2cBusEventDeactivate) {
  42. LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3);
  43. }
  44. }
  45. FuriHalI2cBus furi_hal_i2c_bus_external = {
  46. .i2c = I2C3,
  47. .current_handle = NULL,
  48. .callback = furi_hal_i2c_bus_external_event,
  49. };
  50. void furi_hal_i2c_bus_handle_power_event(
  51. FuriHalI2cBusHandle* handle,
  52. FuriHalI2cBusHandleEvent event) {
  53. if(event == FuriHalI2cBusHandleEventActivate) {
  54. LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
  55. hal_gpio_init_ex(
  56. &gpio_i2c_power_sda,
  57. GpioModeAltFunctionOpenDrain,
  58. GpioPullNo,
  59. GpioSpeedLow,
  60. GpioAltFn4I2C1);
  61. hal_gpio_init_ex(
  62. &gpio_i2c_power_scl,
  63. GpioModeAltFunctionOpenDrain,
  64. GpioPullNo,
  65. GpioSpeedLow,
  66. GpioAltFn4I2C1);
  67. LL_I2C_InitTypeDef I2C_InitStruct = {0};
  68. I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C;
  69. I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE;
  70. I2C_InitStruct.DigitalFilter = 0;
  71. I2C_InitStruct.OwnAddress1 = 0;
  72. I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK;
  73. I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
  74. if(furi_hal_version_get_hw_version() > 10) {
  75. I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_400;
  76. } else {
  77. I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100;
  78. }
  79. LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct);
  80. LL_I2C_EnableAutoEndMode(handle->bus->i2c);
  81. LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK);
  82. LL_I2C_DisableOwnAddress2(handle->bus->i2c);
  83. LL_I2C_DisableGeneralCall(handle->bus->i2c);
  84. LL_I2C_EnableClockStretching(handle->bus->i2c);
  85. LL_I2C_Enable(handle->bus->i2c);
  86. } else if(event == FuriHalI2cBusHandleEventDeactivate) {
  87. LL_I2C_Disable(handle->bus->i2c);
  88. hal_gpio_write(&gpio_i2c_power_sda, 1);
  89. hal_gpio_write(&gpio_i2c_power_scl, 1);
  90. hal_gpio_init_ex(
  91. &gpio_i2c_power_sda, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused);
  92. hal_gpio_init_ex(
  93. &gpio_i2c_power_scl, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused);
  94. }
  95. }
  96. FuriHalI2cBusHandle furi_hal_i2c_handle_power = {
  97. .bus = &furi_hal_i2c_bus_power,
  98. .callback = furi_hal_i2c_bus_handle_power_event,
  99. };
  100. void furi_hal_i2c_bus_handle_external_event(
  101. FuriHalI2cBusHandle* handle,
  102. FuriHalI2cBusHandleEvent event) {
  103. if(event == FuriHalI2cBusHandleEventActivate) {
  104. hal_gpio_init_ex(
  105. &gpio_ext_pc0, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C3);
  106. hal_gpio_init_ex(
  107. &gpio_ext_pc1, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C3);
  108. LL_I2C_InitTypeDef I2C_InitStruct = {0};
  109. I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C;
  110. I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE;
  111. I2C_InitStruct.DigitalFilter = 0;
  112. I2C_InitStruct.OwnAddress1 = 0;
  113. I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK;
  114. I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
  115. I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100;
  116. LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct);
  117. LL_I2C_EnableAutoEndMode(handle->bus->i2c);
  118. LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK);
  119. LL_I2C_DisableOwnAddress2(handle->bus->i2c);
  120. LL_I2C_DisableGeneralCall(handle->bus->i2c);
  121. LL_I2C_EnableClockStretching(handle->bus->i2c);
  122. LL_I2C_Enable(handle->bus->i2c);
  123. } else if(event == FuriHalI2cBusHandleEventDeactivate) {
  124. LL_I2C_Disable(handle->bus->i2c);
  125. hal_gpio_write(&gpio_ext_pc0, 1);
  126. hal_gpio_write(&gpio_ext_pc1, 1);
  127. hal_gpio_init_ex(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused);
  128. hal_gpio_init_ex(&gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused);
  129. }
  130. }
  131. FuriHalI2cBusHandle furi_hal_i2c_handle_external = {
  132. .bus = &furi_hal_i2c_bus_external,
  133. .callback = furi_hal_i2c_bus_handle_external_event,
  134. };