]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/dspi/fsl_dspi_hal.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / hal / TARGET_Freescale / TARGET_KPSDK_MCUS / TARGET_KPSDK_CODE / hal / dspi / fsl_dspi_hal.c
1 /*
2  * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * o Redistributions of source code must retain the above copyright notice, this list
9  *   of conditions and the following disclaimer.
10  *
11  * o Redistributions in binary form must reproduce the above copyright notice, this
12  *   list of conditions and the following disclaimer in the documentation and/or
13  *   other materials provided with the distribution.
14  *
15  * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
16  *   contributors may be used to endorse or promote products derived from this
17  *   software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "fsl_dspi_hal.h"
32
33 /*******************************************************************************
34  * Definitions
35  ******************************************************************************/
36
37 /*******************************************************************************
38  * Variables
39  ******************************************************************************/
40
41 /*******************************************************************************
42  * Code
43  ******************************************************************************/
44
45 /*FUNCTION**********************************************************************
46  *
47  * Function Name : DSPI_HAL_Init
48  * Description   : Restore DSPI to reset configuration.
49  * This function basically resets all of the DSPI registers to their default setting including
50  * disabling the module.
51  *
52  *END**************************************************************************/
53 void DSPI_HAL_Init(uint32_t baseAddr)
54 {
55     /* first, make sure the module is enabled to allow writes to certain registers*/
56     DSPI_HAL_Enable(baseAddr);
57
58     /* Halt all transfers*/
59     DSPI_HAL_StopTransfer(baseAddr);
60
61     /* set the registers to their default states*/
62     /* clear the status bits (write-1-to-clear)*/
63     HW_SPI_SR_WR(baseAddr, BM_SPI_SR_TCF | BM_SPI_SR_EOQF | BM_SPI_SR_TFUF |
64                                           BM_SPI_SR_TFFF | BM_SPI_SR_RFOF | BM_SPI_SR_RFDF);
65     HW_SPI_TCR_WR(baseAddr, 0);
66     HW_SPI_CTARn_WR(baseAddr, 0, 0x78000000); /* CTAR0*/
67     HW_SPI_CTARn_WR(baseAddr, 1, 0x78000000); /* CTAR1*/
68     HW_SPI_RSER_WR(baseAddr, 0);
69
70     /* Clear out PUSHR register. Since DSPI is halted, nothing should be transmitted. Be
71      * sure the flush the FIFOs afterwards
72      */
73     HW_SPI_PUSHR_WR(baseAddr, 0);
74
75     /* flush the fifos*/
76     DSPI_HAL_SetFlushFifoCmd(baseAddr, true, true);
77
78     /* Now set MCR to default value, which disables module: set MDIS and HALT, clear other bits */
79     HW_SPI_MCR_WR(baseAddr, BM_SPI_MCR_MDIS | BM_SPI_MCR_HALT);
80 }
81
82 /*FUNCTION**********************************************************************
83  *
84  * Function Name : DSPI_HAL_SetBaudRate
85  * Description   : Set the DSPI baud rate in bits per second.
86  * This function will take in the desired bitsPerSec (baud rate) and will calculate the nearest
87  * possible baud rate without exceeding the desired baud rate, and will return the calculated
88  * baud rate in bits-per-second. It requires that the caller also provide the frequency of the
89  * module source clock (in Hz).
90  *
91  *END**************************************************************************/
92 uint32_t DSPI_HAL_SetBaudRate(uint32_t baseAddr, dspi_ctar_selection_t whichCtar,
93                               uint32_t bitsPerSec, uint32_t sourceClockInHz)
94 {
95     /* for master mode configuration, if slave mode detected, return 0*/
96     if (!DSPI_HAL_IsMaster(baseAddr))
97     {
98         return 0;
99     }
100
101     uint32_t prescaler, bestPrescaler;
102     uint32_t scaler, bestScaler;
103     uint32_t dbr, bestDbr;
104     uint32_t realBaudrate, bestBaudrate;
105     uint32_t diff, min_diff;
106     uint32_t baudrate = bitsPerSec;
107
108     /* find combination of prescaler and scaler resulting in baudrate closest to the */
109     /* requested value */
110     min_diff = 0xFFFFFFFFU;
111     bestPrescaler = 0;
112     bestScaler = 0;
113     bestDbr = 1;
114     bestBaudrate = 0; /* required to avoid compilation warning */
115
116     /* In all for loops, if min_diff = 0, the exit for loop*/
117     for (prescaler = 0; (prescaler < 4) && min_diff; prescaler++)
118     {
119         for (scaler = 0; (scaler < 16) && min_diff; scaler++)
120         {
121             for (dbr = 1; (dbr < 3) && min_diff; dbr++)
122             {
123                 realBaudrate = ((sourceClockInHz * dbr) /
124                                 (s_baudratePrescaler[prescaler] * (s_baudrateScaler[scaler])));
125
126                 /* calculate the baud rate difference based on the conditional statement*/
127                 /* that states that the calculated baud rate must not exceed the desired baud rate*/
128                 if (baudrate >= realBaudrate)
129                 {
130                     diff = baudrate-realBaudrate;
131                     if (min_diff > diff)
132                     {
133                         /* a better match found */
134                         min_diff = diff;
135                         bestPrescaler = prescaler;
136                         bestScaler = scaler;
137                         bestBaudrate = realBaudrate;
138                         bestDbr = dbr;
139                     }
140                 }
141             }
142         }
143     }
144
145     /* write the best dbr, prescalar, and baud rate scalar to the CTAR*/
146     BW_SPI_CTARn_DBR(baseAddr, whichCtar, (bestDbr - 1));
147     BW_SPI_CTARn_PBR(baseAddr, whichCtar, bestPrescaler);
148     BW_SPI_CTARn_BR(baseAddr, whichCtar, bestScaler);
149
150     /* return the actual calculated baud rate*/
151     return bestBaudrate;
152 }
153
154 /*FUNCTION**********************************************************************
155  *
156  * Function Name : DSPI_HAL_SetBaudDivisors
157  * Description   : Configure the baud rate divisors manually.
158  * This function allows the caller to manually set the baud rate divisors in the event that
159  * these dividers are known and the caller does not wish to call the DSPI_HAL_SetBaudRate function.
160  *
161  *END**************************************************************************/
162 void DSPI_HAL_SetBaudDivisors(uint32_t baseAddr,
163                               dspi_ctar_selection_t whichCtar,
164                               const dspi_baud_rate_divisors_t * divisors)
165 {
166     /* these settings are only relevant in master mode*/
167     if (DSPI_HAL_IsMaster(baseAddr))
168     {
169         BW_SPI_CTARn_DBR(baseAddr, whichCtar, divisors->doubleBaudRate);
170         BW_SPI_CTARn_PBR(baseAddr, whichCtar, divisors->prescaleDivisor);
171         BW_SPI_CTARn_BR(baseAddr, whichCtar, divisors->baudRateDivisor);
172     }
173 }
174
175 /*FUNCTION**********************************************************************
176  *
177  * Function Name : DSPI_HAL_SetPcsPolarityMode
178  * Description   : Configure DSPI peripheral chip select polarity.
179  * This function will take in the desired peripheral chip select (PCS) and it's
180  * corresponding desired polarity and will configure the PCS signal to operate with the
181  * desired characteristic.
182  *
183  *END**************************************************************************/
184 void DSPI_HAL_SetPcsPolarityMode(uint32_t baseAddr, dspi_which_pcs_config_t pcs,
185                                  dspi_pcs_polarity_config_t activeLowOrHigh)
186 {
187     uint32_t temp;
188
189     temp = BR_SPI_MCR_PCSIS(baseAddr);
190
191     if (activeLowOrHigh == kDspiPcs_ActiveLow)
192     {
193         temp |= pcs;
194     }
195     else  /* kDspiPcsPolarity_ActiveHigh*/
196     {
197         temp &= ~(unsigned)pcs;
198     }
199
200     BW_SPI_MCR_PCSIS(baseAddr, temp);
201 }
202
203
204 /*FUNCTION**********************************************************************
205  *
206  * Function Name : DSPI_HAL_SetFifoCmd
207  * Description   : Enables (or disables) the DSPI FIFOs.
208  * This function with allow the caller to disable/enable the TX and RX FIFOs (independently).
209  * Note that to disable, the caller must pass in a logic 0 (false) for the particular FIFO
210  * configuration.  To enable, the caller must pass in a logic 1 (true).
211  *
212  *END**************************************************************************/
213 void DSPI_HAL_SetFifoCmd(uint32_t baseAddr, bool enableTxFifo, bool enableRxFifo)
214 {
215     /* first see if MDIS is set or cleared */
216     uint32_t isMdisSet = BR_SPI_MCR_MDIS(baseAddr);
217
218     if (isMdisSet)
219     {
220         /* clear the MDIS bit (enable DSPI) to allow us to write to the fifo disables */
221         DSPI_HAL_Enable(baseAddr);
222     }
223
224     /* Note, the bit definition is "disable FIFO", so a "1" would disable. If user wants to enable
225      * the FIFOs, they pass in true, which we must logically negate (turn to false) to enable the
226      * FIFO
227      */
228     BW_SPI_MCR_DIS_TXF(baseAddr, ~(enableTxFifo == true));
229     BW_SPI_MCR_DIS_RXF(baseAddr, ~(enableRxFifo == true));
230
231     /* set MDIS (disable DSPI) if it was set to begin with */
232     if (isMdisSet)
233     {
234         DSPI_HAL_Disable(baseAddr);
235     }
236 }
237
238 /*FUNCTION**********************************************************************
239  *
240  * Function Name : DSPI_HAL_SetFlushFifoCmd
241  * Description   : Flush DSPI fifos.
242  *
243  *END**************************************************************************/
244 void DSPI_HAL_SetFlushFifoCmd(uint32_t baseAddr, bool enableFlushTxFifo, bool enableFlushRxFifo)
245 {
246     BW_SPI_MCR_CLR_TXF(baseAddr, (enableFlushTxFifo == true));
247     BW_SPI_MCR_CLR_RXF(baseAddr, (enableFlushRxFifo == true));
248 }
249
250 /*FUNCTION**********************************************************************
251  *
252  * Function Name : DSPI_HAL_SetDataFormat
253  * Description   : Configure the data format for a particular CTAR.
254  * This function configures the bits-per-frame, polarity, phase, and shift direction for a
255  * particular CTAR. An example use case is as follows:
256  *    dspi_data_format_config_t dataFormat;
257  *    dataFormat.bitsPerFrame = 16;
258  *    dataFormat.clkPolarity = kDspiClockPolarity_ActiveLow;
259  *    dataFormat.clkPhase = kDspiClockPhase_FirstEdge;
260  *    dataFormat.direction = kDspiMsbFirst;
261  *    DSPI_HAL_SetDataFormat(baseAddr, kDspiCtar0, &dataFormat);
262  *
263  *END**************************************************************************/
264 dspi_status_t DSPI_HAL_SetDataFormat(uint32_t baseAddr,
265                                      dspi_ctar_selection_t whichCtar,
266                                      const dspi_data_format_config_t * config)
267 {
268     /* check bits-per-frame value to make sure it it within the proper range*/
269     /* in either master or slave mode*/
270     if ((config->bitsPerFrame < 4) ||
271         ((config->bitsPerFrame > 16) && (HW_SPI_MCR(baseAddr).B.MSTR == 1)) ||
272         ((config->bitsPerFrame > 32) && (HW_SPI_MCR(baseAddr).B.MSTR == 0)))
273     {
274         return kStatus_DSPI_InvalidBitCount;
275     }
276
277     /* for master mode configuration*/
278     if (DSPI_HAL_IsMaster(baseAddr))
279     {
280         BW_SPI_CTARn_FMSZ(baseAddr, whichCtar, (config->bitsPerFrame - 1));
281         BW_SPI_CTARn_CPOL(baseAddr, whichCtar, config->clkPolarity);
282         BW_SPI_CTARn_CPHA(baseAddr, whichCtar, config->clkPhase);
283         BW_SPI_CTARn_LSBFE(baseAddr, whichCtar, config->direction);
284     }
285     else /* for slave mode configuration*/
286     {
287         BW_SPI_CTARn_SLAVE_FMSZ(baseAddr, whichCtar, (config->bitsPerFrame - 1));
288         BW_SPI_CTARn_SLAVE_CPOL(baseAddr, whichCtar, config->clkPolarity);
289         BW_SPI_CTARn_SLAVE_CPHA(baseAddr, whichCtar, config->clkPhase);
290     }
291     return kStatus_DSPI_Success;
292 }
293
294 /*FUNCTION**********************************************************************
295  *
296  * Function Name : DSPI_HAL_SetDelay
297  * Description   : Manually configures the delay prescaler and scaler for a particular CTAR.
298  * This function configures the:
299  * PCS to SCK delay pre-scalar (PCSSCK) and scalar (CSSCK),
300  * After SCK delay pre-scalar (PASC) and scalar (ASC),
301  * Delay after transfer pre-scalar (PDT)and scalar (DT).
302  *
303  * These delay names are available in type dspi_delay_type_t.
304  *
305  * The user passes which delay they want to configure along with the prescaler and scaler value.
306  * This basically allows the user to directly set the prescaler/scaler values if they have
307  * pre-calculated them or if they simply wish to manually increment either value.
308  *END**************************************************************************/
309 void DSPI_HAL_SetDelay(uint32_t baseAddr, dspi_ctar_selection_t whichCtar, uint32_t prescaler,
310                        uint32_t scaler, dspi_delay_type_t whichDelay)
311 {
312     /* these settings are only relevant in master mode*/
313     if (DSPI_HAL_IsMaster(baseAddr))
314     {
315         if (whichDelay == kDspiPcsToSck)
316         {
317             BW_SPI_CTARn_PCSSCK(baseAddr, whichCtar, prescaler);
318             BW_SPI_CTARn_CSSCK(baseAddr, whichCtar, scaler);
319         }
320
321         if (whichDelay == kDspiLastSckToPcs)
322         {
323             BW_SPI_CTARn_PASC(baseAddr, whichCtar, prescaler);
324             BW_SPI_CTARn_ASC(baseAddr, whichCtar, scaler);
325         }
326
327         if (whichDelay == kDspiAfterTransfer)
328         {
329             BW_SPI_CTARn_PDT(baseAddr, whichCtar, prescaler);
330             BW_SPI_CTARn_DT(baseAddr, whichCtar, scaler);
331         }
332     }
333 }
334
335 /*FUNCTION**********************************************************************
336  *
337  * Function Name : DSPI_HAL_CalculateDelay
338  * Description   : Calculates the delay prescaler and scaler based on desired delay input in
339  *                 nano-seconds.
340  *
341  * This function calculates the values for:
342  * PCS to SCK delay pre-scalar (PCSSCK) and scalar (CSSCK), or
343  * After SCK delay pre-scalar (PASC) and scalar (ASC), or
344  * Delay after transfer pre-scalar (PDT)and scalar (DT).
345  *
346  * These delay names are available in type dspi_delay_type_t.
347  *
348  * The user passes which delay they want to configure along with the desired delay value in
349  * nano-seconds.  The function will calculate the values needed for the prescaler and scaler and
350  * will return the actual calculated delay as an exact delay match may not be acheivable. In this
351  * case, the closest match will be calculated without going below the desired delay value input.
352  * It is possible to input a very large delay value that exceeds the capability of the part, in
353  * which case the maximum supported delay will be returned. It will be up to the higher level
354  * peripheral driver to alert the user of an out of range delay input.
355  *END**************************************************************************/
356 uint32_t DSPI_HAL_CalculateDelay(uint32_t baseAddr, dspi_ctar_selection_t whichCtar,
357                                  dspi_delay_type_t whichDelay, uint32_t sourceClockInHz,
358                                  uint32_t delayInNanoSec)
359 {
360     /* for master mode configuration, if slave mode detected, return 0*/
361     if (!DSPI_HAL_IsMaster(baseAddr))
362     {
363         return 0;
364     }
365
366     uint32_t prescaler, bestPrescaler;
367     uint32_t scaler, bestScaler;
368     uint32_t realDelay, bestDelay;
369     uint32_t diff, min_diff;
370     uint32_t initialDelayNanoSec;
371
372     /* find combination of prescaler and scaler resulting in the delay closest to the
373      * requested value
374      */
375     min_diff = 0xFFFFFFFFU;
376     /* Initialize prescaler and scaler to their max values to generate the max delay */
377     bestPrescaler = 0x3;
378     bestScaler = 0xF;
379     bestDelay = (1000000000/sourceClockInHz) * s_delayPrescaler[bestPrescaler] *
380                  s_delayScaler[bestScaler];
381
382     /* First calculate the initial, default delay */
383     initialDelayNanoSec = 1000000000/sourceClockInHz * 2;
384
385     /* If the initial, default delay is already greater than the desired delay, then
386      * set the delays to their initial value (0) and return the delay. In other words,
387      * there is no way to decrease the delay value further.
388      */
389     if (initialDelayNanoSec >= delayInNanoSec)
390     {
391         DSPI_HAL_SetDelay(baseAddr, whichCtar, 0, 0, whichDelay);
392         return initialDelayNanoSec;
393     }
394
395
396     /* In all for loops, if min_diff = 0, the exit for loop*/
397     for (prescaler = 0; (prescaler < 4) && min_diff; prescaler++)
398     {
399         for (scaler = 0; (scaler < 16) && min_diff; scaler++)
400         {
401             realDelay = (1000000000/sourceClockInHz) * s_delayPrescaler[prescaler] *
402                          s_delayScaler[scaler];
403
404             /* calculate the delay difference based on the conditional statement
405              * that states that the calculated delay must not be less then the desired delay
406              */
407             if (realDelay >= delayInNanoSec)
408             {
409                 diff = realDelay-delayInNanoSec;
410                 if (min_diff > diff)
411                 {
412                     /* a better match found */
413                     min_diff = diff;
414                     bestPrescaler = prescaler;
415                     bestScaler = scaler;
416                     bestDelay = realDelay;
417                 }
418             }
419         }
420     }
421
422     /* write the best dbr, prescalar, and baud rate scalar to the CTAR*/
423     DSPI_HAL_SetDelay(baseAddr, whichCtar, bestPrescaler, bestScaler, whichDelay);
424
425     /* return the actual calculated baud rate*/
426     return bestDelay;
427 }
428
429
430 /*FUNCTION**********************************************************************
431  *
432  * Function Name : DSPI_HAL_SetTxFifoFillDmaIntMode
433  * Description   : Configures the DSPI Tx FIFO Fill request to generate DMA or interrupt requests.
434  * This function configures the DSPI Tx FIFO Fill flag to generate either
435  * an interrupt or DMA request.  The user passes in which request they'd like to generate
436  * of type dspi_dma_or_int_mode_t and whether or not they wish to enable this request.
437  * Note, when disabling the request, the request type is don't care.
438  *
439  *  DSPI_HAL_SetTxFifoFillDmaIntMode(baseAddr, kDspiGenerateDmaReq, true); <- to enable DMA
440  *  DSPI_HAL_SetTxFifoFillDmaIntMode(baseAddr, kDspiGenerateIntReq, true); <- to enable Interrupt
441  *  DSPI_HAL_SetTxFifoFillDmaIntMode(baseAddr, kDspiGenerateIntReq, false); <- to disable
442  *
443  *END**************************************************************************/
444 void DSPI_HAL_SetTxFifoFillDmaIntMode(uint32_t baseAddr, dspi_dma_or_int_mode_t mode, bool enable)
445 {
446     BW_SPI_RSER_TFFF_DIRS(baseAddr, mode);  /* Configure as DMA or interrupt */
447     BW_SPI_RSER_TFFF_RE(baseAddr, (enable == true));  /* Enable or disable the request */
448 }
449
450 /*FUNCTION**********************************************************************
451  *
452  * Function Name : DSPI_HAL_SetRxFifoDrainDmaIntMode
453  * Description   : Configures the DSPI Rx FIFO Drain request to generate DMA or interrupt requests.
454  * This function configures the DSPI Rx FIFO Drain flag to generate either
455  * an interrupt or DMA request.  The user passes in which request they'd like to generate
456  * of type dspi_dma_or_int_mode_t and whether or not they wish to enable this request.
457  * Note, when disabling the request, the request type is don't care.
458  *
459  *  DSPI_HAL_SetRxFifoDrainDmaIntMode(baseAddr, kDspiGenerateDmaReq, true); <- to enable DMA
460  *  DSPI_HAL_SetRxFifoDrainDmaIntMode(baseAddr, kDspiGenerateIntReq, true); <- to enable Interrupt
461  *  DSPI_HAL_SetRxFifoDrainDmaIntMode(baseAddr, kDspiGenerateIntReq, false); <- to disable
462  *
463  *END**************************************************************************/
464 void DSPI_HAL_SetRxFifoDrainDmaIntMode(uint32_t baseAddr, dspi_dma_or_int_mode_t mode, bool enable)
465 {
466     BW_SPI_RSER_RFDF_DIRS(baseAddr, mode);  /* Configure as DMA or interrupt */
467     BW_SPI_RSER_RFDF_RE(baseAddr, (enable == true));  /* Enable or disable the request */
468 }
469
470
471 /*FUNCTION**********************************************************************
472  *
473  * Function Name : DSPI_HAL_SetIntMode
474  * Description   : Configure DSPI interrupts.
475  * This function configures the various interrupt sources of the DSPI.  The parameters are
476  * baseAddr, interrupt source, and enable/disable setting.
477  * The interrupt source is a typedef enum whose value is the bit position of the
478  * interrupt source setting within the RSER register.  In the DSPI, all interrupt
479  * configuration settings are in  one register.  The typedef enum  equates each
480  * interrupt source to the bit position defined in the device header file.
481  * The function  uses these bit positions in its algorithm to enable/disable the
482  * interrupt source, where interrupt source is the dspi_status_and_interrupt_request_t type.
483  * Note, for Tx FIFO Fill and Rx FIFO Drain requests, use the functions:
484  * DSPI_HAL_SetTxFifoFillDmaIntMode and DSPI_HAL_SetRxFifoDrainDmaIntMode respectively as
485  * these requests can generate either an interrupt or DMA request.
486  *
487  *   DSPI_HAL_SetIntMode(baseAddr, kDspiTxComplete, true); <- example use-case
488  *
489  *END**************************************************************************/
490 void DSPI_HAL_SetIntMode(uint32_t baseAddr,
491                                   dspi_status_and_interrupt_request_t interruptSrc,
492                                   bool enable)
493 {
494     uint32_t temp;
495
496     temp = (HW_SPI_RSER_RD(baseAddr) & ~(0x1U << interruptSrc)) |
497                           ((uint32_t)enable << interruptSrc);
498     HW_SPI_RSER_WR(baseAddr, temp);
499 }
500
501 /*FUNCTION**********************************************************************
502  *
503  * Function Name : DSPI_HAL_GetFifoData
504  * Description   : Read fifo registers for debug purposes.
505  *
506  *END**************************************************************************/
507 uint32_t DSPI_HAL_GetFifoData(uint32_t baseAddr, dspi_fifo_t whichFifo, uint32_t whichFifoEntry)
508 {
509     if (whichFifo == kDspiTxFifo)
510     {
511         return HW_SPI_TXFRn_RD(baseAddr, whichFifoEntry);
512     }
513     else
514     {
515         return HW_SPI_RXFRn_RD(baseAddr, whichFifoEntry);
516     }
517 }
518
519 /*FUNCTION**********************************************************************
520  *
521  * Function Name : DSPI_HAL_WriteDataMastermode
522  * Description   : Write data into the data buffer, master mode.
523  * In master mode, the 16-bit data is appended with the 16-bit command info. The command portion
524  * provides characteristics of the data being sent such as: optional continuous chip select
525  * operation between transfers, the desired Clock and Transfer Attributes register to use for the
526  * associated SPI frame, the desired PCS signal to use for the data transfer, whether the current
527  * transfer is the last in the queue, and whether to clear the transfer count (normally needed when
528  * sending the first frame of a data packet). An example use case is as follows:
529  *    dspi_command_config_t commandConfig;
530  *    commandConfig.isChipSelectContinuous = true;
531  *    commandConfig.whichCtar = kDspiCtar0;
532  *    commandConfig.whichPcs = kDspiPcs1;
533  *    commandConfig.clearTransferCount = false;
534  *    commandConfig.isEndOfQueue = false;
535  *    DSPI_HAL_WriteDataMastermode(baseAddr, &commandConfig, dataWord);
536  *
537  *END**************************************************************************/
538 void DSPI_HAL_WriteDataMastermode(uint32_t baseAddr,
539                                   dspi_command_config_t * command,
540                                   uint16_t data)
541 {
542     uint32_t temp;
543
544     /* First, build up the 32-bit word then write it to the PUSHR */
545     temp = BF_SPI_PUSHR_CONT(command->isChipSelectContinuous) |
546            BF_SPI_PUSHR_CTAS(command->whichCtar) |
547            BF_SPI_PUSHR_PCS(command->whichPcs) |
548            BF_SPI_PUSHR_EOQ(command->isEndOfQueue) |
549            BF_SPI_PUSHR_CTCNT(command->clearTransferCount) |
550            BF_SPI_PUSHR_TXDATA(data);
551
552     HW_SPI_PUSHR_WR(baseAddr, temp);
553 }
554
555 /*FUNCTION**********************************************************************
556  *
557  * Function Name : DSPI_HAL_WriteDataMastermode
558  * Description   : Write data into the data buffer, master mode and waits till complete to return.
559  * In master mode, the 16-bit data is appended with the 16-bit command info. The command portion
560  * provides characteristics of the data being sent such as: optional continuous chip select
561  * operation between transfers, the desired Clock and Transfer Attributes register to use for the
562  * associated SPI frame, the desired PCS signal to use for the data transfer, whether the current
563  * transfer is the last in the queue, and whether to clear the transfer count (normally needed when
564  * sending the first frame of a data packet). An example use case is as follows:
565  *    dspi_command_config_t commandConfig;
566  *    commandConfig.isChipSelectContinuous = true;
567  *    commandConfig.whichCtar = kDspiCtar0;
568  *    commandConfig.whichPcs = kDspiPcs1;
569  *    commandConfig.clearTransferCount = false;
570  *    commandConfig.isEndOfQueue = false;
571  *    DSPI_HAL_WriteDataMastermode(baseAddr, &commandConfig, dataWord);
572  *
573  * Note that this function will not return until after the transmit is complete. Also note that
574  * the DSPI must be enabled and running in order to transmit data (MCR[MDIS] & [HALT] = 0).
575  * Since the SPI is a synchronous protocol, receive data will be available when transmit completes.
576  *
577  *END**************************************************************************/
578 void DSPI_HAL_WriteDataMastermodeBlocking(uint32_t baseAddr,
579                                           dspi_command_config_t * command,
580                                           uint16_t data)
581 {
582     uint32_t temp;
583
584     /* First, clear Transmit Complete Flag (TCF) */
585     BW_SPI_SR_TCF(baseAddr, 1);
586
587     /* First, build up the 32-bit word then write it to the PUSHR */
588     temp = BF_SPI_PUSHR_CONT(command->isChipSelectContinuous) |
589            BF_SPI_PUSHR_CTAS(command->whichCtar) |
590            BF_SPI_PUSHR_PCS(command->whichPcs) |
591            BF_SPI_PUSHR_EOQ(command->isEndOfQueue) |
592            BF_SPI_PUSHR_CTCNT(command->clearTransferCount) |
593            BF_SPI_PUSHR_TXDATA(data);
594
595     HW_SPI_PUSHR_WR(baseAddr, temp);
596
597     /* Wait till TCF sets */
598     while(BR_SPI_SR_TCF(baseAddr) == 0) { }
599 }
600
601 /*******************************************************************************
602  * EOF
603  ******************************************************************************/
604