led-matrix-controllers 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,10 @@
1
1
  {
2
2
  "name": "led-matrix-controllers",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/jpadgett314/led-matrix-controllers.git"
7
+ },
4
8
  "type": "module",
5
9
  "main": "./src/index.js",
6
10
  "module": "./src/index.js",
@@ -11,7 +15,6 @@
11
15
  "src",
12
16
  "dist"
13
17
  ],
14
- "packageManager": "yarn@4.12.0",
15
18
  "devDependencies": {
16
19
  "@rollup/plugin-node-resolve": "^16.0.3",
17
20
  "@rollup/plugin-terser": "^0.4.4",
@@ -20,4 +23,4 @@
20
23
  "scripts": {
21
24
  "build": "rollup -c"
22
25
  }
23
- }
26
+ }
@@ -1,33 +1,33 @@
1
- import { DefaultController } from './supported-firmware/FrameworkComputer/inputmodule-rs/DefaultController.js';
2
- import { SigrootController } from './supported-firmware/sigroot/FW_LED_Matrix_Firmware/SigrootController.js';
3
- import { SparkleController } from './supported-firmware/vddCore/sparkle-fw16/SparkleController.js';
4
-
5
- export class HardwareControllerFactory {
6
- static async detectSerial() {
7
- const c1 = new DefaultController();
8
- const c2 = new SigrootController();
9
-
10
- await c1.connect();
11
- if (await c1.verifyFirmware()) {
12
- return c1;
13
- }
14
-
15
- await c2.connect()
16
- if (await c2.verifyFirmware()) {
17
- return c2;
18
- }
19
-
20
- return null;
21
- }
22
-
23
- static async detectHID() {
24
- const c1 = new SparkleController();
25
-
26
- await c1.connect();
27
- if (await c1.verifyFirmware()) {
28
- return c1;
29
- }
30
-
31
- return null;
32
- }
33
- }
1
+ import { DefaultController } from './supported-firmware/FrameworkComputer/inputmodule-rs/DefaultController.js';
2
+ import { SigrootController } from './supported-firmware/sigroot/FW_LED_Matrix_Firmware/SigrootController.js';
3
+ import { SparkleController } from './supported-firmware/vddCore/sparkle-fw16/SparkleController.js';
4
+
5
+ export class HardwareControllerFactory {
6
+ static async detectSerial() {
7
+ const c1 = new DefaultController();
8
+ const c2 = new SigrootController();
9
+
10
+ await c1.connect();
11
+ if (await c1.verifyFirmware()) {
12
+ return c1;
13
+ }
14
+
15
+ await c2.connect()
16
+ if (await c2.verifyFirmware()) {
17
+ return c2;
18
+ }
19
+
20
+ return null;
21
+ }
22
+
23
+ static async detectHID() {
24
+ const c1 = new SparkleController();
25
+
26
+ await c1.connect();
27
+ if (await c1.verifyFirmware()) {
28
+ return c1;
29
+ }
30
+
31
+ return null;
32
+ }
33
+ }
@@ -1,41 +1,41 @@
1
- export const WIDTH = 9;
2
- export const HEIGHT = 34;
3
- export const VID = 0x32AC;
4
- export const VID_ARR = [0x32, 0xAC];
5
- export const PID = 0x0020;
6
- export const PID_ARR = [0x00, 0x20];
7
-
8
- export const GAMMA = Object.freeze([
9
- 0, 0, 0, 0, 0, 0, 0, 1,
10
- 1, 1, 1, 1, 1, 1, 1, 1,
11
- 1, 1, 1, 1, 1, 1, 1, 1,
12
- 1, 1, 1, 1, 1, 1, 1, 1,
13
- 1, 1, 1, 2, 2, 2, 2, 2,
14
- 2, 2, 2, 2, 3, 3, 3, 3,
15
- 3, 3, 3, 4, 4, 4, 4, 4,
16
- 4, 5, 5, 5, 5, 6, 6, 6,
17
- 6, 6, 7, 7, 7, 7, 8, 8,
18
- 8, 9, 9, 9, 10, 10, 10, 11,
19
- 11, 11, 12, 12, 12, 13, 13, 14,
20
- 14, 14, 15, 15, 16, 16, 17, 17,
21
- 17, 18, 18, 19, 19, 20, 20, 21,
22
- 22, 22, 23, 23, 24, 24, 25, 26,
23
- 26, 27, 27, 28, 29, 29, 30, 31,
24
- 32, 32, 33, 34, 34, 35, 36, 37,
25
- 38, 38, 39, 40, 41, 42, 42, 43,
26
- 44, 45, 46, 47, 48, 49, 50, 51,
27
- 52, 53, 54, 55, 56, 57, 58, 59,
28
- 60, 61, 62, 63, 64, 66, 67, 68,
29
- 69, 70, 71, 73, 74, 75, 76, 78,
30
- 79, 80, 82, 83, 84, 86, 87, 88,
31
- 90, 91, 93, 94, 96, 97, 99, 100,
32
- 102, 103, 105, 106, 108, 110, 111, 113,
33
- 115, 116, 118, 120, 121, 123, 125, 127,
34
- 128, 130, 132, 134, 136, 138, 140, 141,
35
- 143, 145, 147, 149, 151, 153, 155, 157,
36
- 159, 161, 164, 166, 168, 170, 172, 174,
37
- 177, 179, 181, 183, 186, 188, 190, 193,
38
- 195, 197, 200, 202, 205, 207, 210, 212,
39
- 215, 217, 220, 222, 225, 228, 230, 233,
40
- 236, 238, 241, 244, 247, 249, 252, 255
41
- ]);
1
+ export const WIDTH = 9;
2
+ export const HEIGHT = 34;
3
+ export const VID = 0x32AC;
4
+ export const VID_ARR = [0x32, 0xAC];
5
+ export const PID = 0x0020;
6
+ export const PID_ARR = [0x00, 0x20];
7
+
8
+ export const GAMMA = Object.freeze([
9
+ 0, 0, 0, 0, 0, 0, 0, 1,
10
+ 1, 1, 1, 1, 1, 1, 1, 1,
11
+ 1, 1, 1, 1, 1, 1, 1, 1,
12
+ 1, 1, 1, 1, 1, 1, 1, 1,
13
+ 1, 1, 1, 2, 2, 2, 2, 2,
14
+ 2, 2, 2, 2, 3, 3, 3, 3,
15
+ 3, 3, 3, 4, 4, 4, 4, 4,
16
+ 4, 5, 5, 5, 5, 6, 6, 6,
17
+ 6, 6, 7, 7, 7, 7, 8, 8,
18
+ 8, 9, 9, 9, 10, 10, 10, 11,
19
+ 11, 11, 12, 12, 12, 13, 13, 14,
20
+ 14, 14, 15, 15, 16, 16, 17, 17,
21
+ 17, 18, 18, 19, 19, 20, 20, 21,
22
+ 22, 22, 23, 23, 24, 24, 25, 26,
23
+ 26, 27, 27, 28, 29, 29, 30, 31,
24
+ 32, 32, 33, 34, 34, 35, 36, 37,
25
+ 38, 38, 39, 40, 41, 42, 42, 43,
26
+ 44, 45, 46, 47, 48, 49, 50, 51,
27
+ 52, 53, 54, 55, 56, 57, 58, 59,
28
+ 60, 61, 62, 63, 64, 66, 67, 68,
29
+ 69, 70, 71, 73, 74, 75, 76, 78,
30
+ 79, 80, 82, 83, 84, 86, 87, 88,
31
+ 90, 91, 93, 94, 96, 97, 99, 100,
32
+ 102, 103, 105, 106, 108, 110, 111, 113,
33
+ 115, 116, 118, 120, 121, 123, 125, 127,
34
+ 128, 130, 132, 134, 136, 138, 140, 141,
35
+ 143, 145, 147, 149, 151, 153, 155, 157,
36
+ 159, 161, 164, 166, 168, 170, 172, 174,
37
+ 177, 179, 181, 183, 186, 188, 190, 193,
38
+ 195, 197, 200, 202, 205, 207, 210, 212,
39
+ 215, 217, 220, 222, 225, 228, 230, 233,
40
+ 236, 238, 241, 244, 247, 249, 252, 255
41
+ ]);
package/src/index.js CHANGED
@@ -1,5 +1,5 @@
1
- export * from './hardware-constants.js'
2
- export * from './HardwareControllerFactory.js';
3
- export * from './supported-firmware/FrameworkComputer/inputmodule-rs/DefaultController.js';
4
- export * from './supported-firmware/sigroot/FW_LED_Matrix_Firmware/SigrootController.js'
5
- export * from './supported-firmware/vddCore/sparkle-fw16/SparkleController.js';
1
+ export * from './hardware-constants.js'
2
+ export * from './HardwareControllerFactory.js';
3
+ export * from './supported-firmware/FrameworkComputer/inputmodule-rs/DefaultController.js';
4
+ export * from './supported-firmware/sigroot/FW_LED_Matrix_Firmware/SigrootController.js'
5
+ export * from './supported-firmware/vddCore/sparkle-fw16/SparkleController.js';
@@ -1,75 +1,123 @@
1
- import { HEIGHT, VID_ARR, WIDTH } from '../../../hardware-constants.js';
2
- import { Command, RX_PACKET_SZ } from './commands.js';
3
-
4
- export class CommandAbstractionLayer {
5
- constructor(portMutex = null) {
6
- this.portMutex = portMutex;
7
- }
8
-
9
- async bootloader() {
10
- await this.portMutex.acquire(async p => {
11
- await p.tx([...VID_ARR, Command.BOOTLOADER]);
12
- });
13
- }
14
-
15
- async draw(matrix) {
16
- let index = 0;
17
- let output = new Uint8Array(39).fill(0);
18
-
19
- // Pack cells into bits
20
- for (let r = 0; r < HEIGHT; r++) {
21
- for (let c = 0; c < WIDTH; c++) {
22
- if (matrix[r][c]) {
23
- output[index >> 3] |= 1 << index % 8;
24
- }
25
- index++;
26
- }
27
- }
28
-
29
- await this.portMutex.acquireIdempotent(
30
- 'drawMatrix',
31
- async p => {
32
- await p.tx([...VID_ARR, Command.DRAW, ...output]);
33
- }
34
- );
35
- }
36
-
37
- async drawGrayscale(matrix) {
38
- // Transpose & Gamma Correction
39
- const buffers = Array.from(
40
- { length: WIDTH },
41
- (_, c) => new Array(
42
- { length: HEIGHT },
43
- (_, r) => GAMMA[Math.floor((matrix[r][c] ?? 0) * 255)]
44
- )
45
- );
46
-
47
- // Only execute the most recent call
48
- await this.portMutex.acquireIdempotent(
49
- 'drawMatrix',
50
- async p => {
51
- for (let i = 0; i < WIDTH; i++) {
52
- await p.tx([Command.STAGE_GREY_COL, i, ...buffers[i]]);
53
- }
54
- await p.tx([Command.DRAW_GREY_COL_BUFFER]);
55
- }
56
- );
57
- }
58
-
59
- async version() {
60
- let ver = {};
61
-
62
- await this.portMutex.acquire(async p => {
63
- await p.tx([...VID_ARR, Command.VERSION]);
64
- const response = await p.rx(RX_PACKET_SZ);
65
-
66
- // MMMMMMMM mmmmPPPP 0000000p
67
- ver.major = response[0];
68
- ver.minor = response[1] >> 4;
69
- ver.patch = response[1] & 0x0F;
70
- ver.preRelease = response[2] == 1;
71
- });
72
-
73
- return ver;
74
- }
75
- }
1
+ import { HEIGHT, VID_ARR, WIDTH } from '../../../hardware-constants.js';
2
+ import { Command, RX_PACKET_SZ } from './commands.js';
3
+
4
+ export class CommandAbstractionLayer {
5
+ constructor(portMutex = null) {
6
+ this.portMutex = portMutex;
7
+ }
8
+
9
+ async bootloader() {
10
+ await this.portMutex.acquire(async p => {
11
+ await p.tx([...VID_ARR, Command.BOOTLOADER]);
12
+ });
13
+ }
14
+
15
+ async brightness(brightness) {
16
+ await this.portMutex.acquire(async p => {
17
+ await p.tx([...VID_ARR, Command.BRIGHTNESS, brightness]);
18
+ });
19
+ }
20
+
21
+ async draw(matrix) {
22
+ let index = 0;
23
+ let output = new Uint8Array(39).fill(0);
24
+
25
+ // Pack cells into bits
26
+ for (let r = 0; r < HEIGHT; r++) {
27
+ for (let c = 0; c < WIDTH; c++) {
28
+ if (matrix[r][c]) {
29
+ output[index >> 3] |= 1 << index % 8;
30
+ }
31
+ index++;
32
+ }
33
+ }
34
+
35
+ await this.portMutex.acquireIdempotent(
36
+ 'drawMatrix',
37
+ async p => {
38
+ await p.tx([...VID_ARR, Command.DRAW, ...output]);
39
+ }
40
+ );
41
+ }
42
+
43
+ async drawGrayscale(matrix) {
44
+ // Transpose & Gamma Correction
45
+ const buffers = Array.from(
46
+ { length: WIDTH },
47
+ (_, c) => new Array(
48
+ { length: HEIGHT },
49
+ (_, r) => GAMMA[Math.floor((matrix[r][c] ?? 0) * 255)]
50
+ )
51
+ );
52
+
53
+ // Only execute the most recent call
54
+ await this.portMutex.acquireIdempotent(
55
+ 'drawMatrix',
56
+ async p => {
57
+ for (let i = 0; i < WIDTH; i++) {
58
+ await p.tx([...VID_ARR, Command.STAGE_GREY_COL, i, ...buffers[i]]);
59
+ }
60
+ await p.tx([...VID_ARR, Command.DRAW_GREY_COL_BUFFER]);
61
+ }
62
+ );
63
+ }
64
+
65
+ async asleep() {
66
+ let asleep = false;
67
+
68
+ await this.portMutex.acquire(async p => {
69
+ await p.tx([...VID_ARR, Command.SLEEP]);
70
+ asleep = await p.rx(RX_PACKET_SZ);
71
+ asleep = asleep[0] != 0x00;
72
+ });
73
+
74
+ return asleep;
75
+ }
76
+
77
+ async sleep() {
78
+ await this.portMutex.acquire(async p => {
79
+ await p.tx([...VID_ARR, Command.SLEEP, 0x01]);
80
+ });
81
+ }
82
+
83
+ async wake() {
84
+ await this.portMutex.acquire(async p => {
85
+ await p.tx([...VID_ARR, Command.SLEEP]);
86
+ });
87
+ }
88
+
89
+ async pattern(pattern) {
90
+ await this.portMutex.acquireIdempotent(
91
+ 'drawMatrix',
92
+ async p => {
93
+ await p.tx([...VID_ARR, Command.PATTERN, pattern]);
94
+ }
95
+ );
96
+ }
97
+
98
+ async percent(percent) {
99
+ await this.portMutex.acquireIdempotent(
100
+ 'drawMatrix',
101
+ async p => {
102
+ await p.tx([...VID_ARR, Command.PATTERN, Pattern.PERCENTAGE, percent]);
103
+ }
104
+ );
105
+ }
106
+
107
+ async version() {
108
+ let ver = {};
109
+
110
+ await this.portMutex.acquire(async p => {
111
+ await p.tx([...VID_ARR, Command.VERSION]);
112
+ const response = await p.rx(RX_PACKET_SZ);
113
+
114
+ // MMMMMMMM mmmmPPPP 0000000p
115
+ ver.major = response[0];
116
+ ver.minor = response[1] >> 4;
117
+ ver.patch = response[1] & 0x0F;
118
+ ver.preRelease = response[2] == 1;
119
+ });
120
+
121
+ return ver;
122
+ }
123
+ }
@@ -1,54 +1,54 @@
1
- import { close, getPort } from '../../../web-serial/port.js';
2
- import { PortMutex } from '../../../web-serial/PortMutex.js';
3
- import { PortOperations } from '../../../web-serial/PortOperations.js';
4
- import { CommandAbstractionLayer } from './CommandAbstractionLayer.js';
5
-
6
- export class DefaultController extends CommandAbstractionLayer {
7
- async bootloader() {
8
- return super.bootloader();
9
- }
10
-
11
- async connect() {
12
- const port = await getPort();
13
-
14
- if (port?.connected) {
15
- await close(port);
16
- await port.open({ baudRate: 115200 });
17
- this.portMutex = new PortMutex(new PortOperations(port));
18
- }
19
- }
20
-
21
- async draw(matrix) {
22
- switch (this.#bitDepth) {
23
-
24
- case BitDepth.GRAY_8BIT:
25
- super.drawGrayscale(matrix);
26
- break;
27
-
28
- case BitDepth.MONO_1BIT:
29
- super.draw(matrix);
30
- break;
31
- }
32
- }
33
-
34
- async verifyFirmware() {
35
- try {
36
- const version = await super.version();
37
-
38
- return version
39
- && version.major != undefined
40
- && version.minor != undefined
41
- && version.patch != undefined
42
- && version.preRelease != undefined;
43
-
44
- } catch {
45
- return false;
46
- }
47
- }
48
-
49
- async version() {
50
- return super.version();
51
- }
52
-
53
- #bitDepth;
54
- }
1
+ import { close, getPort } from '../../../web-serial/port.js';
2
+ import { PortMutex } from '../../../web-serial/PortMutex.js';
3
+ import { PortOperations } from '../../../web-serial/PortOperations.js';
4
+ import { CommandAbstractionLayer } from './CommandAbstractionLayer.js';
5
+
6
+ export class DefaultController extends CommandAbstractionLayer {
7
+ async bootloader() {
8
+ return super.bootloader();
9
+ }
10
+
11
+ async connect() {
12
+ const port = await getPort();
13
+
14
+ if (port?.connected) {
15
+ await close(port);
16
+ await port.open({ baudRate: 115200 });
17
+ this.portMutex = new PortMutex(new PortOperations(port));
18
+ }
19
+ }
20
+
21
+ async draw(matrix) {
22
+ switch (this.#bitDepth) {
23
+
24
+ case BitDepth.GRAY_8BIT:
25
+ super.drawGrayscale(matrix);
26
+ break;
27
+
28
+ case BitDepth.MONO_1BIT:
29
+ super.draw(matrix);
30
+ break;
31
+ }
32
+ }
33
+
34
+ async verifyFirmware() {
35
+ try {
36
+ const version = await super.version();
37
+
38
+ return version
39
+ && version.major != undefined
40
+ && version.minor != undefined
41
+ && version.patch != undefined
42
+ && version.preRelease != undefined;
43
+
44
+ } catch {
45
+ return false;
46
+ }
47
+ }
48
+
49
+ async version() {
50
+ return super.version();
51
+ }
52
+
53
+ #bitDepth;
54
+ }
@@ -1,36 +1,36 @@
1
- // All replies to all commands are 32 bytes
2
- export const RX_PACKET_SZ = 32;
3
-
4
- export const Command = Object.freeze({
5
- ANIMATE: 0x04,
6
- BRIGHTNESS: 0x00,
7
- BOOTLOADER: 0x02,
8
- DRAW: 0x06,
9
- DRAW_GREY_COL_BUFFER: 0x08,
10
- GAME_CTRL: 0x11,
11
- GAME_STATUS: 0x12,
12
- PANIC: 0x05,
13
- PATTERN: 0x01,
14
- SLEEP: 0x03,
15
- STAGE_GREY_COL: 0x07,
16
- START_GAME: 0x10,
17
- VERSION: 0x20,
18
- });
19
-
20
- // Used with Command.PATTERN
21
- export const Pattern = Object.freeze({
22
- DISPLAY_LOTUS_HORIZONTAL: 0x03,
23
- DISPLAY_LOTUS_VERTICAL: 0x07,
24
- DISPLAY_PANIC: 0x06,
25
- DOUBLE_GRADIENT: 0x02,
26
- FULL_BRIGHTNESS: 0x05,
27
- GRADIENT: 0x01,
28
- PERCENTAGE: 0x00,
29
- ZIG_ZAG: 0x04,
30
- });
31
-
32
- // DRAW or DRAW_GREY_COL_BUFFER
33
- export const BitDepth = Object.freeze({
34
- GRAY_8BIT: '8-bit',
35
- MONO_1BIT: '1-bit',
36
- })
1
+ // All replies to all commands are 32 bytes
2
+ export const RX_PACKET_SZ = 32;
3
+
4
+ export const Command = Object.freeze({
5
+ ANIMATE: 0x04,
6
+ BRIGHTNESS: 0x00,
7
+ BOOTLOADER: 0x02,
8
+ DRAW: 0x06,
9
+ DRAW_GREY_COL_BUFFER: 0x08,
10
+ GAME_CTRL: 0x11,
11
+ GAME_STATUS: 0x12,
12
+ PANIC: 0x05,
13
+ PATTERN: 0x01,
14
+ SLEEP: 0x03,
15
+ STAGE_GREY_COL: 0x07,
16
+ START_GAME: 0x10,
17
+ VERSION: 0x20,
18
+ });
19
+
20
+ // Used with Command.PATTERN
21
+ export const Pattern = Object.freeze({
22
+ DISPLAY_LOTUS_HORIZONTAL: 0x03,
23
+ DISPLAY_LOTUS_VERTICAL: 0x07,
24
+ DISPLAY_PANIC: 0x06,
25
+ DOUBLE_GRADIENT: 0x02,
26
+ FULL_BRIGHTNESS: 0x05,
27
+ GRADIENT: 0x01,
28
+ PERCENTAGE: 0x00,
29
+ ZIG_ZAG: 0x04,
30
+ });
31
+
32
+ // DRAW or DRAW_GREY_COL_BUFFER
33
+ export const BitDepth = Object.freeze({
34
+ GRAY_8BIT: '8-bit',
35
+ MONO_1BIT: '1-bit',
36
+ })