Example #1
0
/*
 * ISR context
 * uart_rx_cb() will be called when UART rx interrupt assert,
 * then we should featch data from HW FIFO quickly.
 * fucntion: fetch data from HW FIFO to rx ring buffer
 * we should use uart_get_byte(&ch) to fetch byte from HW FIFO as quickly as possible
 */
void uart_rx_cb(void)
{
    uint16   roomleft = 0;
    PKT_FIFO     *infor;
    PKT_FIFO     *temp_info;
    uint8        ch = 0;

    PKT_DESC     *rx_desc = &(UARTPort.Rx_desc);
    BUFFER_INFO  *rx_ring = &(UARTPort.Rx_Buffer);

    static uint8  ATMatchNum = 0;
    static uint8  IWMatchNum = 0;

    /*
     * MCU only forward uart rx data to air
     * here,copy to rx ring and return
     */
#if (UARTRX_TO_AIR_LEVEL == 2)
    if (iot_uart_rx_mode == UARTRX_PUREDATA_MODE) {
        while (uart_get_byte(&ch)) {
            Buf_Push(rx_ring,ch);
        }
        return;
    }
#endif

    /*
     * MCU should collect data to be packet
     */
    //normal case
    Buf_GetRoomLeft(rx_ring,roomleft);

    while (uart_get_byte(&ch)) {
        //new receive begin,detect packet header at first
        switch (rx_desc->cur_type)   {
            case PKT_UNKNOWN: {
                /**************** detect packet type ***************/
                //support more ATcmd prefix analysis
                /*case 1:AT#*/
                if (ATCmdPrefixAT[ATMatchNum] == ch) {
                    ATMatchNum++;
                } else {
                    ATMatchNum = 0;
                }
                /*case 2:iwpriv ra0*/
                if (ATCmdPrefixIW[IWMatchNum] == ch) {
                    IWMatchNum++;
                } else {
                    IWMatchNum = 0;
                }

                if ((ATMatchNum == sizeof(ATCmdPrefixAT)-1) || //match case 1: AT#
                    (IWMatchNum == sizeof(ATCmdPrefixIW)-1)) {  //match case 2:iwpriv ra0
                    rx_desc->cur_num = rx_desc->pkt_num;
                    infor = &(rx_desc->infor[rx_desc->cur_num]);
                    infor->pkt_len = 0;

                    if (ATMatchNum == sizeof(ATCmdPrefixAT)-1) {
                        rx_desc->cur_type = PKT_ATCMD;             //match case 1: AT#
                    } else if (IWMatchNum == sizeof(ATCmdPrefixIW)-1) {
                        rx_desc->cur_type = PKT_IWCMD;             //match case 2:iwpriv ra0
                    }

                    ATMatchNum = 0;
                    IWMatchNum = 0;
                    continue;
                }
            }
            break;

            case PKT_ATCMD:
            case PKT_IWCMD: {
                infor = &(rx_desc->infor[rx_desc->cur_num]);

                /*received one complete packet*/
                if (ch == '\n' || ch == '\r')  {
                    //if task has consumed some packets
                    if (rx_desc->cur_num != rx_desc->pkt_num) {
                        temp_info = infor;
                        infor     = &(rx_desc->infor[rx_desc->pkt_num]);
                        infor->pkt_len = temp_info->pkt_len;
                        temp_info->pkt_len = 0;
                        temp_info->pkt_type = PKT_UNKNOWN;
                    }

                    infor->pkt_type = rx_desc->cur_type;  // PKT_ATCMD / PKT_IWCMD;
                    rx_desc->pkt_num++;
                    rx_desc->cur_type = PKT_UNKNOWN;
                } else {
                    /*continue to receiving packet */
                    Buf_Push(rx_ring,ch);
                    roomleft--;
                    infor->pkt_len++;
                }

                /*
                 * if overflow,we discard the current packet
                 * example1:packet length > ring size
                 * example2:rx ring buff can no be freed by task as quickly as rx interrupt coming
                 */
                if ((!roomleft) || (rx_desc->pkt_num >= NUM_DESCS)) {
                    //rollback
                    Buff_RollBack(rx_ring,infor->pkt_len);

                    roomleft += infor->pkt_len;

                    infor->pkt_type = PKT_UNKNOWN;
                    infor->pkt_len = 0;
                    rx_desc->cur_type = PKT_UNKNOWN;

                    if (rx_desc->pkt_num >= NUM_DESCS) {
                        rx_desc->pkt_num--;
                    }
                }
            }
            break;
            default:
                break;
        }
    }
}
Example #2
0
/*********************************************************************************************************
** Function name:           UartProcessMsg()
**  Descriptions:           处理串口消息
** input parameters:        无
** Output parameters::      无
** Returned value:          无
** Created by:              
** Created Date:            2014.10.03
**--------------------------------------------------------------------------------------------------------
** Modified by:             
** Modified date:           2014.10.03
**--------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
void UartProcessMsg(u8 ch)
{
    u16   roomleft = 0;
    PKT_FIFO     *infor;
    PKT_FIFO     *temp_info;   
    PKT_DESC     *rx_desc = &(UART1Port.Rx_desc);
    BUFFER_INFO  *rx_ring = &(UART1Port.Rx_Buffer); 
    static u16 AMHeadLen = sizeof(RCTRL_STRU_MSGHEAD);
    static u16 AMBodyLen =0;
    static u8  PDMatchNum = 0;
    static u8  PrintMatchNum = 0;
    
    Buf_GetRoomLeft(rx_ring,roomleft);
    
    switch (rx_desc->cur_type)
    {
        case PKT_UNKNOWN:
        {  
            /**************** detect packet type ***************/
            if (PureDataPrefix[PDMatchNum] == ch)
            {         
                PDMatchNum++;
            }
            else
            {         
                PDMatchNum = 0;
            } 
            if (PrintCmdPrefix[PrintMatchNum] == ch)
            {         
                PrintMatchNum++;
            }
            else
            {         
                PrintMatchNum = 0;
            }         
            if ((PDMatchNum == sizeof(PureDataPrefix)-1) ||  
                (PrintMatchNum == sizeof(PrintCmdPrefix)-1))   //match case 3:arm  data
            {   
                
                rx_desc->cur_num = rx_desc->pkt_num;                  
                infor = &(rx_desc->infor[rx_desc->cur_num]);
                infor->pkt_len = 0;
                
                if (PrintMatchNum == sizeof(PrintCmdPrefix)-1)
                {            
                    rx_desc->cur_type = PKT_PRINTCMD;           //match case 2:iwpriv ra0
                }
                else if (PDMatchNum == sizeof(PureDataPrefix)-1)
                {  
                    u8 i= 0;
                    rx_desc->cur_type = PKT_PUREDATA;           //match case 2:iwpriv ra0
                    if(roomleft<AMHeadLen)
                    {
                        rx_desc->cur_type= PKT_UNKNOWN;
                    }
                    else
                    {
                        for(i = 0;i < sizeof(PureDataPrefix)-1;i++)
                        {
                            Buf_Push(rx_ring,PureDataPrefix[i]);
                        }
                        roomleft= roomleft-sizeof(PureDataPrefix)+1;
                        infor = &(rx_desc->infor[rx_desc->cur_num]);
                        infor->pkt_len = infor->pkt_len + i;
                    }                                       
                }
                PrintMatchNum = 0;
                PDMatchNum = 0;
            }           
        }
        break;
        case PKT_PRINTCMD:
        {          
            /*
            * received one complete packet
            */
            if(ch == '\0'||ch == '\n' || ch == '\r')
            {   
                rx_desc->cur_type = PKT_UNKNOWN;
                return;
            }
        }
        break;
        
        case PKT_PUREDATA:
        {   
            infor = &(rx_desc->infor[rx_desc->cur_num]);
            Buf_Push(rx_ring,ch);
            roomleft--;
            infor->pkt_len++;
            if(infor->pkt_len==AC_PAYLOADLENOFFSET)
            {
                AMBodyLen = ch;
            }
            else if(infor->pkt_len==(AC_PAYLOADLENOFFSET +1))
            {
                AMBodyLen = (AMBodyLen<<8) + ch;
            }   
            /*
            * if overflow,we discard the current packet
            * example1:packet length > ring size
            * example2:rx ring buff can no be freed by task as quickly as rx interrupt coming
            */    
            if ((!roomleft) || (rx_desc->pkt_num >= NUM_DESCS))
            {   
                //rollback
                Buff_RollBack(rx_ring,infor->pkt_len);
                
                roomleft += infor->pkt_len;
                
                infor->pkt_type = PKT_UNKNOWN;
                infor->pkt_len = 0;
                rx_desc->cur_type = PKT_UNKNOWN;
                
                if (rx_desc->pkt_num >= NUM_DESCS)
                {
                    rx_desc->pkt_num--;
                }
                
            }      
            /*
            * received one complete packet
            */
            if(AMHeadLen+AMBodyLen==infor->pkt_len)
            {   
                //if task has consumed some packets
                if (rx_desc->cur_num != rx_desc->pkt_num)
                {   
                    temp_info = infor;
                    infor     = &(rx_desc->infor[rx_desc->pkt_num]);
                    infor->pkt_len = temp_info->pkt_len;
                    temp_info->pkt_len = 0;
                    temp_info->pkt_type = PKT_UNKNOWN;
                }
                
                infor->pkt_type = rx_desc->cur_type;  // PKT_ATCMD / PKT_IWCMD;
                rx_desc->pkt_num++;
                rx_desc->cur_type = PKT_UNKNOWN;
                AMBodyLen =0;
                return;                    
            }
        }
        break;
        default:
        break;
    } 
}