Project: SPI_MSTransfer

No I mean, KinetisK MISO is both for master and slave mode, whereas MISO in kinetisL is MISO in master, but MOSI is for slave mode

So on Kinetis L, you swap the 11 & 12 (or 5 and 0) before connecting to a kinetisK

3.2 support with dynamic addressing (only SPI0 right now)

Code:
[ATTACH]13778._xfImport[/ATTACH]
 
Got me totally confused on that one. Hey, you are creating a monster been actually reading the kl25z manual related to SPI and actually understand most of what you did for slave init. Still working on a couple of things but will get there.

Will retest with the new version for the lc to start.

Mike
 
Ok. LC still works, been testing it at 9Mhz and 400Khz for LED and 10ms loops.

Working on T3.2 but having some problems. Nothing coming across to the slave. Think I have to add back in events into master and recheck the wiring. Testing at 30Mhz and using same gpio. By the way when I first compiled forgot to change from SPI1 to SPI and it gave me a compile error - SPI1 not defined.
 
Looks like I had a bracket mixup in ISR code, it's a good thing I keep looking over the code... I formatted it in the IDE to trace down any mis-places. Heres a patched update of the ISR

Code:
[ATTACH]13782._xfImport[/ATTACH]

Also got rid of the red warning for the 3.x register setting to use parenthesis

Yeah SPI1 and SPI2 dont work on the 3.x yet, make sure MISO connects to MISO for the 3.2 to 3.5
the LC is MOSI to MISO (swapped)

Swapped from the 3.2 to a 3.5, had to modify a begin() to make it compile, so I could start working on SPI1 & SPI2

Heres the mod:

Code:
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  [COLOR="#FF0000"]if [/COLOR]( &SPIWire == &SPI1 ) {
    spi_mst_spi_addr = 0x4002D000; // SPI1 SLAVE MEMORYMAP
    sSPI_port = 1;
[COLOR="#FF0000"]  }
  if [/COLOR]( &SPIWire == &SPI2 ) {
    spi_mst_spi_addr = 0x400AC000; // SPI2 SLAVE MEMORYMAP
    sSPI_port = 2;
  }
#endif

They used "else if" before, but the compiler define seems to have broke that from the first if statement, so ill leave it at this :)
 
not working with 3.2 to 3.5. Tried a few different combinations just in case. So should try spi1 to check.
 
SPI0 works here....... i flashed it before uploading from #1579, 3.2 and 3.5 tested

Still working on the SPI1 registers (SPI1 doesnt seem to kick on yet, debugging....), I switched the lines back to SPI0 to test it for you and it is indeed still working
 
Last edited:
Hey Hey! SPI1 SLAVE MODE IS OPERATIONAL! :) begin(SPI) // begin(SPI1)

I'm using pins 0, 1, 31, 32
I need to see what I can swap one at a time, because if we use 31 and 32 we loose access to uart4

EDIT, on 3.5, only pins 0 and 1 work in slave mode, 5 and 21 do NOT.., still testing other 2 pins..
EDIT 2, SPI1 SCLK pin 20 does NOT work, ONLY pin 32 works as slave CLK!

That means the 3.5 slave mode looses access to UART4 TX

EDIT, it's final, for SPI1 slave there is ONLY 4 pins to use: 0, 1, 31, and 32. You loose UART4. Live with it :)
I had to add address mapping for the GPIOx_PDIRs since LC/3.2 uses GPIOD_PDIR, and T3.5 uses GPIOB_PDIR, tests worked swapping back and forth fine between SPI and SPI1 :) gonna clean up the begin() for SPI1 now and then work on SPI2, then we must verify those pins against a 3.6 for functionality, if its the same layout, it should just work when I map those memory addresses
 
Last edited:
I don't expect UART4 is used much - if so it might be used to connect to another Teensy in which case this would be an upgrade.
Odd you are seeing MOSI and MISO usage not as defined and typically used for T_3.2?
 
I don't expect UART4 is used much - if so it might be used to connect to another Teensy in which case this would be an upgrade.
Odd you are seeing MOSI and MISO usage not as defined and typically used for T_3.2?

