Hello Everyone,
I am using the RS-485 interface from XMOS that can be found here. The question I have is the following:
is the rs485_send_packet() function a blocking function? when I see the code:
int rs485_send_packet(chanend c, unsigned char data[], unsigned len)
{
int ret;
c <: RS485_CMD_SEND_PACKET;
c <: len;
for (int i = 0; i < len; i++)
{
c <: (unsigned)data;
}
c :> ret;
return (ret == len);
}
I see that it needs to wait for the data to return through the channel in order to continue. However I have the following code
void sendPackage(unsigned char header_id, unsigned char len,unsigned char * bytes, chanend c_rs485_send)
{
unsigned char buffer_out[220];
buffer_out[0] = 0xAA; //MHeader
buffer_out[1] = 0x55; //MHeader
buffer_out[2] = len+2; //MLen
buffer_out[3] = header_id; //PayloadID
buffer_out[4] = len; //Payload Len
unsigned char checksum = len+2;
checksum ^= header_id;
checksum ^= len;
for (int byte = 0; byte < len; ++byte)
{
checksum ^= bytes[byte];
buffer_out[byte+5] = bytes[byte];
}
buffer_out[len + 5]=checksum;
rs485_send_packet(c_rs485_send, buffer_out, len+6);
}
while(1)
{
receiveResponse_data_t responseData;
responseData.data_len=0;
responseData.state=YUJIN_STATE_MAIN_HEAD_0;
select
{
case i_proto.buttons_Leds(unsigned char buttons_leds_state):
timeout_occoured=0;
sendPackage(YUJIN_PAYLOAD_SET_BUTTONS_LEDS_STATE,1,&buttons_leds_state,c_rs485_send);
break;
case i_proto.displayLeds(unsigned char display):
timeout_occoured=0;
SendPackage(YUJIN_PAYLOAD_SHOW_LED,1,&display,c_rs485_send);
break;
}
}
When I send 2 packages one after the other one of the packets gets lost. but when I add a delay the 2 messages get through. Is as if the SendPackage() function gets executed and immediately the code jumps to the next part of the select statement and sends the second packet without waiting for the 1st one to be sent.
Any help appreciated.
Thanks.
RS-485 Interface Question Topic is solved
-
- Member++
- Posts: 16
- Joined: Wed Apr 15, 2015 9:31 am
-
- XCore Legend
- Posts: 1913
- Joined: Thu Jun 10, 2010 11:43 am
Some ideas and questions...issue could be software or hardware but suspecting is software related.
1) Check if rs485_send_packet is blocking or non-blocking by calling rs485_send_packet without the use of the select function.
Try to apply using a while(1) loop and continue to call rs485_send_packet to verify that you can stream out packets without issues and that each packet is truly received and is being digested by your external RS485 device. Does this method function correctly without delays ?
2) You do not state the baud rates being used by this RS485 setup. Are you using a slow baud rate (9600 bps, etc.) or relatively fast 1 Mbps ?
3) Vendor and P/N of the RS485 transceivers being used ? Are the RS485 receivers internally fail safe biased ? Is your RS485 network fail-safe biased ? On RS485 networks, when there is no master driving the RS485 wires then RS485 receivers may pick up stray noise and treat as a false start bit since the wires are effectively floating. The noise is usually from external events such as long wires, motors, induction, etc. This can be avoided by confirming that the RS485 receivers are fail safe biased internally OR you can bias the RS485 network externally using pull-up and pull-down resistors (the values will vary with the number of RS485 nodes in your setup - many articles on the internal on this subject). If you have many RS485 nodes or even more than one - limit the debugging of this setup by using a single RS485 node till you have a solid and working configuration. Then introduce another RS485 node, etc.
Are you properly terminating the RS485 setup ? The start and end of the RS485 chain must be terminated to avoid reflections with often 100 to 120 ohms resistor.
Note: If you apply external fail safe idle resistors onto this setup then the values for the pull-up & pull-down resistors will also vary if you use termination versus if you do not use termination. Recommend that you do apply termination resistors.
RS485 transceivers rated for your communication speed ? Some transceivers offer slew rate control for the transmitter for best quality of signal. Best to review the datasheet for the RS485 transceivers.
4) Assuming you are using RS485, 2 wire (half duplex) ?
5) There is an expected latency (propagation delay) required to send the RS485 packets over copper -> receive the packets by the receiving node(s) -> time must be allotted for the node(s) to be indexed -> time must be allotted for the indexed node to reply back so there must be provision for a turn around time delay. That is, when the RS485 master talks, the RS485 master is driving the 2 wire interface (half duplex configuration) but after talking, the node will take a turn to drive the same 2 wires so that the master can receive the reply. If the master continues to drive the 2 wire interface without delays then the master may be corrupting the reply from the indexed RS485 slave. This is considered to be data collision. It is very possible that the indexed RS485 slave device is a slow processor so you must wait for this delayed reply.
6) Where are you placing the delays that allow for this setup to work ? What is the value amount of the delay that works ?
7) It is possible that the select function is not a "fair" select. First verify if the RS485 setup is operational without the use of select and then consider to review how to allow the select function to be "fair" so that both sections of the select have equal opportunity to be selected.
See this appnote:
http://www.xmos.com/support/examples/AN10016
8) Using the simulator or waverform viewer on the xTimeComposer tool should also allow for verification of the actual operation of your hardware setup.
At this time of writing, not clear on if the issue is hardware or software related but do review the software on the XMOS side first and the above ideas should help to debug the case. Remove the select from the test code for starters and go from there. Have fun !
1) Check if rs485_send_packet is blocking or non-blocking by calling rs485_send_packet without the use of the select function.
Try to apply using a while(1) loop and continue to call rs485_send_packet to verify that you can stream out packets without issues and that each packet is truly received and is being digested by your external RS485 device. Does this method function correctly without delays ?
2) You do not state the baud rates being used by this RS485 setup. Are you using a slow baud rate (9600 bps, etc.) or relatively fast 1 Mbps ?
3) Vendor and P/N of the RS485 transceivers being used ? Are the RS485 receivers internally fail safe biased ? Is your RS485 network fail-safe biased ? On RS485 networks, when there is no master driving the RS485 wires then RS485 receivers may pick up stray noise and treat as a false start bit since the wires are effectively floating. The noise is usually from external events such as long wires, motors, induction, etc. This can be avoided by confirming that the RS485 receivers are fail safe biased internally OR you can bias the RS485 network externally using pull-up and pull-down resistors (the values will vary with the number of RS485 nodes in your setup - many articles on the internal on this subject). If you have many RS485 nodes or even more than one - limit the debugging of this setup by using a single RS485 node till you have a solid and working configuration. Then introduce another RS485 node, etc.
Are you properly terminating the RS485 setup ? The start and end of the RS485 chain must be terminated to avoid reflections with often 100 to 120 ohms resistor.
Note: If you apply external fail safe idle resistors onto this setup then the values for the pull-up & pull-down resistors will also vary if you use termination versus if you do not use termination. Recommend that you do apply termination resistors.
RS485 transceivers rated for your communication speed ? Some transceivers offer slew rate control for the transmitter for best quality of signal. Best to review the datasheet for the RS485 transceivers.
4) Assuming you are using RS485, 2 wire (half duplex) ?
5) There is an expected latency (propagation delay) required to send the RS485 packets over copper -> receive the packets by the receiving node(s) -> time must be allotted for the node(s) to be indexed -> time must be allotted for the indexed node to reply back so there must be provision for a turn around time delay. That is, when the RS485 master talks, the RS485 master is driving the 2 wire interface (half duplex configuration) but after talking, the node will take a turn to drive the same 2 wires so that the master can receive the reply. If the master continues to drive the 2 wire interface without delays then the master may be corrupting the reply from the indexed RS485 slave. This is considered to be data collision. It is very possible that the indexed RS485 slave device is a slow processor so you must wait for this delayed reply.
6) Where are you placing the delays that allow for this setup to work ? What is the value amount of the delay that works ?
7) It is possible that the select function is not a "fair" select. First verify if the RS485 setup is operational without the use of select and then consider to review how to allow the select function to be "fair" so that both sections of the select have equal opportunity to be selected.
See this appnote:
http://www.xmos.com/support/examples/AN10016
8) Using the simulator or waverform viewer on the xTimeComposer tool should also allow for verification of the actual operation of your hardware setup.
At this time of writing, not clear on if the issue is hardware or software related but do review the software on the XMOS side first and the above ideas should help to debug the case. Remove the select from the test code for starters and go from there. Have fun !