Project: SPI_MSTransfer

10 dwords at 4MHz with overhead == ~ 120uS lol :)
At 6MHz it's having a seizure but trying nonetheless lol

I think for LC users 4MHz is enough, right? :)
 
Alright, here it is! ...
Wait a minute, I must be crazy! It's the same library, so if it compiles as is on LC, master should be working! hahahaah :D

For LC, play with the buffers! I lowered them while testing to make it "fit" :)

That was the one comment I made that the forum ATE - the Master is using standard SPI lib so it should just work. The COOL ADD here is SLAVE SPI code for T_3.x and T_LC! The only next add that could make SLAVE code better would be to see how many alternate pins could be easily incorporated rather than hard coded: CS's and SCK, MISO, MOSI to make the Slave more adaptable.

The other note was that - just yesterday I pulled my T_LC from the SPI wiring to the T_3.6 I had started to set up :(
 
I can make that adaptable too! (slave CS,MISO,MOSI,SCK pin!)
That what you want?? :D I need a break first lol but Yeah I can add that too
How you want it defined? overloaded or by slave.setMISO(pin) (like teensy ) :p
I swept through the ISR in a matter of hours just t get LC built in hehehe

The functions already exist (setMISO, setMOSI, setSCK, setCS) for the master to select the slave hardware port, we can just add a _slave option use in them

should we remove the pinMode(13, OUTPUT) if we add dynamic pins, wouldnt want the slave to drive an output while connected to a master if we're not hardcoding

OH!!! the CS might be a problem, theres while loops in the ISR that keep it active while it collects necessary data:
Code:
                while ( !(GPIOD_PDIR & 0x01) ) {

This means while pin 2 is active, keep collecting transfers
 
10 dwords at 4MHz with overhead == ~ 120uS lol :)
At 6MHz it's having a seizure but trying nonetheless lol

I think for LC users 4MHz is enough, right? :)

If Paul's note about SPI bus speed F_BUS/4 applies with T_LC : F_CPU=48000000 and F_BUS=24000000

Master SPI should go as high as 6 MHZ? And on Slave the other T_3.x's were running higher than that. Though T_LC may have other hardware limits.

Reliable is job #1 - but the less time spent on overhead - or more data in the same time ... the better
 
Just to be clear - I'm only instigating and egg'ing you on :)

I can make that adaptable too! (slave CS,MISO,MOSI,SCK pin!)
That what you want?? :D I need a break first lol but Yeah I can add that too
How you want it defined? overloaded or by slave.setMISO(pin) (like teensy ) :p
I swept through the ISR in a matter of hours just t get LC built in hehehe

The functions already exist (setMISO, setMOSI, setSCK, setCS) for the master to select the slave hardware port, we can just add a _slave option use in them

Indeed use of standard SPI on Master is adaptable. You did good work hardcoding the Slave SPI - it just seems it might work in a few more cases across the Teensy family where the Slave could be adapted to fit. Though since this is all new to add a Slave it could be seen as reasonable that the Slave start with the required MST pins dedicated.
 
Not really sure, if LC can do 48cpu.. I'd imagine the max would be 6MHz, then again I'm breadboarding on jumpers and, unless I did anything else wrong I don't know :)
Other than possible hardware limits, there is a severe lack of slave mode usage for the KL series, at least we got it to a working state :)
 
Code:
SPI_MSTransfer   FACT

3.5               VS                       2xLC

$24.25                       2x $11.65 ($23.30)
1 USBSer, 6 uarts            2x USBserial, 6 uarts
3 Wire busses                4x Wire busse
NO TOUCH PINS                22 TOUCH PINS!
3 SPI ports!                 2 free, 1 shared! (3 total!)

ha ha lil humour :)
 
ha ha indeed ... leaving off the 256KB .vs. 16 KB RAM and 120(+)MHz .vs. 48 Mhz specs :)

Also from Oshpark 2 T_LC's is $22.58

Running the Slave on T_LC's SPI1 (or T_3.5/3.6) could be really cool - then SPI1 could get data to feed a SPI0 display or other device to feed the Master.
 
