Configure sc16is7xx chip on compute module
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
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
Re: Configure sc16is7xx chip on compute module
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
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
-
- Raspberry Pi Engineer & Forum Moderator
- Posts: 4549
- Joined: Mon Sep 29, 2014 1:07 pm
- Location: Cambridge
Re: Configure sc16is7xx chip on compute module
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:
Call it sc16is752-i2c-overlay.dts, compile it to sc16is752-i2c-overlay.dtb using
Copy the .dtb into /boot/overlays and use it like this:
Something like this ought to work:
Code: Select all
// Overlay for the SC16IS752 I2C-connected UART
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2708";
fragment@0 {
target = <&i2c_arm>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
sc16is752: sc16is752@51 {
compatible = "nxp,sc16is752";
reg = <0x51>;
clocks = <&sc16is752_clock>;
interrupt-parent = <&gpio>;
interrupts = <255 2>; /* high-to-low edge triggered */
gpio-controller;
#gpio-cells = <2>;
};
};
};
fragment@1 {
target = <&clocks>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
sc16is752_clock: sc16is752_clock@10 {
compatible = "fixed-clock";
reg = <10>;
#clock-cells = <0>;
clock-output-name = "sc16is752";
clock-frequency = <0>;
};
};
};
fragment@2 {
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";
};
};
Code: Select all
dtc -@ -I dts -O dtb -o sc16is752-i2c-overlay.dtb sc16is752-i2c-overlay.dts
Code: Select all
dtoverlay=sc16is752-i2c,clkrate=48000000,irqpin=21
Re: Configure sc16is7xx chip on compute module
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:
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
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";
fragment@0 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
sc16is752: sc16is752@4D {
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>;
};
};
};
};
};
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
Re: Configure sc16is7xx chip on compute module
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
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
Re: Configure sc16is7xx chip on compute module
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
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
Re: Configure sc16is7xx chip on compute module
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
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
Re: Configure sc16is7xx chip on compute module
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:

Raspberry compute module:

