⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 freemaster_serial.c

📁 BCM 控制demo源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        else
        {
            pcm_wFlags.flg.bRxLastCharSOB = 1;
            return;
        }
    }
    
    // we have got a common character preceeded by the SOB - 
    // this is the command code!
    if(pcm_wFlags.flg.bRxLastCharSOB)
    {
        // reset reciving process
        pcm_pRxBuff = pcm_pCommBuffer;
        *pcm_pRxBuff++ = nRxChar;
        
        // start computing the checksum
        pcm_nRxCheckSum = nRxChar;
        pcm_nRxTodo = 0;

        // fast command?
        if((nRxChar & FMSTR_FASTCMD) == FMSTR_FASTCMD)
        {
            // there will be no length information
            pcm_wFlags.flg.bRxMsgLengthNext = 0;
            // as it is encoded in the command byte directly
            pcm_nRxTodo = ((nRxChar & FMSTR_FASTCMD_DATALEN_MASK) >> FMSTR_FASTCMD_DATALEN_SHIFT) + 1;
        }
        // standard command
        else
        {
            // the message length will come in next byte
            pcm_wFlags.flg.bRxMsgLengthNext = 1;
        }

        // command code stored & processed
        pcm_wFlags.flg.bRxLastCharSOB = 0;
        return;
    }

    // we are waiting for the length byte
    if(pcm_wFlags.flg.bRxMsgLengthNext)
    {
        // this byte, total data length and the checksum
        pcm_nRxTodo = 1 + nRxChar + 1;
        // now read the data bytes
        pcm_wFlags.flg.bRxMsgLengthNext = 0;

    }
    
    // waiting for a data byte?
    if(pcm_nRxTodo)
    {
        // add this byte to checksum
        pcm_nRxCheckSum += nRxChar;
        
        // was it the last byte of the message (checksum)?
        if(!--pcm_nRxTodo)
        {
            // receive buffer overflow?
            if(pcm_pRxBuff == NULL)
            {
                FMSTR_SendError(FMSTR_STC_CMDTOOLONG);
            }
            // checksum error?
            else if((pcm_nRxCheckSum & 0xff) != 0)
            {
                FMSTR_SendError(FMSTR_STC_CMDCSERR);
            }
            // message is okay
            else 
            {
                // do decode now!
                FMSTR_ProtocolDecoder(pcm_pCommBuffer);
            }
        }
        // not the last character, is there a space in buffer?
        else if(pcm_pRxBuff)
        {
            if(pcm_pRxBuff < (pcm_pCommBuffer + FMSTR_COMM_BUFFER_SIZE))
            {
                // store byte 
                *pcm_pRxBuff++ = nRxChar;
            }
            // buffer is full!
            else
            {
                // NULL rx pointer means buffer overflow - but we still need
                // to receive all message characters (for the single-wire mode)
                // so keep "receiving" - but throw away all characters from now
                pcm_pRxBuff = NULL;
            }
        }
    }
}

/*******************************************************************************
*
* @brief    Routine to quick-receive a character (put to a queue only)
*
* This function puts received character into a queue and exits as soon as possible.
*
*******************************************************************************/

#if FMSTR_SHORT_INTR

static void FMSTR_RxQueue(FMSTR_BCHR nRxChar)
{ 
    // future value of write pointer
    FMSTR_BPTR wpnext = pcm_pRQueueWP + 1;
    
    if(wpnext >= (pcm_pRQueueBuffer + FMSTR_COMM_RQUEUE_SIZE))
        wpnext = pcm_pRQueueBuffer;
    
    // any space in queue?
    if(wpnext != pcm_pRQueueRP)
    {
        *pcm_pRQueueWP = (FMSTR_U8) nRxChar;
        pcm_pRQueueWP = wpnext;
    }
}

#endif // FMSTR_SHORT_INTR 

/*******************************************************************************
*
* @brief    Late processing of queued characters
*
* This function takes the queued characters and calls FMSTR_Rx() for each of them,
* just like as the characters would be received from SCI one by one.
*
*******************************************************************************/

#if FMSTR_SHORT_INTR

static void FMSTR_RxDequeue(void)
{ 
    FMSTR_BCHR nChar = 0;
    
    // get all queued characters
    while(pcm_pRQueueRP != pcm_pRQueueWP)
    {
        nChar = *pcm_pRQueueRP++;

        if(pcm_pRQueueRP >= (pcm_pRQueueBuffer + FMSTR_COMM_RQUEUE_SIZE))
            pcm_pRQueueRP = pcm_pRQueueBuffer;

        // emulate the SCI receive event        
        if(!pcm_wFlags.flg.bTxActive)
            FMSTR_Rx(nChar);
    }
}

#endif // FMSTR_SHORT_INTR

/**************************************************************************//*!
*
* @brief    Handle SCI communication (both TX and RX)
*
* This function checks the SCI flags and calls the Rx and/or Tx functions
*
* @note This function can be called either from SCI ISR or from the polling routine
*
******************************************************************************/

#if FMSTR_USE_SCI

