Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 11 of 11

Thread: SPIFIO issues

  1. #1
    Member
    Join Date
    Mar 2013
    Location
    Austin, TX
    Posts
    93

    SPIFIO issues

    Hello,
    I keep coming back to SPIFIFO but have yet to get it reading correctly.
    I've got it working fine with and DAC as that just involves sending but I simply can't get anything back from this serial flash chip.

    This code returns the correct value.
    Code:
    //setup
       pinMode(10, OUTPUT);
       spi4teensy3::init();
    
    //loop
      digitalWriteFast(cs,LOW);
      spi4teensy3::send(0x05);
      byte s=spi4teensy3::receive();
      digitalWriteFast(cs,HIGH);

    These do not.
    Code:
    //setup
       pinMode(10, OUTPUT);
       SPIFIFO.begin(10,SPI_CLOCK_12MHz);  //other speeds have been tried
    
    //this loop
      SPIFIFO.write(0x05);
      byte s1 =SPIFIFO.read();
    
    //or this
      SPIFIFO.write(0x05, SPI_CONTINUE);
      SPIFIFO.write(0);
      byte s1 =SPIFIFO.read();
      byte s2 =SPIFIFO.read();
    
    //or this
      SPIFIFO.clear();
      SPIFIFO.write(0x05, SPI_CONTINUE);
      byte s1 =SPIFIFO.read();
      SPIFIFO.write(0);
      byte s2 =SPIFIFO.read();
    In every situation I get 0 back and don't see anything on the scope on the RX pin of the 3.1. There are things happening on CS, TX and CLK.
    What am I missing?

    Thanks.
    Last edited by john-mike; 01-11-2015 at 01:14 AM.

  2. #2
    Member
    Join Date
    Mar 2013
    Location
    Austin, TX
    Posts
    93
    Ooops spelling it wrong in the tread title is not a good sign.

  3. #3
    Junior Member
    Join Date
    Nov 2013
    Posts
    18
    HI John,

    did you manage to solve your problem yet ?
    Have the same issues.

  4. #4
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,789
    Normally, I don't investigate when the "forum rule" isn't followed. But in this case, I'm making an exception, because there's been a few messages lately reporting problems with SPIFIFO, but so far, none following the forum rule with a complete program and hardware details.

    I tested with a Winbond W25Q64FV chip connected to Teensy 3.1, using Teensyduino 1.21-test2.

    Here's how I connected everything:

    Click image for larger version. 

Name:	flash.jpg 
Views:	159 
Size:	68.0 KB 
ID:	3292

    Because a complete program wasn't provided, I had to write one for testing.

    Here's what I wrote, to query the JEDEC device identification info. The ID bytes are documented in section 6.2.1 on page 20 of Winbond's datasheet.

    Code:
    #include "SPIFIFO.h"
    
    void setup() {
      byte manufacturerID, memoryType, capacity;
    
      while (!Serial) ; // wait for serial monitor
      delay(100);
      Serial.println("SPIFIFO Test");
      SPIFIFO.begin(10, SPI_CLOCK_12MHz);
      delay(1);
      
      SPIFIFO.write(0x9F, SPI_CONTINUE);
      SPIFIFO.write(0, SPI_CONTINUE);
      SPIFIFO.write(0, SPI_CONTINUE);
      SPIFIFO.write(0);
      SPIFIFO.read();
      manufacturerID = SPIFIFO.read();
      memoryType = SPIFIFO.read();
      capacity = SPIFIFO.read();
    
      Serial.print("manufacturerID = ");
      Serial.println(manufacturerID, HEX);
      Serial.print("memoryType = ");
      Serial.println(memoryType, HEX);
      Serial.print("capacity = ");
      Serial.println(capacity, HEX);
    }
    
    void loop() {
    }
    Here's what I see in the serial monitor:

    Click image for larger version. 

Name:	sc.png 
Views:	118 
Size:	9.3 KB 
ID:	3293
    (click for full size)

    It certainly seems to be working properly. Just to make sure, I connected my oscilloscope.

    Click image for larger version. 

