/*
 * Modbus_functions.h
 *
 *  Created on: 8. 3. 2020
 *      Author: Ondrej Vitoslavsky
 */

#ifndef MODBUS_FUNCTIONS_H_
#define MODBUS_FUNCTIONS_H_



#define MODBUS_ADDRESS_BROADCAST	0

#define MODBUS_FUNC_READ_HOLDING_REGISTER         3U
#define MODBUS_FUNC_WRITE_REGISTER                6U
#define MODBUS_FUNC_WRITE_MULTIPLE_REGISTERS      16U
#define MODBUS_FUNC_READWRITE_MULTIPLE_REGISTERS  23U
#define MODBUS_FUNC_ERROR                         128U


#define MODBUS_FUNC_READ_ADDR_OFF               MODBUS_PDU_DATA_OFF
#define MODBUS_FUNC_READ_REGCNT_OFF             MODBUS_PDU_DATA_OFF+2
#define MODBUS_FUNC_READ_BYTECNT_OFF            MODBUS_PDU_DATA_OFF+0
#define MODBUS_FUNC_READ_VALUES_OFF            	MODBUS_PDU_DATA_OFF+1
#define MODBUS_FUNC_READ_SIZE                   4

#define MODBUS_FUNC_WRITE_ADDR_OFF              MODBUS_PDU_DATA_OFF
#define MODBUS_FUNC_WRITE_VALUE_OFF             MODBUS_PDU_DATA_OFF+2
#define MODBUS_FUNC_WRITE_SIZE                  4

#define MODBUS_FUNC_WRITE_MUL_ADDR_OFF          MODBUS_PDU_DATA_OFF
#define MODBUS_FUNC_WRITE_MUL_REGCNT_OFF        MODBUS_PDU_DATA_OFF+2
#define MODBUS_FUNC_WRITE_MUL_BYTECNT_OFF       MODBUS_PDU_DATA_OFF+4
#define MODBUS_FUNC_WRITE_MUL_VALUES_OFF        MODBUS_PDU_DATA_OFF+5
#define MODBUS_FUNC_WRITE_MUL_SIZE_MIN          7

#define MODBUS_FUNC_READWRITE_READ_ADDR_OFF     MODBUS_PDU_DATA_OFF+0
#define MODBUS_FUNC_READWRITE_READ_REGCNT_OFF   MODBUS_PDU_DATA_OFF+2
#define MODBUS_FUNC_READWRITE_READ_BYTECNT_OFF  MODBUS_PDU_DATA_OFF+0
#define MODBUS_FUNC_READWRITE_READ_VALUES_OFF   MODBUS_PDU_DATA_OFF+1
#define MODBUS_FUNC_READWRITE_WRITE_ADDR_OFF    MODBUS_PDU_DATA_OFF+4
#define MODBUS_FUNC_READWRITE_WRITE_REGCNT_OFF  MODBUS_PDU_DATA_OFF+6
#define MODBUS_FUNC_READWRITE_WRITE_BYTECNT_OFF MODBUS_PDU_DATA_OFF+8
#define MODBUS_FUNC_READWRITE_WRITE_VALUES_OFF  MODBUS_PDU_DATA_OFF+9
#define MODBUS_FUNC_READWRITE_SIZE_MIN          9


typedef enum
{
    EXCEPTION_NONE = 0x00,
	EXCEPTION_ILLEGAL_FUNCTION = 0x01,
	EXCEPTION_ILLEGAL_DATA_ADDRESS = 0x02,
	EXCEPTION_ILLEGAL_DATA_VALUE = 0x03,
	EXCEPTION_SLAVE_DEVICE_FAILURE = 0x04,
	EXCEPTION_ACKNOWLEDGE = 0x05,
	EXCEPTION_SLAVE_BUSY = 0x06,
	EXCEPTION_MEMORY_PARITY_ERROR = 0x08,
	EXCEPTION_GATEWAY_PATH_FAILED = 0x0A,
	EXCEPTION_GATEWAY_TARGET_FAILED = 0x0B
} ModbusException;


/**
  * @brief  Modbus function 0x03
  * @note   reads multiple data from holding registers.
  * @param  Frame pointer to first byte in PDU.
  * @param  Length length of data in PDU.
  * @retval Transfered Word.
  */
ModbusException    Modbus_Function_Read_Holding_Register(uint8_t* Frame, uint16_t* Length);

/**
  * @brief  Modbus function 0x06
  * @note   Writes data holding registers.
  * @param  Frame pointer to first byte in PDU.
  * @param  Length length of data in PDU.
  * @retval Transfered Word.
  */
ModbusException    Modbus_Function_Write_Holding_Register(uint8_t* Frame, uint16_t* Length);

/**
  * @brief  Modbus function 0x10
  * @note   Writes multiple data from holding registers.
  * @param  Frame pointer to first byte in PDU.
  * @param  Length length of data in PDU.
  * @retval Transfered Word.
  */
ModbusException    Modbus_Function_Write_Multiple_Holding_Register(uint8_t* Frame, uint16_t* Length);

/**
  * @brief  Modbus function 0x17
  * @note   Writes and reads multiple data from holding registers.
  * @param  Frame pointer to first byte in PDU.
  * @param  Length length of data in PDU.
  * @retval Transfered Word.
  */
ModbusException    Modbus_Function_Read_Write_Multiple_Holding_Register(uint8_t* Frame, uint16_t* Length);

/**
  * @brief  Transfers 2 uint8_t bytes to uint16_t word.
  * @note   Transfers 2 uint8_t bytes to uint16_t word.
  * @param  Frame buffer containing bytes to convert.
  * @param  Address address of first Byte in Frame.
  * @retval Transfered Word.
  */
uint16_t Modbus_Byte_to_Word(uint8_t * Frame, uint16_t Address);


#endif /* MODBUS_FUNCTIONS_H_ */