void FMSTR_ProcessSCI(void)
{
    // read & clear status    
    register FMSTR_U16 wSciSR = FMSTR_SCI_RDCLRSR();

    // transmitter active and empty?
    if (pcm_wFlags.flg.bTxActive)
    {
        // able to send another character?
        if(wSciSR & FMSTR_SCISR_TDRE)
            FMSTR_Tx();
        
        // ignore (read-out) received character (loopback?)
        if(wSciSR & FMSTR_SCISR_RDRF)
        {
            volatile FMSTR_U16 nRxChar;
            nRxChar = FMSTR_SCI_GETCHAR(); 
        }
    }
    // transmitter not active, able to receive
    else
    {
        // data byte received?
        if (wSciSR & FMSTR_SCISR_RDRF)
        {
            register FMSTR_BCHR nRxChar = 0;
            nRxChar = FMSTR_SCI_GETCHAR();

#if FMSTR_SHORT_INTR
            FMSTR_RxQueue(nRxChar);
#else
            FMSTR_Rx(nRxChar);  
#endif          
        }
    }
}

#endif

/**************************************************************************//*!
*
* @brief    Handle JTAG communication (both TX and RX)
*
* This function checks the JTAG flags and calls the Rx and/or Tx functions
*
* @note This function can be called either from JTAG ISR or from the polling routine
*
******************************************************************************/

#if FMSTR_USE_JTAG

void FMSTR_ProcessJTAG(void)
{
    // read & clear status    
    register FMSTR_U16 wJtagSR = FMSTR_JTAG_GETSR();

    // transmitter active?
    if (pcm_wFlags.flg.bTxActive)
    {
        // able to transmit a new character? (TX must be empty = read-out by PC)
        if(!(wJtagSR & FMSTR_JTAG_OTXRXSR_TDF))
        {
        
#if FMSTR_USE_JTAG_TXFIX
            // if TDF bit is useless due to silicon bug, use the RX flag
            // instead (PC sends us a dummy word to kick the RX flag on)
            if(wJtagSR & FMSTR_JTAG_OTXRXSR_RDF)
#endif
            {
                // send one byte always
                FMSTR_Tx();
                
                // try to fill-up the full 32bit JTAG word
                while(pcm_wFlags.flg.bTxActive && pcm_wJtagTxCtr)
                    FMSTR_Tx();
            }               
        }

        // ignore (read-out) the JTAG-received word
        if(wJtagSR & FMSTR_JTAG_OTXRXSR_RDF)
        {
            volatile FMSTR_U16 nRxWord;
            nRxWord = FMSTR_JTAG_GETWORD();
        }
    }
    // transmitter not active
    else
    {
        // JTAG 32bit word (four bytes) received?
        if(wJtagSR & FMSTR_JTAG_OTXRXSR_RDF)
        {
            register FMSTR_U32 nRxDWord;
            FMSTR_INDEX i;
            
            nRxDWord = FMSTR_JTAG_GETDWORD();
            
            // process all bytes, MSB first
            for(i=0; i<4; i++)
            {
#if FMSTR_SHORT_INTR
                FMSTR_RxQueue((FMSTR_BCHR)((nRxDWord >> 24) & 0xff));
                
#else
                FMSTR_Rx((FMSTR_BCHR)((nRxDWord >> 24) & 0xff));
            
                // ignore the rest if previous bytes triggered a transmission
                // (i.e. the packet was complete and only filled-up to 32bit word)
                if(pcm_wFlags.flg.bTxActive)
                    break;
#endif          
                // next byte of 32bit word
                nRxDWord = nRxDWord << 8;
            }
        }
    }
}

#endif

/*******************************************************************************
*
* @brief    API: Main "Polling" call from the application main loop
*
* This function either handles all the SCI communictaion (polling-only mode = 
* FMSTR_POLL_DRIVEN) or decodes messages received on the background by SCI interrupt
* (short-interrupt mode = FMSTR_SHORT_INTR). 
*
* In fully interrupt-driven mode (FMSTR_LONG_INTR) this function does nothing.
*
*******************************************************************************/

void FMSTR_Poll(void)
{ 
#if FMSTR_POLL_DRIVEN

#if FMSTR_USE_SCI
    FMSTR_ProcessSCI(); 
    
#elif FMSTR_USE_JTAG
    FMSTR_ProcessJTAG(); 
    
#endif
    
#elif FMSTR_SHORT_INTR

    // process queued SCI characters
    FMSTR_RxDequeue(); 
    
#endif
}

#else // FMSTR_USE_SCI || FMSTR_USE_JTAG

// Empty implementation of communication functions.
// Without a SCI and JTAG the FreeMaster driver still passes the compilation, 
// but no communication is supported. The user may imlement his own communication
// protocol and use FreeMaster by calling FMSTR_ProtocolDecoder and 
// overriding the FMSTR_SendResponse calls

void FMSTR_SendResponse(FMSTR_BPTR pResponse, FMSTR_SIZE8 nLength) {}
void FMSTR_Poll(void) {}

#endif // FMSTR_USE_SCI || FMSTR_USE_JTAG

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -