drv_spi.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /*
  2. * Copyright (c) 2006-2024 RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024-10-08 wumingzi first implementation
  9. * 2024-10-08 wumingzi add custom configuration and support muti spi obj
  10. */
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #include <time.h>
  14. #include "rtdef.h"
  15. #include "rttypes.h"
  16. #include "sdkconfig.h"
  17. #include "hal/spi_hal.h" /*bsp/ESP32_C3/packages/ESP-IDF-latest/components/hal/include/hal/spi_types.h*/
  18. #include "driver/gpio.h" /*bsp/ESP32_C3/packages/ESP-IDF-latest/components/driver/include/driver/gpio.h*/
  19. #include "driver/spi_master.h"
  20. #include "drv_spi.h"
  21. #include "drivers/dev_spi.h"
  22. #ifdef RT_USING_SPI
  23. #ifdef BSP_USING_SPI2
  24. #define LOG_TAG "drv.spi"
  25. #include <rtdbg.h>
  26. static struct rt_spi_bus spi_bus2;
  27. static spi_device_handle_t spi;
  28. static spi_bus_config_t buscfg;
  29. static struct esp32_spi spi_bus_obj[] = {
  30. #ifdef BSP_USING_SPI2
  31. {
  32. .bus_name = "spi2",
  33. .spi_bus = &spi_bus2,
  34. .esp32_spi_bus_cfg = &buscfg,
  35. },
  36. #endif /* BSP_USING_SPI2 */
  37. };
  38. /* private rt-thread spi ops function */
  39. static rt_err_t spi_configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration);
  40. static rt_ssize_t spixfer(struct rt_spi_device* device, struct rt_spi_message* message);
  41. static struct rt_spi_ops esp32_spi_ops =
  42. {
  43. .configure = spi_configure,
  44. .xfer = spixfer,
  45. };
  46. /**
  47. * @brief SPI Initialization
  48. * @param esp32_spi: SPI BUS
  49. * @retval None
  50. */
  51. static void esp32_spi_init(struct esp32_spi *esp32_spi)
  52. {
  53. spi_configure(NULL,NULL);
  54. }
  55. static rt_err_t spi_configure(struct rt_spi_device* device,
  56. struct rt_spi_configuration* configuration)
  57. {
  58. static spi_bus_config_t buscfg =
  59. {
  60. .miso_io_num=SPI2_IOMUX_PIN_NUM_MISO, /*MISO*/
  61. .mosi_io_num=SPI2_IOMUX_PIN_NUM_MOSI, /*MOSI*/
  62. .sclk_io_num=SPI2_IOMUX_PIN_NUM_CLK, /*CLK*/
  63. .quadwp_io_num=-1, /*不使用*/
  64. .quadhd_io_num=-1, /*不使用*/
  65. .max_transfer_sz=4092 /*最大传送数据长度*/
  66. };
  67. esp_err_t err = spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO);
  68. ESP_ERROR_CHECK(err);
  69. static spi_device_interface_config_t devcfg;
  70. if(configuration->data_width == 8)
  71. {
  72. size_t length; /*/< Total data length, in bits*/
  73. size_t rxlength; /*/< Total data length received, should be not greater than ``length`` in full-duplex mode (0 defaults this to the value of ``length``)*/
  74. }
  75. LOG_W("configuration->max_hz = %d \n",configuration->max_hz);
  76. if(configuration->max_hz >= SPI_MASTER_FREQ_80M)
  77. {
  78. devcfg.clock_speed_hz = SPI_MASTER_FREQ_80M; /*/< 80MHz*/
  79. }
  80. else if(configuration->max_hz >= SPI_MASTER_FREQ_40M)
  81. {
  82. devcfg.clock_speed_hz = SPI_MASTER_FREQ_40M; /*/< 40MHz*/
  83. }
  84. else if(configuration->max_hz >= SPI_MASTER_FREQ_26M)
  85. {
  86. devcfg.clock_speed_hz = SPI_MASTER_FREQ_26M; /*/< 26.67MHz*/
  87. }
  88. else if(configuration->max_hz >= SPI_MASTER_FREQ_20M)
  89. {
  90. devcfg.clock_speed_hz = SPI_MASTER_FREQ_20M; /*/< 20MHz*/
  91. }
  92. else if(configuration->max_hz >= SPI_MASTER_FREQ_16M)
  93. {
  94. devcfg.clock_speed_hz = SPI_MASTER_FREQ_16M; /*/< 16MHz*/
  95. }
  96. else if(configuration->max_hz >= SPI_MASTER_FREQ_13M)
  97. {
  98. devcfg.clock_speed_hz = SPI_MASTER_FREQ_13M; /*/< 13.33MHz*/
  99. }
  100. else if(configuration->max_hz >= SPI_MASTER_FREQ_11M)
  101. {
  102. devcfg.clock_speed_hz = SPI_MASTER_FREQ_11M; /*/< 11.43MHz*/
  103. }
  104. else if(configuration->max_hz >= SPI_MASTER_FREQ_10M)
  105. {
  106. devcfg.clock_speed_hz = SPI_MASTER_FREQ_10M; /*/< 10MHz*/
  107. }
  108. else if(configuration->max_hz >= SPI_MASTER_FREQ_9M)
  109. {
  110. devcfg.clock_speed_hz = SPI_MASTER_FREQ_9M ; /*/< 8.89MHz*/
  111. }
  112. else
  113. {
  114. devcfg.clock_speed_hz = SPI_MASTER_FREQ_8M ;
  115. }
  116. switch (configuration->mode)
  117. {
  118. case RT_SPI_MODE_0: /*!< CPOL = 0, CPHA = 0 */
  119. devcfg.mode = 0;
  120. case RT_SPI_MODE_1: /*!< CPOL = 0, CPHA = 1 */
  121. devcfg.mode = 1;
  122. case RT_SPI_MODE_2: /*!< CPOL = 1, CPHA = 0 */
  123. devcfg.mode = 2;
  124. case RT_SPI_MODE_3: /*!< CPOL = 1, CPHA = 1 */
  125. devcfg.mode = 3;
  126. default:
  127. devcfg.mode = 0;
  128. }
  129. /* todo: support changing cs_pin,queue_size or specifing spi_device_interface_config_t and
  130. * spi_transaction_t by resever data.Meanwhile finish the initialization of interrupt
  131. * callback function and dma.
  132. */
  133. devcfg.spics_io_num = RT_BSP_SPI_CS_PIN;
  134. devcfg.queue_size = 7;
  135. err = spi_bus_add_device(SPI2_HOST, &devcfg, &spi);
  136. ESP_ERROR_CHECK(err);
  137. /* Although there is only one spi bus object, it will be a template for other bsps of ESP32 series */
  138. for(int i = 0; i < sizeof(spi_bus_obj)/sizeof(spi_bus_obj[0]); i++)
  139. {
  140. spi_bus_obj[i].bus_name = "spi2";
  141. spi_bus_obj[i].spi_bus = &spi_bus2;
  142. spi_bus_obj[i].esp32_spi_bus_cfg = &buscfg;
  143. }
  144. return RT_EOK;
  145. };
  146. static rt_ssize_t spixfer(struct rt_spi_device* device, struct rt_spi_message* message)
  147. {
  148. RT_ASSERT(device != NULL);
  149. RT_ASSERT(message != NULL);
  150. static spi_transaction_t trans;
  151. trans.tx_buffer = message->send_buf;
  152. trans.rx_buffer = message->recv_buf;
  153. trans.length = (message->length)*8;
  154. trans.rxlength = (message->length)*8;
  155. spi_device_acquire_bus(spi, portMAX_DELAY);
  156. esp_err_t err = spi_device_polling_transmit(spi, &trans);
  157. spi_device_release_bus(spi);
  158. ESP_ERROR_CHECK(err);
  159. return RT_EOK;
  160. };
  161. /**
  162. * Attach the spi device to SPI bus, this function must be used after initialization.
  163. */
  164. rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin)
  165. {
  166. RT_ASSERT(bus_name != RT_NULL);
  167. RT_ASSERT(device_name != RT_NULL);
  168. rt_err_t result;rt_device_t busp = RT_NULL;
  169. struct rt_spi_device *spi_device;
  170. /* attach the device to spi bus*/
  171. spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
  172. RT_ASSERT(spi_device != RT_NULL);
  173. result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
  174. if (result != RT_EOK)
  175. {
  176. LOG_E("%s attach to %s faild, %d\n", device_name, bus_name, result);
  177. }
  178. RT_ASSERT(result == RT_EOK);
  179. LOG_D("%s attach to %s done", device_name, bus_name);
  180. return result;
  181. }
  182. int rt_hw_spi_init(void)
  183. {
  184. int result = 0;
  185. for(int i = 0; i < sizeof(spi_bus_obj)/sizeof(spi_bus_obj[0]); i++)
  186. {
  187. spi_bus_obj[i].spi_bus->parent.user_data = (void *)&spi_bus_obj[i];
  188. result = rt_spi_bus_register(spi_bus_obj[i].spi_bus, spi_bus_obj[i].bus_name, &esp32_spi_ops);
  189. RT_ASSERT(result == RT_EOK);
  190. LOG_D("%s bus init done", spi_bus_obj[i].bus_name);
  191. }
  192. return result;
  193. }
  194. INIT_BOARD_EXPORT(rt_hw_spi_init);
  195. #endif /* BSP_USING_SPI0 || BSP_USING_SPI1 || BSP_USING_SPI2 || BSP_USING_SPI3 || BSP_USING_SPI4*/
  196. #endif /* RT_USING_SPI */