spi_core.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. /*
  2. * File : spi_core.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. */
  13. #include <drivers/spi.h>
  14. extern rt_err_t rt_spi_bus_device_init(struct rt_spi_bus *bus, const char *name);
  15. extern rt_err_t rt_spidev_device_init(struct rt_spi_device *dev, const char *name);
  16. rt_err_t rt_spi_bus_register(struct rt_spi_bus *bus,
  17. const char *name,
  18. const struct rt_spi_ops *ops)
  19. {
  20. rt_err_t result;
  21. result = rt_spi_bus_device_init(bus, name);
  22. if (result != RT_EOK)
  23. return result;
  24. /* initialize mutex lock */
  25. rt_mutex_init(&(bus->lock), name, RT_IPC_FLAG_FIFO);
  26. /* set ops */
  27. bus->ops = ops;
  28. /* initialize owner */
  29. bus->owner = RT_NULL;
  30. return RT_EOK;
  31. }
  32. rt_err_t rt_spi_bus_attach_device(struct rt_spi_device *device,
  33. const char *name,
  34. const char *bus_name,
  35. void *user_data)
  36. {
  37. rt_err_t result;
  38. rt_device_t bus;
  39. /* get physical spi bus */
  40. bus = rt_device_find(bus_name);
  41. if (bus != RT_NULL && bus->type == RT_Device_Class_SPIBUS)
  42. {
  43. device->bus = (struct rt_spi_bus *)bus;
  44. /* initialize spidev device */
  45. result = rt_spidev_device_init(device, name);
  46. if (result != RT_EOK)
  47. return result;
  48. rt_memset(&device->config, 0, sizeof(device->config));
  49. device->parent.user_data = user_data;
  50. return RT_EOK;
  51. }
  52. /* not found the host bus */
  53. return -RT_ERROR;
  54. }
  55. rt_err_t rt_spi_configure(struct rt_spi_device *device,
  56. struct rt_spi_configuration *cfg)
  57. {
  58. rt_err_t result;
  59. RT_ASSERT(device != RT_NULL);
  60. /* set configuration */
  61. device->config.data_width = cfg->data_width;
  62. device->config.mode = cfg->mode & RT_SPI_MODE_MASK ;
  63. device->config.max_hz = cfg->max_hz ;
  64. if (device->bus != RT_NULL)
  65. {
  66. result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER);
  67. if (result == RT_EOK)
  68. {
  69. if (device->bus->owner == device)
  70. {
  71. device->bus->ops->configure(device, &device->config);
  72. }
  73. /* release lock */
  74. rt_mutex_release(&(device->bus->lock));
  75. }
  76. }
  77. return RT_EOK;
  78. }
  79. rt_err_t rt_spi_send_then_send(struct rt_spi_device *device,
  80. const void *send_buf1,
  81. rt_size_t send_length1,
  82. const void *send_buf2,
  83. rt_size_t send_length2)
  84. {
  85. rt_err_t result;
  86. struct rt_spi_message message;
  87. RT_ASSERT(device != RT_NULL);
  88. RT_ASSERT(device->bus != RT_NULL);
  89. result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER);
  90. if (result == RT_EOK)
  91. {
  92. if (device->bus->owner != device)
  93. {
  94. /* not the same owner as current, re-configure SPI bus */
  95. result = device->bus->ops->configure(device, &device->config);
  96. if (result == RT_EOK)
  97. {
  98. /* set SPI bus owner */
  99. device->bus->owner = device;
  100. }
  101. else
  102. {
  103. /* configure SPI bus failed */
  104. result = -RT_EIO;
  105. goto __exit;
  106. }
  107. }
  108. /* send data1 */
  109. message.send_buf = send_buf1;
  110. message.recv_buf = RT_NULL;
  111. message.length = send_length1;
  112. message.cs_take = 1;
  113. message.cs_release = 0;
  114. message.next = RT_NULL;
  115. result = device->bus->ops->xfer(device, &message);
  116. if (result == 0)
  117. {
  118. result = -RT_EIO;
  119. goto __exit;
  120. }
  121. /* send data2 */
  122. message.send_buf = send_buf2;
  123. message.recv_buf = RT_NULL;
  124. message.length = send_length2;
  125. message.cs_take = 0;
  126. message.cs_release = 1;
  127. message.next = RT_NULL;
  128. result = device->bus->ops->xfer(device, &message);
  129. if (result == 0)
  130. {
  131. result = -RT_EIO;
  132. goto __exit;
  133. }
  134. result = RT_EOK;
  135. }
  136. else
  137. {
  138. return -RT_EIO;
  139. }
  140. __exit:
  141. rt_mutex_release(&(device->bus->lock));
  142. return result;
  143. }
  144. rt_err_t rt_spi_send_then_recv(struct rt_spi_device *device,
  145. const void *send_buf,
  146. rt_size_t send_length,
  147. void *recv_buf,
  148. rt_size_t recv_length)
  149. {
  150. rt_err_t result;
  151. struct rt_spi_message message;
  152. RT_ASSERT(device != RT_NULL);
  153. RT_ASSERT(device->bus != RT_NULL);
  154. result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER);
  155. if (result == RT_EOK)
  156. {
  157. if (device->bus->owner != device)
  158. {
  159. /* not the same owner as current, re-configure SPI bus */
  160. result = device->bus->ops->configure(device, &device->config);
  161. if (result == RT_EOK)
  162. {
  163. /* set SPI bus owner */
  164. device->bus->owner = device;
  165. }
  166. else
  167. {
  168. /* configure SPI bus failed */
  169. result = -RT_EIO;
  170. goto __exit;
  171. }
  172. }
  173. /* send data */
  174. message.send_buf = send_buf;
  175. message.recv_buf = RT_NULL;
  176. message.length = send_length;
  177. message.cs_take = 1;
  178. message.cs_release = 0;
  179. message.next = RT_NULL;
  180. result = device->bus->ops->xfer(device, &message);
  181. if (result == 0)
  182. {
  183. result = -RT_EIO;
  184. goto __exit;
  185. }
  186. /* recv data */
  187. message.send_buf = RT_NULL;
  188. message.recv_buf = recv_buf;
  189. message.length = recv_length;
  190. message.cs_take = 0;
  191. message.cs_release = 1;
  192. message.next = RT_NULL;
  193. result = device->bus->ops->xfer(device, &message);
  194. if (result == 0)
  195. {
  196. result = -RT_EIO;
  197. goto __exit;
  198. }
  199. result = RT_EOK;
  200. }
  201. else
  202. {
  203. return -RT_EIO;
  204. }
  205. __exit:
  206. rt_mutex_release(&(device->bus->lock));
  207. return result;
  208. }
  209. rt_size_t rt_spi_transfer(struct rt_spi_device *device,
  210. const void *send_buf,
  211. void *recv_buf,
  212. rt_size_t length)
  213. {
  214. rt_err_t result;
  215. struct rt_spi_message message;
  216. RT_ASSERT(device != RT_NULL);
  217. RT_ASSERT(device->bus != RT_NULL);
  218. result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER);
  219. if (result == RT_EOK)
  220. {
  221. if (device->bus->owner != device)
  222. {
  223. /* not the same owner as current, re-configure SPI bus */
  224. result = device->bus->ops->configure(device, &device->config);
  225. if (result == RT_EOK)
  226. {
  227. /* set SPI bus owner */
  228. device->bus->owner = device;
  229. }
  230. else
  231. {
  232. /* configure SPI bus failed */
  233. rt_set_errno(-RT_EIO);
  234. result = 0;
  235. goto __exit;
  236. }
  237. }
  238. /* initial message */
  239. message.send_buf = send_buf;
  240. message.recv_buf = recv_buf;
  241. message.length = length;
  242. message.cs_take = 1;
  243. message.cs_release = 1;
  244. message.next = RT_NULL;
  245. /* transfer message */
  246. result = device->bus->ops->xfer(device, &message);
  247. if (result == 0)
  248. {
  249. rt_set_errno(-RT_EIO);
  250. goto __exit;
  251. }
  252. }
  253. else
  254. {
  255. rt_set_errno(-RT_EIO);
  256. return 0;
  257. }
  258. __exit:
  259. rt_mutex_release(&(device->bus->lock));
  260. return result;
  261. }
  262. struct rt_spi_message *rt_spi_transfer_message(struct rt_spi_device *device,
  263. struct rt_spi_message *message)
  264. {
  265. rt_err_t result;
  266. struct rt_spi_message *index;
  267. RT_ASSERT(device != RT_NULL);
  268. /* get first message */
  269. index = message;
  270. if (index == RT_NULL)
  271. return index;
  272. result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER);
  273. if (result != RT_EOK)
  274. {
  275. rt_set_errno(-RT_EBUSY);
  276. return index;
  277. }
  278. /* reset errno */
  279. rt_set_errno(RT_EOK);
  280. /* configure SPI bus */
  281. if (device->bus->owner != device)
  282. {
  283. /* not the same owner as current, re-configure SPI bus */
  284. result = device->bus->ops->configure(device, &device->config);
  285. if (result == RT_EOK)
  286. {
  287. /* set SPI bus owner */
  288. device->bus->owner = device;
  289. }
  290. else
  291. {
  292. /* configure SPI bus failed */
  293. rt_set_errno(-RT_EIO);
  294. result = 0;
  295. goto __exit;
  296. }
  297. }
  298. /* transmit each SPI message */
  299. while (index != RT_NULL)
  300. {
  301. /* transmit SPI message */
  302. result = device->bus->ops->xfer(device, index);
  303. if (result == 0)
  304. {
  305. rt_set_errno(-RT_EIO);
  306. break;
  307. }
  308. index = index->next;
  309. }
  310. __exit:
  311. /* release bus lock */
  312. rt_mutex_release(&(device->bus->lock));
  313. return index;
  314. }
  315. rt_err_t rt_spi_take_bus(struct rt_spi_device *device)
  316. {
  317. rt_err_t result = RT_EOK;
  318. RT_ASSERT(device != RT_NULL);
  319. RT_ASSERT(device->bus != RT_NULL);
  320. result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER);
  321. if (result != RT_EOK)
  322. {
  323. rt_set_errno(-RT_EBUSY);
  324. return -RT_EBUSY;
  325. }
  326. /* reset errno */
  327. rt_set_errno(RT_EOK);
  328. /* configure SPI bus */
  329. if (device->bus->owner != device)
  330. {
  331. /* not the same owner as current, re-configure SPI bus */
  332. result = device->bus->ops->configure(device, &device->config);
  333. if (result == RT_EOK)
  334. {
  335. /* set SPI bus owner */
  336. device->bus->owner = device;
  337. }
  338. else
  339. {
  340. /* configure SPI bus failed */
  341. rt_set_errno(-RT_EIO);
  342. /* release lock */
  343. rt_mutex_release(&(device->bus->lock));
  344. return -RT_EIO;
  345. }
  346. }
  347. return result;
  348. }
  349. rt_err_t rt_spi_release_bus(struct rt_spi_device *device)
  350. {
  351. RT_ASSERT(device != RT_NULL);
  352. RT_ASSERT(device->bus != RT_NULL);
  353. RT_ASSERT(device->bus->owner != device);
  354. /* release lock */
  355. rt_mutex_release(&(device->bus->lock));
  356. return RT_EOK;
  357. }
  358. rt_err_t rt_spi_take(struct rt_spi_device *device)
  359. {
  360. rt_err_t result;
  361. struct rt_spi_message message;
  362. RT_ASSERT(device != RT_NULL);
  363. RT_ASSERT(device->bus != RT_NULL);
  364. rt_memset(&message, 0, sizeof(message));
  365. message.cs_take = 1;
  366. result = device->bus->ops->xfer(device, &message);
  367. return result;
  368. }
  369. rt_err_t rt_spi_release(struct rt_spi_device *device)
  370. {
  371. rt_err_t result;
  372. struct rt_spi_message message;
  373. RT_ASSERT(device != RT_NULL);
  374. RT_ASSERT(device->bus != RT_NULL);
  375. rt_memset(&message, 0, sizeof(message));
  376. message.cs_release = 1;
  377. result = device->bus->ops->xfer(device, &message);
  378. return result;
  379. }