William Kane / Generic

Dependents:   LaserioLib

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers abcc_spi_drv.c Source File

abcc_spi_drv.c

00001 /*******************************************************************************
00002 ********************************************************************************
00003 **                                                                            **
00004 ** ABCC Driver version 4.01.01 (2015-12-14)                                   **
00005 **                                                                            **
00006 ** Delivered with:                                                            **
00007 **    ABP         7.16.01 (2015-10-14)                                        **
00008 **                                                                            */
00009 /*******************************************************************************
00010 ********************************************************************************
00011 ** COPYRIGHT NOTIFICATION (c) 2013 HMS Industrial Networks AB                 **
00012 **                                                                            **
00013 ** This code is the property of HMS Industrial Networks AB.                   **
00014 ** The source code may not be reproduced, distributed, or used without        **
00015 ** permission. When used together with a product from HMS, permission is      **
00016 ** granted to modify, reproduce and distribute the code in binary form        **
00017 ** without any restrictions.                                                  **
00018 **                                                                            **
00019 ** THE CODE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. HMS DOES NOT    **
00020 ** WARRANT THAT THE FUNCTIONS OF THE CODE WILL MEET YOUR REQUIREMENTS, OR     **
00021 ** THAT THE OPERATION OF THE CODE WILL BE UNINTERRUPTED OR ERROR-FREE, OR     **
00022 ** THAT DEFECTS IN IT CAN BE CORRECTED.                                       **
00023 ********************************************************************************
00024 ********************************************************************************
00025 ** File Description:
00026 ** SPI driver implementation
00027 ********************************************************************************
00028 ********************************************************************************
00029 */
00030 
00031 #include "abcc_drv_cfg.h"
00032 #include "abcc.h"
00033 
00034 #if( ABCC_CFG_DRV_SPI )
00035 
00036 #include "abcc_td.h"
00037 #include "../abcc_debug_err.h"
00038 #include "abcc_sys_adapt.h"
00039 #include "../abcc_timer.h"
00040 #include "../abcc_drv_if.h"
00041 #include "../abcc_mem.h"
00042 #include "../abcc_handler.h"
00043 #include "abcc_crc32.h"
00044 #include "abcc_sys_adapt_spi.h"
00045 
00046 /*******************************************************************************
00047 ** Constants
00048 ********************************************************************************
00049 */
00050 #define ABCC_MSG_HEADER_TYPE_SIZEOF 12
00051 
00052 /*------------------------------------------------------------------------------
00053 ** Since the masking of control registers are endian dependent since
00054 ** we operating on the mosi and misu structures that are little endian
00055 -------------------------------------------------------------------------------*/
00056 #ifdef ABCC_SYS_BIG_ENDIAN
00057 static const UINT16 iSpiCtrlWrPdWalid =   ABP_SPI_CTRL_WRPD_VALID << 8;
00058 static const UINT16 iSpiCtrlCmdCntShift  =  9;
00059 static const UINT16 iSpiCtrlCmdCnt  =     ABP_SPI_CTRL_CMDCNT << 8;
00060 static const UINT16 iSpiCtrl_M =          ABP_SPI_CTRL_M << 8;
00061 static const UINT16 iSpiCtrlLastFrag =    ABP_SPI_CTRL_LAST_FRAG << 8;
00062 static const UINT16 iSpiCtrl_T =          ABP_SPI_CTRL_T << 8;
00063 
00064 static const UINT16 iSpiStatusWrMsgFull = ABP_SPI_STATUS_WRMSG_FULL;
00065 static const UINT16 iSpiStatusCmdCnt =    ABP_SPI_STATUS_CMDCNT;
00066 static const UINT16 iSpiStatusCmdCntShift  =  1;
00067 static const UINT16 iSpiStatus_M =        ABP_SPI_STATUS_M;
00068 static const UINT16 iSpiStatusLastFrag =  ABP_SPI_STATUS_LAST_FRAG;
00069 static const UINT16 iSpiStatusNewPd =     ABP_SPI_STATUS_NEW_PD;
00070 
00071 #else
00072 static const UINT16 iSpiCtrlWrPdWalid =   ABP_SPI_CTRL_WRPD_VALID;
00073 static const UINT16 iSpiCtrlCmdCntShift  =  1;
00074 static const UINT16 iSpiCtrlCmdCnt  =     ABP_SPI_CTRL_CMDCNT;
00075 static const UINT16 iSpiCtrl_M =          ABP_SPI_CTRL_M;
00076 static const UINT16 iSpiCtrlLastFrag =    ABP_SPI_CTRL_LAST_FRAG;
00077 static const UINT16 iSpiCtrl_T =          ABP_SPI_CTRL_T;
00078 
00079 static const UINT16 iSpiStatusWrMsgFull = ABP_SPI_STATUS_WRMSG_FULL << 8;
00080 static const UINT16 iSpiStatusCmdCnt =    ABP_SPI_STATUS_CMDCNT << 8;
00081 static const UINT16 iSpiStatusCmdCntShift  =  9;
00082 static const UINT16 iSpiStatus_M =        ABP_SPI_STATUS_M << 8;
00083 static const UINT16 iSpiStatusLastFrag =  ABP_SPI_STATUS_LAST_FRAG << 8;
00084 static const UINT16 iSpiStatusNewPd =     ABP_SPI_STATUS_NEW_PD << 8;
00085 #endif
00086 
00087 
00088 
00089 
00090 /*------------------------------------------------------------------------------
00091 ** Help defines.
00092 ** Note: They are in words and not bytes.
00093 **------------------------------------------------------------------------------
00094 */
00095 
00096 #define NUM_BYTES_2_WORDS(x) ( ( (x) + 1 ) >> 1 )
00097 
00098 
00099 #define SPI_DEFAULT_PD_LEN 0
00100 #define CRC_WORD_LEN_IN_WORDS 2
00101 #define SPI_FRAME_SIZE_EXCLUDING_DATA (7)
00102 
00103 #if ABCC_CFG_SPI_MSG_FRAG_LEN > ABCC_CFG_MAX_MSG_SIZE
00104 #error  spi fragmentation length cannot exceed max msg size
00105 #endif
00106 #define MAX_PAYLOAD_WORD_LEN ( ( NUM_BYTES_2_WORDS( ABCC_CFG_SPI_MSG_FRAG_LEN ) ) + ( NUM_BYTES_2_WORDS( ABCC_CFG_MAX_PROCESS_DATA_SIZE ) ) + ( CRC_WORD_LEN_IN_WORDS ) )
00107 
00108 
00109 
00110 #define INSERT_SPI_CTRL_CMDCNT( ctrl, cmdcnt)  ctrl = ( ( ctrl ) & ~iSpiCtrlCmdCnt ) | ( ( cmdcnt ) << iSpiCtrlCmdCntShift )
00111 #define EXTRACT_SPI_STATUS_CMDCNT( status ) ( ( ( status ) & iSpiStatusCmdCnt ) >> iSpiStatusCmdCntShift )
00112 #define SPI_BASE_FRAME_WORD_LEN  5 /* Frame length excluding MSG and PD data */
00113 
00114 
00115 /*******************************************************************************
00116 ** Typedefs
00117 ********************************************************************************
00118 */
00119 
00120 
00121 
00122 /*------------------------------------------------------------------------------
00123 ** SPI MOSI structure (7044 - ABCC40).
00124 **------------------------------------------------------------------------------
00125 */
00126 
00127 typedef struct drv_SpiMosiFrameType
00128 {
00129    UINT16 iSpiControl;
00130    UINT16 iMsgLen;
00131    UINT16 iPdLen;
00132    UINT16 iIntMaskAppStatus;
00133    UINT16 iData[ MAX_PAYLOAD_WORD_LEN ];
00134    UINT16   dummy;
00135 } drv_SpiMosiFrameType;
00136 
00137 
00138 /*------------------------------------------------------------------------------
00139 ** SPI MISO structure
00140 **------------------------------------------------------------------------------
00141 */
00142 typedef struct
00143 {
00144    UINT16 iReserved;
00145    UINT16 iLedStat;
00146    UINT16 iSpiStatusAnbStatus;
00147    UINT16 iNetTime[ 2 ];
00148    UINT16 iData[ MAX_PAYLOAD_WORD_LEN ];
00149 } drv_SpiMisoFrameType;
00150 
00151 
00152 /*------------------------------------------------------------------------------
00153 ** Message fragmentation info types.
00154 **------------------------------------------------------------------------------
00155 */
00156 typedef struct
00157 {
00158   ABP_MsgType*       psWriteMsg;          /* Pointer to the write message. */
00159   UINT16*            puCurrPtr;           /* Pointer to the current fragment. */
00160   INT16              iNumWordsLeft;       /* Number of words left to send. */
00161   UINT16             iCurrFragLength;     /* Current fragmention block length. */
00162 } drv_SpiWriteMsgFragInfoType;
00163 
00164 
00165 typedef struct
00166 {
00167   ABP_MsgType* psReadMsg;                 /* Pointer to the receive message buffer. */
00168   UINT16*            puCurrPtr;           /* Pointer to the current position in receive buffer. */
00169   UINT16             iNumWordsReceived;   /* Number of words received. */
00170 } drv_SpiReadMsgFragInfoType;
00171 
00172 
00173 /*------------------------------------------------------------------------------
00174 ** Internal SPI states.
00175 **------------------------------------------------------------------------------
00176 */
00177 typedef enum
00178 {
00179    SM_SPI_INIT = 0,
00180    SM_SPI_RDY_TO_SEND_MOSI,
00181    SM_SPI_WAITING_FOR_MISO
00182 } drv_SpiStateType;
00183 
00184 
00185 /*******************************************************************************
00186 ** Private Globals
00187 ********************************************************************************
00188 */
00189 
00190 /*------------------------------------------------------------------------------
00191 ** MISO privates.
00192 **------------------------------------------------------------------------------
00193 */
00194 static drv_SpiMisoFrameType         spi_drv_sMisoFrame;           /* Place holder for the MISO frame. */
00195 static drv_SpiReadMsgFragInfoType   spi_drv_sReadFragInfo;        /* Read message info. */
00196 static BOOL                         spi_drv_fNewMisoReceived;     /* MISO received flag. */
00197 static UINT8                        spi_drv_bAnbStatus;           /* Latest received anb status. */
00198 static UINT16                       spi_drv_iLedStatus;            /* Latest received anb status. */
00199 static UINT8                        spi_drv_bAnbCmdCnt;            /* Latest correct received cmd count */
00200 static UINT8*                       spi_drv_bpRdPd;                /* Pointer to latest correctly received RdPd */
00201 
00202 static ABP_MsgType*                 spi_drv_psReadMessage;        /* Pointer to the read message. */
00203 
00204 
00205 
00206 /*------------------------------------------------------------------------------
00207 ** MOSI privates.
00208 **------------------------------------------------------------------------------
00209 */
00210 static drv_SpiMosiFrameType         spi_drv_sMosiFrame;           /* Place holder for the MISO frame. */
00211 static drv_SpiWriteMsgFragInfoType  spi_drv_sWriteFragInfo;       /* Write message info. */
00212 static UINT8                        spi_drv_bNbrOfCmds;           /* Number of commands support by the application. */
00213 static UINT8                        spi_drv_bNextAppStatus;       /* Appstatus to be sent in next MOSI frame */
00214 static UINT8                        spi_drv_bNextIntMask;         /* Intmask to be sent in next MOSI frame */
00215 
00216 
00217 /*------------------------------------------------------------------------------
00218 ** General privates.
00219 **------------------------------------------------------------------------------
00220 */
00221 static UINT16                       spi_drv_iPdOffset;            /* Offset in payload where the PD is located. */
00222 static UINT16                       spi_drv_iCrcOffset;           /* Offset in payload where the CRC is located. */
00223 
00224 static UINT16                       spi_drv_iPdSize;              /* PD size in spiFrame. */
00225 static UINT16                       spi_drv_iWritePdSize;         /* Current write PD size. */
00226 static UINT16                       spi_drv_iReadPdSize;          /* Current read PD size. */
00227 
00228 static UINT16                       spi_drv_iSpiFrameSize;        /* Current Spi frame size. */
00229 static BOOL                         spi_drv_fRetransmit;          /* Indicate retransmission. */
00230 
00231 static drv_SpiStateType             spi_drv_eState;               /* SPI driver state. */
00232 static ABCC_TimerHandle             xWdTmoHandle;
00233 static BOOL                         fWdTmo;                       /* Current wd timeout status */
00234 
00235 static UINT16                       spi_drv_iMsgLen;              /* Message length ( in words ) */
00236 
00237 
00238 
00239 
00240 
00241 /*******************************************************************************
00242 ** Private forward declarations.
00243 ********************************************************************************
00244 */
00245 static void spi_drv_DataReceived( void );
00246 static void spi_drv_ResetReadFragInfo( void );
00247 static void spi_drv_ResetWriteFragInfo( void );
00248 
00249 static void DrvSpiSetMsgReceiverBuffer( ABP_MsgType* const psReadMsg );
00250 
00251 
00252 /*******************************************************************************
00253 ** Private Services
00254 ********************************************************************************
00255 */
00256 
00257 
00258 /*------------------------------------------------------------------------------
00259 **  Handles preparation and transmission of the MOSI frame.
00260 **  Depending on the physical implementation of the SPI transaction this method
00261 **  could be blocking until the MISO is received.
00262 **------------------------------------------------------------------------------
00263 ** Arguments:
00264 **       None.
00265 **
00266 ** Returns:
00267 **       Driver status.
00268 **------------------------------------------------------------------------------
00269 */
00270 void ABCC_DrvSpiRunDriverTx( void )
00271 {
00272    UINT32 lCrc;
00273    BOOL   fHandleWriteMsg = FALSE;
00274    UINT16 iRdyForCmd;
00275 
00276    ABCC_PORT_UseCritical();
00277 
00278    if (spi_drv_eState ==  SM_SPI_RDY_TO_SEND_MOSI )
00279    {
00280       spi_drv_eState = SM_SPI_WAITING_FOR_MISO;
00281 
00282       if ( !spi_drv_fRetransmit )
00283       {
00284          /*
00285          ** Everything is OK. Reset retransmission and toggle the T bit.
00286          */
00287          spi_drv_sMosiFrame.iSpiControl ^= iSpiCtrl_T;
00288       }
00289 
00290       spi_drv_fRetransmit = FALSE;
00291 
00292       /*---------------------------------------------------------------------------
00293       ** Write message handling.
00294       **---------------------------------------------------------------------------
00295       */
00296       ABCC_PORT_EnterCritical();
00297       if (spi_drv_sWriteFragInfo.psWriteMsg != NULL )
00298       {
00299          fHandleWriteMsg = TRUE;
00300       }
00301       ABCC_PORT_ExitCritical();
00302 
00303       if ( fHandleWriteMsg )
00304       {
00305          ABCC_ASSERT( spi_drv_sWriteFragInfo.puCurrPtr );
00306          /*
00307          ** Write the message to be sent.
00308          */
00309          spi_drv_sMosiFrame.iSpiControl |= iSpiCtrl_M;
00310 
00311          if( spi_drv_sWriteFragInfo.iNumWordsLeft <= spi_drv_iMsgLen )
00312          {
00313             spi_drv_sMosiFrame.iSpiControl |= iSpiCtrlLastFrag;
00314             spi_drv_sWriteFragInfo.iCurrFragLength = spi_drv_sWriteFragInfo.iNumWordsLeft;
00315          }
00316          else
00317          {
00318             /*
00319             ** This is not the last fragment.
00320             */
00321             spi_drv_sMosiFrame.iSpiControl &= ~iSpiCtrlLastFrag;
00322             spi_drv_sWriteFragInfo.iCurrFragLength = spi_drv_iMsgLen;
00323          }
00324 
00325          /*
00326          ** Copy the message into the MOSI frame buffer.
00327          */
00328          ABCC_PORT_MemCpy( (void*)spi_drv_sMosiFrame.iData,
00329                            (void*)spi_drv_sWriteFragInfo.puCurrPtr,
00330                            spi_drv_sWriteFragInfo.iCurrFragLength << 1 );
00331       }
00332       else
00333       {
00334          /*
00335          ** There is no message fragment to be sent.
00336          */
00337          spi_drv_sMosiFrame.iSpiControl &= ~iSpiCtrl_M;
00338          spi_drv_sMosiFrame.iSpiControl &= ~iSpiCtrlLastFrag;
00339       }
00340 
00341       iRdyForCmd = 0;
00342       if ( spi_drv_bNbrOfCmds > 3 )
00343       {
00344          iRdyForCmd = 3;
00345       }
00346       else
00347       {
00348          iRdyForCmd =  spi_drv_bNbrOfCmds & 0x3;
00349       }
00350       INSERT_SPI_CTRL_CMDCNT(spi_drv_sMosiFrame.iSpiControl, iRdyForCmd );
00351 
00352 
00353       ABCC_SetLowAddrOct( spi_drv_sMosiFrame.iIntMaskAppStatus, spi_drv_bNextAppStatus );
00354       ABCC_SetHighAddrOct( spi_drv_sMosiFrame.iIntMaskAppStatus, spi_drv_bNextIntMask );
00355       spi_drv_bpRdPd = NULL;
00356 
00357 
00358       /*
00359       ** Apply the CRC checksum.
00360       */
00361       lCrc = CRC_Crc32( (UINT16*)&spi_drv_sMosiFrame, spi_drv_iSpiFrameSize*2 - 6 );
00362       lCrc = lTOlLe( lCrc );
00363 
00364       ABCC_PORT_MemCpy( &spi_drv_sMosiFrame.iData[ spi_drv_iCrcOffset ],
00365                         &lCrc,
00366                         ABP_UINT32_SIZEOF );
00367       /*
00368       ** Send the MOSI frame.
00369       */
00370       ABCC_SYS_SpiSendReceive( &spi_drv_sMosiFrame, &spi_drv_sMisoFrame, spi_drv_iSpiFrameSize << 1 );
00371    }
00372    else if ( spi_drv_eState == SM_SPI_INIT )
00373    {
00374       ABCC_TimerStart( xWdTmoHandle, ABCC_CFG_WD_TIMEOUT_MS );
00375       spi_drv_eState = SM_SPI_RDY_TO_SEND_MOSI;
00376    }
00377 }
00378 
00379 
00380 /*------------------------------------------------------------------------------
00381 **  Handle the reception of the MISO frame.
00382 **------------------------------------------------------------------------------
00383 ** Arguments:
00384 **       psResp:  Pointer to the response message.
00385 **
00386 ** Returns:
00387 **       None.
00388 **------------------------------------------------------------------------------
00389 */
00390 ABP_MsgType* ABCC_DrvSpiRunDriverRx( void )
00391 {
00392    UINT32 lRecievedCrc;
00393    UINT32 lCalculatedCrc;
00394    ABP_MsgType* psWriteMsg = NULL;
00395 
00396    if( spi_drv_eState == SM_SPI_WAITING_FOR_MISO )
00397    {
00398       if( !spi_drv_fNewMisoReceived )
00399       {
00400          /*
00401          ** Nothing has happened. No MISO was received.
00402          */
00403          return psWriteMsg;
00404       }
00405       else
00406       {
00407          spi_drv_fNewMisoReceived = FALSE;
00408       }
00409 
00410       lCalculatedCrc = CRC_Crc32( (UINT16*)&spi_drv_sMisoFrame, spi_drv_iSpiFrameSize*2 - 4 );
00411       lCalculatedCrc = lLeTOl( lCalculatedCrc );
00412 
00413       ABCC_PORT_MemCpy( &lRecievedCrc,
00414                         &spi_drv_sMisoFrame.iData[ spi_drv_iCrcOffset ],
00415                         ABP_UINT32_SIZEOF );
00416 
00417       if( lCalculatedCrc != lRecievedCrc )
00418       {
00419          /*
00420          ** We will request a retransmit if the data is corrupt.
00421          */
00422          spi_drv_fRetransmit = TRUE;
00423          spi_drv_eState = SM_SPI_RDY_TO_SEND_MOSI;
00424          return NULL;
00425       }
00426 
00427       /*
00428       ** Restart watchdog
00429       */
00430       if( fWdTmo )
00431       {
00432         ABCC_CbfWdTimeoutRecovered();
00433       }
00434 
00435       ABCC_TimerStop( xWdTmoHandle );
00436       fWdTmo = FALSE;
00437       ABCC_TimerStart( xWdTmoHandle, ABCC_CFG_WD_TIMEOUT_MS );
00438 
00439 
00440       /*
00441       ** Save the current anybus status.
00442       */
00443       spi_drv_bAnbStatus =  ABCC_GetLowAddrOct( spi_drv_sMisoFrame.iSpiStatusAnbStatus );
00444       spi_drv_iLedStatus  = iLeTOi( spi_drv_sMisoFrame.iLedStat );
00445 
00446       spi_drv_bAnbCmdCnt = (UINT8)EXTRACT_SPI_STATUS_CMDCNT( spi_drv_sMisoFrame.iSpiStatusAnbStatus  );
00447 
00448       if( spi_drv_sMisoFrame.iSpiStatusAnbStatus & iSpiStatusNewPd )
00449       {
00450          /*
00451          ** Report the new process data.
00452          */
00453          spi_drv_bpRdPd = (UINT8*)&spi_drv_sMisoFrame.iData[ spi_drv_iPdOffset ];
00454       }
00455 
00456       /*---------------------------------------------------------------------------
00457       ** Write message handling.
00458       **---------------------------------------------------------------------------
00459       */
00460       if( spi_drv_sWriteFragInfo.iCurrFragLength != 0 )
00461       {
00462          /*
00463          ** Write the message to be sent.
00464          */
00465          if( !( spi_drv_sMisoFrame.iSpiStatusAnbStatus & iSpiStatusWrMsgFull ) )
00466          {
00467             /*
00468             ** Write message was received.
00469             ** Update the write fragmentation information.
00470             */
00471             spi_drv_sWriteFragInfo.puCurrPtr         += spi_drv_sWriteFragInfo.iCurrFragLength;
00472             spi_drv_sWriteFragInfo.iNumWordsLeft     -= spi_drv_sWriteFragInfo.iCurrFragLength;
00473             spi_drv_sWriteFragInfo.iCurrFragLength    = 0;
00474 
00475             if( spi_drv_sWriteFragInfo.iNumWordsLeft <= 0 )
00476             {
00477                psWriteMsg = (ABP_MsgType*)spi_drv_sWriteFragInfo.psWriteMsg;
00478 
00479                spi_drv_ResetWriteFragInfo();
00480 
00481                if( ( ABCC_GetLowAddrOct( ( (ABP_MsgType16*)psWriteMsg )->sHeader.iCmdReserved ) & ABP_MSG_HEADER_C_BIT ) == 0)
00482                {
00483                   spi_drv_bNbrOfCmds++;
00484                }
00485             }
00486          }
00487       }
00488 
00489       /*---------------------------------------------------------------------------
00490       ** Read message handling
00491       ** --------------------------------------------------------------------------
00492       */
00493       if( spi_drv_sMisoFrame.iSpiStatusAnbStatus & iSpiStatus_M )
00494       {
00495          /*
00496          ** Read message was received.
00497          ** Update the read fragmentation information.
00498          */
00499 
00500          if( spi_drv_sReadFragInfo.puCurrPtr == 0 )
00501          {
00502             DrvSpiSetMsgReceiverBuffer( ABCC_MemAlloc() );
00503 
00504             if( spi_drv_sReadFragInfo.puCurrPtr == 0 )
00505             {
00506                ABCC_ERROR( ABCC_SEV_WARNING, ABCC_EC_OUT_OF_MSG_BUFFERS, 0 );
00507                return( NULL );
00508             }
00509          }
00510 
00511          if( ( ( spi_drv_sReadFragInfo.iNumWordsReceived + spi_drv_iMsgLen ) << 1 ) >
00512              ( ABCC_CFG_MAX_MSG_SIZE + ABCC_MSG_HEADER_TYPE_SIZEOF ) )
00513          {
00514             /*
00515             ** Message size exceeds buffer.
00516             */
00517             ABCC_ERROR( ABCC_SEV_FATAL, ABCC_EC_RDMSG_SIZE_ERR, 0 );
00518 
00519             return( NULL );
00520          }
00521 
00522          ABCC_PORT_MemCpy( spi_drv_sReadFragInfo.puCurrPtr,
00523                            spi_drv_sMisoFrame.iData,
00524                            spi_drv_iMsgLen << 1 );
00525 
00526          spi_drv_sReadFragInfo.puCurrPtr += spi_drv_iMsgLen;
00527          spi_drv_sReadFragInfo.iNumWordsReceived += spi_drv_iMsgLen;
00528 
00529          if( spi_drv_sMisoFrame.iSpiStatusAnbStatus & iSpiStatusLastFrag )
00530          {
00531             /*
00532             ** Last fragment of the read message. Return the message.
00533             ** Update the application flow control.
00534             */
00535             if( ABCC_GetLowAddrOct( ( (ABP_MsgType16*)spi_drv_sReadFragInfo.psReadMsg)->sHeader.iCmdReserved ) & ABP_MSG_HEADER_C_BIT )
00536             {
00537                spi_drv_bNbrOfCmds--;
00538             }
00539 
00540             spi_drv_psReadMessage = spi_drv_sReadFragInfo.psReadMsg;
00541             spi_drv_ResetReadFragInfo();
00542          }
00543       }
00544 
00545       /*
00546       ** Clear the valid pd for the next frame.
00547       */
00548       spi_drv_sMosiFrame.iSpiControl &= ~iSpiCtrlWrPdWalid;
00549       spi_drv_eState = SM_SPI_RDY_TO_SEND_MOSI;
00550    }
00551    else if( spi_drv_eState == SM_SPI_INIT )
00552    {
00553       spi_drv_eState = SM_SPI_RDY_TO_SEND_MOSI;
00554    }
00555 
00556    return psWriteMsg;
00557 } /* end of spi_drv_HandleMiso() */
00558 
00559 
00560 /*------------------------------------------------------------------------------
00561 ** Callback from the physical layer to indicate that a MISO frame was received.
00562 **------------------------------------------------------------------------------
00563 ** Arguments:
00564 **       None.
00565 **
00566 ** Returns:
00567 **       None.
00568 **------------------------------------------------------------------------------
00569 */
00570 static void spi_drv_DataReceived( void )
00571 {
00572    spi_drv_fNewMisoReceived = TRUE;
00573 }
00574 
00575 /*------------------------------------------------------------------------------
00576 ** Reset the read fragmentation information.
00577 **------------------------------------------------------------------------------
00578 ** Arguments:
00579 **       None.
00580 **
00581 ** Returns:
00582 **       None.
00583 **------------------------------------------------------------------------------
00584 */
00585 static void spi_drv_ResetReadFragInfo( void )
00586 {
00587    spi_drv_sReadFragInfo.iNumWordsReceived = 0;
00588    spi_drv_sReadFragInfo.psReadMsg = NULL;
00589    spi_drv_sReadFragInfo.puCurrPtr = NULL;
00590 }
00591 
00592 
00593 /*------------------------------------------------------------------------------
00594 ** Reset the write fragmentation information.
00595 **------------------------------------------------------------------------------
00596 ** Arguments:
00597 **       None.
00598 **
00599 ** Returns:
00600 **       None.
00601 **------------------------------------------------------------------------------
00602 */
00603 static void spi_drv_ResetWriteFragInfo( void )
00604 {
00605    ABCC_PORT_UseCritical();
00606 
00607    spi_drv_sWriteFragInfo.iNumWordsLeft = 0;
00608    spi_drv_sWriteFragInfo.iCurrFragLength = 0;
00609    spi_drv_sWriteFragInfo.puCurrPtr = NULL;
00610 
00611    ABCC_PORT_EnterCritical();
00612    spi_drv_sWriteFragInfo.psWriteMsg = NULL;
00613    ABCC_PORT_ExitCritical();
00614 }
00615 
00616 
00617 /*------------------------------------------------------------------------------
00618 ** Watchdog timeouthandler
00619 **------------------------------------------------------------------------------
00620 ** Arguments:
00621 **       None.
00622 **
00623 ** Returns:
00624 **       None.
00625 **------------------------------------------------------------------------------
00626 */
00627 static void drv_WdTimeoutHandler( void )
00628 {
00629    fWdTmo = TRUE;
00630    ABCC_CbfWdTimeout();
00631 }
00632 
00633 
00634 
00635 /*******************************************************************************
00636 ** Public Services
00637 ********************************************************************************
00638 */
00639 void ABCC_DrvSpiInit( UINT8 bOpmode )
00640 {
00641 
00642    UINT16 i;
00643    /*
00644    ** Initialize privates and states.
00645    */
00646    ABCC_ASSERT_ERR( bOpmode == 1, ABCC_SEV_FATAL, ABCC_EC_INCORRECT_OPERATING_MODE, (UINT32)bOpmode );
00647 
00648    spi_drv_sMosiFrame.iSpiControl = 0;
00649    for ( i = 0; i < MAX_PAYLOAD_WORD_LEN; i++ )
00650    {
00651       spi_drv_sMosiFrame.iData[ i ] = 0;
00652       spi_drv_sMisoFrame.iData[ i ] = 0;
00653    }
00654 
00655 
00656    spi_drv_ResetReadFragInfo();
00657    spi_drv_fNewMisoReceived = FALSE;
00658    spi_drv_bAnbStatus = 0;
00659    spi_drv_psReadMessage = 0;
00660    spi_drv_ResetWriteFragInfo();
00661    spi_drv_sMosiFrame.iIntMaskAppStatus = 0;
00662    spi_drv_bNbrOfCmds = 0;
00663    spi_drv_eState = SM_SPI_INIT;
00664    spi_drv_iPdSize = SPI_DEFAULT_PD_LEN;
00665    spi_drv_iWritePdSize = SPI_DEFAULT_PD_LEN;
00666    spi_drv_iReadPdSize = SPI_DEFAULT_PD_LEN;
00667    spi_drv_iPdOffset = NUM_BYTES_2_WORDS( ABCC_CFG_SPI_MSG_FRAG_LEN );
00668    spi_drv_iCrcOffset = NUM_BYTES_2_WORDS( ABCC_CFG_SPI_MSG_FRAG_LEN ) + SPI_DEFAULT_PD_LEN;
00669    spi_drv_iSpiFrameSize = SPI_FRAME_SIZE_EXCLUDING_DATA + spi_drv_iCrcOffset;
00670    spi_drv_fRetransmit = FALSE;
00671    spi_drv_iMsgLen = 0;
00672 
00673    spi_drv_iMsgLen = NUM_BYTES_2_WORDS( ABCC_CFG_SPI_MSG_FRAG_LEN );
00674    spi_drv_sMosiFrame.iMsgLen = iTOiLe( spi_drv_iMsgLen );
00675 
00676    spi_drv_sMosiFrame.iPdLen = iTOiLe( spi_drv_iPdSize );
00677    spi_drv_bNextAppStatus = 0;
00678    spi_drv_bNextIntMask = 0;
00679    spi_drv_bpRdPd = NULL;
00680    spi_drv_bAnbCmdCnt = 0;
00681    xWdTmoHandle = ABCC_TimerCreate( drv_WdTimeoutHandler );
00682    fWdTmo = FALSE;
00683 
00684    /*
00685    ** Register the MISO indicator for the physical SPI driver.
00686    */
00687    ABCC_SYS_SpiRegDataReceived( spi_drv_DataReceived );
00688 
00689 #if( ABCC_CFG_SYNC_MEASUREMENT_IP )
00690    /*
00691    ** Initialise sync measurement flag
00692    */
00693    fAbccUserSyncMeasurementIp = FALSE;
00694 #endif
00695 }
00696 
00697 BOOL ABCC_DrvSpiWriteMessage( ABP_MsgType* psWriteMsg )
00698 {
00699    ABCC_PORT_UseCritical();
00700    ABCC_ASSERT( psWriteMsg );
00701 
00702    ABCC_PORT_EnterCritical();
00703    ABCC_ASSERT(spi_drv_sWriteFragInfo.psWriteMsg == NULL );
00704    spi_drv_sWriteFragInfo.puCurrPtr = (UINT16*)psWriteMsg;
00705    spi_drv_sWriteFragInfo.iNumWordsLeft = NUM_BYTES_2_WORDS( iLeTOi( psWriteMsg->sHeader.iDataSize ) + ABCC_MSG_HEADER_TYPE_SIZEOF );
00706    spi_drv_sWriteFragInfo.psWriteMsg = psWriteMsg;
00707    ABCC_PORT_ExitCritical();
00708 
00709    /*
00710    ** The SPI driver still owns the buffer.
00711    */
00712    return( FALSE );
00713 }
00714 
00715 
00716 void ABCC_DrvSpiWriteProcessData( void* pxProcessData )
00717 {
00718    (void)pxProcessData;
00719    if( spi_drv_eState == SM_SPI_RDY_TO_SEND_MOSI )
00720    {
00721       spi_drv_sMosiFrame.iSpiControl |= iSpiCtrlWrPdWalid;
00722    }
00723    else
00724    {
00725       ABCC_ERROR(ABCC_SEV_WARNING, ABCC_EC_SPI_OP_NOT_ALLOWED_DURING_SPI_TRANSACTION,0);
00726    }
00727 }
00728 
00729 BOOL ABCC_DrvSpiIsReadyForWriteMessage( void )
00730 {
00731    BOOL fRdyForWrMsg = FALSE;
00732    ABCC_PORT_UseCritical();
00733 
00734    ABCC_PORT_EnterCritical();
00735    if ( spi_drv_sWriteFragInfo.psWriteMsg == NULL )
00736    {
00737       fRdyForWrMsg = TRUE;
00738    }
00739    ABCC_PORT_ExitCritical();
00740    return fRdyForWrMsg;
00741 }
00742 
00743 
00744 BOOL ABCC_DrvSpiIsReadyForCmd( void )
00745 {
00746    return ( pnABCC_DrvISReadyForWriteMessage() &&  ( spi_drv_bAnbCmdCnt > 0 ) );
00747 }
00748 
00749 
00750 void ABCC_DrvSpiSetNbrOfCmds( UINT8 bNbrOfCmds )
00751 {
00752    spi_drv_bNbrOfCmds = bNbrOfCmds;
00753 }
00754 
00755 
00756 void ABCC_DrvSpiSetAppStatus( ABP_AppStatusType eAppStatus )
00757 {
00758    spi_drv_bNextAppStatus = eAppStatus;
00759 }
00760 
00761 
00762 void ABCC_DrvSpiSetPdSize( const UINT16  iReadPdSize, const UINT16  iWritePdSize)
00763 {
00764    if( spi_drv_eState == SM_SPI_RDY_TO_SEND_MOSI )
00765    {
00766       /*
00767       ** Use the largest PD data size since the PD cannot be fragmented.
00768       */
00769       spi_drv_iWritePdSize = NUM_BYTES_2_WORDS( iWritePdSize );
00770       spi_drv_iReadPdSize = NUM_BYTES_2_WORDS( iReadPdSize );
00771 
00772       spi_drv_iPdSize = spi_drv_iWritePdSize;
00773       if( spi_drv_iReadPdSize > spi_drv_iWritePdSize )
00774       {
00775          spi_drv_iPdSize = spi_drv_iReadPdSize;
00776       }
00777 
00778       /*
00779       ** Update the CRC position and the total frame size since the process data
00780       ** size might have changed.
00781       */
00782       spi_drv_iCrcOffset = spi_drv_iPdOffset + spi_drv_iPdSize;
00783       spi_drv_iSpiFrameSize = SPI_FRAME_SIZE_EXCLUDING_DATA + spi_drv_iCrcOffset;
00784       spi_drv_sMosiFrame.iPdLen = iTOiLe( spi_drv_iPdSize );
00785    }
00786    else
00787    {
00788       ABCC_ERROR(ABCC_SEV_WARNING, ABCC_EC_SPI_OP_NOT_ALLOWED_DURING_SPI_TRANSACTION,0);
00789    }
00790 }
00791 
00792 static void DrvSpiSetMsgReceiverBuffer( ABP_MsgType* const psReadMsg )
00793 {
00794    if ( spi_drv_sReadFragInfo.puCurrPtr == NULL )
00795    {
00796       spi_drv_sReadFragInfo.psReadMsg = psReadMsg;
00797       spi_drv_sReadFragInfo.puCurrPtr = (UINT16*)psReadMsg;
00798       spi_drv_sReadFragInfo.iNumWordsReceived = 0;
00799    }
00800    else
00801    {
00802       ABCC_ERROR(ABCC_SEV_WARNING, ABCC_EC_SPI_OP_NOT_ALLOWED_DURING_SPI_TRANSACTION,0);
00803    }
00804 }
00805 
00806 
00807 UINT16 ABCC_DrvSpiGetIntStatus( void )
00808 {
00809    ABCC_ERROR(ABCC_SEV_FATAL, ABCC_EC_INTSTATUS_NOT_SUPPORTED_BY_DRV_IMPL, 0);
00810 
00811    return 0xFFFF;
00812 }
00813 
00814 
00815 UINT8 ABCC_DrvSpiGetAnybusState( void )
00816 {
00817    return spi_drv_bAnbStatus & 0x7;
00818 }
00819 
00820 
00821 void* ABCC_DrvSpiReadProcessData( void )
00822 {
00823    UINT8* pxRdPd = NULL;
00824 
00825    if(  spi_drv_eState == SM_SPI_RDY_TO_SEND_MOSI )
00826    {
00827       pxRdPd = spi_drv_bpRdPd;
00828    }
00829    return pxRdPd;
00830 }
00831 
00832 
00833 ABP_MsgType* ABCC_DrvSpiReadMessage( void )
00834 {
00835    ABP_MsgType* psRdMsg = NULL;
00836 
00837    if( spi_drv_eState == SM_SPI_RDY_TO_SEND_MOSI )
00838    {
00839       if ( spi_drv_psReadMessage != NULL )
00840       {
00841          psRdMsg = spi_drv_psReadMessage;
00842          spi_drv_psReadMessage = NULL;
00843      }
00844    }
00845    return psRdMsg;
00846 }
00847 
00848 void ABCC_DrvSpiSetIntMask( const UINT16 iIntMask )
00849 {
00850    spi_drv_bNextIntMask = (UINT8)iIntMask;
00851 }
00852 
00853 
00854 void* ABCC_DrvSpiGetWrPdBuffer( void )
00855 {
00856    return &spi_drv_sMosiFrame.iData[ spi_drv_iPdOffset ];
00857 }
00858 
00859 
00860 UINT16 ABCC_DrvSpiGetModCap( void )
00861 {
00862    ABCC_ERROR( ABCC_SEV_WARNING , ABCC_EC_MODCAP_NOT_SUPPORTED_BY_DRV_IMPL, 0);
00863    return 0;
00864 }
00865 
00866 UINT16 ABCC_DrvSpiGetLedStatus( void )
00867 {
00868    return spi_drv_iLedStatus;
00869 }
00870 
00871 BOOL ABCC_DrvSpiIsReadyForWrPd( void )
00872 {
00873    if ( spi_drv_eState == SM_SPI_RDY_TO_SEND_MOSI )
00874    {
00875       return TRUE;
00876    }
00877    return FALSE;
00878 }
00879 
00880 
00881 BOOL ABCC_DrvSpiIsSupervised( void )
00882 {
00883    /*
00884    ** The Anybus supervision bis is stored in bit 3
00885    */
00886    return  ( spi_drv_bAnbStatus  >> 3 ) & 1;
00887 }
00888 
00889 UINT8 ABCC_DrvSpiGetAnbStatus( void )
00890 {
00891    return (UINT8)spi_drv_bAnbStatus & 0xf;
00892 }
00893 
00894 
00895 #endif
00896 
00897 
00898 
00899 
00900 
00901 /*******************************************************************************
00902 ** End of spi_drv.c
00903 ********************************************************************************
00904 */