drv_spi.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /*
  2. * Copyright (c) 2006-2018, 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 <dmac.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. };
  30. struct drv_cs
  31. {
  32. int cs_index;
  33. int cs_pin;
  34. };
  35. static volatile spi_t *const spi_instance[4] =
  36. {
  37. (volatile spi_t *)SPI0_BASE_ADDR,
  38. (volatile spi_t *)SPI1_BASE_ADDR,
  39. (volatile spi_t *)SPI_SLAVE_BASE_ADDR,
  40. (volatile spi_t *)SPI3_BASE_ADDR
  41. };
  42. static rt_err_t drv_spi_configure(struct rt_spi_device *device,
  43. struct rt_spi_configuration *configuration)
  44. {
  45. rt_err_t ret = RT_EOK;
  46. int freq = 0;
  47. struct drv_spi_bus *bus = DRV_SPI_DEVICE(device->bus);
  48. struct drv_cs * cs = (struct drv_cs *)device->parent.user_data;
  49. RT_ASSERT(bus != RT_NULL);
  50. gpiohs_set_drive_mode(cs->cs_pin, GPIO_DM_OUTPUT);
  51. gpiohs_set_pin(cs->cs_pin, GPIO_PV_HIGH);
  52. #ifdef BSP_USING_SPI1_AS_QSPI
  53. /* Todo:QSPI*/
  54. #else
  55. spi_init(bus->spi_instance, configuration->mode & RT_SPI_MODE_3, SPI_FF_STANDARD, configuration->data_width, 0);
  56. #endif
  57. freq = spi_set_clk_rate(bus->spi_instance, configuration->max_hz > MAX_CLOCK ? MAX_CLOCK : configuration->max_hz);
  58. rt_kprintf("set spi freq %d\n", freq);
  59. return ret;
  60. }
  61. void __spi_set_tmod(uint8_t spi_num, uint32_t tmod)
  62. {
  63. RT_ASSERT(spi_num < SPI_DEVICE_MAX);
  64. volatile spi_t *spi_handle = spi[spi_num];
  65. uint8_t tmod_offset = 0;
  66. switch(spi_num)
  67. {
  68. case 0:
  69. case 1:
  70. case 2:
  71. tmod_offset = 8;
  72. break;
  73. case 3:
  74. default:
  75. tmod_offset = 10;
  76. break;
  77. }
  78. set_bit(&spi_handle->ctrlr0, 3 << tmod_offset, tmod << tmod_offset);
  79. }
  80. static rt_uint32_t drv_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
  81. {
  82. struct drv_spi_bus *bus = DRV_SPI_DEVICE(device->bus);
  83. struct drv_cs * cs = (struct drv_cs *)device->parent.user_data;
  84. struct rt_spi_configuration *cfg = &device->config;
  85. uint32_t * tx_buff = RT_NULL;
  86. uint32_t * rx_buff = RT_NULL;
  87. int i;
  88. rt_ubase_t dummy = 0xFFFFFFFFU;
  89. __spi_set_tmod(bus->spi_instance, SPI_TMOD_TRANS_RECV);
  90. RT_ASSERT(bus != RT_NULL);
  91. if(message->cs_take)
  92. {
  93. gpiohs_set_pin(cs->cs_pin, GPIO_PV_LOW);
  94. }
  95. if(message->length)
  96. {
  97. spi_instance[bus->spi_instance]->dmacr = 0x3;
  98. spi_instance[bus->spi_instance]->ssienr = 0x01;
  99. sysctl_dma_select(bus->dma_send_channel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + bus->spi_instance * 2);
  100. sysctl_dma_select(bus->dma_recv_channel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + bus->spi_instance * 2);
  101. if(!message->recv_buf)
  102. {
  103. dmac_set_single_mode(bus->dma_recv_channel, (void *)(&spi_instance[bus->spi_instance]->dr[0]), &dummy, DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE,
  104. DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, message->length);
  105. }
  106. else
  107. {
  108. rx_buff = rt_calloc(message->length * 4, 1);
  109. if(!rx_buff)
  110. {
  111. goto transfer_done;
  112. }
  113. dmac_set_single_mode(bus->dma_recv_channel, (void *)(&spi_instance[bus->spi_instance]->dr[0]), rx_buff, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT,
  114. DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, message->length);
  115. }
  116. if(!message->send_buf)
  117. {
  118. dmac_set_single_mode(bus->dma_send_channel, &dummy, (void *)(&spi_instance[bus->spi_instance]->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE,
  119. DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, message->length);
  120. }
  121. else
  122. {
  123. tx_buff = rt_malloc(message->length * 4);
  124. if(!tx_buff)
  125. {
  126. goto transfer_done;
  127. }
  128. for(i = 0; i < message->length; i++)
  129. {
  130. tx_buff[i] = ((uint8_t *)message->send_buf)[i];
  131. }
  132. dmac_set_single_mode(bus->dma_send_channel, tx_buff, (void *)(&spi_instance[bus->spi_instance]->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE,
  133. DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, message->length);
  134. }
  135. spi_instance[bus->spi_instance]->ser = 1U << cs->cs_index;
  136. dmac_wait_done(bus->dma_send_channel);
  137. dmac_wait_done(bus->dma_recv_channel);
  138. spi_instance[bus->spi_instance]->ser = 0x00;
  139. spi_instance[bus->spi_instance]->ssienr = 0x00;
  140. if(message->recv_buf)
  141. {
  142. for(i = 0; i < message->length; i++)
  143. {
  144. ((uint8_t *)message->recv_buf)[i] = (uint8_t)rx_buff[i];
  145. }
  146. }
  147. transfer_done:
  148. if(tx_buff)
  149. {
  150. rt_free(tx_buff);
  151. }
  152. if(rx_buff)
  153. {
  154. rt_free(rx_buff);
  155. }
  156. }
  157. if(message->cs_release)
  158. {
  159. gpiohs_set_pin(cs->cs_pin, GPIO_PV_HIGH);
  160. }
  161. return message->length;
  162. }
  163. const static struct rt_spi_ops drv_spi_ops =
  164. {
  165. drv_spi_configure,
  166. drv_spi_xfer
  167. };
  168. int rt_hw_spi_init(void)
  169. {
  170. rt_err_t ret = RT_EOK;
  171. #ifdef BSP_USING_SPI1
  172. {
  173. static struct drv_spi_bus spi_bus1;
  174. spi_bus1.spi_instance = SPI_DEVICE_1;
  175. spi_bus1.dma_send_channel = DMAC_CHANNEL1;
  176. spi_bus1.dma_recv_channel = DMAC_CHANNEL2;
  177. ret = rt_spi_bus_register(&spi_bus1.parent, "spi1", &drv_spi_ops);
  178. #ifdef BSP_SPI1_USING_SS0
  179. {
  180. static struct rt_spi_device spi_device10;
  181. static struct drv_cs cs10 =
  182. {
  183. .cs_index = SPI_CHIP_SELECT_0,
  184. .cs_pin = SPI1_CS0_PIN
  185. };
  186. rt_spi_bus_attach_device(&spi_device10, "spi10", "spi1", (void *)&cs10);
  187. }
  188. #endif
  189. #ifdef BSP_SPI1_USING_SS1
  190. {
  191. static struct rt_spi_device spi_device11;
  192. static struct drv_cs cs11 =
  193. {
  194. .cs_index = SPI_CHIP_SELECT_1,
  195. .cs_pin = SPI1_CS1_PIN
  196. };
  197. rt_spi_bus_attach_device(&spi_device11, "spi11", "spi1", (void *)&cs11);
  198. }
  199. #endif
  200. #ifdef BSP_SPI1_USING_SS2
  201. {
  202. static struct rt_spi_device spi_device12;
  203. static struct drv_cs cs12 =
  204. {
  205. .cs_index = SPI_CHIP_SELECT_2,
  206. .cs_pin = SPI1_CS2_PIN
  207. };
  208. rt_spi_bus_attach_device(&spi_device12, "spi12", "spi1", (void *)&cs12);
  209. }
  210. #endif
  211. #ifdef BSP_SPI1_USING_SS3
  212. {
  213. static struct rt_spi_device spi_device13;
  214. static struct drv_cs cs13 =
  215. {
  216. .cs_index = SPI_CHIP_SELECT_2,
  217. .cs_pin = SPI1_CS2_PIN
  218. };
  219. rt_spi_bus_attach_device(&spi_device13, "spi13", "spi1", (void *)&cs13);
  220. }
  221. #endif
  222. }
  223. #endif
  224. return ret;
  225. }
  226. INIT_DEVICE_EXPORT(rt_hw_spi_init);
  227. #endif