Project: SPI_MSTransfer

@Robin. @tonton81 has a couple of other Teensy libraries of note:

IFCT - Improved Flexcan Teensy Library (https://forum.pjrc.com/threads/52906-IFCT-Improved-Flexcan-Teensy-Library?highlight=canquitto ): He reworked most of the existing Flexcan code from scratch into a new library that supports current libraries and forks of collin80, teachop, and pawelsky, as well as a plugin for the MCP2515 library. It supports multiple mailboxes that are easily configurable as well as simplifies using filters - it does all the work for you.

CANquitto
CANquitto is a new canbus protocol library designed for teensy 3.x series MCUs. Currently in development stage, it has adopted quite a few features. This library takes advantage of IFCT and Circular_Buffer libraries when dealing with payload re-assembly.
Forum: https://forum.pjrc.com/threads/53776-CANquitto
  • Multi-master design: nodes can control each other, and 2 or more nodes can control a single node.
  • Payload transfers: You can send payloads to other nodes which they'll receive in their callback.
  • GPIO controls, read/write/toggle/pinmode,analogread pins on any nodes
  • Serial/UART controls, full UART/USBSerial functionality combined with Stream class, allows pass-by-reference.
  • Also support SPI and i2c_t3.

IMCTFD ( https://github.com/tonton81/IMCTFD ) - Improved Microchip CAN-FD Teensy FlexData Library (MCP2517FD). It uses SPI to communicate from the Teensy 3.x to a CAN-FD controller. So essentially you now can use a Teensy that will support the CAN-FD protocol.
FORUM: https://forum.pjrc.com/threads/5432...-CAN-Teensy-FlexData-Library?highlight=IMCTFD
  • This library was developed based on IFCT, libraries developed for and used on the Teensy 3.x platform. There are several benefits that are not even covered in the current Microchip API, or any other libraries.

Respectfully
Mike
 
Tonton (Tony):

I've hammered my brains against the wall for (more or less) the entire day. I've been unable to get your basic examples to work.
The ones I loaded were the SPI2WayExamples -> master, and SPI2WayExamples -> slave. They were loaded onto virgin Teensy 3.6-es, and the wiring is as specified (MOSI <> MOSI, MISO <> MISO, CS <> CS, SCK <> SCK) as 11, 12, 15, and 14, respectively (nice tip of the hat to Defragster!)

The message that keeps coming back in the text window is as below, but repeats endlessly as the counter increments:
Code:
C:\Users\furys\AppData\Local\Temp\arduino_modified_sketch_764008\master.ino Feb 15 2019 17:51:58
F_CPU	180000000
DBG: [S_CS 15] CB Capacity: 8 Length: 250
F&F (OT=0)micros() _time==99991
F&F (OT=1)micros() _time==99992
F&F (OT=2)micros() _time==99992
F&F (OT=3)micros() _time==99992
F&F (OT=4)micros() _time==99992
F&F (OT=5)micros() _time==99992
F&F (OT=6)micros() _time==99992
F&F (OT=7)micros() _time==99992
F&F (OT=8)micros() _time==99991
F&F (OT=9)micros() _time==99991
F&F (OT=10)micros() _time==99991
F&F (OT=11)micros() _time==99991

The text window for the slave shows this:
Code:
Teensy Online @ millis=5300

D:\Users\rmartin\Documents\Arduino\libraries\SPI_MSTransfer\examples\SPI2WayExamples\slave\slave.ino Feb 15 2019 17:58:10
F_CPU	180000000
and nothing more.

This is a picture of it. The master is on the left, slave is on the right.
WIN_20190215_18_13_56_Pro.jpg

What on earth am I doing wrong? I'd have expected to see at least something; some transaction working; the failure message on the master repeats regardless of whether the slave is powered on (or even connected). I feel like this should be obvious, but...it's not.

I tried lowering the bus speed to 16M, then 8M, but no joy at all on that; changed the wires (that's helped, before), moved board locations (this one is fairly new, so isn't so noisy yet). So it has to be something I'm missing.

I went through your README, line by line. It's a bit confusing, because you mention that we need to cross the streams (MOSI <> MISO, MISO <> MOSI) but that makes no difference; neither does connecting the (slave's?) pin 2 to the master's pin 15 (your A_ConfigDefines file sets both ends to 15).
 
Last edited:
slave pins used should be 2, 11, 12, and 14 for T3.x models

the config file is for the master selected spi pins, the slave’s is fixed
 
Last edited:
slave pins used should be 2, 11, 12, and 14 for T3.x models

the config file is for the master selected spi pins, the slave’s is fixed

Okay, using the examples files, again under SPI2WayExamples (master and slave).

The A_ConfigDefines.h files are set up to use 15 for CS and 14 for SCK, but nothing's happening between them; those examples, out of the box, appear not to work.

These are both Teensy 3.6es, brand new, and I've tested the boards, very little noise. The Saleae, however, is telling me that things are definitely not all right:
screenshot.jpg

So, right now, it's set up as:

Master Slave
MOSI 11 12
MISO 12 11
SCK 14 14
CS 15 2

Swapping MOSI and MISO doesn't help a lot. It looks like it's trying to do...something, I guess. If it helps, the fastest I need this to go (at the moment) is 8MHz on the bus. And I'm okay using the default SPI0 pins. I'm getting the sense I haven't hooked this up correctly, although it sort of appears that there's progress...? I defer to your opinon on that...
 

Attachments

  • screenshot.jpg
    screenshot.jpg
    66.6 KB · Views: 128
  • screenshot.jpg
    screenshot.jpg
    67.6 KB · Views: 117
not sure why it wouldnt work, check common ground with the new setup? I will have to find time maybe day or 2 to setup 2 teensies
 
Unless tonton81 evolved this to a broken point rather than improving it - this code was working almost a year ago after this thread started with two T_3.6's doing SPI to SPI transfers of some 50 to 100 bytes very reliably a few hundred times/second and was at 24 or 32 Mhz. This was with the main T_3.6 throttled grabbing GPS and 9DOF motion data and the SPI was to offload some of the calc's to feed a monitor program to graph the results on a PC and sending the data to USB slowed it down and this let it work out 400-600+ 9DOF updates/sec gaining it a couple hundred data points processing per second. And that was before the T_3.6 was running at 256 Mhz so it wasn't tested there.

i.e. … if the right setup is followed and programmed - it should work really well unless a tiny error was introduced.
 
most of the time it was bad grounding and cheap pololu cabling that caused no outputs due to corrupt crc data it may look like it’s doing nothing because of the wiring but it’s discarding the corrupt data while firing callbacks for valid data

SPI2 for example on T3.5/3.6 was finicky with grounding as well, best results for SPI2 came from ground point located near it’s pads, but SPI/SPI1 should work fine with GND located next to pin 0
 
Hi,
I have a project in mind that would need some kind of high speed serial communication between a Raspberry Pi Zero W and a Teensy 3.6. I have already tested communication over USB, UART and I2C but the best I could get to run relatively stable was a UART connection with 1Mbit/s. Better than nothing but still to slow for how many data I have to push from the Pi to the micro controller. The main Problem is that the Teensy is already pretty busy with some time critical stuff and cant sit there just collecting the data, which would take with the speed I have achieved so far at least one or two seconds. So I did some research and was surprised how little support there is for custom SPI communication between these two boards, specially with the Teensy in slave mode. This library seems to be the only really usable stuff I could found, so I wonder if it would be possible to interface the slave part of this code with a master part on the Raspberry written in Python, or is this library only intended for Teensy/ Teensy communication and woud not work otherwise?
 
It’s won’t work because of chip specific registers and custom protocol for two way communication, a complete code rewrite is needed for the rasp pi, to be compatible with this, and it won’t be an easy task to achieve :)
 
