Subversion Repositories FlightCtrl

Rev

Rev 2108 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2108 Rev 2109
1
#include "twimaster.h"
1
#include "twimaster.h"
2
#include "analog.h"
2
#include "analog.h"
-
 
3
#include "output.h"
3
#include <inttypes.h>
4
#include <inttypes.h>
4
#include <util/twi.h>
5
#include <util/twi.h>
5
#include <avr/interrupt.h>
6
#include <avr/interrupt.h>
6
 
7
 
7
uint8_t twiState;
8
uint8_t twiState;
8
uint8_t twiTroubleSpot;
9
uint8_t twiTroubleSpot;
9
uint8_t twiGotStatus;
10
uint8_t twiGotStatus;
10
 
11
 
11
volatile uint16_t IMU3200SensorInputs[4];
12
volatile uint16_t IMU3200SensorInputs[4];
12
 
13
 
13
void twimaster_init(void) {
14
void twimaster_init(void) {
14
        // Set pullups
15
        // Set pullups
15
        uint8_t sreg = SREG;
16
        uint8_t sreg = SREG;
16
        cli();
17
        cli();
17
        DDRC = 0;
18
        DDRC = 0;
18
        PORTC = ((1 << 4) | (1 << 5));
19
        PORTC = ((1 << 4) | (1 << 5));
19
        TWBR = ((F_CPU / SCL_CLOCK) - 16) / 2;
20
        TWBR = ((F_CPU / SCL_CLOCK) - 16) / 2;
20
        twiState = TWI_STATE_INIT_0;
21
        twiState = TWI_STATE_INIT_0;
21
        SREG = sreg;
22
        SREG = sreg;
22
}
23
}
23
 
24
 
24
void I2CStart(void) {
25
void I2CStart(void) {
25
        TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN) | (1 << TWIE);
26
        TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN) | (1 << TWIE);
26
}
27
}
27
 
28
 
28
void I2CStop(void) {
29
void I2CStop(void) {
29
        TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN);
30
        TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN);
30
}
31
}
31
 
32
 
32
void I2CWriteByte(int8_t byte) {
33
void I2CWriteByte(int8_t byte) {
33
        TWDR = byte;
34
        TWDR = byte;
34
        TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE);
35
        TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE);
35
}
36
}
36
 
37
 
37
void I2CReceiveByte(void) {
38
void I2CReceiveByte(void) {
38
        TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE) | (1 << TWEA);
39
        TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE) | (1 << TWEA);
39
}
40
}
40
 
41
 
41
void I2CReceiveLastByte(void) {
42
void I2CReceiveLastByte(void) {
42
        TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE);
43
        TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE);
43
}
44
}
44
 
45
 
45
void I2CReset(void) {
46
void I2CReset(void) {
-
 
47
  debugOut.analog[29]++;
46
        I2CStop();
48
        I2CStop();
47
        TWCR = (1 << TWINT); // reset to original state incl. interrupt flag reset
49
        TWCR = (1 << TWINT); // reset to original state incl. interrupt flag reset
48
        TWAMR = 0;
50
        TWAMR = 0;
49
        TWAR = 0;
51
        TWAR = 0;
50
        TWDR = 0;
52
        TWDR = 0;
51
        TWSR = 0;
53
        TWSR = 0;
52
        TWBR = 0;
54
        TWBR = 0;
53
        // Naaaah we dont need this: init_I2C();
55
        // Naaaah we dont need this: init_I2C();
54
        I2CStart();
56
        I2CStart();
55
        twiState = TWI_STATE_INIT_0;
57
        twiState = TWI_STATE_INIT_0;
56
}
58
}
57
 
59
 
58
void twimaster_setNeutral(void) {
60
void twimaster_setNeutral(void) {
59
        twiState = TWI_STATE_INIT_0;
61
        twiState = TWI_STATE_INIT_0;
60
        I2CStart();
62
        I2CStart();
61
}
63
}
62
 
64
 
63
void twimaster_startCycle(void) {
65
void twimaster_startCycle(void) {
-
 
66
        if (sensorDataReady & TWI_DATA_READY) { // if OK last time
64
        twiState = TWI_STATE_LOOP_0;
67
          twiState = TWI_STATE_LOOP_0;
65
        I2CStart();
68
          I2CStart();
-
 
69
        } else {                                // go get em.
-
 
70
          I2CReset();
-
 
71
        }
66
}
72
}
67
 
73
 
68
const uint8_t EXPECTED_STATUS[] = { START, MT_SLA_ACK, MT_DATA_ACK,
74
const uint8_t EXPECTED_STATUS[] = { START, MT_SLA_ACK, MT_DATA_ACK,
69
                MT_DATA_ACK, MT_DATA_ACK, REPEATED_START, MT_SLA_ACK, MT_DATA_ACK,
75
                MT_DATA_ACK, MT_DATA_ACK, REPEATED_START, MT_SLA_ACK, MT_DATA_ACK,
70
                REPEATED_START, MR_SLA_ACK, MR_DATA_ACK, MR_DATA_ACK, MR_DATA_ACK,
76
                REPEATED_START, MR_SLA_ACK, MR_DATA_ACK, MR_DATA_ACK, MR_DATA_ACK,
71
                MR_DATA_ACK, MR_DATA_ACK, MR_DATA_ACK, MR_DATA_ACK, MR_DATA_NACK };
77
                MR_DATA_ACK, MR_DATA_ACK, MR_DATA_ACK, MR_DATA_ACK, MR_DATA_NACK };
72
const uint8_t GYRO_CONFIGURATION[] = { 15, 3 << 3 };
78
const uint8_t GYRO_CONFIGURATION[] = { 15, 3 << 3 };
73
 
79
 
74
ISR( TWI_vect) {
80
ISR( TWI_vect) {
75
        if (twiState == sizeof(EXPECTED_STATUS)) {
81
        if (twiState == sizeof(EXPECTED_STATUS)) {
76
                // We have come too far, panic!
82
                // We have come too far, panic!
77
                I2CReset();
83
                I2CReset();
78
        }
84
        }
79
 
85
 
80
        uint8_t cur_twi_state = twiState;
86
        uint8_t cur_twi_state = twiState;
81
        twiState++;
87
        twiState++;
82
        uint8_t status = TWSR_FILTER;
88
        uint8_t status = TWSR_FILTER;
83
        if (status != EXPECTED_STATUS[cur_twi_state]) {
89
        if (status != EXPECTED_STATUS[cur_twi_state]) {
84
                // A little confusion between repeated and nonrepeated start is OK.
90
                // A little confusion between repeated and nonrepeated start is OK.
85
                if (!((status == START && EXPECTED_STATUS[cur_twi_state]
91
                if (!((status == START && EXPECTED_STATUS[cur_twi_state]
86
                                == REPEATED_START) || (status == REPEATED_START
92
                                == REPEATED_START) || (status == REPEATED_START
87
                                && EXPECTED_STATUS[cur_twi_state] == START))) {
93
                                && EXPECTED_STATUS[cur_twi_state] == START))) {
88
                        // Panic, reset
94
                        // Panic, reset
89
                        twiTroubleSpot = cur_twi_state;
95
                        twiTroubleSpot = cur_twi_state;
90
                        twiGotStatus = status;
96
                        twiGotStatus = status;
91
                        I2CReset();
97
                        I2CReset();
92
                }
98
                }
93
        }
99
        }
94
 
100
 
95
        uint8_t dataIndex = cur_twi_state - TWI_STATE_LOOP_0 - 5;
101
        uint8_t dataIndex = cur_twi_state - TWI_STATE_LOOP_0 - 5;
96
        // Fix endiannness!
102
        // Fix endiannness!
97
        if (dataIndex & 1)
103
        if (dataIndex & 1)
98
                dataIndex &= ~1;
104
                dataIndex &= ~1;
99
        else
105
        else
100
                dataIndex |= 1;
106
                dataIndex |= 1;
101
 
107
 
102
        switch (cur_twi_state) {
108
        switch (cur_twi_state) {
103
        case TWI_STATE_INIT_0:
109
        case TWI_STATE_INIT_0:
104
                I2CWriteByte((SLA << 1) | 0);
110
                I2CWriteByte((SLA << 1) | 0);
105
                break;
111
                break;
106
        case TWI_STATE_INIT_0 + 1:
112
        case TWI_STATE_INIT_0 + 1:
107
                I2CWriteByte(GYRO_CONFIGURATION_START);
113
                I2CWriteByte(GYRO_CONFIGURATION_START);
108
                break;
114
                break;
109
        case TWI_STATE_INIT_0 + 2:
115
        case TWI_STATE_INIT_0 + 2:
110
                I2CWriteByte(GYRO_CONFIGURATION[0]);
116
                I2CWriteByte(GYRO_CONFIGURATION[0]);
111
                break;
117
                break;
112
        case TWI_STATE_INIT_0 + 3:
118
        case TWI_STATE_INIT_0 + 3:
113
                I2CWriteByte(GYRO_CONFIGURATION[1]);
119
                I2CWriteByte(GYRO_CONFIGURATION[1]);
114
                break;
120
                break;
115
        case TWI_STATE_INIT_0 + 4:
121
        case TWI_STATE_INIT_0 + 4:
116
                I2CStop();
122
                I2CStop();
117
                // Need to check ACK ans return to 0 if not (skipping start below).
123
                // Need to check ACK ans return to 0 if not (skipping start below).
118
                I2CStart();
124
                I2CStart();
119
                break;
125
                break;
120
        case TWI_STATE_LOOP_0:
126
        case TWI_STATE_LOOP_0:
121
                I2CWriteByte((SLA << 1) | 0);
127
                I2CWriteByte((SLA << 1) | 0);
122
                break;
128
                break;
123
        case TWI_STATE_LOOP_0 + 1:
129
        case TWI_STATE_LOOP_0 + 1:
124
                I2CWriteByte(GYRO_DATA_START);
130
                I2CWriteByte(GYRO_DATA_START);
125
                break;
131
                break;
126
        case TWI_STATE_LOOP_0 + 2:
132
        case TWI_STATE_LOOP_0 + 2:
127
                I2CStop();
133
                I2CStop();
128
                I2CStart();
134
                I2CStart();
129
                break;
135
                break;
130
        case TWI_STATE_LOOP_0 + 3:
136
        case TWI_STATE_LOOP_0 + 3:
131
                I2CWriteByte((SLA << 1) | 1);
137
                I2CWriteByte((SLA << 1) | 1);
132
                break;
138
                break;
133
        case TWI_STATE_LOOP_0 + 4:
139
        case TWI_STATE_LOOP_0 + 4:
134
                I2CReceiveByte();
140
                I2CReceiveByte();
135
                break;
141
                break;
136
        default: // data bytes
142
        default: // data bytes
137
                ((uint8_t*) IMU3200SensorInputs)[dataIndex] = TWDR;
143
                ((uint8_t*) IMU3200SensorInputs)[dataIndex] = TWDR;
138
                if (twiState < TWI_STATE_LOOP_0 + 5 + sizeof(IMU3200SensorInputs) - 1)
144
                if (twiState < TWI_STATE_LOOP_0 + 5 + sizeof(IMU3200SensorInputs) - 1)
139
                        I2CReceiveByte();
145
                        I2CReceiveByte();
140
                else
146
                else
141
                        I2CReceiveLastByte();
147
                        I2CReceiveLastByte();
142
                break;
148
                break;
143
        case TWI_STATE_LOOP_0 + 5 + sizeof(IMU3200SensorInputs) - 1: // last data byte
149
        case TWI_STATE_LOOP_0 + 5 + sizeof(IMU3200SensorInputs) - 1: // last data byte
144
                ((uint8_t*) IMU3200SensorInputs)[dataIndex] = TWDR;
150
                ((uint8_t*) IMU3200SensorInputs)[dataIndex] = TWDR;
145
                // Dont re-init the gyro but just restart the loop.
151
                // Dont re-init the gyro but just restart the loop.
146
                I2CStop();
152
                I2CStop();
147
                sensorDataReady |= TWI_DATA_READY;
153
                sensorDataReady |= TWI_DATA_READY;
-
 
154
                debugOut.analog[28]++;
148
                break;
155
                break;
149
        }
156
        }
150
}
157
}
151
 
158