Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1910 | - | 1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
||
3 | #include <util/twi.h> |
||
4 | #include <util/delay.h> |
||
5 | //#include "eeprom.h" |
||
6 | #include "twimaster.h" |
||
7 | //#include "analog.h" |
||
8 | #include "configuration.h" |
||
9 | |||
10 | volatile uint8_t twi_state = TWI_STATE_IDLE; |
||
11 | volatile uint8_t dac_channel = 0; |
||
12 | volatile uint16_t I2CTimeout = 100; |
||
13 | volatile uint8_t DACValues[4]; |
||
14 | uint8_t DACChannel = 0; |
||
15 | |||
16 | #define SCL_CLOCK 200000L |
||
17 | #define I2C_TIMEOUT 30000 |
||
18 | |||
19 | /************************************************** |
||
20 | * Initialize I2C (TWI) |
||
21 | **************************************************/ |
||
22 | void I2C_init(void) { |
||
23 | uint8_t i; |
||
24 | uint8_t sreg = SREG; |
||
25 | cli(); |
||
26 | |||
27 | // SDA is INPUT |
||
28 | DDRC &= ~(1 << DDC1); |
||
29 | // SCL is output |
||
30 | DDRC |= (1 << DDC0); |
||
31 | // pull up SDA |
||
32 | PORTC |= (1 << PORTC0) | (1 << PORTC1); |
||
33 | |||
34 | // TWI Status Register |
||
35 | // prescaler 1 (TWPS1 = 0, TWPS0 = 0) |
||
36 | TWSR &= ~((1 << TWPS1) | (1 << TWPS0)); |
||
37 | |||
38 | // set TWI Bit Rate Register |
||
39 | TWBR = ((SYSCLK / SCL_CLOCK) - 16) / 2; |
||
40 | |||
41 | twi_state = TWI_STATE_IDLE; |
||
42 | SREG = sreg; |
||
43 | } |
||
44 | |||
45 | /**************************************** |
||
46 | * Start I2C |
||
47 | ****************************************/ |
||
48 | void I2C_Start(uint8_t start_state) { |
||
49 | twi_state = start_state; |
||
50 | // TWI Control Register |
||
51 | // clear TWI interrupt flag (TWINT=1) |
||
52 | // disable TWI Acknowledge Bit (TWEA = 0) |
||
53 | // enable TWI START Condition Bit (TWSTA = 1), MASTER |
||
54 | // disable TWI STOP Condition Bit (TWSTO = 0) |
||
55 | // disable TWI Write Collision Flag (TWWC = 0) |
||
56 | // enable i2c (TWEN = 1) |
||
57 | // enable TWI Interrupt (TWIE = 1) |
||
58 | TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN) | (1 << TWIE); |
||
59 | } |
||
60 | |||
61 | /**************************************** |
||
62 | * Stop I2C |
||
63 | ****************************************/ |
||
64 | void I2C_Stop(uint8_t start_state) { |
||
65 | twi_state = start_state; |
||
66 | // TWI Control Register |
||
67 | // clear TWI interrupt flag (TWINT=1) |
||
68 | // disable TWI Acknowledge Bit (TWEA = 0) |
||
69 | // diable TWI START Condition Bit (TWSTA = 1), no MASTER |
||
70 | // enable TWI STOP Condition Bit (TWSTO = 1) |
||
71 | // disable TWI Write Collision Flag (TWWC = 0) |
||
72 | // enable i2c (TWEN = 1) |
||
73 | // disable TWI Interrupt (TWIE = 0) |
||
74 | TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); |
||
75 | } |
||
76 | |||
77 | /**************************************** |
||
78 | * Write to I2C |
||
79 | ****************************************/ |
||
80 | void I2C_WriteByte(int8_t byte) { |
||
81 | // move byte to send into TWI Data Register |
||
82 | TWDR = byte; |
||
83 | // clear interrupt flag (TWINT = 1) |
||
84 | // enable i2c bus (TWEN = 1) |
||
85 | // enable interrupt (TWIE = 1) |
||
86 | TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE); |
||
87 | } |
||
88 | |||
89 | /**************************************** |
||
90 | * Receive byte and send ACK |
||
91 | ****************************************/ |
||
92 | void I2C_ReceiveByte(void) { |
||
93 | TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE) | (1 << TWEA); |
||
94 | } |
||
95 | |||
96 | /**************************************** |
||
97 | * I2C receive last byte and send no ACK |
||
98 | ****************************************/ |
||
99 | void I2C_ReceiveLastByte(void) { |
||
100 | TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE); |
||
101 | } |
||
102 | |||
103 | /**************************************** |
||
104 | * Reset I2C |
||
105 | ****************************************/ |
||
106 | void I2C_Reset(void) { |
||
107 | // stop i2c bus |
||
108 | I2C_Stop(TWI_STATE_IDLE); |
||
109 | TWCR = (1 << TWINT); // reset to original state incl. interrupt flag reset |
||
110 | TWAMR = 0; |
||
111 | TWAR = 0; |
||
112 | TWDR = 0; |
||
113 | TWSR = 0; |
||
114 | TWBR = 0; |
||
115 | I2C_init(); |
||
116 | } |
||
117 | |||
118 | /**************************************** |
||
119 | * I2C ISR |
||
120 | ****************************************/ |
||
121 | ISR (TWI_vect) |
||
122 | { |
||
123 | switch (twi_state) { // First i2c_start from SendMotorData() |
||
124 | case 0: break; |
||
125 | |||
126 | // Writing ADC values. |
||
127 | case 7: |
||
128 | twi_state++; |
||
129 | I2C_WriteByte(0x98); // Address the DAC |
||
130 | break; |
||
131 | |||
132 | case 8: |
||
133 | twi_state++; |
||
134 | I2C_WriteByte(0x10 + (DACChannel << 1)); // Select DAC Channel (0x10 = A, 0x12 = B, 0x14 = C) |
||
135 | break; |
||
136 | |||
137 | case 9: |
||
138 | twi_state++; |
||
139 | I2C_WriteByte(DACValues[DACChannel]); |
||
140 | break; |
||
141 | |||
142 | case 10: |
||
143 | twi_state++; |
||
144 | I2C_WriteByte(0x80); // 2nd byte for all channels is 0x80 |
||
145 | break; |
||
146 | |||
147 | case 11: |
||
148 | twi_state++; |
||
149 | I2C_Stop(TWI_STATE_IDLE); |
||
150 | I2CTimeout = 10; |
||
151 | // repeat case 7...10 until all DAC Channels are updated |
||
152 | if (DACChannel < 2) { |
||
153 | DACChannel++; // jump to next channel |
||
154 | I2C_Start(TWI_STATE_GYRO_OFFSET_TX); // start transmission for next channel |
||
155 | } else { |
||
156 | DACChannel = 0; // reset dac channel counter |
||
157 | } |
||
158 | break; |
||
159 | |||
160 | default: |
||
161 | I2C_Stop(TWI_STATE_IDLE); |
||
162 | I2CTimeout = 10; |
||
163 | } |
||
164 | } |