Timer 3 working with slower clock and all 16 bits.
[fw/altos] / src / avr / ao_i2c_usart.c
1 /*
2  * Copyright © 2011 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 #include "ao.h"
19
20 /*
21  * Atmega32u4 TWI master mode (I2C)
22  */
23
24 __xdata uint8_t ao_i2c_mutex;
25
26 /* Send bytes over I2C.
27  *
28  * This just polls; the I2C is set to go as fast as possible,
29  * so using interrupts would take way too long
30  */
31 void
32 ao_i2c_send(void __xdata *block, uint16_t len) __reentrant
33 {
34         uint8_t *d = block;
35
36         ao_mutex_get(&ao_i2c_mutex);
37         while (len--) {
38                 while (!(UCSR1A & (1 << UDRE1)));
39                 UDR1 = *d++;
40                 while (!(UCSR1A & (1 << RXC1)));
41                 (void) UDR1;
42         }
43         ao_mutex_put(&ao_i2c_mutex);
44 }
45
46 /* Receive bytes over I2C.
47  *
48  * This sets up tow DMA engines, one reading the data and another
49  * writing constant values to the I2C transmitter as that is what
50  * clocks the data coming in.
51  */
52 void
53 ao_i2c_recv(void __xdata *block, uint16_t len) __reentrant
54 {
55         uint8_t *d = block;
56
57         ao_mutex_get(&ao_i2c_mutex);
58         while (len--) {
59                 while (!(UCSR1A & (1 << UDRE1)));
60                 UDR1 = 0;
61                 while (!(UCSR1A & (1 << RXC1)));
62                 *d++ = UDR1;
63         }
64         ao_mutex_put(&ao_i2c_mutex);
65 }
66
67 #define XCK1_DDR        DDRD
68 #define XCK1_PORT       PORTD
69 #define XCK1            PORTD5
70 #define XMS1_DDR        DDRE
71 #define XMS1_PORT       PORTE
72 #define XMS1            PORTE6
73
74 void
75 ao_i2c_init(void)
76 {
77         /* Ensure the TWI is powered */
78
79         /*
80          * Set pin directions
81          */
82         XCK1_DDR |= (1 << XCK1);
83
84         /* Clear chip select (which is negated) */
85         XMS1_PORT |= (1 < XMS1);
86         XMS1_DDR |= (1 << XMS1);
87
88         /* Set baud register to zero (required before turning transmitter on) */
89         UBRR1 = 0;
90
91         UCSR1C = ((0x3 << UMSEL10) |    /* Master I2C mode */
92                   (0 << UCSZ10) |       /* I2C mode 0 */
93                   (0 << UCPOL1));       /* I2C mode 0 */
94
95         /* Enable transmitter and receiver */
96         UCSR1B = ((1 << RXEN1) |
97                   (1 << TXEN1));
98
99         /* It says that 0 is a legal value; we'll see... */
100         UBRR1 = 0;
101 }