diff --git a/firmware/src/commands.c b/firmware/src/commands.c index 6f8b27d..6b38a85 100644 --- a/firmware/src/commands.c +++ b/firmware/src/commands.c @@ -1,11 +1,12 @@ -#include "config.h" #include "commands.h" +#include "common.h" #include "parsing.h" #include "uart.h" #include "eeprom.h" #include #include +#include #include #include @@ -57,8 +58,33 @@ void commandRead(char* arg) { return; } - // TODO read data and output it - uartPutString("ERR not implemented\n"); + 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) { diff --git a/firmware/src/commands.h b/firmware/src/commands.h index 159a8f3..b1bf0ac 100644 --- a/firmware/src/commands.h +++ b/firmware/src/commands.h @@ -1,7 +1,7 @@ #ifndef COMMANDS_H_ #define COMMANDS_H_ -#include "config.h" +#include "common.h" #include "parsing.h" void executeCommand(CommandLine cmdLine); diff --git a/firmware/src/common.h b/firmware/src/common.h new file mode 100644 index 0000000..ba6e843 --- /dev/null +++ b/firmware/src/common.h @@ -0,0 +1,33 @@ +#ifndef COMMON_H_ +#define COMMON_H_ + +#include "config.h" +#include +#include + +// Define macro for NOP instruction +#define _NOP() __asm__ __volatile__ ("nop"); + +// Define type for EEPROM addresses +typedef uint16_t address_t; + +// Define highest valid address for the EEPROM +#define HIGHEST_VALID_ADDRESS 0x7fff + +// Type definition for address ranges (from-to) +typedef struct { + bool isValid; + address_t from; + address_t to; +} AddressRange; + +// Define type for a block of data (bytes) +typedef struct { + uint8_t* data; + uint8_t maxSize; + uint8_t bytes; +} DataBuffer; + +#define DATA_BLOCK_SIZE 64 + +#endif /* COMMON_H_ */ diff --git a/firmware/src/eeprom.c b/firmware/src/eeprom.c index 619e9fe..7b7e00d 100644 --- a/firmware/src/eeprom.c +++ b/firmware/src/eeprom.c @@ -1,4 +1,3 @@ -#include "config.h" #include "eeprom.h" #include @@ -114,3 +113,37 @@ void eepromWriteByte(address_t address, uint8_t data) { // Write pulse width high (50ns) _NOP(); } + +// Read multiple bytes from EEPROM into a buffer +address_t eepromReadBlock(AddressRange addressRange, DataBuffer* buffer) { + // Set read mode + eepromSetReadMode(); + + buffer->bytes = 0; + + address_t currentAddress = addressRange.from; + address_t highestAddress = addressRange.to; + + if (highestAddress > HIGHEST_VALID_ADDRESS) { + highestAddress = HIGHEST_VALID_ADDRESS; + } + + while (currentAddress <= highestAddress && buffer->bytes < buffer->maxSize) { + buffer->data[buffer->bytes++] = eepromReadByte(currentAddress++); + } + + return currentAddress; +} + +// // Write multiple bytes from a buffer to EEPROM +// address_t eepromWriteBlock(address_t currentAddress, DataBuffer buffer) { +// // Set write mode +// eepromSetWriteMode(); + +// for (uint8_t i = 0; currentAddress <= HIGHEST_VALID_ADDRESS && i < buffer.bytes; i++) { +// eepromWriteByte(currentAddress++, buffer.data[i]); +// // TODO address overflow +// } + +// return currentAddress; +// } diff --git a/firmware/src/eeprom.h b/firmware/src/eeprom.h index 442fbf2..c12bbd2 100644 --- a/firmware/src/eeprom.h +++ b/firmware/src/eeprom.h @@ -2,14 +2,9 @@ #define EEPROM_H_ #include "config.h" +#include "common.h" #include -// Define macro for NOP instruction -#define _NOP() __asm__ __volatile__ ("nop"); - -// Define type for (to be shifted) addresses -typedef uint16_t address_t; - // Define address length // TODO 15 or 16? #define ADDRESS_LENGTH 15 @@ -45,4 +40,10 @@ uint8_t eepromReadByte(address_t address); // Write byte (assumes we're in write mode) void eepromWriteByte(address_t address, uint8_t data); +// Read multiple bytes from EEPROM into a buffer +address_t eepromReadBlock(AddressRange addressRange, DataBuffer* buffer); + +// // Write multiple bytes from a buffer to EEPROM +// address_t eepromWriteBlock(address_t addressRange, DataBuffer buffer); + #endif /* EEPROM_H_ */ diff --git a/firmware/src/main.c b/firmware/src/main.c index cc580f7..70d302d 100644 --- a/firmware/src/main.c +++ b/firmware/src/main.c @@ -1,4 +1,5 @@ #include "config.h" +#include "common.h" #include "uart.h" #include "eeprom.h" #include "parsing.h" diff --git a/firmware/src/parsing.h b/firmware/src/parsing.h index 9885dee..fe15c27 100644 --- a/firmware/src/parsing.h +++ b/firmware/src/parsing.h @@ -1,8 +1,7 @@ #ifndef PARSING_H_ #define PARSING_H_ -#include "config.h" -#include "eeprom.h" +#include "common.h" #include // Type definition for a command line with optional argument (actually just two pointers to strings) @@ -11,13 +10,6 @@ typedef struct { char* arg; } CommandLine; -// Type definition for address ranges (from-to) -typedef struct { - bool isValid; - address_t from; - address_t to; -} AddressRange; - void parseNextCommand(); CommandLine readNextCommand(char* buffer, uint8_t bufferLength); CommandLine tokenizeCommand(char* cmd);