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
* @author Andi Dittrich <http://andidittrich.de>
* @version 1.0
* @license MIT Style X11 License
* @author Andi Dittrich <http://andidittrich.de>
* @version 1.0
* @license MIT Style X11 License
*/
@ -15,29 +15,29 @@
// 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){
*target |= (1<<bit);
*target |= (1<<bit);
};
// 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){
*target &= ~(1<<bit);
*target &= ~(1<<bit);
};
// 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){
*target ^= (1<<bit);
*target ^= (1<<bit);
};
// 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){
if (enable){
BIT_SET(target, bit);
}else{
BIT_CLEAR(target, bit);
}
if (enable){
BIT_SET(target, bit);
}else{
BIT_CLEAR(target, bit);
}
};
#endif /* BITIO_H_ */

View File

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

View File

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

View File

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

View File

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