Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 */
Generated on Tue Jul 12 2022 15:51:56 by
