#ifndef ENUMS_H
#define ENUMS_H

#include <enums.h>


//////////////////////////////////////////////////////////////////
//
//  Error Codes

#define E_OK                0                 //all good
#define E_SKIP              10                //all good
#define E_QUEUED            20                //all good
#define E_INVALID_PARAMETER 30                //all good
#define E_NO_SUCH_PID       2001              //cant find PID
#define E_QUERY_BUFFER_END  99                //have no free query buffer slot

#define E_USER_START        1000              // base offset for sub system errors

// VFD
#define E_VFD_RUN           300                 // Motor should spin but dosnt
#define E_VFD_LOSS          301                 // Motor should not spin but does

#define E_VFD_CUSTOM        1000                // Custom VFD error

#define E_VFD_NORMAL        E_VFD_CUSTOM        // VFD Normal Operation
#define E_VFD_OVERLOAD      E_VFD_CUSTOM + 1    // Motor overload
#define E_VFD_TIMEOUT       E_VFD_CUSTOM + 2    // Timeout


// PID
#define E_PID_CUSTOM        2000                // Custom PID error
#define E_PID_TIMEOUT       E_PID_CUSTOM + 2    // Timeout
#define E_PID_OVERHEAT      E_PID_CUSTOM + 3    // Timeout

// Extruder Feed
#define E_FEED_OVERLOAD     4001

//////////////////////////////////////////////////////////////////
//
//  Component Keys
typedef enum COMPONENT_KEY
{
  COMPONENT_KEY_NONE = 0,
  COMPONENT_KEY_APP = 1,
  COMPONENT_KEY_PID = 2,
  COMPONENT_KEY_RELAY_1 = 51,
  COMPONENT_KEY_RELAY_2 = 52,
  COMPONENT_KEY_RELAY_3 = 53,
  COMPONENT_KEY_RELAY_4 = 54,
  COMPONENT_KEY_RELAY_5 = 55,
  COMPONENT_KEY_PID_0 = 100,
  COMPONENT_KEY_PID_1 = 101,
  COMPONENT_KEY_VFD = 200,
  COMPONENT_KEY_VFD_LOAD = 210,
  COMPONENT_KEY_MB_RELAY_0 = 300,
  COMPONENT_KEY_MB_RELAY_1 = 301,
  COMPONENT_KEY_MB_RELAY_2 = 302,
  COMPONENT_KEY_MB_ANALOG_0 = 400,
  COMPONENT_KEY_MB_ANALOG_1 = 401,
  COMPONENT_KEY_MB_ANALOG_2 = 402,
  COMPONENT_KEY_MB_ANALOG_3POS_SWITCH_0 = 501,
  COMPONENT_KEY_MB_ANALOG_3POS_SWITCH_1 = 502,
  COMPONENT_KEY_STEPPER_0 = 601,
  COMPONENT_KEY_STEPPER_1 = 602,
  COMPONENT_KEY_FEEDBACK_0 = 701,
  COMPONENT_KEY_FEEDBACK_1 = 702,
  COMPONENT_KEY_END = 1000,
} COMPONENT_KEY;

enum ERROR
{
  ERROR_OK = 0,
  ERROR_WARNING = 1,
  ERROR_FATAL = 2
};

enum MBB_STATE
{
  WAITING = 0,
  QUERY = 1,
  RESPONSE = 2,
  IDLE = 3,
  UNKNOWN = 4,
};

// Modbus query state
enum QUERY_STATE
{
  QUEUED = 1,
  PROCESSING = 2,
  SENT = 3,
  RESPONDED = 4,
  DONE = 5
};

#define ku8MBReadCoils 0x01          ///< Modbus function 0x01 Read Coils
#define ku8MBReadDiscreteInputs 0x02 ///< Modbus function 0x02 Read Discrete Inputs
#define ku8MBWriteSingleCoil 0x05    ///< Modbus function 0x05 Write Single Coil
#define ku8MBWriteMultipleCoils 0x0F ///< Modbus function 0x0F Write Multiple Coils

// Modbus function codes for 16 bit access
#define ku8MBReadHoldingRegisters 0x03       ///< Modbus function 0x03 Read Holding Registers
#define ku8MBReadInputRegisters 0x04         ///< Modbus function 0x04 Read Input Registers
#define ku8MBWriteSingleRegister 0x06        ///< Modbus function 0x06 Write Single Register
#define ku8MBWriteMultipleRegisters 0x10     ///< Modbus function 0x10 Write Multiple Registers
#define ku8MBMaskWriteRegister 0x16          ///< Modbus function 0x16 Mask Write Register
#define ku8MBReadWriteMultipleRegisters 0x17 ///< Modbus function 0x17 Read Write Multiple Registers
#define ku8MBLinkTestOmronMX2Only 0x08       ///< Modbus function 0x08 Test

// Modbus protocol errors
#define ERR_MODBUS_0x01 -41   // Modbus 0x01 protocol illegal function exception
#define ERR_MODBUS_0x02 -42   // Modbus 0x02 protocol illegal data address exception
#define ERR_MODBUS_0x03 -43   // Modbus 0x03 protocol illegal data value exception
#define ERR_MODBUS_0x04 -44   // Modbus 0x4 protocol slave device failure exception
#define ERR_MODBUS_0xe0 -45   // Modbus 0xe0 Master invalid response slave ID exception
#define ERR_MODBUS_0xe1 -46   // Modbus 0xe1 Master invalid response function exception
#define ERR_MODBUS_0xe2 -47   // Modbus 0xe2 Master response timed out exception
#define ERR_MODBUS_0xe3 -48   // Modbus 0xe3 Master invalid response CRC exception
#define ERR_MODBUS_UNKNOW -56 // Modbus unknown error (protocol failure)
#define ERR_MODBUS_STATE -57  // Forbidden ( invalid ) state of the inverter
#define ERR_MODBUS_BLOCK -58  // Attempt to turn on the VT with the inverter locked

// Omron Mx2 specific
#define ERR_MODBUS_MX2_0x01 -49 // Omron mx2 Exception code 0x01 The specified function is not supported
#define ERR_MODBUS_MX2_0x02 -50 // Omron mx2 Exception code 0x02 The specified function was not found.
#define ERR_MODBUS_MX2_0x03 -52 // Omron mx2 Exception code 0x03 Unacceptable data format
#define ERR_MODBUS_MX2_0x05 -52 // Omron mx2 communication error over Modbus (function communication check 0x08 Omron mx2)
#define ERR_MODBUS_MX2_0x21 -53 // Omron mx2 Exception code 0x21 Data written to the storage register is outside the inverter
#define ERR_MODBUS_MX2_0x22 -54 // Omron mx2 Exception code 0x22 These functions are not available for the inverter
#define ERR_MODBUS_MX2_0x23 -55 // Omron mx2 Exception code 0x23 The register (bit) into which the value should be written is read-only

#define ERR_MODBUS_TIMEOUT  255 // App specific error code for timeouts

//////////////////////////////////////////////////////////////////
//
//  PH - Firmware specific register mapping - TCP & RS485
//

#define MB_R_SYSTEM_ERROR 0

// Omron Register Mapping (Read mirror)
#define MB_R_FREQ_TARGET 1
#define MB_R_VFD_LOAD 2
#define MB_R_VFD_STATUS 3
#define MB_R_VFD_STATE 4
#define MB_R_VFD_DIRECTION 4

// Omron - MX2 related PlasticHub Coil Mapping (Write)
#define MB_W_VFD_RUN 5
#define MB_W_FREQ_TARGET 6
#define MB_W_DIRECTION 7
#define MB_R_VFD_APP_STATE 8

#define MB_W_RESET_REG 100    // Reset the controller via Modbus (FN 0x3)
#define MB_R_APP_STATE_REG 9  // Application state register (FN 0x3)


