DmaSpi for teensyduino 1.21

Status
Not open for further replies.

christoph

Well-known member
DmaSpi now partially supports the Teensy LC. Only SPI0 is supported. I still have to think about a convenient interface scheme that allows transfers and chip select object to be "tied" to a specific SPI instance.

github: https://github.com/crteensy/DmaSpi

For anyone who wants to use DmaSpi in their Teensy LC library ports, please try it and tell me if it worked as desired and if you'd like to see any changes or enhancements. I'm also happy about suggestions regarding SPI1 support and how a suitable interface should look like.

Thanks to manitou for helping me with this!

Regards

Christoph
 
Hi,

I just switched to the new Version supporting Teensy LC. Even the DmaSpi sample of yours is not compiling. It says "init_count not declared in this scope". I'm using Arduino 1.6.1 on Mac OS X with Teensyduino 1.21.
Any suggestions?
 
compiler putput is:

In file included from name.ino:20:0:
.../Arduino/libraries/DmaSpi/DmaSpi.h: In static member function 'static void AbstractDmaSpi<DMASPI_INSTANCE>::end()':
.../Arduino/libraries/DmaSpi/DmaSpi.h:298:11: error: 'init_count' was not declared in this scope
if (init_count == 0)
^
Error compiling.
 
Thank you KurtE!

Now it's working. And as I took a look at the file it was obvious ;)

@christoph: Please correct this in the repository. The DmaSpi lib is awesome by the way!
 
Collecting some thoughts here...

Two major features are still missing in DmaSpi:
  1. Support for SPI1 (Teensy LC)
  2. Support for 16-bit transfers (Teensy 3.x and LC)
The idea behind the interface is (and should remain) to create a transfer object, register it with the DmaSpi library, and have it handled asynchronously in the future. The application code can come back any time to check if the transfer has been handled and if it is finished. The transfer can be altered and re-registered while it is not being handled by the library.

When a transfer is started, two things must happen:
  1. The SPI hardware is configured for the slave (clock speed, mode, bit order, bit count). Information about configuration must be included in the transfer object, or in other objects referenced by the transfer object.
  2. the slave is selected. This usually means that the corresponding slave select line is pulled low, but may also include other actions. This again must be specified by the transfer object.
Finishing a transfer just does the opposite: Deselect the slave and do some SPI cleanup.

I'm now facing a number of challenges:
  • Teensy 3.x and Teensy LC have different SPIs, but with a similar interface.
  • The Teensy LC SPIs (SPI and SPI1) are different classes.
  • SPISettings doesn't include the transfer bit count, but it does include speed, bit order, and mode.
I'll have to create my own set of wrappers around the different SPIs (Teensy 3.x vs LC) and similar SPIs in different classes (Teensy LC SPI vs SPI1). Also, the transfer must have aditional information about the word size somewhere. All that should be interchangeable without too much hassle so that users can simply move a slave from SPI to SPI1.
 
Yes, the devices don't care how the 16 bits are sent. However, the DMA controller does:

The SSD1351 display controller expects 16 bits of data per pixel, MSB first. Many display controllers use that format. The Teensys are little endian, so they store the lower 8 bits of a 16-bit word at the lower memory address:
Code:
   [0]      [1]
+--------+--------+
|0      7|8     15|
+--------+--------+
 rrrrrggg gggbbbbb <- color channel bits
I have to send byte [1] first, MSB first, and then byte [0], MSB first. This is fine when done by the CPU and it's also how it's usually done. However, the DMA controller can't do that. I could store the pixels with reversed byte order (byte[1] at the lower address), but one color channel would be scattered over the two bytes, making for two accesses for that color channel:
Code:
   [0]      [1]
+--------+--------+
|8     15|0      7| <- reversed byte order in memory
+--------+--------+
 gggbbbbb rrrrrggg  <- color channel bits, green channel scattered
and that significantly slows down the process of manipulating pixels.

So I need 16-bit SPI, MSB first, if I want to avoid that extra effort for manipulating pixels. I've already checked if the non-DMA implementation of SPI::transfer16() gives correct results, and it does.
 
Regarding LC and two different SPI classes: I will probably let the DmaSpi classes be a wrapper for the SPI they work with, and have them derive from a common base. They can then expose a common interface to the ChipSelect and Transfer classes, and nobody has to worry about the subtle differences between them.
 
Sooo there have been a few new teensyduino releases and I simply couldn't test them all. Recent github activity shows continued interest in this library, which is great. Two feature requests have come up:
The first one is easy, but a bit limited. There could also be a user callback when a transfer has been actually started. Callbacks can be implemented in custom chip select classes as well, so there already is a way to do this with a bit of customization.

Long transfers can be done with two or more split transfers, but there must be away of adding several consecutive transfers without any ISR having a chance to sneak another one in between them. I'm thinking about adding a way of registering a chain of transfers which must be prepared by the user, including loops (and the dangers assciated with that):


Any other feature requests? Did you encounter any other problems?
 
There is another thing I noticed, when I uncomment this line:
Code:
#define DEBUG_DMASPI 1

Then the Teensy fails to boot (& seems to go into a reboot loop) and I get a 'USB Device Not Recognized' warning from Windows 7.
 
Please open an issue. That's probably a tough nut to crack because it occurs during startup and limits the possible debugging output vectors...

However, I assume that you enabled the debugging output for a reason - what reason was that? Did you encounter a totally different problem?
 
Status
Not open for further replies.
Back
Top