Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/firmware-loader/images/board-xrp-nano.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions public/firmware-loader/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@
"description": "XRP robot headers",
"image": "/firmware-loader/images/board-xrp-2350.jpg",
"nextLevel": "boards/xrp-2350.json"
},
{
"id": "xrp-nano",
"name": "NanoXRP",
"description": "NanoXRP with the RP2040 controller",
"image": "/firmware-loader/images/board-xrp-nano.jpg",
"nextLevel": "boards/xrp-nano.json"
}
]
}
11 changes: 8 additions & 3 deletions public/firmware-loader/wizard-assets.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
{
"powerOff": {
"xrp-beta": "/firmware-loader/images/board-xrp-beta_poweroff.jpg",
"xrp-2350": "/firmware-loader/images/board-xrp-2350_poweroff.jpg"
"xrp-2350": "/firmware-loader/images/board-xrp-2350_poweroff.jpg",
"xrp-nano": "/firmware-loader/images/board-xrp-nano_poweroff.jpg"
},
"bootSel": {
"xrp-beta": "/firmware-loader/images/board-xrp-beta_bootsel.jpg",
"xrp-2350": "/firmware-loader/images/board-xrp-2350_bootsel.jpg"
"xrp-2350": "/firmware-loader/images/board-xrp-2350_bootsel.jpg",
"xrp-nano": "/firmware-loader/images/board-xrp-nano_bootsel.jpg"
},
"selectDir": {
"xrp-beta-win": "/firmware-loader/images/board-xrp-beta-selectdir-win.png",
"xrp-beta-mac": "/firmware-loader/images/board-xrp-beta-selectdir-mac.jpg",
"xrp-beta-linux": "/firmware-loader/images/board-xrp-beta-selectdir-linux.png",
"xrp-2350-win": "/firmware-loader/images/board-xrp-2350-selectdir-win.png",
"xrp-2350-mac": "/firmware-loader/images/board-xrp-2350-selectdir-mac.jpg",
"xrp-2350-linux": "/firmware-loader/images/board-xrp-2350-selectdir-linux.png"
"xrp-2350-linux": "/firmware-loader/images/board-xrp-2350-selectdir-linux.png",
"xrp-nano-win": "/firmware-loader/images/board-xrp-beta-selectdir-win.png",
"xrp-nano-mac": "/firmware-loader/images/board-xrp-beta-selectdir-mac.jpg",
"xrp-nano-linux": "/firmware-loader/images/board-xrp-beta-selectdir-linux.png"
}
}
23 changes: 15 additions & 8 deletions src/components/dialogs/firmware-install-wizard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ function boardIdToProcessor(boardId: string): 2040 | 2350 {
return boardId === 'xrp-2350' ? 2350 : 2040;
}

/** The NanoXRP is RP2040-based but runs its own firmware build. */
function boardIdIsNanoXRP(boardId: string): boolean {
return boardId === 'xrp-nano';
}

/** BOOTSEL mass-storage drive name for the given XRP board. */
function expectedDriveForBoard(boardId: string): string {
return boardId === 'xrp-2350' ? 'RP2350' : 'RPI-RP2';
Expand Down Expand Up @@ -155,10 +160,12 @@ export default function FirmwareInstallWizard({
const { t } = useTranslation();
const os = useMemo(() => detectOsFamily(), []);

const boardCtx = boardIdIsNanoXRP(boardId) ? { context: 'nano' } : undefined;

const cmd = CommandToXRPMgr.getInstance();

useEffect(() => {
cmd.setProcessorTypeForFirmwareLoader(boardIdToProcessor(boardId));
cmd.setProcessorTypeForFirmwareLoader(boardIdToProcessor(boardId), boardIdIsNanoXRP(boardId));
}, [boardId, cmd]);

const [phase, setPhase] = useState<WizardUiPhase>({ kind: 'instruction', step: 1 });
Expand Down Expand Up @@ -238,7 +245,7 @@ export default function FirmwareInstallWizard({
setError(null);
setPhase({ kind: 'uf2' });
setUf2Pct(0);
cmd.setProcessorTypeForFirmwareLoader(boardIdToProcessor(boardId));
cmd.setProcessorTypeForFirmwareLoader(boardIdToProcessor(boardId), boardIdIsNanoXRP(boardId));

try {
if (!dirHandle) {
Expand Down Expand Up @@ -442,28 +449,28 @@ export default function FirmwareInstallWizard({
<div className="mx-auto flex w-full max-w-2xl flex-col items-center gap-6">
{phase.step === 1 && (
<>
<h2 className="text-center text-lg font-semibold">{t('firmwareWizardStep1Title')}</h2>
<h2 className="text-center text-lg font-semibold">{t('firmwareWizardStep1Title', boardCtx)}</h2>
<img src={imgPowerOff} alt="" className="max-h-72 w-full rounded-lg object-contain" />
<p className="text-center text-sm text-mountain-mist-700 dark:text-shark-300">
{t('firmwareWizardStep1Body')}
{t('firmwareWizardStep1Body', boardCtx)}
</p>
</>
)}
{phase.step === 2 && (
<>
<h2 className="text-center text-lg font-semibold">{t('firmwareWizardStep2Title')}</h2>
<h2 className="text-center text-lg font-semibold">{t('firmwareWizardStep2Title', boardCtx)}</h2>
<img src={imgBootSel} alt="" className="max-h-72 w-full rounded-lg object-contain" />
<p className="text-center text-sm text-mountain-mist-700 dark:text-shark-300">
{t('firmwareWizardStep2Body')}
{t('firmwareWizardStep2Body', boardCtx)}
</p>
</>
)}
{phase.step === 3 && (
<>
<h2 className="text-center text-lg font-semibold">{t('firmwareWizardStep3Title')}</h2>
<h2 className="text-center text-lg font-semibold">{t('firmwareWizardStep3Title', boardCtx)}</h2>
<img src={imgSelectDir} alt="" className="max-h-72 w-full rounded-lg object-contain" />
<p className="mb-2 text-center text-sm text-mountain-mist-700 dark:text-shark-300">
{t('firmwareWizardStep3Body', { drive: cmd.getXRPDrive() })}
{t('firmwareWizardStep3Body', { drive: cmd.getXRPDrive(), ...boardCtx })}
</p>
<button
type="button"
Expand Down
39 changes: 25 additions & 14 deletions src/managers/commandstoxrpmgr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,17 @@ export class CommandToXRPMgr {

if (hiddenLines != undefined && hiddenLines.length > 0) {
if (hiddenLines[0].substring(2) != 'ERROR') {
if (this.PROCESSOR == undefined) {
if (hiddenLines[1].includes('RP2350')) {
this.PROCESSOR = 2350;
} else if (hiddenLines[1].includes('RP2040')) {
this.PROCESSOR = 2040;
this.is_NanoXRP = hiddenLines[1].includes('NanoXRP');
this.connection?.setNanoXRP(this.is_NanoXRP);
}
// Always recompute from the live version string: checkIfNeedUpdate
// resets is_NanoXRP on every new attach, and the user may have
// swapped boards since PROCESSOR was last set.
if (hiddenLines[1].includes('RP2350')) {
this.PROCESSOR = 2350;
this.is_NanoXRP = false;
this.connection?.setNanoXRP(false);
} else if (hiddenLines[1].includes('RP2040')) {
this.PROCESSOR = 2040;
this.is_NanoXRP = hiddenLines[1].includes('NanoXRP');
this.connection?.setNanoXRP(this.is_NanoXRP);
}
if(hiddenLines[1].includes('XRP')){ //is this an XRP version of microPython?
this.is_XRP_MP = true;
Expand All @@ -215,10 +218,14 @@ export class CommandToXRPMgr {

/**
* getBoardId - map the connected XRP's processor to the firmware-loader board id.
* RP2040 boards are the "xrp-beta"; everything else (RP2350) is "xrp-2350".
* RP2040 boards are the "xrp-beta" (or "xrp-nano" for the NanoXRP variant);
* everything else (RP2350) is "xrp-2350".
*/
private getBoardId(): string {
return this.PROCESSOR === 2040 ? 'xrp-beta' : 'xrp-2350';
if (this.PROCESSOR !== 2040) {
return 'xrp-2350';
}
return this.is_NanoXRP ? 'xrp-nano' : 'xrp-beta';
}

/**
Expand Down Expand Up @@ -368,10 +375,13 @@ export class CommandToXRPMgr {

/**
* Set RP2040 vs RP2350 before UF2 install when the user has not connected yet
* (getVersionInfo would not have run).
* (getVersionInfo would not have run). isNanoXRP distinguishes the NanoXRP
* from the beta board (both RP2040).
*/
public setProcessorTypeForFirmwareLoader(processor: 2040 | 2350) {
public setProcessorTypeForFirmwareLoader(processor: 2040 | 2350, isNanoXRP: boolean = false) {
this.PROCESSOR = processor;
this.is_NanoXRP = processor === 2040 && isNanoXRP;
this.connection?.setNanoXRP(this.is_NanoXRP);
}

/**
Expand Down Expand Up @@ -1131,7 +1141,7 @@ export class CommandToXRPMgr {

getFirmwareFilename(): string {
if (this.PROCESSOR === 2350) return 'firmware2350.uf2';
if (this.is_NanoXRP) return 'firnware2040nanoxrp.uf2';
if (this.is_NanoXRP) return 'firmware2040nanoxrp.uf2';
return 'firmware2040.uf2';
}

Expand All @@ -1144,7 +1154,8 @@ export class CommandToXRPMgr {
* @returns the XRP type
*/
getXRPType(): string {
return (this.PROCESSOR! === 2350) ? "V1" : "beta";
if (this.PROCESSOR! === 2350) return "V1";
return this.is_NanoXRP ? "nano" : "beta";
}

}
2 changes: 2 additions & 0 deletions src/utils/i18n/locales/en/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,10 @@
"firmwareWizardStartFlash": "Start firmware copy",
"firmwareWizardStep1Title": "Turn off the board",
"firmwareWizardStep1Body": "Power off your XRP and disconnect it from your computer.",
"firmwareWizardStep1Body_nano": "Power off your XRP, the green LED must be off.",
"firmwareWizardStep2Title": "Enter BOOTSEL mode",
"firmwareWizardStep2Body": "Hold the BOOTSEL button while you connect it to your computer via USB. Then release the BOOT SEL button",
"firmwareWizardStep2Body_nano": "Hold the \"B\" button (the boot button) while you turn the robot back on by pressing the red toggle switch. Then release the boot button.",
"firmwareWizardStep3Title": "Select the boot drive folder",
"firmwareWizardStep3Body": "Click the button below and pick the drive named {{ drive }} (or your board’s USB drive) so the app can write firmware.uf2. If your browser asks for permission to view or edit files on the drive, choose Edit files or Allow.",
"firmwareWizardChooseFolder": "Choose folder…",
Expand Down
2 changes: 2 additions & 0 deletions src/utils/i18n/locales/es/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,10 @@
"firmwareWizardStartFlash": "Iniciar copia del firmware",
"firmwareWizardStep1Title": "Apague la placa",
"firmwareWizardStep1Body": "Apague su XRP y desconéctelo de la computadora.",
"firmwareWizardStep1Body_nano": "Apague su XRP; el LED verde debe estar apagado.",
"firmwareWizardStep2Title": "Entre en modo BOOTSEL",
"firmwareWizardStep2Body": "Mantenga pulsado el botón BOOTSEL mientras conecta la placa a su computadora por USB. Luego suelte el botón BOOT SEL.",
"firmwareWizardStep2Body_nano": "Mantenga pulsado el botón \"B\" (el botón de arranque) mientras vuelve a encender el robot pulsando el interruptor rojo. Luego suelte el botón de arranque.",
"firmwareWizardStep3Title": "Seleccione la carpeta de arranque",
"firmwareWizardStep3Body": "Pulse el botón de abajo y elija la unidad llamada {{ drive }} (o la unidad USB de su placa) para que la aplicación pueda escribir firmware.uf2. Si el navegador pide permiso para ver o editar archivos en la unidad, elija Editar archivos o Permitir.",
"firmwareWizardChooseFolder": "Elegir carpeta…",
Expand Down