Project: SPI_MSTransfer

Looking clean now! :)

Code:
#elif defined(KINETISL) //////////////////////////////////////////////////////////////
      while ( !(GPIOD_PDIR & sSPI_port_gpioloop) ) { // wait here until MASTER confirms F&F receipt
        if ( (*(KINETISL_SPI_t *)spi_mst_spi_addr).S & SPI_S_SPRF ) {
          if ( (((*(KINETISL_SPI_t *)spi_mst_spi_addr).DH) << 8 | ((*(KINETISL_SPI_t *)spi_mst_spi_addr).DL)) == 0xD0D0 ) return;
          (*(KINETISL_SPI_t *)spi_mst_spi_addr).DH = 0xBA;
          (*(KINETISL_SPI_t *)spi_mst_spi_addr).DL = 0xBE;
        }
      }
#endif ///////////////////////////////////////////////////////////////////////////////

I'm going to base it off 400KHz for now, because this shows it's not an issue with the ISR code. I need to finish off the slave library so I can start working on the 3.x series dynamic SPI0/1/2 slave ports (if im able to get them working of course :))
 
Moving along, we got the CRCs passing now (still at 400KHz), I changed led toggle to use a digitalread and digitalwrite instead, stopped doing F&F loop using overload 0 for ACK transfer, and its working like a charm!
I'll keep working my way down the ISR...
 
Got curious and found this:
when the SPI of Kl25 is configured as master mode, the SPI clock signal SPSCK is an output clock, it's output frequency is called baudrate:
BaudRateDivisor = (SPPR + 1) × [2**(SPR + 1)]
BaudRate = BusClock / BaudRateDivisor
For detailed information, pls refer to section 37.4.6 SPI Baud Rate Generation in the KL25P80M48SF0RM.pdf.

For the SPI0 module of Kl25, the SPI0 uses BusClock as it's driving clock, the BusClock is 24MHz, when the SPPR=0 and SPR=0, the SPSCK get the maximum baudrate, which is 24M/((0+1)*2)=12MHz, that is why the PE gives you a baudrate list, the 12MHz is the maximum value.

For the SPI1 module of KL25, the SPI1 uses System clock as it's driving clock, the system clock is 48MHz, with the same baudrate setting, the baudrate of SPi1 is twice of SPI0 module. When the SPPR=0 and SPR=0, the SPSCK get the maximum baudrate, which is 48M/((0+1)*2)=24MHz.

From software perspective, you can use the hal function to set baudrate. uint32_t SPI_HAL_SetBaud(SPI_Type * base, uint32_t bitsPerSec, uint32_t sourceClockInHz);


https://community.nxp.com/thread/377893
Also see https://github.com/ARMmbed/mbed-hal...urce/TARGET_KSDK_CODE/hal/dspi/fsl_dspi_hal.c

But now I am confused if the LC is in slave mode shouldn't it use the clk from the source? This is what happens when I start looking at the code instead of just using and observing - sorry to be a pain.

EDIT:
Still curious but just want to put this somewhere so I don't loose it:
https://os.mbed.com/users/mbed_offi...c209510/vendor/Freescale/KL25Z/hal/spi_api.c/
https://community.nxp.com/thread/390070
 
Last edited:
Lots of confusion on this chip and similar on many sites, but its working great at 400KHz, we can return to it later on but this shows the ISR is doing well, no crashes have been occuring since! :)

EDIT, just did UART/Serial section:

Code:
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 
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 
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 
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

Now theres an ACK transfer16 with digitalread and digitalwrite AND serial printing, and the LC isnt crashing :)

I'll keep working down the list to finish it off :)

BTW, the SPIx_BR register for the KL series is used only for master mode, in slave mode it's not used. I believe the slave bus is alot slower than the transmission speeds
 
Last edited:
Great work Tony. Going to be interesting when the T4.x comes out. :) Enough on that.

Can't wait to see it when you get it done. At 4Mhz was working great with the F&F as is with the sketch I posted. Pretty much the only thing different was the LED and sending from the slave to the master. Of course the SPI bus speed as well :)

Should try at 10ms as is to see what happens :) Curiosity again. Think I will just wait to test 10ms.

Btw did I say my tests were with a 25ms loop, don't remember if I mentioned that :)
 
Yup you can try after, F&F *should* still work at 4MHz if you only use that, but 400KHz is at least working with EVERYTHING else..
 
