merge hostsim in main
[aversive.git] / modules / comm / mf2_server / mf2_server.c
1 /*  
2  *  Copyright Droids Corporation, Microb Technology, Eirbot (2005)
3  * 
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  *  Revision : $Id: mf2_server.c,v 1.1.2.5 2007-05-23 17:18:11 zer0 Exp $
19  *
20  */
21
22 /* Olivier MATZ, Droids-corp 2007 */
23
24 #include <stdio.h>
25
26 #include <aversive.h>
27 #include <aversive/wait.h>
28 #include <timer.h>
29 #include <mf2_server.h>
30 #include <mf2_server_config.h>
31
32
33 #define data_Z() do { cbi(DDR(MF2_SERVER_DATA_PORT), MF2_SERVER_DATA_BIT); } while(0)
34 #define data_0() do { sbi(DDR(MF2_SERVER_DATA_PORT), MF2_SERVER_DATA_BIT); } while(0)
35 #define read_data() (bit_is_set(PIN(MF2_SERVER_DATA_PORT), MF2_SERVER_DATA_BIT))
36 #define data_is_Z() (!bit_is_set(DDR(MF2_SERVER_DATA_PORT), MF2_SERVER_DATA_BIT))
37
38 #define clk_Z() do { cbi(DDR(MF2_SERVER_CLK_PORT), MF2_SERVER_CLK_BIT); } while(0)
39 #define clk_0() do { sbi(DDR(MF2_SERVER_CLK_PORT), MF2_SERVER_CLK_BIT); } while(0)
40 #define read_clk() (bit_is_set(PIN(MF2_SERVER_CLK_PORT), MF2_SERVER_CLK_BIT))
41 #define clk_is_Z() (!bit_is_set(DDR(MF2_SERVER_CLK_PORT), MF2_SERVER_CLK_BIT))
42
43 #define MF2_SERVER_STATE_READY 0
44 #define MF2_SERVER_STATE_SEND  1
45 #define MF2_SERVER_STATE_RECV  2
46
47 static volatile uint8_t mf2_state=0;
48
49 typedef void (event)(char);
50 static event * tx_event = NULL;
51 static event * rx_event = NULL;
52 static volatile uint8_t mf2_step=0;
53 static volatile uint8_t mf2_parity_cpt=0;
54 static volatile char mf2_data_send=0;
55 static volatile char mf2_data_recv=0;
56
57
58 #define WAIT_KBD_CYCLE 600
59 #define WAIT_KBD_CYCLE4 WAIT_KBD_CYCLE/4
60
61
62 void recv(void)
63 {
64         uint8_t i;
65         uint16_t c=0;
66         uint16_t d=0;
67         data_Z();
68         clk_Z();
69         if (read_data())
70                 printf("burp\r\n");
71 /*      wait_4cyc(WAIT_KBD_CYCLE4); */
72 /*      wait_4cyc(WAIT_KBD_CYCLE4); */
73 /*      wait_4cyc(WAIT_KBD_CYCLE4); */
74         clk_0();
75         wait_4cyc(WAIT_KBD_CYCLE4);
76         
77         
78         for (i=0; i<8 ; i++) {
79                 if (read_data()) 
80                         c |= 1 << i;
81                 clk_Z();
82                 wait_4cyc(WAIT_KBD_CYCLE4);
83                 if (read_data()) 
84                         d |= 1 << i;
85                 clk_0();
86                 wait_4cyc(WAIT_KBD_CYCLE4);
87         }
88
89         // parite
90         clk_Z();
91         wait_4cyc(WAIT_KBD_CYCLE4);
92         clk_0();
93         wait_4cyc(WAIT_KBD_CYCLE4);
94
95         // ack
96         clk_Z();
97         data_0();
98         wait_4cyc(WAIT_KBD_CYCLE4);
99         clk_0();
100         wait_4cyc(WAIT_KBD_CYCLE4);
101
102         // stop
103         clk_Z();
104         data_Z();
105         wait_4cyc(WAIT_KBD_CYCLE4);
106         clk_0();
107         wait_4cyc(WAIT_KBD_CYCLE4);
108         clk_Z();
109         
110         printf("%x\r\n", c);
111         printf("%x\r\n", d);
112         wait_4cyc(2*WAIT_KBD_CYCLE4);
113         while(1);
114 }
115
116 static inline int8_t mf2_server_bus_free(void)
117 {
118         return read_clk() && read_data();
119 }
120
121
122 int8_t mf2_server_ready(void)
123 {
124         return (mf2_state==MF2_SERVER_STATE_READY && mf2_server_bus_free());
125 }
126
127 /* a virer XXX */
128 void disp(char c);
129
130 #if 0
131 static inline void dump(void)
132 {
133         char c=0;
134         if(read_data()) 
135                 c|=1;
136         if(read_clk()) 
137                 c|=0x10;
138
139         if(data_is_Z()) 
140                 c|=2;
141         if(clk_is_Z()) 
142                 c|=0x20;
143
144         disp((char)(c));
145 }
146 #else
147 #define dump() do {} while(0)
148 #endif
149
150 void mf2_server_timer_cb(void)
151 {
152 /*      static uint16_t i=0; */
153         static uint16_t t;
154
155         /* if it is just polling */
156         if (mf2_state == MF2_SERVER_STATE_READY) {
157                 clk_Z();
158                 data_Z();
159
160                 /* the central server has something to say */
161                 if (read_clk() && !read_data()) {
162                         mf2_state = MF2_SERVER_STATE_RECV;
163                         mf2_step = 1;
164                         timer1A_register_OC_intr_at_tics(mf2_server_timer_cb, timer1_get()+MF2_SERVER_CLK_HALF_PERIOD);
165                         //                      recv();
166                         dump();
167                         return;
168                 }       
169                 /* nothing to do if the central server has nothing to say */
170                 else {
171                         /* reload timer */
172                         timer1A_register_OC_intr_at_tics(mf2_server_timer_cb, timer1_get()+MF2_SERVER_READ_POLL_PERIOD);
173                         return;
174                 }
175         }
176
177         /* an operation is running */
178
179         /* reload timer */
180         timer1A_register_OC_intr_at_tics(mf2_server_timer_cb, timer1_get()+MF2_SERVER_CLK_HALF_PERIOD);
181
182         /* XXX we should check if clk is 0 when clk_Z() */
183         if (mf2_state == MF2_SERVER_STATE_RECV) {
184                 switch(mf2_step) {
185                 case 1:
186                         mf2_data_recv=0;
187                         dump();
188                         clk_0();
189                         break;
190                 case 2:
191                         dump();
192                         clk_Z();
193                         break;
194
195                 case 3:
196                 case 5:
197                 case 7:
198                 case 9:
199                 case 11:
200                 case 13:
201                 case 15:
202                 case 17:
203                         //                      t = timer1_get();
204                         dump();
205                         clk_0();
206                         if(read_data())
207                                 mf2_data_recv |= (1 << ( (mf2_step-3)/2 ) );
208                         break;
209                 case 4:
210                 case 6:
211                 case 8:
212                 case 10:
213                 case 12:
214                 case 14:
215                 case 16:
216                 case 18:
217 /*                      printf("%d\n",  timer1_get() - t); */
218 /*                      while(1); */
219                         dump();
220                         clk_Z();
221                         break;
222
223                 case 19:
224                         /* parity */
225                         dump();
226                         clk_0();
227                         break;
228                 case 20:
229                         dump();
230                         clk_Z();
231                         data_0();
232                         break;
233                 case 21:
234                         dump();
235                         clk_0();
236                         break;
237                 case 22:
238                         dump();
239                         clk_Z();
240                         data_Z();
241                         break;
242
243                 default:
244                         if (rx_event) {
245 /*                              c=check_rx_buf(rx_buf); */
246                                 rx_event((char)(mf2_data_recv));
247 /*                              rx_event((char)(0xED)); */
248                         }
249                         mf2_state = MF2_SERVER_STATE_READY; 
250                         mf2_step = 0;
251                         timer1A_register_OC_intr_at_tics(mf2_server_timer_cb, timer1_get()+MF2_SERVER_READ_POLL_PERIOD);
252                         return;
253                 }
254                 mf2_step++;
255         }
256         else {
257                 switch(mf2_step) {
258                 case 1:
259                         data_0();
260                         break;
261                 case 2:
262                         clk_0();
263                         break;
264                 case 3:
265                 case 5:
266                 case 7:
267                 case 9:
268                 case 11:
269                 case 13:
270                 case 15:
271                 case 17:
272                         if(mf2_data_send & (1<<((mf2_step-3)/2))) {
273                                 data_Z();
274                                 mf2_parity_cpt ++;
275                         }
276                         else {
277                                 data_0();
278                         }
279                         clk_Z();
280                         break;
281                 case 4:
282                 case 6:
283                 case 8:
284                 case 10:
285                 case 12:
286                 case 14:
287                 case 16:
288                 case 18:
289                         /* XXX */
290                         if(!(read_clk())) {
291 /*                              /\*                     recv(); *\/ */
292 /*                                                      printf("Ceci est un test\n"); */
293 /*                                                      printf("%d\n", mf2_step); */
294 /*                                                      printf("%2.2x\n", mf2_data_send); */
295 /*                                                      while(1); */
296                                 mf2_step=0;
297                                 mf2_state = MF2_SERVER_STATE_RECV;
298                                 
299                         }
300                         clk_0();
301                         break;
302
303                 case 19:
304                         if(!(mf2_parity_cpt%2))
305                                 data_Z();
306                         else
307                                 data_0();
308                         clk_Z();
309                         break;
310                 case 20:
311                         clk_0();
312                         break;
313                 case 21:
314                         clk_Z();
315                         data_Z();
316                         break;
317                 case 22:
318                         clk_0();
319                         break;
320                 case 23:
321                         clk_Z();
322                         break;
323                 case 24:
324                 case 25:
325                         break;
326                 default:
327                         mf2_state = MF2_SERVER_STATE_READY;
328                         mf2_step = 0;
329                         timer1A_register_OC_intr_at_tics(mf2_server_timer_cb, timer1_get()+MF2_SERVER_READ_POLL_PERIOD);
330                         return;
331                 }
332                 mf2_step++;
333         }
334 }
335         
336
337
338 int8_t mf2_server_send(char c)
339 {
340         uint8_t flags;
341
342         IRQ_LOCK(flags);
343
344         if (!mf2_server_ready()) {
345                 IRQ_UNLOCK(flags);
346                 //              recv();
347                 return -1;
348         }
349
350         mf2_state = MF2_SERVER_STATE_SEND;
351         mf2_step = 1;
352         mf2_data_send = c;
353         mf2_parity_cpt = 0;
354         timer1A_register_OC_intr_at_tics(mf2_server_timer_cb, 
355                                          timer1_get()+MF2_SERVER_CLK_HALF_PERIOD);
356         clk_Z();
357         data_Z();
358         IRQ_UNLOCK(flags);
359         return 0;
360 }
361
362 void mf2_server_init(void)
363 {
364         cbi(MF2_SERVER_DATA_PORT, MF2_SERVER_DATA_BIT);
365         cbi(MF2_SERVER_CLK_PORT, MF2_SERVER_CLK_BIT);
366
367         timer1A_register_OC_intr_at_tics(mf2_server_timer_cb, 
368                                          timer1_get()+MF2_SERVER_READ_POLL_PERIOD);
369
370         /* XXX choose timer */
371         clk_Z();
372         data_Z();
373 }
374
375 /* This function is used to register another function which will be */
376 /* executed at each byte transmission. */
377 void mf2_server_register_tx_event(void (*f)(char))
378 {
379         u08 flags;
380         IRQ_LOCK(flags);
381         tx_event = f;
382         IRQ_UNLOCK(flags);
383 }
384
385 /* This function is used to register another function which will be */
386 /* executed at each byte reception. */
387 void mf2_server_register_rx_event(void (*f)(char))
388 {
389         u08 flags;
390         IRQ_LOCK(flags);
391         rx_event = f;
392         IRQ_UNLOCK(flags);
393 }
394