/****************************************************************************/
/* Copyright 2007 MBARI.                                                    */
/* Monterey Bay Aquarium Research Institute Proprietary Information.        */
/* All rights reserved.       																						  */
/*																																					*/
/* Command_Handler.c - Handles all incoming RS485nds												*/
/*																																					*/
/* Rev History:																															*/
/* Initial Creation 11/2007		B.Kieft							     											*/
/*																																					*/
/*																																					*/
/****************************************************************************/

#include <stdlib.h>
#include "loadControl_main.h"

char received_spi_data_mastr[MAX_SPI_CHARS];
char sent_spi_data_mastr[MAX_SPI_CHARS];

//////
////// Control Commands
#SEPARATE
void handle_load_power() {
	// Commanded to turn OFF load
	if(parameter == 0) {
    check_slave_on(); // Make sure slave is powered
    spi_write(70);    // Command slave to turn OFF load
    delay_ms(50);     // Pause for slave to respond
    
    // Check the response from the slave
    SPI_strread(received_spi_data_mastr);
    if( atoi32(received_spi_data_mastr) !=  70) {
      // Set slave error
	    slv_cmd_err = true;  	    	      	
    }
    else {
    	// No errors 
    	load_is_on = false;
  	  check_slave_off();  // now safe to turn off slave
    }
	}
	// Commanded to turn ON load
	else if(parameter == 1) {
  	output_bit(PIN_B4, HI); // Turn on slave processor
  	slave_is_on = true;
		delay_ms(300);          // Time for slave to boot up and initialize ~ 170 ms. Worst case observed ~ 300 ms. 
		
    spi_write(71);          // Command slave to turn ON load               
    delay_ms(50);           //Pause for slave to respond

    // Check the response from the slave    
    SPI_strread(received_spi_data_mastr);
    if( atoi32(received_spi_data_mastr) !=  71) {
    	// Set slave error
  	  slv_cmd_err = true;       	     	
    }   
    else {
    	// No errors. The load is on
    	load_is_on = true;
    	delay_ms(25); // give slave time to check for overcurrent
    } 
	}
	else {
    //set error
  	invld_param_err = true;		
	}

  // Send response
  send_485_response(empty_string[0]);	
}


#SEPARATE
void handle_comm_relay() {
  if(parameter == 0) {
    output_bit(PIN_B1, HI); 
    delay_ms(8);           // Hold time for latching relay
    output_bit(PIN_B1, LO); 
    relay_status_closed = 0;    
  }
  else if(parameter == 1) {
    output_bit(PIN_B2, HI); 
    delay_ms(8);           // Hold time for latching relay
    output_bit(PIN_B2, LO); 
    relay_status_closed = 1;
  }
  else {
  	//set error
  	invld_param_err = true;
  }
  // Save the parameter to flash
  write_eeprom8(EE_relay_status_closed, relay_status_closed);
  // Now read it back just to be sure...
  if( (relay_status_closed != read_eeprom(EE_relay_status_closed)) ) {    
    // There was an error.
    flash_write_err = true;
  }  
  // Send response
  send_485_response(empty_string[0]);   
}

#SEPARATE
void handle_sleep_enable() {
  if(parameter == 0) {
    sleep_enabled = false;
  }
  else if(parameter == 1) {
    sleep_enabled = true;
  }
  else {
  	//invalid parameter
	  invld_param_err = true;
  }
  // Send response
  send_485_response(empty_string[0]);   	
}

#SEPARATE
void handle_clear_errors() {
  check_slave_on(); // Make sure slave is powered
  spi_write(81);    // Command slave to turn OFF load
  delay_ms(50);     // Pause for slave to respond
   
  // Check the response from the slave
  SPI_strread(received_spi_data_mastr);
  if( atoi32(received_spi_data_mastr) !=  81) {
    // Set slave error
	  slv_cmd_err = true;  	    	      	
  }
  else {
    // No errors so clear the master now
	  clear_errors(true); 
  }
  // Send response
  send_485_response(empty_string[0]);
  check_slave_off();	
}

//////
////// Read Status Commands
#SEPARATE
void handle_read_bus_voltage() {  
  output_bit(PIN_C2, HI); // Flip on the reference voltage
  set_adc_channel(0);	
  delay_ms(9);            // Reference voltage circuit rise time
  do_adc_voltage_calcs(25);
  output_bit(PIN_C2, LO); // Turn off the reference voltage
  
  sprintf(response_message, "%5.3w",adc_value_glob); 
  send_485_response(response_message);
  
}


