Commit cf22eabc2701cc9ddfd4a921ba7c6e0822db5d7a

Authored by Jimmy Bergström
Committed by Stéphane Raimbault
1 parent c7eb7b96

Implemented runtime configurable RTS delay

doc/Makefile.am
@@ -29,6 +29,8 @@ TXT3 = \ @@ -29,6 +29,8 @@ TXT3 = \
29 modbus_rtu_set_serial_mode.txt \ 29 modbus_rtu_set_serial_mode.txt \
30 modbus_rtu_get_rts.txt \ 30 modbus_rtu_get_rts.txt \
31 modbus_rtu_set_rts.txt \ 31 modbus_rtu_set_rts.txt \
  32 + modbus_rtu_get_rts_delay.txt \
  33 + modbus_rtu_set_rts_delay.txt \
32 modbus_rtu_set_custom_rts.txt \ 34 modbus_rtu_set_custom_rts.txt \
33 modbus_send_raw_request.txt \ 35 modbus_send_raw_request.txt \
34 modbus_set_bits_from_bytes.txt \ 36 modbus_set_bits_from_bytes.txt \
doc/modbus_rtu_get_rts_delay.txt 0 → 100644
  1 +modbus_rtu_get_rts_delay(3)
  2 +===========================
  3 +
  4 +
  5 +NAME
  6 +----
  7 +modbus_rtu_get_rts_delay - get the current RTS delay in RTU
  8 +
  9 +
  10 +SYNOPSIS
  11 +--------
  12 +*int modbus_rtu_get_rts_delay(modbus_t *'ctx');*
  13 +
  14 +
  15 +DESCRIPTION
  16 +-----------
  17 +
  18 +The _modbus_rtu_get_rts_delay()_ function shall get the current Request To Send
  19 +delay period of the libmodbus context 'ctx'.
  20 +
  21 +This function can only be used with a context using a RTU backend.
  22 +
  23 +
  24 +RETURN VALUE
  25 +------------
  26 +The _modbus_rtu_get_rts_delay()_ function shall return the current RTS delay in
  27 +microseconds if successful. Otherwise it shall return -1 and set errno.
  28 +
  29 +
  30 +ERRORS
  31 +------
  32 +*EINVAL*::
  33 +The libmodbus backend is not RTU.
  34 +
  35 +
  36 +SEE ALSO
  37 +--------
  38 +linkmb:modbus_rtu_set_rts_delay[3]
  39 +
  40 +
  41 +AUTHORS
  42 +-------
  43 +Jimmy Bergström <jimmy@ekontroll.com>
  44 +
  45 +The libmodbus documentation was written by Stéphane Raimbault
  46 +<stephane.raimbault@gmail.com>
doc/modbus_rtu_set_rts_delay.txt 0 → 100644
  1 +modbus_rtu_set_rts_delay(3)
  2 +===========================
  3 +
  4 +
  5 +NAME
  6 +----
  7 +modbus_rtu_set_rts_delay - set the RTS delay in RTU
  8 +
  9 +
  10 +SYNOPSIS
  11 +--------
  12 +*int modbus_rtu_set_rts_delay(modbus_t *'ctx', int 'us');*
  13 +
  14 +
  15 +DESCRIPTION
  16 +-----------
  17 +
  18 +The _modbus_rtu_set_rts_delay()_ function shall set the Request To Send delay
  19 +period of the libmodbus context 'ctx'.
  20 +
  21 +This function can only be used with a context using a RTU backend.
  22 +
  23 +
  24 +RETURN VALUE
  25 +------------
  26 +The _modbus_rtu_set_rts_delay()_ function shall return 0 if successful.
  27 +Otherwise it shall return -1 and set errno.
  28 +
  29 +
  30 +ERRORS
  31 +------
  32 +*EINVAL*::
  33 +The libmodbus backend is not RTU or a negative delay was specified.
  34 +
  35 +
  36 +SEE ALSO
  37 +--------
  38 +linkmb:modbus_rtu_get_rts_delay[3]
  39 +
  40 +
  41 +AUTHORS
  42 +-------
  43 +Jimmy Bergström <jimmy@ekontroll.com>
  44 +
  45 +The libmodbus documentation was written by Stéphane Raimbault
  46 +<stephane.raimbault@gmail.com>
