1 /*
2 * @file mibspi_priv.c
3 *
4 * @brief
5 * The file implements MIBSPI Driver with DMA.
6 *
7 * The ti/drivers/mibspi/include/reg_mibspi.h has the register layer definitons for the
8 * MIBSPI Module.
9 *
10 *
11 * \par
12 * NOTE:
13 * (C) Copyright 2020 Texas Instruments, Inc.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 *
19 * Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 *
22 * Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the
25 * distribution.
26 *
27 * Neither the name of Texas Instruments Incorporated nor the names of
28 * its contributors may be used to endorse or promote products derived
29 * from this software without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
37 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
41 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 */
44 /* Include Files */
45 #include <stdint.h>
46 #include <string.h>
47 #include <stdio.h>
48 #include <ti/osal/osal.h>
49 #include <ti/osal/MemoryP.h>
50 #include <ti/drv/mibspi/MIBSPI.h>
51 #include "mibspi_priv.h"
52 #include "mibspi_trace_priv.h"
53 #include "mibspi_utils.h"
55 /**************************************************************************
56 ************************** Local Definitions **********************************
57 **************************************************************************/
58 /* Flag to enalbe Params check */
59 #define SPI_PARAMS_CHECK
61 /* Support for multi icount in one transfer to achieve high throughput , this is only supported in blocking mode */
62 #define SPI_MULT_ICOUNT_SUPPORT
64 typedef enum Mibspi_DmaCtrlChType_tag
65 {
66 MIBSPI_DMACTRL_CH_TX,
67 MIBSPI_DMACTRL_CH_RX,
68 MIBSPI_DMACTRL_CH_BOTH,
69 } Mibspi_DmaCtrlChType_e;
71 /**************************************************************************
72 ************************* MibSPI Driver Functions Prototype ********************
73 **************************************************************************/
75 /* Local Driver Functions */
76 #ifdef SPI_PARAMS_CHECK
77 static int32_t MIBSPI_validateParams(const MIBSPI_Params *params);
78 static int32_t MIBSPI_validateTransferParams(const MIBSPI_Transaction *transaction, const MibSpiDriver_Object *ptrMibSpiDriver);
79 #endif
81 static void MIBSPI_initSlave(MibSpi_HwCfg* ptrHwCfg, const MIBSPI_Params *params);
82 static void MIBSPI_initMaster(MibSpi_HwCfg* ptrHwCfg, const MIBSPI_Params *params);
83 static int32_t MIBSPI_openSlaveMode(MibSpiDriver_Object *ptrMibSpiDriver, MibSpi_HwCfg* ptrHwCfg, const MIBSPI_Params *params);
84 static int32_t MIBSPI_openMasterMode(MibSpiDriver_Object *ptrMibSpiDriver, MibSpi_HwCfg* ptrHwCfg, const MIBSPI_Params *params);
85 static void MIBSPI_enablePinSettings(CSL_mss_spiRegs *ptrMibSpiReg, MIBSPI_PinMode pinMode, uint8_t chipSelectMask);
86 static void MIBSPI_setMasterClockRate(CSL_mss_spiRegs *ptrMibSpiReg, uint32_t clockSrcFreq, uint32_t desiredSpiClock);
87 static void MIBSPI_setResetMode(CSL_mss_spiRegs *ptrMibSpiReg, bool reset);
88 static void MIBSPI_writeDataRAM(MibSpiDriver_Object *ptrMibSpiDriver, uint8_t group, uint16_t *data, uint16_t dataElem);
89 static uint32_t MIBSPI_readDataRAM(MibSpiDriver_Object *ptrMibSpiDriver, uint8_t group, uint16_t *data, uint16_t dataElem);
90 static void MIBSPI_transferGroupEnable(CSL_mss_spiRegs *ptrMibSpiReg, uint8_t group);
91 static void MIBSPI_transferGroupDisable(CSL_mss_spiRegs *ptrMibSpiReg, uint8_t group);
92 static void MIBSPI_transferSetPStart(CSL_mss_spiRegs *ptrMibSpiReg, uint8_t group, uint8_t offset);
93 static uint32_t MIBSPI_checkTGComplete(CSL_mss_spiRegs *ptrMibSpiReg, uint8_t group);
94 static void MIBSPI_enableLoopback(CSL_mss_spiRegs *ptrMibSpiReg, MibSpi_LoopBackType loopbacktype);
95 static void MIBSPI_disableLoopback(CSL_mss_spiRegs *ptrMibSpiReg);
96 static void MIBSPI_setClockPhasePolarity(volatile CSL_mss_spiRegs *ptrMibSpiReg, uint8_t clockFmt);
97 static void MIBSPI_SPIEnable(CSL_mss_spiRegs *ptrMibSpiReg);
98 static void MIBSPI_SPIDisable(CSL_mss_spiRegs *ptrMibSpiReg);
99 static void MIBSPI_dataTransfer
100 (
101 MibSpiDriver_Object *ptrMibSpiDriver,
102 uint8_t *srcData,
103 uint8_t *dstData,
104 uint16_t dataElemSize,
105 uint8_t group
106 );
108 static void MIBSPI_ISR(uintptr_t arg);
109 static void MIBSPI_initTransactionState(Mibspi_transactionState_t *transactionState,
110 MIBSPI_Transaction *transaction);
111 static void MIBSPI_resetTransactionState(Mibspi_transactionState_t *transactionState);
112 static uint32_t MIBSPI_getPolarity(MIBSPI_FrameFormat frameFormat);
113 static uint32_t MIBSPI_getPhase(MIBSPI_FrameFormat frameFormat);
114 static int32_t MIBSPI_getDrvStats(MIBSPI_Handle handle, MIBSPI_Stats *ptrStats);
115 static void MIBSPI_validateIPVersionInfo(const MibSpi_HwCfg* ptrHwCfg);
116 static void MIBSPI_getVersionInfo(const CSL_mss_spiRegs *ptrMibSpiReg, MibSpi_VersionInfo *ver);
117 static void MIBSPI_enableErrorInterrupt(CSL_mss_spiRegs *ptrMibSpiReg, uint32_t enableFlag);
118 static void MIBSPI_setErrorInterruptLevel(CSL_mss_spiRegs *ptrMibSpiReg, uint32_t level);
119 #ifdef MIBSPI_DMA_ENABLE
120 static void MIBSPI_enableGroupInterrupt(CSL_mss_spiRegs *ptrMibSpiReg, uint8_t group, uint32_t intLine);
121 static void MIBSPI_disableGroupInterrupt(CSL_mss_spiRegs *ptrMibSpiReg, uint8_t group);
122 static void MIBSPI_dmaCtrlGroupConfig(CSL_mss_spiRegs *ptrMibSpiReg, uint16_t bufId, uint8_t iCount, uint8_t dmaCtrlGroup);
123 static void MIBSPI_dmaCtrlGroupStart(CSL_mss_spiRegs *ptrMibSpiReg, uint8_t dmaCtrlGroup, Mibspi_DmaCtrlChType_e chType );
124 static void MIBSPI_dmaCtrlGroupDisable(CSL_mss_spiRegs *ptrMibSpiReg, uint8_t dmaCtrlGroup);
125 #endif
127 /**************************************************************************
128 ************************** Global Variables **********************************
129 **************************************************************************/
130 /* NONE */
132 /**************************************************************************
133 ************************* MibSPI Driver Local Functions ************************
134 **************************************************************************/
136 #ifdef SPI_PARAMS_CHECK
137 /**
138 * @b Description
139 * @n
140 * SPI driver parameter validation
141 *
142 * @param[in] params SPI driver parameters
143 *
144 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
145 *
146 * @retval Successful =0
147 * Failed <0
148 */
149 static int32_t MIBSPI_validateParams(const MIBSPI_Params *params)
150 {
151 int32_t retVal = (int32_t)0;
152 uint8_t index;
153 uint8_t ramBufOffset = 0U;
156 /* Validate dataSize, only 8bits and 16bits are supported */
157 if( (params->dataSize != 8U) && (params->dataSize != 16U))
158 {
159 retVal = MIBSPI_STATUS_ERROR;
160 goto Exit;
161 }
164 /* Validate bitRate */
165 if(params->mode == MIBSPI_MASTER)
166 {
167 if(params->u.masterParams.bitRate == 0U)
168 {
169 retVal = MIBSPI_STATUS_ERROR;
170 goto Exit;
172 }
173 if( (params->u.masterParams.numSlaves == 0U) || (params->u.masterParams.numSlaves > MIBSPI_SLAVE_MAX) )
174 {
175 retVal = MIBSPI_STATUS_ERROR;
176 goto Exit;
177 }
179 /* Validate slave profile configuraiton */
180 for(index = 0; index < params->u.masterParams.numSlaves; index++)
181 {
182 const MIBSPI_SlaveProfile *ptrSlaveProf;
184 /* Get the pointer to the slave profile */
185 ptrSlaveProf = ¶ms->u.masterParams.slaveProf[index];
187 /* Validate CS signal number */
188 if(ptrSlaveProf->chipSelect >= MIBSPI_MAX_CS)
189 {
190 retVal = MIBSPI_STATUS_ERROR;
191 goto Exit;
192 }
194 if(ptrSlaveProf->ramBufLen > MIBSPI_RAM_MAX_ELEM)
195 {
196 retVal = MIBSPI_STATUS_ERROR;
197 goto Exit;
198 }
200 ramBufOffset += ptrSlaveProf->ramBufLen;
202 }
204 /* Validate total RAM Elements exceed the size of MibSPI RAM */
205 if(ramBufOffset > MIBSPI_RAM_MAX_ELEM)
206 {
207 retVal = MIBSPI_STATUS_ERROR;
208 goto Exit;
209 }
210 }
211 else
212 {
213 /* Validate CS signal number */
214 if(params->u.slaveParams.chipSelect >= MIBSPI_MAX_CS)
215 {
216 retVal = MIBSPI_STATUS_ERROR;
217 goto Exit;
218 }
219 }
221 /* Validate DMA driver handle */
222 if(params->dmaEnable == (uint8_t)1U)
223 {
224 if(params->dmaHandle == NULL)
225 {
226 retVal = MIBSPI_STATUS_ERROR;
227 }
228 }
229 Exit:
230 return retVal;
231 }
233 /**
234 * @b Description
235 * @n
236 * SPI driver parameter validation
237 *
238 * @param[in] params SPI driver parameters
239 *
240 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
241 *
242 * @retval Successful =0
243 * Failed <0
244 */
245 static int32_t MIBSPI_validateTransferParams(const MIBSPI_Transaction *transaction, const MibSpiDriver_Object *ptrMibSpiDriver)
246 {
247 MibSpi_HwCfg const *hwAttrs;
248 int32_t status = MIBSPI_STATUS_SUCCESS;
249 uintptr_t key;
251 hwAttrs = ptrMibSpiDriver->ptrHwCfg;
253 /* Check the transaction arguments */
254 if (transaction->count == 0U)
255 {
256 status = MIBSPI_STATUS_ERROR;
257 }
259 /* Sanity check of parameters */
260 /* Both Tx and Rx cannot be dummy transaction */
261 if((transaction->txBuf == NULL) && (transaction->rxBuf == NULL))
262 {
263 status = MIBSPI_STATUS_ERROR;
264 }
266 if((transaction->slaveIndex >= MIBSPI_SLAVE_MAX)
267 ||
268 (transaction->slaveIndex >= hwAttrs->numDmaReqLines))
269 {
270 status = MIBSPI_STATUS_ERROR;
271 }
273 if(ptrMibSpiDriver->params.dataSize == 16U)
274 {
275 if(transaction->count % 2U != 0)
276 {
277 status = MIBSPI_STATUS_ERROR;
278 }
279 }
281 #ifndef SPI_MULT_ICOUNT_SUPPORT
282 {
283 uint16_t dataLength;
285 if(ptrMibSpiDriver->params.dataSize == 16U)
286 {
287 /* MIBSPI reads in 2 bytes format */
288 dataLength = (uint16_t)transaction->count >> 1U;
289 }
290 else
291 {
292 dataLength = transaction->count;
293 }
295 /* Check data elements */
296 if(dataLength > hwAttrs->mibspiRamSize)
297 {
298 status = MIBSPI_STATUS_ERROR;
299 }
300 }
301 #endif
303 /* Check if a transfer is in progress */
304 key = HwiP_disable();
306 if ( ptrMibSpiDriver->transactionState.transaction != NULL)
307 {
308 status = MIBSPI_STATUS_ERROR;
309 }
311 /* Transfer is in progress */
312 HwiP_restore(key);
313 return status;
314 }
316 #endif
318 /**
319 * @b Description
320 * @n
321 * Enable pin settings for SPI driver
322 *
323 * @param[in] ptrMibSpiReg Pointer to the SPI driver Register Base Address
324 * @param[in] pinMode Pin mode Configuration
325 * @param[in] chipSelectMask Bit Mask for enabled Chip select
326 *
327 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
328 *
329 * @retval Not Applicable
330 */
331 static void MIBSPI_enablePinSettings(CSL_mss_spiRegs *ptrMibSpiReg, MIBSPI_PinMode pinMode, uint8_t chipSelectMask)
332 {
333 uint32_t regVal = 0;
335 switch(pinMode)
336 {
337 /* 3pin setting, enable CLK, SIMO, SOMI */
338 case MIBSPI_PINMODE_3PIN:
339 /* SPIPC0 Register: Set Port pins to functional */
340 CSL_FINS(regVal, SPI_SPIPC0_CLKFUN, 1U);
341 CSL_FINS(regVal, SPI_SPIPC0_SIMOFUN0, 1U);
342 CSL_FINS(regVal, SPI_SPIPC0_SOMIFUN0, 1U);
343 ptrMibSpiReg->SPIPC0 = regVal;
344 break;
346 /* 4pin with CS setting, enable CLK, SIMO, SOMI and CSx */
347 case MIBSPI_PINMODE_4PIN_CS:
348 /* SPIPC0 Register: Set Port pins to functional */
349 CSL_FINS(regVal, SPI_SPIPC0_SCSFUN, (uint32_t)chipSelectMask);
350 CSL_FINS(regVal, SPI_SPIPC0_CLKFUN, 1U);
351 CSL_FINS(regVal, SPI_SPIPC0_SIMOFUN0, 1U);
352 CSL_FINS(regVal, SPI_SPIPC0_SOMIFUN0, 1U);
354 //CSL_FINS(regVal, SPI_SPIPC0_SOMIFUN, 0U);
355 //CSL_FINS(regVal, SPI_SPIPC0_SOMIFUN, 0U);
357 ptrMibSpiReg->SPIPC0 = regVal; /* enable SOMI */
358 break;
360 default:
361 Mibspi_assert(0);
362 break;
363 }
365 /* SPIPC7 Register: Set Port Pullup/Pulldown control: 0 to enable, 1 to disable */
366 regVal = ptrMibSpiReg->SPIPC7;
367 CSL_FINS(regVal, SPI_SPIPC7_SOMIPDIS0, 0);
368 CSL_FINS(regVal, SPI_SPIPC7_SIMOPDIS0, 0);
369 CSL_FINS(regVal, SPI_SPIPC7_CLKPDIS, 0);
370 CSL_FINS(regVal, SPI_SPIPC7_ENAPDIS, 0);
371 CSL_FINS(regVal, SPI_SPIPC7_SCSPDIS, 0);
372 ptrMibSpiReg->SPIPC7 = regVal;
374 /* SPIPC8 Register: Set Port Pullup/Pulldown value: 0 to pulldown, 1 to pullup */
375 regVal = ptrMibSpiReg->SPIPC8;
376 CSL_FINS(regVal, SPI_SPIPC8_SCSPSEL, 0x1U);
377 CSL_FINS(regVal, SPI_SPIPC8_ENAPSEL, 1U);
378 CSL_FINS(regVal, SPI_SPIPC8_CLKPSEL, 1U);
379 CSL_FINS(regVal, SPI_SPIPC8_SIMOPSEL0, 1U);
380 CSL_FINS(regVal, SPI_SPIPC8_SOMIPSEL0, 1U);
381 ptrMibSpiReg->SPIPC8 = regVal;
383 return;
384 }
386 /**
387 * @b Description
388 * @n
389 * Change SPI master clock prescaler
390 *
391 * @param[in] ptrMibSpiReg Pointer to the SPI driver Register Base Address
392 * @param[in] clockSrcFreq SPI Module source clock frequency
393 * @param[in] desiredSpiClock Desired SPI clock rate on CLOCK pin
394 *
395 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
396 *
397 * @retval None
398 */
399 static void MIBSPI_setMasterClockRate(CSL_mss_spiRegs *ptrMibSpiReg, uint32_t clockSrcFreq, uint32_t desiredSpiClock)
400 {
401 uint8_t clockDivisor;
403 clockDivisor = (uint8_t)(clockSrcFreq / desiredSpiClock);
405 /* Put MibSpi module in reset */
406 CSL_FINS(ptrMibSpiReg->SPIGCR1, SPI_SPIGCR1_SPIEN, 0U);
408 /* Set MibSpi clockDivisor */
409 CSL_FINS(ptrMibSpiReg->SPIFMT[0],SPI_SPIFMT_PRESCALE, (uint32_t)((uint32_t)clockDivisor - 1U));
411 /* Finally start MIBSPI1 */
412 CSL_FINS(ptrMibSpiReg->SPIGCR1, SPI_SPIGCR1_SPIEN, 1U);
414 }
416 /**
417 * @b Description
418 * @n
419 * This function brings Mibspi module out of reset.
420 *
421 * @param[in] ptrMibSpiReg Pointer to the SPI driver Register Base Address
422 * @param[in] reset true - mibspi module will be set in reset mode.
423 * false - it brings MibSPI out of reset mode.
424 *
425 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
426 *
427 * @retval None
428 */
429 static void MIBSPI_setResetMode(CSL_mss_spiRegs *ptrMibSpiReg, bool reset)
430 {
431 if(reset == true)
432 {
433 /* Set MibSpi in Reset mode */
434 CSL_FINS(ptrMibSpiReg->SPIGCR0, SPI_SPIGCR0_NRESET, 0U);
435 }
436 else
437 {
439 /* Bring MibSpi out of Reset mode */
440 CSL_FINS(ptrMibSpiReg->SPIGCR0, SPI_SPIGCR0_NRESET, 1U);
441 }
442 }
444 /**
445 * @b Description
446 * @n
447 * This function Enabe SPI and set SPI in MibSPI mode.
448 *
449 * @param[in] ptrMibSpiReg SPI module base address
450 *
451 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
452 *
453 * @retval None
454 */
455 static void MIBSPI_SPIEnable(CSL_mss_spiRegs *ptrMibSpiReg)
456 {
457 /* Acitvate SPI */
458 CSL_FINS(ptrMibSpiReg->SPIGCR1, SPI_SPIGCR1_ENABLE, 1U);
460 /* Enable MibSpi multibuffered mode and enable buffer RAM */
461 CSL_FINS(ptrMibSpiReg->MIBSPIE, SPI_MIBSPIE_MSPIENA, 1U);
462 }
464 /**
465 * @b Description
466 * @n
467 * This function Disable SPI and set SPI in SPI mode.
468 *
469 * @param[in] ptrMibSpiReg SPI module base address
470 *
471 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
472 *
473 * @retval None
474 */
475 static void MIBSPI_SPIDisable(CSL_mss_spiRegs *ptrMibSpiReg)
476 {
477 /* Disable MibSpi multibuffered mode and enable buffer RAM */
478 CSL_FINS(ptrMibSpiReg->MIBSPIE, SPI_MIBSPIE_MSPIENA, 0U);
480 /* De-acitvate SPI */
481 CSL_FINS(ptrMibSpiReg->SPIGCR1, SPI_SPIGCR1_SPIEN, 0U);
482 }
484 /**
485 * @b Description
486 * @n
487 * This function initiates a transfer for the specified transfer group.
488 *
489 * @param[in] ptrMibSpiReg SPI module base address
490 * @param[in] group Transfer group (0..7)
491 *
492 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
493 *
494 * @retval None
495 */
496 static void MIBSPI_transferGroupEnable(CSL_mss_spiRegs *ptrMibSpiReg, uint8_t group)
497 {
498 /* Enable Transfer group */
499 CSL_FINS(ptrMibSpiReg->TGCTRL[group],SPI_TGCTRL_TGENA, 1U);
500 }
503 /**
504 * @b Description
505 * @n
506 * This function initiates a transfer for the specified transfer group.
507 *
508 * @param[in] ptrMibSpiReg SPI module base address
509 * @param[in] group Transfer group (0..7)
510 *
511 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
512 *
513 * @retval None
514 */
515 static void MIBSPI_transferGroupDisable(CSL_mss_spiRegs *ptrMibSpiReg, uint8_t group)
516 {
517 /* Disable Transfer group */
518 CSL_FINS(ptrMibSpiReg->TGCTRL[group],SPI_TGCTRL_TGENA, 0U);
520 /* Transfer is completed , disable SPI */
521 MIBSPI_SPIDisable(ptrMibSpiReg);
522 }
524 /**
525 * @b Description
526 * @n
527 * This function sets the start offset of a transfer for the specified transfer group.
528 *
529 * @param[in] ptrMibSpiReg SPI module base address
530 * @param[in] group Transfer group
531 * @param[in] offset RAM offset For the TG group
532 *
533 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
534 *
535 * @retval None
536 */
537 static void MIBSPI_transferSetPStart(CSL_mss_spiRegs *ptrMibSpiReg, uint8_t group, uint8_t offset)
538 {
539 CSL_FINS(ptrMibSpiReg->TGCTRL[group],SPI_TGCTRL_PSTART, (uint32_t)offset);
540 }
542 /**
543 * @b Description
544 * @n
545 * This function checks to see if the transfer for the specified transfer group
546 * has finished.
547 *
548 * @param[in] ptrMibSpiReg SPI module base address
549 * @param[in] group Transfer group
550 *
551 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
552 *
553 * @retval =1 Transfer is finished.
554 * =0 Transfer is not finished.
555 */
556 static uint32_t MIBSPI_checkTGComplete(CSL_mss_spiRegs *ptrMibSpiReg, uint8_t group)
557 {
558 uint32_t status = 0U;
559 uint32_t groupMask;
560 uint32_t intFlagReady = 0U;
562 /* Get the bit mask of the group */
563 groupMask = (uint32_t)1U << group;
565 /* Read TGINT flag */
566 intFlagReady = CSL_FEXT(ptrMibSpiReg->TGINTFLAG,SPI_TGINTFLAG_INTFLGRDY);
567 if ( intFlagReady & groupMask)
568 {
569 /* Transfer finished, clear the corresponding flag */
570 CSL_FINS(ptrMibSpiReg->TGINTFLAG,SPI_TGINTFLAG_INTFLGRDY, groupMask);
571 status = 1U;
572 }
574 return (status);
575 }
577 /**
578 * @b Description
579 * @n
580 * This function enables the Loopback mode for self test. Loopback is SPI master only feature.
581 *
582 * @param[in] ptrMibSpiReg Mibspi module base address
583 * @param[in] loopbacktype Digital or Analog
584 *
585 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
586 *
587 * @retval None.
588 */
589 static void MIBSPI_enableLoopback(CSL_mss_spiRegs *ptrMibSpiReg, MibSpi_LoopBackType loopbacktype)
590 {
591 uint32_t regVal;
593 /* Put MibSpi module in reset */
594 CSL_FINS(ptrMibSpiReg->SPIGCR1,SPI_SPIGCR1_SPIEN, 0U);
596 regVal = ptrMibSpiReg->IOLPBKTSTCR;
597 /* Set Loopback either in Analog or Digital Mode */
598 CSL_FINS(regVal,SPI_IOLPBKTSTCR_LPBKTYPE, loopbacktype);
600 /* For IOLPBK in SLave mode, set loopback enable in MIBSPI_transaction as it immediately trigger TG0 */
601 if ((loopbacktype == MIBSPI_LOOPBK_ANALOG)
602 &&
603 (CSL_FEXT(ptrMibSpiReg->SPIGCR1,SPI_SPIGCR1_MASTER) == CSL_SPI_SPIGCR1_MASTER_SLAVE))
604 {
605 CSL_FINS(regVal,SPI_IOLPBKTSTCR_IOLPBKTSTENA, 0x5U);
606 }
607 else
608 {
609 /* Enable Loopback */
610 CSL_FINS(regVal,SPI_IOLPBKTSTCR_IOLPBKTSTENA, 0xAU);
611 }
612 if (loopbacktype == MIBSPI_LOOPBK_ANALOG)
613 {
614 CSL_FINS(regVal,SPI_IOLPBKTSTCR_RXPENA, 0x1U);
615 }
617 ptrMibSpiReg->IOLPBKTSTCR = regVal;
618 /* Restart MIBSPI1 */
620 regVal = ptrMibSpiReg->SPIGCR1;
621 CSL_FINS(regVal,SPI_SPIGCR1_SPIEN, 1U);
623 if (CSL_FEXT(ptrMibSpiReg->SPIGCR1,SPI_SPIGCR1_MASTER) == CSL_SPI_SPIGCR1_MASTER_MASTER)
624 {
625 CSL_FINS(regVal,SPI_SPIGCR1_LOOPBACK, 1U);
626 }
627 ptrMibSpiReg->SPIGCR1 = regVal;
628 }
630 /**
631 * @b Description
632 * @n
633 * This function disable the Loopback mode.
634 *
635 * @param[in] ptrMibSpiReg Mibspi module base address
636 *
637 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
638 *
639 * @retval None.
640 */
641 static void MIBSPI_disableLoopback(CSL_mss_spiRegs *ptrMibSpiReg)
642 {
643 /* Put MibSpi module in reset */
644 CSL_FINS(ptrMibSpiReg->SPIGCR1,SPI_SPIGCR1_SPIEN, 0U);
646 /* Disable Loopback either in Analog or Digital Mode */
647 CSL_FINS(ptrMibSpiReg->IOLPBKTSTCR,SPI_IOLPBKTSTCR_IOLPBKTSTENA, 0x5U);
649 /* Restart MIBSPI1 */
650 CSL_FINS(ptrMibSpiReg->SPIGCR1,SPI_SPIGCR1_SPIEN, 1U);
651 }
653 /**
654 * @b Description
655 * @n
656 * This function sets the Polarity and phase for MibSpi as requested.
657 *
658 * @param[in] ptrMibSpiReg MibSpi register base address
659 * @param[in] clockFmt MibSpiSPI functional mode (clock/polarity)
660 *
661 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
662 *
663 * @retval None.
664 */
665 static void MIBSPI_setClockPhasePolarity(volatile CSL_mss_spiRegs *ptrMibSpiReg, uint8_t clockFmt)
666 {
667 uint32_t regVal;
668 /* Put MibSpi module in reset */
669 CSL_FINS(ptrMibSpiReg->SPIGCR1,SPI_SPIGCR1_SPIEN, 0U);
671 /* Set MibSpi Slave functional Mode Clock/polarity */
672 regVal = ptrMibSpiReg->SPIFMT[0];
673 CSL_FINS(regVal, SPI_SPIFMT_PHASE, MIBSPI_getPhase((MIBSPI_FrameFormat)clockFmt)); /* PHASE */
674 CSL_FINS(regVal, SPI_SPIFMT_POLARITY, MIBSPI_getPolarity((MIBSPI_FrameFormat)clockFmt)); /* POLARITY */
675 ptrMibSpiReg->SPIFMT[0] = regVal;
677 /* Finally start MIBSPI1 */
678 CSL_FINS(ptrMibSpiReg->SPIGCR1,SPI_SPIGCR1_SPIEN, 1U);
679 }
681 #ifdef MIBSPI_DMA_ENABLE
682 /**
683 * @b Description
684 * @n
685 * This function enables the transfer group finished interrupt.
686 *
687 * @param[in] ptrMibSpiReg SPI module base address
688 * @param[in] group Transfer group
689 * @param[in] intLine Interrupt Line - 0->INT0, 1->INT1
690 *
691 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
692 *
693 * @retval None.
694 */
695 static void MIBSPI_enableGroupInterrupt(CSL_mss_spiRegs *ptrMibSpiReg, uint8_t group, uint32_t intLine)
696 {
697 if(intLine == 0)
698 {
699 /* INT0 interrupt */
700 CSL_FINS(ptrMibSpiReg->TGITLVCR,SPI_TGITLVCR_CLRINTLVLRDY, (uint32_t)1U << group);
701 }
702 else
703 {
704 /* INT1 interrupt */
705 CSL_FINS(ptrMibSpiReg->TGITLVST,SPI_TGITLVST_SETINTLVLRDY, (uint32_t)1U << group);
706 }
708 /* Enable interrupt */
709 CSL_FINS(ptrMibSpiReg->TGITENST,SPI_TGITENST_SETINTENRDY, (uint32_t)1U << group);
710 }
712 /**
713 * @b Description
714 * @n
715 * This function disables the transfer group finished interrupt.
716 *
717 * @param[in] ptrMibSpiReg SPI module base address
718 * @param[in] group Transfer group
719 *
720 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
721 *
722 * @retval None.
723 */
724 static void MIBSPI_disableGroupInterrupt(CSL_mss_spiRegs *ptrMibSpiReg, uint8_t group)
725 {
726 /* Disable interrupt */
727 CSL_FINS(ptrMibSpiReg->TGITENCR,SPI_TGITENCR_CLRINTENRDY, (uint32_t)1U << group);
728 }
730 /**
731 * @b Description
732 * @n
733 * This function set the MIBSPI DMA channel Control Register depending on given
734 * input parameters
735 *
736 * @param[in] ptrMibSpiReg MibSpi Register base address
737 * @param[in] bufId Buffer id
738 * @param[in] iCount icount configuration
739 * @param[in] dmaCtrlGroup MibSPI DMA Control group(0..7)
740 *
741 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
742 *
743 * @retval None.
744 */
745 static void MIBSPI_dmaCtrlGroupConfig(CSL_mss_spiRegs *ptrMibSpiReg, uint16_t bufId, uint8_t iCount, uint8_t dmaCtrlGroup)
746 {
747 uint32_t regVal = 0;
749 /* Setting Transmit channel DMA request */
750 CSL_FINS(regVal,SPI_DMACTRL_TXDMA_MAP, (uint32_t)dmaCtrlGroup * 2U);
751 CSL_FINS(regVal,SPI_DMACTRL_TXDMAENA, 0U);
752 CSL_FINS(regVal,SPI_DMACTRL_BUFID, (uint32_t)bufId);
753 CSL_FINS(regVal,SPI_DMACTRL_ICOUNT, (uint32_t)iCount);
754 CSL_FINS(regVal,SPI_DMACTRL_ONESHOT, 1U);
756 /* Setting Receive channel DMA request */
757 CSL_FINS(regVal,SPI_DMACTRL_RXDMA_MAP, (uint32_t)dmaCtrlGroup * 2U + 1);
758 CSL_FINS(regVal,SPI_DMACTRL_RXDMAENA, 0U);
759 CSL_FINS(regVal,SPI_DMACTRL_BUFID, (uint32_t)bufId);
760 CSL_FINS(regVal,SPI_DMACTRL_ICOUNT, (uint32_t)iCount);
761 CSL_FINS(regVal,SPI_DMACTRL_ONESHOT, 1U);
763 ptrMibSpiReg->DMACTRL[dmaCtrlGroup] = regVal;
764 return;
765 }
767 static void MIBSPI_dmaCtrlGroupStart(CSL_mss_spiRegs *ptrMibSpiReg, uint8_t dmaCtrlGroup, Mibspi_DmaCtrlChType_e chType )
768 {
769 uint32_t regVal = ptrMibSpiReg->DMACTRL[dmaCtrlGroup];
771 if ((chType == MIBSPI_DMACTRL_CH_TX)
772 ||
773 (chType == MIBSPI_DMACTRL_CH_BOTH))
774 {
775 /* Setting Transmit channel DMA request */
776 CSL_FINS(regVal,SPI_DMACTRL_TXDMAENA, 1U);
777 }
778 if ((chType == MIBSPI_DMACTRL_CH_RX)
779 ||
780 (chType == MIBSPI_DMACTRL_CH_BOTH))
781 {
782 /* Setting Receive channel DMA request */
783 CSL_FINS(regVal,SPI_DMACTRL_RXDMAENA, 1U);
784 }
785 ptrMibSpiReg->DMACTRL[dmaCtrlGroup] = regVal;
786 return;
787 }
789 /**
790 * @b Description
791 * @n
792 * This function reset the MIBSPI TX and RX DMA channel Control Register
793 *
794 * @param[in] ptrMibSpiReg MibSpi Register base address
795 * @param[in] dmaCtrlGroup MibSPI DMA Control group(0..7)
796 *
797 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
798 *
799 * @retval None.
800 */
801 static void MIBSPI_dmaCtrlGroupDisable(CSL_mss_spiRegs *ptrMibSpiReg, uint8_t dmaCtrlGroup)
802 {
803 /* Get MibSpi Register & Ram Base address */
804 uint32_t regVal = ptrMibSpiReg->DMACTRL[dmaCtrlGroup];
806 CSL_FINS(regVal, SPI_DMACTRL_ONESHOT, 0U);
807 CSL_FINS(regVal, SPI_DMACTRL_BUFID, 0U);
808 CSL_FINS(regVal, SPI_DMACTRL_RXDMA_MAP, 0U);
809 CSL_FINS(regVal, SPI_DMACTRL_TXDMA_MAP, 0U);
810 CSL_FINS(regVal, SPI_DMACTRL_RXDMAENA, 0U);
811 CSL_FINS(regVal, SPI_DMACTRL_TXDMAENA, 0U);
812 CSL_FINS(regVal, SPI_DMACTRL_NOBRK, 0U);
813 CSL_FINS(regVal, SPI_DMACTRL_ICOUNT, 0U);
814 CSL_FINS(regVal, SPI_DMACTRL_BUFID7, 0U);
815 ptrMibSpiReg->DMACTRL[dmaCtrlGroup] = regVal;
817 }
818 #endif
820 /**
821 * @b Description
822 * @n
823 * Initializes the MIBSPI as a SPI master
824 *
825 * @param[in] ptrHwCfg Pointer to the SPI driver hardward Configuration
826 * @param[in] params SPI device configuration parameters
827 *
828 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
829 *
830 * @retval None
831 */
832 static void MIBSPI_initMaster(MibSpi_HwCfg* ptrHwCfg, const MIBSPI_Params * params)
833 {
834 CSL_mibspiRam *ptrMibSpiRam;
835 CSL_mss_spiRegs *ptrMibSpiReg;
836 uint32_t flag;
837 uint32_t index;
838 uint8_t csnr = 0;
839 uint8_t chipSelectMask;
840 uint8_t ramBufOffset = 0;
841 uint32_t regVal;
843 /* Get Register and RAM base */
844 ptrMibSpiRam = ptrHwCfg->ptrMibSpiRam;
845 ptrMibSpiReg = ptrHwCfg->ptrSpiRegBase;
847 /* Bring MIBSPI out of reset */
848 ptrMibSpiReg->SPIGCR0 = 0U;
849 ptrMibSpiReg->SPIGCR0 = 1U;
851 /* Enable MibSpi multibuffered mode and enable buffer RAM */
852 CSL_FINS(ptrMibSpiReg->MIBSPIE,SPI_MIBSPIE_MSPIENA, 1U);
854 /* Wait for buffer initialization complete before accessing MibSPI Ram */
855 while(1)
856 {
857 flag = CSL_FEXT(ptrMibSpiReg->SPIFLG,SPI_SPIFLG_BUFINITACTIVE);
858 if(flag == 0)
859 {
860 break;
861 }
862 }
864 MIBSPI_socMemInit(ptrHwCfg->mibspiInstId);
865 /* Set MibSpi master mode and clock configuration */
866 regVal = ptrMibSpiReg->SPIGCR1;
867 CSL_FINS(regVal,SPI_SPIGCR1_MASTER, CSL_SPI_SPIGCR1_MASTER_MASTER);
868 CSL_FINS(regVal,SPI_SPIGCR1_CLKMOD, CSL_SPI_SPIGCR1_CLKMOD_INTERNAL);
869 ptrMibSpiReg->SPIGCR1 = regVal;
871 /* SPIENV pin pulled high when not active */
872 CSL_FINS(ptrMibSpiReg->SPIINT0,SPI_SPIINT0_ENABLEHIGHZ, 0U);
874 /* Delays Configuration: this master only configuraion, hence set it to all zeros */
875 if( (params->u.masterParams.c2tDelay != 0U) ||
876 (params->u.masterParams.t2cDelay != 0U) )
877 {
878 regVal = ptrMibSpiReg->SPIDELAY;
879 CSL_FINS(regVal, SPI_SPIDELAY_C2TDELAY, (uint32_t)params->u.masterParams.c2tDelay);
880 CSL_FINS(regVal, SPI_SPIDELAY_T2CDELAY, (uint32_t)params->u.masterParams.t2cDelay);
881 ptrMibSpiReg->SPIDELAY = regVal;
882 }
883 else
884 {
885 ptrMibSpiReg->SPIDELAY = 0x0U;
886 }
888 /* Set Data Format 0 */
889 regVal = ptrMibSpiReg->SPIFMT[0];
890 CSL_FINS(regVal, SPI_SPIFMT_PHASE, MIBSPI_getPhase(params->frameFormat)); /* PHASE */
891 CSL_FINS(regVal, SPI_SPIFMT_POLARITY, MIBSPI_getPolarity(params->frameFormat)); /* POLARITY */
892 CSL_FINS(regVal, SPI_SPIFMT_WDELAY, (uint32_t) params->u.masterParams.wDelay); /* WDELAY */
893 CSL_FINS(regVal, SPI_SPIFMT_PRESCALE, 0U); /* PRESCALE */
894 CSL_FINS(regVal, SPI_SPIFMT_SHIFTDIR, (uint32_t) params->shiftFormat); /* SHIFTDIR */
895 CSL_FINS(regVal, SPI_SPIFMT_CHARLEN, (uint32_t) params->dataSize); /* CHARlEN */
896 ptrMibSpiReg->SPIFMT[0] = regVal;
898 /* Set Data Format 1 */
899 regVal = ptrMibSpiReg->SPIFMT[1];
900 CSL_FINS(regVal, SPI_SPIFMT_PRESCALE, 18U); /* PRESCALE */
901 CSL_FINS(regVal, SPI_SPIFMT_CHARLEN, (uint32_t) params->dataSize); /* CHARlEN */
902 ptrMibSpiReg->SPIFMT[1] = regVal;
904 /* Set Data Format 2 */
905 regVal = ptrMibSpiReg->SPIFMT[2];
906 CSL_FINS(regVal, SPI_SPIFMT_PRESCALE, 18U); /* PRESCALE */
907 CSL_FINS(regVal, SPI_SPIFMT_CHARLEN, (uint32_t)params->dataSize); /* CHARlEN */
908 ptrMibSpiReg->SPIFMT[2] = regVal;
910 /* Set Data Format 3 */
911 regVal = ptrMibSpiReg->SPIFMT[3];
912 CSL_FINS(regVal, SPI_SPIFMT_PRESCALE, 18U); /* PRESCALE */
913 CSL_FINS(regVal, SPI_SPIFMT_CHARLEN, (uint32_t)params->dataSize); /* CHARlEN */
914 ptrMibSpiReg->SPIFMT[3] = regVal;
916 /* Set Default Chip Select pattern: 1- chip select is set to "1" when SPI is IDLE
917 Debug Note: Only CS0 can be set to 1 */
918 CSL_FINS(ptrMibSpiReg->SPIDEF,SPI_SPIDEF_CSDEF0, 0xFFU);
920 /* Enable ECC if enabled */
921 if(params->eccEnable)
922 {
923 /* Enable ECC detection and signal bit Error correction */
924 regVal = ptrMibSpiReg->PAR_ECC_CTRL;
925 CSL_FINS(regVal, SPI_PAR_ECC_CTRL_EDEN, 0xAU);
926 CSL_FINS(regVal, SPI_PAR_ECC_CTRL_EDAC_MODE, 0xAU);
927 CSL_FINS(regVal, SPI_PAR_ECC_CTRL_SBE_EVT_EN, 0xAU);
928 ptrMibSpiReg->PAR_ECC_CTRL = regVal;
929 }
931 for (index = 0; index < params->u.masterParams.numSlaves; index++)
932 {
933 /* Initialize transfer groups for number of slaves connected to SPI master */
934 regVal = ptrMibSpiReg->TGCTRL[index];
935 CSL_FINS(regVal, SPI_TGCTRL_ONESHOT, 1U); /* Oneshot trigger */
936 CSL_FINS(regVal, SPI_TGCTRL_TRIGEVT, 7U); /* Trigger event : Always */
937 CSL_FINS(regVal, SPI_TGCTRL_TRIGSRC, 0U); /* Trigger source : disabled */
938 CSL_FINS(regVal, SPI_TGCTRL_PSTART, 0U); /* TG start address : 0 */
939 ptrMibSpiReg->TGCTRL[index] = regVal;
940 }
942 /* Initialize transfer groups end pointer */
943 CSL_FINS(ptrMibSpiReg->LTGPEND,SPI_LTGPEND_LPEND, 0xFFU);
945 /* Initialize TX Buffer Ram */
946 for (index = 0; index < params->u.masterParams.numSlaves; index++)
947 {
948 uint8_t ramBufIndex = 0;
949 uint8_t wDelayEnable = 0;
951 /* Multibuffer RAM control:
952 * buffer mode : 0x6
953 * CSHOLD: 0x0
954 */
956 wDelayEnable = params->u.masterParams.wDelay? (uint8_t)1U : (uint8_t)0U;
957 if(params->pinMode == MIBSPI_PINMODE_4PIN_CS)
958 {
959 chipSelectMask = (uint8_t)(0x1U << params->u.masterParams.slaveProf[index].chipSelect);
960 csnr = ~chipSelectMask;
961 }
962 else
963 {
964 /* 3-pin mode, set CSNR to 0xFF */
965 csnr = (uint8_t)MIBSPI_CS_NONE;
966 }
968 for (ramBufIndex = 0; ramBufIndex < params->u.masterParams.slaveProf[index].ramBufLen; ramBufIndex++)
969 {
970 uint32_t txControlWd = 0;
971 uint16_t txCtrlWd16;
972 volatile uint16_t *txCtrlWdPtr;
974 CSL_FINS(txControlWd, MIBSPIRAM_TX_BUFMODE, MIBSPI_RAM_BUFFER_MODE);
975 CSL_FINS(txControlWd, MIBSPIRAM_TX_CSHOLD, params->csHold);
976 CSL_FINS(txControlWd, MIBSPIRAM_TX_WDEL, wDelayEnable);
977 CSL_FINS(txControlWd, MIBSPIRAM_TX_CSNR, csnr);
978 txCtrlWd16 = ((txControlWd & 0xFFFF0000) >> 16);
979 txCtrlWdPtr = (uint16_t *)&ptrMibSpiRam->tx[ramBufOffset];
980 #ifdef __little_endian__
981 txCtrlWdPtr++;
982 #elif defined(__big_endian__)
983 //Do nothing. FIrst 16 bit word is the control word */
984 #else
985 #error "Unknown endianness"
986 #endif
987 *txCtrlWdPtr = txCtrlWd16;
988 ramBufOffset++;
989 }
991 if(ramBufOffset > MIBSPI_RAM_MAX_ELEM)
992 {
993 Mibspi_assert(0);
994 }
995 }
997 /* Clear pending interrupts */
998 ptrMibSpiReg->SPIFLG |= 0xFFFFU;
1000 /* Clear pending TG interrupts */
1001 ptrMibSpiReg->TGINTFLAG |= 0xFFFFFFFFU;
1003 /* Enable Error interrupts: Lower 8bits */
1004 MIBSPI_enableErrorInterrupt(ptrMibSpiReg, 0x1U);
1006 /* Set Interrupt Levels - Interrupts are mapped to INT1 */
1007 MIBSPI_setErrorInterruptLevel(ptrMibSpiReg, 0x1U);
1009 /* Enable TG Interrupts to INT1 */
1010 ptrMibSpiReg->TGITENST|= 0xFFFFFFFFU;
1012 /* Pin settings for SPI signal */
1013 if(params->pinMode == MIBSPI_PINMODE_4PIN_CS)
1014 {
1015 chipSelectMask = (uint8_t)0U;
1016 for (index = 0; index < params->u.masterParams.numSlaves; index++)
1017 {
1018 chipSelectMask |= (uint8_t)(0x1U << params->u.masterParams.slaveProf[index].chipSelect);
1019 }
1020 }
1021 else
1022 {
1023 chipSelectMask = (uint8_t)0x0U;
1024 }
1025 MIBSPI_enablePinSettings(ptrMibSpiReg, params->pinMode, chipSelectMask);
1027 /* Finally start MIBSPI1 */
1028 CSL_FINS(ptrMibSpiReg->SPIGCR1,SPI_SPIGCR1_SPIEN, 1U);
1029 }
1031 /**
1032 * @b Description
1033 * @n
1034 * Initializes the MIBSPI as a SPI slave
1035 *
1036 * @param[in] ptrHwCfg Pointer to the SPI driver hardward Configuration
1037 * @param[in] params SPI device configuration parameters
1038 *
1039 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
1040 *
1041 * @retval None
1042 */
1043 static void MIBSPI_initSlave(MibSpi_HwCfg* ptrHwCfg, const MIBSPI_Params *params)
1044 {
1045 CSL_mibspiRam *ptrMibSpiRam;
1046 CSL_mss_spiRegs *ptrMibSpiReg;
1047 uint32_t flag;
1048 uint32_t index;
1049 uint32_t regVal;
1051 /* Get Register and RAM base */
1052 ptrMibSpiRam = ptrHwCfg->ptrMibSpiRam;
1053 ptrMibSpiReg = ptrHwCfg->ptrSpiRegBase;
1055 /* Bring MIBSPI out of reset */
1056 ptrMibSpiReg->SPIGCR0 = 0U;
1057 ptrMibSpiReg->SPIGCR0 = 1U;
1059 /* Enable MIBSPI1 multibuffered mode and enable buffer RAM */
1060 CSL_FINS(ptrMibSpiReg->MIBSPIE,SPI_MIBSPIE_MSPIENA, 1U);
1062 /* Wait for buffer initialization complete before accessing MibSPI registers */
1063 while(1)
1064 {
1065 flag = CSL_FEXT(ptrMibSpiReg->SPIFLG,SPI_SPIFLG_BUFINITACTIVE);
1066 if(flag == 0)
1067 {
1068 break;
1069 }
1070 }
1072 MIBSPI_socMemInit(ptrHwCfg->mibspiInstId);
1074 regVal = ptrMibSpiReg->SPIGCR1;
1075 /* MIBSPI1 slave mode and clock configuration */
1076 CSL_FINS(regVal,SPI_SPIGCR1_MASTER, CSL_SPI_SPIGCR1_MASTER_SLAVE);
1077 CSL_FINS(regVal,SPI_SPIGCR1_CLKMOD, CSL_SPI_SPIGCR1_CLKMOD_EXTERNAL);
1078 ptrMibSpiReg->SPIGCR1 = regVal;
1080 /* SPIENA pin pulled high when not active */
1081 CSL_FINS(ptrMibSpiReg->SPIINT0,SPI_SPIINT0_ENABLEHIGHZ, 0U);
1083 /* Delays Configuration: this is only used by master, hence set it to all zeros */
1084 ptrMibSpiReg->SPIDELAY = 0x0U;
1086 /* Set Data Format 0 */
1087 regVal = ptrMibSpiReg->SPIFMT[0];
1088 CSL_FINS(regVal, SPI_SPIFMT_PHASE, MIBSPI_getPhase(params->frameFormat)); /* PHASE */
1089 CSL_FINS(regVal, SPI_SPIFMT_POLARITY, MIBSPI_getPolarity(params->frameFormat)); /* POLARITY */
1090 CSL_FINS(regVal, SPI_SPIFMT_PRESCALE, 4U); /* PRESCALE */
1091 CSL_FINS(regVal, SPI_SPIFMT_SHIFTDIR, (uint32_t)(params->shiftFormat)); /* SHIFTDIR */
1092 CSL_FINS(regVal, SPI_SPIFMT_CHARLEN, (uint32_t)params->dataSize); /* CHARlEN */
1093 ptrMibSpiReg->SPIFMT[0] = regVal;
1095 /* Set Data Format 1,2,3. Used mulitple TG group transfer */
1096 regVal = ptrMibSpiReg->SPIFMT[1];
1097 CSL_FINS(regVal, SPI_SPIFMT_PRESCALE, 18U); /* PRESCALE */
1098 CSL_FINS(regVal, SPI_SPIFMT_CHARLEN, (uint32_t)params->dataSize); /* CHARlEN */
1099 ptrMibSpiReg->SPIFMT[1] = regVal;
1101 regVal = ptrMibSpiReg->SPIFMT[2];
1102 CSL_FINS(regVal, SPI_SPIFMT_PRESCALE, 18U); /* PRESCALE */
1103 CSL_FINS(regVal, SPI_SPIFMT_CHARLEN, (uint32_t)params->dataSize); /* CHARlEN */
1104 ptrMibSpiReg->SPIFMT[2] = regVal;
1106 regVal = ptrMibSpiReg->SPIFMT[3];
1107 CSL_FINS(regVal, SPI_SPIFMT_PRESCALE, 18U); /* PRESCALE */
1108 CSL_FINS(regVal, SPI_SPIFMT_CHARLEN, (uint32_t)params->dataSize); /* CHARlEN */
1109 ptrMibSpiReg->SPIFMT[3] = regVal;
1112 /* Enable ECC if enabled */
1113 if(params->eccEnable)
1114 {
1115 /* Enable ECC detection and signal bit Error correction */
1116 regVal = ptrMibSpiReg->PAR_ECC_CTRL;
1117 CSL_FINS(regVal,SPI_PAR_ECC_CTRL_EDEN, 0xAU);
1118 CSL_FINS(regVal,SPI_PAR_ECC_CTRL_EDAC_MODE, 0xAU);
1119 CSL_FINS(regVal,SPI_PAR_ECC_CTRL_SBE_EVT_EN, 0xAU);
1120 ptrMibSpiReg->PAR_ECC_CTRL = regVal;
1121 }
1123 for (index = 0; index < MIBSPI_NUM_TRANS_GROUP; index++)
1124 {
1125 /* Initialize transfer groups */
1126 regVal = ptrMibSpiReg->TGCTRL[index];
1127 CSL_FINS(regVal,SPI_TGCTRL_ONESHOT, 1U); /* Oneshot trigger */
1128 CSL_FINS(regVal,SPI_TGCTRL_TRIGEVT, 7U); /* Trigger event : Always */
1129 CSL_FINS(regVal,SPI_TGCTRL_TRIGSRC, 0U); /* Trigger source : disabled */
1130 CSL_FINS(regVal,SPI_TGCTRL_PSTART, 0U); /* TG start address : 0 */
1131 ptrMibSpiReg->TGCTRL[index] = regVal;
1132 }
1134 /* Initialize transfer groups end pointer */
1135 CSL_FINS(ptrMibSpiReg->LTGPEND,SPI_LTGPEND_LPEND, 0x0U);
1137 /* Initialize TX Buffer Ram, every element contains 16bits of data */
1138 for (index = 0; index < MIBSPI_RAM_MAX_ELEM; index++)
1139 {
1140 uint32_t txControlWd = 0;
1141 uint16_t txCtrlWd16;
1142 uint16_t *txCtrlWdPtr;
1144 CSL_FINS(txControlWd, MIBSPIRAM_TX_BUFMODE, MIBSPI_RAM_BUFFER_MODE);
1145 CSL_FINS(txControlWd, MIBSPIRAM_TX_CSHOLD, params->csHold);
1146 CSL_FINS(txControlWd, MIBSPIRAM_TX_CSNR, MIBSPI_CS_NONE);
1147 txCtrlWd16 = ((txControlWd & 0xFFFF0000) >> 16);
1148 txCtrlWdPtr = (uint16_t *)&ptrMibSpiRam->tx[index];
1149 #ifdef __little_endian__
1150 txCtrlWdPtr++;
1151 #elif defined(__big_endian__)
1152 //Do nothing. FIrst 16 bit word is the control word */
1153 #else
1154 #error "Unknown endianness"
1155 #endif
1156 *txCtrlWdPtr = txCtrlWd16;
1157 }
1159 /* Clear pending interrupts */
1160 ptrMibSpiReg->SPIFLG |= 0xFFFFU;
1162 /* Clear pending TG interrupts */
1163 ptrMibSpiReg->TGINTFLAG |= 0xFFFFFFFFU;
1165 /* Enable Error interrupts: Lower 8bits */
1166 MIBSPI_enableErrorInterrupt(ptrMibSpiReg, 0x1U);
1168 /* Set Interrupt Levels - Interrupts are mapped to INT0 */
1169 MIBSPI_setErrorInterruptLevel(ptrMibSpiReg, 0x1U);
1171 /* Enable TG Interrupts to INT1 */
1172 ptrMibSpiReg->TGITENST|= 0xFFFFFFFFU;
1174 /* Pin settings for SPI signal */
1175 MIBSPI_enablePinSettings(ptrMibSpiReg, params->pinMode, (uint8_t)(0x1U <<params->u.slaveParams.chipSelect));
1177 /* Finally start MIBSPI1 */
1178 CSL_FINS(ptrMibSpiReg->SPIGCR1,SPI_SPIGCR1_SPIEN, 1U);
1179 }
1181 /**
1182 * @b Description
1183 * @n
1184 * This function updates the data for the specified transfer group,
1185 * the length of the data must match the length of the transfer group.
1186 *
1187 * @param[in] ptrMibSpiDriver MibSpi driver Handle
1188 * @param[in] group Transfer group (0..7)
1189 * @param[in] data Data buffer address
1190 * @param[in] dataElem Data element size
1191 *
1192 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
1193 *
1194 * @retval None
1195 */
1196 static void MIBSPI_writeDataRAM(MibSpiDriver_Object *ptrMibSpiDriver, uint8_t group, uint16_t *data, uint16_t dataElem)
1197 {
1198 CSL_mss_spiRegs *ptrMibSpiReg;
1199 CSL_mibspiRam *ptrMibSpiRam;
1200 uint32_t start;
1201 uint32_t index;
1203 /* Get MibSpi Register & RAM Base address */
1204 ptrMibSpiReg = ptrMibSpiDriver->ptrHwCfg->ptrSpiRegBase;
1205 ptrMibSpiRam = ptrMibSpiDriver->ptrHwCfg->ptrMibSpiRam;
1207 /* Fetch the start address from Register */
1208 start = CSL_FEXT(ptrMibSpiReg->TGCTRL[group],SPI_TGCTRL_PSTART);
1210 /* Write data in TX RAM */
1211 if(data == NULL)
1212 {
1213 for(index=start; index < (start + dataElem); index++)
1214 {
1215 CSL_MIBSPIRAM_SET_TX_TXDATA(ptrMibSpiRam, index, ptrMibSpiDriver->txScratchBuffer);
1216 }
1217 }
1218 else
1219 {
1220 if(ptrMibSpiDriver->params.dataSize == 16U)
1221 {
1222 for(index=start; index < (start + dataElem); index++)
1223 {
1224 CSL_MIBSPIRAM_SET_TX_TXDATA(ptrMibSpiRam, index, data[index-start]);
1225 }
1226 }
1227 else
1228 {
1229 uint8_t *pBuffer = (uint8_t *)data;
1231 for(index=start; index < (start + dataElem); index++)
1232 {
1233 CSL_MIBSPIRAM_SET_TX_TXDATA(ptrMibSpiRam, index, pBuffer[index-start]);
1234 }
1235 }
1236 }
1237 }
1239 /**
1240 * @b Description
1241 * @n
1242 * This function transfers the data from the specified transfer group receive
1243 * buffers to the data array, the length of the data must match the length
1244 * of the transfer group.
1245 *
1246 * @param[in] ptrMibSpiDriver MibSpi driver Handle
1247 * @param[in] group Transfer group (0..7)
1248 * @param[out] data Pointer to data array
1249 * @param[in] dataElem Data element size
1250 *
1251 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
1252 *
1253 * @retval return error flags from data buffer, if there was a receive error on
1254 * one of the buffers this will be reflected in the return value.
1255 */
1256 static uint32_t MIBSPI_readDataRAM(MibSpiDriver_Object *ptrMibSpiDriver, uint8_t group, uint16_t *data, uint16_t dataElem)
1257 {
1258 CSL_mss_spiRegs *ptrMibSpiReg;
1259 volatile CSL_mibspiRam *ptrMibSpiRam;
1260 uint16_t mibspiFlags = 0U;
1261 uint32_t ret;
1262 uint32_t start;
1263 uint32_t index;
1265 /* Get MibSpi Register & Ram Base address */
1266 ptrMibSpiReg = ptrMibSpiDriver->ptrHwCfg->ptrSpiRegBase;
1267 ptrMibSpiRam = ptrMibSpiDriver->ptrHwCfg->ptrMibSpiRam;
1269 /* Fetch the start address from Register */
1270 start = CSL_FEXT(ptrMibSpiReg->TGCTRL[group],SPI_TGCTRL_PSTART);
1272 if(data == NULL)
1273 {
1274 /* Save data from RAM into scrach buffer */
1275 for(index=start; index < (start + dataElem); index++)
1276 {
1277 /* Wait until data is available */
1278 while(CSL_MIBSPIRAM_GET_RX_RXEMPTY(ptrMibSpiRam, index) != 0U)
1279 {
1280 }
1282 mibspiFlags |= CSL_MIBSPIRAM_GET_RX_RXFLAGS(ptrMibSpiRam, index);
1284 ptrMibSpiDriver->rxScratchBuffer = CSL_MIBSPIRAM_GET_RX_RXDATA(ptrMibSpiRam, index);
1285 }
1286 }
1287 else
1288 {
1290 /* Save data from RAM */
1291 for(index=start; index < (start + dataElem); index++)
1292 {
1294 /* Wait until data is available */
1295 while(CSL_MIBSPIRAM_GET_RX_RXEMPTY(ptrMibSpiRam,index) != 0U)
1296 {
1297 }
1299 mibspiFlags |= CSL_MIBSPIRAM_GET_RX_RXFLAGS(ptrMibSpiRam, index);
1301 if(ptrMibSpiDriver->params.dataSize == 16U)
1302 {
1303 data[index-start] = CSL_MIBSPIRAM_GET_RX_RXDATA(ptrMibSpiRam, index);
1304 }
1305 else
1306 {
1307 uint8_t *pBuffer = (uint8_t *)data;
1309 pBuffer[index-start] = (uint8_t)(CSL_MIBSPIRAM_GET_RX_RXDATA(ptrMibSpiRam, index) & 0xFFU);
1310 }
1311 }
1312 }
1314 /* Rx Flags */
1315 ret = ((uint32_t)mibspiFlags >> 8U) & 0x5FU;
1317 return ret;
1318 }
1320 /**
1321 * @b Description
1322 * @n
1323 * The function is the registered ISR for the MIBSPI interrupt.
1324 *
1325 * @param[in] arg
1326 * Argument which is registered with the OS while registering
1327 * the ISR
1328 *
1329 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
1330 *
1331 * @retval
1332 * Not applicable
1333 */
1334 static void MIBSPI_ISR (uintptr_t arg)
1335 {
1336 MibSpiDriver_Object *ptrMibSpiDriver;
1337 CSL_mss_spiRegs *ptrMibSpiReg;
1338 volatile uint32_t intVector;
1339 uint8_t group = 0U;
1341 /* Get the MibSpi driver handle */
1342 ptrMibSpiDriver = (MibSpiDriver_Object *)arg;
1344 if(ptrMibSpiDriver != (MibSpiDriver_Object *)NULL)
1345 {
1346 ptrMibSpiReg = ptrMibSpiDriver->ptrHwCfg->ptrSpiRegBase;
1348 /* Handles the TG Complete Interrupt */
1349 intVector = ptrMibSpiReg->TGINTFLAG;
1350 intVector = intVector >> 16U;
1351 for(group = 0U ; group < MIBSPI_SLAVE_MAX; group++)
1352 {
1353 if(intVector & (0x1U << group))
1354 {
1355 ptrMibSpiDriver->hwStats.TGComplete[group]++;
1356 ptrMibSpiReg->TGINTFLAG = (uint32_t)0x10000U << group;
1358 #ifdef SPI_MULT_ICOUNT_SUPPORT
1359 /* All transfer done ? - check icount status */
1360 if((ptrMibSpiReg->DMACTRL[group] & 0x3FU) != 0)
1361 {
1362 MIBSPI_transferGroupEnable(ptrMibSpiReg, group);
1364 }
1365 #endif
1366 }
1367 }
1369 /* Found out the interrupt source and increment the stats count */
1370 intVector = ptrMibSpiReg->SPIFLG;
1371 if (intVector & 0x1U)
1372 {
1373 ptrMibSpiDriver->hwStats.dlenErr++;
1374 }
1375 if (intVector & 0x2U)
1376 {
1377 ptrMibSpiDriver->hwStats.timeout++;
1378 }
1379 if (intVector & 0x4U)
1380 {
1381 ptrMibSpiDriver->hwStats.parErr++;
1382 }
1383 if (intVector & 0x8U)
1384 {
1385 /* Master only interrupt */
1386 ptrMibSpiDriver->hwStats.desync++;
1387 }
1388 if (intVector & 0x10U)
1389 {
1390 /* Master only interrupt */
1391 ptrMibSpiDriver->hwStats.bitErr++;
1392 }
1393 if (intVector & 0x40U)
1394 {
1395 /* Master only interrupt */
1396 ptrMibSpiDriver->hwStats.rxOvrnErr++;
1397 }
1398 if (intVector & 0x100U)
1399 {
1400 /* Master only interrupt */
1401 ptrMibSpiDriver->hwStats.rxFull++;
1402 }
1403 if (intVector & 0x200U)
1404 {
1405 /* Master only interrupt */
1406 ptrMibSpiDriver->hwStats.txEmpty++;
1407 }
1409 ptrMibSpiReg->SPIFLG = intVector;
1410 }
1412 return;
1413 }
1415 /**
1416 * @b Description
1417 * @n
1418 * This function takes source and destination address and invoke MibSPI to transfer it over DMA/CPU
1419 *
1420 * @param[in] ptrMibSpiDriver MibSpi driver handle
1421 * @param[in] srcData Input buffer pointer to send the Data from
1422 * @param[in] dstData Output buffer pointer to get the Data
1423 * @param[in] dataElemSize Data Elements size
1424 * @param[in] group MibSPI transfer group used for this transfer
1425 *
1426 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
1427 *
1428 * @retval Successful =0
1429 * Failed <0
1430 */
1431 static void MIBSPI_dataTransfer
1432 (
1433 MibSpiDriver_Object * ptrMibSpiDriver,
1434 uint8_t *srcData,
1435 uint8_t *dstData,
1436 uint16_t dataElemSize,
1437 uint8_t group
1438 )
1439 {
1440 MibSpi_HwCfg const *ptrHwCfg;
1441 CSL_mss_spiRegs *ptrMibSpiReg;
1442 uint8_t ramOffset = 0U;
1443 uint16_t bufId = 0U;
1444 uint8_t iCount = 0U;
1446 /* Get MibSpi driver hardware config */
1447 ptrHwCfg = ptrMibSpiDriver->ptrHwCfg;
1449 /* Get MibSpi Register & Ram Base address */
1450 ptrMibSpiReg = ptrHwCfg->ptrSpiRegBase;
1452 /* Put SPI in active mode */
1453 MIBSPI_SPIEnable(ptrMibSpiReg);
1455 /* Find out bufId and RAM offset */
1456 if(ptrMibSpiDriver->params.mode == MIBSPI_SLAVE)
1457 {
1458 ramOffset = 0U;
1460 /* Find out iCount and bufid */
1461 if (dataElemSize > MIBSPI_RAM_MAX_ELEM)
1462 {
1463 /* (iCount + 1) transfer of size MIBSPI_RAM_MAX_ELEM */
1464 iCount = (uint8_t)(dataElemSize / MIBSPI_RAM_MAX_ELEM - 1U);
1465 bufId = (uint16_t)(MIBSPI_RAM_MAX_ELEM -1U);
1466 }
1467 else
1468 {
1469 /* One transfer of dataElemSize */
1470 iCount = (uint8_t)0U;
1471 bufId = (uint16_t)(dataElemSize -1U);
1472 }
1473 }
1474 else
1475 {
1476 uint8_t ramLen = 0;
1478 Mibspi_assert(group < MIBSPI_UTILS_ARRAYSIZE(ptrMibSpiDriver->rambufStart));
1479 ramOffset = ptrMibSpiDriver->rambufStart[group];
1480 ramLen = ptrMibSpiDriver->params.u.masterParams.slaveProf[group].ramBufLen;
1482 /* Find out iCound and bufid */
1483 if (dataElemSize > ramLen)
1484 {
1485 /* (iCount + 1) transfer of size ramLen */
1486 iCount = (uint8_t)(dataElemSize / ramLen - 1U);
1487 bufId = (uint16_t)ramOffset + (uint16_t)ramLen -(uint16_t)1U;
1488 }
1489 else
1490 {
1491 /* One transfer of dataElemSize */
1492 iCount = 0;
1493 bufId = (uint16_t)ramOffset + dataElemSize - (uint16_t)1U;
1494 }
1495 }
1497 /* Initialize transfer group start offset */
1498 MIBSPI_transferSetPStart(ptrMibSpiReg, group, ramOffset);
1500 /* This is only needed for XWR16xx/XWR18xx/XWR68xx device */
1501 MIBSPI_transferSetPStart(ptrMibSpiReg, (uint8_t)(group + 1U), (uint8_t)(bufId + 1U));
1503 /* Initialize transfer groups end pointer */
1504 CSL_FINS(ptrMibSpiReg->LTGPEND,SPI_LTGPEND_LPEND, (uint32_t)bufId);
1506 #ifdef MIBSPI_DMA_ENABLE
1507 /* Configure DMA in the following 3 cases
1508 Case 1: SrcData=NULL, DstData!=NULL => Read data from SPI with dummy write
1509 Case 2: SrcData!=NULL, DstData=NULL => Write data to SPI with dummy read
1510 Case 3: SrcData!=NULL, DstData!=NULL => duplex Read/Write
1511 */
1512 if(ptrMibSpiDriver->params.dmaEnable == (uint8_t)1U)
1513 {
1514 MibSpi_dmaXferInfo_t dmaXferInfo;
1515 uint32_t txRAMAddr;
1516 uint32_t rxRAMAddr;
1517 CSL_mibspiRam *ptrMibSpiRam;
1519 /* Disable TG complete interrupt */
1520 MIBSPI_disableGroupInterrupt(ptrMibSpiReg, group);
1522 /* Disable SPI DMA */
1523 MIBSPI_dmaCtrlGroupDisable(ptrMibSpiReg, group);
1526 ptrMibSpiRam = ptrHwCfg->ptrMibSpiRam;
1527 /* Get MibSPI RAM address */
1528 txRAMAddr = (uint32_t)(&(ptrMibSpiRam->tx[ramOffset]));
1529 rxRAMAddr = (uint32_t)(&(ptrMibSpiRam->rx[ramOffset]));
1532 /* Case 1: SrcData=NULL, DstData!=NULL => Read data from SPI with dummy write */
1533 dmaXferInfo.dmaReqLine = group;
1534 if (srcData != NULL)
1535 {
1536 dmaXferInfo.tx.saddr = MibspiUtils_virtToPhy(srcData);
1537 }
1538 else
1539 {
1540 dmaXferInfo.tx.saddr = NULL;
1541 }
1542 dmaXferInfo.tx.daddr = MibspiUtils_virtToPhy((const void *)txRAMAddr);
1543 dmaXferInfo.rx.saddr = MibspiUtils_virtToPhy((const void *)rxRAMAddr);
1544 if (dstData != NULL)
1545 {
1546 dmaXferInfo.rx.daddr = MibspiUtils_virtToPhy(dstData);
1547 }
1548 else
1549 {
1550 dmaXferInfo.rx.daddr = NULL;
1551 }
1552 if(ptrMibSpiDriver->params.dataSize == 8U)
1553 {
1554 dmaXferInfo.size.elemSize = 1;
1555 }
1556 else
1557 {
1558 dmaXferInfo.size.elemSize = 2;
1559 }
1560 dmaXferInfo.size.elemCnt = bufId + 1U;
1561 dmaXferInfo.size.frameCnt = iCount + 1U;
1562 Mibspi_assert(MIBSPI_dmaTransfer(ptrMibSpiDriver->mibspiHandle, &dmaXferInfo) == MIBSPI_STATUS_SUCCESS);;
1564 /* Configuring the mibspi dmaCtrl for the channel */
1565 MIBSPI_dmaCtrlGroupConfig(ptrMibSpiReg, bufId, iCount, group);
1567 /* Setup TG interrupt */
1568 MIBSPI_enableGroupInterrupt(ptrMibSpiReg, group, MIBSPI_INT_LEVEL);
1570 if ((CSL_FEXT(ptrMibSpiReg->IOLPBKTSTCR,SPI_IOLPBKTSTCR_LPBKTYPE) == MIBSPI_LOOPBK_ANALOG)
1571 &&
1572 (CSL_FEXT(ptrMibSpiReg->SPIGCR1,SPI_SPIGCR1_MASTER) == CSL_SPI_SPIGCR1_MASTER_SLAVE))
1573 {
1574 CSL_FINS(ptrMibSpiReg->IOLPBKTSTCR,SPI_IOLPBKTSTCR_IOLPBKTSTENA, 0xAU);
1575 }
1577 Mibspi_assert(MIBSPI_dmaStartTransfer(ptrMibSpiDriver->mibspiHandle, group) == MIBSPI_STATUS_SUCCESS);
1579 MIBSPI_dmaCtrlGroupStart(ptrMibSpiReg, group, MIBSPI_DMACTRL_CH_BOTH);
1581 /* Start TG group transfer */
1582 MIBSPI_transferGroupEnable(ptrMibSpiReg, group);
1585 }
1586 else
1587 #endif
1588 {
1589 uint32_t index;
1590 uint16_t size;
1592 size = (uint32_t)bufId + 1U - (uint32_t)ramOffset;
1594 for(index = 0; index <= iCount; index++)
1595 {
1596 /* Read data with dummy write through CPU mode */
1597 if ((srcData == (uint8_t *)NULL) && (dstData != (uint8_t *)NULL))
1598 {
1599 MIBSPI_transferGroupEnable(ptrHwCfg->ptrSpiRegBase, group);
1601 while(MIBSPI_checkTGComplete(ptrMibSpiReg, group) == 0U)
1602 {
1603 }
1605 /* Read data from local buffer to MibSPI Rx RAM */
1606 MIBSPI_readDataRAM(ptrMibSpiDriver, group, (uint16_t *)dstData, size);
1608 }
1609 else if( (srcData != (uint8_t *)NULL) && (dstData == (uint8_t *)NULL))
1610 {
1611 /* Write data from MibSPI Rx RAM to local buffer */
1612 MIBSPI_writeDataRAM(ptrMibSpiDriver, group, (uint16_t *)srcData, size);
1614 MIBSPI_transferGroupEnable(ptrHwCfg->ptrSpiRegBase, group);
1616 while(MIBSPI_checkTGComplete(ptrMibSpiReg, group) == 0U)
1617 {
1618 }
1619 /* Read data from local buffer to MibSPI Rx RAM */
1620 MIBSPI_readDataRAM(ptrMibSpiDriver, group, (uint16_t *)NULL, size);
1622 }
1623 else
1624 {
1625 /* Write data from local buffer to MibSPI Tx RAM */
1626 MIBSPI_writeDataRAM(ptrMibSpiDriver, group, (uint16_t *)srcData, size);
1628 MIBSPI_transferGroupEnable(ptrHwCfg->ptrSpiRegBase, group);
1630 /* Wait for the transfer to complete */
1631 while(MIBSPI_checkTGComplete(ptrMibSpiReg, group) == 0U)
1632 {
1633 }
1635 /* Read the data from RX RAM */
1636 MIBSPI_readDataRAM(ptrMibSpiDriver, group, (uint16_t *)dstData, size);
1638 }
1640 srcData = (srcData == (uint8_t *)NULL)? (uint8_t *)NULL : (uint8_t *)(srcData + size * ptrMibSpiDriver->params.dataSize / 8U);
1641 dstData = (dstData == (uint8_t *)NULL)? (uint8_t *)NULL : (uint8_t *)(dstData + size * ptrMibSpiDriver->params.dataSize / 8U);
1643 /* Transfer finished, unblock the thread */
1644 SemaphoreP_post(ptrMibSpiDriver->transferCompleteSem);
1645 }
1646 }
1648 return;
1649 }
1651 /**
1652 * @b Description
1653 * @n
1654 * SPI interface funtion to open SPI device.
1655 *
1656 * @param[in] ptrMibSpiDriver MibSpi driver handle
1657 * @param[in] ptrHwCfg SPI device Hardware configuration
1658 * @param[in] params SPI device configuration parameters
1659 *
1660 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
1661 *
1662 * @retval Successful =0
1663 * Failed <0
1664 */
1665 static int32_t MIBSPI_openSlaveMode(MibSpiDriver_Object *ptrMibSpiDriver, MibSpi_HwCfg* ptrHwCfg, const MIBSPI_Params *params)
1666 {
1667 int32_t retVal = 0;
1669 /* Initializing mibspi as a SPI slave */
1670 MIBSPI_initSlave(ptrHwCfg, params);
1672 if(params->dmaEnable)
1673 {
1674 #ifdef MIBSPI_DMA_ENABLE
1676 retVal = MIBSPI_dmaConfig(ptrMibSpiDriver->mibspiHandle, MIBSPI_SLAVEMODE_TRANS_GROUP);
1677 if(retVal < 0)
1678 {
1679 retVal = MIBSPI_STATUS_ERROR;
1680 goto exit;
1681 }
1682 #else
1683 retVal = MIBSPI_STATUS_ERROR;
1684 goto exit;
1685 #endif
1686 }
1688 /* Save driver info for Slave mode */
1689 ptrMibSpiDriver->rambufStart [MIBSPI_SLAVEMODE_TRANS_GROUP] = 0U;
1690 ptrMibSpiDriver->rambufEnd [MIBSPI_SLAVEMODE_TRANS_GROUP] = MIBSPI_RAM_MAX_ELEM;
1692 exit:
1693 return (retVal);
1694 }
1696 /**
1697 * @b Description
1698 * @n
1699 * SPI interface funtion to open SPI device.
1700 *
1701 * @param[in] ptrMibSpiDriver MibSpi driver handle
1702 * @param[in] ptrHwCfg SPI device Hardware configuration
1703 * @param[in] params SPI device configuration parameters
1704 *
1705 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
1706 *
1707 * @retval Successful =0
1708 * Failed <0
1709 */
1710 static int32_t MIBSPI_openMasterMode(MibSpiDriver_Object *ptrMibSpiDriver, MibSpi_HwCfg* ptrHwCfg, const MIBSPI_Params *params)
1711 {
1712 int32_t retVal = 0;
1713 uint8_t index;
1714 uint8_t ramBufOffset = 0;
1716 /* Initializing mibspi as a SPI master */
1717 MIBSPI_initMaster(ptrHwCfg, params);
1719 /* Configure the Master clock prescaler */
1720 MIBSPI_setMasterClockRate(ptrHwCfg->ptrSpiRegBase, ptrHwCfg->clockSrcFreq, params->u.masterParams.bitRate);
1722 for(index = 0; index < params->u.masterParams.numSlaves; index++)
1723 {
1724 /***************************************
1725 ******** Save RAM offset information *******
1726 **************************************/
1727 ptrMibSpiDriver->rambufStart[index] = ramBufOffset;
1728 ptrMibSpiDriver->rambufEnd[index] = ramBufOffset + params->u.masterParams.slaveProf[index].ramBufLen;
1729 ramBufOffset =ptrMibSpiDriver->rambufEnd[index];
1731 /***************************************
1732 ****** DMA Configuration if enabled *******
1733 **************************************/
1734 #ifdef MIBSPI_DMA_ENABLE
1735 if(params->dmaEnable)
1736 {
1737 retVal = MIBSPI_dmaConfig(ptrMibSpiDriver->mibspiHandle, index);
1739 if (retVal != MIBSPI_STATUS_SUCCESS)
1740 {
1741 break;
1742 }
1743 }
1744 #endif
1746 }
1748 return (retVal);
1749 }
1751 /**************************************************************************
1752 ************************* MibSPI Exported Driver Functions *********************
1753 **************************************************************************/
1755 /**
1756 * @b Description
1757 * @n
1758 * SPI interface funtion to open SPI device.
1759 *
1760 * @param[in] handle SPI device handle
1761 * @param[in] params SPI device configuration parameters
1762 *
1763 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
1764 *
1765 * @retval SPI device handle.
1766 */
1767 MIBSPI_Handle MIBSPI_openCore(MIBSPI_Handle handle, const MIBSPI_Params *params)
1768 {
1769 MIBSPI_Config* ptrSPIConfig;
1770 MibSpi_HwCfg* ptrHwCfg;
1771 SemaphoreP_Params semParams;
1772 MIBSPI_Handle retHandle = (MIBSPI_Handle)NULL;
1773 MibSpiDriver_Object* ptrMibSpiDriver = NULL;
1774 int32_t retVal = MIBSPI_STATUS_SUCCESS;
1775 OsalRegisterIntrParams_t interruptRegParams;
1777 /* Get the SPI driver Configuration: */
1778 ptrSPIConfig = (MIBSPI_Config*)handle;
1780 /* Get the hardware configuration: */
1781 ptrHwCfg = (MibSpi_HwCfg*)ptrSPIConfig->hwAttrs;
1783 /* Validate hardware configuration */
1784 Mibspi_assert(ptrHwCfg != NULL);
1785 Mibspi_assert(ptrHwCfg->ptrSpiRegBase != NULL);
1786 Mibspi_assert(ptrHwCfg->ptrMibSpiRam != NULL);
1788 #ifdef SPI_PARAMS_CHECK
1789 /* Validate params for SPI driver */
1790 retVal = MIBSPI_validateParams(params);
1791 MIBSPITRACE_ERROR_IF((retVal < 0), "SPI Driver (%p) failed params validation\n", ptrHwCfg->ptrSpiRegBase);
1792 if(retVal < 0)
1793 {
1794 /* Error: SPI Driver found incorrect parameters. */
1795 goto exit;
1796 }
1797 else
1798 #endif
1799 {
1800 /* Ensure that the driver is NOT being used: */
1801 Mibspi_assert (ptrSPIConfig->object != NULL);
1802 ptrMibSpiDriver = (MibSpiDriver_Object *)ptrSPIConfig->object;
1804 /* Check instance was not previously opened */
1805 if (ptrMibSpiDriver->mibspiHandle == NULL)
1806 {
1807 /* Initialize the memory: */
1808 memset ((void *)ptrMibSpiDriver, 0, sizeof(MibSpiDriver_Object));
1810 /* Save parameters and hardware configurations */
1811 ptrMibSpiDriver->params = *params;
1813 /* Save the Driver handle and Hw config */
1814 ptrMibSpiDriver->ptrHwCfg = ptrHwCfg;
1815 MIBSPI_validateIPVersionInfo(ptrHwCfg);
1816 ptrMibSpiDriver->mibspiHandle = handle;
1817 ptrMibSpiDriver->txScratchBuffer = ptrMibSpiDriver->params.txDummyValue;
1819 MIBSPI_resetTransactionState(&ptrMibSpiDriver->transactionState);
1820 /* Call open function for the MibSPI operating mode */
1821 if(params->mode == MIBSPI_SLAVE)
1822 {
1823 retVal = MIBSPI_openSlaveMode(ptrMibSpiDriver, ptrHwCfg, params);
1824 }
1825 else
1826 {
1827 retVal = MIBSPI_openMasterMode(ptrMibSpiDriver, ptrHwCfg, params);
1828 }
1829 if(retVal < 0)
1830 {
1831 goto exit;
1832 }
1834 /* Create a binary semaphore which is used to handle the Blocking operation. */
1835 SemaphoreP_Params_init(&semParams);
1836 semParams.mode = SemaphoreP_Mode_BINARY;
1837 ptrMibSpiDriver->transferCompleteSem = SemaphoreP_create(0U, &semParams);
1839 /* Register SPI Interrupt handling ISR */
1840 /* Initialize with defaults */
1841 Osal_RegisterInterrupt_initParams(&interruptRegParams);
1842 /* Populate the interrupt parameters */
1843 interruptRegParams.corepacConfig.arg=(uintptr_t)ptrMibSpiDriver;
1844 interruptRegParams.corepacConfig.name=(char *)"MibSpiInt";
1845 interruptRegParams.corepacConfig.isrRoutine=MIBSPI_ISR;
1846 #if defined(_TMS320C6X)
1847 interruptRegParams.corepacConfig.corepacEventNum=(int32_t)ptrHwCfg->interrupt1Num; /* Event going in to CPU */
1848 interruptRegParams.corepacConfig.intVecNum = OSAL_REGINT_INTVEC_EVENT_COMBINER; /* Host Interrupt vector */
1849 #else
1850 interruptRegParams.corepacConfig.priority = 0x1U;
1851 interruptRegParams.corepacConfig.intVecNum=(int32_t)ptrHwCfg->interrupt1Num; /* Host Interrupt vector */
1852 interruptRegParams.corepacConfig.corepacEventNum = (int32_t)ptrHwCfg->interrupt1Num;
1853 #endif
1854 /* Register interrupts */
1855 Osal_RegisterInterrupt(&interruptRegParams, &ptrMibSpiDriver->hwiHandle);
1857 if (ptrMibSpiDriver->hwiHandle == NULL)
1858 {
1859 retVal = MIBSPI_STATUS_ERROR;
1860 }
1862 if (retVal == MIBSPI_STATUS_SUCCESS)
1863 {
1864 Osal_EnableInterrupt(interruptRegParams.corepacConfig.corepacEventNum, interruptRegParams.corepacConfig.intVecNum);
1866 /* Setup the return handle: */
1867 retHandle = handle;
1868 }
1869 }
1870 else
1871 {
1872 retVal = MIBSPI_STATUS_ERROR;
1873 }
1874 }
1875 exit:
1876 if((retVal < 0) && (ptrMibSpiDriver != NULL) )
1877 {
1878 /* Cleanup in case of error */
1879 if(ptrMibSpiDriver->hwiHandle)
1880 {
1881 Osal_DeleteInterrupt(ptrMibSpiDriver->hwiHandle, ptrMibSpiDriver->ptrHwCfg->interrupt1Num);
1882 }
1883 }
1885 return (retHandle);
1886 }
1888 /**
1889 * @b Description
1890 * @n
1891 * SPI interface funtion to close SPI device.
1892 *
1893 * @param[in] handle SPI device handle
1894 *
1895 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
1896 *
1897 * @retval None.
1898 */
1899 void MIBSPI_closeCore(MIBSPI_Handle handle)
1900 {
1901 MibSpiDriver_Object* ptrMibSpiDriver;
1902 CSL_mss_spiRegs *ptrMibSpiReg;
1904 /* Sanity check handle */
1905 Mibspi_assert(handle != NULL);
1907 /* Get the Object from SPI Handle */
1908 ptrMibSpiDriver = (MibSpiDriver_Object *)handle->object;
1910 /* Sanity check driver handle */
1911 if(ptrMibSpiDriver != (MibSpiDriver_Object *)NULL)
1912 {
1913 /* Get the Register base address from SPI Handle */
1914 ptrMibSpiReg = ptrMibSpiDriver->ptrHwCfg->ptrSpiRegBase;
1916 Mibspi_assert(ptrMibSpiDriver->transactionState.transaction == NULL);
1918 #ifdef MIBSPI_DMA_ENABLE
1919 if(ptrMibSpiDriver->params.dmaEnable)
1920 {
1922 if (ptrMibSpiDriver->params.mode == MIBSPI_SLAVE)
1923 {
1924 MIBSPI_dmaFreeChannel(ptrMibSpiDriver->mibspiHandle, MIBSPI_SLAVEMODE_TRANS_GROUP);
1925 }
1926 else
1927 {
1928 uint32_t index;
1930 for (index = 0; index < ptrMibSpiDriver->params.u.masterParams.numSlaves; index++)
1931 {
1932 MIBSPI_dmaFreeChannel(ptrMibSpiDriver->mibspiHandle, index);
1933 }
1934 }
1935 }
1936 #endif
1938 /* Does the SPI Driver in Blocking mode? */
1939 if (ptrMibSpiDriver->transferCompleteSem)
1940 {
1941 /* Delete the semaphore */
1942 SemaphoreP_delete (ptrMibSpiDriver->transferCompleteSem);
1943 }
1945 /* Disable MibSPI */
1946 MIBSPI_setResetMode(ptrMibSpiReg, true);
1948 /* Delete Hwi */
1949 if(ptrMibSpiDriver->hwiHandle)
1950 {
1953 Osal_DeleteInterrupt(ptrMibSpiDriver->hwiHandle, ptrMibSpiDriver->ptrHwCfg->interrupt1Num);
1954 }
1955 memset(ptrMibSpiDriver, 0, sizeof(*ptrMibSpiDriver));
1957 }
1958 }
1960 /**
1961 * @b Description
1962 * @n
1963 * SPI interface funtion to send command to SPI driver.
1964 *
1965 * @param[in] handle SPI device handle
1966 * @param[in] cmd Command to SPI device
1967 * @param[in] arg Command Argument to SPI device
1968 *
1969 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
1970 *
1971 * @retval Status of SPI device command.
1972 */
1973 int32_t MIBSPI_controlCore(MIBSPI_Handle handle, uint32_t cmd, const void *arg)
1974 {
1975 MibSpiDriver_Object *ptrMibSpiDriver;
1976 CSL_mss_spiRegs *ptrMibSpiReg;
1977 int32_t status = MIBSPI_STATUS_SUCCESS;
1978 MibSpi_LoopBackType loopbacktype;
1980 /* Sanity check params */
1981 if( (handle == NULL) || (arg == NULL))
1982 {
1983 status = MIBSPI_STATUS_ERROR;
1984 }
1985 else
1986 {
1987 /* Get the Object from SPI Handle */
1988 ptrMibSpiDriver = (typeof (ptrMibSpiDriver))handle->object;
1990 /* Get the Register base address from SPI Handle */
1991 ptrMibSpiReg = ptrMibSpiDriver->ptrHwCfg->ptrSpiRegBase;
1993 switch (cmd)
1994 {
1995 case MIBSPI_CMD_LOOPBACK_ENABLE:
1996 {
1997 loopbacktype = *(MibSpi_LoopBackType *)arg;
1999 /* Sanity check the input parameters */
2000 if ((loopbacktype == MIBSPI_LOOPBK_DIGITAL) && (ptrMibSpiDriver->params.mode != MIBSPI_MASTER))
2001 {
2002 /* Loopback is not supported in Slave mode */
2003 status = MIBSPI_STATUS_ERROR;
2004 }
2005 else if ( (loopbacktype == MIBSPI_LOOPBK_DIGITAL) || (loopbacktype == MIBSPI_LOOPBK_ANALOG) )
2006 {
2007 /* Enable Loopback here in case Deice act as MibSPI Slave */
2008 MIBSPI_enableLoopback(ptrMibSpiReg, loopbacktype);
2009 status = MIBSPI_STATUS_SUCCESS;
2010 }
2011 else
2012 {
2013 /* Disable MibSPI LoopBack */
2014 MIBSPI_disableLoopback(ptrMibSpiReg);
2016 status = MIBSPI_STATUS_SUCCESS;
2017 }
2018 }
2020 break;
2022 case MIBSPI_CMD_SET_CLOCK_PHASEPOLARITY:
2023 {
2024 uint32_t frameFmt;
2025 frameFmt = *(uint32_t *)arg;
2027 /* 2 bit setting */
2028 frameFmt = frameFmt & 0x3U;
2030 /* Sanity check the input parameters */
2031 if (ptrMibSpiDriver->params.mode != MIBSPI_SLAVE)
2032 {
2033 /* Loopback is not supported in Master mode */
2034 status = MIBSPI_STATUS_ERROR;
2035 }
2036 else
2037 {
2038 MIBSPI_setClockPhasePolarity(ptrMibSpiReg, (uint8_t)frameFmt);
2039 status = MIBSPI_STATUS_SUCCESS;
2040 }
2041 }
2042 break;
2044 case MIBSPI_CMD_GET_STATS:
2045 {
2046 MIBSPI_Stats *stats;
2047 stats = (MIBSPI_Stats *)arg;
2048 status = MIBSPI_getDrvStats(handle, stats);
2049 }
2050 break;
2052 default:
2053 /* Command is not supported */
2054 status = MIBSPI_STATUS_UNDEFINEDCMD;
2055 break;
2056 }
2057 }
2058 return (status);
2059 }
2061 static void MIBSPI_initTransactionState(Mibspi_transactionState_t *transactionState, MIBSPI_Transaction *transaction)
2062 {
2063 uintptr_t key;
2065 key = HwiP_disable();
2067 transactionState->edmaCbCheck = MIBSPI_NONE_EDMA_CALLBACK_OCCURED;
2068 transactionState->transferErr = MIBSPI_XFER_ERR_NONE;
2069 transactionState->transaction = transaction;
2070 transactionState->transaction->status = MIBSPI_TRANSFER_STARTED;
2072 HwiP_restore(key);
2073 }
2075 static void MIBSPI_resetTransactionState(Mibspi_transactionState_t *transactionState)
2076 {
2077 uintptr_t key;
2079 key = HwiP_disable();
2081 transactionState->edmaCbCheck = MIBSPI_NONE_EDMA_CALLBACK_OCCURED;
2082 transactionState->transferErr = MIBSPI_XFER_ERR_NONE;
2083 transactionState->transaction = NULL;
2085 HwiP_restore(key);
2086 }
2088 /**
2089 * @b Description
2090 * @n
2091 * SPI interface funtion to initiate SPI transaction based on the transaction configuration.
2092 *
2093 * @param[in] handle SPI device handle
2094 * @param[in] transaction Transaction configuration
2095 *
2096 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
2097 *
2098 * @retval true if transaction is successful
2099 * false if transaction is failed
2100 */
2101 bool MIBSPI_transferCore(MIBSPI_Handle handle, MIBSPI_Transaction *transaction)
2102 {
2103 uintptr_t key;
2104 MibSpiDriver_Object *ptrMibSpiDriver;
2105 SemaphoreP_Status semaStatus;
2106 bool ret = false;
2107 uint16_t dataLength;
2108 int32_t status = MIBSPI_STATUS_SUCCESS;
2111 /* Get the MibSpi driver handle */
2112 ptrMibSpiDriver = (MibSpiDriver_Object *)handle->object;
2114 #ifdef SPI_PARAMS_CHECK
2115 status = MIBSPI_validateTransferParams(transaction, ptrMibSpiDriver);
2116 if (status != MIBSPI_STATUS_SUCCESS)
2117 {
2118 /* Initialiaze transaction as failed transer */
2119 transaction->status = MIBSPI_TRANSFER_FAILED;
2120 ret = false;
2122 }
2123 #endif
2124 if (status == MIBSPI_STATUS_SUCCESS)
2125 {
2126 if(ptrMibSpiDriver->params.dataSize == 16U)
2127 {
2128 /* MIBSPI reads in 2 bytes format */
2129 dataLength = (uint16_t)transaction->count >> 1U;
2130 }
2131 else
2132 {
2133 dataLength = transaction->count;
2134 }
2136 MIBSPI_initTransactionState(&ptrMibSpiDriver->transactionState, transaction);
2138 #ifndef SPI_MULT_ICOUNT_SUPPORT
2139 if(ptrMibSpiDriver->params.mode == MIBSPI_SLAVE)
2140 {
2141 MIBSPI_dataTransfer(ptrMibSpiDriver, transaction->txBuf, transaction->rxBuf, dataLength, MIBSPI_SLAVEMODE_TRANS_GROUP);
2142 }
2143 else
2144 {
2145 MIBSPI_dataTransfer(ptrMibSpiDriver, transaction->txBuf, transaction->rxBuf, dataLength, transaction->slaveIndex);
2146 }
2148 if (ptrMibSpiDriver->params.transferMode == MIBSPI_MODE_BLOCKING)
2149 {
2150 semaStatus = SemaphoreP_pend(ptrMibSpiDriver->transferCompleteSem, ptrMibSpiDriver->params.transferTimeout);
2151 if(semaStatus != SemaphoreP_OK)
2152 {
2153 /* Populate status code */
2154 transaction->status = MIBSPI_TRANSFER_TIMEOUT;
2155 ret = false;
2156 }
2157 else
2158 {
2159 /* Populate status code */
2160 transaction->status = MIBSPI_TRANSFER_COMPLETED;
2161 ret = true;
2162 }
2163 }
2164 else
2165 {
2166 /* Execution should not reach here */
2167 transaction->status = MIBSPI_TRANSFER_FAILED;
2168 ret = false;
2169 }
2170 #else
2171 do {
2172 uint32_t ramSize;
2173 uint16_t remainSize;
2174 uint16_t dataSizeInBytes = 2U;
2176 if(ptrMibSpiDriver->params.dataSize == 16U)
2177 {
2178 dataSizeInBytes = 2U;
2179 }
2180 else
2181 {
2182 dataSizeInBytes = 1U;
2183 }
2185 /* Find out rambuf size */
2186 if(ptrMibSpiDriver->params.mode == MIBSPI_SLAVE)
2187 {
2188 ramSize = MIBSPI_RAM_MAX_ELEM;
2189 }
2190 else
2191 {
2192 ramSize = ptrMibSpiDriver->params.u.masterParams.slaveProf[transaction->slaveIndex].ramBufLen;
2193 }
2195 /*
2196 * If dataLength is bigger than ramSize, there will be two data transfers:
2197 * 1. multiple of ramSize
2198 * 2. remaining data after multiple of ramsize
2199 * If dataLength is smaller or equal to ramSize, there will be one data transfer
2200 */
2201 remainSize = (dataLength > ramSize) ? dataLength%ramSize : 0U;
2203 if(remainSize > 0U)
2204 {
2205 /* Size of the first transfer */
2206 dataLength -= remainSize;
2207 }
2209 if(ptrMibSpiDriver->params.mode == MIBSPI_SLAVE)
2210 {
2211 MIBSPI_dataTransfer(ptrMibSpiDriver, (uint8_t *)transaction->txBuf, (uint8_t *)transaction->rxBuf, dataLength, MIBSPI_SLAVEMODE_TRANS_GROUP);
2212 }
2213 else
2214 {
2215 MIBSPI_dataTransfer(ptrMibSpiDriver, (uint8_t *)transaction->txBuf, (uint8_t *)transaction->rxBuf, dataLength, transaction->slaveIndex);
2216 }
2218 if (ptrMibSpiDriver->params.transferMode == MIBSPI_MODE_BLOCKING)
2219 {
2220 semaStatus = SemaphoreP_pend(ptrMibSpiDriver->transferCompleteSem, ptrMibSpiDriver->params.transferTimeout);
2221 if(semaStatus != SemaphoreP_OK)
2222 {
2223 /* Populate status code */
2224 transaction->status = MIBSPI_TRANSFER_TIMEOUT;
2225 ret = false;
2226 remainSize = 0;
2227 }
2228 else
2229 {
2230 /* Populate status code */
2231 transaction->status = MIBSPI_TRANSFER_COMPLETED;
2232 ret = true;
2233 }
2234 }
2235 else
2236 {
2237 /* Execution should not reach here */
2238 transaction->status = MIBSPI_TRANSFER_FAILED;
2239 ret = false;
2240 remainSize = 0;
2241 }
2243 /* Check if transfer finished */
2244 if(remainSize == 0)
2245 {
2246 break;
2247 }
2249 /* Change buffer pointer and data size for the second transfer */
2250 transaction->txBuf = (void *)((transaction->txBuf == NULL)? NULL: (uint8_t *)transaction->txBuf + dataLength * dataSizeInBytes);
2251 transaction->rxBuf = (void *)((transaction->rxBuf == NULL)? NULL: (uint8_t *)transaction->rxBuf + dataLength * dataSizeInBytes);
2252 dataLength = remainSize;
2254 /* Transfer the remaining size */
2255 if(ptrMibSpiDriver->params.mode == MIBSPI_SLAVE)
2256 {
2257 MIBSPI_dataTransfer(ptrMibSpiDriver, (uint8_t *)transaction->txBuf, (uint8_t *)transaction->rxBuf, dataLength, MIBSPI_SLAVEMODE_TRANS_GROUP);
2258 }
2259 else
2260 {
2261 MIBSPI_dataTransfer(ptrMibSpiDriver, (uint8_t *)transaction->txBuf, (uint8_t *)transaction->rxBuf, dataLength, transaction->slaveIndex);
2262 }
2264 if (ptrMibSpiDriver->params.transferMode == MIBSPI_MODE_BLOCKING)
2265 {
2266 semaStatus = SemaphoreP_pend(ptrMibSpiDriver->transferCompleteSem, ptrMibSpiDriver->params.transferTimeout);
2267 if(semaStatus != SemaphoreP_OK)
2268 {
2269 /* Populate status code */
2270 transaction->status = MIBSPI_TRANSFER_TIMEOUT;
2271 ret = false;
2272 }
2273 else
2274 {
2275 /* Populate status code */
2276 transaction->status = MIBSPI_TRANSFER_COMPLETED;
2277 ret = true;
2278 }
2279 }
2280 else
2281 {
2282 /* Execution should not reach here */
2283 transaction->status = MIBSPI_TRANSFER_FAILED;
2284 ret = false;
2285 }
2286 }while(0);
2288 #endif
2289 }
2290 /* Disable transfer group */
2291 MIBSPI_transferGroupDisable((ptrMibSpiDriver->ptrHwCfg->ptrSpiRegBase), transaction->slaveIndex);
2293 /* Clear transaction handle */
2294 key = HwiP_disable();
2296 ptrMibSpiDriver->transactionState.transaction = NULL;
2298 HwiP_restore(key);
2299 return ret;
2300 }
2302 /**
2303 * @b Description
2304 * @n
2305 * SPI interface funtion to cancell an ongoing transaction.
2306 *
2307 * @param[in] handle SPI device handle
2308 *
2309 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
2310 *
2311 * @retval None
2312 */
2313 void MIBSPI_transferCancelCore(MIBSPI_Handle handle)
2314 {
2315 /* Stop Transfer is in progress */
2316 MIBSPITRACE_ERROR("SPI:(%p) Error! Stop Transaction is not supported\n", handle);
2318 /* This API is not supported, hence throw an assertion */
2319 Mibspi_assert(0);
2321 return;
2322 }
2325 /**
2326 * @b Description
2327 * @n
2328 * Get SPI driver internal stats
2329 *
2330 * @param[in] handle SPI device handle
2331 * @param[in] ptrStats pointer to SPI driver stats structure
2332 *
2333 * \ingroup SPI_DRIVER_INTERNAL_FUNCTION
2334 *
2335 * @retval None
2336 */
2337 static int32_t MIBSPI_getDrvStats(MIBSPI_Handle handle, MIBSPI_Stats *ptrStats)
2338 {
2339 MibSpiDriver_Object *ptrMibSpiDriver;
2340 int32_t retCode = 0;
2342 /* Validate input parameters */
2343 if((handle == NULL) || (ptrStats == NULL))
2344 {
2345 retCode = MIBSPI_STATUS_ERROR;
2346 }
2347 else
2348 {
2349 /* Get the MibSpi driver handle */
2350 ptrMibSpiDriver = (MibSpiDriver_Object *)handle->object;
2352 ptrStats->dlenErr = ptrMibSpiDriver->hwStats.dlenErr;
2353 ptrStats->timeout = ptrMibSpiDriver->hwStats.timeout;
2354 ptrStats->parErr = ptrMibSpiDriver->hwStats.parErr;
2355 ptrStats->desync = ptrMibSpiDriver->hwStats.desync;
2356 ptrStats->bitErr = ptrMibSpiDriver->hwStats.bitErr;
2357 ptrStats->rxOvrnErr = ptrMibSpiDriver->hwStats.rxOvrnErr;
2358 }
2360 return retCode;
2361 }
2365 void MIBSPI_dmaDoneCb(MIBSPI_Handle mibspiHandle)
2366 {
2367 MibSpiDriver_Object* ptrMibSpiDriver = NULL;
2368 MIBSPI_Config* ptrSPIConfig;
2369 CSL_mss_spiRegs *ptrMibSpiReg;
2371 /* Get the SPI driver Configuration: */
2372 ptrSPIConfig = (MIBSPI_Config*)mibspiHandle;
2374 ptrMibSpiDriver = (MibSpiDriver_Object*)ptrSPIConfig->object;
2376 ptrMibSpiReg = ptrMibSpiDriver->ptrHwCfg->ptrSpiRegBase;
2377 if ((CSL_FEXT(ptrMibSpiReg->IOLPBKTSTCR,SPI_IOLPBKTSTCR_LPBKTYPE) == MIBSPI_LOOPBK_ANALOG)
2378 &&
2379 (CSL_FEXT(ptrMibSpiReg->SPIGCR1,SPI_SPIGCR1_MASTER) == CSL_SPI_SPIGCR1_MASTER_SLAVE)
2380 &&
2381 (CSL_FEXT(ptrMibSpiReg->IOLPBKTSTCR,SPI_IOLPBKTSTCR_IOLPBKTSTENA) == 0xAU))
2382 {
2383 CSL_FINS(ptrMibSpiReg->IOLPBKTSTCR,SPI_IOLPBKTSTCR_IOLPBKTSTENA, 0x5U);
2384 }
2386 if ((ptrMibSpiDriver->params.transferMode == MIBSPI_MODE_BLOCKING) && (ptrMibSpiDriver->transferCompleteSem != NULL) )
2387 {
2388 /* MibSPI-RX DMA complete interrupt */
2389 SemaphoreP_post(ptrMibSpiDriver->transferCompleteSem);
2390 }
2391 else
2392 {
2393 if (ptrMibSpiDriver->transactionState.transaction != NULL)
2394 {
2395 /* Call the transfer completion callback function */
2396 if ((ptrMibSpiDriver->transactionState.transaction->status == MIBSPI_TRANSFER_STARTED) &&
2397 (ptrMibSpiDriver->transactionState.transferErr == MIBSPI_XFER_ERR_NONE))
2398 {
2399 ptrMibSpiDriver->transactionState.transaction->status = MIBSPI_TRANSFER_COMPLETED;
2400 }
2401 else
2402 {
2403 ptrMibSpiDriver->transactionState.transaction->status = MIBSPI_TRANSFER_FAILED;
2404 }
2406 ptrMibSpiDriver->params.transferCallbackFxn(mibspiHandle, ptrMibSpiDriver->transactionState.transaction);
2407 MIBSPI_resetTransactionState(&ptrMibSpiDriver->transactionState);
2408 }
2409 }
2410 }
2412 static uint32_t MIBSPI_getPhase(MIBSPI_FrameFormat frameFormat)
2413 {
2414 uint32_t phase = 0;
2416 switch (frameFormat)
2417 {
2418 case MIBSPI_POL0_PHA0: /*!< SPI mode Polarity 0 Phase 0 */
2419 case MIBSPI_POL1_PHA0: /*!< SPI mode Polarity 1 Phase 0 */
2420 phase = 0;
2421 break;
2422 case MIBSPI_POL0_PHA1: /*!< SPI mode Polarity 0 Phase 1 */
2423 case MIBSPI_POL1_PHA1: /*!< SPI mode Polarity 1 Phase 1 */
2424 phase = 1;
2425 break;
2426 default:
2427 Mibspi_assert(FALSE);
2428 }
2429 return phase;
2430 }
2432 static uint32_t MIBSPI_getPolarity(MIBSPI_FrameFormat frameFormat)
2433 {
2434 uint32_t polarity = 0;
2436 switch (frameFormat)
2437 {
2438 case MIBSPI_POL0_PHA0: /*!< SPI mode Polarity 0 Phase 0 */
2439 case MIBSPI_POL0_PHA1: /*!< SPI mode Polarity 0 Phase 1 */
2440 polarity = 0;
2441 break;
2442 case MIBSPI_POL1_PHA0: /*!< SPI mode Polarity 1 Phase 0 */
2443 case MIBSPI_POL1_PHA1: /*!< SPI mode Polarity 1 Phase 1 */
2444 polarity = 1;
2445 break;
2446 default:
2447 Mibspi_assert(FALSE);
2448 }
2449 return polarity;
2450 }
2452 static void MIBSPI_getVersionInfo(const CSL_mss_spiRegs *ptrMibSpiReg, MibSpi_VersionInfo *ver)
2453 {
2454 ver->minor = CSL_FEXT(ptrMibSpiReg->SPIREV,SPI_SPIREV_MINOR);
2455 ver->custom = CSL_FEXT(ptrMibSpiReg->SPIREV,SPI_SPIREV_CUSTOM);
2456 ver->major = CSL_FEXT(ptrMibSpiReg->SPIREV,SPI_SPIREV_MAJOR);
2457 ver->rtl = CSL_FEXT(ptrMibSpiReg->SPIREV,SPI_SPIREV_RTL);
2458 ver->functionality = CSL_FEXT(ptrMibSpiReg->SPIREV,SPI_SPIREV_FUNC);
2459 ver->scheme = CSL_FEXT(ptrMibSpiReg->SPIREV,SPI_SPIREV_SCHEME);
2461 }
2463 static void MIBSPI_validateIPVersionInfo(const MibSpi_HwCfg* ptrHwCfg)
2464 {
2465 MibSpi_VersionInfo versionInfo;
2467 MIBSPI_getVersionInfo(ptrHwCfg->ptrSpiRegBase, &versionInfo);
2468 Mibspi_assert(versionInfo.custom == ptrHwCfg->versionInfo.custom);
2469 Mibspi_assert(versionInfo.minor == ptrHwCfg->versionInfo.minor);
2470 Mibspi_assert(versionInfo.major == ptrHwCfg->versionInfo.major);
2471 Mibspi_assert(versionInfo.rtl == ptrHwCfg->versionInfo.rtl);
2472 Mibspi_assert(versionInfo.functionality == ptrHwCfg->versionInfo.functionality);
2473 Mibspi_assert(versionInfo.scheme == ptrHwCfg->versionInfo.scheme);
2474 }
2476 static void MIBSPI_enableErrorInterrupt(CSL_mss_spiRegs *ptrMibSpiReg, uint32_t enableFlag)
2477 {
2478 uint32_t regVal = ptrMibSpiReg->SPIINT0;
2480 CSL_FINS(regVal, SPI_SPIINT0_DLENERRENA, enableFlag);
2481 CSL_FINS(regVal, SPI_SPIINT0_TIMEOUTENA, enableFlag);
2482 CSL_FINS(regVal, SPI_SPIINT0_PARERRENA, enableFlag);
2483 CSL_FINS(regVal, SPI_SPIINT0_DESYNCENA, enableFlag);
2484 CSL_FINS(regVal, SPI_SPIINT0_BITERRENA, enableFlag);
2485 CSL_FINS(regVal, SPI_SPIINT0_OVRNINTENA, enableFlag);
2486 ptrMibSpiReg->SPIINT0 = regVal;
2487 }
2489 static void MIBSPI_setErrorInterruptLevel(CSL_mss_spiRegs *ptrMibSpiReg, uint32_t level)
2490 {
2491 uint32_t regVal = ptrMibSpiReg->SPILVL;
2493 CSL_FINS(regVal, SPI_SPILVL_DLENERRLVL, level);
2494 CSL_FINS(regVal, SPI_SPILVL_TIMEOUTLVL, level);
2495 CSL_FINS(regVal, SPI_SPILVL_PARERRLVL, level);
2496 CSL_FINS(regVal, SPI_SPILVL_DESYNCLVL, level);
2497 CSL_FINS(regVal, SPI_SPILVL_BITERRLVL, level);
2498 CSL_FINS(regVal, SPI_SPILVL_OVRNINTLVL, level);
2499 ptrMibSpiReg->SPILVL = regVal;
2500 }