Skip to content

Commit

Permalink
refactor: remove intel-hex dependency and update hex file reading method
Browse files Browse the repository at this point in the history
  • Loading branch information
barrenechea committed Oct 8, 2024
1 parent e464075 commit 535d6e0
Show file tree
Hide file tree
Showing 11 changed files with 198 additions and 66 deletions.
13 changes: 6 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ A modern, ESM-compatible, TypeScript implementation of the STK500v1 protocol for
- Can be used in Node.js or browser environments
- No dependency on avrdude or the Arduino IDE
- TypeScript support for improved developer experience
- **Built-in Intel HEX parsing** (no need for external parsing libraries)

## Installation

Expand All @@ -22,9 +23,8 @@ Here's a basic example of how to use stk500-esm to program an Arduino:

```typescript
import { SerialPort } from "serialport";
import intel_hex from "intel-hex";
import Stk500 from "stk500-esm";
import fs from "fs/promises";
import Stk500 from "stk500-esm";

const stk = new Stk500();

Expand All @@ -42,9 +42,8 @@ async function upload(path: string) {
const hexData = await fs.readFile("path/to/your/sketch.hex", {
encoding: "utf8",
});
const hex = intel_hex.parse(hexData).data;
serialPort = new SerialPort({ path, baudRate: board.baud });
await stk.bootload(serialPort, hex, board, false);
await stk.bootload(serialPort, hexData, board, false);
console.log("Programming successful!");
} catch (error) {
console.error("Programming failed:", error);
Expand Down Expand Up @@ -83,11 +82,11 @@ Replace `uno.ts` with the appropriate example file and `/dev/ttyACM0` with your

The main class `Stk500` provides the following methods:

- `bootload(stream: NodeJS.ReadWriteStream, hex: Buffer, opt: Board, use_8_bit_addresses = false): Promise<void>`
- `bootload(stream: NodeJS.ReadWriteStream, hexData: string | Buffer, opt: Board, use_8_bit_addresses = false): Promise<void>`
- `sync(stream: NodeJS.ReadWriteStream, attempts: number, timeout: number): Promise<Buffer>`
- `verifySignature(stream: NodeJS.ReadWriteStream, signature: Buffer, timeout: number): Promise<Buffer>`
- `upload(stream: NodeJS.ReadWriteStream, hex: Buffer, pageSize: number, timeout: number, use_8_bit_addresses = false): Promise<void>`
- `verify(stream: NodeJS.ReadWriteStream, hex: Buffer, pageSize: number, timeout: number, use_8_bit_addresses = false): Promise<void>`
- `upload(stream: NodeJS.ReadWriteStream, hexData: string | Buffer, pageSize: number, timeout: number, use_8_bit_addresses = false): Promise<void>`
- `verify(stream: NodeJS.ReadWriteStream, hexData: string | Buffer, pageSize: number, timeout: number, use_8_bit_addresses = false): Promise<void>`

For more detailed API information, please refer to the TypeScript definitions or the source code.

Expand Down
10 changes: 3 additions & 7 deletions examples/avr4809.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import fs from "fs/promises";
import { SerialPort } from "serialport";
import intel_hex from "intel-hex";
import Stk500 from "../src/index.js";

const stk = new Stk500();
Expand All @@ -13,11 +12,6 @@ const board = {
timeout: 400,
};

async function readHexFile(filePath) {
const data = await fs.readFile(filePath, { encoding: "utf8" });
return intel_hex.parse(data).data;
}

function createSerialPort(path, baudRate) {
return new Promise((resolve, reject) => {
const serialPort = new SerialPort({ path, baudRate });
Expand All @@ -38,7 +32,9 @@ async function closeSerialPort(serialPort) {
async function upload(path) {
let serialPort;
try {
const hex = await readHexFile("arduino-1.0.6/168/avr4809.cpp.hex");
const hex = await fs.readFile("arduino-1.0.6/168/avr4809.cpp.hex", {
encoding: "utf8",
});
serialPort = await createSerialPort(path, board.baudRate);
await stk.bootload(serialPort, hex, board, true);
console.log("Programming SUCCESS!");
Expand Down
10 changes: 3 additions & 7 deletions examples/diecimila-duemilanove168.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import fs from "fs/promises";
import { SerialPort } from "serialport";
import intel_hex from "intel-hex";
import Stk500 from "../src/index.js";

const stk = new Stk500();
Expand All @@ -13,11 +12,6 @@ const board = {
timeout: 400,
};

async function readHexFile(filePath) {
const data = await fs.readFile(filePath, { encoding: "utf8" });
return intel_hex.parse(data).data;
}

function createSerialPort(path, baudRate) {
return new Promise((resolve, reject) => {
const serialPort = new SerialPort({ path, baudRate });
Expand All @@ -38,7 +32,9 @@ async function closeSerialPort(serialPort) {
async function upload(path) {
let serialPort;
try {
const hex = await readHexFile("arduino-1.0.6/168/StandardFirmata.cpp.hex");
const hex = await fs.readFile("arduino-1.0.6/168/StandardFirmata.cpp.hex", {
encoding: "utf8",
});
serialPort = await createSerialPort(path, board.baudRate);
await stk.bootload(serialPort, hex, board, false);
console.log("Programming SUCCESS!");
Expand Down
11 changes: 4 additions & 7 deletions examples/duemilanove328.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import fs from "fs/promises";
import { SerialPort } from "serialport";
import intel_hex from "intel-hex";
import Stk500 from "../src/index.js";

const stk = new Stk500();
Expand All @@ -13,11 +12,6 @@ const board = {
timeout: 400,
};

async function readHexFile(filePath) {
const data = await fs.readFile(filePath, { encoding: "utf8" });
return intel_hex.parse(data).data;
}

function createSerialPort(path, baudRate) {
return new Promise((resolve, reject) => {
const serialPort = new SerialPort({ path, baudRate });
Expand All @@ -38,7 +32,10 @@ async function closeSerialPort(serialPort) {
async function upload(path) {
let serialPort;
try {
const hex = await readHexFile("arduino-1.0.6/duemilanove328/StandardFirmata.cpp.hex");
const hex = await fs.readFile(
"arduino-1.0.6/duemilanove328/StandardFirmata.cpp.hex",
{ encoding: "utf8" }
);
serialPort = await createSerialPort(path, board.baudRate);
await stk.bootload(serialPort, hex, board, false);
console.log("Programming SUCCESS!");
Expand Down
10 changes: 3 additions & 7 deletions examples/lgt8f328.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import fs from "fs/promises";
import { SerialPort } from "serialport";
import intel_hex from "intel-hex";
import Stk500 from "../src/index.js";

const stk = new Stk500();
Expand All @@ -13,11 +12,6 @@ const board = {
timeout: 400,
};

async function readHexFile(filePath) {
const data = await fs.readFile(filePath, { encoding: "utf8" });
return intel_hex.parse(data).data;
}

function createSerialPort(path, baudRate) {
return new Promise((resolve, reject) => {
const serialPort = new SerialPort({ path, baudRate });
Expand All @@ -38,7 +32,9 @@ async function closeSerialPort(serialPort) {
async function upload(path) {
let serialPort;
try {
const hex = await readHexFile("arduino-2.3.3/lgt8f328/Blink.ino.hex");
const hex = await fs.readFile("arduino-2.3.3/lgt8f328/Blink.ino.hex", {
encoding: "utf8",
});
serialPort = await createSerialPort(path, board.baudRate);
await stk.bootload(serialPort, hex, board, false);
console.log("Programming SUCCESS!");
Expand Down
10 changes: 3 additions & 7 deletions examples/nano.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import fs from "fs/promises";
import { SerialPort } from "serialport";
import intel_hex from "intel-hex";
import Stk500 from "../src/index.js";

const stk = new Stk500();
Expand All @@ -13,11 +12,6 @@ const board = {
timeout: 400,
};

async function readHexFile(filePath) {
const data = await fs.readFile(filePath, { encoding: "utf8" });
return intel_hex.parse(data).data;
}

function createSerialPort(path, baudRate) {
return new Promise((resolve, reject) => {
const serialPort = new SerialPort({ path, baudRate });
Expand All @@ -38,7 +32,9 @@ async function closeSerialPort(serialPort) {
async function upload(path) {
let serialPort;
try {
const hex = await readHexFile("arduino-2.3.3/nano/Blink.ino.hex");
const hex = await fs.readFile("arduino-2.3.3/nano/Blink.ino.hex", {
encoding: "utf8",
});
serialPort = await createSerialPort(path, board.baudRate);
await stk.bootload(serialPort, hex, board, false);
console.log("Programming SUCCESS!");
Expand Down
10 changes: 3 additions & 7 deletions examples/uno.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import fs from "fs/promises";
import { SerialPort } from "serialport";
import intel_hex from "intel-hex";
import Stk500 from "../src/index.js";

const stk = new Stk500();
Expand All @@ -13,11 +12,6 @@ const board = {
timeout: 400,
};

async function readHexFile(filePath) {
const data = await fs.readFile(filePath, { encoding: "utf8" });
return intel_hex.parse(data).data;
}

function createSerialPort(path, baudRate) {
return new Promise((resolve, reject) => {
const serialPort = new SerialPort({ path, baudRate });
Expand All @@ -38,7 +32,9 @@ async function closeSerialPort(serialPort) {
async function upload(path) {
let serialPort;
try {
const hex = await readHexFile("arduino-1.0.6/uno/StandardFirmata.cpp.hex");
const hex = await fs.readFile("arduino-1.0.6/uno/StandardFirmata.cpp.hex", {
encoding: "utf8",
});
serialPort = await createSerialPort(path, board.baudRate);
await stk.bootload(serialPort, hex, board, false);
console.log("Programming SUCCESS!");
Expand Down
12 changes: 2 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "stk500-esm",
"version": "1.0.1",
"version": "1.1.0",
"description": "A modern, ESM-compatible, TypeScript implementation of the STK500v1 protocol for programming Arduino boards directly from Node.js or the browser.",
"main": "dist/index.js",
"module": "dist/index.js",
Expand Down Expand Up @@ -30,7 +30,6 @@
"@types/node": "^22.7.5",
"eslint": "^9.12.0",
"globals": "^15.10.0",
"intel-hex": "^0.2.0",
"serialport": "^12.0.0",
"tsx": "^4.19.1",
"typescript": "^5.6.2",
Expand Down
29 changes: 24 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Constants from "./lib/constants.js";
import sendCommand from "./lib/sendCommand.js";
import { parseIntelHex } from "./lib/intelHexParser.js";

interface Board {
name: string;
Expand Down Expand Up @@ -200,13 +201,16 @@ class STK500 {

async upload(
stream: NodeJS.ReadWriteStream,
hex: Buffer,
hexData: string | Buffer,
pageSize: number,
timeout: number,
use8BitAddresses = false
): Promise<void> {
this.log("program");

// Parse the Intel HEX data
const { data: hex } = parseIntelHex(hexData);

let pageaddr = 0;
let writeBytes;
let useaddr;
Expand Down Expand Up @@ -258,13 +262,16 @@ class STK500 {

async verify(
stream: NodeJS.ReadWriteStream,
hex: Buffer,
hexData: string | Buffer,
pageSize: number,
timeout: number,
use8BitAddresses = false
): Promise<void> {
this.log("verify");

// Parse the Intel HEX data
const { data: hex } = parseIntelHex(hexData);

let pageaddr = 0;
let writeBytes;
let useaddr;
Expand Down Expand Up @@ -331,7 +338,7 @@ class STK500 {

async bootload(
stream: NodeJS.ReadWriteStream,
hex: Buffer,
hexData: string | Buffer,
opt: Board,
use8BitAddresses = false
): Promise<void> {
Expand All @@ -347,8 +354,20 @@ class STK500 {
await this.verifySignature(stream, opt.signature, opt.timeout);
await this.setOptions(stream, parameters, opt.timeout);
await this.enterProgrammingMode(stream, opt.timeout);
await this.upload(stream, hex, opt.pageSize, opt.timeout, use8BitAddresses);
await this.verify(stream, hex, opt.pageSize, opt.timeout, use8BitAddresses);
await this.upload(
stream,
hexData,
opt.pageSize,
opt.timeout,
use8BitAddresses
);
await this.verify(
stream,
hexData,
opt.pageSize,
opt.timeout,
use8BitAddresses
);
await this.exitProgrammingMode(stream, opt.timeout);
}
}
Expand Down
Loading

0 comments on commit 535d6e0

Please sign in to comment.