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
>
> 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
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
Greetings Klaus
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion
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
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
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