Project: SPI_MSTransfer

Go for it. Did you glance at the CS version I did? not sure it if might show any issues or alternate paths forward - but KIST - keep it simple Tony. I never enabled the spi0_isr() and I swear it was working just watching CS.

I expected it would but not surprised there were some dozens of errors running F&F some 100's of thousands of times if CS fires before a byte is on the wire.
 
yup, the cs would make a good nvic disabler and the EOF would reenable it, that way we wouldnt miss initial byte while keeping spi0 quiet after
 
After further tests, the spi0_isr is way more faster at data capture than the pin interrupt
16 will have to move forward in the direction of shared variable usage protection that im currently still researching, the errors only occur when both the isr and main access the same queue, because it can be replicated with the slave queue, itll help me test different things after i do a little research

btw, to test the interrupt you didnt need all that code:)

just
Code:
attachInterrupt(2, spi0_isr, FALLING);
in setup(), and comment out the nvic enable, done
 
yup itll help on reading material, in practice is where not all things pass with flying colors :)
will try as much as possible to get things goin smooth
 
After further tests, the spi0_isr is way more faster at data capture than the pin interrupt
16 will have to move forward in the direction of shared variable usage protection that im currently still researching, the errors only occur when both the isr and main access the same queue, because it can be replicated with the slave queue, itll help me test different things after i do a little research

btw, to test the interrupt you didnt need all that code:)

just
Code:
attachInterrupt(2, spi0_isr, FALLING);
in setup(), and comment out the nvic enable, done

It was needed for general solution :: Some of the added code was to get the user specific CS pin - it can't be hard coded, the other code was to preserve the current entry point for spi0_isr in case it was needed to support the CS code.

Yes, pin interrupt goes through a port interrupt _isr() then pin detect calculated and route to the _isr() - increased priority could help that - but assuming CS fires 'a byte' before spi0_isr() thought it might have time.

I was just trying to show the alternate path in case it got rid of all the muck and fight over multiple interrupts ... oddly it worked at first - now it refuses . . .
 
Back to working with the uploaded SPI_MSTransfer_csSlave.zip. Not sure what I broke in editor - but the uploaded code should work.

<EDIT>: only 8 misses and up to 750,000 1 millis F&F's : that is less than 0.00114 percent error - this is MUCH better than I reported before at 0.025 % error.

Master is doing the Slave LED Toggle.

Then made this single change to slave.ino with : #define SPI_SLV_CS 2
slave.beginSlave( SPI_SLV_CS );

T_3.6 Master again at 240 MHz and SPI at 30 MHz, and T_3.5 at 168 MHz. F&F message freq is 500 Hz - >= 2 millis(). No errors up to 89,000 F&F when slave plugged in then the Master. Transfer time at ~50 us.

Then hit 3 by 100,000 F&F's - then no more until the 4th at 187788:
25256.00, #, #, #, #, #, #, #, #, #, #, #,187788,3

Bad LASTVAL TEST INCREMENT <<<<<<<<<<<<<<<<<<<< DIFF OF> -12.00
25280.00,25281.00,25282.00,25283.00,25284.00,25285.00,25286.00,25287.00,25288.00,25289.00,25290.00,25291.00,187789,4
25292.00, #, #, #, #, #, #, #, #, #, #, #,187790,4

Then another good long run to 284340 :
4232.00, #, #, #, #, #, #, #, #, #, #, #,284338,5

Bad LASTVAL TEST INCREMENT <<<<<<<<<<<<<<<<<<<< DIFF OF> -12.00
4256.00,4257.00,4258.00,4259.00,4260.00,4261.00,4262.00,4263.00,4264.00,4265.00,4266.00,4267.00,284339,6
4268.00, #, #, #, #, #, #, #, #, #, #, #,284340,6

Just changed Master output to 1,000 Hz with >= 1 millis() and one error on starting - then no more errors until 84,070. With some tweaks/corrections this is looking very stable. The retry takes entirely too long. Turned off the LED Toggle and it fails about the same - so the problem is in the SYNC for F&F?

<EDIT>: only 8 misses and up to 750,000 1 millis F&F's : that is less than 0.00114 percent error - this is MUCH better than I reported before at 0.025 % error.
 
Last edited:
not the sync, for the master->slave, it writes to the queue from isr, then returning to loop it's read and removed from queue


the slave->master writes to local queue, master pulls out queue and pops it

in both cases, the data sharing is clashing, eventually, due to the race condition between loop busy state and isr, which explains why a lower clock can possibly crash due to keeping the cpu busy writing all the prints and calculations and the next isr event, where a higher cpu speed processes faster in order not to slow down the isr capture, which also explains why the higher priority NVIC setting for spi0_isr worked better putting most if not other modules in back priority
 
Will let you resolve the queue isr read/write versus code queue'ing for write.

One Million and ONE error:
SLAVE::
43368.00, #, #, #, #, #, #, #, #, #, #, #,1067552,1

MASTER::
F&F (OT=1)micros() _time==49

Bumping the Slave's PIN interrupt priority seems to help - just need to know the associated PORT. Pin #2 is PortD { pins: 51-55, 47,48,2, 5-8, 14, 20, 21 } - is the list if I scanned the schematic right.
Just started a fresh run with this [1,000 F&F and 10 Toggle per second] - so far ZERO errors up to 400,000 F&F messages:
Code:
    NVIC_SET_PRIORITY(IRQ_PORTD, 0);
    attachInterrupt( addr, CS_isr, FALLING );

First Error showed at ~425,000?. Just passed 500,000 still with a single error.

With default Priority: Last run was 133 errors in 3,134,204 that is 0.0042% with the 1,000 F&F and 10 Toggle per second.

Made DEBUG msg more terse and shortened the delay()'s on err text - they cascade in larger groups. In between it runs long stretches of no errors.
There were two sets of errors under 50,000 - then still at only 5 errors up to error #6 at 236225, then cascaded up to 14 in the next couple 10K and no new ones until 432956, that is 150,000 with no errors.

With default priority The CS solution seems as stable as the old code - or 5 times better based on error rate observed [0.005% versus 0.025%].
 
your saying the v16 has errors using spi0 isr? with nvic set to 1 ?

Can't say for sure when I did the last long run - not sure when the spi0 NVIC pri went up - but the last I tested was as noted.

The CS interrupt will be much less frequent than the spi0 though right? So less system over head even with the pin parsing.

Still only one error at 1.32 million F&F's with elevated CS isr()

<edit>:I was saying I saw errors in this post that was using V16.

<edit2>:
This prior post saw errors gone in V16 - about the same rate as with CS driving the SPI - but one interrupt per transfer instead of 100.

Current CS run near 2 million - still one error - this is the same :: 38396.00, #, #, #, #, #, #, #, #, #, #, #,1974741,1
 
Last edited:
im not even sure not if the spi0 interrupts fire every byte, either way, everything goes one->way through the entire isr scope, i tried the CS thing before but it didnt fix the slave send issue and it got me errors, i even tried the portd irq to 1 before and i got errors & serial output lag sometimes, the sub calls in the isr block-wait for the spi data so there shouldnt be any loss as shown by error reports

so there can not be reentrant issues with current spi isr, otherwise the pointers would clash

the high cpu frequency must be done processing by the next packet for it to successfully pass, thats why the master sends work, even though theres no queue protection
im pretty sure with the cross-over imx cpu teensy 4 you wont have an issue with this as the processing will be so fast that if it can work at current clock speeds, it should be capable of even higher successful speeds

fixing the shared datatypes should allow us to "downclock" our cpu frequency, but this means, you could possibly send more than the alloted queue space over time because its processing them 1 callback at a time

you could still hardcode the pin2 in your CS layout since it wont be changed until the queues are fixed, but 2 was chosen so that Serial2 pin 10TX could be used as there are no alternates for it, and , it seemed like a waste to loose a uart TX when a project may need it

EDIT: the spi0_isr refires only if you clear the flag, which doesnt happen until:
A) master sends the kill signal before deassertion
B) deassertion

only then the ISR refires, but never again until the flag is cleared, which never happens until the full SPI0_isr is completed, or line goes HIGH

clearing the flag prematurely while shifting a byte is asking for out of sync issues, especially with organized switch statements
 
Last edited:
Using CS as above I just dropped SPI to 12 MHz and no errors at 230 K F&F's.

Will drop the CPU speeds where I was getting errors last night.

Dropped Slave to 120 MHz against 240 MHz Master as above - seeing some errors under 30 K?

