]> rtime.felk.cvut.cz Git - arc.git/commitdiff
Moved to a fresher SPI driver from default.
authorMahil <Mahil@LT056.cpac.loc>
Wed, 7 Mar 2012 14:51:12 +0000 (15:51 +0100)
committerMahil <Mahil@LT056.cpac.loc>
Wed, 7 Mar 2012 14:51:12 +0000 (15:51 +0100)
arch/ppc/mpc55xx/drivers/Spi.c

index 7930a68dfe1286bea71991520a86a72a5e48cb16..a7017b6db32ab74be2e45bdbca18559049533216 100644 (file)
@@ -40,9 +40,9 @@
  *   - DMA and FIFO is implementations\r
  *   - Soft CS by callback\r
  *\r
- *\r
- *   Device\r
+ *   Devices\r
  *   - MPC5606S\r
+ *   - MPC5604B\r
  *\r
  * Implementation Notes:\r
  * - This driver implements SPI_LEVEL_DELIVERED = 2 but with a number\r
 //#include <stdio.h>\r
 #include "Mcu.h"\r
 #include "math.h"\r
+#if (SPI_IMPLEMENTATION==SPI_DMA)\r
 #include "Dma.h"\r
+#endif\r
 #include "Det.h"\r
 #include "isr.h"\r
 /* ----------------------------[private define]------------------------------*/\r
 #define SPIE_OK                                0\r
 #define SPIE_JOB_NOT_DONE   1\r
 \r
+#if defined(CFG_MPC5604B)\r
+#define CTAR_CNT    6\r
+#else\r
+#define CTAR_CNT    8\r
+#endif\r
+\r
 //#define SPI_IMPLEMENTATION   SPI_FIFO\r
 #define USE_DIO_CS          STD_ON\r
 \r
 #define SPI_INTERNAL_MTU    72\r
 \r
 /* The depth of the HW FIFO */\r
-#define FIFO_DEPTH                     5\r
+#define FIFO_DEPTH                     4\r
 \r
 /* Define for debug purposes, checks that SPI/DMA is ok */\r
 //#define STEP_VALIDATION              1\r
 #if defined(USE_LOCAL_RAMLOG)\r
 #define RAMLOG_STR(_x) ramlog_str(_x)\r
 #define RAMLOG_DEC(_x) ramlog_dec(_x)\r
+#define RAMLOG_HEX(_x) ramlog_hex(_x)\r
 #else\r
 #define RAMLOG_STR(_x)\r
 #define RAMLOG_DEC(_x)\r
+#define RAMLOG_HEX(_x)\r
 #endif\r
 \r
+#define SPI_ASSERT(_exp)       if( !(_exp) ) while(1) {}\r
+\r
 /* ----------------------------[private macro]-------------------------------*/\r
 \r
 #ifndef MIN\r
 #define GET_SPI_HW_PTR(_unit)  \\r
         ((volatile struct DSPI_tag *)(0xFFF90000 + 0x4000*(_unit)))\r
 \r
-#define GET_SPI_UNIT_PTR(_unit) &Spi_Unit[_unit]\r
+#define GET_SPI_UNIT_PTR(_unit) &Spi_Unit[Spi_CtrlToUnit[_unit]]\r
 \r
 #define ENABLE_EOQ_INTERRUPT(_spi_hw) _spi_hw->RSER.B.EOQF_RE = 1\r
 #define DISABLE_EOQ_INTERRUPT(_spi_hw) _spi_hw->RSER.B.EOQF_RE = 0\r
