Replace tabs with spaces

This commit is contained in:
Lexi / Zoe 2021-04-03 18:44:22 +02:00
parent fccd19dbf4
commit 28be3c4e8b
Signed by: binaryDiv
GPG Key ID: F8D4956E224DA232
5 changed files with 242 additions and 242 deletions

View File

@ -1,8 +1,8 @@
/** /**
* BitIO.h * BitIO.h
* @author Andi Dittrich <http://andidittrich.de> * @author Andi Dittrich <http://andidittrich.de>
* @version 1.0 * @version 1.0
* @license MIT Style X11 License * @license MIT Style X11 License
*/ */
@ -15,29 +15,29 @@
// set bit // set bit
static inline void BIT_SET(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline)); static inline void BIT_SET(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));
static inline void BIT_SET(volatile uint8_t *target, uint8_t bit){ static inline void BIT_SET(volatile uint8_t *target, uint8_t bit){
*target |= (1<<bit); *target |= (1<<bit);
}; };
// set clear // set clear
static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline)); static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));
static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit){ static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit){
*target &= ~(1<<bit); *target &= ~(1<<bit);
}; };
// bit toogle // bit toogle
static inline void BIT_TOGGLE(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline)); static inline void BIT_TOGGLE(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));
static inline void BIT_TOGGLE(volatile uint8_t *target, uint8_t bit){ static inline void BIT_TOGGLE(volatile uint8_t *target, uint8_t bit){
*target ^= (1<<bit); *target ^= (1<<bit);
}; };
// set bit by boolean // set bit by boolean
static inline void BIT_BOOL_SET(volatile uint8_t *target, uint8_t bit, bool enable) __attribute__((always_inline)); static inline void BIT_BOOL_SET(volatile uint8_t *target, uint8_t bit, bool enable) __attribute__((always_inline));
static inline void BIT_BOOL_SET(volatile uint8_t *target, uint8_t bit, bool enable){ static inline void BIT_BOOL_SET(volatile uint8_t *target, uint8_t bit, bool enable){
if (enable){ if (enable){
BIT_SET(target, bit); BIT_SET(target, bit);
}else{ }else{
BIT_CLEAR(target, bit); BIT_CLEAR(target, bit);
} }
}; };
#endif /* BITIO_H_ */ #endif /* BITIO_H_ */

View File

