AG903ライブラリリファレンス
内容インデックスホーム
前へ上へ次へ
sspmgr.c

SSP Manager

SSP Manager Layer

none

AXELL CORPORATION

2017_02_22 初版 

2017_10_26 Ver2.0 

2025_03_06 [SDK3.7] SSPで1ワードの送信ができない不具合を修正 (#5633) 

2025_03_06 [SDK3.7] SSPライブラリにSPIモードでの送受信アクセス機能を追加 (#5662) 

2025_03_06 [SDK3.7] SSPライブラリにDMAによる送受信関数を追加 (#5780)

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: }
 
名前 
説明 
 
SSPへの受信DMA取り付け 
 
SSPへの送信DMA取り付け 
 
受信FIFOクリア 
 
受信キュークリア 
 
送信FIFOクリア 
 
送信キュークリア 
 
SSPからの受信DMA取り外し 
 
SSPからの送信DMA取り外し 
 
DMAモード無効設定 
 
伝送停止 (Disable) 
 
DMAモード有効設定 
 
伝送許可 
 
SSPハンドル取得 
 
キュー状態取得 
 
ステータス取得 
 
SSPモジュール初期化 
 
DMAによるデータ受信 
 
SSPハンドル解放 
 
リセット 
 
DMAによるデータ送信 
 
コールバック登録 
 
I2Sモード設定 
 
受信バッファ設定 (PIO) 
 
受信DMA転送ビート数の設定 
 
受信FIFOしきい値設定 
 
送信バッファ設定 (PIO) 
 
Channel Status Bit設定 (S/PDIF) 
 
S/PDIFモード設定 
 
User Bit設定 (S/PDIF) 
 
User Bit(1ブロック分)設定 (S/PDIF) 
 
SPIモード設定 
 
SSPモード設定 
 
送信DMA転送ビート数の設定 
 
送信FIFOしきい値設定 
 
SPIフォーマットでの送受信停止 (SPIモード用) 
 
SPIフォーマットでの送受信開始 (SPIモード用) 
 
データ受信 (SPIモード用) 
 
DMAによるデータ受信 (SPIモード用) 
 
データ送信 (SPIモード用) 
 
DMAによるデータ送信 (SPIモード用) 
 
データ送受信 (SPIモード用) 
 
DMAによるデータ送受信 (SPIモード用) 
Copyright (c) 2017-2025 Axell Corporation. All rights reserved.