cleanup uart stuff

- use new per-cpu headers
- remove interrupt handling from uart functions
- correct baudrate calculation
- introduce UART_DOUBLESPEED to use fast mode
- introduce UART_SECOND to use 2nd uart on mega128
- move uart functions to main.c, delete uart.[ch]
- rename XTAL to F_CPU (avrlibc style)
- move some defines from Makefile to main.c
This commit is contained in:
Olaf Rempel 2006-05-19 22:19:18 +02:00
parent cb5d02f4ba
commit c897637dc2
10 changed files with 200 additions and 215 deletions

98
main.c
View File

@ -61,6 +61,18 @@
#define VERSION_HIGH '0'
#define VERSION_LOW '7'
/* MCU frequency */
#define F_CPU 7372800
/* UART Baudrate */
#define BAUDRATE 115200
/* use "Double Speed Operation" */
//#define UART_DOUBLESPEED
/* use second UART on mega128 / can128 */
//#define UART_USE_SECOND
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
@ -68,23 +80,6 @@
#include <avr/boot.h>
#include <avr/pgmspace.h>
#ifndef XTAL
#warning "Set XTAL in Makefile"
#endif
#ifdef START_BOOTICE
#warning "Using START_BOOTICE"
#if XTAL == 7372800
#else
#warning "BOOTICE mode - External Crystal/Oszillator must be 7,3728 MHz"
#undef XTAL
#define XTAL 7372800
#endif
#endif
// UART handling - some definitions from P. Fleury's Library - thanks
#include "uart.h"
/* enable/disable readout of fuse and lock-bits
(will not work for Mega169 since not supported by AVRPROG 1.37 */
#define ENABLEREADFUSELOCK
@ -109,6 +104,18 @@ unsigned char gBuffer[UART_RX_BUFFER_SIZE];
uint32_t address;
unsigned char device;
void sendchar(char data)
{
loop_until_bit_is_set(UART_STATUS, UART_TXREADY);
UART_DATA = data;
}
char recvchar(void)
{
loop_until_bit_is_set(UART_STATUS, UART_RXREADY);
return UART_DATA;
}
unsigned char BufferLoad(unsigned int size, unsigned char mem)
{
unsigned int data, cnt;
@ -116,7 +123,7 @@ unsigned char BufferLoad(unsigned int size, unsigned char mem)
for (cnt = 0; cnt < UART_RX_BUFFER_SIZE; cnt++) {
if (cnt < size)
gBuffer[cnt] = recchar();
gBuffer[cnt] = recvchar();
else
gBuffer[cnt] = 0xFF;
}
@ -259,8 +266,16 @@ int main(void)
BLDDR &= ~(1<<BLPNUM); // set as Input
BLPORT |= (1<<BLPNUM); // Enable pullup
USART_Init(UART_BAUD_SELECT(BAUDRATE,XTAL),UARTSINGLE); // single speed
// USART_Init(UART_BAUD_SELECT(BAUDRATE/2,XTAL),UARTDOUBLE); // double speed
// Set baud rate
UART_BAUD_HIGH = (UART_CALC_BAUDRATE(BAUDRATE)>>8) & 0xFF;
UART_BAUD_LOW = (UART_CALC_BAUDRATE(BAUDRATE) & 0xFF);
#ifdef UART_DOUBLESPEED
UART_STATUS = UART_DOUBLE;
#endif
UART_CTRL = UART_CTRL_DATA;
UART_CTRL2 = UART_CTRL2_DATA;
#ifdef START_POWERSAVE
/*
@ -311,34 +326,31 @@ int main(void)
// Timer-Setup for ATmega8
// - verify that the configuration is valid for the target AVR
#define F_OSC XTAL
#define UART0_STATUS UCSRA
#define UART0_DATA UDR
#define MY_WAIT 900
// wait ca 1 sec (900ms)
TCCR1A = 0; // timer setup
// F_OSC / 8 / 1000 -> 1ms
#if (((F_OSC / 8 / 1000)*MY_WAIT) < 65535)
#if (((F_CPU / 8 / 1000)*MY_WAIT) < 65535)
#warning Information: setting prescaler to 8
#define WAIT_VALUE ((F_OSC / 8 / 1000)*MY_WAIT)
#define WAIT_VALUE ((F_CPU / 8 / 1000)*MY_WAIT)
TCCR1B |= _BV(CS01);
#elif ((((F_OSC / 64 / 1000)*MY_WAIT) < 65535))
#elif ((((F_CPU / 64 / 1000)*MY_WAIT) < 65535))
#warning Information: setting prescaler to 64
#define WAIT_VALUE ((F_OSC / 64 / 1000)*MY_WAIT)
#define WAIT_VALUE ((F_CPU / 64 / 1000)*MY_WAIT)
TCCR1B |= _BV(CS01)| _BV(CS00);
#elif ((((F_OSC / 256 / 1000)*MY_WAIT) < 65535))
#elif ((((F_CPU / 256 / 1000)*MY_WAIT) < 65535))
#warning Information: setting prescaler to 256
#define WAIT_VALUE ((F_OSC / 256 / 1000)*MY_WAIT)
#define WAIT_VALUE ((F_CPU / 256 / 1000)*MY_WAIT)
TCCR1B |= _BV(CS02);
#else //((((F_OSC / 1024 / 1000)*MY_WAIT) < 65535))
#else //((((F_CPU / 1024 / 1000)*MY_WAIT) < 65535))
#warning Information: setting prescaler to 1024
#define WAIT_VALUE ((F_OSC / 1024 / 1000)*MY_WAIT)
#define WAIT_VALUE ((F_CPU / 1024 / 1000)*MY_WAIT)
TCCR1B |= _BV(CS00) |_BV(CS02); //1024 prescaler
#endif
while (1) {
if (UART0_STATUS & (1<<RXC)) {
if (UART0_DATA == 'S')
if (UART_STATUS & (1<<UART_RXREADY)) {
if (UART_DATA == 'S')
break;
}
if (TCNT1 >= WAIT_VALUE){
@ -360,15 +372,15 @@ int main(void)
#endif
for(;;) {
val = recchar();
val = recvchar();
// Autoincrement?
if (val == 'a') {
sendchar('Y'); // Autoincrement is quicker
//write address
} else if (val == 'A') {
address = recchar(); //read address 8 MSB
address = (address<<8) | recchar();
address = recvchar(); //read address 8 MSB
address = (address<<8) | recvchar();
address = address<<1; // !! convert from word address to byte address
sendchar('\r');
@ -381,15 +393,15 @@ int main(void)
// Start buffer load
} else if (val == 'B') {
tempi = recchar() << 8; // Load high byte of buffersize
tempi |= recchar(); // Load low byte of buffersize
val = recchar(); // Load memory type ('E' or 'F')
tempi = recvchar() << 8; // Load high byte of buffersize
tempi |= recvchar(); // Load low byte of buffersize
val = recvchar(); // Load memory type ('E' or 'F')
sendchar (BufferLoad(tempi, val)); // Start downloading of buffer
// Block read
} else if (val == 'g') {
tempi = (recchar() << 8) | recchar();
val = recchar(); // Get memtype
tempi = (recvchar() << 8) | recvchar();
val = recvchar(); // Get memtype
BlockRead(tempi, val); // Perform the block read
// Chip erase
@ -461,12 +473,12 @@ int main(void)
// clear and set LED ignored
} else if ((val == 'x') || (val == 'y')) {
recchar();
recvchar();
sendchar('\r');
// set device
} else if (val == 'T') {
device = recchar();
device = recvchar();
sendchar('\r');
// Return software identifier

View File

@ -39,11 +39,6 @@ MCU = atmega8
## MCU = atmega32
## MCU = at90can128
XTAL=16000000
#XTAL=2000000UL
#BAUDRATE=115200
BAUDRATE=9600UL
#Pin "STARTPIN" on port "STARTPORT" in this port has to grounded
# (active low) to start the bootloader
BLPORT = PORTB
@ -62,7 +57,7 @@ BLPNUM = PINB0
# * BOOTICE-Mode - to flash the JTAGICE upgrade.ebn file.
# No startup-sequence in this mode. Jump directly to the
# parser-loop on reset
# XTAL in BOOTICEMODE must be 7372800 Hz to be compatible
# F_CPU in BOOTICEMODE must be 7372800 Hz to be compatible
# with the org. JTAGICE-Firmware */
# * WAIT-mode waits 1 sec for the S command if nothing is recived
# then the user prog is started ..
@ -188,7 +183,7 @@ TARGET = main
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c uart.c
SRC = $(TARGET).c
# List Assembler source files here.
@ -226,7 +221,7 @@ CSTANDARD = -std=gnu99
# Place -D or -U options here
CDEFS = -DBLPORT=$(BLPORT) -DBLDDR=$(BLDDR) -DBLPIN=$(BLPIN) -DBLPNUM=$(BLPNUM)
CDEFS += -D$(STARTMODE) -DBOOTSIZE=$(BOOTSIZE) -DBAUDRATE=$(BAUDRATE)
CDEFS += -D$(STARTMODE) -DBOOTSIZE=$(BOOTSIZE)
ifdef XTAL
CDEFS += -DXTAL=$(XTAL)
endif

View File

@ -7,4 +7,37 @@
#define SIG_BYTE2 0x97
#define SIG_BYTE1 0x02
#ifdef UART_DOUBLESPEED
#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)(F_CPU) / ((uint32_t)(baudRate) *8) -1)
#else
#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)(F_CPU) / ((uint32_t)(baudRate)*16) -1)
#endif
#ifndef UART_USE_SECOND
#define UART_BAUD_HIGH UBRR0H
#define UART_BAUD_LOW UBRR0L
#define UART_STATUS UCSR0A
#define UART_TXREADY UDRE0
#define UART_RXREADY RXC0
#define UART_DOUBLE U2X0
#define UART_CTRL UCSR0B
#define UART_CTRL_DATA ((1<<TXEN0) | (1<<RXEN0))
#define UART_CTRL2 UCSR0C
#define UART_CTRL2_DATA ((1<<UCSZ01) | (1<<UCSZ00))
#define UART_DATA UDR0
#else
#define UART_BAUD_HIGH UBRR1H
#define UART_BAUD_LOW UBRR1L
#define UART_STATUS UCSR1A
#define UART_TXREADY UDRE1
#define UART_RXREADY RXC1
#define UART_DOUBLE U2X1
#define UART_CTRL UCSR1B
#define UART_CTRL_DATA ((1<<TXEN1) | (1<<RXEN1))
#define UART_CTRL2 UCSR1C
#define UART_CTRL2_DATA ((1<<UCSZ11) | (1<<UCSZ10))
#define UART_DATA UDR1
#endif
#endif // #ifndef _MEGA128_H_

View File

@ -8,4 +8,37 @@
#define SIG_BYTE2 0x97
#define SIG_BYTE1 0x81
#ifdef UART_DOUBLESPEED
#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)(F_CPU) / ((uint32_t)(baudRate) *8) -1)
#else
#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)(F_CPU) / ((uint32_t)(baudRate)*16) -1)
#endif
#ifndef UART_USE_SECOND
#define UART_BAUD_HIGH UBRR0H
#define UART_BAUD_LOW UBRR0L
#define UART_STATUS UCSR0A
#define UART_TXREADY UDRE0
#define UART_RXREADY RXC0
#define UART_DOUBLE U2X0
#define UART_CTRL UCSR0B
#define UART_CTRL_DATA ((1<<TXEN0) | (1<<RXEN0))
#define UART_CTRL2 UCSR0C
#define UART_CTRL2_DATA ((1<<UCSZ01) | (1<<UCSZ00))
#define UART_DATA UDR0
#else
#define UART_BAUD_HIGH UBRR1H
#define UART_BAUD_LOW UBRR1L
#define UART_STATUS UCSR1A
#define UART_TXREADY UDRE1
#define UART_RXREADY RXC1
#define UART_DOUBLE U2X1
#define UART_CTRL UCSR1B
#define UART_CTRL_DATA ((1<<TXEN1) | (1<<RXEN1))
#define UART_CTRL2 UCSR1C
#define UART_CTRL2_DATA ((1<<UCSZ11) | (1<<UCSZ10))
#define UART_DATA UDR1
#endif
#endif // #ifndef _MEGA128CAN_H_

View File

@ -7,4 +7,23 @@
#define SIG_BYTE2 0x94
#define SIG_BYTE1 0x03
#ifdef UART_DOUBLESPEED
#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)(F_CPU) / ((uint32_t)(baudRate) *8) -1)
#else
#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)(F_CPU) / ((uint32_t)(baudRate)*16) -1)
#endif
#define UART_BAUD_HIGH UBRRH
#define UART_BAUD_LOW UBRRL
#define UART_STATUS UCSRA
#define UART_TXREADY UDRE
#define UART_RXREADY RXC
#define UART_DOUBLE U2X
#define UART_CTRL UCSRB
#define UART_CTRL_DATA ((1<<TXEN) | (1<<RXEN))
#define UART_CTRL2 UCSRC
#define UART_CTRL2_DATA ((1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0))
#define UART_DATA UDR
#endif // #ifndef _MEGA16_H_

View File

@ -7,4 +7,23 @@
#define SIG_BYTE2 0x94
#define SIG_BYTE1 0x05
#ifdef UART_DOUBLESPEED
#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)(F_CPU) / ((uint32_t)(baudRate) *8) -1)
#else
#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)(F_CPU) / ((uint32_t)(baudRate)*16) -1)
#endif
#define UART_BAUD_HIGH UBRRH
#define UART_BAUD_LOW UBRRL
#define UART_STATUS UCSRA
#define UART_TXREADY UDRE
#define UART_RXREADY RXC
#define UART_DOUBLE U2X
#define UART_CTRL UCSRB
#define UART_CTRL_DATA ((1<<TXEN) | (1<<RXEN))
#define UART_CTRL2 UCSRC
#define UART_CTRL2_DATA ((1<<UCSZ1) | (1<<UCSZ0))
#define UART_DATA UDR
#endif // #ifndef _MEGA169_H_

View File

@ -7,4 +7,23 @@
#define SIG_BYTE2 0x95
#define SIG_BYTE1 0x02
#ifdef UART_DOUBLESPEED
#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)(F_CPU) / ((uint32_t)(baudRate) *8) -1)
#else
#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)(F_CPU) / ((uint32_t)(baudRate)*16) -1)
#endif
#define UART_BAUD_HIGH UBRRH
#define UART_BAUD_LOW UBRRL
#define UART_STATUS UCSRA
#define UART_TXREADY UDRE
#define UART_RXREADY RXC
#define UART_DOUBLE U2X
#define UART_CTRL UCSRB
#define UART_CTRL_DATA ((1<<TXEN) | (1<<RXEN))
#define UART_CTRL2 UCSRC
#define UART_CTRL2_DATA ((1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0))
#define UART_DATA UDR
#endif // #ifndef _MEGA32_H_

19
mega8.h
View File

@ -8,4 +8,23 @@
#define SIG_BYTE2 0x93
#define SIG_BYTE1 0x07
#ifdef UART_DOUBLESPEED
#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)(F_CPU) / ((uint32_t)(baudRate) *8) -1)
#else
#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)(F_CPU) / ((uint32_t)(baudRate)*16) -1)
#endif
#define UART_BAUD_HIGH UBRRH
#define UART_BAUD_LOW UBRRL
#define UART_STATUS UCSRA
#define UART_TXREADY UDRE
#define UART_RXREADY RXC
#define UART_DOUBLE U2X
#define UART_CTRL UCSRB
#define UART_CTRL_DATA ((1<<TXEN) | (1<<RXEN))
#define UART_CTRL2 UCSRC
#define UART_CTRL2_DATA ((1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0))
#define UART_DATA UDR
#endif // #ifndef _MEGA8_H_

151
uart.c
View File

@ -1,151 +0,0 @@
#include <avr/io.h>
/* most of the definitions borrowed from Peter Fleury's UART-Library
extende for control-register C and ATmega169 */
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \
|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega8535__) \
|| defined(__AVR_ATmega323__)
/* ATMega with one USART */
#define ATMEGA_USART
#define UART0_UBRR_HIGH UBRRH
#define UART0_UBRR_LOW UBRRL
#define UART0_RECEIVE_INTERRUPT SIG_UART_RECV
#define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA
#define UART0_STATUS UCSRA
#define UART0_CONTROL UCSRB
#define UART0_DATA UDR
#define UART0_UDRIE UDRIE
#elif defined(__AVR_ATmega162__)
/* ATMega with two USART */
#define ATMEGA_USART0
#define ATMEGA_USART1
#define UART0_UBRR_HIGH UBRR0H
#define UART0_UBRR_LOW UBRR0L
#define UART1_UBRR_HIGH UBRR1H
#define UART1_UBRR_LOW UBRR1L
#define UART0_RECEIVE_INTERRUPT SIG_USART0_RECV
#define UART1_RECEIVE_INTERRUPT SIG_USART1_RECV
#define UART0_TRANSMIT_INTERRUPT SIG_USART0_DATA
#define UART1_TRANSMIT_INTERRUPT SIG_USART1_DATA
#define UART0_STATUS UCSR0A
#define UART0_CONTROL UCSR0B
#define UART0_CONTROL2 UCSR0C
#define UART0_DATA UDR0
#define UART0_UDRIE UDRIE0
#define UART1_STATUS UCSR1A
#define UART1_CONTROL UCSR1B
#define UART1_CONTROL2 UCSR1C
#define UART1_DATA UDR1
#define UART1_UDRIE UDRIE1
#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) || defined(__AVR_AT90CAN128__)
/* ATMega with two USART */
#define ATMEGA_USART0
#define ATMEGA_USART1
#define UART0_UBRR_HIGH UBRR0H
#define UART0_UBRR_LOW UBRR0L
#define UART1_UBRR_HIGH UBRR1H
#define UART1_UBRR_LOW UBRR1L
#define UART0_RECEIVE_INTERRUPT SIG_UART0_RECV
#define UART1_RECEIVE_INTERRUPT SIG_UART1_RECV
#define UART0_TRANSMIT_INTERRUPT SIG_UART0_DATA
#define UART1_TRANSMIT_INTERRUPT SIG_UART1_DATA
#define UART0_STATUS UCSR0A
#define UART0_CONTROL UCSR0B
#define UART0_CONTROL2 UCSR0C
#define UART0_DATA UDR0
#define UART0_UDRIE UDRIE0
#define UART1_STATUS UCSR1A
#define UART1_CONTROL UCSR1B
#define UART1_CONTROL2 UCSR1C
#define UART1_DATA UDR1
#define UART1_UDRIE UDRIE1
#elif defined(__AVR_ATmega169__)
#define ATMEGA_USART
#define UART0_UBRR_HIGH UBRR0H
#define UART0_UBRR_LOW UBRR0L
// TODO #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV
// TODO #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA
#define UART0_STATUS UCSR0A
#define UART0_CONTROL UCSR0B
#define UART0_CONTROL2 UCSR0C
#define UART0_DATA UDR0
#define UART0_DOUBLEAVAIL
// TODO #define UART0_UDRIE UDRIE
#else
#error "Processor type not supported in uart.c !"
#endif
void USART_Init(unsigned int baudrate, unsigned char doublespeed)
{
// Set baud rate
UART0_UBRR_HIGH = (unsigned char)(baudrate>>8);
UART0_UBRR_LOW = (unsigned char)baudrate;
// Enable 2x speed - TODO adopt to all uCs
#ifdef UART0_DOUBLEAVAIL
if (doublespeed) UCSR0A = (1<<U2X0);
#endif
#if defined (ATMEGA_USART)
/* Enable USART receiver and transmitter and disable interrupts */
UART0_CONTROL = (1<<RXEN)|(1<<TXEN)|(0<<RXCIE)|(0<<UDRIE);
/* Set frame format: asynchronous, 8data, no parity, 1stop bit */
#ifdef URSEL
UCSRC = (1<<URSEL)|(3<<UCSZ0);
#else
UCSRC = (3<<UCSZ0);
#endif
#elif defined (ATMEGA_USART0 )
/* Enable USART receiver and transmitter and disable interrupts */
UART0_CONTROL = (1<<RXEN0)|(1<<TXEN0)|(0<<RXCIE0)|(0<<UDRIE0);
/* Set frame format: asynchronous, 8data, no parity, 1stop bit */
#ifdef URSEL0
UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
#else
UCSR0C = (3<<UCSZ00);
#endif
#endif
}
void sendchar(char data)
{
int i = 0;
UART0_DATA = data;
if(SREG & 0x80)
{
while ( !(UART0_STATUS&0x40) && (i<10000) )
{
i++;
}
}
else
while( !(UART0_STATUS&0x40) );
UART0_STATUS=UART0_STATUS|0x40; //delete TXCflag
}
char recchar(void)
{
int i = 0;
if(SREG & 0x80)
{
// while (!(UART0_STATUS & (1<<RXC0)) && (i<10000))
while (!(UART0_STATUS & 0x80) && (i<10000))
{
i++;
}
}
else
// while(!(UART0_STATUS & (1<<RXC0)));
while(!(UART0_STATUS & 0x80));
return UART0_DATA ;
}

13
uart.h
View File

@ -1,13 +0,0 @@
#ifndef UART_H
#define UART_H
#define UART_BAUD_SELECT(baudRate,xtalCpu) (((xtalCpu)+(baudRate*8))/((baudRate)*16)-1)
#define UARTDOUBLE 1
#define UARTSINGLE 0
void USART_Init(unsigned int, unsigned char);
void sendchar(char);
char recchar(void);
#endif