Subversion Repositories FlightCtrl

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1910 - 1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/twi.h>
4
#include <util/delay.h>
5
//#include "eeprom.h"
6
#include "twimaster.h"
7
//#include "analog.h"
8
#include "configuration.h"
9
 
10
volatile uint8_t twi_state = TWI_STATE_IDLE;
11
volatile uint8_t dac_channel = 0;
12
volatile uint16_t I2CTimeout = 100;
13
volatile uint8_t DACValues[4];
14
uint8_t DACChannel = 0;
15
 
16
#define SCL_CLOCK  200000L
17
#define I2C_TIMEOUT 30000
18
 
19
/**************************************************
20
 * Initialize I2C (TWI)                        
21
 **************************************************/
22
void I2C_init(void) {
23
        uint8_t i;
24
        uint8_t sreg = SREG;
25
        cli();
26
 
27
        // SDA is INPUT
28
        DDRC &= ~(1 << DDC1);
29
        // SCL is output
30
        DDRC |= (1 << DDC0);
31
        // pull up SDA
32
        PORTC |= (1 << PORTC0) | (1 << PORTC1);
33
 
34
        // TWI Status Register
35
        // prescaler 1 (TWPS1 = 0, TWPS0 = 0)
36
        TWSR &= ~((1 << TWPS1) | (1 << TWPS0));
37
 
38
        // set TWI Bit Rate Register
39
        TWBR = ((SYSCLK / SCL_CLOCK) - 16) / 2;
40
 
41
        twi_state = TWI_STATE_IDLE;
42
    SREG = sreg;
43
}
44
 
45
/****************************************
46
 * Start I2C                          
47
 ****************************************/
48
void I2C_Start(uint8_t start_state) {
49
        twi_state = start_state;
50
        // TWI Control Register
51
        // clear TWI interrupt flag (TWINT=1)
52
        // disable TWI Acknowledge Bit (TWEA = 0)
53
        // enable TWI START Condition Bit (TWSTA = 1), MASTER
54
        // disable TWI STOP Condition Bit (TWSTO = 0)
55
        // disable TWI Write Collision Flag (TWWC = 0)
56
        // enable i2c (TWEN = 1)
57
        // enable TWI Interrupt (TWIE = 1)
58
        TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN) | (1 << TWIE);
59
}
60
 
61
/****************************************
62
 * Stop I2C                          
63
 ****************************************/
64
void I2C_Stop(uint8_t start_state) {
65
        twi_state = start_state;
66
        // TWI Control Register
67
        // clear TWI interrupt flag (TWINT=1)
68
        // disable TWI Acknowledge Bit (TWEA = 0)
69
        // diable TWI START Condition Bit (TWSTA = 1), no MASTER
70
        // enable TWI STOP Condition Bit (TWSTO = 1)
71
        // disable TWI Write Collision Flag (TWWC = 0)
72
        // enable i2c (TWEN = 1)
73
        // disable TWI Interrupt (TWIE = 0)
74
        TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN);
75
}
76
 
77
/****************************************
78
 *    Write to I2C                      
79
 ****************************************/
80
void I2C_WriteByte(int8_t byte) {
81
        // move byte to send into TWI Data Register
82
        TWDR = byte;
83
        // clear interrupt flag (TWINT = 1)
84
        // enable i2c bus (TWEN = 1)
85
        // enable interrupt (TWIE = 1)
86
        TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE);
87
}
88
 
89
/****************************************
90
 * Receive byte and send ACK        
91
 ****************************************/
92
void I2C_ReceiveByte(void) {
93
        TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE) | (1 << TWEA);
94
}
95
 
96
/****************************************
97
 * I2C receive last byte and send no ACK
98
 ****************************************/
99
void I2C_ReceiveLastByte(void) {
100
        TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE);
101
}
102
 
103
/****************************************
104
 * Reset I2C                        
105
 ****************************************/
106
void I2C_Reset(void) {
107
        // stop i2c bus
108
        I2C_Stop(TWI_STATE_IDLE);
109
        TWCR = (1 << TWINT); // reset to original state incl. interrupt flag reset
110
        TWAMR = 0;
111
        TWAR = 0;
112
        TWDR = 0;
113
        TWSR = 0;
114
        TWBR = 0;
115
        I2C_init();
116
}
117
 
118
/****************************************
119
 * I2C ISR
120
 ****************************************/
121
ISR (TWI_vect)
122
{
123
        switch (twi_state) { // First i2c_start from SendMotorData()
124
        case 0: break;
125
 
126
                // Writing ADC values.
127
        case 7:
128
            twi_state++;
129
                I2C_WriteByte(0x98); // Address the DAC
130
                break;
131
 
132
        case 8:
133
            twi_state++;
134
                I2C_WriteByte(0x10 + (DACChannel << 1)); // Select DAC Channel (0x10 = A, 0x12 = B, 0x14 = C)
135
                break;
136
 
137
        case 9:
138
            twi_state++;
139
                I2C_WriteByte(DACValues[DACChannel]);
140
                break;
141
 
142
        case 10:
143
            twi_state++;
144
                I2C_WriteByte(0x80); // 2nd byte for all channels is 0x80
145
                break;
146
 
147
        case 11:
148
            twi_state++;
149
                I2C_Stop(TWI_STATE_IDLE);
150
                I2CTimeout = 10;
151
                // repeat case 7...10 until all DAC Channels are updated
152
                if (DACChannel < 2) {
153
                        DACChannel++; // jump to next channel
154
                        I2C_Start(TWI_STATE_GYRO_OFFSET_TX); // start transmission for next channel
155
                } else {
156
                        DACChannel = 0; // reset dac channel counter
157
                }
158
                break;
159
 
160
        default:
161
                I2C_Stop(TWI_STATE_IDLE);
162
                I2CTimeout = 10;
163
        }
164
}