# HG changeset patch # User Thinker K.F. Li # Date 1235202599 -28800 # Node ID a0ce8ebf2f188f8ad91aedda7472460a3a8d610d LED on PINB0 & PINB1 and UART testing. - LED flasing on PINB0 & PINB1. - print 'hello' messages to UART for every flashing round. diff -r 000000000000 -r a0ce8ebf2f18 include/avriotools.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/avriotools.h Sat Feb 21 15:49:59 2009 +0800 @@ -0,0 +1,65 @@ +#ifndef __AVRIOTOOLS_H_ +#define __AVRIOTOOLS_H_ +#include +#include + +typedef enum {PM_INPUT, PM_OUTPUT} pin_mode_t; + +extern int pin_mode(volatile uint8_t * port, int pin, pin_mode_t mode); +#define pin_hi(port, pin) do { port |= _BV(pin); } while(0) +#define pin_lo(port, pin) do { port &= ~_BV(pin); } while(0) + + +#define UBRRH UBRR0L +#define UBRRL UBRR0L +#define UCSRA UCSR0A +#define U2X U2X0 +#define UDRE UDRE0 +#define UDR UDR0 +#define RXC RXC0 +#define FE FE0 +#define DOR DOR0 + +extern int uart_init(uint32_t baud); +#define uart_getc(c) \ + do { \ + loop_until_bit_is_set(UCSRA, RXC); \ + if (UCSRA & _BV(FE)) \ + continue; \ + if (UCSRA & _BV(DOR)) \ + continue; \ + c = UDR; \ + } while(0) +/* + * c == -1 if not data been read. + * \note c must be an integer. + */ +#define uart_getc_nowait(c) \ + do { \ + c = -1; \ + if(bit_is_clear(UCSRA, RXC)) break; \ + if (UCSRA & _BV(FE)) \ + break; \ + if (UCSRA & _BV(DOR)) \ + break; \ + c = UDR; \ + } while(0) +#define uart_putc(c) \ + do { \ + loop_until_bit_is_set(UCSRA, UDRE); \ + UDR = ((uint8_t)(c & 0xff)); \ + } while(0) +/* + * c == -1 if it been wrote out. + * \note c must be an integer. + */ +#define uart_putc_nowait(c) \ + do { \ + if(bit_is_clear(UCSRA, UDRE)) \ + break; \ + UDR = ((uint8_t)(c & 0xff)); \ + c = -1; \ + } while(0) + + +#endif /* __AVRIOTOOLS_H_ */ diff -r 000000000000 -r a0ce8ebf2f18 src/avriotools.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/avriotools.c Sat Feb 21 15:49:59 2009 +0800 @@ -0,0 +1,76 @@ +#include "avriotools.h" +#include + +typedef struct _port_regs { + volatile uint8_t *port, *ddr, *pin; +} port_regs_t; + +static port_regs_t regs[] = { + { &PORTB, &DDRB, &PINB }, + { &PORTD, &DDRD, &PIND } +}; +#define NPORTS (sizeof(regs) / sizeof(*regs)) + +#define ERR -1 +#define OK 0 + +int pin_mode(volatile uint8_t * port, int pin, pin_mode_t mode) { + port_regs_t *preg; + int i; + + for(i = 0; i < NPORTS; i++) { + preg = regs + i; + if(preg->port == port) + break; + } + if(i == NPORTS) + return ERR; + + switch(mode) { + case PM_INPUT: + *preg->ddr &= ~_BV(pin); + *preg->port |= _BV(pin); + break; + + case PM_OUTPUT: + *preg->ddr |= _BV(pin); + break; + + default: + return ERR; + } + + return OK; +} + +/* To make setbaud.h no more complaint */ +#define BAUD 9600 +#include + +int uart_init(uint32_t baud) { + unsigned long ubrr_v; + long err; + + if(baud > (F_CPU / 8)) + return ERR; + +#define F_CPUx2 (F_CPU * 2UL) + + ubrr_v = (F_CPU + baud * 8UL) / (baud * 16UL) - 1UL; + /* Allow bias of baud rate in 2%, or use U2X clock. + * ATmega168 divides baud rate generator clock by 2, 8, or 16. + * Setting U2X bit makes the clock divided by 8 instead of 16. + * It makes more accurately output and higher max baud rate. + */ + err = 16L * 100L * (ubrr_v + 1) * baud - F_CPU * 100L; + if(err > F_CPUx2 || err < -F_CPUx2 || ubrr_v < 2) { + ubrr_v = (F_CPU + baud * 4UL) / (baud * 8UL) - 1UL; + UCSRA |= (1 << U2X); + } else { + UCSRA &= ~(1 << U2X); + } + + UBRRH = ubrr_v >> 8; + UBRRL = ubrr_v & 0xff; + return OK; +} diff -r 000000000000 -r a0ce8ebf2f18 tests/ledtest.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/ledtest.c Sat Feb 21 15:49:59 2009 +0800 @@ -0,0 +1,41 @@ +#include +#include "avriotools.h" +#include +#include + +int main(int argc, char *const argv[]) { + int i, cnt = 0; + const char *msg = "hello%d\n"; + char buf[64]; + + uart_init(400000); + + pin_mode(&PORTB, PINB0, PM_OUTPUT); + pin_mode(&PORTB, PINB1, PM_OUTPUT); + pin_lo(PORTB, PINB1); + for(i = 0; i < 30; i++) { + pin_hi(PORTB, PINB0); + _delay_ms(100); + pin_lo(PORTB, PINB0); + _delay_ms(100); + } + + while(1) { + pin_hi(PORTB, PINB0); + _delay_ms(100); + pin_lo(PORTB, PINB0); + _delay_ms(100); + pin_hi(PORTB, PINB0); + _delay_ms(100); + pin_lo(PORTB, PINB0); + _delay_ms(100); + pin_hi(PORTB, PINB0); + _delay_ms(500); + pin_lo(PORTB, PINB0); + _delay_ms(100); + + sprintf(buf, msg, cnt++); + for(i = 0; buf[i] != 0; i++) + uart_putc(buf[i]); + } +}