node-raspberrypi-usbboot
Advanced tools
Comparing version 0.3.0-cm4-33a3daf7fe4a2f5cd69438c61b86efb02f062607 to 0.3.0-cm4-701744f0bbc02bd7d322ed7e989af576a7156689
/// <reference types="node" /> | ||
import { EventEmitter } from 'events'; | ||
export declare const isUsbBootCapableUSBDevice: (idVendor: number, idProduct: number) => boolean; | ||
export declare class UsbbootDevice extends EventEmitter { | ||
export declare abstract class UsbbootDevice extends EventEmitter { | ||
portId: string; | ||
static readonly LAST_STEP = 41; | ||
abstract readonly LAST_STEP: number; | ||
private _step; | ||
@@ -13,2 +13,8 @@ constructor(portId: string); | ||
} | ||
export declare class CM3 extends UsbbootDevice { | ||
readonly LAST_STEP = 40; | ||
} | ||
export declare class CM4 extends UsbbootDevice { | ||
readonly LAST_STEP = 10; | ||
} | ||
export declare class UsbbootScanner extends EventEmitter { | ||
@@ -15,0 +21,0 @@ private usbbootDevices; |
@@ -7,3 +7,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.UsbbootScanner = exports.UsbbootDevice = exports.isUsbBootCapableUSBDevice = void 0; | ||
exports.UsbbootScanner = exports.CM4 = exports.CM3 = exports.UsbbootDevice = exports.isUsbBootCapableUSBDevice = void 0; | ||
// tslint:disable:no-bitwise | ||
@@ -107,2 +107,3 @@ const usb = require("@balena.io/usb"); | ||
const USB_PRODUCT_ID_BCM2711_BOOT = 0x2711; | ||
const USB_PRODUCT_ID_BCM2711_MASS_STORAGE = 1; | ||
// When the pi reboots in mass storage mode, it has this product id | ||
@@ -179,2 +180,6 @@ const USB_VENDOR_ID_NETCHIP_TECHNOLOGY = 0x0525; | ||
}; | ||
const isComputeModule4InMassStorageMode = (device) => { | ||
return (device.deviceDescriptor.idVendor === USB_VENDOR_ID_BROADCOM_CORPORATION && | ||
device.deviceDescriptor.idProduct === USB_PRODUCT_ID_BCM2711_MASS_STORAGE); | ||
}; | ||
const initializeDevice = (device) => { | ||
@@ -258,10 +263,7 @@ // interface is a reserved keyword in TypeScript so we use iface | ||
const getFileBuffer = async (device, filename) => { | ||
let buffer = await safeReadFile(filename); | ||
const folder = device.deviceDescriptor.idProduct === USB_PRODUCT_ID_BCM2711_BOOT | ||
? 'cm4' | ||
: 'raspberrypi'; | ||
const buffer = await safeReadFile(Path.join(folder, filename)); | ||
if (buffer === undefined) { | ||
const folder = device.deviceDescriptor.idProduct === USB_PRODUCT_ID_BCM2711_BOOT | ||
? 'cm4' | ||
: 'raspberrypi'; | ||
buffer = await safeReadFile(Path.join(folder, filename)); | ||
} | ||
if (buffer === undefined) { | ||
debug("Can't read file", filename); | ||
@@ -283,3 +285,3 @@ } | ||
* This needs to be sent to the out endpoint of the USB device | ||
* as a 24 bytes big-endian buffer where: | ||
* as a 24 bytes little-endian buffer where: | ||
* | ||
@@ -294,4 +296,4 @@ * - The first 4 bytes contain the size of the bootcode.bin buffer | ||
const bootMessageBuffer = Buffer.alloc(bootMessageBufferSize); | ||
// The bootcode length should be stored in 4 big-endian bytes | ||
bootMessageBuffer.writeInt32BE(bootCodeBufferLength, BOOT_MESSAGE_BOOTCODE_LENGTH_OFFSET); | ||
// The bootcode length should be stored in 4 little-endian bytes | ||
bootMessageBuffer.writeInt32LE(bootCodeBufferLength, BOOT_MESSAGE_BOOTCODE_LENGTH_OFFSET); | ||
return bootMessageBuffer; | ||
@@ -322,3 +324,3 @@ }; | ||
get progress() { | ||
return Math.round((this._step / UsbbootDevice.LAST_STEP) * 100); | ||
return Math.round((this._step / this.LAST_STEP) * 100); | ||
} | ||
@@ -334,10 +336,30 @@ get step() { | ||
exports.UsbbootDevice = UsbbootDevice; | ||
// LAST_STEP is hardcoded here as it is depends on the bootcode.bin file we send to the pi. | ||
// List of steps: | ||
// 0) device connects with iSerialNumber 0 and we write bootcode.bin to it | ||
// 1) the device detaches | ||
// 2 - 39) the device reattaches with iSerialNumber 1 and we upload the files it requires (the number of steps depends on the device) | ||
// 40) the device detaches | ||
// 41) the device reattaches as a mass storage device | ||
UsbbootDevice.LAST_STEP = 41; | ||
class CM3 extends UsbbootDevice { | ||
constructor() { | ||
super(...arguments); | ||
// LAST_STEP is hardcoded here as it is depends on the bootcode.bin file we send to the pi. | ||
// List of steps: | ||
// 0) device connects with iSerialNumber 0 and we write bootcode.bin to it | ||
// 1) the device detaches | ||
// 2 - 38) the device reattaches with iSerialNumber 1 and we upload the files it requires (the number of steps depends on the device) | ||
// 39) the device detaches | ||
// 40) the device reattaches as a mass storage device | ||
this.LAST_STEP = 40; | ||
} | ||
} | ||
exports.CM3 = CM3; | ||
class CM4 extends UsbbootDevice { | ||
constructor() { | ||
super(...arguments); | ||
// LAST_STEP is hardcoded here as it is depends on the bootcode.bin file we send to the pi. | ||
// List of steps: | ||
// 0) device connects with iSerialNumber 0 and we write bootcode.bin to it | ||
// 1) the device detaches | ||
// 2 - 8) the device reattaches with iSerialNumber 1 and we upload the files it requires (the number of steps depends on the device) | ||
// 9) the device detaches | ||
// 10) the device reattaches as a mass storage device | ||
this.LAST_STEP = 10; | ||
} | ||
} | ||
exports.CM4 = CM4; | ||
class UsbbootScanner extends events_1.EventEmitter { | ||
@@ -355,3 +377,3 @@ constructor() { | ||
start() { | ||
debug('Waiting for BCM2835/6/7'); | ||
debug('Waiting for BCM2835/6/7/2711'); | ||
// Prepare already connected devices | ||
@@ -369,3 +391,3 @@ usb.getDeviceList().map(this.boundAttachDevice); | ||
this.interval = setInterval(() => { | ||
usb.getDeviceList().forEach(this.boundAttachDevice); | ||
// usb.getDeviceList().forEach(this.boundAttachDevice); | ||
}, POLLING_INTERVAL_MS); | ||
@@ -382,3 +404,3 @@ } | ||
usbbootDevice.step = step; | ||
if (step === UsbbootDevice.LAST_STEP) { | ||
if (step === usbbootDevice.LAST_STEP) { | ||
this.remove(device); | ||
@@ -395,3 +417,6 @@ } | ||
if (usbbootDevice === undefined) { | ||
usbbootDevice = new UsbbootDevice(key); | ||
const Cls = device.deviceDescriptor.idProduct === USB_PRODUCT_ID_BCM2711_BOOT | ||
? CM4 | ||
: CM3; | ||
usbbootDevice = new Cls(key); | ||
this.usbbootDevices.set(key, usbbootDevice); | ||
@@ -415,5 +440,7 @@ this.emit('attach', usbbootDevice); | ||
this.attachedDeviceIds.add(getDeviceId(device)); | ||
if (isRaspberryPiInMassStorageMode(device) && | ||
this.usbbootDevices.has(devicePortId(device))) { | ||
this.step(device, 41); | ||
const usbbootDevice = this.get(device); | ||
if ((isRaspberryPiInMassStorageMode(device) || | ||
isComputeModule4InMassStorageMode(device)) && | ||
usbbootDevice !== undefined) { | ||
this.step(device, usbbootDevice.LAST_STEP); | ||
return; | ||
@@ -453,3 +480,6 @@ } | ||
} | ||
const step = device.deviceDescriptor.iSerialNumber === 0 ? 1 : 40; | ||
const usbbootDevice = this.getOrCreate(device); | ||
const step = device.deviceDescriptor.iSerialNumber === 0 | ||
? 1 | ||
: usbbootDevice.LAST_STEP - 1; | ||
debug('detach', devicePortId(device), step); | ||
@@ -460,4 +490,4 @@ this.step(device, step); | ||
setTimeout(() => { | ||
const usbbootDevice = this.get(device); | ||
if (usbbootDevice !== undefined && usbbootDevice.step === step) { | ||
const $usbbootDevice = this.get(device); | ||
if ($usbbootDevice !== undefined && $usbbootDevice.step === step) { | ||
debug('device', devicePortId(device), 'did not reattached after', DEVICE_UNPLUG_TIMEOUT, 'ms.'); | ||
@@ -470,4 +500,2 @@ this.remove(device); | ||
while (true) { | ||
this.step(device, step); | ||
step += 1; | ||
let data; | ||
@@ -486,2 +514,4 @@ try { | ||
} | ||
this.step(device, step); | ||
step += 1; | ||
const message = parseFileMessageBuffer(data); | ||
@@ -488,0 +518,0 @@ debug('Received message', FileMessageCommand[message.command], message.filename, devicePortId(device)); |
@@ -8,6 +8,12 @@ # Change Log | ||
# v0.3.0 | ||
## (2020-12-09) | ||
## (2021-03-26) | ||
* Add support for compute module 4 [Alexis Svinartchouk] | ||
* Fix size endianness of boot_message_t message [Alexis Svinartchouk] | ||
# v0.2.11 | ||
## (2021-02-10) | ||
* Update @balena.io/usb from 1.3.12 to 1.3.14 [Alexis Svinartchouk] | ||
# v0.2.10 | ||
@@ -14,0 +20,0 @@ ## (2020-11-30) |
{ | ||
"name": "node-raspberrypi-usbboot", | ||
"version": "0.3.0-cm4-33a3daf7fe4a2f5cd69438c61b86efb02f062607", | ||
"version": "0.3.0-cm4-701744f0bbc02bd7d322ed7e989af576a7156689", | ||
"description": "Transforms Raspberry Pi Compute Modules and Zeros to mass storage devices.", | ||
@@ -28,3 +28,3 @@ "main": "build/index.js", | ||
"dependencies": { | ||
"@balena.io/usb": "^1.3.12", | ||
"@balena.io/usb": "^1.3.14", | ||
"debug": "^4.1.1" | ||
@@ -31,0 +31,0 @@ }, |
Sorry, the diff of this file is not supported yet
28224965
576
Updated@balena.io/usb@^1.3.14