/** * Modbus slave */ #ifndef MODBUS_H #define MODBUS_H #include #include #include // Config - TODO do this via cmake #define MB_SUPPORT_FC01 // READ_COILS #define MB_SUPPORT_FC02 // READ_DISCRETES #define MB_SUPPORT_FC03 // READ_HOLDING_REGISTERS #define MB_SUPPORT_FC04 // READ_INPUT_REGISTERS #define MB_SUPPORT_FC05 // WRITE_SINGLE_COIL #define MB_SUPPORT_FC06 // WRITE_SINGLE_REGISTER #define MB_SUPPORT_FC15 // WRITE_MULTIPLE_COILS #define MB_SUPPORT_FC16 // WRITE_MULTIPLE_REGISTERS #define MB_SUPPORT_FC22 // MASK_WRITE_REGISTER #define MB_SUPPORT_FC23 // READ_WRITE_MULTIPLE_REGISTERS typedef enum ModbusException { MB_EXCEPTION_OK = 0, MB_EXCEPTION_ILLEGAL_FUNCTION = 1, MB_EXCEPTION_ILLEGAL_DATA_ADDRESS = 2, MB_EXCEPTION_ILLEGAL_DATA_VALUE = 3, MB_EXCEPTION_SLAVE_DEVICE_FAILURE = 4, // other codes exist but are not meaningful for simple slave devices } ModbusException_t; typedef enum ModbusFunction { FC01_READ_COILS = 1, FC02_READ_DISCRETES = 2, FC03_READ_HOLDING_REGISTERS = 3, FC04_READ_INPUT_REGISTERS = 4, FC05_WRITE_SINGLE_COIL = 5, FC06_WRITE_SINGLE_REGISTER = 6, FC15_WRITE_MULTIPLE_COILS = 15, FC16_WRITE_MULTIPLE_REGISTERS = 16, FC22_MASK_WRITE_REGISTER = 22, FC23_READ_WRITE_MULTIPLE_REGISTERS = 23, } ModbusFunction_t; typedef enum ModbusError { MB_OK = 0, MB_ERROR = 1, MB_ERR_NOTFORME = 2, MB_ERR_NEEDMORE = 3, MB_ERR_CHECKSUM = 4, MB_ERR_BADPROTO = 5, } ModbusError_t; typedef enum ModbusProtocol { MB_PROTO_RTU, MB_PROTO_TCP } ModbusProtocol_t; typedef struct ModbusSlave ModbusSlave_t; struct ModbusSlave { uint8_t addr; ModbusProtocol_t proto; void *userData; ModbusException_t (*startOfAccess)(ModbusSlave_t *ms, ModbusFunction_t fcx, uint8_t slave_id); void (*endOfAccess)(ModbusSlave_t *ms); #ifdef MB_SUPPORT_FC01 ModbusException_t (*readCoil)(ModbusSlave_t *ms, uint16_t reference, bool *value); #endif #ifdef MB_SUPPORT_FC02 ModbusException_t (*readDiscrete)(ModbusSlave_t *ms, uint16_t reference, bool *value); #endif #if defined(MB_SUPPORT_FC03) || defined(MB_SUPPORT_FC22) || defined(MB_SUPPORT_FC23) ModbusException_t (*readHolding)(ModbusSlave_t *ms, uint16_t reference, uint16_t *value); #endif #ifdef MB_SUPPORT_FC04 ModbusException_t (*readInput)(ModbusSlave_t *ms, uint16_t reference, uint16_t *value); #endif #if defined(MB_SUPPORT_FC15) || defined(MB_SUPPORT_FC05) ModbusException_t (*writeCoil)(ModbusSlave_t *ms, uint16_t reference, bool value); #endif #if defined(MB_SUPPORT_FC06) || defined(MB_SUPPORT_FC16) || defined(MB_SUPPORT_FC22) || defined(MB_SUPPORT_FC23) ModbusException_t (*writeHolding)(ModbusSlave_t *ms, uint16_t reference, uint16_t value); #endif }; ModbusError_t mb_handleRequest( ModbusSlave_t *ms, const uint8_t *req, size_t req_size, uint8_t* resp, size_t resp_capacity, size_t *resp_size ); #endif //MODBUS_H