PDA

View Full Version : Teensy 3 SPI wrapper class



christoph
11-17-2013, 05:04 PM
I needed access to the SPI's CTAR's in an array-like manner, because I wanted to use the CTAR number as template argument for a class that needs to define a CTAR. So I created a wrapper that provides that:


#ifndef _SPI_H_
#define _SPI_H_

#include <mk20dx128.h>

#include <stdint.h>

class DSPI_REGS
{
public:
volatile uint32_t MCR; // +0x00
private:
uint32_t _dummy0; // +0x04
public:
volatile uint32_t TCR; // +0x08
volatile uint32_t CTAR0; // +0x0C
volatile uint32_t CTAR1; // +0x10
private:
uint32_t _dummy1[6];
public:
volatile uint32_t SR; // +0x2C
volatile uint32_t RSER; // +0x30
volatile uint32_t PUSHR; // +0x34
volatile uint32_t POPR; // +0x38
volatile uint32_t TXFR0; // +0x3C
volatile uint32_t TXFR1; // +0x40
volatile uint32_t TXFR2; // +0x44
volatile uint32_t TXFR3; // +0x48
private:
uint32_t _dummy2[12];
public:
volatile uint32_t RXFR0; // +0x7C
volatile uint32_t RXFR1; // +0x80
volatile uint32_t RXFR2; // +0x84
volatile uint32_t RXFR3; // +0x88
} __attribute__((packed));

template<uint32_t base> // couldn't use a pointer argument here, sorry!
class DSPI : public DSPI_REGS
{
class CTARn
{
public:
volatile uint32_t& operator[](const uint8_t& i) const
{
volatile uint32_t* p = &(((DSPI_REGS*)base)->CTAR0);
return p[i & 1];
}
};
class TXFRn
{
public:
volatile uint32_t& operator[](const uint8_t& i) const
{
volatile uint32_t* p = &(((DSPI_REGS*)base)->TXFR0);
return p[i & 3];
}
};
class RXFRn
{
public:
volatile uint32_t& operator[](const uint8_t& i) const
{
volatile uint32_t* p = &(((DSPI_REGS*)base)->RXFR0);
return p[i & 3];
}
};
public:
CTARn CTAR;
TXFRn TXFR;
RXFRn RXFR;
};

DSPI<0x4002C000>& SPI0 = *( ( DSPI<0x4002C000>* ) 0x4002C000 );

#endif // _SPI_H_

It's not fully tested, but compiles fine and each member's address is correct, it seems. If anyone tries it, please tell me if you found any errors or caveats.

The SPI can now be used like a structure, as in
SPI0.MCR = SPI_MCR_MSTR | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF;
SPI0.CTAR[0] = SPI_CTAR_BR(3);

Regards

Christoph