/*==================================================================================================

FILE INFORMATION HEADER

USED IN PROJECT:			S1003065-01 PPS-TX/S1003067-01 PPS-RX software application
ITEM TYPE:					Source Code
ITEM NAME:					xlru_psm.cpp
ITEM DESCRIPTION:			This file contains the implementation of the class e and the interfaces for the PSM / REP connection
TARGET:						ATSAM4LC8B / ATSAM4LS8B
DOC REFERENCES:				SWDS1003065-01/SWDS1003065-01
PROGRAMMER NAME(S):			A.Chessa, L.Vallongo
COPYRIGHT:					LEONARDO-FINMECCANICA S.p.A
REVISION HISTORY:
- 01.00: first release

====================================================================================================
© Copyright LEONARDO S.p.A.. All rights reserved
Any right of industrial and intellectual property on this document,
and of technical Know-how herein contained, belongs to
LEONARDO S.p.A. and/or third parties.
According to the law, it is forbidden to disclose, reproduce or however
use this document and any data herein contained for any use without
previous written authorization by LEONARDO S.p.A.
==================================================================================================*/
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include "xlru_psm.h"
#include "xlru_message_def.h"
#include "xlru_common_func.h"
#include "xlru_bytes_def.h"
#include "xlru_log.h"

using namespace xlru;

//GENERAL DECLARATION

char psm_rx_buffer[BUFFER_DIM];		//bytes buffer to store input

char psm_tx_buffer[BUFFER_DIM];		//bytes buffer to store output

/*header received */

/*uint8_t PPS_Mode_Status = PPSPowerUp;
uint8_t PPS_Current_limitation_status = PPSNoCurrentLimitation;
uint8_t PPS_wow_tellback_status = PPSWowNotActive;
uint8_t PPS_Health_Status = PPSHealthGo;
uint8_t PPS_Hazard_Status = PPSNoHazard;
uint8_t PPS_Status_byte[6] = {0, 0, 0, 0, 0};*/

uint32_t psm_error_link = 0;

//*** STATIC
xlru_psm::xlru_psm_command_t xlru_psm::xlru_psm_command;
xlru_psm::xlru_psm_status_t xlru_psm::xlru_psm_status;
xlru_counter_t xlru_psm::xlru_counter;

char xlru_psm::xlru_psm_fcs_prev = 'p';

void xlru_psm::psm_header_master(void)
{
	//SOM
	psm_tx_buffer[0] = SOM;

	//DSTID
	psm_tx_buffer[1] = DSTID_PSM;

	// FCS
	char fcs_temp = ((xlru_psm::xlru_psm_fcs_prev%16)+'a');
	psm_tx_buffer[FCS_INDEX] = fcs_temp;
	xlru_psm::xlru_psm_fcs_prev = fcs_temp;

	psm_tx_buffer[ACK_INDEX] = XGET;
}

//****************************************************
// MASTER - from EIF TO PSM - SET MESSAGE - PSM Operative Control Msg

void xlru_psm::psm_set_message_payload_master(void)
{
	psm_tx_buffer[4] = PSM_COMMAND_MSG;				//"C"

	switch (xlru_psm::xlru_psm_command.cmd_id)
	{
		case 0:
			psm_tx_buffer[5] = PSM_CMDID_POWER_DOWN; 	//'P'
			break;
		case 1:
			psm_tx_buffer[5] = PSM_CMDID_POWER_RECYCLE;	//'R'
			break;
		case 2:
			psm_tx_buffer[5] = PSM_CMDID_GO;			//'G'
			break;
		default:
			psm_tx_buffer[5] = PSM_CMDID_GO;			//'G'
			break;
	}

	switch (xlru_psm::xlru_psm_command.emergency)
	{
		case 0:
			psm_tx_buffer[6] = PSM_EMERGENCY_E; 	//'E'
			break;
		case 1:
			psm_tx_buffer[6] = PSM_EMERGENCY_IGNORE;	//'B'
			break;
		case 2:
			psm_tx_buffer[6] = PSM_EMERGENCY_NOT_E;			//<>'E'
			break;
		default:
			psm_tx_buffer[6] = '_';			//'e'
			break;
	}

	switch (xlru_psm::xlru_psm_command.fast_cmd)
	{
		case 0:
			psm_tx_buffer[7] = PSM_FAST_CMD_CHARGE; 	//'C'
			break;
		case 1:
			psm_tx_buffer[7] = PSM_FAST_CMD_DISCHARGE;	//'_'
			break;
		default:
			psm_tx_buffer[7] = PSM_FAST_CMD_DISCHARGE; 	//'_'
			break;
	}

	if (xlru_psm::xlru_psm_command.panic_code)
		psm_tx_buffer[8] = xlru_psm::xlru_psm_command.panic_code+'0';  //STATUS_SPARE;
	else
		psm_tx_buffer[8] = STATUS_SPARE;

    psm_tx_buffer[9] = STATUS_SPARE;
	psm_tx_buffer[10] = 0;

	char checksum[2] = {0};
	calc_checksum(checksum, psm_tx_buffer);
	psm_tx_buffer[10] = checksum[0];
	psm_tx_buffer[11] = checksum[1];

	psm_tx_buffer[12]= CR_EOM;
	psm_tx_buffer[13]= 0;
}


