Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.

Bobi

Member Since 19 Sep 2011
Offline Last Active Nov 14 2011 09:21 PM
-----

Posts I've Made

In Topic: FreeRTOS handling hardware interrupts

14 November 2011 - 10:16 AM

Hi, I found the problem!!! It works great now.
There are a few things which need to be done:
  • In the documentation of the AT91F_AIC_ConfigureIt function the first parameter is described as "pointer to the AIC registers" and therefore when you configure your interrupt you should pass AT91C_BASE_AIC but not AT91C_BASE_PIOA. I'm not absolutely sure why is that but it just works only if I pass the AT91C_BASE_AIC register. You do the same for the AT91F_AIC_EnableIt call. The activation level that works for me is AT91C_AIC_SRCTYPE_EXT_LOW_LEVEL - (AIC) External Sources Code Label Low-level Sensitive.
  • If you are using IAR you have to do a few more steps. You need to decide whether your interrupt service routine should cause a context switch. Look here for an example.

In my case - I needed a context switch, so I had to create a DriverISR.s79 assembler file where I execute
portSAVE_CONTEXT
call the ISR routine
portRESTORE_CONTEXT

And this is all FreeRTOS specific (this is also described in the demo from the link above).

Best Regards,
Bobi

In Topic: FreeRTOS handling hardware interrupts

10 November 2011 - 02:27 PM

Well, it's kind of impossible to troubleshoot interrupt issues remotely ;-) I am not very familiar with FreeRTOS itself, but according to the information I've found on the Internet, it requires some special coding for ISR routines, like declaring __attribute__((interrupt("IRQ"))) (?) and portENTER_CRITICAL()/portEXIT_CRITICAL() macros (?) - so I would suggest you looking at the FreeRTOS documentation and samples.


No, the register contains bit mask, so you'd need to use 1 << 29; usually the code looks like

...
isr = AT91C_BASE_PIOA->PIO_ISR;
if(isr & SW1)
{
  // Button
}
...
AT91C_BASE_AIC->AIC_EOICR = 0; // Clear AIC to complete ISR processing


Hi, thanks for your replies!
I already have a working demo of the same functionality which was included in the Getting Started Tutorial I got from Atmel. It works perfectly fine and the code looks like executing exactly the same steps except that they are using a different port. FreeRTOS have implemented their own port and one solution I can think of is to get FreeRTOS running with the Atmel port for sam7x512.

In Topic: FreeRTOS handling hardware interrupts

09 November 2011 - 06:54 PM

static void prvSetupHardware( void )
{
  ...
  // The second parameter should be button pin               		
  AT91F_PIO_InterruptEnable(AT91C_BASE_PIOA, SW1);
  ...        
}
Also, don't forget to read PIO_ISR in Handler().


OK, I did this and now when I deploy the bin file on the Netduino and connect it in my Computer I see an instant flash and the LED stays ON and when you press the button nothing happens. There must be something else... ?

How is the right way to read the PIO_ISR register? Should I simply say:
   if(PIO_ISR  == 29){
      // ...
   }

In Topic: FreeRTOS handling hardware interrupts

09 November 2011 - 04:59 PM

In the above code, there is missing call to enable clock on PIOA (i.e. AT91F_PMC_EnablePeriphClock) and AT91F_PIO_InterruptEnable() for the button. Also, you should use constants instead of hardcoded values in AT91F_AIC_ConfigureIt(), like PIO_INTERRUPT_LEVEL, AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE.

Hi,

Thanks for the fast reply! It looks perfectly fine to me now but it still doesn't work. What am I misssing?

#define PIO_INTERRUPT_LEVEL 0x7
#define AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE ((unsigned int) 0x1 <<  5)

void Handler(void)
{
        AT91F_PIO_ClearOutput( AT91C_BASE_PIOB, LED1 ); // turn LED OFF				
}

static void prvSetupHardware( void )
{
	AT91F_PIO_CfgOutput( AT91C_BASE_PIOB, LED1 );        
        AT91F_PIO_SetOutput( AT91C_BASE_PIOB, LED1 );	// turn LED ON              
	
	AT91F_PMC_EnablePeriphClock( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA );
	AT91F_PMC_EnablePeriphClock( AT91C_BASE_PMC, 1 << AT91C_ID_PIOB ) ;
	                        
        AT91F_PIO_InterruptEnable(AT91C_BASE_PIOA, 1 << AT91C_ID_PIOA);
        
        AT91F_PIO_CfgInput( AT91C_BASE_PIOA, SW1 );
        AT91F_PIO_CfgPullup( AT91C_BASE_PIOA, SW1 );
        AT91F_PIO_CfgInputFilter( AT91C_BASE_PIOA, SW1 );
        
        AT91F_AIC_ConfigureIt(AT91C_BASE_PIOA, 
                              AT91C_ID_PIOA, 
                              PIO_INTERRUPT_LEVEL, 
                              AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE, 
                              Handler);
        AT91F_AIC_EnableIt(AT91C_BASE_PIOA, AT91C_ID_PIOA);        
}

I'm not aboslutely sure about the PIO_INTERRUPT_LEVEL value. In the documentation they say that its between 0(lowest) and 7(highest). Otherwise this is what you mean, right?

In Topic: FreeRTOS handling hardware interrupts

09 November 2011 - 03:33 PM

All I/O lines of the same port share one interrupt. In your trivial case, you could just simply check the appropriate bit of PIO_ISR register in the interrupt handler.


Hi,

Ok great and do you think that the interrupt initialization is OK then, because when I press the button nothing happens?
Is there any way to debug your code when it's running on the netduino if you don't have a jtag?

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.