hw_i2c.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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. * 2018-01-04 Sundm75 the first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include "ls1c_i2c.h"
  13. #include "../libraries/ls1c_pin.h"
  14. #ifdef RT_USING_I2C
  15. struct ls1c_i2c_bus
  16. {
  17. struct rt_i2c_bus_device parent;
  18. rt_uint32_t u32Module;
  19. };
  20. rt_size_t rt_i2c_master_xfer(struct rt_i2c_bus_device *bus,
  21. struct rt_i2c_msg *msgs,
  22. rt_uint32_t num)
  23. {
  24. struct ls1c_i2c_bus * i2c_bus = (struct ls1c_i2c_bus *)bus;
  25. ls1c_i2c_info_t i2c_info;
  26. struct rt_i2c_msg *msg;
  27. int i;
  28. rt_int32_t ret = RT_EOK;
  29. i2c_info.clock = 50000; // 50kb/s
  30. i2c_info.I2Cx = i2c_bus->u32Module;
  31. i2c_init(&i2c_info);
  32. for (i = 0; i < num; i++)
  33. {
  34. msg = &msgs[i];
  35. if (msg->flags == RT_I2C_RD)
  36. {
  37. i2c_send_start_and_addr(&i2c_info, msg->addr, LS1C_I2C_DIRECTION_READ);
  38. i2c_receive_ack(&i2c_info);
  39. i2c_receive_data(&i2c_info, (rt_uint8_t *)msg->buf, msg->len);
  40. i2c_send_stop(&i2c_info);
  41. }
  42. else if(msg->flags == RT_I2C_WR)
  43. {
  44. i2c_send_start_and_addr(&i2c_info, msg->addr, LS1C_I2C_DIRECTION_WRITE);
  45. i2c_receive_ack(&i2c_info);
  46. i2c_send_data(&i2c_info, (rt_uint8_t *)msg->buf, msg->len);
  47. i2c_send_stop(&i2c_info);
  48. }
  49. ret++;
  50. }
  51. return ret;
  52. }
  53. rt_err_t rt_i2c_bus_control(struct rt_i2c_bus_device *bus,
  54. rt_uint32_t cmd,
  55. rt_uint32_t arg)
  56. {
  57. struct ls1c_i2c_bus * i2c_bus = (struct ls1c_i2c_bus *)bus;
  58. RT_ASSERT(bus != RT_NULL);
  59. i2c_bus = (struct ls1c_i2c_bus *)bus->parent.user_data;
  60. RT_ASSERT(i2c_bus != RT_NULL);
  61. switch (cmd)
  62. {
  63. case RT_DEVICE_CTRL_CONFIG :
  64. break;
  65. }
  66. return RT_EOK;
  67. }
  68. static const struct rt_i2c_bus_device_ops ls1c_i2c_ops =
  69. {
  70. rt_i2c_master_xfer,
  71. RT_NULL,
  72. rt_i2c_bus_control
  73. };
  74. #ifdef RT_USING_I2C0
  75. static struct ls1c_i2c_bus ls1c_i2c_bus_0 =
  76. {
  77. {1},
  78. LS1C_I2C_0,
  79. };
  80. #endif
  81. #ifdef RT_USING_I2C1
  82. static struct ls1c_i2c_bus ls1c_i2c_bus_1 =
  83. {
  84. {1},
  85. LS1C_I2C_1,
  86. };
  87. #endif
  88. #ifdef RT_USING_I2C2
  89. static struct ls1c_i2c_bus ls1c_i2c_bus_2 =
  90. {
  91. {1},
  92. LS1C_I2C_2,
  93. };
  94. #endif
  95. int ls1c_hw_i2c_init(void)
  96. {
  97. struct ls1c_i2c_bus* ls1c_i2c;
  98. #ifdef RT_USING_I2C0
  99. /*
  100. pin_set_purpose(2, PIN_PURPOSE_OTHER);
  101. pin_set_purpose(3, PIN_PURPOSE_OTHER);
  102. pin_set_remap(2, PIN_REMAP_SECOND);
  103. pin_set_remap(3, PIN_REMAP_SECOND);
  104. */
  105. #endif
  106. #ifdef RT_USING_I2C1
  107. pin_set_purpose(2, PIN_PURPOSE_OTHER);
  108. pin_set_purpose(3, PIN_PURPOSE_OTHER);
  109. pin_set_remap(2, PIN_REMAP_SECOND);
  110. pin_set_remap(3, PIN_REMAP_SECOND);
  111. #endif
  112. #ifdef RT_USING_I2C2
  113. pin_set_purpose(51, PIN_PURPOSE_OTHER);
  114. pin_set_purpose(50, PIN_PURPOSE_OTHER);
  115. pin_set_remap(51, PIN_REMAP_FOURTH);
  116. pin_set_remap(50, PIN_REMAP_FOURTH);
  117. #endif
  118. #ifdef RT_USING_I2C0
  119. ls1c_i2c = &ls1c_i2c_bus_0;
  120. ls1c_i2c->parent.ops = &ls1c_i2c_ops;
  121. rt_i2c_bus_device_register(&ls1c_i2c->parent, "i2c0");
  122. rt_kprintf("i2c0_init!\n");
  123. #endif
  124. #ifdef RT_USING_I2C1
  125. ls1c_i2c = &ls1c_i2c_bus_1;
  126. ls1c_i2c->parent.ops = &ls1c_i2c_ops;
  127. rt_i2c_bus_device_register(&ls1c_i2c->parent, "i2c1");
  128. rt_kprintf("i2c1_init!\n");
  129. #endif
  130. #ifdef RT_USING_I2C2
  131. ls1c_i2c = &ls1c_i2c_bus_2;
  132. ls1c_i2c->parent.ops = &ls1c_i2c_ops;
  133. rt_i2c_bus_device_register(&ls1c_i2c->parent, "i2c2");
  134. rt_kprintf("i2c2_init!\n");
  135. #endif
  136. return RT_EOK;
  137. }
  138. INIT_BOARD_EXPORT(ls1c_hw_i2c_init);
  139. #endif