Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
14 years ago

SPI and uClinux

Hi all,

I have a design in which I have to use SPI in order to communicate with an external PIC. I find that it is not enough to select SPI driver in uClinux kernel configuration because when I try to open /dev/spi0 I receive the message: "No such device or address". What am I missing? Where am I wrong?

Thanks in advance

Marco

10 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Hi all,

    I have a design in which I have to use SPI in order to communicate with an external PIC. I find that it is not enough to select SPI driver in uClinux kernel configuration because when I try to open /dev/spi0 I receive the message: "No such device or address". What am I missing? Where am I wrong?

    Thanks in advance

    Marco

    --- Quote End ---

    Can you post your output about the kernel version, configuration and design info?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi liunx, thanks for your reply. Attached and below you can find the information you asked for.

    --- Quote Start ---

    Linux version 2.6.30 (marco@uClinux) (gcc version 3.4.6)# 404 PREEMPT Tue Oct 11

    17:44:02 CEST 2011

    uClinux/Nios II

    Built 1 zonelists in Zone order, mobility grouping off. Total pages: 32512

    Kernel command line:

    NR_IRQS:32

    PID hash table entries: 512 (order: 9, 2048 bytes)

    Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)

    Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)

    Memory available: 126552k/3382k RAM, 0k/0k ROM (1879k kernel code, 1502k data)

    Calibrating delay loop... 61.64 BogoMIPS (lpj=308224)

    Mount-cache hash table entries: 512

    net_namespace: 264 bytes

    NET: Registered protocol family 16

    init_BSP(): registering device resources

    bio: create slab <bio-0> at 0

    NET: Registered protocol family 2

    IP route cache hash table entries: 1024 (order: 0, 4096 bytes)

    TCP established hash table entries: 4096 (order: 3, 32768 bytes)

    TCP bind hash table entries: 4096 (order: 2, 16384 bytes)

    TCP: Hash tables configured (established 4096 bind 4096)

    TCP reno registered

    NET: Registered protocol family 1

    JFFS2 version 2.2. (NAND) © 2001-2006 Red Hat, Inc.

    JFFS2: default compression mode: priority

    io scheduler noop registered

    io scheduler deadline registered (default)

    ienable reg:100

    ienable reg:108

    pio_fpga_in - s

    ttyJ0 at MMIO 0x8004d50 (irq = 1) is a Altera JTAG UART

    console [ttyJ0] enabled

    ttyS0 at MMIO 0x8004c80 (irq = 7) is a Altera UART

    ttyS1 at MMIO 0x8000000 (irq = 6) is a Altera UART

    SLIP: version 0.8.4-NET3.019-NEWTTY (dynamic channels, max=256).

    0 : New Bus ID

    BUG: No TSE MDIO Reset

    Altera TSE MII Bus: probed

    Found phy with ID=0x1410cc2 at address=0x12

    Altera TSE MII Bus: MDIO Bus Registered

    eth0 (): not using net_device_ops yet

    eth0:Successed to register TSE net device

    Altera Triple Speed MAC IP Driver(v8.0) developed by SLS,August-2008,--Linux 2.6

    .27-rc3

    physmap platform flash device: 04000000 at 0c000000

    physmap-flash.0: Found 1 x16 devices at 0x0 in 16-bit bank

    Amd/Fujitsu Extended Query Table at 0x0040

    physmap-flash.0: CFI does not contain boot bank location. Assuming top.

    number of CFI chips: 1

    cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.

    cmdlinepart partition parsing not available

    RedBoot partition parsing not available

    Using physmap partition information

    Creating 9 MTD partitions on "physmap-flash.0":

    0x000000000000-0x000002800000 : "userspace"

    0x000002800000-0x000002900000 : "U-Boot"

    0x000002900000-0x000002d00000 : "uImage1"

    0x000002d00000-0x000003100000 : "uImage2"

    0x000003100000-0x000003500000 : "uImage3"

    0x000003500000-0x000003880000 : "DEFAULT_MMU"

    0x000003880000-0x000003c00000 : "MAXIMUM_MMU"

    0x000003c00000-0x000003f80000 : "USER_IMAGE"

    0x000003f80000-0x000003fa0000 : "options-bits"

    TCP cubic registered

    NET: Registered protocol family 17

    RPC: Registered udp transport module.

    RPC: Registered tcp transport module.

    Freeing unused kernel memory: 772k freed (0x1028c000 - 0x1034c000)

    Shell invoked to run file: /etc/rc

    Command: hostname uClinux

    Command: mount -t proc proc /proc -o noexec,nosuid,nodev

    Command: mount -t sysfs sysfs /sys -o noexec,nosuid,nodev

    Command: mount -t devpts devpts /dev/pts -o noexec,nosuid

    Command: mkdir /var/tmp

    Command: mkdir /var/log

    Command: mkdir /var/run

    Command: mkdir /var/lock

    Command: mkdir /var/empty

    Command: ifconfig lo 127.0.0.1

    Command: route add -net 127.0.0.0 netmask 255.0.0.0 lo

    Command: ifconfig eth0 hw ether 00:07:ED:11:80:c9

    Command: ifconfig eth0 192.168.100.229

    Command: route add default gw 192.168.100.1

    Command: mount -t jffs2 /dev/mtdblock0 /mnt

    Command: inetd&

    [28]

    Command: cat /etc/motd

    Welcome to

    ____ _ _

    / __| ||_|

    _ _| | | | _ ____ _ _ _ _

    | | | | | | || | _ \| | | |\ \/ /

    | |_| | |__| || | | | | |_| |/

    | ___\____|_||_|_| |_|\____|\_/\_/

    | |

    |_|

    For further information check:

    http://www.uclinux.org/

    Sash command shell (version 1.1.1)

    />

    --- Quote End ---

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Ok, reading documentation in Linux kernel I find that if I want to use open() and write() function within my software I need to write a protocol driver or simply use spidev driver. I added in config.c the following code

    
    static struct spi_board_info nios2_spi_devices = {
            .modalias = "spidev",
            .max_speed_hz = 173.3 * 1000,
            .bus_num = 1,
            .chip_select = 0,
            .irq = na_spi_irq,
            .mode = SPI_MODE_0,
    };
    

    and I did what is described in spidev documentation, but I am still not able to have spidev1.0 in /dev directory. Can anyone help me?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Ok, reading documentation in Linux kernel I find that if I want to use open() and write() function within my software I need to write a protocol driver or simply use spidev driver. I added in config.c the following code

    
    static struct spi_board_info nios2_spi_devices = {
            .modalias = "spidev",
            .max_speed_hz = 173.3 * 1000,
            .bus_num = 1,
            .chip_select = 0,
            .irq = na_spi_irq,
            .mode = SPI_MODE_0,
    };
    
    and I did what is described in spidev documentation, but I am still not able to have spidev1.0 in /dev directory. Can anyone help me?

    --- Quote End ---

    You need to do three things

    1. you need to add your spi device driver like altera_spi in config.c

    2. you need to add spi_board_info, bus_num should match with step1

    3. Make sure your spi device (altera_spi) probe did not returned error with unsupported mode

    Point to note is spidev is not spi hardware driver, it is spi user level driver and need to be linked to actual driver with bus_num

    I will post snippet of my code asap
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    1. Add a SPI device (Actual SPI device driver), in my case it is altera spi

    
    static struct resource spi_master_resource = {
         = {
               .start = SPI_MASTER_BASE,
               .end = SPI_MASTER_END,
               .flags = IORESOURCE_MEM,
               },
         = {
               .start = SPI_MASTER_IRQ,
               .end = SPI_MASTER_IRQ,
               .flags = IORESOURCE_IRQ,
               },
    };
    static struct platform_device spi_master_device = {
        .name = "spi_altera",
        .id = 0,        /* Bus number */
        .num_resources = ARRAY_SIZE(spi_master_resource),
        .resource = spi_master_resource,
    };
    
    2. Add spi board info. The id in SPI device and bus_num in spi board info shall match. you can add multiple entries if you have many.

    
    static struct spi_board_info nios2_spi_devices = {
         /* the modalias must be the same as spi device driver name */
         .modalias = "spidev",    /* Name of spi_driver for this device */
         .max_speed_hz = 4000000,    /* max spi clock (SCK) speed in HZ */
         .bus_num = 0,                /* bus number */
         .chip_select = 4,
         .mode = SPI_CPOL | SPI_CPHA,
         },
    
    3. Add a device in device table

    
    /dev/spimas        c    640     0       0       153       0       0       0       -
    
    4. If all these things are done, still spi does show up, debug your spi device probe (not spidev), it may be returning due to not supported mode bits
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi neolux, thanks for your answer :-)

    I followed these steps, but it didn't work. After platform_driver_probe in altera_spi_init it returns -19, so there's an error. How can i fix it?Where can I find the error code list?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Hi neolux, thanks for your answer :-)

    I followed these steps, but it didn't work. After platform_driver_probe in altera_spi_init it returns -19, so there's an error. How can i fix it?Where can I find the error code list?

    --- Quote End ---

    knowing error code doesn't help much. go to spi_altera.c put printk before all returns and verify why and where it is returning. You can go further if required.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I will update you about this. I'm using 20090730 release, so I have no spi_altera.c but altspi.c, but it should be the same.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi again,

    I found that there is an error in drivers/base/platform.c. Error code is ENODEV (dsl you were right).

    
    int __init_or_module platform_driver_probe(struct platform_driver *drv,
                    int (*probe)(struct platform_device *))
    {
            int retval, code;
            /* temporary section violation during probe() */
            drv->probe = probe;
            retval = code = platform_driver_register(drv);
            /* Fixup that section violation, being paranoid about code scanning
             * the list of drivers in order to probe new devices.  Check to see
             * if the probe was successful, and make sure any forced probes of
             * new devices fail.
             */
            spin_lock(&platform_bus_type.p->klist_drivers.k_lock);
            //drv->probe = NULL; Commented by me
            if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list))
                    retval = -ENODEV;
            drv->driver.probe = platform_drv_probe_fail;
            spin_unlock(&platform_bus_type.p->klist_drivers.k_lock);
            if (code != retval)
                    platform_driver_unregister(drv);
            return retval;
    }
    

    I think the error is due to "list_empty" that should returns 0 but returns 1. Am I right? Am i right when I comment drv->probe = NULL? What else should I do?