66#define MIN(a,b) ((a)<(b)?(a):(b))
70#define MAX(a,b) ((a)>(b)?(a):(b))
75volatile uint32_t framebuffer_index = 0;
88volatile bool dma_first;
92 const uint8_t *pinList, uint8_t serpentine) {
96 if (numPins > NUM_DIGITAL_PINS) numPins = NUM_DIGITAL_PINS;
100 if ((
params & 0x3F) < 6) {
115extern "C" void xbar_connect(
unsigned int input,
unsigned int output);
116static volatile uint32_t *standard_gpio_addr(
volatile uint32_t *fastgpio) {
117 return (
volatile uint32_t *)((uint32_t)fastgpio - 0x01E48000);
134void ObjectFLED::begin(uint16_t period, uint16_t t0h, uint16_t t1h, uint16_t latchDelay) {
150 for (uint32_t i=0; i <
numpins; i++) {
152 if (pin >= NUM_DIGITAL_PINS)
continue;
153 uint8_t bit = digitalPinToBit(pin);
155 uint8_t offset = ((uint32_t)portOutputRegister(pin) - (uint32_t)&GPIO6_DR) >> 14;
156 if (offset > 3)
continue;
159 uint32_t mask = 1 << bit;
162 *portControlRegister(pin) &= ~0xF9;
166 *(&IOMUXC_GPR_GPR26 + offset) &= ~mask;
167 *standard_gpio_addr(portModeRegister(pin)) |= mask;
179 comp1load[2] = (uint16_t)((
float)F_BUS_ACTUAL / 1000000000.0 * (
float)
T1H / (1.0 + ((
OC_FACTOR - 1.0)/3)) );
181 TMR4_SCTRL0 = TMR_SCTRL_OEN | TMR_SCTRL_FORCE | TMR_SCTRL_MSTR;
182 TMR4_CSCTRL0 = TMR_CSCTRL_CL1(1) | TMR_CSCTRL_TCF1EN;
187 TMR4_CTRL0 = TMR_CTRL_CM(1) | TMR_CTRL_PCS(8) | TMR_CTRL_LENGTH | TMR_CTRL_OUTMODE(3);
188 TMR4_SCTRL1 = TMR_SCTRL_OEN | TMR_SCTRL_FORCE;
193 TMR4_CTRL1 = TMR_CTRL_CM(1) | TMR_CTRL_PCS(8) | TMR_CTRL_COINIT | TMR_CTRL_OUTMODE(3);
194 TMR4_SCTRL2 = TMR_SCTRL_OEN | TMR_SCTRL_FORCE;
199 TMR4_CTRL2 = TMR_CTRL_CM(1) | TMR_CTRL_PCS(8) | TMR_CTRL_COINIT | TMR_CTRL_OUTMODE(3);
202 CCM_CCGR2 |= CCM_CCGR2_XBAR1(CCM_CCGR_ON);
203 xbar_connect(XBARA1_IN_QTIMER4_TIMER0, XBARA1_OUT_DMA_CH_MUX_REQ30);
204 xbar_connect(XBARA1_IN_QTIMER4_TIMER1, XBARA1_OUT_DMA_CH_MUX_REQ31);
205 xbar_connect(XBARA1_IN_QTIMER4_TIMER2, XBARA1_OUT_DMA_CH_MUX_REQ94);
206 XBARA1_CTRL0 = XBARA_CTRL_STS1 | XBARA_CTRL_EDGE1(3) | XBARA_CTRL_DEN1 |
207 XBARA_CTRL_STS0 | XBARA_CTRL_EDGE0(3) | XBARA_CTRL_DEN0;
208 XBARA1_CTRL1 = XBARA_CTRL_STS0 | XBARA_CTRL_EDGE0(3) | XBARA_CTRL_DEN0;
216 dma1.TCD->ATTR = DMA_TCD_ATTR_SSIZE(3) | DMA_TCD_ATTR_SMOD(4) | DMA_TCD_ATTR_DSIZE(2);
217 dma1.TCD->NBYTES_MLOFFYES = DMA_TCD_NBYTES_DMLOE |
218 DMA_TCD_NBYTES_MLOFFYES_MLOFF(-65536) |
219 DMA_TCD_NBYTES_MLOFFYES_NBYTES(16);
221 dma1.TCD->DADDR = &GPIO1_DR_SET;
222 dma1.TCD->DOFF = 16384;
224 dma1.TCD->DLASTSGA = -65536;
226 dma1.TCD->CSR = DMA_TCD_CSR_DREQ;
227 dma1.triggerAtHardwareEvent(DMAMUX_SOURCE_XBAR1_0);
231 dma2next.TCD->ATTR = DMA_TCD_ATTR_SSIZE(3) | DMA_TCD_ATTR_DSIZE(2);
232 dma2next.TCD->NBYTES_MLOFFYES = DMA_TCD_NBYTES_DMLOE |
233 DMA_TCD_NBYTES_MLOFFYES_MLOFF(-65536) |
234 DMA_TCD_NBYTES_MLOFFYES_NBYTES(16);
236 dma2next.TCD->DADDR = &GPIO1_DR_CLEAR;
245 dma2.triggerAtHardwareEvent(DMAMUX_SOURCE_XBAR1_1);
251 dma3.TCD->ATTR = DMA_TCD_ATTR_SSIZE(3) | DMA_TCD_ATTR_SMOD(4) | DMA_TCD_ATTR_DSIZE(2);
252 dma3.TCD->NBYTES_MLOFFYES = DMA_TCD_NBYTES_DMLOE |
253 DMA_TCD_NBYTES_MLOFFYES_MLOFF(-65536) |
254 DMA_TCD_NBYTES_MLOFFYES_NBYTES(16);
256 dma3.TCD->DADDR = &GPIO1_DR_CLEAR;
257 dma3.TCD->DOFF = 16384;
259 dma3.TCD->DLASTSGA = -65536;
261 dma3.TCD->CSR = DMA_TCD_CSR_DREQ | DMA_TCD_CSR_DONE;
262 dma3.triggerAtHardwareEvent(DMAMUX_SOURCE_XBAR1_2);
270void fillbits(uint32_t *dest,
const uint8_t *pixels,
int n, uint32_t mask) {
272 uint8_t pix = *pixels++;
273 if (!(pix & 0x80)) *dest |= mask;
275 if (!(pix & 0x40)) *dest |= mask;
277 if (!(pix & 0x20)) *dest |= mask;
279 if (!(pix & 0x10)) *dest |= mask;
281 if (!(pix & 0x08)) *dest |= mask;
283 if (!(pix & 0x04)) *dest |= mask;
285 if (!(pix & 0x02)) *dest |= mask;
287 if (!(pix & 0x01)) *dest |= mask;
358 if (i % (serp * 4) == 0) {
359 if (jChange < 0) { j = i / 4 * 3; jChange = 3; }
360 else { j = (i / 4 + serp - 1) * 3; jChange = -3; }
371 if (i % (serp * 3) == 0) {
372 if (jChange < 0) { j = i; jChange = 3; }
373 else { j = i + (serp - 1) * 3; jChange = -3; }
383 if (i % (serp * 3) == 0) {
384 if (jChange < 0) { j = i; jChange = 3; }
385 else { j = i + (serp - 1) * 3; jChange = -3; }
395 if (i % (serp * 3) == 0) {
396 if (jChange < 0) { j = i; jChange = 3; }
397 else { j = i + (serp - 1) * 3; jChange = -3; }
407 if (i % (serp * 3) == 0) {
408 if (jChange < 0) { j = i; jChange = 3; }
409 else { j = i + (serp - 1) * 3; jChange = -3; }
420 if (i % (serp * 3) == 0) {
421 if (jChange < 0) { j = i; jChange = 3; }
422 else { j = i + (serp - 1) * 3; jChange = -3; }
468 uint16_t enable = TMR4_ENBL;
469 TMR4_ENBL = enable & ~7;
472 TMR4_SCTRL0 = TMR_SCTRL_OEN | TMR_SCTRL_FORCE | TMR_SCTRL_MSTR;
473 TMR4_SCTRL1 = TMR_SCTRL_OEN | TMR_SCTRL_FORCE;
474 TMR4_SCTRL2 = TMR_SCTRL_OEN | TMR_SCTRL_FORCE;
477 XBARA1_CTRL0 |= XBARA_CTRL_STS1 | XBARA_CTRL_STS0;
478 XBARA1_CTRL1 |= XBARA_CTRL_STS0;
484 framebuffer_index = count;
487 for (uint32_t i=0; i <
numpins; i++) {
491 arm_dcache_flush_delete(
bitdata, count * 128);
496 dma2.TCD->DADDR = &GPIO1_DR_CLEAR;
497 dma2.TCD->CITER_ELINKNO = count * 8;
498 dma2.TCD->CSR = DMA_TCD_CSR_DREQ;
501 dma2.TCD->DADDR = &GPIO1_DR_CLEAR;
504 dma2.TCD->CSR = DMA_TCD_CSR_INTMAJOR | DMA_TCD_CSR_ESG;
508 dma2next.TCD->CSR = DMA_TCD_CSR_ESG;
510 dma2next.TCD->CSR = DMA_TCD_CSR_ESG | DMA_TCD_CSR_INTMAJOR;
514 dma3.clearComplete();
528 TMR4_ENBL = enable | 7;
539 dma2.clearInterrupt();
551 memset(dest, 0,
sizeof(
bitdata)/2);
552 uint32_t index = framebuffer_index;
553 uint32_t count =
numbytes - framebuffer_index;
555 framebuffer_index = index + count;
556 for (
int i=0; i <
numpins; i++) {
560 arm_dcache_flush_delete(dest, count * 128);
565 dma2next.TCD->CITER_ELINKNO = count * 8;
566 uint32_t remain =
numbytes - (index + count);
568 dma2next.TCD->CSR = DMA_TCD_CSR_DREQ;
570 dma2next.TCD->CSR = DMA_TCD_CSR_ESG;
572 dma2next.TCD->CSR = DMA_TCD_CSR_ESG | DMA_TCD_CSR_INTMAJOR;
604 for (uint32_t
x = 0;
x < count * 3;
x += 3) {
606 *((uint8_t*)
leds +
x) = (( *((uint8_t*)
leds +
x) * (1 + (255 - fadeAmt))) >> 8) + \
607 (( ((color >> 16) & 0xFF) * (1 + fadeAmt)) >> 8);
609 *((uint8_t*)
leds +
x + 1) = (( *((uint8_t*)
leds +
x + 1) * (1 + (255 - fadeAmt))) >> 8) + \
610 (( ((color >> 8) & 0xFF) * (1 + fadeAmt)) >> 8);
612 *((uint8_t*)
leds +
x + 2) = (( *((uint8_t*)
leds +
x + 2) * (1 + (255 - fadeAmt))) >> 8) + \
613 (( (color & 0xFF) * (1 + fadeAmt)) >> 8);
619void drawSquare(
void*
leds, uint16_t planeY, uint16_t planeX,
int yCorner,
int xCorner, uint32_t size, uint32_t color) {
620 if (size != 0) { size--; }
622 for (
int x = xCorner;
x <= xCorner + (int)size;
x++) {
624 if ((
x >= 0) && (
x < planeX)) {
625 if ((yCorner >= 0) && (yCorner < planeY)) {
626 *((uint8_t*)
leds + (yCorner * planeX +
x) * 3) = ((color >> 16) & 0xFF);
627 *((uint8_t*)
leds + (yCorner * planeX +
x) * 3 + 1) = ((color >> 8) & 0xFF);
628 *((uint8_t*)
leds + (yCorner * planeX +
x) * 3 + 2) = (color & 0xFF);
630 if ((yCorner + size >= 0) && (yCorner + size < planeY)) {
631 *((uint8_t*)
leds + ((yCorner + size) * planeX +
x) * 3) = ((color >> 16) & 0xFF);
632 *((uint8_t*)
leds + ((yCorner + size) * planeX +
x) * 3 + 1) = ((color >> 8) & 0xFF);
633 *((uint8_t*)
leds + ((yCorner + size) * planeX +
x) * 3 + 2) = (color & 0xFF);
637 for (
int y = yCorner;
y <= yCorner + (int)size;
y++) {
638 if ((
y >= 0) && (
y < planeY)) {
639 if ((xCorner >= 0) && (xCorner < planeX)) {
640 *((uint8_t*)
leds + (xCorner +
y * planeX) * 3) = ((color >> 16) & 0xFF);
641 *((uint8_t*)
leds + (xCorner +
y * planeX) * 3 + 1) = ((color >> 8) & 0xFF);
642 *((uint8_t*)
leds + (xCorner +
y * planeX) * 3 + 2) = (color & 0xFF);
644 if ((xCorner + size >= 0) && (xCorner + size < planeX)) {
645 *((uint8_t*)
leds + (xCorner + size +
y * planeX) * 3) = ((color >> 16) & 0xFF);
646 *((uint8_t*)
leds + (xCorner + size +
y * planeX) * 3 + 1) = ((color >> 8) & 0xFF);
647 *((uint8_t*)
leds + (xCorner + size +
y * planeX) * 3 + 2) = (color & 0xFF);
uint8_t * frameBufferLocal
uint8_t pin_bitnumLocal[NUM_DIGITAL_PINS]
uint8_t pinlist[NUM_DIGITAL_PINS]
uint32_t update_begin_micros
void setBalance(uint32_t)
static DMAMEM uint32_t bitdata[BYTES_PER_DMA *64]
void genFrameBuffer(uint32_t)
ObjectFLED(uint16_t numLEDs, void *drawBuf, uint8_t config, uint8_t numPins, const uint8_t *pinList, uint8_t serpentine=0)
static DMAMEM uint32_t bitmask[4]
void waitForDmaToFinish()
static DMASetting dma2next
void setBrightness(uint8_t)
static uint8_t pin_bitnum[NUM_DIGITAL_PINS]
static uint8_t * frameBuffer
static uint8_t pin_offset[NUM_DIGITAL_PINS]
uint8_t pin_offsetLocal[NUM_DIGITAL_PINS]
void drawSquare(void *, uint16_t, uint16_t, int, int, uint32_t, uint32_t)
void fadeToColorBy(void *, uint16_t, uint32_t, uint8_t)
Implements a simple red square effect for 2D LED grids.