It’s won’t work because of chip specific registers and custom protocol for two way communication, a complete code rewrite is needed for the rasp pi, to be compatible with this, and it won’t be an easy task to achieve :)
Thank you for your time. I see, so no easy way to make this work... Your lib looks great though. I now know where to look if I happen come across a fitting use case for your lib.

At least I since found a way to solve my problem. Dramatically increasing the RX buffer in serial1.c and introducing a simple handshake to prevent overflow should do the trick for now. It's not pretty but will work for my needs until there are faster alternatives available :)
 
teensy supports RTS and CTS and has high baud rates, no need to implement it in software when it’s capable in hardware. Not sure if rasp pi supports RTS/CTS but it’s there on teensy side, it prevents overflow and buffers don’t need to be adjusted
 
Thanks for the advice, I haven't really thought about a hardware implementation. Indeed, I think the raspberry also has this feature and this would be definitely a simpler and less error prone solution to prevent overflow. But I will stick with the bigger buffer. There is plenty of RAM and it would keep the raspberry transmitting longer than without. Today, I also want to test some termination resistors and try to push the speed a little bit more, cause both IC's should normally be capable of much higher baudrates. Sadly I have no oscilloscope to actually test if signal reflection is really the limiting factor here.
 
I hope this question isn't too off-topic, but this thread likely is inhabited by people who know the answer (eg tonton81).

