avr_firmware: Add prelim. ATmega32 platform; add LCD support

This commit is contained in:
2015-06-25 00:22:15 +02:00
parent b569efafc8
commit 2d1d386785
8 changed files with 217 additions and 8 deletions

View File

@@ -1,12 +1,17 @@
CC=avr-gcc
CCOPTS=-mmcu=atmega164a -std=c11 -flto -Os -ggdb -Wall -Wextra -pedantic -DF_CPU=8000000UL
#CCOPTS=-mmcu=atmega164a -std=c11 -flto -Os -ggdb -Wall -Wextra -pedantic -DF_CPU=8000000UL
CCOPTS=-mmcu=atmega32 -std=c11 -flto -Os -ggdb -Wall -Wextra -pedantic -DF_CPU=8000000UL
CCSRCS ::= uart.c main.c modem.c timer.c
CCSRCS ::= uart.c main.c modem.c timer.c lcd.c
all: fw.elf
prog: fw.elf
sudo avrdude -c avrisp2 -p m32 -U flash:w:$<
fw.elf: $(addprefix objs/,$(CCSRCS:.c=.o))
$(CC) $(CCOPTS) -o $@ $^
@size $@
objs/%.o: src/%.c
$(CC) $(CCOPTS) -c -MMD -MP -o $@ $<
@@ -18,3 +23,5 @@ clean:
$(addprefix objs/,$(CCSRCS:.c=.P))
-include $(addprefix objs/,$(CCSRCS:.c=.P))
.PHONY: clean all prog

View File

@@ -1,4 +1,14 @@
#define LCD_DPORT PORTC
#define LCD_DDDR DDRC
#define LCD_DPIN PINC
#define LCD_CPORT PORTA
#define LCD_CDDR DDRA
#define LCD_RS 0
#define LCD_RW 1
#define LCD_EN 2
#define UART0_CTS_PORT PIND
#define UART0_RTS_PORT PIND
#define UART0_CTS 5

98
avr_firmware/src/lcd.c Normal file
View File

@@ -0,0 +1,98 @@
#include <stdbool.h>
#include <stdint.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "config.h"
#include "lcd.h"
#define LCD_CMASK ((_BV(LCD_RS) | _BV(LCD_RW) | (_BV(LCD_EN))))
uint8_t _lcdRead(bool rs)
{
LCD_CPORT = (LCD_CPORT & ~LCD_CMASK) | _BV(LCD_RW) | (rs?_BV(LCD_RS):0);
LCD_DDDR = 0x00;
LCD_CPORT |= _BV(LCD_EN);
_delay_us(0.32);
uint8_t ret = LCD_DPIN;
LCD_CPORT &= ~_BV(LCD_EN);
_delay_us(0.06);
return ret;
}
void _lcdWrite(bool rs, uint8_t data)
{
LCD_CPORT = (LCD_CPORT & ~LCD_CMASK) | (rs?_BV(LCD_RS):0);
LCD_DDDR = 0xff;
LCD_DPORT = data;
LCD_CPORT |= _BV(LCD_EN);
_delay_us(0.45);
LCD_CPORT &= ~_BV(LCD_EN);
}
void _lcdBusyWait()
{
while (_lcdRead(false) & _BV(7));
}
uint8_t lcdRead(bool rs)
{
_lcdBusyWait();
return _lcdRead(rs);
}
void lcdWrite(bool rs, uint8_t data)
{
_lcdBusyWait();
_lcdWrite(rs, data);
}
void lcdWriteStr(char const* str)
{
while (*str != '\0')
lcdWrite(true, (uint8_t)*str++);
}
void lcdWriteStrP(char const* str)
{
char c;
while ((c = pgm_read_byte(str++)) != '\0')
lcdWrite(true, (uint8_t)c);
}
static const uint8_t lineLUT[4] PROGMEM = {0x00, 0x40, 0x14, 0x54};
void lcdSetPos(unsigned x, unsigned y)
{
const uint8_t adr = pgm_read_byte(&lineLUT[y]) + x;
lcdWrite(false, 0x80 | adr);
}
int lcdInit()
{
LCD_DDDR = 0x00;
LCD_CDDR |= LCD_CMASK;
lcdWrite(false, 0x38);
lcdWrite(false, 0x0c);
lcdWrite(false, 0x01);
lcdWrite(false, 0x06);
lcdWrite(false, 0x80);
return 0;
}

11
avr_firmware/src/lcd.h Normal file
View File

