Learning Materials for DMA, SPI, and General Hardware Manipulation on Teensy 3.6

Status
Not open for further replies.

Guilt

Member
The bottom line here is that I'm in over my head and I have too many questions to just drop this all into a stackoverflow question and hope for an answer. Where do I find the definition and function of SPI0_SR, DMAMUX_SOURCE_SPI0_TX, etc? Why would you set SPI0_SR to 0xFF0F0000? Where do all of these register names and magic numbers come from? Do these terms get defined in the processor's datasheet? Is there a guide I'm missing?



Why I ask:

For a current project I need to continuously read data from an SD card, decompress it (almost entirely with lookup tables, nothing complex) and stream it out at a constant 8.6Mb/s. Between the hardware SPI interface and the DMA features, this seems like a very realistic goal on the Teensy 3.6.

I'm running into a lot of trouble though.

Firstly, it looks like the wire library outputs data at whatever speed it feels like. The SPISettings that you feed it looks to be more of a suggestion than anything else; it can't really hit a perfect 8.6Mb/s.

A kind user's suggestion here was to run in SPI slave mode, and use analogWriteFrequency() to generate the needed clock signal (then you can just feed it from that pwm pin into the SCK pin). That seems to work just fine, but introduces some new problems. The way I found to use the Teensy in SPI Slave mode was through one of a few libraries, the newest of which has no documentation in its github page, so source code comments in its example, and a lot of magic numbers in the .cpp file. Tonton81 has done some really impressive work here, I think, but I have no idea what value I need to pass in for "spimode"/"_fmsz".

In order to read, decompress, and output SD card data all continuously, I was planning on using a double-buffer and a DMA transfer to SPI, but dmachannel seems to be more or less undocumented as well. I got it to work using some copy/pasted code from these forums:
Code:
 SPI0_SR = 0xFF0F0000;
  SPI0_RSER = 0x00;
  SPI0_RSER = SPI_RSER_TFFF_RE | SPI_RSER_TFFF_DIRS; // Make sure SPI triggers a DMA transfer after each transmit
  
  dmachannel.sourceBuffer(data, 8); // The data for which we wish to transmit and its length
  dmachannel.destination((volatile uint8_t&)SPI0_PUSHR); // Move data into the SPI FIFO register
  dmachannel.triggerAtHardwareEvent(DMAMUX_SOURCE_SPI0_TX); // Only transfer data once the previous byte has been transmited (This is to ensure all bytes are sent)
  // dmachannel.disableOnCompletion(); // Stop after transmitting all 256 bytes
  dmachannel.interruptAtCompletion();
  // dmachannel.attachInterrupt(dmaFinishedTest);

  dmachannel.enable(); // Begin transmit
Which is pretty perfect if we're running in SPI Master mode but only outputs data on every other byte in slave mode for some reason.
 
You can find all neded information in the reference manuals:

https://www.pjrc.com/teensy/datasheets.html

https://github.com/TeensyUser/doc/wiki/Datasheets

The, you can always look at the sourcecode of the existing libraries to see how things are done.


For your SD access - you can use the 4-bit interface, or much easier, the library (and buffer the data: so, you don't need to do "constant" 8.6MB which is somewhat not archievable because of unpredictable wait-times of the SD card for block -adressing)
Bill Greimann wrote a very fast SD-library, too.
 
I've made note about Greimann's SD library - thank you again.
I'm reading the SPI chapter and running into some difficulties; it feels like there's a glossary that I'm missing? The document seems to use the terms SPI and DSPI interchangeably, and throws around terms it doesn't bother to define. In particular,
NOTE: Serial Data Out output buffers are controlled through SIU (or SIUL) and cannot be controlled through the module.
makes reference to SIU and SIUL, and in the Kinetis K66 (MK66FX1M0) manual those terms exclusively appear in that note. It's also not totally clear to me which module it refers to... the entire chip, or just this instance of SPI? Is there additional papers that I can cross-reference to parse some of this?
 
Status
Not open for further replies.
Back
Top