I gather that the connections between Teensy's needs to be MISO -> MOSI and MOSI -> MISO. This is like a UART hookup rather than the way SPI is intended to be used, right?

I presume there's a reason for this, so I took a look in the NXP reference manual and found sections 57.3.6 and 57.3.7 starting on the bottom of page 1818. This, along with the block diagram 57.1 seems to suggest that, indeed, the input to the SPI block is the input in both master and slave more, and the same for the output.

So, it seems that MISO and MOSI are misnomers, and the Teensy pins would more accurately be called MISI and MOSO, which would be weird!

Looking further into the reference manual in table 11.3.1 on page 186 it seems that the (e.g.) the SPI1_SIN and SPI1_SOUT internal signals can have their assignments swapped by changing the Port Control Module ALT functionality from 2 to 7.

I am just learning about SPI slave mode on the T3.6, but it seems that if this functionality could be incorporated into this library and perhaps TSPISlave it would match "proper" SPI and maybe help avoid future head-scratching. Is this possible? I will do some more reading, but I'm very new to this. I did get TSPISlave working fine after I noticed the
unconventional hookup.
cheers,
Doug
 
I hope this question isn't too off-topic, but this thread likely is inhabited by people who know the answer (eg tonton81).

I gather that the connections between Teensy's needs to be MISO -> MOSI and MOSI -> MISO. This is like a UART hookup rather than the way SPI is intended to be used, right?

...

That doesn't agree with first post this thread of Github ReadMe:
Slave's wiring:
T_3.5 :: T_3.6 > Connections
GND :: GND > GND
14 :: 14 > SCK
12 :: 11 > MOSI
11 :: 12 > MISO
02 :: 15 > CS

Pin 2 was chosen so that later on when I add Serial2 support pin10 would be available. Pin 14 for clock so that Led could be used
NOTE: SPI communication between teensy master&slave, MISO GOES TO MOSI, and MOSI to MISO, crossed, just like uart.
 
Right, I think we are saying the same thing. In this implementation MISO goes to MOSI and MOSI goes to MISO. pins 11 -> 12 and 12 -> 11.

In normal SPI MISO goes to MISO and MOSI goes to MOSI.

Doug
 
There is an exception with LC in slave mode, it is the opposite when connected to a T3/T4. LC in slave mode, MOSI is MISO and MISO is MOSI. Basically they reversed it in slave mode.
 
Maybe I've answered my own question.

MK66 Pin PTE1 and PTE3 can have their SPI1_SIN and SPI1_SOUT functions exchanged, BUT the Teensy 3.6 uses MK66 pins PTB16 and PTB17 for SPI1 data, and it looks like these cannot be swapped because the other alternative MUX configurations are used for other functions.

So, I think I now understand why Teensy 3.6 pin 0 should really be called MOSO, and pin 1 should be called MISI !! It will never catch on, though. Too weird looking...

cheers,
Doug
 
There is an exception with LC in slave mode, it is the opposite when connected to a T3/T4. LC in slave mode, MOSI is MISO and MISO is MOSI. Basically they reversed it in slave mode.

Sorry, I don't think I follow. I realize the LC is different from T3 and I thought the LC is correct. Having data flow into a pin labelled MISO while in slave mode is just perverse. No aspersions are being cast on your work, it seems a Teensy problem/limitation/design choice that is the issue.
 
For LC, it has nothing to do with the design. In master mode it's properly fit. It's just the way NXP designed the chip itself

In master mode:
MISO == MISO
MOSI == MOSI

In slave mode:
MISO == MOSI
MOSI == MISO
 
p#1839 noted a T_3.6 - no note on T_LC.

The Master In Slave Out and Master Out Slave In follows the expected pattern as defined - the T_LC is an exception where it would not work otherwise because of the nature of the T_LC hardware as tonton81 found it in Slave mode the names are reversed when used. For normal SPI use otherwise the hardware works with the names and function as indicated on the published Teensy cards.
 
