view target-utils/loadagent/binflash.c @ 928:65953c172f24

rvinterf/lowlevel: new hex dump format
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 23 May 2023 05:23:19 +0000
parents b34384991094
children
line wrap: on
line source

/*
 * Here we are going to implement our new binary protocol
 * for flash programming.
 */

#include "types.h"

void
binary_flash_prog_main(program_func)
	int (*program_func)();
{
	u8 buf[2048] __attribute__ ((aligned (2)));
	u32 flash_offset;
	unsigned nbytes, p;
	int c;

	for (;;) {
		do
			c = serial_in_poll();
		while (c < 0);
		if (c == 0x04)
			return;
		if (c != 0x01) {
			serial_out(0x15);	/* NAK */
			printf("ERROR: invalid command opcode\n");
			return;
		}
		/* receive header */
		for (p = 0; p < 6; p++) {
			c = serial_in_timeout(1000000);		/* 0.6 s */
			if (c < 0) {
intermediate_timeout:		serial_out(0x15);	/* NAK */
				printf("ERROR: timeout receiving command\n");
				return;
			}
			buf[p] = c;
		}
		flash_offset =  ((u32) buf[0] << 24) |
				((u32) buf[1] << 16) |
				((u32) buf[2] << 8) |
				 (u32) buf[3];
		if (flash_offset & 1) {
			serial_out(0x15);	/* NAK */
			printf("ERROR: odd flash offset\n");
			return;
		}
		nbytes = ((u32) buf[4] << 8) | (u32) buf[5];
		if (nbytes & 1) {
			serial_out(0x15);	/* NAK */
			printf("ERROR: odd byte count\n");
			return;
		}
		if (nbytes > sizeof buf) {
			serial_out(0x15);	/* NAK */
			printf("ERROR: byte count exceeds buffer\n");
			return;
		}
		/* receive data */
		for (p = 0; p < nbytes; p++) {
			c = serial_in_timeout(1000000);		/* 0.6 s */
			if (c < 0)
				goto intermediate_timeout;
			buf[p] = c;
		}
		c = program_func(flash_offset, nbytes >> 1, buf);
		if (c < 0)
			return;
		serial_out(0x06);	/* ACK */
	}
}