# HG changeset patch # User John Tsiombikas # Date 1488923445 -7200 # Node ID c47d05df066750ca61f7c59af6795baa43c8b747 initial commit diff -r 000000000000 -r c47d05df0667 .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Tue Mar 07 23:50:45 2017 +0200 @@ -0,0 +1,6 @@ +\.o$ +\.swp$ +\.eep$ +\.hex$ +\.map$ +^test_ftdi$ diff -r 000000000000 -r c47d05df0667 Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Tue Mar 07 23:50:45 2017 +0200 @@ -0,0 +1,38 @@ +src = $(wildcard *.c) +obj = $(src:.c=.o) +bin = test_ftdi +hex = $(bin).hex +eep = $(bin).eep + +mcu_gcc = atmega644p +mcu_dude = m644p + +CC = avr-gcc +OBJCOPY = avr-objcopy + +CFLAGS = -Os -pedantic -Wall -mmcu=$(mcu_gcc) -DXTAL=14745600 +LDFLAGS = -Wl,-Map,$(bin).map -mmcu=$(mcu_gcc) -lprintf_min + +.PHONY: all +all: $(hex) $(eep) + +$(bin): $(obj) + $(CC) -o $@ $(obj) $(LDFLAGS) + +$(hex): $(bin) + $(OBJCOPY) -j .text -j .data -O ihex -R .eeprom $< $@ + +$(eep): $(bin) + $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@ + +.PHONY: fuses +fuses: + avrdude -c usbtiny -p $(mcu_dude) -U lfuse:w:0xf7:m -U hfuse:w:0x99:m -U efuse:w:0xff:m + +.PHONY: program +program: $(hex) + avrdude -c usbtiny -p $(mcu_dude) -e -U flash:w:$(hex) + +.PHONY: clean +clean: + rm -f $(bin) $(obj) $(hex) $(eep) $(bin).map diff -r 000000000000 -r c47d05df0667 serial.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/serial.c Tue Mar 07 23:50:45 2017 +0200 @@ -0,0 +1,106 @@ +#ifdef XTAL +#define F_CLK XTAL +#define F_CPU XTAL +#else +#warning "compiled for 1mhz internal rc osc. serial comms won't work" +#define F_CLK 1000000 +#define F_CPU 1000000 +#endif + +#include +#include +#include +#include +#include + +static int uart_send_char(char c, FILE *fp); +static int uart_get_char(FILE *fp); + +#define BUF_SZ 64 +#define BUF_IDX_MASK 0x3f +#define NEXT_IDX(x) (((x) + 1) & BUF_IDX_MASK) +static char outbuf[BUF_SZ]; +static volatile unsigned char out_rd, out_wr; +static char inbuf[BUF_SZ]; +static volatile unsigned char in_rd, in_wr; + +static FILE std_stream = FDEV_SETUP_STREAM(uart_send_char, uart_get_char, _FDEV_SETUP_RW); + + + +void init_serial(long baud) +{ + unsigned int ubrr_val = F_CLK / 16 / baud - 1; + + power_usart0_enable(); + + /* set baud generator timer reset value */ + UBRR0H = (unsigned char)(ubrr_val >> 8); + UBRR0L = (unsigned char)ubrr_val; + + /* enable rx/tx and recv interrupt */ + UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0); + /* set frame format: 8n1 */ + UCSR0C = 3 << UCSZ00; + + stdin = stdout = stderr = &std_stream; +} + +int have_input(void) +{ + return in_wr != in_rd; +} + +static int uart_send_char(char c, FILE *fp) +{ + int next; + + if(c == '\n') { + uart_send_char('\r', fp); + } + + next = NEXT_IDX(out_wr); + while(next == out_rd); + + outbuf[out_wr] = c; + out_wr = next; + + /* enable the Tx data register empty interrupt */ + UCSR0B |= 1 << UDRIE0; + return 0; +} + +static int uart_get_char(FILE *fp) +{ + char c; + + while(in_rd == in_wr); + + c = inbuf[in_rd]; + in_rd = NEXT_IDX(in_rd); + return c; +} + +ISR(USART0_RX_vect) +{ + char c = UDR0; + + if(c == '\r') { + c = '\n'; + } + + inbuf[in_wr] = c; + in_wr = NEXT_IDX(in_wr); +} + +/* USART Tx data register empty (can send more data) */ +ISR(USART0_UDRE_vect) +{ + if(out_rd != out_wr) { + UDR0 = outbuf[out_rd]; + out_rd = NEXT_IDX(out_rd); + } else { + /* no more data to send for now, disable the interrupt */ + UCSR0B &= ~(1 << UDRIE0); + } +} diff -r 000000000000 -r c47d05df0667 serial.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/serial.h Tue Mar 07 23:50:45 2017 +0200 @@ -0,0 +1,7 @@ +#ifndef SERIAL_H_ +#define SERIAL_H_ + +void init_serial(long baud); +int have_input(void); + +#endif /* SERIAL_H_ */ diff -r 000000000000 -r c47d05df0667 test.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test.c Tue Mar 07 23:50:45 2017 +0200 @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include +#include "serial.h" + +void procmd(const char *cmd); + +#define MAX_INPUT_SIZE 128 +static char input[MAX_INPUT_SIZE]; +static unsigned char inp_cidx; + +int main(void) +{ + init_serial(38400); + sei(); + + printf("welcome!\n"); + + for(;;) { + while(have_input()) { + int c = getchar(); + putchar(c); + + if(c == '\r' || c == '\n') { + input[inp_cidx] = 0; + procmd(input); + inp_cidx = 0; + } else if(inp_cidx < sizeof input - 1) { + input[inp_cidx++] = c; + } + } + } + return 0; +} + +void procmd(const char *cmd) +{ + if(strcmp(cmd, "info") == 0) { + printf("test firmware v0\n"); + } else { + printf("unknown command: %s\n", cmd); + } +}