/**************************************************************************** * @fn ZDiagsClearStats * * @brief Clears the statistics table in RAM and NV if option flag set. * * @param clearNV - Option flag to clear NV data. * * @return System Clock. */ uint32 ZDiagsClearStats( bool clearNV ) { uint32 retValue = 0; #if defined ( FEATURE_SYSTEM_STATS ) // clears statistics table osal_memset( &DiagsStatsTable, 0, sizeof( DiagStatistics_t ) ); // saves System Clock when statistics were cleared retValue = DiagsStatsTable.SysClock = osal_GetSystemClock(); if ( clearNV ) { uint16 bootCnt = 0; // Boot count is not part of DiagsStatsTable, it has to be initialized separately osal_nv_write( ZCD_NV_BOOTCOUNTER, 0, sizeof(bootCnt), &bootCnt ); // Clears values in NV and saves the system clock for the last time stats were cleared osal_nv_write( ZCD_NV_DIAGNOSTIC_STATS, 0, sizeof( DiagStatistics_t ), &DiagsStatsTable ); } #endif // FEATURE_SYSTEM_STATS return ( retValue ); }
/**************************************************************************** * @fn ZDiagsSaveStatsToNV * * @brief Saves the statistics table from RAM to NV. * * @param none. * * @return System Time. */ uint32 ZDiagsSaveStatsToNV( void ) { uint32 sysClock = 0; #if defined ( FEATURE_SYSTEM_STATS ) // call this function to update the DiagsStatsTable with MAC values, // the return value does not need to be saved because the function // is updating the value in DiagsStatsTable (void)ZDiagsGetStatsAttr( ZDIAGS_MAC_RX_CRC_PASS ); (void)ZDiagsGetStatsAttr( ZDIAGS_MAC_RX_CRC_FAIL ); (void)ZDiagsGetStatsAttr( ZDIAGS_MAC_RX_BCAST ); (void)ZDiagsGetStatsAttr( ZDIAGS_MAC_TX_BCAST ); (void)ZDiagsGetStatsAttr( ZDIAGS_MAC_RX_UCAST ); (void)ZDiagsGetStatsAttr( ZDIAGS_MAC_TX_UCAST ); (void)ZDiagsGetStatsAttr( ZDIAGS_MAC_TX_UCAST_RETRY ); (void)ZDiagsGetStatsAttr( ZDIAGS_MAC_TX_UCAST_FAIL ); // System Clock when statistics were saved sysClock = DiagsStatsTable.SysClock = osal_GetSystemClock(); // save the statistics table from RAM to NV osal_nv_write( ZCD_NV_DIAGNOSTIC_STATS, 0, sizeof( DiagStatistics_t ), &DiagsStatsTable ); #endif // returns the System Time return ( sysClock ); }
/********************************************************************* * @fn sensor_ProcessOSALMsg * * @brief Process an incoming task message. * * @param pMsg - message to process * * @return none */ static void sensor_ProcessOSALMsg( osal_event_hdr_t *pMsg ) { /* switch ( pMsg->event ) { case KEY_CHANGE: //sensor_HandleKeys( ((keyChange_t *)pMsg)->state, ((keyChange_t *)pMsg)->keys ); break; } */ cummWheelRevs++; cummCrankRevs++; lastWheelEvtTime = 0x0000FFFF & (uint32) ((osal_GetSystemClock() * 1.024)); lastCrankEvtTime = 0x0000FFFF & (uint32) ((osal_GetSystemClock() * 1.024)); //HalLedSet(HAL_LED_2, HAL_LED_MODE_TOGGLE); }
/*************************************************************************************************** * @fn HalLedBlink * * @brief Blink the leds * * @param leds - bit mask value of leds to be blinked * numBlinks - number of blinks * percent - the percentage in each period where the led * will be on * period - length of each cycle in milliseconds * * @return None ***************************************************************************************************/ void HalLedBlink (uint8 leds, uint8 numBlinks, uint8 percent, uint16 period) { #if (defined (BLINK_LEDS)) && (HAL_LED == TRUE) uint8 led; HalLedControl_t *sts; if (leds && percent && period) { if (percent < 100) { led = HAL_LED_1; leds &= HAL_LED_ALL; sts = HalLedStatusControl.HalLedControlTable; while (leds) { if (leds & led) { /* Store the current state of the led before going to blinking if not already blinking */ if(sts->mode < HAL_LED_MODE_BLINK ) preBlinkState |= (led & HalLedState); sts->mode = HAL_LED_MODE_OFF; /* Stop previous blink */ sts->time = period; /* Time for one on/off cycle */ sts->onPct = percent; /* % of cycle LED is on */ sts->left = numBlinks; /* Number of blink cycles */ if (!numBlinks) sts->mode |= HAL_LED_MODE_FLASH; /* Continuous */ sts->next = osal_GetSystemClock(); /* Start now */ sts->mode |= HAL_LED_MODE_BLINK; /* Enable blinking */ leds ^= led; } led <<= 1; sts++; } // Cancel any overlapping timer for blink events osal_stop_timerEx(Hal_TaskID, HAL_LED_BLINK_EVENT); osal_set_event (Hal_TaskID, HAL_LED_BLINK_EVENT); } else { HalLedSet (leds, HAL_LED_MODE_ON); /* >= 100%, turn on */ } } else { HalLedSet (leds, HAL_LED_MODE_OFF); /* No on time, turn off */ } #elif (HAL_LED == TRUE) percent = (leds & HalLedState) ? HAL_LED_MODE_OFF : HAL_LED_MODE_ON; HalLedOnOff (leds, percent); /* Toggle */ #else // HAL LED is disabled, suppress unused argument warnings (void) leds; (void) numBlinks; (void) percent; (void) period; #endif /* BLINK_LEDS && HAL_LED */ }
/************************************************************************************************* * @fn Hal_UART_ProcessRxEvent * * @brief Process the Rx data by putting them in Rx Buffer. Callback will happen if idle timeout * or Rx buffer is full * * @param void * * @return void *************************************************************************************************/ static void Hal_UART_RxProcessEvent(void) { uint8 ch = HAL_UART_GETBYTE(); uartRecord.rx.pBuffer[uartRecord.rx.bufferTail++] = ch; if (uartRecord.rx.bufferTail >= uartRecord.rx.maxBufSize) { uartRecord.rx.bufferTail = 0; } uartRecord.rxChRvdTime = osal_GetSystemClock(); }
/************************************************************************************************* * @fn Hal_UARTPoll * * @brief This routine simulate polling and has to be called by the main loop * * @param void * * @return void *************************************************************************************************/ void HalUARTPoll(void) { if (!uartRecord.configured) // If port is not configured, no point to poll it. { return; } if (!uartRecord.intEnable) // Check Port for items to process. { if (HAL_UART_GET_RX_STATUS()) { Hal_UART_RxProcessEvent(); } if (HAL_UART_GET_TX_STATUS()) { Hal_UART_TxProcessEvent(); } } if ((Hal_UART_RxBufLen(0) + 1) >= uartRecord.rx.maxBufSize) // Report if Rx Buffer is full. { Hal_UART_SendCallBack (0, HAL_UART_RX_FULL) ; } if ((uartRecord.rxChRvdTime != 0) && // Report if Rx Buffer is idled. ((osal_GetSystemClock() - uartRecord.rxChRvdTime) > uartRecord.idleTimeout)) { Hal_UART_SendCallBack (0, HAL_UART_RX_TIMEOUT) ; uartRecord.rxChRvdTime = 0; } /* Send back warning when buffer it threshold and turn off flow */ if (Hal_UART_RxBufLen(0) >= uartRecord.rx.maxBufSize - uartRecord.flowControlThreshold) { Hal_UART_SendCallBack (0, HAL_UART_RX_ABOUT_FULL) ; } if (uartRecord.flowControl) { if (Hal_UART_RxBufLen(0) > uartRecord.rx.maxBufSize / 2) { Hal_UART_FlowControlSet (0, HAL_UART_FLOW_OFF); } else { Hal_UART_FlowControlSet (0, HAL_UART_FLOW_ON); } } }
/************************************************************************************************* * @fn Hal_UARTPollIsr * * @brief This routine simulate polling and has to be called by the main loop * * @param void * * @return void *************************************************************************************************/ void HalUARTPollIsr(void) { uint16 head = uartRecord.tx.bufferHead; uint16 tail = uartRecord.tx.bufferTail; /* If port is not configured, no point to poll it. */ if (!uartRecord.configured) { return; } halIntState_t intState; HAL_ENTER_CRITICAL_SECTION(intState); procRx(); procTx(); HAL_EXIT_CRITICAL_SECTION(intState); uint8 evts = 0; /* Report if Rx Buffer is full. */ if ((Hal_UART_RxBufLen(0) + 1) >= uartRecord.rx.maxBufSize) { evts = HAL_UART_RX_FULL; } /* Report if Rx Buffer is idled. */ if ((uartRecord.rxChRvdTime != 0) && ((osal_GetSystemClock() - uartRecord.rxChRvdTime) > uartRecord.idleTimeout)) { uartRecord.rxChRvdTime = 0; evts |= HAL_UART_RX_TIMEOUT; } if (Hal_UART_RxBufLen(0) >= uartRecord.rx.maxBufSize - uartRecord.flowControlThreshold) { evts |= HAL_UART_RX_ABOUT_FULL; } if (!txMT && (head == tail)) { txMT = true; evts |= HAL_UART_TX_EMPTY; } if (evts && uartRecord.callBackFunc) { (uartRecord.callBackFunc)(0, evts); } }
/*************************************************************************************************** * @fn HalLedBlink * * @brief Blink the leds * * @param leds - bit mask value of leds to be blinked * numBlinks - number of blinks, 0 for continuous * percent - the percentage in each period where the led * will be on * period - length of each cycle in milliseconds * * @return None ***************************************************************************************************/ void HalLedBlink ( uint8 leds, uint8 numBlinks, uint8 percent, uint16 period ) { #if (defined (BLINK_LEDS)) && (HAL_LED == TRUE) uint8 led; HalLedControl_t *sts; if ( leds && percent && period ) { if ( percent < 100 ) { led = HAL_LED_1; leds &= HAL_LED_ALL; sts = HalLedStatusTable; while ( leds ) { if ( leds & led ) { /* Store the current state of the led before going to blinking */ preBlinkState |= (led & ledState); sts->mode = HAL_LED_MODE_OFF; // Stop previous blink sts->time = period; // Time for one on/off cycle sts->onPct = percent; // % of cycle LED is on sts->todo = numBlinks; // Number of blink cycles if ( !numBlinks ) sts->mode |= HAL_LED_MODE_FLASH; // Continuous sts->next = osal_GetSystemClock(); // Start now sts->mode |= HAL_LED_MODE_BLINK; // Enable blinking leds ^= led; } led <<= 1; sts++; } osal_stop_timerEx(Hal_TaskID, HAL_LED_BLINK_EVENT); osal_set_event( Hal_TaskID, HAL_LED_BLINK_EVENT ); } else HalLedSet( leds, HAL_LED_MODE_ON ); // >= 100%, turn on } else HalLedSet( leds, HAL_LED_MODE_OFF ); // No on time, turn off #elif (HAL_LED == TRUE) percent = (leds & ledState) ? HAL_LED_MODE_OFF : HAL_LED_MODE_ON; HalLedOnOff( leds, percent ); // Toggle #endif /* BLINK_LEDS && HAL_LED */ }
/*************************************************************************************************** * @fn MT_UtilTimeAlive * * @brief Process Time Alive * * @param None. * * @return None ***************************************************************************************************/ void MT_UtilTimeAlive(void) { uint8 timeAlive[4]; uint32 tmp32; /* Time since last reset (seconds) */ tmp32 = osal_GetSystemClock() / 1000; /* Convert to high byte first into temp buffer */ timeAlive[0] = BREAK_UINT32(tmp32, 0); timeAlive[1] = BREAK_UINT32(tmp32, 1); timeAlive[2] = BREAK_UINT32(tmp32, 2); timeAlive[3] = BREAK_UINT32(tmp32, 3); /* Build and send back the response */ MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), MT_UTIL_TIME_ALIVE, sizeof(timeAlive), timeAlive); }
/********************************************************************* * @fn TransmitApp_MessageMSGCB * * @brief Data message processor callback. This function processes * any incoming data - probably from other devices. So, based * on cluster ID, perform the intended action. * * @param none * * @return none */ void TransmitApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ) { int16 i; uint8 error = FALSE; switch ( pkt->clusterId ) { case TRANSMITAPP_CLUSTERID_TESTMSG: if (pkt->cmd.DataLength != TransmitApp_MaxDataLength) { error = TRUE; } for (i=4; i<pkt->cmd.DataLength; i++) { if (pkt->cmd.Data[i] != i%256) error = TRUE; } if (error) { // Display error LED HalLedSet(HAL_LED_1, HAL_LED_MODE_ON); } else { if ( !timerOn ) { osal_start_timerEx( TransmitApp_TaskID, TRANSMITAPP_RCVTIMER_EVT, TRANSMITAPP_DISPLAY_TIMER ); clkShdw = osal_GetSystemClock(); timerOn = TRUE; } rxAccum += pkt->cmd.DataLength; } break; // Could receive control messages in the future. default: break; } }
/************************************************************************************************* * @fn procRx * * @brief Process Tx bytes. * * @param void * * @return void *************************************************************************************************/ static void procRx(void) { uint16 tail = uartRecord.rx.bufferTail; while (UARTCharsAvail(HAL_UART_PORT)) { uartRecord.rx.pBuffer[tail++] = UARTCharGetNonBlocking(HAL_UART_PORT); if (tail >= uartRecord.rx.maxBufSize) { tail = 0; } } if (uartRecord.rx.bufferTail != tail) { uartRecord.rx.bufferTail = tail; uartRecord.rxChRvdTime = osal_GetSystemClock(); } }
/*************************************************************************************************** * @fn HalLedUpdate * * @brief Update leds to work with blink * * @param none * * @return none ***************************************************************************************************/ void HalLedUpdate (void) { uint8 led; uint8 pct; uint8 leds; HalLedControl_t *sts; uint32 time; uint16 next; uint16 wait; next = 0; led = HAL_LED_1; leds = HAL_LED_ALL; sts = HalLedStatusControl.HalLedControlTable; /* Check if sleep is active or not */ if (!HalLedStatusControl.sleepActive) { while (leds) { if (leds & led) { if (sts->mode & HAL_LED_MODE_BLINK) { time = osal_GetSystemClock(); if (time >= sts->next) { if (sts->mode & HAL_LED_MODE_ON) { pct = 100 - sts->onPct; /* Percentage of cycle for off */ sts->mode &= ~HAL_LED_MODE_ON; /* Say it's not on */ HalLedOnOff (led, HAL_LED_MODE_OFF); /* Turn it off */ if (!(sts->mode & HAL_LED_MODE_FLASH)) { sts->todo--; /* Not continuous, reduce count */ if (!sts->todo) { sts->mode ^= HAL_LED_MODE_BLINK; /* No more blinks */ } } } else { pct = sts->onPct; /* Percentage of cycle for on */ sts->mode |= HAL_LED_MODE_ON; /* Say it's on */ HalLedOnOff (led, HAL_LED_MODE_ON); /* Turn it on */ } if (sts->mode & HAL_LED_MODE_BLINK) { wait = (((uint32)pct * (uint32)sts->time) / 100); sts->next = time + wait; } else { /* no more blink, no more wait */ wait = 0; /* After blinking, set the LED back to the state before it blinks */ HalLedSet (led, ((preBlinkState & led)!=0)?HAL_LED_MODE_ON:HAL_LED_MODE_OFF); /* Clear the saved bit */ preBlinkState &= (led ^ 0xFF); } } else { wait = sts->next - time; /* Time left */ } if (!next || ( wait && (wait < next) )) { next = wait; } } leds ^= led; } led <<= 1; sts++; } if (next) { osal_start_timerEx(Hal_TaskID, HAL_LED_BLINK_EVENT, next); /* Schedule event */ } } }
/********************************************************************* * @fn TransmitApp_DisplayResults * * @brief Display the results and clear the accumulators * * @param none * * @return none */ void TransmitApp_DisplayResults( void ) { #ifdef LCD_SUPPORTED #define LCD_W 16 uint32 rxShdw, txShdw, tmp; byte lcd_buf[LCD_W+1]; byte idx; #endif // The OSAL timers are not real-time, so calculate the actual time expired. uint32 msecs = osal_GetSystemClock() - clkShdw; clkShdw = osal_GetSystemClock(); rxTotal += rxAccum; txTotal += txAccum; #if defined ( LCD_SUPPORTED ) rxShdw = (rxAccum * 1000 + msecs/2) / msecs; txShdw = (txAccum * 1000 + msecs/2) / msecs; osal_memset( lcd_buf, ' ', LCD_W ); lcd_buf[LCD_W] = NULL; idx = 4; tmp = (rxShdw >= 100000) ? 99999 : rxShdw; do { lcd_buf[idx--] = (uint8) ('0' + (tmp % 10)); tmp /= 10; } while ( tmp ); idx = LCD_W-1; tmp = rxTotal; do { lcd_buf[idx--] = (uint8) ('0' + (tmp % 10)); tmp /= 10; } while ( tmp ); HalLcdWriteString( (char*)lcd_buf, HAL_LCD_LINE_1 ); osal_memset( lcd_buf, ' ', LCD_W ); idx = 4; tmp = (txShdw >= 100000) ? 99999 : txShdw; do { lcd_buf[idx--] = (uint8) ('0' + (tmp % 10)); tmp /= 10; } while ( tmp ); idx = LCD_W-1; tmp = txTotal; do { lcd_buf[idx--] = (uint8) ('0' + (tmp % 10)); tmp /= 10; } while ( tmp ); HalLcdWriteString( (char*)lcd_buf, HAL_LCD_LINE_2 ); #else DEBUG_INFO( COMPID_APP, SEVERITY_INFORMATION, 3, rxAccum, (uint16)msecs, (uint16)rxTotal ); #endif if ( (rxAccum == 0) && (txAccum == 0) ) { osal_stop_timerEx( TransmitApp_TaskID, TRANSMITAPP_RCVTIMER_EVT ); timerOn = FALSE; } rxAccum = txAccum = 0; }
/********************************************************************* * @fn TransmitApp_ProcessEvent * * @brief Generic Application Task event processor. This function * is called to process all events for the task. Events * include timers, messages and any other user defined events. * * @param task_id - The OSAL assigned task ID. * @param events - events to process. This is a bit map and can * contain more than one event. * * @return none */ UINT16 TransmitApp_ProcessEvent( byte task_id, UINT16 events ) { afIncomingMSGPacket_t *MSGpkt; byte dstEP; zAddrType_t *dstAddr; afDataConfirm_t *afDataConfirm; ZDO_NewDstAddr_t *ZDO_NewDstAddr; // Data Confirmation message fields ZStatus_t sentStatus; byte sentEP; if ( events & SYS_EVENT_MSG ) { MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( TransmitApp_TaskID ); while ( MSGpkt ) { switch ( MSGpkt->hdr.event ) { case KEY_CHANGE: TransmitApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys ); break; case AF_DATA_CONFIRM_CMD: // This message is received as a confirmation of a data packet sent. // The status is of ZStatus_t type [defined in ZComDef.h] // The message fields are defined in AF.h afDataConfirm = (afDataConfirm_t *)MSGpkt; sentEP = afDataConfirm->endpoint; sentStatus = afDataConfirm->hdr.status; if ( (ZSuccess == sentStatus) && (TransmitApp_epDesc.endPoint == sentEP) ) { txAccum += TransmitApp_MaxDataLength; if ( !timerOn ) { osal_start_timerEx( TransmitApp_TaskID,TRANSMITAPP_RCVTIMER_EVT, TRANSMITAPP_DISPLAY_TIMER); clkShdw = osal_GetSystemClock(); timerOn = TRUE; } } // Action taken when confirmation is received: Send the next message. TransmitApp_SetSendEvt(); break; case AF_INCOMING_MSG_CMD: TransmitApp_MessageMSGCB( MSGpkt ); break; case ZDO_NEW_DSTADDR: ZDO_NewDstAddr = (ZDO_NewDstAddr_t *)MSGpkt; dstEP = ZDO_NewDstAddr->dstAddrDstEP; dstAddr = &ZDO_NewDstAddr->dstAddr; TransmitApp_DstAddr.addrMode = (afAddrMode_t)dstAddr->addrMode; TransmitApp_DstAddr.endPoint = dstEP; if ( dstAddr->addrMode == Addr16Bit ) { TransmitApp_DstAddr.addr.shortAddr = dstAddr->addr.shortAddr; } break; case ZDO_STATE_CHANGE: TransmitApp_NwkState = (devStates_t)(MSGpkt->hdr.status); break; default: break; } // Release the memory osal_msg_deallocate( (uint8 *)MSGpkt ); // Next MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( TransmitApp_TaskID ); } // Squash compiler warnings until values are used. (void)sentStatus; (void)sentEP; // Return unprocessed events return (events ^ SYS_EVENT_MSG); } // Send a message out if ( events & TRANSMITAPP_SEND_MSG_EVT ) { if ( TransmitApp_State == TRANSMITAPP_STATE_SENDING ) { TransmitApp_SendTheMessage(); } // Return unprocessed events return (events ^ TRANSMITAPP_SEND_MSG_EVT); } // Timed wait from error if ( events & TRANSMITAPP_SEND_ERR_EVT ) { TransmitApp_SetSendEvt(); // Return unprocessed events return (events ^ TRANSMITAPP_SEND_ERR_EVT); } // Receive timer if ( events & TRANSMITAPP_RCVTIMER_EVT ) { // Setup to display the next result osal_start_timerEx( TransmitApp_TaskID, TRANSMITAPP_RCVTIMER_EVT, TRANSMITAPP_DISPLAY_TIMER ); TransmitApp_DisplayResults(); return (events ^ TRANSMITAPP_RCVTIMER_EVT); } // Discard unknown events return 0; }
long OS_millis(void) { osalTimeUpdate(); return osal_GetSystemClock(); }
/************************************************************************************************** * @fn DataUpdate_ProcessEvent * * @brief Update values from A/D sensor and diags * * @param uint8 task_id * @param uint16 events - event mask * * @return uint16 - 0 (for now) ************************************************************************************************** */ uint16 DataUpdate_ProcessEvent(uint8 task_id, uint16 events) { #if ADV_DEBUG_MESSAGE_FORMAT==1 // variables that are needed if we're running the advanced debugging message format int vdd_div_3; int vdd; int16 tempvalCC2541; int spare; #endif int tempval; int16 tempval2; int16 tempval3; int16 tempval4; int16 tempavg; uint16 timeval; uint16 sensorval; #if USE_SEPARATE_TEMP_AD_CHANNEL==0 uint8 lmp_configured; uint8 lmp_configure_tries; #endif #ifdef FAKE_SENS_DATA #ifdef O2_SENSOR uint16 max_fake = 1000; uint16 min_fake = 600; static int16 fake_adj = 1; static uint16 fakesensorval = 600; #endif #ifdef CO_SENSOR uint16 max_fake = 1300; uint16 min_fake = 380; static int16 fake_adj = 1; static uint16 fakesensorval = 380; #endif #endif if (events & 1) { timeval = (uint16) (osal_GetSystemClock() & 0xffff); cyclecount++; if (cyclecount>9) { cyclecount=0; // Also, set P1_0 (the LED) as an output, and drive high P1DIR = P1DIR | 0x01; P1 = P1 | 0x01; } /* Enable channel */ ADCCFG |= 0x80; P0DIR = 0x83; // force P0.0, P0.1, and P0.7 to be inputs APCFG = 0x83; HalAdcSetReference (0x40); // use AIN7 for ref (0x08 would be AVDD5, 0x00 would be internal ref #if USE_SEPARATE_TEMP_AD_CHANNEL==0 // Configure LMP9100 to output temperature if (lmp91KinitComplete) { // Because the processor may have been sleeping, re-configure I2C intf. before // performing the I2C transaction HalI2CExitSleep(); lmp_configure_tries=0; lmp_configured=0; // We can't hang out in this loop forever, but we can retry a couple // of times, to get over any instability on the I2C bus while ((lmp_configure_tries<4) && (!lmp_configured)) { // Set this flag so that we presume that communication is working. // The flag will get cleared (quickly) as a side-effect in the // communication routines if we fail again. lmp91kOK=1; lmp_configured=LMP91000_I2CSwitchVoutToTempSensor(); lmp_configure_tries++; } // end while // Because the processor may go into sleep mode, save the state of the I2C // interface before continuing. HalI2CEnterSleep(); } // end if (lmp91KinitComplete) #endif // Read temperature from LMP9100 if (!lmp91kOK) { // If we're not communicating, then the LMP91000 may not be in the right // state, so just use a previous value. tempval = oldtempval; } else { tempval = HalAdcRead(HAL_ADC_CHANNEL_0, HAL_ADC_RESOLUTION_12); tempval2 = HalAdcRead(HAL_ADC_CHANNEL_0, HAL_ADC_RESOLUTION_12); tempval3 = HalAdcRead(HAL_ADC_CHANNEL_0, HAL_ADC_RESOLUTION_12); tempval4 = HalAdcRead(HAL_ADC_CHANNEL_0, HAL_ADC_RESOLUTION_12); // Get a bit of noise out of the temperature measurment by averaging 4 // samples. // By the way, we expect nominal values to be around 1100 or so // at room temperature, so we can fairly safely add 4 16-bit values // together without thinking too much about overflow. // If the nominal values were larger, we'd promote to a larger // data type before averaging. tempavg = (tempval+tempval2+tempval3+tempval4)/4; oldtempval=tempavg; } // Convert temp to tenths of degrees C, based on the table in // the datasheet for the LMP91000, and assuming a 2.5v ref tempval = convertTemp(tempavg); // Now, get ready to measure the oxygen sensor HalAdcSetReference (0x40); // use AIN7 for ref #if USE_SEPARATE_TEMP_AD_CHANNEL==0 if (lmp91KinitComplete) { // Because the processor may have been sleeping, re-configure I2C intf. before // performing the I2C transaction(s) HalI2CExitSleep(); lmp_configure_tries=0; lmp_configured=0; // we can't hang out in this loop forever, but we can retry a couple // of times, to get over any instability on the I2C while ((lmp_configure_tries<4) && (!lmp_configured)) { // Set this flag so that we presume that communication is working. // The flag will get cleared (quickly) as a side-effect in the // communication routines if we fail again. lmp91kOK=1; // Likely redundant, but doesn't hurt LMP91000_I2CConfigureForO2Sensor( SensTIAGain , SensRLoad, SensRefVoltageSource, SensIntZSel); if (lmp91kOK) { lmp_configured = LMP91000_I2CSwitchVoutToO2Sensor(SensModeOp); } lmp_configure_tries++; } // end while // Because the processor may go into sleep mode, save the state of the I2C // interface before continuing. HalI2CEnterSleep(); } // end if (lmp91KinitComplete) #endif if (!lmp91kOK) { // If we're not communicating, then the LMP91000 may not be in the right // state, so just use a previous value. sensorval = oldsensorval; } else { #if USE_SEPARATE_TEMP_AD_CHANNEL==1 sensorval = HalAdcRead(HAL_ADC_CHANNEL_1,HAL_ADC_RESOLUTION_12); #else sensorval = HalAdcRead(HAL_ADC_CHANNEL_0,HAL_ADC_RESOLUTION_12); #endif oldsensorval = sensorval; } // Depending on compile options, build the message, or gather // additional diagnostic info and then build the debug mode message #ifdef FAKE_SENS_DATA fakesensorval += fake_adj; if ((fakesensorval >= max_fake) || (fakesensorval <= min_fake)) fake_adj = -1 * fake_adj; sensorval = fakesensorval; #endif #if ADV_DEBUG_MESSAGE_FORMAT==0 updateSensorData ((uint16)timeval, (uint16)tempval, (uint16)sensorval); DataReadyFlag = 1; #else // Gather additional interesting diagnostic info before updating structure spare = HalAdcRead(0x01, HAL_ADC_RESOLUTION_12); // Spare A/D chan - use for battery measurement later // Turn on the test mode to enable temperature measurement // from the CC2544's internal temp sensor ATEST=1; // ATEST.ATEST_CTRL=0x01; TR0=1; // TR0.ADCTM=1; HalAdcSetReference(0); // use internal ref voltage (1.15 V) //HalAdcSetReference ( 0x80); // use AVDD5 pin for ref // CC2541 Internal temp sensor is A/D input 14 (0x0e) tempvalCC2541 = HalAdcRead(0x0E, HAL_ADC_RESOLUTION_12); /* Turn off test modes */ TR0=0; // TR0.ADCTM=0; ATEST=0; // The analog temperature sensor in the CC2544 should give back a value // of 1480 at 25 degrees C and VDD=3, // and will change by a value of 4.5 per degree C // // So, to get temperature in 0.1 degrees C units, consider the // following formula: // tempval2 = tempvalCC2541-1480; tempvalCC2541 = (int16) (250.0 + (tempval2/4.5)); HalAdcSetReference(0); // use internal ref voltage (1.15 V) // Pick up VDD divided by 3 vdd_div_3 = HalAdcRead(0x0F, HAL_ADC_RESOLUTION_12); // VDD/3 // Convert to millivolts (and get rid of the divide by 3, since we're doing math // vdd = (int) (1.15*vdd_div_3*3.0*1000.0 / 2047.0); // convert to millivolts // vdd = (int) (vdd_div_3 * 1.6853932584269662921348314606742); // more precisely vdd = (int) (vdd_div_3 * 1.6853); // close enough // Pick up the spare A/D input HalAdcSetReference (0x40); // use AIN7 for ref spare = HalAdcRead(0x01, HAL_ADC_RESOLUTION_12); updateSensorData ((uint16)timeval, (uint16)tempval, (uint16)sensorval, (uint16)tempvalCC2541, (uint16)vdd, (uint16)spare); DataReadyFlag = 1; #endif // Set the light control I/O (LightOn=1 => P1_1=0) nuSOCKET_updateLight(); // Also, set P1_0 (the LED) as an output, and drive low P1DIR = P1DIR | 0x01; P1 = P1&0xFE; return (events ^ 1);; } return (0); } // end DataUpdate_ProcessEvent()
/*************************************************************************************************** * @fn uart_NpiSerialCallback * * @brief uart callback function * * @param port: uart port; events: events * * @return None ***************************************************************************************************/ void uart_NpiSerialCallback( uint8 port, uint8 events ) { (void)port;//加个 (void),是未了避免编译告警,明确告诉缓冲区不用理会这个变量 static uint32 old_time; //老时间 static uint32 old_time_data_len = 0; //老时间是的数据长度 uint32 new_time; //新时间 uint8 readMaxBytes = 32; if (events & (HAL_UART_RX_TIMEOUT | HAL_UART_RX_FULL)) //串口有数据 { uint8 numBytes = 0; numBytes = NPI_RxBufLen(); //读出串口缓冲区有多少字节 if(numBytes == 0) { old_time_data_len = 0; return; } if(old_time_data_len == 0) { old_time = osal_GetSystemClock(); //有数据来时, 记录一下 old_time_data_len = numBytes; } else { new_time = osal_GetSystemClock(); //当前时间 if( (numBytes >= readMaxBytes) || ( (new_time - old_time) > 50/*ms*/)) { uint8 sendBytes = 0; //申请缓冲区buffer uint8 *buffer = osal_mem_alloc(numBytes); if(numBytes > readMaxBytes) { sendBytes = readMaxBytes; } else { sendBytes = numBytes; } if(buffer) { //读取读取串口缓冲区数据,释放串口数据 NPI_ReadTransport(buffer,numBytes); //NPI_WriteTransport(buffer,numBytes); //NPI_WriteTransport("\r\n",2); //sprintf(buffer,"numBytes=%d\r\n",numBytes); //NPI_WriteTransport(buffer,strlen(buffer)); //NPI_WriteTransport(tmpbuffer,strlen(tmpbuffer)); // 命令处理函数 Uart_Msg_Handle(buffer,numBytes); //Uart_Msg_Handle(tmpbuffer,strlen(tmpbuffer)); //释放申请的缓冲区 osal_mem_free(buffer); } old_time = new_time; old_time_data_len = numBytes - sendBytes; } } } }
/*************************************************************************************************** * @fn HalLedUpdate * * @brief Update leds to work with blink * * @param none * * @return none ***************************************************************************************************/ void HalLedUpdate( void ) { #if (defined (BLINK_LEDS)) uint8 led; uint8 pct; uint8 leds; HalLedControl_t *sts; uint32 time; uint16 next; uint16 wait; next = 0; led = HAL_LED_1; leds = HAL_LED_ALL; sts = HalLedStatusTable; while ( leds ) { if ( leds & led ) { if ( sts->mode & HAL_LED_MODE_BLINK ) { time = osal_GetSystemClock(); if ( time >= sts->next ) { if (sts->mode & HAL_LED_MODE_ON ) { pct = 100 - sts->onPct; // Percentage of cycle for off sts->mode &= ~HAL_LED_MODE_ON; // Say it's not on HalLedOnOff( led, HAL_LED_MODE_OFF ); // Turn it off if (!(sts->mode & HAL_LED_MODE_FLASH)) { sts->todo--; /* Not continuous, reduce count */ } } else if ( !(sts->todo) && !(sts->mode & HAL_LED_MODE_FLASH) ) { sts->mode ^= HAL_LED_MODE_BLINK; /* No more blinks */ } else { pct = sts->onPct; /* Percentage of cycle for on */ sts->mode |= HAL_LED_MODE_ON; /* Say it's on */ HalLedOnOff (led, HAL_LED_MODE_ON); /* Turn it on */ } if ( sts->mode & HAL_LED_MODE_BLINK ) { wait = (((uint32)pct * (uint32)sts->time) / 100); sts->next = time + wait; } else { /* no more blink, no more wait */ wait = 0; /* After blinking, set the LED back to the state before it blinks */ HalLedSet (led, ((preBlinkState & led)!=0)?HAL_LED_MODE_ON:HAL_LED_MODE_OFF); /* Clear the saved bit */ preBlinkState &= (0xff ^ led); } } else wait = sts->next - time; // Time left if ( !next || ( wait && (wait < next) ) ) next = wait; } leds ^= led; } led <<= 1; sts++; } if ( next ) osal_start_timerEx(Hal_TaskID, HAL_LED_BLINK_EVENT, next); // Come back later #endif /* BLINK_LEDS */ }
/**************************************************************************** * @fn ZDiagsUpdateStats * * @brief Update statistics and/or metrics for a specific Attribute Id * * @param attributeId input - unique identifier for the required attribute * * @return none. */ void ZDiagsUpdateStats( uint16 attributeId ) { #if defined ( FEATURE_SYSTEM_STATS ) switch ( attributeId ) { // System and Hardware Diagnostics case ZDIAGS_SYSTEM_CLOCK: DiagsStatsTable.SysClock = osal_GetSystemClock(); break; case ZDIAGS_PERSISTENT_MEMORY_WRITES: DiagsStatsTable.PersistentMemoryWrites++; break; // NWK Diagnostics case ZDIAGS_ROUTE_DISC_INITIATED: DiagsStatsTable.RouteDiscInitiated++; break; case ZDIAGS_NEIGHBOR_ADDED: DiagsStatsTable.NeighborAdded++; break; case ZDIAGS_NEIGHBOR_REMOVED: DiagsStatsTable.NeighborRemoved++; break; case ZDIAGS_NEIGHBOR_STALE: DiagsStatsTable.NeighborStale++; break; case ZDIAGS_JOIN_INDICATION: DiagsStatsTable.JoinIndication++; break; case ZDIAGS_CHILD_MOVED: DiagsStatsTable.ChildMoved++; break; case ZDIAGS_NWK_FC_FAILURE: DiagsStatsTable.NwkFcFailure++; break; case ZDIAGS_NWK_DECRYPT_FAILURES: DiagsStatsTable.NwkDecryptFailures++; break; case ZDIAGS_PACKET_BUFFER_ALLOCATE_FAILURES: DiagsStatsTable.PacketBufferAllocateFailures++; break; case ZDIAGS_RELAYED_UCAST: DiagsStatsTable.RelayedUcast++; break; case ZDIAGS_PHY_TO_MAC_QUEUE_LIMIT_REACHED: DiagsStatsTable.PhyToMacQueueLimitReached++; break; case ZDIAGS_PACKET_VALIDATE_DROP_COUNT: DiagsStatsTable.PacketValidateDropCount++; break; // APS Diagnostics case ZDIAGS_APS_RX_BCAST: DiagsStatsTable.ApsRxBcast++; break; case ZDIAGS_APS_TX_BCAST: DiagsStatsTable.ApsTxBcast++; break; case ZDIAGS_APS_RX_UCAST: DiagsStatsTable.ApsRxUcast++; break; case ZDIAGS_APS_TX_UCAST_SUCCESS: DiagsStatsTable.ApsTxUcastSuccess++; break; case ZDIAGS_APS_TX_UCAST_RETRY: DiagsStatsTable.ApsTxUcastRetry++; break; case ZDIAGS_APS_TX_UCAST_FAIL: DiagsStatsTable.ApsTxUcastFail++; break; case ZDIAGS_APS_FC_FAILURE: DiagsStatsTable.ApsFcFailure++; break; case ZDIAGS_APS_UNAUTHORIZED_KEY: DiagsStatsTable.ApsUnauthorizedKey++; break; case ZDIAGS_APS_DECRYPT_FAILURES: DiagsStatsTable.ApsDecryptFailures++; break; case ZDIAGS_APS_INVALID_PACKETS: DiagsStatsTable.ApsInvalidPackets++; break; case ZDIAGS_MAC_RETRIES_PER_APS_TX_SUCCESS: DiagsStatsTable.MacRetriesPerApsTxSuccess++; break; default: break; } #endif // FEATURE_SYSTEM_STATS }