/****************************************************************************** * @fn HalUARTPollDMA * * @brief Poll a USART module implemented by DMA, including the hybrid solution in which the Rx * is driven by DMA but the Tx is driven by ISR. * * @param none * * @return none *****************************************************************************/ static void HalUARTPollDMA(void) { uint8 evt = 0; //static uint16 cnt; static uint32 systemClock = 0; //static uint32 time[100] = {0}; ///static uint8 i = 0; //static uint32 SystemClockPre = 0; //static uint8 cntpre = 0; #if DMA_PM PxIEN &= ~DMA_RDYIn_BIT; // Clear to not race with DMA_RDY_IN ISR. { if (dmaRdyIsr || HAL_UART_DMA_RDY_IN() || HalUARTBusyDMA()) { // Master may have timed-out the SRDY asserted state & may need a new edge. #if HAL_UART_TX_BY_ISR if (!HAL_UART_DMA_RDY_IN() && (dmaCfg.txHead != dmaCfg.txTail)) #else if (!HAL_UART_DMA_RDY_IN() && ((dmaCfg.txIdx[0] != 0) || (dmaCfg.txIdx[1] != 0))) #endif { HAL_UART_DMA_CLR_RDY_OUT(); } dmaRdyIsr = 0; if (dmaRdyDly == 0) { (void)osal_set_event(Hal_TaskID, HAL_PWRMGR_HOLD_EVENT); } if ((dmaRdyDly = ST0) == 0) // Reserve zero to signify that the delay expired. { dmaRdyDly = 0xFF; } HAL_UART_DMA_SET_RDY_OUT(); } else if ((dmaRdyDly != 0) && (!DMA_PM_DLY || ((uint8)(ST0 - dmaRdyDly) > DMA_PM_DLY))) { dmaRdyDly = 0; (void)osal_set_event(Hal_TaskID, HAL_PWRMGR_CONSERVE_EVENT); } } PxIEN |= DMA_RDYIn_BIT; #endif #if !HAL_UART_TX_BY_ISR HalUARTPollTxTrigDMA(); #endif cnt = HalUARTRxAvailDMA(); // Wait to call until after the above DMA Rx bug work-around. #if HAL_UART_DMA_IDLE #if 0 if (dmaCfg.rxTick) { // Use the LSB of the sleep timer (ST0 must be read first anyway) to measure the Rx timeout. if ((ST0 - dmaCfg.rxTick) > HAL_UART_DMA_IDLE) { dmaCfg.rxTick = 0; evt = HAL_UART_RX_TIMEOUT; } } else if (cnt != 0) { if ((dmaCfg.rxTick = ST0) == 0) // Zero signifies that the Rx timeout is not running. { dmaCfg.rxTick = 0xFF; } } #endif #if 1 // osalTimeUpdate(); systemClock = osal_GetSystemClock( ); if (dmaCfg.rxTick) { // Use the LSB of the sleep timer (ST0 must be read first anyway) to measure the Rx timeout. // if ((systemClock - dmaCfg.rxTick) > HAL_UART_DMA_IDLE) if ((systemClock - dmaCfg.rxTick) > 3) { dmaCfg.rxTick = 0; evt = HAL_UART_RX_TIMEOUT; } } else if (cnt != 0) { dmaCfg.rxTick = systemClock; } #endif #else if (cnt != 0) { // if (i < 100) { // systemClock = osal_GetSystemClock( ); // time[i] = systemClock-SystemClockPre // SystemClockPre = systemClock; // i++; } evt = HAL_UART_RX_TIMEOUT; } #endif if (cnt >= HAL_UART_DMA_FULL) { evt |= HAL_UART_RX_FULL; } else if (cnt >= HAL_UART_DMA_HIGH) { evt |= HAL_UART_RX_ABOUT_FULL; if (!DMA_PM && (UxUCR & UCR_FLOW)) { HAL_UART_DMA_CLR_RDY_OUT(); // Disable Rx flow. } } if (dmaCfg.txMT) { dmaCfg.txMT = FALSE; evt |= HAL_UART_TX_EMPTY; } if ((evt != 0) && (dmaCfg.uartCB != NULL)) { dmaCfg.uartCB(HAL_UART_DMA-1, evt); } if (DMA_PM && (dmaRdyDly == 0) && !HalUARTBusyDMA()) { HAL_UART_DMA_CLR_RDY_OUT(); } } /********************************************************************* * LOCAL FUNCTIONS */ static uint8 App_DataXOR(uint8 *msg, uint8 ucLen) { uint8 ucCheckVaule = 0x00; uint8 i; for (i = 0; i < ucLen; i++) { ucCheckVaule ^= msg[i]; } return ucCheckVaule; } static uint8 App_MsgCheck(uint8 *pucMsg, uint8 ucMsgLen) { uint8 ucDataLen; uint8 ucTemp; if (MSG_HEAD_FLAG == pucMsg[0]) { ucDataLen = pucMsg[2]; if ((ucMsgLen == ucDataLen + MSG_EXT_DATA_LEN)) { ucTemp = App_DataXOR(pucMsg, ucDataLen + 3); if (ucTemp == pucMsg[ucDataLen + 3]) { return SUCCESS; } } } return FAILURE; } /********************************************************************* * PUBLIC FUNCTIONS */ /********************************************************************* * @fn App_SerialCB * * @brief * * @param port - UART port. * @param event - the UART port event flag. * * @return none */ void App_SerialCB(uint8 port, uint8 event) { //static uint8 msg[MAX_APP_PAYLOAD] = {0}; //t static // uint8 temp[MAX_APP_PAYLOAD*2] = {0}; // uint8 buf[MAX_APP_PAYLOAD*2] = {0}; // uint8 bufLen = 0; //uint8 packet[MAX_APP_PAYLOAD] = {0}; //uint8 packetLen =0; //uint8 dataLen = 0; //static uint8 ucLen = 0; //t static uint8 ucRet; // uint8 i; uartMsg_t* msgPtr; static uint32 preCount = 0; static uint32 aftercount = 0; (void)port; if ((event & (HAL_UART_RX_FULL | HAL_UART_RX_ABOUT_FULL | HAL_UART_RX_TIMEOUT))) { osal_memset(msg,0,MAX_APP_PAYLOAD); //t ucLen = HalUARTRead(0, msg, MAX_APP_PAYLOAD); // HalUARTWrite(0,msg,ucLen); //t test #if 0 //t { uint8 data[] = {0x02,0x00,0x0b,0x54,0x29,0xde,0xf7,0xff,0x19,0xa4,0x08,0x0f,0x1f,0x00,0x07}; uint8 data1[] = {0xff,0xff,0xff,0xff,0xff}; if (ucLen != 15) { HalUARTWrite(0,msg,ucLen); //t test HalUARTWrite(0,data1,5); //t test } else { ucRet = osal_memcmp(data,msg,15); if (ucRet != true) { HalUARTWrite(0,msg,ucLen); //t test HalUARTWrite(0,data1,5); //t test } } } #endif // HalUARTWrite(0,msg,ucLen); //t test preCount++; ucRet = App_MsgCheck(msg, ucLen); // ucRet = 7; //t if (SUCCESS == ucRet) { #if 1 //t msgPtr = (uartMsg_t *)osal_msg_allocate( sizeof(uartMsg_t) ); if ( msgPtr ) { msgPtr->hdr.event = SBP_DATA_UART_EVT; msgPtr->len = ucLen; osal_memcpy(msgPtr->data, msg, ucLen); osal_msg_send( simpleBLEPeripheral_TaskID, (uint8 *)msgPtr ); } #endif aftercount++; } #if 0 if (ucLen == 0) { return; }else { HalUARTWrite(0,msg,ucLen); //t test return; } osal_memcpy(&buf[bufLen], msg, ucLen); bufLen += ucLen; while(1) { for (i = 0; i= bufLen) //数据长度不够 { bufLen -= i; osal_memcpy(temp,&buf[i],bufLen); osal_memcpy(buf,temp,bufLen); return; } dataLen = buf[i + 2]; if (dataLen > DATA_MAX_LEN) // 从重找头 { continue; } if ((dataLen + MSG_EXT_DATA_LEN + i) > bufLen) { bufLen -= i; osal_memcpy(temp,&buf[i],bufLen); osal_memcpy(buf,temp,bufLen); return; } packetLen = dataLen + MSG_EXT_DATA_LEN; osal_memcpy(packet, &buf[i], packetLen); ucRet = App_MsgCheck(packet, packetLen); if (SUCCESS == ucRet) { // send data to database { uartMsg_t* msgPtr; { //t for test // if (packet[1] == 0x00) // { // return; // } HalUARTWrite(0,packet,packetLen); //t test } #if 0 //t // Send the address to the database task msgPtr = (uartMsg_t *)osal_msg_allocate( sizeof(uartMsg_t) ); if ( msgPtr ) { msgPtr->hdr.event = SBP_DATA_UART_EVT; msgPtr->len = packetLen; osal_memcpy(msgPtr->data, packet, packetLen); // osal_msg_send( dataBase_TaskID, (uint8 *)msgPtr ); osal_msg_send( simpleBLEPeripheral_TaskID, (uint8 *)msgPtr ); } #endif } // 继续下一个循环 if ((i + packetLen) < bufLen) { bufLen -= (i + packetLen); osal_memcpy(temp,&buf[i + packetLen],bufLen); osal_memcpy(buf,temp,bufLen); i = 0; break; } else if ((i + packetLen) == bufLen) //数据刚好取完 { bufLen = 0; return; } else { //error; } } else { continue; } } // 找不到头 if (bufLen == i) { bufLen = 0; return; } } #endif } return; } 说明: iar complier 设置 xINT_HEAP_LEN=3072 INT_HEAP_LEN=2072 HALNODEBUG OSAL_CBTIMER_NUM_TASKS=1 HAL_AES_DMA=TRUE HAL_DMA=TRUE xPOWER_SAVING xPLUS_BROADCASTER HAL_LCD=FALSE HAL_LED=TRUE HAL_UART=TRUE HAL_KEY=FALSE HalUARTPollDMA()这个函数修改说明: 没有使用STO,计数,使用systemClock = osal_GetSystemClock( ); 计数。 App_SerialCB()这个函数在 NPI_InitTransport( App_SerialCB );(此函数在mian里面初始化) 注册为回调函数。其里面的测试变量preCount,aftercount,为静态的,会出现不同的值,及丢数了