drv_spi.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. * Copyright (c) 2019 Winner Microelectronics Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018-11-12 fanwenl 1st version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include "wm_hostspi.h"
  13. #include "wm_spi_hal.h"
  14. #include "wm_io.h"
  15. #include "wm_gpio_afsel.h"
  16. #include "pin_map.h"
  17. #include "drv_spi.h"
  18. #ifdef BSP_USING_SPI
  19. #define BSP_SPI_MAX_HZ (20* 1000 *1000)
  20. struct wm_sw_spi_cs
  21. {
  22. rt_int16_t pin;
  23. };
  24. struct wm_spi
  25. {
  26. struct rt_spi_configuration *cfg;
  27. };
  28. static rt_err_t wm_hostspi_init(struct rt_spi_configuration *cfg)
  29. {
  30. spi_clear_fifo();
  31. spi_set_endian(1);
  32. if (cfg->data_width == 8)
  33. {
  34. tls_spi_trans_type(SPI_BYTE_TRANSFER);
  35. }
  36. if (cfg->data_width == 16)
  37. {
  38. tls_spi_trans_type(SPI_WORD_TRANSFER);
  39. }
  40. spi_set_mode(cfg->mode);
  41. spi_set_chipselect_mode(SPI_CS_INACTIVE_MODE);
  42. spi_force_cs_out(1);
  43. if(cfg->max_hz > BSP_SPI_MAX_HZ)
  44. {
  45. cfg->max_hz = BSP_SPI_MAX_HZ;
  46. }
  47. spi_set_sclk(cfg->max_hz);
  48. spi_set_tx_trigger_level(0);
  49. spi_set_rx_trigger_level(7);
  50. spi_set_rx_channel(1);
  51. spi_set_tx_channel(1);
  52. return RT_EOK;
  53. }
  54. static rt_err_t spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *cfg)
  55. {
  56. RT_ASSERT(cfg != RT_NULL);
  57. RT_ASSERT(device != RT_NULL);
  58. /*将cfg参数放到device中*/
  59. struct wm_spi *hspi = (struct wm_spi *)device->bus->parent.user_data;
  60. hspi->cfg = cfg;
  61. wm_hostspi_init(cfg);
  62. return RT_EOK;
  63. }
  64. static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
  65. {
  66. RT_ASSERT(device != RT_NULL);
  67. RT_ASSERT(device->bus != RT_NULL);
  68. RT_ASSERT(device->bus->parent.user_data != RT_NULL);
  69. struct wm_sw_spi_cs *cs = device->parent.user_data;
  70. struct tls_spi_transfer tls_transfer;
  71. tls_transfer.tx_buf = message->send_buf;
  72. tls_transfer.rx_buf = message->recv_buf;
  73. tls_transfer.len = message->length;
  74. rt_int32_t length = 0;
  75. rt_int32_t remain_length = message->length;
  76. length = spi_fill_txfifo(&tls_transfer, remain_length);
  77. spi_set_sclk_length(length * 8, 0);
  78. if (message->cs_take)
  79. {
  80. tls_gpio_write((enum tls_io_name)cs->pin, 0);
  81. }
  82. spi_sclk_start();
  83. while (remain_length > 0)
  84. {
  85. while (spi_i2s_get_busy_status() == 1)
  86. ;
  87. length = spi_get_rxfifo(&tls_transfer, remain_length);
  88. remain_length -= length;
  89. if (remain_length == 0)
  90. {
  91. while (spi_i2s_get_busy_status() == 1)
  92. ;
  93. if (message->cs_release)
  94. {
  95. tls_gpio_write((enum tls_io_name)cs->pin, 1);
  96. }
  97. }
  98. while (spi_i2s_get_busy_status() == 1)
  99. ;
  100. length = spi_fill_txfifo(&tls_transfer, remain_length);
  101. if (length)
  102. {
  103. spi_set_sclk_length(length * 8, 0);
  104. spi_sclk_start();
  105. }
  106. }
  107. while (spi_i2s_get_busy_status() == 1)
  108. ;
  109. if (message->cs_release)
  110. {
  111. tls_gpio_write((enum tls_io_name)cs->pin, 1);
  112. }
  113. return message->length - remain_length;
  114. }
  115. rt_err_t wm_spi_bus_attach_device(const char *bus_name, const char *device_name, rt_uint32_t pin)
  116. {
  117. rt_err_t ret;
  118. rt_int16_t gpio_pin;
  119. struct rt_spi_device *spi_device;
  120. struct wm_sw_spi_cs *cs_pin;
  121. gpio_pin = wm_get_pin(pin);
  122. if (gpio_pin == WM_PIN_DEFAULT)
  123. {
  124. return -RT_ERROR;
  125. }
  126. spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
  127. RT_ASSERT(spi_device != RT_NULL);
  128. cs_pin = (struct wm_sw_spi_cs *)rt_malloc(sizeof(struct wm_sw_spi_cs));
  129. RT_ASSERT(cs_pin != RT_NULL);
  130. cs_pin->pin = gpio_pin;
  131. tls_gpio_cfg((enum tls_io_name)gpio_pin, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);
  132. tls_gpio_write((enum tls_io_name)gpio_pin, 1);
  133. ret = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
  134. return ret;
  135. }
  136. static struct rt_spi_ops wm_spi_ops =
  137. {
  138. .configure = spi_configure,
  139. .xfer = spixfer
  140. };
  141. struct wm_spi spi;
  142. struct rt_spi_bus wm_spi_bus;
  143. int wm_hw_spi_bus_init(void)
  144. {
  145. rt_int16_t gpio_pin;
  146. gpio_pin = wm_get_pin(WM_SPI_CK_PIN);
  147. if (gpio_pin >= 0)
  148. {
  149. wm_spi_ck_config((enum tls_io_name)gpio_pin);
  150. }
  151. gpio_pin = wm_get_pin(WM_SPI_DI_PIN);
  152. if (gpio_pin >= 0)
  153. {
  154. wm_spi_di_config((enum tls_io_name)gpio_pin);
  155. }
  156. gpio_pin = wm_get_pin(WM_SPI_DO_PIN);
  157. if (gpio_pin >= 0)
  158. {
  159. wm_spi_do_config((enum tls_io_name)gpio_pin);
  160. }
  161. wm_spi_bus.parent.user_data = &spi;
  162. rt_spi_bus_register(&wm_spi_bus, "spi0", &wm_spi_ops);
  163. return RT_EOK;
  164. }
  165. INIT_PREV_EXPORT(wm_hw_spi_bus_init);
  166. #endif /* BSP_USING_SPI */