added uart test to projects

master
Ondřej Hruška 9 years ago
parent d464545207
commit 312ab6d897
  1. 8
      projects/rgb_random_wander/lib/README.md
  2. 137
      projects/uart_test/Makefile
  3. 6
      projects/uart_test/lib/meta.h
  4. 97
      projects/uart_test/lib/uart.c
  5. 43
      projects/uart_test/lib/uart.h
  6. 49
      projects/uart_test/main.c

@ -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.

@ -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

@ -0,0 +1,6 @@
#pragma once
/** Weird constructs for the compiler */
// general macros
#define SECTION(pos) __attribute__((naked, used, section(pos)))

@ -0,0 +1,97 @@
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <stdbool.h>
#include <stdint.h>
#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;
}

@ -0,0 +1,43 @@
#pragma once
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <stdbool.h>
#include <stdint.h>
/** 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();

@ -0,0 +1,49 @@
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <stdint.h>
#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);
}
Loading…
Cancel
Save