Teensy 4 getting closer

This commit is contained in:
Phillip Burgess 2020-05-15 17:35:10 -07:00
parent 3e64c1e127
commit 60414a4d0d
3 changed files with 85 additions and 4 deletions

3
arch.h
View file

@ -1138,6 +1138,9 @@ uint32_t _PM_timerStop(void *tptr) {
return _PM_timerGetCount(tptr);
}
#define _PM_clockHoldHigh asm("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop");
#define _PM_clockHoldLow asm("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop");
#elif defined(CIRCUITPY)
// Teensy 4 CircuitPython magic goes here.

84
core.c
View file

@ -241,7 +241,7 @@ ProtomatterStatus _PM_begin(Protomatter_core *core) {
// Figure out clockMask and rgbAndClockMask, clear matrix buffers
if (core->bytesPerElement == 1) {
core->portOffset = _PM_byteOffset(core->rgbPins[0]);
#if defined(_PM_portToggleRegister)
#if defined(_PM_portToggleRegister) && !defined(_PM_STRICT_32BIT_IO)
// Clock and rgbAndClockMask are 8-bit values
core->clockMask = _PM_portBitMask(core->clockPin) >> (core->portOffset * 8);
core->rgbAndClockMask =
@ -258,7 +258,7 @@ ProtomatterStatus _PM_begin(Protomatter_core *core) {
}
} else if (core->bytesPerElement == 2) {
core->portOffset = _PM_wordOffset(core->rgbPins[0]);
#if defined(_PM_portToggleRegister)
#if defined(_PM_portToggleRegister) && !defined(_PM_STRICT_32BIT_IO)
// Clock and rgbAndClockMask are 16-bit values
core->clockMask =
_PM_portBitMask(core->clockPin) >> (core->portOffset * 16);
@ -563,6 +563,9 @@ IRAM_ATTR void _PM_row_handler(Protomatter_core *core) {
// before setting the clock back low. If undefined, nothing goes there.
#if !defined(PEW) // arch.h can define a custom PEW if needed (e.g. ESP32)
#if !defined(_PM_STRICT_32BIT_IO) // Partial access to 32-bit GPIO OK
#if defined(_PM_portToggleRegister)
#define PEW \
*toggle = *data++; /* Toggle in new data + toggle clock low */ \
@ -578,7 +581,28 @@ IRAM_ATTR void _PM_row_handler(Protomatter_core *core) {
*clear_full = rgbclock; /* Clear RGB data + clock */ \
///< Bitbang one set of RGB data bits to matrix
#endif
#endif // PEW
#else // ONLY 32-bit GPIO
#if defined(_PM_portToggleRegister)
#define PEW \
*toggle = *data++ << shift; /* Toggle in new data + toggle clock low */ \
_PM_clockHoldLow; \
*toggle = clock; /* Toggle clock high */ \
_PM_clockHoldHigh;
#else
#define PEW \
*set = *data++ << shift; /* Set RGB data high */ \
_PM_clockHoldLow; \
*set = clock; /* Set clock high */ \
_PM_clockHoldHigh; \
*clear = rgbclock; /* Clear RGB data + clock */ \
///< Bitbang one set of RGB data bits to matrix
#endif
#endif // end 32-bit GPIO
#endif // end PEW
#if _PM_chunkSize == 1
#define PEW_UNROLL PEW
@ -608,6 +632,8 @@ IRAM_ATTR void _PM_row_handler(Protomatter_core *core) {
// three-function maintenance then.)
IRAM_ATTR static void blast_byte(Protomatter_core *core, uint8_t *data) {
#if !defined(_PM_STRICT_32BIT_IO) // Partial access to 32-bit GPIO OK
#if defined(_PM_portToggleRegister)
// If here, it was established in begin() that the RGB data bits and
// clock are all within the same byte of a PORT register, else we'd be
@ -645,9 +671,37 @@ IRAM_ATTR static void blast_byte(Protomatter_core *core, uint8_t *data) {
*((volatile uint8_t *)core->clearReg + core->portOffset) =
core->rgbAndClockMask;
#endif
#else // ONLY 32-bit GPIO
#if defined(_PM_portToggleRegister)
volatile _PM_PORT_TYPE *toggle = (volatile _PM_PORT_TYPE *)core->toggleReg;
#else
volatile _PM_PORT_TYPE *set = (volatile _PM_PORT_TYPE *)core->setReg;
volatile _PM_PORT_TYPE *clear = (volatile _PM_PORT_TYPE *)core->clearReg;
_PM_PORT_TYPE rgbclock = core->rgbAndClockMask; // RGB + clock bit
#endif
_PM_PORT_TYPE clock = core->clockMask; // Clock bit
uint8_t shift = core->portOffset * 8;
uint8_t chunks = (core->width + (_PM_chunkSize - 1)) / _PM_chunkSize;
// PORT has already been initialized with RGB data + clock bits
// all LOW, so we don't need to initialize that state here.
while (chunks--) {
PEW_UNROLL // _PM_chunkSize RGB+clock writes
}
#if defined(_PM_portToggleRegister)
*((volatile uint32_t *)core->clearReg) = core->rgbAndClockMask;
#endif
#endif // 32-bit GPIO
}
IRAM_ATTR static void blast_word(Protomatter_core *core, uint16_t *data) {
#if !defined(_PM_STRICT_32BIT_IO) // Partial access to 32-bit GPIO OK
#if defined(_PM_portToggleRegister)
// See notes above -- except now 16-bit word in PORT.
volatile uint16_t *toggle =
@ -671,6 +725,27 @@ IRAM_ATTR static void blast_word(Protomatter_core *core, uint16_t *data) {
*((volatile uint16_t *)core->clearReg + core->portOffset) =
core->rgbAndClockMask;
#endif
#else // ONLY 32-bit GPIO
#if defined(_PM_portToggleRegister)
volatile _PM_PORT_TYPE *toggle = (volatile _PM_PORT_TYPE *)core->toggleReg;
#else
volatile _PM_PORT_TYPE *set = (volatile _PM_PORT_TYPE *)core->setReg;
volatile _PM_PORT_TYPE *clear = (volatile _PM_PORT_TYPE *)core->clearReg;
_PM_PORT_TYPE rgbclock = core->rgbAndClockMask; // RGB + clock bit
#endif
_PM_PORT_TYPE clock = core->clockMask; // Clock bit
uint8_t shift = core->portOffset * 16;
uint8_t chunks = (core->width + (_PM_chunkSize - 1)) / _PM_chunkSize;
while (chunks--) {
PEW_UNROLL // _PM_chunkSize RGB+clock writes
}
#if defined(_PM_portToggleRegister)
*((volatile _PM_PORT_TYPE *)core->clearReg) = core->rgbAndClockMask;
#endif
#endif // 32-bit GPIO
}
IRAM_ATTR static void blast_long(Protomatter_core *core, uint32_t *data) {
@ -690,6 +765,9 @@ IRAM_ATTR static void blast_long(Protomatter_core *core, uint32_t *data) {
_PM_PORT_TYPE rgbclock = core->rgbAndClockMask; // RGB + clock bit
#endif
_PM_PORT_TYPE clock = core->clockMask; // Clock bit
#if defined(_PM_STRICT_32BIT_IO)
uint8_t shift = 0;
#endif
uint8_t chunks = (core->width + (_PM_chunkSize - 1)) / _PM_chunkSize;
while (chunks--) {
PEW_UNROLL // _PM_chunkSize RGB+clock writes

View file

@ -108,7 +108,7 @@ RGB+clock are on different PORTs on nRF52840.
uint8_t latchPin = 32;
uint8_t oePin = 33;
#elif defined(ARDUINO_TEENSY40)
uint8_t rgbPins[] = {15, 16, 17, 20, 21, 22}; // A1-2, A6-8 (skip SDA, SCL)
uint8_t rgbPins[] = {15, 16, 17, 20, 21, 22}; // A1-A3, A6-A8, skips SDA,SCL
uint8_t addrPins[] = {2, 3, 4, 5};
uint8_t clockPin = 23; // A9
uint8_t latchPin = 6;