Rev 726 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | ingob | 1 | /*############################################################################ |
2 | ############################################################################*/ |
||
3 | |||
687 | killagreg | 4 | #include <avr/io.h> |
5 | #include <avr/interrupt.h> |
||
6 | |||
1 | ingob | 7 | #include "main.h" |
685 | killagreg | 8 | #include "twimaster.h" |
9 | #include "fc.h" |
||
1 | ingob | 10 | |
694 | killagreg | 11 | volatile uint8_t twi_state = 0; |
12 | volatile uint8_t motor = 0; |
||
898 | pangu | 13 | volatile uint8_t motor_rx[12]; |
1 | ingob | 14 | |
694 | killagreg | 15 | /**************************************************/ |
16 | /* Initialize I2C (TWI) */ |
||
17 | /**************************************************/ |
||
726 | killagreg | 18 | void I2C_Init(void) |
1 | ingob | 19 | { |
694 | 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 | |||
694 | killagreg | 40 | /****************************************/ |
41 | /* Start I2C */ |
||
42 | /****************************************/ |
||
726 | killagreg | 43 | void I2C_Start(void) |
1 | ingob | 44 | { |
694 | 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 | |||
694 | killagreg | 56 | /****************************************/ |
57 | /* Stop I2C */ |
||
58 | /****************************************/ |
||
726 | killagreg | 59 | void I2C_Stop(void) |
1 | ingob | 60 | { |
694 | 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 | |||
694 | killagreg | 72 | /****************************************/ |
73 | /* Reset I2C */ |
||
74 | /****************************************/ |
||
726 | killagreg | 75 | void I2C_Reset(void) |
173 | holgerb | 76 | { |
694 | killagreg | 77 | // stop i2c bus |
726 | killagreg | 78 | I2C_Stop(); |
694 | killagreg | 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; |
||
726 | killagreg | 88 | I2C_Init(); |
89 | I2C_Start(); |
||
90 | I2C_WriteByte(0); |
||
173 | holgerb | 91 | } |
92 | |||
694 | killagreg | 93 | /****************************************/ |
94 | /* Write to I2C */ |
||
95 | /****************************************/ |
||
726 | killagreg | 96 | void I2C_WriteByte(int8_t byte) |
685 | killagreg | 97 | { |
694 | killagreg | 98 | // move byte to send into TWI Data Register |
1 | ingob | 99 | TWDR = byte; |
694 | 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); |
694 | killagreg | 104 | } |
685 | killagreg | 105 | |
106 | |||
694 | killagreg | 107 | /****************************************/ |
108 | /* Receive byte and send ACK */ |
||
109 | /****************************************/ |
||
726 | killagreg | 110 | void I2C_ReceiveByte(void) |
694 | killagreg | 111 | { |
112 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWEA); |
||
1 | ingob | 113 | } |
114 | |||
694 | killagreg | 115 | /****************************************/ |
116 | /* I2C receive last byte and send no ACK*/ |
||
117 | /****************************************/ |
||
726 | killagreg | 118 | void I2C_ReceiveLastByte(void) |
1 | ingob | 119 | { |
694 | killagreg | 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 | { |
694 | killagreg | 134 | // Master Transmit |
135 | case 0: // Send SLA-W |
||
726 | killagreg | 136 | I2C_WriteByte(0x52+(motor*2)); |
1 | ingob | 137 | break; |
694 | killagreg | 138 | case 1: // Send Data to Salve |
1 | ingob | 139 | switch(motor++) |
140 | { |
||
141 | case 0: |
||
898 | pangu | 142 | I2C_WriteByte(Motor_FrontLeft); |
1 | ingob | 143 | break; |
685 | killagreg | 144 | case 1: |
898 | pangu | 145 | I2C_WriteByte(Motor_RearRight); |
1 | ingob | 146 | break; |
147 | case 2: |
||
898 | pangu | 148 | I2C_WriteByte(Motor_FrontRight); |
149 | break; |
||
150 | case 3: |
||
151 | I2C_WriteByte(Motor_RearLeft); |
||
152 | break; |
||
153 | case 4: |
||
726 | killagreg | 154 | I2C_WriteByte(Motor_Right); |
1 | ingob | 155 | break; |
898 | pangu | 156 | case 5: |
726 | killagreg | 157 | I2C_WriteByte(Motor_Left); |
1 | ingob | 158 | break; |
159 | } |
||
160 | break; |
||
694 | killagreg | 161 | case 2: // repeat case 0+1 for all Slaves |
898 | pangu | 162 | if (motor<6) twi_state = 0; |
726 | killagreg | 163 | I2C_Start(); // Repeated start -> switch salve or switch Master Transmit -> Master Receive |
685 | killagreg | 164 | break; |
165 | |||
694 | killagreg | 166 | // Master Receive |
167 | case 3: // Send SLA-R |
||
726 | killagreg | 168 | I2C_WriteByte(0x53+(motorread*2)); |
1 | ingob | 169 | break; |
170 | case 4: |
||
694 | killagreg | 171 | //Transmit 1st byte |
726 | killagreg | 172 | I2C_ReceiveByte(); |
1 | ingob | 173 | break; |
694 | killagreg | 174 | case 5: //Read 1st byte and transmit 2nd Byte |
1 | ingob | 175 | motor_rx[motorread] = TWDR; |
726 | killagreg | 176 | I2C_ReceiveLastByte(); |
694 | killagreg | 177 | break; |
178 | case 6: |
||
179 | //Read 2nd byte |
||
898 | pangu | 180 | motor_rx[motorread+6] = TWDR; |
694 | killagreg | 181 | motorread++; |
898 | pangu | 182 | if (motorread > 5) motorread=0; |
173 | holgerb | 183 | |
694 | killagreg | 184 | default: |
726 | killagreg | 185 | I2C_Stop(); |
694 | killagreg | 186 | twi_state = 0; |
173 | holgerb | 187 | I2CTimeout = 10; |
694 | killagreg | 188 | motor = 0; |
1 | ingob | 189 | } |
190 | } |