]> git.gir.st - tmk_keyboard.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
[tmk_keyboard.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
Imprint / Impressum