/********************************************************************* * @fn zllSampleLight_HandleKeys * * @brief Handles all key events for this device. * * @param shift - true if in shift/alt. * @param keys - bit field for key events. * * @return none */ static void zllSampleLight_HandleKeys( byte shift, byte keys ) { (void)shift; // Intentionally unreferenced parameter #ifdef HAL_BOARD_ZLIGHT // Zlight has only a single button static uint32 keyPressTime = 0; if ( keys ) { keyPressTime = osal_getClock(); } else //key released { if ( keyPressTime ) { keyPressTime = ( osal_getClock() - keyPressTime ); if ( keyPressTime <= KEY_HOLD_SHORT_INTERVAL ) { zllTarget_PermitJoin( PERMIT_JOIN_DURATION ); } else if ( keyPressTime > KEY_HOLD_LONG_INTERVAL ) { zllTarget_ClassicalCommissioningStart(); } else { zllTarget_ResetToFactoryNew(); } keyPressTime = 0; } } #else //HAL_BOARD_CC2530EB ? if ( keys & CLASSIC_COMMISS_KEY ) { zllTarget_ClassicalCommissioningStart(); } if ( keys & FACTORY_RESET_KEY ) { zllTarget_ResetToFactoryNew(); } if ( keys & PERMIT_JOIN_KEY ) { zllTarget_PermitJoin( PERMIT_JOIN_DURATION ); HalLcdWriteString( "PermitJoin", HAL_LCD_LINE_3 ); } if ( keys & DISPLAY_NWK_KEY_KEY ) { #if ( HAL_LCD == TRUE ) zllSampleLight_PrintNwkKey( FALSE ); #endif //( HAL_LCD == TRUE ) } #endif //HAL_BOARD_ZLIGHT }
/********************************************************************* * @fn thermometerMeasIndicate * * @brief Prepare and send a thermometer measurement notification * * @return none */ static void thermometerMeasIndicate(void) { // att value notification structure uint8 *p = thermometerMeas.value; // temperature uint32 temperature; //flags uint8 flags = thermometerFlags[thermometerFlagsIdx]; // flags 1 byte long *p++ = flags; if(flags & THERMOMETER_FLAGS_FARENHEIT) { temperature = (thermometerCelcius *9/5) +320; } else { temperature = thermometerCelcius; } temperature = 0xFF000000 | temperature; //osal_buffer_uint32 osal_buffer_uint32( p, temperature ); //temperature is 4 bytes long *p++; *p++; *p++; *p++; //timestamp if (flags & THERMOMETER_FLAGS_TIMESTAMP) { UTCTimeStruct time; // Get time structure from OSAL osal_ConvertUTCTime( &time, osal_getClock() ); *p++ = (time.year & 0x00FF); *p++ = (time.year & 0xFF00)>>8; //*p++ = time.year; //*p++; *p++=time.month; *p++=time.day; *p++=time.hour; *p++=time.minutes; *p++=time.seconds; }
static void encap_picture_param(struct ther_info *ti, struct display_param *param) { unsigned short time; UTCTimeStruct utc; osal_ConvertUTCTime(&utc, osal_getClock() - ti->start_sec); time = ((unsigned short)utc.hour << 8) | utc.minutes; param->time = time; param->batt_percentage = ti->batt_percentage; param->ble_link = ti->ble_connect; param->temp = ti->temp_current; param->max_temp = ti->temp_max; }
/*************************************************************************************************** * @fn MT_SysGetUtcTime * * @brief Get the OSAL UTC time * * @param None * * @return 32-bit and Parsed UTC time ***************************************************************************************************/ void MT_SysGetUtcTime(void) { uint8 len; uint8 *buf; len = sizeof( UTCTime ) + sizeof( UTCTimeStruct ); buf = osal_mem_alloc( len ); if ( buf ) { uint8 *pBuf; UTCTime utcSecs; UTCTimeStruct utcTime; // Get current 32-bit UTC time and parse it utcSecs = osal_getClock(); osal_ConvertUTCTime( &utcTime, utcSecs ); // Start with 32-bit UTC time pBuf = osal_buffer_uint32( buf, utcSecs ); // Concatenate parsed UTC time fields *pBuf++ = utcTime.hour; *pBuf++ = utcTime.minutes; *pBuf++ = utcTime.seconds; *pBuf++ = utcTime.month + 1; // Convert to human numbers *pBuf++ = utcTime.day + 1; *pBuf++ = LO_UINT16( utcTime.year ); *pBuf++ = HI_UINT16( utcTime.year ); /* Build and send back the response */ MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS), MT_SYS_GET_TIME, (uint8)(pBuf-buf), buf); osal_mem_free( buf ); } }
/********************************************************************* * @fn loadcontrol_event_loop * * @brief Event Loop Processor for loadcontrol. * * @param uint8 task id - load control task id * @param uint16 events - event bitmask * * @return none */ uint16 loadcontrol_event_loop( uint8 task_id, uint16 events ) { afIncomingMSGPacket_t *MSGpkt; if ( events & SYS_EVENT_MSG ) { while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( loadControlTaskID )) ) { switch ( MSGpkt->hdr.event ) { case ZCL_INCOMING_MSG: // Incoming ZCL foundation command/response messages loadcontrol_ProcessZCLMsg( (zclIncomingMsg_t *)MSGpkt ); break; case KEY_CHANGE: loadcontrol_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys ); break; case ZDO_STATE_CHANGE: if (DEV_ROUTER == (devStates_t)(MSGpkt->hdr.status)) { #if SECURE { // check to see if link key had already been established linkKeyStatus = loadcontrol_KeyEstablish_ReturnLinkKey(ESPAddr.addr.shortAddr); if (linkKeyStatus != ZSuccess) { // send out key establishment request osal_set_event( loadControlTaskID, LOADCONTROL_KEY_ESTABLISHMENT_REQUEST_EVT); } } #endif } break; default: break; } // Release the memory osal_msg_deallocate( (uint8 *)MSGpkt ); } // return unprocessed events return (events ^ SYS_EVENT_MSG); } // event to intiate key establishment request if ( events & LOADCONTROL_KEY_ESTABLISHMENT_REQUEST_EVT ) { zclGeneral_KeyEstablish_InitiateKeyEstablishment(loadControlTaskID, &ESPAddr, loadControlTransID); return ( events ^ LOADCONTROL_KEY_ESTABLISHMENT_REQUEST_EVT ); } // handle processing of identify timeout event triggered by an identify command if ( events & LOADCONTROL_IDENTIFY_TIMEOUT_EVT ) { if ( loadControlIdentifyTime > 0 ) { loadControlIdentifyTime--; } loadcontrol_ProcessIdentifyTimeChange(); return ( events ^ LOADCONTROL_IDENTIFY_TIMEOUT_EVT ); } // event to get current time if ( events & LOADCONTROL_UPDATE_TIME_EVT ) { loadControlTime = osal_getClock(); osal_start_timerEx( loadControlTaskID, LOADCONTROL_UPDATE_TIME_EVT, LOADCONTROL_UPDATE_TIME_PERIOD ); return ( events ^ LOADCONTROL_UPDATE_TIME_EVT ); } // event to handle load control complete event if ( events & LOADCONTROL_LOAD_CTRL_EVT ) { // load control evt completed // Send response back // DisableDefaultResponse is set to false - it is recommended to turn on // default response since Report Event Status Command does not have // a response. rsp.eventStatus = EVENT_STATUS_LOAD_CONTROL_EVENT_COMPLETED; zclSE_LoadControl_Send_ReportEventStatus( LOADCONTROL_ENDPOINT, &ESPAddr, &rsp, false, loadControlTransID ); HalLcdWriteString("Load Evt Complete", HAL_LCD_LINE_3); HalLedSet(HAL_LED_4, HAL_LED_MODE_OFF); return ( events ^ LOADCONTROL_LOAD_CTRL_EVT ); } // Discard unknown events return 0; }
static void ther_handle_ps_event(unsigned char event, unsigned char *data, unsigned char *len) { struct ther_info *ti = &ther_info; UTCTimeStruct utc; uint16 high_temp_threshold; switch (event) { case THER_PS_GET_WARNING_ENABLED: *data = ti->warning_enabled; *len = 1; print(LOG_DBG, MODULE "get warning enabled: %d\n", *data); break; case THER_PS_SET_WARNING_ENABLED: ti->warning_enabled = *data; print(LOG_DBG, MODULE "set warning enabled: %d\n", *data); break; case THER_PS_CLEAR_WARNING: print(LOG_DBG, MODULE "clear warning: %d\n", *data); ther_clear_high_temp_warning(ti); break; case THER_PS_GET_HIGH_WARN_TEMP: memcpy(data, &ti->high_temp_threshold, sizeof(ti->high_temp_threshold)); *len = sizeof(ti->high_temp_threshold); print(LOG_DBG, MODULE "get high temp: %d\n", *(unsigned short *)data); break; case THER_PS_SET_HIGH_WARN_TEMP: memcpy(&high_temp_threshold, data, sizeof(high_temp_threshold)); if (storage_write_high_temp_threshold(high_temp_threshold)) { print(LOG_DBG, MODULE "set high temp: %d\n", high_temp_threshold); ti->high_temp_threshold = high_temp_threshold; ti->next_warning_threshold = ti->high_temp_threshold; } else { print(LOG_DBG, MODULE "set high temp: %d failed\n", high_temp_threshold); } break; case THER_PS_GET_TIME: osal_ConvertUTCTime(&utc, osal_getClock()); memcpy(data, &utc, sizeof(utc)); *len = sizeof(utc); print(LOG_DBG, MODULE "get time: %d-%02d-%02d %02d:%02d:%02d\n", utc.year, utc.month, utc.day, utc.hour, utc.minutes, utc.seconds); break; case THER_PS_SET_TIME: memcpy(&utc, data, sizeof(utc)); osal_setClock(osal_ConvertUTCSecs(&utc)); print(LOG_DBG, MODULE "set time: %d-%02d-%02d %02d:%02d:%02d\n", utc.year, utc.month, utc.day, utc.hour, utc.minutes, utc.seconds); ti->start_sec = osal_ConvertUTCSecs(&utc); break; case THER_PS_GET_DEBUG: { ti->mode = CAL_MODE; /* * stop temp measurement */ osal_stop_timerEx(ti->task_id, TH_TEMP_MEASURE_EVT); ther_temp_power_on(); ti->temp_measure_stage = TEMP_STAGE_SETUP; /* * stop batt measurement */ osal_stop_timerEx(ti->task_id, TH_BATT_EVT); } *(unsigned short *)data = ther_get_hw_adc(HAL_ADC_CHANNEL_0, FROM_CUSTOM); *len = 2; break; case THER_PS_SET_DEBUG: break; default: *len = 0; break; } }
/********************************************************************* * @fn thermometerMeasIndicate * * @brief Prepare and send a thermometer measurement indication * * @return none */ static void thermometerMeasIndicate(void) { // Thermometer measurement value stored in this structure. attHandleValueInd_t thermometerMeas; thermometerMeas.pValue = GATT_bm_alloc(gapConnHandle, ATT_HANDLE_VALUE_IND, THERMOMETER_MEAS_LEN, NULL); if (thermometerMeas.pValue != NULL) { // att value notification structure uint8 *p = thermometerMeas.pValue; // temperature uint32 temperature; //flags uint8 flags = thermometerFlags[thermometerFlagsIdx]; // flags 1 byte long *p++ = flags; if(flags & THERMOMETER_FLAGS_FARENHEIT) { temperature = (thermometerCelcius *9/5) +320; } else { temperature = thermometerCelcius; } temperature = 0xFF000000 | temperature; //osal_buffer_uint32 p = osal_buffer_uint32( p, temperature ); //timestamp if (flags & THERMOMETER_FLAGS_TIMESTAMP) { UTCTimeStruct time; // Get time structure from OSAL osal_ConvertUTCTime( &time, osal_getClock() ); *p++ = LO_UINT16(time.year); *p++ = HI_UINT16(time.year); *p++ = time.month; *p++ = time.day; *p++ = time.hour; *p++ = time.minutes; *p++ = time.seconds; } if(flags & THERMOMETER_FLAGS_TYPE) { uint8 site; Thermometer_GetParameter( THERMOMETER_TYPE, &site ); *p++ = site; } thermometerMeas.len = (uint8) (p - thermometerMeas.pValue); thermometerMeas.handle = THERMOMETER_TEMP_VALUE_POS; // Queue indication. thermometerStoreIndications( &thermometerMeas); //advertise measurement is ready thermometer_Advertise(); } }
/********************************************************************* * @fn thermometerMeasNotify * * @brief Prepare and send a thermometer measurement notification * * @return none */ static void thermometerImeasNotify(void) { if (temperatureIMeasCharConfig == true) { attHandleValueNoti_t thermometerIMeas; thermometerIMeas.pValue = GATT_bm_alloc( gapConnHandle, ATT_HANDLE_VALUE_NOTI, THERMOMETER_IMEAS_LEN, NULL ); if ( thermometerIMeas.pValue != NULL ) { // att value notification structure uint8 *p = thermometerIMeas.pValue; // temperature uint32 temperature; //flags uint8 flags = thermometerFlags[thermometerFlagsIdx]; // flags 1 byte long *p++ = flags; if(flags & THERMOMETER_FLAGS_FARENHEIT) { temperature = (thermometerCelcius *9/5) +320; } else { temperature = thermometerCelcius; } temperature = 0xFF000000 | temperature; //osal_buffer_uint32 p = osal_buffer_uint32( p, temperature ); //timestamp if (flags & THERMOMETER_FLAGS_TIMESTAMP) { UTCTimeStruct time; // Get time structure from OSAL osal_ConvertUTCTime( &time, osal_getClock() ); *p++ = LO_UINT16(time.year); *p++ = HI_UINT16(time.year); *p++ = time.month; *p++ = time.day; *p++ = time.hour; *p++ = time.minutes; *p++ = time.seconds; } if(flags & THERMOMETER_FLAGS_TYPE) { uint8 site; Thermometer_GetParameter( THERMOMETER_TYPE, &site ); *p++ = site; } thermometerIMeas.len = (uint8) (p - thermometerIMeas.pValue); if ( Thermometer_IMeasNotify( gapConnHandle, &thermometerIMeas) != SUCCESS ) { GATT_bm_free( (gattMsg_t *)&thermometerIMeas, ATT_HANDLE_VALUE_NOTI ); } } } }
/********************************************************************* * @fn bpFinalMeas * * @brief Prepare and send a bloodPressure measurement indication * * @return none */ static void bpFinalMeas(void) { // att value notification structure uint8 *p = bloodPressureMeas.value; //flags uint8 flags = bloodPressureFlags[bloodPressureFlagsIdx]; // flags 1 byte long *p++ = flags; //bloodpressure components *p++ = bpSystolic; *p++; *p++ = bpDiastolic; *p++; *p++ = bpMAP; *p++; //timestamp if (flags & BLOODPRESSURE_FLAGS_TIMESTAMP) { UTCTimeStruct time; // Get time structure from OSAL osal_ConvertUTCTime( &time, osal_getClock() ); *p++ = 0x07; *p++ = 0xdb; *p++=time.month; *p++=time.day; *p++=time.hour; *p++=time.minutes; *p++=time.seconds; } if(flags & BLOODPRESSURE_FLAGS_PULSE) { *p++ = bpPulseRate; *p++; } if(flags & BLOODPRESSURE_FLAGS_USER) { *p++ = bpUserId; } if(flags & BLOODPRESSURE_FLAGS_STATUS) { *p++ = bpMeasStatus; *p++; } bloodPressureMeas.len = (uint8) (p - bloodPressureMeas.value); //store measurment bpStoreIndications(&bloodPressureMeas); //send stored measurements bpSendStoredMeas(); //start disconnect timer osal_start_timerEx( bloodPressureTaskId, BP_DISCONNECT_EVT, BP_DISCONNECT_PERIOD ); }
/********************************************************************* * @fn loadcontrol_event_loop * * @brief Event Loop Processor for loadcontrol. * * @param uint8 task id - load control task id * @param uint16 events - event bitmask * * @return none */ uint16 loadcontrol_event_loop( uint8 task_id, uint16 events ) { afIncomingMSGPacket_t *MSGpkt; if ( events & SYS_EVENT_MSG ) { while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( loadControlTaskID )) ) { switch ( MSGpkt->hdr.event ) { case ZDO_CB_MSG: loadcontrol_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt ); break; case ZCL_INCOMING_MSG: // Incoming ZCL foundation command/response messages loadcontrol_ProcessZCLMsg( (zclIncomingMsg_t *)MSGpkt ); break; case KEY_CHANGE: loadcontrol_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys ); break; case ZDO_STATE_CHANGE: if (DEV_ROUTER == (devStates_t)(MSGpkt->hdr.status)) { #if SECURE { // check to see if link key had already been established linkKeyStatus = loadcontrol_KeyEstablish_ReturnLinkKey(ESPAddr.addr.shortAddr); if (linkKeyStatus != ZSuccess) { cId_t cbkeCluster = ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT; zAddrType_t dstAddr; // Send out a match for the key establishment dstAddr.addrMode = AddrBroadcast; dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR; ZDP_MatchDescReq( &dstAddr, NWK_BROADCAST_SHORTADDR, ZCL_SE_PROFILE_ID, 1, &cbkeCluster, 0, NULL, FALSE ); } } #endif } break; #if defined( ZCL_KEY_ESTABLISH ) case ZCL_KEY_ESTABLISH_IND: if ((MSGpkt->hdr.status) == TermKeyStatus_Success) { ESPAddr.endPoint = LOADCONTROL_ENDPOINT; // set destination endpoint back to application endpoint } break; #endif default: break; } // Release the memory osal_msg_deallocate( (uint8 *)MSGpkt ); } // return unprocessed events return (events ^ SYS_EVENT_MSG); } // event to intiate key establishment request if ( events & LOADCONTROL_KEY_ESTABLISHMENT_REQUEST_EVT ) { zclGeneral_KeyEstablish_InitiateKeyEstablishment(loadControlTaskID, &ESPAddr, loadControlTransID); return ( events ^ LOADCONTROL_KEY_ESTABLISHMENT_REQUEST_EVT ); } // handle processing of identify timeout event triggered by an identify command if ( events & LOADCONTROL_IDENTIFY_TIMEOUT_EVT ) { if ( loadControlIdentifyTime > 0 ) { loadControlIdentifyTime--; } loadcontrol_ProcessIdentifyTimeChange(); return ( events ^ LOADCONTROL_IDENTIFY_TIMEOUT_EVT ); } // event to get current time if ( events & LOADCONTROL_UPDATE_TIME_EVT ) { loadControlTime = osal_getClock(); osal_start_timerEx( loadControlTaskID, LOADCONTROL_UPDATE_TIME_EVT, LOADCONTROL_UPDATE_TIME_PERIOD ); return ( events ^ LOADCONTROL_UPDATE_TIME_EVT ); } // event to handle load control complete event if ( events & LOADCONTROL_LOAD_CTRL_EVT ) { // load control evt completed // Send response back // DisableDefaultResponse is set to FALSE - it is recommended to turn on // default response since Report Event Status Command does not have // a response. rsp.eventStatus = EVENT_STATUS_LOAD_CONTROL_EVENT_COMPLETED; zclSE_LoadControl_Send_ReportEventStatus( LOADCONTROL_ENDPOINT, &ESPAddr, &rsp, FALSE, loadControlTransID ); HalLcdWriteString("Load Evt Complete", HAL_LCD_LINE_3); HalLedSet(HAL_LED_4, HAL_LED_MODE_OFF); return ( events ^ LOADCONTROL_LOAD_CTRL_EVT ); } // Discard unknown events return 0; }
long OS_get_millis(void) { osalTimeUpdate(); return osal_getClock() * 1000 + osal_getMSClock(); }
static void sensorTag_ClockGet(UTCTimeStruct *t, UTCTime delta) { osal_ConvertUTCTime(t, osal_getClock() - delta); }
uint16 SensorTag_ProcessEvent(uint8 task_id, uint16 events) { VOID task_id; // OSAL required parameter that isn't used in this function /////////////////////////////////////////////////////////////////////// // system event handle // /////////////////////////////////////////////////////////////////////// if (events & SYS_EVENT_MSG) { uint8 *msg; if ((msg = osal_msg_receive(sensorTag_TaskID)) != NULL) { sensorTag_ProcessOSALMsg((osal_event_hdr_t *) msg); // release the OSAL message osal_msg_deallocate(msg); } // return unprocessed events return (events ^ SYS_EVENT_MSG); } /////////////////////////////////////////////////////////////////////// // start device event // /////////////////////////////////////////////////////////////////////// if (events & EVT_START_DEVICE) { // start the device GAPRole_StartDevice(&sensorTag_PeripheralCBs); // start bond manager #if !defined(GAPBONDMGR_NO_SUPPORT) GAPBondMgr_Register(&sensorTag_BondMgrCBs); #endif // start peripheral device oled_init(); adxl345_softrst(); // adxl345_self_calibration(); steps = 0; BATCD_PXIFG = ~(BATCD_BV); BATCD_IEN |= BATCD_IENBIT; osal_start_reload_timer(sensorTag_TaskID, EVT_RTC, PERIOD_RTC); pwmgr_state_change(PWMGR_S0, 0); fmsg(("\033[40;32m\n[power on]\033[0m\n")); return (events ^ EVT_START_DEVICE); } /////////////////////////////////////////////////////////////////////// // key long press handle // /////////////////////////////////////////////////////////////////////// if (events & EVT_MODE) { if (key1_press) { oled_clr_screen(); if ((opmode & 0xF0) == MODE_NORMAL) { opmode = MODE_WORKOUT | MODE_TIME; workout.steps = normal.steps; workout.time = osal_getClock(); fmsg(("\033[40;32m[workout mode]\033[0m\n")); } else { opmode = MODE_NORMAL | MODE_TIME; fmsg(("\033[40;32m[normal mode]\033[0m\n")); } pwmgr_state_change(pwmgr, TIME_OLED_OFF); } return (events ^ EVT_MODE); } if (events & EVT_SLEEP) { if (key1_press) { oled_clr_screen(); opmode = MODE_SLEEP; fmsg(("\033[40;32m[sleep mode]\033[0m\n")); pwmgr_state_change(pwmgr, TIME_OLED_OFF); } return (events ^ EVT_SLEEP); } if (events & EVT_SYSRST) { if (key1_press) { fmsg(("\033[40;32m[system reset]\033[0m\n")); HAL_SYSTEM_RESET(); // adxl345_self_calibration(); } return (events ^ EVT_SYSRST); } /////////////////////////////////////////////////////////////////////// // display handle // /////////////////////////////////////////////////////////////////////// if (events & EVT_DISP) { if (pwmgr == PWMGR_S1) { sensorTag_HandleDisp(opmode, acc); } else { // display battery only sensorTag_BattDisp(batt_get_level()); } if (pwmgr != PWMGR_S6) { osal_start_timerEx(sensorTag_TaskID, EVT_DISP, PERIOD_DISP); } return (events ^ EVT_DISP); } /////////////////////////////////////////////////////////////////////// // g-sensor handle // /////////////////////////////////////////////////////////////////////// if (events & EVT_GSNINT1) { adxl345_exit_sleep(); pwmgr_state_change(PWMGR_S3, TIME_GSEN_OFF); return (events ^ EVT_GSNINT1); } if (events & EVT_GSNINT2) { unsigned char sampling; unsigned char i; sampling = adxl345_chk_fifo(); for (i=0; i<sampling; i++) { adxl345_read(acc); #if (DEBUG_MESSAGE & MSG_STEPS) { unsigned long tmp = algo_step(acc); if (normal.steps != tmp) { stepmsg(("\033[1;33mstep=%0lu\n\033[0m", tmp)); } normal.steps = tmp; } #else normal.steps = algo_step(acc); #endif } normal.distance = calc_distance(normal.steps, pi.stride); workout.distance = calc_distance((normal.steps - workout.steps), pi.stride); normal.calorie = calc_calorie(normal.distance, pi.weight); workout.calorie = calc_calorie(workout.distance, pi.weight); return (events ^ EVT_GSNINT2); } if (events & EVT_GSENSOR) { adxl345_exit_sleep(); return (events ^ EVT_GSENSOR); } /////////////////////////////////////////////////////////////////////// // RTC handle // /////////////////////////////////////////////////////////////////////// if (events & EVT_RTC) { // performed once per second // record data if ((pwmgr != PWMGR_S5) && (pwmgr != PWMGR_S6)) { #if defined(HAL_IMAGE_A) || defined(HAL_IMAGE_B) if ((osal_getClock() - mark.time) >= (12UL*60UL)) { #else if ((osal_getClock() - mark.time) >= (12UL)) { #endif if (!hash_is_full()) { unsigned short tmp = normal.steps - mark.steps; switch (opmode & 0xF0) { case MODE_WORKOUT: tmp |= 0x8000; break; case MODE_SLEEP: tmp |= 0x4000; break; } hash_put(&tmp); } mark.time = osal_getClock(); #if defined(HAL_IMAGE_A) || defined(HAL_IMAGE_B) if ((mark.time % (24UL*60UL*60UL)) <= (13UL*60UL)) { #else if ((mark.time % (24UL*60UL*60UL)) <= (13UL)) { #endif dmsg(("reset steps...\n")); normal.steps = 0; workout.steps = 0; STEPS = 0; } mark.steps = normal.steps; } } // power management switch (pwmgr) { case PWMGR_S0: pmsg(("\033[40;35mS0 (power on)\033[0m\n")); if (pwmgr_saving_timer()) { adxl345_enter_sleep(); osal_pwrmgr_device(PWRMGR_BATTERY); pwmgr_state_change(PWMGR_S4, 0); } break; case PWMGR_S1: pmsg(("\033[40;35mS1 (rtc+gsen+ble+oled)\033[0m\n")); if (pwmgr_saving_timer()) { oled_enter_sleep(); osal_stop_timerEx(sensorTag_TaskID, EVT_MODE); osal_stop_timerEx(sensorTag_TaskID, EVT_SLEEP); osal_stop_timerEx(sensorTag_TaskID, EVT_SYSRST); pwmgr_state_change(PWMGR_S3, TIME_GSEN_OFF); } break; case PWMGR_S2: pmsg(("\033[40;35mS2 (rtc+gsen+ble)\033[0m\n")); if (gapProfileState == GAPROLE_WAITING) { // enable key interrupt mode InitBoard(OB_READY); pwmgr_state_change(PWMGR_S3, TIME_GSEN_OFF); } break; case PWMGR_S3: pmsg(("\033[40;35mS3 (rtc+gsen)\033[0m\n")); if (steps == normal.steps) { if (pwmgr_saving_timer()) { adxl345_enter_sleep(); pwmgr_state_change(PWMGR_S4, 0); } } else { steps = normal.steps; pwmgr_state_change(pwmgr, TIME_GSEN_OFF); } break; case PWMGR_S4: pmsg(("\033[40;35mS4 (rtc)\033[0m\n")); dmsg(("$")); break; default: case PWMGR_S5: pmsg(("\033[40;35mS5 (shutdown)\033[0m\n")); adxl345_shutdown(); osal_stop_timerEx(sensorTag_TaskID, EVT_RTC); break; case PWMGR_S6: pmsg(("\033[40;35mS6 (rtc+oled)\033[0m\n")); if (pwmgr_saving_timer()) { oled_enter_sleep(); // enable key interrupt mode InitBoard(OB_READY); pwmgr_state_change(PWMGR_S5, 0); } break; } // battery measure if ((!batt_measure()) && (pwmgr != PWMGR_S6)) { pwmgr_state_change(PWMGR_S5, 0); } return (events ^ EVT_RTC); } /////////////////////////////////////////////////////////////////////// // battery charge detect handle // /////////////////////////////////////////////////////////////////////// if (events & EVT_CHARGING) { if (pwmgr != PWMGR_S1) { if (!BATCD_SBIT) { dmsg(("[charging]\n")); oled_exit_sleep(); if ((pwmgr == PWMGR_S5) || (pwmgr == PWMGR_S6)) { osal_start_reload_timer(sensorTag_TaskID, EVT_RTC, PERIOD_RTC); pwmgr_state_change(PWMGR_S4, 0); } } else { dmsg(("[no charge]\n")); oled_enter_sleep(); } } return (events ^ EVT_CHARGING); } /////////////////////////////////////////////////////////////////////// // discard unknown events // /////////////////////////////////////////////////////////////////////// return 0; }
/****************************************************************************** * @fn modbus_process_msg * * @brief Process modbus message * * @param uint8 - the pointer the buffer * uint8 - length * * @return none */ static void modbus_process_msg( uint8 *data_buffer, uint8 len) { uint8 num, tempByte; uint8 zero = 0; uint16 i; uint16 address; boatMonitor_t *pTempMonitor; UTCTime utcSecs; UTCTimeStruct utcTime; utcSecs = osal_getClock(); osal_ConvertUTCTime( &utcTime, utcSecs ); address = BUILD_UINT16( data_buffer[3], data_buffer[2]); if(( data_buffer[0] == modbus_id) || ( data_buffer[0] == 255)) { if(data_buffer[1] == MODBUS_SINGLE_WRITE) { HalUARTWrite( 0, data_buffer, len); if( address == MODBUS_ADDRESS) { modbus_id = data_buffer[5]; osal_nv_write( ZCD_NV_MODBUS_ID, 0, sizeof(modbus_id), &modbus_id); } if( address == MODBUS_BAUDRATE) { if((data_buffer[5] >=0) &&(data_buffer[5] <= 4)) { modbus_set_baudrate = data_buffer[5]; osal_nv_write( ZCD_NV_BAUDRATE, 0, sizeof(modbus_set_baudrate), &modbus_set_baudrate); restore_factory_setting(); } } } else if( data_buffer[1] == MODBUS_MULTI_WRITE) { if( address == MODBUS_SERIALNUMBER_LOWORD) { if(data_buffer[6] == 8) { for( uint8 k=0;k<4;k++) { ttt[k] = data_buffer[2*k+8]; osal_nv_write( ZCD_NV_SERIAL_NUM, 0, sizeof(ttt), ttt); } } } // write system UTC if( address == MODBUS_SYS_HOUR) { if( data_buffer[6] >= 12) modbus_setUtcTime( &data_buffer[7]); } } else if( data_buffer[1] == MODBUS_SINGLE_READ) { num = data_buffer[5]; uint8 *pBuf; uint8 index=0; pBuf = osal_mem_alloc(num*2+5); if( pBuf != NULL) { pBuf[index++] = data_buffer[0]; pBuf[index++] = data_buffer[1]; pBuf[index++] = num*2; //modbus_send_byte( data_buffer[0], CRC_NO); //modbus_send_byte( data_buffer[1], CRC_NO); //modbus_send_byte( num*2, CRC_NO); for( i = 0; i < num; i++) { if ( i + address <= MODBUS_SERIALNUMBER_LOWORD + 3) { //modbus_send_byte( zero, CRC_NO); pBuf[index++] = zero; pBuf[index++] = ttt[ i + address - MODBUS_SERIALNUMBER_LOWORD]; } else if( i + address == MODBUS_FIRMWARE_VERSION_NUMBER_LO) { pBuf[index++] = zero; pBuf[index++] = ttt[4]; } else if( i + address == MODBUS_FIRMWARE_VERSION_NUMBER_HI) { pBuf[index++] = zero; pBuf[index++] = ttt[5]; } else if( i + address == MODBUS_ADDRESS) { pBuf[index++] = zero; pBuf[index++] = modbus_id; } else if( i + address == MODBUS_PRODUCT_ID) { pBuf[index++] = zero; pBuf[index++] = 210; } // System UTC Time else if( i + address == MODBUS_SYS_HOUR) { pBuf[index++] = zero; pBuf[index++] = utcTime.hour; } else if( i + address == MODBUS_SYS_MINUTES) { pBuf[index++] = zero; pBuf[index++] = utcTime.minutes; } else if( i + address == MODBUS_SYS_SECONDS) { pBuf[index++] = zero; pBuf[index++] = utcTime.seconds; } else if( i + address == MODBUS_SYS_MONTH) { tempByte = utcTime.month + 1; pBuf[index++] = zero; pBuf[index++] = tempByte; } else if( i + address == MODBUS_SYS_DAY) { tempByte = utcTime.day + 1; pBuf[index++] = zero; pBuf[index++] = tempByte; } else if( i + address == MODBUS_SYS_YEAR) { tempByte = HI_UINT16( utcTime.year); pBuf[index++] = tempByte; tempByte = LO_UINT16( utcTime.year); pBuf[index++] = tempByte; } /*else if( i + address == MODBUS_WATER_SWITCH) { if(leaveTimeCounter){ tempByte = water_switch; //leaveTimeCounter=0; } else tempByte = zero; pBuf[index++] = zero; pBuf[index++] = tempByte; } else if( i + address == MODBUS_DETECT_POWER) { uint16 power_temp; if(leaveTimeCounter){ power_temp = (ad_power-196)*10/10.57+90;//(ad_power-186)*100/74+90;//((ad_power-644)*64)/100+70; //leaveTimeCounter = 0; }else power_temp = 0; tempByte = HI_UINT16( power_temp); pBuf[index++] = tempByte; tempByte = LO_UINT16( power_temp); pBuf[index++] = tempByte; } else if( i + address == MODBUS_WATER_ID) { if(leaveTimeCounter){ tempByte = water_id; //leaveTimeCounter=0; } else tempByte = zero; pBuf[index++] = zero; pBuf[index++] = tempByte; } else if( i + address == MODBUS_WATER_RSSI) { if(leaveTimeCounter){ tempByte = (uint8)water_rssi; } else tempByte = zero; pBuf[index++] = 255; pBuf[index++] = tempByte; } else if( i + address == MODBUS_WATER_SWITCH1) { if(leaveTimeCounter1){ tempByte = water_switch1; //leaveTimeCounter=0; } else tempByte = zero; pBuf[index++] = zero; pBuf[index++] = tempByte; } else if( i + address == MODBUS_DETECT_POWER1) { uint16 power_temp; if(leaveTimeCounter1){ power_temp = (ad_power1-196)*10/10.57+90;//(ad_power-186)*100/74+90;//((ad_power-644)*64)/100+70; //leaveTimeCounter = 0; }else power_temp = 0; tempByte = HI_UINT16( power_temp); pBuf[index++] = tempByte; tempByte = LO_UINT16( power_temp); pBuf[index++] = tempByte; } else if( i + address == MODBUS_WATER_ID1) { if(leaveTimeCounter1){ tempByte = water_id1; //leaveTimeCounter=0; } else tempByte = zero; pBuf[index++] = zero; pBuf[index++] = tempByte; }*/ else if( i + address == MODBUS_BAUDRATE) { tempByte = modbus_set_baudrate; pBuf[index++] = zero; pBuf[index++] = tempByte; } else if( i + address == MODBUS_PANID) { tempByte = HI_UINT16( _NIB.nwkPanId); pBuf[index++] = tempByte; tempByte = LO_UINT16( _NIB.nwkPanId); pBuf[index++] = tempByte; } else if( i + address == MODBUS_DEVICE_TYPE) { tempByte = zgDeviceLogicalType; pBuf[index++] = zero; pBuf[index++] = tempByte; } else if( i + address == MODBUS_CHANNEL_LIST_HI) { tempByte = BREAK_UINT32(zgDefaultChannelList, 3); pBuf[index++] = tempByte; tempByte = BREAK_UINT32(zgDefaultChannelList, 2); pBuf[index++] = tempByte; } else if( i + address == MODBUS_CHANNEL_LIST_LO) { tempByte = BREAK_UINT32(zgDefaultChannelList, 1); pBuf[index++] = tempByte; tempByte = BREAK_UINT32(zgDefaultChannelList, 0); pBuf[index++] = tempByte; } else if( (i + address >= MODBUS_EXTENDED_ADDR_HI) && (i + address <= MODBUS_EXTENDED_ADDR_LO)) { tempByte = aExtendedAddress[ i+address-MODBUS_EXTENDED_ADDR_HI]; pBuf[index++] = zero; pBuf[index++] = tempByte; } else if( (i + address >= MODBUS_SECURITY_KEY_START) && (i + address <= MODBUS_SECURITY_KEY_END)) { tempByte = defaultKey[ i+address-MODBUS_SECURITY_KEY_START]; pBuf[index++] = zero; pBuf[index++] = tempByte; } /*else if( i + address == MODBUS_DETECT_PIN1) { uint16 power_temp; if(leaveTimeCounter){ power_temp = detectPin1; }else power_temp = 0; tempByte = HI_UINT16( power_temp); pBuf[index++] = tempByte; tempByte = LO_UINT16( power_temp); pBuf[index++] = tempByte; } else if( i + address == MODBUS_DETECT_PIN2) { uint16 power_temp; if(leaveTimeCounter){ power_temp = detectPin2; //leaveTimeCounter=0; }else power_temp = 0; tempByte = HI_UINT16( power_temp); pBuf[index++] = tempByte; tempByte = LO_UINT16( power_temp); pBuf[index++] = tempByte; }*/ else if( i + address == MODBUS_MONITOR_NUM) { tempByte = numMonitor; pBuf[index++] = zero; pBuf[index++] = tempByte; } else if( (i + address >= MODBUS_FIRST_MONITOR_ID) && ( i+ address <= MODBUS_LAST_MONITOR_ID)) { if( i + address == MODBUS_FIRST_MONITOR_ID) { pTempMonitor = pBoatMonitor; } else { pTempMonitor = pBoatMonitor; for( uint8 j=0; j<((i+address)-MODBUS_FIRST_MONITOR_ID); j++) { if(pTempMonitor) pTempMonitor = pTempMonitor->next; } } pBuf[index++]= zero; if(pTempMonitor != NULL) { pBuf[index++]= pTempMonitor->modbus_id; } else pBuf[index++]= zero; } else if( (i + address >= MODBUS_FIRST_DETECT_POWER) && ( i+ address <= MODBUS_LAST_DETECT_POWER)) { if( i + address == MODBUS_FIRST_DETECT_POWER) { pTempMonitor = pBoatMonitor; } else { pTempMonitor = pBoatMonitor; for( uint8 j=0; j<((i+address)-MODBUS_FIRST_DETECT_POWER); j++) { if(pTempMonitor) pTempMonitor = pTempMonitor->next; } } if(pTempMonitor != NULL) { uint16 power_temp; power_temp = (pTempMonitor->ad_power-196)*10/10.57+90; tempByte = HI_UINT16( power_temp); pBuf[index++] = tempByte; tempByte = LO_UINT16( power_temp); pBuf[index++] = tempByte; } else { pBuf[index++]= zero; pBuf[index++]= zero; } } else if( (i + address >= MODBUS_FIRST_WATER_SWITCH) && ( i+ address <= MODBUS_LAST_WATER_SWITCH)) { if( i + address == MODBUS_FIRST_WATER_SWITCH) { pTempMonitor = pBoatMonitor; } else { pTempMonitor = pBoatMonitor; for( uint8 j=0; j<((i+address)-MODBUS_FIRST_WATER_SWITCH); j++) { if(pTempMonitor) pTempMonitor = pTempMonitor->next; } } pBuf[index++]= zero; if(pTempMonitor != NULL) { pBuf[index++]= pTempMonitor->water_switch; } else pBuf[index++]= zero; } else if((i + address >= MODBUS_FIRST_DETECT_PIN1) && ( i+ address <= MODBUS_LAST_DETECT_PIN1)) { if( i + address == MODBUS_FIRST_DETECT_PIN1) { pTempMonitor = pBoatMonitor; } else { pTempMonitor = pBoatMonitor; for( uint8 j=0; j<((i+address)-MODBUS_FIRST_DETECT_PIN1); j++) { if(pTempMonitor) pTempMonitor = pTempMonitor->next; } } if(pTempMonitor != NULL) { tempByte = HI_UINT16( pTempMonitor->detectPin1); pBuf[index++] = tempByte; tempByte = LO_UINT16( pTempMonitor->detectPin1); pBuf[index++] = tempByte; } else { pBuf[index++]= zero; pBuf[index++]= zero; } } else if((i + address >= MODBUS_FIRST_DETECT_PIN2) && ( i+ address <= MODBUS_LAST_DETECT_PIN2)) { if( i + address == MODBUS_FIRST_DETECT_PIN2) { pTempMonitor = pBoatMonitor; } else { pTempMonitor = pBoatMonitor; for( uint8 j=0; j<((i+address)-MODBUS_FIRST_DETECT_PIN2); j++) { if(pTempMonitor) pTempMonitor = pTempMonitor->next; } } if(pTempMonitor != NULL) { tempByte = HI_UINT16( pTempMonitor->detectPin2); pBuf[index++] = tempByte; tempByte = LO_UINT16( pTempMonitor->detectPin2); pBuf[index++] = tempByte; } else { pBuf[index++]= zero; pBuf[index++]= zero; } } else if( (i + address >= MODBUS_FIRST_RSSI) && ( i+ address <= MODBUS_LAST_RSSI)) { if( i + address == MODBUS_FIRST_RSSI) { pTempMonitor = pBoatMonitor; } else { pTempMonitor = pBoatMonitor; for( uint8 j=0; j<((i+address)-MODBUS_FIRST_RSSI); j++) { if(pTempMonitor) pTempMonitor = pTempMonitor->next; } } if(pTempMonitor->rssi>=0) pBuf[index++] = 0; else pBuf[index++]= 0xff; if(pTempMonitor != NULL) { pBuf[index++]= pTempMonitor->rssi; } else pBuf[index++]= zero; } else { pBuf[index++] = zero; pBuf[index++] = zero; } } for( i=0; i<num*2+3; i++) CRC16_byte(pBuf[i]); pBuf[num*2+3] = CRChi; pBuf[num*2+4] = CRClo; P1_0 = 1; send_str_Uart( pBuf, num*2+5, 0); P1_0 = 0; osal_mem_free(pBuf); } else{ send_str_Uart( pBuf, num*2+5, 0); } } } }
/********************************************************************* * @fn ipd_event_loop * * @brief Event Loop Processor for ipd. * * @param uint8 task_id - ipd task id * @param uint16 events - event bitmask * * @return none */ uint16 ipd_event_loop( uint8 task_id, uint16 events ) { afIncomingMSGPacket_t *MSGpkt; if ( events & SYS_EVENT_MSG ) { while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( ipdTaskID )) ) { switch ( MSGpkt->hdr.event ) { case ZCL_INCOMING_MSG: // Incoming ZCL foundation command/response messages ipd_ProcessZCLMsg( (zclIncomingMsg_t *)MSGpkt ); break; case KEY_CHANGE: ipd_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys ); break; case ZDO_STATE_CHANGE: if (DEV_END_DEVICE == (devStates_t)(MSGpkt->hdr.status)) { #if SECURE { // check to see if link key had already been established linkKeyStatus = ipd_KeyEstablish_ReturnLinkKey(ESPAddr.addr.shortAddr); if (linkKeyStatus != ZSuccess) { // send out key establishment request osal_set_event( ipdTaskID, IPD_KEY_ESTABLISHMENT_REQUEST_EVT); } else { // link key already established, resume sending reports osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD ); } } #else { osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD ); } #endif // Per smart energy spec end device polling requirement of not to poll < 7.5 seconds. NLME_SetPollRate ( SE_DEVICE_POLL_RATE ); } break; #if defined( ZCL_KEY_ESTABLISH ) case ZCL_KEY_ESTABLISH_IND: if ((MSGpkt->hdr.status) == TermKeyStatus_Success) { osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD ); } break; #endif default: break; } // Release the memory osal_msg_deallocate( (uint8 *)MSGpkt ); } // return unprocessed events return (events ^ SYS_EVENT_MSG); } // event to intiate key establishment request if ( events & IPD_KEY_ESTABLISHMENT_REQUEST_EVT ) { zclGeneral_KeyEstablish_InitiateKeyEstablishment(ipdTaskID, &ESPAddr, ipdTransID); return ( events ^ IPD_KEY_ESTABLISHMENT_REQUEST_EVT ); } // event to get current price if ( events & IPD_GET_PRICING_INFO_EVT ) { zclSE_Pricing_Send_GetCurrentPrice( IPD_ENDPOINT, &ESPAddr, option, TRUE, 0 ); osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD ); return ( events ^ IPD_GET_PRICING_INFO_EVT ); } // handle processing of identify timeout event triggered by an identify command if ( events & IPD_IDENTIFY_TIMEOUT_EVT ) { if ( ipdIdentifyTime > 0 ) { ipdIdentifyTime--; } ipd_ProcessIdentifyTimeChange(); return ( events ^ IPD_IDENTIFY_TIMEOUT_EVT ); } // event to get current time if ( events & IPD_UPDATE_TIME_EVT ) { ipdTime = osal_getClock(); osal_start_timerEx( ipdTaskID, IPD_UPDATE_TIME_EVT, IPD_UPDATE_TIME_PERIOD ); return ( events ^ IPD_UPDATE_TIME_EVT ); } // Discard unknown events return 0; }