Dropped Master to 168 MHz and no errors at 85,000 - will let it run . . .
 
Yeah, maybe we'll incorporate both styles

you should be able to point both to the same function anyways, and call attachinterrupt when you want CS interrupt style, or NVIC for SPI interrupt style
perhaps we could do an interrupt style overload too after, like "SLAVE","CS INTERRUPT" or "SLAVE","SPI INTERRUPT"
 
Running both at the M=168/S=120:12MHz SPI :: 20924.00, #, #, #, #, #, #, #, #, #, #, #,1907750,0

I played with the slave to print # of isr() hits - the CS hits twice as often as spi0_isr it seems:
spi0isr #26 csisr #52

Interesting note - it was STABLE - the MASTER reported ONE ERROR for each new SLAVE upload - while it was offline programming then came up running!
 
Last note for now - CS does work - may not be as good or better.

Just removed DEBUGHACK for full Slave string print and that breaks it at 1 ms prints - the Terse DEBUGHACK formatted output runs much faster and was keeping up.

<edit>: Started the FULL print emulate of the false values at 500 Hz F&F - every 2 ms and it is working on 120 MHz T_3.5 Slave to keep up with 168 MHz T-3.6 Master
 
Last edited:
I have a relatively simple question, will this eventually work a T3.5 as a master and a T3.2 as the slave? Reason for asking is that I have a breakout board that has a T3.2 with a 8266 in a mega style breakout board that I would like to eventually use as the slave. The 8266 is connected to the one of the serial ports :( which is the only draw back or advantage depending on how you look at it.

Yes, I know its a bit early but was just curious.
 
T_3.2 should work - I have not hooked one up yet - though either of us could :) It has OC menu item for 120 MHz if needed. The fast ILI9341 at 24 MHz SPI works super well on the T_3.2.

update: my CS drive SPI_MST is still running > 3 Hours < with only the one Master error when I restarted the Slave running the full formatted output line at 500 updates/sec.
 
I think I am going to give it a shot tomorrow. Think right now its just a matter of getting the speeds matched. In my early tests the master/slave sometimes worked sometimes didn't with the 35/35 combination.

On your update sounds like you all are making progress. Been playing with Watson's kalman filter all day. No matter what I tried with Brian's uNavAHRS code I could not get rid of the drift. By the way did you try sending messages from the slave to the master as well?
 
I did not try any of the slave to master messages. I wasn't following what the issue was and tried the CS for ISR on Slave - seems to work about as well. The CS triggers about twice as often and has a shared vector across all pins on the common port to be deciphered. The direct spi0 interrupt will be better and it only ONCE per transaction so it acts well and will be better to use.

I have a T-3.1 with a header from the T_3.6 beta time I can easily wire up - will see what I have for a second Master Teensy - I have a similar beta T_3.6 header'd up like the T_3.5 beta I'm using now as slave. I'll grab the wire diagram and maybe cut some wires to try it.
 
I have a T_3.6 Master @180 running against a T_3.1 @96 no problem, LED Flashing @ 10 Hz Toggle with SPI @12 MHz and the Master pushing F&F at 500 Hz.

T_3.1 is running full formatted 142 character string - not DEBUGHACK abbreviated.

>> I am still running my Slave with CS isr() - did not edit back to the spi0_isr yet.

Zero OverTime's in the first few minutes. Just ran the wires as noted before.

Just bumped Master SPI to 30 MHz - No problem - now cycling at 55 uS instead of 105 Us.

Tony: Only problem is no #ifdef on Serial 4,5,6 for T_3.1/3.2.

Reverted to MST_V16 using spio_isr and it works as above.

Mike: Had to refix the Serial4,5,6 - Quick Hack:
#define Serial4 Serial1
#define Serial5 Serial1
#define Serial6 Serial1
 
Last edited:
Tim. Wow. Thanks for checking configuration, I didn't expect that :) At least we know now that it should work on any Teensy 3.x. Think I will play around with it a bit more later today - have a bunch of errands to run this morning.
 
im getting errors here when using the CS version even with portd set to 1, even serial monitor prints jumps in groups and eventually locks up in my tests

the spi0 version is streaming consistantly
 
Last edited:
I just added ifdef's for serials 4->6 in the switch statements as well so theyre not compiled unless ur using 3.5/3.6
 
Back
Top