1 /*
2 * Copyright (c) 2022 OpenLuat & AirM2M
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy of
5 * this software and associated documentation files (the "Software"), to deal in
6 * the Software without restriction, including without limitation the rights to
7 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8 * the Software, and to permit persons to whom the Software is furnished to do so,
9 * subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 */
21
22 #include "user.h"
23
24 #define HSPIM_CR0_CLEAR_MASK ((uint32_t)~0xFFEEFFFF)
25 #define HSPIM_CR0_MODE_SELECT_CLEAR_MASK ((uint32_t)~0x1C00)
26 #define HSPIM_CR1_CLEAR_MASK ((uint32_t)~0xFFFFF)
27 #define HSPIM_FCR_CLEAR_MASK ((uint32_t)~0x3F3F3F00)
28 #define HSPIM_DCR_RECEIVE_LEVEL_CLEAR_MASK ((uint32_t)~0x3F80)
29 #define HSPIM_DCR_TRANSMIT_LEVEL_CLEAR_MASK ((uint32_t)~0x7F)
30
31
32 #define HSPIM_CR0_PARAM_ENABLE_POS (0x18)
33 #define HSPIM_CR0_PARAM_DMA_RECEIVE_ENABLE_POS (0x14)
34 #define HSPIM_CR0_PARAM_DMA_TRANSMIT_ENABLE_POS (0x10)
35 #define HSPIM_CR0_PARAM_INTERRPUT_RX_POS (0x0F)
36 #define HSPIM_CR0_PARAM_INTERRPUT_TX_POS (0x0E)
37 #define HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS (0x0D)
38 #define HSPIM_CR0_PARAM_MODEL_SELECT_POS (0x0A)
39 #define HSPIM_CR0_PARAM_FIRST_BIT_POS (0x09)
40 #define HSPIM_CR0_PARAM_CPOL_POS (0x08)
41 #define HSPIM_CR0_PARAM_CPHA_POS (0x07)
42 #define HSPIM_CR0_PARAM_DIVIDE_ENABLE_POS (0x02)
43 #define HSPIM_CR0_PARAM_TRANSMIT_ENABLE_POS (0x01)
44 #define HSPIM_CR0_PARAM_BUSY_POS (0x00)
45
46 #define HSPIM_CR1_PARAM_BAUDRATE_POS (0x0A)
47 #define HSPIM_CR1_PARAM_RECEIVE_DATA_LENGTH_POS (0x00)
48
49 #define HSPIM_DCR_PARAM_DMA_RECEIVE_LEVEL_POS (0x07)
50 #define HSPIM_DCR_PARAM_DMA_TRANSMIT_LEVEL_POS (0x00)
51
52 #define HSPIM_FCR_PARAM_TRANSIMIT_FIFO_EMPTY_THRESHOULD_POS (0x08)
53 #define HSPIM_FCR_PARAM_RECEIVE_FIFO_FULL_THRESHOULD_POS (0x10)
54
55 #define HSPIM_SR_PUSH_FULL_TX (1 << 4)
56 #define HSPIM_SR_POP_EMPTY_RX (1 << 10)
57 #define HSPIM_FIFO_TX_NUM (64)
58 #define HSPIM_FIFO_RX_NUM (64)
59 #define HSPIM_FIFO_LEVEL (48)
60
61 #define SPIM_FIFO_TX_NUM (16)
62 #define SPIM_FIFO_RX_NUM (16)
63 #define SPIM_FIFO_RX_LEVEL (7)
64 #define SPIM_FIFO_TX_LEVEL (8)
65 typedef struct
66 {
67 const volatile void *RegBase;
68 const int32_t IrqLine;
69 const uint16_t DMATxChannel;
70 const uint16_t DMARxChannel;
71 CBFuncEx_t Callback;
72 void *pParam;
73 HANDLE Sem;
74 Buffer_Struct TxBuf;
75 Buffer_Struct RxBuf;
76 uint32_t Speed;
77 uint8_t DMATxStream;
78 uint8_t DMARxStream;
79 uint8_t Is16Bit;
80 uint8_t IsOnlyTx;
81 uint8_t IsBusy;
82 uint8_t IsBlockMode;
83 }SPI_ResourceStruct;
84
85 static SPI_ResourceStruct prvSPI[SPI_MAX] = {
86 {
87 HSPIM,
88 SPI5_IRQn,
89 SYSCTRL_PHER_CTRL_DMA_CHx_IF_HSPI_TX,
90 SYSCTRL_PHER_CTRL_DMA_CHx_IF_HSPI_RX,
91 },
92 {
93 SPIM0,
94 SPI0_IRQn,
95 SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI0_TX,
96 SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI0_RX,
97 },
98 {
99 SPIM1,
100 SPI1_IRQn,
101 SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI1_TX,
102 SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI1_RX,
103 },
104 {
105 SPIM2,
106 SPI2_IRQn,
107 SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI2_TX,
108 SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI2_RX,
109 },
110 {
111 SPIS0,
112 SPI0_IRQn,
113 SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI0_TX,
114 SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI0_RX,
115 },
116 };
117
HSPI_IrqHandle(int32_t IrqLine,void * pData)118 static void HSPI_IrqHandle(int32_t IrqLine, void *pData)
119 {
120 uint32_t SpiID = HSPI_ID0;
121 uint32_t RxLevel, i, TxLen;
122 HSPIM_TypeDef *SPI = HSPIM;
123 volatile uint32_t DummyData;
124 if (!prvSPI[SpiID].IsBusy)
125 {
126
127 ISR_Clear(prvSPI[SpiID].IrqLine);
128 ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
129 return;
130 }
131 if (prvSPI[SpiID].RxBuf.Data)
132 {
133 while (prvSPI[SpiID].RxBuf.Pos < prvSPI[SpiID].RxBuf.MaxLen)
134 {
135 if (SPI->SR & HSPIM_SR_POP_EMPTY_RX)
136 {
137 break;
138 }
139 else
140 {
141 prvSPI[SpiID].RxBuf.Data[prvSPI[SpiID].RxBuf.Pos] = SPI->RDR;
142 prvSPI[SpiID].RxBuf.Pos++;
143 }
144 }
145 }
146 else
147 {
148 while (prvSPI[SpiID].RxBuf.Pos < prvSPI[SpiID].RxBuf.MaxLen)
149 {
150 if (SPI->SR & HSPIM_SR_POP_EMPTY_RX)
151 {
152 break;
153 }
154 else
155 {
156 DummyData = SPI->RDR;
157 prvSPI[SpiID].RxBuf.Pos++;
158 }
159 }
160 }
161
162
163 if (prvSPI[SpiID].RxBuf.Pos >= prvSPI[SpiID].RxBuf.MaxLen)
164 {
165 SPI->CR0 &= ~(7 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
166 prvSPI[SpiID].IsBusy = 0;
167 ISR_Clear(prvSPI[SpiID].IrqLine);
168 ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
169 if ((prvSPI[SpiID].TxBuf.Pos != prvSPI[SpiID].RxBuf.Pos) || (prvSPI[SpiID].RxBuf.Pos != prvSPI[SpiID].RxBuf.MaxLen))
170 {
171 DBG("%u, %u", prvSPI[SpiID].TxBuf.Pos, prvSPI[SpiID].RxBuf.Pos);
172 }
173 #ifdef __BUILD_OS__
174 if (prvSPI[SpiID].IsBlockMode)
175 {
176 OS_MutexRelease(prvSPI[SpiID].Sem);
177 }
178 #endif
179 prvSPI[SpiID].Callback((void *)SpiID, prvSPI[SpiID].pParam);
180 return;
181 }
182
183 if (prvSPI[SpiID].TxBuf.Pos < prvSPI[SpiID].TxBuf.MaxLen)
184 {
185 i = 0;
186 TxLen = (HSPIM_FIFO_TX_NUM - (SPI->FSR & 0x0000003f));
187 if (TxLen > (prvSPI[SpiID].TxBuf.MaxLen -prvSPI[SpiID].TxBuf.Pos))
188 {
189 TxLen = prvSPI[SpiID].TxBuf.MaxLen - prvSPI[SpiID].TxBuf.Pos;
190 }
191 while((i < TxLen))
192 {
193 SPI->WDR = prvSPI[SpiID].TxBuf.Data[prvSPI[SpiID].TxBuf.Pos + i];
194 i++;
195 }
196 prvSPI[SpiID].TxBuf.Pos += TxLen;
197 if (prvSPI[SpiID].TxBuf.Pos >= prvSPI[SpiID].TxBuf.MaxLen)
198 {
199 SPI->FCR = (63 << HSPIM_FCR_PARAM_TRANSIMIT_FIFO_EMPTY_THRESHOULD_POS)|(0 << HSPIM_FCR_PARAM_RECEIVE_FIFO_FULL_THRESHOULD_POS)|(63);
200 SPI->CR0 &= ~(7 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
201 SPI->CR0 |= (5 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
202 }
203 }
204 else
205 {
206 SPI->FCR = (63 << HSPIM_FCR_PARAM_TRANSIMIT_FIFO_EMPTY_THRESHOULD_POS)|(0 << HSPIM_FCR_PARAM_RECEIVE_FIFO_FULL_THRESHOULD_POS)|(63);
207 SPI->CR0 &= ~(7 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
208 SPI->CR0 |= (5 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
209 }
210 }
211
SPI_DMADoneCB(void * pData,void * pParam)212 static int32_t SPI_DMADoneCB(void *pData, void *pParam)
213 {
214 uint32_t SpiID = (uint32_t)pData;
215 uint32_t RxLevel;
216
217 if (prvSPI[SpiID].RxBuf.MaxLen > prvSPI[SpiID].RxBuf.Pos)
218 {
219 RxLevel = ((prvSPI[SpiID].RxBuf.MaxLen - prvSPI[SpiID].RxBuf.Pos) > 4080)?4000:(prvSPI[SpiID].RxBuf.MaxLen - prvSPI[SpiID].RxBuf.Pos);
220
221 DMA_ClearStreamFlag(prvSPI[SpiID].DMATxStream);
222
223 DMA_ClearStreamFlag(prvSPI[SpiID].DMARxStream);
224
225 if (prvSPI[SpiID].IsOnlyTx)
226 {
227 DMA_ForceStartStream(prvSPI[SpiID].DMATxStream, &prvSPI[SpiID].TxBuf.Data[prvSPI[SpiID].TxBuf.Pos], RxLevel, SPI_DMADoneCB, (void *)SpiID, 1);
228 DMA_ForceStartStream(prvSPI[SpiID].DMARxStream, &prvSPI[SpiID].RxBuf.Data[prvSPI[SpiID].RxBuf.Pos], RxLevel, NULL, NULL, 0);
229 }
230 else
231 {
232 DMA_ForceStartStream(prvSPI[SpiID].DMATxStream, &prvSPI[SpiID].TxBuf.Data[prvSPI[SpiID].TxBuf.Pos], RxLevel, NULL, NULL, 0);
233 DMA_ForceStartStream(prvSPI[SpiID].DMARxStream, &prvSPI[SpiID].RxBuf.Data[prvSPI[SpiID].RxBuf.Pos], RxLevel, SPI_DMADoneCB, (void *)SpiID, 1);
234 }
235 prvSPI[SpiID].RxBuf.Pos += RxLevel;
236 prvSPI[SpiID].TxBuf.Pos += RxLevel;
237 }
238
239 else
240 {
241 prvSPI[SpiID].IsBusy = 0;
242 if ((prvSPI[SpiID].TxBuf.Pos != prvSPI[SpiID].RxBuf.Pos) || (prvSPI[SpiID].RxBuf.Pos != prvSPI[SpiID].RxBuf.MaxLen))
243 {
244 DBG("%u, %u", prvSPI[SpiID].TxBuf.Pos, prvSPI[SpiID].RxBuf.Pos);
245 }
246 #ifdef __BUILD_OS__
247 if (prvSPI[SpiID].IsBlockMode)
248 {
249 OS_MutexRelease(prvSPI[SpiID].Sem);
250 }
251 #endif
252 prvSPI[SpiID].Callback((void *)SpiID, prvSPI[SpiID].pParam);
253 }
254
255
256 }
257
SPI_IrqHandle(int32_t IrqLine,void * pData)258 static void SPI_IrqHandle(int32_t IrqLine, void *pData)
259 {
260 uint32_t SpiID = (uint32_t)pData;
261 volatile uint32_t DummyData;
262 uint32_t RxLevel, SR, i, TxLen;
263 SPI_TypeDef *SPI = (SPI_TypeDef *)prvSPI[SpiID].RegBase;
264 if (!prvSPI[SpiID].IsBusy)
265 {
266 SR = SPI->ICR;
267 SPI->IMR = 0;
268 SPI->SER = 0;
269 ISR_Clear(prvSPI[SpiID].IrqLine);
270 ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
271 return;
272 }
273 TxLen = SPIM_FIFO_TX_NUM - SPI->TXFLR;
274
275 SR = SPI->ICR;
276 if (prvSPI[SpiID].RxBuf.Data)
277 {
278 while(SPI->RXFLR)
279 {
280 prvSPI[SpiID].RxBuf.Data[prvSPI[SpiID].RxBuf.Pos] = SPI->DR;
281 prvSPI[SpiID].RxBuf.Pos++;
282 }
283 }
284 else
285 {
286 while(SPI->RXFLR)
287 {
288 DummyData = SPI->DR;
289 prvSPI[SpiID].RxBuf.Pos++;
290 }
291 }
292
293 if (prvSPI[SpiID].RxBuf.Pos >= prvSPI[SpiID].RxBuf.MaxLen)
294 {
295
296 SR = SPI->ICR;
297 SPI->IMR = 0;
298 SPI->SER = 0;
299 prvSPI[SpiID].IsBusy = 0;
300 ISR_Clear(prvSPI[SpiID].IrqLine);
301 ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
302 if (prvSPI[SpiID].TxBuf.Pos != prvSPI[SpiID].RxBuf.Pos)
303 {
304 DBG("%u, %u", prvSPI[SpiID].TxBuf.Pos, prvSPI[SpiID].RxBuf.Pos);
305 }
306 #ifdef __BUILD_OS__
307 if (prvSPI[SpiID].IsBlockMode)
308 {
309 OS_MutexRelease(prvSPI[SpiID].Sem);
310 }
311 #endif
312 prvSPI[SpiID].Callback((void *)SpiID, prvSPI[SpiID].pParam);
313 return;
314 }
315
316 if (prvSPI[SpiID].TxBuf.Pos < prvSPI[SpiID].TxBuf.MaxLen)
317 {
318 i = 0;
319 if (TxLen > (prvSPI[SpiID].TxBuf.MaxLen -prvSPI[SpiID].TxBuf.Pos))
320 {
321 TxLen = prvSPI[SpiID].TxBuf.MaxLen - prvSPI[SpiID].TxBuf.Pos;
322 }
323 while((i < TxLen))
324 {
325 SPI->DR = prvSPI[SpiID].TxBuf.Data[prvSPI[SpiID].TxBuf.Pos + i];
326 i++;
327 }
328 prvSPI[SpiID].TxBuf.Pos += i;
329 }
330 else
331 {
332
333 if ((prvSPI[SpiID].RxBuf.MaxLen - prvSPI[SpiID].RxBuf.Pos) >= SPIM_FIFO_RX_NUM)
334 {
335 SPI->RXFTLR = (SPIM_FIFO_RX_NUM - 1);
336 }
337 else
338 {
339 SPI->RXFTLR = prvSPI[SpiID].RxBuf.MaxLen - prvSPI[SpiID].RxBuf.Pos - 1;
340 }
341 SPI->IMR = SPI_IMR_RXOIM|SPI_IMR_RXFIM;
342 }
343 }
344
SPI_DummyCB(void * pData,void * pParam)345 static int32_t SPI_DummyCB(void *pData, void *pParam)
346 {
347 return 0;
348 }
349
HSPI_MasterInit(uint8_t SpiID,uint8_t Mode,uint32_t Speed)350 static void HSPI_MasterInit(uint8_t SpiID, uint8_t Mode, uint32_t Speed)
351 {
352 HSPIM_TypeDef *SPI = (HSPIM_TypeDef *)prvSPI[SpiID].RegBase;
353 uint32_t div = (SystemCoreClock / Speed) >> 1;
354 uint32_t ctrl = (1 << 24) | (1 << 10) | (1 << 2) | (1 << 1);
355 switch(Mode)
356 {
357 case SPI_MODE_0:
358 break;
359 case SPI_MODE_1:
360 ctrl |= (1 << HSPIM_CR0_PARAM_CPHA_POS);
361 break;
362 case SPI_MODE_2:
363 ctrl |= (1 << HSPIM_CR0_PARAM_CPOL_POS);
364 break;
365 case SPI_MODE_3:
366 ctrl |= (1 << HSPIM_CR0_PARAM_CPOL_POS)|(1 << HSPIM_CR0_PARAM_CPHA_POS);
367 break;
368 }
369 SPI->CR1 = (div << HSPIM_CR1_PARAM_BAUDRATE_POS) + 1;
370 SPI->CR0 = ctrl;
371 SPI->DCR = 30|(1 << 7);
372 prvSPI[SpiID].Speed = (SystemCoreClock >> 1) / div;
373
374 ISR_SetHandler(prvSPI[SpiID].IrqLine, HSPI_IrqHandle, (uint32_t)SpiID);
375 #ifdef __BUILD_OS__
376 ISR_SetPriority(prvSPI[SpiID].IrqLine, IRQ_MAX_PRIORITY + 1);
377 #else
378 ISR_SetPriority(prvSPI[SpiID].IrqLine, 3);
379 #endif
380 ISR_Clear(prvSPI[SpiID].IrqLine);
381 ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
382
383 }
384
SPI_MasterInit(uint8_t SpiID,uint8_t DataBit,uint8_t Mode,uint32_t Speed,CBFuncEx_t CB,void * pUserData)385 void SPI_MasterInit(uint8_t SpiID, uint8_t DataBit, uint8_t Mode, uint32_t Speed, CBFuncEx_t CB, void *pUserData)
386 {
387 SPI_TypeDef *SPI;
388 uint32_t ctrl;
389 uint32_t div;
390 switch(SpiID)
391 {
392 case HSPI_ID0:
393 HSPI_MasterInit(SpiID, Mode, Speed);
394 break;
395 case SPI_ID0:
396 SYSCTRL->PHER_CTRL &= ~SYSCTRL_PHER_CTRL_SPI0_SLV_EN;
397 case SPI_ID1:
398 case SPI_ID2:
399 SPI = (SPI_TypeDef *)prvSPI[SpiID].RegBase;
400 SPI->SSIENR = 0;
401 SPI->SER = 0;
402 SPI->IMR = 0;
403 SPI->DMACR = 0;
404 ctrl = DataBit - 1;
405 switch(Mode)
406 {
407 case SPI_MODE_0:
408 break;
409 case SPI_MODE_1:
410 ctrl |= SPI_CTRLR0_SCPH;
411 break;
412 case SPI_MODE_2:
413 ctrl |= SPI_CTRLR0_SCPOL;
414 break;
415 case SPI_MODE_3:
416 ctrl |= SPI_CTRLR0_SCPOL|SPI_CTRLR0_SCPH;
417 break;
418 }
419 div = (SystemCoreClock >> 2) / Speed;
420 if (div % 2) div++;
421 prvSPI[SpiID].Speed = (SystemCoreClock >> 2) / div;
422 SPI->CTRLR0 = ctrl;
423 SPI->BAUDR = div;
424 SPI->TXFTLR = 0;
425 SPI->RXFTLR = 0;
426 SPI->DMATDLR = 7;
427 SPI->DMARDLR = 0;
428 ISR_SetHandler(prvSPI[SpiID].IrqLine, SPI_IrqHandle, (uint32_t)SpiID);
429 #ifdef __BUILD_OS__
430 ISR_SetPriority(prvSPI[SpiID].IrqLine, IRQ_LOWEST_PRIORITY - 2);
431 #else
432 ISR_SetPriority(prvSPI[SpiID].IrqLine, 5);
433 #endif
434 ISR_Clear(prvSPI[SpiID].IrqLine);
435 ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
436 SPI->SSIENR = 1;
437 break;
438 // case SPI_ID3:
439 // SYSCTRL->PHER_CTRL |= SYSCTRL_PHER_CTRL_SPI0_SLV_EN;
440 // break;
441 default:
442 return;
443 }
444 prvSPI[SpiID].DMATxStream = 0xff;
445 prvSPI[SpiID].DMARxStream = 0xff;
446 if (CB)
447 {
448 prvSPI[SpiID].Callback = CB;
449 }
450 else
451 {
452 prvSPI[SpiID].Callback = SPI_DummyCB;
453 }
454 prvSPI[SpiID].pParam = pUserData;
455 #ifdef __BUILD_OS__
456 if (!prvSPI[SpiID].Sem)
457 {
458 prvSPI[SpiID].Sem = OS_MutexCreate();
459 }
460 #endif
461 }
462
463
SPI_SetTxOnlyFlag(uint8_t SpiID,uint8_t OnOff)464 void SPI_SetTxOnlyFlag(uint8_t SpiID, uint8_t OnOff)
465 {
466 prvSPI[SpiID].IsOnlyTx = OnOff;
467 }
468
SPI_SetCallbackFun(uint8_t SpiID,CBFuncEx_t CB,void * pUserData)469 void SPI_SetCallbackFun(uint8_t SpiID, CBFuncEx_t CB, void *pUserData)
470 {
471 if (CB)
472 {
473 prvSPI[SpiID].Callback = CB;
474 }
475 else
476 {
477 prvSPI[SpiID].Callback = SPI_DummyCB;
478 }
479 prvSPI[SpiID].pParam = pUserData;
480 }
481
482
SPI_DMATransfer(uint8_t SpiID,uint8_t UseDMA)483 static void SPI_DMATransfer(uint8_t SpiID, uint8_t UseDMA)
484 {
485 uint32_t RxLevel;
486
487 RxLevel = (prvSPI[SpiID].RxBuf.MaxLen > 4080)?4000:prvSPI[SpiID].RxBuf.MaxLen;
488 prvSPI[SpiID].RxBuf.Pos += RxLevel;
489 prvSPI[SpiID].TxBuf.Pos += RxLevel;
490 DMA_StopStream(prvSPI[SpiID].DMATxStream);
491 DMA_StopStream(prvSPI[SpiID].DMARxStream);
492 if (prvSPI[SpiID].IsOnlyTx)
493 {
494 DMA_ForceStartStream(prvSPI[SpiID].DMATxStream, prvSPI[SpiID].TxBuf.Data, RxLevel, SPI_DMADoneCB, (void *)SpiID, 1);
495 DMA_ForceStartStream(prvSPI[SpiID].DMARxStream, prvSPI[SpiID].RxBuf.Data, RxLevel, NULL, NULL, 0);
496 }
497 else
498 {
499 DMA_ForceStartStream(prvSPI[SpiID].DMATxStream, prvSPI[SpiID].TxBuf.Data, RxLevel, NULL, NULL, 0);
500 DMA_ForceStartStream(prvSPI[SpiID].DMARxStream, prvSPI[SpiID].RxBuf.Data, RxLevel, SPI_DMADoneCB, (void *)SpiID, 1);
501 }
502
503
504 }
505
HSPI_Transfer(uint8_t SpiID,uint8_t UseDMA)506 static int32_t HSPI_Transfer(uint8_t SpiID, uint8_t UseDMA)
507 {
508 HSPIM_TypeDef *SPI = (HSPIM_TypeDef *)prvSPI[SpiID].RegBase;
509 uint32_t TxLen, i;
510 if (UseDMA)
511 {
512 SPI->CR0 &= ~(7 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
513 SPI->CR0 |= (1 << HSPIM_CR0_PARAM_DMA_TRANSMIT_ENABLE_POS)|(1 << HSPIM_CR0_PARAM_DMA_RECEIVE_ENABLE_POS);
514 SPI->FCR = (32 << HSPIM_FCR_PARAM_TRANSIMIT_FIFO_EMPTY_THRESHOULD_POS)|(0 << HSPIM_FCR_PARAM_RECEIVE_FIFO_FULL_THRESHOULD_POS)|(3 << 6)|(63);
515 SPI->FCR &= ~(3 << 6);
516 SPI_DMATransfer(SpiID, UseDMA);
517 }
518 else
519 {
520 SPI->CR0 &= ~(7 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
521 // SPI->CR0 &= ~(1 << 10);
522 SPI->CR0 &= ~((1 << HSPIM_CR0_PARAM_DMA_TRANSMIT_ENABLE_POS)|(1 << HSPIM_CR0_PARAM_DMA_RECEIVE_ENABLE_POS));
523
524
525
526 if (prvSPI[SpiID].TxBuf.MaxLen <= HSPIM_FIFO_TX_NUM)
527 {
528 TxLen = prvSPI[SpiID].TxBuf.MaxLen;
529 SPI->FCR = (32 << HSPIM_FCR_PARAM_TRANSIMIT_FIFO_EMPTY_THRESHOULD_POS)|((TxLen - 1) << HSPIM_FCR_PARAM_RECEIVE_FIFO_FULL_THRESHOULD_POS)|(3 << 6)|(63);
530 SPI->CR0 |= (5 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
531 }
532 else
533 {
534 TxLen = HSPIM_FIFO_TX_NUM;
535 SPI->FCR = (32 << HSPIM_FCR_PARAM_TRANSIMIT_FIFO_EMPTY_THRESHOULD_POS)|(63 << HSPIM_FCR_PARAM_RECEIVE_FIFO_FULL_THRESHOULD_POS)|(3 << 6)|(63);
536 SPI->CR0 |= (3 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
537 }
538
539 SPI->FCR &= ~(3 << 6);
540
541 for(i = 0; i < TxLen; i++)
542 {
543 SPI->WDR = prvSPI[SpiID].TxBuf.Data[i];
544 }
545 prvSPI[SpiID].TxBuf.Pos += TxLen;
546 // SPI->CR0 |= (1 << 10);
547 ISR_Clear(prvSPI[SpiID].IrqLine);
548 ISR_OnOff(prvSPI[SpiID].IrqLine, 1);
549 return ERROR_NONE;
550 }
551 return ERROR_NONE;
552 }
553
SPI_Transfer(uint8_t SpiID,const uint8_t * TxData,uint8_t * RxData,uint32_t Len,uint8_t UseDMA)554 int32_t SPI_Transfer(uint8_t SpiID, const uint8_t *TxData, uint8_t *RxData, uint32_t Len, uint8_t UseDMA)
555 {
556 uint32_t SR;
557 SPI_TypeDef *SPI;
558 if (prvSPI[SpiID].IsBusy)
559 {
560 return -ERROR_DEVICE_BUSY;
561 }
562 prvSPI[SpiID].IsBusy = 1;
563 //
564 uint32_t RxLevel, i, TxLen;
565 Buffer_StaticInit(&prvSPI[SpiID].TxBuf, TxData, Len);
566 Buffer_StaticInit(&prvSPI[SpiID].RxBuf, RxData, Len);
567 switch(SpiID)
568 {
569 case HSPI_ID0:
570 ISR_Clear(prvSPI[SpiID].IrqLine);
571 ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
572 return HSPI_Transfer(SpiID, UseDMA);
573 case SPI_ID0:
574 SYSCTRL->PHER_CTRL &= ~SYSCTRL_PHER_CTRL_SPI0_SLV_EN;
575 case SPI_ID1:
576 case SPI_ID2:
577 break;
578 // case SPI_ID3:
579 // SYSCTRL->PHER_CTRL |= SYSCTRL_PHER_CTRL_SPI0_SLV_EN;
580 // break;
581 default:
582 return -ERROR_ID_INVALID;
583 }
584 SPI = (SPI_TypeDef *)prvSPI[SpiID].RegBase;
585 SPI->SER = 0;
586 if (UseDMA)
587 {
588
589 SR = SPI->ICR;
590 SPI->IMR = 0;
591 SPI->DMACR = SPI_DMACR_RDMAE|SPI_DMACR_TDMAE;
592 ISR_Clear(prvSPI[SpiID].IrqLine);
593 ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
594 SPI->SER = 1;
595 SPI_DMATransfer(SpiID, 1);
596
597 }
598 else
599 {
600 ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
601
602 if (prvSPI[SpiID].RxBuf.MaxLen <= SPIM_FIFO_RX_NUM)
603 {
604 SPI->RXFTLR = prvSPI[SpiID].RxBuf.MaxLen - 1;
605 TxLen = prvSPI[SpiID].RxBuf.MaxLen;
606 SPI->IMR = SPI_IMR_RXOIM|SPI_IMR_RXFIM;
607 }
608 else
609 {
610 SPI->IMR = SPI_IMR_TXEIM;
611 SPI->RXFTLR = SPIM_FIFO_RX_LEVEL;
612 SPI->TXFTLR = SPIM_FIFO_TX_LEVEL;
613 TxLen = SPIM_FIFO_TX_NUM;
614 }
615 for(i = 0; i < TxLen; i++)
616 {
617 SPI->DR = prvSPI[SpiID].TxBuf.Data[i];
618 }
619 prvSPI[SpiID].TxBuf.Pos += TxLen;
620 ISR_Clear(prvSPI[SpiID].IrqLine);
621 ISR_OnOff(prvSPI[SpiID].IrqLine, 1);
622 }
623 SPI->SER = 1;
624
625 return ERROR_NONE;
626 }
627
628
prvSPI_BlockTransfer(uint8_t SpiID,const uint8_t * TxData,uint8_t * RxData,uint32_t Len)629 static int32_t prvSPI_BlockTransfer(uint8_t SpiID, const uint8_t *TxData, uint8_t *RxData, uint32_t Len)
630 {
631 volatile uint32_t DummyData;
632 uint32_t TxLen, RxLen, i, To;
633 HSPIM_TypeDef *HSPI;
634 SPI_TypeDef *SPI;
635 prvSPI[SpiID].IsBusy = 1;
636 switch(SpiID)
637 {
638 case HSPI_ID0:
639 HSPI = (HSPIM_TypeDef *)prvSPI[SpiID].RegBase;
640 ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
641 HSPI->FCR = (32 << HSPIM_FCR_PARAM_TRANSIMIT_FIFO_EMPTY_THRESHOULD_POS)|(32 << HSPIM_FCR_PARAM_RECEIVE_FIFO_FULL_THRESHOULD_POS)|(3 << 6)|(63);
642 HSPI->FCR &= ~(3 << 6);
643 HSPI->CR0 &= ~(7 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
644 if (Len <= HSPIM_FIFO_TX_NUM)
645 {
646 TxLen = Len;
647 }
648 else
649 {
650 TxLen = HSPIM_FIFO_TX_NUM;
651 }
652 for(i = 0; i < TxLen; i++)
653 {
654 HSPI->WDR = TxData[i];
655 }
656 if (RxData)
657 {
658 for(RxLen = 0; RxLen < Len; RxLen++)
659 {
660 while (HSPI->SR & HSPIM_SR_POP_EMPTY_RX)
661 {
662 ;
663 }
664 RxData[RxLen] = HSPI->RDR;
665 if (TxLen < Len)
666 {
667 HSPI->WDR = TxData[TxLen];
668 TxLen++;
669 }
670 }
671 }
672 else
673 {
674 while(TxLen < Len)
675 {
676 while ((HSPI->FSR & 0x7f) > 16)
677 {
678 ;
679 }
680 HSPI->WDR = TxData[TxLen];
681 TxLen++;
682 }
683 while ((HSPI->FSR & 0x7f))
684 {
685 ;
686 }
687 // for(RxLen = 0; RxLen < Len; RxLen++)
688 // {
689 // while (HSPI->SR & HSPIM_SR_POP_EMPTY_RX)
690 // {
691 // ;
692 // }
693 // DummyData = HSPI->RDR;
694 // if (TxLen < Len)
695 // {
696 // HSPI->WDR = TxData[TxLen];
697 // TxLen++;
698 // }
699 // }
700 }
701 break;
702 case SPI_ID0:
703 case SPI_ID1:
704 case SPI_ID2:
705 SPI = (SPI_TypeDef *)prvSPI[SpiID].RegBase;
706 ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
707 SPI->SER = 0;
708 if (Len <= SPIM_FIFO_TX_NUM)
709 {
710 TxLen = Len;
711 }
712 else
713 {
714 TxLen = SPIM_FIFO_TX_NUM;
715 }
716 for(i = 0; i < TxLen; i++)
717 {
718 SPI->DR = TxData[i];
719 }
720 SPI->SER = 1;
721 if (RxData)
722 {
723 for(RxLen = 0; RxLen < Len; RxLen++)
724 {
725 while (!SPI->RXFLR)
726 {
727 ;
728 }
729 RxData[RxLen] = SPI->DR;
730 if (TxLen < Len)
731 {
732 SPI->DR = TxData[TxLen];
733 TxLen++;
734 }
735 }
736 }
737 else
738 {
739 for(RxLen = 0; RxLen < Len; RxLen++)
740 {
741 while (!SPI->RXFLR)
742 {
743 ;
744 }
745 DummyData = SPI->DR;
746 if (TxLen < Len)
747 {
748 SPI->DR = TxData[TxLen];
749 TxLen++;
750 }
751 }
752 }
753 SPI->SER = 0;
754 break;
755 }
756 prvSPI[SpiID].IsBusy = 0;
757 prvSPI[SpiID].Callback((void *)SpiID, prvSPI[SpiID].pParam);
758 return 0;
759 }
760
SPI_BlockTransfer(uint8_t SpiID,const uint8_t * TxData,uint8_t * RxData,uint32_t Len)761 int32_t SPI_BlockTransfer(uint8_t SpiID, const uint8_t *TxData, uint8_t *RxData, uint32_t Len)
762 {
763 #ifdef __BUILD_OS__
764 if ( (prvSPI[SpiID].DMARxStream == 0xff) || (prvSPI[SpiID].DMATxStream == 0xff) || OS_CheckInIrq() || ((prvSPI[SpiID].Speed >> 3) >= (Len * 100000)))
765 {
766 prvSPI[SpiID].IsBlockMode = 0;
767 #endif
768 return prvSPI_BlockTransfer(SpiID, TxData, RxData, Len);
769 #ifdef __BUILD_OS__
770 }
771 int32_t Result;
772 uint32_t Time = (Len * 1000) / (prvSPI[SpiID].Speed >> 3);
773 prvSPI[SpiID].IsBlockMode = 1;
774 if (TxData)
775 {
776 Result = SPI_Transfer(SpiID, TxData, RxData, Len, 1);
777 }
778 else
779 {
780 Result = SPI_Transfer(SpiID, RxData, RxData, Len, 1);
781 }
782 if (Result)
783 {
784 prvSPI[SpiID].IsBlockMode = 0;
785 DBG("!");
786 return Result;
787 }
788 if (OS_MutexLockWtihTime(prvSPI[SpiID].Sem, Time + 10))
789 {
790 DBG("!!!");
791 SPI_TransferStop(SpiID);
792 prvSPI[SpiID].IsBlockMode = 0;
793 return -1;
794 }
795 prvSPI[SpiID].IsBlockMode = 0;
796 return 0;
797 #endif
798 }
799
800
prvSPI_FlashBlockTransfer(uint8_t SpiID,const uint8_t * TxData,uint32_t WLen,uint8_t * RxData,uint32_t RLen)801 static int32_t prvSPI_FlashBlockTransfer(uint8_t SpiID, const uint8_t *TxData, uint32_t WLen, uint8_t *RxData, uint32_t RLen)
802 {
803 volatile uint32_t DummyData;
804 uint32_t TxLen, RxLen, i;
805 HSPIM_TypeDef *HSPI;
806 SPI_TypeDef *SPI;
807 prvSPI[SpiID].IsBusy = 1;
808 switch(SpiID)
809 {
810 case HSPI_ID0:
811 HSPI = (HSPIM_TypeDef *)prvSPI[SpiID].RegBase;
812
813 HSPI->FCR = (32 << HSPIM_FCR_PARAM_TRANSIMIT_FIFO_EMPTY_THRESHOULD_POS)|(32 << HSPIM_FCR_PARAM_RECEIVE_FIFO_FULL_THRESHOULD_POS)|(3 << 6)|(63);
814 HSPI->FCR &= ~(3 << 6);
815 HSPI->CR0 &= ~(7 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
816 if (WLen <= HSPIM_FIFO_TX_NUM)
817 {
818 TxLen = WLen;
819 }
820 else
821 {
822 TxLen = HSPIM_FIFO_TX_NUM;
823 }
824 for(i = 0; i < TxLen; i++)
825 {
826 HSPI->WDR = TxData[i];
827 }
828 for(RxLen = 0; RxLen < WLen; RxLen++)
829 {
830 while (HSPI->SR & HSPIM_SR_POP_EMPTY_RX)
831 {
832 ;
833 }
834 DummyData = HSPI->RDR;
835 if (TxLen < WLen)
836 {
837 HSPI->WDR = TxData[TxLen];
838 TxLen++;
839 }
840 }
841 if (RLen <= HSPIM_FIFO_TX_NUM)
842 {
843 TxLen = RLen;
844 }
845 else
846 {
847 TxLen = HSPIM_FIFO_TX_NUM;
848 }
849 for(i = 0; i < TxLen; i++)
850 {
851 HSPI->WDR = TxData[i];
852 }
853 for(RxLen = 0; RxLen < RLen; RxLen++)
854 {
855 while (HSPI->SR & HSPIM_SR_POP_EMPTY_RX)
856 {
857 ;
858 }
859 RxData[RxLen] = HSPI->RDR;
860 if (TxLen < RLen)
861 {
862 HSPI->WDR = 0xff;
863 TxLen++;
864 }
865 }
866
867 break;
868 case SPI_ID0:
869 case SPI_ID1:
870 case SPI_ID2:
871 SPI = (SPI_TypeDef *)prvSPI[SpiID].RegBase;
872 ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
873 SPI->SER = 0;
874 if (WLen <= SPIM_FIFO_TX_NUM)
875 {
876 TxLen = WLen;
877 }
878 else
879 {
880 TxLen = SPIM_FIFO_TX_NUM;
881 }
882 for(i = 0; i < TxLen; i++)
883 {
884 SPI->DR = TxData[i];
885 }
886 SPI->SER = 1;
887 for(RxLen = 0; RxLen < WLen; RxLen++)
888 {
889 while (!SPI->RXFLR)
890 {
891 ;
892 }
893 DummyData = SPI->DR;
894 if (TxLen < WLen)
895 {
896 SPI->DR = TxData[TxLen];
897 TxLen++;
898 }
899 }
900 if (RLen <= SPIM_FIFO_TX_NUM)
901 {
902 TxLen = RLen;
903 }
904 else
905 {
906 TxLen = SPIM_FIFO_TX_NUM;
907 }
908 for(i = 0; i < TxLen; i++)
909 {
910 SPI->DR = TxData[i];
911 }
912
913 for(RxLen = 0; RxLen < RLen; RxLen++)
914 {
915 while (!SPI->RXFLR)
916 {
917 ;
918 }
919 RxData[RxLen] = SPI->DR;
920 if (TxLen < RLen)
921 {
922 SPI->DR = 0xff;
923 TxLen++;
924 }
925 }
926 SPI->SER = 0;
927 break;
928 }
929 prvSPI[SpiID].IsBusy = 0;
930 prvSPI[SpiID].Callback((void *)SpiID, prvSPI[SpiID].pParam);
931 return 0;
932 }
933
SPI_FlashBlockTransfer(uint8_t SpiID,const uint8_t * TxData,uint32_t WLen,uint8_t * RxData,uint32_t RLen)934 int32_t SPI_FlashBlockTransfer(uint8_t SpiID, const uint8_t *TxData, uint32_t WLen, uint8_t *RxData, uint32_t RLen)
935 {
936 #ifdef __BUILD_OS__
937 if ( (prvSPI[SpiID].DMARxStream == 0xff) || (prvSPI[SpiID].DMATxStream == 0xff) || OS_CheckInIrq() || ((prvSPI[SpiID].Speed >> 3) >= ((WLen + RLen) * 100000)))
938 {
939 prvSPI[SpiID].IsBlockMode = 0;
940 #endif
941 return prvSPI_FlashBlockTransfer(SpiID, TxData, WLen, RxData, RLen);
942 #ifdef __BUILD_OS__
943 }
944 int32_t Result;
945 uint32_t Time = ((WLen + RLen) * 1000) / (prvSPI[SpiID].Speed >> 3);
946 uint8_t *Temp = malloc(WLen + RLen);
947 memcpy(Temp, TxData, WLen);
948 prvSPI[SpiID].IsBlockMode = 1;
949
950 if (TxData)
951 {
952 Result = SPI_Transfer(SpiID, Temp, Temp, WLen + RLen, 1);
953 }
954 else
955 {
956 Result = SPI_Transfer(SpiID, Temp, Temp, WLen + RLen, 1);
957 }
958 if (Result)
959 {
960 prvSPI[SpiID].IsBlockMode = 0;
961 free(Temp);
962 return Result;
963 }
964 if (OS_MutexLockWtihTime(prvSPI[SpiID].Sem, Time + 10))
965 {
966 free(Temp);
967 DBG("!!!");
968 DMA_StopStream(prvSPI[SpiID].DMATxStream);
969 DMA_StopStream(prvSPI[SpiID].DMARxStream);
970 SPI_TransferStop(SpiID);
971 prvSPI[SpiID].IsBlockMode = 0;
972 return -1;
973 }
974 memcpy(RxData, Temp + WLen, RLen);
975 prvSPI[SpiID].IsBlockMode = 0;
976 free(Temp);
977 return 0;
978 #endif
979 }
980
981
SPI_DMATxInit(uint8_t SpiID,uint8_t Stream,uint32_t Channel)982 void SPI_DMATxInit(uint8_t SpiID, uint8_t Stream, uint32_t Channel)
983 {
984 SPI_TypeDef *SPI;
985 HSPIM_TypeDef *HSPI;
986 DMA_InitTypeDef DMA_InitStruct;
987 DMA_BaseConfig(&DMA_InitStruct);
988 DMA_InitStruct.DMA_Peripheral = prvSPI[SpiID].DMATxChannel;
989 DMA_InitStruct.DMA_Priority = DMA_Priority_3;
990 prvSPI[SpiID].DMATxStream = Stream;
991 switch(SpiID)
992 {
993 case HSPI_ID0:
994 HSPI = (HSPIM_TypeDef *)prvSPI[SpiID].RegBase;
995 if (prvSPI[SpiID].IsOnlyTx)
996 {
997 DMA_InitStruct.DMA_Priority = DMA_Priority_0;
998 }
999 DMA_InitStruct.DMA_PeripheralBurstSize = DMA_BurstSize_32;
1000 DMA_InitStruct.DMA_MemoryBurstSize = DMA_BurstSize_32;
1001 DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&HSPI->WDR;
1002 break;
1003 case SPI_ID0:
1004 case SPI_ID1:
1005 case SPI_ID2:
1006 SPI = (SPI_TypeDef *)prvSPI[SpiID].RegBase;
1007 DMA_InitStruct.DMA_PeripheralBurstSize = DMA_BurstSize_8;
1008 DMA_InitStruct.DMA_MemoryBurstSize = DMA_BurstSize_8;
1009 DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&SPI->DR;
1010 break;
1011 // case SPI_ID3:
1012 // SYSCTRL->PHER_CTRL |= SYSCTRL_PHER_CTRL_SPI0_SLV_EN;
1013 // break;
1014 default:
1015 return;
1016 }
1017 DMA_ConfigStream(Stream, &DMA_InitStruct);
1018 }
SPI_DMARxInit(uint8_t SpiID,uint8_t Stream,uint32_t Channel)1019 void SPI_DMARxInit(uint8_t SpiID, uint8_t Stream, uint32_t Channel)
1020 {
1021 SPI_TypeDef *SPI;
1022 HSPIM_TypeDef *HSPI;
1023 DMA_InitTypeDef DMA_InitStruct;
1024 DMA_BaseConfig(&DMA_InitStruct);
1025 DMA_InitStruct.DMA_Peripheral = prvSPI[SpiID].DMARxChannel;
1026 DMA_InitStruct.DMA_Priority = DMA_Priority_2;
1027 prvSPI[SpiID].DMARxStream = Stream;
1028 switch(SpiID)
1029 {
1030 case HSPI_ID0:
1031 HSPI = (HSPIM_TypeDef *)prvSPI[SpiID].RegBase;
1032 DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&HSPI->RDR;
1033 break;
1034 case SPI_ID0:
1035 case SPI_ID1:
1036 case SPI_ID2:
1037 SPI = (SPI_TypeDef *)prvSPI[SpiID].RegBase;
1038 DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&SPI->DR;
1039 break;
1040 // case SPI_ID3:
1041 // SYSCTRL->PHER_CTRL |= SYSCTRL_PHER_CTRL_SPI0_SLV_EN;
1042 // break;
1043 default:
1044 return;
1045 }
1046 DMA_ConfigStream(Stream, &DMA_InitStruct);
1047 }
1048
SPI_TransferStop(uint8_t SpiID)1049 void SPI_TransferStop(uint8_t SpiID)
1050 {
1051 uint16_t Data;
1052 ISR_Clear(prvSPI[SpiID].IrqLine);
1053 ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
1054 SPI_TypeDef *SPI;
1055 HSPIM_TypeDef *HSPI;
1056 uint32_t TxLen, i;
1057 DMA_StopStream(prvSPI[SpiID].DMATxStream);
1058 DMA_StopStream(prvSPI[SpiID].DMARxStream);
1059 switch(SpiID)
1060 {
1061 case HSPI_ID0:
1062 HSPI = (HSPIM_TypeDef *)prvSPI[SpiID].RegBase;
1063 HSPI->CR0 &= ~(7 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
1064 HSPI->FCR = (32 << HSPIM_FCR_PARAM_TRANSIMIT_FIFO_EMPTY_THRESHOULD_POS)|(32 << HSPIM_FCR_PARAM_RECEIVE_FIFO_FULL_THRESHOULD_POS)|(3 << 6)|(63);
1065 HSPI->FCR &= ~(3 << 6);
1066 break;
1067 case SPI_ID0:
1068 SYSCTRL->PHER_CTRL &= ~SYSCTRL_PHER_CTRL_SPI0_SLV_EN;
1069 case SPI_ID1:
1070 case SPI_ID2:
1071 SPI = (SPI_TypeDef *)prvSPI[SpiID].RegBase;
1072 while(SPI->TXFLR){;}
1073 while(SPI->RXFLR){Data = SPI->DR;}
1074 SPI->SER = 0;
1075 break;
1076 // case SPI_ID3:
1077 // SYSCTRL->PHER_CTRL |= SYSCTRL_PHER_CTRL_SPI0_SLV_EN;
1078 // break;
1079 default:
1080 return ;
1081 }
1082
1083 prvSPI[SpiID].IsBusy = 0;
1084
1085 }
1086
SPI_IsTransferBusy(uint8_t SpiID)1087 uint8_t SPI_IsTransferBusy(uint8_t SpiID)
1088 {
1089 return prvSPI[SpiID].IsBusy;
1090 }
1091
SPI_SetNewConfig(uint8_t SpiID,uint32_t Speed,uint8_t NewMode)1092 void SPI_SetNewConfig(uint8_t SpiID, uint32_t Speed, uint8_t NewMode)
1093 {
1094 HSPIM_TypeDef *HSPI;
1095 SPI_TypeDef *SPI;
1096 uint32_t div;
1097 if (prvSPI[SpiID].IsBusy) return;
1098
1099 switch(SpiID)
1100 {
1101 case HSPI_ID0:
1102 HSPI = (HSPIM_TypeDef *)prvSPI[SpiID].RegBase;
1103 div = (SystemCoreClock / Speed) >> 1;
1104 HSPI->CR1 = (div << HSPIM_CR1_PARAM_BAUDRATE_POS) + 1;
1105 prvSPI[SpiID].Speed = (SystemCoreClock >> 1) / div;
1106 HSPI->CR0 &= ~((1 << HSPIM_CR0_PARAM_CPOL_POS)|(1 << HSPIM_CR0_PARAM_CPHA_POS));
1107 switch(NewMode)
1108 {
1109 case SPI_MODE_0:
1110
1111 break;
1112 case SPI_MODE_1:
1113 HSPI->CR0 |= (1 << HSPIM_CR0_PARAM_CPHA_POS);
1114 break;
1115 case SPI_MODE_2:
1116 HSPI->CR0 |= (1 << HSPIM_CR0_PARAM_CPOL_POS);
1117 break;
1118 case SPI_MODE_3:
1119 HSPI->CR0 |= (1 << HSPIM_CR0_PARAM_CPOL_POS)|(1 << HSPIM_CR0_PARAM_CPHA_POS);
1120 break;
1121 }
1122 break;
1123 case SPI_ID0:
1124 case SPI_ID1:
1125 case SPI_ID2:
1126 SPI = (SPI_TypeDef *)prvSPI[SpiID].RegBase;
1127 SPI->SSIENR = 0;
1128 div = (SystemCoreClock >> 2) / Speed;
1129 if (div % 2) div++;
1130 prvSPI[SpiID].Speed = (SystemCoreClock >> 2) / div;
1131 SPI->BAUDR = div;
1132 SPI->CTRLR0 &= ~(SPI_CTRLR0_SCPOL|SPI_CTRLR0_SCPH);
1133 switch(NewMode)
1134 {
1135 case SPI_MODE_0:
1136 break;
1137 case SPI_MODE_1:
1138 SPI->CTRLR0 |= SPI_CTRLR0_SCPH;
1139 break;
1140 case SPI_MODE_2:
1141 SPI->CTRLR0 |= SPI_CTRLR0_SCPOL;
1142 break;
1143 case SPI_MODE_3:
1144 SPI->CTRLR0 |= SPI_CTRLR0_SCPOL|SPI_CTRLR0_SCPH;
1145 break;
1146 }
1147 SPI->SSIENR = 1;
1148 break;
1149 }
1150 }
1151