1 | /*
|
2 | * TID.c
|
3 | * fuelmeter
|
4 | *
|
5 | * Created by Alexander Peters on 25.12.07.
|
6 | * Copyright 2007 __MyCompanyName__. All rights reserved.
|
7 | *
|
8 | */
|
9 |
|
10 | #include <TID.h>
|
11 | #include <avr/io.h>
|
12 | #include <avr/interrupt.h>
|
13 | #include <util/delay.h>
|
14 | #include <string.h>
|
15 |
|
16 | #define _PORT PORTD
|
17 | #define _DDR DDRD
|
18 | #define _PIN PIND
|
19 | #define _SCL_out 0
|
20 | #define _SCL_in 1
|
21 | #define _MRQ_out 2
|
22 | #define _MRQ_in 3
|
23 | #define _SDA_out 4
|
24 | #define _SDA_in 5
|
25 | #define _AA 6
|
26 |
|
27 | #define _address 0x4A
|
28 |
|
29 |
|
30 | #define _step 128
|
31 |
|
32 | char string[9] = "TEST ";
|
33 | volatile char symbol[2], buffer[10];
|
34 | volatile uint8_t state, mark, bitToSend, ByteToSend, cyclesRem;
|
35 |
|
36 | void MRQ_high(void){
|
37 | _PORT &= ~(1<<_MRQ_out);
|
38 | }
|
39 |
|
40 | void MRQ_low(void){
|
41 | _PORT |= (1<<_MRQ_out);
|
42 | }
|
43 |
|
44 | void SCL_high(void){
|
45 | _PORT &= ~(1<<_SCL_out);
|
46 | }
|
47 |
|
48 | void SCL_low(void){
|
49 | _PORT |= (1<<_SCL_out);
|
50 | }
|
51 |
|
52 | void SDA_high(void){
|
53 | _PORT &= ~(1<<_SDA_out);
|
54 | }
|
55 |
|
56 | void SDA_low(void){
|
57 | _PORT |= (1<<_SDA_out);
|
58 | }
|
59 |
|
60 |
|
61 | uint8_t get_MRQ(void){
|
62 | return (_PIN & (1<< _MRQ_in));
|
63 | }
|
64 |
|
65 | uint8_t get_SCL(void){
|
66 | return (_PIN & (1<< _SCL_in));
|
67 | }
|
68 |
|
69 | uint8_t get_SDA(void){
|
70 | return (_PIN & (1<< _SDA_in));
|
71 | }
|
72 |
|
73 | void init_DDR(void){
|
74 | _DDR = (0<< _MRQ_in | 1<< _MRQ_out | 0<< _SCL_in | 1<< _SCL_out | 0<< _SDA_in |1<< _SDA_out | 1<<_AA);
|
75 | }
|
76 |
|
77 | void init_timer(void){
|
78 | TCCR2 = (0<<FOC2 | 0<<WGM20 | 0<<COM21 | 0<<COM20 | 0<<WGM21 | 1<<CS22 | 1<<CS21 | 1<<CS20); //normal operation, prescaler 1024
|
79 | TIMSK &= ~(1<<TOIE2 | 1<<OCIE2); //timer2 overflow/output compare interrupt disabled
|
80 | }
|
81 |
|
82 | void enable_timer_int(void){
|
83 | TIMSK |= (1<<TOIE2); //timer2 overflow interrupt enabled
|
84 | }
|
85 |
|
86 | void disable_timer_int(void){
|
87 | TIMSK &= ~(1<<TOIE2); //timer2 overflow interrupt disabled
|
88 | }
|
89 |
|
90 |
|
91 | void start_timer_ns(uint16_t ns){
|
92 | uint16_t steps = (ns/_step);
|
93 | cyclesRem=steps/256;
|
94 | TCNT2=(steps-(cyclesRem*256));
|
95 | enable_timer_int();
|
96 | }
|
97 |
|
98 | void start_timer_us(uint16_t us){
|
99 | uint16_t steps = (1000*(us/_step));
|
100 | cyclesRem=steps/256;
|
101 | TCNT2=(steps-(cyclesRem*256));
|
102 | enable_timer_int();
|
103 | }
|
104 |
|
105 | void delay_50us(uint8_t i){
|
106 | for(;i>0;i--){
|
107 | _delay_us(50);
|
108 | }
|
109 | }
|
110 |
|
111 | void TID_on(void){
|
112 | _PORT |= (1 << _AA); //set bit
|
113 |
|
114 | for(uint8_t i=0; i<100;i++){ //warte 1sec
|
115 | _delay_ms(10);
|
116 | }
|
117 |
|
118 | state=1;
|
119 | }
|
120 |
|
121 | void TID_off(void){
|
122 | _PORT &= ~(1<< _AA); //clear bit
|
123 | state=0;
|
124 | }
|
125 |
|
126 | void TID_init(void){
|
127 | init_DDR();
|
128 | init_timer();
|
129 |
|
130 | SDA_high();
|
131 | SCL_high();
|
132 | MRQ_high();
|
133 |
|
134 | sei();
|
135 | }
|
136 |
|
137 | void send_start(void){
|
138 | PORTC=1;
|
139 |
|
140 | MRQ_low();
|
141 | while(get_SDA()); //warte bis SDA low
|
142 | delay_50us(2);
|
143 | MRQ_high();
|
144 | PORTC=2;
|
145 |
|
146 | while(!get_SDA()); //warte bis SDA high
|
147 | delay_50us(2);
|
148 |
|
149 | SDA_low();
|
150 | delay_50us(3);
|
151 |
|
152 | SCL_low();
|
153 | delay_50us(3);
|
154 |
|
155 | PORTC=3;
|
156 | }
|
157 |
|
158 | void send_stop(void){
|
159 |
|
160 | SDA_low();
|
161 | delay_50us(2);
|
162 | MRQ_high();
|
163 | delay_50us(2);
|
164 | SCL_high();
|
165 | delay_50us(2);
|
166 | SDA_high();
|
167 | delay_50us(2);
|
168 |
|
169 | }
|
170 |
|
171 | void send_bit(uint8_t bit){
|
172 |
|
173 | if(bit){ //put bit on bus
|
174 | SDA_high();
|
175 | }else{
|
176 | SDA_low();
|
177 | }
|
178 | _delay_us(5);
|
179 |
|
180 | SCL_high(); //set bit valid
|
181 | while(!get_SCL()); //wait for slave
|
182 | delay_50us(1); //wait
|
183 | SCL_low();
|
184 |
|
185 | _delay_us(50);
|
186 |
|
187 | }
|
188 |
|
189 | uint8_t end_Byte(void){
|
190 | uint8_t ack;
|
191 |
|
192 | SDA_high();
|
193 | delay_50us(1);
|
194 | SCL_high();
|
195 |
|
196 | while(!get_SCL());
|
197 |
|
198 | ack=get_SDA();
|
199 | delay_50us(1);
|
200 | SDA_low();
|
201 |
|
202 | while(!get_SDA());
|
203 | delay_50us(2);
|
204 |
|
205 | return ack;
|
206 | }
|
207 |
|
208 | void send_Byte(char Byte){
|
209 | uint8_t parity=1;
|
210 |
|
211 | for(uint8_t i=6; i>0; i--){
|
212 | if((Byte & ~(1<<i))){
|
213 | parity = !parity;
|
214 | }
|
215 |
|
216 | send_bit((Byte & ~(1<<i)));
|
217 | }
|
218 |
|
219 | send_bit(parity);
|
220 |
|
221 | PORTC=end_Byte();
|
222 | }
|
223 |
|
224 | void TID_update(void){
|
225 |
|
226 |
|
227 | TID_init();
|
228 |
|
229 | TID_on();
|
230 |
|
231 | symbol[0]=0x10;
|
232 | symbol[1]=0x01;
|
233 |
|
234 | send_start();
|
235 | send_Byte(_address);
|
236 | delay_50us(2);
|
237 | MRQ_low();
|
238 | delay_50us(2);
|
239 |
|
240 |
|
241 |
|
242 | for(uint8_t i=0; i<2;i++){
|
243 | send_Byte(symbol[i]);
|
244 | }
|
245 |
|
246 | for(uint8_t i=0; i<8;i++){
|
247 | send_Byte(string[i]);
|
248 | }
|
249 |
|
250 | send_stop();
|
251 |
|
252 | }
|