Compare commits
No commits in common. "213a1430894a1561f903c82420f01c3e61ffdcfb" and "1f668b60327028263f460e7ba4011a448b27fc1b" have entirely different histories.
213a143089
...
1f668b6032
|
|
@ -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");
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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_ */
|
||||||
|
|
|
||||||
|
|
@ -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_ */
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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_ */
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue