Skip to content

Commit

Permalink
Start adding support for Apollo3 devices
Browse files Browse the repository at this point in the history
  • Loading branch information
csonsino committed Sep 9, 2019
1 parent 203e7bf commit 488347a
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 1 deletion.
23 changes: 22 additions & 1 deletion Adafruit_NeoPixel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,15 @@ extern "C" void espShow(
uint16_t pin, uint8_t *pixels, uint32_t numBytes, uint8_t type);
#endif // ESP8266

#if defined (AM_PART_APOLLO3)
extern "C" void apollo3UnsetPin(
uint16_t pin);
extern "C" void apollo3SetPin(
uint16_t pin);
extern "C" void apollo3Show(
uint16_t pin, uint8_t *pixels, uint32_t numBytes, uint8_t type);
#endif // AM_PART_APOLLO3

/*!
@brief Transmit pixel data in RAM to NeoPixels.
@note On most architectures, interrupts are temporarily disabled in
Expand Down Expand Up @@ -1700,6 +1709,10 @@ void Adafruit_NeoPixel::show(void) {
}
#endif

#elif defined (AM_PART_APOLLO3) // Apollo3

apollo3Show(pin, pixels, numBytes, is800KHz);

#elif defined (__SAMD51__) // M4

uint8_t *ptr, *end, p, bitMask, portNum, bit;
Expand Down Expand Up @@ -2163,8 +2176,16 @@ void Adafruit_NeoPixel::show(void) {
@param p Arduino pin number (-1 = no pin).
*/
void Adafruit_NeoPixel::setPin(uint16_t p) {
if(begun && (pin >= 0)) pinMode(pin, INPUT);
if(begun && (pin >= 0)) {
#if defined(AM_PART_APOLLO3)
apollo3UnsetPin(pin);
#endif
pinMode(pin, INPUT);
}
pin = p;
#if defined(AM_PART_APOLLO3)
apollo3SetPin(pin);
#endif
if(begun) {
pinMode(p, OUTPUT);
digitalWrite(p, LOW);
Expand Down
125 changes: 125 additions & 0 deletions apollo3.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// This provides the functionality for Apollo3 devices.

#if defined(AM_PART_APOLLO3)

#include <ap3_types.h>
#include <am_hal_gpio.h>

// The timing method used to control the NeoPixels
// TODO: Implement something better (interrupts, DMA, etc)
#define PIN_METHOD_FAST_GPIO

/*!
@brief Unset the NeoPixel output pin number.
@param p Arduino pin number (-1 = no pin).
*/
void apollo3UnsetPin(uint16_t pin) {
#if defined(PIN_METHOD_FAST_GPIO)
// Unconfigure the pin for Fast GPIO.
am_hal_gpio_fastgpio_disable(pin);
#endif
}

/*!
@brief Set the NeoPixel output pin number.
@param p Arduino pin number (-1 = no pin).
*/
void apollo3SetPin(uint16_t pin) {
#if defined(PIN_METHOD_FAST_GPIO)
// Configure the pin to be used for Fast GPIO.
am_hal_gpio_fastgpio_disable(pin);
am_hal_gpio_fastgpio_clr(pin);

am_hal_gpio_fast_pinconfig((uint64_t)0x1 << pin,
g_AM_HAL_GPIO_OUTPUT, 0);
// uint32_t ui32Ret = am_hal_gpio_fast_pinconfig((uint64_t)0x1 << pin,
// g_AM_HAL_GPIO_OUTPUT, 0);
// if (ui32Ret) {
// am_util_stdio_printf(
// "Error returned from am_hal_gpio_fast_pinconfig() = .\n", ui32Ret);
// }
#endif
}

// Note - The timings used below are based on the Arduino Zero,
// Gemma/Trinket M0 code.

/*!
@brief Transmit pixel data in RAM to NeoPixels.
@note The current design is a quick hack and should be replaced with
a more robust timing mechanism.
*/
void apollo3Show(
uint8_t pin, uint8_t *pixels, uint32_t numBytes, boolean is800KHz) {

uint8_t *ptr, *end, p, bitMask;
ptr = pixels;
end = ptr + numBytes;
p = *ptr++;
bitMask = 0x80;

#if defined(PIN_METHOD_FAST_GPIO)
#ifdef NEO_KHZ400 // 800 KHz check needed only if 400 KHz support enabled
if(is800KHz) {
#endif
for(;;) {
am_hal_gpio_fastgpio_set(pin);
//asm("nop; nop; nop; nop; nop; nop; nop; nop;");
asm("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;");
if(p & bitMask) {
asm("nop; nop; nop; nop; nop; nop; nop; nop;"
"nop; nop; nop; nop; nop; nop; nop; nop;"
"nop; nop; nop; nop;");
am_hal_gpio_fastgpio_clr(pin);
} else {
am_hal_gpio_fastgpio_clr(pin);
asm("nop; nop; nop; nop; nop; nop; nop; nop;"
"nop; nop; nop; nop; nop; nop; nop; nop;"
"nop; nop; nop; nop;");
}
if(bitMask >>= 1) {
asm("nop; nop; nop; nop; nop; nop; nop; nop; nop;");
} else {
if(ptr >= end) break;
p = *ptr++;
bitMask = 0x80;
}
}
#ifdef NEO_KHZ400
} else { // 400 KHz bitstream
// NOTE - These timings probably need to be tweaked
for(;;) {
am_hal_gpio_fastgpio_set(pin);
//asm("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;");
asm("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;");
if(p & bitMask) {
asm("nop; nop; nop; nop; nop; nop; nop; nop;"
"nop; nop; nop; nop; nop; nop; nop; nop;"
"nop; nop; nop; nop; nop; nop; nop; nop;"
"nop; nop; nop;");
am_hal_gpio_fastgpio_clr(pin);
} else {
am_hal_gpio_fastgpio_clr(pin);
asm("nop; nop; nop; nop; nop; nop; nop; nop;"
"nop; nop; nop; nop; nop; nop; nop; nop;"
"nop; nop; nop; nop; nop; nop; nop; nop;"
"nop; nop; nop;");
}
asm("nop; nop; nop; nop; nop; nop; nop; nop;"
"nop; nop; nop; nop; nop; nop; nop; nop;"
"nop; nop; nop; nop; nop; nop; nop; nop;"
"nop; nop; nop; nop; nop; nop; nop; nop;");
if(bitMask >>= 1) {
asm("nop; nop; nop; nop; nop; nop; nop;");
} else {
if(ptr >= end) break;
p = *ptr++;
bitMask = 0x80;
}
}
}
#endif // NEO_KHZ400
#endif // PIN_METHOD_FAST_GPIO
}

#endif // AM_PART_APOLLO3

0 comments on commit 488347a

Please sign in to comment.