My setup is as follows:
1. We tested using two configurations:
a. Using PIO Port-A pin as Interrupt and,
b. Using PIO Port-A pin as a input to Atmel AT91SAM7x256 development kit.
2. We take falling edge of joystick input and use it to turn on LED for 20ms.
3. We used AT91LIB files for configuration.
4. I have tried AT91SAM7x256-ek as well my customize hardware also.
The problems we encountered using above setup are as follows:
1. Please refer the attached timing diagrams drawn based on observations on digital storage oscilloscope. Graph-A shows example input pulse generated from the joystick. Note Graph-B, this shows the trigger pulse generated by ISR, we get trigger pulses at both rising and falling edge of input pulses. This behavior is observed to occur at random intervals.
2. Our program (attached below) expects behavior as shown in Graph-C, i.e. the trigger pulse must be generated only at the falling edges of the input pulses.
Code:
//-----------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------
#include <board.h>
#include <pio/pio.h>
#include <pio/pio_it.h>
#include <pit/pit.h>
#include <tc/tc.h>
#include <aic/aic.h>
#include <utility/trace.h>
#include <pmc/pmc.h>
#include <TWI/TWI.h>
#include <SPI/SPI.h>
#include <USART0/USART0.h>
#include <TIMERS/TIMERS.h>
#include <AT45DB642D/AT45DB642D.h>
#include <stdio.h>
#include <string.h>
//------------------------------------------------------------------------------
// Definitions+
//------------------------------------------------------------------------------
#define RFIND 4
#define MAX_COUNTERS 10
#define MAX_TIMERS 10
#define OFF 0
#define ON 1
//-----------------------------------------------------------------------
#define irq0INTERRUPT_PRIORITY AT91C_AIC_PRIOR_HIGHEST
#define irq1INTERRUPT_PRIORITY AT91C_AIC_PRIOR_HIGHEST
#define cnINTERRUPT_PRIORITY 6
#define tc0INTERRUPT_PRIORITY 5
#define tc1INTERRUPT_PRIORITY 5//AT91C_AIC_PRIOR_HIGHEST
#define tc2INTERRUPT_PRIORITY 5
#define uart0INTERRUPT_PRIORITY 5
#define pitINTERRUPT_PRIORITY 5
//========================================================================================
#define PIN_INPUT_7 {AT91C_PIO_PA21, AT91C_BASE_PIOA, AT91C_ID_PIOA, PIO_INPUT, PIO_DEGLITCH | PIO_PULLUP}
//----------------------------------------------------------------------------------------------------------------
#define PIN_OUTPUT_20 {AT91C_PIO_PB19, AT91C_BASE_PIOB, AT91C_ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT}
//-----------------------------------------------------------------------
typedef void (*TIMER_ROUTINE) (void);
struct
{
unsigned int Tticks_;
TIMER_ROUTINE Troutine_;
unsigned char Tenabled_;
}Timers[MAX_TIMERS];
static void SetupHardware(void);
void PIO_Set_CP1(void);
void PIO_Clear_CP1(void);
void InitTimers(void);
char startTimer(unsigned short ticks, TIMER_ROUTINE routine);
void delay(unsigned long dly);
void restoreParameters(void);
//========================================================================================
const Pin CAMERA1_SENSOR_IP = PIN_INPUT_7;
//EIPULSE1
//========================================================================================
const Pin CAMERA_PULSE = PIN_OUTPUT_20;
//========================================================================================
#define CAMERA_PULSE_HIGH PIO_Clear(&CAMERA_PULSE)
#define CAMERA_PULSE_LOW PIO_Set(&CAMERA_PULSE)
//========================================================================================
volatile unsigned int porta=0;
unsigned char j=0;
volatile unsigned char timerTicked = 0x00;
volatile unsigned char var1=0;
//=====================================================================================
// ALL INTERRUPT ROUTINS
//=====================================================================================
//----------------------------------------------------------------------------------
void vPITISR(void)
{
// Clear status register
PIT_GetPIVR();
timerTicked = 1;
}
//----------------------------------------------------------------------------------
void ISR_IP1(void)
{
if(!PIO_Get(&CAMERA1_SENSOR_IP) && !var1)
{
var1=1;
PIO_Set_CP1();
}
else
{
var1=0;
}
}
//=====================================================================================
// INITIALIZE ROUTINS
//=====================================================================================
void InitTimers(void)
{
unsigned char i = 0x00;
for(i=0; i<MAX_TIMERS; i++)
{
Timers[i].Tenabled_ = 0x00;
Timers[i].Tticks_ = 0x00;
Timers[i].Troutine_ = 0x00;
}
}
//----------------------------------------------------------------------------------
char startTimer(unsigned short ticks, TIMER_ROUTINE routine)
{
unsigned char i = 0x00;
for(i=0; i<MAX_TIMERS; i++)
{
if(0x00 == Timers[i].Tenabled_)
{
Timers[i].Tenabled_ = 0x01;
Timers[i].Tticks_ = ticks;
Timers[i].Troutine_ = routine;
return 1;
}
}
return(0);
}
//----------------------------------------------------------------------------------
static void SetupHardware(void)
{
AT91C_BASE_AIC->AIC_EOICR = 0;
//----------------- Configure PIO B Registers --------------------------
PIO_Configure(&CAMERA_PULSE,1);
//----------------- Configure PIO A Registers --------------------------
PIO_Configure(&CAMERA1_SENSOR_IP, 1);
// Initialize interrupts
PIO_InitializeInterrupts(cnINTERRUPT_PRIORITY);
PIO_ConfigureIt(&CAMERA1_SENSOR_IP, (void (*)(const Pin *)) ISR_IP1);
PIO_EnableIt(&CAMERA1_SENSOR_IP);
//------------------ Configure PIT -------------------------------------
AIC_ConfigureIT(AT91C_ID_SYS,pitINTERRUPT_PRIORITY, (void(*)(void))vPITISR);
AIC_EnableIT(AT91C_ID_SYS);
PIT_Init(1000,48);
PIT_EnableIT();
}
//----------------------------------------------------------------------------------
void PIO_Set_CP1(void)
{
CAMERA_PULSE_HIGH;
startTimer(20,(TIMER_ROUTINE)PIO_Clear_CP1);
}
//----------------------------------------------------------------------------------
void PIO_Clear_CP1(void)
{
CAMERA_PULSE_LOW;
}
void delay(unsigned long dly)
{
while(dly--);
}
/*-----------------------------------------------------------------------------
* Function Name : int main(void)
* Object : Main Entry Point
*-----------------------------------------------------------------------------*/
int main(void)
{
/* Setup any hardware that has not already been configured by the low
level init routines. */
AT91C_BASE_AIC->AIC_EOICR = 0;
SetupHardware();
InitTimers();
CAMERA_PULSE_LOW;
while(1)
{
//-------------------------------------------
if(timerTicked)
{
timerTicked = 0x00;
unsigned char i = 0x00;
for(i = 0x00; i < MAX_TIMERS; i++)
{
if(Timers[i].Tenabled_ == 1)
{
Timers[i].Tticks_--;
if(Timers[i].Tticks_ == 0)
{
Timers[i].Troutine_();
Timers[i].Tenabled_ = 0;
}
}
}
}//END TIMER
//-------------------------------------------
}
}