Replace tabs with spaces
This commit is contained in:
parent
fccd19dbf4
commit
28be3c4e8b
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue