S32 SDK
quadspi_driver.c
Go to the documentation of this file.
1 /*
2  * Copyright 2017 NXP
3  * All rights reserved.
4  *
5  * THIS SOFTWARE IS PROVIDED BY NXP "AS IS" AND ANY EXPRESSED OR
6  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
7  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
8  * IN NO EVENT SHALL NXP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
9  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
11  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
12  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
13  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
14  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
15  * THE POSSIBILITY OF SUCH DAMAGE.
16  */
17 
18 #include "quadspi_driver.h"
19 #include "quadspi_hw_access.h"
20 #include "edma_driver.h"
21 #include "osif.h"
22 #include "interrupt_manager.h"
23 
24 /*******************************************************************************
25  * Variables
26  ******************************************************************************/
27 
30 /* Minimum Tx buffer fill needed to allow Tx operation to start */
31 #define QSPI_TX_MIN_BUF_FILL 4U
32 /* Wrap-around value for timeout */
33 #define QSPI_TIMEOUT_WRAP 0xFFFFFFFFU
34 
35 /* Operations codes for state->operation field */
36 #define QSPI_OP_READ 0U
37 #define QSPI_OP_READ_INT 1U
38 #define QSPI_OP_WRITE 2U
39 
40 /* Mask of QuadSPI IP-related error flags */
41 #define QSPI_ERR_FLAGS_MASK (QuadSPI_FR_TBUF_MASK | \
42  QuadSPI_FR_ILLINE_MASK | \
43  QuadSPI_FR_RBOF_MASK | \
44  QuadSPI_FR_IPAEF_MASK | \
45  QuadSPI_FR_IPIEF_MASK | \
46  QuadSPI_FR_IPGEF_MASK)
47 
48 
49 /* Table of base addresses for QuadSPI instances. */
51 
52 /* Pointer to runtime state structure.*/
53 qspi_state_t * g_qspiStatePtr[QuadSPI_INSTANCE_COUNT] = {NULL};
54 
55 /* Table of Tx DMA requests. */
56 const uint8_t g_qspiDmaTxSrc[QuadSPI_INSTANCE_COUNT] = FEATURE_QSPI_DMA_TX_REQ;
57 
58 /* Table of Rx DMA requests. */
59 const uint8_t g_qspiDmaRxSrc[QuadSPI_INSTANCE_COUNT] = FEATURE_QSPI_DMA_RX_REQ;
60 
61 /* Table to of QSPI interrupt sources. */
62 const IRQn_Type g_qspiIrqId[QuadSPI_INSTANCE_COUNT] = QuadSPI_IRQS;
63 
64 /*******************************************************************************
65  * Private Functions
66  ******************************************************************************/
67 
68 
69  /*FUNCTION**********************************************************************
70  *
71  * Function Name : QSPI_DRV_Timeout
72  * Description : Checks for timeout condition
73  *
74  *END**************************************************************************/
75 static bool QSPI_DRV_Timeout(uint32_t startTime, uint32_t timeout)
76 {
77  uint32_t currentTime;
78  bool retVal;
79 
80  currentTime = OSIF_GetMilliseconds();
81  if (currentTime >= startTime)
82  {
83  retVal = ((currentTime - startTime) > timeout)?true:false;
84  }
85  else
86  {
87  /* wrap around */
88  retVal = ((QSPI_TIMEOUT_WRAP - startTime + currentTime) > timeout)?true:false;
89  }
90  return retVal;
91 }
92 
93 
94 /*FUNCTION**********************************************************************
95  *
96  * Function Name : QSPI_DRV_ProcessData
97  * Description : Processes read data
98  *
99  *END**************************************************************************/
100 static inline status_t QSPI_DRV_ProcessData(uint32_t value, qspi_state_t * state)
101 {
102  status_t status = STATUS_SUCCESS;
103 
104  if (state->data)
105  {
106  /* Normal read */
107  *((uint32_t *)(state->data)) = value;
108  state->data += 4U;
109  }
110  else if (state->roData)
111  {
112  /* Verify */
113  if (*((uint32_t *)(state->roData)) != value)
114  {
115  status = STATUS_ERROR;
116  }
117  state->roData += 4U;
118  }
119  else
120  {
121  /* Blank check */
122  if (value != 0xFFFFFFFFU)
123  {
124  status = STATUS_ERROR;
125  }
126  }
127  state->size -= 4;
128  return status;
129 }
130 
131 
132 /*FUNCTION**********************************************************************
133  *
134  * Function Name : QSPI_DRV_ProcessLastData
135  * Description : Processes last few data bytes (less than 4)
136  *
137  *END**************************************************************************/
138 static inline status_t QSPI_DRV_ProcessLastData(uint32_t value, qspi_state_t * state)
139 {
140  uint8_t cnt;
141  status_t status = STATUS_SUCCESS;
142  uint32_t dataSize;
143 
144  dataSize = state->size;
145  if (state->data)
146  {
147  /* Normal read */
148  for (cnt = 0U; cnt < dataSize; cnt++)
149  {
150  *state->data = (uint8_t)(value & 0xFFU);
151  value >>= 8U;
152  state->data++;
153  }
154  }
155  else if (state->roData)
156  {
157  /* Verify */
158  for (cnt = 0U; cnt < dataSize; cnt++)
159  {
160  if (*(state->roData) != (value & 0xFFU))
161  {
162  status = STATUS_ERROR;
163  }
164  value >>= 8U;
165  state->roData++;
166  }
167  }
168  else
169  {
170  /* Blank check */
171  if (~value & ((1U << (dataSize * 8U)) - 1U))
172  {
173  status = STATUS_ERROR;
174  }
175  }
176  state->size = 0U;
177  return status;
178 }
179 
180 
181 /*FUNCTION**********************************************************************
182  *
183  * Function Name : QSPI_DRV_FillTxBuf
184  * Description : Fill Tx buffer
185  *
186  *END**************************************************************************/
187 static void QSPI_DRV_FillTxBuf(QuadSPI_Type *baseAddr, qspi_state_t * state)
188 {
189  uint32_t data;
190  uint8_t cnt;
191 
192  while ((QSPI_DRV_GetTxWatermarkAvailable(baseAddr)) && (state->size > 0U))
193  {
194  if (state->size < 4U)
195  {
196  /* Processes last few data bytes (less than 4) */
197  data = 0U;
198  for (cnt = 0U; cnt < state->size; cnt++)
199  {
200  data += (*(state->roData) << (8U * cnt));
201  state->roData++;
202  }
203  state->size = 0;
204  }
205  else
206  {
207  data = *(uint32_t *)(state->roData);
208  state->size -= 4;
209  state->roData += 4;
210  }
211 
212  QSPI_DRV_WriteTxData(baseAddr, data);
213  }
214 
215  return;
216 }
217 
218 
219 /*FUNCTION**********************************************************************
220  *
221  * Function Name : QSPI_DRV_ErrorCheck
222  * Description : Checks if there were errors during IP command execution
223  *
224  *END**************************************************************************/
225 static inline status_t QSPI_DRV_ErrorCheck(QuadSPI_Type *baseAddr)
226 {
227  if (baseAddr->FR & QSPI_ERR_FLAGS_MASK)
228  {
229  /* clear error flags */
230  baseAddr->FR = QSPI_ERR_FLAGS_MASK;
231  return STATUS_ERROR;
232  }
233  return STATUS_SUCCESS;
234 
235 }
236 
237 
238 /*FUNCTION**********************************************************************
239  *
240  * Function Name : QSPI_DRV_PadTxBuf
241  * Description : Pad Tx buffer up to a minimum number of entries required
242  * by the device for transmission to start
243  *
244  *END**************************************************************************/
245 static inline void QSPI_DRV_PadTxBuf(QuadSPI_Type *baseAddr)
246 {
247  uint32_t bufFill;
248 
249  bufFill = QSPI_DRV_GetTxBufFill(baseAddr);
250  while (bufFill < QSPI_TX_MIN_BUF_FILL)
251  {
252  QSPI_DRV_WriteTxData(baseAddr, 0xFFFFFFFFUL);
253  bufFill++;
254  }
255 }
256 
257 
258 /*FUNCTION**********************************************************************
259  *
260  * Function Name : QSPI_DRV_SwReset
261  * Description : Resets the QuadSPI device
262  *
263  *END**************************************************************************/
264 static void QSPI_DRV_SwReset(QuadSPI_Type *baseAddr)
265 {
266  /* Enable QuadSPI module before asserting the reset bits. */
267  QSPI_DRV_Enable(baseAddr);
268  /* Software reset AHB domain and Serial Flash domain at the same time. */
269  QSPI_DRV_SwResetOn(baseAddr);
270  /* Disable QuadSPI module before de-asserting the reset bits. */
271  QSPI_DRV_Disable(baseAddr);
272  /* De-asset Software reset AHB domain and Serial Flash domain bits. */
273  QSPI_DRV_SwResetOff(baseAddr);
274 }
275 
276 
277 
278 /*FUNCTION**********************************************************************
279  *
280  * Function Name : QSPI_DRV_ConfigureChipOptions
281  * Description : Configures chip-specific QuadSPI options
282  *
283  *END**************************************************************************/
284 static void QSPI_DRV_ConfigureChipOptions(QuadSPI_Type *baseAddr, const qspi_user_config_t * userConfigPtr)
285 {
286  /* always enable pads input buffers */
287  uint8_t option = QSPI_MCR_SCLKCFG_INPUT_EN;
288 
289  if (userConfigPtr->clock_src == QSPI_CLK_SRC_FIRC_DIV1)
290  {
291  /* configure clock source selection */
292  option |= QSPI_MCR_SCLKCFG_CLK_SRC;
293  }
294  if (userConfigPtr->readMode == QSPI_READ_MODE_EXTERNAL_DQS)
295  {
296  /* configure external DQS mode */
297  option |= QSPI_MCR_SCLKCFG_EXT_DQS;
298  }
299  QSPI_DRV_SetChipOptions(baseAddr, option);
300 }
301 
302 
303 /*FUNCTION**********************************************************************
304  *
305  * Function Name : QSPI_DRV_ConfigureChipOptions
306  * Description : Configures chip-specific QuadSPI options
307  *
308  *END**************************************************************************/
309 static void QSPI_DRV_IRQHandler(uint32_t instance)
310 {
311  QuadSPI_Type *baseAddr;
312  qspi_state_t * state;
313  uint8_t cnt;
314  uint32_t size;
315  status_t status = STATUS_SUCCESS;
316 
317  baseAddr = g_qspiBase[instance];
318  state = g_qspiStatePtr[instance];
319 
320  if (state->operation == QSPI_OP_READ_INT)
321  {
322  /* For interrupt transfer read the received data from the device Rx buffer */
323  size = state->size >> 2;
324  for (cnt = 0; cnt < size; cnt++)
325  {
326  status = QSPI_DRV_ProcessData(baseAddr->RBDR[cnt], state);
327  if (status != STATUS_SUCCESS)
328  {
329  break;
330  }
331  }
332  if ((state->size > 0) && (status == STATUS_SUCCESS))
333  {
334  /* check incomplete word */
335  status = QSPI_DRV_ProcessLastData(baseAddr->RBDR[size], state);
336  }
337  if (status != STATUS_SUCCESS)
338  {
339  state->status = status;
340  }
341  }
342 
343  /* No need to check the transfer end event, interrupt is only used for this event */
344  QSPI_DRV_DisableInt(baseAddr, QuadSPI_RSER_TFIE_MASK);
345  /* For write operations call callback to announce the end event to the user */
346  /* For read operations this will be done from DMA callback */
347  if ((state->callback != NULL) && (state->operation == QSPI_OP_WRITE))
348  {
349  state->callback(instance, state->callbackParam);
350  }
351 }
352 
353 
354 #if (QuadSPI_INSTANCE_COUNT > 0U)
355 /*FUNCTION**********************************************************************
356  *
357  * Function Name : QSPI_IRQHandler
358  * Description : Implementation of QSPI interrupt handler named in start-up code
359  *
360  *END**************************************************************************/
361 void QSPI_IRQHandler(void)
362 {
363  QSPI_DRV_IRQHandler(0);
364 }
365 #endif
366 
367 
368 /*FUNCTION**********************************************************************
369  *
370  * Function Name : QSPI_DRV_EndDmaTransfer
371  * Description : Callback that handles the end of a DMA transfer
372  *
373  *END**************************************************************************/
374 static void QSPI_DRV_EndDmaTransfer(void *stateStruct, edma_chn_status_t status)
375 {
376  qspi_state_t * state;
377  QuadSPI_Type *baseAddr;
378 
379  state = (qspi_state_t *)stateStruct;
380  baseAddr = g_qspiBase[state->instance];
381 
382  /* Record error if there was any */
383  if (status == EDMA_CHN_ERROR)
384  {
385  state->status = STATUS_ERROR;
386  }
387  (void)EDMA_DRV_StopChannel(state->dmaChannel);
388  QSPI_DRV_DisableDmaReq(baseAddr);
389  /* For read operations call callback to announce the end event to the user */
390  /* For write operations this will be done from interrupt handler */
391  if ((state->callback != NULL) && (state->operation != QSPI_OP_WRITE))
392  {
393  state->callback(state->instance, state->callbackParam);
394  }
395 }
396 
397 
398 /*FUNCTION**********************************************************************
399  *
400  * Function Name : QSPI_DRV_ConfigDmaRx
401  * Description : Sets up an Rx DMA transfer
402  *
403  *END**************************************************************************/
404 static void QSPI_DRV_ConfigDmaRx(uint32_t instance, qspi_state_t * state)
405 {
406  QuadSPI_Type *baseAddr;
407 
408  baseAddr = g_qspiBase[instance];
409  /* Set the DMA request source */
410  (void)EDMA_DRV_SetChannelRequest(state->dmaChannel, g_qspiDmaRxSrc[instance]);
411 
412  /* Configure the transfer control descriptor for the Rx channel */
413  (void)EDMA_DRV_ConfigMultiBlockTransfer(state->dmaChannel,
415  QSPI_DRV_GetRxDataAddr(baseAddr),
416  (uint32_t)(state->data),
418  4, state->size >> 2, true);
419 
420  /* Setup callback for DMA transfer end */
421  (void)EDMA_DRV_InstallCallback(state->dmaChannel,
422  (edma_callback_t)(QSPI_DRV_EndDmaTransfer),
423  (void*)(state));
424 
425  /* Start DMA channel */
426  (void)EDMA_DRV_StartChannel(state->dmaChannel);
427 
428  /* Enable Rx DMA requests in QSPI */
429  QSPI_DRV_EnableRxDmaReq(baseAddr);
430 }
431 
432 
433 /*FUNCTION**********************************************************************
434  *
435  * Function Name : QSPI_DRV_ConfigDmaTx
436  * Description : Sets up a Tx DMA transfer
437  *
438  *END**************************************************************************/
439 static void QSPI_DRV_ConfigDmaTx(uint32_t instance, qspi_state_t * state)
440 {
441  QuadSPI_Type *baseAddr;
442 
443  baseAddr = g_qspiBase[instance];
444  /* Set the DMA request source */
445  (void)EDMA_DRV_SetChannelRequest(state->dmaChannel, g_qspiDmaTxSrc[instance]);
446 
447  /* Configure the transfer control descriptor for the Tx channel */
448  (void)EDMA_DRV_ConfigMultiBlockTransfer(state->dmaChannel,
450  (uint32_t)(state->roData),
451  QSPI_DRV_GetTxDataAddr(baseAddr),
453  4, state->size >> 2, true);
454 
455  /* Setup callback for DMA transfer end */
456  (void)EDMA_DRV_InstallCallback(state->dmaChannel,
457  (edma_callback_t)(QSPI_DRV_EndDmaTransfer),
458  (void*)(state));
459 
460  /* Start DMA channel */
461  (void)EDMA_DRV_StartChannel(state->dmaChannel);
462 
463  /* Enable Tx DMA requests in QSPI */
464  QSPI_DRV_EnableTxDmaReq(baseAddr);
465 }
466 
467 
470 /*******************************************************************************
471  * Code
472  ******************************************************************************/
473 
474 
475 /*FUNCTION**********************************************************************
476  *
477  * Function Name : QSPI_DRV_Init
478  * Description : Initializes the qspi driver
479  * Implements : QSPI_DRV_Init_Activity
480  *
481  *END**************************************************************************/
482 status_t QSPI_DRV_Init(uint32_t instance,
483  const qspi_user_config_t * userConfigPtr,
484  qspi_state_t * state)
485 {
486  QuadSPI_Type *baseAddr;
487 
489  DEV_ASSERT(g_qspiStatePtr[instance] == NULL);
490 
491  baseAddr = g_qspiBase[instance];
492  g_qspiStatePtr[instance] = state;
493 
494  /* Initialize driver status structure */
495  state->dmaSupport = userConfigPtr->dmaSupport;
496  state->dmaChannel = userConfigPtr->dmaChannel;
497  state->callback = userConfigPtr->callback;
498  state->callbackParam = userConfigPtr->callbackParam;
499  state->instance = instance;
500  state->status = STATUS_SUCCESS;
501 
502  /* Reset module */
503  QSPI_DRV_SwReset(baseAddr);
504 
505  /* Apply configuration settings */
506  QSPI_DRV_SetMemMap(baseAddr, userConfigPtr->side, userConfigPtr->memSize);
507  QSPI_DRV_SetAddrOptions(baseAddr, userConfigPtr->columnAddr, userConfigPtr->wordAddresable);
508  QSPI_DRV_SetRxCfg(baseAddr, userConfigPtr->sampleDelay, userConfigPtr->clockPhase);
509  QSPI_DRV_SetCsHoldTime(baseAddr, userConfigPtr->csHoldTime);
510  QSPI_DRV_SetCsSetupTime(baseAddr, userConfigPtr->csSetupTime);
511  /* Unused side lines are "no matter" so just repeat idle settings on both sides */
512  QSPI_DRV_SetIdleLineValues(baseAddr, userConfigPtr->io2IdleValue, userConfigPtr->io3IdleValue,
513  userConfigPtr->io2IdleValue, userConfigPtr->io3IdleValue);
514  QSPI_DRV_SetEndianess(baseAddr, userConfigPtr->endianess);
515  QSPI_DRV_SetRxBufReadout(baseAddr, QSPI_RX_READOUT_IP);
516  /* Watermarks are used in DMA mode */
517  QSPI_DRV_SetTxWatermark(baseAddr, 2U);
518  QSPI_DRV_SetRxWatermark(baseAddr, 1U);
519 
520  if (userConfigPtr->dataRate == QSPI_DATE_RATE_SDR)
521  {
522  /* Check for unsupported modes */
523  DEV_ASSERT(((userConfigPtr->readMode == QSPI_READ_MODE_INTERNAL_SAMPLING) &&
524  (userConfigPtr->side == QSPI_FLASH_SIDE_B)) ||
525  ((userConfigPtr->readMode == QSPI_READ_MODE_INTERNAL_SAMPLING) &&
526  (userConfigPtr->side == QSPI_FLASH_SIDE_A)) ||
527  ((userConfigPtr->readMode == QSPI_READ_MODE_INTERNAL_DQS) &&
528  (userConfigPtr->side == QSPI_FLASH_SIDE_A)));
529  QSPI_DDR_Disable(baseAddr);
530  if (userConfigPtr->readMode == QSPI_READ_MODE_INTERNAL_SAMPLING)
531  {
532  QSPI_DQS_Disable(baseAddr);
533  }
534  else
535  {
536  QSPI_DQS_Enable(baseAddr);
537  }
538  }
539  else /* QSPI_DATE_RATE_DDR */
540  {
541  /* Check for unsupported modes */
543  QSPI_DDR_Enable(baseAddr);
544  QSPI_DQS_Enable(baseAddr);
545  }
546 
547  /* Configure chip-specific options */
548  QSPI_DRV_ConfigureChipOptions(baseAddr, userConfigPtr);
549 
550  /* Enable QSPI interrupt. */
551  INT_SYS_EnableIRQ(g_qspiIrqId[instance]);
552 
553  /* Enable QuadSPI module */
554  QSPI_DRV_Enable(baseAddr);
555 
556  return STATUS_SUCCESS;
557 }
558 
559 
560 /*FUNCTION**********************************************************************
561  *
562  * Function Name : QSPI_DRV_Deinit
563  * Description : De-initialize the qspi driver
564  * Implements : QSPI_DRV_Deinit_Activity
565  *
566  *END**************************************************************************/
567 status_t QSPI_DRV_Deinit(uint32_t instance)
568 {
569  QuadSPI_Type *baseAddr;
570 
572  baseAddr = g_qspiBase[instance];
573 
574  /* Disable QuadSPI module */
575  QSPI_DRV_Disable(baseAddr);
576 
577  /* Enable QSPI interrupt. */
578  INT_SYS_DisableIRQ(g_qspiIrqId[instance]);
579 
580  g_qspiStatePtr[instance] = NULL;
581 
582  return STATUS_SUCCESS;
583 }
584 
585 
586 /*FUNCTION**********************************************************************
587  *
588  * Function Name : QSPI_DRV_AhbSetup
589  * Description : Sets up AHB accesses to the serial flash
590  * Implements : QSPI_DRV_AhbSetup_Activity
591  *
592  *END**************************************************************************/
593 status_t QSPI_DRV_AhbSetup(uint32_t instance, const qspi_ahb_config_t *config)
594 {
596  QuadSPI_Type *baseAddr;
597 
598  baseAddr = g_qspiBase[instance];
599 
600  QSPI_DRV_SetAhbBuf0(baseAddr, config->sizes[0U], config->masters[0U], config->highPriority);
601  QSPI_DRV_SetAhbBuf1(baseAddr, config->sizes[1U], config->masters[1U]);
602  QSPI_DRV_SetAhbBuf2(baseAddr, config->sizes[2U], config->masters[2U]);
603  QSPI_DRV_SetAhbBuf3(baseAddr, config->sizes[3U], config->masters[3U], config->allMasters);
604 
605  return STATUS_SUCCESS;
606 }
607 
608 
609 /*FUNCTION**********************************************************************
610  *
611  * Function Name : QSPI_DRV_IpCommand
612  * Description : Launches a simple IP command
613  * Implements : QSPI_DRV_IpCommand_Activity
614  *
615  *END**************************************************************************/
616 status_t QSPI_DRV_IpCommand(uint32_t instance, uint8_t lut, uint32_t timeout)
617 {
619  QuadSPI_Type *baseAddr;
620  qspi_state_t * state;
621  status_t status = STATUS_SUCCESS;
622  uint32_t startTime;
623 
624  baseAddr = g_qspiBase[instance];
625  state = g_qspiStatePtr[instance];
626  state->status = STATUS_SUCCESS;
627  /* Trigger IP command with specified sequence and dummy size */
628  QSPI_DRV_IpTrigger(baseAddr, lut, 1U);
629  /* Wait for command to complete */
630  startTime = OSIF_GetMilliseconds();
631  do
632  {
633  status = QSPI_DRV_IpGetStatus(instance);
634  }
635  while ((status == STATUS_BUSY) && !QSPI_DRV_Timeout(startTime, timeout));
636  if (status == STATUS_BUSY)
637  {
638  status = STATUS_TIMEOUT;
639  }
640  return status;
641 }
642 
643 
644 /*FUNCTION**********************************************************************
645  *
646  * Function Name : QSPI_DRV_IpRead
647  * Description : Launches an IP read command
648  * Implements : QSPI_DRV_IpRead_Activity
649  *
650  *END**************************************************************************/
651 status_t QSPI_DRV_IpRead(uint32_t instance,
652  uint8_t lut,
653  uint32_t addr,
654  uint8_t * dataRead,
655  const uint8_t * dataCmp,
656  uint32_t size,
657  qspi_transfer_type_t transferType,
658  uint32_t timeout)
659 {
661  status_t status = STATUS_SUCCESS;
662  status_t errors = STATUS_SUCCESS;
663  QuadSPI_Type *baseAddr;
664  qspi_state_t * state;
665  uint32_t startTime;
666 
667  baseAddr = g_qspiBase[instance];
668  state = g_qspiStatePtr[instance];
669 
670  state->operation = QSPI_OP_READ;
671  state->status = STATUS_SUCCESS;
672  state->data = dataRead;
673  state->size = size;
674  state->roData = dataCmp;
675  if (transferType != QSPI_TRANSFER_TYPE_SYNC)
676  {
677  /* clear leftover flags from previous transfers */
678  QSPI_DRV_ClearIntFlag(baseAddr, QuadSPI_FR_TFF_MASK);
679  /* enable end of transfer interrupt for asynchronous transfers */
680  QSPI_DRV_EnableInt(baseAddr, QuadSPI_RSER_TFIE_MASK);
681  if (transferType == QSPI_TRANSFER_TYPE_ASYNC_DMA)
682  {
683  /* Prepare DMA transfer */
684  QSPI_DRV_ConfigDmaRx(instance, state);
685  }
686  else
687  {
688  /* read will be done in interrupt */
689  state->operation = QSPI_OP_READ_INT;
690  }
691  }
692  /* Set read address */
693  QSPI_DRV_SetIpAddr(baseAddr, addr);
694  /* Trigger IP command with specified sequence and size */
695  QSPI_DRV_IpTrigger(baseAddr, lut, (uint16_t)size);
696  if (transferType == QSPI_TRANSFER_TYPE_SYNC)
697  {
698  /* Wait for command to be completed */
699  startTime = OSIF_GetMilliseconds();
700  while (QSPI_DRV_GetBusyStatus(baseAddr) || QSPI_DRV_GetRxBufFill(baseAddr))
701  {
702  if (QSPI_DRV_GetRxDataEvent(baseAddr))
703  {
704  if (status == STATUS_SUCCESS)
705  {
706  /* check received word */
707  if (state->size >= 4)
708  {
709  status = QSPI_DRV_ProcessData(baseAddr->RBDR[0U], state);
710  }
711  else
712  {
713  status = QSPI_DRV_ProcessLastData(baseAddr->RBDR[0U], state);
714  }
715  }
716  QSPI_DRV_RxPop(baseAddr);
717  }
718  if (QSPI_DRV_Timeout(startTime, timeout))
719  {
720  status = STATUS_TIMEOUT;
721  break;
722  }
723  }
724  /* Reset Rx queue */
725  QSPI_DRV_ClearRxBuf(baseAddr);
726  /* Check for errors reported by the QuadSPI */
727  errors = QSPI_DRV_ErrorCheck(baseAddr);
728  if (status == STATUS_SUCCESS)
729  {
730  status = errors;
731  }
732  }
733  return status;
734 }
735 
736 
737 /*FUNCTION**********************************************************************
738  *
739  * Function Name : QSPI_DRV_IpWrite
740  * Description : Launches an IP write command
741  * Implements : QSPI_DRV_IpWrite_Activity
742  *
743  *END**************************************************************************/
744 status_t QSPI_DRV_IpWrite(uint32_t instance,
745  uint8_t lut,
746  uint32_t addr,
747  uint8_t * data,
748  uint32_t size,
749  qspi_transfer_type_t transferType,
750  uint32_t timeout)
751 {
752  QuadSPI_Type *baseAddr;
753  qspi_state_t * state;
754  status_t status = STATUS_SUCCESS;
755  status_t errors = STATUS_SUCCESS;
756  uint32_t startTime;
757 
759  baseAddr = g_qspiBase[instance];
760  state = g_qspiStatePtr[instance];
761 
762  state->operation = QSPI_OP_WRITE;
763  state->status = STATUS_SUCCESS;
764  state->roData = data;
765  state->size = size;
766 
767  /* Set write address */
768  QSPI_DRV_SetIpAddr(baseAddr, addr);
769  /* Fill Tx FIFO with initial data */
770  QSPI_DRV_ClearTxBuf(baseAddr);
771  QSPI_DRV_FillTxBuf(baseAddr, state);
772  /* If not enough Tx data, pad Tx buffer up to 16 bytes */
773  QSPI_DRV_PadTxBuf(baseAddr);
774 
775  if (transferType != QSPI_TRANSFER_TYPE_SYNC)
776  {
777  /* clear leftover flags from previous transfers */
778  QSPI_DRV_ClearIntFlag(baseAddr, QuadSPI_FR_TFF_MASK);
779  /* enable end of transfer interrupt for asynchronous transfers */
780  QSPI_DRV_EnableInt(baseAddr, QuadSPI_RSER_TFIE_MASK);
781  }
782  if ((transferType == QSPI_TRANSFER_TYPE_ASYNC_DMA) && (state->size > 0))
783  {
784  /* If not all data could fit in the buffer, prepare DMA transfer */
785  QSPI_DRV_ConfigDmaTx(instance, state);
786  }
787 
788  /* Trigger IP command with specified sequence and size */
789  QSPI_DRV_IpTrigger(baseAddr, lut, (uint16_t)size);
790  if (transferType == QSPI_TRANSFER_TYPE_SYNC)
791  {
792  /* Wait for command to be completed */
793  startTime = OSIF_GetMilliseconds();
794  while (QSPI_DRV_GetBusyStatus(baseAddr))
795  {
796  /* Keep feeding the Tx FIFO */
797  QSPI_DRV_FillTxBuf(baseAddr, state);
798  if (QSPI_DRV_Timeout(startTime, timeout))
799  {
800  status = STATUS_TIMEOUT;
801  break;
802  }
803  }
804  /* Check for errors reported by the QuadSPI */
805  errors = QSPI_DRV_ErrorCheck(baseAddr);
806  if (status == STATUS_SUCCESS)
807  {
808  status = errors;
809  }
810  }
811  return status;
812 }
813 
814 
815 /*FUNCTION**********************************************************************
816  *
817  * Function Name : QSPI_DRV_IpErase
818  * Description : Launches an IP erase command
819  * Implements : QSPI_DRV_IpErase_Activity
820  *
821  *END**************************************************************************/
822 status_t QSPI_DRV_IpErase(uint32_t instance,
823  uint8_t lut,
824  uint32_t addr)
825 {
826  QuadSPI_Type *baseAddr;
827  qspi_state_t * state;
828 
830 
831  baseAddr = g_qspiBase[instance];
832  state = g_qspiStatePtr[instance];
833 
834  state->status = STATUS_SUCCESS;
835  /* Set erase address */
836  QSPI_DRV_SetIpAddr(baseAddr, addr);
837  /* Trigger IP command with specified sequence and dummy size */
838  QSPI_DRV_IpTrigger(baseAddr, lut, 1U);
839  /* Do not wait for command to complete */
840  return STATUS_SUCCESS;
841 }
842 
843 
844 /*FUNCTION**********************************************************************
845  *
846  * Function Name : QSPI_DRV_IpGetStatus
847  * Description : Checks the status of the currently running IP command
848  * Implements : QSPI_DRV_IpGetStatus_Activity
849  *
850  *END**************************************************************************/
851 status_t QSPI_DRV_IpGetStatus(uint32_t instance)
852 {
853  QuadSPI_Type *baseAddr;
854 
856 
857  baseAddr = g_qspiBase[instance];
858  if (QSPI_DRV_GetBusyStatus(baseAddr))
859  {
860  return STATUS_BUSY;
861  }
862  /* Check for errors reported by the QuadSPI */
863  return QSPI_DRV_ErrorCheck(baseAddr);
864 }
865 
866 
867 /*FUNCTION**********************************************************************
868  *
869  * Function Name : QSPI_DRV_GetDefaultConfig
870  * Description : Returns default configuration structure for QuadSPI
871  * Implements : QSPI_DRV_GetDefaultConfig_Activity
872  *
873  *END**************************************************************************/
875 {
876  userConfigPtr->dataRate = QSPI_DATE_RATE_SDR; /* single data rate */
877  userConfigPtr->dmaSupport = false; /* no DMA support by default */
878  userConfigPtr->dmaChannel = 0U;
879  userConfigPtr->callback = NULL;
880  userConfigPtr->callbackParam = NULL;
882  userConfigPtr->side = QSPI_FLASH_SIDE_A; /* serial memory connected to side A */
883  userConfigPtr->memSize = 0x7FFFFFU; /* Size: 8 MB */
884  userConfigPtr->csHoldTime = 1U;
885  userConfigPtr->csSetupTime = 1U;
886  userConfigPtr->columnAddr = 0U;
887  userConfigPtr->wordAddresable = false;
888  userConfigPtr->sampleDelay = QSPI_SAMPLE_DELAY_1;
890  userConfigPtr->endianess = QSPI_END_64BIT_LE; /* little endian */
891  userConfigPtr->clock_src = QSPI_CLK_SRC_FIRC_DIV1; /* use FIRC as clock source */
892  userConfigPtr->io2IdleValue = 1U;
893  userConfigPtr->io3IdleValue = 1U;
894 
895  return STATUS_SUCCESS;
896 }
897 
898 
899 /*******************************************************************************
900  * EOF
901  ******************************************************************************/
uint8_t masters[QSPI_AHB_BUFFERS]
status_t QSPI_DRV_IpRead(uint32_t instance, uint8_t lut, uint32_t addr, uint8_t *dataRead, const uint8_t *dataCmp, uint32_t size, qspi_transfer_type_t transferType, uint32_t timeout)
Launches an IP read command.
qspi_endianess_t endianess
__I uint32_t RBDR[QuadSPI_RBDR_COUNT]
Definition: S32K148.h:9791
#define QuadSPI_FR_TFF_MASK
Definition: S32K148.h:10130
qspi_sample_delay_t sampleDelay
#define FEATURE_QSPI_DMA_RX_REQ
List of DMA Rx requests.
status_t EDMA_DRV_StopChannel(uint8_t channel)
Stops the eDMA channel.
Definition: edma_driver.c:838
status_t QSPI_DRV_IpWrite(uint32_t instance, uint8_t lut, uint32_t addr, uint8_t *data, uint32_t size, qspi_transfer_type_t transferType, uint32_t timeout)
Launches an IP write command.
qspi_transfer_type_t
Driver type Implements : qspi_transfer_type_t_Class.
uint32_t OSIF_GetMilliseconds(void)
Returns the number of miliseconds elapsed since starting the internal timer or starting the scheduler...
uint16_t sizes[QSPI_AHB_BUFFERS]
qspi_clock_src_t clock_src
#define QuadSPI_IRQS
Definition: S32K148.h:9817
IRQn_Type
Defines the Interrupt Numbers definitions.
Definition: S32K148.h:192
status_t EDMA_DRV_SetChannelRequest(uint8_t channel, uint8_t req)
Configures the DMA request for the eDMA channel.
Definition: edma_driver.c:863
status_t QSPI_DRV_Deinit(uint32_t instance)
De-initialize the qspi driver.
void INT_SYS_DisableIRQ(IRQn_Type irqNumber)
Disables an interrupt for a given IRQ number.
#define DEV_ASSERT(x)
Definition: devassert.h:77
qspi_callback_t callback
__IO uint32_t FR
Definition: S32K148.h:9781
edma_chn_status_t
Channel status for eDMA channel.
Definition: edma_driver.h:193
qspi_date_rate_t dataRate
status_t QSPI_DRV_IpErase(uint32_t instance, uint8_t lut, uint32_t addr)
Launches an IP erase command.
#define QuadSPI_INSTANCE_COUNT
Definition: S32K148.h:9800
Driver configuration structure.
status_t
Status return codes. Common error codes will be a unified enumeration (C enum) that will contain all ...
Definition: status.h:44
status_t QSPI_DRV_AhbSetup(uint32_t instance, const qspi_ahb_config_t *config)
Sets up AHB accesses to the serial flash.
#define FEATURE_QSPI_DMA_TX_REQ
List of DMA Tx requests.
status_t QSPI_DRV_IpGetStatus(uint32_t instance)
Checks the status of the currently running IP command.
status_t QSPI_DRV_IpCommand(uint32_t instance, uint8_t lut, uint32_t timeout)
Launches a simple IP command.
status_t EDMA_DRV_StartChannel(uint8_t channel)
Starts an eDMA channel.
Definition: edma_driver.c:813
qspi_read_mode_t readMode
Driver internal context structure.
qspi_sample_phase_t clockPhase
qspi_flash_side_t side
#define QuadSPI_RSER_TFIE_MASK
Definition: S32K148.h:10183
AHB configuration structure.
void INT_SYS_EnableIRQ(IRQn_Type irqNumber)
Enables an interrupt for a given IRQ number.
status_t QSPI_DRV_GetDefaultConfig(qspi_user_config_t *userConfigPtr)
Returns default configuration structure for QuadSPI.
void(* edma_callback_t)(void *parameter, edma_chn_status_t status)
Definition for the eDMA channel callback function.
Definition: edma_driver.h:204
QuadSPI_Type *const g_qspiBase[]
Table of base addresses for QuadSPI instances.
status_t QSPI_DRV_Init(uint32_t instance, const qspi_user_config_t *userConfigPtr, qspi_state_t *state)
Initializes the qspi driver.
status_t EDMA_DRV_ConfigMultiBlockTransfer(uint8_t channel, edma_transfer_type_t type, uint32_t srcAddr, uint32_t destAddr, edma_transfer_size_t transferSize, uint32_t blockSize, uint32_t blockCount, bool disableReqOnCompletion)
Configures a multiple block data transfer with DMA.
Definition: edma_driver.c:589
status_t EDMA_DRV_InstallCallback(uint8_t channel, edma_callback_t callback, void *parameter)
Registers the callback function and the parameter for eDMA channel.
Definition: edma_driver.c:293
#define QuadSPI_BASE_PTRS
Definition: S32K148.h:9811