hi folks,
I want to use the GPIO from the soekris 4801 board. what I actually
want to do is, i will sent an signal to one of the 20 pin headers pin,
which should create an interrupt on the GPIO. I know that I have to
use the GPIO 0 to 7 for interrupt handling.
but now i have a problem. I don't know if my order of the code is
correct or if I forgot something. I use a voyage linux with kernel
2.6.25.
thank you for your help.
I try to realize it in a RTAI module. here is my code:
#include linux/kernel.h
#include linux/module.h
#include linux/version.h
#include linux/sched.h
#include asm/io.h
#include rtai.h
#include rtai_sched.h
#include rtai_fifos.h
#define INDEX_REG 0x2E
#define DATA_REG0x2F
#define LDR_INDEX 0x07
#define SIO_ID_INDEX0x20
#define BASE_ADDR_MSB_INDEX 0x60
#define BASE_ADDR_LSB_INDEX 0x61
#define INT_NUM_INDEX 0x70
#define INT_TYPE_INDEX 0x71
#define LDC_INDEX 0x30
#define GPIO_PSR_INDEX 0xF0
#define GPIO_PCR_INDEX 0xF1
#define GPIO_PERR_INDEX 0xF2
#define GPIO_LDR_VALUE 0x07
#define PC87366_ID 0xE9
#define OFFSET_GPDO00x00
#define OFFSET_GPDI00x01
#define OFFSET_GPEVEN0 0x02
#define OFFSET_GPEVST0 0x03
#define OFFSET_GPDO10x04
#define OFFSET_GPDI10x05
#define OFFSET_GPEVEN1 0x06
#define OFFSET_GPEVST1 0x07
#define OFFSET_GPDO20x08
#define OFFSET_GPDI20x09
#define OFFSET_GPDO30x0A
#define OFFSET_GPDI30x0B
#if LINUX_VERSION_CODE KERNEL_VERSION(2,4,0)
MODULE_LICENSE(GPL);
#endif
static int interrupts = 0; /* how many interrupts we've serviced */
int gpioBaseAddr = 0;
static void disable_parport_int(void)
{
outb(GPIO_PERR_INDEX,INDEX_REG);
outb(0x01,DATA_REG );
outb(0x00, (gpioBaseAddr + OFFSET_GPEVEN0));
}
static void enable_parport_int(void)
{
outb(GPIO_PERR_INDEX,INDEX_REG);
outb(0x01,DATA_REG );
outb(0x10, (gpioBaseAddr + OFFSET_GPEVEN0));
}
static void isr_code(void)
{
disable_parport_int();
outb(0x10,(gpioBaseAddr +OFFSET_GPEVST0));
interrupts++;
printk(int number: %d\n,interrupts );
enable_parport_int();
return;
}
void initGPIO(int irq)
{
unsigned char sioId;
int temp = 0;
//Read SIO ID
outb(SIO_ID_INDEX,INDEX_REG);//Set index for SIO ID
sioId = inb(DATA_REG);
printk(Super IO id is %d\n, sioId);
//switch to GPIO function bloc LDN
outb(LDR_INDEX,INDEX_REG);
outb(GPIO_LDR_VALUE,DATA_REG);
//Write Interrupt number
if(irq 0 irq = 15) {
outb(INT_NUM_INDEX,INDEX_REG);
outb(0x10 | irq,DATA_REG);
printk(GPIO is interrupt %d.\n, irq);
outb(INT_TYPE_INDEX,INDEX_REG);
outb(0x00,DATA_REG);
}
//Read GPIO port base address
outb(BASE_ADDR_MSB_INDEX,INDEX_REG);
temp = inb(DATA_REG);
gpioBaseAddr = temp 8;
outb(BASE_ADDR_LSB_INDEX,INDEX_REG);
temp = inb(DATA_REG);
gpioBaseAddr |= temp;
printk(GPIO ports base adress is 0x%04X\n, gpioBaseAddr);
}
int init_module(void)
{
int retval;
retval = rt_request_global_irq(12, isr_code);
if (retval) {
if (retval == -EINVAL) {
printk(invalid IRQ\n);
} else if (retval == -EBUSY) {
/* already a handler */
printk(IRQ already assigned by RTAI\n);
}
return retval;
}
initGPIO(12);
// Set GPIO27 as an ouput (push-pull)
//Select pin 27
outb(GPIO_PSR_INDEX,INDEX_REG);
outb(0x27, DATA_REG );
//Set as a push-pull
outb(GPIO_PCR_INDEX,INDEX_REG);
outb(0x03,DATA_REG );
// Set GPIO13 as an ouput (push-pull)
//Select pin 13
outb(GPIO_PSR_INDEX, INDEX_REG);
outb(0x13 ,DATA_REG);
//Set as a push-pull
outb(GPIO_PCR_INDEX,INDEX_REG);
outb( 0x03 ,DATA_REG);
// Set GPIO04 as an input (without pull-up)
//Select pin 04
outb(GPIO_PSR_INDEX,INDEX_REG);
outb(0x04,DATA_REG );
//Set as a input with no pull-up, rising edge event, no debounce
outb(GPIO_PCR_INDEX,INDEX_REG);
outb(0x20,DATA_REG );
//Enalbe interrupt on GPIO04
outb(GPIO_PERR_INDEX,INDEX_REG);
outb(0x01,DATA_REG );
outb(0x10, (gpioBaseAddr + OFFSET_GPEVEN0));
rt_free_global_irq(12);
rt_startup_irq(12);
rt_enable_irq(12);