/******************************************************************** * Function: void ProcessMenu(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This function parses the input string given * by the user. * * Note: None *******************************************************************/ void ProcessMenu(void) { int i; // Debug // If the line is empty return. if(RS232cp == 0) return; // Strip the CR/NL character. RS232_Out_Data[RS232cp] = '\0'; // Test different menu options if(strcmpram2pgm("help", RS232_Out_Data) == 0) putrsUSBUSART("\r\nAvailable commands:\r\n\r\n* help - Displays this message, recursive style!\r\n* setMessage <text> - Defines a new message to be displayed on the POV.\r\n* showMessage - Shows the current message\r\n* version - Displays firmware version."); else if(strncmpram2pgm("setMessage ", RS232_Out_Data, 10) == 0) { // Copy message strncpy(message, &RS232_Out_Data[11], MESSAGE_LENGTH); message[MESSAGE_LENGTH] = '\0'; writeEEPROM(0x00, crc(0x00, (char) strlen(message))); writeEEPROM(0x01, (char) strlen(message)); writeStrEEPROM(0x03, strlen(message), message); writeEEPROM(0x02, strcrc(message)); // Display confirmation strcpypgm2ram(RS232_Out_Data, "\r\nYour message is now defined as:\r\n\t"); strcat(RS232_Out_Data, message); putsUSBUSART(RS232_Out_Data); } else if(strcmpram2pgm("showMessage", RS232_Out_Data) == 0) { sprintf(RS232_Out_Data, "\r\nYour message is defined as:\r\n\t%s", message); putsUSBUSART(RS232_Out_Data); } else if(strcmpram2pgm("version", RS232_Out_Data) == 0) putrsUSBUSART("\r\nPOV serial configuration. Version 0.9"); else putrsUSBUSART("\r\nUnknown command. Type 'help' for the list of available commands."); clearRS232Buffer = 1; }
enum XPL_CMD_MSG_TYPE_RSP xpl_handle_message_part(void) { switch (xpl_msg_state) { case WAITING_CMND: // If it is a command header -> set buffer state to CMD_RECEIVED if (strcmpram2pgm("xpl-cmnd", xpl_rx_buffer_shadow)==0) { xpl_msg_state = CMND_RECEIVED; } break; case CMND_RECEIVED: // check if we have the target in the buffer if (strcmpram2pgm("target=*", xpl_rx_buffer_shadow) == 0){ // Yes, message is wildcard and hence destined to us xpl_msg_state = WAITING_CMND_TYPE; } else if (strncmpram2pgm("target=hollie-utilmon.", xpl_rx_buffer_shadow, XPL_TARGET_VENDOR_DEVICEID_INSTANCE_ID_OFFSET)==0){ if (strcmp(xpl_instance_id, xpl_rx_buffer_shadow + XPL_TARGET_VENDOR_DEVICEID_INSTANCE_ID_OFFSET) == 0){ // bingo message if for us xpl_msg_state = WAITING_CMND_TYPE; } else { // Too bad, message is not for us. Wait for the next one xpl_msg_state = WAITING_CMND; } } break; case WAITING_CMND_TYPE: if (strcmpram2pgm("config.list", xpl_rx_buffer_shadow) == 0) { // No need to wait for the command here, this is a simple device, we only support one command xpl_msg_state = WAITING_CMND; return CONFIGURATION_CAPABILITIES_MSG_TYPE; } else if (strcmpram2pgm("config.response", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND_CONFIG_RESPONSE; } else if (strcmpram2pgm("sensor.request", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND_SENSOR_REQUEST; } else if (strcmpram2pgm("hbeat.request", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND_HBEAT_REQUEST; } else if (strcmpram2pgm("config.current", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND_CONFIG_CURRENT; } else if (strcmpram2pgm("control.basic", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND_CONTROL_BASIC; } else if (strcmpram2pgm("}", xpl_rx_buffer_shadow) == 0) { // just wait for command } else { xpl_msg_state = WAITING_CMND; } break; case WAITING_CMND_CONFIG_CURRENT: if (strcmpram2pgm("command=request", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND; return CONFIG_STATUS_MSG_TYPE; } else if (xpl_rx_buffer_shadow[0] == '{') { //do nothing } else { xpl_msg_state = WAITING_CMND; } break; case WAITING_CMND_HBEAT_REQUEST: if (strcmpram2pgm("command=request", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND; // We need a random backoff here to ensure that we don't flood the // network with all nodes responding at the same time. // We use the time_ticks for that. That variable is never bigger than // 300, so we divide by ten and feed that value into the delay function Delay10KTCYx(time_ticks/10); return HEARTBEAT_MSG_TYPE; } else if (xpl_rx_buffer_shadow[0] == '{') { //do nothing } else { xpl_msg_state = WAITING_CMND; } break; case WAITING_CMND_SENSOR_REQUEST: if (strcmpram2pgm("command=current", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND_SENSOR_REQUEST_DEVICE; } else if (xpl_rx_buffer_shadow[0] == '{') { //do nothing } else { xpl_msg_state = WAITING_CMND; } break; case WAITING_CMND_SENSOR_REQUEST_DEVICE: if (strcmpram2pgm("device=gas", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND; return GAS_DEVICE_CURRENT_MSG_TYPE; } else if (strcmpram2pgm("device=water", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND; return WATER_DEVICE_CURRENT_MSG_TYPE; } else if (strcmpram2pgm("device=elec", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND; return ELEC_DEVICE_CURRENT_MSG_TYPE; } else if (strncmpram2pgm("device=output", xpl_rx_buffer_shadow,13) == 0) { xpl_output_id = xpl_convert_2_ushort(xpl_rx_buffer_shadow+13); xpl_msg_state = WAITING_CMND; return OUTPUT_DEVICE_CURRENT_MSG_TYPE; } else { xpl_msg_state = WAITING_CMND; } break; case WAITING_CMND_CONTROL_BASIC: if (strcmpram2pgm("device=pwmout", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND_CONTROL_VALUE; } else if (strcmpram2pgm("mode=flood", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND; return FLOOD_NETWORK_MSG_TYPE; } else if (strncmpram2pgm("device=output", xpl_rx_buffer_shadow,13) == 0) { xpl_output_id = xpl_convert_2_ushort(xpl_rx_buffer_shadow+13); xpl_msg_state = WAITING_CMND_CONTROL_OUPUT; } else if (xpl_rx_buffer_shadow[0] == '{') { //do nothing } else { xpl_msg_state = WAITING_CMND; } break; case WAITING_CMND_CONTROL_VALUE: if (strcmpram2pgm("type=variable", xpl_rx_buffer_shadow) == 0) { // do nothing } else if (strncmpram2pgm("value=", xpl_rx_buffer_shadow, 6) == 0) { // Extract the value to set the PWM to xpl_pwm_value = xpl_convert_2_ushort(xpl_rx_buffer_shadow+6); if (xpl_pwm_value == 255) { SetDCPWM1(0x3FF); } else { SetDCPWM1(((short)xpl_pwm_value)<<2); } xpl_msg_state = WAITING_CMND; return PWM_CURRENT_MSG_TYPE; } else { xpl_msg_state = WAITING_CMND; } break; case WAITING_CMND_CONTROL_OUPUT: if (strcmpram2pgm("type=output", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND_CONTROL_OUPUT_CURRENT; } else { xpl_msg_state = WAITING_CMND; } break; case WAITING_CMND_CONTROL_OUPUT_CURRENT: if (strcmpram2pgm("current=enable", xpl_rx_buffer_shadow) == 0 || strcmpram2pgm("current=high", xpl_rx_buffer_shadow) == 0 || strcmpram2pgm("current=on", xpl_rx_buffer_shadow) == 0) { output_state_enable(xpl_output_id); return OUTPUT_DEVICE_CURRENT_MSG_TYPE; } else if (strcmpram2pgm("current=disable", xpl_rx_buffer_shadow) == 0 || strcmpram2pgm("current=low", xpl_rx_buffer_shadow) == 0 || strcmpram2pgm("current=off", xpl_rx_buffer_shadow) == 0) { output_state_disable(xpl_output_id); return OUTPUT_DEVICE_CURRENT_MSG_TYPE; } else if (strcmpram2pgm("current=pulse", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND_CONTROL_OUPUT_CURRENT_PULSE; } else if (strcmpram2pgm("current=toggle", xpl_rx_buffer_shadow) == 0) { output_state_toggle(xpl_output_id); return OUTPUT_DEVICE_CURRENT_MSG_TYPE; } else { xpl_msg_state = WAITING_CMND; } break; case WAITING_CMND_CONTROL_OUPUT_CURRENT_PULSE: if (strncmpram2pgm("data1=", xpl_rx_buffer_shadow,6) == 0) { output_state_pulse(xpl_output_id,xpl_convert_2_ushort(xpl_rx_buffer_shadow+6)); return OUTPUT_DEVICE_CURRENT_MSG_TYPE; } else { xpl_msg_state = WAITING_CMND; } break; case WAITING_CMND_CONFIG_RESPONSE: // what we write here depends on the node type, this is not yet generic code :( // maybe we need to implement here a function from the xpl_impl.c file // For now we just parse the instance_id and put it in EEPROM if (strncmpram2pgm("newconf=", xpl_rx_buffer_shadow, 8) == 0) { // Copy the new instance id to the correct variable strcpy(xpl_instance_id,xpl_rx_buffer_shadow + 8); } else if (strncmpram2pgm("newoutputs=", xpl_rx_buffer_shadow, 11) == 0) { output_count = xpl_convert_2_ushort(xpl_rx_buffer_shadow+11); } else if (strncmpram2pgm("newinputs=", xpl_rx_buffer_shadow, 10) == 0) { input_count = xpl_convert_2_ushort(xpl_rx_buffer_shadow+10); } else if (xpl_rx_buffer_shadow[0] == '}'){ xpl_msg_state = WAITING_CMND; xpl_trig_register |= WRITE_EEPROM; } break; } return -1; }
enum XPL_CMD_MSG_TYPE_RSP xpl_handle_message_part(void) { char lpcount; char strlength; char input_value[8]; //printf("\nmp@st%d@flc%d@fd%d@fwp%d@fwr%d@%s",xpl_msg_state,xpl_flow,xpl_rx_fifo_data_count,xpl_rx_fifo_write_pointer,xpl_rx_fifo_read_pointer,xpl_rx_buffer_shadow); switch (xpl_msg_state) { case WAITING_CMND: // If it is a command header -> set buffer state to CMD_RECEIVED if (strcmpram2pgm("xpl-cmnd", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = CMND_RECEIVED; } break; case CMND_RECEIVED: // check if we have the target in the buffer if (strcmpram2pgm("target=*", xpl_rx_buffer_shadow) == 0) { // Yes, message is wildcard and hence destined to us xpl_msg_state = WAITING_CMND_TYPE; } else if (strncmpram2pgm("target=hollie-utilmon.", xpl_rx_buffer_shadow, XPL_TARGET_VENDOR_DEVICEID_INSTANCE_ID_OFFSET) == 0) { if (strcmp(xpl_instance_id, xpl_rx_buffer_shadow + XPL_TARGET_VENDOR_DEVICEID_INSTANCE_ID_OFFSET) == 0) { // bingo message if for us xpl_msg_state = WAITING_CMND_TYPE; } else { // Too bad, message is not for us. Wait for the next one xpl_msg_state = WAITING_CMND; } } break; case WAITING_CMND_TYPE: if (strcmpram2pgm("config.list", xpl_rx_buffer_shadow) == 0) { // No need to wait for the command here, this is a simple device, we only support one command xpl_msg_state = WAITING_CMND; return CONFIGURATION_CAPABILITIES_MSG_TYPE; } else if (strcmpram2pgm("config.response", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND_CONFIG_RESPONSE; } else if (strcmpram2pgm("sensor.request", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND_SENSOR_REQUEST; } else if (strcmpram2pgm("hbeat.request", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND_HBEAT_REQUEST; } else if (strcmpram2pgm("config.current", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND_CONFIG_CURRENT; } else if (strcmpram2pgm("control.basic", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND_CONTROL_BASIC; } else if (strcmpram2pgm("}", xpl_rx_buffer_shadow) == 0) { // just wait for command } else { xpl_msg_state = WAITING_CMND; } break; case WAITING_CMND_CONFIG_CURRENT: if (strcmpram2pgm("command=request", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND; return CONFIG_STATUS_MSG_TYPE; } else if (xpl_rx_buffer_shadow[0] == '{') { //do nothing } else { xpl_msg_state = WAITING_CMND; } break; case WAITING_CMND_HBEAT_REQUEST: if (strcmpram2pgm("command=request", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND; // We need a random backoff here to ensure that we don't flood the // network with all nodes responding at the same time. // We use the time_ticks for that. That variable is never bigger than // 300, so we divide by ten and feed that value into the delay function Delay10KTCYx(time_ticks / 10); return HEARTBEAT_MSG_TYPE; } else if (xpl_rx_buffer_shadow[0] == '{') { //do nothing } else { xpl_msg_state = WAITING_CMND; } break; case WAITING_CMND_SENSOR_REQUEST: if (strcmpram2pgm("command=current", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND_SENSOR_REQUEST_DEVICE; } else if (xpl_rx_buffer_shadow[0] == '{') { //do nothing } else { xpl_msg_state = WAITING_CMND; } break; case WAITING_CMND_SENSOR_REQUEST_DEVICE: if (strcmpram2pgm("device=gas", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND; return GAS_DEVICE_CURRENT_MSG_TYPE; } else if (strcmpram2pgm("device=water", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND; return WATER_DEVICE_CURRENT_MSG_TYPE; } else if (strcmpram2pgm("device=elec", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND; return ELEC_DEVICE_CURRENT_MSG_TYPE; } else { xpl_msg_state = WAITING_CMND; } break; case WAITING_CMND_CONTROL_BASIC: if (strcmpram2pgm("device=pwmout", xpl_rx_buffer_shadow) == 0) { #ifdef PWM_ENABLED xpl_msg_state = WAITING_CMND_CONTROL_VALUE; #else xpl_msg_state = WAITING_CMND; #endif } else if (strcmpram2pgm("mode=flood", xpl_rx_buffer_shadow) == 0) { xpl_msg_state = WAITING_CMND; return FLOOD_NETWORK_MSG_TYPE; } else if (xpl_rx_buffer_shadow[0] == '{') { //do nothing } else { xpl_msg_state = WAITING_CMND; } break; case WAITING_CMND_CONTROL_VALUE: if (strcmpram2pgm("type=variable", xpl_rx_buffer_shadow) == 0) { // do nothing } else if (strncmpram2pgm("current=", xpl_rx_buffer_shadow, 8) == 0) { // Extract the value to set the PWM to strcpy(input_value, xpl_rx_buffer_shadow + 8); strlength = strlen(input_value); xpl_pwm_value = 0; lpcount = 0; while (lpcount < strlength) { xpl_pwm_value *= 10; xpl_pwm_value += (input_value[lpcount] - 0x30); lpcount++; } if (xpl_pwm_value == 255) { SetDCPWM1(0x3FF); } else { SetDCPWM1(((short) xpl_pwm_value) << 2); } xpl_msg_state = WAITING_CMND; return PWM_CURRENT_MSG_TYPE; } else { xpl_msg_state = WAITING_CMND; } break; case WAITING_CMND_CONFIG_RESPONSE: // what we write here depends on the node type, this is not yet generic code :( // maybe we need to implement here a function from the xpl_impl.c file // For now we just parse the instance_id and put it in EEPROM if (strncmpram2pgm("newconf=", xpl_rx_buffer_shadow, 8) == 0) { // Make sure we're not receiving data right now, as interrupts will be disabled during EEPROM write later in this function if (xpl_flow == FLOW_ON) { xpl_flow = FLOW_OFF; putc(XOFF, _H_USART); } // We are about to change our ID here, so send an end message to notify the network xpl_send_config_end(); // Copy the new instance id to the correct variable strcpy(xpl_instance_id, xpl_rx_buffer_shadow + 8); // Put the new instance id name in EEPROM so that it retains value after a power cycle strlength = strlen(xpl_instance_id); // We put this in a local variable because else it it re-calculated every loop cycle for (lpcount = 0; lpcount < strlength; lpcount++) { eeprom_write(lpcount + XPL_EEPROM_INSTANCE_ID_OFFSET, xpl_instance_id[lpcount]); } // End with a '\0' in EEPROM eeprom_write(lpcount + XPL_EEPROM_INSTANCE_ID_OFFSET, 0x00); // We don't reset here any more, there are more settings to come! // Reset the xpl function to apply the new name // Buffer content gets lost here, but we don't mind as we need to start again xpl_init_instance_id(); xpl_msg_state = WAITING_CMND; xpl_flow = FLOW_ON; putc(XON, _H_USART); return HEARTBEAT_MSG_TYPE; // Don't return yet, we need to get the PWM_enable setting from the command } break; } return -1; }