@ -7,110 +7,110 @@
// Initialize EEPROM // Initialize EEPROM
void eepromInit() { void eepromInit() {
// Set initial value for control port (all disabled -- INVERTED VALUES, ~CE, ~OE, ~WE) // Set initial value for control port (all disabled -- INVERTED VALUES, ~CE, ~OE, ~WE)
BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_CE); BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_CE);
BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_OE); BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_OE);
BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_WE); BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_WE);
// Set data direction register for control port // Set data direction register for control port
EEP_CTRL_DDR |= (1 << EEP_CTRL_BIT_CE) EEP_CTRL_DDR |= (1 << EEP_CTRL_BIT_CE)
| (1 << EEP_CTRL_BIT_OE) | (1 << EEP_CTRL_BIT_OE)
| (1 << EEP_CTRL_BIT_WE); | (1 << EEP_CTRL_BIT_WE);
// Set initial value for address (0x0000) // Set initial value for address (0x0000)
EEP_ADDR_LOW_PORT = 0x00; EEP_ADDR_LOW_PORT = 0x00;
EEP_ADDR_HIGH_PORT = 0x00; EEP_ADDR_HIGH_PORT = 0x00;
// Set data direction register for address ports // Set data direction register for address ports
EEP_ADDR_LOW_DDR = 0xFF; EEP_ADDR_LOW_DDR = 0xFF;
EEP_ADDR_HIGH_DDR = 0xFF; EEP_ADDR_HIGH_DDR = 0xFF;
// Set data direction register and initial value for IO port (initialize in reading mode) // Set data direction register and initial value for IO port (initialize in reading mode)
EEP_DATA_PORT = 0x00; EEP_DATA_PORT = 0x00;
EEP_DATA_DDR = 0x00; EEP_DATA_DDR = 0x00;
} }
// Enable read mode (set data direction registers and enable output) // Enable read mode (set data direction registers and enable output)
void eepromSetReadMode() { void eepromSetReadMode() {
// Reset control bits (shouldn't be necessary, but let's be safe) // Reset control bits (shouldn't be necessary, but let's be safe)
BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_CE); BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_CE);
BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_OE); BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_OE);
BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_WE); BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_WE);
// Set data pins as input, reset PORT to disable pullups // Set data pins as input, reset PORT to disable pullups
EEP_DATA_PORT = 0x00; EEP_DATA_PORT = 0x00;
EEP_DATA_DDR = 0x00; EEP_DATA_DDR = 0x00;
} }
// Enable write mode (set data direction registers) // Enable write mode (set data direction registers)
void eepromSetWriteMode() { void eepromSetWriteMode() {
// Reset control bits (shouldn't be necessary, but let's be safe) // Reset control bits (shouldn't be necessary, but let's be safe)
BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_CE); BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_CE);
BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_OE); BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_OE);
BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_WE); BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_WE);
// Set data pins as output, reset data port // Set data pins as output, reset data port
EEP_DATA_PORT = 0x00; EEP_DATA_PORT = 0x00;
EEP_DATA_DDR = 0xFF; EEP_DATA_DDR = 0xFF;
} }
// Set address // Set address
static inline void eepromSetAddress(address_t address) { static inline void eepromSetAddress(address_t address) {
// Set low and high address bytes // Set low and high address bytes
// (We actually only have 15 bit, the 16th will just be ignored) // (We actually only have 15 bit, the 16th will just be ignored)
EEP_ADDR_LOW_PORT = address & 0xFF; EEP_ADDR_LOW_PORT = address & 0xFF;
EEP_ADDR_HIGH_PORT = address >> 8; EEP_ADDR_HIGH_PORT = address >> 8;
} }
// Read byte (assumes we're in read mode) // Read byte (assumes we're in read mode)
uint8_t eepromReadByte(address_t address) { uint8_t eepromReadByte(address_t address) {
// Assume we're in read mode // Assume we're in read mode
// Set address // Set address
eepromSetAddress(address); eepromSetAddress(address);
// Latch address // Latch address
BIT_CLEAR(&EEP_CTRL_PORT, EEP_CTRL_BIT_CE); BIT_CLEAR(&EEP_CTRL_PORT, EEP_CTRL_BIT_CE);
BIT_CLEAR(&EEP_CTRL_PORT, EEP_CTRL_BIT_OE); BIT_CLEAR(&EEP_CTRL_PORT, EEP_CTRL_BIT_OE);
// 1 tick = 62.5 ns, EEPROM access time is 150 ns. // 1 tick = 62.5 ns, EEPROM access time is 150 ns.
// 2 NOPs seem to be sufficient, but let's be sure. // 2 NOPs seem to be sufficient, but let's be sure.
_NOP(); _NOP();
_NOP(); _NOP();
_NOP(); _NOP();
// Get data // Get data
uint8_t byte = EEP_DATA_PIN; uint8_t byte = EEP_DATA_PIN;
// Reset ~OE, ~CE // Reset ~OE, ~CE
BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_OE); BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_OE);
BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_CE); BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_CE);
// Read and return data byte // Read and return data byte
return byte; return byte;
} }
// Write byte (assumes we're in write mode) // Write byte (assumes we're in write mode)
void eepromWriteByte(address_t address, uint8_t data) { void eepromWriteByte(address_t address, uint8_t data) {
// Assume we're in write mode // Assume we're in write mode
// Set address // Set address
eepromSetAddress(address); eepromSetAddress(address);
// Falling edge: latch address // Falling edge: latch address
BIT_CLEAR(&EEP_CTRL_PORT, EEP_CTRL_BIT_CE); BIT_CLEAR(&EEP_CTRL_PORT, EEP_CTRL_BIT_CE);
BIT_CLEAR(&EEP_CTRL_PORT, EEP_CTRL_BIT_WE); BIT_CLEAR(&EEP_CTRL_PORT, EEP_CTRL_BIT_WE);
// Set data byte // Set data byte
EEP_DATA_PORT = data; EEP_DATA_PORT = data;
// Data setup time (50ns) // Data setup time (50ns)
_NOP(); _NOP();
// Rising edge: latch data, start write cycle // Rising edge: latch data, start write cycle
BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_WE); BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_WE);
BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_CE); BIT_SET(&EEP_CTRL_PORT, EEP_CTRL_BIT_CE);
// Write pulse width high (50ns) // Write pulse width high (50ns)
_NOP(); _NOP();
} }

View File

@ -6,18 +6,18 @@
#include <util/delay.h> #include <util/delay.h>
int main(void) { int main(void) {
// Init components (UART, EEPROM, ...) // Init components (UART, EEPROM, ...)
uartInit(); uartInit();
eepromInit(); eepromInit();
// Initial pause (EEPROM needs 5ms startup time) // Initial pause (EEPROM needs 5ms startup time)
_delay_ms(100); _delay_ms(100);
// Write initial message via UART // Write initial message via UART
uartPutString("INFO -- EEPROM programmer by binaryDiv\r\n"); uartPutString("INFO -- EEPROM programmer by binaryDiv\r\n");
while(1) { while(1) {
// Run main loop endlessly // Run main loop endlessly
protocolMainLoop(); protocolMainLoop();
} }
} }

View File

@ -11,131 +11,131 @@
// Splits a command "CMD ARGS" to two strings "CMD" and "ARGS". Returns pointer // Splits a command "CMD ARGS" to two strings "CMD" and "ARGS". Returns pointer
// to "ARGS" or NULL if no arguments were found. Changes the input string! // to "ARGS" or NULL if no arguments were found. Changes the input string!
char* tokenizeCommand(char* cmd) { char* tokenizeCommand(char* cmd) {
if (cmd == NULL) { if (cmd == NULL) {
return NULL; return NULL;
} }
// Search for a space character // Search for a space character
for (char* p = cmd; *p != '\0'; p++) { for (char* p = cmd; *p != '\0'; p++) {
if (*p == ' ') { if (*p == ' ') {
// Split strings by replacing the space by \0, then return pointer // Split strings by replacing the space by \0, then return pointer
// to command arguments // to command arguments
*p++ = '\0'; *p++ = '\0';
return p; return p;
} }
} }
// No space character found: command has no arguments, return NULL // No space character found: command has no arguments, return NULL
return NULL; return NULL;
} }
// Reads, parses and executes next command // Reads, parses and executes next command
void parseNextCommand() { void parseNextCommand() {
const int bufferLength = 80; const int bufferLength = 80;
char buffer[bufferLength]; char buffer[bufferLength];
// Read next command // Read next command
int readChars = uartGetLine(buffer, bufferLength); int readChars = uartGetLine(buffer, bufferLength);
// Check if line is non-empty and has been read completely // Check if line is non-empty and has been read completely
if (readChars == 0) { if (readChars == 0) {
return; return;
} }
else if (readChars >= bufferLength-1) { else if (readChars >= bufferLength-1) {
// Reading was aborted after bufferLength-1 characters to prevent // Reading was aborted after bufferLength-1 characters to prevent
// buffer overflow. // buffer overflow.
// TODO Actually this isn't quite correct: if exactly bufferLen-1 // TODO Actually this isn't quite correct: if exactly bufferLen-1
// characters have been read including the \n, this could be // characters have been read including the \n, this could be
// true as well... test this? // true as well... test this?
uartPutString("ERROR buffer overflow while reading line\r\n"); uartPutString("ERROR buffer overflow while reading line\r\n");
return; return;
} }
// Tokenize command // Tokenize command
char* cmd = buffer; char* cmd = buffer;
char* args = tokenizeCommand(cmd); char* args = tokenizeCommand(cmd);
// Parse command // Parse command
if (strcmp(cmd, "HELLO") == 0) { if (strcmp(cmd, "HELLO") == 0) {
// HELLO command: initializes connection // HELLO command: initializes connection
uartPutString("OHAI\r\n"); uartPutString("OHAI\r\n");
} }
else if (strcmp(cmd, "READ") == 0) { else if (strcmp(cmd, "READ") == 0) {
// READ command: takes a hex address or address range as argument, // READ command: takes a hex address or address range as argument,
// reads data and returns them in hexadecimal ASCII format. // reads data and returns them in hexadecimal ASCII format.
// Check if arguments exist // Check if arguments exist
if (args == NULL) { if (args == NULL) {
uartPutString("ERROR READ needs an address\r\n"); uartPutString("ERROR READ needs an address\r\n");
return; return;
} }
// Parse address(es) // Parse address(es)
// TODO // TODO
uartPutString(args); uartPutString(args);
// Read... // Read...
// TODO // TODO
} }
else if (strcmp(cmd, "TESTREAD") == 0) { else if (strcmp(cmd, "TESTREAD") == 0) {
// TESTREAD command: for testing purposes, reads a few bytes and // TESTREAD command: for testing purposes, reads a few bytes and
// returns them in a human readable format. // returns them in a human readable format.
uint8_t byte; uint8_t byte;
char outBuffer[20]; char outBuffer[20];
eepromSetReadMode(); eepromSetReadMode();
for (int i = 0x00; i < 0x20; i++) { for (int i = 0x00; i < 0x20; i++) {
itoa(i, outBuffer, 16); itoa(i, outBuffer, 16);
uartPutString("TESTREAD 0x"); uartPutString("TESTREAD 0x");
uartPutString(outBuffer); uartPutString(outBuffer);
uartPutString(": "); uartPutString(": ");
byte = eepromReadByte(i); byte = eepromReadByte(i);
itoa(byte, outBuffer, 16); itoa(byte, outBuffer, 16);
uartPutChar(byte); uartPutChar(byte);
uartPutString(" (0x"); uartPutString(" (0x");
uartPutString(outBuffer); uartPutString(outBuffer);
uartPutString(")\r\n"); uartPutString(")\r\n");
} }
} }
else if (strcmp(cmd, "TESTWRITE") == 0) { else if (strcmp(cmd, "TESTWRITE") == 0) {
// TESTWRITE command: for testing purposes, writes a few bytes // TESTWRITE command: for testing purposes, writes a few bytes
char str[] = "Ohai world"; char str[] = "Ohai world";
address_t addr = 0x00; address_t addr = 0x00;
char* writeStr = str; char* writeStr = str;
if (args != NULL) { if (args != NULL) {
writeStr = args; writeStr = args;
} }
eepromSetWriteMode(); eepromSetWriteMode();
// write input line instead of static string // write input line instead of static string
for (char* p = writeStr; *p != '\0'; p++) { for (char* p = writeStr; *p != '\0'; p++) {
eepromWriteByte(addr, *p); eepromWriteByte(addr, *p);
//_delay_ms(100); //_delay_ms(100);
addr++; addr++;
} }
// TODO necessary? // TODO necessary?
_delay_ms(100); _delay_ms(100);
uartPutString("TESTWRITE success\r\n"); uartPutString("TESTWRITE success\r\n");
} }
else { else {
// unknown command: return error message // unknown command: return error message
uartPutString("ERROR invalid command\r\n"); uartPutString("ERROR invalid command\r\n");
} }
} }
// Runs main loop to parse commands // Runs main loop to parse commands
void protocolMainLoop() { void protocolMainLoop() {
while(1) { while(1) {
// Parse next command // Parse next command
parseNextCommand(); parseNextCommand();
} }
} }

