Go to most recent revision | Details | 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; |
||
13 | volatile uint8_t motor_rx[8]; |
||
1 | ingob | 14 | |
694 | killagreg | 15 | /**************************************************/ |
16 | /* Initialize I2C (TWI) */ |
||
17 | /**************************************************/ |
||
1 | ingob | 18 | void i2c_init(void) |
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 | /****************************************/ |
||
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 | /****************************************/ |
||
1 | ingob | 59 | void i2c_stop(void) |
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 | /****************************************/ |
||
173 | holgerb | 75 | void i2c_reset(void) |
76 | { |
||
694 | 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_write_byte(0); |
||
173 | holgerb | 91 | } |
92 | |||
694 | killagreg | 93 | /****************************************/ |
94 | /* Write to I2C */ |
||
95 | /****************************************/ |
||
96 | void i2c_write_byte(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 | /****************************************/ |
||
110 | void i2c_receive_byte(void) |
||
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 | /****************************************/ |
||
118 | void i2c_receive_last_byte(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 |
||
1 | ingob | 136 | i2c_write_byte(0x52+(motor*2)); |
137 | break; |
||
694 | killagreg | 138 | case 1: // Send Data to Salve |
1 | ingob | 139 | switch(motor++) |
140 | { |
||
141 | case 0: |
||
701 | killagreg | 142 | i2c_write_byte(Motor_Front); |
1 | ingob | 143 | break; |
685 | killagreg | 144 | case 1: |
701 | killagreg | 145 | i2c_write_byte(Motor_Rear); |
1 | ingob | 146 | break; |
147 | case 2: |
||
701 | killagreg | 148 | i2c_write_byte(Motor_Right); |
1 | ingob | 149 | break; |
150 | case 3: |
||
701 | killagreg | 151 | i2c_write_byte(Motor_Left); |
1 | ingob | 152 | break; |
153 | } |
||
154 | break; |
||
694 | killagreg | 155 | case 2: // repeat case 0+1 for all Slaves |
1 | ingob | 156 | if (motor<4) twi_state = 0; |
694 | killagreg | 157 | i2c_start(); // Repeated start -> switch salve or switch Master Transmit -> Master Receive |
685 | killagreg | 158 | break; |
159 | |||
694 | killagreg | 160 | // Master Receive |
161 | case 3: // Send SLA-R |
||
1 | ingob | 162 | i2c_write_byte(0x53+(motorread*2)); |
163 | break; |
||
164 | case 4: |
||
694 | killagreg | 165 | //Transmit 1st byte |
166 | i2c_receive_byte(); |
||
1 | ingob | 167 | break; |
694 | killagreg | 168 | case 5: //Read 1st byte and transmit 2nd Byte |
1 | ingob | 169 | motor_rx[motorread] = TWDR; |
694 | killagreg | 170 | i2c_receive_last_byte(); |
171 | break; |
||
172 | case 6: |
||
173 | //Read 2nd byte |
||
174 | motor_rx[motorread+4] = TWDR; |
||
175 | motorread++; |
||
176 | if (motorread > 3) motorread=0; |
||
173 | holgerb | 177 | |
694 | killagreg | 178 | default: |
1 | ingob | 179 | i2c_stop(); |
694 | killagreg | 180 | twi_state = 0; |
173 | holgerb | 181 | I2CTimeout = 10; |
694 | killagreg | 182 | motor = 0; |
1 | ingob | 183 | } |
184 | } |