Output working now

master
Stefan Krulj 14 years ago
parent ee18e4dfa5
commit f530fb60c9
  1. 74
      char_dev.c
  2. 8
      common.h
  3. 10
      ftdi_daemon.c
  4. 1
      ftdi_daemon.h
  5. 35
      gpio_callbacks.c
  6. 29
      usb_gpio.c
  7. 4
      usb_gpio.h

@ -0,0 +1,74 @@
static char device_buffer[1];
static int major;
static uint8_t buff_empty=1;
static uint8_t buff_start;
static uint8_t buff_end;
static uint8_t buffer[BUFFER_SIZE];
static uint8_t readBuffer(void){
uint8_t ret;
if(buff_empty){
return 0;
}
ret=buffer[buff_end];
buff_end++;
if(buff_end==BUFFER_SIZE){
buff_end=0;
}
if(buff_end==buff_start){
buff_empty=1;
}
return ret;
}
static uint8_t writeToBuffer(uint8_t data){
if(buff_start==buff_end && !buff_empty){
/*overrun*/
printk("<1>%s: Buffer overrun!\n",MOD_NAME);
return 1;
}
buffer[buff_start]=data;
buff_start++;
if(buff_start==BUFFER_SIZE){
buff_start=0;
}
buff_empty=0;
return 0;
}
static ssize_t device_read(struct file *filp, char __user *buffer, size_t length, loff_t *offset){
uint8_t val;
if(!buff_empty){
val = readBuffer();
DEBUG_OUT("<1>%s: device_read invoked writing: mem[%x]=%02x\n",MOD_NAME,buffer,val);
if( copy_to_user(buffer,&val,1)<0 ){
printk("<1>%s: Device read error!\n",MOD_NAME);
return 0;
}
return 1;
}
return 0;
}
static ssize_t device_write(struct file *filp, const char __user *buff, size_t len, loff_t *off){
int ret;
DEBUG_OUT("<1>%s: device_write invoked\n",MOD_NAME);
if(len!=1){
return -EINVAL;
}
ret = copy_from_user(device_buffer, buff, len);
if( ret<0 ){
printk("<1>%s: Device write error!\n",MOD_NAME);
return 0;
}
return len;
}
struct file_operations fops = {
read: device_read,
write: device_write,
};

@ -0,0 +1,8 @@
#ifndef _COMMON_H
#define _COMMON_H
#define MOD_NAME "usb_gpio"
enum pin_commands {CMD_IN, CMD_OUTH, CMD_OUTL, CMD_H, CMD_L, CMD_READ};
#endif //_COMMON_H

