spi_core.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. #include <drivers/spi.h>
  2. extern rt_err_t rt_spi_bus_device_init(struct rt_spi_bus* bus, const char* name);
  3. extern rt_err_t rt_spidev_device_init(struct rt_spi_device* dev, const char* name);
  4. rt_err_t rt_spi_bus_register(struct rt_spi_bus* bus, const char* name, struct rt_spi_ops* ops)
  5. {
  6. rt_err_t result;
  7. result = rt_spi_bus_device_init(bus, name);
  8. if (result != RT_EOK) return result;
  9. /* initialize mutex lock */
  10. rt_mutex_init(&(bus->lock), name, RT_IPC_FLAG_FIFO);
  11. /* set ops */
  12. bus->ops = ops;
  13. /* initialize owner */
  14. bus->owner = RT_NULL;
  15. return RT_EOK;
  16. }
  17. rt_err_t rt_spi_bus_attach_device(struct rt_spi_device* device, const char* name, const char* bus_name, void* user_data)
  18. {
  19. rt_device_t bus;
  20. /* get physical spi bus */
  21. bus = rt_device_find(bus_name);
  22. if (bus != RT_NULL && bus->type == RT_Device_Class_SPIBUS)
  23. {
  24. device->bus = (struct rt_spi_bus*)bus;
  25. /* initialize spidev device */
  26. rt_spidev_device_init(device, name);
  27. rt_memset(&device->config, 0, sizeof(device->config));
  28. device->parent.user_data = user_data;
  29. }
  30. /* not found the host bus */
  31. return -RT_ERROR;
  32. }
  33. rt_err_t rt_spi_configure(struct rt_spi_device* device, struct rt_spi_configuration* cfg)
  34. {
  35. rt_err_t result;
  36. RT_ASSERT(device != RT_NULL);
  37. /* set configuration */
  38. device->config.data_width = cfg->data_width;
  39. device->config.mode = cfg->mode & RT_SPI_MODE_MASK ;
  40. device->config.max_hz = cfg->max_hz ;
  41. if (device->bus != RT_NULL)
  42. {
  43. result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER);
  44. if (result == RT_EOK)
  45. {
  46. if (device->bus->owner == device)
  47. {
  48. device->bus->ops->configure(device, &device->config);
  49. }
  50. /* release lock */
  51. rt_mutex_release(&(device->bus->lock));
  52. }
  53. }
  54. return RT_EOK;
  55. }
  56. rt_err_t rt_spi_send_then_send(struct rt_spi_device* device, const void *send_buf1, rt_size_t send_length1,
  57. const void* send_buf2, rt_size_t send_length2)
  58. {
  59. rt_err_t result;
  60. struct rt_spi_message message;
  61. RT_ASSERT(device != RT_NULL);
  62. RT_ASSERT(device->bus != RT_NULL);
  63. result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER);
  64. if (result == RT_EOK)
  65. {
  66. if (device->bus->owner != device)
  67. {
  68. /* not the same owner as current, re-configure SPI bus */
  69. result = device->bus->ops->configure(device, &device->config);
  70. if (result == RT_EOK)
  71. {
  72. /* set SPI bus owner */
  73. device->bus->owner = device;
  74. }
  75. else
  76. {
  77. /* configure SPI bus failed */
  78. result = -RT_EIO;
  79. goto __exit;
  80. }
  81. }
  82. /* send data1 */
  83. message.send_buf = send_buf1;
  84. message.recv_buf = RT_NULL;
  85. message.length = send_length1;
  86. message.cs_take = 1;
  87. message.cs_release = 0;
  88. result = device->bus->ops->xfer(device, &message);
  89. if (result == 0)
  90. {
  91. result = -RT_EIO;
  92. goto __exit;
  93. }
  94. /* send data2 */
  95. message.send_buf = send_buf2;
  96. message.recv_buf = RT_NULL;
  97. message.length = send_length2;
  98. message.cs_take = 0;
  99. message.cs_release = 1;
  100. result = device->bus->ops->xfer(device, &message);
  101. if (result == 0)
  102. {
  103. result = -RT_EIO;
  104. goto __exit;
  105. }
  106. result = RT_EOK;
  107. }
  108. else
  109. {
  110. return -RT_EIO;
  111. }
  112. __exit:
  113. rt_mutex_release(&(device->bus->lock));
  114. return result;
  115. }
  116. rt_err_t rt_spi_send_then_recv(struct rt_spi_device* device, const void *send_buf, rt_size_t send_length,
  117. void* recv_buf, rt_size_t recv_length)
  118. {
  119. rt_err_t result;
  120. struct rt_spi_message message;
  121. RT_ASSERT(device != RT_NULL);
  122. RT_ASSERT(device->bus != RT_NULL);
  123. result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER);
  124. if (result == RT_EOK)
  125. {
  126. if (device->bus->owner != device)
  127. {
  128. /* not the same owner as current, re-configure SPI bus */
  129. result = device->bus->ops->configure(device, &device->config);
  130. if (result == RT_EOK)
  131. {
  132. /* set SPI bus owner */
  133. device->bus->owner = device;
  134. }
  135. else
  136. {
  137. /* configure SPI bus failed */
  138. result = -RT_EIO;
  139. goto __exit;
  140. }
  141. }
  142. /* send data */
  143. message.send_buf = send_buf;
  144. message.recv_buf = RT_NULL;
  145. message.length = send_length;
  146. message.cs_take = 1;
  147. message.cs_release = 0;
  148. result = device->bus->ops->xfer(device, &message);
  149. if (result == 0)
  150. {
  151. result = -RT_EIO;
  152. goto __exit;
  153. }
  154. /* recv data */
  155. message.send_buf = RT_NULL;
  156. message.recv_buf = recv_buf;
  157. message.length = recv_length;
  158. message.cs_take = 0;
  159. message.cs_release = 1;
  160. result = device->bus->ops->xfer(device, &message);
  161. if (result == 0)
  162. {
  163. result = -RT_EIO;
  164. goto __exit;
  165. }
  166. result = RT_EOK;
  167. }
  168. else
  169. {
  170. return -RT_EIO;
  171. }
  172. __exit:
  173. rt_mutex_release(&(device->bus->lock));
  174. return result;
  175. }
  176. rt_size_t rt_spi_transfer(struct rt_spi_device* device, const void *send_buf,
  177. void* recv_buf, rt_size_t length)
  178. {
  179. rt_err_t result;
  180. struct rt_spi_message message;
  181. RT_ASSERT(device != RT_NULL);
  182. RT_ASSERT(device->bus != RT_NULL);
  183. result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER);
  184. if (result == RT_EOK)
  185. {
  186. if (device->bus->owner != device)
  187. {
  188. /* not the same owner as current, re-configure SPI bus */
  189. result = device->bus->ops->configure(device, &device->config);
  190. if (result == RT_EOK)
  191. {
  192. /* set SPI bus owner */
  193. device->bus->owner = device;
  194. }
  195. else
  196. {
  197. /* configure SPI bus failed */
  198. rt_set_errno(-RT_EIO);
  199. result = 0;
  200. goto __exit;
  201. }
  202. }
  203. /* initial message */
  204. message.send_buf = send_buf;
  205. message.recv_buf = recv_buf;
  206. message.length = length;
  207. message.cs_take = message.cs_release = 1;
  208. /* transfer message */
  209. result = device->bus->ops->xfer(device, &message);
  210. if (result == 0)
  211. {
  212. rt_set_errno(-RT_EIO);
  213. goto __exit;
  214. }
  215. }
  216. else
  217. {
  218. rt_set_errno(-RT_EIO);
  219. return 0;
  220. }
  221. __exit:
  222. rt_mutex_release(&(device->bus->lock));
  223. return result;
  224. }