drv_spi.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2017-06-05 tanek first implementation.
  9. * 2018-04-19 misonyo Porting for v85xxf30x
  10. * 2019-03-31 xuzhuoyi Porting for v85xxe230
  11. * 2021-09-21 zhuxw Porting for v85xx
  12. */
  13. #include "drv_spi.h"
  14. #include "board.h"
  15. #include <rtthread.h>
  16. #if defined(RT_USING_SPI) && defined(RT_USING_PIN)
  17. #include <rtdevice.h>
  18. #if !defined(RT_USING_SPI1) && !defined(RT_USING_SPI2)
  19. #error "Please define at least one SPIx"
  20. #endif
  21. /* private rt-thread spi ops function */
  22. static rt_err_t configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration);
  23. static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message);
  24. static struct rt_spi_ops v85xx_spi_ops =
  25. {
  26. configure,
  27. xfer
  28. };
  29. static rt_err_t configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration)
  30. {
  31. SPI_InitType spi_init_struct;
  32. rt_uint32_t spi_periph = (rt_uint32_t)device->bus->parent.user_data;
  33. RT_ASSERT(device != RT_NULL);
  34. RT_ASSERT(configuration != RT_NULL);
  35. if(configuration->data_width > 8)
  36. {
  37. return RT_EIO;
  38. }
  39. {
  40. rt_uint32_t spi_apb_clock;
  41. rt_uint32_t max_hz;
  42. max_hz = configuration->max_hz;
  43. spi_apb_clock = CLK_GetPCLKFreq();
  44. if(max_hz >= spi_apb_clock/2)
  45. {
  46. spi_init_struct.ClockDivision = SPI_CLKDIV_2;
  47. }
  48. else if (max_hz >= spi_apb_clock/4)
  49. {
  50. spi_init_struct.ClockDivision = SPI_CLKDIV_4;
  51. }
  52. else if (max_hz >= spi_apb_clock/8)
  53. {
  54. spi_init_struct.ClockDivision = SPI_CLKDIV_8;
  55. }
  56. else if (max_hz >= spi_apb_clock/16)
  57. {
  58. spi_init_struct.ClockDivision = SPI_CLKDIV_16;
  59. }
  60. else if (max_hz >= spi_apb_clock/32)
  61. {
  62. spi_init_struct.ClockDivision = SPI_CLKDIV_32;
  63. }
  64. else if (max_hz >= spi_apb_clock/64)
  65. {
  66. spi_init_struct.ClockDivision = SPI_CLKDIV_64;
  67. }
  68. else
  69. {
  70. /* min prescaler 128 */
  71. spi_init_struct.ClockDivision = SPI_CLKDIV_128;
  72. }
  73. } /* baudrate */
  74. switch(configuration->mode & RT_SPI_MODE_3)
  75. {
  76. case RT_SPI_MODE_0:
  77. spi_init_struct.SPH = SPI_SPH_0;
  78. spi_init_struct.SPO = SPI_SPO_0;
  79. break;
  80. case RT_SPI_MODE_1:
  81. spi_init_struct.SPH = SPI_SPH_1;
  82. spi_init_struct.SPO = SPI_SPO_0;
  83. break;
  84. case RT_SPI_MODE_2:
  85. spi_init_struct.SPH = SPI_SPH_0;
  86. spi_init_struct.SPO = SPI_SPO_1;
  87. break;
  88. case RT_SPI_MODE_3:
  89. spi_init_struct.SPH = SPI_SPH_1;
  90. spi_init_struct.SPO = SPI_SPO_1;
  91. break;
  92. }
  93. if(!(configuration->mode & RT_SPI_MSB))
  94. {
  95. return RT_EIO;
  96. }
  97. spi_init_struct.Mode = SPI_MODE_MASTER;
  98. spi_init_struct.CSNSoft = SPI_CSNSOFT_ENABLE;
  99. SPI_Init((SPI_TypeDef*)spi_periph, &spi_init_struct);
  100. SPI_Cmd((SPI_TypeDef*)spi_periph, ENABLE);
  101. return RT_EOK;
  102. };
  103. static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message)
  104. {
  105. rt_base_t v85xx_cs_pin = (rt_base_t)device->parent.user_data;
  106. rt_uint32_t spi_periph = (rt_uint32_t)device->bus->parent.user_data;
  107. struct rt_spi_configuration * config = &device->config;
  108. RT_ASSERT(device != RT_NULL);
  109. RT_ASSERT(message != RT_NULL);
  110. /* take CS */
  111. if(message->cs_take)
  112. {
  113. rt_pin_write(v85xx_cs_pin, PIN_LOW);
  114. DEBUG_PRINTF("spi take cs\n");
  115. }
  116. {
  117. if(config->data_width <= 8)
  118. {
  119. const rt_uint8_t * send_ptr = message->send_buf;
  120. rt_uint8_t * recv_ptr = message->recv_buf;
  121. rt_uint32_t size = message->length;
  122. DEBUG_PRINTF("spi poll transfer start: %d\n", size);
  123. while(size--)
  124. {
  125. rt_uint8_t data = 0xFF;
  126. if(send_ptr != RT_NULL)
  127. {
  128. data = *send_ptr++;
  129. }
  130. //Wait until the transmit buffer is empty
  131. while(RESET == SPI_GetStatus((SPI_TypeDef*)spi_periph, SPI_STS_TXEMPTY));
  132. // Send the byte
  133. SPI_SendData((SPI_TypeDef*)spi_periph, data);
  134. //Wait until a data is received
  135. while(RESET == SPI_GetStatus((SPI_TypeDef*)spi_periph, SPI_STS_RNE));
  136. // Get the received data
  137. data = SPI_ReceiveData((SPI_TypeDef*)spi_periph);
  138. if(recv_ptr != RT_NULL)
  139. {
  140. *recv_ptr++ = data;
  141. }
  142. }
  143. DEBUG_PRINTF("spi poll transfer finsh\n");
  144. }
  145. }
  146. /* release CS */
  147. if(message->cs_release)
  148. {
  149. rt_pin_write(v85xx_cs_pin, PIN_HIGH);
  150. DEBUG_PRINTF("spi release cs\n");
  151. }
  152. return message->length;
  153. };
  154. int v85xx_hw_spi_init(void)
  155. {
  156. int result = 0;
  157. #ifdef RT_USING_SPI1
  158. static struct rt_spi_bus spi_bus0;
  159. spi_bus0.parent.user_data = (void *)SPI1;
  160. result = rt_spi_bus_register(&spi_bus0, "spi1", &v85xx_spi_ops);
  161. #endif
  162. #ifdef RT_USING_SPI2
  163. static struct rt_spi_bus spi_bus1;
  164. spi_bus1.parent.user_data = (void *)SPI2;
  165. result = rt_spi_bus_register(&spi_bus1, "spi2", &v85xx_spi_ops);
  166. #endif
  167. return result;
  168. }
  169. INIT_BOARD_EXPORT(v85xx_hw_spi_init);
  170. #endif