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.

Reply via email to