view target-utils/loadagent/binload.c @ 1000:39a6090a052a

doc/How-flash-really-works: article written
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 09 Dec 2023 09:08:19 +0000
parents 3229940734e5
children
line wrap: on
line source

/*
 * Here we are going to implement our new binary protocol for RAM loading
 * for a faster version of fc-xram.
 */

#include "types.h"

void
cmd_binary_memload()
{
	int state, recptr, extlen, datalen;
	u8 record[256], cksum;
	u32 addr;
	u16 rec_count;
	int c, i;

	rec_count = 0;
	for (state = 0; ; ) {
		switch (state) {
		case 0:
			c = serial_in_timeout(3000000);		/* 1.8 s */
			if (c < 0 || c == 0x04)
				return;
			if (c == 0x05) {
				serial_out(0x06);	/* ACK */
				serial_out(rec_count >> 8);
				serial_out(rec_count);
				continue;
			}
			if (c >= 6) {
				record[0] = c;
				extlen = c + 1;
				datalen = c - 5;
				recptr = 1;
				state = 1;
				continue;
			}
			serial_out(0x15);	/* NAK */
			state = 2;
			continue;
		case 1:
			c = serial_in_timeout(1000000);		/* 0.6 s */
			if (c < 0) {
				serial_out(0x15);	/* NAK */
				state = 2;
				continue;
			}
			record[recptr++] = c;
			if (recptr < extlen)
				continue;
			/* verify checksum */
			cksum = 0;
			for (i = 0; i < extlen; i++)
				cksum += record[i];
			if (cksum != 0xFF) {
				serial_out(0x15);	/* NAK */
				state = 2;
				continue;
			}
			addr =  ((u32)record[1] << 24) |
				((u32)record[2] << 16) |
				((u32)record[3] << 8) |
				 (u32)record[4];
			memcpy(addr, record + 5, datalen);
			rec_count++;
			state = 0;
			continue;
		default:
			c = serial_in_timeout(10000000);	/* 6.15 s */
			if (c < 0)
				return;
			serial_out_if_empty(0x15);	/* NAK */
			continue;
		}
	}
}