/*
 * err_hdlr.h
 *
 *  Created on: 03-Aug-2023
 *      Author: Invcuser52
 */

#ifndef ERR_HDLR_H_
#define ERR_HDLR_H_

#include "exo_common.h"
#include "exo_types.h"

#include "stdlib.h"
#include "stdio.h"
#include "string.h"


/*
 * enable this macro to test error handler module
 */
//#define ERR_HANDL_TEST_HOOK_ENABLE


#define ERROR_CODE_TOTAL_IO 			4
#define ERROR_CODE_TOTAL_AHW_SET_1		32
#define ERROR_CODE_TOTAL_AHW_SET_2		1
#define ERROR_CODE_TOTAL_SYSTEM 		6
#define ERROR_CODE_TOTAL_SERVICES 		1
#define ERROR_CODE_TOTAL_COMMS 	        15
#define ERROR_CODE_TOTAL_ADCS           4
#define ERROR_CODE_TOTAL_EPS            3

#define ERROR_GROUP_TOTAL 				8

#define ERROR_CODES_TOTAL 				(ERROR_CODE_TOTAL_IO + 			\
        ERROR_CODE_TOTAL_AHW_SET_1 + 	\
        ERROR_CODE_TOTAL_AHW_SET_2 + 	\
        ERROR_CODE_TOTAL_SYSTEM + 		\
        ERROR_CODE_TOTAL_SERVICES + 	\
										 ERROR_CODE_TOTAL_COMMS + \
        ERROR_CODE_TOTAL_ADCS + \
        ERROR_CODE_TOTAL_EPS)


#define RCVRY_AND_SELF_TEST 			0
#define NO_RCVRY_ONLY_SELF_TEST 		1
#define ERR_HISTORY_SAVED_NUM           5

#define NVM_ERROR_HISTORY_TOTAL_COUNT   20

/**
 * @brief Error handler queue id
 */
typedef enum
{
        ERR_HDLR_DATA_QUEUE_ID,
        ERR_HDLR_QUEUE_ID_MAX
}err_hdlr_queue_id;

typedef enum err_fault_status_def
{
	E_MODULE_OK,
	E_MODULE_FAULT
}err_fault_status;

/*
 * Enumeration for Error Groups
 * Each group will contain associated error list
 * Each group can contain up to 32 error codes max
 */
typedef enum err_group_def
{
	ERR_GROUP_IO,
	ERR_GROUP_AHW_SET_1,
	ERR_GROUP_AHW_SET_2,
	ERR_GROUP_SYSTEM,
	ERR_GROUP_SERVICES,
	ERR_GROUP_COMMS,
	ERR_GROUP_ADCS,
	ERR_GROUP_EPS,
	ERR_GROUP_MAX
}err_group;



/*
 * Error codes of group IO
 */
typedef enum err_io_def
{
	ERR_IO_I2C_FAIL,
	ERR_IO_SPI_FAIL,
	ERR_IO_CAN_FAIL,
	ERR_IO_UART_FAIL,
	ERR_IO_QSPI_FAIL,
	ERR_IO_MAX
}err_code_io;

typedef enum err_state_def
{
	ERR_TCTM_GET_ALL_FAULTS,
	ERR_TCTM_ERR_CODE_STS,
	ERR_TCTM_ERR_HISTORY,
	ERR_TCTM_ERR_BIST_STS,
	ERR_TCTM_INVALID_INPUT
}err_tctm_request_id;

/*
 * 	INVLD_AH_INST_ID ,					///< invalid AH instance ID
	MCU_ID,
	IMU_BMX160_OBC_1,
	IMU_BMX160_OBC_2,
	IMU_BMX160_XXX,
	DIGITAL_THERMOSTAT_DS620_EDGE,
	DIGITAL_THERMOSTAT_DS620_PS,
	DIGITAL_THERMOSTAT_DS620_SPE01,
	DIGITAL_THERMOSTAT_DS620_SPE02,
	DIGITAL_THERMOSTAT_DS620_SPW01,
	DIGITAL_THERMOSTAT_DS620_SPW02,
	DIGITAL_THERMOSTAT_DS620_SPB01,
	HSC_ADM1176_EDGE,
	HSC_ADM1176_PS_2,
	HSC_ADM1176_PS_1,
	TEMP_SENSOR_MCP9843_OBC,
	TEMP_SENSOR_MCP9843_PS,
	TEMP_SENSOR_MCP9843_EDGE,
	TEMP_SENSOR_MCP9843_GPS,

	PSM_INA230_OBC,
	PSM_INA230_PS,
	GPIO_EXPANDER_PCAL6408A_PS,
	GPIO_EXPANDER_MCP23008_EDGE_1,
	GPIO_EXPANDER_MCP23008_EDGE_2,
	GPIO_EXPANDER_MCP23008_OBC_1,
	GPIO_EXPANDER_MCP23008_OBC_2,
	GPIO_EXPANDER_MCP23008_GPS,
	THRUSTER_MORPHEUS_OBC,
	VOLTAGE_SEQUENCER_UCD9801_OBC,
	DATA_LOGGER_ADS7828_PS,
	EXT_MEM_MX25L512_QSPI,
	EXT_MEM_MT25QL512_QSPI,
	EXT_MEM_S25HL512T_QSPI,
	EXT_MEM_MT28EW128_FMC,
	UART_EXPANDER_MAX14830_OBC,


	MAX_AH_INST_ID
 *
 */
