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