Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2222 | - | 1 | /************************************************************************************************************************************** |
2 | * File: twimaster.c |
||
3 | * |
||
4 | * Purpose: controlling I2C |
||
5 | * |
||
6 | * Functions: int void i2c_init(void) |
||
7 | * void i2c_reset(void) |
||
8 | * void i2c_start(void) |
||
9 | * void i2c_stop(void) |
||
10 | * void i2c_write_byte(unsigned char byte) |
||
11 | * void I2C_ReceiveByte(void) |
||
12 | * void I2C_ReceiveLastByte(void) |
||
13 | * ISR(TWI_vect) |
||
14 | * |
||
15 | * hardware: AVR-Ctrl experimental board without LCD display as I2C bus is used |
||
16 | * |
||
17 | * Created: Feb 2013 |
||
18 | * |
||
19 | * Version: 1.00 experimental version |
||
20 | * |
||
21 | * Copyright: (c)2013 dk9nw -at- darc.de |
||
22 | * All rights reserved. This software is available only for non-commercial amateur radio or educational applications. |
||
23 | * Other uses are prohibited. This software may be modified only if |
||
24 | * the resulting code be made available publicly and the original author(s) given credit. |
||
25 | * |
||
26 | ******************************************************************************************************************************************/ |
||
27 | #include "twimaster.h" |
||
28 | |||
29 | unsigned char twi_state = 0; |
||
30 | volatile unsigned char Motor[4]; // turn rate of the connected electrical motor 0 - 255 |
||
31 | |||
32 | |||
33 | // ************************************************************************************************************************** |
||
34 | // initialize the I2C Bus (TWI) |
||
35 | // |
||
36 | void i2c_init(void) |
||
37 | { |
||
38 | static unsigned char sreg; |
||
39 | sreg = SREG; // save backup status register , to be reseted later |
||
40 | cli(); // switch off I-Bit Global Interrupt |
||
41 | |||
42 | //-------------------------------------------------------------------------------------------------------------------- |
||
43 | // TWSR = TWI Status Register containing: TWS7 TWS6 TWS5 TWS4 TWS3 – TWPS1 TWPS0 |
||
44 | // ------------------------- |
||
45 | // TWPS: TWI Prescaler Bits |
||
46 | // |
||
47 | TWSR &= ~((1<<TWPS1)|(1<<TWPS0)); // TWI Status Register Bits 1..0 – TWPS: TWI Prescaler Bits 00=1:1 01=1:4 10=1:16 11=1:64 |
||
48 | |||
49 | //-------------------------------------------------------------------------------------------------------------------- |
||
50 | // TWBR = TWI Bit Rate Register containing: TWBR7 TWBR6 TWBR5 TWBR4 TWBR3 TWBR2 TWBR1 TWBR0 |
||
51 | // set TWI Bit Rate Register // SCL_frequency = ( CPU_Clock_frequency / ( 16 + 2 * TWBR ) * 4**TWPS ) |
||
52 | // // |
||
53 | TWBR = ((SYSCLK/SCL_CLOCK)-16)/2; // TWI Bit Rate (formula is only valid if TWSR=0) |
||
54 | |||
55 | twi_state = 0; |
||
56 | |||
57 | i2c_start(); |
||
58 | |||
59 | SREG = sreg; // write back to old state, |
||
60 | sei(); // Interrupt is activated again |
||
61 | } |
||
62 | // ************************************************************************************************************************** |
||
63 | |||
64 | |||
65 | |||
66 | // ************************************************************************************************************************** |
||
67 | // reset I2C Bus |
||
68 | // |
||
69 | void i2c_reset(void) |
||
70 | { |
||
71 | i2c_stop(); // stop i2c Bus |
||
72 | twi_state = 0; |
||
73 | TWCR = (1<<TWINT); // reset to original state incl. interrupt flag reset |
||
74 | TWAR = 0; |
||
75 | TWDR = 0; |
||
76 | TWSR = 0; |
||
77 | TWBR = 0; |
||
78 | i2c_init(); // initialize the I2C Bus (TWI) |
||
79 | i2c_start(); |
||
80 | i2c_write_byte(0); |
||
81 | } |
||
82 | // ************************************************************************************************************************** |
||
83 | |||
84 | |||
85 | |||
86 | // ************************************************************************************************************************** |
||
87 | // start of I2C Bus |
||
88 | // |
||
89 | void i2c_start(void) |
||
90 | { |
||
91 | // TWCR = TWI Control Register -> TWINT TWEA TWSTA TWSTO TWWC TWEN – TWIE |
||
92 | // -------------------------------------------------------------------- |
||
93 | // TWINT = TWI interrupt flag - to be set to one, to reset the TWINT Flag . |
||
94 | // TWSTA = TWI start and should be set to one, that TWI is started as Master. |
||
95 | // TWEN = TWI enable -> now TWI/I2C is working properly. |
||
96 | // TWIE = TWI Interrupt enable is the TWIE Bit -> should be set |
||
97 | TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE); |
||
98 | |||
99 | //while( !(TWCR & (1<<TWINT) ) ); // wait, that TWINT is zero again, that means that the start conditions have been transferred |
||
100 | } |
||
101 | // ************************************************************************************************************************** |
||
102 | |||
103 | |||
104 | |||
105 | // ************************************************************************************************************************** |
||
106 | // stop the I2C Bus |
||
107 | // |
||
108 | void i2c_stop(void) |
||
109 | { |
||
110 | // TWCR = TWI Control Register -> TWINT TWEA TWSTA TWSTO TWWC TWEN – TWIE |
||
111 | // -------------------------------------------------------------------- |
||
112 | // TWINT = TWI interrupt flag - to be set to one, to reset the TWINT Flag . |
||
113 | // TWSTO TWI STOP Condition Bit (TWSTO = 1) -> now will be stoped |
||
114 | // TWEN = TWI enable -> now TWI/I2C is working properly. |
||
115 | TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN); |
||
116 | } |
||
117 | // ************************************************************************************************************************** |
||
118 | |||
119 | |||
120 | |||
121 | |||
122 | // ************************************************************************************************************************** |
||
123 | // Write to I2C |
||
124 | // |
||
125 | void i2c_write_byte(unsigned char byte) |
||
126 | { |
||
127 | //TWSR = 0x00; // TWI Status Register |
||
128 | |||
129 | TWDR = byte; // move byte to send into TWI Data Register |
||
130 | |||
131 | // TWCR = TWI Control Register -> TWINT TWEA TWSTA TWSTO TWWC TWEN – TWIE |
||
132 | // -------------------------------------------------------------------- |
||
133 | // TWINT = TWI interrupt flag - to be set to one, to reset the TWINT Flag . |
||
134 | // TWEN = TWI enable -> now TWI/I2C is working properly. |
||
135 | // TWIE = TWI Interrupt enable is the TWIE Bit -> should be set |
||
136 | // |
||
137 | TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE); |
||
138 | } |
||
139 | // ************************************************************************************************************************** |
||
140 | |||
141 | |||
142 | |||
143 | // ************************************************************************************************************************** |
||
144 | // Receive byte and send ACK |
||
145 | // |
||
146 | void I2C_ReceiveByte(void) |
||
147 | { |
||
148 | // TWCR = TWI Control Register -> TWINT TWEA TWSTA TWSTO TWWC TWEN – TWIE |
||
149 | // --------------------------------------------------------------------------- |
||
150 | // TWINT = TWI interrupt flag - to be set to one, to reset the TWINT Flag . |
||
151 | // TWEA = TWI Acknowledge Bit (TWEA = 1) |
||
152 | // TWEN = TWI enable -> now TWI/I2C is working properly. |
||
153 | // TWIE = TWI Interrupt enable is the TWIE Bit -> should be set |
||
154 | // |
||
155 | TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE) ; |
||
156 | } |
||
157 | // ************************************************************************************************************************** |
||
158 | |||
159 | |||
160 | |||
161 | // ************************************************************************************************************************** |
||
162 | // I2C receive last byte and send no ACK |
||
163 | // |
||
164 | void I2C_ReceiveLastByte(void) |
||
165 | { |
||
166 | // TWCR = TWI Control Register -> TWINT TWEA TWSTA TWSTO TWWC TWEN – TWIE |
||
167 | // --------------------------------------------------------------------------- |
||
168 | // TWINT = TWI interrupt flag - to be set to one, to reset the TWINT Flag . |
||
169 | // TWEN = TWI enable -> now TWI/I2C is working properly. |
||
170 | // TWIE = TWI Interrupt enable is the TWIE Bit -> should be set |
||
171 | // |
||
172 | TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE); |
||
173 | } |
||
174 | // ************************************************************************************************************************** |
||
175 | |||
176 | |||
177 | |||
178 | // ************************************************************************************************************************** |
||
179 | // Interrupt I2C |
||
180 | //--------------------------------------------------------------------------------------------------------------------------- |
||
181 | ISR(TWI_vect) |
||
182 | { |
||
183 | switch(twi_state++) |
||
184 | { |
||
185 | //------------------------------------------------------------------------------------------------------------------- |
||
186 | // write Motor-Data to BL-Ctrl |
||
187 | //------------------------------------------------------------------------------------------------------------------- |
||
188 | case 0: |
||
189 | i2c_write_byte(0x52); |
||
190 | break; |
||
191 | |||
192 | case 1: |
||
193 | i2c_write_byte(Motor[0]); |
||
194 | break; |
||
195 | |||
196 | case 2: |
||
197 | i2c_stop(); |
||
198 | i2c_start(); |
||
199 | break; |
||
200 | |||
201 | case 3: |
||
202 | i2c_write_byte(0x54); |
||
203 | break; |
||
204 | |||
205 | case 4: |
||
206 | i2c_write_byte(Motor[1]); |
||
207 | break; |
||
208 | |||
209 | case 5: |
||
210 | i2c_stop(); |
||
211 | i2c_start(); |
||
212 | break; |
||
213 | |||
214 | case 6: |
||
215 | i2c_write_byte(0x56); |
||
216 | break; |
||
217 | |||
218 | case 7: |
||
219 | i2c_write_byte(Motor[2]); |
||
220 | break; |
||
221 | |||
222 | case 8: |
||
223 | i2c_stop(); |
||
224 | i2c_start(); |
||
225 | break; |
||
226 | |||
227 | case 9: |
||
228 | i2c_write_byte(0x58); |
||
229 | break; |
||
230 | |||
231 | case 10: |
||
232 | i2c_write_byte(Motor[3]); |
||
233 | break; |
||
234 | |||
235 | case 11: |
||
236 | i2c_stop(); |
||
237 | twi_state = 0; |
||
238 | i2c_start(); |
||
239 | break; |
||
240 | |||
241 | default: |
||
242 | twi_state = 0; |
||
243 | break; |
||
244 | } |
||
245 | } |
||
246 | // EOF ISR(TWI_vect) ***************************************************************************************************** |