Focusing on sc16is752 connection:

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";
fragment@0 {
target = <&i2c_arm>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
sc16is752: sc16is752@4d { /*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>;
};
};
};
fragment@1 {
target = <&clocks>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
sc16is752_clock: sc16is752_clock@10 {
compatible = "fixed-clock";
reg = <10>;
#clock-cells = <0>;
clock-output-name = "sc16is752";
clock-frequency = <100000>;
};
};
};
fragment@2 {
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";
fragment@0 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
sc16is752: sc16is752@4d { /*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 0-@ 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!!!
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:

Raspberry compute module:

Focusing on sc16is752 connection:

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";
fragment@0 {
target = <&i2c_arm>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
sc16is752: sc16is752@4d { /*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>;
};
};
};
fragment@1 {
target = <&clocks>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
sc16is752_clock: sc16is752_clock@10 {
compatible = "fixed-clock";
reg = <10>;
#clock-cells = <0>;
clock-output-name = "sc16is752";
clock-frequency = <100000>;
};
};
};
fragment@2 {
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";
fragment@0 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
sc16is752: sc16is752@4d { /*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 0-@ 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!!!
Re: Configure sc16is7xx chip on compute module
Hi jaf.
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:
According to this code I connect IRQ pin to gpio24 on Raspberry Pi.
Also I added the following lines to /boot/config.txt:
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):
I hope my post will help. Good luck!
Was your module compiled correct? I mean without warnings. If so you should load it with dependencies (read about depmod, modprobe commands).Is it needed to load the model sc16is7xx.ko and/or configure the device tree (one, other or both, we believe both)?.
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
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).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?
Code: Select all
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2709";
fragment@0 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
sc16is750:
sc16is750@4D {
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>;
};
};
};
};
};
Also I added the following lines to /boot/config.txt:
Code: Select all
dtoverlay=sc16is750-tom-i2c
dtparam=i2c1=on
dtparam=i2c1_baudrate=400000
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: -- -- -- -- -- -- -- --
Re: Configure sc16is7xx chip on compute module
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:
-------------------------------------------------------------------------------------------------------------------------
sip@RP01:~$ 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:
sip@RP01:~$ 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:
sip@RP01:~$ 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 !!!
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:
-------------------------------------------------------------------------------------------------------------------------
sip@RP01:~$ 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:
sip@RP01:~$ 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:
sip@RP01:~$ 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 !!!
Re: Configure sc16is7xx chip on compute module
Did you update kernel / firmware to 4.4.y?jaf wrote:sip@RP01:~$ 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 system now expects the extension .dtbo instead of .dtb
Re: Configure sc16is7xx chip on compute module
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:
sip@RP01:~$ 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 !!!!
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:
sip@RP01:~$ 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 !!!!
Re: Configure sc16is7xx chip on compute module
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
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
-
- Posts: 1
- Joined: Mon Jun 20, 2016 12:23 pm
Re: Configure sc16is7xx chip on compute module
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
*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
Re: Configure sc16is7xx chip on compute module
A while back TomD posted:
# 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?
I've enabled the sc16is7xx driver editing my config.txt as follows: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.
# 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?
Re: Configure sc16is7xx chip on compute module
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
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
-
- Raspberry Pi Engineer & Forum Moderator
- Posts: 12998
- Joined: Wed Dec 04, 2013 11:27 am
- Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.
Re: Configure sc16is7xx chip on compute module
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.percramer wrote: ↑Wed Jul 26, 2017 7:11 pmDid 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
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.
I'm not interested in doing contracts for bespoke functionality - please don't ask.
Re: Configure sc16is7xx chip on compute module
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
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
-
- Raspberry Pi Engineer & Forum Moderator
- Posts: 12998
- Joined: Wed Dec 04, 2013 11:27 am
- Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.
Re: Configure sc16is7xx chip on compute module
So my point is I'd like to see either
if your compiler allows it, or
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.
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.
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
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
Code: Select all
struct serial_rs485 rs485conf = {0};
Code: Select all
rs485conf.flags = SER_RS485_ENABLED; //Note =, not |=
rs485conf.delay_rts_after_send = 0;
rs485conf.delay_rts_before_send = 0
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);
Code: Select all
rts_during_rx = !!(rs485->flags & SER_RS485_RTS_AFTER_SEND);
rts_during_tx = !!(rs485->flags & SER_RS485_RTS_ON_SEND);
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
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.
I'm not interested in doing contracts for bespoke functionality - please don't ask.
Re: Configure sc16is7xx chip on compute module
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

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.
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

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.
-
- Raspberry Pi Engineer & Forum Moderator
- Posts: 12998
- Joined: Wed Dec 04, 2013 11:27 am
- Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.
Re: Configure sc16is7xx chip on compute module
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.
So linux-serial@vger.kernel.org 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.
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 <gregkh@linuxfoundation.org> (maintainer:SERIAL DRIVERS)
Jiri Slaby <jslaby@suse.com> (supporter:TTY LAYER)
linux-serial@vger.kernel.org (open list:SERIAL DRIVERS)
linux-kernel@vger.kernel.org (open list)
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.
I'm not interested in doing contracts for bespoke functionality - please don't ask.
-
- Posts: 172
- Joined: Thu Dec 05, 2013 3:09 pm
Re: Configure sc16is7xx chip on compute module
I am using the SC16IS740 single UART chip with sc16is7xx driver included in the Kernel 4.9.13+. The driver is loaded via default sc16is750-i2c DT overlay. I am able to transmit data successfully to a slave device but receiving the response data does not work. I can see the data on the RX pin of the chip with an oscilloscope but the interrupt line on the IRQ pin never goes low so I guess this is the problem.
Is this a known issue of the driver? Earlier in this thread it was mentioned that RX did not work. Are there any tweeks necessary to make receive operation work?
FYI: I am using RS485 mode with RTS pin for automatic direction control, but I guess this does not matter.
Thanks, Ondrej
Is this a known issue of the driver? Earlier in this thread it was mentioned that RX did not work. Are there any tweeks necessary to make receive operation work?
FYI: I am using RS485 mode with RTS pin for automatic direction control, but I guess this does not matter.
Thanks, Ondrej