PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 1828
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Thu Aug 11, 2016 3:55 pm

rpi-update will install a new kernel, overwriting your customised kernel. If you want the new features that the rpi-update kernel brings then you will have to update your kernel sources, rebuild and reinstall. If you are lucky not much will have changed so it won't be necessary to recompile everything.

You might be able to rebuild a single build, but I suspect there will be many gotchas. The easiest option would be to ask for the module to be added to the standard configurations - create an issue here. Since it is only a 24KB module and the overlay that uses it is already in the build, you have a good chance of success.

MasterWuff
Posts: 10
Joined: Thu Jul 14, 2016 10:24 am
Location: Munich

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Thu Aug 11, 2016 4:58 pm

Thanks for the quick response.
This explains the sc16is752-spi1.dtbo in /boot/overlays/
I'm going to compile the kernal and try my luck to ask if it is possible to add the module to the standard configurations. Since there is only one UART on RPi3, perhaps more user will have the problem of one UART connection.

EDIT: If somebody is interested in: https://github.com/raspberrypi/linux/issues/1594

MasterWuff
Posts: 10
Joined: Thu Jul 14, 2016 10:24 am
Location: Munich

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Tue Aug 16, 2016 7:37 am

It works, with SPI and I2C

If someone is interested in my work, here it is (first I2C, later SPI):
HowTo I2C
I’m using a Raspberry Pi 3 with the latest (18.08.2016) Jessie version. i2c is enabled and working.
Since last Friday (12.08.2016) it is not necessary to compile the kernel anymore for the NXP SC16IS7XX. Therefore I have to say thank you PhilE and popcornmix. They managed to get the file in the kernel.

The hardware setup is as described in the data sheet:
http://www.nxp.com/documents/data_sheet ... 6IS762.pdf
NXP SC16IS752 <-> Raspberry Pi
VDD <-> +3,3V
VSS <-> GND
SDA <-> Pin3 (also called SDA)
SCL <-> Pin5 (also called SCL)
A0 <-> GND
A1 <-> GND
IRQ <-> 1k <-> +3,3V
IRQ <-> Pin38 (also called GPIO 20)
RESET <-> +3,3V
I2C/SPI <-> +3,3V

The RESET Pin has to be high, otherwise the chip is in reset mode and you can't communicate to it.

Software Setup:
When I run (i2cdetect -y 1) the address of the sc16is752 is 0x4D

Thanks on the privous update, the module for the SC16IS752 is in the kernel. I just needed to update my kernel.

Code: Select all

sudo rpi-update
sudo reboot
I have loaded the kernel module by default:

Code: Select all

sudo nano /etc/modules
and added here: sc16is7xx

Then there was only the overlay missing. This one was mostly copied of PhilE' and smirnov' from this page:
viewtopic.php?t=128892&p=904524

The file is called: sc16is752-i2c.dts
created with:

Code: Select all

sudo nano sc16is752-i2c.dts
The Overlay itself:

Code: Select all

/dts-v1/;
/plugin/;

/ {
    compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; // Depending on your RPi Board Chip
    
    [email protected] {
        target = <&i2c1>;
        
        frag1: __overlay__ {
            #address-cells = <1>;
            #size-cells = <0>;
            status = "okay";

            sc16is752: [email protected] {
                compatible = "nxp,sc16is752";
                reg = <0x4D>; // i2c address
                clocks = <&sc16is752_clk>;
                interrupt-parent = <&gpio>;
                interrupts = <20 0x2>; //GPIO and falling edge
                gpio-controller;
                #gpio-cells = <0>;
                i2c-max-frequency = <400000>;
      status = "okay";

                sc16is752_clk: sc16is752_clk {
                    compatible = "fixed-clock";
                    #clock-cells = <0>;
                    clock-frequency = <1843200>;
                };
            };
        };
    };

    __overrides__ {
        int_pin = <&sc16is752>,"interrupts:0";
    };
};

After that, I checked my firmware with " uname -r " if it is >4.4 and yes it was because of that, I used the following command to create a dtbo-overlay:

Code: Select all

