drv_i2c.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * Copyright (c) 2006-2020, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-02-26 Jackistang first version
  9. *
  10. */
  11. #include "drv_i2c.h"
  12. #include "i2c.h"
  13. #include <rtdevice.h>
  14. #include <rtthread.h>
  15. #include "board.h"
  16. #ifdef RT_USING_I2C
  17. #if !defined(BSP_USING_I2C0) && !defined(BSP_USING_I2C1)
  18. #error "Please define at least one BSP_USING_I2Cx"
  19. /* this driver can be disabled at menuconfig -> Hardware Drivers Config -> On-chip Peripheral Drivers -> Enable I2C */
  20. #endif
  21. #define DBG_LEVEL DBG_LOG
  22. #include <rtdbg.h>
  23. #define LOG_TAG "drv.i2c"
  24. /* mxc config class */
  25. struct mxc_i2c_config
  26. {
  27. const char *name;
  28. mxc_i2c_regs_t *i2c_periph;
  29. i2c_speed_t speed;
  30. IRQn_Type irq_type;
  31. };
  32. struct mxc_i2c
  33. {
  34. struct rt_i2c_bus_device bus;
  35. struct mxc_i2c_config *config;
  36. };
  37. static struct mxc_i2c_config i2c_config[] =
  38. {
  39. #ifdef BSP_USING_I2C0
  40. {
  41. .name = "i2c0",
  42. .i2c_periph = MXC_I2C_GET_I2C(0),
  43. .irq_type = MXC_I2C_GET_IRQ(0),
  44. .speed = I2C_STD_MODE,
  45. /*I2C_STD_MODE: 100KHz, I2C_FAST_MODE: 400KHz, I2C_FASTPLUS_MODE: 1MHz, I2C_HS_MODE: 3.4MHz */
  46. },
  47. #endif
  48. #ifdef BSP_USING_I2C1
  49. {
  50. .name = "i2c1",
  51. .i2c_periph = MXC_I2C_GET_I2C(1),
  52. .irq_type = MXC_I2C_GET_IRQ(1),
  53. .speed = I2C_STD_MODE,
  54. /*I2C_STD_MODE: 100KHz, I2C_FAST_MODE: 400KHz, I2C_FASTPLUS_MODE: 1MHz, I2C_HS_MODE: 3.4MHz */
  55. },
  56. #endif
  57. };
  58. static struct mxc_i2c i2c_obj[sizeof(i2c_config) / sizeof(i2c_config[0])] = {0};
  59. static rt_size_t mxc_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
  60. struct rt_i2c_msg msgs[],
  61. rt_uint32_t num)
  62. {
  63. rt_uint32_t i, ret;
  64. rt_uint16_t addr;
  65. int error;
  66. int restart = 0;
  67. struct rt_i2c_msg *msg;
  68. struct mxc_i2c *obj = (struct mxc_i2c *)bus;
  69. for (i = 0; i < num; i++)
  70. {
  71. msg = &msgs[i];
  72. if (msg->flags & RT_I2C_ADDR_10BIT || msg->flags & RT_I2C_NO_START || msg->flags & RT_I2C_IGNORE_NACK || msg->flags & RT_I2C_NO_READ_ACK)
  73. {
  74. LOG_E("Not support RT_I2C_ADDR_10BIT or RT_I2C_NO_START or RT_I2C_IGNORE_NACK or RT_I2C_NO_READ_ACK");
  75. return 0;
  76. }
  77. if (msg->flags & RT_I2C_NO_STOP)
  78. {
  79. restart = 1;
  80. }
  81. if (msg->flags & RT_I2C_RD)
  82. {
  83. addr = msg->addr << 1;
  84. if ((error = I2C_MasterRead(obj->config->i2c_periph, (uint8_t)addr, msg->buf, msg->len, restart)) != msg->len)
  85. {
  86. LOG_E("Error writing %d", error);
  87. return 0;
  88. }
  89. }
  90. else /* RT_I2C_WR */
  91. {
  92. addr = msg->addr << 1;
  93. if ((error = I2C_MasterWrite(obj->config->i2c_periph, (uint8_t)addr, msg->buf, msg->len, restart)) != msg->len)
  94. {
  95. LOG_E("Error writing %d", error);
  96. return 0;
  97. }
  98. }
  99. }
  100. ret = i;
  101. return ret;
  102. }
  103. static const struct rt_i2c_bus_device_ops mxc_i2c_ops =
  104. {
  105. mxc_i2c_mst_xfer,
  106. RT_NULL,
  107. RT_NULL,
  108. };
  109. int rt_hw_i2c_init(void)
  110. {
  111. rt_size_t obj_num;
  112. int index;
  113. rt_err_t result = 0;
  114. #ifdef BSP_USING_I2C0
  115. NVIC_EnableIRQ(I2C0_IRQn);
  116. #endif
  117. #ifdef BSP_USING_I2C1
  118. NVIC_EnableIRQ(I2C1_IRQn);
  119. #endif
  120. obj_num = sizeof(i2c_obj) / sizeof(struct mxc_i2c);
  121. for (index = 0; index < obj_num; index++)
  122. {
  123. /* init i2c object */
  124. i2c_obj[index].config = &i2c_config[index];
  125. i2c_obj[index].bus.ops = &mxc_i2c_ops;
  126. /* init i2c device */
  127. I2C_Shutdown(i2c_config[index].i2c_periph);
  128. I2C_Init(i2c_config[index].i2c_periph, i2c_config[index].speed, RT_NULL);
  129. /* register i2c device */
  130. result = rt_i2c_bus_device_register(&i2c_obj[index].bus,
  131. i2c_obj[index].config->name
  132. );
  133. RT_ASSERT(result == RT_EOK);
  134. }
  135. return 0;
  136. }
  137. INIT_DEVICE_EXPORT(rt_hw_i2c_init);
  138. #ifdef BSP_USING_I2C0
  139. void I2C0_IRQHandler(void)
  140. {
  141. rt_interrupt_enter();
  142. I2C_Handler(MXC_I2C0);
  143. rt_interrupt_leave();
  144. }
  145. #endif
  146. #ifdef BSP_USING_I2C1
  147. void I2C1_IRQHandler(void)
  148. {
  149. rt_interrupt_enter();
  150. I2C_Handler(MXC_I2C1);
  151. rt_interrupt_leave();
  152. }
  153. #endif
  154. #endif /* RT_USING_I2C */