View File

@ -6,88 +6,88 @@
// Initialize UART // Initialize UART
void uartInit() { void uartInit() {
// Set Baud register // Set Baud register
UBRRH = UBRRH_VALUE; UBRRH = UBRRH_VALUE;
UBRRL = UBRRL_VALUE; UBRRL = UBRRL_VALUE;
// Reset status register // Reset status register
UCSRA = 0x00; UCSRA = 0x00;
#if USE_2X #if USE_2X
// U2X mode necessary // U2X mode necessary
UCSRA |= (1 << U2X); UCSRA |= (1 << U2X);
#else #else
// U2X mode not necessary // U2X mode not necessary
UCSRA &= ~(1 << U2X); UCSRA &= ~(1 << U2X);
#endif #endif
// Enable transmitter and receiver // Enable transmitter and receiver
UCSRB |= (1 << TXEN) | (1 << RXEN); UCSRB |= (1 << TXEN) | (1 << RXEN);
// Set frame format (8 bit) // Set frame format (8 bit)
UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0); UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);
} }
// Transmit a single character // Transmit a single character
void uartPutChar(unsigned char data) { void uartPutChar(unsigned char data) {
// Block until controller is ready to send // Block until controller is ready to send
while (!(UCSRA & (1 << UDRE))) { while (!(UCSRA & (1 << UDRE))) {
} }
// Write character to UART data register // Write character to UART data register
UDR = data; UDR = data;
} }
// Transmit a string // Transmit a string
void uartPutString(char* data) { void uartPutString(char* data) {
// Write characters until \0 is reached // Write characters until \0 is reached
while (*data) { while (*data) {
uartPutChar(*data++); uartPutChar(*data++);
} }
} }
// Receive a single character (blocking) // Receive a single character (blocking)
unsigned char uartGetChar() { unsigned char uartGetChar() {
// Block until a character has been received // Block until a character has been received
while (!(UCSRA & (1 << RXC))) { while (!(UCSRA & (1 << RXC))) {
} }
// Get character and return // Get character and return
return UDR; return UDR;
} }
// Receive a string until \n (blocking) // Receive a string until \n (blocking)
uint8_t uartGetLine(char* buffer, uint8_t maxLength) { uint8_t uartGetLine(char* buffer, uint8_t maxLength) {
uint8_t readChars = 0; uint8_t readChars = 0;
unsigned char nextChar; unsigned char nextChar;
// Read a maximum of maxLength-1 characters (-1 because we need one char for '\0') // Read a maximum of maxLength-1 characters (-1 because we need one char for '\0')
while (readChars < maxLength - 1) { while (readChars < maxLength - 1) {
// Get next character // Get next character
nextChar = uartGetChar(); nextChar = uartGetChar();
// Skip trailing \n and \r // Skip trailing \n and \r
if (nextChar == '\n' || nextChar == '\r') { if (nextChar == '\n' || nextChar == '\r') {
if (readChars == 0) { if (readChars == 0) {
// Skip trailing \n and \r // Skip trailing \n and \r
continue; continue;
} }
else { else {
// End line (do not append the \r or \n to the buffer) // End line (do not append the \r or \n to the buffer)
break; break;
} }
} }
// Write character to buffer // Write character to buffer
*buffer++ = nextChar; *buffer++ = nextChar;
// Increment counter // Increment counter
readChars++; readChars++;
} }
// Write a terminating '\0' byte // Write a terminating '\0' byte
*buffer++ = '\0'; *buffer++ = '\0';
// Return number of read bytes (excluding the \0) // Return number of read bytes (excluding the \0)
return readChars; return readChars;
} }