Subversion Repositories FlightCtrl

Rev

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

Rev Author Line No. Line
2248 - 1
/*****************************************************************************************************************************
2
* File:                 twimaster.c
3
*
4
* Purpose:              setup of I2C (TWI)
5
*
6
* Functions:    extern void i2c_init (void);                                    // initialize I2C
7
*                               extern void i2c_start (void);                                   // Start I2C
8
*                               extern void i2c_reset(void);                                    // resert I2C
9
*                               extern void i2c_stop (void);                                    // Stop I2C
10
*                               extern void i2c_write_byte (char byte);                 // write 1 Byte
11
*
12
*****************************************************************************************************************************/
13
#include "twimaster.h"
14
#include "main.h"
15
 
16
volatile unsigned char twi_state = 0;
17
unsigned char motor=0;
18
unsigned char motorread=0, MissingMotor=0;
19
unsigned char motor_rx[16], motor_rx2[16];
20
unsigned char MotorPresent[MAX_MOTORS];                                                 // #define MAX_MOTORS      4
21
unsigned char MotorError[MAX_MOTORS];
22
unsigned int I2CError=0;
23
 
24
 
25
// *************************************************************************************************************************************
26
// Initzialize I2C (TWI)
27
//
28
void i2c_init(void)
29
{                                                                                                              
30
        //--------------------------------------------------------------------------------------------------------------------
31
        // TWSR = TWI Status Register containing: TWS7 TWS6 TWS5 TWS4 TWS3 – TWPS1 TWPS0
32
        //
33
        TWSR = 0;                                                                       // TWSR – TWI Status Register
34
 
35
        //--------------------------------------------------------------------------------------------------------------------
36
        // TWBR = TWI Bit Rate Register containing: TWBR7 TWBR6 TWBR5 TWBR4 TWBR3 TWBR2 TWBR1 TWBR0
37
        // set TWI Bit Rate Register                            // SYSCLK = 16000000 and SCL_CLOCK = 200000
38
        TWBR = ((SYSCLK/SCL_CLOCK)-16)/2;                       // selects the division factor for the bit rate generator
39
}
40
// *************************************************************************************************************************************
41
 
42
 
43
 
44
//-------------------------------------------------------------------------------------------------------------------------------------
45
// Start I2C
46
//
47
void i2c_start(void)
48
{
49
        // ---------------------------------------------------------------------------
50
        // TWCR = TWI Control Register -> TWINT TWEA TWSTA TWSTO TWWC TWEN – TWIE
51
        // TWINT = TWI interrupt flag - to be set to one, to reset the TWINT Flag
52
        // TWSTA = TWI start and should be set to one, that TWI is started as Master.
53
        // TWEN = TWI enable -> now TWI/I2C is working  properly.
54
        // TWIE = TWI Interrupt enable is the TWIE Bit -> should be set
55
        //
56
        TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE);
57
}
58
//-------------------------------------------------------------------------------------------------------------------------------------
59
 
60
 
61
 
62
//-------------------------------------------------------------------------------------------------------------------------------------
63
// Stop I2C
64
//
65
void i2c_stop(void)
66
{
67
        // ---------------------------------------------------------------------------
68
        // TWCR = TWI Control Register -> TWINT TWEA TWSTA TWSTO TWWC TWEN – TWIE
69
        // TWINT = TWI interrupt flag - to be set to one, to reset the TWINT Flag
70
        // TWSTO = TWI STOP Condition Bit (TWSTO = 1) -> now will be stoped
71
        // TWEN = TWI enable -> TWI/I2C is working  properly
72
        //
73
    TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
74
}
75
//-------------------------------------------------------------------------------------------------------------------------------------
76
 
77
 
78
 