char* xlru_psm::psm_set_message_master(void)
{
	memset(psm_tx_buffer, 0, sizeof(psm_tx_buffer));
	psm_header_master();
	psm_set_message_payload_master();
	return psm_tx_buffer;
}

//****************************************************
// MASTER - from EIF TO PSM - GET MESSAGE

void xlru_psm::psm_get_message_payload_master(void)
{
	/*psm_tx_buffer[4] = PSM_GET_MESSAGE;			//"S", LCU General Status Message
	psm_tx_buffer[5] = 0;

	char checksum[2] = {0};
	calc_checksum(checksum, psm_tx_buffer);
	psm_tx_buffer[5] = checksum[0];
	psm_tx_buffer[6] = checksum[1];

	psm_tx_buffer[7]= CR_EOM;
	psm_tx_buffer[8]= 0;*/
}

char* xlru_psm::psm_get_message_master(void)
{
	psm_header_master();
	psm_get_message_payload_master();
	return psm_tx_buffer;
}

void xlru_psm::init(void)
{
	xlru_psm::xlru_psm_status.status.overtempHazard = false;
	xlru_psm::xlru_psm_status.status.overtempWarning = false;
	xlru_psm::xlru_psm_status.status.unitOk = false;

	xlru_psm::set_psm_cmd_id(DEF_CMDID);
	xlru_psm::set_psm_emergency(DEF_EMERGENCY);
	xlru_psm::set_psm_fast_cmd(DEF_FAST_CMD);
}

//***********************************************************************************
void xlru_psm::psm_reset_buffer_TX_RX(void)
{
	memset(psm_tx_buffer, 0, sizeof(psm_tx_buffer));
	memset(psm_rx_buffer, 0, sizeof(psm_rx_buffer));
}

char * xlru_psm::psm_getStringTx(void)
{
	return psm_tx_buffer;
}

char * xlru_psm::psm_getStringRx(void)
{
	return psm_rx_buffer;
}

void xlru_psm::psm_setStringTx(char *txt)
{
	strcpy(psm_tx_buffer, txt);
}

void xlru_psm::psm_setStringRx(char *txt)
{
	strcpy(psm_rx_buffer, txt);
}

