ARM with edge triggered vPreemptiveTick ISR

I have found that edge trigger interrupts work better (at least with my rev of a AT91SAM7X256).  One caveat, the SAM7 AIX is supposed to clear ICCR automatically (which is why I switched to edge in the first place) but I seem to need to add: "AT91C_BASE_AIC->AIC_ICCR = (0x1 << AT91C_ID_SYS);" to get it to work, maybe I’m doing something else wrong? By adding the above I was able to xTaskCreate( vQEITask,…) the same vQEITask twice.  This task toggles a pin every 10ms. I can see on a scope the second instance toggles about 35us after the first, works great, every 10ms two pulses.  If I use level interrupts the second instance of the task does not seem to run.  My guess is that one of the interrupts is being missed… Anyone else have similar experiences? David.

ARM with edge triggered vPreemptiveTick ISR

Thanks for the info. To be honest I cannot remember why I went for level rather than edge, maybe I copied the code from somewhere.  I know that my SAM7X devices were pre-production (seemed I got them months before they were publicly available) and had various errata – maybe that is it.  Can you post your changes here? Regards.

ARM with edge triggered vPreemptiveTick ISR

Sorry about the pieces.  Since I’m trying to match Atmel lib boards/components etc layout and I’m using CodeSourcery G++ personal edition there are many changes for layout alone diff’s are not too useful.  Ultimately I plan on using the AT91SAM9XE256 in my design. I plan on contributing both ports when done. You should know, I have not tested vNonPreemptiveTick with this! Also as shown with ulFractional below I am looking to use the AT91C_BASE_PITC->PITC_PIVR register as a fractional tick counter. This in combination with your xTickCount gives a precise time stamp.  I want to sync multiple board ticks via gps 1pps and/or IEEE-1588. Most other chips support similar reads of the counter although many down-count. In port.c: #define portINT_EDGE_SENSITIVE  AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE #define portINT_PRIORITY 6 static void prvSetupTimerInterrupt( void ) { #if configUSE_PREEMPTION == 0 … #else AIC_ConfigureIT( AT91C_ID_SYS, (portINT_PRIORITY | portINT_EDGE_SENSITIVE),   ( void (*)(void) ) vPreemptiveTick ); #endif … } In portISR.c void vPreemptiveTick( void ) __attribute__((naked)); void vPreemptiveTick( void ) {   /* Save the context of the current task. */   portSAVE_CONTEXT();   ulFractionalClock = AT91C_BASE_PITC->PITC_PIVR; /* clear PITS bit in PIT_SR */   /* The following should be automatic with edge, but nogo ARGH! */   AT91C_BASE_AIC->AIC_ICCR = (0x1 << AT91C_ID_SYS);           /* Increment the tick count – this may wake a task. */   vTaskIncrementTick();   /* Find the highest priority task that is ready to run. */   vTaskSwitchContext();       /* End the interrupt in the AIC. In board_cstartup handler. */          AT91C_BASE_AIC->AIC_EOICR = 0;           portRESTORE_CONTEXT(); } Regards, David.

ARM with edge triggered vPreemptiveTick ISR

After reviewing my code I have one more thought to add. One possible reason to use level vs edge is that more than one source may cause the interrupt. The level is cleared when you clear all possible sources. Edge does not have this option. I only use the PIT interrupt with AT91C_ID_SYS.