jaf
Posts: 12
Joined: Sat Dec 05, 2015 3:32 pm

Configure sc16is7xx chip on compute module

Sun Dec 13, 2015 4:43 pm

Hello everybody:

My name is Jorge and I am in a project where I need to use an i2c bus connected Raspberri pi sc16is752 a chip. Raspbian use jessie version with kernel version 4.1.3+

I compiled the module sc16is7xx.ko with result ok and now I do not know how to use it. If I'm not mistaken, now I need to configure the chip inside the device-tree system, but do not know how.

I saw that in the url "http://lxr.free-electrons.com/source/Do ... .txt?v=4.1" There is information on how to configure the device tree, but I don't understand how to do it .

I appreciate your help.

Thank you so much

Best regards

jaf
Posts: 12
Joined: Sat Dec 05, 2015 3:32 pm

Re: Configure sc16is7xx chip on compute module

Wed Dec 16, 2015 5:07 am

Hello everybody:

I have gone a little further with my problem. I explain:

The first thing I had to do is run the command:

sudo rpi-update

Once executed, it has generated the "/boot/bcm2708-rpi-cm.dtb" file

This file I obtained the .dts by DTC tool and editing a plain text editor (vi), I have seen the hardware architecture elements which is supposed my RP.

Now I have doubt as to include my chip sc16is752 in this file (if so how to do it) or create a new file containing the configuration of the chip and is in turn linked / connected to the bus i2c1de RP

Within the kernel source code, I have seen that there is the following file:

"..... / Linux_kernel_src / Documentation / devicetree / bindings / serial / NXP, sc16is7xx.txt" with the following contents:

* NXP advanced SC16IS7xx Universal Asynchronous Receiver-Transmitter (UART)

Required properties:
- Compatible: Should be one of the following:
 - "Nxp, sc16is740" for NXP SC16IS740,
 - "Nxp, sc16is741" for NXP SC16IS741,
 - "Nxp, sc16is750" for NXP SC16IS750,
 - "Nxp, sc16is752" for NXP SC16IS752,
 - "Nxp, sc16is760" for NXP SC16IS760,
 - "Nxp, sc16is762" for NXP SC16IS762.
- Reg: SC16IS7xx I2C address of the device.
- Interrupt-parent: The phandle for the interrupt controller That
 For This IC interrupts services.
- Interrupts: Should Contain the UART interrupt
- Clocks: Reference clock source to the IC.

Optional properties:
- Gpio-controller: Marks the device as a GPIO controller node.
- # Gpio-cells: Should be two. The first cell is the number and GPIO
 the second cell is used to specify the GPIO polarity:
 0 = active high,
 1 = active low.

Example:
 sc16is750: sc16is750 @ 51 {
 Compatible = "nxp, sc16is750";
 reg = <0x51>;
 clocks = <& clk20m>;
 interrupt-parent = <& GPIO3>;
 interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
 gpio-controller;
 # Gpio-cells = <2>;
 };



I understand that with the example that brings it could generate an dts for the device, generating the dbt, copy it to the / boot / overlys or directly include the configuration of this chip in /boot/bcm2708-rpi-cm.dts file ( generate DTB), set something in the config.txt file and restart.

Once all these steps, and after rebooting, should appear in the / dev two new devices one for each UART, for example / dev / sc16x1 and / dev / sc16x2

- Does anyone know if this is so?
- How is it done?
- How do I build the .dts file?
- What needs to be put in the file /boot/config.txt?

On the other hand, how or where the system indicates that the chip is connected to the i2c-1 like me?

Thank you all for your help

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

Re: Configure sc16is7xx chip on compute module

Wed Dec 16, 2015 9:53 pm

You didn't mention your IRQ and clock arrangements, or which I2C address you are going to use. I'm going to assume you are using I2C address 0x51 (see Table 32 in the manual for the configuration required - just divide the address shown by 2, so 0xa2 becomes 0x51).

Something like this ought to work:

Code: Select all

// Overlay for the SC16IS752 I2C-connected UART
/dts-v1/;
/plugin/;

/ {
        compatible = "brcm,bcm2708";

        [email protected] {
                target = <&i2c_arm>;
                __overlay__ {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "okay";

			sc16is752: [email protected] {
				compatible = "nxp,sc16is752";
				reg = <0x51>;
				clocks = <&sc16is752_clock>;
				interrupt-parent = <&gpio>;
				interrupts = <255 2>; /* high-to-low edge triggered */
				gpio-controller;
				#gpio-cells = <2>;
			};
                };
        };

        [email protected] {
                target = <&clocks>;
                __overlay__ {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "okay";

			sc16is752_clock: [email protected] {
				compatible = "fixed-clock";
				reg = <10>;
				#clock-cells = <0>;
				clock-output-name = "sc16is752";
				clock-frequency = <0>;
			};
                };
        };

        [email protected] {
                target = <&gpio>;
                __overlay__ {
			sc16is752_pins: sc16is752_pins {
                                brcm,pins = <255>;
                                brcm,function = <0>; /* in */
			};
                };
        };

        __overrides__ {
                clkrate = <&sc16is752_clock>,"clock-frequency:0";
                irqpin = <&sc16is752>,"interrupts:0",
                	<&sc16is752_pins>,"brcm,pins:0";
        };
};
Call it sc16is752-i2c-overlay.dts, compile it to sc16is752-i2c-overlay.dtb using

Code: Select all

dtc [email protected] -I dts -O dtb -o sc16is752-i2c-overlay.dtb sc16is752-i2c-overlay.dts
Copy the .dtb into /boot/overlays and use it like this:

Code: Select all

dtoverlay=sc16is752-i2c,clkrate=48000000,irqpin=21

tomd
Posts: 1
Joined: Tue Dec 22, 2015 1:01 am

Re: Configure sc16is7xx chip on compute module

Tue Dec 22, 2015 1:18 am

Hi Jorge,

Your question about this chip came up at the same time I was working on the same problem. Being very new to this sort of stuff when I began, it took a long time to get right, so hopefully this will save you some time on your quest to get this chip working.

The biggest issue with using this chip with Raspberry Pi is that the driver that is packaged with the latest Pi kernel is broken, and seems to allow sending but not receiving data. This has been updated in the mainline Linux kernel, but it looks like the Pi kernel isn't going to get updated any time soon. I took the source code from the newer driver and took out all the code relating to checking the config options that aren't supported by the Pi kernel - CONFIG_SC16IS7XX_I2C/SPI from memory.

The device tree overlay I used is as follows:

Code: Select all

  GNU nano 2.4.2                  File: sc16is752-overlay.dts                                            

    // Definitions for SC16IS752 UART
    /dts-v1/;
    /plugin/;

    / {
       compatible = "brcm,bcm2708";

       [email protected] {
          target = <&i2c1>;
          __overlay__ {
             #address-cells = <1>;
             #size-cells = <0>;
             status = "okay";

             sc16is752: [email protected] {
                compatible = "nxp,sc16is752";
                reg = <0x4D>;
                clocks = <&klok>;
                interrupt-parent = <&gpio>;
                interrupts = <23 0x2>; /* falling edge */

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

This is a modified version of a dts from this thread on this forum viewtopic.php?t=112048&p=793204

The things you may have to change are the address (reg) and the interrupts depending on how you have set them up.

Also check that your hardware is set up correctly! I had many issues with pins being pulled high when the should be low etc etc.

Good luck with this!

Tom

jaf
Posts: 12
Joined: Sat Dec 05, 2015 3:32 pm

Re: Configure sc16is7xx chip on compute module

Mon Dec 28, 2015 4:06 pm

Hey there:

First of all thank you very much for all your help.

Here I put the results of the tests upon the comments from PhilE and Tomd:


---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
PhilE:

I generated the "sc16is752-i2c-overlay.dts" and I file "compiled" as "sc16is752-i2c-overlay.dtb" correctly. Then I copied to the /boot/overlays"and restart the RP.
 
After restarting, if I run the "i2cdetect-and 1" command. It returns the following result:

     0 1 2 3 4 5 6 7 8 9 a b c d e f
00: - - - - - - - - - - - - -
10: - - - - - - - - - - - - - - - -
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: - - - - - - - - - - - - - - - -
40: - - - - - - - - - - - - - 4d - -
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: - - - - - - - - - - - - - - - -
70: - - - - - - - -

Should this "4d" value be used in any part of the file ".dts" before generating the ".dtb"?


If I run the "sudo vcdbg log msg" command, following log show you the results:

012803.085: Loaded overlay 'sc16is752-i2c'
012803.103: dtparam: clkrate = 48000000
012803.669: dtparam: irqpin = 21
012804.561: dtparam: i2c_arm = on
012827.871: dtparam: cache_line_size = 32
012861.861: gpioman: gpioman_get_pin_num: attempting to get pin number for SMPS_SDA before we're ready
012861.888: gpioman: gpioman_get_pin_num: attempting to get pin number for SMPS_SCL before we're ready

---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------



---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
Tomd:

Same case as with PhilE file. I took .dts code file, I have generated the DTB, but after restarting, I do not know how to continue. What it appears to me after running the command "i2cdetect-and 1" is the same as in the previous case, and from here, I do not know how to continue.


If I run the "sudo vcdbg log msg" command, following log shows you the results:

012799.226: Loaded overlay 'sc16is752-i2c'
012799.244: dtparam: clkrate = 48000000
012800.594: Unknown dtparam 'clkrate' - ignored
012800.609: dtparam: irqpin = 21
012801.960: Unknown dtparam 'irqpin' - ignored
012801.985: dtparam: i2c_arm = on
012815.342: dtparam: cache_line_size = 32
012848.507: gpioman: gpioman_get_pin_num: attempting to get pin number for SMPS_SDA before we're ready
012848.530: gpioman: gpioman_get_pin_num: attempting to get pin number for SMPS_SCL before we're ready

---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------


My questions are now as follows:

Supposing that previous steps are correct (the log files included show up a "normal" result), How is it supposed to continue? How is the chip available (usable) for the operating system?. We find no descriptor in /dev directory. Am I missing something?

How do I use it? Let me explain: I need to use one of the UART interfaces with a Xbee and the other UART for a RS485. How I do ?

My idea is that in the /dev directory should appear the new devices (one for each UART, one for XBEE one for RS485). How are these new interfaces identified in the /dev directory?.

What am I missing?.

Thanks again for your help!!!.


Best regards

marli
Posts: 1
Joined: Fri Feb 12, 2016 11:20 am

Re: Configure sc16is7xx chip on compute module

Fri Feb 12, 2016 11:24 am

Hello,

did you get any progress? I am now working on design of a new device with Raspberry, where I would appreciate a few more serial interfaces. I like the purpose of sc16is752, but I would like to know that interfacing with raspberry is not any big issue. Did you find a way how to interface the serial devices hangt on sc16is752?

Marli

User avatar
TBT
Posts: 18
Joined: Wed Oct 02, 2013 11:41 am

Re: Configure sc16is7xx chip on compute module

Thu Mar 24, 2016 8:32 am

Sorry for the late answer. I just randomly came across this thread while googling.

The ports are called /dev/ttySC0 and /dev/ttySC1. The naming part of the code seems not to work for more than 1 chip, since it will try to use /dev/ttySC0 and 1 again.
In case the SC16IS7xx is clocked using an external crystal, you have to define that (frequency) as a "fixed-clock" in the .dts and attach the chip to it. Sadly, I lost the original/working .dts and have only a "decompiled" .dts (from working .dtb) left, but that may be enough to get the idea. Just post If you need it.

As for the chip itself and it's driver: It works basically, but for example, the driver won't read the CTS and wont't write the RTS status (e.g. if you want to wait for CTS to go high to see if the other side is ready/connected or use RTS as device "reset"). Surely you can use any GPIO pin for that, but that's not portable. IIRC the chip's Auto-RTS/CTS, for simple hardware flow control, worked out of the box. Xon/Xoff seems to work too.

As a side note, in our device, there are random hiccups for (at least?) one user. I'm not sure where they're coming from. They are kind of related to those UARTs, but I don't know if the problem is in software, driver or hardware/external wiring.


Best regards
Andreas

jaf
Posts: 12
Joined: Sat Dec 05, 2015 3:32 pm

Re: Configure sc16is7xx chip on compute module

Sun Apr 24, 2016 9:07 pm

Hello:

Thanks for you help !!!

Explain in as much detail as possible everything I have done with this problem

We are integrating the sc16is752 chip with a Raspberry compute module. Our final objective is to obtain 2 UARTs from the I2C channel provided by the compute module.

We are facing difficulties accessing the UARTs from the Compute Module. I will explain first the electrical lay-out and then the configuration done in the Compute Module until now.

I try to be very clear explaining all what we have done. Some things may be evident, but I think they will be a good help for anyone dealing with similar problems. I hope advanced developers will understand. Specific questions are at the end of the mail.

The connections diagram is:

SC16IS752:
Image

Raspberry compute module:
Image


Focusing on sc16is752 connection:
Image


Therefore, the connection is between pins:
RaspberryPiComputeModule Pin-9 (SDA) to sc16is752 Pin-14
RaspberryPiComputeModule Pin-11 (SCL) to sc16is752 Pin-13

We use pool-up resistances (1.8K) in both signals.

Compute Module configuration:

I2C:
• The first step is to enable the i2c bus within the raspberry advanced options with the command:
raspi-config
• Install the i2c-tools with the command:
sudo apt-get install i2c-tools
• Once configured and installed the tools, execute command:
i2cdetect -y 1 (the 1 comes from the fact that we phisically use i2c 1)
• Output:
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- 4d -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
• We will use this “4d”, later in the .dts file

Module/driver:
We try now to generate upon the sources in Linux kernel (“sc16is7xx.c”), a file called “sc16is7xx.ko, which defines the way how the operating system will communicate with the chip sc16is752.
We have completed this step but we have here the doubt if there is any parameter we need to specify in the file to make is coherent with the specific Compute Module hardware. We are concerned that we do not define in any place the descriptors of the ports that we should use to access both UARTS. We have found some references in google to /dev/ttySC0 and /dev/ttySC1, but no parameter like this is defined nowhere, so we basically think something is missing.

The “sc16is7xx.c” file:
----
https://github.com/raspberrypi/linux/bl ... c16is7xx.c
----

Our “/boot/config.txt” file is configured like:
-------------------------------------------------------------------------------
# For more options and information see
# http://www.raspberrypi.org/documentatio ... fig-txt.md
# Some settings may impact device functionality. See link above for details

# uncomment if you get no picture on HDMI for a default "safe" mode
#hdmi_safe=1

# uncomment this if your display has a black border of unused pixels visible
# and your display can output without overscan
#disable_overscan=1

# uncomment the following to adjust overscan. Use positive numbers if console
# goes off screen, and negative if there is too much border
#overscan_left=16
#overscan_right=16
#overscan_top=16
#overscan_bottom=16

# uncomment to force a console size. By default it will be display's size minus
# overscan.
#framebuffer_width=1280
#framebuffer_height=720

# uncomment if hdmi display is not detected and composite is being output
#hdmi_force_hotplug=1

# uncomment to force a specific HDMI mode (this will force VGA)
#hdmi_group=1
#hdmi_mode=1

# uncomment to force a HDMI mode rather than DVI. This can make audio work in
# DMT (computer monitor) modes
#hdmi_drive=2

# uncomment to increase signal to HDMI, if you have interference, blanking, or
# no display
#config_hdmi_boost=4

# uncomment for composite PAL
#sdtv_mode=2

#uncomment to overclock the arm. 700 MHz is the default.
#arm_freq=800

# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on

# Uncomment this to enable the lirc-rpi module
#dtoverlay=lirc-rpi

# Additional overlays and parameters are documented /boot/overlays/README



# ----> I have tested here with different values matching the .dts file
# dtoverlay=sc16is752-i2c,clkrate=48000000,irqpin=21
dtoverlay=sc16is752-i2c,clkrate=100000,irqpin=22
# ----> I have tested here with i2c_arm=on and (i2c0=on and i2c1=on), since we found some reference that this second option was needed for raspberry compute module
#dtparam=i2c_arm=on
dtparam=i2c0=on
dtparam=i2c1=on
-------------------------------------------------------------------------------

We have tested with following dts files:
.dts version 1
-------------------------------------------------------------------------------
// Overlay for the SC16IS752 I2C-connected UART
/dts-v1/;
/plugin/;

/ {
compatible = "brcm,bcm2708";

[email protected] {
target = <&i2c_arm>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";

sc16is752: [email protected] { /*4d is the address identified with i2cdetect command*/
compatible = "nxp,sc16is752";
reg = <0x4d>;
clocks = <&sc16is752_clock>;
interrupt-parent = <&gpio>;
interrupts = <255 2>; /* high-to-low edge triggered */
gpio-controller;
#gpio-cells = <2>;
};
};
};

[email protected] {
target = <&clocks>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";

sc16is752_clock: [email protected] {
compatible = "fixed-clock";
reg = <10>;
#clock-cells = <0>;
clock-output-name = "sc16is752";
clock-frequency = <100000>;
};
};
};

[email protected] {
target = <&gpio>;
__overlay__ {
sc16is752_pins: sc16is752_pins {
brcm,pins = <255>;
brcm,function = <0>; /* in */
};
};
};

__overrides__ {
clkrate = <&sc16is752_clock>,"clock-frequency:0";
irqpin = <&sc16is752>,"interrupts:0",
<&sc16is752_pins>,"brcm,pins:0";
};
};
-------------------------------------------------------------------------------


.dts version 2
-------------------------------------------------------------------------------
// Definitions for SC16IS752 UART
/dts-v1/;
/plugin/;

/ {
compatible = "brcm,bcm2708";

[email protected] {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";

sc16is752: [email protected] { /*4d is the address identified with i2cdetect command*/
compatible = "nxp,sc16is752";
reg = <0x4D>;
clocks = <&klok>;
interrupt-parent = <&gpio>;
interrupts = <23 0x2>; /* falling edge */

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

The commands used to gerarate .dtb from .dts and .dts from .dtb are:
# Generate dtb from dts
dtc -O dtb -o nombre_de_fichero.dtbo -b [email protected] file_name.dts
# Generate dts from dtb
dtc -I dtb -O dts /boot/overlays/file_name.dtb > /path/file_name.dts



And now the questions:
• Is it needed to load the model sc16is7xx.ko and/or configure the device tree (one, other or both, we believe both)?.
• Is it needed to configure/adapt the sc16is7xx.c somehow?. Specially dealing with the access to /dev/ttySC0 and /dev/ttySC1. This is really our problem: we are not able to find these devices in our system.
• Is it needed to consider the sc16is7xx.c code to generate the .dts file for the device tree?. Do we need to change anything in .dts file?
• Is .dts version1 or version2 correct?. Which one should we use?. Any changes needed?
• Is there any file where the devices /dev/ttySC0 y /dev/ttySC1 should be declared?

I have tried to explain our configuration with maximum clarity, but if you think something is missing, please let me know.

Thanks for your support!!!

smirnov
Posts: 1
Joined: Fri Apr 29, 2016 1:29 pm

Re: Configure sc16is7xx chip on compute module

Fri Apr 29, 2016 2:41 pm

Hi jaf.
Is it needed to load the model sc16is7xx.ko and/or configure the device tree (one, other or both, we believe both)?.
Was your module compiled correct? I mean without warnings. If so you should load it with dependencies (read about depmod, modprobe commands).

I have successfully launched sc16is750 with Raspberry Pi 2.
During compilation I had warnings like "warning: 'sc16is7xx_probe' defined but not used". To get rid of it I used the following Makefile:

Code: Select all

KDIR = /lib/modules/$(shell uname -r)/build
PWD = $(shell pwd)
obj-m:= sc16is7xx.o
CFLAGS_sc16is7xx.o := -DCONFIG_SERIAL_SC16IS7XX_I2C
default: 
    $(MAKE) -C $(KDIR) M=$(PWD) modules 
Is it needed to configure/adapt the sc16is7xx.c somehow? Specially dealing with the access to /dev/ttySC0 and /dev/ttySC1. This is really our problem: we are not able to find these devices in our system. Is it needed to consider the sc16is7xx.c code to generate the .dts file for the device tree?. Do we need to change anything in .dts file?
No, the module works good without any changes. I created new device tree overlay sc16is750-tom-i2c-overlay.dts, compiled it and add to /boot/overlays/. I used code which was posted by tomd (but with little changes).

Code: Select all

/dts-v1/;
/plugin/;

/ {
    compatible = "brcm,bcm2709";
    
    [email protected] {
        target = <&i2c1>;
        __overlay__ {
            #address-cells = <1>;
            #size-cells = <0>;
            status = "okay";

sc16is750:
            [email protected] {
                compatible = "nxp,sc16is750";
                reg = <0x4D>;
                clocks = <&klok>;//<&clk_uart0>;
                interrupt-parent = <&gpio>;
                interrupts = <24 0x2>; /* falling edge */

klok:
                klok {
                    compatible = "fixed-clock";
                    #clock-cells = <0>;
                    clock-frequency = <14745600>;
                };
            };
        };
    };
};
According to this code I connect IRQ pin to gpio24 on Raspberry Pi.
Also I added the following lines to /boot/config.txt:

Code: Select all

dtoverlay=sc16is750-tom-i2c

dtparam=i2c1=on
dtparam=i2c1_baudrate=400000
If everything is fine /dev/ttySC0 will appear (you shouldn't declare it by yourself) and i2cdetect will looks like this (4d replaced by UU):

Code: Select all

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- UU -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --      
I hope my post will help. Good luck!

jaf
Posts: 12
Joined: Sat Dec 05, 2015 3:32 pm

Re: Configure sc16is7xx chip on compute module

Mon May 30, 2016 10:02 pm

Hello:

Thanks for your answer and sorry for taking so long to respond.

I have test all your indications, but I keep having problems.

The first step is to make sure the driver is loaded:


-------------------------------------------------------------------------------------------------------------------------
[email protected]:~$ lsmod
Module Size Used by
cfg80211 496721 0
rfkill 21180 1 cfg80211
i2c_bcm2708 5740 0
bcm2835_gpiomem 3823 0
bcm2835_wdt 4101 0
uio_pdrv_genirq 3737 0
uio 10121 1 uio_pdrv_genirq
sc16is7xx 12542 0
regmap_i2c 4078 1 sc16is7xx

i2c_dev 6169 0
ipv6 364716 31

I think that all it's ok
-------------------------------------------------------------------------------------------------------------------------






-------------------------------------------------------------------------------------------------------------------------
In the /boot/config.txt file, I have added the following lines:
dtdebug=1
dtoverlay=sc16is752-tom-i2c

dtparam=i2c1=on
dtparam=i2c1_baudrate=400000

( Only I change all references sc16is750 by sc16is752 )
-------------------------------------------------------------------------------------------------------------------------






-------------------------------------------------------------------------------------------------------------------------
Next step is view log of device tree and it has some faults:

[email protected]:~$ sudo vcdbg log msg


012860.706: dtdebug: Failed to open overlay file 'overlays/sc16is752-tom-i2c.dtbo'
012860.721: Failed to load overlay 'sc16is752-tom-i2c'

012860.751: dtparam: i2c1=on

I don't understand why puts ...dtbo, because I put into the overlays directory "overlays/sc16is752-tom-i2c.dtb"
-------------------------------------------------------------------------------------------------------------------------






-------------------------------------------------------------------------------------------------------------------------
The results of "i2cdetec -y 1" command is:

[email protected]:~$ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- 4d -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Not is UU, but the module is loaded correctly ( or at least I think so )
-------------------------------------------------------------------------------------------------------------------------





-------------------------------------------------------------------------------------------------------------------------
I have put into the sc16is7xx.c a lot of "printk" instructions for debug the execution functions init and exit and all its ok, but curiously the printk instructions writed into the probe function not are writed into the /var/log/kern.log ( I can view too with dmesg command )
-------------------------------------------------------------------------------------------------------------------------





-------------------------------------------------------------------------------------------------------------------------
I have the /proc/device-tree directory correctly generated, but I don't know interpret that it contains.
-------------------------------------------------------------------------------------------------------------------------




I do not know what I have bad or that is what I need to do more.

Thanks for your support !!!

DirkS
Posts: 9970
Joined: Tue Jun 19, 2012 9:46 pm
Location: Essex, UK

Re: Configure sc16is7xx chip on compute module

Tue May 31, 2016 10:27 am

jaf wrote:[email protected]:~$ sudo vcdbg log msg


012860.706: dtdebug: Failed to open overlay file 'overlays/sc16is752-tom-i2c.dtbo'
012860.721: Failed to load overlay 'sc16is752-tom-i2c'

012860.751: dtparam: i2c1=on

I don't understand why puts ...dtbo, because I put into the overlays directory "overlays/sc16is752-tom-i2c.dtb"
Did you update kernel / firmware to 4.4.y?
The system now expects the extension .dtbo instead of .dtb

jaf
Posts: 12
Joined: Sat Dec 05, 2015 3:32 pm

Re: Configure sc16is7xx chip on compute module

Wed Jun 01, 2016 8:50 pm

Hello:
Thanks for your answer.

----------------------------------------------------------------------------------------
I have resolved my problem. But in my case, not only was necessary change the file extension .dtb by dtbo, also I had that
create two files:

-rwxr-xr-x 1 root root 969 Jun 1 00:10 sc16is752-tom-i2c.dtbo
-rwxr-xr-x 1 root root 969 Jun 1 00:10 sc16is752-tom-i2c-overlay.dtb

and after a lot of tests, I saw that the name of .dtbo must be without -"overlay" and the name of .dtb must be with -"overlay"

The two files are same ( really .dtbo it's a copy of .dtb ) with the name changed.
----------------------------------------------------------------------------------------





----------------------------------------------------------------------------------------
Now, I cant see in the /dev directory the new devices:

[email protected]:~$ ls -l /dev/ttySC*
crw-rw---- 1 root dialout 245, 0 Jun 1 02:17 /dev/ttySC0
crw-rw---- 1 root dialout 245, 1 Jun 1 02:17 /dev/ttySC1
----------------------------------------------------------------------------------------




And I have made a simple c program, for open the two descriptors with ok results (aparently):

int main() {

int Lcl_FdSC0 = 0;
int Lcl_FdSC1 = 0;

Lcl_FdSC0 = open( "/dev/ttySC0", O_RDWR | O_NOCTTY | O_NDELAY);
Lcl_FdSC1 = open( "/dev/ttySC1", O_RDWR | O_NOCTTY | O_NDELAY);

printf("\nHELLO WORLD ttySC0: [%d]", Lcl_FdSC0);
printf("\nHELLO WORLD ttySC1: [%d]", Lcl_FdSC1);

return 0;
}

----------------------------------------------------------------------------------------

and the results:

----------------------------------------------------------------------------------------
HELLO WORLD ttySC0: [3]
HELLO WORLD ttySC1: [4]
----------------------------------------------------------------------------------------


Now, I am making tests.

Thanks to everybody for you support !!!!

jaf
Posts: 12
Joined: Sat Dec 05, 2015 3:32 pm

Re: Configure sc16is7xx chip on compute module

Thu Jun 02, 2016 9:56 pm

Hello:

I'm here again.

For make a first test, I'm trying to send string until the xbee conected on UART1 ( /dev/ttySC1 ) but don't run.

I have installed into raspberry the lilbrary "libxbee3" downloaded from "https://github.com/attie/libxbee3.git" and I'm trying with the most easy example. Here put the code:

--------------------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <xbee.h>

int main(void) {
void *d;
struct xbee *xbee;
struct xbee_con *con;
unsigned char txRet;
xbee_err ret;

/* setup libxbee, using the USB to Serial adapter '/dev/ttyUSB0' at 57600 baud */
// if ((ret = xbee_setup(&xbee, "xbee1", "/dev/ttyUSB0", 57600)) != XBEE_ENONE) {
if ((ret = xbee_setup(&xbee, "xbee1", "/dev/ttySC1", 9600)) != XBEE_ENONE) {
printf("ret: %d (%s)\n", ret, xbee_errorToStr(ret));
return ret;
}


/* create a new AT connection to the local XBee */
if ((ret = xbee_conNew(xbee, &con, "Local AT", NULL)) != XBEE_ENONE) {
xbee_log(xbee, -1, "xbee_conNew() returned: %d (%s)", ret, xbee_errorToStr(ret));
return ret;
}


/* send the AT command 'NI' (request the Node Identifier)
when the response is recieved, the packet will be directed to the callback function */
ret = xbee_conTx(con, &txRet, "NI");
/* print out the return value
if this is non-zero, then check 'enum xbee_errors' in xbee.h for its meaning
alternatively look at the xbee_errorToStr() function */
printf("tx: %d\n", ret);



// THIS IS MY TRACE
if (ret != 0 ) {printf("tx: %d - [%s]\n", ret, xbee_errorToStr(ret));}



if (ret) {
/* if ret was non-zero, then some error occured
if ret == XBEE_ETX then it is possible that txRet is now -17 / XBEE_ETIMEOUT
alternatively, txRet will contain the status code returned by the XBee */
printf("txRet: %d\n", txRet);
} else {
struct xbee_pkt *pkt;
if ((ret = xbee_conRx(con, &pkt, NULL)) != XBEE_ENONE) {
printf("Error after calling xbee_conRx(): %s\n", xbee_errorToStr(ret));
} else {
int i;
printf("Response is %d bytes long:\n", pkt->dataLen);
for (i = 0; i < pkt->dataLen; i++) {
printf("%3d: 0x%02X - %c\n", i, pkt->data, (((pkt->data >= ' ') && (pkt->data <= '~'))?pkt->data:'.'));
}
}
}

/* shutdown the connection */
if ((ret = xbee_conEnd(con)) != XBEE_ENONE) {
xbee_log(xbee, -1, "xbee_conEnd() returned: %d", ret);
return ret;
}

/* shutdown libxbee */
xbee_shutdown(xbee);

return 0;
}
--------------------------------------------------------------------------------------------



My trace prints:
tx: -17 - [A timeout occured]


How I cant test that the module, device-tree configuration, etc are runing correctly ? ( I have tried with /dev/ttySC0, but the results are the same )

I have writed a lot of printk(KERN_INFO, "text debug.....") into the functions of sc16is7xx.c, compile the module, rmmod sc16is7xx and insmod sc16is7xx.ko again, but I think that don't must be as dificult.

Please, somebody can say me, how can I found the problem ? or Am I making something wrong ?

Thanks again for your support

arturioxas
Posts: 1
Joined: Mon Jun 20, 2016 12:23 pm

Re: Configure sc16is7xx chip on compute module

Mon Jun 20, 2016 12:28 pm

Hello, I've been succesful in configuring SC16is752 to send and receive via RS-232 without any flow control but now I have to implement RS-485 which uses RTS pin to control direction. The problem is that only transmission works and RTS never becomes low. At first it was vice-versa, but later I spotted a soldering mistake. What kind of mistake could it be or is it software bug?

*edit - It was a software mistake - pySerial somehow fails to use its ioctl modules and as I wrote ioctl manually everything works fine

*edit - pySerial fails if you request delays after sending. As creator says: "Users of RS-485 can request via ioctl that RTS signals should be activated selected number of milliseconds before the actual data transmission or stay active after the transmission is finished. In sc16is7xx, however, RTS signalling is handled by the hardware and driver has no way of providing this feature". So be aware and don't use delays

armcapp
Posts: 9
Joined: Thu Jun 29, 2017 12:56 am

Re: Configure sc16is7xx chip on compute module

Tue Jul 11, 2017 5:01 pm

A while back TomD posted:
The biggest issue with using this chip with Raspberry Pi is that the driver that is packaged with the latest Pi kernel is broken, and seems to allow sending but not receiving data. This has been updated in the mainline Linux kernel, but it looks like the Pi kernel isn't going to get updated any time soon.
I've enabled the sc16is7xx driver editing my config.txt as follows:
# Overlay for the NXP SC16IS750 UART with I2C Interface
# Enables the chip on I2C1 at 0x48. To select another address,
# please refer to table 10 in reference manual.
dtoverlay=sc16is750-i2c,int_pin=24,addr=0x48

Writing to the driver (ttySC0) works fine. I see an I2C transfer from the pi to the NXP board and serial data on the NXP tx pin.

The problem is when send serial data to the NXP rx pin I would expect it to kick off an I2C read transfer from the PI, but the I2C lines show no activity.

Is what TomD mentioned still true. Are "reads" still broken?

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

Re: Configure sc16is7xx chip on compute module

Wed Jul 26, 2017 7:11 pm

Did anybody get any further with this? We have got the uart part working for an SC16IS762. Both uarts show and transmit data. But we want to use them in RS485 mode also and we can't get that working. If we write a little program to test it and use something like (which is invalid, i know, it is just to test the driver) :

struct serial_rs485 rs485conf;

rs485conf.flags |= SER_RS485_ENABLED;
//rs485conf.flags |= SER_RS485_RTS_ON_SEND;
//rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND);

if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {
/* Error handling. See errno. */
}

the driver does respond. It tells us :

unsupported RTS signalling on_send:%d after_send:%d - exactly one of RS485 RTS flags should be set

But if we send actual valid values for SER_RS485_RTS_ON_SEND then it fails with an ioctl error 22. And this error goes away if we comment out : rs485conf.flags |= SER_RS485_ENABLED;

There does show data up on the logic analyser if we run the above code (and then a correct version). But the correct registers never show up, so the enabling of the rs485 mode and the polarity register.

But i am a bit lost now on what to do. Manually change the driver and compile a new kernel? Isn't there anybody who has got this working with a current version of raspbian? It seemed to have worked with older versions if i read the posts on the internet.

Regards,

Per

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

Re: Configure sc16is7xx chip on compute module

Thu Jul 27, 2017 7:10 am

percramer wrote:
Wed Jul 26, 2017 7:11 pm
Did anybody get any further with this? We have got the uart part working for an SC16IS762. Both uarts show and transmit data. But we want to use them in RS485 mode also and we can't get that working. If we write a little program to test it and use something like (which is invalid, i know, it is just to test the driver) :

struct serial_rs485 rs485conf;

rs485conf.flags |= SER_RS485_ENABLED;
//rs485conf.flags |= SER_RS485_RTS_ON_SEND;
//rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND);

if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {
/* Error handling. See errno. */
}

the driver does respond. It tells us :

unsupported RTS signalling on_send:%d after_send:%d - exactly one of RS485 RTS flags should be set
What reasoning are you giving for it being invalid? The obvious one I see is that you appear to have allocated rs485conf on the stack and not initialised it. Setting/clearing individual bits after that point is likely to leave a mess in the rest of the structure.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

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

Re: Configure sc16is7xx chip on compute module

Thu Jul 27, 2017 11:32 am

Hi,

well it is just a small snippet of the program of course :)

It is invalid because the driver says :

static int sc16is7xx_config_rs485(struct uart_port *port,
struct serial_rs485 *rs485)
{
struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);

if (rs485->flags & SER_RS485_ENABLED) {
bool rts_during_rx, rts_during_tx;

rts_during_rx = rs485->flags & SER_RS485_RTS_AFTER_SEND;
rts_during_tx = rs485->flags & SER_RS485_RTS_ON_SEND;

if (rts_during_rx == rts_during_tx)
dev_err(port->dev,
"unsupported RTS signalling on_send:%d after_send:%d - exactly one of RS485 RTS flags should be set\n",
rts_during_tx, rts_during_rx);

/*
* RTS signal is handled by HW, it's timing can't be influenced.
* However, it's sometimes useful to delay TX even without RTS
* control therefore we try to handle .delay_rts_before_send.
*/
if (rs485->delay_rts_after_send)
return -EINVAL;
}

port->rs485 = *rs485;
one->config.flags |= SC16IS7XX_RECONF_RS485;
queue_kthread_work(&s->kworker, &one->reg_work);

return 0;
}

and since i am not passing SER_RS485_RTS_AFTER_SEND and SER_RS485_RTS_ON_SEND it will fail that check in the driver. But that was done on purpose to check if the data was reaching the drivers code.

What we tried is:

int fd = open("/dev/mydevice", O_RDWR);
if (fd < 0) {
/* Error handling. See errno. */
printf("ERROR! Open() failed \r\n");
}

struct serial_rs485 rs485conf;

rs485conf.flags |= SER_RS485_ENABLED;
rs485conf.flags |= SER_RS485_RTS_ON_SEND;
rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);
/* rs485conf.flags |= SER_RS485_RX_DURING_TX; */

if (ioctl(fd, TIOCSRS485, &rs485conf) < 0) {
/* Error handling. See errno. */
printf("ERROR! ioctl settings update failed \r\n");
}

char buffer_to_send[11] = "HELLO WORLD";
if (write(fd, buffer_to_send, sizeof(buffer_to_send)) != sizeof(buffer_to_send)) {
printf("ERROR! write() failed \r\n");
}

if (close(fd) < 0) {
/* Error handling. See errno. */
printf("ERROR! Close() failed \r\n");
}

And then open the correct port of course, just can't remember by head which on it was right now (and i am not near the device). And like i said, we do see data on the i2c bus, even data for the EFCR registers, but all that is set are the SC16IS7XX_EFCR_RXDISABLE_BIT and SC16IS7XX_EFCR_TXDISABLE_BIT. We never see the registers passing that we actually need (SC16IS7XX_EFCR_AUTO_RS485_BIT and SC16IS7XX_EFCR_RTS_INVERT_BIT).

We tried a lot already, so any help is really appreciated

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

Re: Configure sc16is7xx chip on compute module

Thu Jul 27, 2017 2:25 pm

So my point is I'd like to see either

Code: Select all

struct serial_rs485 rs485conf = {0};
if your compiler allows it, or

Code: Select all

rs485conf.flags = SER_RS485_ENABLED; //Note =, not |=
rs485conf.delay_rts_after_send = 0;
rs485conf.delay_rts_before_send = 0
Otherwise you have an uninitialised structure with potentially random things set in it.
The driver is checking delay_rts_after_send is 0, so that is important.

Having just had a discussion here, we're not convinced the driver code is correct in the error checking path if SER_RS485_RTS_AFTER_SEND and SER_RS485_RTS_ON_SEND are set.

Code: Select all

		bool rts_during_rx, rts_during_tx;

		rts_during_rx = rs485->flags & SER_RS485_RTS_AFTER_SEND;
		rts_during_tx = rs485->flags & SER_RS485_RTS_ON_SEND;

		if (rts_during_rx == rts_during_tx)
			dev_err(port->dev,
				"unsupported RTS signalling on_send:%d after_send:%d - exactly one of RS485 RTS flags should be set\n",
				rts_during_tx, rts_during_rx);
Bool is dependent on the compiler, and is often just a typedef of char. Assigning flags&RTS_AFTER_SEND to a char would give 4. Assigning flags&RTS_ON_SEND would give 2. 2 != 4, therefore no error message.

Code: Select all

		rts_during_rx = !!(rs485->flags & SER_RS485_RTS_AFTER_SEND);
		rts_during_tx = !!(rs485->flags & SER_RS485_RTS_ON_SEND);
would be the normal way of dealing with that in order to guarantee true/false as an answer.

Not withstanding that, the correct code path looks reasonable assuming that the sc16is7xx_reg_proc work queue is waking up appropriately to call sc16is7xx_reconf_rs485.

I was going to suggest that you could configure the chip for RS485 via device tree. As per docs http://elixir.free-electrons.com/linux/ ... /rs485.txt, adding

Code: Select all

		linux,rs485-enabled-at-boot-time;
		rs485-rts-delay = <0 0>;		// in milliseconds
to the relevant device tree overlay.
However having just checked the code, only 3 serial drivers check that, and sc16is7xx is not one of them :-(
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

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

Re: Configure sc16is7xx chip on compute module

Thu Jul 27, 2017 8:33 pm

Wow a lot of useful info. I am a c# programmer (and hardware developer) by trade, so i must admit that going back to good old c takes some getting used to again... But the issue is with the driver, we have got it working now. But only by altering the driver and recompiling it.

We get a correct behaviour of the rts line (for the rs485 transceiver we use it needs to go high on sending), and data is showing. I have added an image of our logic analyser ;)

Image

If the image doesn't show up then the link is https://ibb.co/fSujAQ

What we changed for testing is :

static int sc16is7xx_config_rs485(struct uart_port *port,
struct serial_rs485 *rs485)
{
const u32 mask = SC16IS7XX_EFCR_AUTO_RS485_BIT |
SC16IS7XX_EFCR_RTS_INVERT_BIT;
u32 efcr = 0;

if (rs485->flags & SER_RS485_ENABLED) {
bool rts_during_rx, rts_during_tx;

rts_during_rx = rs485->flags & SER_RS485_RTS_AFTER_SEND;
rts_during_tx = rs485->flags & SER_RS485_RTS_ON_SEND;

if (rts_during_rx == rts_during_tx)
dev_err(port->dev,
"Recompile van de driver werkt signalling on_send:%d after_send:%d - exactly one of RS485 RTS flags should be set\n",
rts_during_tx, rts_during_rx);
}

//unsigned long irqflags;
//spin_lock_irqsave(&port->lock, irqflags);
if (rs485->flags & SER_RS485_ENABLED) {
efcr |= SC16IS7XX_EFCR_AUTO_RS485_BIT;

if (rs485->flags & SER_RS485_RTS_AFTER_SEND)
efcr |= SC16IS7XX_EFCR_RTS_INVERT_BIT;
}
//spin_unlock_irqrestore(&port->lock, irqflags);

sc16is7xx_port_update(port, SC16IS7XX_EFCR_REG, mask, efcr);

port->rs485 = *rs485;

return 0;
}

It now sets the RS485 options as supposed. There are a few parts where the current driver seems to give issues :

1.
if (rs485->delay_rts_after_send)
return -EINVAL;

Gives an error. Could it be because the chip doesn't allow delays?

2.
one->config.flags |= SC16IS7XX_RECONF_RS485;
queue_kthread_work(&s->kworker, &one->reg_work);

Thread never seems to start or run. We have added extra debug messages in the function to test it.

3.
unsigned long irqflags;
spin_lock_irqsave(&port->lock, irqflags);

Locks everything. Still need to check out what it is meant to do though...

But i understand your points with the structure, those make sense. But i don't think they are causing the driver to fail though. What we have changed in our driver is partially code from a driver version of a few months ago.

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

Re: Configure sc16is7xx chip on compute module

Thu Jul 27, 2017 9:19 pm

Ouch, that sort of change shouldn't be necessary, but that's a nice bit of debugging.

This is all code from the upstream kernel, so really needs reporting there.

Code: Select all

host:~/Pi/linux$ ./scripts/get_maintainer.pl drivers/tty/serial/sc16is7xx.c 
Greg Kroah-Hartman <[email protected]> (maintainer:SERIAL DRIVERS)
Jiri Slaby <[email protected]> (supporter:TTY LAYER)
[email protected] (open list:SERIAL DRIVERS)
[email protected] (open list)
So [email protected] is probably the first place to ask (a search through the mailing list archives would be worth it first). You may need to subscribe first, at least to guarantee that you get the responses!

The other thing to do is to check out who/what is holding that spinlock. serial-core.c is doing some stuff with it around the call to port->rs485_config, but should be releasing it immediately afterwards, and therefore allowing the kthread_work do actually set stuff. Something should be handling calling spin_lock_init at some point, but I haven't looked out that code.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

Return to “Advanced users”