int xlru_psm::xlru_psm_command_message_decoder(char* buffer)
{
	char tmp = 0;

	int error = 0;
	int value = 0;

	//check message's len, if it is too short, return error
	int len = strlen(buffer);

	if (len<(PSM_CHK_TXL_INDEX-1))
		return DECODE_TOO_SHORT;	//message is too short
	memset( &xlru_psm::xlru_psm_status, 0, sizeof( xlru_psm::xlru_psm_status ) );

	//MODE STATUS
	tmp = buffer[PSM_STS_INDEX];
	switch(tmp)
	{
		case PSM_STS_IDLE:
			xlru_psm::xlru_psm_status.mode_status = PSMIdle;
			break;
		case PSM_STS_POWERUP:
			xlru_psm::xlru_psm_status.mode_status = PSMPowerUp;
			break;
		case PSM_STS_FAIL:
			xlru_psm::xlru_psm_status.mode_status = PSMFail;
			break;
		case PSM_STS_MICROINTERR:
			xlru_psm::xlru_psm_status.mode_status = PSMMicroInterrupt;
			break;
		case PSM_STS_BACKUP:
			xlru_psm::xlru_psm_status.mode_status = PSMBackuUp;
			break;
		case PSM_STS_NORMAL:
			xlru_psm::xlru_psm_status.mode_status = PSMNormal;
			break;
		default:
			error++;
			break;
	}

	//hazard_status
	tmp = buffer[PSM_HAZARD_INDEX];
	switch(tmp)
	{
		case PSM_HAZARD_NORMAL:
			xlru_psm::xlru_psm_status.hazard_status = PSMHazardNormal;
			break;
		case PSM_HAZARD_WARNING:
			xlru_psm::xlru_psm_status.hazard_status = PSMWarning;
			break;
		case PSM_HAZARD_1:
			xlru_psm::xlru_psm_status.hazard_status = PSMHazard1;
			break;
		case PSM_HAZARD_2:
			xlru_psm::xlru_psm_status.hazard_status = PSMHazard2;
			break;
		default:
			error++;
			break;
	}

	//PSM_3SEC_INDEX
	tmp = buffer[PSM_3SEC_INDEX];
	switch(tmp)
	{
		case PSM_3SEC_CHARGED:
			xlru_psm::xlru_psm_status._3sec_status = PSM3SecCharged;
			break;
		case PSM_3SEC_NOT_CHARGED:
			xlru_psm::xlru_psm_status._3sec_status = PSM3SecNotCharged;
			break;
		default:
			error++;
			break;
	}

	//PSM_WOW_INDEX
	tmp = buffer[PSM_WOW_INDEX];
	switch(tmp)
	{
		case PSM_WOW_ACTIVE:
			xlru_psm::xlru_psm_status.wow_status = PSMWowActive;
			break;
		case PSM_WOW_INACTIVE:
			xlru_psm::xlru_psm_status.wow_status = PSMWowInactive;
			break;
		default:
			error++;
			break;
	}

	//PSM_AC_INDEX
	tmp = buffer[PSM_AC_INDEX];
	switch(tmp)
	{
		case PSM_AC_OK:
			xlru_psm::xlru_psm_status.ac_status = PSMACOk;
			break;
		case PSM_AC_1:
			xlru_psm::xlru_psm_status.ac_status = PSMAC1PhaseA;
			break;
		case PSM_AC_2:
			xlru_psm::xlru_psm_status.ac_status = PSMAC2PhaseB;
			break;
		case PSM_AC_3:
			xlru_psm::xlru_psm_status.ac_status = PSMAC3;
			break;
		case PSM_AC_4:
			xlru_psm::xlru_psm_status.ac_status = PSMAC4PhaseC;
			break;
		case PSM_AC_5:
			xlru_psm::xlru_psm_status.ac_status = PSMAC5;
			break;
		case PSM_AC_6:
			xlru_psm::xlru_psm_status.ac_status = PSMAC6;
			break;
		case PSM_AC_7:
			xlru_psm::xlru_psm_status.ac_status = PSMAC7;
			break;
		case PSMACFail:
			xlru_psm::xlru_psm_status.ac_status = PSMACFail;
			break;
		default:
			error++;
			break;
	}

	//PSM_BS_INDEX
	tmp = buffer[PSM_BS_INDEX];
	switch(tmp)
	{
		case PSM_BS_NORMAL:
			xlru_psm::xlru_psm_status.bs_status = PSMBattleShortCmdOff;
			break;
		case PSM_BS_ACTIVE:
			xlru_psm::xlru_psm_status.bs_status = PSMBattleShortCmdOn;
			break;
		default:
			error++;
			break;
	}

	//PSM_DC_INDEX
	tmp = buffer[PSM_DC_INDEX];
	switch(tmp)
	{
		case PSM_DC_OK:
			xlru_psm::xlru_psm_status.dc_status = PSMUV270OK;
			break;
		case PSM_DC_FAIL:
			xlru_psm::xlru_psm_status.dc_status = PSMUV270Fail;
			break;
		default:
			error++;
			break;
	}

	//PSM_PFC_INDEX
	tmp = buffer[PSM_PFC_INDEX];
	switch(tmp)
	{
		case PSM_PFC_NORMAL:
			xlru_psm::xlru_psm_status.pfc_status = PSMUV350veOV350vnormal;
			break;
		case PSM_PFC_UNDER:
			xlru_psm::xlru_psm_status.pfc_status = PSMUV350v;
			break;
		case PSM_PFC_OVER:
			xlru_psm::xlru_psm_status.pfc_status = PSMOV350v;
			break;
		default:
			error++;
			break;
	}

	//PSM_OUT_RAIL5V_INDEX
	tmp = buffer[PSM_OUT_RAIL5V_INDEX];
	switch(tmp)
	{
		case PSM_OUT_RAIL_NORMAL:
			xlru_psm::xlru_psm_status.out_rail_VOLT5V_status = PSMOutRailNormal;
			break;
		case PSM_OUT_RAIL_UNDER:
			xlru_psm::xlru_psm_status.out_rail_VOLT5V_status = PSMOutRailUnder;
			break;
		case PSM_OUT_RAIL_OVER:
			xlru_psm::xlru_psm_status.out_rail_VOLT5V_status = PSMOutRailOver;
			break;
		default:
			error++;
			break;
	}

	//PSM_OUT_RAIL3V3_INDEX
	tmp = buffer[PSM_OUT_RAIL3V3_INDEX];
	switch(tmp)
	{
		case PSM_OUT_RAIL_NORMAL:
			xlru_psm::xlru_psm_status.out_rail_VOLT3V3_status = PSMOutRailNormal;
			break;
		case PSM_OUT_RAIL_UNDER:
			xlru_psm::xlru_psm_status.out_rail_VOLT3V3_status = PSMOutRailUnder;
			break;
		case PSM_OUT_RAIL_OVER:
			xlru_psm::xlru_psm_status.out_rail_VOLT3V3_status = PSMOutRailOver;
			break;
		default:
			error++;
			break;
	}

	//PSM_OUT_RAIL15V_INDEX
	tmp = buffer[PSM_OUT_RAIL15V_INDEX];
	switch(tmp)
	{
		case PSM_OUT_RAIL_NORMAL:
			xlru_psm::xlru_psm_status.out_rail_VOLT15V_status = PSMOutRailNormal;
			break;
		case PSM_OUT_RAIL_UNDER:
			xlru_psm::xlru_psm_status.out_rail_VOLT15V_status = PSMOutRailUnder;
			break;
		case PSM_OUT_RAIL_OVER:
			xlru_psm::xlru_psm_status.out_rail_VOLT15V_status = PSMOutRailOver;
			break;
		default:
			error++;
			break;
	}

	//PSM_OUT_RAILNEG15V_INDEX
	tmp = buffer[PSM_OUT_RAILNEG15V_INDEX];
	switch(tmp)
	{
		case PSM_OUT_RAIL_NORMAL:
			xlru_psm::xlru_psm_status.out_rail_VOLTNEG15V_status = PSMOutRailNormal;
			break;
		case PSM_OUT_RAIL_UNDER:
			xlru_psm::xlru_psm_status.out_rail_VOLTNEG15V_status = PSMOutRailUnder;
			break;
		case PSM_OUT_RAIL_OVER:
			xlru_psm::xlru_psm_status.out_rail_VOLTNEG15V_status = PSMOutRailOver;
			break;
		default:
			error++;
			break;
	}

	//PSM_IN_AMP
	bool ok=xlru::hex3u8f(&xlru_psm::xlru_psm_status.in_amp, &buffer[PSM_IN_AMP1_INDEX], PSM_IN_AMP_LSB);
	if (!ok)
			error++;	//problem in decode value;

	//PSM_OUT_VOLT3V3_1_INDEX
	ok=xlru::hex3s16f(&xlru_psm::xlru_psm_status.out_volt_VOLT3V3, &buffer[PSM_OUT_VOLT3V3_1_INDEX], PSM_OUT_VOLT_LSB);
	if (!ok)
			error++;	//problem in decode value;

	//PSM_OUT_VOLT5V_1_INDEX
	ok=xlru::hex3s16f(&xlru_psm::xlru_psm_status.out_volt_VOLT5V, &buffer[PSM_OUT_VOLT5V_1_INDEX], PSM_OUT_VOLT_LSB);
	if (!ok)
			error++;	//problem in decode value;
	
	//PSM_OUT_VOLT15V_1_INDEX
	ok=xlru::hex3s16f(&xlru_psm::xlru_psm_status.out_volt_VOLT15V, &buffer[PSM_OUT_VOLT15V_1_INDEX], PSM_OUT_VOLT_LSB);
	if (!ok)
			error++;	//problem in decode value;
	
	//PSM_OUT_VOLTNEG15V_1_INDEX
	ok=xlru::hex3s16f(&xlru_psm::xlru_psm_status.out_volt_VOLTNEG15V, &buffer[PSM_OUT_VOLTNEG15V_1_INDEX], PSM_OUT_VOLT_LSB);
	if (!ok)
			error++;	//problem in decode value;
	
	//PSM_TEMP_INDEX
    ok=xlru::hex2s8(&xlru_psm::xlru_psm_status.temperature, &buffer[PSM_TEMP1_INDEX]);
    if (!ok)
            error++;	//problem in decode value;

	//PSM_ETI_INDEX
	ok=xlru::hex2u16(&xlru_psm::xlru_psm_status.eti, &buffer[PSM_ETI1_INDEX]);
	if (!ok)
			error++;	//problem in decode value;

	//PSM_ON_COUNTER_INDEX
	ok=xlru::hex2u16(&xlru_psm::xlru_psm_status.on_counter, &buffer[PSM_ON_COUNTER1_INDEX]);
	if (!ok)
			error++;	//problem in decode value;

	//PSM_SW_MAJOR_INDEX
	ok=xlru::hex2u8(&xlru_psm::xlru_psm_status.sw_major, &buffer[PSM_SW_MAJORL_INDEX]);
	if (!ok)
			error++;	//problem in decode value;

	//PSM_SW_MINOR_INDEX
	ok=xlru::hex2u8(&xlru_psm::xlru_psm_status.sw_minor, &buffer[PSM_SW_MINORL_INDEX]);
	if (!ok)
			error++;	//problem in decode value;

	//PSM_UNC_COUNTER_INDEX
	ok=xlru::hex2u8(&xlru_psm::xlru_psm_status.unc_counter, &buffer[PSM_UNC_COUNTERL_INDEX]);
	if (!ok)
			error++;	//problem in decode value;


	//PSM_BIT_STATUS

	//BYTES#4 -
	ok=xlru::hex2u8(&value , &buffer[PSM_BITE_WORD1_INDEX]);
	if (!ok)
		error++;	//problem in decode value;
	xlru_psm::xlru_psm_status.byte4.b7_battle_short_cmd = ((value & PSM4_Bit7_battle_short_cmd) == PSM4_Bit7_battle_short_cmd);
	xlru_psm::xlru_psm_status.byte4.b6_uv_270v = ((value & PSM4_Bit6_uv_270v) == PSM4_Bit6_uv_270v);
	xlru_psm::xlru_psm_status.byte4.b5_ov_temp_haz = ((value & PSM4_Bit5_ov_temp_haz) == PSM4_Bit5_ov_temp_haz);
	xlru_psm::xlru_psm_status.byte4.b4_ps_interlock_n = ((value & PSM4_Bit4_ps_interlock_n) == PSM4_Bit4_ps_interlock_n);
	xlru_psm::xlru_psm_status.byte4.b3_ac_loss = ((value & PSM4_Bit3_ac_loss) == PSM4_Bit3_ac_loss);
	xlru_psm::xlru_psm_status.byte4.b2_uc_interlock_o = ((value & PSM4_Bit2_uc_interlock_o) == PSM4_Bit2_uc_interlock_o);
	xlru_psm::xlru_psm_status.byte4.b1_lcu_rdy_uc = ((value & PSM4_Bit1_lcu_rdy_uc) == PSM4_Bit1_lcu_rdy_uc);
	xlru_psm::xlru_psm_status.byte4.b0_rdr_on_sts = ((value & PSM4_Bit0_rdr_on_sts) == PSM4_Bit0_rdr_on_sts);

	/*Byte 3*/
	ok=xlru::hex2u8(&value , &buffer[PSM_BITE_WORD2_INDEX]);
	if (!ok)
		error++;	//problem in decode value;
	xlru_psm::xlru_psm_status.byte3.b7_pwr_err = ((value & PSM3_Bit7_pwr_err) == PSM3_Bit7_pwr_err);
	xlru_psm::xlru_psm_status.byte3.b6_blko_tst = ((value & PSM3_Bit6_blko_tst) == PSM3_Bit6_blko_tst);
	xlru_psm::xlru_psm_status.byte3.b5_ov_350v = ((value & PSM3_Bit5_ov_350v) == PSM3_Bit5_ov_350v);
	xlru_psm::xlru_psm_status.byte3.b4_uv_350v = ((value & PSM3_Bit4_uv_350v) == PSM3_Bit4_uv_350v);
	xlru_psm::xlru_psm_status.byte3.b3_3sec_in = ((value & PSM3_Bit3_3sec_in) == PSM3_Bit3_3sec_in);
	xlru_psm::xlru_psm_status.byte3.b2_wow_out = ((value & PSM3_Bit2_wow_out) == PSM3_Bit2_wow_out);
	xlru_psm::xlru_psm_status.byte3.b1_uv_13v_b = ((value & PSM3_Bit1_uv_13v_b) == PSM3_Bit1_uv_13v_b);
	xlru_psm::xlru_psm_status.byte3.b0_ov_13v_b = ((value & PSM3_Bit0_ov_13v_b) == PSM3_Bit0_ov_13v_b);

	/*Byte 2*/
	ok=xlru::hex2u8(&value , &buffer[PSM_BITE_WORD3_INDEX]);
	if (!ok)
		error++;	//problem in decode value;
	xlru_psm::xlru_psm_status.byte2.b7_uv_3v3 = ((value & PSM2_Bit7_uv_3v3) == PSM2_Bit7_uv_3v3);
	xlru_psm::xlru_psm_status.byte2.b6_ov_3v3 = ((value & PSM2_Bit6_ov_3v3) == PSM2_Bit6_ov_3v3);
	xlru_psm::xlru_psm_status.byte2.b5_uv_5v = ((value & PSM2_Bit5_uv_5v) == PSM2_Bit5_uv_5v);
	xlru_psm::xlru_psm_status.byte2.b4_ov_5v = ((value & PSM2_Bit4_ov_5v) == PSM2_Bit4_ov_5v);
	xlru_psm::xlru_psm_status.byte2.b3_uv_15v = ((value & PSM2_Bit3_uv_15v) == PSM2_Bit3_uv_15v);
	xlru_psm::xlru_psm_status.byte2.b2_ov_15v = ((value & PSM2_Bit2_ov_15v) == PSM2_Bit2_ov_15v);
	xlru_psm::xlru_psm_status.byte2.b1_uv_m15v = ((value & PSM2_Bit1_uv_m15v) == PSM2_Bit1_uv_m15v);
	xlru_psm::xlru_psm_status.byte2.b0_ov_m15v = ((value & PSM2_Bit0_ov_m15v) == PSM2_Bit0_ov_m15v);

	/*Byte 1*/
	ok=xlru::hex2u8(&value , &buffer[PSM_BITE_WORD4_INDEX]);
	if (!ok)
		error++;	//problem in decode value;
	xlru_psm::xlru_psm_status.byte1.b7_ov_dc_bus_current = ((value & PSM1_Bit7_ov_dc_bus_current) == PSM1_Bit7_ov_dc_bus_current);
	xlru_psm::xlru_psm_status.byte1.b6_ov_board_temp = ((value & PSM1_Bit6_ov_board_temp) == PSM1_Bit6_ov_board_temp);
	xlru_psm::xlru_psm_status.byte1.b5_ov_temp_haz_2 = ((value & PSM1_Bit5_ov_temp_haz_2) == PSM1_Bit5_ov_temp_haz_2);
	xlru_psm::xlru_psm_status.byte1.b4_rs232_comm = ((value & PSM1_Bit4_rs232_comm) == PSM1_Bit4_rs232_comm);
	xlru_psm::xlru_psm_status.byte1.b3_rs485_comm = ((value & PSM1_Bit3_rs485_comm) == PSM1_Bit3_rs485_comm);
	xlru_psm::xlru_psm_status.byte1.b2_rs422_comm = ((value & PSM1_Bit2_rs422_comm) == PSM1_Bit2_rs422_comm);
	xlru_psm::xlru_psm_status.byte1.b1_PSM_EIF_comm = ((value & PSM1_Bit1_PSM_EIF_comm) == PSM1_Bit1_PSM_EIF_comm);


	//controlla se la lunghezza e' maggiore del messaggio standard ed in questi caso sono state accodate delle ulteriori informazioni
	if (len>PSM_EOM_TX_INDEX)
	{
		//prendo ogni byte presente e lo stampo come extrainfo

	}

	xlru_psm::xlru_psm_status.status.unitOk=xlru_psm::xlru_psm_status.mode_status==PSMNormal;

	switch(xlru_psm::xlru_psm_status.hazard_status)
	{
		case PSMHazardNormal:
			xlru_psm::xlru_psm_status.status.overtempWarning=false;
			xlru_psm::xlru_psm_status.status.overtempHazard=false;
			break;

		case PSMWarning:
		case PSMHazard1:
			xlru_psm::xlru_psm_status.status.overtempWarning=true;
			xlru_psm::xlru_psm_status.status.overtempHazard=true;
			break;

		default:
			xlru_psm::xlru_psm_status.status.overtempHazard=true;
			xlru_psm::xlru_psm_status.status.overtempWarning=true;
	}

	if (buffer[PSM_SPARE1_TX_INDEX]!='_')
	{
		xlru_psm::xlru_psm_status.recycled=true;
		if (buffer[PSM_SPARE1_TX_INDEX]=='P')
			xlru_psm::xlru_psm_status.recycled_code=-1;
		else
			xlru_psm::xlru_psm_status.recycled_code=(unsigned char)buffer[PSM_SPARE2_TX_INDEX];

	}
	else
	{
		xlru_psm::xlru_psm_status.recycled=false;
		xlru_psm::xlru_psm_status.recycled_code=-1;
	}

	return error;
}