#SEPARATE
void handle_read_load_voltage() {   
  check_slave_on(); // Make sure slave is powered
  spi_write(50);              
  delay_ms(50);     //Pause for slave to do calculation
    
  SPI_strread(received_spi_data_mastr);
  check_slave_off(); // See if it's ok to turn slave off
  
  sprintf(response_message, "%s",received_spi_data_mastr); 
  send_485_response(response_message);   
}


#SEPARATE
void handle_read_bus_current() {
  output_bit(PIN_C2, HI); // Turn on the reference voltage
  set_adc_channel(1);	
  delay_ms(9);            // Reference voltage circuit rise time

  do_adc_current_calcs(VREF, VREF, RSENSE, CURRDIVISOR); // In this case, VREF == VSCALE
  output_bit(PIN_C2, LO); // Turn off the reference voltage	
  
  sprintf(response_message, "%5.3w",adc_value_glob); 
  send_485_response(response_message);
}


#SEPARATE
void handle_read_load_current() { 
  check_slave_on(); // Make sure slave is powered  	
  spi_write(51);                
  delay_ms(50);     //Takes approx 32 msec to complete transaction

  // Get repsonse from slave
  SPI_strread(received_spi_data_mastr);
  sprintf(response_message, "%s",received_spi_data_mastr); 
 	send_485_response(response_message); 
  check_slave_off(); // See if it's ok to turn slave off 	
}


#SEPARATE
void handle_read_gf_current() { 
  if( (parameter >= 0) && (parameter <= 3) ) {	
    check_slave_on(); // Make sure slave is powered    	
    spi_write(parameter+1);    	
  
    delay_ms(50); //Takes approx 32 msec to complete transaction
  
    // Get repsonse from slave and send response on
    SPI_strread(received_spi_data_mastr);
    sprintf(response_message, "%s",received_spi_data_mastr); 
   	send_485_response(response_message);     
    check_slave_off(); // See if it's ok to turn slave off   	
  }
  else {
    //Invalid Parameter
  	invld_param_err = true;
    send_485_response(empty_string[0]);
  }  
}


#SEPARATE
void handle_read_startup_oc_threshold() { 
  sprintf(response_message, "%Lu",startup_oc_threshold);  
  send_485_response(response_message);	
}


#SEPARATE
void handle_read_q_oc_threshold() {
  sprintf(response_message, "%Lu",steady_oc_threshold);  
  send_485_response(response_message);	
}


#SEPARATE
void handle_read_startup_oc_time() { 
  sprintf(response_message, "%Lu",startup_oc_time);  
  send_485_response(response_message);	
}


#SEPARATE
void handle_read_comm_realy_status() { 
  sprintf(response_message, "%u", relay_status_closed);  
  send_485_response(response_message);	
}

#SEPARATE
void handle_read_device_serial_number() { 
  send_485_response(empty_string[0]); 
}

#SEPARATE
void handle_sw_version() {
  sprintf(response_message, "%s", sw_version);  
  send_485_response(response_message);	
}


//////
////// Set Threshold Commands
#SEPARATE
void handle_oc_threshold_startup() {
  if( (parameter >= 0) && (parameter <= 10000) ) {
  	check_slave_on();                  // Make sure slave is powered
    spi_write(60);                     // Send Command and parameter
    sprintf(sent_spi_data_mastr, "%Lu ",parameter); // Note kluge. Have to send space char as termination. Should use interrupt on slave
    SPI_strwrite(sent_spi_data_mastr);

    delay_ms(50);                      // Wait for response and read
    SPI_strread(received_spi_data_mastr);
    delay_ms(3);       // Allow slave to do int32 math routines before sending a 485 response        
    
                                       // Check for errors
    if( atoi32(received_spi_data_mastr) ==  parameter) {
   	                                   // Success
      startup_oc_threshold = parameter;// Slave has threshold so it's now safe to store it in the master
      // Save the parameter to flash
      write_eeprom16(EE_startup_oc_threshold, startup_oc_threshold);
      // Now read it back just to be sure...
      if( (startup_oc_threshold != read_eeprom16(EE_startup_oc_threshold)) ) {    
        // There was an error.
        flash_write_err = true;
      }  
      // Send response
   	  sprintf(response_message, "%Lu", startup_oc_threshold); 
   	  send_485_response(response_message);    	
    }
    else {
    	// Send slave error here
   	  slv_cmd_err = true;
   	  sprintf(response_message, "%Lu", parameter); 
   	  send_485_response(response_message);
    }
    check_slave_off(); // See if it's ok to turn slave off    
  }
  else {
  	//Out of range. Send parameter error here
  	invld_param_err = true;
    send_485_response(empty_string[0]);	  	
  }   
}


