Registers not setting as expected in debugging mode

Go To Last Post
16 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi All

 

I am using an Xplained sam4s board. My goal is to understand working with the Parallel input/output controller. What i have done is written a simple program that when you push the on board button the on board LED goes on. In helping me identify exactly what is going on i have set additional registers and debugged the board while watching the registers on the I/O view in atmel studio 7. What is puzzling is that i set a few registers for REG_PIOC_PER but i do not see these changing to 1's in the I/O view of atmel studio. I have attached the code i have written as well as a picture. In the picture the debug process is at the red arrow and the REG_PIOC_PER registers should have been set by this point. I expect to see the bits in the I/O view to change however they do not. Can someone please point me in the right direction here as i am pretty confused.

 

/////////////////////////////////////////////////////////////////////////
////////////Default Button on PINA2 and onboard LED on PINC23///////////
////////////////////////////////////////////////////////////////////////

#include <asf.h>

int main (void)
{
	
	board_init();
	
	void delay (void){
		for (volatile uint16_t x=0; x<65535;x++){
			asm ("nop");
		}
	}
	
	//to use pin as general input output:
	//1. enable the parallel input output controller for that pin. this also disables the
	//peripherals on the pin
	//2. set the mode of the pin, input, output etc

	//enable parallel input output C port controller for GPIO pin(PIOC)
	REG_PIOC_PER |= (1<<0);
	REG_PIOC_PER |= (1<<1);
	REG_PIOC_PER |= (1<<2);
	REG_PIOC_PER |= (1<<3);
	REG_PIOC_PER |= (1<<4);
	REG_PIOC_PER |= (1<<5);
	REG_PIOC_PER |= (1<<6);
	REG_PIOC_PER |= (1<<7);
	REG_PIOC_PER |= (1<<8);
	REG_PIOA_PER |= (1<<9);
	
	//set LED pin as output (output enable)
	REG_PIOC_OER |= (1<<23);
	
	//set Button as input (output disable)
	REG_PIOA_ODR |= (1<<2);

	while (1) {
		
		//Set output data register based on button status
		if (REG_PIOA_PDSR & (1<<2)){
			
			REG_PIOC_CODR |= (1<<23);
			
		}
		else{
			
			REG_PIOC_SODR |= (1<<23);
			
		}
		
		
	}
	
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Look at the assembler view to see the code the compiler generated.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is the assembly code:

 

--- C:\Users\Atticus\Documents\Atmel Studio\7.0\Default Button\Default Button\Debug/../src/main.c 
{
00400394   push	{r3, lr}		 
	board_init();
00400396   ldr	r3, [pc, #148]		 
00400398   blx	r3		 
	REG_PIOC_PER |= (1<<0);
0040039A   ldr	r3, [pc, #148]		 
0040039C   ldr	r2, [r3]		 
0040039E   orr	r2, r2, #1		 
004003A2   str	r2, [r3]		 
	REG_PIOC_PER |= (1<<1);
004003A4   ldr	r2, [r3]		 
004003A6   orr	r2, r2, #2		 
004003AA   str	r2, [r3]		 
	REG_PIOC_PER |= (1<<2);
004003AC   ldr	r2, [r3]		 
004003AE   orr	r2, r2, #4		 
004003B2   str	r2, [r3]		 
	REG_PIOC_PER |= (1<<3);
004003B4   ldr	r2, [r3]		 
004003B6   orr	r2, r2, #8		 
004003BA   str	r2, [r3]		 
	REG_PIOC_PER |= (1<<4);
004003BC   ldr	r2, [r3]		 
004003BE   orr	r2, r2, #16		 
004003C2   str	r2, [r3]		 
	REG_PIOC_PER |= (1<<5);
004003C4   ldr	r2, [r3]		 
004003C6   orr	r2, r2, #32		 
004003CA   str	r2, [r3]		 
	REG_PIOC_PER |= (1<<6);
004003CC   ldr	r2, [r3]		 
004003CE   orr	r2, r2, #64		 
004003D2   str	r2, [r3]		 
	REG_PIOC_PER |= (1<<7);
004003D4   ldr	r2, [r3]		 
004003D6   orr	r2, r2, #128		 
004003DA   str	r2, [r3]		 
	REG_PIOC_PER |= (1<<8);
004003DC   ldr	r2, [r3]		 
004003DE   orr	r2, r2, #256		 
004003E2   str	r2, [r3]		 
	REG_PIOA_PER |= (1<<9);
004003E4   ldr	r2, [pc, #76]		 
004003E6   ldr	r3, [r2]		 
004003E8   orr	r3, r3, #512		 
004003EC   str	r3, [r2]		 
	REG_PIOC_OER |= (1<<23);
004003EE   add.w	r2, r2, #1040		 
004003F2   ldr	r3, [r2]		 
004003F4   orr	r3, r3, #8388608		 
004003F8   str	r3, [r2]		 
	REG_PIOA_ODR |= (1<<2);
004003FA   sub.w	r2, r2, #1020		 
004003FE   ldr	r3, [r2]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Data sheet says:

This register can only be written if the WPEN bit is cleared in the PIO Write Protection Mode Register.

Please don't write the bits one-at-a-time like that.   It hurts to look at!

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

westfw wrote:

Data sheet says:

This register can only be written if the WPEN bit is cleared in the PIO Write Protection Mode Register.

Please don't write the bits one-at-a-time like that.   It hurts to look at!

 

 

Thanks, i saw this in the data sheet however tutorials on the net do not clear this bit when setting the PIO registers so i assumed i dont understand the datasheet. What is strange though is the code still works however registers do not get set as seen during debugging.

 

One question, i am not at home now to test this out but do you need to clear this bit every time you set a PIO register? Also why is the write protection not disabled on reset as stated by the datasheet? Or am i interpreting this incorrectly ?

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So i cleared the WPEN bit in the PIO_WPMR register and still no luck so i changed the optimization of the compiler to none and still no luck.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
Look at the assembler view to see the code the compiler generated.

 

I am busy reading up on assembly. At the moment i have no idea what the assembly code is doing.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Any ideas? I'm still stuck with this.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Access: Write-only

The debugger can't read the register any better than you can from code. 

If you really need to see some activity you can try a disable first

REG_PIOC_PDR |= (1<<0);

and you should then see changes in the PSR register (the read only status).

/Lars 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Lars. This is an eye opener for me. I thought that the debugger will show you exactly what the status of each and every register is at any time. From what you have said now i believe you can only read the registers which have read access? Looking at the data sheet the status registers do however give enough information to inform you of all the registers state, is this correct?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What is the use of the debugger showing the registers that are write only registers if it can anyways not read them?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well you can still write the register from the debugger.

/Lars

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok that makes sense. Thank you

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@Calvin,

 

Personally,  I would try to write a concise, neatly formatted program.    You have used ASF

I have just written a bare-metal version:

/*
* calvingloster_raw.c
*
* Created: 27-Sep-19 13:00:21
* Author : David Prentice
*/

#include "sam.h"

int main(void)
{
    /* Initialize the SAM system */
    SystemInit();

    //enable clocks for PORTA, PORTC
    PMC->PMC_PCER0 = (1 << ID_PIOA)|(1 << ID_PIOC);
    //set LED pin as output (output enable)
    REG_PIOC_OER = (1<<23);  //steering registers are write-only
    //set Button as input (output disable)
    REG_PIOA_ODR = (1<<2);

    while (1) {        
        //Set output data register based on button status
        if (REG_PIOA_PDSR & (1<<2)) {
            REG_PIOC_CODR = (1<<23);  //steering registers are write-only
        }
        else{
            REG_PIOC_SODR = (1<<23);
        }
    }
}

Build and observe the dependencies.    "sam.h" draws in all the "component_peripheral.h" and "instance_peripheral.h".    It still needs a lot of datasheet studying.

 

Using ASF draws in even more header files.     My head hurts when I see ASF.

If you can follow ASF,   it is probably a good way to construct a program.

 

Oh,   you can set many bits in the REG_PIOC_PER register in a single statement.    One explanatory comment + one executable statement seems more straightforward (to me).

 

And yes,  the datasheet tells you how to use the PIO Write Protection Mode Register.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks David. I tried following what ASF does but there is so much abstraction it also hurt my head.

 

Your code looks better i prefer using simpler code. Thanks again for the boards:)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I advise you to persevere with ASF or equivalent.   You have a younger brain.

 

It will be the best way to make practical applications.

 

David.