Compare commits

..

No commits in common. "213a1430894a1561f903c82420f01c3e61ffdcfb" and "1f668b60327028263f460e7ba4011a448b27fc1b" have entirely different histories.

8 changed files with 111 additions and 88 deletions

View File

@ -6,7 +6,6 @@
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <util/delay.h> #include <util/delay.h>
@ -37,6 +36,14 @@ void executeCommand(CommandLine cmdLine) {
// ERASE command: Takes a hex address range as argument and writes 0x00 bytes to the specified range. // ERASE command: Takes a hex address range as argument and writes 0x00 bytes to the specified range.
commandErase(cmdLine.arg); commandErase(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 { else {
// unknown command: return error message // unknown command: return error message
uartPutLine("ERROR invalid command"); uartPutLine("ERROR invalid command");
@ -72,6 +79,11 @@ void commandHelp() {
uartPutLine("HELP - READ 0000:0FFF"); uartPutLine("HELP - READ 0000:0FFF");
uartPutLine("HELP - WRITE 0000"); uartPutLine("HELP - WRITE 0000");
uartPutLine("HELP - ERASE 0000:0FFF"); uartPutLine("HELP - ERASE 0000:0FFF");
// TODO remove those
uartPutLine("HELP - TESTREAD (only for testing)");
uartPutLine("HELP - TESTWRITE (only for testing)");
uartPutLine("OK"); uartPutLine("OK");
} }
@ -90,12 +102,14 @@ void commandRead(char* arg) {
uartPutLine("OK"); uartPutLine("OK");
// Create data buffer uint8_t byteBuffer[DATA_BLOCK_SIZE];
DataBuffer buffer; DataBuffer buffer = {
.data = byteBuffer,
.maxSize = DATA_BLOCK_SIZE,
.bytes = 0
};
do { do {
buffer.bytes = 0;
// Read a single block with up to DATA_BLOCK_SIZE bytes // Read a single block with up to DATA_BLOCK_SIZE bytes
Address nextAddress = eepromReadBlock(range, &buffer); Address nextAddress = eepromReadBlock(range, &buffer);
range.isValid = nextAddress.isValid; range.isValid = nextAddress.isValid;
@ -106,16 +120,16 @@ void commandRead(char* arg) {
// First the size of the package (1 byte) followed by the data bytes // First the size of the package (1 byte) followed by the data bytes
uartPutChar(buffer.bytes); uartPutChar(buffer.bytes);
for (uint8_t i = 0; i < buffer.bytes; i++) { for (int i = 0; i < buffer.bytes; i++) {
uartPutChar(buffer.data[i]); uartPutChar(buffer.data[i]);
} }
} else { } else {
// Fancy ASCII output // Fancy ASCII output
uartPutString("<0x"); uartPutChar('<');
uartPutHexByte(buffer.bytes); uartPutInteger(buffer.bytes);
uartPutChar('>'); uartPutChar('>');
for (uint8_t i = 0; i < buffer.bytes; i++) { for (int i = 0; i < buffer.bytes; i++) {
uartPutChar(' '); uartPutChar(' ');
uartPutHexByte(buffer.data[i]); uartPutHexByte(buffer.data[i]);
} }
@ -144,12 +158,17 @@ void commandWrite(char* arg) {
return; return;
} }
// Create data buffer
uint8_t byteBuffer[DATA_BLOCK_SIZE];
DataBuffer buffer = {
.data = byteBuffer,
.maxSize = DATA_BLOCK_SIZE,
.bytes = 0
};
// "OK" indicates that data can be sent now. // "OK" indicates that data can be sent now.
uartPutLine("OK START"); uartPutLine("OK START");
// Create data buffer
DataBuffer buffer;
Address currentAddress = startAddress; Address currentAddress = startAddress;
uint8_t block_length = 0; uint8_t block_length = 0;
@ -160,8 +179,10 @@ void commandWrite(char* arg) {
// Read and check block length // Read and check block length
block_length = uartGetChar(); block_length = uartGetChar();
if (block_length > DATA_BLOCK_SIZE) { if (block_length > buffer.maxSize) {
uartPutLine("ERROR maximal block size is: " STR(DATA_BLOCK_SIZE)); uartPutString("ERROR maximal block size is: ");
uartPutInteger(buffer.maxSize);
uartPutLine(NULL);
return; return;
} }
@ -174,6 +195,9 @@ void commandWrite(char* arg) {
if (buffer.bytes > 0) { if (buffer.bytes > 0) {
currentAddress = eepromWriteBlock(currentAddress, buffer); currentAddress = eepromWriteBlock(currentAddress, buffer);
// TODO wait necessary?
//_delay_ms(100);
if (!currentAddress.isValid) { if (!currentAddress.isValid) {
uartPutLine("ERROR reached end of EEPROM while writing block"); uartPutLine("ERROR reached end of EEPROM while writing block");
return; return;
@ -195,28 +219,54 @@ void commandWrite(char* arg) {
uartPutLine("OK END"); uartPutLine("OK END");
} }
void commandErase(char* arg) { void commandErase() {
if (arg == NULL) { uartPutLine("ERROR not implemented");
uartPutLine("ERROR ERASE needs a start address"); }
return;
}
// Parse address(es) // TESTREAD command: for testing purposes, reads a few bytes and returns them in a human readable format.
AddressRange range = parseAddressRange(arg); void commandTestRead() {
if (!range.isValid || range.to < range.from) { eepromSetReadMode();
uartPutLine("ERROR invalid address format");
return;
}
uint32_t bytesErased = eepromEraseBlock(range); for (uint8_t i = 0x00; i < 0x20; i++) {
uartPutString("TESTREAD 0x");
uartPutHexByte(i);
uartPutString(": ");
if (bytesErased == 0) { uint8_t byte = eepromReadByte(i);
uartPutLine("ERROR 0 bytes erased");
} else { if (byte >= 32 && byte <= 126) {
char outBuffer[16]; uartPutChar(byte);
snprintf(outBuffer, 16, "%lu", bytesErased); } else {
uartPutString("OK erased "); uartPutChar('?');
uartPutString(outBuffer); }
uartPutLine(" bytes");
uartPutString(" (0x");
uartPutHexByte(byte);
uartPutLine(")");
} }
} }
// 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);
uartPutLine("TESTWRITE success");
}

View File

@ -12,4 +12,8 @@ void commandRead(char* arg);
void commandWrite(char* arg); void commandWrite(char* arg);
void commandErase(); void commandErase();
// TODO commands only for testing
void commandTestRead();
void commandTestWrite(char* arg);
#endif /* COMMANDS_H_ */ #endif /* COMMANDS_H_ */

View File

@ -8,10 +8,6 @@
// Define macro for NOP instruction // Define macro for NOP instruction
#define _NOP() __asm__ __volatile__ ("nop"); #define _NOP() __asm__ __volatile__ ("nop");
// Define macro to convert a preprocessor constant to a string literal
#define STR_(x) #x
#define STR(x) STR_(x)
// Define type for EEPROM addresses // Define type for EEPROM addresses
typedef uint16_t address_t; typedef uint16_t address_t;
@ -32,11 +28,12 @@ typedef struct {
} AddressRange; } AddressRange;
// Define type for a block of data (bytes) // Define type for a block of data (bytes)
#define DATA_BLOCK_SIZE 64
typedef struct { typedef struct {
uint8_t data[DATA_BLOCK_SIZE]; uint8_t* data;
uint8_t maxSize;
uint8_t bytes; uint8_t bytes;
} DataBuffer; } DataBuffer;
#define DATA_BLOCK_SIZE 64
#endif /* COMMON_H_ */ #endif /* COMMON_H_ */

View File

@ -132,7 +132,7 @@ Address eepromReadBlock(AddressRange addressRange, DataBuffer* buffer) {
highestAddress = HIGHEST_VALID_ADDRESS; highestAddress = HIGHEST_VALID_ADDRESS;
} }
while (currentAddress <= highestAddress && buffer->bytes < DATA_BLOCK_SIZE) { while (currentAddress <= highestAddress && buffer->bytes < buffer->maxSize) {
buffer->data[buffer->bytes++] = eepromReadByte(currentAddress++); buffer->data[buffer->bytes++] = eepromReadByte(currentAddress++);
// Handle integer overflow // Handle integer overflow
@ -172,34 +172,3 @@ Address eepromWriteBlock(Address startAddress, DataBuffer buffer) {
return (Address) {true, currentAddress}; return (Address) {true, currentAddress};
} }
// Erase block of data on the EEPROM
uint32_t eepromEraseBlock(AddressRange addressRange) {
// Set write mode
eepromSetWriteMode();
if (!addressRange.isValid) {
return 0;
}
address_t currentAddress = addressRange.from;
address_t highestAddress = addressRange.to;
if (highestAddress > HIGHEST_VALID_ADDRESS) {
highestAddress = HIGHEST_VALID_ADDRESS;
}
uint32_t bytesErased = 0;
while (currentAddress <= highestAddress) {
eepromWriteByte(currentAddress++, 0x00);
bytesErased++;
// Handle integer overflow
if (currentAddress == 0) {
break;
}
}
return bytesErased;
}

View File

@ -5,6 +5,10 @@
#include "common.h" #include "common.h"
#include <avr/io.h> #include <avr/io.h>
// Define address length
// TODO 15 or 16?
#define ADDRESS_LENGTH 15
// Macros for IO pins // Macros for IO pins
#define EEP_ADDR_LOW_PORT PORTC #define EEP_ADDR_LOW_PORT PORTC
#define EEP_ADDR_LOW_DDR DDRC #define EEP_ADDR_LOW_DDR DDRC
@ -42,7 +46,4 @@ Address eepromReadBlock(AddressRange addressRange, DataBuffer* buffer);
// Write multiple bytes from a buffer to EEPROM // Write multiple bytes from a buffer to EEPROM
Address eepromWriteBlock(Address startAddress, DataBuffer buffer); Address eepromWriteBlock(Address startAddress, DataBuffer buffer);
// Erase block of data on the EEPROM
uint32_t eepromEraseBlock(AddressRange addressRange);
#endif /* EEPROM_H_ */ #endif /* EEPROM_H_ */

View File

@ -13,7 +13,7 @@
// Read and parse command line and dispatch command // Read and parse command line and dispatch command
void parseNextCommand() { void parseNextCommand() {
const int bufferLength = 40; const int bufferLength = 80;
char buffer[bufferLength]; char buffer[bufferLength];
// Read next command // Read next command

View File

@ -4,15 +4,8 @@
#include <avr/io.h> #include <avr/io.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <util/setbaud.h> #include <util/setbaud.h>
// Hexadecimal digit lookup table
static const char hexDigitLookupTable[] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
// Initialize UART // Initialize UART
void uartInit() { void uartInit() {
// Set Baud register // Set Baud register
@ -63,12 +56,18 @@ void uartPutLine(char* data) {
uartPutChar('\n'); uartPutChar('\n');
} }
// Convert an integer to decimal ASCII and transmit
void uartPutInteger(int value) {
char outBuffer[32];
snprintf(outBuffer, 32, "%d", value);
uartPutString(outBuffer);
}
// Convert a byte to hexadecimal ASCII and transmit // Convert a byte to hexadecimal ASCII and transmit
void uartPutHexByte(uint8_t byte) { void uartPutHexByte(uint8_t byte) {
// First hex digit: most significant 4 bits char outBuffer[8];
uartPutChar(hexDigitLookupTable[(byte >> 4) & 0x0f]); snprintf(outBuffer, 8, "%02hhX", byte);
// Second hex digit: least significant 4 bits uartPutString(outBuffer);
uartPutChar(hexDigitLookupTable[byte & 0x0f]);
} }
// Receive a single character (blocking) // Receive a single character (blocking)

View File

@ -16,6 +16,9 @@ void uartPutString(char* data);
// Transmit a string followed by a line break // Transmit a string followed by a line break
void uartPutLine(char* data); void uartPutLine(char* data);
// Convert an integer to decimal ASCII and transmit
void uartPutInteger(int value);
// Convert a byte to hexadecimal ASCII and transmit // Convert a byte to hexadecimal ASCII and transmit
void uartPutHexByte(uint8_t byte); void uartPutHexByte(uint8_t byte);