/*! \file gfambrtuslv.h \brief Header file of the \b gfambrtuslv library. */ #if !defined(AGD_MBRTUSLV_H__84F27BE0_71CA_4910_8631_B0EEA21DC84A__INCLUDED_) #define AGD_MBRTUSLV_H__84F27BE0_71CA_4910_8631_B0EEA21DC84A__INCLUDED_ #include #include #ifdef __cplusplus extern "C" { #endif // __cplusplus ///////////////////////////////////////////////////////////////////////////// // gfambrtuslv.h - Declarations: /*! \typedef HMBRTUSLV \brief Defines a Handle to a Modbus RTU Slave. */ typedef void *HMBRTUSLV; ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // Modbus Slave /*! \typedef GFA_MODBUS_RTU_SLV_STATES \brief Defines the Slave's states used in the state machine. \verbatim typedef enum _GFA_MODBUS_RTU_SLV_STATES { MB_RTU_SLV_Void = -1, MB_RTU_SLV_Idle, MB_RTU_SLV_RxSlvID, MB_RTU_SLV_RxFunc, MB_RTU_SLV_RxDataInfo, MB_RTU_SLV_RxDataPayload, MB_RTU_SLV_RxCRC, MB_RTU_SLV_RxComplete, MB_RTU_SLV_TxStart, MB_RTU_SLV_TxWaitEnd }GFA_MODBUS_RTU_SLV_STATES; \endverbatim */ typedef enum _GFA_MODBUS_RTU_SLV_STATES { MB_RTU_SLV_Void = -1, MB_RTU_SLV_Idle, MB_RTU_SLV_RxSlvID, MB_RTU_SLV_RxFunc, MB_RTU_SLV_RxDataInfo, MB_RTU_SLV_RxDataPayload, MB_RTU_SLV_RxCRC, MB_RTU_SLV_RxComplete, MB_RTU_SLV_TxStart, MB_RTU_SLV_TxWaitEnd }GFA_MODBUS_RTU_SLV_STATES; ///////////////////////////////////////////////////////////////////////////// /*! \typedef typedef void (*PFN_GFA_SLAVE_PRE_READ_REGISTERS)(uint8_t func, uint16_t start, uint16_t count) \brief Defines the pointer to a callback function, that is called before the slave attempts to read from registers. \param func The modbus function code. \param start The physical start address of the registers to be read. \param count The number of registers to be read. */ typedef void (*PFN_GFA_SLAVE_PRE_READ_REGISTERS) (uint8_t func, uint16_t start, uint16_t count); /*! \typedef typedef void (*PFN_GFA_SLAVE_POST_READ_REGISTERS)(uint8_t func, uint16_t start, uint16_t count) \brief Defines the pointer to a callback function, that is called after the slave has read read from registers. \param func The modbus function code. \param start The physical start address of the registers to be read. \param count The number of registers to be read. */ typedef void (*PFN_GFA_SLAVE_POST_READ_REGISTERS) (uint8_t func, uint16_t start, uint16_t count); /*! \typedef typedef void (*PFN_GFA_SLAVE_PRE_WRITE_REGISTERS)(uint8_t func, uint16_t start, uint16_t count) \brief Defines the pointer to a callback function, that is called before the slave attempts to write to registers. \param func The modbus function code. \param start The physical start address of the registers to be written to. \param count The number of registers to be written to. */ typedef void (*PFN_GFA_SLAVE_PRE_WRITE_REGISTERS) (uint8_t func, uint16_t start, uint16_t count); /*! \typedef typedef void (*PFN_POST_WRITE_REGISTERS)(uint8_t func, uint16_t start, uint16_t count) \brief Defines the pointer to a callback function, that is called after the slave has written to registers. \param func The modbus function code. \param start The physical start address of the registers to be written to. \param count The number of registers to be written to. */ typedef void (*PFN_POST_WRITE_REGISTERS) (uint8_t func, uint16_t start, uint16_t count); /*! \typedef typedef void (*PFN_GFA_SLAVE_PRE_TRANSMIT)(LPMODBUS_RTU_ADU padu) \brief Defines the pointer to a callback function, that is called before the slave sends the response to a previous request. \param padu A pointer to a MODBUS_RTU_ADU (Application Data Unit) structure to be sent. MODBUS_RTU_ADU is defined in \b gfambrtucom.h. */ typedef void (*PFN_GFA_SLAVE_PRE_TRANSMIT) (LPMODBUS_RTU_ADU padu); /*! \typedef typedef void (*PFN_GFA_SLAVE_POST_TRANSMIT)(LPMODBUS_RTU_ADU padu) \brief Defines the pointer to a callback function, that is called after the slave has sent the response to a previous request. \param padu A pointer to a MODBUS_RTU_ADU (Application Data Unit) structure that has been sent. MODBUS_RTU_ADU is defined in \b gfambrtucom.h. */ typedef void (*PFN_GFA_SLAVE_POST_TRANSMIT) (LPMODBUS_RTU_ADU padu); /*! \typedef typedef uint16_t (*PFN_GFA_SLAVE_MAP_REG_ADDR)(uint16_t addr) \brief Defines the pointer to a callback function, that is called to map a modbus register address to a physical register address (index). If not implemented, the modbus address is interpreted as physical address \param addr Modbus address to be mapped. \return The mapped physical address. */ typedef uint16_t (*PFN_GFA_SLAVE_MAP_REG_ADDR) (uint16_t addr); /*! \typedef typedef void (*PFN_GFA_SLAVE_STATE_CHANGED)(GFA_MODBUS_RTU_SLV_STATES newState, GFA_MODBUS_RTU_SLV_STATES oldState) \brief Defines the pointer to a callback function, that is called after the slave's state has changed. \param newState The new state of the slave. \param oldState The previous state of the slave. */ typedef void (*PFN_GFA_SLAVE_STATE_CHANGED) (GFA_MODBUS_RTU_SLV_STATES newState, GFA_MODBUS_RTU_SLV_STATES oldState); ///////////////////////////////////////////////////////////////////////////// /*! \typedef GFA_MODBUS_REGISTER \brief Struct that holds information about the slave's registers. \verbatim typedef struct _GFA_MODBUS_REGISTER { volatile uint16_t *pRegs; // pointer to an array of registers size_t nCountRegs; // number of registers }GFA_MODBUS_REGISTER, *LPGFA_MODBUS_REGISTER; typedef const GFA_MODBUS_REGISTER *LPCGFA_MODBUS_REGISTER; \endverbatim */ typedef struct _GFA_MODBUS_REGISTER { volatile uint16_t *pRegs; size_t nCountRegs; }GFA_MODBUS_REGISTER, *LPGFA_MODBUS_REGISTER; typedef const GFA_MODBUS_REGISTER *LPCGFA_MODBUS_REGISTER; ///////////////////////////////////////////////////////////////////////////// /*! \typedef GFA_MODBUS_SLAVE_APP_INTERFACE \brief Defines a set of functions to interact with a Modbus application. Any of these function pointers may be NULL, if not needed. \verbatim typedef struct _GFA_MODBUS_SLAVE_APP_INTERFACE { PFN_GFA_SLAVE_MAP_REG_ADDR pfnMapRegAddr; // maps a modbus register address to a hardware address. PFN_GFA_SLAVE_PRE_READ_REGISTERS pfnPreRead; // called before the slave attempts to read from registers PFN_GFA_SLAVE_POST_READ_REGISTERS pfnPostRead; // called after the slave has read from registers PFN_GFA_SLAVE_PRE_WRITE_REGISTERS pfnPreWrite; // called before the slave attempts to write to registers PFN_POST_WRITE_REGISTERS pfnPostWrite; // called after the slave has written to registers PFN_GFA_SLAVE_PRE_TRANSMIT pfnPreTransmit; // called before the slave sends the response to a request PFN_GFA_SLAVE_POST_TRANSMIT pfnPostTransmit; // called after the slave has sent the response to a request PFN_GFA_SLAVE_STATE_CHANGED pfnStateChanged; // called if the slave's state has changed }GFA_MODBUS_SLAVE_APP_INTERFACE, *LPGFA_MODBUS_SLAVE_APP_INTERFACE; typedef const GFA_MODBUS_SLAVE_APP_INTERFACE *LPCGFA_MODBUS_SLAVE_APP_INTERFACE; \endverbatim */ typedef struct _GFA_MODBUS_SLAVE_APP_INTERFACE { PFN_GFA_SLAVE_MAP_REG_ADDR pfnMapRegAddr; PFN_GFA_SLAVE_PRE_READ_REGISTERS pfnPreRead; PFN_GFA_SLAVE_POST_READ_REGISTERS pfnPostRead; PFN_GFA_SLAVE_PRE_WRITE_REGISTERS pfnPreWrite; PFN_POST_WRITE_REGISTERS pfnPostWrite; PFN_GFA_SLAVE_PRE_TRANSMIT pfnPreTransmit; PFN_GFA_SLAVE_POST_TRANSMIT pfnPostTransmit; PFN_GFA_SLAVE_STATE_CHANGED pfnStateChanged; }GFA_MODBUS_SLAVE_APP_INTERFACE, *LPGFA_MODBUS_SLAVE_APP_INTERFACE; typedef const GFA_MODBUS_SLAVE_APP_INTERFACE *LPCGFA_MODBUS_SLAVE_APP_INTERFACE; ///////////////////////////////////////////////////////////////////////////// /*! \typedef GFA_MODBUS_RTU_SLAVE_PARAMETERS \brief Used to create a Modbus RTU Slave \verbatim typedef struct _GFA_MODBUS_RTU_SLAVE_PARAMETERS { uint8_t slaveID; // the slave id HFIFO hFifoRX; // handle to the receive fifo buffer HFIFO hFifoTX; // handle to the transmit fifo buffer GFA_MODBUS_REGISTER regMap; // register information GFA_MODBUS_SLAVE_APP_INTERFACE appItf; // app interface }GFA_MODBUS_RTU_SLAVE_PARAMETERS, *LPGFA_MODBUS_RTU_SLAVE_PARAMETERS; typedef const GFA_MODBUS_RTU_SLAVE_PARAMETERS *LPCGFA_MODBUS_RTU_SLAVE_PARAMETERS; \endverbatim */ typedef struct _GFA_MODBUS_RTU_SLAVE_PARAMETERS { uint8_t slaveID; HFIFO hFifoRX; HFIFO hFifoTX; GFA_MODBUS_REGISTER regMap; GFA_MODBUS_SLAVE_APP_INTERFACE appItf; }GFA_MODBUS_RTU_SLAVE_PARAMETERS, *LPGFA_MODBUS_RTU_SLAVE_PARAMETERS; typedef const GFA_MODBUS_RTU_SLAVE_PARAMETERS *LPCGFA_MODBUS_RTU_SLAVE_PARAMETERS; ///////////////////////////////////////////////////////////////////////////// /*! \fn HMBRTUSLV GfaModbusRTUSlvCreate(LPCGFA_MODBUS_RTU_SLAVE_PARAMETERS pslp) \brief Creates and initializes a Modbus RTU Slave. \param pslp A const pointer to a \ref GFA_MODBUS_RTU_SLAVE_PARAMETERS structure. \return If successful, returns a handle to the newly created slave, or NULL in the case of an error. */ HMBRTUSLV GfaModbusRTUSlvCreate(LPCGFA_MODBUS_RTU_SLAVE_PARAMETERS pslp); /*! \fn void GfaModbusRTUSlvRelease(HMBRTUSLV hMbSlv) \brief Releases a modbus slave, that was previously created with \ref GfaModbusRTUSlvCreate. \param hMbSlv Handle to the modbus slave that has been acquired by a call to \ref GfaModbusRTUSlvCreate. */ void GfaModbusRTUSlvRelease(HMBRTUSLV hMbSlv); /*! \fn bool GfaModbusRTUSlvStateMachine(HMBRTUSLV hMbSlv) \brief The modbus slave's state machine. This function is the heart beat of the slave and must be called repeatedly. \param hMbSlv Handle to the modbus slave that has been acquired by a call to \ref GfaModbusRTUSlvCreate. \return \b true if successful, or \b false only if hMbSlv is NULL or an invalid state was detected. */ bool GfaModbusRTUSlvStateMachine(HMBRTUSLV hMbSlv); /*! \fn bool GfaModbusRTUSlvSetID(HMBRTUSLV hMbSlv, uint8_t newID) \brief Assigns the slave a new slave id. \param hMbSlv Handle to the modbus slave that has been acquired by a call to \ref GfaModbusRTUSlvCreate. \param newID The new Slave ID. \return \b true if successful, or \b false if \b hMbSlv is \b NULL or \b newID is not a valid slave id. \note A new slave id can be assigned at any time, however, the changes take effect only when the slave is in idle state (between two requests)! */ bool GfaModbusRTUSlvSetID(HMBRTUSLV hMbSlv, uint8_t newID); ///////////////////////////////////////////////////////////////////////////// #ifdef __cplusplus } #endif // __cplusplus #endif // !defined(AGD_MBRTUSLV_H__84F27BE0_71CA_4910_8631_B0EEA21DC84A__INCLUDED_)