Project Home
Project Home
Trackers
Trackers
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - GPIO interrupts on Intel Atom E3800 (Baytrail): (1 Item)
   
GPIO interrupts on Intel Atom E3800 (Baytrail)  
Hello!

I am trying to use level triggered interrupts on my Intel Atom E3800 based board. A GPIO pin, wich I want to use is 
GPIO_S5[13]. So This GPIO is located in Intel Legacy Block (iLB) and registers, wich correspond to this GPIO, are mapped
 to memory (not to legacy space). To configure this GPIO I made the follows:

...
pci_attach( 0 );
//Find the PCI/ISA bus (intel legacy block)
pci_find_class(0x060100, 0, &busnum, &devfuncnum);
//Get IOBASE register, which contains base address for memory mapped GPIOs registers (GPSSUS) accoding to datasheet
pci_read_config32(busnum, devfuncnum, 0x4C, 1, &ioBaseRegister);
uint32_t ioControllerBaseAddr = ioBaseRegister & 0xFFFFC000;
//Get pad configuration register for GPIO_S5[13]
uint64_t s5_13_pad_config =  (ioControllerBaseAddr + 0x2000 + 0x140);
uint32_t * ptr = (uint32_t*) mmap_device_memory( 0, 4, PROT_READ|PROT_WRITE|PROT_NOCACHE, 0, s5_13_pad_config );
// (1<<26) - Set  Gb Tne to 1 ( Detect falling edge. For level interrupt mode it will enable active low level irq)
// (1<<27) - Set Direct Irq En (direct_irq_en)
// (1<<24) - Set Gd Level (gd_level): When this bit is set a level irq will be choose and not edge irq
*ptr |= (1<<26)|(1<<27)|(1<<24);
//Get pad value register for GPIO_S5[13]
uint64_t s5_13_pad_val_unmaped =  (ioControllerBaseAddr + 0x2000 + 0x148);
ptr = (uint32_t*) mmap_device_memory( 0, 4, PROT_READ|PROT_WRITE|PROT_NOCACHE, 0, s5_13_pad_val_unmaped );
//Enable input, disable output
*ptr |= (1<<1);
*ptr &= ~(1<<2);
//Connect gpios5[13] to IRQ0 (APIC 67)
uint64_t direct_irq0 =  (ioControllerBaseAddr + 0x2000 + 0x980);
ptr = (uint32_t*) mmap_device_memory( 0, 4, PROT_READ|PROT_WRITE|PROT_NOCACHE, 0, direct_irq0 );
*ptr &= ~(0x7F);
*ptr |= 13;
pci_detach( phdl )
...

In my startup-apic -vv output a see:
...
[13] vec: 67,   cpumask:00000001, ID: 2, busid:0, busintr:13, dest intin:13, type:0, flags:00000005
...

So when I am waiting for interrupt I do the follows:

struct sigevent int_event;
static int int_counter;

const struct sigevent *handler (void *area, int id) {
     int_counter++;
     return (&int_event);
}


void * interruptWaitThread( void*  arg )
{
	ThreadCtl( _NTO_TCTL_IO, 0 );
	struct sigevent event;

	int_event.sigev_notify = SIGEV_INTR;

	InterruptAttach( 13, &handler, NULL, 0, _NTO_INTR_FLAGS_TRK_MSK);

	while (1)
	{

		InterruptWait (0, NULL);
		printf (" Got interrupt %lu ( 0x%lX ) #%4ld\n", 13, 13, int_counter);

	}
	return( 0 );
}

But the interruptWaitThread have never unblocked from InterruptWait(). What am doing wrong?

Regards, 
Vasily.