diff --git a/doc/Makefile.am b/doc/Makefile.am index e7f704e..e05438f 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -29,6 +29,8 @@ TXT3 = \ modbus_rtu_set_serial_mode.txt \ modbus_rtu_get_rts.txt \ modbus_rtu_set_rts.txt \ + modbus_rtu_get_rts_delay.txt \ + modbus_rtu_set_rts_delay.txt \ modbus_rtu_set_custom_rts.txt \ modbus_send_raw_request.txt \ modbus_set_bits_from_bytes.txt \ diff --git a/doc/modbus_rtu_get_rts_delay.txt b/doc/modbus_rtu_get_rts_delay.txt new file mode 100644 index 0000000..43853d4 --- /dev/null +++ b/doc/modbus_rtu_get_rts_delay.txt @@ -0,0 +1,46 @@ +modbus_rtu_get_rts_delay(3) +=========================== + + +NAME +---- +modbus_rtu_get_rts_delay - get the current RTS delay in RTU + + +SYNOPSIS +-------- +*int modbus_rtu_get_rts_delay(modbus_t *'ctx');* + + +DESCRIPTION +----------- + +The _modbus_rtu_get_rts_delay()_ function shall get the current Request To Send +delay period of the libmodbus context 'ctx'. + +This function can only be used with a context using a RTU backend. + + +RETURN VALUE +------------ +The _modbus_rtu_get_rts_delay()_ function shall return the current RTS delay in +microseconds if successful. Otherwise it shall return -1 and set errno. + + +ERRORS +------ +*EINVAL*:: +The libmodbus backend is not RTU. + + +SEE ALSO +-------- +linkmb:modbus_rtu_set_rts_delay[3] + + +AUTHORS +------- +Jimmy Bergström + +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_rtu_set_rts_delay.txt b/doc/modbus_rtu_set_rts_delay.txt new file mode 100644 index 0000000..39af7df --- /dev/null +++ b/doc/modbus_rtu_set_rts_delay.txt @@ -0,0 +1,46 @@ +modbus_rtu_set_rts_delay(3) +=========================== + + +NAME +---- +modbus_rtu_set_rts_delay - set the RTS delay in RTU + + +SYNOPSIS +-------- +*int modbus_rtu_set_rts_delay(modbus_t *'ctx', int 'us');* + + +DESCRIPTION +----------- + +The _modbus_rtu_set_rts_delay()_ function shall set the Request To Send delay +period of the libmodbus context 'ctx'. + +This function can only be used with a context using a RTU backend. + + +RETURN VALUE +------------ +The _modbus_rtu_set_rts_delay()_ function shall return 0 if successful. +Otherwise it shall return -1 and set errno. + + +ERRORS +------ +*EINVAL*:: +The libmodbus backend is not RTU or a negative delay was specified. + + +SEE ALSO +-------- +linkmb:modbus_rtu_get_rts_delay[3] + + +AUTHORS +------- +Jimmy Bergström + +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/src/modbus-rtu-private.h b/src/modbus-rtu-private.h index e0abaa1..a1d0473 100644 --- a/src/modbus-rtu-private.h +++ b/src/modbus-rtu-private.h @@ -25,10 +25,6 @@ #define _MODBUS_RTU_CHECKSUM_LENGTH 2 -/* Time waited beetween the RTS switch before transmit data or after transmit - data before to read (1 ms) */ -#define _MODBUS_RTU_TIME_BETWEEN_RTS_SWITCH 1000 - #if defined(_WIN32) #if !defined(ENOTSUP) #define ENOTSUP WSAEOPNOTSUPP @@ -69,6 +65,7 @@ typedef struct _modbus_rtu { #endif #if HAVE_DECL_TIOCM_RTS int rts; + int rts_delay; int onebyte_time; void (*set_rts) (modbus_t *ctx, int on); #endif diff --git a/src/modbus-rtu.c b/src/modbus-rtu.c index 6974624..02516e2 100644 --- a/src/modbus-rtu.c +++ b/src/modbus-rtu.c @@ -284,11 +284,11 @@ static ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_lengt } ctx_rtu->set_rts(ctx, ctx_rtu->rts == MODBUS_RTU_RTS_UP); - usleep(_MODBUS_RTU_TIME_BETWEEN_RTS_SWITCH); + usleep(ctx_rtu->rts_delay); size = write(ctx->s, req, req_length); - usleep(ctx_rtu->onebyte_time * req_length + _MODBUS_RTU_TIME_BETWEEN_RTS_SWITCH); + usleep(ctx_rtu->onebyte_time * req_length + ctx_rtu->rts_delay); ctx_rtu->set_rts(ctx, ctx_rtu->rts != MODBUS_RTU_RTS_UP); return size; @@ -1028,6 +1028,57 @@ int modbus_rtu_get_rts(modbus_t *ctx) } } +int modbus_rtu_set_rts_delay(modbus_t *ctx, int us) +{ + if (ctx == NULL || us < 0) { + errno = EINVAL; + return -1; + } + + if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) { +#if HAVE_DECL_TIOCM_RTS + modbus_rtu_t *ctx_rtu; + ctx_rtu = (modbus_rtu_t *)ctx->backend_data; + ctx_rtu->rts_delay = us; + return 0; +#else + if (ctx->debug) { + fprintf(stderr, "This function isn't supported on your platform\n"); + } + errno = ENOTSUP; + return -1; +#endif + } else { + errno = EINVAL; + return -1; + } +} + +int modbus_rtu_get_rts_delay(modbus_t *ctx) +{ + if (ctx == NULL) { + errno = EINVAL; + return -1; + } + + if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) { +#if HAVE_DECL_TIOCM_RTS + modbus_rtu_t *ctx_rtu; + ctx_rtu = (modbus_rtu_t *)ctx->backend_data; + return ctx_rtu->rts_delay; +#else + if (ctx->debug) { + fprintf(stderr, "This function isn't supported on your platform\n"); + } + errno = ENOTSUP; + return -1; +#endif + } else { + errno = EINVAL; + return -1; + } +} + int modbus_rtu_set_custom_rts(modbus_t *ctx, void (*set_rts) (modbus_t *ctx, int on)) { if (ctx == NULL) { @@ -1209,9 +1260,12 @@ modbus_t* modbus_new_rtu(const char *device, ctx_rtu->rts = MODBUS_RTU_RTS_NONE; /* Calculate estimated time in micro second to send one byte */ - ctx_rtu->onebyte_time = (1000 * 1000) * (1 + data_bit + (parity == 'N' ? 0 : 1) + stop_bit) / baud; + ctx_rtu->onebyte_time = 1000000 * (1 + data_bit + (parity == 'N' ? 0 : 1) + stop_bit) / baud; ctx_rtu->set_rts = _modbus_rtu_ioctl_rts; + + /* The delay before and after transmission when toggling the RTS pin */ + ctx_rtu->rts_delay = ctx_rtu->onebyte_time; #endif ctx_rtu->confirmation_to_ignore = FALSE; diff --git a/src/modbus-rtu.h b/src/modbus-rtu.h index 58d0630..4f20f66 100644 --- a/src/modbus-rtu.h +++ b/src/modbus-rtu.h @@ -33,6 +33,9 @@ MODBUS_API int modbus_rtu_set_rts(modbus_t *ctx, int mode); MODBUS_API int modbus_rtu_get_rts(modbus_t *ctx); MODBUS_API int modbus_rtu_set_custom_rts(modbus_t *ctx, void (*set_rts) (modbus_t *ctx, int on)); +MODBUS_API int modbus_rtu_set_rts_delay(modbus_t *ctx, int us); +MODBUS_API int modbus_rtu_get_rts_delay(modbus_t *ctx); + MODBUS_END_DECLS #endif /* MODBUS_RTU_H */