79
//-------------------------------------------------------------------------------------------------------------------------------------
80
// I2C Reset
81
//
82
void i2c_reset(void)
83
{
84
        i2c_stop();                
85
        twi_state = 0;
86
        motor = TWDR;                                                                   // TWI Data Register (TWDR) siehe S 227 
87
        motor = 0;                                                                              // ist das letzte gesendete oder empfangene Byte
88
        TWCR = 0x80;
89
        TWAMR = 0;
90
        TWAR = 0;
91
        TWDR = 0;
92
        TWSR = 0;
93
        TWBR = 0;
94
        i2c_init();
95
        i2c_start();
96
        i2c_write_byte(0);
97
}
98
//-------------------------------------------------------------------------------------------------------------------------------------
99
 
100
 
101
 
102
//---------------------------------------------------------------------------------------------------------------------------------------------
103
//  write via I2C
104
//
105
void i2c_write_byte(char byte)
106
{
107
    TWSR = 0x00;
108
    TWDR = byte;                                                                                                // sende dieses Byte via TWI Data Register
109
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
110
}
111
//---------------------------------------------------------------------------------------------------------------------------------------------
112
 
113
 
114
 
115
//---------------------------------------------------------------------------------------------------------------------------------------------
116
//  write byte via I2C
117
//
118
void I2C_WriteByte(int8_t byte)
119
{
120
    // move byte to send into TWI Data Register
121
    TWDR = byte;
122
    // clear interrupt flag (TWINT = 1)
123
    // enable i2c bus (TWEN = 1)
124
    // enable interrupt (TWIE = 1)
125
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
126
}
127
//---------------------------------------------------------------------------------------------------------------------------------------------
128
 
129
 
130
 
131
//---------------------------------------------------------------------------------------------------------------------------------------------
132
// ein Byte gelesen und sendet ACK
133
//
134
void I2C_ReceiveByte(void)
135
{
136
   TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWEA);
137
}
138
//---------------------------------------------------------------------------------------------------------------------------------------------
139
 
140
 
141
 
142
//---------------------------------------------------------------------------------------------------------------------------------------------
143
// I2C empfing das letzte Byte und sendet kein ACK
144
//
145
void I2C_ReceiveLastByte(void)
146
{
147
   TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
148
}
149
//---------------------------------------------------------------------------------------------------------------------------------------------
150
 
151
 
152
 
