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