/* * 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; } } }
/********************************************************************************************************* ** 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; } }