From 312ab6d897e605e3d7ba3ecbaf04321e3f88252c Mon Sep 17 00:00:00 2001 From: MightyPork Date: Thu, 23 Apr 2015 22:35:58 +0200 Subject: [PATCH] added uart test to projects --- projects/rgb_random_wander/lib/README.md | 8 -- projects/uart_test/Makefile | 137 +++++++++++++++++++++++ projects/uart_test/lib/meta.h | 6 + projects/uart_test/lib/uart.c | 97 ++++++++++++++++ projects/uart_test/lib/uart.h | 43 +++++++ projects/uart_test/main.c | 49 ++++++++ 6 files changed, 332 insertions(+), 8 deletions(-) delete mode 100644 projects/rgb_random_wander/lib/README.md create mode 100644 projects/uart_test/Makefile create mode 100644 projects/uart_test/lib/meta.h create mode 100644 projects/uart_test/lib/uart.c create mode 100644 projects/uart_test/lib/uart.h create mode 100644 projects/uart_test/main.c diff --git a/projects/rgb_random_wander/lib/README.md b/projects/rgb_random_wander/lib/README.md deleted file mode 100644 index 7ac9922..0000000 --- a/projects/rgb_random_wander/lib/README.md +++ /dev/null @@ -1,8 +0,0 @@ -AVR utils library -================= - -This is my ever-evolving library (not only) for AVR programming. - -When I'm done with a project, I copy the current library to the project, so it doesn't break when I do further improvements. - -Each library file contains a large comment block explaining it's function. diff --git a/projects/uart_test/Makefile b/projects/uart_test/Makefile new file mode 100644 index 0000000..c05c801 --- /dev/null +++ b/projects/uart_test/Makefile @@ -0,0 +1,137 @@ +## === CPU settings === +# CPU type +MCU = atmega328p +# CPU frequency +F_CPU = 16000000 +# Fuses +LFUSE = 0xFF +HFUSE = 0xDE +EFUSE = 0x05 + + +## === Source files === +# Main C file +MAIN = main.c +# Extra C files in this folder +LOCAL_SOURCE = + +# Library directory (with C files) +EXTRA_SOURCE_DIR = lib/ +# C files in the library directory +EXTRA_SOURCE_FILES = uart.c + + +## === Programmer === +PROGRAMMER_TYPE = arduino +PROGRAMMER_ARGS = -b 57600 -P /dev/ttyUSB0 + + +## === C flags === + +CFLAGS = -std=gnu99 -mmcu=$(MCU) -DF_CPU=$(F_CPU)UL -I. -I$(EXTRA_SOURCE_DIR) +CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums +CFLAGS += -Wall -Wno-main -Wno-strict-prototypes -Wno-comment +CFLAGS += -g2 -Wextra -Wfatal-errors -Wno-unused-but-set-variable +CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--relax +# CFLAGS += -lm ## Math +# CFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm ## for floating-point printf +# CFLAGS += -Wl,-u,vfprintf -lprintf_min ## for smaller printf +CFLAGS_BUILD = $(CFLAGS) -Os + + +# --------------------------------------------------------------------------- + +## Defined programs / locations +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +AVRSIZE = avr-size +AVRDUDE = avrdude + +## === File lists === +TARGET = $(strip $(basename $(MAIN))) +SRC1 = $(TARGET).c +SRC = $(SRC1) +EXTRA_SOURCE = $(addprefix $(EXTRA_SOURCE_DIR), $(EXTRA_SOURCE_FILES)) +SRC += $(EXTRA_SOURCE) +SRC += $(LOCAL_SOURCE) + +HEADERS = $(SRC:.c=.h) +OBJ = $(SRC:.c=.o) + + +## === File generation === +all: $(TARGET).hex size +pre: $(TARGET).pre + +%.hex: %.elf + $(OBJCOPY) -R .eeprom -O ihex $< $@ + +%.elf: $(SRC) + $(CC) $(CFLAGS_BUILD) $(SRC) --output $@ + +%.pre: $(SRC1) + $(CC) $(CFLAGS) -E $(SRC1) --output $@ + +%.eeprom: %.elf + $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@ + +%.lst: %.elf + $(OBJDUMP) -S $< > $@ + +# Show debug info +debug: + @echo + @echo "Source files:" $(SRC) + @echo "MCU, F_CPU, BAUD:" $(MCU), $(F_CPU), $(BAUD) + @echo + + +# Disassemble the ELF +disassemble: $(TARGET).lst +dis: disassemble +lst: disassemble + +# Make eeprom file +eeprom: $(TARGET).eeprom + +# Show how big the resulting program is +size: $(TARGET).elf + $(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf + +# Clean all produced trash +clean: + rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \ + $(TARGET).o $(TARGET).d $(TARGET).eep $(TARGET).lst \ + $(TARGET).lss $(TARGET).sym $(TARGET).map $(TARGET)~ \ + $(TARGET).eeprom + +# Clean all trash +purge: + rm -f *.elf *.hex *.obj *.o *.d *.eep *.lst *.lss *.sym *.map *~ + + +## === avrdude === + +flash: $(TARGET).hex + $(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$< + +flashe: $(TARGET).eeprom + $(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U eeprom:w:$< + +shell: + $(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nt + + +# === fuses === + +FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m + +fuses: + $(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) \ + $(PROGRAMMER_ARGS) $(FUSE_STRING) +show_fuses: + $(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nv + +set_default_fuses: FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m +set_default_fuses: fuses diff --git a/projects/uart_test/lib/meta.h b/projects/uart_test/lib/meta.h new file mode 100644 index 0000000..ec16799 --- /dev/null +++ b/projects/uart_test/lib/meta.h @@ -0,0 +1,6 @@ +#pragma once + +/** Weird constructs for the compiler */ + +// general macros +#define SECTION(pos) __attribute__((naked, used, section(pos))) diff --git a/projects/uart_test/lib/uart.c b/projects/uart_test/lib/uart.c new file mode 100644 index 0000000..f16b0b5 --- /dev/null +++ b/projects/uart_test/lib/uart.c @@ -0,0 +1,97 @@ +#include +#include +#include +#include +#include + +#include "uart.h" + +void _uart_init_do(uint16_t ubrr) { + /*Set baud rate */ + UBRR0H = (uint8_t) (ubrr >> 8); + UBRR0L = (uint8_t) ubrr; + + // Enable Rx and Tx + UCSR0B = (1 << RXEN0) | (1 << TXEN0); + + // 8-bit data, 1 stop bit + UCSR0C = (0b11 << UCSZ00); +} + + +/** Enable or disable RX ISR */ +void uart_isr_rx(bool yes) +{ + if(yes) { + UCSR0B |= (1 << RXCIE0); + } else { + UCSR0B &= ~(1 << RXCIE0); + } +} + +/** Enable or disable TX ISR (1 byte is sent) */ +void uart_isr_tx(bool yes) +{ + if(yes) { + UCSR0B |= (1 << TXCIE0); + } else { + UCSR0B &= ~(1 << TXCIE0); + } +} + +/** Enable or disable DRE ISR (all is sent) */ +void uart_isr_dre(bool yes) +{ + if(yes) { + UCSR0B |= (1 << UDRIE0); + } else { + UCSR0B &= ~(1 << UDRIE0); + } +} + + + + +/** Send byte over UART */ +void uart_tx(uint8_t data) +{ + // Wait for transmit buffer + while (!uart_tx_ready()); + // send it + UDR0 = data; +} + +/** Send string over UART */ +void uart_puts(const char* str) +{ + while (*str) { + uart_tx(*str++); + } +} + +/** Send progmem string over UART */ +void uart_puts_pgm(const char* str) +{ + char c; + while ((c = pgm_read_byte(str++))) { + uart_tx(c); + } +} + +/** Receive one byte over UART */ +uint8_t uart_rx() +{ + // Wait for data to be received + while (!uart_rx_ready()); + // Get and return received data from buffer + return UDR0; +} + +/** Clear receive buffer */ +void uart_flush() +{ + uint8_t dummy; + while (UCSR0A & (1 << RXC0)) + dummy = UDR0; +} + diff --git a/projects/uart_test/lib/uart.h b/projects/uart_test/lib/uart.h new file mode 100644 index 0000000..fad3a9f --- /dev/null +++ b/projects/uart_test/lib/uart.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include +#include +#include +#include + +/** Init UART for given baudrate */ +#define uart_init(baud) _uart_init_do(F_CPU / 16 / (baud) - 1) + +void _uart_init_do(uint16_t ubrr); + +/** Check if there's a byte in the RX register */ +#define uart_rx_ready() (0 != (UCSR0A & (1 << RXC0))) + +/** Check if transmission of everything is done */ +#define uart_tx_ready() (0 != (UCSR0A & (1 << UDRE0))) + +/** Enable or disable RX ISR */ +void uart_isr_rx(bool enable); + +/** Enable or disable TX ISR (1 byte is sent) */ +void uart_isr_tx(bool enable); + +/** Enable or disable DRE ISR (all is sent) */ +void uart_isr_dre(bool enable); + +/** Send byte over UART */ +#define uart_putc(data) uart_tx(data) +void uart_tx(uint8_t data); + +/** Send string over UART */ +void uart_puts(const char* str); + +/** Send progmem string over UART */ +void uart_puts_pgm(const char* str); + +/** Receive one byte over UART */ +uint8_t uart_rx(); + +/** Clear receive buffer */ +void uart_flush(); diff --git a/projects/uart_test/main.c b/projects/uart_test/main.c new file mode 100644 index 0000000..aaed3e2 --- /dev/null +++ b/projects/uart_test/main.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#include + +#include "lib/meta.h" +#include "lib/uart.h" + +const char str[] PROGMEM = "Hello UART!\r\n"; + + +// Echo, but with ROT13. +ISR(USART_RX_vect) +{ + char c = uart_rx(); + + if (c == 13) { + uart_tx(10); + uart_tx(13); + return; + } + + if ((c >= 'a' && c <= 'm') || (c >= 'A' && c <= 'M')) { + c += 13; + } else + if ((c >= 'n' && c <= 'z') || (c >= 'N' && c <= 'Z')) { + c -= 13; + } + + uart_tx(c); +} + + +void SECTION(".init8") init() +{ + uart_init(9600); + uart_isr_rx(1); + sei(); +} + + +void main() +{ + uart_puts_pgm(str); + + while(1); +}