Hi, I have the save problem. I'm writing 2 bytes to an external device over SPI and i'm waiting for one byte response.
I saw on the scope that the device send the response on the MISO, but i can't read it with spidev. i'm using one transfert struct for full duplex commnication and i'm waiting for 2 dummy byte and 1 real response byte, but unfortunately it's not the case. when i short the MISO and MOSI, i can read what i write on the spi bus. do you have some suggestions? Thanks, Le jeudi 11 décembre 2014 20:50:58 UTC+1, janszyma...@gmail.com a écrit : > > Hi, > > 1) I said your clock should not be much higher than the maximum clock, > that a device can handle. It can be anything within the range. You are OK > with 1MHz, no need to change it. > SPI mode and pin mode on BBB are 2 different things, you are OK here as > well. > > 2) Your software calls to IOCtl will handle CS, just use a 3 bytes > transfer. And yes the dummy value can be anything. > > Change only one thing at a time. My guess is that by doing #2 above you > will be fine, unless there are things you didn't tell me like hardware > issues (wrong pinouts, wrong power supply, wrong voltage levels) > > Jan > > > > > On Thursday, December 11, 2014 9:50:10 PM UTC+11, lambert...@gmail.com > wrote: > >> Hi Jan, >> >> Thanks for your answer. >> >> 1) >> SPI_MODE : >> I am currently using the SPI_MODE_1 so it seems ok (CPOL = 0x02 | CPHA = >> 0x01 ==> 0x01) >> >> I have also a MODE0 in my device tree file : >> spi0_pins_s0: spi0_pins_s0 { >> pinctrl-single,pins = < >> 0x150 0x10 /* spi0_sclk, OUTPUT_PULLUP | MODE0 */ >> 0x154 0x30 /* spi0_d0, INPUT_PULLUP | MODE0 */ >> 0x158 0x10 /* spi0_d1, OUTPUT_PULLUP | MODE0 */ >> 0x15c 0x10 /* spi0_cs0, OUTPUT_PULLUP | MODE0 */ >> >> >> But it is not the same thing right ? In the datasheet of the Beaglebone >> Black (link <http://www.adafruit.com/datasheets/BBB_SRM.pdf>), Page 72, >> in the P9 header Pinout, I can see that the pin that I need is a spi with >> particular mode. That's why I put MODE 0 here. >> >> >> Speed Clock >> My speed is currently 1 000 000 (in my dtc file and in my code). >> I have no idea how to setup the speed, I see often 1 000 000 in example >> so I took this value. >> So if I have a look on the datasheet and compute the min/max, its seems >> that the value must be between 1.501 MHz and 2.252 MHz.. >> >> So I will try to update the speed to see if I can see any differences in >> my result >> >> 2) >> But in fact in my case I have not to handle the CS or the fact to write >> dummy byte right? Spidev handles the CS for me. Moreover If I use only one >> struct spi_ioc_transfer to handle my message I always write the same number >> of bytes that I read (because I have only 1 field len in the structure) >> >> If I follow your advice with a len of 3 bytes it means that at each iocl >> call I will write/read 3 bytes. I guess that I must handle this dummy byte >> if I used oldchool way like read/write syscall (But in my understanding I >> cannot do it because I need to have the CS low between the write and the >> read and I cannot set the CS from userland) >> >> 3) >> I will follow your advise and use this method with only one structure >> with a len set to 3. >> The dummy byte of 0xff it is just a convention right ? I can put 0x0 or >> 0x42 it will be the same result right ? >> >> Thanks again for your advice. >> Arthur. >> >> >> >> Le mercredi 10 décembre 2014 22:49:10 UTC+1, janszyma...@gmail.com a >> écrit : >>> >>> Hi Artur, >>> >>> Sorry to hear, you have problems, but usually there is something very >>> simple, that you might be doing wrong: >>> >>> 1) Check you SPI setting. For your device you need CPOL=0 and CPHA=1 - >>> see page 8 of http://www.ti.com/lit/ds/symlink/ads1299.pdf and the max >>> freq of master clock 444ns -> 2.252... MHz (please verify that) >>> >>> 2) You need to understand a bigger picture, how the SPI works. In a >>> nutshell it is a Master/Slave arrangement, where the master always >>> generates the clock. In your case BBB is a master and ADS1299 is a slave. >>> The data on DIN, DOUT or MISO, MOSI lines flows both ways simultaneously. >>> 2a) To perform the write transaction, master sends a byte (bytes) >>> generating the signals CS, CLK and MOSI. At the same time MISO is coming >>> from slave device. You need to read the incoming data to flush the buffer, >>> even if it is (the data) meaningless. >>> 2b) >>> To perform the read transaction, master sends a dummy data and redas the >>> response. >>> >>> 3) In you case it depends on the transaction, but as you mention, you >>> need to sens 2 bytes and read one response, you do the followin: >>> write 3 byes, specifically 2 command byte and one dummy byte (usually >>> 0xff) and read back 3 bytes. Ignore the first 2 bytes read and the third >>> one will be your valid data. All within the same transaction (one CS) >>> >>> REMEMBER: to read you need to perform a dummy write. >>> As for your code, all version should work. I would use a simultaneous >>> read write of 3 bytes. >>> >>> Hope this will help. >>> >>> Jan >>> >>> >>> >>> >>> >>> >>> On Thursday, December 11, 2014 4:28:37 AM UTC+11, lambert...@gmail.com >>> wrote: >>>> >>>> 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, janszyma...@gmail.com 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 >>>> >>>> ... >>> >>> -- 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 beagleboard+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.