p#1839 noted a T_3.6 - no note on T_LC.

The Master In Slave Out and Master Out Slave In follows the expected pattern as defined - the T_LC is an exception where it would not work otherwise because of the nature of the T_LC hardware as tonton81 found it in Slave mode the names are reversed when used. For normal SPI use otherwise the hardware works with the names and function as indicated on the published Teensy cards.

Right, post 1839 didn't mention LC, and indeed I'm only looking at T 3.6 and the reference manual for the MK66. I only mentioned the LC because Tonton did, and I remembered from Tonton's readme for TSPISlave that the LC and the T3 were different. In that readme it shows the following:

LC connections:

LC HOST
MISO -> MISO
MOSI -> MOSI

T3.x connections:

T3 HOST
MOSI -> MISO
MISO -> MOSI


And, as you pointed out, Tonton's readme for this library says that for T 3.6/6 MISO GOES TO MOSI, and MOSI to MISO. They have to be hooked up crossed.

My point is that T3 is "wrong" compared with every other SPI I've seen (and LC looks right). Wikipedia shows the usual configurations, including daisychained slaves.

Clearly, this is the only way SPI works for T3, and I think I understand why from looking in the NXP manual for the MK66. The particular MK66 pins chosen to be routed out for SPI data can't have their functions swapped by the Port Control Module. BUT, some of the NXP pins do that that functionality for SPI so it would be possible to implement normal SPI with the MXP MK66, so it's probably more accurate to guess that this was a choice made by Paul S. when he was balancing all sorts of competing factors.

I'm in no way criticising Paul, or anyone, other than perhaps to say that I don't think these T3.x pins should be labelled MISO and MOSI. That just seems wrong, and I disagree when you say that the hardware works as shown on the printed cards. For example, T3.6 pin 0 is called MOSI which means that when the device is a Master, data flows Out, and when it's a Slave, data flows In, right? But that's not that happens. Data only flows out of pin 0, right?

They could perhaps be called SPI Out and SPI In, or something like that, which is not conventional but at least correct. That being said, there is no official standard for SPI so I suppose anything goes as longs as it's documented somewhere.

Anyway, I need to put a T3.6 in SPI slave mode so that an FPGA can send my T3-based hardware commands. Tonton's TSPISlave library has already been a real help, and I expect I can gain some learning from SPI_MSTransfer to implement a simple acknowledgement reply.

Thanks,
Doug
 
oh... :eek: ... when connecting to typical slave displays - MOSI goes to MOSI and MISO to MISO … I was online when tonton81 started this and it made sense and seemed normal …
 
@tonton81 - first good morning and yes its been a while, been distracted with other projects :(.

Was looking the SPI_MSTransfer library to see what it would take to get working with the Teensy 4.x. Think you pretty much did most of the heavy lifting with the TPISlave_t4 library anyway which is what I am looking at as well. Wondering if the two can be linked - think its feasible?

Looks like there are two places that spi0 (assuming that is just reference SPI) that do the heavy lifting in MSTransfer:
Code:
void SPI_MSTransfer::begin() {
  if ( _slave_access ) {
and
Code:
void spi0_isr(void) {

Most of whats done in the spi0_isr is pushr which you so nicely provided in your SPIslave_t4 lib :) So it would just be a matter of converting this:
Code:
  while ( !(GPIOD_PDIR & 0x01) ) {
    if ( SPI0_SR & 0xF0 ) {
      SPI0_PUSHR_SLAVE = 0xDEAF; data[buffer_pos] = SPI0_POPR; buffer_pos++;
      if ( buffer_pos >= SPI_MST_DATA_BUFFER_MAX ) break; // BUFFER LENGTH PROTECTION
    }
    if ( data[1] && buffer_pos >= data[1] ) break;
  }
and this
Code:
      while ( !(GPIOD_PDIR & 0x01) ) { // wait here until MASTER confirms F&F receipt
        if ( SPI0_SR & 0xF0 ) {
          SPI0_PUSHR_SLAVE = 0xBABE;
          if ( SPI0_POPR == 0xD0D0 ) break;
        }
      }
      SPI0_SR |= SPI_SR_RFDF; return;
type code. I just have a lot of reading to do.

and of course the SPI0 slave initialization code in the begin function?
 
Back
Top