Clean up comments, redundant declarations, loose ends
This commit is contained in:
parent
d980bc15a0
commit
1257af6e90
13 changed files with 247 additions and 1743 deletions
13
README.md
13
README.md
|
|
@ -39,15 +39,16 @@ help keep up-to-date with any future changes here!
|
|||
|
||||
The common ground for architectures to support this library:
|
||||
|
||||
* 32-bit device (e.g. ARM core, but potentially ESP32 and others in future)
|
||||
* 32-bit device (e.g. ARM core, ESP32 and others)
|
||||
* One or more 32-bit GPIO PORTs with atomic (single-cycle, not
|
||||
read-modify-write) bitmask SET and CLEAR registers. A bitmask TOGGLE
|
||||
register, if present, may improve performance but is NOT required.
|
||||
* There may be performance or storage benefits if the architecture tolerates
|
||||
8-bit or word-aligned 16-bit accesses within the 32-bit PORT registers
|
||||
(e.g. writing just one of four bytes, rather than the whole 32 bits), but
|
||||
this is NOT required. The library does not use any unaligned accesses
|
||||
(i.e. "middle word" of a 32-bit register), even if a device allows such.
|
||||
this is NOT a hardware requirement. Also, the library does not use any
|
||||
unaligned accesses (i.e. "middle word" of a 32-bit register), even if a
|
||||
device tolerates such.
|
||||
|
||||
# Software Components
|
||||
|
||||
|
|
@ -93,7 +94,7 @@ drawing functions.
|
|||
|
||||
The C code has the same limitations as the Arduino library: all RGB data
|
||||
pins and the clock pin MUST be on the same PORT register, and it's most
|
||||
memory efficient (though still a bit gluttonous) if those pins are all
|
||||
memory efficient (though still slightly gluttonous) if those pins are all
|
||||
within the same 8-bit byte within the PORT (they do not need to be
|
||||
contiguous or sequential within that byte). Other pins (matrix address lines,
|
||||
latch and output enable) can reside on any PORT or bit.
|
||||
|
|
@ -105,8 +106,8 @@ source files, as in the Arduino library .cpp and .h). core.c contains only
|
|||
the device-neutral bitbang code and should not have any "#ifdef DEVICE"- or
|
||||
"#ifdef ENVIRONMENT"-like lines (exception for the 565 color conversion
|
||||
functions, since the internal representation is common to both Arduino and
|
||||
CircuitPython. Macros for things like getting a PORT register address from a
|
||||
pin, or setting up a timer peripheral, all occur in the arch header files,
|
||||
CircuitPython). Macros for things like getting a PORT register address from
|
||||
a pin, or setting up a timer peripheral, all occur in the arch header files,
|
||||
which are ONLY #included by core.c (to prevent problems like multiple
|
||||
instances of ISR functions, which must be singularly declared at
|
||||
compile-time).
|
||||
|
|
|
|||
|
|
@ -36,34 +36,12 @@
|
|||
// Arduino-specific wrapper for the Protomatter C library (provides
|
||||
// constructor and so forth, builds on Adafruit_GFX). There should
|
||||
// not be any device-specific #ifdefs here. See notes in core.c and
|
||||
// arch.h regarding portability.
|
||||
// arch/arch.h regarding portability.
|
||||
|
||||
#include "Adafruit_Protomatter.h" // Also includes core.h & Adafruit_GFX.h
|
||||
|
||||
extern Protomatter_core *_PM_protoPtr; ///< In core.c (via arch.h)
|
||||
|
||||
// Overall matrix refresh rate (frames/second) is a function of matrix width
|
||||
// and chain length, number of address lines, number of bit planes, CPU speed
|
||||
// and whether or not a GPIO toggle register is available. There is no "this
|
||||
// will run at X-frames-per-second" constant figure. You typically just have
|
||||
// to try it out and perhaps trade off some bit planes for refresh rate until
|
||||
// the image looks good and stable. Anything over 100 Hz is usually passable,
|
||||
// around 250 Hz is where things firm up. And while this could proceed higher
|
||||
// in some situations, the tradeoff is that faster rates use progressively
|
||||
// more CPU time (because it's timer interrupt based and not using DMA or
|
||||
// special peripherals). So a throttle is set here, an approximate maximum
|
||||
// frame rate which the software will attempt to avoid exceeding (but may
|
||||
// refresh slower than this, and in many cases will...just need to set an
|
||||
// upper limit to avoid excessive CPU load). An incredibly long comment block
|
||||
// for a single constant, thank you for coming to my TED talk!
|
||||
#define _PM_MAX_REFRESH_HZ 250 ///< Upper limit (ish) to matrix refresh rate
|
||||
|
||||
// Time (in milliseconds) to pause following any change in address lines
|
||||
// (individually or collectively). Some matrices respond slowly there...
|
||||
// must pause on change for matrix to catch up. Defined here (rather than
|
||||
// arch.h) because it's not architecture-specific.
|
||||
#define _PM_ROW_DELAY 8 ///< Delay time between row address line changes (ms)
|
||||
|
||||
Adafruit_Protomatter::Adafruit_Protomatter(uint16_t bitWidth, uint8_t bitDepth,
|
||||
uint8_t rgbCount, uint8_t *rgbList,
|
||||
uint8_t addrCount, uint8_t *addrList,
|
||||
|
|
@ -85,7 +63,7 @@ Adafruit_Protomatter::Adafruit_Protomatter(uint16_t bitWidth, uint8_t bitDepth,
|
|||
}
|
||||
|
||||
Adafruit_Protomatter::~Adafruit_Protomatter(void) {
|
||||
_PM_free(&core);
|
||||
_PM_deallocate(&core);
|
||||
_PM_protoPtr = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
* @file arch.h
|
||||
*
|
||||
* Part of Adafruit's Protomatter library for HUB75-style RGB LED matrices.
|
||||
* This file establishes some very low-level things and includes headers
|
||||
* specific to each supported device. This should ONLY be included by
|
||||
* core.c, nowhere else. Ever.
|
||||
*
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
|
|
@ -14,9 +17,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
// Establishes some very low-level things specific to each supported device.
|
||||
// This should ONLY be included by core.c, nowhere else. Ever.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string.h>
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
/*
|
||||
Common ground for architectures to support this library:
|
||||
|
||||
- 32-bit device (e.g. ARM core, but potentially others in the future)
|
||||
- 32-bit device (e.g. ARM core, ESP32, potentially others in the future)
|
||||
- One or more 32-bit GPIO PORTs with atomic bitmask SET and CLEAR registers.
|
||||
A TOGGLE register, if present, may improve performance but is NOT required.
|
||||
- Tolerate 8-bit or word-aligned 16-bit accesses within the 32-bit PORT
|
||||
|
|
@ -129,9 +129,17 @@ _PM_clockHoldLow: Additional code (e.g. NOPs) needed to delay
|
|||
_PM_minMinPeriod: Mininum value for the "minPeriod" class member,
|
||||
so bit-angle-modulation time always doubles with
|
||||
each bitplane (else lower bits may be the same).
|
||||
_PM_allocate: Memory allocation function, should return a
|
||||
pointer to a buffer of requested size, aligned
|
||||
to the architecture's largest native type.
|
||||
If not defined, malloc() is used.
|
||||
_PM_free: Corresponding deallocator for _PM_allocate().
|
||||
If not defined, free() is used.
|
||||
*/
|
||||
|
||||
#if defined(ARDUINO) // COMPILING IN ARDUINO IDE ---------------------------
|
||||
// ENVIRONMENT-SPECIFIC DECLARATIONS ---------------------------------------
|
||||
|
||||
#if defined(ARDUINO) // COMPILING FOR ARDUINO ------------------------------
|
||||
|
||||
#include <Arduino.h> // Pull in all that stuff.
|
||||
|
||||
|
|
@ -149,21 +157,9 @@ _PM_minMinPeriod: Mininum value for the "minPeriod" class member,
|
|||
|
||||
#define _PM_delayMicroseconds(us) mp_hal_delay_us(us)
|
||||
|
||||
#ifdef SAMD51
|
||||
#define __SAMD51__
|
||||
#define F_CPU (120000000)
|
||||
#endif
|
||||
#ifdef SAMD21
|
||||
#define _SAMD21_
|
||||
#endif
|
||||
|
||||
#ifdef STM32F405xx
|
||||
#define STM32F4_SERIES (1)
|
||||
#endif
|
||||
|
||||
// No #else here. In non-Arduino case, declare things in the arch-specific
|
||||
// sections below...unless other environments provide device-neutral
|
||||
// functions as above, in which case those could go here (w/#elif).
|
||||
// files below...unless other environments provide device-neutral functions
|
||||
// as above, in which case those could go here (w/#elif).
|
||||
|
||||
#endif // END CIRCUITPYTHON ------------------------------------------------
|
||||
|
||||
|
|
@ -195,18 +191,18 @@ _PM_minMinPeriod: Mininum value for the "minPeriod" class member,
|
|||
#define _PM_minMinPeriod 100 ///< Minimum timer interval for least bit
|
||||
#endif
|
||||
|
||||
#ifndef _PM_ALLOCATOR
|
||||
#define _PM_ALLOCATOR(x) (malloc((x))) ///< Memory alloc call
|
||||
#if !defined(_PM_allocate)
|
||||
#define _PM_allocate(x) (malloc((x))) ///< Memory alloc call
|
||||
#endif
|
||||
|
||||
#ifndef _PM_FREE
|
||||
#define _PM_FREE(x) (free((x))) ///< Memory free call
|
||||
#if !defined(_PM_free)
|
||||
#define _PM_free(x) (free((x))) ///< Corresponding memory free call
|
||||
#endif
|
||||
|
||||
#ifndef IRAM_ATTR
|
||||
#if !defined(IRAM_ATTR)
|
||||
#define IRAM_ATTR ///< Neutralize ESP32-specific attribute in core.c
|
||||
#endif
|
||||
|
||||
#ifndef _PM_PORT_TYPE
|
||||
#if !defined(_PM_PORT_TYPE)
|
||||
#define _PM_PORT_TYPE uint32_t ///< PORT register size/type
|
||||
#endif
|
||||
|
|
|
|||
1601
src/arch/arch.h.bak
1601
src/arch/arch.h.bak
File diff suppressed because it is too large
Load diff
|
|
@ -1,8 +1,25 @@
|
|||
// ESP32-SPECIFIC CODE -----------------------------------------------------
|
||||
/*!
|
||||
* @file esp32.h
|
||||
*
|
||||
* Part of Adafruit's Protomatter library for HUB75-style RGB LED matrices.
|
||||
* This file contains ESP32-SPECIFIC CODE.
|
||||
*
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Written by Phil "Paint Your Dragon" Burgess and Jeff Epler for
|
||||
* Adafruit Industries, with contributions from the open source community.
|
||||
*
|
||||
* BSD license, all text here must be included in any redistribution.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(ESP32)
|
||||
|
||||
#if defined(ARDUINO)
|
||||
#if defined(ARDUINO) // COMPILING FOR ARDUINO ------------------------------
|
||||
|
||||
#include "driver/timer.h"
|
||||
|
||||
|
|
@ -95,12 +112,12 @@ IRAM_ATTR uint32_t _PM_timerStop(void *tptr) {
|
|||
return _PM_timerGetCount(tptr);
|
||||
}
|
||||
|
||||
#elif defined(CIRCUITPY)
|
||||
#elif defined(CIRCUITPY) // COMPILING FOR CIRCUITPYTHON --------------------
|
||||
|
||||
// ESP32 CircuitPython magic goes here. If any of the above Arduino-specific
|
||||
// defines, structs or functions are useful as-is, don't copy them, just
|
||||
// move them above the ARDUINO check so fixes/changes carry over, thx.
|
||||
|
||||
#endif
|
||||
#endif // END CIRCUITPYTHON ------------------------------------------------
|
||||
|
||||
#endif // END ESP32
|
||||
|
|
|
|||
|
|
@ -1,8 +1,25 @@
|
|||
// NRF52-SPECIFIC CODE -----------------------------------------------------
|
||||
/*!
|
||||
* @file nrf52.h
|
||||
*
|
||||
* Part of Adafruit's Protomatter library for HUB75-style RGB LED matrices.
|
||||
* This file contains NRF52-SPECIFIC CODE.
|
||||
*
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Written by Phil "Paint Your Dragon" Burgess and Jeff Epler for
|
||||
* Adafruit Industries, with contributions from the open source community.
|
||||
*
|
||||
* BSD license, all text here must be included in any redistribution.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(NRF52_SERIES)
|
||||
|
||||
#if defined(ARDUINO)
|
||||
#if defined(ARDUINO) // COMPILING FOR ARDUINO ------------------------------
|
||||
|
||||
// digitalPinToPort, g_ADigitalPinMap[] are Arduino specific:
|
||||
|
||||
|
|
@ -58,7 +75,7 @@ void _PM_IRQ_HANDLER(void) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#elif defined(CIRCUITPY)
|
||||
#elif defined(CIRCUITPY) // COMPILING FOR CIRCUITPYTHON --------------------
|
||||
|
||||
#include "nrf_gpio.h"
|
||||
|
||||
|
|
@ -82,13 +99,14 @@ volatile uint32_t *_PM_portClearRegister(uint32_t pin) {
|
|||
#define _PM_pinInput(pin) nrf_gpio_cfg_input(pin)
|
||||
#define _PM_pinHigh(pin) nrf_gpio_pin_set(pin)
|
||||
#define _PM_pinLow(pin) nrf_gpio_pin_clear(pin)
|
||||
#define _PM_portBitMask(pin) (1u << ((pin) % 32))
|
||||
#define _PM_portBitMask(pin) (1u << ((pin) & 31))
|
||||
|
||||
#define _PM_byteOffset(pin) ((pin % 32) / 8)
|
||||
#define _PM_wordOffset(pin) ((pin % 32) / 16)
|
||||
|
||||
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
|
||||
#error SRSLY
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define _PM_byteOffset(pin) ((pin & 31) / 8)
|
||||
#define _PM_wordOffset(pin) ((pin & 31) / 16)
|
||||
#else
|
||||
#define _PM_byteOffset(pin) (3 - ((pin & 31) / 8))
|
||||
#define _PM_wordOffset(pin) (1 - ((pin & 31) / 16))
|
||||
#endif
|
||||
|
||||
// CircuitPython implementation is tied to a specific freq (but the counter
|
||||
|
|
@ -110,12 +128,14 @@ void _PM_IRQ_HANDLER(void) {
|
|||
_PM_row_handler(_PM_protoPtr); // In core.c
|
||||
}
|
||||
|
||||
#else
|
||||
#else // END CIRCUITPYTHON -------------------------------------------------
|
||||
|
||||
// Non-arduino byte offset macros, timer and ISR work go here.
|
||||
// Byte offset macros, timer and ISR work for other environments go here.
|
||||
|
||||
#endif
|
||||
|
||||
// CODE COMMON TO ALL ENVIRONMENTS -----------------------------------------
|
||||
|
||||
void _PM_timerInit(void *tptr) {
|
||||
static const struct {
|
||||
NRF_TIMER_Type *tc; // -> Timer peripheral base address
|
||||
|
|
|
|||
|
|
@ -1,8 +1,25 @@
|
|||
// CODE COMMON TO BOTH SAMD51 AND SAMD21 -----------------------------------
|
||||
/*!
|
||||
* @file samd-common.h
|
||||
*
|
||||
* Part of Adafruit's Protomatter library for HUB75-style RGB LED matrices.
|
||||
* This file contains SAMD-SPECIFIC CODE (SAMD51 & SAMD21).
|
||||
*
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Written by Phil "Paint Your Dragon" Burgess and Jeff Epler for
|
||||
* Adafruit Industries, with contributions from the open source community.
|
||||
*
|
||||
* BSD license, all text here must be included in any redistribution.
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(__SAMD51__) || defined(_SAMD21_)
|
||||
#pragma once
|
||||
|
||||
#if defined(ARDUINO)
|
||||
#if defined(__SAMD51__) || defined(SAMD51) || defined(_SAMD21_) || defined(SAMD21)
|
||||
|
||||
#if defined(ARDUINO) // COMPILING FOR ARDUINO ------------------------------
|
||||
|
||||
// g_APinDescription[] table and pin indices are Arduino specific:
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
|
|
@ -38,7 +55,7 @@ void _PM_IRQ_HANDLER(void) {
|
|||
_PM_row_handler(_PM_protoPtr); // In core.c
|
||||
}
|
||||
|
||||
#elif defined(CIRCUITPY)
|
||||
#elif defined(CIRCUITPY) // COMPILING FOR CIRCUITPYTHON --------------------
|
||||
|
||||
#include "hal_gpio.h"
|
||||
|
||||
|
|
@ -46,25 +63,22 @@ void _PM_IRQ_HANDLER(void) {
|
|||
#define _PM_pinInput(pin) gpio_set_pin_direction(pin, GPIO_DIRECTION_IN)
|
||||
#define _PM_pinHigh(pin) gpio_set_pin_level(pin, 1)
|
||||
#define _PM_pinLow(pin) gpio_set_pin_level(pin, 0)
|
||||
#define _PM_portBitMask(pin) (1u << ((pin) % 32))
|
||||
#define _PM_portBitMask(pin) (1u << ((pin) & 31))
|
||||
|
||||
#define _PM_byteOffset(pin) ((pin % 32) / 8)
|
||||
#define _PM_wordOffset(pin) ((pin % 32) / 16)
|
||||
|
||||
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
|
||||
#error SRSLY
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define _PM_byteOffset(pin) ((pin & 31) / 8)
|
||||
#define _PM_wordOffset(pin) ((pin & 31) / 16)
|
||||
#else
|
||||
#define _PM_byteOffset(pin) (3 - ((pin & 31) / 8))
|
||||
#define _PM_wordOffset(pin) (1 - ((pin & 31) / 16))
|
||||
#endif
|
||||
|
||||
// CircuitPython implementation is tied to a specific freq (but the counter
|
||||
// is dynamically allocated):
|
||||
#define _PM_timerFreq 48000000
|
||||
// Partly because IRQs must be declared at compile-time, and partly
|
||||
// because we know Arduino's already set up one of the GCLK sources
|
||||
// for 48 MHz.
|
||||
|
||||
// Because it's tied to a specific timer right now, there can be only
|
||||
// one instance of the Protomatter_core struct. The Arduino library
|
||||
// sets up this pointer when calling begin().
|
||||
// As currently implemented, there can be only one instance of the
|
||||
// Protomatter_core struct. This pointer is set up when starting the matrix.
|
||||
void *_PM_protoPtr = NULL;
|
||||
|
||||
// Timer interrupt service routine
|
||||
|
|
@ -74,10 +88,10 @@ void _PM_IRQ_HANDLER(void) {
|
|||
_PM_row_handler(_PM_protoPtr); // In core.c
|
||||
}
|
||||
|
||||
#else
|
||||
#else // END CIRCUITPYTHON -------------------------------------------------
|
||||
|
||||
// Other port byte offset macros, timer and ISR work go here.
|
||||
// Byte offset macros, timer and ISR work for other environments go here.
|
||||
|
||||
#endif
|
||||
|
||||
#endif // END __SAMD51__ || _SAMD21_
|
||||
#endif // END SAMD51/SAMD21
|
||||
|
|
|
|||
|
|
@ -1,8 +1,25 @@
|
|||
// SAMD21-SPECIFIC CODE ----------------------------------------------------
|
||||
/*!
|
||||
* @file samd21.h
|
||||
*
|
||||
* Part of Adafruit's Protomatter library for HUB75-style RGB LED matrices.
|
||||
* This file contains SAMD21-SPECIFIC CODE.
|
||||
*
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Written by Phil "Paint Your Dragon" Burgess and Jeff Epler for
|
||||
* Adafruit Industries, with contributions from the open source community.
|
||||
*
|
||||
* BSD license, all text here must be included in any redistribution.
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(_SAMD21_)
|
||||
#pragma once
|
||||
|
||||
#if defined(ARDUINO)
|
||||
#if defined(_SAMD21_) || defined(SAMD21) // Arduino, Circuitpy SAMD21 defs
|
||||
|
||||
#if defined(ARDUINO) // COMPILING FOR ARDUINO ------------------------------
|
||||
|
||||
// g_APinDescription[] table and pin indices are Arduino specific:
|
||||
#define _PM_portOutRegister(pin) \
|
||||
|
|
@ -17,12 +34,15 @@
|
|||
#define _PM_portToggleRegister(pin) \
|
||||
&PORT_IOBUS->Group[g_APinDescription[pin].ulPort].OUTTGL.reg
|
||||
|
||||
#else
|
||||
#else // END ARDUINO -------------------------------------------------------
|
||||
|
||||
// Non-Arduino port register lookups go here
|
||||
// Non-Arduino port register lookups go here, if not already declared
|
||||
// in samd-common.h.
|
||||
|
||||
#endif
|
||||
|
||||
// CODE COMMON TO ALL ENVIRONMENTS -----------------------------------------
|
||||
|
||||
// Initialize, but do not start, timer
|
||||
void _PM_timerInit(void *tptr) {
|
||||
static const struct {
|
||||
|
|
@ -127,4 +147,4 @@ inline uint32_t _PM_timerStop(void *tptr) {
|
|||
return count;
|
||||
}
|
||||
|
||||
#endif // END _SAMD21_
|
||||
#endif // END _SAMD21_ || SAMD21
|
||||
|
|
|
|||
|
|
@ -1,8 +1,25 @@
|
|||
// SAMD51-SPECIFIC CODE ----------------------------------------------------
|
||||
/*!
|
||||
* @file samd51.h
|
||||
*
|
||||
* Part of Adafruit's Protomatter library for HUB75-style RGB LED matrices.
|
||||
* This file contains SAMD51-SPECIFIC CODE.
|
||||
*
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Written by Phil "Paint Your Dragon" Burgess and Jeff Epler for
|
||||
* Adafruit Industries, with contributions from the open source community.
|
||||
*
|
||||
* BSD license, all text here must be included in any redistribution.
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(__SAMD51__)
|
||||
#pragma once
|
||||
|
||||
#if defined(ARDUINO)
|
||||
#if defined(__SAMD51__) || defined(SAMD51) // Arduino, Circuitpy SAMD51 defs
|
||||
|
||||
#if defined(ARDUINO) // COMPILING FOR ARDUINO ------------------------------
|
||||
|
||||
// g_APinDescription[] table and pin indices are Arduino specific:
|
||||
#define _PM_portOutRegister(pin) \
|
||||
|
|
@ -17,9 +34,7 @@
|
|||
#define _PM_portToggleRegister(pin) \
|
||||
&PORT->Group[g_APinDescription[pin].ulPort].OUTTGL.reg
|
||||
|
||||
#elif defined(CIRCUITPY)
|
||||
|
||||
#include "hal_gpio.h"
|
||||
#elif defined(CIRCUITPY) // COMPILING FOR CIRCUITPYTHON --------------------
|
||||
|
||||
#define _PM_portOutRegister(pin) (&PORT->Group[(pin / 32)].OUT.reg)
|
||||
|
||||
|
|
@ -29,12 +44,16 @@
|
|||
|
||||
#define _PM_portToggleRegister(pin) (&PORT->Group[(pin / 32)].OUTTGL.reg)
|
||||
|
||||
#define F_CPU (120000000)
|
||||
|
||||
#else
|
||||
|
||||
// Other port register lookups go here
|
||||
|
||||
#endif
|
||||
|
||||
// CODE COMMON TO ALL ENVIRONMENTS -----------------------------------------
|
||||
|
||||
// Initialize, but do not start, timer
|
||||
void _PM_timerInit(void *tptr) {
|
||||
static const struct {
|
||||
|
|
@ -193,4 +212,4 @@ uint32_t _PM_timerStop(void *tptr) {
|
|||
|
||||
#define _PM_minMinPeriod 160
|
||||
|
||||
#endif // END __SAMD51__
|
||||
#endif // END __SAMD51__ || SAMD51
|
||||
|
|
|
|||
|
|
@ -1,22 +1,42 @@
|
|||
// STM32F4xx SPECIFIC CODE -------------------------------------------------
|
||||
/*!
|
||||
* @file stm32.h
|
||||
*
|
||||
* Part of Adafruit's Protomatter library for HUB75-style RGB LED matrices.
|
||||
* This file contains STM32-SPECIFIC CODE.
|
||||
*
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Written by Phil "Paint Your Dragon" Burgess and Jeff Epler for
|
||||
* Adafruit Industries, with contributions from the open source community.
|
||||
*
|
||||
* BSD license, all text here must be included in any redistribution.
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(STM32F4_SERIES)
|
||||
#pragma once
|
||||
|
||||
#if defined(STM32F4_SERIES) || defined(STM32F405xx) // Arduino, CircuitPy
|
||||
|
||||
#if defined(ARDUINO) // COMPILING FOR ARDUINO ------------------------------
|
||||
|
||||
// Arduino port register lookups go here, else ones in arch.h are used.
|
||||
|
||||
#elif defined(CIRCUITPY) // COMPILING FOR CIRCUITPYTHON --------------------
|
||||
|
||||
#if defined(ARDUINO)
|
||||
// Arduino port register lookups go here
|
||||
#elif defined(CIRCUITPY)
|
||||
#include "timers.h"
|
||||
|
||||
#undef _PM_portBitMask
|
||||
#define _PM_portBitMask(pin) (1u << ((pin) % 16))
|
||||
#define _PM_byteOffset(pin) ((pin % 16) / 8)
|
||||
#define _PM_wordOffset(pin) ((pin % 16) / 16)
|
||||
#define _PM_portBitMask(pin) (1u << ((pin) & 15))
|
||||
#define _PM_byteOffset(pin) ((pin & 15) / 8)
|
||||
#define _PM_wordOffset(pin) ((pin & 15) / 16)
|
||||
|
||||
#define _PM_pinOutput(pin_) \
|
||||
do { \
|
||||
int8_t pin = (pin_); \
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0}; \
|
||||
GPIO_InitStruct.Pin = 1 << (pin % 16); \
|
||||
GPIO_InitStruct.Pin = 1 << (pin & 15); \
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; \
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL; \
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; \
|
||||
|
|
@ -26,16 +46,16 @@
|
|||
do { \
|
||||
int8_t pin = (pin_); \
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0}; \
|
||||
GPIO_InitStruct.Pin = 1 << (pin % 16); \
|
||||
GPIO_InitStruct.Pin = 1 << (pin & 15); \
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; \
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL; \
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; \
|
||||
HAL_GPIO_Init(pin_port(pin / 16), &GPIO_InitStruct); \
|
||||
} while (0)
|
||||
#define _PM_pinHigh(pin) \
|
||||
HAL_GPIO_WritePin(pin_port(pin / 16), 1 << (pin % 16), GPIO_PIN_SET)
|
||||
HAL_GPIO_WritePin(pin_port(pin / 16), 1 << (pin & 15), GPIO_PIN_SET)
|
||||
#define _PM_pinLow(pin) \
|
||||
HAL_GPIO_WritePin(pin_port(pin / 16), 1 << (pin % 16), GPIO_PIN_RESET)
|
||||
HAL_GPIO_WritePin(pin_port(pin / 16), 1 << (pin & 15), GPIO_PIN_RESET)
|
||||
|
||||
#define _PM_PORT_TYPE uint16_t
|
||||
|
||||
|
|
@ -116,6 +136,6 @@ uint32_t _PM_timerStop(void *tptr) {
|
|||
|
||||
#define _PM_minMinPeriod 140
|
||||
|
||||
#endif
|
||||
#endif // END CIRCUITPYTHON ------------------------------------------------
|
||||
|
||||
#endif // END STM32F4_SERIES
|
||||
#endif // END STM32F4_SERIES || STM32F405xx
|
||||
|
|
|
|||
|
|
@ -1,11 +1,28 @@
|
|||
// i.MX 1062-SPECIFIC CODE (Teensy 4.0, 4.1) -------------------------------
|
||||
/*!
|
||||
* @file teensy4.h
|
||||
*
|
||||
* Part of Adafruit's Protomatter library for HUB75-style RGB LED matrices.
|
||||
* This file contains i.MX 1062 (Teensy 4.x) SPECIFIC CODE.
|
||||
*
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Written by Phil "Paint Your Dragon" Burgess and Jeff Epler for
|
||||
* Adafruit Industries, with contributions from the open source community.
|
||||
*
|
||||
* BSD license, all text here must be included in any redistribution.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(__IMXRT1062__)
|
||||
|
||||
// i.MX only allows full 32-bit aligned writes to GPIO.
|
||||
#define _PM_STRICT_32BIT_IO ///< Change core.c behavior for long accesses only
|
||||
|
||||
#if defined(ARDUINO)
|
||||
#if defined(ARDUINO) // COMPILING FOR ARDUINO ------------------------------
|
||||
|
||||
static const struct {
|
||||
volatile uint32_t *base; ///< GPIO base address for pin
|
||||
|
|
@ -146,10 +163,10 @@ uint32_t _PM_timerStop(void *tptr) {
|
|||
|
||||
#define _PM_chunkSize 1 ///< DON'T unroll loop, Teensy 4 is SO FAST
|
||||
|
||||
#elif defined(CIRCUITPY)
|
||||
#elif defined(CIRCUITPY) // COMPILING FOR CIRCUITPYTHON --------------------
|
||||
|
||||
// Teensy 4 CircuitPython magic goes here.
|
||||
|
||||
#endif
|
||||
#endif // END CIRCUITPYTHON ------------------------------------------------
|
||||
|
||||
#endif // END __IMXRT1062__ (Teensy 4)
|
||||
|
|
|
|||
29
src/core.c
29
src/core.c
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
|
||||
// Device- and environment-neutral core matrix-driving functionality.
|
||||
// See notes near top of arch.h regarding assumptions of hardware
|
||||
// See notes near top of arch/arch.h regarding assumptions of hardware
|
||||
// "common ground." If you find yourself doing an "#ifdef ARDUINO" or
|
||||
// "#ifdef _SAMD21_" in this file, STOP. Idea is that the code in this
|
||||
// file is neutral and portable (within aforementioned assumptions).
|
||||
|
|
@ -128,15 +128,15 @@ ProtomatterStatus _PM_init(Protomatter_core *core, uint16_t bitWidth,
|
|||
// the pin bitmasks.
|
||||
|
||||
rgbCount *= 6; // Convert parallel count to pin count
|
||||
if ((core->rgbPins = (uint8_t *)_PM_ALLOCATOR(rgbCount * sizeof(uint8_t)))) {
|
||||
if ((core->addr = (_PM_pin *)_PM_ALLOCATOR(addrCount * sizeof(_PM_pin)))) {
|
||||
if ((core->rgbPins = (uint8_t *)_PM_allocate(rgbCount * sizeof(uint8_t)))) {
|
||||
if ((core->addr = (_PM_pin *)_PM_allocate(addrCount * sizeof(_PM_pin)))) {
|
||||
memcpy(core->rgbPins, rgbList, rgbCount * sizeof(uint8_t));
|
||||
for (uint8_t i = 0; i < addrCount; i++) {
|
||||
core->addr[i].pin = addrList[i];
|
||||
}
|
||||
return PROTOMATTER_OK;
|
||||
}
|
||||
_PM_FREE(core->rgbPins);
|
||||
_PM_free(core->rgbPins);
|
||||
core->rgbPins = NULL;
|
||||
}
|
||||
return PROTOMATTER_ERR_MALLOC;
|
||||
|
|
@ -223,9 +223,9 @@ ProtomatterStatus _PM_begin(Protomatter_core *core) {
|
|||
|
||||
// Allocate matrix buffer(s). Don't worry about the return type...
|
||||
// though we might be using words or longs for certain pin configs,
|
||||
// _PM_ALLOCATOR() by definition always aligns to the longest type.
|
||||
// _PM_allocate() by definition always aligns to the longest type.
|
||||
if (!(core->screenData =
|
||||
(uint8_t *)_PM_ALLOCATOR(screenBytes + rgbMaskBytes))) {
|
||||
(uint8_t *)_PM_allocate(screenBytes + rgbMaskBytes))) {
|
||||
return PROTOMATTER_ERR_MALLOC;
|
||||
}
|
||||
|
||||
|
|
@ -428,16 +428,16 @@ void _PM_resume(Protomatter_core *core) {
|
|||
}
|
||||
|
||||
// Free memory associated with core structure. Does NOT dealloc struct.
|
||||
void _PM_free(Protomatter_core *core) {
|
||||
void _PM_deallocate(Protomatter_core *core) {
|
||||
if ((core)) {
|
||||
_PM_stop(core);
|
||||
// TO DO: Set all pins back to inputs here?
|
||||
if (core->screenData)
|
||||
_PM_FREE(core->screenData);
|
||||
_PM_free(core->screenData);
|
||||
if (core->addr)
|
||||
_PM_FREE(core->addr);
|
||||
_PM_free(core->addr);
|
||||
if (core->rgbPins) {
|
||||
_PM_FREE(core->rgbPins);
|
||||
_PM_free(core->rgbPins);
|
||||
core->rgbPins = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -821,11 +821,11 @@ void _PM_swapbuffer_maybe(Protomatter_core *core) {
|
|||
}
|
||||
}
|
||||
|
||||
// CircuitPython happens to use the same internal canvas representation
|
||||
// This is all 565 stuff. No reason not to put it in a .c, right?
|
||||
|
||||
#if defined(ARDUINO) || defined(CIRCUITPY)
|
||||
|
||||
// Arduino and CircuitPython happen to use the same internal canvas
|
||||
// representation.
|
||||
|
||||
// 16-bit (565) color conversion functions go here (rather than in the
|
||||
// Arduino lib .cpp) because knowledge is required of chunksize and the
|
||||
// toggle register (or lack thereof), which are only known to this file,
|
||||
|
|
@ -1203,8 +1203,7 @@ void _PM_convert_565(Protomatter_core *core, uint16_t *source, uint16_t width) {
|
|||
}
|
||||
}
|
||||
|
||||
#endif // END ARDUINO || CIRCUITPYTHON
|
||||
|
||||
#endif // END ARDUINO || CIRCUITPY
|
||||
|
||||
// Note to future self: I've gone back and forth between implementing all
|
||||
// this either as it currently is (with byte, word and long cases for various
|
||||
|
|
|
|||
18
src/core.h
18
src/core.h
|
|
@ -189,7 +189,7 @@ extern void _PM_resume(Protomatter_core *core);
|
|||
deallocate the structure itself.
|
||||
@param core Pointer to Protomatter_core structure.
|
||||
*/
|
||||
extern void _PM_free(Protomatter_core *core);
|
||||
extern void _PM_deallocate(Protomatter_core *core);
|
||||
|
||||
/*!
|
||||
@brief Matrix "row handler" that's called by the timer interrupt.
|
||||
|
|
@ -236,6 +236,15 @@ extern uint32_t _PM_timerStop(void *tptr);
|
|||
*/
|
||||
extern uint32_t _PM_timerGetCount(void *tptr);
|
||||
|
||||
/*!
|
||||
@brief Pauses until the next vertical blank to avoid 'tearing' animation
|
||||
(if display is double-buffered). If single-buffered, has no effect.
|
||||
@param core Pointer to Protomatter_core structure.
|
||||
*/
|
||||
extern void _PM_swapbuffer_maybe(Protomatter_core *core);
|
||||
|
||||
#if defined(ARDUINO) || defined(CIRCUITPY)
|
||||
|
||||
/*!
|
||||
@brief Converts image data from GFX16 canvas to the matrices weird
|
||||
internal format.
|
||||
|
|
@ -248,12 +257,7 @@ extern uint32_t _PM_timerGetCount(void *tptr);
|
|||
extern void _PM_convert_565(Protomatter_core *core, uint16_t *source,
|
||||
uint16_t width);
|
||||
|
||||
/*!
|
||||
@brief Pauses until the next vertical blank to avoid 'tearing' animation
|
||||
(if display is double-buffered). If single-buffered, has no effect.
|
||||
@param core Pointer to Protomatter_core structure.
|
||||
*/
|
||||
extern void _PM_swapbuffer_maybe(Protomatter_core *core);
|
||||
#endif // END ARDUINO || CIRCUITPY
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
Loading…
Reference in a new issue