You mean for the connections? I saw a mention long ago about the K series they mixed up the slave mode labeling/latching (for master mode it's labeled properly), so the pins act opposite of normal when in slave mode
It's funny trying to make the busses work in slave mode when you need exactly the right set of pins to make it work :)

Isn't it also weird that on the K & L series pin2 is not a CS pin of SPI0, however, it works accross all K & L series? While the LC requires pin6 as CS1, and T3.5 requires pin31 as CS1...
 
Having a BBQ now - house full of people. But quick question for later:
Code:
     T3.5 Master  T3.2 slave
clk       14          14
cs        15          02
mosi      11          11 (DOUT) ?
miso      12          12 (DIN) ?
          GND        GND

on slave its slave.begin(SPI) correct not SPI0?

Thanks
Mike

PS. At some point you are going to have to publish a allowable pin mapping for master and slave configurations since there is now way in h...l I am going to remember them, probably no one else either :)
 
3.2/3.5/3.6 is same

so pin 12 of Teensy 3.2 and 3.5 are MISO

I prefer looking over the 3.5/3.6 card :)

btw, SPI2 not working yet, trying main and alt pins without success
still working on it..

EDIT: SPI2 slave support works! just gotta narrow down the pins, few mins

SPI2 SLAVE on T3.5 ONLY works with pins 43,51,52,53
 
Last edited:
Figured it out - still had the LC connected but not plugged in - was causing a drain. Working fine - just like before. Lesson learned for the future.

Running on SPI0 no issues now except can't run at 30Mhz had reduce it to 27Mhz and it works fine.

EDIT: Didn't we talk about this before.....
 
play with ground points :)

btw, I put this when begin(SPIx) is called, console output:

Code:
SPI Slave pins connections: 2,11,12,14 ( if referenced to begin(SPI))
SPI1 Slave pins connections: 0, 1, 31, 32 ( if referenced to begin(SPI1))
SPI2 Slave pins connections: 43,51,52,53 ( if referenced to begin(SPI2))
it will be displayed on console after begin is called

EDIT did quick rewiring and changing SPI2 -> SPI1 -> SPI, all work as expected :)

SPI_MST has dynamic SPI slave support now! 3.6 still needs to be tested to confirm pin states are same as 3.5

But with the slave starting up, it's easy to know which pins to wire! :)


Code:
[COLOR="#FF0000"]SPI Slave pins connections: 2,11,12,14[/COLOR]
Hello World!
1 2 3 4 5 6 7 8 9 10 
Hello World!
1 2 3 4 5 6 7 8 9 10 
Hello World!
1 2 3 4 5 6 7 8 9 10 
Hello World!
1 2 3 4 5 6 7 8 9 10

Heres the new slave version with all LC,3.2,3.5 bus support

Code:
[ATTACH]13786._xfImport[/ATTACH]
 
Last edited:
26MHz as well here good, 30 no, then again i have double jumpering for testing, so not sure. My wiring was so flimsy it didnt work half the time till i took my cutter and sat it on top of the wires, then signal was solid :)

i have events(), led, F&F (10 words) all running at 26MHz
 
I don't have pins soldered to a T3.6, but by "dangling" unsoldered joints, I can assure you that SPI & SPI1 at least work. I would presume SPI2 (the 4 pads) should work as well.
The SPI registers for the 3.5 & 3.6 look exactly the same anyways

So we got a slave library that can use any SPI port as a slave

I threw back on my T3.5 as a slave (since it has pins) on SPI0 and put slave.begin(SPI); and its working fine :)

Code:
#if [COLOR="#006400"]defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)[/COLOR]
  while ( !((*(volatile uint32_t *)spi_mst_gpiodir_addr) & sSPI_port_gpioloop) ) {
    if ( (*(KINETISK_SPI_t *)spi_mst_spi_addr).SR & 0xF0 ) {
      (*(KINETISK_SPI_t *)spi_mst_spi_addr).PUSHR = 0xDEAF; data[buffer_pos] = (*(KINETISK_SPI_t *)spi_mst_spi_addr).POPR; buffer_pos++;
      if ( buffer_pos >= SPI_MST_DATA_BUFFER_MAX ) return; // BUFFER LENGTH PROTECTION
    }
    if ( data[1] && buffer_pos >= data[1] ) break;
  }

#elif [COLOR="#0000FF"]defined(KINETISL)[/COLOR] //////////////////////////////////////////////////////////////
  while ( !((*(volatile uint32_t *)spi_mst_gpiodir_addr) & sSPI_port_gpioloop) ) {
    if ( (*(KINETISL_SPI_t *)spi_mst_spi_addr).S & SPI_S_SPRF ) {
      data[buffer_pos] = (((*(KINETISL_SPI_t *)spi_mst_spi_addr).DH) << 8 | ((*(KINETISL_SPI_t *)spi_mst_spi_addr).DL));
      buffer_pos++;
      (*(KINETISL_SPI_t *)spi_mst_spi_addr).DH = 0xDE;
      (*(KINETISL_SPI_t *)spi_mst_spi_addr).DL = 0xAD;
      if ( buffer_pos >= SPI_MST_DATA_BUFFER_MAX ) return; // BUFFER LENGTH PROTECTION
    }
    if ( data[1] && buffer_pos >= data[1] ) break;
  }