sooo, you want an option to run slave off a LC’s SPI1 port?
I do believe I could get that running, other than the register setup, we’d need to probably add compiler defines to replace registers like SPI0_C1 with SPI1_C1

it would be defined in the H after

actually we might not even care we could redefine every SPI0 from all kinetisK and kinetisL series, only one will be defined and compiled anyways, so if we redefine internally SPI0 to SPI1 even though it would redefine the 3.x sections, the compiler wont include them since only the LC is defined anyways, so a mass define WITH a slave register config should be fine

#define SPI0 SPI1 // example? :)
 
Post #1478 Sounded too easy with the yes to alternate pins. If the SPI 0 and 1 bus units function the same - it seemed possible the change would just be the accepted pin subsets. But indeed - at compile time only the target code needs to compile to working - so #define could be sufficient.

How long is the Slave block now? How localized { librariafied } is the process? It was sort of small - but coded inline to work. The Slave code is an ISR - so two copies of the code selectable at runtime by choosing which to Attach could be one way?
 
that would be too much code duplication if we do.2 isrs, which would require adding 2 entries when we add something
ill work on spi1 support when i get home later on :)

the LC and 3.x share the same ISR function but are defined per controller

post 1475 contains latest mst source

the way i did it is that if we add more functionality, both the L and K series can use it right away, instead of writing two different ISRS
 
Last edited:
Wow the LC really has "issues" with SPI1 in slave mode. As a sanity check, I compared my results with 3 LC's and all are the SAME.

SPI1 behaves totally different in terms of ALT pins.

1) The ALT pin, located on the LC card ( 21(MOSI1) ), in slave mode, simply DOES NOT WORK.
2) SPI1 does NOT work with GPIO2 ! It ONLY WORKS WITH GPIO6 !!!
3) Theres only one clock line, so that works fine.

Long story short, to use SPI1 on TeensyLC (as a slave), It is mandatory to use pins:
6: CS1 ( 2 does NOT work for SPI1 slave mode)
0: MOSI1 (21 does NOT work in SPI1 slave mode)
1: MISO1 (exception: 1 and 5 works)
20: SCK

Thats my days worth of testing. Like I said, I tried this among 3 brand new LC's, and all have same behaviour. The ALT pins simply do NOT work for SPI1 slave mode, SPI0 remains unaffected using default MST pin configs..

What does this mean for us? We could live with it, but you'd need to relocate Serial1 ,setTX and setRX, to pins, 1 or 4, and ,3 or 21, respectively, to use Serial1.

This is the type of thing that should be documented for the TeensyLC for future referencing
 
Last edited:
What is this? SPI1 is working now in SPI_MST test code after fiddling with the day...
I'll look into customizing it, so far it's "switchable" via a bool between SPI0 & SPI1 of the LC. gotta love the terinary operator...

Code:
Ex1: ( !sSPI_port ) ? SPI0_C1 &= ~SPI_C1_SPTIE : SPI1_C1 &= ~SPI_C1_SPTIE;
Ex2: if ( ( !sSPI_port ) ? SPI0_S & SPI_S_SPRF : SPI1_S & SPI_S_SPRF ) {
Ex3: if ( (( !sSPI_port ) ? ((uint16_t)(SPI0_DH << 8) | SPI0_DL) : ((uint16_t)(SPI1_DH << 8) | SPI1_DL)) == 0xD0D0 ) break;
Ex4: 
            ( !sSPI_port ) ? SPI0_DH = 0xBA : SPI1_DH = 0xBA;
            ( !sSPI_port ) ? SPI0_DL = 0xBE : SPI1_DL = 0xBE;

:)

Code:
Teensy NOT Online @ millis=570
Teensy Online @ millis=600

C:\examples\slave\slave.ino May  8 2018 19:11:43
Cycle Counter Not Enabled :0
Hello world!
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!

SPI0 is hardwired to 2,11,12,14
SPI1 is hardwired to 0,5,6,20

Luckily, both 2 and 6 are on PORTD, so a simple swap is all thats needed for the ISR while pin loops:

