Saisissez le code ici...
Hi Jan,
Ok so I have done some progress I am almost done. My last issue is purely a
software issue.
So first I found a first issue which was due to bad voltage. I was
supplying my slave thanks to the Beaglebone Black. I need a voltage of 5V
delivered by the VDD_5V. Thanks to an oscilloscope I was able to see that
the pin delivered 0V... In fact when you supply the BB by using the USB the
VDD_5V cannot be use. You must use the 5V jack....
Thanks to that I can see to the oscilloscope that I sent the good message
to my slave (CS, SCLK, MOSI) are ok !! So now when I want to read a
register of my slave I can see the good answer on the oscilloscope on the
MISO pin. So eveyrthing seems to be great. I am able to send a command to
my slave and get the good answer. The problem is that I am not able to read
properly this value on my MISO pin.
I found plenty of spidev example in c on the web.. So I implemented three
spidev code with three differents ways from the web. The three software get
me wrong value and not the same (so funny...)
Code that I tried :
One spio_ioc_transfer structure per bytes (crazy ???!)
tx & rx in the same structure.
static void read_register_value (unsigned char *data, int length, int fd)
{
struct spi_ioc_transfer spi[length];
int i = 0;
int retVal = -1;
// one spi transfer for each byte
for (i = 0 ; i < length ; i++)
{
spi[i].tx_buf = (unsigned long)(data + i); // transmit from "data"
spi[i].rx_buf = (unsigned long)(data + i) ; // receive into "data"
spi[i].len = sizeof(*(data + i)) ;
spi[i].delay_usecs = 0 ;
spi[i].speed_hz = 1000000;
spi[i].bits_per_word = 8 ;
spi[i].cs_change = 0;
}
retVal = ioctl (fd, SPI_IOC_MESSAGE(length), &spi) ;
if(retVal < 0)
{
perror("Problem transmitting spi data..ioctl");
exit(1);
}
}
Only one spi_ioc_transfer structure for rx and tx
but use ioctl call for each byte
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long)spiregister,
.rx_buf = (unsigned long)rx,
.len = ARRAY_SIZE(spiregister),
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
};
// send command of 2 bytes
// send the first byte
spiregister[0] = 0x20
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1)
pabort("Config : can't send spi message");
sleep(1);
// send the second byte
spiregister[1] = 0x0; // RREG of 1 register only
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1)
pabort("Config : can't send spi message");
sleep(1);
Use a structure for rx and a structure for tx, but send all in the same
ioctl call.
unsigned char buf_rx[10];
unsigned char buf_tx[10];
struct spi_ioc_transfer mesg[2];
// write 2 bytes
buf_tx[0] = OPT_CODE_RREG + ID_REG;
buf_tx[1] = 0x0;
mesg[0].tx_buf = (unsigned long)buf_tx;
mesg[0].rx_buf = (unsigned long)NULL;
mesg[0].len = 2;
mesg[0].cs_change = 0;
// read 1 bytes
mesg[1].tx_buf = (unsigned long)NULL;
mesg[1].rx_buf = (unsigned long)buf_rx;
mesg[1].len = 1;
mesg[1].cs_change = 0;
ret = ioctl(fd, SPI_IOC_MESSAGE(2), mesg);
if (ret < 1)
pabort("Config : can't send spi message");
usleep(100);
So I have a very dummy question. What is the good way to write/read from
the master with spidev in C.
Requisite here :
- Send a command to say which register I want to read.
- Read the answer from my spi slave
My command must be 2 bytes longs.
My answer is 1 byte longs.
So I would appreciate to find a working example which using spidev properly.
Thanks !
Arthur.
Le mercredi 12 novembre 2014 22:57:40 UTC+1, [email protected] a écrit :
>
> Hi Arthur,
>
> BBB is a very time consuming hobby.
> Take it ease, relax, go for a walk and when you return, try:
>
> 1) try your project as root
> if no luck follow my (working) path
>
> 2) Try to repeat my settings and see if it works for you.
> I wasn't able to build the original Linux spidev_test, so...
>
> What I have is:
>
> root@beaglebone:~# uname -a
> Linux beaglebone 3.8.13-bone50 #1 SMP Tue May 13 13:24:52 UTC 2014 armv7l
> GNU/Linux
>
> Following the instruction from here
> http://www.nagavenkat.adurthi.com/2014/02/spi-communication-beaglebone-black-as-master-to-arduino-as-slave/
>
> I created SPI-4SS-00A0.dts and compiled it into SPI-4SS-00A0.dts following
> exactly the instruction
>
> By doing that you should have in /sys/devices/bone_capemgr.9/slots
>
> 0: 54:PF---
> 1: 55:PF---
> 2: 56:PF---
> 3: 57:PF---
> 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
> 5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
> 8: ff:P-O-L Override Board Name,00A0,Override Manuf,SPI-4SS
>
> To test it I obtained and created files in /opt/test/test2 as attached:
> build
> SimpleGPIO.cpp - from Derek Molloy
> https://github.com/derekmolloy/beaglebone/blob/master/SimpleGPIO.cpp
> SimpleGPIO.h - from Derek Molloy
> https://github.com/derekmolloy/beaglebone/blob/master/SimpleGPIO.h
> test2.cpp - mine main file
>
> unzip attached and compile
>
> root@beaglebone:/opt/test/test2# ./build
> Building test2 - J.Sz.
> root@beaglebone:/opt/test/test2#
>
> then run (have P9-18 and P9-21 connected as loopback)
>
> root@beaglebone:/opt/test/test2# ./test2
> Initialize SS pins for SPI
> Initialize SPI
> SPI transfer
> rx = 30 31 32 33 34 35 36 37
> rx = 31 32
> rx = 33 34
> rx = 35 36
> rx = 37 38
> rx = 30 31 32 33 34 35 36 37
> ...
>
> press CTRL-C to terminate or let it run and observe with a scope all SPI0
> signals
>
> Hope this will help
>
> Jan
>
> Sorry, I don't see how to insert a file so:
> build is:
>
> #!/bin/bash
> echo "Building test2 - J.Sz."
> g++ test2.cpp SimpleGPIO.cpp -o test2
>
> test2.cpp is
>
> //#ifndef SPICOMM_H_
> //#define SPICOMM_H_
>
>
> #include <stdint.h>
> #include <unistd.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <getopt.h>
> #include <fcntl.h>
> #include <sys/ioctl.h>
> #include <linux/types.h>
> #include <linux/spi/spidev.h>
> #include "SimpleGPIO.h"
> #include <iostream>
> #include <string>
> #include "SimpleGPIO.h"
>
> using namespace std;
>
> // example functions from
> http://www.nagavenkat.adurthi.com/2014/02/spi-communication-beaglebone-black-as-master-to-arduino-as-slave/
>
> #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
>
> static void pabort(const char *s)
> {
> perror(s);
> abort();
> }
>
>
> //4 SS pins for 4 SPI devices
> void init_motor_spi_ss(int gpio1,int gpio2,int gpio3,int gpio4){
> //export the pins. I have used then pins described in the table above
> gpio_export(gpio1);
> gpio_export(gpio2);
> gpio_export(gpio3);
> gpio_export(gpio4);
>
> // set them as High. The SS pins should be high when idle(no commuication)
>
> gpio_set_dir(gpio1, OUTPUT_PIN);
> gpio_set_dir(gpio2, OUTPUT_PIN);
> gpio_set_dir(gpio3, OUTPUT_PIN);
> gpio_set_dir(gpio4, OUTPUT_PIN);
>
> gpio_set_value(gpio1, HIGH);
> gpio_set_value(gpio2, HIGH);
> gpio_set_value(gpio3, HIGH);
> gpio_set_value(gpio4, HIGH);
>
> }
>
> static const char *device = "/dev/spidev1.0"; // this is when SPI0 was
> enabled. change it when SPI1 is enabled
> static uint8_t mode=0; //this mode works well for me
> static uint8_t bits = 8; //arduino accepts 8 bits at once
> //static uint32_t speed = 1000000; //1MHz speed
> static uint32_t speed = 1000000; //2MHz speed
> static uint16_t delay=0;
>
> static void init_spi(void)
> {
> int fd;
> int ret = 0;
>
> fd = open(device, O_RDWR);
> if (fd < 0)
> pabort("can't open device");
>
> /*
> * spi mode
> */
> ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
> if (ret == -1)
> pabort("can't set spi mode");
> ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
> if (ret == -1)
> pabort("can't get spi mode");
>
> /*
> * bits per word
> */
> ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
> if (ret == -1)
> pabort("can't set bits per word");
> ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
> if (ret == -1)
> pabort("can't get bits per word");
>
> /*
> * max speed hz
> */
> ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
> if (ret == -1)
> pabort("can't set max speed hz");
> ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
> if (ret == -1)
> pabort("can't get max speed hz");
>
> }
>
> void spi_transfer(uint8_t *txbuffer, int size, int gpio)
> {
>
> int fd;
> int ret = 0;
> //uint8_t tx[8];
> //tx[0]='0';
> //tx[1]='1';
> //tx[2]='2';
> //tx[3]='3';
> //tx[4]='4';
> //tx[5]='5';
> //tx[6]='6';
> //tx[7]='7';
>
> //uint8_t rx[ARRAY_SIZE(txbuffer)] = {0, };
> uint8_t rx[size];
>
>
> struct spi_ioc_transfer tr = {
> //tr.tx_buf = (unsigned long)tx,
> //tr.rx_buf = (unsigned long)rx,
> //tr.len = ARRAY_SIZE(tx),
> tr.tx_buf = (unsigned long)txbuffer,
> tr.rx_buf = (unsigned long)rx,
> tr.len = size,
> tr.delay_usecs = delay,
> tr.speed_hz = speed,
> tr.bits_per_word = bits,
> };
>
> fd = open(device, O_RDWR);
> if (fd < 0)
> pabort("can't open device");
>
>
> gpio_set_value(gpio, LOW);
> ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
> if (ret < 1)
> pabort("can't send spi message");
>
> close(fd);
> gpio_set_value(gpio, HIGH);
>
> cout<<"rx = ";
> for(int i=0;i<size;i++){
> printf("%.2X",rx[i]);
> cout<<" ";
> }
> cout<<endl;
>
> }
>
> int main(int argc, char *argv[]){
>
> cout << "Initialize SS pins for SPI" << endl;
> init_motor_spi_ss(48, 49, 60, 115);
>
> cout << "Initialize SPI" << endl;
> init_spi();
>
> cout << "SPI transfer" << endl;
> while(1)
>
>
> {
>
> spi_transfer((uint8_t *)"01234567", 8, 48);
> spi_transfer((uint8_t *)"12", 2, 48);
> spi_transfer((uint8_t *)"34", 2, 49);
> spi_transfer((uint8_t *)"56", 2, 60);
> spi_transfer((uint8_t *)"78", 2, 115);
> }
>
>
>
>
> return 0;
> }
>
>
> THE END
>
>
>
>
>
> On Thursday, November 13, 2014 5:10:44 AM UTC+11, [email protected]
> wrote:
>>
>> Hi Jan,
>>
>> So I put a simple wire between pin 18 and 21 and try to run the
>> spidev_test... Same result... FF only.... I also check with an
>> oscilloscope. I see nothing... I am not able to see my data.
>>
>> root@beaglebone:~# ./spidev_test -D /dev/spidev1.0
>>> spi mode: 0
>>> bits per word: 8
>>> max speed: 500000 Hz (500 KHz)
>>> FF FF FF FF FF FF
>>> FF FF FF FF FF FF
>>> FF FF FF FF FF FF
>>> FF FF FF FF FF FF
>>> FF FF FF FF FF FF
>>> FF FF FF FF FF FF
>>> FF FF
>>
>>
>> So first I am currently using my own dtc file from input on the web :
>>
>> /dts-v1/;
>>> /plugin/;
>>> / {
>>> compatible = "ti,beaglebone", "ti,beaglebone-black";
>>> /* identification */
>>> part-number = "spi0pinmux";
>>> fragment@0 {
>>> target = <&am33xx_pinmux>;
>>> __overlay__ {
>>> spi0_pins_s0: spi0_pins_s0 {
>>> pinctrl-single,pins = <
>>> 0x150 0x30 /* spi0_sclk, INPUT_PULLUP | MODE0 */
>>> 0x154 0x30 /* spi0_d0, INPUT_PULLUP | MODE0 */
>>> 0x158 0x10 /* spi0_d1, OUTPUT_PULLUP | MODE0 */
>>> 0x15c 0x10 /* spi0_cs0, OUTPUT_PULLUP | MODE0 */
>>> >;
>>> };
>>> };
>>> };
>>> fragment@1 {
>>> target = <&spi0>;
>>> __overlay__ {
>>> #address-cells = <1>;
>>> #size-cells = <0>;
>>> status = "okay";
>>> pinctrl-names = "default";
>>> pinctrl-0 = <&spi0_pins_s0>;
>>> spidev@0 {
>>> spi-max-frequency = <24000000>;
>>> reg = <0>;
>>> compatible = "linux,spidev";
>>> };
>>> };
>>> };
>>> };
>>
>>
>> So I build the dtbo file :
>>
>> dtc -O dtb -o /lib/firmware/BB-ARTHUR-SPI0-00A0.dtbo -b 0 -@
>>> BB-ARTHUR-SPI0-00A0.dts
>>> echo BB-ARTHUR-SPI0 > /sys/devices/bone_capemgr.9/slots
>>
>>
>> Then I run uname -r to get the current linux version : 3.8.13-bone47
>> I download kernel source from kernel.org to get the spidev_test.c file.
>> I compile it on the board and I run it.
>>
>> Do I wrong somewhere ? I am currently running the original EMMC
>> distribution of the beaglebone black ( The board was ordered few weeks ago,
>> so I can guess that I used a very recent version of the beagleboard
>> binary).
>>
>> I also found in your link something about patching the kernel :
>>
>> diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
>>> index 911e9e0..622adf5 100644
>>> --- a/drivers/spi/spidev.c
>>> +++ b/drivers/spi/spidev.c
>>> @@ -646,6 +646,7 @@ static int spidev_remove(struct spi_device *spi)
>>>
>>> static const struct of_device_id spidev_dt_ids[] = {
>>> { .compatible = "rohm,dh2228fv" },
>>> + { .compatible = "linux,spidev" },
>>> {},
>>> };
>>
>>
>> Do I have to download my own source to build a beagleboard image and to
>> patch the kernel before with this patch to be able to use SPI ?
>>
>> Thanks & Regards,
>> Arthur.
>>
>> Le mardi 11 novembre 2014 00:54:29 UTC+1, [email protected] a écrit :
>>>
>>> Hi,
>>>
>>> Following the links: http://elinux.org/BeagleBone_Black_Enable_SPIDEV
>>> and
>>> http://www.nagavenkat.adurthi.com/2014/02/spi-communication-beaglebone-black-as-master-to-arduino-as-slave/
>>>
>>> I was able to make it work, but I have a SS too long (1.4ms) for my need.
>>> For easy test connect MOSI and MISO with a wire (loopback) to eliminate
>>> connection problem with you SPI slave.
>>> Hope this will help. When you done, can you measure the timing a let me
>>> know?
>>> I can post you my code if you need it.
>>>
>>> Jan
>>>
>>> On Tuesday, November 11, 2014 5:03:38 AM UTC+11, [email protected]
>>> wrote:
>>>>
>>>> Hi,
>>>>
>>>> I am trying to communicate with a device (ADS1299à by using the
>>>> Beaglebone black but without success. First I have to enable spi dev
>>>> entries in /dev. There are plenty of blog/tuto which are giving dtc file
>>>> to
>>>> generate our own dtbo. But dtc files seems to not be always the same.
>>>>
>>>> In fact I can see that there are already some dtbo files in
>>>> /lib/firmware :
>>>> root@beaglebone:~# ls /lib/firmware/ | grep SPI
>>>> ADAFRUIT-SPI0-00A0.dtbo
>>>> ADAFRUIT-SPI1-00A0.dtbo
>>>> BB-SPIDEV0-00A0.dtbo
>>>> BB-SPIDEV1-00A0.dtbo
>>>> BB-SPIDEV1A1-00A0.dtbo
>>>>
>>>> So I want to use only SPI0 because I know that SPI1 is already used by
>>>> HDMI. Can I used theses dtbo files ? Is it better to write my own ? It is
>>>> quite strange, when I enable one of theses dtbo files, I get not only one
>>>> but two entries in /dev ??
>>>>
>>>> Currently I want to validate my wiring between the two boards. I found
>>>> a piece of code to read the device id in register of the device though
>>>> SPI.
>>>> But when I try to read this register, I can only get 1 or only get 0
>>>> (depends of the dtbo files)
>>>>
>>>> Any advice of the good way to process here ?
>>>>
>>>> Thanks & Regards,
>>>> Arthur.
>>>>
>>>>
>>>>
>>>>
>>>>
--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.