AG903ライブラリリファレンス
内容インデックスホーム
Body Source
本文ソース
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: }
Copyright (c) 2017-2025 Axell Corporation. All rights reserved.