hw_spi.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. #include "board.h"
  2. typedef struct
  3. {
  4. unsigned int spi; //SPI对象
  5. int speed; //SPI速度
  6. int data_bits; //数据位
  7. unsigned int mode;
  8. unsigned int endian;
  9. unsigned int clk_port;
  10. int clk_pin;
  11. unsigned int miso_port;
  12. int miso_pin;
  13. unsigned int mosi_port;
  14. int mosi_pin;
  15. int af;
  16. } hw_spi_t;
  17. typedef struct
  18. {
  19. unsigned int spi; //SPI对象
  20. unsigned int cs_port;
  21. int cs_pin;
  22. } hw_spi_device_t;
  23. static hw_spi_t hw_spi_map[HW_SPI_NUMBER] = {
  24. { SPI0, 2000000, 8, SPI_CK_PL_LOW_PH_1EDGE, SPI_ENDIAN_MSB, GPIOA, 5, GPIOA, 6, GPIOA, 7, GPIO_AF_0 }
  25. };
  26. static hw_spi_device_t hw_spi_device_map[HW_SPI_DEVICE_NUMBER] = {
  27. { SPI0, GPIOB, 2 },
  28. { SPI0, GPIOB, 1 },
  29. { SPI0, GPIOB, 0 }
  30. };
  31. #define SPI_DEVICE_TAKE(a) GPIO_BOP(hw_spi_device_map[a].cs_port) = 1 << (hw_spi_device_map[a].cs_pin+16)
  32. #define SPI_DEVICE_UNTAKE(a) GPIO_BOP(hw_spi_device_map[a].cs_port) = 1 << (hw_spi_device_map[a].cs_pin)
  33. /**
  34. * 读写一个字节
  35. *
  36. * @author LXZ (011621)
  37. *
  38. * @param spi
  39. * @param value
  40. *
  41. * @return rt_uint16_t
  42. */
  43. static uint16_t hw_spi_readwrite_byte(unsigned int spi, uint16_t value) {
  44. /* loop while data register in not emplty */
  45. while(RESET == spi_i2s_flag_get(spi,SPI_FLAG_TBE));
  46. /* send half word through the SPI peripheral */
  47. spi_i2s_data_transmit(spi,value);
  48. /* wait to receive a half word */
  49. while(RESET == spi_i2s_flag_get(spi,SPI_FLAG_RBNE));
  50. /* return the half word read from the SPI bus */
  51. return spi_i2s_data_receive(spi);
  52. }
  53. /**
  54. * 读写连续数据
  55. *
  56. * @author LXZ (011621)
  57. *
  58. * @param spi
  59. * @param src
  60. * @param dst
  61. * @param length
  62. *
  63. * @return rt_uint32_t
  64. */
  65. int hw_spi_readwrite(uint8_t port, const uint8_t *cmd, uint8_t *dst, int size) {
  66. int i = 0;
  67. uint8_t temp = 0;
  68. unsigned int spi = hw_spi_device_map[port].spi;
  69. while (i < size) {
  70. /* loop while data register in not emplty */
  71. while(RESET == spi_i2s_flag_get(spi,SPI_FLAG_TBE));
  72. if (cmd != 0) {
  73. temp = cmd[i];
  74. }
  75. else {
  76. temp = 0xff;
  77. }
  78. /* send byte through the SPI peripheral */
  79. spi_i2s_data_transmit(spi,temp);
  80. /* wait to receive a byte */
  81. while(RESET == spi_i2s_flag_get(spi,SPI_FLAG_RBNE));
  82. temp = (uint8_t)spi_i2s_data_receive(spi);
  83. if (dst != 0) {
  84. dst[i] = temp;
  85. }
  86. i++;
  87. }
  88. return size;
  89. }
  90. /**
  91. * 选中设备
  92. *
  93. * @author LXZ (011621)
  94. *
  95. * @param port
  96. */
  97. void hw_spi_device_take(int port) {
  98. SPI_DEVICE_TAKE(port);
  99. }
  100. /**
  101. * 释放设备
  102. *
  103. * @author LXZ (011621)
  104. *
  105. * @param port
  106. */
  107. void hw_spi_device_release(int port) {
  108. SPI_DEVICE_UNTAKE(port);
  109. }
  110. /**
  111. * 硬件SPI初始化
  112. *
  113. * @author LXZ (011621)
  114. *
  115. * @param void
  116. */
  117. void hw_spi_init(void) {
  118. spi_parameter_struct spi_init_struct;
  119. int index = 0;
  120. unsigned int spi;
  121. int clk;
  122. int apb;
  123. unsigned long port;
  124. int pin;
  125. int af;
  126. int frame_size;
  127. while (index < HW_SPI_DEVICE_NUMBER) {
  128. port = (uint32_t)hw_spi_device_map[index].cs_port;
  129. pin = 1 << hw_spi_device_map[index].cs_pin;
  130. if (port != 0) {
  131. //使能时钟
  132. rcu_periph_clock_enable(rcu_periph_clock_bit(port));
  133. //配置IO为输出
  134. gpio_mode_set(port, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, pin);
  135. gpio_output_options_set(port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, pin);
  136. }
  137. GPIO_BOP(hw_spi_device_map[index].cs_port) = 1 << (hw_spi_device_map[index].cs_pin);
  138. index++;
  139. }
  140. index = 0;
  141. while (index < HW_SPI_NUMBER) {
  142. //CLK
  143. port = (uint32_t)hw_spi_map[index].clk_port;
  144. pin = 1 << hw_spi_map[index].clk_pin;
  145. af = hw_spi_map[index].af;
  146. if (port != 0) {
  147. //使能时钟
  148. rcu_periph_clock_enable(rcu_periph_clock_bit(port));
  149. //配置IO为AF
  150. gpio_mode_set(port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, pin);
  151. gpio_output_options_set(port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, pin);
  152. gpio_af_set(port, af, pin);
  153. }
  154. //MISO
  155. port = (uint32_t)hw_spi_map[index].miso_port;
  156. pin = 1 << hw_spi_map[index].miso_pin;
  157. if (port != 0) {
  158. //使能时钟
  159. rcu_periph_clock_enable(rcu_periph_clock_bit(port));
  160. //配置IO为AF
  161. gpio_mode_set(port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, pin);
  162. gpio_output_options_set(port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, pin);
  163. gpio_af_set(port, af, pin);
  164. }
  165. //MOSI
  166. port = (uint32_t)hw_spi_map[index].mosi_port;
  167. pin = 1 << hw_spi_map[index].mosi_pin;
  168. if (port != 0) {
  169. //使能时钟
  170. rcu_periph_clock_enable(rcu_periph_clock_bit(port));
  171. //配置IO为AF
  172. gpio_mode_set(port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, pin);
  173. gpio_output_options_set(port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, pin);
  174. gpio_af_set(port, af, pin);
  175. }
  176. //SPI外设时钟
  177. spi = hw_spi_map[index].spi;
  178. rcu_periph_clock_enable(rcu_periph_clock_bit(spi));
  179. //数据帧长度
  180. if(hw_spi_map[index].data_bits==16)
  181. {
  182. frame_size =SPI_FRAMESIZE_16BIT;
  183. }
  184. else
  185. {
  186. frame_size =SPI_FRAMESIZE_8BIT;
  187. }
  188. //SPI速度
  189. clk = HW_BOART_CORE_FREQ*1000000;
  190. if (hw_spi_map[index].speed >= clk / 2) {
  191. apb = SPI_PSC_2;
  192. }
  193. else if (hw_spi_map[index].speed >= clk / 4) {
  194. apb = SPI_PSC_4;
  195. }
  196. else if (hw_spi_map[index].speed >= clk / 8) {
  197. apb = SPI_PSC_8;
  198. }
  199. else if (hw_spi_map[index].speed >= clk / 16) {
  200. apb = SPI_PSC_16;
  201. }
  202. else if (hw_spi_map[index].speed >= clk / 32) {
  203. apb = SPI_PSC_32;
  204. }
  205. else if (hw_spi_map[index].speed >= clk / 64) {
  206. apb = SPI_PSC_64;
  207. }
  208. else if (hw_spi_map[index].speed >= clk / 128) {
  209. apb = SPI_PSC_128;
  210. }
  211. else {
  212. /* min prescaler 256 */
  213. apb = SPI_PSC_256;
  214. }
  215. spi_i2s_deinit(spi);
  216. spi_struct_para_init(&spi_init_struct);
  217. /* SPI0 parameter config */
  218. spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
  219. spi_init_struct.device_mode = SPI_MASTER;
  220. spi_init_struct.frame_size = frame_size;
  221. spi_init_struct.clock_polarity_phase = hw_spi_map[index].mode;
  222. spi_init_struct.nss = SPI_NSS_SOFT;
  223. spi_init_struct.prescale = SPI_PSC_256;
  224. spi_init_struct.endian = hw_spi_map[index].endian;
  225. spi_init(spi, &spi_init_struct);
  226. /* enable SPI0 */
  227. spi_enable(spi);
  228. hw_spi_readwrite_byte(spi, 0xff);
  229. index++;
  230. }
  231. }