1 /**
2  * @file      mbmaster_api.h
3  * @copyright Copyright (C) 2015-2018 Alibaba Group Holding Limited
4  */
5 
6 #ifndef MBMASTER_API_H
7 #define MBMASTER_API_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 #include <stdio.h>
14 #include <string.h>
15 
16 #include "k_api.h"
17 
18 #include "mbmaster_default_config.h"
19 #include "adu.h"
20 #include "auxiliary.h"
21 
22 /**
23  * @addtogroup aos_mbmaster mbmaster
24  * modbus master protocol.
25  *
26  * @{
27  */
28 
29 /* This enum is used to define the parity */
30 typedef enum {
31     MB_PAR_NONE,
32     MB_PAR_ODD,
33     MB_PAR_EVEN
34 } mb_parity_t;
35 
36 /* This enum is used to define the return value */
37 typedef enum mb_status {
38     MB_SUCCESS = 0u,
39     MB_MUTEX_ERROR,
40     MB_INVALID_SLAVE_ADDR,
41     MB_INVALID_PARAM,
42     MB_RESPOND_EXCEPTION,  /**< remote device respond exception */
43     MB_RESPOND_LENGTH_ERR, /**< The length field is not consistent with the data length */
44     MB_RESPOND_FRAME_ERR,  /**< frame is too short or CRC error */
45     MB_RESPOND_TIMEOUT,
46     MB_CANNOT_GET_HANDLER, /**< alloc handler failed. check whether MBMASTER_CONFIG_HANDLER_MAX is set large enough */
47     MB_SLAVE_NO_RESPOND,
48     MB_FRAME_SEND_ERR,
49     MB_SERIAL_INIT_FAILED,
50     MB_SERIAL_UNINIT_FAILED,
51     MB_FUNCTION_CODE_NOT_SUPPORT,
52 } mb_status_t;
53 
54 /* This enum is used to define the modbus mode */
55 typedef enum {
56     MB_RTU,
57     MB_ASCII,
58     MB_TCP
59 } mb_mode_t;
60 
61 /* forward declaration */
62 typedef struct mb_handler mb_handler_t;
63 
64 /* Define the callback function type */
65 typedef mb_status_t (*frame_send_func_t)(mb_handler_t *handler, uint32_t timeout);
66 typedef mb_status_t (*frame_recv_func_t)(mb_handler_t *handler);
67 typedef mb_status_t (*adu_assemble_func_t)(mb_handler_t *handler);
68 typedef mb_status_t (*adu_disassemble_func_t)(mb_handler_t *handler);
69 
70 typedef struct mb_handler {
71     uint8_t used;       /**< The value is 1 when used */
72     uint8_t slave_addr;
73     uint8_t mode;
74 
75     uint8_t  mb_frame_buff[ADU_BUF_MAX_LENGTH]; /**< Buffer used to send and receive frame*/
76     uint8_t  pdu_offset;                        /**< Offset of the pdu on mb_frame_buff[] */
77     uint8_t  pdu_length;                        /**< length of the pdu on mb_frame_buff[] */
78     uint32_t mb_frame_length;                   /**< The length of the whole frame */
79 
80     uint32_t respond_timeout;
81 
82     frame_send_func_t      frame_send;      /**< The callback funciton to send the frame */
83     frame_recv_func_t      frame_recv;      /**< The callback funciton to receive the frame */
84     adu_assemble_func_t    adu_assemble;    /**< The callback funciton to assemble frame at ADU layer */
85     adu_disassemble_func_t adu_disassemble; /**< The callback funciton to disassemble frame at ADU layer */
86 
87     MB_MUTEX_T mb_mutex;
88 
89     void *private;
90 } mb_handler_t;
91 
92 /**
93  * This function will alloc a handler and initializes the port for communication
94  * @param[out]  handler     returns a pointer to the assigned handler
95  * @param[in]   port        port usend to communication
96  * @param[in]   baud_rate   baud rate used by port
97  * @param[in]   parity      parity used by port
98  * @param[in]   timeout     timeout for response
99  * @return  the operation status, MB_SUCCESS is OK, other is error
100  */
101 mb_status_t mbmaster_rtu_init(mb_handler_t **handler, uint8_t port, uint32_t baud_rate, mb_parity_t parity, uint32_t timeout);
102 
103 /**
104  * This function will free the handler and uninitializes the port for communication
105  * @param[in]  req_handler  the handler pointer returned from mbmaster_rtu_init
106  * @return  the operation status, MB_SUCCESS is OK, other is error
107  */
108 mb_status_t mbmaster_rtu_uninit(mb_handler_t *req_handler);
109 
110 /**
111  * This function will initiate a read coils request(function code 0x01)
112  * @param[in]   req_handler    the handler pointer returned from mbmaster_rtu_init
113  * @param[in]   slave_addr     slave address of the remote device
114  * @param[in]   start_addr     starting address
115  * @param[in]   quantity       quantity of coils
116  * @param[out]  respond_buf    data receive from remote device, length must >= (quantity / 8 + 1) bytes
117  * @param[out]  respond_count  the number of bytes of data received
118  * @param[in]   timeout        the timeout time(ms) for sending the request, 0xFFFFFFFF means waiting for ever
119  * @return  the operation status, MB_SUCCESS is OK, other is error
120  * @note  when MB_RESPOND_EXCEPTION is returned, the first byte of respond_buf holds the exception code
121  */
122 mb_status_t mbmaster_read_coils(mb_handler_t *req_handler, uint8_t slave_addr, uint16_t start_addr,
123                                 uint16_t quantity, uint8_t *respond_buf, uint8_t *respond_count,
124                                 uint32_t timeout);
125 
126 /**
127  * This function will initiate a read discrete inputs request(function code 0x02)
128  * @param[in]   req_handler    the handler pointer returned from mbmaster_rtu_init
129  * @param[in]   slave_addr     slave address of the remote device
130  * @param[in]   start_addr     starting address
131  * @param[in]   quantity       quantity of inputs
132  * @param[out]  respond_buf    data receive from remote device, length must >= (quantity / 8 + 1) bytes
133  * @param[out]  respond_count  the number of bytes of data received
134  * @param[in]   timeout        the timeout time(ms) for sending the request, 0xFFFFFFFF means waiting for ever
135  * @return  the operation status, MB_SUCCESS is OK, other is error
136  * @note  when MB_RESPOND_EXCEPTION is returned, the first byte of respond_buf holds the exception code
137  */
138 mb_status_t mbmaster_read_discrete_inputs(mb_handler_t *req_handler, uint8_t slave_addr, uint16_t start_addr,
139                                           uint16_t quantity, uint8_t *respond_buf, uint8_t *respond_count,
140                                           uint32_t timeout);
141 
142 /**
143  * This function will initiate a read holding registers request(function code 0x03)
144  * @param[in]   req_handler    the handler pointer returned from mbmaster_rtu_init
145  * @param[in]   slave_addr     slave address of the remote device
146  * @param[in]   start_addr     starting address
147  * @param[in]   quantity       quantity of registers
148  * @param[out]  respond_buf    data receive from remote device, length must >= (quantity * 2) bytes
149  * @param[out]  respond_count  the number of bytes of data received
150  * @param[in]   timeout        the timeout time(ms) for sending the request, 0xFFFFFFFF means waiting for ever
151  * @return  the operation status, MB_SUCCESS is OK, other is error
152  * @note    when MB_RESPOND_EXCEPTION is returned, the first byte of respond_buf holds the exception code
153  */
154 mb_status_t mbmaster_read_holding_registers(mb_handler_t *req_handler, uint8_t slave_addr,
155                                            uint16_t start_addr, uint16_t quantity,
156                                            uint8_t *respond_buf, uint8_t *respond_count, uint32_t timeout);
157 
158 /**
159  * This function will initiate a read input registers request(function code 0x04)
160  * @param[in]   req_handler    the handler pointer returned from mbmaster_rtu_init
161  * @param[in]   slave_addr     slave address of the remote device
162  * @param[in]   start_addr     starting address
163  * @param[in]   quantity       quantity of input registers
164  * @param[out]  respond_buf    data receive from remote device, length must >= (quantity * 2) bytes
165  * @param[out]  respond_count  the number of bytes of data received
166  * @param[in]   timeout        the timeout time(ms) for sending the request, 0xFFFFFFFF means waiting for ever
167  * @return  the operation status, MB_SUCCESS is OK, other is error
168  * @note    when MB_RESPOND_EXCEPTION is returned, the first byte of respond_buf holds the exception code
169  */
170 mb_status_t mbmaster_read_input_registers(mb_handler_t *req_handler, uint8_t slave_addr,
171                                          uint16_t start_addr, uint16_t quantity,
172                                          uint8_t *respond_buf, uint8_t *respond_count, uint32_t timeout);
173 
174 /**
175  * This function will initiate a write single coil request(function code 0x05)
176  * @param[in]   req_handler     the handler pointer returned from mbmaster_rtu_init
177  * @param[in]   slave_addr      slave address of the remote device
178  * @param[in]   register_addr   coil address
179  * @param[in]   register_value  coil value, 0x0000 for off, 0xFF00 for on
180  * @param[out]  resp_addr       coil address responded from remote device
181  * @param[out]  resp_value      coil value responded from remote device
182  * @param[out]  excepiton_code  exception code, when MB_RESPOND_EXCEPTION is returned
183  * @param[in]   timeout        the timeout time(ms) for sending the request, 0xFFFFFFFF means waiting for ever
184  * @return  the operation status, MB_SUCCESS is OK, other is error
185  */
186 mb_status_t mbmaster_write_single_coil(mb_handler_t *req_handler, uint8_t slave_addr, uint16_t coil_addr,
187                                        uint16_t coil_value, uint16_t *resp_addr, uint16_t *resp_value,
188                                        uint8_t *exception_code, uint32_t timeout);
189 
190 /**
191  * This function will initiate a write single register request(function code 0x06)
192  * @param[in]   req_handler     the handler pointer returned from mbmaster_rtu_init
193  * @param[in]   slave_addr      slave address of the remote device
194  * @param[in]   register_addr   register address
195  * @param[in]   register_value  regitter value
196  * @param[out]  resp_addr       register address responded from remote device
197  * @param[out]  resp_value      register value responded from remote device
198  * @param[out]  excepiton_code  exception code, when MB_RESPOND_EXCEPTION is returned
199  * @param[in]   timeout        the timeout time(ms) for sending the request, 0xFFFFFFFF means waiting for ever
200  * @return  the operation status, MB_SUCCESS is OK, other is error
201  */
202 mb_status_t mbmaster_write_single_register(mb_handler_t *req_handler, uint8_t slave_addr, uint16_t register_addr,
203                                            uint16_t register_value, uint16_t *resp_addr, uint16_t *resp_value,
204                                            uint8_t *exception_code, uint32_t timeout);
205 
206 /**
207  * This function will initiate a write mutiple coils request(function code 0x0F)
208  * @param[in]   req_handler     the handler pointer returned from mbmaster_rtu_init
209  * @param[in]   slave_addr      slave address of the remote device
210  * @param[in]   start_addr      start address
211  * @param[in]   quantity        quantity of outputs
212  * @param[in]   outputs_buf     outputs value(bit array, 0 to be OFF. 1 to be ON)
213  * @param[out]  resp_addr       start address responded from remote device
214  * @param[out]  resp_quantity   quantity responded from remote device
215  * @param[out]  excepiton_code  exception code, when MB_RESPOND_EXCEPTION is returned
216  * @param[in]   timeout        the timeout time(ms) for sending the request, 0xFFFFFFFF means waiting for ever
217  * @return  the operation status, MB_SUCCESS is OK, other is error
218  */
219 mb_status_t mbmaster_write_multiple_coils(mb_handler_t *req_handler, uint8_t slave_addr, uint16_t start_addr,
220                                           uint16_t quantity, uint8_t *outputs_buf, uint16_t *resp_addr,
221                                           uint16_t *resp_quantity, uint8_t *exception_code, uint32_t timeout);
222 /**
223  * This function will initiate a write mutiple registers request(function code 0x10)
224  * @param[in]   req_handler     the handler pointer returned from mbmaster_rtu_init
225  * @param[in]   slave_addr      slave address of the remote device
226  * @param[in]   start_addr      start address
227  * @param[in]   quantity        quantity of registers
228  * @param[in]   outputs_buf     registers value
229  * @param[out]  resp_addr       start address responded from remote device
230  * @param[out]  resp_quantity   registers quantity responded from remote device
231  * @param[out]  excepiton_code  exception code, when MB_RESPOND_EXCEPTION is returned
232  * @param[in]   timeout        the timeout time(ms) for sending the request, 0xFFFFFFFF means waiting for ever
233  * @return  the operation status, MB_SUCCESS is OK, other is error
234  */
235 mb_status_t mbmaster_write_multiple_registers(mb_handler_t *req_handler, uint8_t slave_addr, uint16_t start_addr,
236                                               uint16_t quantity, uint8_t *outputs_buf, uint16_t *resp_addr,
237                                               uint16_t *resp_quantity, uint8_t *exception_code, uint32_t timeout);
238 /** @} */
239 
240 #ifdef __cplusplus
241 }
242 #endif
243 
244 #endif /* MBMASTER_API_H */
245 
246