Nick Posted March 15, 2016 Posted March 15, 2016 This maybe something that just isn't available yet, but if I can help with the development I am happy to. I have created the following patches as a starting point but they don't yet work. Looking at the source code for the spidev module and comparing it to the H3 datasheet, it would appear that the H3 uses the sun6i spi register addresses. Though the datasheet lists the RX and TX buffers as 64 bytes whereas the sun6i spidev driver implements 128byte buffers. I'm assuming that this wont be a problem at least for testing as long as I don't try and transfer or receive more than 64 bytes. As you can see from the dtsi patch, I have updated the module memory location and the IRQ & DMA channels. The clock gating appears to already be configured in the H3 dtsi file so hopefully that is correct. --- /arch/arm/boot/dts/sun8i-h3.dtsi 2016-03-14 19:04:16.977158383 +0000 +++ ./sun8i-h3.dtsi 2016-03-14 21:49:55.806634593 +0000 @@ -591,5 +591,37 @@ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>; }; + spi0_clk: clk@01c200a0 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-mod0-clk"; + reg = <0x01c200a0 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "spi0"; + }; + spi0: spi@01c68000 { + compatible = "allwinner,sun6i-a31-spi"; + reg = <0x01c68000 0x1000>; + interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ahb_gates 20>, <&spi0_clk>; + clock-names = "ahb", "mod"; + dmas = <&dma SUN4I_DMA_DEDICATED 23>, + <&dma SUN4I_DMA_DEDICATED 23>; + dma-names = "rx", "tx"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + spi0_pins_a: spi0@0 { + allwinner,pins = "PC2", "PC0", "PC1"; + allwinner,function = "spi0"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + spi0_cs0_pins_a: spi0_cs0@0 { + allwinner,pins = "PC3"; + allwinner,function = "spi0"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; }; }; --- /arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts 2016-03-14 19:04:17.013140384 +0000 +++ ./sun8i-h3-orangepi-pc.dts 2016-03-14 21:50:23.646635423 +0000 @@ -104,3 +104,21 @@ /* USB VBUS is always on */ status = "okay"; }; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins_a>, + <&spi0_cs0_pins_a>; + status = "okay"; + spi0_0 { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "spidev"; + + reg = <0>; + spi-max-frequency = <500000>; + }; +}; + + At the moment the only feedback that I get is no /dev/spi* is there anyway of getting some debugging info from the driver printk's maybe?
tkaiser Posted March 15, 2016 Posted March 15, 2016 Have you already looked through the 'real' development thread, especially the posts from @martinayotte: http://forum.armbian.com/index.php/topic/617-wip-orange-pi-one-support-for-the-upcoming-orange-pi-one/page-10
Nick Posted March 15, 2016 Author Posted March 15, 2016 No I haven't I did a quick forum search but I (stupidly) ignored that one as my brain saw orange pi one and discounted it. I'll have a read through tonight and see if I can pick up any nuggets. Would you prefer me to contribute anything I find to that thread or carry on with this one?
martinayotte Posted March 15, 2016 Posted March 15, 2016 For making SPI working, not only DTS need to be patched, but also the SPIdev driver itself to become HW SPI friendly. --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -695,6 +695,7 @@ static struct class *spidev_class; static const struct of_device_id spidev_dt_ids[] = { { .compatible = "rohm,dh2228fv" }, { .compatible = "lineartechnology,ltc2488" }, + { .compatible = "allwinner,sun4i-a10-spi" }, + { .compatible = "allwinner,sun6i-a31-spi" }, {}, }; MODULE_DEVICE_TABLE(of, spidev_dt_ids); Here is in attachment my updated patches ... BTW, to be able to submit those patches to Mainline in a near future, I had to do the same exercise directly on 4.5.0-rc6+, which I finally succeeded yesterday. (I still other issues with this 4.5.0-rc6+, but not related to my patches themselves) EDIT : The 4.5.0 has been released last Sunday, so I guess I will need to merge it again in the new 4.6.0-rcX branch ... ;-) orangepipc-patches.zip
Nick Posted March 15, 2016 Author Posted March 15, 2016 That's great work, thank you. I'll test them later and hopefully all will be well. I am a little confused as to why those lines aren't already in the driver though? I have successful run the spidev driver on the A20, which uses the sun4i-a10 model without having to patch spidev.
martinayotte Posted March 15, 2016 Posted March 15, 2016 I am a little confused as to why those lines aren't already in the driver though? I have successful run the spidev driver on the A20, which uses the sun4i-a10 model without having to patch spidev. Do you mean with 4.4.x ? While doing some tests on my Olimex-Micro-A20, I've discovered that it was required there too. Maybe you had older version. This "spidev_dt_ids" list has been added in Mainline around November, I think. Before that, it wasn't required.
Nick Posted March 15, 2016 Author Posted March 15, 2016 Yes 4.4.5, Zador helped me to get it running on a banana pi m1+ using Linux next and Jessie. I've just checked spidev.c on my build VM and it doesn't contain the lines that you have added, however it appears that they are added via spi-sun4i.c and spi-sun6i.c Here is an example form spi-sun6i.c static const struct of_device_id sun6i_spi_match[] = { { .compatible = "allwinner,sun6i-a31-spi", }, {} }; MODULE_DEVICE_TABLE(of, sun6i_spi_match); I haven't read through the full driver code yet, but I would imagine that they are pulled in at some point and added to the struct.
Nick Posted March 23, 2016 Author Posted March 23, 2016 There is something weird going on with the SPI, I seem to be getting a spurious short clock pulse. See the attached pic: The blue trace is the active low CS line, the yellow trace is the CLK line. As you can see, the CS line goes low and sometime later there is a burst of 8 bits, but in between the two events there is a very short extra pulse on the CLK line. I'm guessing this explains why I can't talk to the poor slave device Edit: Finally got around to trying spitest... root@opi:/# ./spitest -D /dev/spidev0.0 can't send spi message: Success Aborted root@opi:/# ./spitest -D /dev/spidev0.0 -s 50000 can't send spi message: Success Aborted root@opi:/# ./spitest -D /dev/spidev0.0 -l can't set spi mode: Invalid argument Aborted root@opi:/#
tcmichals Posted June 9, 2016 Posted June 9, 2016 Any success getting SPI to work with mainline i.e 4.7rc?
mmarks Posted September 5, 2016 Posted September 5, 2016 I've been looking at the missing spidev problem with the current mainline (4.7.2). I built armbian vanilla (mainline) Jessie on linux and noticed that although the correct spi device info has now been included in the device tree for h3 (sun8i-h3.dtsi) the changes martinayotte noted for the spidev driver have not been made. I tried adding his spidev patch file to the userpatches but it seems to be getting ignored or overwritten in the build script. Is there a way to rebuild without pulling in the git updates? I note that there is a spidev.ko but loading it with modprobe doesnt create any spi devices
martinayotte Posted September 6, 2016 Posted September 6, 2016 I've been using Dynamic Overlay to load SPIs into the DTS. There is no need to do any modprobe, since the Kernel will load it automatically when DTS is updated. mkdir /sys/kernel/config/device-tree/overlays/spi cat spidev-enable.dtbo > /sys/kernel/config/device-tree/overlays/spi/dtbo // Enable the spidev interface/dts-v1/;/plugin/;/ { compatible = "allwinner,sun8i-h3"; fragment@0 { target-path = "/aliases"; __overlay__ { /* Path to the SPI controller nodes */ spi0 = "/soc@01c00000/spi@01c68000"; spi1 = "/soc@01c00000/spi@01c69000"; }; }; fragment@1 { target = <&spi0>; __overlay__ { pinctrl-names = "default"; pinctrl-0 = <&spi0_pins_a>, <&spi0_cs0_pins_a>; status = "okay"; #address-cells = <1>; #size-cells = <0>; spidev@0 { compatible = "spidev"; reg = <0x0>; spi-max-frequency = <1000000>; }; }; }; fragment@2 { target = <&spi1>; __overlay__ { pinctrl-names = "default"; pinctrl-0 = <&spi1_pins_a>, <&spi1_cs0_pins_a>; status = "okay"; #address-cells = <1>; #size-cells = <0>; spidev@0 { compatible = "spidev"; reg = <0x0>; spi-max-frequency = <1000000>; }; }; };}; 1
mmarks Posted September 7, 2016 Posted September 7, 2016 I wish it was that easy :-) If I use your overlay source directly and copy it to the overlay dtbo as you suggest I see the following errors in dmesg: ... [ 496.553300] Invalid device tree blob header[ 496.553371] create_overlay: failed to unflatten tree I thought I needed to compile the dts first into the dtbo with: dtc -O dtb -I dts -o spidev-enable.dtbo -b 0 spidev-enable.dts But that gives an error too: root@nanopineo:~# dtc -O dtb -I dts -o spidev-enable.dtbo -b 0 spidev-enable.dtsError: spidev-enable.dts:3.2-8 syntax errorOf course it doesn't say what the syntax error is. I'm wondering it was something stupid like different line ending characters. That is sometimes as issue moving between windows and linux environments. I'll check that next. But my question is: do you need to compile it first or will it happen automatically when its copied to the configfs?
martinayotte Posted September 7, 2016 Posted September 7, 2016 Sorry if I didn't gave details earlier. Yes, you need to compile the DTBO, but using the DTC compiler supporting Dynamic Overlays developped by Pantelis Antoniou. I can be found there : https://github.com/pantoniou/dtc.git With this version, You need to invoke it with '-@' option : dtc -@ -O dtb -I dts -o spidev-enable.dtbo spidev-enable.dts
mmarks Posted September 7, 2016 Posted September 7, 2016 Thanks! It wasn't quite so obvious but I did get it to work eventually. I found that building the default git mainline from pantoniou/dtc produced a dtc that would not accept the -@ option. However I noticed that there were several branches that were more recent - e.g dt-overlays8. When I built that branch it produced a dtc that although it gave a few warnings did produce a dtbo that could be copied into the configfs and suddenly the spidevs showed up in /dev. Here's exactly what I did: I found that the dtc build required flex and bison so I installed them: apt-get install flex bison I cloned the dtc git with the dt-overlays8 branch: git clone -b dt-overlays8 https://github.com/pantoniou/dtc I built that version ( DTC 1.4.1-gf7da040f) and used that to compile the dts: dtc -@ -O dtb -I dts -o spidev-enable.dtbo spidev-enable.dts There were a couple of warnings: Warning (unit_address_vs_reg): Node /fragment@0 has a unit name, but no reg propertyWarning (unit_address_vs_reg): Node /fragment@1 has a unit name, but no reg propertyWarning (unit_address_vs_reg): Node /fragment@2 has a unit name, but no reg property Then copied the result to the directory I created earlier: sudo cat spidev-enable.dtbo > /sys/kernel/config/device-tree/overlays/spi/dtbo Two spidevs then showed up in /dev! ls /dev/spi*/dev/spidev0.0 /dev/spidev1.0 Now I'll have to wire up something (maybe a logic analyzer) to test them. I hope I don't have the spi speed problem I saw earlier... Thanks again for your help. When it all works it is simply magical!
mmarks Posted September 7, 2016 Posted September 7, 2016 Let me add that I did test the spidev0.0 with a logic analyzer and it works! I'm still exploring some aspects of it e.g. the CS control, but it doesn't seem to have the same huge delay between cs assertion and data that I saw previously.
martinayotte Posted September 7, 2016 Posted September 7, 2016 Yes, you're right, I forgot to mention the dt-overlays8 branch ... About speed issue, when I faced some, if it is the same as you, I've discovered that it was in the python library that was setting CONFIG_SPEED to 100KHz instead of 10MHz. http://forum.armbian.com/index.php/topic/1523-spi-issue-with-banana-proa20/#entry13824
bomber Posted September 7, 2016 Posted September 7, 2016 For compiling my dtbo i used dtc located in /usr/src/linux-headers-4.6.7-sun8i/scripts/dtc , not system one located at /usr/bin/dtc Version: DTC 1.4.1-g4273dca2 it has -@ param
martinayotte Posted September 7, 2016 Posted September 7, 2016 Of course, this version is patched one coming from the above github version (I've created the patch about a month ago).
mmarks Posted September 20, 2016 Posted September 20, 2016 I'm still finding the H3 SPI to be too slow for driving LCD SPI displays. I'm using the vanilla 4.7.2 kernel, applying overlays for I2C and SPI. Using a C program to directly access the spi with ioctl calls the best speed I was able to achieve for single byte writes was <30 Kb/sec. This is with 8 MHZ SPI clock. The speed limiting problem is still long delays on CS assert and deassert: 5us from CS assert to SPI data start, 25 us from SPI data end to CS deassert. The actual data time is about 1us with 8 MHz clock so ~97% of the time is wasted in the hardware CS delays, not counting the delay between sending bytes This makes the H3 many times slower with displays than Arduino, and far, far slower than Teensy which I've used for many IOT projects. Legacy kernel experiments show the same sort of delays. I thought the more recent kernels might be better. But not yet. I'd really like to use the Neo for projects that use SPI for small displays, or interfacing a digital radio chip or ADC, etc, but the slow speed is holding me back at the moment. For example an IOT gateway. I know its not the H3 based hardware that's limiting the speed, just the driver and that can be fixed. I'm interested in any ideas or experimental results anyone has on this topic.
jbuzar Posted January 18, 2017 Posted January 18, 2017 We also would like to do continuous SPI communication and experience the CS delays. Will this eventually be improved in 4.10 kernel?
zador.blood.stained Posted January 18, 2017 Posted January 18, 2017 We also would like to do continuous SPI communication and experience the CS delays. Will this eventually be improved in 4.10 kernel? 4.10 will contain fix that enables large SPI transfers. I don't think it affects these CS delay issues.
martinayotte Posted January 18, 2017 Posted January 18, 2017 Zador, if you remember, I've committed a patch few days ago to get large transfers under 4.9.
zador.blood.stained Posted January 18, 2017 Posted January 18, 2017 @martinayotte I know, but the question was specifically about the 4.10 or patches that will land officially in this kernel version. And still this patchdoesn't change anything regarding CS handling.
jbuzar Posted January 18, 2017 Posted January 18, 2017 4.10 will contain fix that enables large SPI transfers. I don't think it affects these CS delay issues. What does "large SPI transfer" mean in KB, MB?
zador.blood.stained Posted January 18, 2017 Posted January 18, 2017 For the H3 controller it is 16 bytes (its FIFO depth), and I made a mistake - 4.10 will include the fix for A10/A20 (sun4i) SPI controller, not for the A31/H3 (sun6i) one, but @martinayotte made an experimental patch for the H3 controller too.
martinayotte Posted January 18, 2017 Posted January 18, 2017 In fact, H3 has 64 bytes FIFO, while some other AllWinner SoC has 128 bytes FIFO. Yes, the patch committed few days ago allow large transfer, example, using flashcp to upload SPL into SPI Flash, it produce transfers of 4096 bytes. I didn't check with a logic analyser how the CS line is reacting during such large transfer, but I presume kernel driver should only asserting CS to LOW during the whole transfer. I will verify that when I get chance ...
tcmichals Posted January 19, 2017 Posted January 19, 2017 The SPI select is driven by software, ie. drivers/spi.c not hardware. Looking at spi.c spi_transfer_one_message assert CS setup/clear upper level call backs call into SPI driver sun6i_spi_transfer_one clear ISR callbacks etc setup SPI chip etc start the transfer. So, even if the SPI transfer rate is increased, the about of time from CS is asserted to the first SPI data transfer should be constant (i.e the time it takes to execute the code)
peter12 Posted January 24, 2017 Posted January 24, 2017 hi there, please, I have orange pi lite and using spi to control ws2812b. My problem is, that firs led is green (when other are off), when I set all to blue first led is blue too, when all to green first is green, when all to red first is yellow. Any idea what is causing this issue? Or any idea how to leave first LED off completely rather than being green? Thanks. UPDATE: I found out GREEN is always in up (turned on) state for first LED in strip. So according to my opinion, final last data are somehow corrupted and therefore green part of first led is in "ON" state.
zakk Posted February 24, 2017 Posted February 24, 2017 I've been using Dynamic Overlay to load SPIs into the DTS. There is no need to do any modprobe, since the Kernel will load it automatically when DTS is updated. mkdir /sys/kernel/config/device-tree/overlays/spi cat spidev-enable.dtbo > /sys/kernel/config/device-tree/overlays/spi/dtbo // Enable the spidev interface /dts-v1/; /plugin/; / { compatible = "allwinner,sun8i-h3"; fragment@0 { target-path = "/aliases"; __overlay__ { /* Path to the SPI controller nodes */ spi0 = "/soc@01c00000/spi@01c68000"; spi1 = "/soc@01c00000/spi@01c69000"; }; }; fragment@1 { target = <&spi0>; __overlay__ { pinctrl-names = "default"; pinctrl-0 = <&spi0_pins_a>, <&spi0_cs0_pins_a>; status = "okay"; #address-cells = <1>; #size-cells = <0>; spidev@0 { compatible = "spidev"; reg = <0x0>; spi-max-frequency = <1000000>; }; }; }; fragment@2 { target = <&spi1>; __overlay__ { pinctrl-names = "default"; pinctrl-0 = <&spi1_pins_a>, <&spi1_cs0_pins_a>; status = "okay"; #address-cells = <1>; #size-cells = <0>; spidev@0 { compatible = "spidev"; reg = <0x0>; spi-max-frequency = <1000000>; }; }; }; }; I follow this thread and have a little problem. I compiled Linux-4.10 and it comes with /boot/dtb/overlay/sun8i-h3-spi0-spidev.dtbo, then I did this: cat sun8i-h3-spi0-spidev.dtbo > /sys/kernel/config/device-tree/overlays/spi/dtbo I got /dev/spidev0.0 but after reboot, the spidev0.0 is gone and need to do the command above again. Can I put it to rc.local?, but I am not sure is this correct way to load spi overlay. Please advise
martinayotte Posted February 24, 2017 Posted February 24, 2017 That is normal. The way using "cat" is making things really dynamic, and yes you could add it into rc.local, but there is an easier way since few weeks : Simply add the following in /boot/armbienEnv.txt : overlays=sun8i-h3-spi0-spidev This will make uboot load it for you on every boot. 1
Recommended Posts