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

Thread: Ethernet on T3.6 SPI1 with FIFO

  1. #1
    Member
    Join Date
    Jul 2016
    Location
    Denmark
    Posts
    26

    Ethernet on T3.6 SPI1 with FIFO

    i am trying to use a Wiz850io with the T3.6 but on SPI1
    i think i have changed all the things that need changing but it gets stuck in the right in the beginning when tying to read the chip type.
    it seems to be this while loop in the SPIFIFO that never reaches completion
    line 382 in SPIFIFO.h
    Code:
    inline void write(uint32_t b, uint32_t cont=0) __attribute__((always_inline)) {
      uint32_t pcsbits = pcs1 << 16;
      if (pcsbits) {
        KINETISK_SPI1.PUSHR = (b & 0xFF) | pcsbits | (cont ? SPI_PUSHR_CONT : 0);
        while (((KINETISK_SPI1.SR) & (15 << 12)) > (3 << 12)) ; // wait if FIFO full
      } else {
        *reg1 = 0;
        KINETISK_SPI1.SR = SPI_SR_EOQF;
        KINETISK_SPI1.PUSHR = (b & 0xFF) | (cont ? 0 : SPI_PUSHR_EOQ);
        if (cont) {
          while (((KINETISK_SPI1.SR) & (15 << 12)) > (3 << 12)) ;
        } else {
          while (!(KINETISK_SPI1.SR & SPI_SR_EOQF)){
            //------------remove this------------------------
            digitalWrite(13,HIGH);
            delay(200);
            digitalWrite(13,LOW);
            delay(200);
            //------------------------------------
          }
          *reg1 = 1;
        }
      }
    }
    any ideas is greatly appreciated

    the all the changes i have made to the Ethernet an core libs are here:
    https://github.com/alex-Arc/cores/tree/SPI1FIFO
    https://github.com/alex-Arc/Ethernet...ternet_SPI_pin
    Last edited by alex-arc; 09-22-2017 at 09:19 PM. Reason: add line number

  2. #2
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,574
    It may not be the problem, but only SPI0 has a FIFO of depth 4. SPI1 and SPI2 have depth-1 FIFO

  3. #3
    Member
    Join Date
    Jul 2016
    Location
    Denmark
    Posts
    26
    Quote Originally Posted by manitou View Post
    It may not be the problem, but only SPI0 has a FIFO of depth 4. SPI1 and SPI2 have depth-1 FIFO
    yes that is some of it

    Code:
    while (((KINETISK_SPI1.SR) & (15 << 12)) > (3 << 12)) ; // wait if FIFO full
    should be
    Code:
    while (((KINETISK_SPI1.SR) & (15 << 12)) > ((1-1) << 12)) ; // wait if FIFO full
    thanks to KurtE https://forum.pjrc.com/threads/45321...highlight=SPI1

    it stile doesn't work.
    i am trying with out the FIFO function and that doesn't work either so i must have done something very wrong
    Code:
    // #include "SPIFIFO.h"
    // #ifdef  HAS_SPIFIFO
    // #define USE_SPIFIFO
    // #endif

  4. #4
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,441
    That was one of the first things I ran into with SPI1/2 when testing on T3.6, which is why I have the SPIN library (github/kurte), which has the full checking and the like.

    But sometimes that is not enough. You have to carefully go through the logic, in certain cases. Ran into issue with ILI9341 library for reading pixels. Would do something like: PUSHR, PUSHR, PUSHR and then expect to have 3 bytes on the POPR to get the color...
    So from your above:
    Code:
    inline void write(uint32_t b, uint32_t cont=0) __attribute__((always_inline)) {
      uint32_t pcsbits = pcs1 << 16;
      if (pcsbits) {
        KINETISK_SPI1.PUSHR = (b & 0xFF) | pcsbits | (cont ? SPI_PUSHR_CONT : 0);
        while (((KINETISK_SPI1.SR) & (15 << 12)) > (3 << 12)) ; // wait if FIFO full
      } else {
        *reg1 = 0;
        KINETISK_SPI1.SR = SPI_SR_EOQF;
        KINETISK_SPI1.PUSHR = (b & 0xFF) | (cont ? 0 : SPI_PUSHR_EOQ);
        if (cont) {
          while (((KINETISK_SPI1.SR) & (15 << 12)) > (3 << 12)) ;
        } else {
          while (!(KINETISK_SPI1.SR & SPI_SR_EOQF)){
            //------------remove this------------------------
            digitalWrite(13,HIGH);
            delay(200);
            digitalWrite(13,LOW);
            delay(200);
            //------------------------------------
          }
          *reg1 = 1;
        }
      }
    }
    Not sure what your pcs1 is?

    You say it hangs, but maybe hard to say without seeing how this is called. That is are you passing in in cont?

    You might want to take a look at my ili9341_t3n library and how it uses my SPIN...
    In particular I have simple helper functions like:
    Code:
    #ifdef KINETISK	
    	void writecommand_cont(uint8_t c) __attribute__((always_inline)) {
    		_pkinetisk_spi->PUSHR = c | (pcs_command << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
    		_pspin->waitFifoNotFull();
    	}
    	void writedata8_cont(uint8_t c) __attribute__((always_inline)) {
    		_pkinetisk_spi->PUSHR = c | (pcs_data << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
    		_pspin->waitFifoNotFull();
    	}
    	void writedata16_cont(uint16_t d) __attribute__((always_inline)) {
    		_pkinetisk_spi->PUSHR = d | (pcs_data << 16) | SPI_PUSHR_CTAS(1) | SPI_PUSHR_CONT;
    		_pspin->waitFifoNotFull();
    	}
    	void writecommand_last(uint8_t c) __attribute__((always_inline)) {
    		uint32_t mcr = _pkinetisk_spi->MCR;
    		_pkinetisk_spi->PUSHR = c | (pcs_command << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_EOQ;
    		_pspin->waitTransmitComplete(mcr);
    	}
    	void writedata8_last(uint8_t c) __attribute__((always_inline)) {
    		uint32_t mcr = _pkinetisk_spi->MCR;
    		_pkinetisk_spi->PUSHR = c | (pcs_data << 16) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_EOQ;
    		_pspin->waitTransmitComplete(mcr);
    	}
    	void writedata16_last(uint16_t d) __attribute__((always_inline)) {
    		uint32_t mcr = _pkinetisk_spi->MCR;
    		_pkinetisk_spi->PUSHR = d | (pcs_data << 16) | SPI_PUSHR_CTAS(1) | SPI_PUSHR_EOQ;
    		_pspin->waitTransmitComplete(mcr);
    	}
    #endif
    But this has the added stuff of controlling the chip select pin(s). In my case the library makes sure the DC is on a hardware CS pin... And optionally CS can also be hardware CS (but not necessary). That is why here we have functions that are different for data versus command.

    And from SPIN:
    Code:
    #if defined(KINETISK)
    void SPINClass::waitFifoNotFull(void) {
        uint32_t sr;
        uint32_t tmp __attribute__((unused));
        do {
            sr = port().SR;
            if (sr & 0xF0) tmp = port().POPR;  // drain RX FIFO
        } while ((uint32_t)(sr & (15 << 12)) > (uint32_t)((_fifo_size-1) << 12));
    }
    void SPINClass::waitFifoEmpty(void) {
        uint32_t sr;
        uint32_t tmp __attribute__((unused));
        do {
            sr = port().SR;
            if (sr & 0xF0) tmp = port().POPR;  // drain RX FIFO
        } while ((sr & 0xF0F0) > 0);             // wait both RX & TX empty
    }
    void SPINClass::waitTransmitComplete(void)  {
        uint32_t tmp __attribute__((unused));
        while (!(port().SR & SPI_SR_TCF)) ; // wait until final output done
        tmp = port().POPR;                  // drain the final RX FIFO word
    }
    void SPINClass::waitTransmitComplete(uint32_t mcr) {
        uint32_t tmp __attribute__((unused));
        while (1) {
            uint32_t sr = port().SR;
            if (sr & SPI_SR_EOQF) break;  // wait for last transmit
            if (sr &  0xF0) tmp = port().POPR;
        }
        port().SR = SPI_SR_EOQF;
        port().MCR = mcr;
        while (port().SR & 0xF0) {
            tmp = port().POPR;
        }
    }
    Note my spin objects know the fifo size... Also they are holding onto a pointer to registers for SPI...
    Hopefully from this you can pick and choose what you need to get yours to work.

  5. #5
    Member
    Join Date
    Jul 2016
    Location
    Denmark
    Posts
    26
    Soooo.....

    Ethernet.cpp and socket.cpp uses SPI directly to.
    i fogot to change them to SPI1
    *sigh*

  6. #6
    Member
    Join Date
    Jul 2016
    Location
    Denmark
    Posts
    26
    Thanks KurtE.
    after fixing the stuff in Ethernet and Socket i still cant get it to work.
    SPIFIFO1 is mostly a clone of SPIFIFO (i was hoping for a quick fix) and looking at it, it looks like i will have to do with out FIFO or free up alternate pins for SPI0 or i wont make it to my deadline

  7. #7
    Member
    Join Date
    Jul 2016
    Location
    Denmark
    Posts
    26
    for those interested, i have made a table with my test results, from my quick test setup
    https://github.com/alex-Arc/Ethernet_speed_test

  8. #8
    We are trying to use a WIZ820io with a Teensy 3.6 on SPI2 (SPI0 is being used with LTC2983 temperature measurement system) and have run into the problems described above. Alex, from your last post is sounds like you got things working, is that correct? Do you mind sharing what all you needed to change, as we will need to change it again to use SPI2 as opposed to SPI1.

    Thanks!

  9. #9
    Member
    Join Date
    Jul 2016
    Location
    Denmark
    Posts
    26
    i think it was mostly just switching from SPI to SPI1 in socket.cpp and w5100.cpp
    https://github.com/alex-Arc/Ethernet...ternet_SPI_pin

Posting Permissions

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