Skip to content

Commit

Permalink
add WS.LED command and ws_led API
Browse files Browse the repository at this point in the history
  • Loading branch information
mikecat committed Sep 5, 2023
1 parent 9a0db52 commit 7651bbe
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 3 deletions.
11 changes: 11 additions & 0 deletions docs/Commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,17 @@ function commandDRAW(args) {
}
}

async function commandWS_LED(args) {
// フルカラーLED用の色情報を送信する
const numLED = args[0], numRepeat = args.length > 1 ? args[1] : 1;
if (numLED <= 0 || numRepeat <= 0 || numLED * 3 > ARRAY_SIZE) return;
const colorData = [];
for (let i = 0; i < numLED; i++) {
colorData.push([readArray(i * 3 + 0) & 0xff, readArray(i * 3 + 1) & 0xff, readArray(i * 3 + 2) & 0xff]);
}
await wsLedManager.sendColors(colorData, numRepeat, ["led"]);
}

async function commandSEC_PUBKEY(args) {
// Ed25519の秘密鍵から公開鍵を求める
// args[0] : 公開鍵(出力)の仮想アドレス
Expand Down
2 changes: 1 addition & 1 deletion docs/Compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ const basicCommands = {
"IoT.OUT": {func: commandIoT_OUT, minArg: 1, maxArg: 3},
"SWITCH" : {func: commandSWITCH, minArg: 0, maxArg: 2},
"DRAW" : {func: commandDRAW, minArg: 2, maxArg: 5},
"WS.LED" : null,
"WS.LED" : {func: commandWS_LED, minArg: 1, maxArg: 2},
"SEC.PUBKEY" : {func: commandSEC_PUBKEY, minArg: 2, maxArg: 2},
"SEC.SIGN" : {func: commandSEC_SIGN, minArg: 4, maxArg: 4},
"PC.CLEAR" : {func: commandPC_CLEAR, minArg: 1, maxArg: 1},
Expand Down
48 changes: 48 additions & 0 deletions docs/IO.js
Original file line number Diff line number Diff line change
Expand Up @@ -526,3 +526,51 @@ const i2cManager = (function() {
"performI2C": performI2C,
};
})();

const wsLedManager = (function() {
// 以下の仕様の関数(非同期可)の配列
// 引数
// data : 色データ (3要素の配列の、1要素以上の配列)
// 各要素となる配列は、色を表す0~255の値を前(先に送信する)から順に格納する
// WS2812では緑、赤、青 (GRB) の順
// numRepeat : 繰り返し回数 (1以上の整数)
// ports : 出力対象のポートID (文字列) の配列
// 返り値
// ドントケア
const wsLedDevices = [];

// デバイスを追加する
function addDevice(device) {
wsLedDevices.push(device);
}

// LEDの色情報を送信する
// 引数
// data : 色データ (3要素の配列の、1要素以上の配列)
// 各要素となる配列は、色を表す0~255の値を前(先に送信する)から順に格納する
// WS2812では緑、赤、青 (GRB) の順
// numRepeat : 繰り返し回数 (1以上の整数)
// ports : 出力対象のポートID (文字列) の配列
// 返り値
// なし
async function sendColors(data, numRepeat, ports) {
console.log(data, numRepeat, ports);
const devicePromises = [];
for (let i = 0; i < wsLedDevices.length; i++) {
const deviceFunction = wsledDevicees[i];
devicePromises.push(new Promise(async function(resolve, reject) {
try {
resolve(await deviceFunction(data, numRepeat, ports));
} catch (error) {
reject(error);
}
}));
}
await Promise.allSettled(devicePromises);
}

return {
"addDevice": addDevice,
"sendColors": sendColors,
};
})();
38 changes: 36 additions & 2 deletions docs/Usr.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
"use strict";

const wsLedPorts = {
0x5000: [null, null, null, null, null, "in3", "in4", null, null, null, "in1", "in2"],
0x5001: ["out1", "out2", "out3", "out4", null, "led", null, null, "out5", "out6"],
};

const apiMap = {
0x2100: { // rnd
"tableAddr": 0xC0,
Expand Down Expand Up @@ -174,8 +179,37 @@ const apiMap = {
0x212E: { // ws_led
"tableAddr": 0xEE,
"returnsValue": false,
"func": function(env, countrepeat, data, gpiomask) {
throw "Not implemented: WS_LED";
"func": async function(env, countrepeat, data, gpiomask) {
console.log(countrepeat, data.toString(16), gpiomask.toString(16));
// 出力先のポートを取得する
const gpioMaskUpper = (gpiomask >>> 16) & 0xffff, gpioMaskLower = gpiomask & 0xffff;
if (!(gpioMaskUpper in wsLedPorts) || gpioMaskLower >= 0x4000) return;
const portStatus = ioManager.getPortStatus();
const portList = wsLedPorts[gpioMaskUpper];
const portsToOutput = [];
for (let i = 0; i < portList.length; i++) {
if ((gpioMaskLower >> (2 + i)) & 1) {
const port = portList[i];
if (port in portStatus && portStatus[port].status === "output_binary") {
portsToOutput.push(port);
}
}
}
if (portsToOutput.length === 0) return;
// 出力するデータを取得する
// TODO
// ・端数のデータも出力する
// ・短い間に連続して呼ばれた場合、切らずに前回の続きとして出力する
const colorData = [];
for (let i = 0; i < countrepeat - 2; i += 3) {
const colorElement = [0, 0, 0];
for (let j = 0; j < 3; j++) {
colorElement[j] = env.readMemory((data + i + j) >>> 0, 1, false);
}
colorData.push(colorElement);
}
// 出力する
await wsLedManager.sendColors(colorData, 1, portsToOutput);
},
},
};
Expand Down

0 comments on commit 7651bbe

Please sign in to comment.