dtc [email protected] -I dts –O dtb –o sc16is752-i2c.dtbo sc16is752-i2c.dts


This was copied to the overlay folder:

Code: Select all

sudo cp sc16is752-i2c.dtbo /boot/overlays/
and activated in the " /boot/config.txt ". In the config.txt I added the Name of the file dtoverlay=sc16is752-i2c
I saved it and restarted the Pi.


Check if everything works:

Code: Select all

lsmod
(here I have the file “sc16is7xx”)

Code: Select all

sudo vcdbg log msg

(here is “Loaded overlay ‘sc16is752-i2c’”)

Code: Select all

ls –l /dev/ttyS*

(and here are the Pi’s UART Ports: /dev/ttyS0 /dev/ttySC0 /dev/ttySC1)

Later in this post, you can find a sample code.


HowTo SPI
The hardware setup is as described in the data sheet:
http://www.nxp.com/documents/data_sheet ... 6IS762.pdf
NXP SC16IS752 <-> Raspberry Pi
VDD <-> +3,3V
VSS <-> GND
SCLK <-> Pin23
CS <-> Pin24 (also called Chip Select)
SO <-> Pin21 (also called Miso)
SI <-> Pin19 (also called Mosi)
IRQ <-> 1k <-> +3,3V
IRQ <-> Pin38 (also called GPIO 20)
RESET <-> +3,3V
I2C/SPI <-> GND

The RESET Pin has to be high, otherwise the chip is in reset mode and you can't communicate to it.

Software Setup:
Thanks on the privous update, the module for the SC16IS752 is in the kernel. I just needed to update my kernel.

Code: Select all

sudo rpi-update
sudo reboot
I have loaded the kernel module by default:

Code: Select all

sudo nano /etc/modules
and added here: sc16is7xx

Then there was only the overlay missing. This one is copied of PhilE'

The file is called: sc16is752_0.dts
created with:

Code: Select all

sudo nano sc16is752_0.dts
The Overlay itself:

Code: Select all

/dts-v1/;
/plugin/;

/ {
    compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709";

    [email protected] {
        target = <&spidev1>;
        __overlay__ {
            status = "disabled";
        };
    };

    [email protected] {
        target = <&spi0>;

        frag1: __overlay__ {
            #address-cells = <1>;
            #size-cells = <0>;
            status = "okay";

            sc16is752: [email protected] {
                compatible = "nxp,sc16is752";
                reg = <0>; // CE0
                clocks = <&sc16is752_clk>;
                interrupt-parent = <&gpio>; 
                interrupts = <20 0x2>; //GPIO and falling edge
                gpio-controller;
                #gpio-cells = <0>;
                spi-max-frequency = <4000000>;
      status = "okay";

                sc16is752_clk: sc16is752_clk {
                    compatible = "fixed-clock";
                    #clock-cells = <0>;
                    clock-frequency = <1843200>;
                };
            };
        };
    };

    __overrides__ {
        int_pin = <&sc16is752>,"interrupts:0";
    };
};

After that, I checked my firmware with " uname -r " if it is >4.4 and yes it was because of that, I used the following command to create a dtbo-overlay:

Code: Select all

dtc [email protected] -I dts –O dtb –o sc16is752_0.dtbo sc16is752_0.dts


This was copied to the overlay folder:

Code: Select all

sudo cp sc16is752_0.dtbo /boot/overlays/
and activated in the " /boot/config.txt ". In the config.txt I added the Name of the file dtoverlay=sc16is752_0
I saved it and restarted the Pi.


Check if everything works:

Code: Select all

lsmod
(here I have the file “sc16is7xx”)

Code: Select all

sudo vcdbg log msg

(here is “Loaded overlay ‘sc16is752_0’”)

Code: Select all

ls –l /dev/ttyS*

(and here are the Pi’s UART Ports: /dev/ttyS0 /dev/ttySC0 /dev/ttySC1)


Sample Code
UART communication with python:
You can connect RXT and TXD, to check if it works

Code: Select all

