user3714405
user3714405

Reputation: 51

Trouble with SPIDEV, device tree and .dtbo name with Beaglebone Black

I have some weird issue with device tree. I found out that changing name of the .dtbo changed the beahvior of the kernel !

I have modified the BB-SPIDEV1-00A0.dts given in /lib/firmware with Angstrom :

/*
 * Copyright (C) 2013 CircuitCo
 *
 * Virtual cape for SPI1 on connector pins P9.29 P9.31 P9.30 P9.28
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
/dts-v1/;
/plugin/;

/ {
    compatible = "ti,beaglebone", "ti,beaglebone-black";

    /* identification */
    part-number = "BB-SPI1-01";
    version = "00A0";

    /* state the resources this cape uses */
    exclusive-use =
        /* the pin header uses */
        "P9.31",    /* spi1_sclk */
        "P9.29",    /* spi1_d0 */
        "P9.30",    /* spi1_d1 */
        "P9.28",    /* spi1_cs0 */
            "P9.42",    /* spi1_cs1 */
        /* the hardware ip uses */
        "spi1";

    fragment@0 {
        target = <&am33xx_pinmux>;
        __overlay__ {
            /* default state has all gpios released and mode set to uart1 */
            bb_spi1_pins: pinmux_bb_spi1_pins {
                pinctrl-single,pins = <
                    0x190 0x13  /* mcasp0_aclkx.spi1_sclk,  OUTPUT_PULLUP | MODE3 */
                    0x194 0x33  /* mcasp0_fsx.spi1_d0,      INPUT_PULLUP | MODE3 */
                    0x198 0x13  /* mcasp0_axr0.spi1_d1,     OUTPUT_PULLUP | MODE3 */
                    0x19c 0x13  /* mcasp0_ahclkr.spi1_cs0,      OUTPUT_PULLUP | MODE3 */
                    0x164 0x12  /* eCAP0_in_PWM0_out.spi1_cs1   OUTPUT_PULLUP | MODE2 */
                    0x1A0 0x32  /* Other P42 pin, INPUT_PULLUP */
                >;
            };
        };
    };

    fragment@1 {
        target = <&spi1>;   /* spi1 is numbered correctly */
        __overlay__ {
            status = "okay";
            pinctrl-names = "default";
            pinctrl-0 = <&bb_spi1_pins>;

            #address-cells = <1>;
            #size-cells = <0>;

            spi1_0{
                #address-cells = <1>;
                #size-cells = <0>;

                compatible = "spidev";

                reg = <0>;
                spi-max-frequency = <16000000>;
            };


            spi1_1{
                #address-cells = <1>;
                #size-cells = <0>;

                compatible = "spidev";

                reg = <1>;
                spi-max-frequency = <16000000>;
            };
        };
    };
};

I compiled it to two names : BB-SPIDEV1-00A0.dtbo and BB-SPI1-01-00A0.dtbo

When I load one of them in /sys/devices/bone_capemgr.9/slots, the spidev behaves differently !

With BB-SPIDEV1, spidev1.0 works good without any issue. But the chip select of spidev1.1 doesn't work ! The pin 42 is in the wrong mode, and the pin is not allocated with spi1

