Commit bf6718c9b1364624f2f41dec96a1814a3856b619
Committed by
Stéphane Raimbault
1 parent
2f911c3b
Add the support to RTS signal in order to have RS485 working on some linux box with RS485 on-board.
Showing
3 changed files
with
76 additions
and
1 deletions
src/modbus-rtu-private.h
| ... | ... | @@ -80,7 +80,12 @@ typedef struct _modbus_rtu { |
| 80 | 80 | #endif |
| 81 | 81 | #if HAVE_DECL_TIOCSRS485 |
| 82 | 82 | int serial_mode; |
| 83 | + int usage_rts; | |
| 83 | 84 | #endif |
| 84 | 85 | } modbus_rtu_t; |
| 85 | 86 | |
| 87 | +/* Time waited beetween the RTS switch before transmit data o after transmit data before to read */ | |
| 88 | +#define TIME_BETWEEN_RTS_SWITCH 10000 | |
| 89 | +void _modbus_rtu_setrts(int fd, int on); | |
| 90 | + | |
| 86 | 91 | #endif /* _MODBUS_RTU_PRIVATE_H_ */ | ... | ... |
src/modbus-rtu.c
| ... | ... | @@ -264,7 +264,21 @@ ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_length) |
| 264 | 264 | DWORD n_bytes = 0; |
| 265 | 265 | return (WriteFile(ctx_rtu->w_ser.fd, req, req_length, &n_bytes, NULL)) ? n_bytes : -1; |
| 266 | 266 | #else |
| 267 | - return write(ctx->s, req, req_length); | |
| 267 | + modbus_rtu_t *ctx_rtu = ctx->backend_data; | |
| 268 | + if (ctx_rtu->usage_rts == MODBUS_USE_RTS) { | |
| 269 | + ssize_t size; | |
| 270 | + | |
| 271 | + _modbus_rtu_setrts(ctx->s,1); | |
| 272 | + usleep(TIME_BETWEEN_RTS_SWITCH); | |
| 273 | + | |
| 274 | + size = write(ctx->s, req, req_length); | |
| 275 | + usleep(TIME_BETWEEN_RTS_SWITCH); | |
| 276 | + _modbus_rtu_setrts(ctx->s,0); | |
| 277 | + | |
| 278 | + return size; | |
| 279 | + } else { | |
| 280 | + return write(ctx->s, req, req_length); | |
| 281 | + } | |
| 268 | 282 | #endif |
| 269 | 283 | } |
| 270 | 284 | |
| ... | ... | @@ -703,6 +717,10 @@ static int _modbus_rtu_connect(modbus_t *ctx) |
| 703 | 717 | #if HAVE_DECL_TIOCSRS485 |
| 704 | 718 | /* The RS232 mode has been set by default */ |
| 705 | 719 | ctx_rtu->serial_mode = MODBUS_RTU_RS232; |
| 720 | + | |
| 721 | + /* The RTS usage has been set by default */ | |
| 722 | + ctx_rtu->usage_rts = MODBUS_NO_USE_RTS; | |
| 723 | + | |
| 706 | 724 | #endif |
| 707 | 725 | |
| 708 | 726 | return 0; |
| ... | ... | @@ -764,6 +782,38 @@ int modbus_rtu_get_serial_mode(modbus_t *ctx) { |
| 764 | 782 | } |
| 765 | 783 | } |
| 766 | 784 | |
| 785 | +int modbus_rtu_set_usage_rts(modbus_t *ctx, int mode) | |
| 786 | +{ | |
| 787 | + if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) { | |
| 788 | + modbus_rtu_t *ctx_rtu = ctx->backend_data; | |
| 789 | + | |
| 790 | + if (mode == MODBUS_NO_USE_RTS || mode == MODBUS_USE_RTS ) { | |
| 791 | + ctx_rtu->usage_rts = mode; | |
| 792 | + return 0; | |
| 793 | + } | |
| 794 | + | |
| 795 | + if (ctx->debug) { | |
| 796 | + fprintf(stderr, "This function isn't supported on your platform\n"); | |
| 797 | + } | |
| 798 | + errno = ENOTSUP; | |
| 799 | + return -1; | |
| 800 | + } | |
| 801 | + | |
| 802 | + /* Wrong backend and invalid mode specified */ | |
| 803 | + errno = EINVAL; | |
| 804 | + return -1; | |
| 805 | +} | |
| 806 | + | |
| 807 | +int modbus_rtu_get_usage_rts(modbus_t *ctx) { | |
| 808 | + if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) { | |
| 809 | + modbus_rtu_t *ctx_rtu = ctx->backend_data; | |
| 810 | + return ctx_rtu->usage_rts; | |
| 811 | + } else { | |
| 812 | + errno = EINVAL; | |
| 813 | + return -1; | |
| 814 | + } | |
| 815 | +} | |
| 816 | + | |
| 767 | 817 | void _modbus_rtu_close(modbus_t *ctx) |
| 768 | 818 | { |
| 769 | 819 | /* Closes the file descriptor in RTU mode */ |
| ... | ... | @@ -915,3 +965,17 @@ modbus_t* modbus_new_rtu(const char *device, |
| 915 | 965 | |
| 916 | 966 | return ctx; |
| 917 | 967 | } |
| 968 | + | |
| 969 | +void _modbus_rtu_setrts(int fd, int on) | |
| 970 | +{ | |
| 971 | + int controlbits; | |
| 972 | + | |
| 973 | + ioctl(fd, TIOCMGET, &controlbits); | |
| 974 | + if (on) { | |
| 975 | + controlbits |= TIOCM_RTS; | |
| 976 | + } else { | |
| 977 | + controlbits &= ~TIOCM_RTS; | |
| 978 | + } | |
| 979 | + ioctl(fd, TIOCMSET, &controlbits); | |
| 980 | +} | |
| 981 | + | ... | ... |
src/modbus-rtu.h
| ... | ... | @@ -32,7 +32,13 @@ modbus_t* modbus_new_rtu(const char *device, int baud, char parity, |
| 32 | 32 | #define MODBUS_RTU_RS232 0 |
| 33 | 33 | #define MODBUS_RTU_RS485 1 |
| 34 | 34 | |
| 35 | +#define MODBUS_NO_USE_RTS 0 | |
| 36 | +#define MODBUS_USE_RTS 1 | |
| 37 | + | |
| 35 | 38 | int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode); |
| 36 | 39 | int modbus_rtu_get_serial_mode(modbus_t *ctx); |
| 37 | 40 | |
| 41 | +int modbus_rtu_set_usage_rts(modbus_t *ctx, int mode); | |
| 42 | +int modbus_rtu_get_usage_rts(modbus_t *ctx); | |
| 43 | + | |
| 38 | 44 | #endif /* _MODBUS_RTU_H_ */ | ... | ... |