void xlru_psm::set_psm_fast_cmd(int value)
{
	xlru_psm::xlru_psm_command.fast_cmd = value;
}

void xlru_psm::set_psm_emergency(int value)
{
	xlru_psm::xlru_psm_command.emergency = value;
}

void xlru_psm::set_psm_cmd_id(int value)
{
	xlru_psm::xlru_psm_command.cmd_id = value;
}

void xlru_psm::set_psm_panic_code(unsigned int value)
{
	xlru_psm::xlru_psm_command.panic_code =value;
}

unsigned int xlru_psm::get_psm_fast_cmd()
{
	return xlru_psm::xlru_psm_command.fast_cmd;
}

unsigned int xlru_psm::get_psm_emergency()
{
	return xlru_psm::xlru_psm_command.emergency;
}

unsigned int xlru_psm::get_psm_cmd_id()
{
	return xlru_psm::xlru_psm_command.cmd_id;
}

void xlru_psm::xlru_display(int (*print_func)(const char*, ...))
{
	print_func("\n   -> Info from PSM <-\n");

	print_func("     %-35s: %d.%d\n","board version.release", xlru_psm::xlru_psm_status.sw_major, xlru_psm::xlru_psm_status.sw_minor);

	print_func("     %-35s: %c\n","mode_status", xlru_psm::xlru_psm_status.mode_status);
	print_func("     %-35s: %c\n","hazard_status",xlru_psm::xlru_psm_status.hazard_status);
	print_func("     %-35s: %c\n","3sec_status",xlru_psm::xlru_psm_status._3sec_status);
	print_func("     %-35s: %c\n","wow_status",xlru_psm::xlru_psm_status.wow_status);
	print_func("     %-35s: %c\n","ac_status",xlru_psm::xlru_psm_status.ac_status);
	print_func("     %-35s: %c\n","bs_status",xlru_psm::xlru_psm_status.bs_status);
	print_func("     %-35s: %c\n","dc_status",xlru_psm::xlru_psm_status.dc_status);
	print_func("     %-35s: %c\n","pfc_status",xlru_psm::xlru_psm_status.pfc_status);

	print_func("     %-35s: %c    %-35s: %-4.1f\n","VOLT3V3_status",xlru_psm::xlru_psm_status.out_rail_VOLT3V3_status, "VOLT3V3" ,xlru_psm::xlru_psm_status.out_volt_VOLT3V3);
	print_func("     %-35s: %c    %-35s: %-4.1f\n","VOLT5V_status",xlru_psm::xlru_psm_status.out_rail_VOLT5V_status, "VOLT5V" ,xlru_psm::xlru_psm_status.out_volt_VOLT5V);
	print_func("     %-35s: %c    %-35s: %-4.1f\n","VOLT15V_status",xlru_psm::xlru_psm_status.out_rail_VOLT15V_status, "VOLT15V" ,xlru_psm::xlru_psm_status.out_volt_VOLT5V);
	print_func("     %-35s: %c    %-35s: %-4.1f\n","VOLTNEG15V_status",xlru_psm::xlru_psm_status.out_rail_VOLTNEG15V_status, "VOLTNEG15V" ,xlru_psm::xlru_psm_status.out_volt_VOLTNEG15V);

	print_func("     %-35s: %-4.1f %-35s: %-4.1f\n","in_amp",xlru_psm::xlru_psm_status.in_amp, "temperature(°)" ,xlru_psm::xlru_psm_status.temperature);
	print_func("     %-35s: %-4.1f %-35s: %-4.1f\n","on_counter",xlru_psm::xlru_psm_status.on_counter, "unc_counter" ,xlru_psm::xlru_psm_status.unc_counter);
	print_func("     %-35s: %-4.1f %-35s: %-4.1f\n","eti",xlru_psm::xlru_psm_status.eti);

	print_func("\n");

}

