drv_spi.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  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. #define DRV_SPI_DEVICE(spi_bus) (struct drv_spi_bus *)(spi_bus)
  21. struct drv_spi_bus
  22. {
  23. struct rt_spi_bus parent;
  24. spi_device_num_t spi_instance;
  25. dmac_channel_number_t dma_send_channel;
  26. dmac_channel_number_t dma_recv_channel;
  27. };
  28. struct drv_cs
  29. {
  30. int cs_index;
  31. int cs_pin;
  32. };
  33. static volatile spi_t *const spi_instance[4] =
  34. {
  35. (volatile spi_t *)SPI0_BASE_ADDR,
  36. (volatile spi_t *)SPI1_BASE_ADDR,
  37. (volatile spi_t *)SPI_SLAVE_BASE_ADDR,
  38. (volatile spi_t *)SPI3_BASE_ADDR
  39. };
  40. static rt_err_t drv_spi_configure(struct rt_spi_device *device,
  41. struct rt_spi_configuration *configuration)
  42. {
  43. rt_err_t ret = RT_EOK;
  44. struct drv_spi_bus *bus = DRV_SPI_DEVICE(device->bus);
  45. struct drv_cs * cs = (struct drv_cs *)device->parent.user_data;
  46. RT_ASSERT(bus != RT_NULL);
  47. gpiohs_set_drive_mode(cs->cs_pin, GPIO_DM_OUTPUT);
  48. gpiohs_set_pin(cs->cs_pin, GPIO_PV_HIGH);
  49. #ifdef BSP_USING_SPI1_AS_QSPI
  50. /* Todo:QSPI*/
  51. #else
  52. spi_init(bus->spi_instance, configuration->mode & RT_SPI_MODE_3, SPI_FF_STANDARD, configuration->data_width, 0);
  53. #endif
  54. spi_set_clk_rate(bus->spi_instance, configuration->max_hz);
  55. return ret;
  56. }
  57. extern void spi_receive_data_normal_dma(dmac_channel_number_t dma_send_channel_num,
  58. dmac_channel_number_t dma_receive_channel_num,
  59. spi_device_num_t spi_num, spi_chip_select_t chip_select, const void *cmd_buff,
  60. size_t cmd_len, void *rx_buff, size_t rx_len);
  61. static rt_uint32_t drv_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
  62. {
  63. struct drv_spi_bus *bus = DRV_SPI_DEVICE(device->bus);
  64. struct drv_cs * cs = (struct drv_cs *)device->parent.user_data;
  65. struct rt_spi_configuration *cfg = &device->config;
  66. const uint8_t * tx_buff = message->send_buf;
  67. uint8_t * rx_buff = message->recv_buf;
  68. uint32_t dummy[1024];
  69. size_t send_size, recv_size;
  70. send_size = message->length;
  71. recv_size = message->length;
  72. RT_ASSERT(bus != RT_NULL);
  73. if(message->cs_take)
  74. {
  75. gpiohs_set_pin(cs->cs_pin, GPIO_PV_LOW);
  76. }
  77. if(message->length)
  78. {
  79. if(!tx_buff)
  80. {
  81. tx_buff = (uint8_t *)&dummy;
  82. send_size = 1;
  83. }
  84. if(!rx_buff)
  85. {
  86. rx_buff = (uint8_t *)&dummy;
  87. recv_size = 1;
  88. }
  89. spi_dup_send_receive_data_dma(bus->dma_send_channel, bus->dma_recv_channel, bus->spi_instance, cs->cs_index, tx_buff, send_size, rx_buff, recv_size);
  90. }
  91. if(message->cs_release)
  92. {
  93. gpiohs_set_pin(cs->cs_pin, GPIO_PV_HIGH);
  94. }
  95. return message->length;
  96. }
  97. const static struct rt_spi_ops drv_spi_ops =
  98. {
  99. drv_spi_configure,
  100. drv_spi_xfer
  101. };
  102. int rt_hw_spi_init(void)
  103. {
  104. rt_err_t ret = RT_EOK;
  105. #ifdef BSP_USING_SPI1
  106. {
  107. static struct drv_spi_bus spi_bus1;
  108. spi_bus1.spi_instance = SPI_DEVICE_1;
  109. spi_bus1.dma_send_channel = DMAC_CHANNEL1;
  110. spi_bus1.dma_recv_channel = DMAC_CHANNEL2;
  111. ret = rt_spi_bus_register(&spi_bus1.parent, "spi1", &drv_spi_ops);
  112. #ifdef BSP_SPI1_USING_SS0
  113. {
  114. static struct rt_spi_device spi_device10;
  115. static struct drv_cs cs10 =
  116. {
  117. .cs_index = SPI_CHIP_SELECT_0,
  118. .cs_pin = SPI1_CS0_PIN
  119. };
  120. rt_spi_bus_attach_device(&spi_device10, "spi10", "spi1", (void *)&cs10);
  121. }
  122. #endif
  123. #ifdef BSP_SPI1_USING_SS1
  124. {
  125. static struct rt_spi_device spi_device11;
  126. static struct drv_cs cs11 =
  127. {
  128. .cs_index = SPI_CHIP_SELECT_1,
  129. .cs_pin = SPI1_CS1_PIN
  130. };
  131. rt_spi_bus_attach_device(&spi_device11, "spi11", "spi1", (void *)&cs11);
  132. }
  133. #endif
  134. #ifdef BSP_SPI1_USING_SS2
  135. {
  136. static struct rt_spi_device spi_device12;
  137. static struct drv_cs cs12 =
  138. {
  139. .cs_index = SPI_CHIP_SELECT_2,
  140. .cs_pin = SPI1_CS2_PIN
  141. };
  142. rt_spi_bus_attach_device(&spi_device12, "spi12", "spi1", (void *)&cs12);
  143. }
  144. #endif
  145. #ifdef BSP_SPI1_USING_SS3
  146. {
  147. static struct rt_spi_device spi_device13;
  148. static struct drv_cs cs13 =
  149. {
  150. .cs_index = SPI_CHIP_SELECT_2,
  151. .cs_pin = SPI1_CS2_PIN
  152. };
  153. rt_spi_bus_attach_device(&spi_device13, "spi13", "spi1", (void *)&cs13);
  154. }
  155. #endif
  156. }
  157. #endif
  158. return ret;
  159. }
  160. INIT_DEVICE_EXPORT(rt_hw_spi_init);
  161. #endif