import serial
ser = serial.Serial(“/dev/ttySC1“) # Open named port
ser.baudrate = 9600  # Set baud rate to 9600
data_s = “Hallo”
ser.write(data_s.encode(‘ascii’))  # Send data to the receiver
data_r = ser.read(5)  # Read 5 bytes
ser.close
print("Data sent: " + str(data_s))
print("Data received: " + str(data_r))
GPIO control from Terminal:
Look in /sys/class/gpio/ which number your device has. My one was 504

Code: Select all

echo 504 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio504/direction
echo 1 > /sys/class/gpio/gpio504/value
EDIT1: Error correction *18.08.2016
EDIT2: Added SPI *30.08.2016
EIDT3: Added Sample Code *11.11.2016
Last edited by MasterWuff on Sat Nov 12, 2016 10:37 am, edited 2 times in total.

danka90
Posts: 1
Joined: Mon Sep 12, 2016 1:32 pm

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Mon Sep 12, 2016 1:37 pm

Thank you for your descreption, I followed it, but I get an error after Raspberry reboot. I don't have /dev/ttySC* devices and in dmesg output I find the following:
[ 4.257388] /soc/[email protected]/[email protected]: could not get #clock-cells for /soc/[email protected]
[ 4.257519] sc16is7xx: probe of 1-004d failed with error -2
What did I wrong?

Regards,

Daniel

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 1828
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Tue Sep 13, 2016 9:00 am

Error -2 is -ENOENT - "No such file or directory" - in other words it can't find a device at address 4D. Without any other evidence I suspect a wiring fault.

Try "sudo i2cdetect -y 1", which will scan the I2C1 bus for devices - you should see something at address 4D.

paulenuta
Posts: 29
Joined: Fri Oct 28, 2016 5:59 am
Location: Romania

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Thu Nov 03, 2016 10:13 am

Thanks a lot PhilE for this:
by PhilE » Wed Jul 13, 2016 9:25 am
I think I've found the problem. Although DT clocks are located using their phandles (references to labels - "<&sc16is752_clk>"), the clock framework expects clocks to have unique names. In the DT case the name can either come from the "clock-output-names" property or, in its absence, the name of the node that declares the clock. Because in your case the clock nodes both have the same name (which in my opinion ought to be OK because they are effectively local to each device), the second clock instance never gets created and the second driver instance hangs around waiting for it.

Renaming the clock nodes..
I got now 4 UARTS with 2 sc16is752 on I2C.

raspnoobin
Posts: 2
Joined: Tue Dec 13, 2016 5:21 pm

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Tue Dec 13, 2016 6:03 pm

First of all I'd like to thank you all for the help I got from this thread and of course also a huge thank you for the people who wrote the module/dts files!

I successfully connected two sc16IS752 via I2C to my PI (IC1 -> ttySC0, ttySC1; IC2 -> ttySC2, ttySC3) and all seemed to work perfectly.

I then started a "stress test" this afternoon to see how it all behaves under heavy load and encountered a problem. If I send data simultaneously asynchronous between the ICs on all four ports ( ttySC0 <-> ttySC3 and ttySC1 <-> ttySC2, two parallel running scripts) the communication will hang sooner or later.

It would appear as if both ICs throw interrupts at the same time and one of them gets ignored and the IRQ never read out/cleared (see attached image).


To allow 4 UARTs I changed the DT clock part as follows (the second dts-file uses "_2" instead of "_1", GPIOs in use for the IRQs are 20 and 21):

Code: Select all

sc16is752_clk_1: sc16is752_clk_1 {
                    compatible = "fixed-clock";

		    clock-output-name = "sc16is752_clk_1";

                    #clock-cells = <0>;
                    clock-frequency = <1843200>;
                };
Other than this I didn't change anything and followed the instructions in this thread to the letter.


Does anyone have an idea what the problem could be?


I'm new to the PI and have not even a clue about device tree overlays. Every bit of help is therefore very much appreciated!


Edit: I changed the GPIO pin of one of the ICs from 20 to 27. Now I at least get an exception and it no longer just hangs.

Code: Select all