void xlru_psm::xlru_add_error(int n_error)	//error into last decode response message
{
	xlru_psm::xlru_counter.last_decode_error += n_error;
}

void xlru_psm::xlru_add_rx(int n_rx)				//response messages
{
	xlru_psm::xlru_counter.rx_mess+= n_rx;
}

void xlru_psm::xlru_add_rx_error(int n_error)		//response messages with error
{
	xlru_psm::xlru_counter.rx_mess_error += n_error;
}

void xlru_psm::xlru_add_no_rx(int n_error)	//count messages without response
{
	xlru_psm::xlru_counter.no_response += n_error;
}

void xlru_psm::xlru_set_last_error(char *last_error)	//report last error
{
	strcpy(xlru_psm::xlru_counter.last_error, last_error);
}

void xlru_psm::xlru_set_last_rx(char *last_rx)		//report last received message
{
	strcpy(xlru_psm::xlru_counter.last_rx, last_rx);
}
void xlru_psm::xlru_set_last_tx(char *last_tx)		//report last trasmitted message
{
	strcpy(xlru_psm::xlru_counter.last_tx, last_tx);
}
char* xlru_psm::xlru_get_last_rx()
{
	return xlru_psm::xlru_counter.last_rx;
}
char* xlru_psm::xlru_get_last_tx()
{
	return xlru_psm::xlru_counter.last_tx;
}
char* xlru_psm::xlru_get_last_error()
{
	return xlru_psm::xlru_counter.last_error;
}

