view target-utils/loadagent/binflash.c @ 752:c79aaed75bd8

compile-fc-batt: allow possible third field in source lines Battery tables maintained in the fc-battery-conf repository will now have a third field added, defining thresholds for the battery bars icon, and there will be a new utility to compile them into the new /etc/batterytab2 file read by the FC Tourmaline version of our FCHG driver. For backward compatibility with the original Magnetite version of FCHG, compile-fc-batt remains the tool for compiling the original /etc/batterytab file format, and it needs to ignore the newly added third field in battery table sources.
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 05 Nov 2020 20:37:55 +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 */
	}
}