00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include "chip.h"
00050
00051
00052
00053
00054
00055
00056
00057
00058 #define DMA_QSPI_LLI 2
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 static void QSPID_Spi_Cb(uint32_t channel, QspiDma_t* pArg)
00071 {
00072 Qspi *pQspiHw = pArg->Qspid.pQspiHw;
00073 if (channel != pArg->RxChNum)
00074 return;
00075
00076 ReleaseMutex(pArg->progress);
00077 QSPI_EndTransfer(pQspiHw);
00078 memory_sync();
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088 static void QSPID_qspiTx_Cb(uint32_t channel, QspiDma_t* pArg)
00089 {
00090 Qspi *pQspiHw = pArg->Qspid.pQspiHw;
00091 if (channel != pArg->TxChNum)
00092 return;
00093
00094 ReleaseMutex(pArg->progress);
00095 QSPI_EndTransfer(pQspiHw);
00096 while(!QSPI_GetStatus(pArg->Qspid.pQspiHw, IsEofInst ));
00097 memory_sync();
00098 }
00099
00100
00101
00102
00103
00104
00105
00106
00107 static void QSPID_qspiRx_Cb(uint32_t channel, QspiDma_t* pArg)
00108 {
00109 Qspi *pQspiHw = pArg->Qspid.pQspiHw;
00110 if (channel != pArg->RxChNum)
00111 return;
00112
00113 ReleaseMutex(pArg->progress);
00114 QSPI_EndTransfer(pQspiHw);
00115 while(!QSPI_GetStatus(pArg->Qspid.pQspiHw, IsEofInst ));
00116 memory_sync();
00117 }
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 static uint8_t QSPID_configureQpsiDma(QspiDma_t *pQspidma, uint32_t Addr,
00130 QspiBuffer_t *pBuffer, Access_t const ReadWrite)
00131 {
00132 sXdmadCfg xdmadCfg, xdmadRxCfg,xdmadTxCfg;
00133 uint8_t chanNum;
00134 uint8_t qspi_id = pQspidma->Qspid.qspiId;
00135 Qspi *pQspiHw = pQspidma->Qspid.pQspiHw;
00136 uint32_t xdmaCndc, xdmaInt, BurstSize, ChannelWidth;
00137
00138
00139
00140
00141 if(pQspidma->Qspid.qspiMode == QSPI_MR_SMM_SPI) {
00142
00143
00144 xdmadTxCfg.mbr_sa = (uint32_t)pBuffer->pDataTx;
00145 xdmadTxCfg.mbr_da = (uint32_t)&pQspiHw->QSPI_TDR;
00146 xdmadTxCfg.mbr_ubc = (pBuffer->TxDataSize);
00147
00148 xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
00149 XDMAC_CC_MBSIZE_SINGLE |
00150 XDMAC_CC_DSYNC_MEM2PER |
00151 XDMAC_CC_CSIZE_CHK_1 |
00152 XDMAC_CC_DWIDTH_BYTE|
00153 XDMAC_CC_SIF_AHB_IF0 |
00154 XDMAC_CC_DIF_AHB_IF1 |
00155 XDMAC_CC_SAM_INCREMENTED_AM |
00156 XDMAC_CC_DAM_FIXED_AM |
00157 XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
00158 ( qspi_id, XDMAD_TRANSFER_TX ));
00159
00160 xdmadTxCfg.mbr_bc = 0;
00161 xdmadTxCfg.mbr_sus = 0;
00162 xdmadTxCfg.mbr_dus =0;
00163
00164
00165
00166 xdmadRxCfg.mbr_da = (uint32_t)pBuffer->pDataRx;
00167 xdmadRxCfg.mbr_sa = (uint32_t)&pQspiHw->QSPI_RDR;
00168 xdmadRxCfg.mbr_ubc = (pBuffer->RxDataSize);
00169 xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
00170 XDMAC_CC_MBSIZE_SINGLE |
00171 XDMAC_CC_DSYNC_PER2MEM |
00172 XDMAC_CC_CSIZE_CHK_1 |
00173 XDMAC_CC_DWIDTH_BYTE|
00174 XDMAC_CC_SIF_AHB_IF1 |
00175 XDMAC_CC_DIF_AHB_IF0 |
00176 XDMAC_CC_SAM_FIXED_AM |
00177 XDMAC_CC_DAM_INCREMENTED_AM |
00178 XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
00179 ( qspi_id, XDMAD_TRANSFER_RX ));
00180
00181 xdmadRxCfg.mbr_bc = 0;
00182 xdmadRxCfg.mbr_sus = 0;
00183 xdmadRxCfg.mbr_dus =0;
00184 xdmaCndc = 0;
00185
00186 xdmaInt = (XDMAC_CIE_BIE |
00187 XDMAC_CIE_RBIE |
00188 XDMAC_CIE_WBIE |
00189 XDMAC_CIE_ROIE);
00190
00191 memory_barrier();
00192 if (XDMAD_ConfigureTransfer
00193 ( pQspidma->pXdmad, pQspidma->RxChNum, &xdmadRxCfg, xdmaCndc, 0, xdmaInt))
00194 return QSPID_ERROR;
00195
00196 if (XDMAD_ConfigureTransfer
00197 ( pQspidma->pXdmad, pQspidma->TxChNum, &xdmadTxCfg, xdmaCndc, 0, xdmaInt))
00198 return QSPID_ERROR;
00199 return 0;
00200
00201 } else {
00202 if(ReadWrite == WriteAccess) {
00203 xdmadCfg.mbr_sa = (uint32_t)pBuffer->pDataTx;
00204 xdmadCfg.mbr_da = (uint32_t)( QSPIMEM_ADDR | Addr);
00205 xdmadCfg.mbr_ubc = (pBuffer->TxDataSize);
00206 chanNum = pQspidma->TxChNum;
00207 ChannelWidth = XDMAC_CC_DWIDTH_BYTE;
00208 BurstSize = XDMAC_CC_MBSIZE_SIXTEEN;
00209 } else if(ReadWrite == ReadAccess) {
00210 xdmadCfg.mbr_da = (uint32_t)pBuffer->pDataRx;
00211 xdmadCfg.mbr_sa = (uint32_t)( QSPIMEM_ADDR | Addr);
00212 xdmadCfg.mbr_ubc = ((pBuffer->RxDataSize>>2) + 1);
00213 chanNum = pQspidma->RxChNum;
00214 ChannelWidth = XDMAC_CC_DWIDTH_WORD;
00215 BurstSize = XDMAC_CC_MBSIZE_SIXTEEN;
00216 } else {
00217 TRACE_ERROR(" QSPI error \n\r");
00218 return 1;
00219 }
00220
00221 xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_MEM_TRAN |
00222 XDMAC_CC_MEMSET_NORMAL_MODE |
00223 BurstSize |
00224 ChannelWidth |
00225 XDMAC_CC_SIF_AHB_IF1 |
00226 XDMAC_CC_DIF_AHB_IF1 |
00227 XDMAC_CC_SAM_INCREMENTED_AM |
00228 XDMAC_CC_DAM_INCREMENTED_AM ;
00229
00230 xdmadCfg.mbr_bc = 0;
00231 xdmadCfg.mbr_sus = 0;
00232 xdmadCfg.mbr_dus =0;
00233
00234 xdmaCndc = 0;
00235
00236
00237
00238 xdmaInt = (XDMAC_CIE_BIE |
00239 XDMAC_CIE_RBIE |
00240 XDMAC_CIE_WBIE |
00241 XDMAC_CIE_ROIE);
00242
00243 memory_barrier();
00244 if (XDMAD_ConfigureTransfer( pQspidma->pXdmad, chanNum, &xdmadCfg, xdmaCndc, 0, xdmaInt))
00245 return QSPID_ERROR;
00246 return 0;
00247 }
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 uint32_t QSPID_Configure( QspiDma_t *pQspidma, QspiMode_t Mode,
00263 uint32_t dwConf, sXdmad* pXdmad)
00264 {
00265
00266
00267 QSPI_ConfigureInterface(&pQspidma->Qspid, Mode, dwConf);
00268
00269 pQspidma->Qspid.qspiCommand.Instruction = 0;
00270 pQspidma->Qspid.qspiCommand.Option = 0;
00271
00272 pQspidma->RxChNum = QSPID_CH_NOT_ENABLED;
00273 pQspidma->TxChNum = QSPID_CH_NOT_ENABLED;
00274
00275 pQspidma->pXdmad = pXdmad;
00276
00277
00278 XDMAD_Initialize( pQspidma->pXdmad, 0 );
00279
00280
00281 NVIC_ClearPendingIRQ(XDMAC_IRQn);
00282 NVIC_SetPriority( XDMAC_IRQn ,1);
00283 NVIC_EnableIRQ(XDMAC_IRQn);
00284
00285
00286 return QSPI_SUCCESS;
00287 }
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 uint32_t QSPID_EnableQspiRxChannel(QspiDma_t *pQspidma)
00302 {
00303 static uint16_t DmaChannel;
00304
00305
00306 if (pQspidma->RxChNum != QSPID_CH_NOT_ENABLED) {
00307 return QSPID_ERROR_LOCK;
00308 }
00309
00310
00311 DmaChannel = XDMAD_AllocateChannel(
00312 pQspidma->pXdmad, XDMAD_TRANSFER_MEMORY, XDMAD_TRANSFER_MEMORY);
00313 if ( DmaChannel == XDMAD_ALLOC_FAILED ){
00314 return QSPID_ERROR;
00315 }
00316
00317 pQspidma->RxChNum = DmaChannel;
00318
00319 XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->RxChNum,
00320 (XdmadTransferCallback)QSPID_qspiRx_Cb, pQspidma);
00321
00322 if (XDMAD_PrepareChannel( pQspidma->pXdmad, pQspidma->RxChNum ))
00323 return QSPID_ERROR;
00324 return 0;
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 uint32_t QSPID_EnableQspiTxChannel(QspiDma_t *pQspidma)
00339 {
00340 static uint16_t DmaChannel;
00341
00342
00343 if (pQspidma->TxChNum != QSPID_CH_NOT_ENABLED) {
00344 return QSPID_ERROR_LOCK;
00345 }
00346
00347 DmaChannel = XDMAD_AllocateChannel( pQspidma->pXdmad,
00348 XDMAD_TRANSFER_MEMORY, XDMAD_TRANSFER_MEMORY);
00349 if ( DmaChannel == XDMAD_ALLOC_FAILED ) {
00350 return QSPID_ERROR;
00351 }
00352
00353 pQspidma->TxChNum = DmaChannel;
00354
00355 XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->TxChNum,
00356 (XdmadTransferCallback)QSPID_qspiTx_Cb, pQspidma);
00357
00358 if (XDMAD_PrepareChannel( pQspidma->pXdmad, pQspidma->TxChNum ))
00359 return QSPID_ERROR;
00360
00361 return 0;
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375 uint32_t QSPID_EnableSpiChannel(QspiDma_t *pQspidma)
00376 {
00377 static uint16_t DmaChannel;
00378
00379
00380 if (pQspidma->RxChNum != QSPID_CH_NOT_ENABLED) {
00381 return QSPID_ERROR_LOCK;
00382 }
00383
00384
00385 if (pQspidma->TxChNum != QSPID_CH_NOT_ENABLED) {
00386 return QSPID_ERROR_LOCK;
00387 }
00388
00389
00390 DmaChannel = XDMAD_AllocateChannel
00391 ( pQspidma->pXdmad, pQspidma->Qspid.qspiId, XDMAD_TRANSFER_MEMORY);
00392 if ( DmaChannel == XDMAD_ALLOC_FAILED ) {
00393 return QSPID_ERROR;
00394 }
00395
00396 pQspidma->RxChNum = DmaChannel;
00397
00398
00399 DmaChannel = XDMAD_AllocateChannel( pQspidma->pXdmad,
00400 XDMAD_TRANSFER_MEMORY, pQspidma->Qspid.qspiId);
00401 if ( DmaChannel == XDMAD_ALLOC_FAILED ) {
00402 return QSPID_ERROR;
00403 }
00404
00405 pQspidma->TxChNum = DmaChannel;
00406
00407
00408 XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->RxChNum,
00409 (XdmadTransferCallback)QSPID_Spi_Cb, pQspidma);
00410 if (XDMAD_PrepareChannel( pQspidma->pXdmad, pQspidma->RxChNum ))
00411 return QSPID_ERROR;
00412
00413
00414 XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->TxChNum, NULL, NULL);
00415 if ( XDMAD_PrepareChannel( pQspidma->pXdmad, pQspidma->TxChNum ))
00416 return QSPID_ERROR;
00417
00418 return 0;
00419 }
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 uint32_t QSPID_DisableQspiRxChannel(QspiDma_t *pQspidma)
00433 {
00434
00435 XDMAC_SoftwareFlushReq(pQspidma->pXdmad->pXdmacs, pQspidma->RxChNum);
00436 XDMAD_StopTransfer(pQspidma->pXdmad, pQspidma->RxChNum);
00437
00438 XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->RxChNum, NULL, NULL);
00439
00440
00441
00442 XDMAD_FreeChannel( pQspidma->pXdmad, pQspidma->RxChNum);
00443
00444 pQspidma->RxChNum = QSPID_CH_NOT_ENABLED;
00445
00446 return 0;
00447 }
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 uint32_t QSPID_DisableQspiTxChannel(QspiDma_t *pQspidma)
00462 {
00463
00464 XDMAC_SoftwareFlushReq(pQspidma->pXdmad->pXdmacs, pQspidma->TxChNum);
00465 XDMAD_StopTransfer(pQspidma->pXdmad, pQspidma->TxChNum);
00466
00467 XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->TxChNum, NULL, NULL);
00468
00469
00470 XDMAD_FreeChannel( pQspidma->pXdmad, pQspidma->TxChNum);
00471
00472 pQspidma->TxChNum = QSPID_CH_NOT_ENABLED;
00473
00474 return 0;
00475 }
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488 uint32_t QSPID_DisableSpiChannel(QspiDma_t *pQspidma)
00489 {
00490
00491 XDMAC_SoftwareFlushReq(pQspidma->pXdmad->pXdmacs, pQspidma->RxChNum);
00492
00493 XDMAD_StopTransfer(pQspidma->pXdmad, pQspidma->RxChNum);
00494 XDMAD_StopTransfer(pQspidma->pXdmad, pQspidma->TxChNum);
00495
00496 XDMAD_SetCallback(pQspidma->pXdmad, pQspidma->RxChNum, NULL, NULL);
00497
00498
00499 XDMAD_FreeChannel( pQspidma->pXdmad, pQspidma->RxChNum);
00500
00501 XDMAD_FreeChannel( pQspidma->pXdmad, pQspidma->TxChNum);
00502
00503 pQspidma->RxChNum = QSPID_CH_NOT_ENABLED;
00504 pQspidma->TxChNum = QSPID_CH_NOT_ENABLED;
00505
00506 return 0;
00507 }
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519 uint32_t QSPID_ReadWriteQSPI(QspiDma_t *pQspidma, Access_t const ReadWrite)
00520 {
00521 QspiBuffer_t *pBuffer = &pQspidma->Qspid.qspiBuffer;
00522 uint8_t chanNum;
00523 uint32_t semTimer = 0x7FF;
00524
00525
00526
00527 if (pQspidma->progress) {
00528 return QSPID_ERROR_LOCK;
00529 }
00530 LockMutex(pQspidma->progress, semTimer);
00531 if(ReadWrite == WriteAccess) {
00532 chanNum = pQspidma->TxChNum;
00533 } else if(ReadWrite == ReadAccess) {
00534 chanNum = pQspidma->RxChNum;
00535 } else {
00536 TRACE_ERROR("%s QSPI Access Error\n\r", __FUNCTION__);
00537 }
00538
00539 if (QSPID_configureQpsiDma
00540 ( pQspidma, pQspidma->Qspid.pQspiFrame->Addr, pBuffer, ReadWrite) )
00541 return QSPID_ERROR_LOCK;
00542
00543 SCB_CleanInvalidateDCache();
00544
00545 if (XDMAD_StartTransfer( pQspidma->pXdmad,chanNum ))
00546 return QSPID_ERROR_LOCK;
00547 return 0;
00548 }
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 uint32_t QSPID_ReadWriteSPI(QspiDma_t *pQspidma, Access_t const ReadWrite)
00561 {
00562 QspiBuffer_t *pBuffer = &pQspidma->Qspid.qspiBuffer;
00563 uint32_t semTimer = 0x7FF;
00564
00565 assert(pBuffer->pDataRx);
00566 assert(pBuffer->pDataTx);
00567
00568
00569 if (pQspidma->progress) {
00570
00571 return QSPID_ERROR_LOCK;
00572 }
00573
00574 LockMutex(pQspidma->progress, semTimer);
00575
00576
00577 if (QSPID_configureQpsiDma
00578 ( pQspidma, pQspidma->Qspid.pQspiFrame->Addr, pBuffer, ReadWrite) )
00579 return QSPID_ERROR_LOCK;
00580
00581 SCB_CleanInvalidateDCache();
00582
00583
00584 if (XDMAD_StartTransfer( pQspidma->pXdmad, pQspidma->RxChNum ))
00585 return QSPID_ERROR_LOCK;
00586 if (XDMAD_StartTransfer( pQspidma->pXdmad, pQspidma->TxChNum ))
00587 return QSPID_ERROR_LOCK;
00588 return 0;
00589 }
00590
00591
00592
00593
00594
00595
00596
00597 uint32_t QSPID_IsBusy(volatile uint8_t *QspiSemaphore)
00598 {
00599 if( Is_LockFree(QspiSemaphore) ) {
00600 return 1;
00601 } else {
00602 return 0;
00603 }
00604 }