1 /* Copyright 2018 Espressif Systems (Shanghai) PTE LTD
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef _ESP_MB_MASTER_INTERFACE_H
17 #define _ESP_MB_MASTER_INTERFACE_H
18 
19 #include <stdint.h>                 // for standard int types definition
20 #include <stddef.h>                 // for NULL and std defines
21 #include "soc/soc.h"                // for BITN definitions
22 #include "esp_modbus_common.h"      // for common types
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 #define MB_MASTER_CHECK(a, err_code, format, ...) MB_RETURN_ON_FALSE(a, err_code, TAG, format __VA_OPT__(,) __VA_ARGS__)
29 
30 #define MB_MASTER_ASSERT(con) do { \
31         if (!(con)) { ESP_LOGE(TAG, "assert errno:%d, errno_str: !(%s)", errno, strerror(errno)); assert(0 && #con); } \
32     } while (0)
33 
34 /*!
35  * \brief Modbus descriptor table parameter type defines.
36  */
37 typedef enum {
38     PARAM_TYPE_U8 = 0x00,                   /*!< Unsigned 8 */
39     PARAM_TYPE_U16 = 0x01,                  /*!< Unsigned 16 */
40     PARAM_TYPE_U32 = 0x02,                  /*!< Unsigned 32 */
41     PARAM_TYPE_FLOAT = 0x03,                /*!< Float type */
42     PARAM_TYPE_ASCII = 0x04                 /*!< ASCII type */
43 } mb_descr_type_t;
44 
45 /*!
46  * \brief Modbus descriptor table parameter size in bytes.
47  */
48 typedef enum {
49     PARAM_SIZE_U8 = 0x01,                   /*!< Unsigned 8 */
50     PARAM_SIZE_U16 = 0x02,                  /*!< Unsigned 16 */
51     PARAM_SIZE_U32 = 0x04,                  /*!< Unsigned 32 */
52     PARAM_SIZE_FLOAT = 0x04,                /*!< Float size */
53     PARAM_SIZE_ASCII = 0x08,                /*!< ASCII size */
54     PARAM_SIZE_ASCII24 = 0x18,              /*!< ASCII24 size */
55     PARAM_MAX_SIZE
56 } mb_descr_size_t;
57 
58 /*!
59  * \brief Modbus parameter options for description table
60  */
61 typedef union {
62     struct {
63         int opt1;                         /*!< Parameter option1 */
64         int opt2;                         /*!< Parameter option2 */
65         int opt3;                         /*!< Parameter option3 */
66     };
67     struct {
68         int min;                          /*!< Parameter minimum value */
69         int max;                          /*!< Parameter maximum value */
70         int step;                         /*!< Step of parameter change tracking */
71     };
72 } mb_parameter_opt_t;
73 
74 /**
75  * @brief Permissions for the characteristics
76  */
77 typedef enum {
78     PAR_PERMS_READ               = 1 << BIT0,                                   /**< the characteristic of the device are readable */
79     PAR_PERMS_WRITE              = 1 << BIT1,                                   /**< the characteristic of the device are writable*/
80     PAR_PERMS_TRIGGER            = 1 << BIT2,                                   /**< the characteristic of the device are triggerable */
81     PAR_PERMS_READ_WRITE         = PAR_PERMS_READ | PAR_PERMS_WRITE,            /**< the characteristic of the device are readable & writable */
82     PAR_PERMS_READ_TRIGGER       = PAR_PERMS_READ | PAR_PERMS_TRIGGER,          /**< the characteristic of the device are readable & triggerable */
83     PAR_PERMS_WRITE_TRIGGER      = PAR_PERMS_WRITE | PAR_PERMS_TRIGGER,         /**< the characteristic of the device are writable & triggerable */
84     PAR_PERMS_READ_WRITE_TRIGGER = PAR_PERMS_READ_WRITE | PAR_PERMS_TRIGGER,    /**< the characteristic of the device are readable & writable & triggerable */
85 } mb_param_perms_t;
86 
87 /**
88  * @brief Characteristics descriptor type is used to describe characteristic and
89  * link it with Modbus parameters that reflect its data.
90  */
91 typedef struct {
92     uint16_t            cid;                /*!< Characteristic cid */
93     const char*         param_key;          /*!< The key (name) of the parameter */
94     const char*         param_units;        /*!< The physical units of the parameter */
95     uint8_t             mb_slave_addr;      /*!< Slave address of device in the Modbus segment */
96     mb_param_type_t     mb_param_type;      /*!< Type of modbus parameter */
97     uint16_t            mb_reg_start;       /*!< This is the Modbus register address. This is the 0 based value. */
98     uint16_t            mb_size;            /*!< Size of mb parameter in registers */
99     uint16_t            param_offset;       /*!< Parameter name (OFFSET in the parameter structure) */
100     mb_descr_type_t     param_type;         /*!< Float, U8, U16, U32, ASCII, etc. */
101     mb_descr_size_t     param_size;         /*!< Number of bytes in the parameter. */
102     mb_parameter_opt_t  param_opts;         /*!< Parameter options used to check limits and etc. */
103     mb_param_perms_t    access;             /*!< Access permissions based on mode */
104 } mb_parameter_descriptor_t;
105 
106 /**
107  * @brief Modbus register request type structure
108  */
109 typedef struct {
110     uint8_t slave_addr;             /*!< Modbus slave address */
111     uint8_t command;                /*!< Modbus command to send */
112     uint16_t reg_start;             /*!< Modbus start register */
113     uint16_t reg_size;              /*!< Modbus number of registers */
114 } mb_param_request_t;
115 
116 /**
117  * @brief Initialize Modbus controller and stack for TCP port
118  *
119  * @param[out] handler handler(pointer) to master data structure
120  * @return
121  *     - ESP_OK                 Success
122  *     - ESP_ERR_NO_MEM         Parameter error
123  *     - ESP_ERR_NOT_SUPPORTED  Port type not supported
124  *     - ESP_ERR_INVALID_STATE  Initialization failure
125  */
126 esp_err_t mbc_master_init_tcp(void** handler);
127 
128 /**
129  * @brief Initialize Modbus Master controller and stack for Serial port
130  *
131  * @param[out] handler handler(pointer) to master data structure
132  * @param[in] port_type type of stack
133  * @return
134  *     - ESP_OK                 Success
135  *     - ESP_ERR_NO_MEM         Parameter error
136  *     - ESP_ERR_NOT_SUPPORTED  Port type not supported
137  *     - ESP_ERR_INVALID_STATE  Initialization failure
138  */
139 esp_err_t mbc_master_init(mb_port_type_t port_type, void** handler);
140 
141 /**
142  * @brief Initialize Modbus Master controller interface handle
143  *
144  * @param[in] handler - pointer to master data structure
145  */
146 void mbc_master_init_iface(void* handler);
147 
148 /**
149  * @brief Destroy Modbus controller and stack
150  *
151  * @return
152  *     - ESP_OK   Success
153  *     - ESP_ERR_INVALID_STATE Parameter error
154  */
155 esp_err_t mbc_master_destroy(void);
156 
157 /**
158  * @brief Start Modbus communication stack
159  *
160  * @return
161  *     - ESP_OK   Success
162  *     - ESP_ERR_INVALID_ARG Modbus stack start error
163  */
164 esp_err_t mbc_master_start(void);
165 
166 /**
167  * @brief Set Modbus communication parameters for the controller
168  *
169  * @param comm_info Communication parameters structure.
170  *
171  * @return
172  *     - ESP_OK Success
173  *     - ESP_ERR_INVALID_ARG Incorrect parameter data
174  */
175 esp_err_t mbc_master_setup(void* comm_info);
176 
177 /***************************** Specific interface functions ********************************************
178  * Interface functions below provide basic methods to read/write access to slave devices in Modbus
179  * segment as well as API to read specific supported characteristics linked to Modbus parameters
180  * of devices in Modbus network.
181 *******************************************************************************************************/
182 
183 /**
184  * @brief Assign parameter description table for Modbus controller interface.
185  *
186  * @param[in] descriptor pointer to parameter description table
187  * @param num_elements number of elements in the table
188  *
189  * @return
190  *     - esp_err_t ESP_OK - set descriptor successfully
191  *     - esp_err_t ESP_ERR_INVALID_ARG - invalid argument in function call
192  */
193 esp_err_t mbc_master_set_descriptor(const mb_parameter_descriptor_t* descriptor, const uint16_t num_elements);
194 
195 /**
196  * @brief Send data request as defined in parameter request, waits response
197  *        from slave and returns status of command execution. This function provides standard way
198  *        for read/write access to Modbus devices in the network.
199  *
200  * @param[in] request pointer to request structure of type mb_param_request_t
201  * @param[in] data_ptr pointer to data buffer to send or received data (dependent of command field in request)
202  *
203  * @return
204  *     - esp_err_t ESP_OK - request was successful
205  *     - esp_err_t ESP_ERR_INVALID_ARG - invalid argument of function
206  *     - esp_err_t ESP_ERR_INVALID_RESPONSE - an invalid response from slave
207  *     - esp_err_t ESP_ERR_TIMEOUT - operation timeout or no response from slave
208  *     - esp_err_t ESP_ERR_NOT_SUPPORTED - the request command is not supported by slave
209  *     - esp_err_t ESP_FAIL - slave returned an exception or other failure
210  */
211 esp_err_t mbc_master_send_request(mb_param_request_t* request, void* data_ptr);
212 
213 /**
214  * @brief Get information about supported characteristic defined as cid. Uses parameter description table to get
215  *        this information. The function will check if characteristic defined as a cid parameter is supported
216  *        and returns its description in param_info. Returns ESP_ERR_NOT_FOUND if characteristic is not supported.
217  *
218  * @param[in] cid characteristic id
219  * @param param_info pointer to pointer of characteristic data.
220  *
221  * @return
222  *     - esp_err_t ESP_OK - request was successful and buffer contains the supported characteristic name
223  *     - esp_err_t ESP_ERR_INVALID_ARG - invalid argument of function
224  *     - esp_err_t ESP_ERR_NOT_FOUND - the characteristic (cid) not found
225  *     - esp_err_t ESP_FAIL - unknown error during lookup table processing
226 */
227 esp_err_t mbc_master_get_cid_info(uint16_t cid, const mb_parameter_descriptor_t** param_info);
228 
229 /**
230  * @brief Read parameter from modbus slave device whose name is defined by name and has cid.
231  *        The additional data for request is taken from parameter description (lookup) table.
232  *
233  * @param[in] cid id of the characteristic for parameter
234  * @param[in] name pointer into string name (key) of parameter (null terminated)
235  * @param[out] value pointer to data buffer of parameter
236  * @param[out] type parameter type associated with the name returned from parameter description table.
237  *
238  * @return
239  *     - esp_err_t ESP_OK - request was successful and value buffer contains
240  *                          representation of actual parameter data from slave
241  *     - esp_err_t ESP_ERR_INVALID_ARG - invalid argument of function or parameter descriptor
242  *     - esp_err_t ESP_ERR_INVALID_RESPONSE - an invalid response from slave
243  *     - esp_err_t ESP_ERR_INVALID_STATE - invalid state during data processing or allocation failure
244  *     - esp_err_t ESP_ERR_TIMEOUT - operation timed out and no response from slave
245  *     - esp_err_t ESP_ERR_NOT_SUPPORTED - the request command is not supported by slave
246  *     - esp_err_t ESP_ERR_NOT_FOUND - the parameter is not found in the parameter description table
247  *     - esp_err_t ESP_FAIL - slave returned an exception or other failure
248 */
249 esp_err_t mbc_master_get_parameter(uint16_t cid, char* name, uint8_t* value, uint8_t *type);
250 
251 /**
252  * @brief Set characteristic's value defined as a name and cid parameter.
253  *        The additional data for cid parameter request is taken from master parameter lookup table.
254  *
255  * @param[in] cid id of the characteristic for parameter
256  * @param[in] name pointer into string name (key) of parameter (null terminated)
257  * @param[out] value pointer to data buffer of parameter (actual representation of json value field in binary form)
258  * @param[out] type pointer to parameter type associated with the name returned from parameter lookup table.
259  *
260  * @return
261  *     - esp_err_t ESP_OK - request was successful and value was saved in the slave device registers
262  *     - esp_err_t ESP_ERR_INVALID_ARG - invalid argument of function or parameter descriptor
263  *     - esp_err_t ESP_ERR_INVALID_RESPONSE - an invalid response from slave during processing of parameter
264  *     - esp_err_t ESP_ERR_INVALID_STATE - invalid state during data processing or allocation failure
265  *     - esp_err_t ESP_ERR_TIMEOUT - operation timed out and no response from slave
266  *     - esp_err_t ESP_ERR_NOT_SUPPORTED - the request command is not supported by slave
267  *     - esp_err_t ESP_FAIL - slave returned an exception or other failure
268 */
269 esp_err_t mbc_master_set_parameter(uint16_t cid, char* name, uint8_t* value, uint8_t *type);
270 
271 #ifdef __cplusplus
272 }
273 #endif
274 
275 #endif // _ESP_MB_MASTER_INTERFACE_H
276