1:
12:
13:
17:
18:
19:
#include "AG903_errno.h"
20:
#include "AG903_intno.h"
21:
#include "ssp/sspmgr.h"
22:
#include "ssp/sspprm.h"
23:
#include "int/intmgr.h"
24:
#include "dmac/dmacprm.h"
25:
#include "sys/sscprm.h"
26:
27:
28:
#define AG903_SSP_TXQUE_ARY_LEN (
AG903_SSP_TXQUE_NUM+1)
29:
#define AG903_SSP_RXQUE_ARY_LEN (
AG903_SSP_RXQUE_NUM+1)
30:
#if AG903_SSP_TXQUE_ARY_LEN <= 1
31:
#error AG903_SSP_TXQUE_ARY_LEN
32:
#endif
33:
#if AG903_SSP_RXQUE_ARY_LEN <= 1
34:
#error AG903_SSP_RXQUE_ARY_LEN
35:
#endif
36:
37:
38:
39:
typedef void (*AG903_SSPMgrIntHdr)(
void);
40:
41:
typedef struct _AG903_SSPMgrQue{
42: uint8_t* buf;
43: uint32_t size;
44: } AG903_SSPMgrQue;
45:
46:
typedef struct _AG903_SSPMgrRxQue{
47: AG903_SSPMgrQue que[AG903_SSP_RXQUE_ARY_LEN];
48: uint32_t wp;
49: uint32_t rp;
50: } AG903_SSPMgrRxQue;
51:
52:
typedef struct _AG903_SSPMgrTxQue{
53: AG903_SSPMgrQue que[AG903_SSP_TXQUE_ARY_LEN];
54: uint32_t wp;
55: uint32_t rp;
56: } AG903_SSPMgrTxQue;
57:
58:
typedef struct _AG903_SSPMgrTransferStat{
59: uint8_t* buf;
60: uint8_t* bufp;
61: uint32_t size;
62: uint32_t cnt;
63: } AG903_SSPMgrTransferStat;
64:
65:
typedef struct _AG903_SSPMgrChStat{
66: AG903_SSPMgrTransferStat tx;
67: AG903_SSPMgrTransferStat rx;
68: int32_t hdrid;
69: uint8_t format;
70: uint8_t wordlen;
71: uint8_t slave;
72: uint8_t tx_thod;
73: uint8_t rx_thod;
74: uint8_t pio;
75: uint8_t dma;
76: uint8_t reserve[1];
77: } AG903_SSPMgrChStat;
78:
79:
typedef struct _AG903_SSPMgrRegStat{
80:
AG903_SSPPrmIntCtrl ictrl;
81:
AG903_SSPPrmCtrl2 ctrl2;
82: } AG903_SSPMgrRegStat;
83:
84:
typedef struct _AG903_SSPMgrDmaStat{
85: uint8_t attach;
86: uint8_t stat;
87: uint8_t dma_ch;
88: uint8_t dma_if;
89: uint8_t ctrlwidth;
90: uint8_t ctrlbeat;
91: uint32_t txrxdr;
92: int32_t hdrid;
93: } AG903_SSPMgrDmaStat;
94:
95:
typedef struct _AG903_SSPMgrHandleStat{
96:
AG903_SSPMgrClbk clbk;
97: uint8_t lock;
98: uint8_t reserve[3];
99: } AG903_SSPMgrHandleStat;
100:
101:
102:
static AG903_SSPMgrChStat SspChStat[
AG903_SSP_CH_NUM];
103:
static AG903_SSPMgrRegStat SspRegStat[
AG903_SSP_CH_NUM];
104:
static AG903_SSPMgrDmaStat SspDmaStatTx[
AG903_SSP_CH_NUM];
105:
static AG903_SSPMgrDmaStat SspDmaStatRx[
AG903_SSP_CH_NUM];
106:
static AG903_SSPMgrSpiParam SspSpiParam[
AG903_SSP_CH_NUM];
107:
static AG903_SSPMgrHandleStat SspHandleStat[
AG903_SSP_CH_NUM];
108:
static AG903_SSPMgrRxQue SspRxQue[
AG903_SSP_CH_NUM];
109:
static AG903_SSPMgrTxQue SspTxQue[
AG903_SSP_CH_NUM];
110:
111:
112:
#define AG903_SSP_ENABLE_SEND (1<<0)
113:
#define AG903_SSP_ENABLE_RECEIVE (1<<1)
114:
115:
116:
#define AG903_SSP_DMA_SEND (1<<0)
117:
#define AG903_SSP_DMA_RECEIVE (1<<1)
118:
119:
120:
121:
#define AG903_SSP_DMA_DIR_TX (1<<0)
122:
#define AG903_SSP_DMA_DIR_RX (1<<1)
123:
124:
125:
#define AG903_SSP_DMA_STAT_STOP 0
126:
#define AG903_SSP_DMA_STAT_XMIT 1
127:
128:
static void SSPMgr_Init(uint8_t ch);
129:
static _Bool SSPMgr_CheckIdle(uint8_t ch);
130:
static _Bool SSPMgr_CheckBusy(uint8_t ch);
131:
static int32_t SSPMgr_CheckHandle(
AG903_SSPMgrHandle* handle, uint8_t* ch);
132:
static int32_t SSPMgr_SetTxData(uint8_t ch, _Bool que);
133:
static int32_t SSPMgr_GetRxData(uint8_t ch, _Bool que);
134:
static uint8_t* SSPMgr_SetTxFifo(uint8_t ch, uint8_t* buf, uint32_t size, uint32_t* setnum);
135:
static uint8_t* SSPMgr_GetRxFifo(uint8_t ch, uint8_t* buf, uint32_t size, uint32_t* getnum);
136:
static int32_t SSPMgr_DisableTransfer(uint8_t ch);
137:
static void SSPMgr_Inthdr0(
void);
138:
static void SSPMgr_Inthdr1(
void);
139:
static void SSPMgr_Inthdr2(
void);
140:
static void SSPMgr_Inthdr3(
void);
141:
static void SSPMgr_IntProcess(uint8_t ch);
142:
static void SSPMgr_IntSend(uint8_t ch, uint32_t* event);
143:
static void SSPMgr_IntReceive(uint8_t ch, uint32_t* event);
144:
static int32_t SSPMgr_SetTxQue(uint8_t ch, AG903_SSPMgrQue* que);
145:
static int32_t SSPMgr_GetTxQue(uint8_t ch, AG903_SSPMgrQue* que);
146:
static uint32_t SSPMgr_GetNextTxQuePoint(uint32_t current);
147:
static void SSPMgr_GetTxQueEntry(uint8_t ch, uint32_t* entry);
148:
static void SSPMgr_ClearTxQue(uint8_t ch);
149:
static int32_t SSPMgr_SetRxQue(uint8_t ch, AG903_SSPMgrQue* que);
150:
static int32_t SSPMgr_GetRxQue(uint8_t ch, AG903_SSPMgrQue* que);
151:
static uint32_t SSPMgr_GetNextRxQuePoint(uint32_t current);
152:
static void SSPMgr_GetRxQueEntry(uint8_t ch, uint32_t* entry);
153:
static void SSPMgr_ClearRxQue(uint8_t ch);
154:
155:
static int32_t SSPMgr_WriteTxFifoBest(uint8_t ch,
const void* buf, uint32_t num);
156:
static int32_t SSPMgr_ReadRxFifoBest(uint8_t ch,
void* buf, uint32_t num);
157:
static int32_t SSPMgr_SendDma(uint8_t ch,
const void* buf, uint32_t num);
158:
static int32_t SSPMgr_ReceiveDma(uint8_t ch,
void* buf, uint32_t num);
159:
static int32_t SSPMgr_DisableDma(uint8_t ch, uint32_t dma_dir);
160:
static int32_t SSPMgr_SpiSendTemplate(uint8_t ch,
const void* buf, uint32_t num, uint8_t dma_tx_enable);
161:
static int32_t SSPMgr_SpiReceiveTemplate(uint8_t ch,
void* buf, uint32_t num, uint8_t dma_rx_enable);
162:
static int32_t SSPMgr_SpiSendReceiveTemplate(uint8_t ch,
const void *tx_buf, uint32_t tx_num,
void* rx_buf, uint32_t rx_num, uint8_t dma_tx_enable, uint8_t dma_rx_enable);
163:
static void SSPMgr_SetDmaInterface(uint8_t ssp_ch, uint8_t dma_if, uint8_t dir);
164:
static int32_t SSPMgr_AttachDma(uint8_t ch, uint8_t dma_dir, uint8_t dma_ch, uint8_t dma_if);
165:
static int32_t SSPMgr_DetachDma(uint8_t ch, uint8_t dma_dir);
166:
static int32_t SSPMgr_SetDmaBeat(uint8_t ch, uint8_t dma_dir, uint8_t beat);
167:
static void SSPMgr_IntHdr0TxDma(
void);
168:
static void SSPMgr_IntHdr0RxDma(
void);
169:
static void SSPMgr_IntHdr1TxDma(
void);
170:
static void SSPMgr_IntHdr1RxDma(
void);
171:
static void SSPMgr_IntHdr2TxDma(
void);
172:
static void SSPMgr_IntHdr2RxDma(
void);
173:
static void SSPMgr_IntHdr3TxDma(
void);
174:
static void SSPMgr_IntHdr3RxDma(
void);
175:
static void SSPMgr_IntProcessDma(uint8_t ch, uint8_t dma_dir);
176:
static int32_t SSPMgr_IsSpiFlashLike(uint8_t ch);
177:
178:
static const AG903_SSPMgrIntHdr SspIntHdr[
AG903_SSP_CH_NUM] =
179: { SSPMgr_Inthdr0, SSPMgr_Inthdr1, SSPMgr_Inthdr2, SSPMgr_Inthdr3 };
180:
181:
192: int32_t
AG903_SSPMgrInit(uint8_t ch)
193: {
194:
AG903_INTMgrHdrPrm inthdr;
195: int32_t retval =
AG903_ENONE;
196: int32_t hdrid;
197:
198:
if(
AG903_SSP_CH_NUM <= ch) {
199:
return -
AG903_EINVAL;
200: }
201:
202: SSPMgr_Init(ch);
203:
204:
if(0 >= SspChStat[ch].hdrid) {
205: inthdr.atr =
AG903_INT_HLNG;
206: inthdr.intno =
AG903_IRQ12_SSP0+ch;
207: inthdr.func = (
void*)SspIntHdr[ch];
208: hdrid =
AG903_INTMgrSetHandler(&inthdr);
209:
if(0 >= hdrid) {
210:
return -
AG903_EFAULT;
211: }
212: SspChStat[ch].hdrid = hdrid;
213: }
214:
215:
AG903_INTMgrEnableInt(
AG903_IRQ12_SSP0+ch);
216:
217:
return retval;
218: }
219:
220:
230: int32_t
AG903_SSPMgrGetHandle(uint8_t ch,
AG903_SSPMgrHandle** handle)
231: {
232: int32_t retval =
AG903_ENONE;
233:
234:
if( (
AG903_SSP_CH_NUM <= ch) ||
235: (NULL == handle) ) {
236:
return -
AG903_EINVAL;
237: }
238:
if(
true == SspHandleStat[ch].lock) {
239:
return -
AG903_EBUSY;
240: }
241:
242: SspHandleStat[ch].lock =
true;
243:
244: (*handle) = (
AG903_SSPMgrHandle*)&SspHandleStat[ch];
245:
246:
return retval;
247: }
248:
249:
259: int32_t
AG903_SSPMgrReleaseHandle(
AG903_SSPMgrHandle* handle)
260: {
261: int32_t retval =
AG903_ENONE;
262: _Bool idle;
263: uint8_t ch;
264:
265: retval = SSPMgr_CheckHandle(handle, &ch);
266:
if(
AG903_ENONE != retval) {
267:
return -
AG903_EINVAL;
268: }
269: idle = SSPMgr_CheckIdle(ch);
270:
if(
true != idle) {
271:
return -
AG903_EBUSY;
272: }
273:
274: SspHandleStat[ch].lock =
false;
275:
276:
return retval;
277: }
278:
279:
289: int32_t
AG903_SSPMgrSetCallback(
AG903_SSPMgrHandle* handle,
AG903_SSPMgrClbk clbk)
290: {
291: int32_t retval =
AG903_ENONE;
292: uint8_t ch;
293:
294: retval = SSPMgr_CheckHandle(handle, &ch);
295:
if(
AG903_ENONE != retval) {
296:
return -
AG903_EINVAL;
297: }
298:
299: SspHandleStat[ch].clbk = clbk;
300:
301:
return retval;
302: }
303:
304:
315: int32_t
AG903_SSPMgrSetSspMode(
AG903_SSPMgrHandle* handle,
AG903_SSPMgrSspParam* param)
316: {
317:
AG903_SSPPrmCtrl ctrl = {0};
318: int32_t retval =
AG903_ENONE;
319: _Bool idle;
320: uint8_t ch;
321:
322: retval = SSPMgr_CheckHandle(handle, &ch);
323:
if(
AG903_ENONE != retval) {
324:
return -
AG903_EINVAL;
325: }
326:
if(NULL == param) {
327:
return -
AG903_EINVAL;
328: }
329:
if( (
AG903_SSP_SDL_MAX < param->wordlen) ||
330: (
AG903_SSP_SSPDIV_MIN > param->clkdiv) ||
331: (param->clkdiv & 0x01) ){
332:
return -
AG903_EINVAL;
333: }
334: idle = SSPMgr_CheckIdle(ch);
335:
if(
true != idle) {
336:
return -
AG903_EBUSY;
337: }
338:
339: ctrl.format = AG903_SSP_FORMAT_SSP;
340:
if(
true == param->slave) {
341: ctrl.opm = AG903_SSP_OPM_SLAVE;
342: }
343:
else {
344: ctrl.opm = AG903_SSP_OPM_MASTER;
345: }
346: ctrl.sdl = param->wordlen-1;
347: ctrl.sclk_div = (param->clkdiv>>1)-1;
348:
349:
AG903_SSPPrmSetControl(ch, &ctrl);
350:
351: SspChStat[ch].format = AG903_SSP_FORMAT_SSP;
352: SspChStat[ch].wordlen = param->wordlen;
353: SspChStat[ch].slave = param->slave;
354: SspChStat[ch].tx_thod =
AG903_SSP_TXFIFO_THRESHOLD;
355: SspChStat[ch].rx_thod =
AG903_SSP_RXFIFO_THRESHOLD;
356:
357:
return retval;
358: }
359:
360:
371: int32_t
AG903_SSPMgrSetSpiMode(
AG903_SSPMgrHandle* handle,
AG903_SSPMgrSpiParam* param)
372: {
373:
AG903_SSPPrmCtrl ctrl = {0};
374:
AG903_SSPPrmCtrl2 ctrl2;
375: int32_t retval =
AG903_ENONE;
376: _Bool idle;
377: uint8_t ch;
378:
379: retval = SSPMgr_CheckHandle(handle, &ch);
380:
if(
AG903_ENONE != retval) {
381:
return -
AG903_EINVAL;
382: }
383:
if(NULL == param) {
384:
return -
AG903_EINVAL;
385: }
386:
if( (
AG903_SSP_SDL_MAX < param->wordlen) ||
387: (
AG903_SSP_SPIDIV_MIN > param->clkdiv) ||
388: (0x01 & param->clkdiv) ||
389: (AG903_SSP_POL_TYPENUM <= param->polarity) ||
390: (AG903_SSP_FIRSTBIT_TYPENUM <= param->firstbit) ||
391: (AG903_SSP_SPICLK_MODENUM <= param->sclktype) ){
392:
return -
AG903_EINVAL;
393: }
394: idle = SSPMgr_CheckIdle(ch);
395:
if(
true != idle) {
396:
return -
AG903_EBUSY;
397: }
398:
399: ctrl.format = AG903_SSP_FORMAT_SPI;
400:
if (param->flash) {
401: ctrl.spi_flash = 1;
402: }
403:
if(AG903_SSP_FIRSTBIT_LSB == param->firstbit) {
404: ctrl.lsb = 1;
405: }
406:
if(AG903_SSP_POL_NEGATIVE == param->polarity) {
407: ctrl.spi_fspo = 0;
408: }
409:
if(
true == param->slave) {
410: ctrl.opm = AG903_SSP_OPM_SLAVE;
411: }
412:
else {
413: ctrl.opm = AG903_SSP_OPM_MASTER;
414: }
415:
switch(param->sclktype) {
416:
case AG903_SSP_SPICLK_MODE0:
417: ctrl.sclkpo = 0;
418: ctrl.sclkph = 0;
419:
break;
420:
case AG903_SSP_SPICLK_MODE1:
421: ctrl.sclkpo = 0;
422: ctrl.sclkph = 1;
423:
break;
424:
case AG903_SSP_SPICLK_MODE2:
425: ctrl.sclkpo = 1;
426: ctrl.sclkph = 0;
427:
break;
428:
case AG903_SSP_SPICLK_MODE3:
429: ctrl.sclkpo = 1;
430: ctrl.sclkph = 1;
431:
break;
432:
default:
433:
434:
break;
435: }
436: ctrl.sdl = param->wordlen-1;
437: ctrl.sclk_div = (param->clkdiv>>1)-1;
438:
439:
AG903_SSPPrmSetControl(ch, &ctrl);
440:
441:
AG903_SSPPrmGetControl2(ch, &ctrl2);
442: ctrl2.fsos = 0;
443: ctrl2.fs = (AG903_SSP_POL_NEGATIVE==param->polarity) ? 1 : 0;
444:
AG903_SSPPrmSetControl2(ch, &ctrl2);
445:
446: SspChStat[ch].format = AG903_SSP_FORMAT_SPI;
447: SspChStat[ch].wordlen = param->wordlen;
448: SspChStat[ch].slave = param->slave;
449: SspChStat[ch].tx_thod =
AG903_SSP_TXFIFO_THRESHOLD;
450: SspChStat[ch].rx_thod =
AG903_SSP_RXFIFO_THRESHOLD;
451:
452: SspSpiParam[ch] = *param;
453:
454:
return retval;
455: }
456:
457:
468: int32_t
AG903_SSPMgrSetI2sMode(
AG903_SSPMgrHandle* handle,
AG903_SSPMgrI2sParam* param)
469: {
470:
AG903_SSPPrmCtrl ctrl = {0};
471: int32_t retval =
AG903_ENONE;
472: _Bool idle;
473: uint8_t ch;
474:
475: retval = SSPMgr_CheckHandle(handle, &ch);
476:
if(
AG903_ENONE != retval) {
477:
return -
AG903_EINVAL;
478: }
479:
if(NULL == param) {
480:
return -
AG903_EINVAL;
481: }
482:
if( (
AG903_SSP_SDL_MAX < param->wordlen) ||
483: (
AG903_SSP_SSPDIV_MIN > param->clkdiv) ||
484: (0x01 & param->clkdiv) ||
485: (AG903_SSP_POL_TYPENUM <= param->polarity) ||
486: (AG903_SSP_FIRSTBIT_TYPENUM <= param->firstbit) ||
487: (AG903_SSP_JUSTIFIED_TYPENUM <= param->justified) ) {
488:
return -
AG903_EINVAL;
489: }
490: idle = SSPMgr_CheckIdle(ch);
491:
if(
true != idle) {
492:
return -
AG903_EBUSY;
493: }
494:
495: ctrl.format = AG903_SSP_FORMAT_I2S;
496: ctrl.fsdist = 1;
497:
if(AG903_SSP_FIRSTBIT_LSB == param->firstbit) {
498: ctrl.lsb = 1;
499: }
500:
if(AG903_SSP_POL_NEGATIVE == param->polarity) {
501: ctrl.fspo = 1;
502: }
503:
if(AG903_SSP_RIGHT_JUSTIFIED == param->justified) {
504: ctrl.fsjstfy = 1;
505: }
506:
if(
true == param->slave) {
507:
if(
true == param->mono) {
508: ctrl.opm = AG903_SSP_OPM_SLAVE;
509: }
510:
else {
511: ctrl.opm = AG903_SSP_OPM_SLAVE_STEREO;
512: }
513: }
514:
else {
515:
if(
true == param->mono) {
516: ctrl.opm = AG903_SSP_OPM_MASTER;
517: }
518:
else {
519: ctrl.opm = AG903_SSP_OPM_MASTER_STEREO;
520: }
521: }
522: ctrl.sdl = param->wordlen-1;
523: ctrl.pdl = param->padlen;
524: ctrl.sclk_div = (param->clkdiv>>1)-1;
525:
526:
AG903_SSPPrmSetControl(ch, &ctrl);
527:
528: SspChStat[ch].format = AG903_SSP_FORMAT_I2S;
529: SspChStat[ch].wordlen = param->wordlen;
530: SspChStat[ch].slave = param->slave;
531: SspChStat[ch].tx_thod =
AG903_SSP_TXFIFO_THRESHOLD;
532: SspChStat[ch].rx_thod =
AG903_SSP_RXFIFO_THRESHOLD;
533:
534:
return retval;
535: }
536:
537:
548: int32_t
AG903_SSPMgrSetSpdifMode(
AG903_SSPMgrHandle* handle,
AG903_SSPMgrSpdifParam* param)
549: {
550:
AG903_SSPPrmCtrl ctrl = {0};
551: int32_t retval =
AG903_ENONE;
552: _Bool idle;
553: uint8_t ch;
554:
555: retval = SSPMgr_CheckHandle(handle, &ch);
556:
if(
AG903_ENONE != retval) {
557:
return -
AG903_EINVAL;
558: }
559:
if(NULL == param) {
560:
return -
AG903_EINVAL;
561: }
562:
if((16!=param->datalen)&&(20!=param->datalen)&&(24!=param->datalen)) {
563:
return -
AG903_EINVAL;
564: }
565: idle = SSPMgr_CheckIdle(ch);
566:
if(
true != idle) {
567:
return -
AG903_EBUSY;
568: }
569: ctrl.format = AG903_SSP_FORMAT_SPDIF;
570:
if(
false == param->validity) {
571: ctrl.validity = 1;
572: }
573: ctrl.sdl = param->datalen-1;
574:
575:
AG903_SSPPrmSetControl(ch, &ctrl);
576:
577: SspChStat[ch].format = AG903_SSP_FORMAT_SPDIF;
578: SspChStat[ch].wordlen = param->datalen;
579: SspChStat[ch].slave =
false;
580: SspChStat[ch].tx_thod =
AG903_SSP_TXFIFO_THRESHOLD;
581: SspChStat[ch].rx_thod =
AG903_SSP_RXFIFO_THRESHOLD;
582:
583:
return retval;
584: }
585:
586:
595: int32_t
AG903_SSPMgrSetSpdifCbit(
AG903_SSPMgrHandle* handle,
AG903_SSPMgrSpdifCbit* cbit)
596: {
597: int32_t retval =
AG903_ENONE;
598: uint32_t status_0;
599: uint32_t status_1;
600: uint8_t ch;
601:
602: retval = SSPMgr_CheckHandle(handle, &ch);
603:
if(
AG903_ENONE != retval) {
604:
return -
AG903_EINVAL;
605: }
606:
if(NULL == cbit) {
607:
return -
AG903_EINVAL;
608: }
609:
610: status_0 = (uint32_t)(cbit->status[0]);
611: status_0 |= (uint32_t)(cbit->status[1]<<8);
612: status_0 |= (uint32_t)(cbit->status[2]<<16);
613: status_0 |= (uint32_t)(cbit->status[3]<<24);
614:
615: status_1 = (uint32_t)(cbit->status[4]);
616:
617:
AG903_SSPPrmSetStatusBit(ch, status_0, status_1);
618:
619:
return retval;
620: }
621:
622:
633: int32_t
AG903_SSPMgrSetSpdifUbit(
AG903_SSPMgrHandle* handle, uint8_t offset, uint32_t ubit)
634: {
635: int32_t retval =
AG903_ENONE;
636: uint8_t ch;
637:
638: retval = SSPMgr_CheckHandle(handle, &ch);
639:
if(
AG903_ENONE != retval) {
640:
return -
AG903_EINVAL;
641: }
642:
if(
AG903_SSP_USERBIT_REGMAX <= offset) {
643:
return -
AG903_EINVAL;
644: }
645:
646:
AG903_SSPPrmSetUserBit(ch, offset, ubit);
647:
648:
return retval;
649: }
650:
651:
660: int32_t
AG903_SSPMgrSetSpdifUbitALL(
AG903_SSPMgrHandle* handle,
AG903_SSPMgrSpdifUbit* ubit)
661: {
662: int32_t retval =
AG903_ENONE;
663: uint8_t loop;
664: uint8_t ch;
665:
666: retval = SSPMgr_CheckHandle(handle, &ch);
667:
if(
AG903_ENONE != retval) {
668:
return -
AG903_EINVAL;
669: }
670:
if(NULL == ubit) {
671:
return -
AG903_EINVAL;
672: }
673:
674:
for(loop=0; loop<
AG903_SSP_USERBIT_REGMAX; loop++) {
675:
AG903_SSPPrmSetUserBit(ch, loop, ubit->userbit[loop]);
676: }
677:
678:
return retval;
679: }
680:
681:
700: int32_t
AG903_SSPMgrSetSendBuf(
AG903_SSPMgrHandle* handle, uint8_t* buf, uint32_t size)
701: {
702: AG903_SSPMgrQue que;
703: int32_t retval =
AG903_ENONE;
704: uint32_t status;
705: uint32_t div;
706: uint8_t enable;
707: uint8_t ch;
708: uint8_t entry;
709: uint8_t threshold;
710:
711: retval = SSPMgr_CheckHandle(handle, &ch);
712:
if(
AG903_ENONE != retval) {
713:
return -
AG903_EINVAL;
714: }
715:
if((NULL == buf) || (0 >= size)) {
716:
return -
AG903_EINVAL;
717: }
718:
if(0 != SspChStat[ch].dma) {
719:
return -
AG903_EPERM;
720: }
721:
722: div = SspChStat[ch].wordlen / 8;
723:
if(0 != (SspChStat[ch].wordlen%8)) {
724: div++;
725: }
726:
727:
do {
728: que.size = size*div;
729: que.buf = buf;
730: retval = SSPMgr_SetTxQue(ch, &que);
731:
if(
AG903_ENONE != retval) {
732:
break;
733: }
734:
735:
if(AG903_SSP_ENABLE_SEND & SspChStat[ch].pio) {
736:
break;
737: }
738:
739: retval = SSPMgr_SetTxData(ch,
true);
740:
if(
AG903_ENONE != retval) {
741:
break;
742: }
743:
AG903_SSPPrmGetTxFifoEntry(ch, &entry);
744:
if(
AG903_SSP_TXFIFO_THRESHOLD >= entry) {
745: threshold = 1;
746: }
747:
else {
748: threshold =
AG903_SSP_TXFIFO_THRESHOLD;
749: }
750: SspChStat[ch].pio |= AG903_SSP_ENABLE_SEND;
751:
AG903_SSPPrmSetTxFifoThreshold(ch, threshold);
752:
AG903_SSPPrmCheckEnable(ch, &enable);
753:
if(0 == enable) {
754:
AG903_SSPPrmGetIntStatus(ch, &status);
755: }
756:
else {
757:
AG903_SSPPrmEnableTxInt(ch);
758: }
759: }
while(0);
760:
761:
return retval;
762: }
763:
764:
784: int32_t
AG903_SSPMgrSetReceiveBuf(
AG903_SSPMgrHandle* handle, uint8_t* buf, uint32_t size)
785: {
786: AG903_SSPMgrQue que;
787: int32_t retval =
AG903_ENONE;
788: uint32_t status;
789: uint32_t div;
790: uint8_t enable;
791: uint8_t ch;
792:
793: retval = SSPMgr_CheckHandle(handle, &ch);
794:
if(
AG903_ENONE != retval) {
795:
return -
AG903_EINVAL;
796: }
797:
if((NULL == buf) || (0 >= size)) {
798:
return -
AG903_EINVAL;
799: }
800:
if(0 != SspChStat[ch].dma) {
801:
return -
AG903_EPERM;
802: }
803:
804: div = SspChStat[ch].wordlen / 8;
805:
if(0 != (SspChStat[ch].wordlen%8)) {
806: div++;
807: }
808:
809:
do {
810: que.size = size*div;
811: que.buf = buf;
812: retval = SSPMgr_SetRxQue(ch, &que);
813:
if(
AG903_ENONE != retval) {
814:
break;
815: }
816:
817:
if(AG903_SSP_ENABLE_RECEIVE & SspChStat[ch].pio) {
818:
break;
819: }
820:
821: retval = SSPMgr_GetRxData(ch,
true);
822:
if(
AG903_ENONE != retval) {
823:
break;
824: }
825: SspChStat[ch].pio |= AG903_SSP_ENABLE_RECEIVE;
826:
AG903_SSPPrmSetRxFifoThreshold(ch,
AG903_SSP_RXFIFO_THRESHOLD);
827:
828:
AG903_SSPPrmCheckEnable(ch, &enable);
829:
if(0 == enable) {
830:
AG903_SSPPrmGetIntStatus(ch, &status);
831: }
832:
else {
833:
AG903_SSPPrmEnableRxInt(ch);
834: }
835: }
while(0);
836:
837:
return retval;
838: }
839:
840:
859: int32_t
AG903_SSPMgrEnableDmaMode(
AG903_SSPMgrHandle* handle, uint8_t mode)
860: {
861: int32_t retval =
AG903_ENONE;
862: _Bool idle;
863: uint8_t ch;
864:
865: retval = SSPMgr_CheckHandle(handle, &ch);
866:
if(
AG903_ENONE != retval) {
867:
return -
AG903_EINVAL;
868: }
869:
if(0 != SspChStat[ch].pio) {
870:
return -
AG903_EPERM;
871: }
872:
873: idle = SSPMgr_CheckIdle(ch);
874:
if(
true != idle) {
875:
return -
AG903_EBUSY;
876: }
877:
878: SspChStat[ch].dma = mode;
879:
880:
return retval;
881: }
882:
883:
893: int32_t
AG903_SSPMgrDisableDmaMode(
AG903_SSPMgrHandle* handle)
894: {
895: int32_t retval =
AG903_ENONE;
896: int32_t result;
897: _Bool idle;
898: uint8_t ch;
899:
900: result = SSPMgr_CheckHandle(handle, &ch);
901:
if(
AG903_ENONE != result) {
902:
return -
AG903_EINVAL;
903: }
904: idle = SSPMgr_CheckIdle(ch);
905:
if(
true != idle) {
906:
return -
AG903_EBUSY;
907: }
908:
909: SspChStat[ch].dma = 0;
910:
911:
return retval;
912: }
913:
914:
926: int32_t
AG903_SSPMgrEnableTransfer(
AG903_SSPMgrHandle* handle)
927: {
928:
AG903_SSPPrmIntCtrl ictrl;
929:
AG903_SSPPrmCtrl2 ctrl2;
930: int32_t retval =
AG903_ENONE;
931: uint32_t status;
932: _Bool idle;
933: uint8_t ch;
934:
935: retval = SSPMgr_CheckHandle(handle, &ch);
936:
if(
AG903_ENONE != retval) {
937:
return -
AG903_EINVAL;
938: }
939: idle = SSPMgr_CheckIdle(ch);
940:
if(
true != idle) {
941:
return -
AG903_EBUSY;
942: }
943:
if( (0 != SspChStat[ch].dma) && (0 != SspChStat[ch].pio) ) {
944:
return -
AG903_EPERM;
945: }
946:
if( (0 == SspChStat[ch].dma) && (0 == SspChStat[ch].pio) ) {
947:
return -
AG903_EPERM;
948: }
949:
950:
AG903_SSPPrmGetIntStatus(ch, &status);
951:
952:
AG903_SSPPrmGetIntControl(ch, &ictrl);
953:
AG903_SSPPrmGetControl2(ch, &ctrl2);
954:
955:
if(0 != SspChStat[ch].dma) {
956: ictrl.rfthien = 0;
957: ictrl.rforien = 0;
958: ictrl.tfthien = 0;
959: ictrl.tfurien = 0;
960:
if(AG903_SSP_DMA_RECEIVE & SspChStat[ch].dma) {
961: ctrl2.txdoe = 0;
962: ictrl.tfdmaen = 0;
963: ictrl.rfdmaen = 1;
964: ctrl2.txen = 0;
965: ctrl2.rxen = 1;
966: }
967:
if(AG903_SSP_DMA_SEND & SspChStat[ch].dma) {
968: ctrl2.txdoe = 1;
969: ictrl.tfdmaen = 1;
970: ictrl.rfdmaen = 0;
971: ctrl2.txen = 1;
972: ctrl2.rxen = 0;
973: }
974: }
975:
else {
976: ictrl.tfdmaen = 0;
977: ictrl.rfdmaen = 0;
978:
if(AG903_SSP_ENABLE_RECEIVE & SspChStat[ch].pio) {
979: ctrl2.txdoe = 0;
980: ctrl2.txen = 0;
981: ctrl2.rxen = 1;
982: ictrl.tfthien = 0;
983: ictrl.tfurien = 0;
984: ictrl.rfthien = 1;
985: ictrl.rforien = 1;
986: }
987:
if(AG903_SSP_ENABLE_SEND & SspChStat[ch].pio) {
988: ctrl2.txdoe = 1;
989: ctrl2.txen = 1;
990: ctrl2.rxen = 0;
991: ictrl.tfthien = 1;
992: ictrl.tfurien = 1;
993: ictrl.rfthien = 0;
994: ictrl.rforien = 0;
995: }
996: }
997:
998: ctrl2.sspen = 1;
999:
1000:
AG903_SSPPrmSetIntControl(ch, &ictrl);
1001:
AG903_SSPPrmSetControl2(ch, &ctrl2);
1002:
1003:
return retval;
1004: }
1005:
1006:
1017: int32_t
AG903_SSPMgrDisableTransfer(
AG903_SSPMgrHandle* handle)
1018: {
1019: int32_t retval =
AG903_ENONE;
1020: uint8_t ch;
1021:
1022: retval = SSPMgr_CheckHandle(handle, &ch);
1023:
if(
AG903_ENONE != retval) {
1024:
return -
AG903_EINVAL;
1025: }
1026:
1027: retval = SSPMgr_DisableTransfer(ch);
1028:
1029:
return retval;
1030: }
1031:
1032:
1041: int32_t
AG903_SSPMgrGetStatus(
AG903_SSPMgrHandle* handle,
AG903_SSPMgrStatus* status)
1042: {
1043:
AG903_SSPPrmStatus getsts;
1044: int32_t retval =
AG903_ENONE;
1045: uint8_t ch;
1046:
1047:
if(NULL == status) {
1048:
return -
AG903_EINVAL;
1049: }
1050: retval = SSPMgr_CheckHandle(handle, &ch);
1051:
if(
AG903_ENONE != retval) {
1052:
return -
AG903_EINVAL;
1053: }
1054:
1055:
AG903_SSPPrmGetStatus(ch, &getsts);
1056: status->txfifo_num = getsts.txfifo_num;
1057: status->rxfifo_num = getsts.rxfifo_num;
1058: status->busy = getsts.busy;
1059: status->txfifo_notfull = getsts.txfifo_notfull;
1060: status->rxfifo_full = getsts.rxfifo_full;
1061:
1062:
return retval;
1063: }
1064:
1065:
1074: int32_t
AG903_SSPMgrClearTxQue(
AG903_SSPMgrHandle* handle)
1075: {
1076: int32_t retval =
AG903_ENONE;
1077: uint8_t ch;
1078:
1079: retval = SSPMgr_CheckHandle(handle, &ch);
1080:
if(
AG903_ENONE != retval) {
1081:
return -
AG903_EINVAL;
1082: }
1083:
1084: SSPMgr_ClearTxQue(ch);
1085:
1086:
return retval;
1087: }
1088:
1089:
1098: int32_t
AG903_SSPMgrClearRxQue(
AG903_SSPMgrHandle* handle)
1099: {
1100: int32_t retval =
AG903_ENONE;
1101: uint8_t ch;
1102:
1103: retval = SSPMgr_CheckHandle(handle, &ch);
1104:
if(
AG903_ENONE != retval) {
1105:
return -
AG903_EINVAL;
1106: }
1107:
1108: SSPMgr_ClearRxQue(ch);
1109:
1110:
return retval;
1111: }
1112:
1113:
1122: int32_t
AG903_SSPMgrGetQueStatus(
AG903_SSPMgrHandle* handle,
AG903_SSPMgrQueStatus* status)
1123: {
1124: int32_t retval =
AG903_ENONE;
1125: uint32_t div;
1126: uint32_t remain;
1127: uint8_t ch;
1128:
1129:
if(NULL == status) {
1130:
return -
AG903_EINVAL;
1131: }
1132: retval = SSPMgr_CheckHandle(handle, &ch);
1133:
if(
AG903_ENONE != retval) {
1134:
return -
AG903_EINVAL;
1135: }
1136:
1137: div = SspChStat[ch].wordlen / 8;
1138:
if(0 != (SspChStat[ch].wordlen%8)) {
1139: div++;
1140: }
1141:
1142: remain = SspChStat[ch].tx.size - SspChStat[ch].tx.cnt;
1143: status->txremain = remain/div;
1144:
if(0 != (remain%div)) {
1145: status->txremain ++;
1146: }
1147: status->received = (SspChStat[ch].rx.cnt/div);
1148: SSPMgr_GetTxQueEntry(ch, &status->txquecnt);
1149: SSPMgr_GetRxQueEntry(ch, &status->rxquecnt);
1150:
1151:
return retval;
1152: }
1153:
1154:
1163: int32_t
AG903_SSPMgrClearTxFifo(
AG903_SSPMgrHandle* handle)
1164: {
1165: int32_t retval =
AG903_ENONE;
1166: uint8_t ch;
1167:
1168: retval = SSPMgr_CheckHandle(handle, &ch);
1169:
if(
AG903_ENONE != retval) {
1170:
return -
AG903_EINVAL;
1171: }
1172:
1173:
AG903_SSPPrmClearTxFifo(ch);
1174:
1175:
return retval;
1176: }
1177:
1178:
1187: int32_t
AG903_SSPMgrClearRxFifo(
AG903_SSPMgrHandle* handle)
1188: {
1189: int32_t retval =
AG903_ENONE;
1190: uint8_t ch;
1191:
1192: retval = SSPMgr_CheckHandle(handle, &ch);
1193:
if(
AG903_ENONE != retval) {
1194:
return -
AG903_EINVAL;
1195: }
1196:
1197:
AG903_SSPPrmClearRxFifo(ch);
1198:
1199:
return retval;
1200: }
1201:
1202:
1216: int32_t
AG903_SSPMgrSetTxFifoThreshold(
AG903_SSPMgrHandle* handle, uint8_t threshold)
1217: {
1218: int32_t retval =
AG903_ENONE;
1219: uint8_t ch;
1220: uint8_t enable;
1221:
1222: retval = SSPMgr_CheckHandle(handle, &ch);
1223:
if(
AG903_ENONE != retval) {
1224:
return -
AG903_EINVAL;
1225: }
1226:
1227:
if (0 >= threshold ||
AG903_SSP_FIFO_DEPTH < threshold) {
1228:
return -
AG903_EINVAL;
1229: }
1230:
1231:
AG903_SSPPrmCheckEnable(ch, &enable);
1232:
if (0 != enable) {
1233:
return -
AG903_EPERM;
1234: }
1235:
1236: SspChStat[ch].tx_thod = threshold;
1237:
AG903_SSPPrmSetTxFifoThreshold(ch, threshold);
1238:
1239:
return retval;
1240: }
1241:
1242:
1256: int32_t
AG903_SSPMgrSetRxFifoThreshold(
AG903_SSPMgrHandle* handle, uint8_t threshold)
1257: {
1258: int32_t retval =
AG903_ENONE;
1259: uint8_t ch;
1260: uint8_t enable;
1261:
1262: retval = SSPMgr_CheckHandle(handle, &ch);
1263:
if(
AG903_ENONE != retval) {
1264:
return -
AG903_EINVAL;
1265: }
1266:
1267:
if (0 >= threshold ||
AG903_SSP_FIFO_DEPTH < threshold) {
1268:
return -
AG903_EINVAL;
1269: }
1270:
1271:
AG903_SSPPrmCheckEnable(ch, &enable);
1272:
if (0 != enable) {
1273:
return -
AG903_EPERM;
1274: }
1275:
1276: SspChStat[ch].rx_thod = threshold;
1277:
AG903_SSPPrmSetRxFifoThreshold(ch, threshold);
1278:
1279:
return retval;
1280: }
1281:
1282:
1293: int32_t
AG903_SSPMgrReset(
AG903_SSPMgrHandle* handle)
1294: {
1295:
AG903_SSPPrmIntCtrl ictrl_clr = {0};
1296:
AG903_SSPPrmCtrl2 ctrl2_clr = {0};
1297: AG903_SSPMgrDmaStat dma_clr = {0};
1298:
AG903_SSPMgrSpiParam spi_clr = {0};
1299: int32_t retval =
AG903_ENONE;
1300: _Bool busy;
1301: uint8_t ch;
1302:
1303: retval = SSPMgr_CheckHandle(handle, &ch);
1304:
if(
AG903_ENONE != retval) {
1305:
return -
AG903_EINVAL;
1306: }
1307: busy = SSPMgr_CheckBusy(ch);
1308:
if(
true == busy) {
1309:
return -
AG903_EBUSY;
1310: }
1311:
1312: SSPMgr_DisableTransfer(ch);
1313:
AG903_SSPPrmClearTxFifo(ch);
1314:
AG903_SSPPrmClearRxFifo(ch);
1315:
1316:
AG903_SSPPrmReset(ch);
1317: SspChStat[ch].tx.buf = NULL;
1318: SspChStat[ch].tx.size = 0;
1319: SspChStat[ch].tx.cnt = 0;
1320: SspChStat[ch].rx.buf = NULL;
1321: SspChStat[ch].rx.size = 0;
1322: SspChStat[ch].rx.cnt = 0;
1323: SspRegStat[ch].ictrl = ictrl_clr;
1324: SspRegStat[ch].ctrl2 = ctrl2_clr;
1325: SspDmaStatTx[ch] = dma_clr;
1326: SspDmaStatRx[ch] = dma_clr;
1327: SspSpiParam[ch] = spi_clr;
1328: SSPMgr_ClearTxQue(ch);
1329: SSPMgr_ClearRxQue(ch);
1330:
1331:
return retval;
1332: }
1333:
1334:
1338:
static void SSPMgr_Init(uint8_t ch)
1339: {
1340:
if(
AG903_SSP_CH_NUM <= ch) {
1341:
return;
1342: }
1343:
1344: SspHandleStat[ch].lock =
false;
1345: SspHandleStat[ch].clbk = NULL;
1346: SspChStat[ch].tx.buf = NULL;
1347: SspChStat[ch].tx.size = 0;
1348: SspChStat[ch].tx.cnt = 0;
1349: SspChStat[ch].rx.buf = NULL;
1350: SspChStat[ch].rx.size = 0;
1351: SspChStat[ch].rx.cnt = 0;
1352: SspChStat[ch].format = AG903_SSP_FORMAT_SSP;
1353: SspChStat[ch].wordlen = 0;
1354: SspChStat[ch].slave =
false;
1355: SspChStat[ch].tx_thod = 2;
1356: SspChStat[ch].rx_thod = 2;
1357: SspChStat[ch].pio = 0;
1358: SspChStat[ch].dma = 0;
1359:
1360: SspRegStat[ch].ictrl.tfthod = 2;
1361: SspRegStat[ch].ictrl.rfthod = 2;
1362: SspRegStat[ch].ictrl.tfdmaen = 0;
1363: SspRegStat[ch].ictrl.rfdmaen = 0;
1364: SspRegStat[ch].ictrl.tfthien = 0;
1365: SspRegStat[ch].ictrl.rfthien = 0;
1366: SspRegStat[ch].ictrl.tfurien = 0;
1367: SspRegStat[ch].ictrl.rforien = 0;
1368: SspRegStat[ch].ctrl2.fsos = 0;
1369: SspRegStat[ch].ctrl2.fs = 0;
1370: SspRegStat[ch].ctrl2.txen = 0;
1371: SspRegStat[ch].ctrl2.rxen = 0;
1372: SspRegStat[ch].ctrl2.ssprst = 0;
1373: SspRegStat[ch].ctrl2.txfclr = 0;
1374: SspRegStat[ch].ctrl2.rxfclr = 0;
1375: SspRegStat[ch].ctrl2.txdoe = 0;
1376: SspRegStat[ch].ctrl2.sspen = 0;
1377:
1378: SspDmaStatTx[ch].attach = 0;
1379: SspDmaStatTx[ch].stat = AG903_SSP_DMA_STAT_STOP;
1380: SspDmaStatTx[ch].dma_ch = 3 + ch;
1381: SspDmaStatTx[ch].dma_if = 3 + ch;
1382: SspDmaStatTx[ch].ctrlwidth = 0;
1383: SspDmaStatTx[ch].ctrlbeat = 0;
1384: SspDmaStatTx[ch].txrxdr = 0xE0400018 + 0x100000*ch;
1385: SspDmaStatTx[ch].hdrid = -1;
1386:
1387: SspDmaStatRx[ch].attach = 0;
1388: SspDmaStatRx[ch].stat = AG903_SSP_DMA_STAT_STOP;
1389: SspDmaStatRx[ch].dma_ch = 4 + ch;
1390: SspDmaStatRx[ch].dma_if = 4 + ch;
1391: SspDmaStatRx[ch].ctrlwidth = 0;
1392: SspDmaStatRx[ch].ctrlbeat = 0;
1393: SspDmaStatRx[ch].txrxdr = 0xE0400018 + 0x100000*ch;
1394: SspDmaStatRx[ch].hdrid = -1;
1395:
1396: SspSpiParam[ch].clkdiv = 2;
1397: SspSpiParam[ch].wordlen = 8;
1398: SspSpiParam[ch].polarity = AG903_SSP_POL_NEGATIVE;
1399: SspSpiParam[ch].firstbit = AG903_SSP_FIRSTBIT_MSB;
1400: SspSpiParam[ch].slave =
false;
1401: SspSpiParam[ch].flash =
false;
1402:
1403: SSPMgr_ClearTxQue(ch);
1404: SSPMgr_ClearRxQue(ch);
1405:
1406:
return;
1407: }
1408:
1409:
1413:
static _Bool SSPMgr_CheckIdle(uint8_t ch)
1414: {
1415: _Bool retval=
false;
1416: uint8_t enable;
1417:
1418:
AG903_SSPPrmCheckEnable(ch, &enable);
1419:
if(0 == enable) {
1420: retval=
true;
1421: }
1422:
return retval;
1423: }
1424:
1425:
1429:
static _Bool SSPMgr_CheckBusy(uint8_t ch)
1430: {
1431:
AG903_SSPPrmStatus status;
1432: _Bool retval=
false;
1433:
1434:
AG903_SSPPrmGetStatus(ch, &status);
1435:
if(
true == status.busy) {
1436: retval =
true;
1437: }
1438:
return retval;
1439: }
1440:
1441:
1446:
static int32_t SSPMgr_CheckHandle(
AG903_SSPMgrHandle* handle, uint8_t* ch)
1447: {
1448: uint32_t get_ch;
1449:
1450: get_ch = ((uint32_t)handle - (uint32_t)SspHandleStat) /
sizeof(AG903_SSPMgrHandleStat);
1451:
1452:
if( (
AG903_SSP_CH_NUM <= get_ch) ||
1453: (&SspHandleStat[get_ch] != (AG903_SSPMgrHandleStat*)handle) ) {
1454:
return -
AG903_EINVAL;
1455: }
1456: (*ch) = (uint8_t)get_ch;
1457:
1458:
return AG903_ENONE;
1459: }
1460:
1461:
1466:
static int32_t SSPMgr_SetTxData(uint8_t ch, _Bool que)
1467: {
1468: AG903_SSPMgrQue txque;
1469: int32_t retval =
AG903_ENONE;
1470: uint32_t cnt;
1471:
1472:
if(
AG903_SSP_CH_NUM <= ch) {
1473:
return -
AG903_EINVAL;
1474: }
1475:
1476:
if(
true == que) {
1477: retval = SSPMgr_GetTxQue(ch, &txque);
1478:
if(
AG903_ENONE == retval) {
1479: SspChStat[ch].tx.buf = txque.buf;
1480: SspChStat[ch].tx.size = txque.size;
1481: SspChStat[ch].tx.bufp = SSPMgr_SetTxFifo(ch, txque.buf, txque.size, &SspChStat[ch].tx.cnt);
1482: }
1483: }
1484:
else {
1485:
if( (NULL != SspChStat[ch].tx.bufp) && (SspChStat[ch].tx.size > SspChStat[ch].tx.cnt) ){
1486: SspChStat[ch].tx.bufp = SSPMgr_SetTxFifo(ch, SspChStat[ch].tx.bufp,
1487: (SspChStat[ch].tx.size-SspChStat[ch].tx.cnt), &cnt);
1488: SspChStat[ch].tx.cnt += cnt;
1489: }
1490: }
1491:
1492:
return retval;
1493: }
1494:
1495:
1500:
static int32_t SSPMgr_GetRxData(uint8_t ch, _Bool que)
1501: {
1502: AG903_SSPMgrQue rxque;
1503: int32_t retval =
AG903_ENONE;
1504: uint32_t cnt;
1505:
1506:
if(
AG903_SSP_CH_NUM <= ch) {
1507:
return -
AG903_EINVAL;
1508: }
1509:
1510:
if(
true == que) {
1511: retval = SSPMgr_GetRxQue(ch, &rxque);
1512:
if(
AG903_ENONE == retval) {
1513: SspChStat[ch].rx.buf = rxque.buf;
1514: SspChStat[ch].rx.size = rxque.size;
1515: SspChStat[ch].rx.bufp = SSPMgr_GetRxFifo(ch, rxque.buf, rxque.size, &SspChStat[ch].rx.cnt);
1516: }
1517: }
1518:
else {
1519:
if( (NULL != SspChStat[ch].rx.bufp) && (SspChStat[ch].rx.size > SspChStat[ch].rx.cnt) ){
1520: SspChStat[ch].rx.bufp = SSPMgr_GetRxFifo(ch, SspChStat[ch].rx.bufp,
1521: (SspChStat[ch].rx.size-SspChStat[ch].rx.cnt), &cnt);
1522: SspChStat[ch].rx.cnt += cnt;
1523: }
1524: }
1525:
return retval;
1526: }
1527:
1528:
1535:
static uint8_t* SSPMgr_SetTxFifo(uint8_t ch, uint8_t* buf, uint32_t size, uint32_t* setnum)
1536: {
1537:
AG903_SSPPrmStatus status;
1538: uint8_t* bufp = buf;
1539: uint32_t cnt=0;
1540: uint32_t loop;
1541: uint32_t val=0;
1542:
1543:
if( (
AG903_SSP_CH_NUM <= ch) ||
1544: (NULL == buf) ||
1545: (NULL == setnum) ) {
1546:
return NULL;
1547: }
1548:
1549:
for(loop=0; loop<
AG903_SSP_FIFO_DEPTH; loop++) {
1550:
if(size <= cnt) {
1551:
break;
1552: }
1553:
AG903_SSPPrmGetStatus(ch, &status);
1554:
if(
true == status.txfifo_notfull) {
1555: val = (*bufp++);
1556: cnt ++;
1557:
if(8 < SspChStat[ch].wordlen) {
1558: val |= ((*bufp++)<<8);
1559: cnt ++;
1560: }
1561:
if(16 < SspChStat[ch].wordlen) {
1562: val |= ((*bufp++)<<16);
1563: cnt ++;
1564: }
1565:
if(24 < SspChStat[ch].wordlen) {
1566: val |= ((*bufp++)<<24);
1567: cnt ++;
1568: }
1569:
AG903_SSPPrmSetData(ch, val);
1570: }
1571:
else {
1572:
break;
1573: }
1574: }
1575:
1576: (*setnum) = cnt;
1577:
1578:
return bufp;
1579: }
1580:
1581:
1588:
static uint8_t* SSPMgr_GetRxFifo(uint8_t ch, uint8_t* buf, uint32_t size, uint32_t* getnum)
1589: {
1590:
AG903_SSPPrmStatus status;
1591: uint8_t* bufp = buf;
1592: uint32_t cnt=0;
1593: uint32_t loop;
1594: uint32_t val;
1595:
1596:
if( (
AG903_SSP_CH_NUM <= ch) ||
1597: (NULL == buf) ||
1598: (NULL == getnum) ) {
1599:
return NULL;
1600: }
1601:
1602:
for(loop=0; loop<
AG903_SSP_FIFO_DEPTH; loop++) {
1603:
if(size <= cnt) {
1604:
break;
1605: }
1606:
AG903_SSPPrmGetStatus(ch, &status);
1607:
if(0 < status.rxfifo_num) {
1608:
AG903_SSPPrmGetData(ch, &val);
1609: (*bufp++) = (uint8_t)val;
1610: cnt++;
1611:
if(8 < SspChStat[ch].wordlen) {
1612: (*bufp++) = (uint8_t)(val>>8);
1613: cnt++;
1614: }
1615:
if(16 < SspChStat[ch].wordlen) {
1616: (*bufp++) = (uint8_t)(val>>16);
1617: cnt++;
1618: }
1619:
if(24 < SspChStat[ch].wordlen) {
1620: (*bufp++) = (uint8_t)(val>>24);
1621: cnt++;
1622: }
1623: }
1624:
else {
1625:
break;
1626: }
1627: }
1628:
1629: (*getnum) = cnt;
1630:
1631:
return bufp;
1632: }
1633:
1634:
1638:
static int32_t SSPMgr_DisableTransfer(uint8_t ch)
1639: {
1640:
AG903_SSPPrmIntCtrl ictrl;
1641:
AG903_SSPPrmCtrl2 ctrl2;
1642: int32_t retval =
AG903_ENONE;
1643:
1644:
if(
AG903_SSP_CH_NUM <= ch) {
1645:
return -
AG903_EINVAL;
1646: }
1647:
1648: SspChStat[ch].dma = 0;
1649: SspChStat[ch].pio = 0;
1650:
1651:
AG903_SSPPrmGetIntControl(ch, &ictrl);
1652:
AG903_SSPPrmGetControl2(ch, &ctrl2);
1653:
1654: ictrl.rfthien = 0;
1655: ictrl.rforien = 0;
1656: ictrl.tfthien = 0;
1657: ictrl.tfurien = 0;
1658: ctrl2.txen = 0;
1659: ctrl2.rxen = 0;
1660: ctrl2.sspen = 0;
1661:
1662:
AG903_SSPPrmSetIntControl(ch, &ictrl);
1663:
AG903_SSPPrmSetControl2(ch, &ctrl2);
1664:
1665:
return retval;
1666: }
1667:
1668:
1669:
1672:
static void SSPMgr_Inthdr0(
void)
1673: {
1674: SSPMgr_IntProcess(0);
1675:
return;
1676: }
1677:
1678:
1681:
static void SSPMgr_Inthdr1(
void)
1682: {
1683: SSPMgr_IntProcess(1);
1684:
return;
1685: }
1686:
1687:
1690:
static void SSPMgr_Inthdr2(
void)
1691: {
1692: SSPMgr_IntProcess(2);
1693:
return;
1694: }
1695:
1696:
1699:
static void SSPMgr_Inthdr3(
void)
1700: {
1701: SSPMgr_IntProcess(3);
1702:
return;
1703: }
1704:
1705:
1709:
static void SSPMgr_IntProcess(uint8_t ch)
1710: {
1711: uint32_t event = 0;
1712: uint32_t intstatus;
1713:
1714:
AG903_SSPPrmGetIntStatus(ch, &intstatus);
1715:
1716:
if(
AG903_SSP_INTSTS_TFTHIBIT & intstatus) {
1717: SSPMgr_IntSend(ch, &event);
1718: }
1719:
1720:
if(
AG903_SSP_INTSTS_RFTHIBIT & intstatus) {
1721: SSPMgr_IntReceive(ch, &event);
1722: }
1723:
1724:
if(
AG903_SSP_INTSTS_TFURIBIT & intstatus) {
1725: event |=
AG903_SSP_EVENT_UNDERRUN;
1726: }
1727:
1728:
if(
AG903_SSP_INTSTS_RFORIBIT & intstatus) {
1729: event |=
AG903_SSP_EVENT_OVERRUN;
1730: }
1731:
1732:
if((0 != event) && (NULL != SspHandleStat[ch].clbk)) {
1733: SspHandleStat[ch].clbk((
AG903_SSPMgrHandle*)&SspHandleStat[ch], event);
1734: }
1735:
1736:
return;
1737: }
1738:
1739:
1744:
static void SSPMgr_IntSend(uint8_t ch, uint32_t* event)
1745: {
1746: int32_t result =
AG903_ENONE;
1747:
1748:
if(AG903_SSP_ENABLE_SEND & SspChStat[ch].pio) {
1749: SSPMgr_SetTxData(ch,
false);
1750:
if(SspChStat[ch].tx.cnt >= SspChStat[ch].tx.size) {
1751: (*event) |=
AG903_SSP_EVENT_SNDEND;
1752: result = SSPMgr_SetTxData(ch,
true);
1753:
if(-
AG903_ENOMSG == result) {
1754:
AG903_SSPPrmDisbleTxInt(ch);
1755: SspChStat[ch].pio &= ~AG903_SSP_ENABLE_SEND;
1756: }
1757: }
1758: }
1759:
1760:
return;
1761: }
1762:
1763:
1768:
static void SSPMgr_IntReceive(uint8_t ch, uint32_t* event)
1769: {
1770: int32_t result =
AG903_ENONE;
1771:
1772:
if(AG903_SSP_ENABLE_RECEIVE & SspChStat[ch].pio) {
1773: SSPMgr_GetRxData(ch,
false);
1774:
if(SspChStat[ch].rx.size <= SspChStat[ch].rx.cnt) {
1775: (*event) |=
AG903_SSP_EVENT_RCVEND;
1776: result = SSPMgr_GetRxData(ch,
true);
1777:
if(-
AG903_ENOMSG == result) {
1778:
AG903_SSPPrmDisbleRxInt(ch);
1779: SspChStat[ch].pio &= ~AG903_SSP_ENABLE_RECEIVE;
1780: }
1781: }
1782: }
1783:
1784:
return;
1785: }
1786:
1787:
1792:
static int32_t SSPMgr_SetTxQue(uint8_t ch, AG903_SSPMgrQue* que)
1793: {
1794: int32_t retval =
AG903_ENONE;
1795: uint32_t wp;
1796: uint32_t next_wp;
1797:
1798:
if( (
AG903_SSP_CH_NUM <= ch) ||
1799: (NULL == que) ){
1800:
return -
AG903_EINVAL;
1801: }
1802:
1803: wp = SspTxQue[ch].wp;
1804: next_wp = SSPMgr_GetNextTxQuePoint(wp);
1805:
if(next_wp == SspTxQue[ch].rp) {
1806: retval = -
AG903_EBUSY;
1807: }
1808:
else {
1809: SspTxQue[ch].que[wp] = (*que);
1810: SspTxQue[ch].wp = next_wp;
1811: }
1812:
1813:
return retval;
1814: }
1815:
1816:
1821:
static int32_t SSPMgr_GetTxQue(uint8_t ch, AG903_SSPMgrQue* que)
1822: {
1823: int32_t retval =
AG903_ENONE;
1824: uint32_t rp;
1825: uint32_t next_rp;
1826:
1827:
if( (
AG903_SSP_CH_NUM <= ch) ||
1828: (NULL == que) ){
1829:
return -
AG903_EINVAL;
1830: }
1831:
1832: rp = SspTxQue[ch].rp;
1833:
if(SspTxQue[ch].wp == rp) {
1834: retval = -
AG903_ENOMSG;
1835: }
1836:
else {
1837: next_rp = SSPMgr_GetNextTxQuePoint(rp);
1838: (*que) = SspTxQue[ch].que[rp];
1839: SspTxQue[ch].rp = next_rp;
1840: }
1841:
1842:
return retval;
1843: }
1844:
1845:
1849:
static uint32_t SSPMgr_GetNextTxQuePoint(uint32_t current)
1850: {
1851: uint32_t next;
1852:
1853: next = current+1;
1854:
if(AG903_SSP_TXQUE_ARY_LEN <= next) {
1855: next = 0;
1856: }
1857:
1858:
return next;
1859: }
1860:
1861:
1866:
static void SSPMgr_GetTxQueEntry(uint8_t ch, uint32_t* entry)
1867: {
1868:
1869:
if(
AG903_SSP_CH_NUM <= ch) {
1870:
return;
1871: }
1872:
1873:
if(SspTxQue[ch].wp >= SspTxQue[ch].rp) {
1874: (*entry) = SspTxQue[ch].wp - SspTxQue[ch].rp;
1875: }
1876:
else {
1877: (*entry) = AG903_SSP_TXQUE_ARY_LEN - SspTxQue[ch].rp + SspTxQue[ch].wp;
1878: }
1879:
1880:
return;
1881: }
1882:
1883:
1887:
static void SSPMgr_ClearTxQue(uint8_t ch)
1888: {
1889:
if(
AG903_SSP_CH_NUM <= ch) {
1890:
return;
1891: }
1892: SspTxQue[ch].wp = 0;
1893: SspTxQue[ch].rp = 0;
1894:
return;
1895: }
1896:
1897:
1902:
static int32_t SSPMgr_SetRxQue(uint8_t ch, AG903_SSPMgrQue* que)
1903: {
1904: int32_t retval =
AG903_ENONE;
1905: uint32_t wp;
1906: uint32_t next_wp;
1907:
1908:
if( (
AG903_SSP_CH_NUM <= ch) ||
1909: (NULL == que) ){
1910:
return -
AG903_EINVAL;
1911: }
1912:
1913: wp = SspRxQue[ch].wp;
1914: next_wp = SSPMgr_GetNextRxQuePoint(wp);
1915:
if(next_wp == SspRxQue[ch].rp) {
1916: retval = -
AG903_EBUSY;
1917: }
1918:
else {
1919: SspRxQue[ch].que[wp] = (*que);
1920: SspRxQue[ch].wp = next_wp;
1921: }
1922:
1923:
return retval;
1924: }
1925:
1926:
1931:
static int32_t SSPMgr_GetRxQue(uint8_t ch, AG903_SSPMgrQue* que)
1932: {
1933: int32_t retval =
AG903_ENONE;
1934: uint32_t rp;
1935: uint32_t next_rp;
1936:
1937:
if( (
AG903_SSP_CH_NUM <= ch) ||
1938: (NULL == que) ){
1939:
return -
AG903_EINVAL;
1940: }
1941:
1942: rp = SspRxQue[ch].rp;
1943:
if(SspRxQue[ch].wp == rp) {
1944: retval = -
AG903_ENOMSG;
1945: }
1946:
else {
1947: next_rp = SSPMgr_GetNextRxQuePoint(rp);
1948: (*que) = SspRxQue[ch].que[rp];
1949: SspRxQue[ch].rp = next_rp;
1950: }
1951:
1952:
return retval;
1953: }
1954:
1955:
1959:
static uint32_t SSPMgr_GetNextRxQuePoint(uint32_t current)
1960: {
1961: uint32_t next;
1962:
1963: next = current+1;
1964:
if(AG903_SSP_RXQUE_ARY_LEN <= next) {
1965: next = 0;
1966: }
1967:
1968:
return next;
1969: }
1970:
1971:
1976:
static void SSPMgr_GetRxQueEntry(uint8_t ch, uint32_t* entry)
1977: {
1978:
1979:
if(
AG903_SSP_CH_NUM <= ch) {
1980:
return;
1981: }
1982:
1983:
if(SspRxQue[ch].wp >= SspRxQue[ch].rp) {
1984: (*entry) = SspRxQue[ch].wp - SspRxQue[ch].rp;
1985: }
1986:
else {
1987: (*entry) = AG903_SSP_RXQUE_ARY_LEN - SspRxQue[ch].rp + SspRxQue[ch].wp;
1988: }
1989:
1990:
return;
1991: }
1992:
1993:
1997:
static void SSPMgr_ClearRxQue(uint8_t ch)
1998: {
1999:
if(
AG903_SSP_CH_NUM <= ch) {
2000:
return;
2001: }
2002: SspRxQue[ch].wp = 0;
2003: SspRxQue[ch].rp = 0;
2004:
return;
2005: }
2006:
2007:
2024: int32_t
AG903_SSPMgrSpiSend(
AG903_SSPMgrHandle* handle,
const void* buf, uint32_t num)
2025: {
2026: int32_t retval =
AG903_ENONE;
2027: uint8_t ch;
2028: uint8_t dma_tx_enable;
2029:
2030: retval = SSPMgr_CheckHandle(handle, &ch);
2031:
if(
AG903_ENONE != retval) {
2032:
return -
AG903_EINVAL;
2033: }
2034:
2035: dma_tx_enable = 0;
2036: retval = SSPMgr_SpiSendTemplate(ch, buf, num, dma_tx_enable);
2037:
2038:
return retval;
2039: }
2040:
2041:
2060: int32_t
AG903_SSPMgrSpiReceive(
AG903_SSPMgrHandle* handle,
void* buf, uint32_t num)
2061: {
2062: int32_t retval =
AG903_ENONE;
2063: uint8_t ch;
2064: uint8_t dma_rx_enable;
2065:
2066: retval = SSPMgr_CheckHandle(handle, &ch);
2067:
if(
AG903_ENONE != retval) {
2068:
return -
AG903_EINVAL;
2069: }
2070:
2071: dma_rx_enable = 0;
2072: retval = SSPMgr_SpiReceiveTemplate(ch, buf, num, dma_rx_enable);
2073:
2074:
return retval;
2075: }
2076:
2077:
2100: int32_t
AG903_SSPMgrSpiSendReceive(
AG903_SSPMgrHandle* handle,
const void* tx_buf, uint32_t tx_num,
void *rx_buf, uint32_t rx_num)
2101: {
2102: int32_t retval =
AG903_ENONE;
2103: uint8_t ch;
2104: uint8_t dma_tx_enable;
2105: uint8_t dma_rx_enable;
2106:
2107: retval = SSPMgr_CheckHandle(handle, &ch);
2108:
if(
AG903_ENONE != retval) {
2109:
return -
AG903_EINVAL;
2110: }
2111:
2112: dma_tx_enable = 0;
2113: dma_rx_enable = 0;
2114: retval = SSPMgr_SpiSendReceiveTemplate(ch, tx_buf, tx_num, rx_buf, rx_num, dma_tx_enable, dma_rx_enable);
2115:
2116:
return retval;
2117: }
2118:
2119:
2133: int32_t
AG903_SSPMgrSpiSendDma(
AG903_SSPMgrHandle* handle,
const void* buf, uint32_t num)
2134: {
2135: int32_t retval =
AG903_ENONE;
2136: uint8_t ch;
2137: uint8_t dma_tx_enable;
2138:
2139: retval = SSPMgr_CheckHandle(handle, &ch);
2140:
if(
AG903_ENONE != retval) {
2141:
return -
AG903_EINVAL;
2142: }
2143:
2144: dma_tx_enable = 1;
2145: retval = SSPMgr_SpiSendTemplate(ch, buf, num, dma_tx_enable);
2146:
2147:
return retval;
2148: }
2149:
2150:
2166: int32_t
AG903_SSPMgrSpiReceiveDma(
AG903_SSPMgrHandle* handle,
void* buf, uint32_t num)
2167: {
2168: int32_t retval =
AG903_ENONE;
2169: uint8_t ch;
2170: uint8_t dma_rx_enable;
2171:
2172: retval = SSPMgr_CheckHandle(handle, &ch);
2173:
if(
AG903_ENONE != retval) {
2174:
return -
AG903_EINVAL;
2175: }
2176:
2177: dma_rx_enable = 1;
2178: retval = SSPMgr_SpiReceiveTemplate(ch, buf, num, dma_rx_enable);
2179:
2180:
return retval;
2181: }
2182:
2183:
2204: int32_t
AG903_SSPMgrSpiSendReceiveDma(
AG903_SSPMgrHandle* handle,
const void* tx_buf, uint32_t tx_num,
void *rx_buf, uint32_t rx_num)
2205: {
2206: int32_t retval =
AG903_ENONE;
2207: uint8_t ch;
2208: uint8_t dma_tx_enable;
2209: uint8_t dma_rx_enable;
2210:
2211: retval = SSPMgr_CheckHandle(handle, &ch);
2212:
if(
AG903_ENONE != retval) {
2213:
return -
AG903_EINVAL;
2214: }
2215:
2216: dma_tx_enable = 1;
2217: dma_rx_enable = 1;
2218: retval = SSPMgr_SpiSendReceiveTemplate(ch, tx_buf, tx_num, rx_buf, rx_num, dma_tx_enable, dma_rx_enable);
2219:
2220:
return retval;
2221: }
2222:
2223:
2226:
static
2227: int32_t SSPMgr_DisableDma(uint8_t ch, uint32_t dma_dir)
2228: {
2229: int32_t retval =
AG903_ENONE;
2230: AG903_SSPMgrDmaStat* dma_stat;
2231: uint8_t dma_ch;
2232: uint32_t enable;
2233:
2234:
if (AG903_SSP_DMA_DIR_TX == dma_dir) {
2235: dma_stat = &SspDmaStatTx[ch];
2236: }
else if (AG903_SSP_DMA_DIR_RX == dma_dir) {
2237: dma_stat = &SspDmaStatRx[ch];
2238: }
else {
2239:
return -
AG903_EPERM;;
2240: }
2241:
2242:
if (0 == dma_stat->attach) {
2243:
return -
AG903_EPERM;;
2244: }
2245:
2246: dma_ch = dma_stat->dma_ch;
2247:
2248:
AG903_DMACPrmGetCHANNEL_ENABLE(&enable);
2249: enable &= ~(1<<dma_ch);
2250:
AG903_DMACPrmSetCHANNEL_ENABLE(enable);
2251:
2252:
return retval;
2253: }
2254:
2255:
2281: int32_t
AG903_SSPMgrSpiEnableTransfer(
AG903_SSPMgrHandle* handle)
2282: {
2283: int32_t retval =
AG903_ENONE;
2284:
AG903_SSPPrmIntCtrl* ictrl;
2285:
AG903_SSPPrmCtrl2* ctrl2;
2286: uint8_t ch;
2287: uint8_t cs;
2288:
2289: retval = SSPMgr_CheckHandle(handle, &ch);
2290:
if(
AG903_ENONE != retval) {
2291:
return -
AG903_EINVAL;
2292: }
2293:
2294:
if (AG903_SSP_FORMAT_SPI != SspChStat[ch].format) {
2295:
return -
AG903_EPERM;
2296: }
2297:
2298:
if (0 != SSPMgr_IsSpiFlashLike(ch)) {
2299: cs = (AG903_SSP_POL_NEGATIVE==SspSpiParam[ch].polarity) ? 0 : 1;
2300: }
else {
2301: cs = 0;
2302: }
2303:
2304: ictrl = &SspRegStat[ch].ictrl;
2305: ictrl->tfthod = SspChStat[ch].tx_thod;
2306: ictrl->rfthod = SspChStat[ch].rx_thod;
2307: ictrl->tfdmaen = 0;
2308: ictrl->rfdmaen = 0;
2309: ictrl->tfthien = 0;
2310: ictrl->rfthien = 0;
2311: ictrl->tfurien = 0;
2312: ictrl->rforien = 0;
2313:
AG903_SSPPrmSetIntControl(ch, ictrl);
2314:
2315: ctrl2 = &SspRegStat[ch].ctrl2;
2316: ctrl2->fsos = 0;
2317: ctrl2->fs = cs;
2318: ctrl2->txen = 0;
2319: ctrl2->rxen = 0;
2320: ctrl2->ssprst = 0;
2321: ctrl2->txfclr = 1;
2322: ctrl2->rxfclr = 1;
2323: ctrl2->txdoe = 0;
2324: ctrl2->sspen = 1;
2325:
AG903_SSPPrmSetControl2(ch, ctrl2);
2326: ctrl2->txfclr = 0;
2327: ctrl2->rxfclr = 0;
2328:
2329:
return retval;
2330: }
2331:
2332:
2343: int32_t
AG903_SSPMgrSpiDisableTransfer(
AG903_SSPMgrHandle* handle)
2344: {
2345: int32_t retval =
AG903_ENONE;
2346:
AG903_SSPPrmIntCtrl* ictrl;
2347:
AG903_SSPPrmCtrl2* ctrl2;
2348: uint8_t ch;
2349:
2350: retval = SSPMgr_CheckHandle(handle, &ch);
2351:
if(
AG903_ENONE != retval) {
2352:
return -
AG903_EINVAL;
2353: }
2354:
2355:
if (AG903_SSP_FORMAT_SPI != SspChStat[ch].format) {
2356:
return -
AG903_EPERM;
2357: }
2358:
2359: ictrl = &SspRegStat[ch].ictrl;
2360: ictrl->tfthod = 2;
2361: ictrl->rfthod = 2;
2362: ictrl->tfdmaen = 0;
2363: ictrl->rfdmaen = 0;
2364: ictrl->tfthien = 0;
2365: ictrl->rfthien = 0;
2366: ictrl->tfurien = 0;
2367: ictrl->rforien = 0;
2368:
AG903_SSPPrmSetIntControl(ch, ictrl);
2369:
2370: ctrl2 = &SspRegStat[ch].ctrl2;
2371: ctrl2->fsos = 0;
2372: ctrl2->fs = 0;
2373: ctrl2->txen = 0;
2374: ctrl2->rxen = 0;
2375: ctrl2->ssprst = 0;
2376: ctrl2->txfclr = 1;
2377: ctrl2->rxfclr = 1;
2378: ctrl2->txdoe = 0;
2379: ctrl2->sspen = 0;
2380:
AG903_SSPPrmSetControl2(ch, ctrl2);
2381: ctrl2->txfclr = 0;
2382: ctrl2->rxfclr = 0;
2383:
2384:
return retval;
2385: }
2386:
2387:
2404: int32_t
AG903_SSPMgrAttachTxDma(
AG903_SSPMgrHandle* handle, uint8_t dma_ch, uint8_t dma_if)
2405: {
2406: int32_t retval =
AG903_ENONE;
2407: uint8_t ch;
2408:
2409: retval = SSPMgr_CheckHandle(handle, &ch);
2410:
if(
AG903_ENONE != retval) {
2411:
return -
AG903_EINVAL;
2412: }
2413:
2414:
return SSPMgr_AttachDma(ch, AG903_SSP_DMA_DIR_TX, dma_ch, dma_if);
2415: }
2416:
2417:
2434: int32_t
AG903_SSPMgrAttachRxDma(
AG903_SSPMgrHandle* handle, uint8_t dma_ch, uint8_t dma_if)
2435: {
2436: int32_t retval =
AG903_ENONE;
2437: uint8_t ch;
2438:
2439: retval = SSPMgr_CheckHandle(handle, &ch);
2440:
if(
AG903_ENONE != retval) {
2441:
return -
AG903_EINVAL;
2442: }
2443:
2444:
return SSPMgr_AttachDma(ch, AG903_SSP_DMA_DIR_RX, dma_ch, dma_if);
2445: }
2446:
2447:
static
2448: int32_t SSPMgr_AttachDma(uint8_t ch, uint8_t dma_dir, uint8_t dma_ch, uint8_t dma_if)
2449: {
2450: AG903_SSPMgrDmaStat dmastat_clr = {0};
2451:
AG903_INTMgrHdrPrm inthdr = {0};
2452: int32_t int_hnd;
2453: int32_t retval =
AG903_ENONE;
2454: uint8_t ssp_enable;
2455: AG903_SSPMgrDmaStat* dma_stat;
2456: AG903_SSPMgrIntHdr isr;
2457:
static const AG903_SSPMgrIntHdr isr_tx[
AG903_SSP_CH_NUM] = {
2458: SSPMgr_IntHdr0TxDma,
2459: SSPMgr_IntHdr1TxDma,
2460: SSPMgr_IntHdr2TxDma,
2461: SSPMgr_IntHdr3TxDma,
2462: };
2463:
static const AG903_SSPMgrIntHdr isr_rx[
AG903_SSP_CH_NUM] = {
2464: SSPMgr_IntHdr0RxDma,
2465: SSPMgr_IntHdr1RxDma,
2466: SSPMgr_IntHdr2RxDma,
2467: SSPMgr_IntHdr3RxDma,
2468: };
2469:
2470:
if (dma_if >= 16) {
2471:
return -
AG903_EINVAL;
2472: }
2473:
2474:
AG903_SSPPrmCheckEnable(ch, &ssp_enable);
2475:
if (0 != ssp_enable) {
2476:
return -
AG903_EPERM;
2477: }
2478:
2479:
2480:
if (AG903_SSP_DMA_DIR_TX == dma_dir) {
2481: dma_stat = &SspDmaStatTx[ch];
2482: isr = isr_tx[ch];
2483: }
else if (AG903_SSP_DMA_DIR_RX == dma_dir) {
2484: dma_stat = &SspDmaStatRx[ch];
2485: isr = isr_rx[ch];
2486: }
else {
2487:
return -
AG903_EPERM;
2488: }
2489:
2490:
if (0 != dma_stat->attach) {
2491:
return -
AG903_EPERM;
2492: }
2493:
2494: inthdr.atr =
AG903_INT_HLNG;
2495: inthdr.intno =
AG903_IRQ26_DMAC;
2496: inthdr.func = (
void*)isr;
2497: retval =
AG903_INTMgrSetHandler(&inthdr);
2498:
if(0 > retval) {
2499:
return retval;
2500: }
2501: int_hnd = retval;
2502:
2503: *dma_stat = dmastat_clr;
2504: dma_stat->attach = 1;
2505: dma_stat->stat = AG903_SSP_DMA_STAT_STOP;
2506: dma_stat->dma_ch = dma_ch;
2507: dma_stat->dma_if = dma_if;
2508: dma_stat->ctrlwidth = 0;
2509: dma_stat->ctrlbeat = 0;
2510: dma_stat->txrxdr = 0xE0400018 + 0x100000*ch;
2511: dma_stat->hdrid = int_hnd;
2512:
2513:
return AG903_ENONE;
2514: }
2515:
2516:
2526: int32_t
AG903_SSPMgrDetachTxDma(
AG903_SSPMgrHandle* handle)
2527: {
2528: int32_t retval =
AG903_ENONE;
2529: uint8_t ch;
2530:
2531: retval = SSPMgr_CheckHandle(handle, &ch);
2532:
if(
AG903_ENONE != retval) {
2533:
return -
AG903_EINVAL;
2534: }
2535:
2536:
return SSPMgr_DetachDma(ch, AG903_SSP_DMA_DIR_TX);
2537: }
2538:
2539:
2549: int32_t
AG903_SSPMgrDetachRxDma(
AG903_SSPMgrHandle* handle)
2550: {
2551: int32_t retval =
AG903_ENONE;
2552: uint8_t ch;
2553:
2554: retval = SSPMgr_CheckHandle(handle, &ch);
2555:
if(
AG903_ENONE != retval) {
2556:
return -
AG903_EINVAL;
2557: }
2558:
2559:
return SSPMgr_DetachDma(ch, AG903_SSP_DMA_DIR_RX);
2560: }
2561:
2562:
static
2563: int32_t SSPMgr_DetachDma(uint8_t ch, uint8_t dma_dir)
2564: {
2565: AG903_SSPMgrDmaStat dmastat_clr = {0};
2566: int32_t retval =
AG903_ENONE;
2567: uint8_t ssp_enable;
2568: AG903_SSPMgrDmaStat* dma_stat;
2569:
2570:
AG903_SSPPrmCheckEnable(ch, &ssp_enable);
2571:
if (0 != ssp_enable) {
2572:
return -
AG903_EPERM;
2573: }
2574:
2575:
if (AG903_SSP_DMA_DIR_TX == dma_dir) {
2576: dma_stat = &SspDmaStatTx[ch];
2577: }
else if (AG903_SSP_DMA_DIR_RX == dma_dir) {
2578: dma_stat = &SspDmaStatRx[ch];
2579: }
else {
2580:
return -
AG903_EPERM;
2581: }
2582:
2583:
if (0 == dma_stat->attach) {
2584:
return -
AG903_EPERM;
2585: }
2586:
2587:
AG903_INTMgrDeleteHandler(dma_stat->hdrid);
2588:
2589: *dma_stat = dmastat_clr;
2590: dma_stat->attach = 0;
2591: dma_stat->stat = AG903_SSP_DMA_STAT_STOP;
2592: dma_stat->dma_ch = 0;
2593: dma_stat->dma_if = 0;
2594: dma_stat->ctrlwidth = 0;
2595: dma_stat->ctrlbeat = 0;
2596: dma_stat->txrxdr = 0;
2597: dma_stat->hdrid = -1;
2598:
2599:
return retval;
2600: }
2601:
2602:
2617: int32_t
AG903_SSPMgrSetTxDmaBeat(
AG903_SSPMgrHandle* handle, uint8_t beat)
2618: {
2619: int32_t retval =
AG903_ENONE;
2620: uint8_t ch;
2621:
2622: retval = SSPMgr_CheckHandle(handle, &ch);
2623:
if(
AG903_ENONE != retval) {
2624:
return -
AG903_EINVAL;
2625: }
2626:
2627:
return SSPMgr_SetDmaBeat(ch, AG903_SSP_DMA_DIR_TX, beat);
2628: }
2629:
2630:
2645: int32_t
AG903_SSPMgrSetRxDmaBeat(
AG903_SSPMgrHandle* handle, uint8_t beat)
2646: {
2647: int32_t retval =
AG903_ENONE;
2648: uint8_t ch;
2649:
2650: retval = SSPMgr_CheckHandle(handle, &ch);
2651:
if(
AG903_ENONE != retval) {
2652:
return -
AG903_EINVAL;
2653: }
2654:
2655:
return SSPMgr_SetDmaBeat(ch, AG903_SSP_DMA_DIR_RX, beat);
2656: }
2657:
2658:
static
2659: int32_t SSPMgr_SetDmaBeat(uint8_t ch, uint8_t dma_dir, uint8_t beat)
2660: {
2661: int32_t retval =
AG903_ENONE;
2662: AG903_SSPMgrDmaStat* dma_stat;
2663:
2664:
if (AG903_SSP_DMA_DIR_TX == dma_dir) {
2665: dma_stat = &SspDmaStatTx[ch];
2666: }
else if (AG903_SSP_DMA_DIR_RX == dma_dir) {
2667: dma_stat = &SspDmaStatRx[ch];
2668: }
else {
2669:
return -
AG903_EPERM;
2670: }
2671:
2672:
if (0 == dma_stat->attach) {
2673:
return -
AG903_EPERM;
2674: }
2675:
2676:
switch (beat) {
2677:
case 1:
2678: dma_stat->ctrlbeat = 0;
2679:
break;
2680:
case 2:
2681: dma_stat->ctrlbeat = 1;
2682:
break;
2683:
case 4:
2684: dma_stat->ctrlbeat = 2;
2685:
break;
2686:
case 8:
2687: dma_stat->ctrlbeat = 3;
2688:
break;
2689:
case 16:
2690: dma_stat->ctrlbeat = 4;
2691:
break;
2692:
default:
2693:
return -
AG903_EINVAL;
2694: }
2695:
2696:
return retval;
2697: }
2698:
2699:
2718: int32_t
AG903_SSPMgrSendDma(
AG903_SSPMgrHandle* handle,
const uint8_t* buf, uint32_t size)
2719: {
2720: int32_t retval =
AG903_ENONE;
2721: uint8_t ch;
2722:
2723: retval = SSPMgr_CheckHandle(handle, &ch);
2724:
if(
AG903_ENONE != retval) {
2725:
return -
AG903_EINVAL;
2726: }
2727:
if((NULL == buf) || (0 >= size)) {
2728:
return -
AG903_EINVAL;
2729: }
2730:
2731:
if (AG903_SSP_DMA_SEND & SspChStat[ch].dma) {
2732:
return SSPMgr_SendDma(ch, buf, size);
2733: }
else {
2734:
return -
AG903_EPERM;
2735: }
2736: }
2737:
2738:
2758: int32_t
AG903_SSPMgrReceiveDma(
AG903_SSPMgrHandle* handle, uint8_t* buf, uint32_t size)
2759: {
2760: int32_t retval =
AG903_ENONE;
2761: uint8_t ch;
2762:
2763: retval = SSPMgr_CheckHandle(handle, &ch);
2764:
if(
AG903_ENONE != retval) {
2765:
return -
AG903_EINVAL;
2766: }
2767:
if((NULL == buf) || (0 >= size)) {
2768:
return -
AG903_EINVAL;
2769: }
2770:
2771:
if (AG903_SSP_DMA_RECEIVE & SspChStat[ch].dma) {
2772:
return SSPMgr_ReceiveDma(ch, buf, size);
2773: }
else {
2774:
return -
AG903_EPERM;
2775: }
2776: }
2777:
2778:
static int32_t SSPMgr_WriteTxFifoBest(uint8_t ch,
const void* buf, uint32_t num)
2779: {
2780:
const uint8_t *src;
2781:
AG903_SSPPrmStatus ssp_status;
2782: uint32_t free_num;
2783: uint32_t tx_num;
2784: uint32_t val;
2785:
2786: src = buf;
2787:
AG903_SSPPrmGetStatus(ch, &ssp_status);
2788: free_num =
AG903_SSP_FIFO_DEPTH - ssp_status.txfifo_num;
2789: tx_num = (num < free_num) ? num : free_num;
2790:
for (uint32_t ii = 0; ii < tx_num; ii++) {
2791: val = 0;
2792:
for (
int ib = 0; ib < SspChStat[ch].wordlen; ib += 8) {
2793: val |= (uint32_t)((*src++)<<ib);
2794: }
2795:
AG903_SSPPrmSetData(ch, val);
2796: }
2797:
2798:
return tx_num;
2799: }
2800:
2801:
static int32_t SSPMgr_ReadRxFifoBest(uint8_t ch,
void* buf, uint32_t num)
2802: {
2803: uint8_t *dst;
2804:
AG903_SSPPrmStatus ssp_status;
2805: uint32_t valid_num;
2806: uint32_t rx_num;
2807: uint32_t val;
2808:
2809: dst = buf;
2810:
AG903_SSPPrmGetStatus(ch, &ssp_status);
2811: valid_num = ssp_status.rxfifo_num;
2812: rx_num = (num < valid_num) ? num : valid_num;
2813:
for (uint32_t ii = 0; ii < rx_num; ii++) {
2814:
AG903_SSPPrmGetData(ch, &val);
2815:
for (
int ib = 0; ib < SspChStat[ch].wordlen; ib += 8) {
2816: *dst++ = (uint8_t)(val>>ib & 0xff);
2817: }
2818: }
2819:
2820:
return rx_num;
2821: }
2822:
2823:
2827:
static int32_t SSPMgr_SendDma(uint8_t ch,
const void* buf, uint32_t num)
2828: {
2829: uint32_t sizeof_word;
2830:
const uint8_t* src;
2831: uint32_t txed_num;
2832: uint32_t tx_num;
2833:
DMACPrmParamCFG dcfg_tx = {0};
2834:
DMACPrmParamCTRL dctrl_tx = {0};
2835: uint8_t dma_ch;
2836: uint8_t dma_if;
2837:
2838:
if (0 == SspDmaStatTx[ch].attach) {
2839:
return -
AG903_EPERM;
2840: }
2841:
2842: sizeof_word = (SspChStat[ch].wordlen + 8-1)/8;
2843: src = buf;
2844: txed_num = 0;
2845: dma_ch = SspDmaStatTx[ch].dma_ch;
2846:
2847:
2848:
if (AG903_SSP_DMA_STAT_STOP == SspDmaStatTx[ch].stat) {
2849: SspDmaStatTx[ch].stat = AG903_SSP_DMA_STAT_XMIT;
2850:
2851:
2852: dma_if = SspDmaStatTx[ch].dma_if;
2853: SSPMgr_SetDmaInterface(ch, dma_if, AG903_SSP_DMA_DIR_TX);
2854:
2855:
if (SspChStat[ch].wordlen > 16) {
2856: SspDmaStatTx[ch].ctrlwidth = 2;
2857: }
else if (SspChStat[ch].wordlen > 8) {
2858: SspDmaStatTx[ch].ctrlwidth = 1;
2859: }
else {
2860: SspDmaStatTx[ch].ctrlwidth = 0;
2861: }
2862:
2863: dcfg_tx.TCIntMsk = 0;
2864: dcfg_tx.ErrIntMsk = 1;
2865: dcfg_tx.AbtIntMsk = 1;
2866: dcfg_tx.SrcRS = 0;
2867: dcfg_tx.SrcHEn = 0;
2868: dcfg_tx.DstRS = SspDmaStatTx[ch].dma_if;
2869: dcfg_tx.DstHEn = 1;
2870:
2871: dcfg_tx.ChGntWin = 0;
2872: dcfg_tx.ChPri = 0;
2873: dcfg_tx.WOMode = 0;
2874: dcfg_tx.UnalignMode = 0;
2875:
AG903_DMACPrmSetCFG_REG(dma_ch, &dcfg_tx);
2876:
2877:
AG903_DMACPrmSetLINK_LIST_POINTER(dma_ch, 0x00000000);
2878:
2879:
AG903_DMACPrmSetDST_ADDR(dma_ch, SspDmaStatTx[ch].txrxdr);
2880: }
2881:
2882:
AG903_DMACPrmSetSRC_ADDR(dma_ch, (uint32_t)&src[txed_num*sizeof_word]);
2883:
2884: tx_num = num - txed_num;
2885:
AG903_DMACPrmSetTRNS_SIZE_1D(dma_ch, tx_num);
2886:
2887: dctrl_tx.ExpEn = 0;
2888: dctrl_tx.ChEn = 1;
2889: dctrl_tx.WDTEn = 0;
2890: dctrl_tx.DstCtrl = 2;
2891: dctrl_tx.SrcCtrl = 0;
2892: dctrl_tx.DstWidth = SspDmaStatTx[ch].ctrlwidth;
2893: dctrl_tx.SrcWidth = SspDmaStatTx[ch].ctrlwidth;
2894: dctrl_tx.TCMsk = 0;
2895: dctrl_tx.SrcTcnt = SspDmaStatTx[ch].ctrlbeat;
2896:
AG903_DMACPrmSetCTRL_REG(dma_ch, &dctrl_tx);
2897:
2898:
return AG903_ENONE;
2899: }
2900:
2901:
2905:
static int32_t SSPMgr_ReceiveDma(uint8_t ch,
void* buf, uint32_t num)
2906: {
2907: uint32_t sizeof_word;
2908: uint8_t* dst;
2909: uint32_t rxed_num;
2910: uint32_t rx_num;
2911:
DMACPrmParamCFG dcfg_rx = {0};
2912:
DMACPrmParamCTRL dctrl_rx = {0};
2913: uint8_t dma_ch;
2914: uint8_t dma_if;
2915:
2916:
if (0 == SspDmaStatRx[ch].attach) {
2917:
return -
AG903_EPERM;
2918: }
2919:
2920: sizeof_word = (SspChStat[ch].wordlen + 8-1)/8;
2921: dst = buf;
2922: rxed_num = 0;
2923: dma_ch = SspDmaStatRx[ch].dma_ch;
2924:
2925:
2926:
if (AG903_SSP_DMA_STAT_STOP == SspDmaStatRx[ch].stat) {
2927: SspDmaStatRx[ch].stat = AG903_SSP_DMA_STAT_XMIT;
2928:
2929:
2930: dma_if = SspDmaStatRx[ch].dma_if;
2931: SSPMgr_SetDmaInterface(ch, dma_if, AG903_SSP_DMA_DIR_RX);
2932:
2933:
if (SspChStat[ch].wordlen > 16) {
2934: SspDmaStatRx[ch].ctrlwidth = 2;
2935: }
else if (SspChStat[ch].wordlen > 8) {
2936: SspDmaStatRx[ch].ctrlwidth = 1;
2937: }
else {
2938: SspDmaStatRx[ch].ctrlwidth = 0;
2939: }
2940:
2941: dcfg_rx.TCIntMsk = 0;
2942: dcfg_rx.ErrIntMsk = 1;
2943: dcfg_rx.AbtIntMsk = 1;
2944: dcfg_rx.SrcRS = SspDmaStatRx[ch].dma_if;
2945: dcfg_rx.SrcHEn = 1;
2946: dcfg_rx.DstRS = 0;
2947: dcfg_rx.DstHEn = 0;
2948:
2949: dcfg_rx.ChGntWin = 0;
2950: dcfg_rx.ChPri = 0;
2951: dcfg_rx.WOMode = 0;
2952: dcfg_rx.UnalignMode = 0;
2953:
AG903_DMACPrmSetCFG_REG(dma_ch, &dcfg_rx);
2954:
2955:
AG903_DMACPrmSetLINK_LIST_POINTER(dma_ch, 0x00000000);
2956:
2957:
AG903_DMACPrmSetSRC_ADDR(dma_ch, SspDmaStatRx[ch].txrxdr);
2958: }
2959:
2960:
AG903_DMACPrmSetDST_ADDR(dma_ch, (uint32_t)&dst[rxed_num*sizeof_word]);
2961:
2962: rx_num = num - rxed_num;
2963:
AG903_DMACPrmSetTRNS_SIZE_1D(dma_ch, rx_num);
2964:
2965: dctrl_rx.ExpEn = 0;
2966: dctrl_rx.ChEn = 1;
2967: dctrl_rx.WDTEn = 0;
2968: dctrl_rx.DstCtrl = 0;
2969: dctrl_rx.SrcCtrl = 2;
2970: dctrl_rx.DstWidth = SspDmaStatRx[ch].ctrlwidth;
2971: dctrl_rx.SrcWidth = SspDmaStatRx[ch].ctrlwidth;
2972: dctrl_rx.TCMsk = 0;
2973: dctrl_rx.SrcTcnt = SspDmaStatRx[ch].ctrlbeat;
2974:
AG903_DMACPrmSetCTRL_REG(dma_ch, &dctrl_rx);
2975:
2976:
return AG903_ENONE;
2977: }
2978:
2979:
static int32_t SSPMgr_SpiSendTemplate(uint8_t ch,
const void* buf, uint32_t num, uint8_t dma_tx_enable)
2980: {
2981: int32_t retval =
AG903_ENONE;
2982:
AG903_SSPPrmIntCtrl* ictrl;
2983:
AG903_SSPPrmCtrl2* ctrl2;
2984: uint32_t istatus;
2985: uint32_t sizeof_word;
2986:
const uint8_t* tx_buf;
2987: uint32_t tx_num;
2988: uint32_t txed_num;
2989: uint32_t event;
2990:
2991:
if (AG903_SSP_FORMAT_SPI != SspChStat[ch].format) {
2992:
return -
AG903_EPERM;
2993: }
2994:
2995:
2996:
if (0 == num) {
2997:
return -
AG903_EINVAL;
2998: }
2999:
3000:
3001:
AG903_SSPPrmGetIntStatus(ch, &istatus);
3002:
3003: ictrl = &SspRegStat[ch].ictrl;
3004: ictrl->tfthod = SspChStat[ch].tx_thod;
3005: ictrl->rfthod = SspChStat[ch].rx_thod;
3006:
if (0 == dma_tx_enable) {
3007: ictrl->tfdmaen = 0;
3008: ictrl->rfdmaen = 0;
3009: }
else {
3010: ictrl->tfdmaen = 1;
3011: ictrl->rfdmaen = 0;
3012: }
3013: ictrl->tfthien = 0;
3014: ictrl->rfthien = 0;
3015: ictrl->tfurien = 0;
3016: ictrl->rforien = 0;
3017:
AG903_SSPPrmSetIntControl(ch, ictrl);
3018:
3019: ctrl2 = &SspRegStat[ch].ctrl2;
3020: ctrl2->txen = 1;
3021: ctrl2->txdoe = 1;
3022: ctrl2->rxen = 0;
3023:
AG903_SSPPrmSetControl2(ch, ctrl2);
3024:
3025:
if (0 == dma_tx_enable) {
3026: sizeof_word = (SspChStat[ch].wordlen + 8-1)/8;
3027: tx_buf = buf;
3028: tx_num = num;
3029: txed_num = 0;
3030:
while (txed_num < tx_num) {
3031: txed_num += SSPMgr_WriteTxFifoBest(ch, &tx_buf[txed_num*sizeof_word], tx_num-txed_num);
3032: }
3033:
3034:
if (NULL != SspHandleStat[ch].clbk) {
3035: event = 0;
3036: event |=
AG903_SSP_EVENT_SNDEND;
3037: SspHandleStat[ch].clbk((
AG903_SSPMgrHandle*)&SspHandleStat[ch], event);
3038: }
3039:
3040: retval =
AG903_ENONE;
3041: }
else {
3042: retval = SSPMgr_SendDma(ch, buf, num);
3043: }
3044:
3045:
return retval;
3046: }
3047:
3048:
static int32_t SSPMgr_SpiReceiveTemplate(uint8_t ch,
void* buf, uint32_t num, uint8_t dma_rx_enable)
3049: {
3050: int32_t retval =
AG903_ENONE;
3051:
AG903_SSPPrmIntCtrl* ictrl;
3052:
AG903_SSPPrmCtrl2* ctrl2;
3053: uint32_t istatus;
3054: uint32_t sizeof_word;
3055: uint8_t* rx_buf;
3056: uint32_t rx_num;
3057: uint32_t rxed_num;
3058: uint32_t event;
3059:
3060:
if (AG903_SSP_FORMAT_SPI != SspChStat[ch].format) {
3061:
return -
AG903_EPERM;
3062: }
3063:
3064:
3065:
if (0 == num) {
3066:
return -
AG903_EINVAL;
3067: }
3068:
3069:
3070:
AG903_SSPPrmGetIntStatus(ch, &istatus);
3071:
3072: ictrl = &SspRegStat[ch].ictrl;
3073: ictrl->tfthod = SspChStat[ch].tx_thod;
3074: ictrl->rfthod = SspChStat[ch].rx_thod;
3075:
if (0 == dma_rx_enable) {
3076: ictrl->tfdmaen = 0;
3077: ictrl->rfdmaen = 0;
3078: }
else {
3079: ictrl->tfdmaen = 0;
3080: ictrl->rfdmaen = 1;
3081: }
3082: ictrl->tfthien = 0;
3083: ictrl->rfthien = 0;
3084: ictrl->tfurien = 0;
3085: ictrl->rforien = 0;
3086:
AG903_SSPPrmSetIntControl(ch, ictrl);
3087:
3088: ctrl2 = &SspRegStat[ch].ctrl2;
3089: ctrl2->txen = 0;
3090: ctrl2->txdoe = 0;
3091: ctrl2->rxen = 1;
3092:
AG903_SSPPrmSetControl2(ch, ctrl2);
3093:
3094:
if (0 == dma_rx_enable) {
3095: sizeof_word = (SspChStat[ch].wordlen + 8-1)/8;
3096: rx_buf = buf;
3097: rx_num = num;
3098: rxed_num = 0;
3099:
while (rxed_num < rx_num) {
3100: rxed_num += SSPMgr_ReadRxFifoBest(ch, &rx_buf[rxed_num*sizeof_word], rx_num-rxed_num);
3101: }
3102:
3103:
if (NULL != SspHandleStat[ch].clbk) {
3104: event = 0;
3105: event |=
AG903_SSP_EVENT_RCVEND;
3106: SspHandleStat[ch].clbk((
AG903_SSPMgrHandle*)&SspHandleStat[ch], event);
3107: }
3108: }
else {
3109: retval = SSPMgr_ReceiveDma(ch, buf, num);
3110: }
3111:
3112:
return retval;
3113: }
3114:
3115:
static int32_t SSPMgr_SpiSendReceiveTemplate(uint8_t ch,
const void *tx_buf, uint32_t tx_num,
void* rx_buf, uint32_t rx_num, uint8_t dma_tx_enable, uint8_t dma_rx_enable)
3116: {
3117: int32_t retval =
AG903_ENONE;
3118:
AG903_SSPPrmIntCtrl* ictrl;
3119:
AG903_SSPPrmCtrl2* ctrl2;
3120: uint32_t istatus;
3121: uint32_t sizeof_word;
3122:
const uint8_t* tx_buf8;
3123: uint8_t* rx_buf8;
3124: uint32_t txed_num;
3125: uint32_t rxed_num;
3126: uint32_t event;
3127:
3128:
if (AG903_SSP_FORMAT_SPI != SspChStat[ch].format) {
3129:
return -
AG903_EPERM;
3130: }
3131:
3132:
if (0 == tx_num || 0 == rx_num || tx_num < rx_num) {
3133:
return -
AG903_EINVAL;
3134: }
3135:
3136:
if (0 == SspDmaStatTx[ch].attach || 0 == (SspChStat[ch].dma & AG903_SSP_DMA_SEND)) {
3137: dma_tx_enable = 0;
3138: }
3139:
if (0 == SspDmaStatRx[ch].attach || 0 == (SspChStat[ch].dma & AG903_SSP_DMA_RECEIVE)) {
3140: dma_rx_enable = 0;
3141: }
3142:
3143:
3144:
AG903_SSPPrmGetIntStatus(ch, &istatus);
3145:
3146: ictrl = &SspRegStat[ch].ictrl;
3147: ictrl->tfthod = SspChStat[ch].tx_thod;
3148: ictrl->rfthod = SspChStat[ch].rx_thod;
3149:
if (0 == dma_tx_enable) {
3150: ictrl->tfdmaen = 0;
3151: }
else {
3152: ictrl->tfdmaen = 1;
3153: }
3154:
if (0 == dma_rx_enable) {
3155: ictrl->rfdmaen = 0;
3156: }
else {
3157: ictrl->rfdmaen = 1;
3158: }
3159: ictrl->tfthien = 0;
3160: ictrl->rfthien = 0;
3161: ictrl->tfurien = 0;
3162: ictrl->rforien = 0;
3163:
AG903_SSPPrmSetIntControl(ch, ictrl);
3164:
3165: sizeof_word = (SspChStat[ch].wordlen + 8-1)/8;
3166: tx_buf8 = tx_buf;
3167: txed_num = 0;
3168: rx_buf8 = rx_buf;
3169: rxed_num = 0;
3170:
3171: txed_num += SSPMgr_WriteTxFifoBest(ch, &tx_buf8[txed_num*sizeof_word], tx_num-txed_num);
3172:
3173: ctrl2 = &SspRegStat[ch].ctrl2;
3174: ctrl2->txen = 1;
3175: ctrl2->txdoe = 1;
3176: ctrl2->rxen = 1;
3177:
AG903_SSPPrmSetControl2(ch, ctrl2);
3178:
3179:
if (0 == dma_tx_enable && 0 == dma_rx_enable) {
3180: retval =
AG903_ENONE;
3181:
while (txed_num < tx_num || rxed_num < rx_num) {
3182:
if (rxed_num < rx_num) {
3183: rxed_num += SSPMgr_ReadRxFifoBest(ch, &rx_buf8[rxed_num*sizeof_word], rx_num-rxed_num);
3184: }
3185:
if (txed_num < tx_num) {
3186: txed_num += SSPMgr_WriteTxFifoBest(ch, &tx_buf8[txed_num*sizeof_word], tx_num-txed_num);
3187: }
3188: }
3189:
if (NULL != SspHandleStat[ch].clbk) {
3190: event = 0;
3191: event |=
AG903_SSP_EVENT_SNDEND;
3192: event |=
AG903_SSP_EVENT_RCVEND;
3193: SspHandleStat[ch].clbk((
AG903_SSPMgrHandle*)&SspHandleStat[ch], event);
3194: }
3195: }
else if (0 != dma_tx_enable && 0 == dma_rx_enable) {
3196: retval = SSPMgr_SendDma(ch, tx_buf, tx_num);
3197:
if (
AG903_ENONE != retval) {
3198:
AG903_SSPPrmClearTxFifo(ch);
3199:
AG903_SSPPrmClearRxFifo(ch);
3200:
return retval;
3201: }
3202:
while (rxed_num < rx_num) {
3203: rxed_num += SSPMgr_ReadRxFifoBest(ch, &rx_buf8[rxed_num*sizeof_word], rx_num-rxed_num);
3204: }
3205:
if (NULL != SspHandleStat[ch].clbk) {
3206: event = 0;
3207: event |=
AG903_SSP_EVENT_RCVEND;
3208: SspHandleStat[ch].clbk((
AG903_SSPMgrHandle*)&SspHandleStat[ch], event);
3209: }
3210: }
else if (0 == dma_tx_enable && 0 != dma_rx_enable) {
3211: retval = SSPMgr_ReceiveDma(ch, rx_buf, rx_num);
3212:
if (
AG903_ENONE != retval) {
3213:
AG903_SSPPrmClearTxFifo(ch);
3214:
AG903_SSPPrmClearRxFifo(ch);
3215:
return retval;
3216: }
3217:
while (txed_num < tx_num) {
3218: txed_num += SSPMgr_WriteTxFifoBest(ch, &tx_buf8[txed_num*sizeof_word], tx_num-txed_num);
3219: }
3220:
if (NULL != SspHandleStat[ch].clbk) {
3221: event = 0;
3222: event |=
AG903_SSP_EVENT_SNDEND;
3223: SspHandleStat[ch].clbk((
AG903_SSPMgrHandle*)&SspHandleStat[ch], event);
3224: }
3225: }
else {
3226: retval = SSPMgr_ReceiveDma(ch, rx_buf, rx_num);
3227:
if (
AG903_ENONE != retval) {
3228:
AG903_SSPPrmClearTxFifo(ch);
3229:
AG903_SSPPrmClearRxFifo(ch);
3230:
return retval;
3231: }
3232: retval = SSPMgr_SendDma(ch, tx_buf, tx_num);
3233:
if (
AG903_ENONE != retval) {
3234: SSPMgr_DisableDma(ch, AG903_SSP_DMA_DIR_RX);
3235:
AG903_SSPPrmClearTxFifo(ch);
3236:
AG903_SSPPrmClearRxFifo(ch);
3237:
return retval;
3238: }
3239: }
3240:
3241:
return retval;
3242: }
3243:
3244:
static int32_t SSPMgr_IsSpiFlashLike(uint8_t ch)
3245: {
3246:
if (AG903_SSP_FORMAT_SPI == SspChStat[ch].format && SspSpiParam[ch].flash) {
3247:
return 1;
3248: }
3249:
return 0;
3250: }
3251:
3252:
static void SSPMgr_SetDmaInterface(uint8_t ssp_ch, uint8_t dma_if, uint8_t dma_dir)
3253: {
3254:
int dmasel_if_d4 = dma_if/4;
3255:
int dmasel_if_m4 = dma_if%4;
3256:
3257:
int dma_no = 23 + 2*ssp_ch + (AG903_SSP_DMA_DIR_RX==dma_dir ? 0 : 1);
3258:
int dmasel_dev = dma_no + 1;
3259:
3260: uint32_t dmasel;
3261:
AG903_SSCPrmGetDmaInterface(dmasel_if_d4, &dmasel);
3262: dmasel &= ~(0xff << dmasel_if_m4*8);
3263: dmasel |= (dmasel_dev<< dmasel_if_m4*8);
3264:
AG903_SSCPrmSetDmaInterface(dmasel_if_d4, dmasel);
3265:
3266: uint32_t synreq;
3267:
AG903_DMACPrmGetSYNC_PERI_IF(&synreq);
3268: synreq |= 1<<dma_if;
3269:
AG903_DMACPrmSetSYNC_PERI_IF(synreq);
3270: }
3271:
3272:
static void SSPMgr_IntHdr0TxDma(
void)
3273: {
3274: SSPMgr_IntProcessDma(0, AG903_SSP_DMA_DIR_TX);
3275:
return;
3276: }
3277:
3278:
static void SSPMgr_IntHdr0RxDma(
void)
3279: {
3280: SSPMgr_IntProcessDma(0, AG903_SSP_DMA_DIR_RX);
3281:
return;
3282: }
3283:
3284:
static void SSPMgr_IntHdr1TxDma(
void)
3285: {
3286: SSPMgr_IntProcessDma(1, AG903_SSP_DMA_DIR_TX);
3287:
return;
3288: }
3289:
3290:
static void SSPMgr_IntHdr1RxDma(
void)
3291: {
3292: SSPMgr_IntProcessDma(1, AG903_SSP_DMA_DIR_RX);
3293:
return;
3294: }
3295:
3296:
static void SSPMgr_IntHdr2TxDma(
void)
3297: {
3298: SSPMgr_IntProcessDma(2, AG903_SSP_DMA_DIR_TX);
3299:
return;
3300: }
3301:
3302:
static void SSPMgr_IntHdr2RxDma(
void)
3303: {
3304: SSPMgr_IntProcessDma(2, AG903_SSP_DMA_DIR_RX);
3305:
return;
3306: }
3307:
3308:
static void SSPMgr_IntHdr3TxDma(
void)
3309: {
3310: SSPMgr_IntProcessDma(3, AG903_SSP_DMA_DIR_TX);
3311:
return;
3312: }
3313:
3314:
static void SSPMgr_IntHdr3RxDma(
void)
3315: {
3316: SSPMgr_IntProcessDma(3, AG903_SSP_DMA_DIR_RX);
3317:
return;
3318: }
3319:
3320:
static void SSPMgr_IntProcessDma(uint8_t ch, uint8_t dma_dir)
3321: {
3322: uint8_t dma_ch;
3323: uint32_t event;
3324: uint32_t st;
3325: AG903_SSPMgrDmaStat* dma_stat;
3326:
3327:
if (AG903_SSP_DMA_DIR_TX == dma_dir) {
3328: dma_stat = &SspDmaStatTx[ch];
3329: }
else if (AG903_SSP_DMA_DIR_RX == dma_dir) {
3330: dma_stat = &SspDmaStatRx[ch];
3331: }
else {
3332:
return;
3333: }
3334:
3335: dma_ch = dma_stat->dma_ch;
3336:
AG903_DMACPrmGetTIMECOUNT_INT(&st);
3337:
if (st & (1<<dma_ch)) {
3338: dma_stat->stat = AG903_SSP_DMA_STAT_STOP;
3339:
3340: event = 0;
3341:
if (AG903_SSP_DMA_DIR_TX == dma_dir) {
3342: event |=
AG903_SSP_EVENT_SNDEND;
3343: }
else if (AG903_SSP_DMA_DIR_RX == dma_dir) {
3344: event |=
AG903_SSP_EVENT_RCVEND;
3345: }
3346:
3347:
if (0 != event && NULL != SspHandleStat[ch].clbk) {
3348: SspHandleStat[ch].clbk((
AG903_SSPMgrHandle*)&SspHandleStat[ch], event);
3349: }
3350:
3351:
AG903_DMACPrmSetTIMECOUNT_INT_CLEAR(1<<dma_ch);
3352: }
3353:
3354:
return;
3355: }