On the other hand, with BB-SPI1-01 (this name isn't important, giving another name is the same, it just has to be different of BB-SPIDEV1), the pin 42 is well allocated :

root@beaglebone:/sys/kernel/debug/pinctrl/44e10800.pinmux# cat pinmux-pins | grep spi
pin 89 (44e10964): 481a0000.spi (GPIO UNCLAIMED) function pinctrl_spi1_pins group pinctrl_spi1_pins
pin 100 (44e10990): 481a0000.spi (GPIO UNCLAIMED) function pinctrl_spi1_pins group pinctrl_spi1_pins
pin 101 (44e10994): 481a0000.spi (GPIO UNCLAIMED) function pinctrl_spi1_pins group pinctrl_spi1_pins
pin 102 (44e10998): 481a0000.spi (GPIO UNCLAIMED) function pinctrl_spi1_pins group pinctrl_spi1_pins
pin 103 (44e1099c): 481a0000.spi (GPIO UNCLAIMED) function pinctrl_spi1_pins group pinctrl_spi1_pins
pin 104 (44e109a0): 481a0000.spi (GPIO UNCLAIMED) function pinctrl_spi1_pins group pinctrl_spi1_pins

and in the good mode :

root@beaglebone:/sys/kernel/debug/pinctrl/44e10800.pinmux# cat pins | grep 964
pin 89 (44e10964) 00000012 pinctrl-single 

BUT this time spidev1.0 doesn't work propely. The MISO line (so the input for the BBB), sees only 0, even if it's false (I checked with an oscilloscope).

So What could be the problem ?

Thanks in advance

Upvotes: 3

Views: 4812

Answers (2)

user3714405
user3714405

Reputation: 51

Well well, again i answer to my question myself. Actually, the Problem was : I was unable to use the Second chip select of SPI channel 1 (spidev.1.1). When I tried to do so, the problem of the names of dtbo appeared and i posted this question. However the name problem isn't resolved yet.

But the problem of

BUT this time spidev1.0 doesn't work propely. The MISO line (so the input for the BBB), sees only 0, even if it's false (I checked with an oscilloscope).

has been solved by changing the mode of the Clock : 0x33 instead of 0x13. Although it's an output, putting as 0x33 change the pin to RXACTIVE_PULLUP. It must be enable that way to receive data.

The strange thing is that 0x13 worked perfectly with BB-SPIDEV1...

Thanks to TekuConcept for the help about the registers, if i have some extra times I will try to dig the registers.

Upvotes: 1

TekuConcept
TekuConcept

Reputation: 1284

Set P9_42B to Mode 4 w/High Impedance (0x2C) - otherwise, the default is Mode 4 Fast-In Pull-Down. Unless this pin is modified by another overlay, no muxing is necessary for P9_42B.

SPI1 (as well as SPI0, I2C, & GPIO2) registers were giving me bus errors when I accessed their registers, rendering the device(s) disabled despite setting their status to 'okay' in respective overlay. So I checked the CM_PER register and sure enough: IDLEST=3 [disabled] and MODULEMODE=0 [disabled]. Though these tests were done on a Debian system, I'm pretty sure the same goes for Angstrom and all other distros.

To enable them, you will need to access the memory address(es) for Power and Clock Management through a preferred language of your choice:

Via PRU Assembly:

.origin 0
.entrypoint START

START:
    MOV  r0, 0x44E00050 // CM_PER_SPI1_CLKCTRL Register [reset = 30000h / disabled]
    LBBO r1, r0, 0, 4   // load register value
    CLR  r1.t16         // set IDLEST to FUNC
    CLR  r1.t17
    SET  r1.t1          // set MODULEMODE to ENABLE
    SBBO r1, r0, 0, 4   // store value
    HALT

Via Python:
Beaglebone IO using Python mmap

Via C/C++: (similar to the python example above)
Referenced from: vabi-robotics.blogspot.com

#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdio.h>
#include <iostream>
#define CM_PER 0x44E00000 //PG 157

using namespace std;

int main(){
    int fd = open("/dev/mem",O_RDWR | O_SYNC);
    ulong* pinconf1 =  (ulong*) mmap(NULL, 0x0FFF, PROT_READ | PROT_WRITE, MAP_SHARED, fd, CM_PER);

    printf("INFO: %X\n", pinconf1[0x50/4]);
    pinconf1[0x50/4] = 0x00000002;
    printf("INFO: %X\n", pinconf1[0x50/4]); // conf. initialized

    return 0;
}

Note: If this is not the issue and one channel is in fact functional, make sure that the channel is disabled before enabling the next channel. Also, confirm that the MS bit is cleared [master], PIN34 bit is cleared [SPIEN is used as chip select], and SINGLE bit is cleared [more than one channel is used] in the MCSPI_MODULCTRL register (SPI1: 0x481A0128)

Upvotes: 1

Related Questions