/****************************************************************************** * * Freescale Semiconductor Inc. * (c) Copyright 2004-2006 Freescale Semiconductor, Inc. * (c) Copyright 2001-2004 Motorola, Inc. * ALL RIGHTS RESERVED. * ****************************************************************************//*! * * @file PE_freemaster_sfio.c * * @brief FreeMASTER SFIO (Matlab/Simulink interface) encapsulation handler * * @version 1.0.2.0 * * @date Aug-17-2006 * ******************************************************************************* * * This file contains the SFIO communication handler and enables the SFIO tool * to run over FreeMASTER. For more information, see Freescale SFIO documentation. * *******************************************************************************/ #include "PE_freemaster.h" #include "PE_freemaster_private.h" #include "PE_freemaster_protocol.h" #if FMSTR_USE_SFIO /* the sfiolib needs to be added to the project */ #include "sfiolib.h" /*********************************** * local variables ***********************************/ static FMSTR_U8 pcm_nSfioRespLen; /* recorder runtime flags */ static volatile union { FMSTR_FLAGS all; struct { unsigned bEvenRun : 1; /* last command executed was the even one */ unsigned bLastOK : 1; /* last command executed properly */ } flg; } pcm_wSfioFlags; /**************************************************************************//*! * * @brief Initialization of SFIO communication layer * ******************************************************************************/ void FMSTR_InitSfio(void) { pcm_wSfioFlags.all = 0; } /**************************************************************************//*! * * @brief Handling SFIOFRAME (even and odd) commands * * @param pMessageIO - original command (in) and response buffer (out) * * @note This function handles the SFIO (Matlab/Simulink Interface) command * encapsulated into FreeMASTER protocol. It emulates the SFIO serial * char-by-char communication. * ******************************************************************************/ 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 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); } /**************************************************************************//*! * * @brief Handling SFIOGETRESP (even and odd) commands * * @param pMessageIO - original command (in) and response buffer (out) * * @note This function handles the retried request for the last SFIO response. * PC may request this retry when the last frame execution took too long * (e.g. due to breakpoint) but is still finished properly. The original * SFIOFRAME command returned timeout, so the PC will use SFIOGETRESP * to finish data. * * The even/odd matching is here to have some dgree of robustness for * a case when SFIOFRAME packet gets lost without ever reaching SFIO engine. * Without any checking, the SFIOGETRESP would just blindly return the * pre-last result and would definietelly cause Simulink problems. * Having the check implemented, the PC can determine the even/odd mismatch * and may re-send the last SFIOFRAME command. * ******************************************************************************/ 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); } #endif /* FMSTR_USE_SFIO */