[En-Nut-Discussion] Problem with GpioIrqEnable

2 views
Skip to first unread message

zonedar

unread,
Mar 1, 2012, 12:03:04 PM3/1/12
to en-nut-d...@egnite.de

Hi All,

I'm working on a project where I have to use a GPIO interrupt. I
apologize if this has been answered before, but in doing several searches
I've not found much on GPIO interrupts.

My code seems to be hanging up in GpioIrqEnable, specifically at the end
of the call to PioCtlA where it does (gpioa_at91.c):

/* Enable interrupt. */
if (enabled) {
outr(PIOA_IER, _BV(bit)); //Never returns
}

Basically it is going into outr and never leaving.

I'm sure I'm missing something but I can't figure it out for the life of me.

I am working with an AT91SAM7X256 and NUT OS 2.0.8 (according to the
configurator).

Here are code snippets:

void
InitializeDSPMonitor(void)
{
GpioPinConfigSet(NUTGPIO_PORTA, 14, GPIO_CFG_DEBOUNCE);
GpioIrqDisable(&sig_GPIO1, 14);
GpioRegisterIrqHandler(&sig_GPIO1, 14, DSP_Irq, NULL);

printf("Entering InitializeDSPMonitor\n");
NutThreadCreate("DSP_Mon", DSP_EventMonitor, 0, 2048);

GpioIrqEnable(&sig_GPIO1, 14); //Hangs up here
printf("Leaving InitializeDSPMonitor\n");
}


Thanks!

-Steve



--
View this message in context: http://old.nabble.com/Problem-with-GpioIrqEnable-tp33422809p33422809.html
Sent from the MicroControllers - Ethernut mailing list archive at Nabble.com.

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Klaus Kloos

unread,
Mar 1, 2012, 1:04:24 PM3/1/12
to Ethernut User Chat (English)

Am 01.03.2012 um 18:03 schrieb zonedar:

>
> Hi All,
>
> I'm working on a project where I have to use a GPIO interrupt. I
> apologize if this has been answered before, but in doing several searches
> I've not found much on GPIO interrupts.
>
> My code seems to be hanging up in GpioIrqEnable, specifically at the end
> of the call to PioCtlA where it does (gpioa_at91.c):
>
> /* Enable interrupt. */
> if (enabled) {
> outr(PIOA_IER, _BV(bit)); //Never returns
> }
>
> Basically it is going into outr and never leaving.
>

Hello Steve

The code of the function GpioIrqEnable is missing. So here is a short guess...
Do you have set an IRQ-Handler for the used PIO before enabling the IRQ?
something like
NutRegisterIrqHandler(&sig_PIOB, MyIrqHandler, NULL);
or (without NutOS)
outr(AIC_SVR(PIOB_ID), (unsigned int) MyIrqHandler);

Greetings Klaus

> I'm sure I'm missing something but I can't figure it out for the life of me.
>
> I am working with an AT91SAM7X256 and NUT OS 2.0.8 (according to the
> configurator).
>
> Here are code snippets:
>
> void
> InitializeDSPMonitor(void)
> {
> GpioPinConfigSet(NUTGPIO_PORTA, 14, GPIO_CFG_DEBOUNCE);
> GpioIrqDisable(&sig_GPIO1, 14);
> GpioRegisterIrqHandler(&sig_GPIO1, 14, DSP_Irq, NULL);
>
> printf("Entering InitializeDSPMonitor\n");
> NutThreadCreate("DSP_Mon", DSP_EventMonitor, 0, 2048);
>
> GpioIrqEnable(&sig_GPIO1, 14); //Hangs up here
> printf("Leaving InitializeDSPMonitor\n");
> }
>
>
> Thanks!
>
> -Steve
>
>


_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

zonedar

unread,
Mar 1, 2012, 2:30:43 PM3/1/12
to en-nut-d...@egnite.de

Hi Klaus,

Thanks for the reply. The call to NutRegisterIrqHandler is inside Nut's
GpioRegisterIrqHandler function below:

int GpioRegisterIrqHandler(GPIO_SIGNAL * sig, int bit, void (*handler) (void
*), void *arg)
{
int rc = 0;

if (sig->ios_vector == 0) {
/* This is the first call. Allocate the vector table. */
sig->ios_vector = malloc(sizeof(GPIO_VECTOR) * 32);
if (sig->ios_vector) {
memset(sig->ios_vector, 0, sizeof(GPIO_VECTOR) * 32);
/* Register our internal PIO interrupt service. */
rc = NutRegisterIrqHandler(sig->ios_sig, sig->ios_handler,
sig->ios_vector);
if (rc == 0) {
rc = NutIrqEnable(sig->ios_sig);
}
}
else {
rc = -1;
}
}
sig->ios_vector[bit].iov_handler = handler;
sig->ios_vector[bit].iov_arg = arg;

return rc;
}

I copied that function in to my source file to be sure that the registration
is being done and it is.

The code for is GpioIrqEnable as follows:

int GpioIrqEnable(GPIO_SIGNAL * sig, int bit)
{
return (sig->ios_ctl) (NUT_IRQCTL_ENABLE, NULL, bit);
}

Where sig->ios_ctl is as follows:

static int PioCtlA(int cmd, void *param, int bit)
{
int rc = 0;
unsigned int *ival = (unsigned int *) param;
uint32_t enabled = inr(PIOA_IMR) & _BV(bit);
printf("\n\n\n\nhere PioCtlA\n");

/* Disable interrupt. */
if (enabled) {
outr(PIOA_IDR, _BV(bit));
}
printf("\n\n\n\nhere2 PioCtlA\n");
switch (cmd) {
case NUT_IRQCTL_STATUS:
if (enabled) {
*ival |= 1;
} else {
*ival &= ~1;
}
printf("\n\n\n\nhere3 PioCtlA\n");
break;
case NUT_IRQCTL_ENABLE:
enabled = 1;
printf("\n\n\n\nhere 4 PioCtlA\n");
break;
case NUT_IRQCTL_DISABLE:
enabled = 0;
printf("\n\n\n\nhere5 PioCtlA\n");
break;
default:
rc = -1;
break;
}

/* Enable interrupt. */
if (enabled) {

printf("\n\n\n\nhere6 PioCtlA\n");
outr(PIOA_IER, _BV(bit)); //NOT returning from here
printf("\n\n\n\nhere7 PioCtlA\n");
}
printf("\n\n\n\nhere8 PioCtlA\n");
return rc;
}


As I mentioned it's not coming out of outr(PIOA_IER, _BV(bit)).

Thanks Again!

-Steve

Klaus Kloos wrote:
>
>
>
> Hello Steve
>
> The code of the function GpioIrqEnable is missing. So here is a short
> guess...
> Do you have set an IRQ-Handler for the used PIO before enabling the IRQ?
> something like
> NutRegisterIrqHandler(&sig_PIOB, MyIrqHandler, NULL);
> or (without NutOS)
> outr(AIC_SVR(PIOB_ID), (unsigned int) MyIrqHandler);
>
> Greetings Klaus
>
>
>


--
View this message in context: http://old.nabble.com/Problem-with-GpioIrqEnable-tp33422809p33423801.html

Klaus Kloos

unread,
Mar 1, 2012, 2:51:04 PM3/1/12
to Ethernut User Chat (English)
Hello Steve

>
>
> Thanks for the reply. The call to NutRegisterIrqHandler is inside Nut's
> GpioRegisterIrqHandler function below:
>
> int GpioRegisterIrqHandler(GPIO_SIGNAL * sig, int bit, void (*handler) (void
> *), void *arg)
> {
> int rc = 0;
>
> if (sig->ios_vector == 0) {
> /* This is the first call. Allocate the vector table. */
> sig->ios_vector = malloc(sizeof(GPIO_VECTOR) * 32);
> if (sig->ios_vector) {
> memset(sig->ios_vector, 0, sizeof(GPIO_VECTOR) * 32);
> /* Register our internal PIO interrupt service. */
> rc = NutRegisterIrqHandler(sig->ios_sig, sig->ios_handler,
> sig->ios_vector);
Where is sig->ios_handler pointing to?
Are you able to set a breakpoint in this IRQ function? Is it called where the IRQ is enabled?

Greetings Klaus

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

zonedar

unread,
Mar 1, 2012, 3:15:35 PM3/1/12
to en-nut-d...@egnite.de

Klaus,

It's pointing to PioCtlA (see my previous post).

In that function it is hanging up at:

outr(PIOA_IER, _BV(bit)); //NOT returning from here

Also in the previous post.

Thanks!


--
View this message in context: http://old.nabble.com/Problem-with-GpioIrqEnable-tp33422809p33424070.html

Klaus Kloos

unread,
Mar 1, 2012, 3:41:19 PM3/1/12
to Ethernut User Chat (English)
Hello Steve

>
>
> It's pointing to PioCtlA (see my previous post).
>
Sorry, ive missed that.
So your IRQ-Handler is PioCtlA, which is enabling the IRQ.... is that right, and is it the way you want it to be? Looks strange to me.
At the beginning of PioCtlA the IRQ is disabled. When the IRQ is enabled, the IRQ-function might be called directly (im not sure about that) leading to a new call to PioCtlA, ... and again..... until the stack is gone.
You will get more information setting a breakpoint at the start of PioCtlA.

Some weeks ago ive asked a similar questions about external IRQs. May be the answer helps you too.
http://permalink.gmane.org/gmane.comp.hardware.microcontrollers.ethernut/12534

Greetings Klaus


> In that function it is hanging up at:
>
> outr(PIOA_IER, _BV(bit)); //NOT returning from here
>
> Also in the previous post.
>
> Thanks!
>
>
>
>

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

zonedar

unread,
Mar 1, 2012, 4:46:08 PM3/1/12
to en-nut-d...@egnite.de

Klaus,

I think I fixed it. You were correct in that as soon as I enabled the
interrupt the IRQ function was being called. Turns out that the problem was
there.

I had my IRQ function set up as follows:

volatile HANDLE *DSP_Content;

static void DSP_Irq(void *arg)
{
NutEventPost(DSP_Content);
}

I changed it to:

volatile HANDLE DSP_Content;
static void DSP_Irq(void *arg)
{
NutEventPostFromIrq(&DSP_Content);
}

...And that fixed it.

Not sure if the interrupts are correct, but at least it's not hanging up.
:-D

Thanks for your help. I was very useful!

-Steve

--
View this message in context: http://old.nabble.com/Problem-with-GpioIrqEnable-tp33422809p33424609.html

Reply all
Reply to author
Forward
0 new messages