@ -6,6 +6,8 @@ uint8_t USB_GPIO_DDR;
uint8_t USB_GPIO_PORT; uint8_t USB_GPIO_PORT;
uint8_t USB_GPIO_PIN; uint8_t USB_GPIO_PIN;
FILE* fd;
volatile uint8_t main_loop=1; volatile uint8_t main_loop=1;
static int vendor=0x0403, device=0x6001; static int vendor=0x0403, device=0x6001;
@ -165,7 +167,7 @@ static int cmd_fsm(char c){
case CMD_READ: case CMD_READ:
ret = get_value((unsigned)pin); ret = get_value((unsigned)pin);
DEBUG_OUT("Value of %d is %d\n", pin,ret); DEBUG_OUT("Value of %d is %d\n", pin,ret);
fputc((char)ret,stdout); fputc((char)ret,fd);
return 0; return 0;
} }
} }
@ -174,14 +176,16 @@ static int cmd_fsm(char c){
int main(void){ int main(void){
int ret=ftdi_chip_init(); int ret=ftdi_chip_init();
fd=fopen("/dev/usb_gpio","rw");
if(ret!=0){ if(ret!=0){
return ret; return ret;
} }
for(;main_loop;){ for(;main_loop;){
//kernel will write commands to the stdin //kernel will write commands to the device file
ret = fgetc(stdin); ret = fgetc(fd);
if( ret!=EOF ){ if( ret!=EOF ){
DEBUG_OUT("read %02x\n",ret);
cmd_fsm(ret); cmd_fsm(ret);
}else{ }else{
//main_loop=0; //main_loop=0;

@ -6,6 +6,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include "common.h" #include "common.h"

@ -1,20 +1,49 @@
static int get_value(struct gpio_chip *gc, unsigned offset){ static int get_value(struct gpio_chip *gc, unsigned offset){
int ret;
DEBUG_OUT("<1>%s: GET_VALUE of pin%d ",MOD_NAME,offset); DEBUG_OUT("<1>%s: GET_VALUE of pin%d ",MOD_NAME,offset);
return 0;
ret=writeToBuffer(offset);
ret|=writeToBuffer(CMD_READ);
return -ret;
} }
static void set_value(struct gpio_chip *chip, unsigned offset, int value){ static void set_value(struct gpio_chip *chip, unsigned offset, int value){
DEBUG_OUT("<1>%s: SET_VALUE of pin%d to %d",MOD_NAME,offset,value); DEBUG_OUT("<1>%s: SET_VALUE of pin%d to %d",MOD_NAME,offset,value);
writeToBuffer(offset);
if(value){
writeToBuffer(CMD_H);
}else{
writeToBuffer(CMD_L);
}
} }
static int set_in(struct gpio_chip *chip, unsigned offset){ static int set_in(struct gpio_chip *chip, unsigned offset){
int ret=0;
DEBUG_OUT("<1>%s: SET_INPUT of pin%d ",MOD_NAME,offset); DEBUG_OUT("<1>%s: SET_INPUT of pin%d ",MOD_NAME,offset);
return 0;
ret=writeToBuffer(offset);
ret|=writeToBuffer(CMD_IN);
return -ret;
} }
static int set_out(struct gpio_chip *chip, unsigned offset, int value){ static int set_out(struct gpio_chip *chip, unsigned offset, int value){
int ret;
DEBUG_OUT("<1>%s: SET_OUTPUT of pin%d to %d",MOD_NAME,offset,value); DEBUG_OUT("<1>%s: SET_OUTPUT of pin%d to %d",MOD_NAME,offset,value);
return 0;
ret=writeToBuffer(offset);
if(value){
ret|=writeToBuffer(CMD_OUTH);
}else{
ret|=writeToBuffer(CMD_OUTL);
}
return -ret;
} }

@ -3,12 +3,14 @@
static struct gpio_chip ft232_chip; static struct gpio_chip ft232_chip;
static struct subprocess_info *sub_info; static struct subprocess_info *sub_info;
#include "char_dev.c"
#include "gpio_callbacks.c" #include "gpio_callbacks.c"
static void usb_gpio_exit(void) { static void usb_gpio_exit(void) {
if( gpiochip_remove(&ft232_chip)<0 ){ if( gpiochip_remove(&ft232_chip)<0 ){
printk("<1>%s: Couldn't free GPIO-pins!\n",MOD_NAME); printk("<1>%s: Couldn't free GPIO-pins!\n",MOD_NAME);
} }
unregister_chrdev(major, MOD_NAME);
printk("<1>%s: Bye!\n",MOD_NAME); printk("<1>%s: Bye!\n",MOD_NAME);
} }
@ -23,6 +25,14 @@ static int usb_gpio_init(void) {
printk("<1>%s: Loading... \n",MOD_NAME); printk("<1>%s: Loading... \n",MOD_NAME);
major = register_chrdev(0, MOD_NAME, &fops);
if(major<0){
printk("<1>%s: Can't register character device!\n",MOD_NAME);
}
printk("<1>%s: Assigned device major #%d minor #0!\n",MOD_NAME,major);
printk("<1>%s: Create device file with: \"mknod /dev/usb_gpio c %d 0\"\n",MOD_NAME,major);
//GPIO registration
ft232_chip.label = MOD_NAME; ft232_chip.label = MOD_NAME;
//Callback functions //Callback functions
@ -44,15 +54,18 @@ static int usb_gpio_init(void) {
if (ret){ if (ret){
printk("<1>%s: Can't register chip!\n",MOD_NAME); printk("<1>%s: Can't register chip!\n",MOD_NAME);
} }
return ret;
//Call the user space handler //Call the user space handler
sub_info = call_usermodehelper_setup( argv[0], argv, envp, GFP_ATOMIC ); /*sub_info = call_usermodehelper_setup( argv[0], argv, envp, GFP_ATOMIC );
if (sub_info == NULL){ if (sub_info == NULL){
return -ENOMEM; return -ENOMEM;
} }
// the helper will run in the background until the module decides to kill it // the helper will run in the background until the module decides to kill it
return call_usermodehelper_exec( sub_info, UMH_NO_WAIT ); ret=call_usermodehelper_exec( sub_info, UMH_NO_WAIT );
if(ret<0){
printk("<1>%s: Couldn't run userspace helper process (%s)!\n",MOD_NAME,);
}*/
} }
module_init(usb_gpio_init); module_init(usb_gpio_init);

@ -11,10 +11,14 @@
#include <linux/kmod.h> #include <linux/kmod.h>
#include <linux/msg.h> #include <linux/msg.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include "usb_gpio_util.h" #include "usb_gpio_util.h"
#include "common.h" #include "common.h"
#define NUM_OF_GPIO 8 #define NUM_OF_GPIO 8
#define BUFFER_SIZE 1024
#ifndef CONFIG_GENERIC_GPIO #ifndef CONFIG_GENERIC_GPIO
#error This module needs generic gpio support (CONFIG_GENERIC_GPIO) #error This module needs generic gpio support (CONFIG_GENERIC_GPIO)

Loading…
Cancel
Save