Oh. Just saw this:
BTW, the SPIx_BR register for the KL series is used only for master mode, in slave mode it's not used. I believe the slave bus is alot slower than the transmission speeds
From what I read in slave mode the clock is based off the master clock but I would think it would be maxed at some speed? Was looking at the SPI core but I am still trying to figure out registers. Is there an easy way to print out the register contents after you set them?
 
Alright, in testing both SPI and SPI1 on the LC ( after doing the whole ISR ), I'm currently at this point:

SPI: cannot run more than 300KHz without the bus crashing
SPI1: cannot run more than 400KHz without the bus crashing

this is testing with multiple objects in tight loop (toggling, F&F, etc)

SPI1 seems like a winner at this point, the LC is getting to be very irritating.....
 
Wait I had ACK mode enabled.

I'm doing this now:
Code:
SPI_MSTransfer teensy_gpio = SPI_MSTransfer("Serial", 43, &SPI2, [COLOR="#0000CD"]300000[/COLOR] ); // bad with default timeouts
SPI_MSTransfer teensy_gpio[COLOR="#FF0000"]2[/COLOR] = SPI_MSTransfer("Serial", 43, &SPI2, [COLOR="#FF0000"]8000000[/COLOR] ); // bad with default timeouts

    teensy_gpio[COLOR="#FF0000"]2[/COLOR].transfer16(buf, 10, 60, 1); // [COLOR="#FF0000"]8mhz[/COLOR]
    teensy_gpio.digitalWrite(13, !teensy_gpio.digitalRead(13)); // [COLOR="#0000CD"]300khz[/COLOR]

using 8mhz for overload 1 (F&F), and 300khz for the rest, seems to work.
To me it seems the LC does not like consistant transfers? :)
 
Here is the master uS output:
Code:
97
97
97
111
96
97
97
97
97
97
111
104
104
97
97
97
97
112
97
96
97
112
111
97
97
97
97
105
104
104
97
111
112
96
97
112
111
97
111
97
105
97
104
104
112
97
97
97
97
104
97
97
97
97
112
104
105
97
97
105
104
97
97
97
97
104
97
97
112
112
112
104
104
104
97
104
97
104
111
97
104
97
104
112
97
111
97
97
97
97
112
97
112
97
105
105
97
97
97
97
105
97
97
97
96
111
97
97
97
104
104
97
97
105
97
97
111
97
97
112
97
97
105
104
111
97
96
112
104
104
97
112
112
97
105
112
112
96
97
97
104
105
97
97
97
105
97
105
112
97
104
105
111
112
97
112
96
104
97
97
97
112
105
97
104
112
97
97
97
112
112
97
105
96
97
105
97
111
97
97
97
104
97
104
104
104
104
112
111
104
97
97
105
97
105
111
97
112
97
97
112
98
98
105
98
98
112
98
105
98
97
105
112
97
97
97
105
112
105
97
112
97
104
97
112
97
112
112
97
97
104
97
96
112
112
105
112
97
97
104
112
97
112
97
112
111
112
96
112
97
96
111
112
111
119
111
104
96
97
97
97
97
111
97
111
104
104
111
97
97
97

and the slave
Code:
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
Hello World!
1 2 3 4 5 6 7 8 9 10 
Hello World!

EDIT: I removed the 5ms before POPR code
It's still running now!
master uS:
Code:
C:\examples\master\master.ino May 12 2018 17:47:59
DBG: [S_CS 43] CB Capacity: 4 Length: 100
88
81
86
82
82
87
82
84
84
84
84
87
87
86
81
87
82
81
86
82
82
86
84
84
81
84
81
82
82
82
82
82
87
82
84
84
81
82
81
82
84
87
82
82
82
84
82
82
86
86
86
81
82
82
82
84
82
82
82
84
81
86
82
82
86
81
84
87
84
81
81
81
82
87
82
82
84
82
84
82
82
82
82
81
81
84
81
87
81
81
82
82
82
81
81
82
81
81
81
82
84
84
84
82
86
82
84
82
86
82
81
82
84
84
81
84
82
86
87
87
82
86
81
81
82
81
87
87
82
87
84
82
83
85
87
87
85
84
82
82
82
87
87
87
86
82
81
82
81
82
81
82
82
82
82
82
87
87
84
86
82
84
81
81
82
87
84
82
84
81
82
82
84
84
84
82
87
82
84
84
81
82
84
84
82
87
84
82
86
84
82
81
81
82
87
82
84
81
82
84
84
84
82
81
84
84
82
84
82
81
86
81
82
84
81
81
87
81
81
82
82
84
82
84

