Author Topic: Getting SPI to work?  (Read 20182 times)

Offline mahdichi

  • Newbie
  • *
  • Posts: 3
  • Karma: +0/-0
    • View Profile
Getting SPI to work?
« on: August 03, 2013, 01:42:48 am »
Hi all,

i try getting SPI to work. i use blow link and this is the result:
https://groups.google.com/forum/#!category-topic/cubieboard/hardware-issue/qcysnyw0tRw

i compiled kernel v4.3.43 with CONFIG_SPI_SUN4I=y and CONFIG_SPI_SPIDEV=m

in /dev i have spidev0.0 but when i compile spidev_test.c it run with error.

I am hoping someone here test it before and can help me.
thanks in advance.

Offline vinifr

  • Newbie
  • *
  • Posts: 32
  • Karma: +2/-0
    • View Profile
Re: Getting SPI to work?
« Reply #1 on: August 04, 2013, 12:12:47 am »
Unfortunately spi_sunxi have no support for full-duplex, this way spidev0.0 doesn't work. But a patch was submitted: https://groups.google.com/forum/?fromgroups=#!topic/linux-sunxi/yEmBiaJ3LAI

Offline mahdichi

  • Newbie
  • *
  • Posts: 3
  • Karma: +0/-0
    • View Profile
Re: Getting SPI to work?
« Reply #2 on: August 04, 2013, 03:53:06 am »
thanks

i test this patch.

one other question,
i don't need  full-duplex support, so can i use spi for read from peripheral without this patch?
do you have any example for half-duplex interface. ( i want connect a ADC to cubieboard)

thank for reply.

Offline vinifr

  • Newbie
  • *
  • Posts: 32
  • Karma: +2/-0
    • View Profile
Re: Getting SPI to work?
« Reply #3 on: August 04, 2013, 10:09:17 am »
Without the patch, you must set .tx_buf=0 when reading and .rx_buf=0 when writing! You can not use .tx_buf and .rx_buf at same time, as spidev does.
Code: [Select]
.tx_buf = (unsigned long)tx,
.rx_buf = (unsigned long)rx,

This way, it is necessary to transfer two messages, one for reading and one for writing.
Code: [Select]
// for writing
struct spi_ioc_transfer tx = {
.tx_buf = (unsigned long)tx,
.rx_buf = 0,
.len = ARRAY_SIZE(tx),
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
};
// for reading
struct spi_ioc_transfer rx = {
.tx_buf = 0,
.rx_buf = (unsigned long)rx,
.len = ARRAY_SIZE(tx),
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
};

Code: [Select]
// writing
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tx);
...
// reading
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &rx);

Have you already searched the driver specific to this ADC?
https://github.com/torvalds/linux/tree/master/drivers/iio/adc
« Last Edit: August 04, 2013, 10:16:07 am by vinifr »

Alchimic

  • Guest
Re: Getting SPI to work?
« Reply #4 on: October 21, 2013, 06:53:30 am »
Hi everyone,

My SPI doesn't work. The SPI devices are defined in script.bin. I selected user mode SPI driver in kernel config and got  /dev/spidev0.0 .

[spi0_para]

spi_used = 1

spi_cs_bitmap = 1

spi_cs0 = port:PI10<3><default><default><default>

spi_sclk = port:PI11<3><default><default><default>

spi_mosi = port:PI12<3><default><default><default>

spi_miso = port:PI13<3><default><default><default>

 

[spi1_para]

spi_used = 0

spi_cs_bitmap = 1

spi_cs0 = port:PA00<4><default><default><default>

spi_sclk = port:PA01<4><default><default><default>

spi_mosi = port:PA02<4><default><default><default>

spi_miso = port:PA03<4><default><default><default>

 

[spi2_para]

spi_used = 0

spi_cs_bitmap = 1

spi_cs0 = port:PB14<2><default><default><default>

spi_sclk = port:PB15<2><default><default><default>

spi_mosi = port:PB16<2><default><default><default>

spi_miso = port:PB17<2><default><default><default>

spi_cs0 = port:PC19<3><default><default><default>

spi_sclk = port:PC20<3><default><default><default>

spi_mosi = port:PC21<3><default><default><default>

spi_miso = port:PC22<3><default><default><default>

 

[spi3_para]

spi_used = 0

spi_cs_bitmap = 1

spi_cs0 = port:PA05<3><default><default><default>

