File indexing completed on 2025-05-11 08:24:05
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084 #include "xqspipsu.h"
0085 #include "xqspipsu_control.h"
0086 #ifndef __rtems__
0087 #include "sleep.h"
0088 #else
0089 #include <bsp/xil-compat.h>
0090 #include <rtems/rtems/cache.h>
0091 #endif
0092
0093
0094 #define MAX_DELAY_CNT 10000000U
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 s32 XQspiPsu_CfgInitialize(XQspiPsu *InstancePtr,
0132 const XQspiPsu_Config *ConfigPtr,
0133 UINTPTR EffectiveAddr)
0134 {
0135 Xil_AssertNonvoid(InstancePtr != NULL);
0136 Xil_AssertNonvoid(ConfigPtr != NULL);
0137 s32 Status;
0138
0139
0140
0141
0142
0143
0144
0145 if ((InstancePtr->IsBusy == (u32)TRUE) ||
0146 (InstancePtr->IsReady == XIL_COMPONENT_IS_READY)) {
0147 Status = (s32)XST_DEVICE_IS_STARTED;
0148 } else {
0149
0150 InstancePtr->IsBusy = (u32)FALSE;
0151 InstancePtr->Config.BaseAddress =
0152 EffectiveAddr + XQSPIPSU_OFFSET;
0153 InstancePtr->Config.ConnectionMode = ConfigPtr->ConnectionMode;
0154 InstancePtr->StatusHandler = StubStatusHandler;
0155 InstancePtr->Config.BusWidth = ConfigPtr->BusWidth;
0156 InstancePtr->Config.InputClockHz = ConfigPtr->InputClockHz;
0157 #if defined (XCLOCKING)
0158 InstancePtr->Config.RefClk = ConfigPtr->RefClk;
0159 #endif
0160 InstancePtr->Config.IsCacheCoherent =
0161 ConfigPtr->IsCacheCoherent;
0162
0163 InstancePtr->SendBufferPtr = NULL;
0164 InstancePtr->RecvBufferPtr = NULL;
0165 InstancePtr->GenFifoBufferPtr = NULL;
0166 InstancePtr->TxBytes = 0;
0167 InstancePtr->RxBytes = 0;
0168 InstancePtr->GenFifoEntries = 0;
0169 InstancePtr->ReadMode = XQSPIPSU_READMODE_DMA;
0170 InstancePtr->GenFifoCS = XQSPIPSU_GENFIFO_CS_LOWER;
0171 InstancePtr->GenFifoBus = XQSPIPSU_GENFIFO_BUS_LOWER;
0172 InstancePtr->IsUnaligned = 0;
0173 InstancePtr->IsManualstart = (u8)TRUE;
0174
0175
0176 XQspiPsu_Select(InstancePtr, XQSPIPSU_SEL_GQSPI_MASK);
0177
0178
0179
0180
0181
0182
0183 XQspiPsu_Reset(InstancePtr);
0184
0185 XQspiPsu_Enable(InstancePtr);
0186
0187 InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
0188
0189 Status = (s32)XST_SUCCESS;
0190 }
0191
0192 return Status;
0193 }
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211 void XQspiPsu_Idle(const XQspiPsu *InstancePtr)
0212 {
0213 u32 RegEn;
0214 u32 DmaStatus;
0215
0216 Xil_AssertVoid(InstancePtr != NULL);
0217 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
0218
0219
0220 RegEn = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
0221 XQSPIPSU_EN_OFFSET);
0222 if ((RegEn & XQSPIPSU_EN_MASK) != 0U) {
0223 DmaStatus = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
0224 XQSPIPSU_QSPIDMA_DST_CTRL_OFFSET);
0225 DmaStatus |= XQSPIPSU_QSPIDMA_DST_CTRL_PAUSE_STRM_MASK;
0226 DmaStatus |= XQSPIPSU_QSPIDMA_DST_CTRL_PAUSE_MEM_MASK;
0227 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
0228 XQSPIPSU_QSPIDMA_DST_CTRL_OFFSET, DmaStatus);
0229 }
0230 #if defined (XCLOCKING)
0231 Xil_ClockDisable(InstancePtr->Config.RefClk);
0232 #endif
0233 }
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251 void XQspiPsu_Reset(XQspiPsu *InstancePtr)
0252 {
0253 Xil_AssertVoid(InstancePtr != NULL);
0254 #ifdef DEBUG
0255 xil_printf("\nXQspiPsu_Reset\r\n");
0256 #endif
0257
0258
0259 XQspiPsu_Abort(InstancePtr);
0260
0261
0262 XQspiPsu_SetDefaultConfig(InstancePtr);
0263
0264 }
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278 void XQspiPsu_Abort(XQspiPsu *InstancePtr)
0279 {
0280 u32 IntrStatus, ConfigReg, FifoStatus;
0281 u32 DelayCount = 0U;
0282
0283 #ifdef __rtems__
0284 u32 FifoStatusMask = XQSPIPSU_ISR_RXEMPTY_MASK;
0285 FifoStatusMask |= XQSPIPSU_ISR_TXEMPTY_MASK;
0286 FifoStatusMask |= XQSPIPSU_ISR_GENFIFOEMPTY_MASK;
0287 #endif
0288
0289 Xil_AssertVoid(InstancePtr != NULL);
0290 #ifdef DEBUG
0291 xil_printf("\nXQspiPsu_Abort\r\n");
0292 #endif
0293 IntrStatus = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
0294 XQSPIPSU_ISR_OFFSET);
0295
0296
0297 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
0298 XQSPIPSU_ISR_OFFSET, IntrStatus | XQSPIPSU_ISR_WR_TO_CLR_MASK);
0299 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
0300 XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET,
0301 XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
0302 XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET));
0303 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
0304 XQSPIPSU_QSPIDMA_DST_STS_OFFSET,
0305 XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
0306 XQSPIPSU_QSPIDMA_DST_STS_OFFSET) |
0307 XQSPIPSU_QSPIDMA_DST_STS_WTC);
0308 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
0309 XQSPIPSU_IDR_OFFSET, XQSPIPSU_IDR_ALL_MASK);
0310 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
0311 XQSPIPSU_QSPIDMA_DST_I_DIS_OFFSET,
0312 XQSPIPSU_QSPIDMA_DST_INTR_ALL_MASK);
0313
0314
0315
0316
0317
0318
0319
0320 ConfigReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
0321 XQSPIPSU_CFG_OFFSET);
0322 ConfigReg &= ~XQSPIPSU_CFG_MODE_EN_MASK;
0323 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
0324 XQSPIPSU_CFG_OFFSET, ConfigReg);
0325
0326 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
0327 XQSPIPSU_FIFO_CTRL_OFFSET,
0328 XQSPIPSU_FIFO_CTRL_RST_TX_FIFO_MASK |
0329 XQSPIPSU_FIFO_CTRL_RST_GEN_FIFO_MASK |
0330 XQSPIPSU_FIFO_CTRL_RST_RX_FIFO_MASK);
0331
0332
0333
0334
0335
0336
0337
0338
0339 FifoStatus = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
0340 #ifdef __rtems__
0341 XQSPIPSU_ISR_OFFSET) & FifoStatusMask;
0342 while(FifoStatus != FifoStatusMask) {
0343 #else
0344 XQSPIPSU_FIFO_CTRL_OFFSET);
0345 while(FifoStatus != 0U) {
0346 #endif
0347 if (DelayCount == MAX_DELAY_CNT) {
0348 #ifdef DEBUG
0349 xil_printf("Timeout error, FIFO reset failed.\r\n");
0350 #endif
0351 } else {
0352
0353 usleep(1);
0354 DelayCount++;
0355 FifoStatus = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
0356 #ifdef __rtems__
0357 XQSPIPSU_ISR_OFFSET) & FifoStatusMask;
0358 #else
0359 XQSPIPSU_FIFO_CTRL_OFFSET);
0360 #endif
0361 }
0362 }
0363
0364 if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
0365 ConfigReg |= XQSPIPSU_CFG_MODE_EN_DMA_MASK;
0366 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
0367 XQSPIPSU_CFG_OFFSET, ConfigReg);
0368 }
0369
0370
0371 InstancePtr->TxBytes = 0;
0372 InstancePtr->RxBytes = 0;
0373 InstancePtr->GenFifoEntries = 0;
0374 InstancePtr->IsBusy = (u32)FALSE;
0375 }
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393 void XQspiPsu_PollDataHandler(XQspiPsu *InstancePtr, u32 StatusReg)
0394 {
0395
0396 Xil_AssertVoid(InstancePtr != NULL);
0397 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
0398 #ifdef DEBUG
0399 xil_printf("\nXQspiPsu_PollDataHandler\r\n");
0400 #endif
0401
0402 if ((StatusReg & XQSPIPSU_ISR_RXNEMPTY_MASK) != (u32)FALSE) {
0403
0404
0405
0406
0407
0408
0409 (void)XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
0410 XQSPIPSU_RXD_OFFSET);
0411
0412 InstancePtr->StatusHandler(InstancePtr->StatusRef,
0413 XST_SPI_POLL_DONE, 0);
0414 }
0415 if ((StatusReg & XQSPIPSU_ISR_POLL_TIME_EXPIRE_MASK) != (u32)FALSE) {
0416 InstancePtr->StatusHandler(InstancePtr->StatusRef,
0417 XST_FLASH_TIMEOUT_ERROR, 0);
0418 }
0419 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_IDR_OFFSET,
0420 (u32)XQSPIPSU_IER_RXNEMPTY_MASK |
0421 (u32)XQSPIPSU_IER_POLL_TIME_EXPIRE_MASK);
0422 InstancePtr->IsBusy = (u32)FALSE;
0423 if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
0424 XQspiPsu_SetReadMode(InstancePtr, XQSPIPSU_READMODE_DMA);
0425 }
0426
0427 XQspiPsu_GenFifoEntryCSDeAssert(InstancePtr);
0428 XQspiPsu_ManualStartEnable(InstancePtr);
0429 }
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449 s32 XQspiPsu_PolledTransfer(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg,
0450 u32 NumMsg)
0451 {
0452 s32 Index;
0453 u32 QspiPsuStatusReg;
0454 u32 IOPending = (u32)FALSE;
0455 u32 DmaIntrSts;
0456 s32 Status;
0457
0458 Xil_AssertNonvoid(InstancePtr != NULL);
0459 Xil_AssertNonvoid(Msg != NULL);
0460 Xil_AssertNonvoid(NumMsg > 0U);
0461 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
0462
0463 for (Index = 0; Index < (s32)NumMsg; Index++) {
0464 Xil_AssertNonvoid(Msg[Index].ByteCount > 0U);
0465 #ifdef __rtems__
0466 if (Msg[Index].TxBfrPtr != NULL) {
0467 rtems_cache_flush_multiple_data_lines(Msg[Index].TxBfrPtr, Msg[Index].ByteCount);
0468 }
0469 #endif
0470 }
0471 #ifdef __rtems__
0472 rtems_cache_flush_multiple_data_lines(Msg, NumMsg * sizeof(*Msg));
0473 #endif
0474
0475
0476
0477
0478
0479 if (InstancePtr->IsBusy == (u32)TRUE) {
0480 Status = (s32)XST_DEVICE_BUSY;
0481 goto END;
0482 }
0483
0484 for (Index = 0; Index < (s32)NumMsg; Index++) {
0485 if ((Msg[Index].ByteCount > XQSPIPSU_DMA_BYTES_MAX) &&
0486 ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE)) {
0487 Status = (s32)XST_FAILURE;
0488 goto END;
0489 }
0490 }
0491
0492
0493
0494
0495 InstancePtr->IsBusy = (u32)TRUE;
0496
0497 #if defined (XCLOCKING)
0498 Xil_ClockEnable(InstancePtr->Config.RefClk);
0499 #endif
0500
0501 XQspiPsu_GenFifoEntryCSAssert(InstancePtr);
0502
0503
0504 Index = 0;
0505 while (Index < (s32)NumMsg) {
0506 XQspiPsu_GenFifoEntryData(InstancePtr, &Msg[Index]);
0507 XQspiPsu_ManualStartEnable(InstancePtr);
0508
0509
0510 do {
0511 QspiPsuStatusReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
0512 XQSPIPSU_ISR_OFFSET);
0513
0514 if (((QspiPsuStatusReg & XQSPIPSU_ISR_TXNOT_FULL_MASK) != (u32)FALSE) &&
0515 ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_TX) != (u32)FALSE) &&
0516 (InstancePtr->TxBytes > 0)) {
0517 XQspiPsu_FillTxFifo(InstancePtr, &Msg[Index],
0518 (u32)XQSPIPSU_TXD_DEPTH);
0519 }
0520
0521 if ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE) {
0522 if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
0523
0524 DmaIntrSts = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
0525 XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET);
0526 if ((DmaIntrSts &
0527 XQSPIPSU_QSPIDMA_DST_I_STS_DONE_MASK) != (u32)FALSE) {
0528 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
0529 XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET, DmaIntrSts);
0530
0531 if (!((Msg[Index].RxAddr64bit >= XQSPIPSU_RXADDR_OVER_32BIT) ||
0532 (Msg[Index].Xfer64bit != (u8)0U)) &&
0533 (InstancePtr->Config.IsCacheCoherent == 0U)) {
0534 Xil_DCacheInvalidateRange((INTPTR)Msg[Index].RxBfrPtr,
0535 (INTPTR)Msg[Index].ByteCount);
0536 }
0537 IOPending = XQspiPsu_SetIOMode(InstancePtr, &Msg[Index]);
0538 InstancePtr->RxBytes = 0;
0539 if (IOPending == (u32)TRUE) {
0540 break;
0541 }
0542 }
0543 } else {
0544 XQspiPsu_IORead(InstancePtr, &Msg[Index], QspiPsuStatusReg);
0545 }
0546 }
0547 } while (((QspiPsuStatusReg &
0548 XQSPIPSU_ISR_GENFIFOEMPTY_MASK) == (u32)FALSE) ||
0549 (InstancePtr->TxBytes != 0) ||
0550 ((QspiPsuStatusReg & XQSPIPSU_ISR_TXEMPTY_MASK) == (u32)FALSE) ||
0551 (InstancePtr->RxBytes != 0));
0552
0553 if ((InstancePtr->IsUnaligned != 0) && (IOPending == (u32)FALSE)) {
0554 InstancePtr->IsUnaligned = 0;
0555 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
0556 (XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET) |
0557 XQSPIPSU_CFG_MODE_EN_DMA_MASK));
0558 InstancePtr->ReadMode = XQSPIPSU_READMODE_DMA;
0559 }
0560 if (IOPending == (u32)TRUE) {
0561 IOPending = (u32)FALSE;
0562 } else {
0563 Index++;
0564 }
0565 }
0566
0567 XQspiPsu_GenFifoEntryCSDeAssert(InstancePtr);
0568 XQspiPsu_ManualStartEnable(InstancePtr);
0569 do {
0570 QspiPsuStatusReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_ISR_OFFSET);
0571 } while ((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) == (u32)FALSE);
0572
0573
0574 InstancePtr->IsBusy = (u32)FALSE;
0575
0576 Status = (s32)XST_SUCCESS;
0577
0578 #if defined (XCLOCKING)
0579 Xil_ClockDisable(InstancePtr->Config.RefClk);
0580 #endif
0581 END:
0582 return Status;
0583 }
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604 s32 XQspiPsu_InterruptTransfer(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg,
0605 u32 NumMsg)
0606 {
0607 s32 Index;
0608 s32 Status;
0609
0610 Xil_AssertNonvoid(InstancePtr != NULL);
0611 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
0612
0613 for (Index = 0; Index < (s32)NumMsg; Index++)
0614 #ifdef __rtems__
0615 {
0616 #endif
0617 Xil_AssertNonvoid(Msg[Index].ByteCount > 0U);
0618 #ifdef __rtems__
0619 if (Msg[Index].TxBfrPtr != NULL) {
0620 rtems_cache_flush_multiple_data_lines(Msg[Index].TxBfrPtr, Msg[Index].ByteCount);
0621 }
0622 }
0623 rtems_cache_flush_multiple_data_lines(Msg, NumMsg * sizeof(*Msg));
0624 #endif
0625
0626
0627
0628
0629
0630 if (InstancePtr->IsBusy == (u32)TRUE) {
0631 Status = (s32)XST_DEVICE_BUSY;
0632 goto END;
0633 }
0634 #if defined (XCLOCKING)
0635 Xil_ClockEnable(InstancePtr->Config.RefClk);
0636 #endif
0637
0638 if ((Msg[0].Flags & XQSPIPSU_MSG_FLAG_POLL) != (u32)FALSE) {
0639 InstancePtr->IsBusy = (u32)TRUE;
0640 XQspiPsu_PollDataConfig(InstancePtr, Msg);
0641 } else {
0642
0643 for (Index = 0; Index < (s32)NumMsg; Index++) {
0644 if ((Msg[Index].ByteCount > XQSPIPSU_DMA_BYTES_MAX) &&
0645 ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE)) {
0646 Status = (s32)XST_FAILURE;
0647 goto END;
0648 }
0649 }
0650
0651
0652
0653
0654 InstancePtr->IsBusy = (u32)TRUE;
0655
0656 InstancePtr->Msg = Msg;
0657 InstancePtr->NumMsg = (s32)NumMsg;
0658 InstancePtr->MsgCnt = 0;
0659
0660
0661 XQspiPsu_GenFifoEntryCSAssert(InstancePtr);
0662
0663
0664 XQspiPsu_GenFifoEntryData(InstancePtr, &Msg[0]);
0665 XQspiPsu_ManualStartEnable(InstancePtr);
0666
0667
0668 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_IER_OFFSET,
0669 (u32)XQSPIPSU_IER_TXNOT_FULL_MASK |
0670 (u32)XQSPIPSU_IER_TXEMPTY_MASK |
0671 (u32)XQSPIPSU_IER_RXNEMPTY_MASK |
0672 (u32)XQSPIPSU_IER_GENFIFOEMPTY_MASK |
0673 (u32)XQSPIPSU_IER_RXEMPTY_MASK);
0674
0675 if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
0676 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_QSPIDMA_DST_I_EN_OFFSET,
0677 XQSPIPSU_QSPIDMA_DST_I_EN_DONE_MASK);
0678 }
0679 }
0680 Status = (s32)XST_SUCCESS;
0681
0682 END:
0683 return Status;
0684 }
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700 s32 XQspiPsu_InterruptHandler(XQspiPsu *InstancePtr)
0701 {
0702 u32 QspiPsuStatusReg, DmaIntrStatusReg = 0;
0703 XQspiPsu_Msg *Msg;
0704 s32 NumMsg;
0705 s32 MsgCnt;
0706 u8 DeltaMsgCnt = 0;
0707 u32 TxRxFlag;
0708
0709 Xil_AssertNonvoid(InstancePtr != NULL);
0710 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
0711 Xil_AssertNonvoid(InstancePtr->NumMsg > 0);
0712 Xil_AssertNonvoid(InstancePtr->Msg != NULL);
0713
0714 Msg = InstancePtr->Msg;
0715 NumMsg = InstancePtr->NumMsg;
0716 MsgCnt = InstancePtr->MsgCnt;
0717 TxRxFlag = Msg[MsgCnt].Flags;
0718
0719
0720 QspiPsuStatusReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_ISR_OFFSET);
0721 if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
0722
0723 DmaIntrStatusReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
0724 XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET);
0725 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET,
0726 DmaIntrStatusReg);
0727 }
0728 if (((DmaIntrStatusReg & XQSPIPSU_QSPIDMA_DST_INTR_ERR_MASK) != (u32)FALSE)) {
0729
0730 InstancePtr->StatusHandler(InstancePtr->StatusRef,
0731 XST_SPI_COMMAND_ERROR, 0);
0732 }
0733
0734 if ((MsgCnt < NumMsg) && ((TxRxFlag & XQSPIPSU_MSG_FLAG_TX) != (u32)FALSE) &&
0735 ((QspiPsuStatusReg & XQSPIPSU_ISR_TXNOT_FULL_MASK) != (u32)FALSE) &&
0736 (InstancePtr->TxBytes > 0)) {
0737 XQspiPsu_FillTxFifo(InstancePtr, &Msg[MsgCnt], (u32)XQSPIPSU_TXD_DEPTH);
0738 }
0739
0740
0741
0742
0743 if ((MsgCnt < NumMsg) && ((TxRxFlag & XQSPIPSU_MSG_FLAG_TX) != (u32)FALSE) &&
0744 ((QspiPsuStatusReg & XQSPIPSU_ISR_TXEMPTY_MASK) != (u32)FALSE) &&
0745 ((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) != (u32)FALSE) &&
0746 (InstancePtr->TxBytes == 0) &&
0747 ((TxRxFlag & XQSPIPSU_MSG_FLAG_RX) == (u32)FALSE)) {
0748 MsgCnt += 1;
0749 DeltaMsgCnt = 1U;
0750 }
0751
0752 if ((MsgCnt < NumMsg) &&
0753 ((TxRxFlag & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE)) {
0754 if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
0755 if ((DmaIntrStatusReg &
0756 XQSPIPSU_QSPIDMA_DST_I_STS_DONE_MASK) != (u32)FALSE) {
0757
0758 if (!((Msg[MsgCnt].RxAddr64bit >= XQSPIPSU_RXADDR_OVER_32BIT) ||
0759 (Msg[MsgCnt].Xfer64bit != (u8)0U)) &&
0760 (InstancePtr->Config.IsCacheCoherent == 0U)) {
0761 Xil_DCacheInvalidateRange((INTPTR)Msg[MsgCnt].RxBfrPtr, (INTPTR)Msg[MsgCnt].ByteCount);
0762 }
0763 if (XQspiPsu_SetIOMode(InstancePtr, &Msg[MsgCnt]) == (u32)TRUE) {
0764 XQspiPsu_GenFifoEntryData(InstancePtr, &Msg[MsgCnt]);
0765 XQspiPsu_ManualStartEnable(InstancePtr);
0766 } else {
0767 InstancePtr->RxBytes = 0;
0768 MsgCnt += 1;
0769 DeltaMsgCnt = 1U;
0770 }
0771 }
0772 } else {
0773 if (InstancePtr->RxBytes != 0) {
0774 XQspiPsu_IORead(InstancePtr, &Msg[MsgCnt], QspiPsuStatusReg);
0775 if (InstancePtr->RxBytes == 0) {
0776 MsgCnt += 1;
0777 DeltaMsgCnt = 1U;
0778 }
0779 }
0780 }
0781 }
0782
0783
0784
0785
0786
0787
0788
0789 if ((MsgCnt < NumMsg) && (DeltaMsgCnt == (u8)FALSE) &&
0790 ((TxRxFlag & XQSPIPSU_MSG_FLAG_RX) == (u32)FALSE) &&
0791 ((TxRxFlag & XQSPIPSU_MSG_FLAG_TX) == (u32)FALSE) &&
0792 ((TxRxFlag & XQSPIPSU_MSG_FLAG_POLL) == (u32)FALSE) &&
0793 ((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) != (u32)FALSE)) {
0794 MsgCnt += 1;
0795 DeltaMsgCnt = 1U;
0796 }
0797 InstancePtr->MsgCnt = MsgCnt;
0798
0799
0800
0801
0802
0803 if (((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) != (u32)FALSE) &&
0804 ((DeltaMsgCnt != (u8)FALSE) || (MsgCnt > NumMsg))) {
0805 if (MsgCnt < NumMsg) {
0806 if (InstancePtr->IsUnaligned != 0) {
0807 InstancePtr->IsUnaligned = 0;
0808 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
0809 XQSPIPSU_CFG_OFFSET, (XQspiPsu_ReadReg(
0810 InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET) |
0811 XQSPIPSU_CFG_MODE_EN_DMA_MASK));
0812 InstancePtr->ReadMode = XQSPIPSU_READMODE_DMA;
0813 }
0814
0815 XQspiPsu_GenFifoEntryData(InstancePtr, &Msg[MsgCnt]);
0816 XQspiPsu_ManualStartEnable(InstancePtr);
0817 } else if (MsgCnt == NumMsg) {
0818
0819 MsgCnt += 1;
0820 InstancePtr->MsgCnt = MsgCnt;
0821
0822 XQspiPsu_GenFifoEntryCSDeAssert(InstancePtr);
0823 XQspiPsu_ManualStartEnable(InstancePtr);
0824 } else {
0825
0826 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_IDR_OFFSET,
0827 (u32)XQSPIPSU_IER_TXNOT_FULL_MASK |
0828 (u32)XQSPIPSU_IER_TXEMPTY_MASK |
0829 (u32)XQSPIPSU_IER_RXNEMPTY_MASK |
0830 (u32)XQSPIPSU_IER_GENFIFOEMPTY_MASK |
0831 (u32)XQSPIPSU_IER_RXEMPTY_MASK);
0832 if (InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) {
0833 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
0834 XQSPIPSU_QSPIDMA_DST_I_DIS_OFFSET,
0835 XQSPIPSU_QSPIDMA_DST_I_EN_DONE_MASK);
0836 }
0837
0838 InstancePtr->IsBusy = (u32)FALSE;
0839 #if defined (XCLOCKING)
0840 Xil_ClockDisable(InstancePtr->Config.RefClk);
0841 #endif
0842
0843 InstancePtr->StatusHandler(InstancePtr->StatusRef,
0844 XST_SPI_TRANSFER_DONE, 0);
0845 }
0846 }
0847 if ((TxRxFlag & XQSPIPSU_MSG_FLAG_POLL) != (u32)FALSE) {
0848 XQspiPsu_PollDataHandler(InstancePtr, QspiPsuStatusReg);
0849 }
0850 return (s32)XST_SUCCESS;
0851 }
0852
0853
0854
0855
0856
0857
0858
0859
0860
0861
0862
0863
0864
0865
0866
0867
0868
0869
0870
0871
0872
0873
0874
0875
0876
0877
0878
0879
0880
0881
0882
0883
0884
0885
0886
0887
0888
0889
0890 void XQspiPsu_SetStatusHandler(XQspiPsu *InstancePtr, void *CallBackRef,
0891 XQspiPsu_StatusHandler FuncPointer)
0892 {
0893 Xil_AssertVoid(InstancePtr != NULL);
0894 Xil_AssertVoid(FuncPointer != NULL);
0895 Xil_AssertVoid(CallBackRef != NULL);
0896 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
0897
0898 InstancePtr->StatusHandler = FuncPointer;
0899 InstancePtr->StatusRef = CallBackRef;
0900 }
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912
0913
0914
0915
0916
0917
0918 void XQspiPsu_WriteProtectToggle(const XQspiPsu *InstancePtr, u32 Toggle)
0919 {
0920 Xil_AssertVoid(InstancePtr != NULL);
0921 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
0922
0923 if (InstancePtr->Config.ConnectionMode ==
0924 XQSPIPSU_CONNECTION_MODE_SINGLE) {
0925
0926 XQspiPsu_GenFifoEntryCSAssert(InstancePtr);
0927
0928 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
0929 XQSPIPSU_GPIO_OFFSET, Toggle);
0930
0931 } else {
0932 #ifdef DEBUG
0933 xil_printf("Dual Parallel/Stacked configuration ");
0934 xil_printf("is not supported by this API\r\n");
0935 #endif
0936 }
0937 }
0938
0939
0940
0941
0942
0943
0944
0945
0946
0947
0948
0949
0950
0951
0952
0953
0954
0955
0956
0957
0958 s32 XQspiPsu_StartDmaTransfer(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg,
0959 u32 NumMsg)
0960 {
0961 s32 Index;
0962 u32 QspiPsuStatusReg = 0;
0963
0964 Xil_AssertNonvoid(InstancePtr != NULL);
0965 Xil_AssertNonvoid(Msg != NULL);
0966 Xil_AssertNonvoid(NumMsg > 0U);
0967 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
0968 for (Index = 0; Index < (s32)NumMsg; Index++) {
0969 Xil_AssertNonvoid(Msg[Index].ByteCount > 0U);
0970 }
0971
0972
0973
0974
0975
0976 if (InstancePtr->IsBusy == (u32)TRUE) {
0977 return (s32)XST_DEVICE_BUSY;
0978 }
0979
0980
0981 for (Index = 0; Index < (s32)NumMsg; Index++) {
0982 if ((Msg[Index].ByteCount > XQSPIPSU_DMA_BYTES_MAX) &&
0983 ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE)) {
0984 return (s32)XST_FAILURE;
0985 }
0986 }
0987
0988
0989
0990
0991
0992 InstancePtr->IsBusy = (u32)TRUE;
0993
0994
0995 XQspiPsu_GenFifoEntryCSAssert(InstancePtr);
0996
0997 Index = 0;
0998 while (Index < (s32)NumMsg) {
0999 InstancePtr->Msg = &Msg[Index];
1000 XQspiPsu_GenFifoEntryData(InstancePtr, &Msg[Index]);
1001 if (InstancePtr->IsManualstart == (u32)TRUE) {
1002 #ifdef DEBUG
1003 xil_printf("\nManual Start\r\n");
1004 #endif
1005 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
1006 XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress,
1007 XQSPIPSU_CFG_OFFSET) |
1008 XQSPIPSU_CFG_START_GEN_FIFO_MASK);
1009 }
1010 do {
1011 if((InstancePtr->ReadMode == XQSPIPSU_READMODE_DMA) &&
1012 ((Msg[Index].Flags & XQSPIPSU_MSG_FLAG_RX) != (u32)FALSE)) {
1013 break;
1014 }
1015 QspiPsuStatusReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_ISR_OFFSET);
1016
1017 } while (((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) == (u32)FALSE) ||
1018 (InstancePtr->TxBytes != 0) ||
1019 ((QspiPsuStatusReg & XQSPIPSU_ISR_TXEMPTY_MASK) == (u32)FALSE));
1020
1021 if(InstancePtr->ReadMode == XQSPIPSU_READMODE_IO) {
1022 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress,
1023 XQSPIPSU_CFG_OFFSET, (XQspiPsu_ReadReg(
1024 InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET) |
1025 XQSPIPSU_CFG_MODE_EN_DMA_MASK));
1026 InstancePtr->ReadMode = XQSPIPSU_READMODE_DMA;
1027 }
1028 Index++;
1029 }
1030 return (s32)XST_SUCCESS;
1031 }
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047 s32 XQspiPsu_CheckDmaDone(XQspiPsu *InstancePtr)
1048 {
1049 u32 QspiPsuStatusReg;
1050 u32 DmaIntrSts;
1051
1052 Xil_AssertNonvoid(InstancePtr != NULL);
1053 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1054
1055 DmaIntrSts = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET);
1056 if ((DmaIntrSts & XQSPIPSU_QSPIDMA_DST_I_STS_DONE_MASK) != (u32)FALSE) {
1057 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_QSPIDMA_DST_I_STS_OFFSET, DmaIntrSts);
1058
1059 if (!((InstancePtr->Msg->RxAddr64bit >= XQSPIPSU_RXADDR_OVER_32BIT) ||
1060 (InstancePtr->Msg->Xfer64bit != (u8)0U)) &&
1061 (InstancePtr->Config.IsCacheCoherent == 0U)) {
1062 Xil_DCacheInvalidateRange((INTPTR)InstancePtr->Msg->RxBfrPtr, (INTPTR)InstancePtr->RxBytes);
1063 }
1064
1065 XQspiPsu_GenFifoEntryCSDeAssert(InstancePtr);
1066 if (InstancePtr->IsManualstart == (u8)TRUE) {
1067 #ifdef DEBUG
1068 xil_printf("\nManual Start\r\n");
1069 #endif
1070 XQspiPsu_WriteReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET,
1071 XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_CFG_OFFSET) |
1072 XQSPIPSU_CFG_START_GEN_FIFO_MASK);
1073 }
1074 do {
1075 QspiPsuStatusReg = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, XQSPIPSU_ISR_OFFSET);
1076 } while ((QspiPsuStatusReg & XQSPIPSU_ISR_GENFIFOEMPTY_MASK) == (u32)FALSE);
1077
1078
1079 InstancePtr->IsBusy = (u32)FALSE;
1080
1081 return (s32)XST_SUCCESS;
1082 }
1083 else {
1084 return (s32)XST_FAILURE;
1085 }
1086
1087 }
1088