typedef enum err_ahw_def_set_1
{
    ERR_IMU_BMX160_OBC_1,
	ERR_IMU_BMX160_OBC_2,
	ERR_IMU_BMX160_XXX,
	ERR_DIGITAL_THERMOSTAT_DS620_EDGE,
	ERR_DIGITAL_THERMOSTAT_DS620_PS,
	ERR_HSC_ADM1176_EDGE,
	ERR_HSC_ADM1176_PS_2,
	ERR_HSC_ADM1176_PS_1,
	ERR_TEMP_SENSOR_MCP9843_OBC,
	ERR_TEMP_SENSOR_MCP9843_PS,
	ERR_TEMP_SENSOR_MCP9843_EDGE,
	ERR_TEMP_SENSOR_MCP9843_GPS,
	ERR_TEMP_SENSOR_MCP9843_SPE01,
	ERR_TEMP_SENSOR_MCP9843_SPE02,
	ERR_TEMP_SENSOR_MCP9843_SPW01,
	ERR_TEMP_SENSOR_MCP9843_SPW02,
	ERR_TEMP_SENSOR_MCP9843_SPB01,
	ERR_PSM_INA230_OBC,
	ERR_PSM_INA230_PS,
	ERR_GPIO_EXPANDER_PCAL6408A_PS,
	ERR_GPIO_EXPANDER_MCP23008_EDGE_1,
	ERR_GPIO_EXPANDER_MCP23008_EDGE_2,
	ERR_GPIO_EXPANDER_MCP23008_OBC_1,
	ERR_GPIO_EXPANDER_MCP23008_OBC_2,
	ERR_GPIO_EXPANDER_MCP23008_GPS,
	ERR_THRUSTER_MORPHEUS_OBC,
	ERR_VOLTAGE_SEQUENCER_UCD9801_OBC,
	ERR_DATA_LOGGER_ADS7828_PS,
	ERR_EXT_MEM_MX25L512_QSPI,
	ERR_EXT_MEM_MT25QL512_QSPI,
	ERR_EXT_MEM_S25HL512T_QSPI,
	ERR_EXT_MEM_MT28EW128_FMC,
	ERR_AHW_ONE_MAX
}err_code_ahw_set_1;

typedef enum err_ahw_def_set_2
{
	ERR_UART_EXPANDER_MAX14830_OBC,
	ERR_AHW_TWO_MAX
}err_code_ahw_set_2;

typedef enum err_system_def
{
	ERR_IRAM_HEAP_FREE_LESSER_THAN_16K,
	ERR_IRAM_HEAP_FREE_LESSER_THAN_8K,
	ERR_ERAM_HEAP_FREE_LESSER_THAN_16K,
	ERR_ERAM_HEAP_FREE_LESSER_THAN_8K,
	ERR_CMALLOC_FREE_LESSER_THAN_4K,
	ERR_OBC_FW_UPDATE_FAIL,
	ERR_SYS_MAX
}err_code_system;

typedef enum err_services_def
{
	ERR_SER_1,
	ERR_SER_MAX
}err_code_services;

