sam_i2c.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*
  2. * Copyright (c)
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Email Notes
  8. * 2022-04-11 Kevin.Liu kevin.liu.mchp@gmail.com First Release
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include <atmel_start.h>
  13. #ifdef SAM_I2C_EXAMPLE
  14. struct sam_i2c_bus
  15. {
  16. struct rt_i2c_bus_device parent;
  17. struct i2c_m_sync_desc *i2c_desc;
  18. char *device_name;
  19. };
  20. #define I2CBUS_NAME "i2c0"
  21. static struct sam_i2c_bus sam_i2c0 =
  22. {
  23. .i2c_desc = &I2C_0,
  24. .device_name = I2CBUS_NAME,
  25. };
  26. static rt_size_t sam_i2c_master_xfer(struct rt_i2c_bus_device *bus,
  27. struct rt_i2c_msg msgs[],
  28. rt_uint32_t num);
  29. static rt_size_t sam_i2c_slave_xfer(struct rt_i2c_bus_device *bus,
  30. struct rt_i2c_msg msgs[],
  31. rt_uint32_t num);
  32. static rt_err_t sam_i2c_bus_control(struct rt_i2c_bus_device *bus,
  33. rt_uint32_t, rt_uint32_t);
  34. static const struct rt_i2c_bus_device_ops sam_i2c_ops =
  35. {
  36. .master_xfer = sam_i2c_master_xfer,
  37. .slave_xfer = sam_i2c_slave_xfer,
  38. .i2c_bus_control = sam_i2c_bus_control,
  39. };
  40. static inline void sam_i2c_update_control(struct rt_i2c_msg *src,
  41. struct _i2c_m_msg *dest)
  42. {
  43. dest->len = (int32_t)src->len;
  44. dest->addr = src->addr;
  45. dest->buffer = src->buf;
  46. /* Get I2C message R/W attribute first */
  47. dest->flags = dest->flags & 0x0001;
  48. if (dest->flags & RT_I2C_ADDR_10BIT)
  49. dest->flags |= I2C_M_TEN;
  50. else
  51. dest->flags |= I2C_M_SEVEN;
  52. }
  53. static rt_size_t sam_i2c_master_xfer(struct rt_i2c_bus_device *bus,
  54. struct rt_i2c_msg msgs[],
  55. rt_uint32_t num)
  56. {
  57. struct sam_i2c_bus *sam_i2c = (struct sam_i2c_bus *)bus;
  58. struct _i2c_m_msg i2c_msg;
  59. rt_size_t i;
  60. RT_ASSERT(bus != RT_NULL);
  61. for (i = 0; i < num; i++)
  62. {
  63. sam_i2c_update_control(&msgs[i], &i2c_msg);
  64. if (i2c_m_sync_transfer(sam_i2c->i2c_desc, &i2c_msg) != 0)
  65. break;
  66. }
  67. return i;
  68. }
  69. static rt_size_t sam_i2c_slave_xfer(struct rt_i2c_bus_device *bus,
  70. struct rt_i2c_msg msgs[],
  71. rt_uint32_t num)
  72. {
  73. return 0;
  74. }
  75. static rt_err_t sam_i2c_bus_control(struct rt_i2c_bus_device *bus,
  76. rt_uint32_t cmd,
  77. rt_uint32_t arg)
  78. {
  79. return RT_ERROR;
  80. struct sam_i2c_bus *sam_i2c = (struct sam_i2c_bus *)bus;
  81. RT_ASSERT(bus != RT_NULL);
  82. switch (cmd)
  83. {
  84. case RT_I2C_DEV_CTRL_CLK:
  85. i2c_m_sync_set_baudrate(sam_i2c->i2c_desc, 0, arg);
  86. break;
  87. default:
  88. return -RT_EIO;
  89. }
  90. return RT_EOK;
  91. }
  92. int rt_hw_i2c_init(void)
  93. {
  94. rt_i2c_bus_device_register(&sam_i2c0.parent, sam_i2c0.device_name);
  95. return 0;
  96. }
  97. #ifdef RT_USING_COMPONENTS_INIT
  98. INIT_BOARD_EXPORT(rt_hw_i2c_init);
  99. #endif
  100. #endif
  101. /*@}*/