00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <conio.h>
00024 #include <stdio.h>
00025 #include <string.h>
00026 #include <dos.h>
00027 #include <stdlib.h>
00028 #include <stdarg.h>
00029 #include <assert.h>
00030 #include "amd186.h"
00031 #include "remote.h"
00032 #include "clib/rtos.h"
00033 #include "clib/hwapi.h"
00034 #include "clib/rtos.h"
00035
00036 #define RC_DMA_LEN 1024
00037
00038
00040 static volatile unsigned dmabuf[RC_DMA_LEN];
00041
00043 static void interrupt (*oldTimerHandler)(...);
00044
00046 static unsigned long queue[RC_QUEUE_SIZE];
00047 static volatile int qHead, qCount;
00048
00049
00050
00051
00052 #ifdef RC_DEBUG
00053 static char dstring[8000];
00054 static char *dstringptr = dstring;
00055
00062 static int dprintf(const char *format, ...)
00063 {
00064 if (dstringptr-dstring>sizeof(dstring)-256)
00065 return 0;
00066 va_list arglist;
00067 va_start(arglist, format);
00068 int ret = vsprintf(dstringptr, format, arglist);
00069
00070 dstringptr += ret;
00071 assert(dstringptr < dstring+sizeof(dstring));
00072
00073 va_end(arglist);
00074 return ret;
00075 }
00076
00082 static void ddump()
00083 {
00084 printf("%s", dstring);
00085 dstring[0] = '\0';
00086 dstringptr = dstring;
00087 }
00088 #endif
00089
00090
00091
00111 static unsigned long DecodeRC5(unsigned const *samples)
00112 {
00113 int state = 3;
00114 int next[4][2] = {{ 1, -1},{ 0, 3},{ 3, -1},{ 2, 1}};
00115 int emit[4][2] = {{ 0, -1},{ -1, 1},{ 1, -1},{ -1, 0}};
00116
00117 unsigned long code = 0;
00118 for (int i=0, b=12; b>=0; i++) {
00119 unsigned t = samples[i];
00120 if (abs(t-RC5_SHORT) < RC5_MARGIN) {
00121 if (emit[state][0] == 0)
00122 b--;
00123 else if (emit[state][0] == 1)
00124 code |= 1L<<b--;
00125 state = next[state][0];
00126 } else if (abs(t-RC5_LONG) < RC5_MARGIN) {
00127 if (emit[state][1] == 0)
00128 b--;
00129 else if (emit[state][1] == 1)
00130 code |= 1L<<b--;
00131 state = next[state][1];
00132 } else {
00133
00134 return 0;
00135 }
00136
00137 if (state == -1)
00138 return 0;
00139 }
00140
00141
00142
00143 unsigned long keycode;
00144 static unsigned long lastcode = 0;
00145
00146 keycode = RCKEY_RC5 | (code & 0x7ff);
00147
00148 if (~(code^lastcode) & 0x800)
00149 keycode |= RCKEY_REPEAT;
00150 lastcode = code;
00151
00152 return keycode;
00153 }
00154
00155
00163 static unsigned long DecodeNEC(unsigned const *samples)
00164 {
00165 unsigned long keycode = RCKEY_NEC;
00166 unsigned long code = 0;
00167 static unsigned long lastcode = 0;
00168
00169 if (abs(samples[0]-NEC_START1) > NEC_MARGIN)
00170 return 0;
00171
00172 if (abs(samples[1]-NEC_START2) < NEC_MARGIN) {
00173 lastcode = 0;
00174 for (int i=0; i<32; i++) {
00175 int t1 = samples[i*2+2];
00176 int t2 = samples[i*2+3];
00177
00178 if (abs(t1-NEC_PULSE)>NEC_MARGIN)
00179 return 0;
00180
00181 if (abs(t2-NEC_PAUSE0)<NEC_MARGIN) {
00182
00183 } else if (abs(t2-NEC_PAUSE1)<NEC_MARGIN) {
00184
00185 code |= 1L << i;
00186 } else {
00187 return 0;
00188 }
00189 }
00190 } else if (abs(samples[1]-NEC_REPEAT) < NEC_MARGIN) {
00191 code = lastcode;
00192 keycode |= RCKEY_REPEAT;
00193 } else {
00194 return 0;
00195 }
00196
00197 if (((code>>16) ^ ~(code>>24)) & 0xff)
00198 return 0;
00199
00200 lastcode = code;
00201 keycode |= (((code>>16)&0xff) | ((code & 0xffff)<<8)) & RCKEY_CODE;
00202
00203 return keycode;
00204 }
00205
00206
00213 static unsigned long DecodeSAMSUNG(unsigned const *samples)
00214 {
00215
00216
00217 if ((abs(samples[0]-SAM_START1) > SAM_MARGIN) ||
00218 (abs(samples[1]-SAM_START2) > SAM_MARGIN))
00219 return 0;
00220
00221 unsigned long code = 0;
00222 for (int i=0; i<32; i++) {
00223 int t1 = samples[i*2+2];
00224 int t2 = samples[i*2+3];
00225
00226 if (abs(t1-SAM_PULSE)>SAM_MARGIN)
00227 return 0;
00228
00229 if (abs(t2-SAM_PAUSE0)<SAM_MARGIN) {
00230
00231 } else if (abs(t2-SAM_PAUSE1)<SAM_MARGIN) {
00232
00233 code |= 1L << i;
00234 } else {
00235 return 0;
00236 }
00237 }
00238
00239
00240
00241 static unsigned long lastcode = 0;
00242 static unsigned long lasttime = 0;
00243
00244 unsigned long time;
00245 unsigned long keycode;
00246
00247 keycode = RCKEY_SAMSUNG | (code >> 16);
00248
00249 RTX_Get_System_Ticks(&time);
00250 if ((code == lastcode) && (time-lasttime < SAM_REPEATMS))
00251 keycode |= RCKEY_REPEAT;
00252
00253 lastcode = code;
00254 lasttime = time;
00255
00256 return keycode;
00257 }
00258
00259
00273 static void DecodeSamples(unsigned *samples, unsigned length)
00274 {
00275 int cooked = 0;
00276 for (int i=0; i<length-1; i++) {
00277 unsigned t = (samples[i+1] - samples[i]) / TICKS_PER_uS;
00278 if (t > RC_TRESHOLD)
00279 samples[cooked++] = t;
00280 }
00281 samples[cooked++] = 0;
00282
00283 #ifdef RC_DEBUG
00284 dprintf("cooklen %d\n", cooked);
00285 dprintf("index pulse pause\n");
00286 for (int i=0; i<cooked; i+=2)
00287 dprintf(" %-4d %5u %5u\n", i, samples[i], samples[i+1]);
00288 #endif
00289
00290 unsigned long key = 0;
00291 if (!key) key = DecodeRC5(samples);
00292 if (!key) key = DecodeNEC(samples);
00293 if (!key) key = DecodeSAMSUNG(samples);
00294
00295 if (key && qCount < RC_QUEUE_SIZE) {
00296 queue[(qHead+qCount) % RC_QUEUE_SIZE] = key;
00297 qCount++;
00298 }
00299 }
00300
00301
00309 static void interrupt timerHandler(...)
00310 {
00311 static unsigned lastpos;
00312 unsigned position;
00313
00314
00315
00316
00317 position = RC_DMA_LEN - inpw(RC_DMACHANNEL ? PCB_D1TC:PCB_D0TC);
00318
00319 if (position == lastpos && position != 0)
00320 {
00321
00322
00323 DecodeSamples((unsigned*)dmabuf, position);
00324
00325
00326
00327 DmaInfo dma;
00328 AMD_GetDmaInfo(RC_DMACHANNEL, &dma);
00329 dma.length = RC_DMA_LEN;
00330 dma.dstMem = (void*)dmabuf;
00331 AMD_StartDma(RC_DMACHANNEL, &dma);
00332 }
00333 lastpos = position;
00334 oldTimerHandler();
00335 }
00336
00337
00344 int RC_KeyAvail()
00345 {
00346 #ifdef RC_DEBUG
00347 ddump();
00348 #endif
00349
00350 return (int)qCount;
00351 }
00352
00353
00361 unsigned long RC_GetKey()
00362 {
00363 while (!RC_KeyAvail()) {
00364 RTX_Sleep_Time(10);
00365 }
00366
00367 unsigned long key;
00368 key = queue[qHead++];
00369 qHead %= RC_QUEUE_SIZE;
00370 qCount--;
00371
00372 return key;
00373 }
00374
00375
00380 void RC_Init()
00381 {
00382
00383
00384 pfe_enable_bus(0xff, true);
00385 pfe_enable_pcs(1);
00386
00387
00388
00389
00390
00391
00392 oldTimerHandler = getvect(0x12);
00393 setvect(0x12, timerHandler);
00394
00395 outpw(PCB_T1CON, TCON_STOP);
00396 outpw(PCB_T1CMPA, 0 );
00397 outpw(PCB_T1CNT, 0 );
00398 outpw(PCB_T1CON, TCON_CONT | TCON_INT | TCON_START);
00399
00400
00401
00402 DmaInfo dma;
00403 dma.control = DCON_BW | DCON_TC | DCON_DMIO | DCON_DINC | DCON_SSYNC | DCON_P;
00404 dma.length = RC_DMA_LEN;
00405 dma.srcPort = PCB_T1CNT;
00406 dma.dstMem = (void*)dmabuf;
00407 AMD_StartDma(RC_DMACHANNEL, &dma);
00408 AMD_EnableDrq(RC_DMACHANNEL, true);
00409 }
00410
00411
00416 void RC_Done()
00417 {
00418
00419
00420 outpw(PCB_T1CON, TCON_STOP);
00421 if (oldTimerHandler)
00422 setvect(0x12, oldTimerHandler);
00423
00424
00425
00426 AMD_StopDma(RC_DMACHANNEL);
00427 }