From e27176134331aaff7a930ba690961fcd32425ac2 Mon Sep 17 00:00:00 2001 From: Dawid Buchwald Date: Thu, 27 May 2021 23:12:56 +0200 Subject: [PATCH] Added sample UART program --- Software/hello-atmega328p-usbasp/main.c | 92 +++++++++++++++++++++++ Software/hello-atmega328p-usbasp/makefile | 82 ++++++++++++++++++++ 2 files changed, 174 insertions(+) create mode 100644 Software/hello-atmega328p-usbasp/main.c create mode 100644 Software/hello-atmega328p-usbasp/makefile diff --git a/Software/hello-atmega328p-usbasp/main.c b/Software/hello-atmega328p-usbasp/main.c new file mode 100644 index 0000000..4781602 --- /dev/null +++ b/Software/hello-atmega328p-usbasp/main.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include + +#define BAUD 9600 +#include + +void uart_init(); +int uart_putchar(char c, FILE *stream); +int uart_getchar(FILE *stream); +void uart_send(char c); +char uart_recv(void); + +FILE uart_output = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); +FILE uart_input = FDEV_SETUP_STREAM(NULL, uart_getchar, _FDEV_SETUP_READ); + +int main(void) +{ + // Configure PB5 as an output using the Port B Data Direction Register (DDRB) + DDRB |= _BV(DDB0); + + // init serial interface + uart_init(); + + // redirect standard output + stdout = &uart_output; + stdin = &uart_input; + + // Loop forever + while (1) + { + // Set PB5 high using the Port B Data Register (PORTB) + PORTB |= _BV(PORTB0); + + // Wait 500ms + _delay_ms(200); + + // Set PB5 low using the Port B Data Register (PORTB) + PORTB &= ~_BV(PORTB0); + + // Wait 500ms + _delay_ms(200); + + // Wait for input from serial + getc(stdin); + + // Print hello + printf("Hello World!\n"); + } +} + +void uart_init() +{ + UBRR0H = UBRRH_VALUE; + UBRR0L = UBRRL_VALUE; + #if USE_2X + UCSR0A |= (1 << U2X0); + #else + UCSR0A &= ~(1 << U2X0); + #endif + + UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); /* 8-bit data, async, no parity, 1 stop bit */ + UCSR0B = _BV(RXEN0) | _BV(TXEN0); /* Enable RX and TX */ +} + +int uart_putchar(char c, FILE *stream) +{ + if (c == '\n') + { + uart_putchar('\r', stream); + } + uart_send(c); + return 0; +} + +int uart_getchar(FILE *stream) +{ + return uart_recv(); +} + +void uart_send(char c) +{ + loop_until_bit_is_set(UCSR0A, UDRE0); + UDR0 = c; +} + +char uart_recv(void) +{ + loop_until_bit_is_set(UCSR0A, RXC0); + return UDR0; +} diff --git a/Software/hello-atmega328p-usbasp/makefile b/Software/hello-atmega328p-usbasp/makefile new file mode 100644 index 0000000..3785fea --- /dev/null +++ b/Software/hello-atmega328p-usbasp/makefile @@ -0,0 +1,82 @@ +NAME := main +BUILD_FOLDER=build +HEX := $(BUILD_FOLDER)/$(NAME).hex +OUT := $(BUILD_FOLDER)/$(NAME).out +MAP := $(BUILD_FOLDER)/$(NAME).map +SOURCES := $(wildcard *.c) +HEADERS := $(wildcard *.h) +OBJECTS := $(patsubst %.c,$(BUILD_FOLDER)/%.o,$(SOURCES)) + +MCU := atmega328p +MCU_AVRDUDE := m328p +PARTNO := usbasp +DEVICE := usb +AVRDUDE_FLAGS := -v -B 5 + +CC := avr-gcc +OBJCOPY := avr-objcopy +SIZE := avr-size -A + +CFLAGS := -Wall -pedantic -mmcu=$(MCU) -std=c99 -g -Os -DF_CPU=1000000UL + +# Picocom settings +PICOCOM_BINARY=picocom +PICOCOM_FLAGS=-fn +TERM_SPEED=-b9600 + +# efuse 11111101 +# efuse bits 7..3 = 11111 (default) +# efuse bits 2..0 = 101 (BOD 2.7V) +EFUSE := 0xfd + +# hfuse 11010111 +# hfuse bit 7 = 1 (external reset enabled) +# hfuse bit 6 = 1 (debugWire disabled) +# hfuse bit 5 = 0 (SPI programming enabled) +# hfuse bit 4 = 1 (watchdog timer always on) +# hfuse bit 3 = 0 (retain EEPROM) +# hfuse bits 2..1 = 11 (bootloader size 256 - no bootloader) +# hfuse bit 0 = 1 (boot reset vector unprogrammed) +HFUSE := 0xd7 + +# lfuse 01100010 +# lfuse bit 7 = 0 (clock divide by 8 enabled) +# lfuse bit 6 = 1 (clock output disabled) +# lfuse bits 5..4 = 10 (maximum startup time) +# lfuse bits 3..0 = 0010 (internal RC oscillator at 1MHz) +LFUSE := 0x62 + +all: $(HEX) $(BUILD_FOLDER) + +clean: + rm -rf $(HEX) $(OUT) $(MAP) $(OBJECTS) $(BUILD_FOLDER) + +$(BUILD_FOLDER): + mkdir $(BUILD_FOLDER) + +flash: $(HEX) + avrdude $(AVRDUDE_FLAGS) -c $(PARTNO) -p $(MCU_AVRDUDE) -P $(DEVICE) -U flash:w:$(HEX) + +fuses: + avrdude $(AVRDUDE_FLAGS) -c $(PARTNO) -p $(MCU_AVRDUDE) -P $(DEVICE) -U efuse:w:$(EFUSE):m -U hfuse:w:$(HFUSE):m -U lfuse:w:$(LFUSE):m + +terminal: + $(PICOCOM_BINARY) $(PICOCOM_FLAGS) $(TERM_SPEED) /dev/tty.usbserial-D309UUZL + +$(HEX): $(OUT) + $(OBJCOPY) -R .eeprom -O ihex $< $@ + +$(OUT): $(OBJECTS) + $(CC) $(CFLAGS) -o $@ -Wl,-Map,$(MAP) $^ + @echo + @$(SIZE) $@ + @echo + +$(BUILD_FOLDER)/%.o: %.c $(HEADERS) $(BUILD_FOLDER) + $(CC) $(CFLAGS) -c -o $@ $< + +$(BUILD_FOLDER)/%.pp: %.c $(BUILD_FOLDER) + $(CC) $(CFLAGS) -E -o $@ $< + +$(BUILD_FOLDER)/%.ppo: %.c $(BUILD_FOLDER) + $(CC) $(CFLAGS) -E $< \ No newline at end of file