/****************************************************************************** * @fn modbus_single_write */ void modbus_single_write( uint8 *data_buffer, uint8 len) { uint8 address; address = BUILD_UINT16( data_buffer[3], data_buffer[2]); if( address == MODBUS_PANID) { zgConfigPANID = BUILD_UINT16( data_buffer[5], data_buffer[4]); osal_nv_write( ZCD_NV_PANID, 0, sizeof(zgConfigPANID), &zgConfigPANID); } else if( address == MODBUS_DEVICE_TYPE) { zgDeviceLogicalType = data_buffer[5]; osal_nv_write( ZCD_NV_LOGICAL_TYPE, 0, sizeof(zgDeviceLogicalType), &zgDeviceLogicalType); restore_factory_setting(); } else if( address == MODBUS_CHANNEL_LIST_HI) { zgDefaultChannelList = BUILD_UINT32( 0, 0, data_buffer[5], data_buffer[4]); } else if( address == MODBUS_CHANNEL_LIST_LO) { zgDefaultChannelList = BUILD_UINT32( data_buffer[5], data_buffer[4], 0, 0 ); osal_nv_write( ZCD_NV_CHANLIST, 0, sizeof(zgDefaultChannelList), &zgDefaultChannelList); } else if( address == MODBUS_FACTORY_RESTORE) { if(data_buffer[5] == 1) { restore_factory_setting(); } } }
/****************************************************************************** * @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); } } } }
static void modbus_process_msg( uint8 *data_buffer, uint8 len) { uint8 num, tempByte; uint8 zero = 0; uint16 i; uint16 address; signalStrength_t* pSigStren; afAddrType_t destAddr; destAddr.addrMode = afAddrBroadcast; destAddr.addr.shortAddr = 0xffff; destAddr.endPoint = 10; address = BUILD_UINT16( data_buffer[3], data_buffer[2]); if( data_buffer[0] == modbus_id) { if(data_buffer[1] == MODBUS_SINGLE_WRITE) { HalUARTWrite( 0, data_buffer, len); if (address == MODBUS_DEVICE_TYPE) { zgDeviceLogicalType = data_buffer[5]; osal_nv_write( ZCD_NV_LOGICAL_TYPE, 0, sizeof(zgDeviceLogicalType), &zgDeviceLogicalType); restore_factory_setting(); } else if( address == MODBUS_FACTORY_RESTORE) { if( address == MODBUS_FACTORY_RESTORE) { if(data_buffer[5] == 1) { restore_factory_setting(); } } } } else if(data_buffer[1] == MODBUS_MULTI_WRITE) { } else if( data_buffer[1] == MODBUS_SINGLE_READ) { num = data_buffer[5]; 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_PANID) { tempByte = HI_UINT16( _NIB.nwkPanId); modbus_send_byte( tempByte, CRC_NO); tempByte = LO_UINT16( _NIB.nwkPanId); modbus_send_byte( tempByte, CRC_NO); } else if( i + address == MODBUS_DEVICE_TYPE) { modbus_send_byte( zero, CRC_NO); modbus_send_byte( zgDeviceLogicalType, CRC_NO); } else if( i + address == MODBUS_CHANNEL_LIST_HI) { tempByte = HI_UINT16(zgConfigPANID); modbus_send_byte( zero, CRC_NO); tempByte = LO_UINT16(zgConfigPANID); modbus_send_byte( zero, CRC_NO); } else if( i + address == MODBUS_CHANNEL_LIST_LO) { tempByte = HI_UINT16(zgConfigPANID); modbus_send_byte( zero, CRC_NO); tempByte = LO_UINT16(zgConfigPANID); modbus_send_byte( zero, CRC_NO); } else if( i + address == MODBUS_SOFTWARE_REV) { modbus_send_byte( zero, CRC_NO); modbus_send_byte( zSoftwareRev, CRC_NO); } else if( (i + address >= MODBUS_EXTENDED_ADDR_HI) && (i + address <= MODBUS_EXTENDED_ADDR_LO)) { modbus_send_byte( zero, CRC_NO); modbus_send_byte( aExtendedAddress[ i+modbusStartAddr-MODBUS_EXTENDED_ADDR_HI], CRC_NO); } else if( (i + address >= MODBUS_SECURITY_KEY_START) && (i + address <= MODBUS_SECURITY_KEY_END)) { modbus_send_byte( zero, CRC_NO); modbus_send_byte( defaultKey[ i+modbusStartAddr-MODBUS_SECURITY_KEY_START], CRC_NO); } else if( i + address == MODBUS_TSTAT_NUM) { modbus_send_byte( zero, CRC_NO); modbus_send_byte( numSignalStren, CRC_NO); } else if( (i + address >= MODBUS_FIRST_TSTAT_ID) && ( i+ address <= MODBUS_LAST_TSTAT_ID)) { if( i + address == MODBUS_FIRST_TSTAT_ID) { pSigStren = pSignalStren; } else { pSigStren = pSignalStren; for( uint8 j=0; j<((i+address)-MODBUS_FIRST_TSTAT_ID); j++) { if(pSigStren) pSigStren = pSigStren->next; } } modbus_send_byte( zero, CRC_NO); if(pSigStren != NULL) { modbus_send_byte( pSigStren->modbus_id, CRC_NO); } else modbus_send_byte( zero, CRC_NO); } else if( (i + address >= MODBUS_FIRST_SIG_STREN) && ( i+ address <= MODBUS_LAST_SIG_STREN)) { if( i + address == MODBUS_FIRST_SIG_STREN) { pSigStren = pSignalStren; } else { pSigStren = pSignalStren; for( uint8 j=0; j<((i+address)-MODBUS_FIRST_SIG_STREN); j++) { if(pSigStren) pSigStren = pSigStren->next; } } modbus_send_byte( zero, CRC_NO); if(pSigStren != NULL) { modbus_send_byte( pSigStren->rssi, CRC_NO); } else modbus_send_byte( zero, CRC_NO); } else { modbus_send_byte( 0, CRC_NO); modbus_send_byte( 1, CRC_NO); } } modbus_send_byte( CRChi, CRC_YES); modbus_send_byte( CRClo, CRC_YES); } } else { AF_DataRequest( &destAddr, &temco_epDesc, TEMCO_CLUSTERID, len, data_buffer, &temcoApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ); } }
/********************************************************************* * @fn temcoApp_ProcessEvent */ uint16 temcoApp_ProcessEvent(uint8 task_id, uint16 events) { osal_event_hdr_t *pMsg; afIncomingMSGPacket_t *pMSGpkt; if( events & SYS_EVENT_MSG) { pMsg = (osal_event_hdr_t *) osal_msg_receive( task_id ); while(pMsg) { switch( pMsg->event) { case AF_INCOMING_MSG_CMD: pMSGpkt = (afIncomingMSGPacket_t *)pMsg; temcoApp_MessageMSGCB(pMSGpkt); break; case ZDO_STATE_CHANGE: if (pMsg->status == DEV_END_DEVICE || pMsg->status == DEV_ROUTER ) //||pMsg->status == DEV_ZB_COORD ) { osal_set_event( temcoAPP_TaskID, ACK_CHECK); // HalLedSet ( HAL_LED_1, HAL_LED_MODE_FLASH ); // HalLedBlink ( HAL_LED_1, 0, 50, 500 ); } break; default: break; } // Release the memory osal_msg_deallocate( (uint8 *) pMsg ); // Next pMsg = (osal_event_hdr_t *) osal_msg_receive( task_id ); } // Return unprocessed events return (events ^ SYS_EVENT_MSG); } if (events & ACK_CHECK) { uint8 ack_byte = 0; if( ack_count > ACK_TIMEOUT_NUM) { ack_count = 0; if( ack_exist == FALSE) { restore_factory_setting(); } } if( ack_exist == TRUE) { zb_SendDataRequest( 0, ACK_CMD_CLUSTERID, 1, &ack_byte, 0, AF_ACK_REQUEST, 0); ack_exist = FALSE; } ack_count ++; osal_start_timerEx( temcoAPP_TaskID, ACK_CHECK, ACK_CHECK_TIMEOUT); // Every minute check ack, if no receive, restart to join a new network return ( events ^ ACK_CHECK); } // Send the command to check TSTAT modbus id if( events & ASK_MODBUS_ID) { uint8 rssi_byte = 0; uint8 deleteId; if( type_assert >= TYPE_ASSERT_TIMEOUT) // Decide which type to start up { #if 0 if( (product_id == 0) || (product_id == 100)) { if( zgDeviceLogicalType == ZG_DEVICETYPE_ROUTER) { zgDeviceLogicalType = ZG_DEVICETYPE_COORDINATOR; restart_to_other_type(); } } else { if( zgDeviceLogicalType == ZG_DEVICETYPE_COORDINATOR) { zgDeviceLogicalType = ZG_DEVICETYPE_ROUTER; restart_to_other_type(); } } #endif // To read register6 of TSTAT if( tstat_id != 0) { //if( zgDeviceLogicalType != ZG_DEVICETYPE_COORDINATOR) // Send a command asking other nodes' modbus id, the response message carry rssi zb_SendDataRequest( 0xffff, RSSI_REQ_CLUSTERID, 1, &rssi_byte, 0, AF_ACK_REQUEST, 0); deleteId = checkNodeAlive(); // check if there are any nodes not alive if( deleteId != 255) deleteSignalStrength(deleteId); // delete the dead id } } else { type_assert ++; HalUARTWrite ( 0, ask_modbus_id, 8 ); } // if not received, send again X seconds later osal_start_timerEx( temcoAPP_TaskID, ASK_MODBUS_ID, RSSI_REQ_TIMEOUT); return ( events ^ ASK_MODBUS_ID); } if( events & SEND_ZIGBEE_FLAG) { if( tstat_id == 0) HalUARTWrite( 0, "zigbee", strlen("zigbee")); else osal_stop_timerEx( temcoAPP_TaskID, SEND_ZIGBEE_FLAG); osal_start_timerEx( temcoAPP_TaskID, SEND_ZIGBEE_FLAG, 3000); } // Discard unknown events return 0; }