#!/bin/bash
CTLOUT="0"
+DATAOUT="0"
CTLIN="0"
+DATAIN="0"
DEV="n"
CTLOUT_LINE=""
+DATAOUT_LINE=""
CTLIN_LINE=""
+DATAIN_LINE=""
if [ ! -f ./ins.conf ]
then
if [[ "$DEV" == "n" ]]
then
CTLOUT_LINE=$(cat /sys/kernel/debug/gpio | grep $CTLOUT)
+ DATAOUT_LINE=$(cat /sys/kernel/debug/gpio | grep $DATAOUT)
CTLIN_LINE=$(cat /sys/kernel/debug/gpio | grep $CTLIN)
-
+ DATAIN_LINE=$(cat /sys/kernel/debug/gpio | grep $DATAIN)
if [[ "$CTLOUT_LINE" == "" ]]
then
exit 1
fi
+
+ if [[ "$DATAOUT_LINE" == "" ]]
+ then
+ echo "couldn't find $DATAOUT"
+ exit 1
+ fi
+
if [[ "$CTLIN_LINE" == "" ]]
then
echo "couldn't find $CTLIN"
exit 1
fi
+
+ if [[ "$DATAIN_LINE" == "" ]]
+ then
+ echo "couldn't find $DATAIN"
+ exit 1
+ fi
+
CTLOUT_LINE=$(echo $CTLOUT_LINE | cut -d "-" -f 2)
CTLOUT_LINE=$(echo $CTLOUT_LINE | cut -d " " -f 1)
+ DATAOUT_LINE=$(echo $DATAOUT_LINE | cut -d "-" -f 2)
+ DATAOUT_LINE=$(echo $DATAOUT_LINE | cut -d " " -f 1)
CTLIN_LINE=$(echo $CTLIN_LINE | cut -d "-" -f 2)
CTLIN_LINE=$(echo $CTLIN_LINE | cut -d " " -f 1)
+ DATAIN_LINE=$(echo $DATAIN_LINE | cut -d "-" -f 2)
+ DATAIN_LINE=$(echo $DATAIN_LINE | cut -d " " -f 1)
else
if [[ "$CTLOUT" == "0" ]]
then
CTLIN_LINE=$(cat /sys/kernel/debug/gpio | grep $CTLIN)
+ DATAIN_LINE=$(cat /sys/kernel/debug/gpio | grep $DATAIN)
if [[ "$CTLIN_LINE" == "" ]]
then
echo "couldn't find $CTLIN in devmode"
exit 1
fi
+ if [[ "$DATAIN_LINE" == "" ]]
+ then
+ echo "couldn't find $DATAIN"
+ exit 1
+ fi
CTLIN_LINE=$(echo $CTLIN_LINE | cut -d "-" -f 2)
CTLIN_LINE=$(echo $CTLIN_LINE | cut -d " " -f 1)
+ DATAIN_LINE=$(echo $DATAIN_LINE | cut -d "-" -f 2)
+ DATAIN_LINE=$(echo $DATAIN_LINE | cut -d " " -f 1)
CTLOUT_LINE="$CTLOUT"
+ DATAOUT_LINE="$DATAOUT"
fi
if [[ "$CTLIN" == "0" ]]
then
CTLOUT_LINE=$(cat /sys/kernel/debug/gpio | grep $CTLOUT)
+ DATAOUT_LINE=$(cat /sys/kernel/debug/gpio | grep $DATAOUT)
if [[ "$CTLOUT_LINE" == "" ]]
then
echo "couldn't find $CTLOUT"
exit 1
fi
+ if [[ "$DATAOUT_LINE" == "" ]]
+ then
+ echo "couldn't find $DATAOUT"
+ exit 1
+ fi
CTLOUT_LINE=$(echo $CTLOUT_LINE | cut -d "-" -f 2)
CTLOUT_LINE=$(echo $CTLOUT_LINE | cut -d " " -f 1)
+ DATAOUT_LINE=$(echo $DATAOUT_LINE | cut -d "-" -f 2)
+ DATAOUT_LINE=$(echo $DATAOUT_LINE | cut -d " " -f 1)
CTLIN_LINE="$CTLIN"
+ DATAIN_LINE="$DATAIN"
fi
fi
echo "CTL OUT: $CTLOUT = $CTLOUT_LINE"
+echo "DATA OUT: $DATAOUT = $DATAOUT_LINE"
echo "CTL IN : $CTLIN = $CTLIN_LINE"
+echo "DATA IN : $DATAIN = $DATAIN_LINE"
-insmod kgpio_irqsk.ko gpio_ctl_o=$CTLOUT_LINE gpio_ctl_i=$CTLIN_LINE
+insmod kgpio_irqsk.ko gpio_ctl_o=$CTLOUT_LINE gpio_data_o=$DATAOUT_LINE gpio_ctl_i=$CTLIN_LINE gpio_data_i=$DATAIN_LINE
#include <linux/time.h>
#include <linux/delay.h>
#include <asm/atomic.h>
+#include <linux/types.h>
+
+#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))
static DECLARE_WAIT_QUEUE_HEAD(this_wq);
static int gpio_ctl_o;
static int gpio_ctl_i;
+static int gpio_data_o;
+static int gpio_data_i;
module_param(gpio_ctl_o, int, 0664);
module_param(gpio_ctl_i, int, 0664);
+module_param(gpio_data_o, int, 0664);
+module_param(gpio_data_i, int, 0664);
static unsigned int gpio_ctl_i_irq;
+static unsigned int gpio_data_i_irq;
+
+static int comms_mode_o = 0;
-static int comms_mode = 0;
+static int comms_mode_i = 0;
static int ctl_bits_count = 0;
static int data_bits_count = 0;
-static void job_handler(struct work_struct* work){
+static u8 o_value = 127;
+static u8 i_value = 0;
+static void job_handler(struct work_struct* work){
printk(KERN_INFO "waitqueue handler: %s\n", __FUNCTION__);
- for(int i = 0; i < 10; i++){
+ for (int i = 0 ; i < 15; i++){
+
+ printk(KERN_INFO "waitqueue handler waiting for: %d...\n", i);
+
+ msleep(100);
+ }
+
+ printk(KERN_INFO "sending ctl start preamble\n");
+
+ for(int i = 0; i < 3; i++){
gpio_set_value(gpio_ctl_o, IRQF_TRIGGER_RISING);
gpio_set_value(gpio_ctl_o, IRQF_TRIGGER_NONE);
+ }
+
+ gpio_set_value(gpio_data_o, IRQF_TRIGGER_RISING);
+
+ gpio_set_value(gpio_data_o, IRQF_TRIGGER_NONE);
+
+ for(int i = 0; i < 8; i++){
+
+ if(CHECK_BIT(o_value, i)){
+
+ if(!comms_mode_o){
+
+ gpio_set_value(gpio_ctl_o, IRQF_TRIGGER_RISING);
+
+ gpio_set_value(gpio_ctl_o, IRQF_TRIGGER_NONE);
+
+ comms_mode_o = 1;
+ }
+
+ gpio_set_value(gpio_data_o, IRQF_TRIGGER_RISING);
+
+ gpio_set_value(gpio_data_o, IRQF_TRIGGER_NONE);
+
+
+ } else {
+
+ if(comms_mode_o){
+
+ gpio_set_value(gpio_ctl_o, IRQF_TRIGGER_RISING);
+
+ gpio_set_value(gpio_ctl_o, IRQF_TRIGGER_NONE);
+ comms_mode_o = 0;
+ }
+
+ gpio_set_value(gpio_data_o, IRQF_TRIGGER_RISING);
+
+ gpio_set_value(gpio_data_o, IRQF_TRIGGER_NONE);
+
+ }
- msleep(1000);
}
+ printk(KERN_INFO "sending ctl trailer\n");
+
+ for(int i = 0; i < 3; i++){
+
+ gpio_set_value(gpio_ctl_o, IRQF_TRIGGER_RISING);
+
+ gpio_set_value(gpio_ctl_o, IRQF_TRIGGER_NONE);
+ }
+
+ gpio_set_value(gpio_data_o, IRQF_TRIGGER_RISING);
+
+ gpio_set_value(gpio_data_o, IRQF_TRIGGER_NONE);
+
+
printk(KERN_INFO "up\n");
condition = 1;
}
-static irqreturn_t gpio_irq_handler(int irq, void *dev_id) {
- printk("gpio irqsk: interrupt\n");
+static irqreturn_t gpio_ctl_irq_handler(int irq, void *dev_id) {
+ printk("gpio irqsk: ctl interrupt\n");
ctl_bits_count += 1;
printk("gpio irqsk: ctl bits count: %d\n", ctl_bits_count);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t gpio_data_irq_handler(int irq, void *dev_id) {
+ printk("gpio irqsk: data interrupt\n");
+
+ if(ctl_bits_count == 3){
+ ctl_bits_count = 0;
+ if(data_bits_count == 0){
+ printk("gpio irqsk: data preamble\n");
+ return IRQ_HANDLED;
+ } else {
+ printk("gpio irqsk: data trailer\n");
+ // skb
+ printk("gpio irqsk: read result: %u\n", i_value);
+ data_bits_count = 0;
+ return IRQ_HANDLED;
+ }
+ }
+
+ if(ctl_bits_count == 1){
+ ctl_bits_count = 0;
+ if(comms_mode_i){
+ comms_mode_i = 0;
+ } else {
+ comms_mode_i = 1;
+ }
+ }
+
+ if(comms_mode_i){
+
+ i_value = i_value | (1 << data_bits_count);
+
+ } else {
+
+ i_value = i_value | (0 << data_bits_count);
+
+ }
+
+ printk("gpio irqsk: data bits count: %d\n", data_bits_count);
return IRQ_HANDLED;
}
if(gpio_ctl_o != 0){
+ if(gpio_data_o == 0){
+ printk("gpio irqsk: gpio_ctl_o should also set gpio_data_o\n");
+ return -1;
+ }
+
if(gpio_request(gpio_ctl_o, "gpio-ctl-o")) {
printk("gpio irqsk: can't allocate gpio_ctl_o: %d\n", gpio_ctl_o);
return -1;
gpio_free(gpio_ctl_o);
return -1;
}
+
+ if(gpio_request(gpio_data_o, "gpio-data-o")) {
+ printk("gpio irqsk: can't allocate gpio_data_o: %d\n", gpio_data_o);
+ gpio_free(gpio_ctl_o);
+ return -1;
+ }
+
+ if(gpio_direction_output(gpio_data_o, IRQF_TRIGGER_NONE)) {
+ printk("gpio irqsk: can't set gpio_data_o to output\n");
+ gpio_free(gpio_ctl_o);
+ gpio_free(gpio_data_o);
+ return -1;
+ }
}
if(gpio_ctl_i != 0){
+ if(gpio_data_i == 0){
+ printk("gpio irqsk: gpio_ctl_i should also set gpio_data_i\n");
+ if(gpio_ctl_o != 0){
+ gpio_free(gpio_ctl_o);
+ gpio_free(gpio_data_o);
+ }
+ return -1;
+ }
+
if(gpio_request(gpio_ctl_i, "gpio-ctl-i")) {
printk("gpio irqsk: can't allocate gpio_ctl_i: %d\n", gpio_ctl_i);
if(gpio_ctl_o != 0){
gpio_free(gpio_ctl_o);
+ gpio_free(gpio_data_o);
}
return -1;
}
printk("gpio irqsk: can't set gpio_ctl_i to input\n");
if(gpio_ctl_o != 0){
gpio_free(gpio_ctl_o);
+ gpio_free(gpio_data_o);
}
gpio_free(gpio_ctl_i);
return -1;
}
+ if(gpio_request(gpio_data_i, "gpio-data-i")) {
+ printk("gpio irqsk: can't allocate gpio_data_i: %d\n", gpio_data_i);
+ if(gpio_ctl_o != 0){
+ gpio_free(gpio_ctl_o);
+ gpio_free(gpio_data_o);
+ }
+ gpio_free(gpio_ctl_i);
+ return -1;
+ }
+
+
+ if(gpio_direction_input(gpio_data_i)) {
+ printk("gpio irqsk: can't set gpio_data_i to input\n");
+ if(gpio_ctl_o != 0){
+ gpio_free(gpio_ctl_o);
+ gpio_free(gpio_data_o);
+ }
+ gpio_free(gpio_ctl_i);
+ gpio_free(gpio_data_i);
+ return -1;
+ }
+
+
gpio_ctl_i_irq = gpio_to_irq(gpio_ctl_i);
- if(request_irq(gpio_ctl_i_irq, gpio_irq_handler, IRQF_TRIGGER_RISING, "gpio_ctl_i_irq", NULL) != 0) {
+ if(request_irq(gpio_ctl_i_irq, gpio_ctl_irq_handler, IRQF_TRIGGER_RISING, "gpio_ctl_i_irq", NULL) != 0) {
+ printk("gpio irqsk: can't request interrupt\n");
+ if(gpio_ctl_o != 0){
+ gpio_free(gpio_ctl_o);
+ gpio_free(gpio_data_o);
+ }
+ gpio_free(gpio_ctl_i);
+ gpio_free(gpio_data_i);
+ return -1;
+ }
+
+ gpio_data_i_irq = gpio_to_irq(gpio_data_i);
+
+ if(request_irq(gpio_data_i_irq, gpio_data_irq_handler, IRQF_TRIGGER_RISING, "gpio_data_i_irq", NULL) != 0) {
printk("gpio irqsk: can't request interrupt\n");
if(gpio_ctl_o != 0){
gpio_free(gpio_ctl_o);
+ gpio_free(gpio_data_o);
}
gpio_free(gpio_ctl_i);
+ gpio_free(gpio_data_i);
+ free_irq(gpio_ctl_i_irq, NULL);
return -1;
}
printk("gpio irqsk: gpio_ctl_i to IRQ %d\n", gpio_ctl_i_irq);
+ printk("gpio irqsk: gpio_data_i to IRQ %d\n", gpio_data_i_irq);
}
printk("gpio irqsk: module is initialized into the kernel\n");
printk("gpio irqsk: ctl_o: %d ctl_i: %d\n", gpio_ctl_o, gpio_ctl_i);
+ printk("gpio irqsk: data_o: %d data_i: %d\n", gpio_data_o, gpio_data_i);
+
if(gpio_ctl_o != 0 && gpio_ctl_i == 0){
+ printk("gpio irqsk: test mode\n");
+
INIT_WORK(&job, job_handler);
schedule_work(&job);
if(gpio_ctl_o != 0){
gpio_free(gpio_ctl_o);
+ gpio_free(gpio_data_o);
}
if(gpio_ctl_i != 0){
gpio_free(gpio_ctl_i);
+ gpio_free(gpio_data_i);
free_irq(gpio_ctl_i_irq, NULL);
+ free_irq(gpio_data_i_irq, NULL);
}
printk("gpio irqsk: module is removed from the kernel\n");