eeprom-programmer/firmware/src/commands.c

159 lines
4.0 KiB
C

#include "commands.h"
#include "common.h"
#include "parsing.h"
#include "uart.h"
#include "eeprom.h"
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <util/delay.h>
// Execute a single parsed command
void executeCommand(CommandLine cmdLine) {
// Parse command
if (strcmp(cmdLine.command, "INIT") == 0) {
// INIT command: Initializes connection.
commandInit();
}
else if (strcmp(cmdLine.command, "READ") == 0) {
// READ command: Takes a hex address range (or single address) as argument,
// reads data and returns it in hexadecimal ASCII format.
commandRead(cmdLine.arg);
}
else if (strcmp(cmdLine.command, "WRITE") == 0) {
// WRITE command: Takes a hex address as argument, reads data from UART and writes it to the EEPROM.
commandRead(cmdLine.arg);
}
else if (strcmp(cmdLine.command, "TESTREAD") == 0) {
// TESTREAD command: for testing purposes, reads a few bytes and returns them in a human readable format.
commandTestRead();
}
else if (strcmp(cmdLine.command, "TESTWRITE") == 0) {
// TESTWRITE command: for testing purposes, writes a few bytes
commandTestWrite(cmdLine.arg);
}
else {
// unknown command: return error message
uartPutString("ERR invalid command\r\n");
}
}
void commandInit() {
// TODO init... or something?
uartPutString("OK\n");
}
void commandRead(char* arg) {
if (arg == NULL) {
uartPutString("ERR READ needs an address or address range\r\n");
return;
}
// Parse address(es)
AddressRange range = parseAddressRange(arg);
if (!range.isValid) {
uartPutString("ERR invalid address format\r\n");
return;
}
uartPutString("OK\n");
uint8_t byteBuffer[DATA_BLOCK_SIZE];
DataBuffer buffer = {
.data = byteBuffer,
.maxSize = DATA_BLOCK_SIZE,
.bytes = 0
};
do {
// Read a single block with up to DATA_BLOCK_SIZE bytes
range.from = eepromReadBlock(range, &buffer);
// TODO binary output
// ASCII output
char outBuffer[20];
sprintf(outBuffer, "<%d>", buffer.bytes);
uartPutString(outBuffer);
for (int i = 0; i < buffer.bytes; i++) {
sprintf(outBuffer, " %02X", buffer.data[i]);
uartPutString(outBuffer);
}
uartPutChar('\n');
} while (buffer.bytes > 0);
}
void commandWrite(char* arg) {
if (arg == NULL) {
uartPutString("ERR WRITE needs a start address\r\n");
return;
}
// Parse address
AddressRange range = parseSingleAddress(arg);
if (!range.isValid) {
uartPutString("ERR invalid address format\r\n");
return;
}
// TODO read data from input and write to EEPROM
uartPutString("ERR not implemented\n");
}
void commandErase() {
// TODO
uartPutString("ERR not implemented\n");
}
// TESTREAD command: for testing purposes, reads a few bytes and returns them in a human readable format.
void commandTestRead() {
uint8_t byte;
char outBuffer[20];
eepromSetReadMode();
for (int i = 0x00; i < 0x20; i++) {
itoa(i, outBuffer, 16);
uartPutString("TESTREAD 0x");
uartPutString(outBuffer);
uartPutString(": ");
byte = eepromReadByte(i);
itoa(byte, outBuffer, 16);
uartPutChar(byte);
uartPutString(" (0x");
uartPutString(outBuffer);
uartPutString(")\r\n");
}
}
// TESTWRITE command: for testing purposes, writes a few bytes
void commandTestWrite(char* arg) {
char str[] = "Ohai world";
address_t addr = 0x00;
char* writeStr = str;
if (arg != NULL) {
writeStr = arg;
}
eepromSetWriteMode();
// write input line instead of static string
for (char* p = writeStr; *p != '\0'; p++) {
eepromWriteByte(addr, *p);
//_delay_ms(100);
addr++;
}
// TODO necessary?
_delay_ms(100);
uartPutString("TESTWRITE success\r\n");
}