Traceback (most recent call last):
  File "./i2cUartTest_12_loop.py", line 16, in <module>
    data_r = ser0.read(4)  # Read 4 bytes
  File "/usr/lib/python2.7/dist-packages/serial/serialposix.py", line 460, in read
    raise SerialException('device reports readiness to read but returned no data (device disconnected?)')
serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected?)
It might very well be a problem of my testing script. I'll also test combinations of different IRQ-GPIOs as soon as I have the time for it.

I'm nonetheless very thankful for any help/idea on how to fix this! Thank you.
Attachments
RP_SC16IS752_IRQ_error_32.png
Both channels are the IRQ lines of the two SC16IS752's.
RP_SC16IS752_IRQ_error_32.png (29.85 KiB) Viewed 7309 times

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 1828
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Wed Dec 14, 2016 2:47 pm

That's interesting - there's an ongoing thread on GitHub (https://github.com/raspberrypi/linux/issues/1490) where people have seen a similar problem with two mcp2515 SPI-connected CAN bus controllers. That thread does include a hardware solution (more of a workaround, really), but we'd like to fix the underlying driver bug (if that's what it is).

It sounds like you may have stumbled on a simpler test scenario - two pairs of UARTs wired back-to-back sounds manageable. If you can post your test script and give some idea how long it takes to fail, it would lower the barrier to a solution even further.

raspnoobin
Posts: 2
Joined: Tue Dec 13, 2016 5:21 pm

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Wed Dec 14, 2016 4:21 pm

PhilE wrote:That's interesting - there's an ongoing thread on GitHub (https://github.com/raspberrypi/linux/issues/1490) where people have seen a similar problem with two mcp2515 SPI-connected CAN bus controllers. That thread does include a hardware solution (more of a workaround, really), but we'd like to fix the underlying driver bug (if that's what it is).

It sounds like you may have stumbled on a simpler test scenario - two pairs of UARTs wired back-to-back sounds manageable. If you can post your test script and give some idea how long it takes to fail, it would lower the barrier to a solution even further.
Thank you very much for your quick reply! I'll have a look at that thread. For now I managed to reassign the UARTs so that this case can't occur since in my case the communication on the four UARTs isn't really independent/asynchronous.


If we cross both UARTS as stated in my initial post, the communication will fail within a few seconds in most cases, minutes at most. So it's very easy to reproduce.
My two testing scripts are very simple though and since I reassigned the GPIOs for the IRQs it no longer hangs but I do get a proper exception (see the "Edit" at the end of my initial post). In this case one script will throw the exception and the other one will continue to work properly.
In the case of IRQ GPIOS 20 and 21 both scripts hanged as if they where waiting for data that never arrived. I haven't had time yet to test other combinations of GPIOs for the IRQs.


Here are my scripts (I changed them a bit before arriving at their current state, so there's some useless leftovers/clutter. I just left them exactly as I used them).


ttySC0 <-> ttySC3:

Code: Select all

#!/usr/bin/python

import serial
ser1 = serial.Serial("/dev/ttySC0") # Open named port
ser1.baudrate = 9600  # Set baud rate to 9600

ser0 = serial.Serial("/dev/ttySC3") # Open named port
ser0.baudrate = 9600  # Set baud rate to 9600

data_s = "test"

while True:
	ser1.write(data_s.encode('ascii'))  
	print("ser0_sent: " + str(data_s))

	data_r = ser0.read(4)  # Read 4 bytes
	print("ser3_read: " + str(data_r))

	ser0.write(data_r.encode('ascii'))
	print("ser3_sent: " + str(data_r))

	data_r1 = ser1.read(4)  # Read 4 bytes
	print("ser0_read: " + str(data_r1))

ser0.close
ser1.close

print("ser.closed()")



ttySC1 <-> ttySC2:

Code: Select all

#!/usr/bin/python

import serial
ser1 = serial.Serial("/dev/ttySC1") # Open named port
ser1.baudrate = 9600  # Set baud rate to 9600

ser0 = serial.Serial("/dev/ttySC2") # Open named port
ser0.baudrate = 9600  # Set baud rate to 9600

data_s = "test"

while True:
	ser1.write(data_s.encode('ascii'))  
	print("ser1_sent: " + str(data_s))

	data_r = ser0.read(4)  # Read 4 bytes
	print("ser2_read: " + str(data_r))

	ser0.write(data_r.encode('ascii'))
	print("ser2_sent: " + str(data_r))

	data_r1 = ser1.read(4)  # Read 4 bytes
	print("ser1_read: " + str(data_r1))

ser0.close
ser1.close

print("ser.closed()")


If there's anything else I can contribute to help solving this problem please let me know.

martinayotte
Posts: 3
Joined: Fri Dec 07, 2012 9:28 pm

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Sun Dec 18, 2016 10:20 pm

Renaming the clock nodes (and the overlays themselves to be more logical), I ended up with these
Hi PhilE,

I've unfortunately issue with the clock using kernel 4.9, it is failing while doing the devm_clk_get() call.
After some searches, I found the following in this page https://www.raspberrypi.org/documentati ... ce-tree.md
Adding clocks under the /clocks node at run-time doesn't cause a new clock provider to be registered, so devm_clk_get will fail for a clock created in an overlay
The only way I got it working is to place the clock DT definition in the main DTB.

Do you have any clues about that ?

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 1828
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Mon Dec 19, 2016 7:22 am

I can't try anything till the new year, so this is just a best guess. On the 4.9 tree we are using a real clock manager, so that may be causing some issues. However there should be nothing stopping us having more than one clock controller, in the same way that we can have more than one GPIO controller.

My comment about adding clocks at runtime applied to using the dtoverlay command line utility. Although the fundamental support for changing the Device Tree at runtime is in the mainline Linux kernel, it isn't useful without some downstream patches which are only found in distros for boards like the Pis and BeagleBones, so some aspects of the kernel don't react, or react well, when an overlay is loaded or unloaded.

How are you applying the overlay now - in config.txt or from a shell?

percramer
Posts: 5
Joined: Thu Aug 09, 2012 12:01 pm

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Mon Jan 02, 2017 1:55 pm

Hi,

i am currently designing a pcb which gives me additional uarts. I now have got i SC16IS752 planned (through i2c), but i prefer 2. I was wondering how your overlay looks like, how to specify the 2 addresses of the 2 ic's.

Regards,

Per

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 1828
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Mon Jan 02, 2017 10:04 pm

You will find the I2C address of the device in the "reg" property of the device node in the overlay in MasterWuff's earlier post (viewtopic.php?p=1024636#p1024636). The address also appears in the node name ([email protected]), although this is really just to follow convention and to "uniquify" it - the kernel ignores the name.

Redguy
Posts: 3
Joined: Mon Nov 28, 2016 10:19 am

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Mon Jan 09, 2017 2:27 pm

I am using the SC16IS752 connected to my raspberry as well, which works okay.. As RS232 uarts..


The datasheet for the chip states that by setting bit 4 of the EFCR register, this chip is capable of driving the direction of a RS232<->RS485 transceiver like the MAX485 through the RTS pin. Once this bit is set, the Uart will take care of the direction itself, which I would prefer above doing this through software using a separate GPIO on the Raspbery Pi.

I took a look at the contents of the .DTS file for the SC16IS752, but this seems to mainly control the connection between the Raspberry and the SC16IS752 chip (SPI, irq pin, clock settings etc.), so my guess would be that the settings I need would have to be set in the driver itself ?

Or is there any way to add these settings to the .DTS file ?

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 1828
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Mon Jan 09, 2017 2:32 pm

The device tree binding are documented here: https://github.com/raspberrypi/linux/bl ... 6is7xx.txt
As you suspected, it only describes how the SC16IS7XX is connected to the host, not how it is configured internally.

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 5563
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Mon Jan 09, 2017 3:11 pm

(Duplicate post to viewtopic.php?f=44&t=170855)

Device tree bindings for RS485 capable UARTs appear to be documented in https://github.com/raspberrypi/linux/bl ... /rs485.txt and imply that property "linux,rs485-enabled-at-boot-time" allows the device to be set into RS485 mode at boot.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
Please don't send PMs asking for support - use the forum.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

PabloP
Posts: 3
Joined: Wed Feb 08, 2017 2:38 pm

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Thu Feb 09, 2017 1:54 pm

Hello to all!

I continued the steps of MasterWuff and of the dts sc16is752-spi1-overlay. dts located in linux / arch / arm / boot / dts / overlays/.

dmesg-l err: without errors.
/dev/ttySC0 and/dev/ttySC1 loaded.

NXP SC16IS752 <-> Raspberry Pi
SCLK <-> Pin11
CS <-> Pin8
SO <-> Pin9
SI <-> Pin10
IRQ <-> Pin16
RESET <-> Pin17
All with function ALT0 formed.

Overlay config.

Code: Select all

/dts-v1/;
/plugin/;

/ {
        compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709";

        [email protected] {
            target = <&spidev0>;
            __overlay__ {
                status = "disabled";
            };
        };

        [email protected] {
                target = <&spi0>;
                frag1: __overlay__ {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        pinctrl-names = "default";
                        cs-gpios = <&gpio 8 0>;
                        status = "okay";

                        sc16is752: [email protected] {
                                compatible = "nxp,sc16is752";
                                reg = <0>; /* CE0 */
                                clocks = <&sc16is752_clk>;
                                interrupt-parent = <&gpio>;
                                interrupts = <16 2>; /* IRQ_TYPE_EDGE_FALLING */
                                #gpio-controller;
                                #gpio-cells = <2>;
                                spi-max-frequency = <4000000>;

                                sc16is752_clk: sc16is752_clk {
                                        compatible = "fixed-clock";
                                        #clock-cells = <0>;
                                        clock-frequency = <14745600>;
                                };
                        };
                };
        };

        [email protected] {
                target = <&aux>;
                __overlay__ {
                        status = "okay";
                };
        };
};
And raspi-gpio config.

Code: Select all

GPIO 08: level=1 fsel=1 alt=  func=OUTPUT
GPIO 09: level=0 fsel=4 alt=0 func=SPI0_MISO
GPIO 10: level=0 fsel=4 alt=0 func=SPI0_MOSI
GPIO 11: level=0 fsel=4 alt=0 func=SPI0_SCLK
GPIO 12: level=0 fsel=0 alt=  func=INPUT
GPIO 13: level=0 fsel=0 alt=  func=INPUT
GPIO 14: level=1 fsel=4 alt=0 func=TXD0
GPIO 15: level=1 fsel=4 alt=0 func=RXD0
GPIO 16: level=0 fsel=0 alt=  func=INPUT
GPIO 17: level=1 fsel=1 alt=  func=OUTPUT
After this introduction, I comment on my problem. The port /dev/ttySC0 does not work correctly. The example in python is supported in READ without returning and a testing program in C that writes and reads for the port, READ returns that it does not find any fact.

Some suggestion?

tom.k.cook
Posts: 47
Joined: Fri Jun 22, 2012 8:51 am

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Wed Mar 15, 2017 5:52 pm

Thanks for a very helpful writeup. I've got a Pi with two SC16IS752s connected by I2C. I wonder if you could clear up two points for me:

1. According to the datasheet, the I2C addresses are in the range 0x90 to 0xAE and I thought I had selected addresses 0x98 and 0xAE, but i2cdetect shows devices at 0x4C and 0x57. These are half the values the datasheet says it could be. Where does this doubling / halving of the addresses come from?
2. I've used a GPIO to drive the SC16IS752's RESET line. Is there some way to tell the driver this, so that it automatically sets the RESET line high before addressing the device?

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 1828
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Fri Mar 17, 2017 9:34 am

Where does this doubling / halving of the addresses come from?
I2C addresses are really 7 bits long, but the inclusion of the direction bit as the LSB (which is where it is transmitted) makes it look like an 8-bit address which is even for reads and odd for writes. Some vendors confusingly give the 8-bit form, with different addresses for read and write, but I2C addresses should really be in the range 0x04(3?) to 0x77.
Is there some way to tell the driver this, so that it automatically sets the RESET line high before addressing the device?
Sorry, not that I can see.

svktylmz
Posts: 2
Joined: Thu Feb 25, 2016 12:51 pm

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Thu Jul 27, 2017 1:53 pm

Hello everyone;

i try to explain my setup and question. i setup the system as the post explained. when i send data from ttySC0 to ttySC1 or (with 2 SC16is752 ) ttySC0 to ttySC2, it receives the data about 10 seconds later. Do you have any idea why? code that im using same as instructed in the post.

thanx

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 1828
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Thu Jul 27, 2017 2:44 pm

10 seconds sounds like a timeout - I suspect the data is delivered immediately but not detected until later. Do you have your IRQ lines wired up correctly? As a test, you could try sending data in the other direction (or use the onboard serial port) to see where the delay occurs.

krazykyran
Posts: 2
Joined: Tue Jul 26, 2016 2:55 pm

Re: SC16IS752 (SC16IS7XX driver) Device Tree problem

Mon May 14, 2018 12:56 am

I concur with raspnoobin regarding the lockup issues with the SC16IS752 when using both serial ports at the same time.

I have designed a CM3 IO board using the SC16IS752 connected to SPI1, using the device tree overlay "sc16is752-spi1.dtbo", and have noticed the following characteristics.
1. RTS/CTS doesnt work (at all) and this is an issue in the sc16is7xx driver, there are patches available on google to explain why, and it is relatively straightforward to experts to fix and recompile, and copy the .ko file into the /lib/modules/xxx/kernel/drivers ..... folder.
2. When using both ttySC0 and ttySC1 ports under high load, or doing a test like raspnoobin has done, the chip will lockup, meaning the IRQ line is always low (asserted) and nothing except a reset will fix this issue.

After looking into the driver code, I see a potential issue in sc16is7xx.c (line 694) here:

Code: Select all

static void sc16is7xx_ist(struct kthread_work *ws)
{
	struct sc16is7xx_port *s = to_sc16is7xx_port(ws, irq_work);
	int i;

	for (i = 0; i < s->devtype->nr_uart; ++i)
		sc16is7xx_port_irq(s, i);
}

static irqreturn_t sc16is7xx_irq(int irq, void *dev_id)
{
	struct sc16is7xx_port *s = (struct sc16is7xx_port *)dev_id;

	kthread_queue_work(&s->kworker, &s->irq_work);

	return IRQ_HANDLED;
}
What I see here is that when the IRQ line goes low (asserted) the sc16is7xx_irq function gets called, which fires off a worker thread called sc16is7xx_ist, which loops through all ports on the sc16is752 chip, processing anything that may have triggered the IRQ.
Normally this works, however consider this case:
1. port ttySC0 triggers IRQ as it receives data, port ttySC1 may have data to be read in its buffer too.
2. IRQ starts worker thread, port ttySC0 is handled first. IRQ line stays low until all events that may have triggered IRQ are handled.
3. worker thread moves on to port ttySC1 and handles all events that may have triggered IRQ.
4. while port ttySC1 is being handled by the worker thread, another interrupt event occurs on port ttySC0
5. worker thread completes its tasks, successfully reading and processing all interrupt events on both ports.
6. IRQ line stays low, because an interrupt event occurred on port ttySC0, which never gets handled by the kernel, because the IRQ line never got a chance to go high before the next interrupt occurs. This causes a lockup.

So the only way out of this issue I see, is that the state of the IRQ line needs to be read inside the sc16is7xx driver.
I am not an expert in kernel module driver coding, but I wonder if someone out there does know how to implement some GPIO read on the IRQ line, then this issue can be fixed.
The second gripe I have is that patches have been submitted to this kernel driver, that havent made it into upstream, even more than 2 years later.

So ... do we need to call this driver by another name, so that we can use it in raspberrypi linux github, so our community can use this chip successfully without kernel upgrades overwriting changes ?

Return to “Device Tree”

Who is online

Users browsing this forum: No registered users and 2 guests