-
I'm having trouble with receiving RS232 data with the 8 serial port card connected to a rpi 5.
I have a device that sends data packets via RS232 and I can reliably receive short packets of data from it, but for any packets over 9 bytes long, I only receive the first 8 or 9 bytes. There is no flow control available on the device (or at least turning xon/xoff on makes no difference and it doesn't provide hardware flow control signals). It is sending at 115200 baud. I upgraded the serial card firmware to the latest. I'm using pyserial in Python to read from the port.
This problem feels like a receive buffer overflow - are there any receive buffers in the RS232 ports on the 8 port serial card? (or are the buffers in the rpi itself?)
Thanks
Edit: My testing has been with a 28 byte packet and with an oscilloscope I see that all 28 bytes are being sent by the device and they are reaching the RX pin on the 8 serial port card.
-
Hi,
The card emulates more sc16is752 chips into the card processor. There is a 64 bytes FIFO for TX and one for RX.
If I remember correctly, we tested the FIFO with packets of 64 bytes, but let me retest it and I will get back to you.
Alex.
-
Thanks.
I've done some more testing to try to find the problem:
- on receiving >9 bytes in a packet the receive part of the serial port stops receiving additional bytes
- subsequent reads from the serial port all timeout and return zero bytes (or block if no timeout is set)
- closing and reopening the port resolves the issue until the next packet with >9 bytes
- transmit works fine regardless of the state of the receive side
- the problem also occurs if I reduce the baud rate (I tried 38400)
- if I use a usb/serial adapter instead of the 8 port serial card the problem doesn't occur
Gavin
-
Hi Gavin,
Sorry for the delay, I am now starting to debug your problem, at first look, everything is working well but I am running the cat command in a terminal "cat /dev/ttySC1" and then sending long strings of characters from a PC with a USB to Serial adapter. Could you share the code you use ?
Alex.
-
This is an simplified version of my code (tested and it has the same fault):
import serial
from time import sleep
device = serial.Serial('/dev/ttySC3', 115200, timeout=1)
device.write('p'.encode('ASCII'))
sleep(0.01)
ack = device.read(255)
print(f'Received {len(ack)} bytes')
Sending a 'p' command to the device on the serial port causes it to reply with a status message of 28 bytes.
-
Hi,
As you might know, the card emulates few UART chips (sc16is752) so I get the real chip I use for the development and test your code, it does pretty much the same and locks the port so I can not access it with the "cat" command anymore until a restart. I suspect there is also a Linux driver problem.
Here is a code that reads every byte in the string without locking the port :
import serial
from time import sleep
device = serial.Serial('/dev/ttySC1', 9600, timeout=0)
device.write('p'.encode('ASCII'))
sleep(0.01)
count = 0
try:
ack = device.read(100)
while count < 100:
sleep(0.01)
ack = ack+ device.read(100)
count = len(ack)
print(ack)
print(f'Received {len(ack)} bytes')
except:
device.close()
print("close the port")
I hope you can use the code like this because it will take me some time to fix this if there is no problem with the SC16IS752 chip driver which I can not modify.
Alex.
-
Thanks for looking in this. I'll try your workaround code and see how it goes.
-
I've had some time to look at this again. The example code didn't help, but what did help was changing the card ID from 1 to 0. When set to 0 (and the config.txt file changed to suit), the ports reliably receive data, but when set to 1 (and config.txt changed and the rpi powered down and restarted), the RS232 ports will not reliably receive data. They reliably send data with ID set to 0 or 1.
Perhaps not related, but the PCB silkscreen indicates that the ID is chosen using switch 6 on SW1, while the schematic shows that switch 5 is for ID1 and switch 6 for ID0 and they are wired to separate pin on the STM32.
-
Hi,
The ID1 signal is spare; we planned to have 4 cards in the stack, but the Linux kernel implementation of the SC16IS752 does not permit that, so only the ID0 signal is used.
It's strange that it behaves differently on different IDs, but I will try to replicate the problem.
-
Not sure if this helps, or even if I understand things correctly: if I set the stack ID to 0 and connect an oscilloscope to the RX pin on RS232 port 3 I see pulses on GPIO 19 pin when I send data to the serial port, typically one per byte of serial data (see image below - blue is GPIO 19 and red the RX pin). Same thing for port2 and GPIO 20, and port 1 and GPIO 19 (not on GPIO 22 as I expected...). But, when I change stack ID to 1 and do the same, there are never pulses on those interrupt pins. Is this expected?
-
Thank you for the detailed debug. I will look into this.
When changing the stack level, the interrupts must change on the second pair of pins. I will check the firmware.