00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdio.h>
00025
00026 #include <aversive.h>
00027 #include <mf2_client.h>
00028 #include <mf2_client_config.h>
00029
00030 #ifdef CONFIG_MODULE_MF2_CLIENT_USE_SCHEDULER
00031 #include <scheduler.h>
00032 #else
00033 #include <aversive/wait.h>
00034 #endif
00035
00036 #define WATCHDOG_TIMEOUT 10000
00037
00038 #define MF2_CLIENT_STATE_IDLE 0
00039 #define MF2_CLIENT_STATE_RECV 1
00040 #define MF2_CLIENT_STATE_XMIT 2
00041 #define MF2_CLIENT_STATE_ACK 3
00042
00043 #define data_Z() cbi(DDR(MF2_CLIENT_DATA_PORT), MF2_CLIENT_DATA_BIT)
00044 #define data_0() sbi(DDR(MF2_CLIENT_DATA_PORT), MF2_CLIENT_DATA_BIT)
00045 #define clk_Z() cbi(DDR(MF2_CLIENT_CLK_PORT), MF2_CLIENT_CLK_BIT)
00046 #define clk_0() sbi(DDR(MF2_CLIENT_CLK_PORT), MF2_CLIENT_CLK_BIT)
00047
00048
00049
00050 static volatile u08 state=MF2_CLIENT_STATE_IDLE;
00051 static volatile u08 current_bitnum;
00052 static volatile u16 rx_buf;
00053 static volatile u16 tx_buf;
00054 static volatile u08 tx_c;
00055 #ifdef CONFIG_MODULE_MF2_CLIENT_USE_SCHEDULER
00056 static volatile s08 sched_event = -1;
00057 #endif
00058
00059 typedef void (event)(char);
00060
00061 static event * tx_event = NULL;
00062 static event * rx_event = NULL;
00063
00064 static s16 check_rx_buf(u16 buf);
00065
00066 #ifdef CONFIG_MODULE_MF2_CLIENT_USE_SCHEDULER
00067 static void watchdog_timeout(void * dummy);
00068 #endif
00069
00070 static void disable_intr(void);
00071 static void set_falling_edge(void);
00072
00073 #define START_BIT 0x0001
00074 #define PARITY_BIT 0x0200
00075 #define STOP_BIT 0x0400
00076
00077 SIGNAL(MF2_CLIENT_INTERRUPT)
00078 {
00079 s16 c;
00080
00081
00082 switch(state) {
00083 case MF2_CLIENT_STATE_IDLE:
00084 rx_buf=0;
00085 state=MF2_CLIENT_STATE_RECV;
00086 current_bitnum=1;
00087 #ifdef CONFIG_MODULE_MF2_CLIENT_USE_SCHEDULER
00088 sched_event = scheduler_add_single_event(watchdog_timeout,
00089 NULL, WATCHDOG_TIMEOUT/SCHEDULER_UNIT);
00090 #endif
00091 break;
00092
00093 case MF2_CLIENT_STATE_RECV:
00094 if(PIN(MF2_CLIENT_DATA_PORT) & (1<<MF2_CLIENT_DATA_BIT))
00095 rx_buf |= (1 << current_bitnum);
00096
00097 if (current_bitnum==10) {
00098 disable_intr();
00099 clk_0();
00100 if (rx_event) {
00101 c=check_rx_buf(rx_buf);
00102 if( c >= 0 ) {
00103 rx_event((char)(c));
00104 }
00105 }
00106 current_bitnum=0;
00107 #ifdef CONFIG_MODULE_MF2_CLIENT_USE_SCHEDULER
00108 if (sched_event != -1) {
00109 scheduler_del_event(sched_event);
00110 sched_event = -1;
00111 }
00112 #endif
00113 data_Z();
00114 clk_Z();
00115 set_falling_edge();
00116 state=MF2_CLIENT_STATE_IDLE;
00117 }
00118 else {
00119 current_bitnum++;
00120 }
00121 break;
00122
00123 case MF2_CLIENT_STATE_XMIT:
00124 if (current_bitnum < 10) {
00125 if (tx_buf & (1<<current_bitnum))
00126 data_Z();
00127 else
00128 data_0();
00129 current_bitnum ++;
00130 }
00131 else {
00132 data_Z();
00133 current_bitnum=0;
00134 state=MF2_CLIENT_STATE_ACK;
00135 }
00136 break;
00137
00138 case MF2_CLIENT_STATE_ACK:
00139
00140
00141
00142 if (tx_event) {
00143 tx_event((char)(tx_c));
00144 }
00145 state=MF2_CLIENT_STATE_IDLE;
00146 #ifdef CONFIG_MODULE_MF2_CLIENT_USE_SCHEDULER
00147 if (sched_event != -1) {
00148 scheduler_del_event(sched_event);
00149 sched_event = -1;
00150 }
00151 #endif
00152 break;
00153
00154 default:
00155 break;
00156 }
00157 }
00158
00159 static void set_falling_edge(void)
00160 {
00161
00162 cbi(MF2_CLIENT_IMASK, MF2_CLIENT_IMASK_BIT);
00163
00164
00165 cbi(MF2_CLIENT_INT_REG, MF2_CLIENT_INT_BIT0);
00166 sbi(MF2_CLIENT_INT_REG, MF2_CLIENT_INT_BIT1);
00167
00168
00169 sbi(MF2_CLIENT_IFLAG, MF2_CLIENT_IMASK_BIT);
00170
00171
00172 sbi(MF2_CLIENT_IMASK, MF2_CLIENT_IMASK_BIT);
00173
00174 }
00175
00176 static void disable_intr(void)
00177 {
00178
00179 cbi(MF2_CLIENT_IMASK, MF2_CLIENT_IMASK_BIT);
00180 }
00181
00182
00183 void mf2_client_init(void)
00184 {
00185 u08 flags;
00186
00187 IRQ_LOCK(flags);
00188
00189 data_Z();
00190 clk_Z();
00191 cbi(MF2_CLIENT_DATA_PORT, MF2_CLIENT_DATA_BIT);
00192 cbi(MF2_CLIENT_CLK_PORT, MF2_CLIENT_CLK_BIT);
00193
00194 set_falling_edge();
00195
00196 state = MF2_CLIENT_STATE_IDLE;
00197 current_bitnum = 0;
00198 IRQ_UNLOCK(flags);
00199 }
00200
00201 static s16 check_rx_buf(u16 buf)
00202 {
00203 u16 mask, cpt=0;
00204
00205
00206 if(buf & START_BIT)
00207 return -1;
00208
00209
00210 if(! (buf & STOP_BIT))
00211 return -2;
00212
00213 for (mask = START_BIT ; mask != STOP_BIT; mask<<=1 ) {
00214 if (buf & mask)
00215 cpt++;
00216 }
00217
00218
00219 if (!(cpt % 2))
00220 return -3;
00221
00222 return (buf>>1) & 0xFF;
00223 }
00224
00225
00226 s08 mf2_client_ready(void)
00227 {
00228 return state==MF2_CLIENT_STATE_IDLE;
00229 }
00230
00231 #ifdef CONFIG_MODULE_MF2_CLIENT_USE_SCHEDULER
00232 static void watchdog_timeout(void * dummy)
00233 {
00234 printf("TIMEOUT\n");
00235 current_bitnum=0;
00236 state=MF2_CLIENT_STATE_IDLE;
00237 data_Z();
00238 clk_Z();
00239 set_falling_edge();
00240 }
00241 #endif
00242
00243 static void start_sending(void * dummy)
00244 {
00245
00246 clk_Z();
00247 data_0();
00248 set_falling_edge();
00249 #ifdef CONFIG_MODULE_MF2_CLIENT_USE_SCHEDULER
00250 sched_event = scheduler_add_single_event(watchdog_timeout,
00251 NULL, WATCHDOG_TIMEOUT/SCHEDULER_UNIT);
00252 #endif
00253 }
00254
00255 s08 mf2_client_send(char c)
00256 {
00257 u16 mask, cpt=0;
00258 u08 flags;
00259
00260 IRQ_LOCK(flags);
00261
00262
00263
00264 if (!mf2_client_ready()) {
00265 IRQ_UNLOCK(flags);
00266 return -1;
00267 }
00268
00269 state=MF2_CLIENT_STATE_XMIT;
00270 current_bitnum = 1;
00271
00272 disable_intr();
00273
00274
00275 clk_0();
00276
00277 IRQ_UNLOCK(flags);
00278
00279 tx_buf = c;
00280 tx_c = c;
00281 tx_buf <<= 1;
00282 tx_buf |= STOP_BIT;
00283
00284 for (mask = START_BIT ; mask != STOP_BIT; mask<<=1 ) {
00285 if (tx_buf & mask)
00286 cpt++;
00287 }
00288
00289 if (!(cpt % 2))
00290 tx_buf |= PARITY_BIT;
00291
00292 #if CONFIG_MODULE_MF2_CLIENT_USE_SCHEDULER
00293 scheduler_add_single_event(start_sending, NULL, 1000L/SCHEDULER_UNIT);
00294 #else
00295 wait_ms(1);
00296 start_sending(NULL);
00297 #endif
00298
00299 return 0;
00300 }
00301
00302
00303
00304 void mf2_client_register_tx_event(void (*f)(char))
00305 {
00306 u08 flags;
00307 IRQ_LOCK(flags);
00308 tx_event = f;
00309 IRQ_UNLOCK(flags);
00310 }
00311
00312
00313
00314 void mf2_client_register_rx_event(void (*f)(char))
00315 {
00316 u08 flags;
00317 IRQ_LOCK(flags);
00318 rx_event = f;
00319 IRQ_UNLOCK(flags);
00320 }
00321