UF2 encode/decode

by Admiral Potato

HTML

<script src="https://wzrd.in/standalone/[email protected]"></script>
<div>
	<input
		type="file"
		name="file_input"
		id="file_input"
	>
</div>
<div>
	<button
		id="encode"
	>encode</button>
	<button
		id="decode"
	>decode</button>
</div>
<div id="download_target">
</div>

JavaScript

console.log('uf2', uf2);

var inputField = document.getElementById('file_input');
var encodeButton = document.getElementById('encode');
var decodeButton = document.getElementById('decode');
var downloadTarget = document.getElementById('download_target');


var ingestedFile = null;

inputField.addEventListener('change', (event) => {
	console.log('Event', event);
	console.log('Event.target.files', event.target.files);
	ingestedFile = event.target.files[0];
});

var prepareDownload = function (data, name) {
	var blob = new Blob(data, { type: 'octet/stream' });
	var url = window.URL.createObjectURL(blob);
	if (this.downloadData) {
		window.URL.revokeObjectURL(this.downloadData.url);
	}
	downloadTarget.innerHTML = `
		<a
			href="${url}"
			target="_blank"
			download="${name}"
		>Download ${name}</a>
	`;
};

var UF2_BLOCK_SIZE = 512;
var UF2_BLOCK_DATA_CAPACITY = 256;
var boardFamily = uf2.familyID('Nordic NRF52840') || 0;
var flashAddress = 0x12000000; // specific to where our NRF speaks to our ROM chip
var flags = (
	uf2.UF2Flags.notMainFlash |
	uf2.UF2Flags.familyIDPresent
);

var encodeUf2File = (sourceArrayBuffer) => {
  var sourceLength = sourceArrayBuffer.byteLength;
  var sourceUint8Array = new Uint8Array(sourceArrayBuffer);
  var totalBlocks = Math.ceil(sourceLength / UF2_BLOCK_DATA_CAPACITY);
  var uf2Size = totalBlocks * UF2_BLOCK_SIZE;
  var uf2ArrayBuffer = new Uint8Array(uf2Size);
  for (var i = 0; i < totalBlocks; i++) {
    var start = i * UF2_BLOCK_DATA_CAPACITY;
    var payload = sourceUint8Array.slice(
      start,
      Math.min(
        sourceLength,
        start + UF2_BLOCK_DATA_CAPACITY
      )
    );
    uf2.encodeBlock(
      {
        boardFamily,
        flags,
        flashAddress,
        blockNumber: i,
        totalBlocks,
        payload,
      },
      uf2ArrayBuffer,
      i * UF2_BLOCK_SIZE
    );
  }
  console.log('Data is ready', {
    sourceArrayBuffer,
    uf2ArrayBuffer,
    sourceLength,
    totalBlocks,
    uf2Size,
  });
 ...