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 _MB_IFACE_COMMON_H
17 #define _MB_IFACE_COMMON_H
18 
19 #include "driver/uart.h"                    // for UART types
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 #if __has_include("esp_check.h")
26 #include "esp_check.h"
27 
28 #define MB_RETURN_ON_FALSE(a, err_code, tag, format, ...) ESP_RETURN_ON_FALSE(a, err_code, tag, format __VA_OPT__(,) __VA_ARGS__)
29 
30 #else
31 
32 // if cannot include esp_check then use custom check macro
33 
34 #define MB_RETURN_ON_FALSE(a, err_code, tag, format, ...) do {                                         \
35         if (!(a)) {                                                                              \
36             ESP_LOGE(tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__);        \
37             return err_code;                                                                               \
38         }                                                                                                  \
39 } while(0)
40 
41 #endif
42 
43 #define MB_CONTROLLER_STACK_SIZE            (CONFIG_FMB_CONTROLLER_STACK_SIZE)   // Stack size for Modbus controller
44 #define MB_CONTROLLER_PRIORITY              (CONFIG_FMB_PORT_TASK_PRIO - 1)    // priority of MB controller task
45 
46 // Default port defines
47 #define MB_DEVICE_ADDRESS   (1)             // Default slave device address in Modbus
48 #define MB_DEVICE_SPEED     (115200)        // Default Modbus speed for now hard defined
49 #define MB_UART_PORT        (UART_NUM_MAX - 1)  // Default UART port number
50 #define MB_PAR_INFO_TOUT    (10)            // Timeout for get parameter info
51 #define MB_PARITY_NONE      (UART_PARITY_DISABLE)
52 
53 // The Macros below handle the endianness while transfer N byte data into buffer
54 #define _XFER_4_RD(dst, src) { \
55     *(uint8_t *)(dst)++ = *(uint8_t*)(src + 1); \
56     *(uint8_t *)(dst)++ = *(uint8_t*)(src + 0); \
57     *(uint8_t *)(dst)++ = *(uint8_t*)(src + 3); \
58     *(uint8_t *)(dst)++ = *(uint8_t*)(src + 2); \
59     (src) += 4; \
60 }
61 
62 #define _XFER_2_RD(dst, src) { \
63     *(uint8_t *)(dst)++ = *(uint8_t *)(src + 1); \
64     *(uint8_t *)(dst)++ = *(uint8_t *)(src + 0); \
65     (src) += 2; \
66 }
67 
68 #define _XFER_4_WR(dst, src) { \
69     *(uint8_t *)(dst + 1) = *(uint8_t *)(src)++; \
70     *(uint8_t *)(dst + 0) = *(uint8_t *)(src)++; \
71     *(uint8_t *)(dst + 3) = *(uint8_t *)(src)++; \
72     *(uint8_t *)(dst + 2) = *(uint8_t *)(src)++ ; \
73 }
74 
75 #define _XFER_2_WR(dst, src) { \
76     *(uint8_t *)(dst + 1) = *(uint8_t *)(src)++; \
77     *(uint8_t *)(dst + 0) = *(uint8_t *)(src)++; \
78 }
79 
80 /**
81  * @brief Types of actual Modbus implementation
82  */
83 typedef enum
84 {
85     MB_PORT_SERIAL_MASTER = 0x00,   /*!< Modbus port type serial master. */
86     MB_PORT_SERIAL_SLAVE,           /*!< Modbus port type serial slave. */
87     MB_PORT_TCP_MASTER,             /*!< Modbus port type TCP master. */
88     MB_PORT_TCP_SLAVE,              /*!< Modbus port type TCP slave. */
89     MB_PORT_COUNT,                  /*!< Modbus port count. */
90     MB_PORT_INACTIVE = 0xFF
91 } mb_port_type_t;
92 
93 /**
94  * @brief Event group for parameters notification
95  */
96 typedef enum
97 {
98     MB_EVENT_NO_EVENTS = 0x00,
99     MB_EVENT_HOLDING_REG_WR = BIT0,         /*!< Modbus Event Write Holding registers. */
100     MB_EVENT_HOLDING_REG_RD = BIT1,         /*!< Modbus Event Read Holding registers. */
101     MB_EVENT_INPUT_REG_RD = BIT3,           /*!< Modbus Event Read Input registers. */
102     MB_EVENT_COILS_WR = BIT4,               /*!< Modbus Event Write Coils. */
103     MB_EVENT_COILS_RD = BIT5,               /*!< Modbus Event Read Coils. */
104     MB_EVENT_DISCRETE_RD = BIT6,            /*!< Modbus Event Read Discrete bits. */
105     MB_EVENT_STACK_STARTED = BIT7           /*!< Modbus Event Stack started */
106 } mb_event_group_t;
107 
108 /**
109  * @brief Type of Modbus parameter
110  */
111 typedef enum {
112     MB_PARAM_HOLDING = 0x00,         /*!< Modbus Holding register. */
113     MB_PARAM_INPUT,                  /*!< Modbus Input register. */
114     MB_PARAM_COIL,                   /*!< Modbus Coils. */
115     MB_PARAM_DISCRETE,               /*!< Modbus Discrete bits. */
116     MB_PARAM_COUNT,
117     MB_PARAM_UNKNOWN = 0xFF
118 } mb_param_type_t;
119 
120 /*!
121  * \brief Modbus serial transmission modes (RTU/ASCII).
122  */
123 typedef enum {
124     MB_MODE_RTU,                     /*!< RTU transmission mode. */
125     MB_MODE_ASCII,                   /*!< ASCII transmission mode. */
126     MB_MODE_TCP,                     /*!< TCP communication mode. */
127     MB_MODE_UDP                      /*!< UDP communication mode. */
128 } mb_mode_type_t;
129 
130 /*!
131  * \brief Modbus TCP type of address.
132  */
133 typedef enum {
134     MB_IPV4 = 0,                     /*!< TCP IPV4 addressing */
135     MB_IPV6 = 1                      /*!< TCP IPV6 addressing */
136 } mb_tcp_addr_type_t;
137 
138 /**
139  * @brief Device communication structure to setup Modbus controller
140  */
141 typedef union {
142     // Serial communication structure
143     struct {
144         mb_mode_type_t mode;                    /*!< Modbus communication mode */
145         uint8_t slave_addr;                     /*!< Modbus slave address field (dummy for master) */
146         uart_port_t port;                       /*!< Modbus communication port (UART) number */
147         uint32_t baudrate;                      /*!< Modbus baudrate */
148         uart_parity_t parity;                   /*!< Modbus UART parity settings */
149         uint16_t dummy_port;                    /*!< Dummy field, unused */
150     };
151     // TCP/UDP communication structure
152     struct {
153         mb_mode_type_t ip_mode;                /*!< Modbus communication mode */
154         uint16_t ip_port;                      /*!< Modbus port */
155         mb_tcp_addr_type_t ip_addr_type;       /*!< Modbus address type */
156         void* ip_addr;                         /*!< Modbus address table for connection */
157         void* ip_netif_ptr;                    /*!< Modbus network interface */
158     };
159 } mb_communication_info_t;
160 
161 /**
162  * common interface method types
163  */
164 typedef esp_err_t (*iface_init)(void**);        /*!< Interface method init */
165 typedef esp_err_t (*iface_destroy)(void);       /*!< Interface method destroy */
166 typedef esp_err_t (*iface_setup)(void*);        /*!< Interface method setup */
167 typedef esp_err_t (*iface_start)(void);         /*!< Interface method start */
168 
169 #ifdef __cplusplus
170 }
171 #endif
172 
173 #endif // _MB_IFACE_COMMON_H
174