Project: SPI_MSTransfer

I put the println after the delay(1) and it seems to be running fine now - usually hangs by now. LC may need a delay between toggle and next operation or any operation to finish processing. Don't know - may be something else completely.

Going to push up the speed a little.
 
Maybe the USBSerial prints dont work properly in the LC ISR as well, if it locks up again, try without prints, 3.x handles them fine, but maybe LC can't

happen again here
gonna try 4mhz without prints
 
Have it running at 4Mhz no issues. Running it at 10/4 Mhz now and working ok. THis is how I have it structured:
Code:
  if ( !(millis() % 100) )  {
#if defined(TLC)
    teensy_gpio2.pinToggle(LED_BUILTIN);
#else      
    teensy_gpio.pinToggle(LED_BUILTIN);
#endif 
    Serial.print("^LT");
    delay(1);
    teensy_gpio3.println("Hello World!");
    }

EDIT: One interesting thing when its running ok the serial output to the monitors is sometime strange. Either the output from the slave to monitor slows while the master is flashing by, or vice versa. Sometime both will slow. All of sudden they get back in sync and are flashing by like crazy
 
Yup, perhaps we should add a "Recommended speed" for slave mode for the LC startup section after tests get stabilized, ex. if we recommend 4, and users want to push it, they can, but stability could be affected
By adding these little notes to the slaves, we can assure the users get the info during testing without searching through files most never read :)

even at 4mhz, i still getting 120Hz on slave with 0 errors both sides

edit so far it hasnt crashed, ill leave it running :)

edit, pc crashed and rebooted, but the master & slave still running :D
 
Last edited:
Ok finally crashed after more than 1 hour:
Code:
20894.00, #, #, #, #, #, #, #, #, #,743603,16 [96 ,0
Hello World!
20904.00, #, #, #, #, #, #, #, #, #,743604,16 [96 ,0
20914.00, #, #, #, #, #, #, #, #, #,743605,16 [96 ,0
20924.00, #, #, #, #, #, #, #, #, #,743606,16 [96 ,0
20934.00, #, #, #, #, #, #, #, #, #,743607,16 [96 ,0
20944.00, #, #, #, #, #, #, #, #, #,743608,16 [96 ,0
20954.00, #, #, #, #, #, #, #, #, #,743609,16 [96 ,0
20964.00, #, #, #, #, #, #, #, #, #,743610,16 [96 ,0
20974.00, #, #, #, #, #, #, #, #, #,743611,16 [96 ,0
20984.00, #, #, #, #, #, #, #, #, #,743612,16 [96 ,0
20994.00, #, #, #, #, #, #, #, #, #,743613,16 [96 ,0
Reset the slave and it started right up again. This was at 10/4 for SPI.

perhaps we should add a "Recommended speed" for slave mode for the LC startup

I agree. Probably need one for the T3.2 that the max SPI Speed is 27Mhz. Or put them as notes in the example on the GitHub page - can create a section for limitations.
 
As an updated I removed the USBSerial print and now running for over an hour at 6/4 Mhz for SPI. Again this is with 10ms F&F, 100ms LED toggles and 500ms slave sends. Going to let it run for another hour and will retest at 10/4 for the fun of it....

UPDATE1: Hit 2 hour mark without crash at 6/4 so switched to 10/4Mhz SPI. Will let that run for awhile to see if it crashes. By the way for the USBserial I made teensy_gpio3.lcmode(10,10) - would that affect it or should it be something else?
 
Last edited:
Not sure, but I just got up in morning here are the results

all 4MHz, LCmode(10,10), 100 led, 8ms F&F, events() in main loop, and for slave 500ms, still running :), ill push it to 6mhz and let it run, it's either 6 or USBSerial, i think the LC cant handle printing from the ISR like the 3.x can, we'll see
 
i think the LC cant handle printing from the ISR like the 3.x can
I can actually say that I agree with you on this one. The only difference between what I tested was the F&F timing. Right now I am pushing 10Mhz and 4Mhz on GPIO2 and its working, absolutely no issues. Going to let this config run for a while and will try and push GPIO2 to 6 as well.
 