src/modbus-rtu-private.h
@@ -25,10 +25,6 @@ @@ -25,10 +25,6 @@
25 25
26 #define _MODBUS_RTU_CHECKSUM_LENGTH 2 26 #define _MODBUS_RTU_CHECKSUM_LENGTH 2
27 27
28 -/* Time waited beetween the RTS switch before transmit data or after transmit  
29 - data before to read (1 ms) */  
30 -#define _MODBUS_RTU_TIME_BETWEEN_RTS_SWITCH 1000  
31 -  
32 #if defined(_WIN32) 28 #if defined(_WIN32)
33 #if !defined(ENOTSUP) 29 #if !defined(ENOTSUP)
34 #define ENOTSUP WSAEOPNOTSUPP 30 #define ENOTSUP WSAEOPNOTSUPP
@@ -69,6 +65,7 @@ typedef struct _modbus_rtu { @@ -69,6 +65,7 @@ typedef struct _modbus_rtu {
69 #endif 65 #endif
70 #if HAVE_DECL_TIOCM_RTS 66 #if HAVE_DECL_TIOCM_RTS
71 int rts; 67 int rts;
  68 + int rts_delay;
72 int onebyte_time; 69 int onebyte_time;
73 void (*set_rts) (modbus_t *ctx, int on); 70 void (*set_rts) (modbus_t *ctx, int on);
74 #endif 71 #endif
src/modbus-rtu.c
@@ -284,11 +284,11 @@ static ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_lengt @@ -284,11 +284,11 @@ static ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_lengt
284 } 284 }
285 285
286 ctx_rtu->set_rts(ctx, ctx_rtu->rts == MODBUS_RTU_RTS_UP); 286 ctx_rtu->set_rts(ctx, ctx_rtu->rts == MODBUS_RTU_RTS_UP);
287 - usleep(_MODBUS_RTU_TIME_BETWEEN_RTS_SWITCH); 287 + usleep(ctx_rtu->rts_delay);
288 288
289 size = write(ctx->s, req, req_length); 289 size = write(ctx->s, req, req_length);
290 290
291 - usleep(ctx_rtu->onebyte_time * req_length + _MODBUS_RTU_TIME_BETWEEN_RTS_SWITCH); 291 + usleep(ctx_rtu->onebyte_time * req_length + ctx_rtu->rts_delay);
292 ctx_rtu->set_rts(ctx, ctx_rtu->rts != MODBUS_RTU_RTS_UP); 292 ctx_rtu->set_rts(ctx, ctx_rtu->rts != MODBUS_RTU_RTS_UP);
293 293
294 return size; 294 return size;
@@ -1028,6 +1028,57 @@ int modbus_rtu_get_rts(modbus_t *ctx) @@ -1028,6 +1028,57 @@ int modbus_rtu_get_rts(modbus_t *ctx)
1028 } 1028 }
1029 } 1029 }
1030 1030
  1031 +int modbus_rtu_set_rts_delay(modbus_t *ctx, int us)
  1032 +{
  1033 + if (ctx == NULL || us < 0) {
  1034 + errno = EINVAL;
  1035 + return -1;
  1036 + }
  1037 +
  1038 + if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) {
  1039 +#if HAVE_DECL_TIOCM_RTS
  1040 + modbus_rtu_t *ctx_rtu;
  1041 + ctx_rtu = (modbus_rtu_t *)ctx->backend_data;
  1042 + ctx_rtu->rts_delay = us;
  1043 + return 0;
  1044 +#else
  1045 + if (ctx->debug) {
  1046 + fprintf(stderr, "This function isn't supported on your platform\n");
  1047 + }
  1048 + errno = ENOTSUP;
  1049 + return -1;
  1050 +#endif
  1051 + } else {
  1052 + errno = EINVAL;
  1053 + return -1;
  1054 + }
  1055 +}
  1056 +
  1057 +int modbus_rtu_get_rts_delay(modbus_t *ctx)
  1058 +{
  1059 + if (ctx == NULL) {
  1060 + errno = EINVAL;
  1061 + return -1;
  1062 + }
  1063 +
  1064 + if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) {
  1065 +#if HAVE_DECL_TIOCM_RTS
  1066 + modbus_rtu_t *ctx_rtu;
  1067 + ctx_rtu = (modbus_rtu_t *)ctx->backend_data;
  1068 + return ctx_rtu->rts_delay;
  1069 +#else
  1070 + if (ctx->debug) {
  1071 + fprintf(stderr, "This function isn't supported on your platform\n");
  1072 + }
  1073 + errno = ENOTSUP;
  1074 + return -1;
  1075 +#endif
  1076 + } else {
  1077 + errno = EINVAL;
  1078 + return -1;
  1079 + }
  1080 +}
  1081 +