Perhaps the LC can handle bursts but not consistancy. The use of a single register prevents the internal registers from overriding, especially when theres no register to enable overriding.
Thats my hunch
The bursts at the front of the line seem to flow fine, as it continues the LC starts to choke, if we run the rest of the "hardware resources" at 300KHz and F&F's at 8MHz, I think we're fine with this?
 
Mike, what you think about this? Swapping from SPI to SPI1 is "simple", you just need to put the SPI object into begin() ( i tested both port swapping just now :) )
Code:
#include <SPI_MSTransfer_Slave.h>

void setup() {
  slave.begin([COLOR="#FF0000"]SPI1[/COLOR]);
  slave.onTransfer(myCallback);
}

void loop() {
  slave.events();
}

void myCallback(uint16_t *buffer, uint16_t length, AsyncMST info) {
  for ( uint16_t i = 0; i < length; i++ ) {
    Serial.print(buffer[i]);
    Serial.print(" ");
  } Serial.println();
}

I use a ternary compare inside the LC define to set the port variable:
Code:
  ( &SPIWire == &SPI ) ? sSPI_port = 0 : sSPI_port = 1;
 
Guess it should work for now. But something just doesn't make sense with the different clocks? Another days issue or project. Anyway, I know this is a long shot but maybe should post as an separate issue for the Teensy LC or on GitHub? Just a thought.

EDIT:
slave.begin(SPI1);
I like that, simple and easy to understand. I should add elegant :)
 
I don't think it's about the clocks, the LC has issues with persistant 2-way traffic which I think the single register can't cope with.. That and the fact we're pushing it past 6MHz is another unknown, but to me this doesnt look code related since all the ISR uses the same LC code for every switch statement, and they all dont crash at their respective frequencies

its also a good thing i equipped the master with unique clocks per class object :)
 
Here is the updated, hopefully working final version for testing, then once confirmed ill switch back to a 3.2 and readd the 3.2 SPI registers, that will just need a simple few tests, then ill see if I can work on adding SPI1 & SPI2 slave support

I plan to readd the 3.2 using memory addressing like i did with the LC, to make the busses dynamically switchable, so when I add SPI1 and SPI2 on 3.5/3.6 i wouldnt need to add any conditional statements

Teensy 3.x series
Code:
0x4002C000; // SPI
0x4002D000; // SPI1
0x400AC000; // SPI2

Enjoy :)

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

Like I said, just put SPI or SPI1 in the begin(x), and your set, both ports have been tested
 
Yeah, thats what Tim suggested, its in a conversion process ATM

there will be a master and slave H and cpp files

all the slave isr code and unneeded slave variables would be stripped from master in the end, but only when i finish the slave file
 
Got it.

Ok here some preliminary test results.
1, at 8Mhz got on master:
Code:
F&F (OT=26) OT_CALC==300  micros() _time==173
F&F (OT=26) OT_CALC==300  micros() _time==173
^LTF&F (OT=26) OT_CALC==300  micros() _time==173
F&F (OT=26) OT_CALC==300  micros() _time==174
F&F (OT=26) OT_CALC==300  micros() _time==173

On slave
Code:
3050.00, #, #, #, #, #, #, #, #, #,31706,32 [96 ,0
3060.00  3061.00  3062.00  3063.00  3064.00  3065.00  3066.00  3067.00  3068.00  3069.00  
3070.00, #, #, #, #, #, #, #, #, #,31707,32 [96 ,0
3080.00, #, #, #, #, #, #, #, #, #,31708,32 [96 ,0
It does seem to hang periodically for a 1second max. By the way the LED is toggling nicely every 100ms. Messages being sent every 10 ms. Have to fix the time when it recycles so I can get a total count.

2. at 8 MHz and 20ms loop;
same type of behavior but believe it or not more fail transmits on the master

