msousa@0: /*
msousa@0: * Copyright (c) 2001-2003,2016 Mario de Sousa (msousa@fe.up.pt)
msousa@0: *
msousa@0: * This file is part of the Modbus library for Beremiz and matiec.
msousa@0: *
msousa@0: * This Modbus library is free software: you can redistribute it and/or modify
msousa@0: * it under the terms of the GNU Lesser General Public License as published by
msousa@0: * the Free Software Foundation, either version 3 of the License, or
msousa@0: * (at your option) any later version.
msousa@0: *
msousa@0: * This program is distributed in the hope that it will be useful, but
msousa@0: * WITHOUT ANY WARRANTY; without even the implied warranty of
msousa@0: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
msousa@0: * General Public License for more details.
msousa@0: *
msousa@0: * You should have received a copy of the GNU Lesser General Public License
msousa@0: * along with this Modbus library. If not, see .
msousa@0: *
msousa@0: * This code is made available on the understanding that it will not be
msousa@0: * used in safety-critical situations without a full and competent review.
msousa@0: */
msousa@0:
msousa@0:
msousa@0: /* mb_master.h */
msousa@0:
msousa@0:
msousa@0: #ifndef MODBUS_MASTER_H
msousa@0: #define MODBUS_MASTER_H
msousa@0:
msousa@0: #include /* struct timespec data structure */
msousa@0:
msousa@0: #include "mb_types.h" /* get the data types */
msousa@0: #include "mb_addr.h" /* get definition of common variable types and error codes */
msousa@0:
msousa@0:
msousa@0:
msousa@0: /***********************************************************************
msousa@0:
msousa@0: Note: All functions used for sending or receiving data via
msousa@0: modbus return these return values.
msousa@0:
msousa@0:
msousa@0: Returns: string_length if OK
msousa@0: -1 on internal error or port failure
msousa@0: -2 on timeout
msousa@0: -3 if a valid yet un-expected frame is received!
msousa@0: -4 for modbus exception errors
msousa@0: (in this case exception code is returned in *error_code)
msousa@0:
msousa@0: ***********************************************************************/
msousa@0:
msousa@0:
msousa@0: /* FUNCTION 0x01 - Read Coils
msousa@0: * Bits are stored on an int array, one bit per int.
msousa@0: */
andrej@1: int read_output_bits(u8 slave,
andrej@1: u16 start_addr,
andrej@1: u16 count,
andrej@1: u16 *dest,
andrej@1: int dest_size,
andrej@1: int fd,
andrej@1: int send_retries,
andrej@1: u8 *error_code,
andrej@1: const struct timespec *response_timeout,
andrej@1: pthread_mutex_t *data_access_mutex);
msousa@0: #define read_coils(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) \
msousa@0: read_output_bits(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10)
msousa@0:
msousa@0:
msousa@0: /* FUNCTION 0x01 - Read Coils
msousa@0: * Bits are stored on an u32 array, 32 bits per u32.
msousa@0: * Unused bits in last u32 are set to 0.
msousa@0: */
andrej@1: int read_output_bits_u32(u8 slave,
andrej@1: u16 start_addr,
andrej@1: u16 count,
andrej@1: u32 *dest,
andrej@1: int fd,
andrej@1: int send_retries,
andrej@1: u8 *error_code,
andrej@1: const struct timespec *response_timeout);
msousa@0: #define read_coils_u32(p1,p2,p3,p4,p5,p6,p7,p8) \
msousa@0: read_output_bits_u32(p1,p2,p3,p4,p5,p6,p7,p8)
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0: /* FUNCTION 0x02 - Read Discrete Inputs
msousa@0: * Bits are stored on an int array, one bit per int.
msousa@0: */
andrej@1: int read_input_bits(u8 slave,
andrej@1: u16 start_addr,
andrej@1: u16 count,
andrej@1: u16 *dest,
andrej@1: int dest_size,
andrej@1: int fd,
andrej@1: int send_retries,
andrej@1: u8 *error_code,
andrej@1: const struct timespec *response_timeout,
andrej@1: pthread_mutex_t *data_access_mutex);
msousa@0: #define read_discrete_inputs(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) \
msousa@0: read_input_bits (p1,p2,p3,p4,p5,p6,p7,p8,p9,p10)
msousa@0:
msousa@0:
msousa@0: /* FUNCTION 0x02 - Read Discrete Inputs
msousa@0: * Bits are stored on an u32 array, 32 bits per u32.
msousa@0: * Unused bits in last u32 are set to 0.
msousa@0: */
andrej@1: int read_input_bits_u32(u8 slave,
andrej@1: u16 start_addr,
andrej@1: u16 count,
andrej@1: u32 *dest,
andrej@1: int fd,
andrej@1: int send_retries,
andrej@1: u8 *error_code,
andrej@1: const struct timespec *response_timeout);
msousa@0: #define read_discrete_inputs_u32(p1,p2,p3,p4,p5,p6,p7,p8) \
msousa@0: read_input_bits_u32 (p1,p2,p3,p4,p5,p6,p7,p8)
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0: /* FUNCTION 0x03 - Read Holding Registers */
andrej@1: int read_output_words(u8 slave,
andrej@1: u16 start_addr,
andrej@1: u16 count,
andrej@1: u16 *dest,
andrej@1: int dest_size,
andrej@1: int fd,
andrej@1: int send_retries,
andrej@1: u8 *error_code,
andrej@1: const struct timespec *response_timeout,
andrej@1: pthread_mutex_t *data_access_mutex);
msousa@0: #define read_holding_registers(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) \
msousa@0: read_output_words (p1,p2,p3,p4,p5,p6,p7,p8,p9,p10)
msousa@0:
msousa@0:
msousa@0: /* FUNCTION 0x03 - Read Holding Registers
msousa@0: * u16 registers are stored in array of u32, two registers per u32.
msousa@0: * Unused bits of last u32 element are set to 0.
msousa@0: */
andrej@1: int read_output_words_u32(u8 slave,
andrej@1: u16 start_addr,
andrej@1: u16 count,
andrej@1: u32 *dest,
andrej@1: int fd,
andrej@1: int send_retries,
andrej@1: u8 *error_code,
andrej@1: const struct timespec *response_timeout);
msousa@0: #define read_holding_registers_u32(p1,p2,p3,p4,p5,p6,p7,p8) \
msousa@0: read_output_words_u32 (p1,p2,p3,p4,p5,p6,p7,p8)
msousa@0:
msousa@0:
msousa@0: /* FUNCTION 0x03 - Read Holding Registers
msousa@0: * return the array with the data to the calling function
msousa@0: */
andrej@1: int read_output_words_u16_ref(u8 slave,
andrej@1: u16 start_addr,
andrej@1: u16 count,
andrej@1: u16 **dest,
andrej@1: int ttyfd,
andrej@1: int send_retries,
andrej@1: u8 *error_code,
andrej@1: const struct timespec *response_timeout);
msousa@0: #define read_holding_registers_u16_ref(p1,p2,p3,p4,p5,p6,p7,p8) \
msousa@0: read_output_words_u16_ref (p1,p2,p3,p4,p5,p6,p7,p8)
msousa@0:
msousa@0:
msousa@0:
msousa@0: /* FUNCTION 0x04 - Read Input Registers */
andrej@1: int read_input_words(u8 slave,
andrej@1: u16 start_addr,
andrej@1: u16 count,
andrej@1: u16 *dest,
andrej@1: int dest_size,
andrej@1: int fd,
andrej@1: int send_retries,
andrej@1: u8 *error_code,
andrej@1: const struct timespec *response_timeout,
andrej@1: pthread_mutex_t *data_access_mutex);
msousa@0: #define read_input_registers(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) \
msousa@0: read_input_words (p1,p2,p3,p4,p5,p6,p7,p8,p9,p10)
msousa@0:
msousa@0:
msousa@0:
msousa@0: /* FUNCTION 0x04 - Read Input Registers
msousa@0: * u16 registers are stored in array of u32, two registers per u32.
msousa@0: * Unused bits of last u32 element are set to 0.
msousa@0: */
andrej@1: int read_input_words_u32(u8 slave,
andrej@1: u16 start_addr,
andrej@1: u16 count,
andrej@1: u32 *dest,
andrej@1: int fd,
andrej@1: int send_retries,
andrej@1: u8 *error_code,
andrej@1: const struct timespec *response_timeout);
msousa@0: #define read_input_registers_u32(p1,p2,p3,p4,p5,p6,p7,p8) \
msousa@0: read_input_words_u32 (p1,p2,p3,p4,p5,p6,p7,p8)
msousa@0:
msousa@0:
msousa@0:
msousa@0: /* FUNCTION 0x04 - Read Input Registers
msousa@0: * return the array with the data to the calling function
msousa@0: */
andrej@1: int read_input_words_u16_ref(u8 slave,
andrej@1: u16 start_addr,
andrej@1: u16 count,
andrej@1: u16 **dest,
andrej@1: int ttyfd,
andrej@1: int send_retries,
andrej@1: u8 *error_code,
andrej@1: const struct timespec *response_timeout);
msousa@0: #define read_input_registers_u16_ref(p1,p2,p3,p4,p5,p6,p7,p8) \
msousa@0: read_input_words_u16_ref (p1,p2,p3,p4,p5,p6,p7,p8)
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0: /* FUNCTION 0x05 - Force Single Coil */
andrej@1: int write_output_bit(u8 slave,
andrej@1: u16 coil_addr,
andrej@1: u16 state,
andrej@1: int fd,
andrej@1: int send_retries,
andrej@1: u8 *error_code,
andrej@1: const struct timespec *response_timeout,
andrej@1: pthread_mutex_t *data_access_mutex);
msousa@0: #define force_single_coil(p1,p2,p3,p4,p5,p6,p7,p8) \
msousa@0: write_output_bit (p1,p2,p3,p4,p5,p6,p7,p8)
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0: /* FUNCTION 0x06 - Write Single Register */
andrej@1: int write_output_word(u8 slave,
andrej@1: u16 reg_addr,
andrej@1: u16 value,
andrej@1: int fd,
andrej@1: int send_retries,
andrej@1: u8 *error_code,
andrej@1: const struct timespec *response_timeout,
andrej@1: pthread_mutex_t *data_access_mutex);
msousa@0: #define write_single_register(p1,p2,p3,p4,p5,p6,p7,p8) \
msousa@0: write_output_word (p1,p2,p3,p4,p5,p6,p7,p8)
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0: /* FUNCTION 0x0F - Force Multiple Coils */
msousa@0: int write_output_bits(u8 slave,
msousa@0: u16 start_addr,
msousa@0: u16 coil_count,
msousa@0: u16 *data,
msousa@0: int fd,
msousa@0: int send_retries,
msousa@0: u8 *error_code,
msousa@0: const struct timespec *response_timeout,
msousa@0: pthread_mutex_t *data_access_mutex);
msousa@0: #define force_multiple_coils(p1,p2,p3,p4,p5,p6,p7,p8,p9) \
msousa@0: write_output_bits (p1,p2,p3,p4,p5,p6,p7,p8,p9)
msousa@0:
msousa@0:
msousa@0: /* FUNCTION 0x0F - Force Multiple Coils
msousa@0: * Bits should be stored on an u32 array, 32 bits per u32.
msousa@0: * Unused bits in last u32 should be set to 0.
msousa@0: */
msousa@0: int write_output_bits_u32(u8 slave,
msousa@0: u16 start_addr,
msousa@0: u16 coil_count,
msousa@0: u32 *data,
msousa@0: int fd,
msousa@0: int send_retries,
msousa@0: u8 *error_code,
msousa@0: const struct timespec *response_timeout);
msousa@0: #define force_multiple_coils_u32(p1,p2,p3,p4,p5,p6,p7,p8) \
msousa@0: write_output_bits_u32 (p1,p2,p3,p4,p5,p6,p7,p8)
msousa@0:
msousa@0:
msousa@0:
msousa@0: /* FUNCTION 0x10 - Force Multiple Registers */
msousa@0: int write_output_words(u8 slave,
msousa@0: u16 start_addr,
msousa@0: u16 reg_count,
msousa@0: u16 *data,
msousa@0: int fd,
msousa@0: int send_retries,
msousa@0: u8 *error_code,
msousa@0: const struct timespec *response_timeout,
msousa@0: pthread_mutex_t *data_access_mutex);
msousa@0: #define force_multiple_registers(p1,p2,p3,p4,p5,p6,p7,p8,p9) \
msousa@0: write_output_words (p1,p2,p3,p4,p5,p6,p7,p8,p9)
msousa@0:
msousa@0:
msousa@0:
msousa@0: /* FUNCTION 0x10 - Force Multiple Registers
msousa@0: * u16 registers are stored in array of u32, two registers per u32.
msousa@0: * Unused bits of last u32 element are set to 0.
msousa@0: */
msousa@0: int write_output_words_u32(u8 slave,
msousa@0: u16 start_addr,
msousa@0: u16 reg_count,
msousa@0: u32 *data,
msousa@0: int fd,
msousa@0: int send_retries,
msousa@0: u8 *error_code,
msousa@0: const struct timespec *response_timeout);
msousa@0:
msousa@0: #define force_multiple_registers_u32(p1,p2,p3,p4,p5,p6,p7,p8) \
msousa@0: write_output_words_u32 (p1,p2,p3,p4,p5,p6,p7,p8)
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0: /* Initialise the Modbus Library to work as Master only */
msousa@0: int mb_master_init(int nd_count);
msousa@0: /* Shut down the Modbus Library */
msousa@0: int mb_master_done(void);
msousa@0:
msousa@0:
msousa@0:
msousa@0: /* Establish a connection to a remote server/slave.
msousa@0: * The address type (naf_tcp, naf_rtu, naf_ascii) specifies the lower
msousa@0: * layer to use for the newly opened node.
msousa@0: */
msousa@0: int mb_master_connect(node_addr_t node_addr);
msousa@0: /* Shut down a connection to a remote server/slave */
msousa@0: int mb_master_close(int nd);
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0: /* Tell the library that communications will be suspended for some time. */
msousa@0: /* RTU and ASCII versions ignore this function
msousa@0: * TCP version closes all the open tcp connections (connections are automatically
msousa@0: * re-established the next time an IO function to the slave is requested).
msousa@0: * To be more precise, the TCP version makes an estimate of how long
msousa@0: * the silence will be based on previous invocations to this exact same
msousa@0: * function, and will only close the connections if this silence is
msousa@0: * expected to be longer than 1 second!
msousa@0: */
msousa@0: int mb_master_tcp_silence_init(void);
msousa@0:
msousa@0:
msousa@0:
msousa@0: #endif /* MODBUS_MASTER_H */
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0: