@@ -1219,73 +1219,84 @@ function* handleFlashEV3(action: ReturnType<typeof firmwareFlashEV3>): Generator
12191219
12201220 defined ( version ) ;
12211221
1222- console . debug (
1223- `EV3 bootloader version: ${ version . getUint32 (
1224- 0 ,
1225- true ,
1226- ) } , HW version: ${ version . getUint32 ( 4 , true ) } `,
1227- ) ;
1222+ try {
1223+ console . debug (
1224+ `EV3 bootloader version: ${ version . getUint32 (
1225+ 0 ,
1226+ true ,
1227+ ) } , HW version: ${ version . getUint32 ( 4 , true ) } `,
1228+ ) ;
1229+ } catch ( err ) {
1230+ console . error ( `Failed to parse ev3 version response: ${ ensureError ( err ) } ` ) ;
1231+ }
12281232
12291233 // FIXME: should be called much earlier.
12301234 yield * put ( didStart ( ) ) ;
12311235
12321236 const sectorSize = 64 * 1024 ; // flash memory sector size
12331237 const maxPayloadSize = 1018 ; // maximum payload size for EV3 commands
12341238
1235- for ( let i = 0 ; i < action . firmware . byteLength ; i += sectorSize ) {
1236- const sectorData = action . firmware . slice ( i , i + sectorSize ) ;
1237- assert ( sectorData . byteLength <= sectorSize , 'sector data too large' ) ;
1239+ console . info ( `Firmware size: ${ action . firmware . byteLength } bytes` ) ;
1240+
1241+ // Extend firmware to sector alignment
1242+ const numSectors = Math . ceil ( action . firmware . byteLength / sectorSize ) ;
1243+ const alignedSize = numSectors * sectorSize ;
1244+ const alignedFirmware = new Uint8Array ( alignedSize ) ;
1245+ alignedFirmware . set ( new Uint8Array ( action . firmware ) ) ;
1246+ // Remaining bytes are already zeroed by Uint8Array constructor
12381247
1239- const erasePayload = new DataView ( new ArrayBuffer ( 8 ) ) ;
1240- erasePayload . setUint32 ( 0 , i , true ) ;
1241- erasePayload . setUint32 ( 4 , sectorData . byteLength , true ) ;
1242- const [ , eraseError ] = yield * sendCommand (
1243- 0xf0 ,
1244- new Uint8Array ( erasePayload . buffer ) ,
1248+ console . info ( `Aligned firmware size: ${ alignedSize } bytes (${ numSectors } sectors)` ) ;
1249+
1250+ // Erase all sectors at once
1251+ const erasePayload = new DataView ( new ArrayBuffer ( 8 ) ) ;
1252+ erasePayload . setUint32 ( 0 , 0 , true ) ; // start address
1253+ erasePayload . setUint32 ( 4 , alignedSize , true ) ; // size
1254+ const [ , eraseError ] = yield * sendCommand (
1255+ 0xf0 ,
1256+ new Uint8Array ( erasePayload . buffer ) ,
1257+ ) ;
1258+
1259+ if ( eraseError ) {
1260+ yield * put (
1261+ alertsShowAlert ( 'alerts' , 'unexpectedError' , {
1262+ error : eraseError ,
1263+ } ) ,
12451264 ) ;
1265+ // FIXME: should have a better error reason
1266+ yield * put ( didFailToFinish ( FailToFinishReasonType . Unknown , eraseError ) ) ;
1267+ yield * put ( firmwareDidFailToFlashEV3 ( ) ) ;
1268+ yield * cleanup ( ) ;
1269+ return ;
1270+ }
1271+
1272+ // Flash the whole firmware in chunks
1273+ for ( let i = 0 ; i < alignedFirmware . byteLength ; i += maxPayloadSize ) {
1274+ const payload = alignedFirmware . slice ( i , i + maxPayloadSize ) ;
12461275
1247- if ( eraseError ) {
1276+ const [ , sendError ] = yield * sendCommand ( 0xf2 , payload ) ;
1277+ if ( sendError ) {
12481278 yield * put (
12491279 alertsShowAlert ( 'alerts' , 'unexpectedError' , {
1250- error : eraseError ,
1280+ error : sendError ,
12511281 } ) ,
12521282 ) ;
12531283 // FIXME: should have a better error reason
1254- yield * put ( didFailToFinish ( FailToFinishReasonType . Unknown , eraseError ) ) ;
1284+ yield * put ( didFailToFinish ( FailToFinishReasonType . Unknown , sendError ) ) ;
12551285 yield * put ( firmwareDidFailToFlashEV3 ( ) ) ;
12561286 yield * cleanup ( ) ;
12571287 return ;
12581288 }
12591289
1260- for ( let j = 0 ; j < sectorData . byteLength ; j += maxPayloadSize ) {
1261- const payload = sectorData . slice ( j , j + maxPayloadSize ) ;
1262-
1263- const [ , sendError ] = yield * sendCommand ( 0xf2 , new Uint8Array ( payload ) ) ;
1264- if ( sendError ) {
1265- yield * put (
1266- alertsShowAlert ( 'alerts' , 'unexpectedError' , {
1267- error : sendError ,
1268- } ) ,
1269- ) ;
1270- // FIXME: should have a better error reason
1271- yield * put ( didFailToFinish ( FailToFinishReasonType . Unknown , sendError ) ) ;
1272- yield * put ( firmwareDidFailToFlashEV3 ( ) ) ;
1273- yield * cleanup ( ) ;
1274- return ;
1275- }
1276- }
1277-
1278- yield * put (
1279- didProgress ( ( i + sectorData . byteLength ) / action . firmware . byteLength ) ,
1280- ) ;
1290+ const progress = ( i + payload . byteLength ) / alignedFirmware . byteLength ;
1291+ yield * put ( didProgress ( progress ) ) ;
12811292
12821293 yield * put (
12831294 alertsShowAlert (
12841295 'firmware' ,
12851296 'flashProgress' ,
12861297 {
12871298 action : 'flash' ,
1288- progress : ( i + sectorData . byteLength ) / action . firmware . byteLength ,
1299+ progress : progress ,
12891300 } ,
12901301 firmwareBleProgressToastId ,
12911302 true ,
0 commit comments