Code:
while ( !(GPIOD_PDIR & sSPI_port_gpioloop) ) {

Where sSPI_port_gpioloop is set to 0x10 when SPI1 is selected, and set to 0x01 when SPI0 is selected

and a simple ISR func forwarder:

Code:
void spi1_isr(void) {
  spi0_isr();
}
void spi0_isr(void) {

haha :)

So currently, for the LC, theres a new bool that swaps all the config/ISR calls

Code:
//sSPI_port = 0; // SPI0
sSPI_port = 1; // SPI1

I test them back to back, then transfer the pins over, and they work properly in switching.
 
Last edited:
That looks great.

What does FLASH/RAM in use show on the sketch: Simple Blink w/USB and the SPI_MST sample above?

What does it show if USB is set NONE with SPI_MST? Using the SPI would allow the MASTER to handle USB SerMon if needed - interesting if the SPI and SPI_MST is smaller than USB code.
 
Code:
Sketch uses 47856 bytes (75%) of program storage space. Maximum is 63488 bytes.
Global variables use 5672 bytes (69%) of dynamic memory, leaving 2520 bytes for local variables. Maximum is 8192 bytes.

It all depends on your buffers of course :)
 
With IDE set to "No USB"

Code:
Sketch uses 44204 bytes (69%) of program storage space. Maximum is 63488 bytes.
Global variables use 4220 bytes (51%) of dynamic memory, leaving 3972 bytes for local variables. Maximum is 8192 bytes.
 
That is pretty full. I have a mostly do nothing T_LC sketch with USB that shows:
Sketch uses 8636 bytes (13%) of program storage space. Maximum is 63488 bytes.
Global variables use 2112 bytes (25%) of dynamic memory, leaving 6080 bytes for local variables. Maximum is 8192 bytes.
 
The LC seems to be running more stable at 2MHz compared to 4MHz

At first I thought it was a code issue, but im not getting intermittant pauses anymore on SPI tranfers now
I'm doing 2MHz with 48MHz LC, printing "Hello World" to slave's USBSerial using teensy_gpio.println("Hello World");, I set the LC for 0 (instead of 25) for delay before assertion, the led is blinking, all in 20ms intervals, at 175uS for F&F
It seems to be running stable (I'm on SPI1 )
 
Well, it's full because it can control alot of the slave hardware :) Library bug ? :D

I created 2 sketches (host doing transfer16's, and slave responding) that switch between SPI0 & SPI1 on LC, I created it to help me diagnose the SPI functionality. Once it was deemed working, It's what helped me port the MST to LC
 
Here's an updated version with swappable SPI slave port

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

To change from SPI1 to SPI, goto the SPI_MSTransfer::begin() method in the CPP, and change the sSPI_port value from 1 to 0.

The 3.x series still use SPI0, the swap only affects the LC defines

EDIT, just an update, there are no issues at all so far at 2MHz with LC
 
should we make use of the SPI constructor for LC?

perhaps instead of “SLAVE”,”STANDALONE” we could do:

“SLAVE”,”SPI0”
“SLAVE”,”SPI1”
Perhaps we could also have the begin() method (outside of debug scope) show a “startup” information. Like, when begin() is called, the hardcoded pins will be shown on the console, sort of like a built in reference as opposed to users looking through pin setups in the doc?
This way they will know right away if they havn’t connected the correct pins.
?

we could also list hardcoded pinout for the LC in debug if user selects SPI0/1
they could be listed on startup with a selection, the. a user could simply recompile with that option:
“SPI1-ALT1”
 
Last edited:
SPI# seems more clear than 'STANDALONE'. Are you going to port the slave to SPI[0,1,2] on T_3.5 and T_3.6?

Could you make a SlaveSPI_t or SPIslv_t library out of this? Does it have to stay locked in the SPI_MST code? I suppose it is wedded to the tonton::SPI_MST protocol - unless it could be really generic and made to respond like i2c does - which only functions against a paired i2c master. In which case - what better way to use it than SPI_MSTransfer.

Odd the T_LC only reliable at 2 MHz - still faster than Serial or i2c - with just a couple more wires :)
 
I dont know about slicing the lib in half, ill see if i can have some things omit during compiling for slave, yeah i could do 3.x series too, but want make sure LC switching is good first
 
Back
Top