Compare commits

...

16 Commits

Author SHA1 Message Date
46d42e5300 0.2.17 2016-04-04 19:13:35 -07:00
ffabb9b16d Bump kindscript to 0.2.19 2016-04-04 19:13:34 -07:00
d62c10d278 Use the improved default parameters 2016-04-04 19:11:33 -07:00
e2b2aa7ff1 0.2.16 2016-04-04 19:04:04 -07:00
664c8dcd35 Bump kindscript to 0.2.18 2016-04-04 19:04:03 -07:00
bd7430b642 Add Buffer.get/setNumber and i2c methods 2016-04-04 19:02:40 -07:00
61fd28d840 Move all target stuff to kindtarget.json 2016-04-04 18:03:52 -07:00
c33df897d5 Remove unused code 2016-04-04 12:56:57 -07:00
3bb0bd2a9f 0.2.15 2016-04-04 09:50:05 -07:00
7751061b51 Bump kindscript to 0.2.17 2016-04-04 09:50:04 -07:00
88a7fa5038 0.2.14 2016-04-03 17:51:51 -07:00
3c8a62df54 Bump kindscript to 0.2.16 2016-04-03 17:51:50 -07:00
c661fd0eca Neopixel seems to work 2016-04-03 17:49:35 -07:00
8a124812b6 First draft of neopixel 2016-04-03 17:38:50 -07:00
02c41b59bd Add Buffer; go to core v0.1.5 2016-04-03 16:52:57 -07:00
b003af6eae Try to fix travis 2016-04-02 21:49:09 -07:00
20 changed files with 740 additions and 171 deletions

View File

@ -3,7 +3,7 @@ node_js:
- "5.7.0" - "5.7.0"
script: script:
- "node node_modules/kindscript/built/kind.js travis" - "node node_modules/kindscript/built/kind.js travis"
- "cd libs/lang-test0; node ../../node_modules/kindscript/built/kind.js run" - "(cd libs/lang-test0; node ../../node_modules/kindscript/built/kind.js run)"
- "node node_modules/kindscript/built/kind.js uploaddoc" - "node node_modules/kindscript/built/kind.js uploaddoc"
sudo: false sudo: false
notifications: notifications:

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -6,6 +6,7 @@
], ],
"public": true, "public": true,
"dependencies": { "dependencies": {
"microbit": "file:../microbit" "microbit": "file:../microbit",
"microbit-radio": "file:../microbit-radio"
} }
} }

View File

@ -59,6 +59,7 @@ testMemoryFreeHOF();
postPreFix() postPreFix()
eqOp() eqOp()
testEnums() testEnums()
testBuffer()
// test some top-level code // test some top-level code
let xsum = 0; let xsum = 0;
@ -722,3 +723,52 @@ function switchB(e: En) {
} }
return r; return r;
} }
function bufferIs(b:Buffer, a:number[]) {
assert(b.length == a.length, "bis-len")
for (let i = 0; i < a.length; ++i) {
if (a[i] != b[i]) {
assert(false, `bufferIs: buf[${i}]:${b[i]} != ${a[i]}`)
}
}
}
function testBuffer() {
let b = pins.createBuffer(3);
assert(b[0] == 0, "buf0");
assert(b[1] == 0, "buf0");
assert(b[2] == 0, "buf0");
assert(b[-100000] == 0, "bufM");
assert(b[100000] == 0, "bufM");
b[0] = 42;
bufferIs(b, [42, 0, 0]);
b[2] = 41;
bufferIs(b, [42, 0, 41]);
b.rotate(1)
bufferIs(b, [0, 41, 42]);
b.rotate(-2)
bufferIs(b, [41, 42, 0]);
b.shift(1)
bufferIs(b, [42, 0, 0]);
b.rotate(9)
bufferIs(b, [42, 0, 0]);
b.rotate(-9)
bufferIs(b, [42, 0, 0]);
b.fill(4);
bufferIs(b, [4, 4, 4]);
b.fill(12, 1, 1);
bufferIs(b, [4, 12, 4]);
b.fill(13, 1, -1);
bufferIs(b, [4, 13, 13]);
b.fill(100, -1, -1);
bufferIs(b, [4, 13, 13]);
b.shift(-1)
bufferIs(b, [0, 4, 13]);
}

155
libs/microbit/buffer.cpp Normal file
View File