///////////////////////////////////////////////////////////////////////////////////////////////////
// Omron related address offset : PID & MX2
#define MB_REGISTER_OFFSET 10

#define MB_W_FEED_VFD_RATIO MB_REGISTER_OFFSET + 6

//  TCP Inbound write register - Omron-E5 : Variable Register
//#define MB_W_PID_0_USER MB_REGISTER_OFFSET + 6
//#define MB_W_PID_1_USER MB_REGISTER_OFFSET + 7
//#define MB_W_PID_2_USER MB_REGISTER_OFFSET + 8

//  TCP read register - Omron-E5 : Variable Register Monitor
#define MB_R_PID_0_USER_MON MB_REGISTER_OFFSET + 3
#define MB_R_PID_1_USER_MON MB_REGISTER_OFFSET + 4
#define MB_R_PID_2_USER_MON MB_REGISTER_OFFSET + 5

//  TCP Inbound write register - Omron-E5 : SetPoint
#define MB_W_PID_1_SP MB_REGISTER_OFFSET + 0
#define MB_W_PID_2_SP MB_REGISTER_OFFSET + 1
#define MB_W_PID_3_SP MB_REGISTER_OFFSET + 2

///////////////////////////////////////////////////////////////////////////////////////////////////
// TemperatureController related address offset for internal values
#define MB_REGISTER_OFFSET_TC MB_REGISTER_OFFSET + 10
#define MB_REGISTER_OFFSET_TC_RANGE           3
//  RS485 read register - TemperatureController
#define MB_R_PID_1_PV MB_REGISTER_OFFSET_TC + 0
#define MB_R_PID_1_SP MB_REGISTER_OFFSET_TC + 1
#define MB_R_PID_1_STATE MB_REGISTER_OFFSET_TC + 2

#define MB_R_PID_2_PV MB_REGISTER_OFFSET_TC + 3
#define MB_R_PID_2_SP MB_REGISTER_OFFSET_TC + 4
#define MB_R_PID_2_STATE MB_REGISTER_OFFSET_TC + 5

#define MB_R_PID_3_PV MB_REGISTER_OFFSET_TC + 6
#define MB_R_PID_3_SP MB_REGISTER_OFFSET_TC + 7
#define MB_R_PID_3_STATE MB_REGISTER_OFFSET_TC + 8
#define MB_R_PRINT       MB_REGISTER_OFFSET + 9

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Modbus System Commands
//
#define MB_R_SYSTEM_CMD_PRINT_REGS 2
#define MB_R_SYSTEM_CMD_PRINT_QUEUE 1
#define MB_R_SYSTEM_CMD_PRINT_MEMORY 5
#define MB_R_SYSTEM_CMD_PRINT_VFD 6
#define MB_R_SYSTEM_CMD_PRINT_PIDS 7

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Relay Addresses
//
#define MB_REGISTER_OFFSET_RELAYS_READ MB_REGISTER_OFFSET_TC + 20

#define MB_R_RELAY_0 MB_REGISTER_OFFSET_RELAYS_READ + 1
#define MB_R_RELAY_1 MB_REGISTER_OFFSET_RELAYS_READ + 2
#define MB_R_RELAY_2 MB_REGISTER_OFFSET_RELAYS_READ + 3
#define MB_R_RELAY_3 MB_REGISTER_OFFSET_RELAYS_READ + 4
#define MB_R_RELAY_4 MB_REGISTER_OFFSET_RELAYS_READ + 5
#define MB_R_RELAY_5 MB_REGISTER_OFFSET_RELAYS_READ + 6
#define MB_R_RELAY_6 MB_REGISTER_OFFSET_RELAYS_READ + 7
#define MB_R_RELAY_7 MB_REGISTER_OFFSET_RELAYS_READ + 8

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Analog Addresses
//
#define MB_REGISTER_OFFSET_ANALOG_READ MB_REGISTER_OFFSET_RELAYS_READ + 10

