Subversion Repositories svnkaklik

Rev

Details | Last modification | View Log

Rev Author Line No. Line
567 kaklik 1
 
2
/*
3
 * Copyright (c) 2006-2007 by Roland Riegel <feedback@roland-riegel.de>
4
 *
5
 * This file is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License version 2 as
7
 * published by the Free Software Foundation.
8
 */
9
 
10
#include <stdio.h>
11
#include <avr/interrupt.h>
12
#include <avr/io.h>
13
#include <avr/pgmspace.h>
14
#include <avr/sfr_defs.h>
15
#include <avr/sleep.h>
16
 
17
#include "uart.h"
18
 
19
/* some mcus have multiple uarts */
20
#ifdef UDR0
21
#define UBRRH UBRR0H
22
#define UBRRL UBRR0L
23
#define UDR UDR0
24
 
25
#define UCSRA UCSR0A
26
#define UDRE UDRE0
27
#define RXC RXC0
28
 
29
#define UCSRB UCSR0B
30
#define RXEN RXEN0
31
#define TXEN TXEN0
32
#define RXCIE RXCIE0
33
 
34
#define UCSRC UCSR0C
35
#define URSEL 
36
#define UCSZ0 UCSZ00
37
#define UCSZ1 UCSZ01
38
#define UCSRC_SELECT 0
39
#else
40
#define UCSRC_SELECT (1 << URSEL)
41
#endif
42
 
43
#ifndef USART_RXC_vect
44
#if defined(UART0_RX_vect)
45
#define USART_RXC_vect UART0_RX_vect
46
#elif defined(UART_RX_vect)
47
#define USART_RXC_vect UART_RX_vect
48
#elif defined(USART0_RX_vect)
49
#define USART_RXC_vect USART0_RX_vect
50
#elif defined(USART_RX_vect)
51
#define USART_RXC_vect USART_RX_vect
52
#elif defined(USART0_RXC_vect)
53
#define USART_RXC_vect USART0_RXC_vect
54
#elif defined(USART_RXC_vect)
55
#define USART_RXC_vect USART_RXC_vect
56
#else
57
#error "Uart receive complete interrupt not defined!"
58
#endif
59
#endif
60
 
61
#define BAUD 9600UL
62
#define UBRRVAL (F_CPU/(BAUD*16)-1)
63
#define USE_SLEEP 1
64
 
65
void uart_init()
66
{
67
    /* set baud rate */
68
    UBRRH = UBRRVAL >> 8;
69
    UBRRL = UBRRVAL & 0xff;
70
    /* set frame format: 8 bit, no parity, 1 bit */
71
    UCSRC = UCSRC_SELECT | (1 << UCSZ1) | (1 << UCSZ0);
72
    /* enable serial receiver and transmitter */
73
#if !USE_SLEEP
74
    UCSRB = (1 << RXEN) | (1 << TXEN);
75
#else
76
    UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
77
#endif
78
}
79
 
80
void uart_putc(uint8_t c)
81
{
82
    if(c == '\n')
83
        uart_putc('\r');
84
 
85
    /* wait until transmit buffer is empty */
86
    while(!(UCSRA & (1 << UDRE)));
87
 
88
    /* send next byte */
89
    UDR = c;
90
}
91
 
92
void uart_putc_hex(uint8_t b)
93
{
94
    /* upper nibble */
95
    if((b >> 4) < 0x0a)
96
        uart_putc((b >> 4) + '0');
97
    else
98
        uart_putc((b >> 4) - 0x0a + 'a');
99
 
100
    /* lower nibble */
101
    if((b & 0x0f) < 0x0a)
102
        uart_putc((b & 0x0f) + '0');
103
    else
104
        uart_putc((b & 0x0f) - 0x0a + 'a');
105
}
106
 
107
void uart_putw_hex(uint16_t w)
108
{
109
    uart_putc_hex((uint8_t) (w >> 8));
110
    uart_putc_hex((uint8_t) (w & 0xff));
111
}
112
 
113
void uart_putdw_hex(uint32_t dw)
114
{
115
    uart_putw_hex((uint16_t) (dw >> 16));
116
    uart_putw_hex((uint16_t) (dw & 0xffff));
117
}
118
 
119
void uart_putw_dec(uint16_t w)
120
{
121
    uint16_t num = 10000;
122
    uint8_t started = 0;
123
 
124
    while(num > 0)
125
    {
126
        uint8_t b = w / num;
127
        if(b > 0 || started || num == 1)
128
        {
129
            uart_putc('0' + b);
130
            started = 1;
131
        }
132
        w -= b * num;
133
 
134
        num /= 10;
135
    }
136
}
137
 
138
void uart_putdw_dec(uint32_t dw)
139
{
140
    uint32_t num = 1000000000;
141
    uint8_t started = 0;
142
 
143
    while(num > 0)
144
    {
145
        uint8_t b = dw / num;
146
        if(b > 0 || started || num == 1)
147
        {
148
            uart_putc('0' + b);
149
            started = 1;
150
        }
151
        dw -= b * num;
152
 
153
        num /= 10;
154
    }
155
}
156
 
157
void uart_puts(const char* str)
158
{
159
    while(*str)
160
        uart_putc(*str++);
161
}
162
 
163
void uart_puts_p(PGM_P str)
164
{
165
    while(1)
166
    {
167
        uint8_t b = pgm_read_byte_near(str++);
168
        if(!b)
169
            break;
170
 
171
        uart_putc(b);
172
    }
173
}
174
 
175
uint8_t uart_getc()
176
{
177
    /* wait until receive buffer is full */
178
#if USE_SLEEP
179
    uint8_t sreg = SREG;
180
    sei();
181
 
182
    while(!(UCSRA & (1 << RXC)))
183
        sleep_mode();
184
 
185
    SREG = sreg;
186
#else
187
    while(!(UCSRA & (1 << RXC)));
188
#endif
189
 
190
    uint8_t b = UDR;
191
    if(b == '\r')
192
        b = '\n';
193
 
194
    return b;
195
}
196
 
197
EMPTY_INTERRUPT(USART_RXC_vect)
198