@ -0,0 +1,155 @@
#include "ksbit.h"
enum class NumberFormat {
Int8LE = 1,
UInt8LE,
Int16LE,
UInt16LE,
Int32LE,
Int8BE,
UInt8BE,
Int16BE,
UInt16BE,
Int32BE,
// UInt32,
};
//% indexerGet=BufferMethods::getByte indexerSet=BufferMethods::setByte
namespace BufferMethods {
//%
int getByte(Buffer buf, int off) {
return max(ManagedBuffer(buf).getByte(off), 0);
}
//%
void setByte(Buffer buf, int off, int v) {
ManagedBuffer(buf).setByte(off, v);
}
//%
uint8_t *getBytes(Buffer buf) {
return buf->payload;
}
/**
* Write a number in specified format in the buffer.
*/
//%
void setNumber(Buffer buf, NumberFormat format, int offset, int value)
{
int8_t i8;
uint8_t u8;
int16_t i16;
uint16_t u16;
int32_t i32;
ManagedBuffer b(buf);
// Assume little endian
#define WRITEBYTES(isz, swap) isz = value; b.writeBytes(offset, (uint8_t*)&isz, sizeof(isz), swap); break
switch (format) {
case NumberFormat::Int8LE: WRITEBYTES(i8, false);
case NumberFormat::UInt8LE: WRITEBYTES(u8, false);
case NumberFormat::Int16LE: WRITEBYTES(i16, false);
case NumberFormat::UInt16LE: WRITEBYTES(u16, false);
case NumberFormat::Int32LE: WRITEBYTES(i32, false);
case NumberFormat::Int8BE: WRITEBYTES(i8, true);
case NumberFormat::UInt8BE: WRITEBYTES(u8, true);
case NumberFormat::Int16BE: WRITEBYTES(i16, true);
case NumberFormat::UInt16BE: WRITEBYTES(u16, true);
case NumberFormat::Int32BE: WRITEBYTES(i32, true);
}
}
/**
* Read a number in specified format from the buffer.
*/
//%
int getNumber(Buffer buf, NumberFormat format, int offset)
{
int8_t i8;
uint8_t u8;
int16_t i16;
uint16_t u16;
int32_t i32;
ManagedBuffer b(buf);
// Assume little endian
#define READBYTES(isz, swap) b.readBytes((uint8_t*)&isz, offset, sizeof(isz), swap); return isz
switch (format) {
case NumberFormat::Int8LE: READBYTES(i8, false);
case NumberFormat::UInt8LE: READBYTES(u8, false);
case NumberFormat::Int16LE: READBYTES(i16, false);
case NumberFormat::UInt16LE: READBYTES(u16, false);
case NumberFormat::Int32LE: READBYTES(i32, false);
case NumberFormat::Int8BE: READBYTES(i8, true);
case NumberFormat::UInt8BE: READBYTES(u8, true);
case NumberFormat::Int16BE: READBYTES(i16, true);
case NumberFormat::UInt16BE: READBYTES(u16, true);
case NumberFormat::Int32BE: READBYTES(i32, true);
}
return 0;
}
/** Returns the length of a Buffer object. */
//% property
int length(Buffer s) {
return s->length;
}
/**
* Fill (a fragment) of the buffer with given value.
*/
//%
void fill(Buffer buf, int value, int offset = 0, int length = -1)
{
ManagedBuffer(buf).fill(value, offset, length);
}
/**
* Return a copy of a fragment of a buffer.
*/
//%
Buffer slice(Buffer buf, int offset = 0, int length = -1)
{
return ManagedBuffer(buf).slice(offset, length).leakData();
}
/**
* Shift buffer left in place, with zero padding.
* @param offset number of bytes to shift; use negative value to shift right
*/
//%
void shift(Buffer buf, int offset)
{
ManagedBuffer(buf).shift(offset);
}
/**
* Rotate buffer left in place.
* @param offset number of bytes to shift; use negative value to shift right
*/
//%
void rotate(Buffer buf, int offset)
{
ManagedBuffer(buf).rotate(offset);
}
// int readBytes(uint8_t *dst, int offset, int length, bool swapBytes = false) const;
// int writeBytes(int dstOffset, uint8_t *src, int length, bool swapBytes = false);
/**
* Write contents of `src` at `dstOffset` in current buffer.
*/
//%
void write(Buffer buf, int dstOffset, Buffer src)
{
//Not supported, we only do up to 4 args :/
//void write(Buffer buf, int dstOffset, Buffer src, int srcOffset = 0, int length = -1)
ManagedBuffer(buf).writeBuffer(dstOffset, ManagedBuffer(src), 0, -1);
}
}

View File