@@ -0,0 +1,11 @@
#ifndef DMXGSM_AVR_LCD_H
#define DMXGSM_AVR_LCD_H
int lcdInit();
void lcdWriteStr(char const* str);
void lcdWriteStrP(char const* str);
void lcdSetPos(unsigned x, unsigned y);
#endif

View File

@@ -1,16 +1,54 @@
#include <stdbool.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <avr/io.h>
#include <avr/sleep.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "timer.h"
#include "modem.h"
#include "uart.h"
#include "lcd.h"
int main()
{
const unsigned char osccal = eeprom_read_byte(0);
OSCCAL = osccal;
DDRD = 1<<7;
timerInit();
uart0Init();
sei();
lcdInit();
uart0Init();
lcdWriteStrP(PSTR("Hallo, Welt!"));
lcdSetPos(0, 1);
char buf[6];
utoa(osccal, buf, 16);
lcdWriteStrP(PSTR("OSCCAL = 0x"));
lcdWriteStr(buf);
unsigned oldSeconds = 0;
while (true) {
sleep_mode();
unsigned seconds = timerGetSeconds();
if (seconds != oldSeconds) {
utoa(seconds, buf, 10);
lcdSetPos(0,2);
lcdWriteStr(buf);
oldSeconds = seconds;
}
}
modemInit();
//modemInit();
//xmitPPP("TEST", 4);
}

View File

@@ -3,15 +3,25 @@
#include "timer.h"
volatile unsigned timerTicks;
volatile unsigned timerTicks, timerSeconds;
ISR(TIMER0_OVF_vect, ISR_NOBLOCK)
ISR(TIMER1_COMPA_vect, ISR_NOBLOCK)
{
static unsigned ledTicks = 0;
++timerTicks;
if (ledTicks >= 24) {
PORTD ^= (1<<7);
ledTicks = 0;
++timerSeconds;
} else
++ledTicks;
}
int timerInit()
{
#ifndef __AVR_ATmega32__
TCCR0A = 0; // CTC mode
TCCR0B = _BV(CS02) | _BV(CS00); // CTC mode, /1024 clk
@@ -19,7 +29,16 @@ int timerInit()
timerTicks = 0u;
TIMSK0 = _BV(TOIE0);
#else
TCCR1A = 0;
TCCR1B = _BV(WGM12) | _BV(CS02); // CTC mode, /256 clk
OCR1AH = 0x02;
OCR1AL = 0x70; // 50 Hz timer ticks
timerTicks = 0u;
timerSeconds = 0u;
TIMSK = _BV(OCIE1A);
#endif
return 0;
}
@@ -27,3 +46,8 @@ unsigned timerGetTicks()
{
return timerTicks;
}
unsigned timerGetSeconds()
{
return timerSeconds>>1;
}

View File

@@ -4,5 +4,6 @@
int timerInit();
unsigned timerGetTicks();
unsigned timerGetSeconds();
#endif

View File

@@ -12,6 +12,22 @@
static volatile unsigned char _uart0RXbuf[UART_RXBUF_SIZE];
static volatile size_t _uart0RXwr, _uart0RXrd;
#ifdef __AVR_ATmega32__
#define USART0_RX_vect USART_RXC_vect
#define UDR0 UDR
#define UBRR0H UBRRH
#define UBRR0L UBRRL
#define UCSR0A UCSRA
#define UCSR0B UCSRB
#define UCSR0C UCSRC
#define RXCIE0 RXCIE
#define RXEN0 RXEN
#define TXEN0 TXEN
#define UCSZ01 UCSZ1
#define UCSZ00 UCSZ0
#define UDRE0 UDRE
#endif
ISR(USART0_RX_vect)
{
_uart0RXbuf[_uart0RXwr++] = UDR0;
@@ -26,23 +42,27 @@ void uart0Init()
UBRR0L = 12; // 38400 baud
UCSR0A = 0;
UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0);
UCSR0B = _BV(RXEN0) | _BV(TXEN0);
UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); // 8 bit, 1 stop, no parity
_uart0RXwr = 0;
_uart0RXrd = UART_RXBUF_SIZE-1;
UCSR0B |= _BV(RXCIE0);
UART0_RTS_PORT |= _BV(UART0_RTS);
}
void uart1Init()
{
#ifndef __AVR_ATmega32__
UBRR1H = 0;
UBRR1L = 1; // 250k baud
UCSR1A = 0;
UCSR1B = _BV(UDRIE1) | _BV(TXEN1);
UCSR1C = _BV(USBS1) | _BV(UCSZ01) | _BV(UCSZ00); // 8 bit, 2 stop, no parity
#endif
}
void uart0Xmit(unsigned char data)