master:
Code:
F&F (OT=29) OT_CALC==300  micros() _time==173
^LTF&F (OT=29) OT_CALC==300  micros() _time==173
F&F (OT=29) OT_CALC==300  micros() _time==173
F&F (OT=29) OT_CALC==300  micros() _time==173
F&F (OT=29) OT_CALC==300  micros() _time==173
F&F (OT=29) OT_CALC==300  micros() _time==174
FAIL_Res #1 RETRY...
FAIL_Res #2 RETRY...
FAIL_Res #3 RETRY...
DBG: [S_CS 15] FAIL_RES #4 Tx ABORT. 
^LTF&F (OT=29) OT_CALC==300  micros() _time==99794
F&F (OT=30) OT_CALC==300  micros() _time==176
F&F (OT=30) OT_CALC==300  micros() _time==173
F&F (OT=30) OT_CALC==300  micros() _time==173
F&F (OT=30) OT_CALC==300  micros() _time==173
F&F (OT=30) OT_CALC==300  micros() _time==173
^LTF&F (OT=30) OT_CALC==300  micros() _time==175

slave:

Code:
20440.00, #, #, #, #, #, #, #, #, #,52068,53 [48 ,0

Bad LASTVAL TEST INCREMENT <<<<<<<<<<<<<<<<<<<< DIFF OF> -10.00
20460.00,20461.00,20462.00,20463.00,20464.00,20465.00,20466.00,20467.00,20468.00,20469.00,52069,54 [48 ,0
20470.00, #, #, #, #, #, #, #, #, #,52070,54 [48 ,0
20480.00, #, #, #, #, #, #, #, #, #,52071,54 [48 ,0
20490.00  20491.00  20492.00  20493.00  20494.00  20495.00  20496.00  20497.00  20498.00  20499.00  
20500.00, #, #, #, #, #, #, #, #, #,52072,54 [48 ,0
20510.00, #, #, #, #, #, #, #, #, #,52073,54 [43 ,0

going to test at 6 and 4, hopefully better.
 
At 6 Mhz transfers to slave choppy and irregular.

At 4 Mhz with 20ms loop seems to be working no problem. At 10ms no problem either.

For a lark I did 10Mhz on the master and the LC just keeps resetting - yeah I know I am crazy. Looks like 4 MHz is it for the LC to get reliable transfers.

Ok. What else do you want me to try tonight?
 
You need it more than I do :)

EDIT: I missed something I am going to do some retesting. I been doing the toggling on the teensy.gpio not a teesny.gpio2.

EDIT2: at 8mhz SPI and 10ms have 11 OTs in 130k sends but nothing like before. For gpio2 running at 400Khz. Probably should reduce to 300Khz.

EDIT3: at 10Mhz SPI, 10ms loop and 300k GPIO2 -> does run but getting a ton of OTs and bad vals on the slave. 400k worse will hang.

EDIT4: at 10Mhz SPI, 10ms loop and no led toggle, no work.
 
Last edited:
Ok just another update. Had my the 3.5/LC setup running at 9Mhz SPI, 400k for the LED and a 10ms running for the past hour and half. Its happily blinking away. No badvals on the slave side and no delays that I can see.

Have a lot of OTs (about 122 at this point) but wondering how valid they really are since they are calculated as OT_CALC = 100*(30000000/SPI_SPEED). Not sure if 30Mhz is really a good base or not.

Mike

update:
Code:
56960.00, #, #, #, #, #, #, #, #, #,194058,159 [96 ,0
56970.00, #, #, #, #, #, #, #, #, #,194059,159 [96 ,0
56980.00, #, #, #, #, #, #, #, #, #,194060,159 [96 ,0
56990.00  56991.00  56992.00  56993.00  56994.00  56995.00  56996.00  56997.00  56998.00  56999.00  
57000.00, #, #, #, #, #, #, #, #, #,194061,159 [96 ,0
57010.00, #, #, #, #, #, #, #, #, #,194062,159 [96 ,0
57020.00, #, #, #, #, #, #, #, #, #,194063,159 [96 ,0
 
Hey I'd like to add a note here. for SPI0, on Teensy 3.x and LC, pins 11 and 12 are SWAPPED.
This confused me for several hours I couldn't figure out why setting the LC to SPI0, a drop in replacement 3.2 should have worked! But nooo, I had to swap pins 11 with 12 !

Code:
[U]KinetisK (SLAVE)[/U]     [U]KinetisL (SLAVE)[/U]                     [U] KinetisK (MASTER)[/U]
    11 MOSI0            12 MISO0                              11 MISO0
    12 MISO0            11 MOSI0                              12 MOSI0

