drv_spi.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-03-18 ZYH first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #ifdef RT_USING_SPI
  13. #include "drv_spi.h"
  14. #include <drv_io_config.h>
  15. #include <spi.h>
  16. #include "dmalock.h"
  17. #include <sysctl.h>
  18. #include <gpiohs.h>
  19. #include <string.h>
  20. #include "utils.h"
  21. #define DRV_SPI_DEVICE(spi_bus) (struct drv_spi_bus *)(spi_bus)
  22. #define MAX_CLOCK (40000000UL)
  23. struct drv_spi_bus
  24. {
  25. struct rt_spi_bus parent;
  26. spi_device_num_t spi_instance;
  27. dmac_channel_number_t dma_send_channel;
  28. dmac_channel_number_t dma_recv_channel;
  29. struct rt_completion dma_completion;
  30. };
  31. struct drv_cs
  32. {
  33. int cs_index;
  34. int cs_pin;
  35. };
  36. static volatile spi_t *const spi_instance[4] =
  37. {
  38. (volatile spi_t *)SPI0_BASE_ADDR,
  39. (volatile spi_t *)SPI1_BASE_ADDR,
  40. (volatile spi_t *)SPI_SLAVE_BASE_ADDR,
  41. (volatile spi_t *)SPI3_BASE_ADDR
  42. };
  43. static rt_err_t drv_spi_configure(struct rt_spi_device *device,
  44. struct rt_spi_configuration *configuration)
  45. {
  46. rt_err_t ret = RT_EOK;
  47. int freq = 0;
  48. struct drv_spi_bus *bus = DRV_SPI_DEVICE(device->bus);
  49. struct drv_cs * cs = (struct drv_cs *)device->parent.user_data;
  50. RT_ASSERT(bus != RT_NULL);
  51. gpiohs_set_drive_mode(cs->cs_pin, GPIO_DM_OUTPUT);
  52. gpiohs_set_pin(cs->cs_pin, GPIO_PV_HIGH);
  53. #ifdef BSP_USING_SPI1_AS_QSPI
  54. /* Todo:QSPI*/
  55. #else
  56. spi_init(bus->spi_instance, configuration->mode & RT_SPI_MODE_3, SPI_FF_STANDARD, configuration->data_width, 0);
  57. #endif
  58. freq = spi_set_clk_rate(bus->spi_instance, configuration->max_hz > MAX_CLOCK ? MAX_CLOCK : configuration->max_hz);
  59. rt_kprintf("set spi freq %d\n", freq);
  60. return ret;
  61. }
  62. void __spi_set_tmod(uint8_t spi_num, uint32_t tmod)
  63. {
  64. RT_ASSERT(spi_num < SPI_DEVICE_MAX);
  65. volatile spi_t *spi_handle = spi[spi_num];
  66. uint8_t tmod_offset = 0;
  67. switch(spi_num)
  68. {
  69. case 0:
  70. case 1:
  71. case 2:
  72. tmod_offset = 8;
  73. break;
  74. case 3:
  75. default:
  76. tmod_offset = 10;
  77. break;
  78. }
  79. set_bit(&spi_handle->ctrlr0, 3 << tmod_offset, tmod << tmod_offset);
  80. }
  81. int dma_irq_callback(void *ctx)
  82. {
  83. struct rt_completion * cmp = ctx;
  84. if(cmp)
  85. {
  86. rt_completion_done(cmp);
  87. }
  88. }
  89. static rt_uint32_t drv_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
  90. {
  91. struct drv_spi_bus *bus = DRV_SPI_DEVICE(device->bus);
  92. struct drv_cs * cs = (struct drv_cs *)device->parent.user_data;
  93. struct rt_spi_configuration *cfg = &device->config;
  94. uint32_t * tx_buff = RT_NULL;
  95. uint32_t * rx_buff = RT_NULL;
  96. int i;
  97. rt_ubase_t dummy = 0xFFFFFFFFU;
  98. if(cfg->data_width != 8)
  99. {
  100. return 0;
  101. }
  102. RT_ASSERT(bus != RT_NULL);
  103. if(message->cs_take)
  104. {
  105. gpiohs_set_pin(cs->cs_pin, GPIO_PV_LOW);
  106. }
  107. if(message->length)
  108. {
  109. bus->dma_send_channel = DMAC_CHANNEL_MAX;
  110. bus->dma_recv_channel = DMAC_CHANNEL_MAX;
  111. rt_completion_init(&bus->dma_completion);
  112. if(message->recv_buf)
  113. {
  114. dmalock_sync_take(&bus->dma_recv_channel, RT_WAITING_FOREVER);
  115. sysctl_dma_select(bus->dma_recv_channel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + bus->spi_instance * 2);
  116. rx_buff = rt_calloc(message->length * 4, 1);
  117. if(!rx_buff)
  118. {
  119. goto transfer_done;
  120. }
  121. }
  122. if(message->send_buf)
  123. {
  124. dmalock_sync_take(&bus->dma_send_channel, RT_WAITING_FOREVER);
  125. sysctl_dma_select(bus->dma_send_channel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + bus->spi_instance * 2);
  126. tx_buff = rt_malloc(message->length * 4);
  127. if(!tx_buff)
  128. {
  129. goto transfer_done;
  130. }
  131. for(i = 0; i < message->length; i++)
  132. {
  133. tx_buff[i] = ((uint8_t *)message->send_buf)[i];
  134. }
  135. }
  136. if(message->send_buf && message->recv_buf)
  137. {
  138. dmac_irq_register(bus->dma_recv_channel, dma_irq_callback, &bus->dma_completion, 1);
  139. __spi_set_tmod(bus->spi_instance, SPI_TMOD_TRANS_RECV);
  140. spi_instance[bus->spi_instance]->dmacr = 0x3;
  141. spi_instance[bus->spi_instance]->ssienr = 0x01;
  142. dmac_set_single_mode(bus->dma_recv_channel, (void *)(&spi_instance[bus->spi_instance]->dr[0]), rx_buff, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT,
  143. DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, message->length);
  144. dmac_set_single_mode(bus->dma_send_channel, tx_buff, (void *)(&spi_instance[bus->spi_instance]->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE,
  145. DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, message->length);
  146. }
  147. else if(message->send_buf)
  148. {
  149. dmac_irq_register(bus->dma_send_channel, dma_irq_callback, &bus->dma_completion, 1);
  150. __spi_set_tmod(bus->spi_instance, SPI_TMOD_TRANS);
  151. spi_instance[bus->spi_instance]->dmacr = 0x2;
  152. spi_instance[bus->spi_instance]->ssienr = 0x01;
  153. dmac_set_single_mode(bus->dma_send_channel, tx_buff, (void *)(&spi_instance[bus->spi_instance]->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE,
  154. DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, message->length);
  155. }
  156. else if(message->recv_buf)
  157. {
  158. dmac_irq_register(bus->dma_recv_channel, dma_irq_callback, &bus->dma_completion, 1);
  159. __spi_set_tmod(bus->spi_instance, SPI_TMOD_RECV);
  160. spi_instance[bus->spi_instance]->ctrlr1 = message->length - 1;
  161. spi_instance[bus->spi_instance]->dmacr = 0x1;
  162. spi_instance[bus->spi_instance]->ssienr = 0x01;
  163. spi_instance[bus->spi_instance]->dr[0] = 0xFF;
  164. dmac_set_single_mode(bus->dma_recv_channel, (void *)(&spi_instance[bus->spi_instance]->dr[0]), rx_buff, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT,
  165. DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, message->length);
  166. }
  167. else
  168. {
  169. goto transfer_done;
  170. }
  171. spi_instance[bus->spi_instance]->ser = 1U << cs->cs_index;
  172. rt_completion_wait(&bus->dma_completion, RT_WAITING_FOREVER);
  173. if(message->recv_buf)
  174. dmac_irq_unregister(bus->dma_recv_channel);
  175. else
  176. dmac_irq_unregister(bus->dma_send_channel);
  177. // wait until all data has been transmitted
  178. while ((spi_instance[bus->spi_instance]->sr & 0x05) != 0x04)
  179. ;
  180. spi_instance[bus->spi_instance]->ser = 0x00;
  181. spi_instance[bus->spi_instance]->ssienr = 0x00;
  182. if(message->recv_buf)
  183. {
  184. for(i = 0; i < message->length; i++)
  185. {
  186. ((uint8_t *)message->recv_buf)[i] = (uint8_t)rx_buff[i];
  187. }
  188. }
  189. transfer_done:
  190. dmalock_release(bus->dma_send_channel);
  191. dmalock_release(bus->dma_recv_channel);
  192. if(tx_buff)
  193. {
  194. rt_free(tx_buff);
  195. }
  196. if(rx_buff)
  197. {
  198. rt_free(rx_buff);
  199. }
  200. }
  201. if(message->cs_release)
  202. {
  203. gpiohs_set_pin(cs->cs_pin, GPIO_PV_HIGH);
  204. }
  205. return message->length;
  206. }
  207. const static struct rt_spi_ops drv_spi_ops =
  208. {
  209. drv_spi_configure,
  210. drv_spi_xfer
  211. };
  212. int rt_hw_spi_init(void)
  213. {
  214. rt_err_t ret = RT_EOK;
  215. #ifdef BSP_USING_SPI1
  216. {
  217. static struct drv_spi_bus spi_bus1;
  218. spi_bus1.spi_instance = SPI_DEVICE_1;
  219. ret = rt_spi_bus_register(&spi_bus1.parent, "spi1", &drv_spi_ops);
  220. #ifdef BSP_SPI1_USING_SS0
  221. {
  222. static struct rt_spi_device spi_device10;
  223. static struct drv_cs cs10 =
  224. {
  225. .cs_index = SPI_CHIP_SELECT_0,
  226. .cs_pin = SPI1_CS0_PIN
  227. };
  228. rt_spi_bus_attach_device(&spi_device10, "spi10", "spi1", (void *)&cs10);
  229. }
  230. #endif
  231. #ifdef BSP_SPI1_USING_SS1
  232. {
  233. static struct rt_spi_device spi_device11;
  234. static struct drv_cs cs11 =
  235. {
  236. .cs_index = SPI_CHIP_SELECT_1,
  237. .cs_pin = SPI1_CS1_PIN
  238. };
  239. rt_spi_bus_attach_device(&spi_device11, "spi11", "spi1", (void *)&cs11);
  240. }
  241. #endif
  242. #ifdef BSP_SPI1_USING_SS2
  243. {
  244. static struct rt_spi_device spi_device12;
  245. static struct drv_cs cs12 =
  246. {
  247. .cs_index = SPI_CHIP_SELECT_2,
  248. .cs_pin = SPI1_CS2_PIN
  249. };
  250. rt_spi_bus_attach_device(&spi_device12, "spi12", "spi1", (void *)&cs12);
  251. }
  252. #endif
  253. #ifdef BSP_SPI1_USING_SS3
  254. {
  255. static struct rt_spi_device spi_device13;
  256. static struct drv_cs cs13 =
  257. {
  258. .cs_index = SPI_CHIP_SELECT_2,
  259. .cs_pin = SPI1_CS2_PIN
  260. };
  261. rt_spi_bus_attach_device(&spi_device13, "spi13", "spi1", (void *)&cs13);
  262. }
  263. #endif
  264. }
  265. #endif
  266. return ret;
  267. }
  268. INIT_DEVICE_EXPORT(rt_hw_spi_init);
  269. #endif