@ -324,7 +324,7 @@ namespace ksrt {
RefAction *stclo(RefAction *a, int idx, uint32_t v) RefAction *stclo(RefAction *a, int idx, uint32_t v)
{ {
//DBG("STCLO "); a->print(); DBG("@%d = %p\n", idx, (void*)v); //DBG("STCLO "); a->print(); DBG("@%d = %p\n", idx, (void*)v);
a->st(idx, v); a->stCore(idx, v);
return a; return a;
} }
@ -334,65 +334,3 @@ namespace ksrt {
uBit.panic(code); uBit.panic(code);
} }
} }
namespace buffer {
RefBuffer *mk(uint32_t size)
{
RefBuffer *r = new RefBuffer();
r->data.resize(size);
return r;
}
char *cptr(RefBuffer *c)
{
return (char*)&c->data[0];
}
int count(RefBuffer *c) { return c->data.size(); }
void fill(RefBuffer *c, int v)
{
memset(cptr(c), v, count(c));
}
void fill_random(RefBuffer *c)
{
int len = count(c);
for (int i = 0; i < len; ++i)
c->data[i] = uBit.random(0x100);
}
void add(RefBuffer *c, uint32_t x) {
c->data.push_back(x);
}
inline bool in_range(RefBuffer *c, int x) {
return (0 <= x && x < (int)c->data.size());
}
uint32_t at(RefBuffer *c, int x) {
if (in_range(c, x)) {
return c->data[x];
}
else {
error(ERR_OUT_OF_BOUNDS);
return 0;
}
}
void set(RefBuffer *c, int x, uint32_t y) {
if (!in_range(c, x))
return;
c->data[x] = y;
}
}
namespace bitvm_bits {
RefBuffer *create_buffer(int size)
{
return buffer::mk(size);
}
}

View File

@ -82,6 +82,10 @@ interface String {
} }
interface Buffer {
[index: number]: number;
}
/** /**
* Converts A string to an integer. * Converts A string to an integer.
* @param s A string to convert into a number. * @param s A string to convert into a number.
@ -93,4 +97,3 @@ interface Object {}
interface Function {} interface Function {}
interface IArguments {} interface IArguments {}
interface RegExp {} interface RegExp {}

View File

@ -271,4 +271,19 @@ declare namespace pins {
declare namespace serial { declare namespace serial {
} }
declare enum NumberFormat {
Int8LE = 1,
UInt8LE = 2,
Int16LE = 3,
UInt16LE = 4,
Int32LE = 5,
Int8BE = 6,
UInt8BE = 7,
Int16BE = 8,
UInt16BE = 9,
Int32BE = 10,
// UInt32,
}
// Auto-generated. Do not edit. Really. // Auto-generated. Do not edit. Really.

View File

@ -22,8 +22,10 @@
"led.ts", "led.ts",
"music.ts", "music.ts",
"pins.cpp", "pins.cpp",
"pins.ts",
"serial.cpp", "serial.cpp",
"serial.ts" "serial.ts",
"buffer.cpp"
], ],
"public": true, "public": true,
"dependencies": {}, "dependencies": {},
@ -31,69 +33,5 @@
"config": { "config": {
"MESSAGE_BUS_LISTENER_DEFAULT_FLAGS": "MESSAGE_BUS_LISTENER_QUEUE_IF_BUSY" "MESSAGE_BUS_LISTENER_DEFAULT_FLAGS": "MESSAGE_BUS_LISTENER_QUEUE_IF_BUSY"
} }
},
"target": {
"id": "microbit",
"name": "BBC micro:bit",
"title": "JavaScript for BBC micro:bit",
"cloud": {
"workspace": false,
"packages": true
},
"blocksprj": {
"id": "blocksprj",
"config": {
"name": "{0} block",
"dependencies": {
"microbit": "*",
"microbit-radio": "*"
},
"description": "",
"files": [
"main.blocks",
"main.blocks.ts",
"README.md"
]
},
"files": {
"main.blocks": "<xml xmlns=\"http://www.w3.org/1999/xhtml\"><block type=\"device_print_message\"><value name=\"text\"><shadow type=\"text\"><field name=\"TEXT\">Hello!</field></shadow></value></block></xml>",
"main.blocks.ts": "\n",
"README.md": "Describe your project here!"
}
},
"tsprj": {
"id": "tsprj",
"config": {
"name": "{0} bit",
"dependencies": {
"microbit": "*",
"microbit-radio": "*"
},
"description": "",
"files": [
"main.ts",
"README.md"
]
},
"files": {
"main.ts": "basic.showString('Hello!')\n",
"README.md": "Describe your project here!"
}
},
"compile": {
"isNative": false,
"hasHex": true
},
"simulator": {
"autoRun": true
},
"compileService": {
"gittag": "v0.1.2",
"serviceId": "ws"
},
"serial": {
"manufacturerFilter": "^mbed$",
"log": true
}
} }
} }

View File

@ -1,6 +1,8 @@
#include "kindscript.h" #include "kindscript.h"
#include "ManagedBuffer.h"
using namespace kindscript; using namespace kindscript;
MicroBitPin *getPin(int id); MicroBitPin *getPin(int id);
typedef ImageData* Image; typedef ImageData* Image;
typedef BufferData* Buffer;

View File

@ -69,6 +69,13 @@ namespace pins {
if (!pin) return 0; \ if (!pin) return 0; \
return pin->op return pin->op
//%
MicroBitPin *getPinAddress(int id) {
return getPin(id);
}
/** /**
* Read the specified pin or connector as either 0 or 1 * Read the specified pin or connector as either 0 or 1
* @param name pin to read from * @param name pin to read from
@ -179,24 +186,33 @@ namespace pins {
} }
} }
// TODO: /**
void i2cReadBuffer(int address, RefBuffer *buf) * Create a new zero-initialized buffer.
* @param size number of bytes in the buffer
*/
//%
Buffer createBuffer(int size)
{ {
uBit.i2c.read(address << 1, buf->cptr(), buf->size()); return ManagedBuffer(size).leakData();
} }
void i2cWriteBuffer(int address, RefBuffer *buf) /**
* Read `size` bytes from a 7-bit I2C `address`.
*/
//%
Buffer i2cReadBuffer(int address, int size, bool repeat = false)
{ {
uBit.i2c.write(address << 1, buf->cptr(), buf->size()); Buffer buf = createBuffer(size);
uBit.i2c.read(address << 1, (char*)buf->payload, size, repeat);
return buf;
} }
int i2cReadRaw(int address, char *data, int length, int repeated) /**
* Write bytes to a 7-bit I2C `address`.
*/
//%
void i2cWriteBuffer(int address, Buffer buf, bool repeat = false)
{ {
return uBit.i2c.read(address, data, length, repeated); uBit.i2c.write(address << 1, (char*)buf->payload, buf->length, repeat);
}
int i2cWriteRaw(int address, const char *data, int length, int repeated)
{
return uBit.i2c.write(address, data, length, repeated);
} }
} }