#SEPARATE
void handle_oc_threshold_q() {
  if( (parameter >= 0) && (parameter <= 10000) ) {
  	check_slave_on();                  // Make sure slave is powered    
    spi_write(61);                     //Send Command and parameter
    sprintf(sent_spi_data_mastr, "%Lu ",parameter); // Note kluge. Have to send space char as termination. Should use interrupt on slave
    SPI_strwrite(sent_spi_data_mastr);

    delay_ms(50);                      // Wait for response and read
    SPI_strread(received_spi_data_mastr);
    delay_ms(3);       // Allow slave to do int32 math routines before sending a 485 response    

                                           // Check for errors
    if( atoi32(received_spi_data_mastr) ==  parameter) {
   	                                   // Success. Send ack
      steady_oc_threshold = parameter; // Slave has threshold so it's now safe to store it in the master
      // Save the parameter to flash
      write_eeprom16(EE_steady_oc_threshold, steady_oc_threshold);
      // Now read it back just to be sure...
      if( (steady_oc_threshold != read_eeprom16(EE_steady_oc_threshold)) ) {    
        // There was an error.
        flash_write_err = true;
      }        
      // Send response
   	  sprintf(response_message, "%Lu", steady_oc_threshold); 
   	  send_485_response(response_message);    	
    }
    else {
    	// Send slave error here
   	  slv_cmd_err = true;
      send_485_response(empty_string[0]);	   	  
    }   
    check_slave_off(); // See if it's ok to turn slave off     
  }
  else {
  	//Out of range. Send parameter error here
  	invld_param_err = true;
    send_485_response(empty_string[0]);  }  
}


#SEPARATE
void handle_oc_time_startup() {
  if( (parameter >= 0) && (parameter <= 10000) ) {
  	check_slave_on();                  // Make sure slave is powered        
    spi_write(62);                     //Send Command and parameter
    sprintf(sent_spi_data_mastr, "%Lu ",parameter); // Note kluge. Have to send space char as termination. Should use interrupt on slave
    SPI_strwrite(sent_spi_data_mastr);

    delay_ms(50);                      // Wait for response and read
    SPI_strread(received_spi_data_mastr);
    
                                       // Check for errors
    if( atoi32(received_spi_data_mastr) ==  parameter) {
   	                                   // Success. Send ack
      startup_oc_time = parameter;     // Slave has threshold so it's now safe to store it in the master 	      
      // Save the parameter to flash
      write_eeprom16(EE_startup_oc_time, startup_oc_time);
      // Now read it back just to be sure...
      if( (startup_oc_time != read_eeprom16(EE_startup_oc_time)) ) {    
        // There was an error.
        flash_write_err = true;
      }  
      // Send response                             
   	  sprintf(response_message, "%Lu", startup_oc_time); 
   	  send_485_response(response_message);    	
    }
    else {
    	// Send slave error here
   	  slv_cmd_err = true;
   	  send_485_response(empty_string[0]);
    }        
    check_slave_off(); // See if it's ok to turn slave off    
  }
  else {
  	//Out of range. Send parameter error here
  	invld_param_err = true;
    send_485_response(empty_string[0]);
  }  
}


#SEPARATE
void handle_set_address() {
  if( (parameter >= 0) && (parameter <= 99) ) {
    RS485_ID = parameter;  

    // Save the parameter to flash
    write_eeprom8(EE_RS485_ID, RS485_ID);
    // Now read it back just to be sure...
    if( (RS485_ID != read_eeprom(EE_RS485_ID)) ) {    
      // There was an error.
      flash_write_err = true;
    }            
  }
  else {
  	//Out of range. Send parameter error here
  	invld_param_err = true; 
  }
  // Send response   
  sprintf(response_message, "%Lu", parameter);     
  send_485_response(response_message);   
}
        	  

