drv_i2c.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-02-22 airm2m first version
  9. */
  10. #include <rtdevice.h>
  11. #include <rtthread.h>
  12. #include "board.h"
  13. #include <stdlib.h>
  14. #ifdef BSP_USING_HW_I2C
  15. #define DBG_TAG "drv.hwi2c"
  16. #ifdef DRV_DEBUG
  17. #define DBG_LVL DBG_LOG
  18. #else
  19. #define DBG_LVL DBG_INFO
  20. #endif /* DRV_DEBUG */
  21. #include <rtdbg.h>
  22. #include <hal_data.h>
  23. static struct rt_i2c_bus_device prv_ra_i2c;
  24. static volatile i2c_master_event_t i2c_event = I2C_MASTER_EVENT_ABORTED;
  25. void i2c_master_callback(i2c_master_callback_args_t *p_args)
  26. {
  27. if (NULL != p_args)
  28. {
  29. /* capture callback event for validating the i2c transfer event*/
  30. i2c_event = p_args->event;
  31. }
  32. }
  33. static fsp_err_t validate_i2c_event(void)
  34. {
  35. uint16_t local_time_out = UINT16_MAX;
  36. /* resetting call back event capture variable */
  37. i2c_event = (i2c_master_event_t)0;
  38. do
  39. {
  40. /* This is to avoid infinite loop */
  41. --local_time_out;
  42. if(0 == local_time_out)
  43. {
  44. return FSP_ERR_TRANSFER_ABORTED;
  45. }
  46. }while(i2c_event == 0);
  47. if(i2c_event != I2C_MASTER_EVENT_ABORTED)
  48. {
  49. /* Make sure this is always Reset before return*/
  50. i2c_event = (i2c_master_event_t)0;
  51. return FSP_SUCCESS;
  52. }
  53. /* Make sure this is always Reset before return */
  54. i2c_event = (i2c_master_event_t)0;
  55. return FSP_ERR_TRANSFER_ABORTED;
  56. }
  57. static rt_ssize_t ra_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
  58. struct rt_i2c_msg msgs[],
  59. rt_uint32_t num)
  60. {
  61. rt_size_t i;
  62. struct rt_i2c_msg *msg = msgs;
  63. RT_ASSERT(bus != RT_NULL);
  64. fsp_err_t err = FSP_SUCCESS;
  65. bool restart = false;
  66. for (i = 0; i < num; i++)
  67. {
  68. if (msg[i].flags & RT_I2C_NO_START)
  69. {
  70. restart = true;
  71. }
  72. if (msg[i].flags & RT_I2C_ADDR_10BIT)
  73. {
  74. LOG_E("10Bit not support");
  75. break;
  76. }
  77. else
  78. {
  79. g_i2c_master1_ctrl.slave = msg[i].addr;
  80. }
  81. if (msg[i].flags & RT_I2C_RD)
  82. {
  83. err = R_IIC_MASTER_Read(&g_i2c_master1_ctrl, msg[i].buf, msg[i].len, restart);
  84. if (FSP_SUCCESS == err)
  85. {
  86. err = validate_i2c_event();
  87. /* handle error */
  88. if(FSP_ERR_TRANSFER_ABORTED == err)
  89. {
  90. LOG_E("POWER_CTL reg I2C read failed");
  91. break;
  92. }
  93. }
  94. /* handle error */
  95. else
  96. {
  97. /* Write API returns itself is not successful */
  98. LOG_E("R_IIC_MASTER_Write API failed");
  99. break;
  100. }
  101. }
  102. else
  103. {
  104. err = R_IIC_MASTER_Write(&g_i2c_master1_ctrl, msg[i].buf, msg[i].len, restart);
  105. if (FSP_SUCCESS == err)
  106. {
  107. err = validate_i2c_event();
  108. /* handle error */
  109. if(FSP_ERR_TRANSFER_ABORTED == err)
  110. {
  111. LOG_E("POWER_CTL reg I2C write failed");
  112. break;
  113. }
  114. }
  115. /* handle error */
  116. else
  117. {
  118. /* Write API returns itself is not successful */
  119. LOG_E("R_IIC_MASTER_Write API failed");
  120. break;
  121. }
  122. }
  123. }
  124. return i;
  125. }
  126. static const struct rt_i2c_bus_device_ops ra_i2c_ops =
  127. {
  128. .master_xfer = ra_i2c_mst_xfer,
  129. .slave_xfer = RT_NULL,
  130. .i2c_bus_control = RT_NULL
  131. };
  132. int ra_hw_i2c_init(void)
  133. {
  134. fsp_err_t err = FSP_SUCCESS;
  135. prv_ra_i2c.ops = &ra_i2c_ops;
  136. prv_ra_i2c.priv = 0;
  137. /* opening IIC master module */
  138. err = R_IIC_MASTER_Open(&g_i2c_master1_ctrl, &g_i2c_master1_cfg);
  139. /* handle error */
  140. if (FSP_SUCCESS != err)
  141. {
  142. LOG_E("R_IIC_MASTER_Open API failed");
  143. return err;
  144. }
  145. rt_i2c_bus_device_register(&prv_ra_i2c, "i2c1");
  146. return 0;
  147. }
  148. INIT_DEVICE_EXPORT(ra_hw_i2c_init);
  149. #endif /* BSP_USING_I2C */