Name:	scope_0.png 
Views:	131 
Size:	37.3 KB 
ID:	3294
    (click for full size)

    Had you posted a complete program, I would have tested with your code and likely found the cause of your trouble. But when the forum rule isn't followed, this is the best I can do. Hopefully it helps?

  5. #5
    Member
    Join Date
    Mar 2013
    Location
    Austin, TX
    Posts
    93
    Sorry I just wanted to show the differences between them without posting the entire thing 4 times.
    There's really nothing else to the test code but I completely understand your frustration and should have just put it up.

    Code:
    //#include <spi4teensy3.h>
    #include <SPIFIFO.h>
    
    /////////////////////////////////////////////////////////
    
    void setup() {
       pinMode(10, OUTPUT);
      // spi4teensy3::init();
       SPIFIFO.begin(10,SPI_CLOCK_12MHz);  //other speeds have been tried
    
    }
    
    /////////////////////////////////////////////////////////
    
    void loop() {
      /*
      digitalWriteFast(10,LOW);
      spi4teensy3::send(0x05);
      byte s=spi4teensy3::receive();
      digitalWriteFast(10,HIGH);
      */
    
      SPIFIFO.write(0x05, SPI_CONTINUE);
      SPIFIFO.write(0);
      byte s1 =SPIFIFO.read();
      byte s2 =SPIFIFO.read();
    
    
      Serial.println(2);
      Serial.println();
    
      delay(200);
    
    }
    The issues seems to have been pull-ups on one board and not another. Maybe?
    Again the exact same setup worked with spi4 but not FIFO. When pull-ups were added FIFO started working.
    This seems odd since I would have seen something on the scope (It's just a DSO nanao 1MHz but you can at least see is something is happening).

    Either way what you have posted there Paul should be helpful to others.

    Thanks again for all of your time!
    Last edited by john-mike; 01-12-2015 at 06:15 PM.

  6. #6
    Senior Member
    Join Date
    Feb 2013
    Posts
    563
    slightly OT (my apologies), but as it's got to do with SPIFIFO and DACs i didn't want to open another thread.

    i was trying to move some code to spififo as it seems to allow for faster DAC update rates than doing things with spi.transfer ... but i'm puzzling over this piece of code, or SPIFIFO.read(); for that matter. i need to send three bytes, which seems to work just fine -- as long as i don't follow the rules (as far as i know, but it looks as if i must be missing something).

    ie AFAIK, for every write there should be a corresponding read, but my program crashes as soon as i actually call SPIFIFO.read() three times. once is ok, twice is ok. there's no obvious problems even when i don't call read at all. the code doesn't look that much different from the W25Q64FV example above, except for the write16:


    Code:
    void set_CHA(uint16_t _data) {
      
                    SPIFIFO.write(0x10, SPI_CONTINUE); //  cmd byte
                    SPIFIFO.write16(_data); 
                    SPIFIFO.read();   
                    SPIFIFO.read(); 
                   //SPIFIFO.read();    // uncomment this and things crash                        
    }
    doing this, meanwhile, does work:

    Code:
    void set_CHA(uint16_t _data) {
      
                    SPIFIFO.write(0x10, SPI_CONTINUE); //  cmd byte
                    SPIFIFO.write(_data>>8, SPI_CONTINUE);
                    SPIFIFO.write(_data); 
                    SPIFIFO.read();   
                    SPIFIFO.read();  
                    SPIFIFO.read();   
                             
    }
    so i guess i'm unclear about what the corresponding read to write16 would look like ?
    Last edited by mxxx; 01-19-2015 at 03:17 PM.

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,789
    Quote Originally Posted by mxxx View Post
    Code:
                   //SPIFIFO.read();    // uncomment this and things crash
    Yes, of course it crashes.

    You must exactly match every SPIFIFO.write() with a corresponding SPIFIFO.read(). Every 16 bit write much be matched with a 16 bit read, and every 8 bit write must be matched with an 8 bit read.

    SPIFIFO is tough to use. You are responsible for remembering what you wrote and later doing the matching reads. It's not easy to write complex code to achieve perfect balance. If you don't perfectly match every write with exactly the same read, or it you ever issue more writes (more than 4) than the FIFO can hold, things go very badly.

    The normal Arduino SPI library is meant to be easy to use. The latest version has SPI.transfer(buffer, length) which is optimized. That's much easier to use, but it doesn't give you the ability to mix with other SPI.transfer() and exploit the FIFO across each function. SPIFIFO gives you that, but the cost is the requirement to exactly match every write with a corresponding read.
    Last edited by PaulStoffregen; 01-19-2015 at 04:00 PM.

  8. #8
    Senior Member
    Join Date
    Feb 2013
    Posts
    563
    ok, though i was wondering why does it crash only *when* i try to match every write with a read?

    i guess my error was assuming that calling SPIFIFO.read(); returns one byte ... which apparently it is not.

    this works:

    Code:
    void set_CHA(uint16_t _data) {
      
                    SPIFIFO.write(0x10, SPI_CONTINUE);
                    SPIFIFO.write16(_data);
                    SPIFIFO.read();   
                    uint16_t tmp = SPIFIFO.read();
                             
    }
    Last edited by mxxx; 01-19-2015 at 04:29 PM.

  9. #9
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,789
    Oh, yeah, SPIFIFO.read() returns either 8 or 16 bits, depending on the write it's matched with.

  10. #10
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    8,002
    Is the maximum SPI-Clock 30MHz (F_BUS/2) ? If so (i'm not sure) are there some lines missing in SPIFIFO.h ? The fastest #define is for 20MHz.
    I'm planning to use SPIFIFO for the flashplayer, so this would be good to know.

    Edit:

    Perhaps

    #define SPI_CLOCK_30MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(60 / 2) * ((1+1)/2)

    ?
    Last edited by Frank B; 01-19-2015 at 05:26 PM.

  11. #11
    Senior Member
    Join Date
    Feb 2013
    Posts
    563
    adding

    Code:
    #if F_BUS == 60000000
    #define HAS_SPIFIFO
    #define SPI_CLOCK_30MHz   (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(60 / 2) * ((1+1)/2) = 30 MHz
    seems to work for me.

    (that said, i haven't checked whether it improves anything, but SPIFIFO at any rate seems to be much faster than SPI.transfer, at least for the kind of simple stuff above. i'm playing around with some 4-channel DDS thingie. using SPI.h, things would bail out at about 20kHz sample clock (though maybe i was doing something wrong). with SPIFIFO i manage 40kHz (at least -- i haven't tried to max it out) ... that's using the PIT timer; ideally though, i'd probably get the audiolibrary to output to SPI)
    Last edited by mxxx; 01-19-2015 at 05:56 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •