Rev 886 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | ingob | 1 | /*############################################################################ |
2 | ############################################################################*/ |
||
3 | |||
886 | killagreg | 4 | #include <avr/io.h> |
5 | #include <avr/interrupt.h> |
||
6 | |||
1 | ingob | 7 | #include "main.h" |
886 | killagreg | 8 | #include "twimaster.h" |
9 | #include "fc.h" |
||
1 | ingob | 10 | |
886 | killagreg | 11 | volatile uint8_t twi_state = 0; |
12 | volatile uint8_t motor = 0; |
||
903 | pangu | 13 | volatile uint8_t motor_rx[MOTOR_COUNT*2]; |
1 | ingob | 14 | |
886 | killagreg | 15 | /**************************************************/ |
16 | /* Initialize I2C (TWI) */ |
||
17 | /**************************************************/ |
||
18 | void I2C_Init(void) |
||
1 | ingob | 19 | { |
886 | killagreg | 20 | uint8_t sreg = SREG; |
21 | cli(); |
||
22 | |||
23 | // SDA is INPUT |
||
24 | DDRC &= ~(1<<DDC1); |
||
25 | // SCL is output |
||
26 | DDRC |= (1<<DDC0); |
||
27 | // pull up SDA |
||
28 | PORTC |= (1<<PORTC0)|(1<<PORTC1); |
||
29 | |||
30 | // TWI Status Register |
||
31 | // prescaler 1 (TWPS1 = 0, TWPS0 = 0) |
||
32 | TWSR &= ~((1<<TWPS1)|(1<<TWPS0)); |
||
33 | |||
34 | // set TWI Bit Rate Register |
||
35 | TWBR = ((SYSCLK/SCL_CLOCK)-16)/2; |
||
36 | |||
37 | SREG = sreg; |
||
1 | ingob | 38 | } |
39 | |||
886 | killagreg | 40 | /****************************************/ |
41 | /* Start I2C */ |
||
42 | /****************************************/ |
||
43 | void I2C_Start(void) |
||
1 | ingob | 44 | { |
886 | killagreg | 45 | // TWI Control Register |
46 | // clear TWI interrupt flag (TWINT=1) |
||
47 | // disable TWI Acknowledge Bit (TWEA = 0) |
||
48 | // enable TWI START Condition Bit (TWSTA = 1), MASTER |
||
49 | // disable TWI STOP Condition Bit (TWSTO = 0) |
||
50 | // disable TWI Write Collision Flag (TWWC = 0) |
||
51 | // enable i2c (TWIE = 1) |
||
52 | // enable TWI Interrupt (TWIE = 1) |
||
53 | TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN) | (1<<TWIE); |
||
1 | ingob | 54 | } |
55 | |||
886 | killagreg | 56 | /****************************************/ |
57 | /* Stop I2C */ |
||
58 | /****************************************/ |
||
59 | void I2C_Stop(void) |
||
1 | ingob | 60 | { |
886 | killagreg | 61 | // TWI Control Register |
62 | // clear TWI interrupt flag (TWINT=1) |
||
63 | // disable TWI Acknowledge Bit (TWEA = 0) |
||
64 | // diable TWI START Condition Bit (TWSTA = 1), no MASTER |
||
65 | // enable TWI STOP Condition Bit (TWSTO = 1) |
||
66 | // disable TWI Write Collision Flag (TWWC = 0) |
||
67 | // enable i2c (TWIE = 1) |
||
68 | // disable TWI Interrupt (TWIE = 0) |
||
69 | TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN); |
||
1 | ingob | 70 | } |
71 | |||
886 | killagreg | 72 | /****************************************/ |
73 | /* Reset I2C */ |
||
74 | /****************************************/ |
||
75 | void I2C_Reset(void) |
||
173 | holgerb | 76 | { |
886 | killagreg | 77 | // stop i2c bus |
78 | I2C_Stop(); |
||
79 | twi_state = 0; |
||
80 | motor = TWDR; // ?? |
||
81 | motor = 0; |
||
82 | TWCR = (1<<TWINT); // reset to original state incl. interrupt flag reset |
||
83 | TWAMR = 0; |
||
84 | TWAR = 0; |
||
85 | TWDR = 0; |
||
86 | TWSR = 0; |
||
87 | TWBR = 0; |
||
88 | I2C_Init(); |
||
89 | I2C_Start(); |
||
90 | I2C_WriteByte(0); |
||
173 | holgerb | 91 | } |
92 | |||
886 | killagreg | 93 | /****************************************/ |
94 | /* Write to I2C */ |
||
95 | /****************************************/ |
||
96 | void I2C_WriteByte(int8_t byte) |
||
97 | { |
||
98 | // move byte to send into TWI Data Register |
||
1 | ingob | 99 | TWDR = byte; |
886 | killagreg | 100 | // clear interrupt flag (TWINT = 1) |
101 | // enable i2c bus (TWEN = 1) |
||
102 | // enable intterupt (TWIW = 1) |
||
1 | ingob | 103 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE); |
104 | } |
||
105 | |||
886 | killagreg | 106 | |
107 | /****************************************/ |
||
108 | /* Receive byte and send ACK */ |
||
109 | /****************************************/ |
||
110 | void I2C_ReceiveByte(void) |
||
1 | ingob | 111 | { |
886 | killagreg | 112 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWEA); |
113 | } |
||
114 | |||
115 | /****************************************/ |
||
116 | /* I2C receive last byte and send no ACK*/ |
||
117 | /****************************************/ |
||
118 | void I2C_ReceiveLastByte(void) |
||
119 | { |
||
120 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE); |
||
121 | } |
||
122 | |||
123 | |||
124 | /****************************************/ |
||
125 | /* I2C ISR */ |
||
126 | /****************************************/ |
||
127 | ISR (TWI_vect) |
||
128 | |||
129 | { |
||
130 | static uint8_t motorread = 0; |
||
131 | |||
132 | switch (twi_state++) // First i2s_start from SendMotorData() |
||
1 | ingob | 133 | { |
886 | killagreg | 134 | // Master Transmit |
135 | case 0: // Send SLA-W |
||
136 | I2C_WriteByte(0x52+(motor*2)); |
||
1 | ingob | 137 | break; |
886 | killagreg | 138 | case 1: // Send Data to Salve |
903 | pangu | 139 | #ifdef HEXAKOPTER |
1 | ingob | 140 | switch(motor++) |
141 | { |
||
142 | case 0: |
||
903 | pangu | 143 | I2C_WriteByte(Motor_FrontLeft); |
144 | break; |
||
145 | case 1: |
||
146 | I2C_WriteByte(Motor_RearRight); |
||
147 | break; |
||
148 | case 2: |
||
149 | I2C_WriteByte(Motor_FrontRight); |
||
150 | break; |
||
151 | case 3: |
||
152 | I2C_WriteByte(Motor_RearLeft); |
||
153 | break; |
||
154 | case 4: |
||
155 | I2C_WriteByte(Motor_Right); |
||
156 | break; |
||
157 | case 5: |
||
158 | I2C_WriteByte(Motor_Left); |
||
159 | break; |
||
160 | } |
||
161 | |||
162 | #else |
||
163 | switch(motor++) |
||
164 | { |
||
165 | case 0: |
||
886 | killagreg | 166 | I2C_WriteByte(Motor_Front); |
1 | ingob | 167 | break; |
886 | killagreg | 168 | case 1: |
169 | I2C_WriteByte(Motor_Rear); |
||
1 | ingob | 170 | break; |
171 | case 2: |
||
886 | killagreg | 172 | I2C_WriteByte(Motor_Right); |
1 | ingob | 173 | break; |
174 | case 3: |
||
886 | killagreg | 175 | I2C_WriteByte(Motor_Left); |
1 | ingob | 176 | break; |
177 | } |
||
903 | pangu | 178 | #endif |
1 | ingob | 179 | break; |
886 | killagreg | 180 | case 2: // repeat case 0+1 for all Slaves |
903 | pangu | 181 | if (motor<MOTOR_COUNT) twi_state = 0; |
886 | killagreg | 182 | I2C_Start(); // Repeated start -> switch salve or switch Master Transmit -> Master Receive |
1 | ingob | 183 | break; |
886 | killagreg | 184 | |
185 | // Master Receive |
||
186 | case 3: // Send SLA-R |
||
187 | I2C_WriteByte(0x53+(motorread*2)); |
||
188 | break; |
||
1 | ingob | 189 | case 4: |
886 | killagreg | 190 | //Transmit 1st byte |
191 | I2C_ReceiveByte(); |
||
1 | ingob | 192 | break; |
886 | killagreg | 193 | case 5: //Read 1st byte and transmit 2nd Byte |
1 | ingob | 194 | motor_rx[motorread] = TWDR; |
886 | killagreg | 195 | I2C_ReceiveLastByte(); |
196 | break; |
||
197 | case 6: |
||
198 | //Read 2nd byte |
||
199 | motor_rx[motorread+4] = TWDR; |
||
903 | pangu | 200 | if (++motorread >= MOTOR_COUNT) motorread=0; |
173 | holgerb | 201 | |
886 | killagreg | 202 | default: |
203 | I2C_Stop(); |
||
204 | twi_state = 0; |
||
173 | holgerb | 205 | I2CTimeout = 10; |
886 | killagreg | 206 | motor = 0; |
1 | ingob | 207 | } |
208 | } |