Skip to content

Commit 5553c64

Browse files
committed
initial commit
0 parents  commit 5553c64

20 files changed

+2891
-0
lines changed

.eslintignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
.eslintrc.js
3+
lib

.eslintrc.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module.exports = {
2+
root: true,
3+
extends: ['eslint:recommended', 'airbnb-base'],
4+
plugins: ['import'],
5+
parserOptions: {
6+
project: './tsconfig.eslint.json',
7+
},
8+
};

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
lib

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# upload-multitool
2+
3+
**WIP:** This project is currently a work in progress
4+
5+
A modern tool for uploading to micro controllers like Arduinos and ESP devices, written in typescript with automated tests.

package.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "upload-multitool",
3+
"version": "0.0.1",
4+
"description": "Micro Controller Uploading Multitool",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "mocha -r ts-node/register test/**/*.ts test/*.ts",
8+
"build": "tsc"
9+
},
10+
"author": "Fraser Bullock",
11+
"license": "UNLICENSED",
12+
"devDependencies": {
13+
"@types/chai": "^4.3.1",
14+
"@types/mocha": "^9.1.1",
15+
"@types/node": "^17.0.33",
16+
"@typescript-eslint/eslint-plugin": "^5.23.0",
17+
"@typescript-eslint/parser": "^5.23.0",
18+
"axios": "^0.27.2",
19+
"chai": "^4.3.6",
20+
"eslint": "^8.15.0",
21+
"eslint-config-airbnb-base": "^15.0.0",
22+
"eslint-config-airbnb-typescript": "^17.0.0",
23+
"eslint-plugin-import": "^2.26.0",
24+
"mocha": "^10.0.0",
25+
"serialport": "^10.4.0",
26+
"ts-node": "^10.8.0",
27+
"typescript": "^4.6.4",
28+
"yaml": "^2.1.0"
29+
},
30+
"dependencies": {
31+
"intel-hex": "^0.1.2"
32+
}
33+
}

src/avr/avr-cpu-data.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// referenced from the avrdude.conf
2+
3+
interface CPUData {
4+
signature: Buffer;
5+
pageSize: number;
6+
numPages: number;
7+
timeout: number;
8+
protocol: string;
9+
delay1?: number;
10+
delay2?: number;
11+
stabDelay?: number;
12+
cmdexeDelay?: number;
13+
synchLoops?: number;
14+
byteDelay?: number;
15+
pollValue?: number;
16+
pollIndex?: number;
17+
}
18+
19+
interface CPUDefinitions {
20+
[key: string]: CPUData;
21+
}
22+
23+
const cpuDefs = {
24+
atmega328p: {
25+
signature: Buffer.from([0x1e, 0x95, 0x0f]),
26+
pageSize: 128,
27+
numPages: 256,
28+
timeout: 400,
29+
protocol: 'stk500v1',
30+
} as CPUData,
31+
atmega168: {
32+
signature: Buffer.from([0x1e, 0x94, 0x06]),
33+
pageSize: 128,
34+
numPages: 128,
35+
timeout: 400,
36+
protocol: 'stk500v1',
37+
} as CPUData,
38+
atmega8: {
39+
signature: Buffer.from([0x1e, 0x93, 0x07]),
40+
pageSize: 64,
41+
numPages: 128,
42+
timeout: 400,
43+
protocol: 'stk500v1',
44+
} as CPUData,
45+
atmega2560: {
46+
signature: Buffer.from([0x1e, 0x98, 0x01]),
47+
pageSize: 256,
48+
numPages: 1024,
49+
delay1: 10,
50+
delay2: 1,
51+
timeout: 0xc8, // 200
52+
stabDelay: 0x64, // 100
53+
cmdexeDelay: 0x19, // 25
54+
synchLoops: 0x20, // 32
55+
byteDelay: 0x00, // 0
56+
pollValue: 0x53,
57+
pollIndex: 0x03, // 3
58+
protocol: 'stk500v2',
59+
} as CPUData,
60+
atmega1280: {
61+
signature: Buffer.from([0x1e, 0x97, 0x03]),
62+
pageSize: 256,
63+
numPages: 512,
64+
delay1: 10,
65+
delay2: 1,
66+
timeout: 0xc8, // 200
67+
stabDelay: 0x64, // 100
68+
cmdexeDelay: 0x19, // 25
69+
synchLoops: 0x20, // 32
70+
byteDelay: 0x00, // 0
71+
pollValue: 0x53,
72+
pollIndex: 0x03, // 3
73+
protocol: 'stk500v2',
74+
} as CPUData,
75+
atmega32u4: {
76+
signature: Buffer.from([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]),
77+
protocol: 'avr109',
78+
} as CPUData,
79+
} as CPUDefinitions;
80+
81+
export default (cpu?: string): CPUData => {
82+
const cpuData = cpuDefs[cpu || ''];
83+
if (!cpuData) throw new Error(`Unknown CPU: ${cpu}`);
84+
return cpuData;
85+
};

src/avr/index.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { SerialPort } from 'serialport/dist/index.d';
2+
import { ProgramConfig } from '../index.d';
3+
4+
import intelHex from 'intel-hex';
5+
import getCpuData from './avr-cpu-data';
6+
import STK500v1 from './stk500-v1';
7+
8+
export const upload = async (serial: SerialPort, config: ProgramConfig) => {
9+
const cpuData = getCpuData(config.cpu);
10+
let uploader = null as STK500v1 | null;
11+
switch (cpuData.protocol) {
12+
case 'stk500v1':
13+
uploader = new STK500v1(serial, { quiet: !config.verbose });
14+
await uploader.bootload(
15+
intelHex.parse(config.hex || '').data,
16+
{
17+
signature: cpuData.signature,
18+
pageSize: cpuData.pageSize,
19+
timeout: cpuData.timeout,
20+
},
21+
);
22+
break;
23+
default:
24+
throw new Error(`Protocol ${cpuData.protocol} not supported`);
25+
}
26+
};
27+
28+
export const isSupported = (cpu: string) => {
29+
try {
30+
const cpuData = getCpuData(cpu);
31+
return ['stk500v1'].includes(cpuData.protocol);
32+
} catch (e) {
33+
return false;
34+
}
35+
};
36+
37+
export default { upload, isSupported };

0 commit comments

Comments
 (0)