#endif ///////////////////////////////////////////////////////////////////////////////

The mappings allow all busses to use the same scope without code duplication :)
 
Last edited:
Amazing piece of work Tony. Keeps changing and getting better. Oh, had the T3.5/3.2 up to 27Mhz no problem. So about the same results for that.
 
Good work indeed. I've been following but not working with it. Hopefully it is worth the extra effort to make it more generic across the Teensy Family and multiple SPI ports - not everyone will need it - though when it fits the application it offers great utility not otherwise around.

Just have to come up with an example that shows some possible usage: Timesyncing a group or using a group to do a coordinated lightshow - some parallel processing? And some good docs.
 
Well your idea was to free up SPI0 for LCD FIFO usage, or host a slave on another port so user can control SPI instead of SPI1 (like some hardcoded libraries using SPI)

Either way, by encouraging the development on SPI1, and the memory map from kinetis.h, was able to open up all port possibilities, at the same time i learned how to use memory addresses and not just registers, to solve issues around multiple port accesses, as well as comparing 2 class references to detect the port being passed in to do the proper setup procedure for that specific port

also the slave library can further limit other peripheral accesses your not using to conserve space on the LC, like Wire, Serial, additional SPI remote usage, by having them undefined (in case you dont use them) those core libraries/functions wont be compiled

example, you can define serial1 to be used by the master and undefine the serial2 etc, each serial port control takes ~ 1k memory usage, ideally with a 3.5/3.6, you can have all features available, but 3.2/LC can be limited to save memory

The master side will be stripped down based on the github version, but not until the slave has a good run.

I suppose we should start a separate repo now for the slave driver?

they cant be inside the same folder, as both files have the same SPI_MSTransfer class...
The compiler will complain

I suppose I should match the class to the filename?

“SPI_MSTransfer” —> “SPI_MSTransfer_Slave” ?
Since the slave self-instantiates “slave” object when “included”, changing the class inside the slave files wont affect sketch code, then perhaps we can have both master and slave in same repo?



Code:
[ATTACH]13787._xfImport[/ATTACH]

Heres the new slave file with the renamed class ("SPI_MSTransfer_Slave"). The master will stay the same class ("SPI_MSTransfer"). It should compile with the future master in the same folder, provided I take the slave's globals out of the master side so they wont be seen as duplicates to throw off the compiler.
 
Last edited:
That started back in post #1498

Could the SPI_Slave code be programmed to 'easily' without using the SPI_Master library? - not that it would be useful. I noted back then that it is sort of wedded with the 'protocol' - since SPI is a BUS where use is defined by the required Slave interface - and this is a paired interface.

so much for the first lib name … now it needs two ... SPI_MSTslave and SPI_MSTmaster or SPImsSt3 and SPImsMt3.
 
it can stay the same name and same directory as long as the slave’s isr code and duplicate vars are removed from master file

only the #include on the slave needs “SPI_MSTransfer_Slave”, everything else is SPI_MSTransfer
 
Yep - did a test compile and what the compiler complained about was exactly what you specified - "the slave’s isr code and duplicate vars". Just curios.

Think this is that better way to go, to keep them in the same directory. If you want to shorten the name you could use SPI_MST and SPI_MST_Slave. This way its less cryptic.
 
the filenames must be different yes, especially since the slave object is self-instantiated when the library is #included
There wouldnt be a way to combine the files into one H that can call both, as the ISR code would still be available to both files, we’d be back at the same same file scenario :)
 
It's not uncommon to have a library with many H/CPP files in the same folder and label it as a single library. FastLed is an example..
The slave one is even easier to setup now than before for the user, just #include and slave.begin(bus); with callback, thats it.. :)

btw, when the 4.0 comes out (not sure if its single/many core)? im pretty sure i will write an even better library specifically for it from scratch, which shouldnt interfere with current version of SPI_MST, so they could run in parallel, but would definately need to add defines for the 4.0 in spi_mst for compiling as master. the 4.0 to 4.0 MST library will be a beast im sure lol :)
 
Last edited:
Back
Top