extern void vGPIOISREntry(void); // GPIO interrupt entry. see in gpio_isr.s79
extern xSemaphoreHandle xSemaphoreGPIO;
/****************************************************************************
* function name: gpio_init
*
* description : This function initializes gpio port for infra-red sensor.
*
* return : none
****************************************************************************/
void gpio_init(void);
/****************************************************************************
* function name: vuGPIO_TASK
*
* description : task responding to infra red GPIO level change interrupt.
*
* return : none
****************************************************************************/
void vuGPIO_TASK( void *pvParameters );
/****************************************************************************
* function name: gpiob_isr_handler
*
* description : This is GPIOB level-change interrupt handler.
*
* AT91SAM7X256 can not identify low level or high level trigger
* of GPIO interrupt. So every voltage process of high->low->high
* will generate two interrupts: high->low and low->high.
*
* In fact, in a process of high->low->high, usually two high->low
* interrupts and two low->high interrupts can occur. And I can not
* find a way to remove these additional interrupts, so I can only
* count the interrupt times in such a proces, and release semophore
* only in the handler of the first high->low interrupt. The glitch
* filter seems help little here.
*
* return : none
****************************************************************************/
__arm void gpiob_isr_handler(void)
{
unsigned int pio_isr;
unsigned int pio_value;
int i;
portBASE_TYPE xSwitchRequired = pdFALSE;
pio_isr = GET_REG(0xFFFFF64C);
if((pio_isr & 0x60000000) == 0)
{
interrupt_count = 0;
portEND_SWITCHING_ISR( xSwitchRequired );
SET_REG(0xFFFFF130, 0); // Write any value to AIC_EOICR to end int handling
return;
}
pio_value = GET_REG(0xFFFFF63C);
if((pio_value & 0x40000000) == 0) // if PB30 is changed
{
for(i=0; i<1024*6*300; i++); // delay 300ms
pio_value = GET_REG(0xFFFFF63C); // read again
if((pio_value & 0x40000000) == 0)
{
//printk("PB30 is changed\n");
interrupt_count ++;
}
}
else if ((pio_value & 0x20000000) == 0) // if PB29 is changed
{
for(i=0; i<1024*6*300; i++); // delay 300ms
pio_value = GET_REG(0xFFFFF63C); // read again
if((pio_value & 0x20000000) == 0)
{
//printk("PB29 is changed\n");
interrupt_count ++;
}
}
else
{
//printk("Unknown IO is changed.\n");
interrupt_count = 0;
}