#define MB_R_ANALOG_0 MB_REGISTER_OFFSET_ANALOG_READ + 1
#define MB_R_ANALOG_1 MB_REGISTER_OFFSET_ANALOG_READ + 2
#define MB_R_ANALOG_2 MB_REGISTER_OFFSET_ANALOG_READ + 3

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Switch Addresses
//
#define MB_REGISTER_OFFSET_SWITCH_READ MB_REGISTER_OFFSET_ANALOG_READ + 10

#define MB_R_SWITCH_0 MB_REGISTER_OFFSET_SWITCH_READ + 1
#define MB_R_SWITCH_1 MB_REGISTER_OFFSET_SWITCH_READ + 2
#define MB_R_SWITCH_2 MB_REGISTER_OFFSET_SWITCH_READ + 3
#define MB_R_SWITCH_3 MB_REGISTER_OFFSET_SWITCH_READ + 4

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Stepper Addresses
//
#define MB_REGISTER_OFFSET_STEPPER MB_REGISTER_OFFSET_SWITCH_READ + 10

#define MB_RW_STEPPER_SPEED_0 MB_REGISTER_OFFSET_STEPPER
#define MB_RW_STEPPER_DIR_OFFSET 1
#define MB_RW_STEPPER_STATUS_OFFSET 2
#define MB_RW_STEPPER_USER_OFFSET 3

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Monitoring & Feedback Addresses
//
#define MB_REGISTER_OFFSET_MONITORING MB_REGISTER_OFFSET_STEPPER + 10
#define MB_MONITORING_STATUS_VFD_MAX_LOAD MB_REGISTER_OFFSET_MONITORING + 1
#define MB_MONITORING_STATUS_FEEDBACK_0 MB_MONITORING_STATUS_VFD_MAX_LOAD + 3
#define MB_MONITORING_STATUS_FEEDBACK_1 MB_MONITORING_STATUS_VFD_MAX_LOAD + 4
#define MB_MONITORING_STATUS_VFD_RETRACT_STATE MB_REGISTER_OFFSET_MONITORING + 5
#define MB_MONITORING_STATUS_VFD_RUN_MODE MB_REGISTER_OFFSET_MONITORING + 6
#define MB_MONITORING_STATUS_VFD_CURRENT MB_REGISTER_OFFSET_MONITORING + 7

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Omron - MX2 States

#define OMRON_STATE_ACCELERATING 4
#define OMRON_STATE_DECELERATING 2
#define OMRON_STATE_RUNNING 3
#define OMRON_STATE_STOPPED 1
#define OMRON_STATE_ERROR 8

// Omron - MX2 states
#define OMRON_STATUS_STOPPED 2
#define OMRON_STATUS_RUNNING 0
// Number of Omron Status Poll Registers
#define OMRON_STATUS_POLL_REGISTERS 7


//  Omron Response Format (E5DC-B_H175-E1-08.pdf : 4-5 / 4.1.3)
//  03 : 86 : 04 : E2 : 63
//  Slave | FN | Error Code | CRC
// 
//  Error Codes
//    -> 01 Function Error Code : An unsupported function code was received.
//    -> 02  Variable address Error : The specified variable area address is out-of-range.
//    -> 03 Variable data Error : The amount of data does not match the number of
//                    elements.
// The byte count is not 2 times the number of elements.
// The response length exceeds the size of the communications buffer.
// The command code or related information in the operation command
//-> 04 Operation error :  The write data contents are not allowed in the present operation mode.
//    • The Communications Writing parameter is set to “OFF” (disabled).
//    • Attempted to write to a parameter in setup area 1 from setup area 0.
//    • Attempted to write to a protect parameter from other than the protect level.
//    • AT execution is in progress.
//    • The command cannot be processed.
//  Set 'cmwt' to 'on' 7-1-3

#endif