I think 6MHz has issues with slave -> master data transfer, no issues at 4, i pushed the slave to 5 sec transfers and its running fine...
 
Got it - when I change to 6Mhz I will change the slave transfer as well - already know at 6mhz had some issues in previous test.
 
Running now at 10Mhz SPI and 6Mhz gpio2. Have 1sec transfers from slave to master, 100ms LED toggles and 10ms transfers to the slave. So far so good, it running fine no OTs, no pauses and no crashes so far. I will let it run a while longer before calling it a total success. :) Guess for the LC its just determining its limitations.

Update: Ok going to call it - its working even at 10/6Mhz as long as you 1 sec transfers from master to slave :)
 
Last edited:
6mhz started failing here for me today with events, 4mhz works fine

im gonna see if i can make it do something just intermittant enough, maybe glitch every second, and see if modifying things can "fix it", so far i got F&F from crashing at 6mhz, pushed it to 10mhz and not crashing anymore

im gonna see one module at a time to see how far i can tweak them
 
Interesting. This LC chip is crazy - spending more time on it than we did for the T3.x. Any config you want me to try?
 
Mike, check this:
Data may be read from the SPI data registers any time after S[SPRF] is set and before
another transfer is finished.
Failure to read the data out of the receive data buffer before a
new transfer ends causes a receive overrun condition, and the data from the new transfer
is lost. The new data is lost because the receive buffer
The S register
must be read when S[SPTEF] is set before writing to the SPI data registers; otherwise, the
write is ignored.
Now, this basically states that when the SPRF is set, the byte could be read, how many times? i guess as long as its there, all the time (until SPTEF is set) at which point a new byte is inside.
So I figured, how the heck could I block consecutive reads while waiting for the empty slot to write only 1 dword...

I figured I would just put this in my SPRF check routine:

Code:
      while ( !(*(KINETISL_SPI_t *)spi_mst_spi_addr).S & SPI_S_SPTEF && !((*(volatile uint32_t *)spi_mst_gpiodir_addr) & sSPI_port_gpioloop) );

This blocks when the register is read until the SPTEF is set (with a CS asserted state as a protection for the while loop), BEFORE it writes the next dword then the while loop continues looking for next SPRF flag
It's running 10MHz F&F's and 6MHz toggle so far, I'll keep poking at it!

it still pauses at 8 for toggle tho
 
Was just looking at the reference manual - spi sounds like a lot like double talk to me - get the general idea but confusing because then it starts going into FIFO or DMA. Almost sounds like they want you to use their FIFO for transfers. I am assuming you looked at Figure 37-40. It shows the SPMF has to be read the reset to 1?
 
its complex, you have to read the SPRF BEFORE the SPTEF is triggered, or you loose the new dword from the master
you need to write to the DH & DL when SPTEF set then read DH & DL before SPTEF is set again
the registers are 8 bits wide, and timing between them is everything

think of it as an ISR
DL is both read and written to for the same purpose, same with DH
if you ignore to read them, the spi starts to discard the master sends
if you write them before reading them, your writes are ignored

BTW yes, SPMF has to be read, here is the catch. It is a read only register, and the library does read it.
The catch is, reading it does nothing except show you if the SPRF or SPTEF bits are set, knowing what those bits are give you ability to read/write the DH/DL (provided the timings and actions match the bits)
The bits in the S register are read only...

We're doing continuous bus traffic and it wasnt designed for this type of constant traffic, the registers reset the moment the CS is retoggled, so the start of traffic is okay, but flowing back and forth for long durations is tricky still because you can only manage handling 2 daya bytes for read and write modes lol its a juggling act :)
 
Last edited:
This is giving me a headache - I was looking at the Definitive Guide to Cortex.... but there is nothing in those series of books that discusses SPI or I2C etc.... Everything is in the reference manual... argh... Learn by doing I guess.

