First draft of neopixel
This commit is contained in:
parent
02c41b59bd
commit
8a124812b6
@ -12,6 +12,11 @@ namespace BufferMethods {
|
|||||||
ManagedBuffer(buf).setByte(off, v);
|
ManagedBuffer(buf).setByte(off, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//%
|
||||||
|
uint8_t *getBytes(Buffer buf) {
|
||||||
|
return buf->payload;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the length of a Buffer object. */
|
/** Returns the length of a Buffer object. */
|
||||||
//% property
|
//% property
|
||||||
int length(Buffer s) {
|
int length(Buffer s) {
|
||||||
|
20
libs/neopixel/kind.json
Normal file
20
libs/neopixel/kind.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "neppixel",
|
||||||
|
"description": "AdaFruit NeoPixel driver for micro:bit",
|
||||||
|
"files": [
|
||||||
|
"neopixel.ts",
|
||||||
|
"sendbuffer.asm"
|
||||||
|
],
|
||||||
|
"testFiles": [
|
||||||
|
"neotest.ts"
|
||||||
|
],
|
||||||
|
"microbit": {
|
||||||
|
"config": {
|
||||||
|
"MICROBIT_BLE_ENABLED": "0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"public": true,
|
||||||
|
"dependencies": {
|
||||||
|
"microbit": "file:../microbit"
|
||||||
|
}
|
||||||
|
}
|
88
libs/neopixel/neopixel.ts
Normal file
88
libs/neopixel/neopixel.ts
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
namespace neopixel {
|
||||||
|
|
||||||
|
//% shim=sendBufferAsm
|
||||||
|
function sendBuffer(buf: Buffer, pin: DigitalPin) {
|
||||||
|
}
|
||||||
|
|
||||||
|
class Strip {
|
||||||
|
buf: Buffer;
|
||||||
|
pin: DigitalPin;
|
||||||
|
brightness: number;
|
||||||
|
|
||||||
|
length() {
|
||||||
|
return this.buf.length / 3
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the brightness of the strip, 0-255.
|
||||||
|
*/
|
||||||
|
setBrigthness(brightness: number): void {
|
||||||
|
this.brightness = brightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the pin where the neopixel is connected, defaults to P0.
|
||||||
|
*/
|
||||||
|
setPin(pin: DigitalPin): void {
|
||||||
|
this.pin = pin;
|
||||||
|
pins.digitalWritePin(this.pin, 0)
|
||||||
|
basic.pause(50)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn off all LEDs.
|
||||||
|
*/
|
||||||
|
clear(): void {
|
||||||
|
this.buf.fill(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shift LEDs forward.
|
||||||
|
*/
|
||||||
|
shift(off: number): void {
|
||||||
|
this.buf.shift(-off * 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shift LEDs forward.
|
||||||
|
*/
|
||||||
|
rotate(): void {
|
||||||
|
this.buf.rotate(-3)
|
||||||
|
}
|
||||||
|
|
||||||
|
display() {
|
||||||
|
basic.pause(1)
|
||||||
|
sendBuffer(this.buf, this.pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set give LED to a given color (range 0-255 for r, g, b)
|
||||||
|
*/
|
||||||
|
setPix(ledoff: number, r: number, g: number, b: number): void {
|
||||||
|
ledoff = ledoff * 3;
|
||||||
|
let br = this.brightness;
|
||||||
|
if (br < 255) {
|
||||||
|
r = (Math.clamp(0, 255, r) * br) >> 8;
|
||||||
|
g = (Math.clamp(0, 255, b) * br) >> 8;
|
||||||
|
b = (Math.clamp(0, 255, b) * br) >> 8;
|
||||||
|
}
|
||||||
|
let buf = this.buf;
|
||||||
|
buf[ledoff + 0] = Math.clamp(0, 255, g);
|
||||||
|
buf[ledoff + 1] = Math.clamp(0, 255, r);
|
||||||
|
buf[ledoff + 2] = Math.clamp(0, 255, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new NeoPixel driver for `numleds` LEDs.
|
||||||
|
* @params numleds number of leds in the strip, eg: 24,30,60,64
|
||||||
|
*/
|
||||||
|
export function create(numleds: number): Strip {
|
||||||
|
let strip = new Strip();
|
||||||
|
strip.buf = pins.createBuffer(numleds * 3);
|
||||||
|
strip.setBrigthness(255)
|
||||||
|
strip.setPin(DigitalPin.P0)
|
||||||
|
return strip;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
92
libs/neopixel/neotest.ts
Normal file
92
libs/neopixel/neotest.ts
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
basic.showLeds(`
|
||||||
|
# . . . .
|
||||||
|
. . . . .
|
||||||
|
. . # . .
|
||||||
|
. . . . .
|
||||||
|
. . . . #
|
||||||
|
`)
|
||||||
|
console.log("Start")
|
||||||
|
|
||||||
|
// Create a NeoPixel driver - specify the number of LEDs:
|
||||||
|
let strip = neopixel.create(24);
|
||||||
|
|
||||||
|
// If your strip is not at P0, specify the pin.
|
||||||
|
strip.setPin(DigitalPin.P0)
|
||||||
|
|
||||||
|
// Brightness defaults to 255 (very bright); 0 is completely off.
|
||||||
|
strip.setBrigthness(20)
|
||||||
|
|
||||||
|
// Set pixels - pixel number, followed by red, green and blue values, between 0 and 255.
|
||||||
|
strip.setPix(0, 255, 255, 255);
|
||||||
|
strip.setPix(1, 0, 255, 255);
|
||||||
|
strip.setPix(2, 255, 0, 255);
|
||||||
|
strip.setPix(3, 255, 255, 0);
|
||||||
|
|
||||||
|
console.log("Send!")
|
||||||
|
|
||||||
|
// Send the image to the strip.
|
||||||
|
strip.display();
|
||||||
|
basic.pause(500);
|
||||||
|
|
||||||
|
console.log("Sent!")
|
||||||
|
|
||||||
|
// Green light travelling the strip:
|
||||||
|
for (let l = 0; l < strip.length(); l++) {
|
||||||
|
strip.clear();
|
||||||
|
strip.setPix(l, 0, 255, 0);
|
||||||
|
strip.display();
|
||||||
|
basic.pause(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
let special = false;
|
||||||
|
let numcol = 0;
|
||||||
|
input.onButtonPressed(Button.A, () => {
|
||||||
|
special = true;
|
||||||
|
let r = 0;
|
||||||
|
let g = 0;
|
||||||
|
let b = 0;
|
||||||
|
if (numcol == 0) {
|
||||||
|
r = 255;
|
||||||
|
g = 255;
|
||||||
|
b = 255;
|
||||||
|
} else if (numcol == 1) {
|
||||||
|
r = 255;
|
||||||
|
} else if (numcol == 2) {
|
||||||
|
b = 255;
|
||||||
|
} else if (numcol == 3) {
|
||||||
|
r = 255;
|
||||||
|
g = 255;
|
||||||
|
} else if (numcol == 4) {
|
||||||
|
r = 10;
|
||||||
|
g = 10;
|
||||||
|
b = 10;
|
||||||
|
}
|
||||||
|
numcol = (numcol + 1) % 5;
|
||||||
|
for (let k = 0; k < 7; k++) {
|
||||||
|
strip.setPix(k, r, g, b);
|
||||||
|
}
|
||||||
|
strip.display();
|
||||||
|
});
|
||||||
|
|
||||||
|
control.inBackground(() => {
|
||||||
|
for (let j = 0; j < 2000000; j++) {
|
||||||
|
if (special) {
|
||||||
|
basic.pause(100);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let r1 = (0 + j * 2) & 63;
|
||||||
|
let g1 = (20 + j * 1) & 63;
|
||||||
|
let b1 = (30 + j * 3) & 63;
|
||||||
|
for (let i = 0; i < strip.length(); i++) {
|
||||||
|
strip.setPix(i, (r1 - i) * 20, (g1 - i) * 20, (b1 - i) * 20);
|
||||||
|
}
|
||||||
|
strip.display()
|
||||||
|
basic.pause(60);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
control.inBackground(() => {
|
||||||
|
while (true) {
|
||||||
|
basic.showString("XMAS!", 150);
|
||||||
|
}
|
||||||
|
});
|
62
libs/neopixel/sendbuffer.asm
Normal file
62
libs/neopixel/sendbuffer.asm
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
push {r4,r5,r6,r7,lr}
|
||||||
|
|
||||||
|
mov r4, r0 ; save buff
|
||||||
|
mov r6, r1 ; save pin
|
||||||
|
|
||||||
|
mov r0, r4
|
||||||
|
bl buffer::count
|
||||||
|
mov r5, r0
|
||||||
|
|
||||||
|
mov r0, r4
|
||||||
|
bl buffer::cptr
|
||||||
|
mov r4, r0
|
||||||
|
|
||||||
|
; setup pin as digital
|
||||||
|
mov r0, r6
|
||||||
|
movs r1, #0
|
||||||
|
bl micro_bit::digitalWritePin
|
||||||
|
|
||||||
|
; load pin address
|
||||||
|
mov r0, r6
|
||||||
|
|
||||||
|
ldr r0, [r0, #8] ; get mbed DigitalOut from MicroBitPin
|
||||||
|
ldr r1, [r0, #4] ; r1-mask for this pin
|
||||||
|
ldr r2, [r0, #16] ; r2-clraddr
|
||||||
|
ldr r3, [r0, #12] ; r3-setaddr
|
||||||
|
|
||||||
|
cpsid i ; disable irq
|
||||||
|
|
||||||
|
b .start
|
||||||
|
|
||||||
|
.nextbit: ; C0
|
||||||
|
str r1, [r3, #0] ; pin := hi C2
|
||||||
|
tst r6, r0 ; C3
|
||||||
|
bne .islate ; C4
|
||||||
|
str r1, [r2, #0] ; pin := lo C6
|
||||||
|
.islate:
|
||||||
|
lsrs r6, r6, #1 ; r6 >>= 1 C7
|
||||||
|
bne .justbit ; C8
|
||||||
|
|
||||||
|
; not just a bit - need new byte
|
||||||
|
adds r4, #1 ; r4++ C9
|
||||||
|
subs r5, #1 ; r5-- C10
|
||||||
|
bcc .stop ; if (r5<0) goto .stop C11
|
||||||
|
.start:
|
||||||
|
movs r6, #0x80 ; reset mask C12
|
||||||
|
nop ; C13
|
||||||
|
|
||||||
|
.common: ; C13
|
||||||
|
str r1, [r2, #0] ; pin := lo C15
|
||||||
|
; always re-load byte - it just fits with the cycles better this way
|
||||||
|
ldrb r0, [r4, #0] ; r0 := *r4 C17
|
||||||
|
b .nextbit ; C20
|
||||||
|
|
||||||
|
.justbit: ; C10
|
||||||
|
; no nops, branch taken is already 3 cycles
|
||||||
|
b .common ; C13
|
||||||
|
|
||||||
|
.stop:
|
||||||
|
str r1, [r2, #0] ; pin := lo
|
||||||
|
cpsie i ; enable irq
|
||||||
|
|
||||||
|
pop {r4,r5,r6,r7,pc}
|
Loading…
Reference in New Issue
Block a user