Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial Apollo3 Implementation #205

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion Adafruit_NeoPixel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1700,6 +1700,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 @@ -2210,7 +2214,18 @@ 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)
// The pin has been mapped to the Apollo3 pad
apollo3UnsetPad(pin);
#endif
pinMode(pin, INPUT);
}
#if defined(AM_PART_APOLLO3)
// Map the specified pin to the Apollo3 pad
p = ap3_gpio_pin2pad(p);
apollo3SetPad(p);
#endif
pin = p;
if(begun) {
pinMode(p, OUTPUT);
Expand Down
6 changes: 6 additions & 0 deletions Adafruit_NeoPixel.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,12 @@ class Adafruit_NeoPixel {

protected:

#if defined (AM_PART_APOLLO3)
void apollo3UnsetPad(ap3_gpio_pad_t pad);
void apollo3SetPad(ap3_gpio_pad_t pad);
void apollo3Show(ap3_gpio_pad_t pad, uint8_t *pixels, uint32_t numBytes, boolean is800KHz);
#endif // AM_PART_APOLLO3

#ifdef NEO_KHZ400 // If 400 KHz NeoPixel support enabled...
boolean is800KHz; ///< true if 800 KHz pixels
#endif
Expand Down
135 changes: 135 additions & 0 deletions apollo3.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// This provides the functionality for Apollo3 devices.

#if defined(AM_PART_APOLLO3)

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

#include "Adafruit_NeoPixel.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 pad number.
@param pad Apollo3 pad number
*/
void Adafruit_NeoPixel::apollo3UnsetPad(ap3_gpio_pad_t pad) {
#if defined(PIN_METHOD_FAST_GPIO)
// Unconfigure the pad for Fast GPIO.
am_hal_gpio_fastgpio_disable(pad);
#endif
}

/*!
@brief Set the NeoPixel output pad number.
@param pad Apollo3 pad number
*/
void Adafruit_NeoPixel::apollo3SetPad(ap3_gpio_pad_t pad) {
#if defined(PIN_METHOD_FAST_GPIO)
// Configure the pad to be used for Fast GPIO.
am_hal_gpio_fastgpio_disable(pad);
am_hal_gpio_fastgpio_clr(pad);

am_hal_gpio_fast_pinconfig((uint64_t)0x1 << pad,
g_AM_HAL_GPIO_OUTPUT, 0);
// uint32_t ui32Ret = am_hal_gpio_fast_pinconfig((uint64_t)0x1 << pad,
// 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 Adafruit_NeoPixel::apollo3Show(
ap3_gpio_pad_t pad, 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)

// disable interrupts
am_hal_interrupt_master_disable();

#ifdef NEO_KHZ400 // 800 KHz check needed only if 400 KHz support enabled
if(is800KHz) {
#endif
for(;;) {
am_hal_gpio_fastgpio_set(pad);
//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(pad);
} else {
am_hal_gpio_fastgpio_clr(pad);
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 may need to be tweaked
for(;;) {
am_hal_gpio_fastgpio_set(pad);
//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(pad);
} else {
am_hal_gpio_fastgpio_clr(pad);
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;
}
}
}

// re-enable interrupts
am_hal_interrupt_master_enable();

#endif // NEO_KHZ400
#endif // PIN_METHOD_FAST_GPIO
}

#endif // AM_PART_APOLLO3