- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 MarcoLink Copied
10 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 ---- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
-19 will be a negative errno value, probably -ENODEV.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page