Read PIO input value

Discussion around product based on ARM Cortex M3 core.

Moderators: nferre, ncollot

Freya
Posts: 58
Joined: Mon Jun 11, 2012 11:57 am

Read PIO input value

Sun Jan 11, 2015 3:48 pm

Hi to all,
I realized a my own borad using a SAAM3S4B MCU.
I need to read some I/O pins in input but I read only 0 regardless pin status.

I define:

Code: Select all

#define JCENTER	0x01<<21	//PIO_PA21_IDX
#define JA		0x01<<20	//PIO_PA20_IDX
#define JB		0x01<<23	//PIO_PA23_IDX
#define JC		0x01<<22	//PIO_PA22_IDX
#define JD		0x01<<19	//PIO_PA19_IDX
#define P1		0x01<<16	//PIO_PA16_IDX
#define P2		0x01<<15	//PIO_PA15_IDX
#define P3		0x01<<24	//PIO_PA24_IDX
#define P4		0x01<<25	//PIO_PA25_IDX
#define P5		0x01<<26	//PIO_PA26_IDX
and initialized them:

Code: Select all

MYBUTTON::MYBUTTON()
{
	uint32_t pin;
	
	pioa = (Pio *)((uint32_t)PIOA);
	pin = JCENTER | JA | JB |JC |JD | P1 | P2 | P3 | P4 | P5;
	pioa->PIO_PUER = pin;	// Enable Pull up
	pioa->PIO_ODR = pin;	// Configure pin as input
	pioa->PIO_IFDR = pin;	// No filter
//	pioa->PIO_IER = pin;	// Enable interrupt
	
}
reading them with:

Code: Select all

uint32_t MYBUTTON::GetPinValue()
{
	return pioa->PIO_PDSR;
}
When I read status registers I get:

OSR 0x28000180
PSR 0x3FFF81DF

that means pins are under control of PIO and are configured as input, but PDSR register is always 0.

Do I forget something?
I checked in forum history, but I found no answer

Thank you
Freya
kshysio
Posts: 25
Joined: Thu Nov 03, 2011 11:17 am

Re: Read PIO input value

Sun Jan 11, 2015 6:07 pm

maybe try to enable clock in PMC?
Freya
Posts: 58
Joined: Mon Jun 11, 2012 11:57 am

Re: Read PIO input value

Wed Jan 14, 2015 9:58 pm

Yes, you are right, my fault.
I was so used with pins in output that I forgot to activate PMC. :shock:

Unfortunately I have also another problem, that is interrupts.
They works too much well because when I press a button only once I got a semi infinite loop in interrupt (I counted 1600 interrupt for only one press) reguardless input filter or not.

Definition:

Code: Select all

MYBUTTON::MYBUTTON()
{
	uint32_t pin;
	
	pioa = (Pio *)((uint32_t)PIOA);
	pin = JCENTER | JA | JB |JC |JD | P1 | P2 | P3 | P4 | P5;
	pioa->PIO_PUER = pin;	// Enable Pull up
	pioa->PIO_ODR = pin;	// Configure pin as input
	pioa->PIO_IFER = pin;	// Enable filter input
//	pioa->PIO_IFDR = pin;	// Disable filter input
	pioa->PIO_IFSCER = pin;	// Enable debouncing filter
	pioa->PIO_SCDR = 0x00;	// Debouncing period
	pioa->PIO_AIMER = pin;	// Additional interrupt information required
	pioa->PIO_ESR = pin;	// Look only for edge interrupt
//	pioa->PIO_LSR = pin;	// Look only for level interrupt
	pioa->PIO_FELLSR = pin;	// Interrupt is a low level or falling edge
//	pioa->PIO_REHLSR = pin;	// Interrupt is a high level or a rising edge
	pioa->PIO_IER |= pin;	// Enable interrupt
	
	if ((PMC->PMC_PCSR0 & (0x01u << ID_PIOA)) != (0x01u << ID_PIOA)) PMC->PMC_PCER0 = 0x01u << ID_PIOA;	// Enable PIO A clock
}


Interrupt handler:

Code: Select all

void PIOA_Handler()
{
	uint32_t t;
	Pio *pioa;
	
	pioa = (Pio *)((uint32_t)PIOA);
	pioa->PIO_IDR = BUTTONS;	// Disable interrupt
	
	t = pioa->PIO_ISR;
	
	myio.PrintString((uint8_t *) "PIOA interrupt  (PIO_ISR)", ' ',0);
	myio.PrintHex(pioa->PIO_ISR, '\n');
	
	
	pioa->PIO_IER = BUTTONS;	// Enable interrupt
	
	return;
}

Do I have to add a loop like:
while(pioa->PIO_ISR);
in order to read all interrupt occurred?

Why cannot I get only one interrupt for pressing button?
kshysio
Posts: 25
Joined: Thu Nov 03, 2011 11:17 am

Re: Read PIO input value

Sat Jan 24, 2015 12:42 am

normally reading ISR register should clear interrupt...
maybe pin is controlled by some of peripheral, than in configuration you need to set bit in PIO_PER register
my working code:

Code: Select all


#define INT_BOTH_MASK	(PIO_PA22|PIO_PA29)

void pio_config(void)
{
   PMC->PMC_PCER0 = 1<<ID_PIOA;		     
   PIOA->PIO_PER	= INT_BOTH_MASK;	// enable paralel input - output
   PIOA->PIO_PUER = INT_BOTH_MASK;	// enable pull up
   PIOA->PIO_IFER = INT_BOTH_MASK;	// enable filter
   PIOA->PIO_IER	= INT_BOTH_MASK;	// enable interrupt
   PIOA->PIO_AIMER	 =	INT_BOTH_MASK;
   PIOA->PIO_ESR	 =  INT_BOTH_MASK;	// enable edge detect
   PIOA->PIO_FELLSR =  INT_BOTH_MASK;	// faling edge sense
   NVIC_EnableIRQ(PIOA_IRQn);
}

void PIOA_Handler(void)
{
   uint32_t status = PIOA->PIO_ISR; 
   
if(status & PIO_PA22)
   {
    // do something...
   }
if(status & PIO_PA29)
   {
    // or something else...
   }
}
Freya
Posts: 58
Joined: Mon Jun 11, 2012 11:57 am

Re: Read PIO input value

Tue Feb 03, 2015 11:32 am

Hi kshysio,
I made some other tests and I am afraid problem may reside elsewhere.
I removed the button clas from my project and added a display class.
In the display class there are the following linea:

Code: Select all

uint8_t dispp[160][26];

uint8_t i, j;

for(j=0; j<X;j++)
{
	for(i=0;i<160;i++) dispp[i][j] = 0x0C;
}		
If X<5 everything works, except UART0 interrupt
If X>5 and X<10 the program change the value in some variables
If X>10 and X<26 the program crashes

It seems that variables or program are overlapping.
Already I enlarged stack, but nothing changed

Someone else experienced the same problem?

Thank you

Return to “SAM3 Cortex-M3 MCU”

Who is online

Users browsing this forum: No registered users and 5 guests