153
//-----------------------------------------------------------------------------------------------------------------------------------------------
154
// Interrupt I2C
155
//
156
ISR (TWI_vect)
157
{
158
        static unsigned char missing_motor;
159
 
160
    switch(twi_state++)
161
    {
162
                //----------------------------------------------------------------------------------------------------------------------------
163
                // write Motor-Data
164
                //----------------------------------------------------------------------------------------------------------------------------
165
        case 0:
166
                    while(Mixer.Motor[motor][0] <= 0 && motor < MAX_MOTORS) motor++;                    // #define MAX_MOTORS      2
167
                        if(motor == MAX_MOTORS)                                                                                                                 // writing finished -> now read 
168
                        {
169
                                motor = 0;
170
                                twi_state = 3;
171
                                if(motorread==0) i2c_write_byte(0x53);                          // Read-Adress of: Motor 1 = 0x53 / 2 = 0x55 / 3 = 0x57 / 4 = 0x59
172
                                if(motorread==1) i2c_write_byte(0x57);
173
                        }
174
                        else
175
                        {
176
                                if(motor==0) i2c_write_byte(0x52);                                      // Write-Adress of: Motor 1 = 0x52 / 2 = 0x54 / 3 = 0x56 / 4 = 0x58
177
                                if(motor==1) i2c_write_byte(0x56);
178
            }
179
                        break;
180
 
181
        case 1:
182
            i2c_write_byte(Motor[motor++]);
183
                        break;
184
 
185
        case 2:
186
                        // TWSR – TWI Status Register -> TWS7 TWS6 TWS5 TWS4 TWS3 - TWPS1 TWPS0
187
            // Data byte has been transmitted; NOT ACK has been received
188
                        if(TWSR == 0x30)                                                                               
189
                        {
190
                                if(!missing_motor) missing_motor = motor;                                       //
191
                                if(++MotorError[motor-1] == 0) MotorError[motor-1] = 255;       //
192
                        }
193
 
194
            i2c_stop();
195
            I2CTimeout = 10;                                                                                            // counted down every 2ms = watchdog
196
            twi_state = 0;
197
            i2c_start();  
198
            break;
199
 
200
                //----------------------------------------------------------------------------------------------------------
201
                // read Motor-Data
202
                //----------------------------------------------------------------------------------------------------------
203
                case 3:
204
            if(TWSR != 0x40)                                                                            // Error?
205
            {                                                                                                           // send 1. Byte to be read              
206
                                MotorPresent[motorread] = 0;
207
                                motorread++;
208
                                if(motorread >= MAX_MOTORS) motorread = 0;                      // #define MAX_MOTORS      2
209
                                i2c_stop();
210
                                twi_state = 0;
211
            }
212
            else
213
            {
214
                                MotorPresent[motorread] = ('1' - '-') + motorread;
215
                                I2C_ReceiveByte();
216
            }
217
            //MissingMotor = missing_motor;
218
                        MissingMotor = 0;
219
            missing_motor = 0;
220
                        break;
221
 
222
                case 4:                                                                                                         // read 1. Byte and send 2. Byte
223
            motor_rx[motorread] = TWDR;
224
            I2C_ReceiveLastByte();                                                                      // no acknowledge
225
            break;
226
 
227
        case 5:
228
            motor_rx2[motorread++] = TWDR;                                                      // read 2. Byte
229
            if(motorread >= MAX_MOTORS) motorread = 0;                          // #define MAX_MOTORS      4
230
            i2c_stop();
231
            twi_state = 0;
232
            break;
233
 
234
                //----------------------------------------------------------------------------------------------------------------------------------
235
                // write Gyro-Offset
236
                //----------------------------------------------------------------------------------------------------------------------------------
237
                case 8:
238
            i2c_write_byte(0x98);                                                                       // Address of DAC see DAC Manual page 17 
239
                break;
240
 
241
        case 9:
242
            i2c_write_byte(0x10);                                                                       // byte sent to chanel A
243
                break;
244
 
245
        case 10:
246
            i2c_write_byte(AnalogOffsetNick);                                           // offset sent to DAC
247
                break;
248
 
249
        case 11:
250
            i2c_write_byte(0x80);                                                                       // The 2nd Byte does not care = 0x80 (Dummy)
251
                break;
252
 
253
        case 12:
254
            i2c_stop();              
255
            I2CTimeout = 10;
256
            i2c_start();  
257
                break;
258
 
259
        case 13:
260
                        i2c_write_byte(0x98);                                                                   // Address of DAC see DAC Manual page 17 
261
        break;
262
 
263
        case 14:
264
            i2c_write_byte(0x12);                                                                       // byte sent to chanel B
265
        break;
266
 
267
        case 15:
268
            i2c_write_byte(AnalogOffsetRoll);                                           // offset sent to DAC
269
        break;
270
 
271
        case 16:
272
            i2c_write_byte(0x80);                                                                       // The 2nd Byte does not care = 0x80 (Dummy)
273
        break;
274
 
275
        case 17:
276
            i2c_stop();              
277
            I2CTimeout = 10;
278
            i2c_start();  
279
        break;
280
 
281
        case 18:
282
            i2c_write_byte(0x98);                                                                       // Address of DAC see DAC Manual page 17 
283
        break;
284
 
285
        case 19:
286
            i2c_write_byte(0x14);                                                                       // byte sent to chanel C
287
        break;
288
 
289
        case 20:
290
            i2c_write_byte(AnalogOffsetGier);                                           // offset sent to DAC
291
        break;
292
 
293
        case 21:
294
            i2c_write_byte(0x80);                                                                       // The 2nd Byte does not care = 0x80 (Dummy)
295
        break;
296
 
297
        case 22:
298
            i2c_stop();              
299
            I2CTimeout = 10;
300
            twi_state = 0;
301
        break;
302
 
303
        default: twi_state = 0;
304
        break;        
305
        }
306
        TWCR |= 0x80;   // TWWC: TWI Write Collision Flag is set to 1
307
}
308
//-----------------------------------------------------------------------------------------------------------------------------------