EDIT: I was able to find a baremetal spi implementation for the KL25 chip and I think its pretty much what you are doing in spi_mstransfer:
Code:
/****************************************************************
             write data then read data to SPI master module
*****************************************************************/
uint8_t SPI_WriteReadData(uint8_t *pRead,uint8_t *pWrite,uint32_t uiLength)
{
	uint16_t i;
	for( i=0;i<uiLength;i++)
	{
        while(!(SPI0_S & SPI_S_SPTEF_MASK ) );
					SPI0_D = pWrite[i];
        while(!(SPI0_S & SPI_S_SPRF_MASK ) );
					pRead[i] = SPI0_D;
	}
    return 1;
}
	
/****************************************************************
              read data then write data to SPI slave module
*****************************************************************/
uint8_t SPI_ReadWriteData(uint8_t *pRead,uint8_t *pWrite,uint32_t uiLength)
{
		uint16_t i;


		for( i=0;i<uiLength;i++)
		{
		while(!(SPI1_S & SPI_S_SPTEF_MASK ) );
		     SPI1_D = pWrite[i];
        while(!(SPI1_S & SPI_S_SPRF_MASK ) );  //read data 
			 pRead[i] = SPI1_D;
		}

    return 1;
}
 
Last edited:
I just posted my debug_t3 lib - pjrc.com/threads/52315-Teensyduino-1-42-Beta-5

The T_LC does fault and report the error I first created - off boundary READ of RAM - but it somehow fails to fail as note on the one that trips up the T_3.6 - a crossed boundary write???

When I get time to make sure I'm not missing something - and if the code isn't too embarrassing I'll start a thread for it. Let me know if you give it a look over there on the Beta 5 thread.
 
That will help find timing register issues with spi mhz difference with LC registers that only cause pauses at higher speeds? :)
 
LOL MIKE!!! This is SO WORTH A NOTE! I'll tell you later! All I can say is 10MHz F&F and 8MHz toggle, but I wanna finish off 2 sections to test more :)

EDIT,

10MHz all around, events() tight loop, led toggling & hello world in a tight 100ms loop, F&F @ 5uS, LCmode(25,25)
slave hammering 500ms transfers
consoles going crazy! :)

no errors on slave packet at 10MHz transfers

technically its your fault we kept unintentionally hitting this problem :)

Tim, sorry but the debug wouldn't have caught it. I did fix a bug that we looked over yesturday though as well. The length of buf[1] for the buf_pos needs to be buf[1]-1, it was counting 1 over before resetting
I corrected all the areas involved :)

oh the LC console is taking a beating with all those master prints, f&f's and led toggling, theres no pauses but because of the speed the serial monitor is lagging lol

EDIT, Smaller and Faster compiles have no issues either :)

EDIT, at 11MHz, LCmode5,5, getting 480Hz F&F's at 2ms cycles, led toggling at 1sec intervals, while capturing slave data every 500ms

LCMode1,1 will crash
LCMode0,5 works for last EDIT

Now, if I made it to 11MHz, I can consider the LC code to be working! I better zip up a copy! :)

EDIT, 0,10 LCMode is needed to have no errors with master -> slave F&F's
otherwise you'll see an increment once every 2-4 minutes or so
no increments at 10

1st value for LCMode is read delay (uS) value, whereas 2nd value is for write delay (uS) value.
I also adapted the master transfer16 functions and SPIx constructor to support LC addressing, so they should work on LC in master mode using internal functions

12MHz doesnt work, but if we achieved 11MHz, it can only mean it's not a code issue anymore, but unexpected expectations from a chip revision :)
 
Last edited:
Tim, I ran your demo on LC
Code:
C:\Users\Tony\Documents\Arduino\sketch_may18a\sketch_may18a.ino May 18 2018 20:38:26

 Not FAULTED.

 >>>> debug_fault   >>>> debug_fault   >>>> Calling _isr#:0