1031 int modbus_rtu_set_custom_rts(modbus_t *ctx, void (*set_rts) (modbus_t *ctx, int on)) 1082 int modbus_rtu_set_custom_rts(modbus_t *ctx, void (*set_rts) (modbus_t *ctx, int on))
1032 { 1083 {
1033 if (ctx == NULL) { 1084 if (ctx == NULL) {
@@ -1209,9 +1260,12 @@ modbus_t* modbus_new_rtu(const char *device, @@ -1209,9 +1260,12 @@ modbus_t* modbus_new_rtu(const char *device,
1209 ctx_rtu->rts = MODBUS_RTU_RTS_NONE; 1260 ctx_rtu->rts = MODBUS_RTU_RTS_NONE;
1210 1261
1211 /* Calculate estimated time in micro second to send one byte */ 1262 /* Calculate estimated time in micro second to send one byte */
1212 - ctx_rtu->onebyte_time = (1000 * 1000) * (1 + data_bit + (parity == 'N' ? 0 : 1) + stop_bit) / baud; 1263 + ctx_rtu->onebyte_time = 1000000 * (1 + data_bit + (parity == 'N' ? 0 : 1) + stop_bit) / baud;
1213 1264
1214 ctx_rtu->set_rts = _modbus_rtu_ioctl_rts; 1265 ctx_rtu->set_rts = _modbus_rtu_ioctl_rts;
  1266 +
  1267 + /* The delay before and after transmission when toggling the RTS pin */
  1268 + ctx_rtu->rts_delay = ctx_rtu->onebyte_time;
1215 #endif 1269 #endif
1216 1270
1217 ctx_rtu->confirmation_to_ignore = FALSE; 1271 ctx_rtu->confirmation_to_ignore = FALSE;
src/modbus-rtu.h
@@ -33,6 +33,9 @@ MODBUS_API int modbus_rtu_set_rts(modbus_t *ctx, int mode); @@ -33,6 +33,9 @@ MODBUS_API int modbus_rtu_set_rts(modbus_t *ctx, int mode);
33 MODBUS_API int modbus_rtu_get_rts(modbus_t *ctx); 33 MODBUS_API int modbus_rtu_get_rts(modbus_t *ctx);
34 MODBUS_API int modbus_rtu_set_custom_rts(modbus_t *ctx, void (*set_rts) (modbus_t *ctx, int on)); 34 MODBUS_API int modbus_rtu_set_custom_rts(modbus_t *ctx, void (*set_rts) (modbus_t *ctx, int on));
35 35
  36 +MODBUS_API int modbus_rtu_set_rts_delay(modbus_t *ctx, int us);
  37 +MODBUS_API int modbus_rtu_get_rts_delay(modbus_t *ctx);
  38 +
36 MODBUS_END_DECLS 39 MODBUS_END_DECLS
37 40
38 #endif /* MODBUS_RTU_H */ 41 #endif /* MODBUS_RTU_H */