import { Uploader } from './uploader'; import { BoardConfig } from '../board'; import type SerialPort from 'serialport'; import avr109 from 'chip.avr.avr109'; import { sleep, promisify, serialportPromisify } from '../util'; class Avr109Uploader extends Uploader { constructor(boardConfig: BoardConfig) { super(boardConfig); } public async bootload(port: SerialPort, hex: Buffer) { const SerialPortConstructor = port.constructor as typeof SerialPort; const uploadPort = await this.pollPort(SerialPortConstructor); const { open, whenClose } = serialportPromisify(uploadPort); const init = promisify(avr109.init).bind(avr109) const opts = { signature: Buffer.from([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]).toString() } await open(); const flasher = await init(uploadPort, opts); const erase = promisify(flasher.erase).bind(flasher) const program = promisify(flasher.program).bind(flasher) const verify = promisify(flasher.verify).bind(flasher) const fuseCheck = promisify(flasher.fuseCheck).bind(flasher) await erase() await program(hex.toString()) await verify(); await fuseCheck(); await whenClose(); } private async pollPort(SerialPortConstructor: typeof SerialPort) { for (let i = 1; i <= 20; i++) { console.log(`poll port ... ${i}`); const list = await SerialPortConstructor.list(); const portInfo = list.find(({ productId }) => { return productId === '0036' }); if (!portInfo) { await sleep(250) continue; } console.log(`poll port done, path: ${portInfo.path}`); return new SerialPortConstructor(portInfo.path, { baudRate: this.boardConfig.baudRate, autoOpen: false }) } throw Error('poll port fail') } protected async reset(port: SerialPort) { if (port.isOpen) { const { close } = serialportPromisify(port); await close(); } const SerialPortConstructor = port.constructor as typeof SerialPort; const tempPort = new SerialPortConstructor(port.path, { baudRate: 1200, autoOpen: false, }) const { open, close } = serialportPromisify(tempPort); await open() await close() } } export default Avr109Uploader;