void xlru_psm::xlru_display_compact(int (*print_func)(const char*, ...))
{
	print_func("\n   -> Info from PSM <-\n");

	print_func("     %-10s: %d.%d\n","ver.rel", xlru_psm::xlru_psm_status.sw_major, xlru_psm::xlru_psm_status.sw_minor);

	print_func("     %-10s: %c    %-10s: %c\n","mode", xlru_psm::xlru_psm_status.mode_status, "ac", xlru_psm::xlru_psm_status.ac_status);
	print_func("     %-10s: %c    %-10s: %c\n","hazard",xlru_psm::xlru_psm_status.hazard_status, "bc", xlru_psm::xlru_psm_status.bs_status);
	print_func("     %-10s: %c    %-10s: %c\n","3sec",xlru_psm::xlru_psm_status._3sec_status, "dc", xlru_psm::xlru_psm_status.dc_status);
	print_func("     %-10s: %c    %-10s: %c\n","wow",xlru_psm::xlru_psm_status.wow_status, "pfc", xlru_psm::xlru_psm_status.pfc_status);

	print_func("     %-10s: %c    %-10s: %-4.1f\n","VOLT3V3",xlru_psm::xlru_psm_status.out_rail_VOLT3V3_status,"volt", xlru_psm::xlru_psm_status.out_volt_VOLT3V3);
	print_func("     %-10s: %c    %-10s: %-4.1f\n","VOLT5V",xlru_psm::xlru_psm_status.out_rail_VOLT5V_status, "volt",xlru_psm::xlru_psm_status.out_volt_VOLT5V);
	print_func("     %-10s: %c    %-10s: %-4.1f\n","VOLT15V",xlru_psm::xlru_psm_status.out_rail_VOLT15V_status, "volt",xlru_psm::xlru_psm_status.out_volt_VOLT15V);
	print_func("     %-10s: %c    %-10s: %-4.1f\n","VOLTNEG15V",xlru_psm::xlru_psm_status.out_rail_VOLTNEG15V_status, "volt",xlru_psm::xlru_psm_status.out_volt_VOLTNEG15V);

	print_func("     %-10s: %-4.1f %-10s: %-4d\n","in_amp",xlru_psm::xlru_psm_status.in_amp, "temp" ,xlru_psm::xlru_psm_status.temperature);
	print_func("     %-10s: %-4d %-10s: %-4d\n","on count.",xlru_psm::xlru_psm_status.on_counter, "unc count." ,xlru_psm::xlru_psm_status.unc_counter);
	print_func("     %-10s: %-4d\n","eti",xlru_psm::xlru_psm_status.eti);

	print_func("\nbit     ->  0 1 2 3 4 5 6 7\n");

		print_func("byte%d   ->  %01d %01d %01d %01d %01d %01d %01d %01d\n",
					1,
					0,
					xlru_psm::xlru_psm_status.byte1.b1_PSM_EIF_comm,
					xlru_psm::xlru_psm_status.byte1.b2_rs422_comm,
					xlru_psm::xlru_psm_status.byte1.b3_rs485_comm,
					xlru_psm::xlru_psm_status.byte1.b4_rs232_comm,
					xlru_psm::xlru_psm_status.byte1.b5_ov_temp_haz_2,
					xlru_psm::xlru_psm_status.byte1.b6_ov_board_temp,
					xlru_psm::xlru_psm_status.byte1.b7_ov_dc_bus_current
					);

		print_func("byte%d   ->  %01d %01d %01d %01d %01d %01d %01d %01d\n",
							2,
							xlru_psm::xlru_psm_status.byte2.b0_ov_m15v,
							xlru_psm::xlru_psm_status.byte2.b1_uv_m15v,
							xlru_psm::xlru_psm_status.byte2.b2_ov_15v,
							xlru_psm::xlru_psm_status.byte2.b3_uv_15v,
							xlru_psm::xlru_psm_status.byte2.b4_ov_5v,
							xlru_psm::xlru_psm_status.byte2.b5_uv_5v,
							xlru_psm::xlru_psm_status.byte2.b6_ov_3v3,
							xlru_psm::xlru_psm_status.byte2.b7_uv_3v3
							);

		print_func("byte%d   ->  %01d %01d %01d %01d %01d %01d %01d %01d\n",
							3,
							xlru_psm::xlru_psm_status.byte3.b0_ov_13v_b,
							xlru_psm::xlru_psm_status.byte3.b1_uv_13v_b,
							xlru_psm::xlru_psm_status.byte3.b2_wow_out,
							xlru_psm::xlru_psm_status.byte3.b3_3sec_in,
							xlru_psm::xlru_psm_status.byte3.b4_uv_350v,
							xlru_psm::xlru_psm_status.byte3.b5_ov_350v,
							xlru_psm::xlru_psm_status.byte3.b6_blko_tst,
							xlru_psm::xlru_psm_status.byte3.b7_pwr_err
							);

		print_func("byte%d   ->  %01d %01d %01d %01d %01d %01d %01d %01d\n",
							4,
							xlru_psm::xlru_psm_status.byte4.b0_rdr_on_sts,
							xlru_psm::xlru_psm_status.byte4.b1_lcu_rdy_uc,
							xlru_psm::xlru_psm_status.byte4.b2_uc_interlock_o,
							xlru_psm::xlru_psm_status.byte4.b3_ac_loss,
							xlru_psm::xlru_psm_status.byte4.b4_ps_interlock_n,
							xlru_psm::xlru_psm_status.byte4.b5_ov_temp_haz,
							xlru_psm::xlru_psm_status.byte4.b6_uv_270v,
							xlru_psm::xlru_psm_status.byte4.b7_battle_short_cmd
							);

		print_func("\n");

}