Debug Info:
9 => 14	0xE	[CNT=1

fault: 
??: 80000000
??: 0
??: 240
psr:E000ED20
adr:677
lr: 20000984
r12:20
r3: 400FF08C
r2: 1FFFFD2C
r1: 1
r0: 20000EF4
r4: 20000EEC
lr: 10250E00
---

1FFFFFFA :: 0-----@8
1FFFFFFB :: 1-----@8
1FFFFFFC :: 2-----@8
1FFFFFFD :: 3-----@8
1FFFFFFE :: 4-----@8
1FFFFFFF :: 5-----@8
20000000 :: 6-----@8
20000001 :: 7-----@8
20000002 :: 8-----@8
20000003 :: 9-----@8
20000004 :: A-----@8
20000005 :: B-----@8
20000006 :: C-----@8
20000007 :: D-----@8
20000008 :: E-----@8
1FFFFFFA :: 100-----@16
1FFFFFFB :: 
 >>>> debug_fault   >>>> debug_fault   >>>> Calling _isr#:2
Debug Info:
0 => 1	0x1	[CNT=2
4 => 0	0x0	[CNT=3
5 => 14	0xE	[CNT=89
6 => 1	0x1	[CNT=99
7 => 90	0x5A	[CNT=98
8 => 77	0x4D	[CNT=94
9 => 14	0xE	[CNT=1

fault: 
??: 5A2
??: 1B47
??: FFFFFFF9
psr:1FFFFFFB
adr:B8D
lr: 3724
r12:1FFFFD2C
r3: F
r2: 1FFFFFFB
r1: 63
r0: 20000004
r4: 1
lr: 372C
---


 >>>> debug_fault   >>>> debug_fault   >>>> Calling _isr#:2
Debug Info:
0 => 1	0x1	[CNT=2
4 => 0	0x0	[CNT=3
5 => 14	0xE	[CNT=89
6 => 1	0x1	[CNT=99
7 => 90	0x5A	[CNT=98
8 => 77	0x4D	[CNT=94
9 => 14	0xE	[CNT=1

fault: 
??: 5A2
??: 1B47
??: FFFFFFF9
psr:1FFFFFFB
adr:B8D
lr: 3724
r12:1FFFFD2C
r3: F
r2: 1FFFFFFB
r1: 63
r0: 20000004
r4: 1
lr: 372C
---


 >>>> debug_fault   >>>> debug_fault   >>>> Calling _isr#:2
Debug Info:
0 => 1	0x1	[CNT=2
4 => 0	0x0	[CNT=3
5 => 14	0xE	[CNT=89
6 => 1	0x1	[CNT=99
7 => 90	0x5A	[CNT=98
8 => 77	0x4D	[CNT=94
9 => 14	0xE	[CNT=1

fault: 
??: 5A2
??: 1B47
??: FFFFFFF9
psr:1FFFFFFB
adr:B8D
lr: 3724
r12:1FFFFD2C
r3: F
r2: 1FFFFFFB
r1: 63
r0: 20000004
r4: 1
lr: 372C
---


 >>>> debug_fault   >>>> debug_fault   >>>> Calling _isr#:2
Debug Info:
0 => 1	0x1	[CNT=2
4 => 0	0x0	[CNT=3
5 => 14	0xE	[CNT=89
6 => 1	0x1	[CNT=99
7 => 90	0x5A	[CNT=98
8 => 77	0x4D	[CNT=94
9 => 14	0xE	[CNT=1

fault: 
??: 5A2
??: 1B47
??: FFFFFFF9
psr:1FFFFFFB
adr:B8D
lr: 3724
r12:1FFFFD2C
r3: F
r2: 1FFFFFFB
r1: 63
r0: 20000004
r4: 1
lr: 372C
---


 >>>> debug_fault   >>>> debug_fault   >>>> Calling _isr#:2
Debug Info:
0 => 1	0x1	[CNT=2
4 => 0	0x0	[CNT=3
5 => 14	0xE	[CNT=89
6 => 1	0x1	[CNT=99
7 => 90	0x5A	[CNT=98
8 => 77	0x4D	[CNT=94
9 => 14	0xE	[CNT=1

fault: 
??: 5A2
??: 1B47
??: FFFFFFF9
psr:1FFFFFFB
adr:B8D
lr: 3724
r12:1FFFFD2C
r3: F
r2: 1FFFFFFB
r1: 63
r0: 20000004
r4: 1
lr: 372C
---

EDIT: 11MHz still smooth scrolling :)
Code:
63620.00, #, #, #, #, #, #, #, #, #,1992233,1 [480 ,0
63630.00, #, #, #, #, #, #, #, #, #,1992234,1 [480 ,0
63640.00, #, #, #, #, #, #, #, #, #,1992235,1 [480 ,0
63650.00, #, #, #, #, #, #, #, #, #,1992236,1 [480 ,0
63660.00, #, #, #, #, #, #, #, #, #,1992237,1 [480 ,0
63670.00, #, #, #, #, #, #, #, #, #,1992238,1 [480 ,0
63680.00, #, #, #, #, #, #, #, #, #,1992239,1 [480 ,0
63690.00, #, #, #, #, #, #, #, #, #,1992240,1 [480 ,0
63700.00, #, #, #, #, #, #, #, #, #,1992241,1 [480 ,0
63710.00, #, #, #, #, #, #, #, #, #,1992242,1 [480 ,0
63720.00, #, #, #, #, #, #, #, #, #,1992243,1 [480 ,0
63730.00, #, #, #, #, #, #, #, #, #,1992244,1 [480 ,0
63740.00, #, #, #, #, #, #, #, #, #,1992245,1 [480 ,0
63750.00, #, #, #, #, #, #, #, #, #,1992246,1 [480 ,0
63760.00, #, #, #, #, #, #, #, #, #,1992247,1 [480 ,0
63770.00, #, #, #, #, #, #, #, #, #,1992248,1 [480 ,0
63780.00, #, #, #, #, #, #, #, #, #,1992249,1 [480 ,0
63790.00, #, #, #, #, #, #, #, #, #,1992250,1 [480 ,0
63800.00, #, #, #, #, #, #, #, #, #,1992251,1 [480 ,0
63810.00  63811.00  63812.00  63813.00  63814.00  63815.00  63816.00  63817.00  63818.00  63819.00  
63820.00, #, #, #, #, #, #, #, #, #,1992252,1 [480 ,0
63830.00, #, #, #, #, #, #, #, #, #,1992253,1 [480 ,0
63840.00, #, #, #, #, #, #, #, #, #,1992254,1 [480 ,0
63850.00, #, #, #, #, #, #, #, #, #,1992255,1 [480 ,0
63860.00, #, #, #, #, #, #, #, #, #,1992256,1 [480 ,0
63870.00, #, #, #, #, #, #, #, #, #,1992257,1 [480 ,0
63880.00, #, #, #, #, #, #, #, #, #,1992258,1 [480 ,0
63890.00, #, #, #, #, #, #, #, #, #,1992259,1 [480 ,0
63900.00, #, #, #, #, #, #, #, #, #,1992260,1 [480 ,0
63910.00, #, #, #, #, #, #, #, #, #,1992261,1 [480 ,0
 
Last edited:
technically its your fault we kept unintentionally hitting this problem
Ok. My fault again, :( but at least you found the bug :)

EDIT, at 11MHz, LCmode5,5, getting 480Hz F&F's at 2ms cycles, led toggling at 1sec intervals, while capturing slave data every 500ms
Cool. GPIO2 at 8Mhz and LCmode(0,10).... maybe (0,5). Well, guess that beats me, with 10Mhz/6Mhz with 1 sec slave transfer and 10ms master transfers :) Have you tested USBserial or you waiting for me to be the guinea pig :) EDIT: Never mind just saw the note you have it in a 100ms loop.

I also adapted the master transfer16 functions and SPIx constructor to support LC addressing, so they should work on LC in master mode using internal functions
Unbelievable.

if we achieved 11MHz, it can only mean it's not a code issue anymore, but unexpected expectations
Call it a day at this point.

You really have been busy today.
 
Back
Top