View File

@ -13,4 +13,43 @@ namespace pins {
export function map(value: number, fromLow: number, fromHigh: number, toLow: number, toHigh: number): number { export function map(value: number, fromLow: number, fromHigh: number, toLow: number, toHigh: number): number {
return ((value - fromLow) * (toHigh - toLow)) / (fromHigh - fromLow) + toLow; return ((value - fromLow) * (toHigh - toLow)) / (fromHigh - fromLow) + toLow;
} }
/**
* Read one number from 7-bit I2C address.
*/
export function i2cReadNumber(address: number, format: NumberFormat): number {
let buf = pins.i2cReadBuffer(address, pins.sizeOf(format))
return buf.getNumber(format, 0)
}
/**
* Write one number to a 7-bit I2C address.
*/
export function i2cWriteNumber(address: number, value: number, format: NumberFormat): void {
let buf = createBuffer(pins.sizeOf(format))
buf.setNumber(format, 0, value)
pins.i2cWriteBuffer(address, buf)
}
/**
* Get the size in bytes of specified number format.
*/
export function sizeOf(format: NumberFormat) {
switch (format) {
case NumberFormat.Int8LE:
case NumberFormat.UInt8LE:
case NumberFormat.Int8BE:
case NumberFormat.UInt8BE:
return 1;
case NumberFormat.Int16LE:
case NumberFormat.UInt16LE:
case NumberFormat.Int16BE:
case NumberFormat.UInt16BE:
return 2;
case NumberFormat.Int32LE:
case NumberFormat.Int32BE:
return 4;
}
return 0;
}
} }

View File

