CH57x_spi0.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /********************************** (C) COPYRIGHT *******************************
  2. * File Name : CH57x_SPI0.c
  3. * Author : WCH
  4. * Version : V1.0
  5. * Date : 2018/12/15
  6. * Description
  7. *******************************************************************************/
  8. #include "CH57x_common.h"
  9. /*******************************************************************************
  10. * Function Name : SPI0_MasterDefInit
  11. * Description : 主机模式默认初始化:模式0+3线全双工+8MHz
  12. * Input : None
  13. * Return : None
  14. *******************************************************************************/
  15. void SPI0_MasterDefInit( void )
  16. {
  17. R8_SPI0_CLOCK_DIV = 4; // 主频时钟4分频
  18. R8_SPI0_CTRL_MOD = RB_SPI_ALL_CLEAR;
  19. R8_SPI0_CTRL_MOD = RB_SPI_MOSI_OE | RB_SPI_SCK_OE ;
  20. R8_SPI0_CTRL_CFG |= RB_SPI_AUTO_IF; // 访问BUFFER/FIFO自动清除IF_BYTE_END标志
  21. R8_SPI0_CTRL_CFG &= ~RB_SPI_DMA_ENABLE; // 不启动DMA方式
  22. }
  23. /*******************************************************************************
  24. * Function Name : SPI0_CLKCfg
  25. * Description : SPI0 基准时钟配置,= d*Tsys
  26. * Input : c: 时钟分频系数
  27. * Return : None
  28. *******************************************************************************/
  29. void SPI0_CLKCfg( UINT8 c )
  30. {
  31. if(c==2)
  32. R8_SPI0_CTRL_CFG |= RB_SPI_MST_DLY_EN;
  33. else
  34. R8_SPI0_CTRL_CFG &= ~RB_SPI_MST_DLY_EN;
  35. R8_SPI0_CLOCK_DIV = c;
  36. }
  37. /*******************************************************************************
  38. * Function Name : SPI0_DataMode
  39. * Description : 设置数据流模式
  40. * Input : m: 数据流模式
  41. refer to ModeBitOrderTypeDef
  42. * Return : None
  43. *******************************************************************************/
  44. void SPI0_DataMode( ModeBitOrderTypeDef m )
  45. {
  46. switch( m )
  47. {
  48. case Mode0_LowBitINFront:
  49. R8_SPI0_CTRL_MOD &= ~RB_SPI_MST_SCK_MOD;
  50. R8_SPI0_CTRL_CFG |= RB_SPI_BIT_ORDER;
  51. break;
  52. case Mode0_HighBitINFront:
  53. R8_SPI0_CTRL_MOD &= ~RB_SPI_MST_SCK_MOD;
  54. R8_SPI0_CTRL_CFG &= ~RB_SPI_BIT_ORDER;
  55. break;
  56. case Mode3_LowBitINFront:
  57. R8_SPI0_CTRL_MOD |= RB_SPI_MST_SCK_MOD;
  58. R8_SPI0_CTRL_CFG |= RB_SPI_BIT_ORDER;
  59. break;
  60. case Mode3_HighBitINFront:
  61. R8_SPI0_CTRL_MOD |= RB_SPI_MST_SCK_MOD;
  62. R8_SPI0_CTRL_CFG &= ~RB_SPI_BIT_ORDER;
  63. break;
  64. default:
  65. break;
  66. }
  67. }
  68. /*******************************************************************************
  69. * Function Name : SPI0_MasterSendByte
  70. * Description : 发送单字节 (buffer)
  71. * Input : d: 发送字节
  72. * Return : None
  73. *******************************************************************************/
  74. void SPI0_MasterSendByte( UINT8 d )
  75. {
  76. R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
  77. R8_SPI0_BUFFER = d;
  78. while( !(R8_SPI0_INT_FLAG & RB_SPI_FREE) );
  79. }
  80. /*******************************************************************************
  81. * Function Name : SPI0_MasterRecvByte
  82. * Description : 接收单字节 (buffer)
  83. * Input : None
  84. * Return : 接收到的字节
  85. *******************************************************************************/
  86. UINT8 SPI0_MasterRecvByte( void )
  87. {
  88. R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
  89. R8_SPI0_BUFFER = 0xFF; // 启动传输
  90. while( !(R8_SPI0_INT_FLAG & RB_SPI_FREE) );
  91. return ( R8_SPI0_BUFFER );
  92. }
  93. /*******************************************************************************
  94. * Function Name : SPI0_MasterTrans
  95. * Description : 使用FIFO连续发送多字节
  96. * Input : pbuf: 待发送的数据内容首地址
  97. len: 请求发送的数据长度,最大4095
  98. * Return : None
  99. *******************************************************************************/
  100. void SPI0_MasterTrans( UINT8 *pbuf, UINT16 len )
  101. {
  102. UINT16 sendlen;
  103. sendlen = len;
  104. R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR; // 设置数据方向为输出
  105. R16_SPI0_TOTAL_CNT = sendlen; // 设置要发送的数据长度
  106. R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END;
  107. while( sendlen )
  108. {
  109. if( R8_SPI0_FIFO_COUNT < SPI_FIFO_SIZE )
  110. {
  111. R8_SPI0_FIFO = *pbuf;
  112. pbuf++;
  113. sendlen--;
  114. }
  115. }
  116. while( R8_SPI0_FIFO_COUNT != 0 ); // 等待FIFO中的数据全部发送完成
  117. }
  118. /*******************************************************************************
  119. * Function Name : SPI0_MasterRecv
  120. * Description : 使用FIFO连续接收多字节
  121. * Input : pbuf: 待发送的数据内容首地址
  122. len: 请求发送的数据长度,最大4095
  123. * Return : None
  124. *******************************************************************************/
  125. void SPI0_MasterRecv( UINT8 *pbuf, UINT16 len )
  126. {
  127. UINT16 readlen;
  128. readlen = len;
  129. R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR; // 设置数据方向为输入
  130. R16_SPI0_TOTAL_CNT = len; // 设置需要接收的数据长度,FIFO方向为输入长度不为0则会启动传输 */
  131. R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END;
  132. while( readlen )
  133. {
  134. if( R8_SPI0_FIFO_COUNT )
  135. {
  136. *pbuf = R8_SPI0_FIFO;
  137. pbuf++;
  138. readlen--;
  139. }
  140. }
  141. }
  142. /*******************************************************************************
  143. * Function Name : SPI0_MasterDMATrans
  144. * Description : DMA方式连续发送数据
  145. * Input : pbuf: 待发送数据起始地址
  146. * len : 待发送数据长度
  147. * Return : None
  148. *******************************************************************************/
  149. void SPI0_MasterDMATrans( PUINT8 pbuf, UINT16 len)
  150. {
  151. R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
  152. R16_SPI0_DMA_BEG = (UINT32)pbuf;
  153. R16_SPI0_DMA_END = (UINT32)(pbuf + len);
  154. R16_SPI0_TOTAL_CNT = len;
  155. R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END|RB_SPI_IF_DMA_END;
  156. R8_SPI0_CTRL_CFG |= RB_SPI_DMA_ENABLE;
  157. while(!(R8_SPI0_INT_FLAG & RB_SPI_IF_CNT_END));
  158. R8_SPI0_CTRL_CFG &= ~RB_SPI_DMA_ENABLE;
  159. }
  160. /*******************************************************************************
  161. * Function Name : SPI0_MasterDMARecv
  162. * Description : DMA方式连续接收数据
  163. * Input : pbuf: 待接收数据存放起始地址
  164. * len : 待接收数据长度
  165. * Return : None
  166. *******************************************************************************/
  167. void SPI0_MasterDMARecv( PUINT8 pbuf, UINT16 len)
  168. {
  169. R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR;
  170. R16_SPI0_DMA_BEG = (UINT32)pbuf;
  171. R16_SPI0_DMA_END = (UINT32)(pbuf + len);
  172. R16_SPI0_TOTAL_CNT = len;
  173. R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END|RB_SPI_IF_DMA_END;
  174. R8_SPI0_CTRL_CFG |= RB_SPI_DMA_ENABLE;
  175. while(!(R8_SPI0_INT_FLAG & RB_SPI_IF_CNT_END));
  176. R8_SPI0_CTRL_CFG &= ~RB_SPI_DMA_ENABLE;
  177. }
  178. /*******************************************************************************
  179. * Function Name : SPI0_SlaveInit
  180. * Description : 设备模式默认初始化,建议设置MISO的GPIO对应为输入模式
  181. * Input : None
  182. * Return : None
  183. *******************************************************************************/
  184. void SPI0_SlaveInit( void )
  185. {
  186. R8_SPI0_CTRL_MOD = RB_SPI_ALL_CLEAR;
  187. R8_SPI0_CTRL_MOD = RB_SPI_MISO_OE | RB_SPI_MODE_SLAVE;
  188. R8_SPI0_CTRL_CFG |= RB_SPI_AUTO_IF;
  189. }
  190. /*******************************************************************************
  191. * Function Name : SPI0_SlaveRecvByte
  192. * Description : 从机模式,接收一字节数据
  193. * Input : None
  194. * Return : 接收到数据
  195. *******************************************************************************/
  196. UINT8 SPI0_SlaveRecvByte( void )
  197. {
  198. R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR;
  199. while( R8_SPI0_FIFO_COUNT == 0 );
  200. return R8_SPI0_FIFO;
  201. }
  202. /*******************************************************************************
  203. * Function Name : SPI0_SlaveSendByte
  204. * Description : 从机模式,发送一字节数据
  205. * Input : d -待发送数据
  206. * Return : None
  207. *******************************************************************************/
  208. void SPI0_SlaveSendByte( UINT8 d )
  209. {
  210. R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
  211. R8_SPI0_FIFO = d;
  212. while( R8_SPI0_FIFO_COUNT != 0 ); // 等待发送完成
  213. }
  214. /*******************************************************************************
  215. * Function Name : SPI0_SlaveRecv
  216. * Description : 从机模式,接收多字节数据
  217. * Input : pbuf: 接收收数据存放起始地址
  218. * len : 请求接收数据长度
  219. * Return : None
  220. *******************************************************************************/
  221. void SPI0_SlaveRecv( PUINT8 pbuf, UINT16 len )
  222. {
  223. UINT16 revlen;
  224. revlen = len;
  225. R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR;
  226. R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END;
  227. while( revlen )
  228. {
  229. if( R8_SPI0_FIFO_COUNT )
  230. {
  231. *pbuf = R8_SPI0_FIFO;
  232. pbuf++;
  233. revlen--;
  234. }
  235. }
  236. }
  237. /*******************************************************************************
  238. * Function Name : SPI0_SlaveTrans
  239. * Description : 从机模式,发送多字节数据
  240. * Input : pbuf: 待发送的数据内容首地址
  241. len: 请求发送的数据长度,最大4095
  242. * Return : None
  243. *******************************************************************************/
  244. void SPI0_SlaveTrans( UINT8 *pbuf, UINT16 len )
  245. {
  246. UINT16 sendlen;
  247. sendlen = len;
  248. R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR; // 设置数据方向为输出
  249. R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END;
  250. while( sendlen )
  251. {
  252. if( R8_SPI0_FIFO_COUNT < SPI_FIFO_SIZE )
  253. {
  254. R8_SPI0_FIFO = *pbuf;
  255. pbuf++;
  256. sendlen--;
  257. }
  258. }
  259. while( R8_SPI0_FIFO_COUNT != 0 ); // 等待FIFO中的数据全部发送完成
  260. }
  261. /*******************************************************************************
  262. * Function Name : SPI0_SlaveDMARecv
  263. * Description : DMA方式连续接收数据
  264. * Input : pbuf: 待接收数据存放起始地址
  265. * len : 待接收数据长度
  266. * Return : None
  267. *******************************************************************************/
  268. void SPI0_SlaveDMARecv( PUINT8 pbuf, UINT16 len)
  269. {
  270. R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR;
  271. R16_SPI0_DMA_BEG = (UINT32)pbuf;
  272. R16_SPI0_DMA_END = (UINT32)(pbuf + len);
  273. R16_SPI0_TOTAL_CNT = len;
  274. R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END|RB_SPI_IF_DMA_END;
  275. R8_SPI0_CTRL_CFG |= RB_SPI_DMA_ENABLE;
  276. while(!(R8_SPI0_INT_FLAG & RB_SPI_IF_CNT_END));
  277. R8_SPI0_CTRL_CFG &= ~RB_SPI_DMA_ENABLE;
  278. }
  279. /*******************************************************************************
  280. * Function Name : SPI0_SlaveDMATrans
  281. * Description : DMA方式连续发送数据
  282. * Input : pbuf: 待发送数据起始地址
  283. * len : 待发送数据长度
  284. * Return : None
  285. *******************************************************************************/
  286. void SPI0_SlaveDMATrans( PUINT8 pbuf, UINT16 len)
  287. {
  288. R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;
  289. R16_SPI0_DMA_BEG = (UINT32)pbuf;
  290. R16_SPI0_DMA_END = (UINT32)(pbuf + len);
  291. R16_SPI0_TOTAL_CNT = len;
  292. R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END|RB_SPI_IF_DMA_END;
  293. R8_SPI0_CTRL_CFG |= RB_SPI_DMA_ENABLE;
  294. while(!(R8_SPI0_INT_FLAG & RB_SPI_IF_CNT_END));
  295. R8_SPI0_CTRL_CFG &= ~RB_SPI_DMA_ENABLE;
  296. }