typedef enum err_comms_modules_def
{
	ERR_COMMS_PKT_DROP,
	ERR_COMMS_PKT_LEN_MISMATCH,
	ERR_COMMS_SBAND_BUSY,
	ERR_COMMS_SBAND_TCP_READ_FAIL,
	ERR_COMMS_SBAND_TCP_CONNECTION_FAIL,
	ERR_COMMS_SBAND_OFF_VOLT_TEMP_EXCEED,
	ERR_COMMS_NACK_RCV_UHF,
	ERR_COMMS_RESTART_UHF,
	ERR_COMMS_SBAND_RSP_CMD,
	ERR_COMMS_SBAND_BUSY_TCP_WRITE,
	ERR_COMMS_SBAND_READ_UDP_RX_FAIL,
	ERR_COMMS_SBAND_UDP_TX_CONNECTION_FAIL,
	ERR_COMMS_SBAND_SEND_UDP_TX_FAIL,
	ERR_COMMS_SBAND_READ_UDP_TX_FAIL,
	ERR_COMMS_SBAND_FW_UPD_FAIL,
    ERR_COMMS_UHF_RSP_TIMEOUT,
	ERR_COMMS_MAX
}err_code_comms_modules;

typedef enum err_adcs_module_def
{
    ERR_IO_INTERFACE_ERR,   ///< Interface error
	ERR_OPERATION_FAILURE,    ///< Operation failure
	ERR_TC_TM_ERROR,          ///< Telecommand and Telemetry Error
	ERR_INVLD_PWR_STATE,      ///< Invalid power state
    ERR_ADCS_MAX            ///< ADCS Max
}err_code_adcs_module;

typedef enum err_eps_def
{
	ERR_EPS_COM_FAIL,
	ERR_EPS_CRC_FAIL,
	ERR_EPS_RESP_ERR,
	ERR_EPS_CTRL_FW_MISMATCH,
	ERR_EPS_MAX
}err_code_eps;

/*
 * Error handler info
 * -1. Error Group			= 3 bits  (0-7)
 * 0. Error ID				= 5 bits  (0- 31)
 * 1. Error set status  	= 1 bit
 * 2. Error counter     	= 3 bit   (0-7)
 * 3. Fault status			= 1 bit
 * 4. Error reporter name 	= 6 bit   (0-63)
 * 5. Reporting time		= 3 bytes (3 times)
 *
 * Total >> 3 + 5 + 1 + 3 + 1 + 3unused + 6 + 2unused + 24 + 24 + 24 =  96/8 = 12 bytes
 *
 * For history of 30 errors will be 12*30 = 360 bytes
 */




typedef struct report_time_info_def
{
	uint8_t hours;
	uint8_t min;
	uint8_t seconds;
}report_time_info;


typedef struct err_handler_info_def
{
	uint8_t group_id 			: 3;
	uint8_t error_code          : 5;
	uint8_t error_set			: 1;
	uint8_t error_cntr			: 3;
	uint8_t error_cntr_limit	: 3;
	uint8_t fault_set			: 1;
	uint8_t reported_module_id	: 8;
	report_time_info reported_time[3];
}err_handler_info;



/*
 * total size 10 bytes
 */
typedef struct err_handler_history_def
{
	uint64_t reported_time;
	uint8_t group_id 			: 3;
	uint8_t error_code          : 5;
	uint8_t fault_set			: 1;
	uint8_t reported_module_id	: 7;

}err_handler_history;

typedef struct err_logs_def
{
	uint8_t err_apperance_cntr;
	uint8_t recovery_success_cntr;
	uint8_t recovery_failure_cntr;
}err_code_status_info;


void err_init(void);
void err_detected(err_group g_id, uint8_t err);
void err_cleared(err_group g_id, uint8_t err);
err_fault_status err_get_fault_status(err_group g_id, uint8_t err);
void periodic_fault_recovery_func_callback();
void periodic_fault_timer_stop_timer(void);
void run_bist();
void save_fault(err_group g_id);
void clear_fault(void);
void read_fault(void);
void read_err_history(uint8_t *read_history_buffer, uint8_t err_his_count);
uint8_t err_run_recovery_particular_error(uint8_t g_id, uint8_t err);
void err_clear_err_cntr(err_group g_id, uint8_t err);

/*API to start timer for sending err handler health data*/
void err_hdlr_health_data_send_tmr_strt();
/*API to send queue request to HM framework*/
void tc_err_hdlr_buff_fw_req_queue(uint32 instance_size, uint32 num_of_instance, uint8 queue_id);

/*This API is clled upon the expiry of the timer function
 * set with determined periodicity to send err handler
 * health data*/

void err_hdlr_health_buff_timer_exp_cb();

/*This API is used to enqueue error handler health data*/
void tc_err_hdlr_buff_fw_enqueue_req(uint8* data, uint8 queue_id);


#ifdef ERR_HANDL_TEST_HOOK_ENABLE
err_fault_status err_handler_test_hook(err_group g_id, uint8_t err);
#endif


#endif /* ERR_HDLR_H_ */
