n/a
Fork of NeoStrip by
Revision 0:9f237b11f0a8, committed 2014-03-12
- Comitter:
- aswild
- Date:
- Wed Mar 12 18:36:58 2014 +0000
- Child:
- 1:f531a2be180d
- Commit message:
- Initial version
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NeoCore.s Wed Mar 12 18:36:58 2014 +0000 @@ -0,0 +1,218 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; NeoCore.s +; +; Allen Wild +; March 2014 +; +; ARM assembly functions for writing to Adafruit NeoPixels +; with the mbed NXP LPC1768 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + AREA neo_core, CODE, READONLY + + IMPORT neo_fio_reg + IMPORT neo_bitmask + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +neo_write_pin +; Set the GPIO pin to the value passed in R0 +; Registers and bitmasks are stored in variables set by the C++ library + LDR R1, =neo_fio_reg ; load pointers to register values + LDR R2, =neo_bitmask + LDR R1, [R1] ; load actual values from memory + LDR R2, [R2] + + CMP R0, #0 ; VALUE == 0 ? + ITE EQ ; (IF-THEN-ELSE) ON NEXT TWO INSTRUCTIONS USING "EQ" FLAG + STREQ R2, [R1,#0x1C] ; if==0, CLEAR BIT + STRNE R2, [R1,#0x18] ; if==1, SET BIT + BX LR + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +neo_zero +; Output a NeoPixel zero, composed of a short +; HIGH pulse and a long LOW pulse + PUSH {LR} + MOV R0, #1 + BL neo_write_pin ; set pin high + + MOV R0, #10 ; delay for long enough + BL neo_delay + + MOV R0, #0 ; set pin low + BL neo_write_pin + + MOV R0, #20 ; delay + BL neo_delay + + POP {LR} + BX LR + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +neo_one +; Output a NeoPixel one, composed of a long +; HIGH pulse and a short LOW pulse + PUSH {LR} + MOV R0, #1 + BL neo_write_pin + + MOV R0, #86 + BL neo_delay + + MOV R0, #0 + BL neo_write_pin + + NOP ; really short delay + NOP + NOP + + POP {LR} + BX LR + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + EXPORT neo_out ; void neo_out(int *data, int n); +; Main function called from the C++ library +; R0 contains a pointer to the array of color data to send +; R1 contains the number of bytes of data to send +neo_out + PUSH {LR, R4, R5, R6, R7, R8} + MOV R7, R1 ; move length to R7 + MOV R6, R0 ; move address to R6 + +neo_byteloop + LDRB R5, [R6] ; load byte to send + MOV R4, #0x80 ; load initial bitmask + +neo_bitloop + AND R3, R5, R4 ; mask current byte + CMP R3, #0 + BLEQ neo_zero ; send current bit + BLNE neo_one + + LSR R4, R4, #1 ; shift bitmask right one + CMP R4, #0 ; if still more bits, loop back + BNE neo_bitloop + + ADD R6, R6, #1 ; increment address + SUB R7, R7, #1 ; decrement count + CMP R7, #0 + BNE neo_byteloop ; continue if not done + + MOV R0, #0 + BL neo_write_pin + POP {R8, R7, R6, R5, R4, LR} + BX LR + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +neo_delay +; delay the specified number of cycles in R0 with a bunch of nops + LDR R2, =neo_delay_end + SUB R2, R2, R0 + BX R2 + 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 + 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 + 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 + NOP + NOP + NOP + NOP +neo_delay_end + BX LR + + END ; end code region + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NeoStrip.cpp Wed Mar 12 18:36:58 2014 +0000 @@ -0,0 +1,93 @@ +/********************************************** + * NeoStrip.cpp + * + * Allen Wild + * March 2014 + * + * Controls a strip of Adafruit NeoPixels, addressable RGB LEDs + * Currently, because of the global nature of the IO register and bitmask variables, + * it is only possible to use one NeoStrip instance at a time. + * + * This library supports only the NXP LPC1768! + */ + +#include "mbed.h" +#include "NeoStrip.h" + +// function to write to the strip, implemented in ARM assembly +extern "C" void neo_out(NeoColor*, int); + +// FastIO register address and bitmask for the GPIO pin +// because these are imported in the assembly +uint32_t neo_fio_reg; +uint32_t neo_bitmask; + +NeoStrip::NeoStrip(PinName pin, int N) : N(N) +{ + bright = 0.5; + Nbytes = N * 3; + strip = (NeoColor*)malloc(N * sizeof(NeoColor)); + if (strip == NULL) + { + printf("NeoStrip: ERROR unable to malloc strip data"); + N = 0; + } + + gpio_init(&gpio, pin, PIN_OUTPUT); // initialize GPIO registers + neo_fio_reg = (uint32_t)gpio.reg_dir; // set registers and bitmask for + neo_bitmask = 1 << ((int)pin & 0x1F); // the assembly to use +} + +void NeoStrip::setBrightness(float bright) +{ + this->bright = bright; +} + +void NeoStrip::setPixel(int p, int color) +{ + int red = (color & 0xFF0000) >> 16; + int green = (color & 0x00FF00) >> 8; + int blue = (color & 0x0000FF); + setPixel(p, red, green, blue); +} + +void NeoStrip::setPixel(int p, uint8_t red, uint8_t green, uint8_t blue) +{ + // set the given pixel's RGB values + // the array is indexed modulo N to avoid overflow + strip[p % N].red = (uint8_t)(red * bright); + strip[p % N].green = (uint8_t)(green * bright); + strip[p % N].blue = (uint8_t)(blue * bright); +} + +void NeoStrip::setPixels(int p, int n, const int *colors) +{ + int r, g, b; + for (int i = 0; i < n; i++) + { + r = (colors[i] & 0xFF0000) >> 16; + g = (colors[i] & 0x00FF00) >>8; + b = colors[i] & 0x0000FF; + setPixel(p+i, r, g, b); + } +} + +void NeoStrip::clear() +{ + for (int i = 0; i < N; i++) + { + strip[i].red = 0; + strip[i].green = 0; + strip[i].blue = 0; + } +} + +void NeoStrip::write() +{ + __disable_irq(); // disable interrupts + neo_out(strip, Nbytes); // output to the strip + __enable_irq(); // enable interrupts + wait_us(50); // wait 50us for the reset pulse +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NeoStrip.h Wed Mar 12 18:36:58 2014 +0000 @@ -0,0 +1,107 @@ +/** + * NeoStrip.h + * + * Allen Wild + * March 2014 + * + * Library for the control of Adafruit NeoPixel addressable RGB LEDs. + */ + + +#ifndef NEOSTRIP_H +#define NEOSTRIP_H + +#ifndef TARGET_LPC1768 +#error NeoStrip only supports the NXP LPC1768! +#endif + +// NeoColor struct definition to hold 24 bit +// color data for each pixel, in GRB order +typedef struct _NeoColor +{ + uint8_t green; + uint8_t red; + uint8_t blue; +} NeoColor; + +/** + * NeoStrip objects manage the buffering and assigning of + * addressable NeoPixels + */ +class NeoStrip +{ + public: + + /** + * Create a NeoStrip object + * + * @param pin The mbed data pin name + * @param N The number of pixels in the strip + */ + NeoStrip(PinName pin, int N); + + /** + * Set an overall brightness scale for the entire strip. + * When colors are set using setPixel(), they are scaled + * according to this brightness. + * + * Because NeoPixels are very bright and draw a lot of current, + * the brightness is set to 0.5 by default. + * + * @param bright The brightness scale between 0 and 1.0 + */ + void setBrightness(float bright); + + /** + * Set a single pixel to the specified color. + * + * This method (and all other setPixel methods) uses modulo-N arithmetic + * when addressing pixels. If p >= N, the pixel address will wrap around. + * + * @param p The pixel number (starting at 0) to set + * @param color A 24-bit color packed into a single int, + * using standard hex color codes (e.g. 0xFF0000 is red) + */ + void setPixel(int p, int color); + + /** + * Set a single pixel to the specified color, with red, green, and blue + * values in separate arguments. + */ + void setPixel(int p, uint8_t red, uint8_t green, uint8_t blue); + + /** + * Set n pixels starting at pixel p. + * + * @param p The first pixel in the strip to set. + * @param n The number of pixels to set. + * @param colors An array of length n containing the 24-bit colors for each pixel + */ + void setPixels(int p, int n, const int *colors); + + /** + * Reset all pixels in the strip to be of (0x000000) + */ + void clear(); + + /** + * Write the colors out to the strip; this method must be called + * to see any hardware effect. + * + * This function disables interrupts while the strip data is being sent, + * each pixel takes approximately 30us to send, plus a 50us reset pulse + * at the end. + */ + void write(); + + protected: + NeoColor *strip; // pixel data buffer modified by setPixel() and used by neo_out() + int N; // the number of pixels in the strip + int Nbytes; // the number of bytes of pixel data (always N*3) + float bright; // the master strip brightness + gpio_t gpio; // gpio struct for initialization and getting register addresses +}; + +#endif + +