@ -374,8 +374,8 @@ declare namespace control {
* @param mode optional definition of how the event should be processed after construction (default is CREATE_AND_QUEUE). * @param mode optional definition of how the event should be processed after construction (default is CREATE_AND_QUEUE).
*/ */
//% weight=21 blockGap=12 blockId="control_raise_event" block="raise event|from source %src=control_event_source|with value %value=control_event_value" blockExternalInputs=1 //% weight=21 blockGap=12 blockId="control_raise_event" block="raise event|from source %src=control_event_source|with value %value=control_event_value" blockExternalInputs=1
//% mode.defl=1 shim=control::raiseEvent //% mode.defl=1 shim=control::raiseEvent
function raiseEvent(src: number, value: number, mode: EventCreationMode): void; function raiseEvent(src: number, value: number, mode?: EventCreationMode): void;
/** /**
* Raises an event in the event bus. * Raises an event in the event bus.
@ -534,6 +534,25 @@ declare namespace pins {
*/ */
//% help=pins/analog-pitch weight=14 async shim=pins::analogPitch //% help=pins/analog-pitch weight=14 async shim=pins::analogPitch
function analogPitch(frequency: number, ms: number): void; function analogPitch(frequency: number, ms: number): void;
/**
* Create a new zero-initialized buffer.
* @param size number of bytes in the buffer
*/
//% shim=pins::createBuffer
function createBuffer(size: number): Buffer;
/**
* Read `size` bytes from a 7-bit I2C `address`.
*/
//% repeat.defl=0 shim=pins::i2cReadBuffer
function i2cReadBuffer(address: number, size: number, repeat?: boolean): Buffer;
/**
* Write bytes to a 7-bit I2C `address`.
*/
//% repeat.defl=0 shim=pins::i2cWriteBuffer
function i2cWriteBuffer(address: number, buf: Buffer, repeat?: boolean): void;
} }
@ -566,4 +585,57 @@ declare namespace serial {
function readScreen(): void; function readScreen(): void;
} }
//% indexerGet=BufferMethods::getByte indexerSet=BufferMethods::setByte
declare interface Buffer {
/**
* Write a number in specified format in the buffer.
*/
//% shim=BufferMethods::setNumber
setNumber(format: NumberFormat, offset: number, value: number): void;
/**
* Read a number in specified format from the buffer.
*/
//% shim=BufferMethods::getNumber
getNumber(format: NumberFormat, offset: number): number;
/** Returns the length of a Buffer object. */
//% property shim=BufferMethods::length
length: number;
/**
* Fill (a fragment) of the buffer with given value.
*/
//% offset.defl=0 length.defl=-1 shim=BufferMethods::fill
fill(value: number, offset?: number, length?: number): void;
/**
* Return a copy of a fragment of a buffer.
*/
//% offset.defl=0 length.defl=-1 shim=BufferMethods::slice
slice(offset?: number, length?: number): Buffer;
/**
* Shift buffer left in place, with zero padding.
* @param offset number of bytes to shift; use negative value to shift right
*/
//% shim=BufferMethods::shift
shift(offset: number): void;
/**
* Rotate buffer left in place.
* @param offset number of bytes to shift; use negative value to shift right
*/
//% shim=BufferMethods::rotate
rotate(offset: number): void;
/**
* Write contents of `src` at `dstOffset` in current buffer.
*/
//% shim=BufferMethods::write
write(dstOffset: number, src: Buffer): void;
}
// Auto-generated. Do not edit. Really. // Auto-generated. Do not edit. Really.

20
libs/neopixel/kind.json Normal file
View 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
View 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
View File

@ -0,0 +1,92 @@
basic.showLeds(`
# . . . .
. . . . .
. . # . .
. . . . .
. . . . #
`)
console.log("Start")
// Create a NeoPixel driver - specify the number of LEDs:
let strip = neopixel.create(7);
// 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);
}
});

View File

@ -0,0 +1,67 @@
sendBufferAsm:
push {r4,r5,r6,r7,lr}
mov r4, r0 ; save buff
mov r6, r1 ; save pin
mov r0, r4
bl BufferMethods::length
mov r5, r0
mov r0, r4
bl BufferMethods::getBytes
mov r4, r0
; setup pin as digital
mov r0, r6
movs r1, #0
bl pins::digitalWritePin
; load pin address
mov r0, r6
bl pins::getPinAddress
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}

View File

@ -1,6 +1,6 @@
{ {
"name": "kindscript-microbit", "name": "kindscript-microbit",
"version": "0.2.13", "version": "0.2.17",
"description": "BBC micro:bit target for KindScript", "description": "BBC micro:bit target for KindScript",
"keywords": [ "keywords": [
"JavaScript", "JavaScript",
@ -17,7 +17,6 @@
"files": [ "files": [
"README.md", "README.md",
"kindtarget.json", "kindtarget.json",
"kindtheme.json",
"built/*.js", "built/*.js",
"built/*.json", "built/*.json",
"built/*.d.ts", "built/*.d.ts",
@ -30,6 +29,6 @@
"typescript": "^1.8.7" "typescript": "^1.8.7"
}, },
"dependencies": { "dependencies": {
"kindscript": "0.2.15" "kindscript": "0.2.19"
} }
} }

View File

@ -527,4 +527,4 @@ namespace ks.rt.ImageMethods {
} }
// TODO ... // TODO ...
} }