@@ -290,13 +302,15 @@ typedef struct {
     uint32          rxQueue[SPI_INTERNAL_MTU];      // Pointed to by DADDR of DMA\r
 #endif\r
        uint32          txCurrIndex;                    // current index for data when sending\r
-       uint32          channelCodes[7];                // Helper array to assign CTAR's\r
+       uint32          channelCodes[(CTAR_CNT-1)];                // Helper array to assign CTAR's\r
        Spi_StatusType status;                          // Status for this unit\r
        const Spi_JobConfigType *       currJob;         // The current job\r
        const Spi_JobType *             currJobIndexPtr; // Points array of jobs current\r
     Spi_JobType                     currJobIndex;\r
        const Spi_SequenceConfigType *  currSeqPtr;     // The Sequence\r
        Spi_CallTypeType callType;                      // 1 -  if the current job is sync. 0 - if not\r
+       volatile struct DSPI_tag *      hwPtr;\r
+       uint8                                                   hwUnit;         // 0...\r
 } Spi_UnitType;\r
 \r
 typedef struct {\r
@@ -372,42 +386,35 @@ Spi_UnitType    Spi_Unit[SPI_CONTROLLER_CNT];
 Spi_SeqUnitType Spi_SeqUnit[SPI_MAX_SEQUENCE];\r
 Spi_JobUnitType Spi_JobUnit[SPI_MAX_JOB];\r
 Spi_ChannelInfoType Spi_ChannelInfo[SPI_MAX_CHANNEL];\r
+uint8 Spi_CtrlToUnit[4];\r
 \r
 \r
 #if (SPI_IMPLEMENTATION == SPI_DMA)\r
 /* When using DMA it assumes predefined names */\r
-Spi_DmaConfigType  Spi_DmaConfig[4] = {\r
+Spi_DmaConfigType  Spi_DmaConfig[SPI_CONTROLLER_CNT] = {\r
 #if (SPI_USE_HW_UNIT_0 == STD_ON )\r
        {\r
            .RxDmaChannel = DMA_DSPI_A_RESULT_CHANNEL,\r
            .TxDmaChannel = DMA_DSPI_A_COMMAND_CHANNEL,\r
        },\r
-#else\r
-       { (Dma_ChannelType)0, (Dma_ChannelType)0 },\r
 #endif\r
 #if (SPI_USE_HW_UNIT_1 == STD_ON )\r
        {\r
            .RxDmaChannel = DMA_DSPI_B_RESULT_CHANNEL,\r
            .TxDmaChannel = DMA_DSPI_B_COMMAND_CHANNEL,\r
        },\r
-#else\r
-       { (Dma_ChannelType)0, (Dma_ChannelType)0 },\r
 #endif\r
 #if (SPI_USE_HW_UNIT_2 == STD_ON )\r
        {\r
            .RxDmaChannel = DMA_DSPI_C_RESULT_CHANNEL,\r
            .TxDmaChannel = DMA_DSPI_C_COMMAND_CHANNEL,\r
        },\r
-#else\r
-       { (Dma_ChannelType)0, (Dma_ChannelType)0 },\r
 #endif\r
 #if (SPI_USE_HW_UNIT_3 == STD_ON )\r
        {\r
            .RxDmaChannel = DMA_DSPI_D_RESULT_CHANNEL,\r
            .TxDmaChannel = DMA_DSPI_D_COMMAND_CHANNEL,\r
        }\r
-#else\r
-       { (Dma_ChannelType)0, (Dma_ChannelType)0 },\r
 #endif\r
 };\r
 #endif\r
@@ -419,10 +426,10 @@ static void Spi_WriteJob_FIFO( Spi_JobType jobIndex );
 \r
 /**\r
  * Get the buffer for a channel.\r
- *
- * @param ch
- * @param length
- * @return
+ *\r
+ * @param ch\r
+ * @param length\r
+ * @return\r
  */\r
 static Spi_DataType *spiGetRxBuf(Spi_ChannelType ch, Spi_NumberOfDataType *length ) {\r
        Spi_DataType *buf;\r
@@ -451,19 +458,19 @@ static const Spi_DataType *spiGetTxBuf(Spi_ChannelType ch, Spi_NumberOfDataType
 }\r
 #endif\r
 \r
-static void Spi_Isr(uint32);\r
+static void Spi_Isr(Spi_UnitType *uPtr );\r
 \r
 static void Spi_Isr_A(void) {\r
-       Spi_Isr(DSPI_CTRL_A);\r
+       Spi_Isr(GET_SPI_UNIT_PTR(DSPI_CTRL_A));\r
 }\r
 static void Spi_Isr_B(void) {\r
-       Spi_Isr(DSPI_CTRL_B);\r
+       Spi_Isr(GET_SPI_UNIT_PTR(DSPI_CTRL_B));\r
 }\r
 static void Spi_Isr_C(void) {\r
-       Spi_Isr(DSPI_CTRL_C);\r
+       Spi_Isr(GET_SPI_UNIT_PTR(DSPI_CTRL_C));\r
 }\r
 static void Spi_Isr_D(void) {\r
-       Spi_Isr(DSPI_CTRL_D);\r
+       Spi_Isr(GET_SPI_UNIT_PTR(DSPI_CTRL_D));\r
 }\r
 /* ----------------------------[public functions]----------------------------*/\r
 \r
@@ -485,9 +492,15 @@ static void Spi_SetJobResult(Spi_JobType Job, Spi_JobResultType result) {
        Spi_JobUnit[Job].jobResult = result;\r
 }\r
 \r
+#if 1\r
+static void Spi_SetHWUnitStatus( Spi_UnitType *uPtr, Spi_StatusType status) {\r
+       uPtr->status = status;\r
+}\r
+#else\r
 static void Spi_SetHWUnitStatus(Spi_HWUnitType HWUnit, Spi_StatusType status) {\r
-       Spi_Unit[HWUnit].status = status;\r
+       Spi_Unit[Spi_CtrlToUnit[HWUnit]].status = status;\r
 }\r
+#endif\r
 \r
 /**\r
  * Get external Ptr to device from index\r
@@ -526,7 +539,7 @@ static const Spi_SequenceConfigType *Spi_GetSeqPtrFromIndex(
  * @return Ptr to the SPI unit\r
  */\r
 static Spi_UnitType *Spi_GetUnitPtrFromIndex(uint32 unit) {\r
-       return &Spi_Unit[unit];\r
+       return &Spi_Unit[Spi_CtrlToUnit[unit]];\r
 }\r
 \r
 /**\r
@@ -634,6 +647,9 @@ static int Spi_Rx_DMA(Spi_UnitType *spiUnit) {
                if (sentTx != gotTx) {\r
                        // Something failed\r
                        DEBUG(DEBUG_LOW,"%s: Expected %d bytes. Got %d bytes\n ",MODULE_NAME,sentTx, gotTx );\r
+#if defined(STEP_VALIDATION)\r
+           SPI_ASSERT(0);\r
+#endif\r
                        return SPIE_BAD;\r
                } else {\r
                        RAMLOG_STR("Rx "); RAMLOG_DEC(gotTx); RAMLOG_STR(" Bytes\n"); DEBUG(DEBUG_LOW,"%s: Got %d bytes\n",MODULE_NAME,gotTx);\r
@@ -697,19 +713,19 @@ static int Spi_Rx_FIFO(Spi_UnitType *spiUnit) {
 \r
        if( jobUnitPtr->hwPtr->TCR.B.SPI_TCNT != jobUnitPtr->fifoSent ) {\r
 #if defined(STEP_VALIDATION)\r
-           while(1) {};\r
+           SPI_ASSERT(0);\r
 #endif\r
                return SPIE_BAD;\r
        }\r
 \r
        /*\r
         * Fill receive buffers, either EB or IB\r
-        * Example with 8-bit CMD, 16-bit ADDR and some data.\r
+        * Example with 8-bit CMD, 16-bit ADDR and some 8-bit data.\r
         *    CMD |  ADDR   |     DATA\r
         *   | 12 | 23 | 34 | 00 | 01 | 02 | 03\r
         *      1    2    3    4    5    6           BYTE CNT\r
-        *      1      2       3    4    5    6      FIFO\r
-        * With a FIFO of 5 we can see that the CMD, ADDR and almost the whole\r
+        *      1      2       3    4   (5)  (6)     FIFO\r
+        * With a FIFO of 4 we can see that the CMD, ADDR and almost the whole\r
         * DATA channel is sent.\r
         */\r
     currChannel = jobUnitPtr->channelsPtr[jobUnitPtr->currRxChIndex];\r
@@ -717,7 +733,7 @@ static int Spi_Rx_FIFO(Spi_UnitType *spiUnit) {
 \r
     if( jobUnitPtr->fifoSent != jobUnitPtr->hwPtr->SR.B.RXCTR ) {\r
 #if defined(STEP_VALIDATION)\r
-        while(1) {};\r
+        SPI_ASSERT(0);\r
 #endif\r
         return SPIE_BAD;\r
     }\r
@@ -736,7 +752,7 @@ static int Spi_Rx_FIFO(Spi_UnitType *spiUnit) {
 \r
         if( copyCnt == 0  ) {\r
 #if defined(STEP_VALIDATION)\r
-        while(1) {};\r
+        SPI_ASSERT(0);\r
 #endif\r
             return SPIE_BAD;\r
         }\r
@@ -749,6 +765,7 @@ static int Spi_Rx_FIFO(Spi_UnitType *spiUnit) {
         if( buf != NULL ) {\r
             for(i=0;i<copyCnt;i++) {\r
                 popVal = jobUnitPtr->hwPtr->POPR.B.RXDATA;\r
+                RAMLOG_STR("%");RAMLOG_HEX(popVal);\r
                 buf[jobUnitPtr->rxChCnt] = (Spi_DataType)popVal;\r
                 jobUnitPtr->rxChCnt += bInChar;\r
             }\r
@@ -756,7 +773,6 @@ static int Spi_Rx_FIFO(Spi_UnitType *spiUnit) {
             for(i=0;i<copyCnt;i++) {\r
                 popVal = jobUnitPtr->hwPtr->POPR.B.RXDATA;\r
                 jobUnitPtr->rxChCnt += bInChar;\r
-\r
             }\r
         }\r
 \r
@@ -776,12 +792,12 @@ static int Spi_Rx_FIFO(Spi_UnitType *spiUnit) {
         }\r
        }\r
 \r
+#if defined(STEP_VALIDATION)\r
        /* Check if we are done with this job */\r
     if( 0 != jobUnitPtr->hwPtr->SR.B.RXCTR ) {\r
-        while(1) {};\r
+        SPI_ASSERT(0);\r
     }\r
-\r
-\r
+#endif\r
 \r
        return rv;\r
 }\r
@@ -793,11 +809,13 @@ static int Spi_Rx_FIFO(Spi_UnitType *spiUnit) {
 /**\r
  * ISR for End of Queue interrupt\r
  *\r
+ * The interrupt handling is quite simple. Since this driver assumes\r
+ * that we are the master the EOQ interrupt is sufficient to check.\r
+ *\r
  * @param unit The HW unit it happend on\r
  */\r
-static void Spi_Isr(uint32 unit) {\r
-       volatile struct DSPI_tag *spiHw = GET_SPI_HW_PTR(unit);\r
-       Spi_UnitType *spiUnit = GET_SPI_UNIT_PTR(unit);\r
+static void Spi_Isr( Spi_UnitType *uPtr) {\r
+       volatile struct DSPI_tag *spiHw = uPtr->hwPtr;\r
        int rv;\r
 \r
        RAMLOG_STR("Spi_Isr\n");\r
@@ -818,15 +836,21 @@ static void Spi_Isr(uint32 unit) {
        }\r
 \r
 #if (SPI_IMPLEMENTATION == SPI_DMA)\r
-       while (!Dma_ChannelDone(Spi_Unit[unit].dmaRxChannel)) {\r
+       while (!Dma_ChannelDone(uPtr->dmaRxChannel)) {\r
                Spi_Global.totalNbrOfWaitRxDMA++;\r
        }\r
 #endif\r
 \r
+#if defined(STEP_VALIDATION)\r
+       /* Since EOQF clears TXRXS */\r
+       SPI_ASSERT( (spiHw->SR.B.EOQF==1) && (spiHw->SR.B.TXRXS == 0));\r
+#endif\r
+\r
        /* Halt DSPI unit until we are ready for next transfer. */\r
        spiHw->MCR.B.HALT = 1;\r
        spiHw->SR.B.EOQF = 1;\r
 \r
+\r
        Spi_Global.totalNbrOfTranfers++;\r
 \r
        // Disable EOQ interrupts\r
@@ -843,26 +867,26 @@ static void Spi_Isr(uint32 unit) {
 \r
        // Update external buffers\r
 #if (SPI_IMPLEMENTATION==SPI_DMA)\r
-       rv = Spi_Rx_DMA(spiUnit);\r
+       rv = Spi_Rx_DMA(uPtr);\r
 \r
 #if (USE_DIO_CS == STD_ON)\r
-    void (*cb)(int) = Spi_JobUnit[spiUnit->currJobIndex].extDeviceCfgPtr->SpiCsCallback;\r
+    void (*cb)(int) = Spi_JobUnit[uPtr->currJobIndex].extDeviceCfgPtr->SpiCsCallback;\r
     if( cb != NULL ) {\r
         cb(0);\r
     }\r
 #endif\r
 #elif (SPI_IMPLEMENTATION==SPI_FIFO)\r
-       rv = Spi_Rx_FIFO(spiUnit);\r
+       rv = Spi_Rx_FIFO(uPtr);\r
 \r
        if( rv == SPIE_JOB_NOT_DONE ) {\r
            /* RX FIFO now empty, but the job is not done -> send more */\r
-           Spi_WriteJob_FIFO ( spiUnit->currJobIndex );\r
+           Spi_WriteJob_FIFO ( uPtr->currJobIndex );\r
                RAMLOG_STR("Spi_Isr END\n");\r
                return;\r
        }\r
 #if (USE_DIO_CS == STD_ON)\r
        else {\r
-           void (*cb)(int) = Spi_JobUnit[spiUnit->currJobIndex].extDeviceCfgPtr->SpiCsCallback;\r
+           void (*cb)(int) = Spi_JobUnit[uPtr->currJobIndex].extDeviceCfgPtr->SpiCsCallback;\r
            if( cb != NULL ) {\r
                cb(0);\r
            }\r
@@ -871,24 +895,24 @@ static void Spi_Isr(uint32 unit) {
 #endif\r
 \r
        // Call notification end\r
-       if (spiUnit->currJob->SpiJobEndNotification != NULL) {\r
-               spiUnit->currJob->SpiJobEndNotification();\r
+       if (uPtr->currJob->SpiJobEndNotification != NULL) {\r
+               uPtr->currJob->SpiJobEndNotification();\r
        }\r
 \r
        if (rv == SPIE_BAD) {\r
                // Fail both job and sequence\r
-               Spi_SetHWUnitStatus(unit, SPI_IDLE);\r
-               Spi_SetJobResult(spiUnit->currJob->SpiJobId, SPI_JOB_FAILED);\r
-               Spi_SetSequenceResult(spiUnit->currSeqPtr->SpiSequenceId,\r
+               Spi_SetHWUnitStatus(uPtr, SPI_IDLE);\r
+               Spi_SetJobResult(uPtr->currJob->SpiJobId, SPI_JOB_FAILED);\r
+               Spi_SetSequenceResult(uPtr->currSeqPtr->SpiSequenceId,\r
                                SPI_SEQ_FAILED);\r
 #if defined(STEP_VALIDATION)\r
-               while(1) {};\r
+               SPI_ASSERT(0);\r
 #endif\r
        } else {\r
                Spi_JobType nextJob;\r
 \r
                // The job is at least done..\r
-               Spi_SetJobResult(spiUnit->currJob->SpiJobId, SPI_JOB_OK);\r
+               Spi_SetJobResult(uPtr->currJob->SpiJobId, SPI_JOB_OK);\r
 \r
                // WriteNextJob should\r
                // 1. Update the JobResult to SPI_JOB_OK\r
@@ -903,21 +927,21 @@ static void Spi_Isr(uint32 unit) {
                //\r
                // So, I no clue what to use the priority thing for :(\r
 \r
-               nextJob = Spi_GetNextJob(spiUnit);\r
+               nextJob = Spi_GetNextJob(uPtr);\r
                if( nextJob != JOB_NOT_VALID ) {\r
                        Spi_JobWrite(nextJob);\r
                        RAMLOG_STR("more_jobs\n");\r
                } else {\r
                        // No more jobs, so set HwUnit and sequence IDLE/OK also.\r
-                       Spi_SetHWUnitStatus(unit, SPI_IDLE);\r
-                       Spi_SetSequenceResult(spiUnit->currSeqPtr->SpiSequenceId,\r
+                       Spi_SetHWUnitStatus(uPtr, SPI_IDLE);\r
+                       Spi_SetSequenceResult(uPtr->currSeqPtr->SpiSequenceId,\r
                                        SPI_SEQ_OK);\r
 \r
-                       if (spiUnit->currSeqPtr->SpiSeqEndNotification != NULL) {\r
-                               spiUnit->currSeqPtr->SpiSeqEndNotification();\r
+                       if (uPtr->currSeqPtr->SpiSeqEndNotification != NULL) {\r
+                               uPtr->currSeqPtr->SpiSeqEndNotification();\r
                        }\r
 \r
-                       Spi_SetHWUnitStatus(unit, SPI_IDLE);\r
+                       Spi_SetHWUnitStatus(uPtr, SPI_IDLE);\r
 \r
                        /* We are now ready for next transfer. */\r
                        spiHw->MCR.B.HALT = 1;\r
@@ -989,7 +1013,7 @@ static void Spi_SetupCTAR( Spi_HWUnitType unit,
         * --> BR=Fsys/(Baudrate.* 2 )\r
         *\r
         */\r
-#if defined(CFG_MPC5516) || defined(CFG_MPC5517) || defined(CFG_MPC5606S)\r
+#if defined(CFG_MPC5516) || defined(CFG_MPC5517) || defined(CFG_MPC560X)\r
        switch(unit) {\r
        case 0:\r
                perClock = PERIPHERAL_CLOCK_DSPI_A;\r
@@ -997,10 +1021,12 @@ static void Spi_SetupCTAR(       Spi_HWUnitType unit,
        case 1:\r
                perClock = PERIPHERAL_CLOCK_DSPI_B;\r
                break;\r
-#if defined(CFG_MPC5516) || defined(CFG_MPC5517)\r
+#if defined(CFG_MPC5516) || defined(CFG_MPC5517) || defined(CFG_MPC5604B)\r
        case 2:\r
                perClock = PERIPHERAL_CLOCK_DSPI_C;\r
                break;\r
+#endif\r
+#if defined(CFG_MPC5516) || defined(CFG_MPC5517)\r
        case 3:\r
                perClock = PERIPHERAL_CLOCK_DSPI_D;\r
                break;\r
@@ -1151,9 +1177,9 @@ static void Spi_SetupCTAR(        Spi_HWUnitType unit,
 \r
 //-------------------------------------------------------------------\r
 \r
-static void Spi_InitController(uint32 unit) {\r
-       volatile struct DSPI_tag *spiHw = GET_SPI_HW_PTR(unit);\r
-       Spi_UnitType *spiUnit = GET_SPI_UNIT_PTR(unit);\r
+static void Spi_InitController(Spi_UnitType *uPtr ) {\r
+\r
+       volatile struct DSPI_tag *spiHw = uPtr->hwPtr;\r
 \r
        /* Module configuration register. */\r
        /* Master mode. */\r
@@ -1192,8 +1218,8 @@ static void Spi_InitController(uint32 unit) {
 #endif\r
 \r
        // Setup CTAR's channel codes..\r
-       for (int i = 0; i < 7; i++) {\r
-               spiUnit->channelCodes[i] = CH_NOT_VALID;\r
+       for (int i = 0; i < (CTAR_CNT-1); i++) {\r
+               uPtr->channelCodes[i] = CH_NOT_VALID;\r
        }\r
 \r
        /* Force to stopped state. */\r
@@ -1209,14 +1235,19 @@ static void Spi_InitController(uint32 unit) {
 #endif\r
 \r
        // Install EOFQ int..\r
-       switch (unit) {\r
-#if defined(CFG_MPC5606S)\r
+       switch (uPtr->hwUnit) {\r
+#if defined(CFG_MPC560X)\r
        case 0:\r
        ISR_INSTALL_ISR2("SPI_A",Spi_Isr_A, DSPI_0_ISR_EOQF, 15, 0);\r
        break;\r
        case 1:\r
        ISR_INSTALL_ISR2("SPI_B",Spi_Isr_B, DSPI_1_ISR_EOQF, 15, 0);\r
        break;\r
+#if defined(CFG_MPC5604B)\r
+       case 2:\r
+       ISR_INSTALL_ISR2("SPI_C",Spi_Isr_C, DSPI_2_ISR_EOQF, 15, 0);\r
+       break;\r
+#endif\r
 #elif defined(CFG_MPC5516) || defined(CFG_MPC5517)\r
        case 0:\r
        ISR_INSTALL_ISR2("SPI_A",Spi_Isr_A, DSPI_A_ISR_EOQF, 15, 0);\r
@@ -1239,25 +1270,25 @@ static void Spi_InitController(uint32 unit) {
 //-------------------------------------------------------------------\r
 \r
 #if (SPI_IMPLEMENTATION==SPI_DMA)\r
-static void Spi_DmaSetup(uint32 unit) {\r
+static void Spi_DmaSetup( Spi_UnitType *uPtr ) {\r
 \r
        Dma_TcdType *tcd;\r
 \r
-       tcd = &Spi_Unit[unit].dmaTxTCD;\r
+       tcd = &uPtr->dmaTxTCD;\r
        *tcd = Spi_DmaTx;\r
-       tcd->SADDR = (uint32) Spi_Unit[unit].txQueue;\r
-       tcd->DADDR = (uint32) &(GET_SPI_HW_PTR(unit)->PUSHR.R);\r
+       tcd->SADDR = (uint32) uPtr->txQueue;\r
+       tcd->DADDR = (uint32) &(uPtr->hwPtr->PUSHR.R);\r
 \r
-       Dma_StopChannel(Spi_Unit[unit].dmaTxChannel);\r
+       Dma_StopChannel(uPtr->dmaTxChannel);\r
        Dma_CheckConfig();\r
 \r
        // CITER and BITER set when we send\r
-       tcd = &Spi_Unit[unit].dmaRxTCD;\r
+       tcd = &uPtr->dmaRxTCD;\r
        *tcd = Spi_DmaRx;\r
-       tcd->SADDR = (uint32) &(GET_SPI_HW_PTR(unit)->POPR.R);\r
-       tcd->DADDR = (uint32) Spi_Unit[unit].rxQueue;\r
+       tcd->SADDR = (uint32) &(uPtr->hwPtr->POPR.R);\r
+       tcd->DADDR = (uint32) uPtr->rxQueue;\r
 \r
-       Dma_StopChannel(Spi_Unit[unit].dmaRxChannel);\r
+       Dma_StopChannel(uPtr->dmaRxChannel);\r
        Dma_CheckConfig();\r
 \r
 }\r
@@ -1266,8 +1297,14 @@ static void Spi_DmaSetup(uint32 unit) {
 //-------------------------------------------------------------------\r
 \r
 void Spi_Init(const Spi_ConfigType *ConfigPtr) {\r
-\r
        const Spi_JobConfigType *jobConfig2;\r
+       Spi_UnitType *uPtr;\r
+       uint32 confMask;\r
+       uint8 ctrlNr;\r
+#if (SPI_IMPLEMENTATION == SPI_DMA )\r
+       uint8 unitNr;\r
+#endif\r
+\r
 \r
        memset(&Spi_Global,0,sizeof(Spi_Global));\r
        Spi_Global.configPtr = ConfigPtr;\r
@@ -1279,42 +1316,39 @@ void Spi_Init(const Spi_ConfigType *ConfigPtr) {
        for (Spi_SequenceType i = (Spi_SequenceType) 0; i < SPI_MAX_SEQUENCE; i++) {\r
                Spi_SetSequenceResult(i, SPI_SEQ_OK);\r
        }\r
-\r
        // Figure out what HW controllers that are used\r
        for (int j = 0; j < Spi_GetJobCnt(); j++) {\r
                jobConfig2 = &Spi_Global.configPtr->SpiJobConfig[j];\r
                Spi_Global.spiHwConfigured |= (1 << jobConfig2->SpiHwUnit);\r
        }\r
 \r
-       // Initialize controllers used\r
-       {\r
-               uint32 confMask;\r
-               uint8 confNr;\r
-\r
-               confMask = Spi_Global.spiHwConfigured;\r
+       confMask = Spi_Global.spiHwConfigured;\r
 \r
-               for (; confMask; confMask &= ~(1 << confNr)) {\r
-                       confNr = ilog2(confMask);\r
-                       DEBUG(DEBUG_LOW,"%s:Configured HW controller %d\n",MODULE_NAME,confNr);\r
-                       Spi_InitController(confNr);\r
-                       Spi_SetHWUnitStatus(confNr, SPI_IDLE);\r
+       for (; confMask; confMask &= ~(1 << ctrlNr)) {\r
+               ctrlNr = ilog2(confMask);\r
+               DEBUG(DEBUG_LOW,"%s:Configured HW controller %d\n",MODULE_NAME,ctrlNr);\r
+               uPtr = GET_SPI_UNIT_PTR(ctrlNr);\r
+               uPtr->hwPtr = GET_SPI_HW_PTR(ctrlNr);\r
+               uPtr->hwUnit = ctrlNr;\r
+               Spi_InitController(uPtr);\r
+               Spi_SetHWUnitStatus(uPtr, SPI_IDLE);\r
 \r
 #if (SPI_IMPLEMENTATION == SPI_DMA )\r
-                       // DMA init...\r
-                       //\r
+               // DMA init...\r
+               //\r
+               unitNr = Spi_CtrlToUnit[ctrlNr];\r
 \r
-                       /* Make sure that this channel shall be used. */\r
-                       //assert (ConfigPtr->SpiHwConfig[confNr].Activated);\r
-                       assert(Spi_DmaConfig[confNr].TxDmaChannel != (-1));\r
-                       assert(Spi_DmaConfig[confNr].RxDmaChannel != (-1));\r
+               /* Make sure that this channel shall be used. */\r
+               //assert (ConfigPtr->SpiHwConfig[ctrlNr].Activated);\r
+               assert(Spi_DmaConfig[unitNr].TxDmaChannel != (-1));\r
+               assert(Spi_DmaConfig[unitNr].RxDmaChannel != (-1));\r
 \r
-                       Spi_Unit[confNr].dmaTxChannel = Spi_DmaConfig[confNr].TxDmaChannel;\r
-                       Spi_Unit[confNr].dmaRxChannel = Spi_DmaConfig[confNr].RxDmaChannel;\r
+               uPtr->dmaTxChannel = Spi_DmaConfig[unitNr].TxDmaChannel;\r
+               uPtr->dmaRxChannel = Spi_DmaConfig[unitNr].RxDmaChannel;\r
 \r
-                       Spi_DmaSetup(confNr);\r
+               Spi_DmaSetup(uPtr);\r
 #endif\r
 \r
-               }\r
        }\r
 \r
        /* Setup the relations for Job, for easy access */\r
@@ -1363,7 +1397,7 @@ void Spi_Init(const Spi_ConfigType *ConfigPtr) {
                                                                (jobConfig->DeviceAssignment << 8) +\r
                                                                chConfig->SpiDataWidth);\r
 \r
-                               for (k = 0; k < 7; k++) {\r
+                               for (k = 0; k < (CTAR_CNT-1); k++) {\r
                                        if (spiUnit->channelCodes[k] == channelCode) {\r
                                                Spi_ChannelInfo[channelIndex].ctarId = k;\r
                                                DEBUG(DEBUG_LOW,"%s: Channel %d re-uses CTAR %d@%d . device=%d,width=%d\n",MODULE_NAME,channelIndex,k,jobConfig->SpiHwUnit,jobConfig->DeviceAssignment,chConfig->SpiDataWidth);\r
@@ -1389,7 +1423,7 @@ void Spi_Init(const Spi_ConfigType *ConfigPtr) {
                                        }\r
                                }\r
                                /* No more CTARS */\r
-                               assert(k<7);\r
+                               assert(k<(CTAR_CNT-1));\r
                        }\r
                }\r
        }\r
@@ -1403,6 +1437,8 @@ Std_ReturnType Spi_DeInit(void) {
        volatile struct DSPI_tag *spiHw;\r
        uint32 confMask;\r
        uint8 confNr;\r
+       Spi_UnitType *uPtr;\r
+\r
 \r
        VALIDATE_W_RV( ( TRUE == Spi_Global.initRun ), SPI_DEINIT_SERVICE_ID, SPI_E_UNINIT, E_NOT_OK );\r
        if (Spi_GetStatus() == SPI_BUSY)\r
@@ -1417,9 +1453,10 @@ Std_ReturnType Spi_DeInit(void) {
                spiHw = GET_SPI_HW_PTR(confNr);\r
                // Disable the hardware..\r
                spiHw->MCR.B.MDIS = 1;\r
+               uPtr = GET_SPI_UNIT_PTR(confNr);\r
 \r
-               Spi_InitController(confNr);\r
-               Spi_SetHWUnitStatus(confNr, SPI_IDLE);\r
+               Spi_InitController(uPtr);\r
+               Spi_SetHWUnitStatus(uPtr, SPI_IDLE);\r
        }\r
 \r
        // SPI022\r
@@ -1431,10 +1468,10 @@ Std_ReturnType Spi_DeInit(void) {
 \r
 #if (SPI_IMPLEMENTATION==SPI_DMA)\r
 /**\r
- *
- * @param spiUnit
- * @param jobConfig
- * @return
+ *\r
+ * @param spiUnit\r
+ * @param jobConfig\r
+ * @return\r
  */\r
 static void Spi_DoWrite_DMA(   Spi_UnitType *spiUnit,Spi_JobType jobIndex,\r
                                                const Spi_JobConfigType *jobConfig )\r
@@ -1479,8 +1516,7 @@ static void Spi_DoWrite_DMA(      Spi_UnitType *spiUnit,Spi_JobType jobIndex,
                        cmd.B.CTAS = Spi_ChannelInfo[channelIndex].ctarId;\r
                        if (extChBuff->src != NULL) {\r
                                if (chConfig->SpiDataWidth > 8) {\r
-                                       cmd.B.TXDATA = (extChBuff->src[k] << 8) + (extChBuff->src[k\r
-                                                       + 1] & 0xff);\r
+                                       cmd.B.TXDATA = (extChBuff->src[k] << 8) + (extChBuff->src[k + 1] & 0xff);\r
                                        k++;\r
                                } else {\r
                                        cmd.B.TXDATA = extChBuff->src[k];\r
@@ -1571,6 +1607,8 @@ static void Spi_WriteJob_FIFO( Spi_JobType jobIndex )
     const Spi_DataType *            buf;\r
     Spi_NumberOfDataType            copyCnt;\r
     Spi_NumberOfDataType            fifoLeft;\r
+//    boolean                         done = 0;\r
+//    boolean                         lastJob = 0;\r
        int     i;\r
        jobUnitPtr = &Spi_JobUnit[jobIndex];\r
 \r
@@ -1581,7 +1619,7 @@ static void Spi_WriteJob_FIFO( Spi_JobType jobIndex )
 \r
 #if defined(STEP_VALIDATION)\r
     if(  jobUnitPtr->hwPtr->SR.B.TXCTR != 0 ) {\r
-        while(1) {};\r
+        SPI_ASSERT(0);\r
     }\r
 #endif\r
 \r
@@ -1603,9 +1641,11 @@ static void Spi_WriteJob_FIFO( Spi_JobType jobIndex )
         /* Set the Chip Select (PCS) */\r
         cmd.R |= (1 << (16 + jobUnitPtr->extDeviceCfgPtr->SpiCsIdentifier));\r
 \r
+#if defined(STEP_VALIDATION)\r
         if( cmd.B.EOQ == 1) {\r
-            while(1) {};\r
+            SPI_ASSERT(0);\r
         }\r
+#endif\r
 \r
         /* Push as much as we can (FIFO or Channel limits) */\r
         for(i=0; i < copyCnt ; i++ ) {\r
@@ -1661,7 +1701,7 @@ static void Spi_WriteJob_FIFO( Spi_JobType jobIndex )
 \r
 #if defined(STEP_VALIDATION)\r
        if( jobUnitPtr->fifoSent != jobUnitPtr->hwPtr->SR.B.TXCTR ) {\r
-           while(1);\r
+           SPI_ASSERT(0);\r
        }\r
 #endif\r
 \r
@@ -1681,19 +1721,19 @@ static void Spi_WriteJob_FIFO( Spi_JobType jobIndex )
         SPICommandType *curr;\r
         int i,lastIndex;\r
 \r
-        i = jobUnitPtr->hwPtr->SR.B.TXNXTPTR;\r
+        i = jobUnitPtr->hwPtr->SR.B.TXNXTPTR;  /* Next entry to send */\r
         lastIndex = ( i + jobUnitPtr->hwPtr->SR.B.TXCTR - 1 ) % FIFO_DEPTH;\r
         while( i != lastIndex )  {\r
             curr = base + i;\r
-            if( curr->B.EOQ == 1) {\r
-                while(1) {};\r
+            if( curr->B.EOQ == 1) {  /* This entry must not have EOQ set */\r
+                SPI_ASSERT(0);\r
             }\r
 \r
             i = (i + 1) % FIFO_DEPTH;\r
         }\r
         curr = base + i;\r
         if( curr->B.EOQ != 1) {\r
-            while(1) {};\r
+            SPI_ASSERT(0);             /* Last entry must have EOQ set */\r
         }\r
     }\r
 #endif\r
@@ -1726,17 +1766,17 @@ static void Spi_WriteJob_FIFO( Spi_JobType jobIndex )
  * @param jobIndex The job to write to the SPI bus\r
  */\r
 static void Spi_JobWrite(Spi_JobType jobIndex) {\r
-       Spi_UnitType *unitPtr = Spi_JobUnit[jobIndex].unitPtr;\r
+       Spi_UnitType *uPtr = Spi_JobUnit[jobIndex].unitPtr;\r
 \r
-       unitPtr->txCurrIndex = 0;\r
-       unitPtr->currJob = Spi_JobUnit[jobIndex].jobCfgPtr;\r
-       unitPtr->currJobIndex = jobIndex;\r
+       uPtr->txCurrIndex = 0;\r
+       uPtr->currJob = Spi_JobUnit[jobIndex].jobCfgPtr;\r
+       uPtr->currJobIndex = jobIndex;\r
 #if (SPI_IMPLEMENTATION == SPI_FIFO)\r
        Spi_JobUnit[jobIndex].txChCnt = 0;\r
        Spi_JobUnit[jobIndex].rxChCnt = 0;\r
 #endif\r
 \r
-       Spi_SetHWUnitStatus(Spi_JobUnit[jobIndex].jobCfgPtr->SpiHwUnit, SPI_BUSY);\r
+       Spi_SetHWUnitStatus(uPtr, SPI_BUSY);\r
        Spi_SetJobResult(jobIndex, SPI_JOB_PENDING);\r
 \r
 #if (USE_DIO_CS == STD_ON)\r
@@ -1746,7 +1786,7 @@ static void Spi_JobWrite(Spi_JobType jobIndex) {
 #endif\r
 \r
 #if (SPI_IMPLEMENTATION==SPI_DMA)\r
-       Spi_DoWrite_DMA( unitPtr, jobIndex, Spi_JobUnit[jobIndex].jobCfgPtr );\r
+       Spi_DoWrite_DMA( uPtr, jobIndex, Spi_JobUnit[jobIndex].jobCfgPtr );\r
 #elif (SPI_IMPLEMENTATION==SPI_FIFO)\r
        Spi_JobUnit[jobIndex].currTxChIndex = 0;\r
        Spi_WriteJob_FIFO ( jobIndex );\r
@@ -1754,7 +1794,6 @@ static void Spi_JobWrite(Spi_JobType jobIndex) {
 \r
 }\r
 \r
-\r
 #if defined(USE_LDEBUG_PRINTF) && ( DEBUG_LVL <= DEBUG_HIGH )\r
 void Spi_PrintSeqInfo(const Spi_SequenceConfigType *seqConfigPtr) {\r
        int i = 0;\r
@@ -1764,8 +1803,7 @@ void Spi_PrintSeqInfo(const Spi_SequenceConfigType *seqConfigPtr) {
        while ((job = seqConfigPtr->JobAssignment[i]) != JOB_NOT_VALID) {\r
                DEBUG(DEBUG_HIGH,"%d ",job);\r
                i++;\r
-       }\r
-       DEBUG(DEBUG_HIGH,"\n");\r
+       } DEBUG(DEBUG_HIGH,"\n");\r
 }\r
 #endif\r
 \r
@@ -1780,25 +1818,25 @@ static void Spi_SeqWrite(Spi_SequenceType seqIndex, Spi_CallTypeType sync) {
 \r
        const Spi_SequenceConfigType *seqConfig;\r
        const Spi_JobConfigType *jobConfig;\r
-       Spi_UnitType *spiUnit;\r
+       Spi_UnitType *uPtr;\r
        Spi_JobType jobIndex;\r
 \r
        seqConfig = Spi_GetSeqPtrFromIndex(seqIndex);\r
        jobIndex = seqConfig->JobAssignment[0];\r
        jobConfig = Spi_GetJobPtrFromIndex(jobIndex);\r
 \r
-       spiUnit = Spi_GetUnitPtrFromIndex(jobConfig->SpiHwUnit);\r
+       uPtr = Spi_GetUnitPtrFromIndex(jobConfig->SpiHwUnit);\r
 \r
        /* Fill in the required fields for job and sequence.. */\r
-       spiUnit->currJobIndexPtr = &seqConfig->JobAssignment[0];\r
-       spiUnit->callType = sync;\r
-       spiUnit->currSeqPtr = seqConfig;\r
+       uPtr->currJobIndexPtr = &seqConfig->JobAssignment[0];\r
+       uPtr->callType = sync;\r
+       uPtr->currSeqPtr = seqConfig;\r
 \r
        Spi_SetSequenceResult(seqIndex, SPI_SEQ_PENDING);\r
 \r
        // Setup interrupt for end of queue\r
        if (    (Spi_Global.asyncMode == SPI_INTERRUPT_MODE) &&\r
-                       (spiUnit->callType== SPI_ASYNC_CALL)) {\r
+                       (uPtr->callType== SPI_ASYNC_CALL)) {\r
                DEBUG(DEBUG_MEDIUM,"%s: async/interrupt mode\n",MODULE_NAME);\r
        } else {\r
                DEBUG(DEBUG_MEDIUM,"%s: sync/polled mode\n",MODULE_NAME);\r
@@ -1810,9 +1848,9 @@ static void Spi_SeqWrite(Spi_SequenceType seqIndex, Spi_CallTypeType sync) {
 \r
        Spi_JobWrite(jobIndex);\r
 \r
-       if (spiUnit->callType == SPI_SYNC_CALL) {\r
+       if (uPtr->callType == SPI_SYNC_CALL) {\r
                while (Spi_GetSequenceResult(seqIndex) == SPI_SEQ_PENDING) {\r
-                       Spi_Isr(jobConfig->SpiHwUnit);\r
+                       Spi_Isr(uPtr);\r
                }\r
        }\r
 \r
@@ -1993,7 +2031,7 @@ Spi_SeqResultType Spi_GetSequenceResult(Spi_SequenceType Sequence) {
 Spi_StatusType Spi_GetHWUnitStatus(Spi_HWUnitType HWUnit) {\r
        VALIDATE_W_RV( ( TRUE == Spi_Global.initRun ), SPI_GETHWUNITSTATUS_SERVICE_ID, SPI_E_UNINIT, SPI_UNINIT );\r
 \r
-       return Spi_Unit[HWUnit].status;\r
+       return Spi_Unit[Spi_CtrlToUnit[HWUnit]].status;\r
 }\r
 \r
 //-------------------------------------------------------------------\r
@@ -2041,21 +2079,24 @@ void Spi_MainFunction_Handling(void) {
 void Spi_MainFunction_Driving(void) {\r
        volatile struct DSPI_tag *spiHw;\r
        uint32 confMask;\r
-       uint8 confNr;\r
+       uint8 ctrlNr;\r
+       Spi_UnitType *uPtr;\r
 \r
        // TODO: check that the queue is empty.. if so do the next job.\r
        if (Spi_Global.asyncMode == SPI_POLLING_MODE) {\r
                confMask = Spi_Global.spiHwConfigured;\r
 \r
-               for (; confMask; confMask &= ~(1 << confNr)) {\r
-                       confNr = ilog2(confMask);\r
-                       spiHw = GET_SPI_HW_PTR(confNr);\r
+               for (; confMask; confMask &= ~(1 << ctrlNr)) {\r
+                       ctrlNr = ilog2(confMask);\r
+                       uPtr = GET_SPI_UNIT_PTR(ctrlNr);\r
+                       spiHw = uPtr->hwPtr;\r
 \r
-                       if (Spi_GetHWUnitStatus(confNr) == SPI_BUSY) {\r
+                       if (Spi_GetHWUnitStatus(ctrlNr) == SPI_BUSY) {\r
                                if (spiHw->SR.B.TXRXS) {\r
                                        // Still not done..\r
                                } else {\r
-                                       Spi_Isr(confNr);\r
+                                       uPtr = GET_SPI_UNIT_PTR(ctrlNr);\r
+                                       Spi_Isr(uPtr);\r
                                }\r
                        }\r
                }\r