*/
/*
-Cable: (walkera TX to parralel port)
+download:
+cg-clone http://zub.fei.tuke.sk/GIT/walkera0701-joystick
+http://zub.fei.tuke.sk/cgi-bin/gitweb.cgi?p=walkera0701-joystick
+
+
+Cable: (walkera TX to parport)
Walkera WK-0701 TX S-VIDEO connector:
- (back side of TX)
- __ __
- / |_| \ connect pin 2 (signal) NPN canon25
- / O 4 3 O \ connect pin 3 (GND) LED ________________ 10
+ (back side of TX)
+ __ __ S-video: canon25
+ / |_| \ pin 2 (signal) NPN parport
+ / O 4 3 O \ pin 3 (GND) LED ________________ 10 ACK
( O 2 1 O ) | C
\ ___ / 2 ________________________|\|_____|/
| [___] | |/| B |\
- ------- 3 __________________________________|________________ 25
+ ------- 3 __________________________________|________________ 25 GND
E
Frame format:
Based on walkera WK-0701 PCM Format description by Shaul Eizikovich.
+(downloaded from http://www.smartpropoplus.com/Docs/Walkera_Wk-0701_PCM.pdf)
Signal pulses:
(ANALOG)
all times in code in ns
*/
+
+//#define WK0701_DEBUG
+//#define WK0701_FULL_DEBUG
+#ifdef WK0701_FULL_DEBUG
+#ifndef WK0701_DEBUG
+#define WK0701_DEBUG
+#endif
+#endif
+
#define RESERVE 20000
#define SYNC_PULSE 1306000
#define BIN0_PULSE 288000
crc2 += (DATA[i] & 8) >> 3;
}
if ((DATA[10] & 7) != (crc1 & 7)) {
- printk(KERN_INFO "walkera0701: Bad OCT 1-4 checksum\n");
+#ifdef WK0701_DEBUG
+ printk(KERN_DEBUG "walkera0701: Bad OCT 1-4 checksum\n");
+#endif
return;
}
if (((DATA[10] & 8) >> 3) != (((crc1 >> 3) + crc2) & 1)) {
- printk(KERN_INFO "walkera0701: Bad BIN - OCT 1-4 checksum\n");
+#ifdef WK0701_DEBUG
+ printk(KERN_DEBUG "walkera0701: Bad BIN - OCT 1-4 checksum\n");
+#endif
return;
}
for (crc1 = crc2 = 0, i = 11; i < 23; i++) {
crc2 += (DATA[i] & 8) >> 3;
}
if ((DATA[23] & 7) != (crc1 & 7)) {
- printk(KERN_INFO "walkera0701: Bad OCT 5-8 checksum\n");
+#ifdef WK0701_DEBUG
+ printk(KERN_DEBUG "walkera0701: Bad OCT 5-8 checksum\n");
+#endif
return;
}
if (((DATA[23] & 8) >> 3) != (((crc1 >> 3) + crc2) & 1)) {
- printk(KERN_INFO "walkera0701: Bad BIN - OCT 5-8 checksum\n");
+#ifdef WK0701_DEBUG
+ printk(KERN_DEBUG "walkera0701: Bad BIN - OCT 5-8 checksum\n");
+#endif
return;
}
val1 = ((DATA[0] & 7) * 256 + DATA[1] * 16 + DATA[2]) >> 2;
magic = (DATA[21] << 4) | DATA[22];
magic_bit = (DATA[24] & 8) >> 3;
-/* printk(KERN_INFO "walkera0701: %4d %4d %4d %4d %4d %4d %4d %4d (magic %2x %d)\n",
- val1, val2, val3, val4, val5, val6, val7, val8, magic,magic_bit);
-*/
+#ifdef WK0701_FULL_DEBUG
+ printk(KERN_DEBUG
+ "walkera0701: %4d %4d %4d %4d %4d %4d %4d %4d (magic %2x %d)\n",
+ val1, val2, val3, val4, val5, val6, val7, val8, magic,
+ magic_bit);
+#endif
input_report_abs(input_dev, ABS_X, val2);
input_report_abs(input_dev, ABS_Y, val1);
input_report_abs(input_dev, ABS_THROTTLE, val3);
IRQlasttime = IRQtime;
//cancel timer,if in handler or active do resync
if (unlikely(0 != hrtimer_try_to_cancel(&walkera0701_timer))) {
+#ifdef WK0701_DEBUG
+ printk(KERN_DEBUG "walkera0701: timer error\n");
+#endif
counter = NO_SYNC;
return;
}
counter = NO_SYNC;
if (likely(abs(pulseTime - SYNC_PULSE) < RESERVE)) //new frame sync
counter = 0;
+#ifdef WK0701_DEBUG
+ else
+ printk(KERN_DEBUG "walkera0701: SYNC lost\n");
+#endif
} else {
if (likely((pulseTime > (ANALOG_MIN_PULSE - RESERVE))
&& (pulseTime <
pulseTime -= (ANALOG_MIN_PULSE - RESERVE);
pulseTime = (u32) pulseTime / ANALOG_DELTA; //overtiping is safe, pulsetime < s32..
DATA[counter++] |= (pulseTime & 7);
- } else
+ } else {
+#ifdef WK0701_DEBUG
+ printk(KERN_DEBUG
+ "walkera0701: pulse time out of range\n");
+#endif
counter = NO_SYNC;
+ }
}
} else {
- if (unlikely(abs(pulseTime - SYNC_PULSE - BIN0_PULSE) < (RESERVE + BIN1_PULSE - BIN0_PULSE))) //frame sync ..
+ if (unlikely(abs(pulseTime - SYNC_PULSE - BIN0_PULSE) < (RESERVE + BIN1_PULSE - BIN0_PULSE))) { //frame sync ..
+#ifdef WK0701_DEBUG
+ printk(KERN_DEBUG "walkera0701: New SYNC pulse\n");
+#endif
+
counter = 0;
+ }
}
hrtimer_start(&walkera0701_timer, ktime_set(0, BIN_SAMPLE),
HRTIMER_MODE_REL);
ACK = read_ack();
return HRTIMER_NORESTART;
}
+
static int walkera0701_open(struct input_dev *dev)
{
open_counter++;
parport_enable_irq(walkera0701_parport);
- printk(KERN_INFO "walkera0701: irq enabled, open count=%d\n",
+#ifdef WK0701_DEBUG
+ printk(KERN_DEBUG "walkera0701: irq enabled, open count=%d\n",
open_counter);
+#endif
return (0);
}
+
static void walkera0701_close(struct input_dev *dev)
{
//TODO if this is enabled, sometime parport not send interupts if module is openned
open_counter--;
if (!open_counter) {
parport_disable_irq(walkera0701_parport);
- printk(KERN_INFO "walkera0701: irq disabled\n");
+#ifdef WK0701_DEBUG
+ printk(KERN_DEBUG "walkera0701: irq disabled\n");
+#endif
}
}
+
static int walkera0701_connect(int parport)
{
int err;
return -ENODEV;
}
if (walkera0701_parport->irq == -1) {
+ parport_put_port(walkera0701_parport);
printk(KERN_ERR "walkera0701: parport without interrupt\n");
return -ENODEV;
}
parport_register_device(walkera0701_parport, "walkera0701",
NULL, NULL, walkera0701_irq_handler,
PARPORT_DEV_EXCL, NULL);
+
if (!walkera0701_pardevice) {
+ parport_put_port(walkera0701_parport);
printk(KERN_ERR "walkera0701: parport busy\n");
return -EBUSY;
}
- parport_negotiate(walkera0701_pardevice->port, IEEE1284_MODE_COMPAT);
-//TODO needed ?
-// parport_put_port(walkera0701_parport);
+ if (0 !=
+ parport_negotiate(walkera0701_pardevice->port,
+ IEEE1284_MODE_COMPAT)) {
+ printk(KERN_ERR "walkera0701: parport unable to negotiate\n");
+ parport_unregister_device(walkera0701_pardevice);
+ parport_put_port(walkera0701_parport);
+ return -EBUSY;
+ }
if (parport_claim(walkera0701_pardevice)) {
printk(KERN_ERR
"walkera0701: parport unable to claim, busy ?\n");
parport_unregister_device(walkera0701_pardevice);
+ parport_put_port(walkera0701_parport);
return -EBUSY;
}
"walkera0701 unable to allocate input device\n");
parport_release(walkera0701_pardevice);
parport_unregister_device(walkera0701_pardevice);
+ parport_put_port(walkera0701_parport);
return -ENOMEM;
}
return (err);
}
open_counter = 0;
- //parport_enable_irq(walkera0701_parport);
return 0;
}
walkera0701_timer.function = walkera0701_timer_handler;
return walkera0701_connect(walkera0701_pp_no);
}
+
static void __exit walkera0701_exit(void)
{
hrtimer_cancel(&walkera0701_timer);
if (walkera0701_pardevice) {
parport_release(walkera0701_pardevice);
parport_unregister_device(walkera0701_pardevice);
+ parport_put_port(walkera0701_parport);
}
}