FMSTR_BPTR FMSTR_SetUpScope(FMSTR_BPTR pMessageIO) { FMSTR_BPTR pResponse = pMessageIO; FMSTR_U8 i, sz, nVarCnt; /* uninitialize scope */ pcm_nScopeVarCount = 0U; /* seek the setup data */ pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 2U); /* scope variable count */ pMessageIO = FMSTR_ValueFromBuffer8(&nVarCnt, pMessageIO); /* scope variable information must fit into our buffers */ if(!nVarCnt || nVarCnt > (FMSTR_U8)FMSTR_MAX_SCOPE_VARS) { return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_INVBUFF); } /* get all addresses and sizes */ for(i=0U; i<nVarCnt; i++) { /* variable size */ pMessageIO = FMSTR_ValueFromBuffer8(&sz, pMessageIO); pcm_pScopeVarSize[i] = sz; /* variable address */ pMessageIO = FMSTR_AddressFromBuffer(&pcm_pScopeVarAddr[i], pMessageIO); /* valid numeric variable sizes only */ if(sz == 0U || sz > 8U) { return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_INVSIZE); } #if FMSTR_CFG_BUS_WIDTH > 1U /* even sizes only */ if(sz & 0x1) { return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_INVSIZE); } #endif #if FMSTR_USE_TSA && FMSTR_USE_TSA_SAFETY if(!FMSTR_CheckTsaSpace(pcm_pScopeVarAddr[i], (FMSTR_SIZE8) sz, 0U)) { return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_EACCESS); } #endif } /* activate scope */ pcm_nScopeVarCount = nVarCnt; /* return just a status */ return FMSTR_ConstToBuffer8(pResponse, FMSTR_STS_OK); }
static void FMSTR_RxDone(void) { /* frame really here? */ if(!pcm_wFlags.flg.bRxFrameReady) return ; /* acknowledge the flag, we're going to process the frame now */ pcm_wFlags.flg.bRxFrameReady = 0U; /* any fragmentation error detected during the receive process? */ if(!pcm_nRxErr) { /* check for our standard frame errors */ /* checksum should be zero */ if(pcm_nRxCheckSum) { pcm_nRxErr = FMSTR_STC_CMDCSERR; } /* checksum okay, check frame length */ else { FMSTR_BPTR pFrame = pcm_pCommBuffer; FMSTR_BCHR len; pFrame = FMSTR_ValueFromBuffer8(&len, pFrame); /* fast command? */ if((len & FMSTR_FASTCMD) == FMSTR_FASTCMD) { /* get length */ len = (FMSTR_BCHR)((len & FMSTR_FASTCMD_DATALEN_MASK) >> FMSTR_FASTCMD_DATALEN_SHIFT); /* add command-byte and checksum (are included in the nRxCtr) */ len += 2; } /* std command */ else { /* get length */ pFrame = FMSTR_ValueFromBuffer8(&len, pFrame); /* add command-byte, length and checksum (are included in the nRxCtr) */ len += 3; } /* now the len received should match the data bytes received */ if(pcm_nRxCtr != len) pcm_nRxErr = FMSTR_STC_CMDCSERR; }
FMSTR_BPTR FMSTR_WriteMemMask(FMSTR_BPTR pMessageIO) { FMSTR_BPTR pResponse = pMessageIO; FMSTR_ADDR nAddr; FMSTR_U8 nSize,nResponseCode; pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 2U); pMessageIO = FMSTR_ValueFromBuffer8(&nSize, pMessageIO); pMessageIO = FMSTR_AddressFromBuffer(&nAddr, pMessageIO); #if FMSTR_USE_TSA && FMSTR_USE_TSA_SAFETY if(!FMSTR_CheckTsaSpace(nAddr, (FMSTR_SIZE8)nSize, FMSTR_TRUE)) { nResponseCode = FMSTR_STC_EACCESS; goto FMSTR_WriteMemMask_exit; } #endif #if FMSTR_CFG_BUS_WIDTH > 1U /* size must be divisible by bus width (mask must not begin in half of memory word) */ if(nSize % FMSTR_CFG_BUS_WIDTH) { nResponseCode = FMSTR_STC_INVSIZE; goto FMSTR_WriteMemMask_exit; } #endif /* put the data */ FMSTR_CopyFromBufferWithMask(nAddr, pMessageIO, (FMSTR_SIZE8)nSize); nResponseCode = FMSTR_STS_OK; //FMSTR_WriteMemMask_exit: return FMSTR_ConstToBuffer8(pResponse, nResponseCode); }
FMSTR_BPTR FMSTR_WriteMem(FMSTR_BPTR pMessageIO) { FMSTR_BPTR pResponse = pMessageIO; FMSTR_ADDR nAddr; FMSTR_U8 nSize,nResponseCode; pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 2U); pMessageIO = FMSTR_ValueFromBuffer8(&nSize, pMessageIO); pMessageIO = FMSTR_AddressFromBuffer(&nAddr, pMessageIO); #if FMSTR_USE_TSA && FMSTR_USE_TSA_SAFETY if(!FMSTR_CheckTsaSpace(nAddr, (FMSTR_SIZE8) nSize, FMSTR_TRUE)) { nResponseCode = FMSTR_STC_EACCESS; goto FMSTR_WriteMem_exit; } #endif /*lint -e{534} ignoring function return value */ FMSTR_CopyFromBuffer(nAddr, pMessageIO, (FMSTR_SIZE8) nSize); nResponseCode = FMSTR_STS_OK; //FMSTR_WriteMem_exit: return FMSTR_ConstToBuffer8(pResponse, nResponseCode); }
FMSTR_BPTR FMSTR_ReadMem(FMSTR_BPTR pMessageIO) { FMSTR_BPTR pResponse = pMessageIO; FMSTR_ADDR nAddr; FMSTR_U8 nSize; pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 2U); pMessageIO = FMSTR_ValueFromBuffer8(&nSize, pMessageIO); pMessageIO = FMSTR_AddressFromBuffer(&nAddr, pMessageIO); #if FMSTR_USE_TSA && FMSTR_USE_TSA_SAFETY if(!FMSTR_CheckTsaSpace(nAddr, (FMSTR_SIZE8) nSize, FMSTR_FALSE)) { return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_EACCESS); } #endif /* check the response will safely fit into comm buffer */ if(nSize > (FMSTR_U8)FMSTR_COMM_BUFFER_SIZE) { return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_RSPBUFFOVF); } /* success */ pResponse = FMSTR_ConstToBuffer8(pResponse, FMSTR_STS_OK); return FMSTR_CopyToBuffer(pResponse, nAddr, (FMSTR_SIZE8) nSize); }
FMSTR_BPTR FMSTR_SfioGetResp(FMSTR_BPTR pMessageIO) { FMSTR_U8 nByte; /* get command and determine if it is even/odd */ FMSTR_ValueFromBuffer8(&nByte, pMessageIO); /* last command must have been finished propely */ if(!pcm_wSfioFlags.flg.bLastOK) return FMSTR_ConstToBuffer8(pMessageIO, FMSTR_STC_SFIOERR); /* only respond to "matching" request (even to even, odd to odd) */ if(nByte & 1) { if(pcm_wSfioFlags.flg.bEvenRun) return FMSTR_ConstToBuffer8(pMessageIO, FMSTR_STC_SFIOUNMATCH); } else { if(!pcm_wSfioFlags.flg.bEvenRun) return FMSTR_ConstToBuffer8(pMessageIO, FMSTR_STC_SFIOUNMATCH); } /* SFIO response to return */ pMessageIO = FMSTR_ConstToBuffer8(pMessageIO, FMSTR_STS_OK | FMSTR_STSF_VARLEN); pMessageIO = FMSTR_ValueToBuffer8(pMessageIO, pcm_nSfioRespLen); return FMSTR_CopyToBuffer(pMessageIO, (FMSTR_ADDR) SFIO_GetOutputBuffer(), pcm_nSfioRespLen); }
FMSTR_BPTR FMSTR_StoreAppCmd(FMSTR_BPTR pMessageIO) { FMSTR_BPTR pResponse = pMessageIO; FMSTR_U8 nArgsLen; FMSTR_U8 nCode; /* the previous command not yet processed */ if(pcm_nAppCmd != FMSTR_APPCMDRESULT_NOCMD) { return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_SERVBUSY); } pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 1U); pMessageIO = FMSTR_ValueFromBuffer8(&nArgsLen, pMessageIO); pMessageIO = FMSTR_ValueFromBuffer8(&nCode, pMessageIO); /* args len is datalen minus one */ nArgsLen--; /* does the application command fit to buffer ? */ if (nArgsLen > (FMSTR_SIZE8) FMSTR_APPCMD_BUFF_SIZE) { return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_INVBUFF); } /* store command data into dedicated buffer */ pcm_nAppCmd = nCode; pcm_nAppCmdLen = nArgsLen; /* data copy */ if(nArgsLen) { FMSTR_ADDR appCmdBuffAddr; FMSTR_ARR2ADDR(appCmdBuffAddr, pcm_pAppCmdBuff); /*lint -e{534} ignoring return value */ FMSTR_CopyFromBuffer(appCmdBuffAddr, pMessageIO, (FMSTR_SIZE8) nArgsLen); } /* mark command as "running" (without any response data) */ pcm_nAppCmdResult = FMSTR_APPCMDRESULT_RUNNING; pcm_nAppCmdResultDataLen = 0U; return FMSTR_ConstToBuffer8(pResponse, FMSTR_STS_OK); }
FMSTR_BPTR FMSTR_GetAppCmdRespData(FMSTR_BPTR pMessageIO) { FMSTR_BPTR pResponse = pMessageIO; FMSTR_U8 nDataLen; FMSTR_U8 nDataOffset; /* the previous command not yet processed */ if(pcm_nAppCmd != FMSTR_APPCMDRESULT_NOCMD) { return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_SERVBUSY); } pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 1U); pMessageIO = FMSTR_ValueFromBuffer8(&nDataLen, pMessageIO); pMessageIO = FMSTR_ValueFromBuffer8(&nDataOffset, pMessageIO); /* the response would not fit into comm buffer */ if(nDataLen > (FMSTR_U16)FMSTR_COMM_BUFFER_SIZE) { return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_RSPBUFFOVF); } /* the data would be fetched outside the app.cmd response data */ if((((FMSTR_U16)nDataOffset) + nDataLen) > (FMSTR_SIZE8)pcm_nAppCmdResultDataLen) { return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_INVSIZE); } pResponse = FMSTR_ConstToBuffer8(pResponse, FMSTR_STS_OK); /* copy to buffer */ { FMSTR_ADDR appCmdBuffAddr; FMSTR_ARR2ADDR(appCmdBuffAddr, pcm_pAppCmdBuff); pResponse = FMSTR_CopyToBuffer(pResponse, appCmdBuffAddr, (FMSTR_SIZE8)nDataLen); } return pResponse; }
FMSTR_BPTR FMSTR_SfioFrame(FMSTR_BPTR pMessageIO) { FMSTR_BPTR pResponse = pMessageIO; FMSTR_U8 i, nFrameLen, nByte; SFIO_U16 nRet = 0; /* get command and remember if it was even/odd */ pMessageIO = FMSTR_ValueFromBuffer8(&nByte, pMessageIO); pcm_wSfioFlags.flg.bEvenRun = (nByte & 1) ? 0 : 1; pcm_wSfioFlags.flg.bLastOK = 0; /* get data length */ pMessageIO = FMSTR_ValueFromBuffer8(&nFrameLen, pMessageIO); /* feed the SFIO engine byte-by-byte */ for(i=0; nRet == 0 && i<nFrameLen; i++) { pMessageIO = FMSTR_ValueFromBuffer8(&nByte, pMessageIO); nRet = SFIO_ProcessRecievedChar(nByte); } /* frame not handled or handled prematurely */ if(!nRet || i < nFrameLen) return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_SFIOERR); /* how much data to return? */ if(nRet > FMSTR_COMM_BUFFER_SIZE) return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_RSPBUFFOVF); /* remember this command had executed properly */ pcm_nSfioRespLen = (FMSTR_U8) nRet; pcm_wSfioFlags.flg.bLastOK = 1; /* SFIO response to return */ pResponse = FMSTR_ConstToBuffer8(pResponse, FMSTR_STS_OK | FMSTR_STSF_VARLEN); pResponse = FMSTR_ValueToBuffer8(pResponse, pcm_nSfioRespLen); return FMSTR_CopyToBuffer(pResponse, (FMSTR_ADDR) SFIO_GetOutputBuffer(), pcm_nSfioRespLen); }
void FMSTR_SendResponse(FMSTR_BPTR pResponse, FMSTR_SIZE8 nLength) { FMSTR_U16 chSum = 0U; FMSTR_U8 i, c; /* remember the buffer to be sent */ pcm_pTxBuff = pResponse; /* status byte and data are already there, compute checksum only */ for (i=0U; i<nLength; i++) { c = 0U; pResponse = FMSTR_ValueFromBuffer8(&c, pResponse); /* add character to checksum */ chSum += c; /* prevent saturation to happen on DSP platforms */ chSum &= 0xffU; } /* store checksum after the message */ pResponse = FMSTR_ValueToBuffer8(pResponse, (FMSTR_U8) (((FMSTR_U16)~(chSum)) + 1U)); /* send the message and the checksum */ pcm_nTxTodo = (FMSTR_SIZE8) (nLength + 1U); /* now transmitting the response */ pcm_wFlags.flg.bTxActive = 1U; pcm_wFlags.flg.bTxFirst = 1U; /* enable TX interrupt */ #if FMSTR_LONG_INTR || FMSTR_SHORT_INTR FMSTR_CAN_ETXI(); #endif #if (FMSTR_SHORT_INTR) && ((FMSTR_USE_FLEXCAN) || (FMSTR_USE_FLEXCAN32)) FMSTR_ProcessCanTx(); #endif }
FMSTR_BOOL FMSTR_ProtocolDecoder(FMSTR_BPTR pMessageIO) { FMSTR_BPTR pResponseEnd; FMSTR_U8 nCmd; /* no EX access by default */ FMSTR_SetExAddr(FMSTR_FALSE); /* command code comes first in the message */ /*lint -e{534} return value is not used */ FMSTR_ValueFromBuffer8(&nCmd, pMessageIO); /* process command */ switch (nCmd) { #if FMSTR_USE_READVAR /* read byte */ #if FMSTR_USE_EX_CMDS case FMSTR_CMD_READVAR8_EX: FMSTR_SetExAddr(FMSTR_TRUE); #endif #if FMSTR_USE_NOEX_CMDS /*lint -fallthrough */ case FMSTR_CMD_READVAR8: #endif pResponseEnd = FMSTR_ReadVar(pMessageIO, 1U); break; /* read word */ #if FMSTR_USE_EX_CMDS case FMSTR_CMD_READVAR16_EX: FMSTR_SetExAddr(FMSTR_TRUE); #endif #if FMSTR_USE_NOEX_CMDS /*lint -fallthrough */ case FMSTR_CMD_READVAR16: #endif pResponseEnd = FMSTR_ReadVar(pMessageIO, 2U); break; /* read dword */ #if FMSTR_USE_EX_CMDS case FMSTR_CMD_READVAR32_EX: FMSTR_SetExAddr(FMSTR_TRUE); #endif #if FMSTR_USE_NOEX_CMDS /*lint -fallthrough */ case FMSTR_CMD_READVAR32: #endif pResponseEnd = FMSTR_ReadVar(pMessageIO, 4U); break; #endif /* FMSTR_USE_READVAR */ #if FMSTR_USE_READMEM /* read a block of memory */ #if FMSTR_USE_EX_CMDS case FMSTR_CMD_READMEM_EX: FMSTR_SetExAddr(FMSTR_TRUE); #endif #if FMSTR_USE_NOEX_CMDS /*lint -fallthrough */ case FMSTR_CMD_READMEM: #endif pResponseEnd = FMSTR_ReadMem(pMessageIO); break; #endif /* FMSTR_USE_READMEM */ #if FMSTR_USE_SCOPE /* prepare scope variables */ #if FMSTR_USE_EX_CMDS case FMSTR_CMD_SETUPSCOPE_EX: FMSTR_SetExAddr(FMSTR_TRUE); #endif #if FMSTR_USE_NOEX_CMDS /*lint -fallthrough */ case FMSTR_CMD_SETUPSCOPE: #endif pResponseEnd = FMSTR_SetUpScope(pMessageIO); break; case FMSTR_CMD_READSCOPE: pResponseEnd = FMSTR_ReadScope(pMessageIO); break; #endif /* FMSTR_USE_SCOPE */ #if FMSTR_USE_RECORDER /* get recorder status */ case FMSTR_CMD_GETRECSTS: pResponseEnd = FMSTR_GetRecStatus(pMessageIO); break; /* start recorder */ case FMSTR_CMD_STARTREC: pResponseEnd = FMSTR_StartRec(pMessageIO); break; /* stop recorder */ case FMSTR_CMD_STOPREC: pResponseEnd = FMSTR_StopRec(pMessageIO); break; /* setup recorder */ #if FMSTR_USE_EX_CMDS case FMSTR_CMD_SETUPREC_EX: FMSTR_SetExAddr(FMSTR_TRUE); #endif #if FMSTR_USE_NOEX_CMDS /*lint -fallthrough */ case FMSTR_CMD_SETUPREC: #endif pResponseEnd = FMSTR_SetUpRec(pMessageIO); break; /* get recorder buffer information (force EX instead of non-EX) */ #if FMSTR_USE_EX_CMDS case FMSTR_CMD_GETRECBUFF_EX: FMSTR_SetExAddr(FMSTR_TRUE); #elif FMSTR_USE_NOEX_CMDS /*lint -fallthrough */ case FMSTR_CMD_GETRECBUFF: #endif pResponseEnd = FMSTR_GetRecBuff(pMessageIO); break; #endif /* FMSTR_USE_RECORDER */ #if FMSTR_USE_APPCMD /* accept the application command */ case FMSTR_CMD_SENDAPPCMD: pResponseEnd = FMSTR_StoreAppCmd(pMessageIO); break; /* get the application command status */ case FMSTR_CMD_GETAPPCMDSTS: pResponseEnd = FMSTR_GetAppCmdStatus(pMessageIO); break; /* get the application command data */ case FMSTR_CMD_GETAPPCMDDATA: pResponseEnd = FMSTR_GetAppCmdRespData(pMessageIO); break; #endif /* FMSTR_USE_APPCMD */ #if FMSTR_USE_WRITEMEM /* write a block of memory */ #if FMSTR_USE_EX_CMDS case FMSTR_CMD_WRITEMEM_EX: FMSTR_SetExAddr(FMSTR_TRUE); #endif #if FMSTR_USE_NOEX_CMDS /*lint -fallthrough */ case FMSTR_CMD_WRITEMEM: #endif pResponseEnd = FMSTR_WriteMem(pMessageIO); break; #endif /* FMSTR_USE_WRITEMEM */ #if FMSTR_USE_WRITEMEMMASK /* write block of memory with a bit mask */ #if FMSTR_USE_EX_CMDS case FMSTR_CMD_WRITEMEMMASK_EX: FMSTR_SetExAddr(FMSTR_TRUE); #endif #if FMSTR_USE_NOEX_CMDS /*lint -fallthrough */ case FMSTR_CMD_WRITEMEMMASK: #endif pResponseEnd = FMSTR_WriteMemMask(pMessageIO); break; #endif /* FMSTR_USE_WRITEMEMMASK */ #if FMSTR_USE_WRITEVAR && FMSTR_USE_NOEX_CMDS /* write byte */ case FMSTR_CMD_WRITEVAR8: pResponseEnd = FMSTR_WriteVar(pMessageIO, 1U); break; /* write word */ case FMSTR_CMD_WRITEVAR16: pResponseEnd = FMSTR_WriteVar(pMessageIO, 2U); break; /* write dword */ case FMSTR_CMD_WRITEVAR32: pResponseEnd = FMSTR_WriteVar(pMessageIO, 4U); break; #endif /* FMSTR_USE_WRITEVAR && FMSTR_USE_NOEX_CMDS */ #if FMSTR_USE_WRITEVARMASK && FMSTR_USE_NOEX_CMDS /* write byte with mask */ case FMSTR_CMD_WRITEVAR8MASK: pResponseEnd = FMSTR_WriteVarMask(pMessageIO, 1U); break; /* write word with mask */ case FMSTR_CMD_WRITEVAR16MASK: pResponseEnd = FMSTR_WriteVarMask(pMessageIO, 2U); break; #endif /* FMSTR_USE_WRITEVARMASK && FMSTR_USE_NOEX_CMDS */ #if FMSTR_USE_TSA /* get TSA table (force EX instead of non-EX) */ #if FMSTR_USE_EX_CMDS case FMSTR_CMD_GETTSAINFO_EX: FMSTR_SetExAddr(FMSTR_TRUE); #elif FMSTR_USE_NOEX_CMDS /*lint -fallthrough */ case FMSTR_CMD_GETTSAINFO: #endif pResponseEnd = FMSTR_GetTsaInfo(pMessageIO); break; #if FMSTR_USE_EX_CMDS case FMSTR_CMD_GETSTRLEN_EX: FMSTR_SetExAddr(FMSTR_TRUE); #endif #if FMSTR_USE_NOEX_CMDS /*lint -fallthrough */ case FMSTR_CMD_GETSTRLEN: #endif pResponseEnd = FMSTR_GetStringLen(pMessageIO); break; #endif /* FMSTR_USE_TSA */ #if FMSTR_USE_BRIEFINFO /* retrieve a subset of board information structure */ case FMSTR_CMD_GETINFOBRIEF: #else /* retrieve board information structure */ case FMSTR_CMD_GETINFO: #endif pResponseEnd = FMSTR_GetBoardInfo(pMessageIO); break; #if FMSTR_USE_SFIO case FMSTR_CMD_SFIOFRAME_0: case FMSTR_CMD_SFIOFRAME_1: pResponseEnd = FMSTR_SfioFrame(pMessageIO); break; case FMSTR_CMD_SFIOGETRESP_0: case FMSTR_CMD_SFIOGETRESP_1: pResponseEnd = FMSTR_SfioGetResp(pMessageIO); break; #endif /* FMSTR_USE_SFIO */ #if FMSTR_USE_PIPES case FMSTR_CMD_PIPE: pResponseEnd = FMSTR_PipeFrame(pMessageIO); break; #endif /* FMSTR_USE_PIPES */ /* unknown command */ default: pResponseEnd = FMSTR_ConstToBuffer8(pMessageIO, FMSTR_STC_INVCMD); break; } /* anything to send back? */ if(pResponseEnd != pMessageIO) { /*lint -e{946,960} subtracting pointers is appropriate here */ FMSTR_SIZE8 nSize = (FMSTR_SIZE8)(pResponseEnd - pMessageIO); FMSTR_SendResponse(pMessageIO, nSize); return FMSTR_TRUE; } else { /* nothing sent out */ return FMSTR_FALSE; } }
FMSTR_BPTR FMSTR_SetUpRec(FMSTR_BPTR pMessageIO) { FMSTR_BPTR pResponse = pMessageIO; FMSTR_SIZE8 nRecVarsetSize; FMSTR_SIZE blen; FMSTR_U8 i, sz; FMSTR_U8 nResponseCode; /* de-initialize first */ FMSTR_AbortRec(); #if FMSTR_REC_OWNBUFF /* user wants to use his own buffer, check if it is valid */ if(!pcm_nRecBuffAddr || !pcm_wRecBuffSize) { return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_INVBUFF); } #elif (FMSTR_USE_FASTREC) == 0 /* size in native sizeof units (=bytes on most platforms) */ FMSTR_ARR2ADDR(pcm_nRecBuffAddr, pcm_pOwnRecBuffer); #endif /* seek the setup data */ #if (FMSTR_USE_FASTREC) == 0 pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 2U); pMessageIO = FMSTR_ValueFromBuffer8(&pcm_nRecTriggerMode, pMessageIO); #else /* (FMSTR_USE_FASTREC) == 0 */ pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 3U); #endif /* (FMSTR_USE_FASTREC) == 0 */ pMessageIO = FMSTR_ValueFromBuffer16(&pcm_wRecTotalSmps, pMessageIO); #if (FMSTR_REC_STATIC_POSTTRIG) == 0 pMessageIO = FMSTR_ValueFromBuffer16(&pcm_wRecPostTrigger, pMessageIO); #else /* (FMSTR_REC_STATIC_POSTTRIG) == 0 */ pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 2U); #endif /* (FMSTR_REC_STATIC_POSTTRIG) == 0 */ #if (FMSTR_REC_STATIC_DIVISOR) == 0 pMessageIO = FMSTR_ValueFromBuffer16(&pcm_wRecTimeDiv, pMessageIO); #else /* (FMSTR_REC_STATIC_DIVISOR) == 0 */ pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 2U); #endif /* (FMSTR_REC_STATIC_DIVISOR) == 0 */ #if (FMSTR_USE_FASTREC) == 0 /* address & size of trigger variable */ pMessageIO = FMSTR_AddressFromBuffer(&pcm_nTrgVarAddr, pMessageIO); pMessageIO = FMSTR_ValueFromBuffer8(&pcm_nTrgVarSize, pMessageIO); /* trigger compare mode */ pMessageIO = FMSTR_ValueFromBuffer8(&pcm_bTrgVarSigned, pMessageIO); /* threshold value */ pMessageIO = FMSTR_ValueFromBuffer32(&pcm_uTrgThreshold.u32, pMessageIO); #else /* (FMSTR_USE_FASTREC) == 0 */ pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 8U); #endif /* (FMSTR_USE_FASTREC) == 0 */ /* recorder variable count */ pMessageIO = FMSTR_ValueFromBuffer8(&pcm_nRecVarCount, pMessageIO); /* rec variable information must fit into our buffers */ if(!pcm_nRecVarCount || pcm_nRecVarCount > (FMSTR_U8)FMSTR_MAX_REC_VARS) { #if FMSTR_REC_COMMON_ERR_CODES goto FMSTR_SetUpRec_exit_error; #else nResponseCode = FMSTR_STC_INVBUFF; goto FMSTR_SetUpRec_exit; #endif } /* calculate sum of sizes of all variables */ nRecVarsetSize = 0U; /* get all addresses and sizes */ for(i=0U; i<pcm_nRecVarCount; i++) { /* variable size */ pMessageIO = FMSTR_ValueFromBuffer8(&sz, pMessageIO); pcm_pRecVarSize[i] = sz; nRecVarsetSize += sz; /* variable address */ pMessageIO = FMSTR_AddressFromBuffer(&pcm_pRecVarAddr[i], pMessageIO); /* valid numeric variable sizes only */ if(sz == 0U || sz > 8U) { #if FMSTR_REC_COMMON_ERR_CODES goto FMSTR_SetUpRec_exit_error; #else nResponseCode = FMSTR_STC_INVSIZE; goto FMSTR_SetUpRec_exit; #endif } #if FMSTR_CFG_BUS_WIDTH > 1U /* even sizes only */ if(sz & 0x1) { #if FMSTR_REC_COMMON_ERR_CODES goto FMSTR_SetUpRec_exit_error; #else nResponseCode = FMSTR_STC_INVSIZE; goto FMSTR_SetUpRec_exit; #endif } #endif /* FMSTR_CFG_BUS_WIDTH > 1U */ #if FMSTR_USE_TSA && FMSTR_USE_TSA_SAFETY if(!FMSTR_CheckTsaSpace(pcm_pRecVarAddr[i], (FMSTR_SIZE8)sz, 0U)) { #if FMSTR_REC_COMMON_ERR_CODES goto FMSTR_SetUpRec_exit_error; #else nResponseCode = FMSTR_STC_EACCESS; goto FMSTR_SetUpRec_exit; #endif } #endif /* FMSTR_USE_TSA && FMSTR_USE_TSA_SAFETY */ } /* fast recorder handles trigger by itself */ #if (FMSTR_USE_FASTREC) == 0 /* any trigger? */ pcm_pCompareFunc = NULL; if(pcm_nRecTriggerMode) { /* access to trigger variable? */ #if FMSTR_USE_TSA && FMSTR_USE_TSA_SAFETY if(!FMSTR_CheckTsaSpace(pcm_nTrgVarAddr, (FMSTR_SIZE8)pcm_nTrgVarSize, 0U)) { #if FMSTR_REC_COMMON_ERR_CODES goto FMSTR_SetUpRec_exit_error; #else nResponseCode = FMSTR_STC_EACCESS; goto FMSTR_SetUpRec_exit; #endif } #endif /* FMSTR_USE_TSA && FMSTR_USE_TSA_SAFETY */ /* get compare function */ #if FMSTR_REC_FLOAT_TRIG if(pcm_bTrgVarSigned&FMSTR_REC_FLOAT_TRIG_MASK) { pcm_pCompareFunc = FMSTR_Comparefloat; } else #else if(pcm_bTrgVarSigned&FMSTR_REC_FLOAT_TRIG_MASK) { #if FMSTR_REC_COMMON_ERR_CODES goto FMSTR_SetUpRec_exit_error; #else nResponseCode = FMSTR_STC_FLOATDISABLED; goto FMSTR_SetUpRec_exit; #endif } #endif { switch(pcm_nTrgVarSize) { #if FMSTR_CFG_BUS_WIDTH == 1U case 1: pcm_pCompareFunc = pcm_bTrgVarSigned ? FMSTR_Compare8S : FMSTR_Compare8U; break; #endif case 2: pcm_pCompareFunc = pcm_bTrgVarSigned ? FMSTR_Compare16S : FMSTR_Compare16U; break; case 4: pcm_pCompareFunc = pcm_bTrgVarSigned ? FMSTR_Compare32S : FMSTR_Compare32U; break; /* invalid trigger variable size */ default: #if FMSTR_REC_COMMON_ERR_CODES goto FMSTR_SetUpRec_exit_error; #else nResponseCode = FMSTR_STC_INVSIZE; goto FMSTR_SetUpRec_exit; #endif } } } #endif /* (FMSTR_USE_FASTREC) == 0 */ /* total recorder buffer length in native sizeof units (=bytes on most platforms) */ blen = (FMSTR_SIZE) (pcm_wRecTotalSmps * nRecVarsetSize / FMSTR_CFG_BUS_WIDTH); /* recorder memory available? */ if(blen > FMSTR_GetRecBuffSize()) { #if FMSTR_REC_COMMON_ERR_CODES goto FMSTR_SetUpRec_exit_error; #else nResponseCode = FMSTR_STC_INVSIZE; goto FMSTR_SetUpRec_exit; #endif } #if (FMSTR_USE_FASTREC) == 0 /* remember the effective end of circular buffer */ pcm_dwRecEndBuffPtr = pcm_nRecBuffAddr + blen; #endif /* (FMSTR_USE_FASTREC) == 0 */ #if FMSTR_USE_FASTREC if(!FMSTR_SetUpFastRec()) { #if FMSTR_REC_COMMON_ERR_CODES goto FMSTR_SetUpRec_exit_error; #else /* FMSTR_REC_COMMON_ERR_CODES */ nResponseCode = FMSTR_STC_FASTRECERR; goto FMSTR_SetUpRec_exit; #endif /* FMSTR_REC_COMMON_ERR_CODES */ } #endif /* FMSTR_USE_FASTREC */ /* everything is okay */ pcm_wRecFlags.flg.bIsConfigured = 1U; nResponseCode = FMSTR_STS_OK; #if FMSTR_REC_COMMON_ERR_CODES goto FMSTR_SetUpRec_exit; FMSTR_SetUpRec_exit_error: nResponseCode = FMSTR_STC_INVSIZE; #endif FMSTR_SetUpRec_exit: return FMSTR_ConstToBuffer8(pResponse, nResponseCode); }
FMSTR_BOOL FMSTR_TxCan(void) { FMSTR_U8 ch; FMSTR_CAN_TCTX tctx; FMSTR_SIZE8 len = pcm_nTxTodo; if(!pcm_wFlags.flg.bTxActive || !pcm_nTxTodo) return FMSTR_FALSE; if(len > 7) len = 7; /* first byte is control */ if(pcm_wFlags.flg.bTxFirst) { /* the first frame and the length*/ pcm_uTxCtlByte = (FMSTR_U8) (FMSTR_CANCTL_FST | len); pcm_uTxFrmCtr = 0U; pcm_wFlags.flg.bTxFirst = 0U; } else { /* the next frame */ pcm_uTxCtlByte &= ~(FMSTR_CANCTL_FST | FMSTR_CANCTL_LEN_MASK); pcm_uTxCtlByte ^= FMSTR_CANCTL_TGL; pcm_uTxCtlByte |= len; pcm_uTxFrmCtr++; } /* prepare transmit buffer */ FMSTR_CAN_TCFG(&tctx); /* set transmit priority and ID */ FMSTR_CAN_TPRI(&tctx, pcm_uTxFrmCtr); FMSTR_CAN_TID(&tctx, FMSTR_CAN_RESPID_IDR0, FMSTR_CAN_RESPID_IDR1, FMSTR_CAN_RESPID_IDR2, FMSTR_CAN_RESPID_IDR3); /* is it the last frame? */ pcm_nTxTodo -= len; if(!pcm_nTxTodo) pcm_uTxCtlByte |= FMSTR_CANCTL_LST; /* set frame len */ FMSTR_CAN_TLEN(&tctx, (FMSTR_U8) (len+1)); /* put control byte */ FMSTR_CAN_PUTBYTE(&tctx, pcm_uTxCtlByte); /* put data part */ while(len--) { pcm_pTxBuff = FMSTR_ValueFromBuffer8(&ch, pcm_pTxBuff); FMSTR_CAN_PUTBYTE(&tctx, ch); } /* submit frame for transmission */ FMSTR_CAN_TX(&tctx); /* if the full frame is safe in tx buffer(s), release the received command */ if(!pcm_nTxTodo) { /* no more transmitting */ pcm_wFlags.flg.bTxActive = 0U; /* start listening immediately (also frees the last received frame) */ FMSTR_Listen(); } /* returning TRUE, frame was sent */ return FMSTR_TRUE; }