As you can see, the K series are direct MISO to MISO, MOSI to MOSI, while the L series are connected MISO TO MOSI and MOSI to MISO.
 
Here is my 3.x port redirection (in case I get SPI1/2 slave support working)
Code:
#if defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)

  Serial.begin(115200); // usb serial
  NVIC_SET_PRIORITY(IRQ_USBOTG, 0);

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

EDIT, 3.2 is now working with the last update, I just need to add in the port conversions while its in a working state, so all I would need to do in the end is test the SPI1/2 registers

EDIT, dynamic slave setup done, now to edit the ISR, the CS will need to be tested (like LC's pin 6 working vs pin 2 on kinetisK SPI0) to edit the CS input with a working pin
Code:
if ( &SPIWire == &SPI ) SIM_SCGC6 |= SIM_SCGC6_SPI0; // enable slave clock
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
else if ( &SPIWire == &SPI1 ) SIM_SCGC6 |= SIM_SCGC6_SPI1; // enable slave clock
else if ( &SPIWire == &SPI2 ) SIM_SCGC3 |= SIM_SCGC3_SPI2; // enable slave clock
#endif

    (*(KINETISK_SPI_t *)spi_mst_spi_addr).MCR |= SPI_MCR_HALT | SPI_MCR_MDIS;
    (*(KINETISK_SPI_t *)spi_mst_spi_addr).MCR = 0x00000000;
    (*(KINETISK_SPI_t *)spi_mst_spi_addr).MCR &= ~SPI_MCR_HALT & ~SPI_MCR_MDIS;
    (*(KINETISK_SPI_t *)spi_mst_spi_addr).CTAR0 = 0;
    (*(KINETISK_SPI_t *)spi_mst_spi_addr).MCR |= SPI_MCR_HALT | SPI_MCR_MDIS;
    (*(KINETISK_SPI_t *)spi_mst_spi_addr).CTAR0 = SPI_CTAR_FMSZ(15);
    (*(KINETISK_SPI_t *)spi_mst_spi_addr).MCR &= ~SPI_MCR_HALT & ~SPI_MCR_MDIS;
    (*(KINETISK_SPI_t *)spi_mst_spi_addr).MCR |= SPI_MCR_HALT | SPI_MCR_MDIS;
    (*(KINETISK_SPI_t *)spi_mst_spi_addr).CTAR0 &= ~(SPI_CTAR_CPOL | SPI_CTAR_CPHA) | 0x00 << 25;
    (*(KINETISK_SPI_t *)spi_mst_spi_addr).MCR &= ~SPI_MCR_HALT & ~SPI_MCR_MDIS;
    (*(KINETISK_SPI_t *)spi_mst_spi_addr).RSER = 0x00020000;
[COLOR="#FF0000"]    CORE_PIN14_CONFIG = PORT_PCR_MUX(2);
    CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
    CORE_PIN12_CONFIG = PORT_PCR_MUX(2);
    CORE_PIN2_CONFIG =  PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(2); // this uses pin 2 for the CS so Serial2 can be used instead.
    sSPI_port_gpioloop = 0x01; // use pin 2 for ISR[/COLOR]
[COLOR="#FF0000"]    NVIC_SET_PRIORITY(IRQ_SPI0, 1); // set priority
    NVIC_ENABLE_IRQ(IRQ_SPI0); // enable CS IRQ
#endif[/COLOR]

The red area will have to be dynamic in the end when i finish the ISR, need to finish ISR first and test the pin conditions after

EDIT: ISR updated. How's this? :)

Code:
                while ( !(GPIOD_PDIR & sSPI_port_gpioloop) ) {
                  if ( (*(KINETISK_SPI_t *)spi_mst_spi_addr).SR & 0xF0 ) {
                    (*(KINETISK_SPI_t *)spi_mst_spi_addr).PUSHR = buf[ ( buf_pos > buf[1] ) ? buf_pos = 0 : buf_pos++];
                    if ( (*(KINETISK_SPI_t *)spi_mst_spi_addr).POPR == 0xD0D0 ) {
                      (*(KINETISK_SPI_t *)spi_mst_spi_addr).SR |= SPI_SR_RFDF; return;
                    }
                  }
                }

This *should* work provided the other slave registers are functioning for slave mode :)
 
Last edited:
Back
Top