spi_sclk = port:PI06<3><default><default><default>

spi_mosi = port:PI07<3><default><default><default>

spi_miso = port:PI08<3><default><default><default>

spi_cs1 = port:PA09<3><default><default><default>

 

[spi_devices]

spi_dev_num = 1

 

[spi_board0]

modalias = "spidev"

max_speed_hz = 10000000

bus_num = 0

chip_select = 0

mode = 0

full_duplex = 0

manual_cs = 0

irq_gpio=104



Compiling a test program (spidev-test.c) and running it I get logic 1 on the CS pin and absolutely nothing on the SCK pin.

The output from dmesg:

[    1.478782] [spi]: sw spi init !!

[    1.485940] [spi]: Found 1 spi devices in config files

[    1.497356] [spi]: boards num modalias         max_spd_hz       bus_num  cs   mode

[    1.511386] [spi]: 0          spidev           10000000         0        0    0x0

[    1.522303] [spi]: bus num = 0, spi used = 1

[    1.532500] [spi]: source = sdram_pll_p, src_clk = 480000000, mclk 96000000

[    1.545339] sun4i-spi sun4i-spi.0: master is unqueued, this is deprecated

[    1.558988] [spi]: allwinners SoC SPI Driver loaded for Bus SPI-0 with 2 Slaves attached


[    1.574916] [spi]: [spi-0]: driver probe succeed, base f1c05000, irq 10, dma_tx_id 36, dma_rx_id



Please, may be someone here may help me with my problem?


Offline vinifr

  • Newbie
  • *
  • Posts: 32
  • Karma: +2/-0
    • View Profile
Re: Getting SPI to work?
« Reply #5 on: October 24, 2013, 07:28:47 pm »
As I said, you can not use .tx_buf and .rx_buf at same time. What software do you use to test SPI0. Is SPI0 available?

Also look for pins conflicting into script.fex. ;)

Emc2

  • Guest
Re: Getting SPI to work?
« Reply #6 on: October 30, 2013, 07:16:52 am »
Hello all. Please help.
How to use SPI in slave mode?

dariuszb

  • Guest
Re: Getting SPI to work?
« Reply #7 on: November 19, 2013, 01:57:44 pm »
I have spi working under userspace, but i must compile it with my custom header:

Code: [Select]
gcc -I /usr/src/linux*5/include spidev_test.c  -o spidev_test
Ofcourse it give me an warning about using kernel in user mode. I connected a 2MB flash to SPI0. There isn't any loopback. I want to read it's id by sending two bytes (9F FF) to this device. But all i got is:

Code: [Select]
./spidev_test
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)

9F FF

When I use it with -l (loopback parameter everything is allright.

Code: [Select]
./spidev_test -l
spi mode: 32
bits per word: 8
max speed: 500000 Hz (500 KHz)

00 1F

My questions:
1) How to avoid this warning, or any hints how to compile program without custom kernel?
2) How to use SPI without -l parameter?

Thanks for any answers!
« Last Edit: November 19, 2013, 02:01:01 pm by dariuszb »

dariuszb

  • Guest
Re: Getting SPI to work?
« Reply #8 on: November 20, 2013, 05:39:32 pm »
I will anwser to one of my questions;)
Quote
1) How to avoid this warning, or any hints how to compile program without custom kernel?

Look here:
https://groups.google.com/forum/#!msg/cubieboard/Mjm8c5umEfU/4msuJgZYQJcJ
Changing one file and no more invalid argument error.

File in /usr/include/linux/spi/spidev.h should have a changed struct inside:
Code: [Select]
struct spi_ioc_transfer {
        __u64           tx_buf;
        __u64           rx_buf;

        __u32           len;
        __u32           speed_hz;


        __u16           delay_usecs;
        __u16           interbyte_usecs;
        __u8            bits_per_word;
        __u8            cs_change;
        __u32           pad;

        /* If the contents of 'struct spi_ioc_transfer' ever change
         * incompatibly, then the ioctl number (currently 0) must change;
         * ioctls with constant size fields get a bit more in the way of
         * error checking than ones (like this) where that field varies.
         *
         * NOTE: struct layout is the same in 64bit and 32bit userspace.
         */
};


Loopback parameteter can be related with kernel. I think there is an unset bit in config register. Try to check it.
« Last Edit: November 20, 2013, 05:49:19 pm by dariuszb »