sam4s Xplained cannot toggle GPIO faster than 3MHz

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

Hi All

 

Ive been trying to setup the PLLB on my sam4S explained board to increase the clock frequency to the maximum. For some reason i cannot make the GPIO pins toggle faster than 3MHz? If i set the CKGR_PLLBR_MULB bits past a point the GPIO's just stop toggling even if the frequency is below 100 MHz. Her is my code:

 

/*
 * ATSAM4S_BARE_1.c
 *
 * Created: 4/24/2020 2:54:59 PM
 * Author : Atticus
 */ 


#include "sam.h"

//delay function
void delay (void){
	for (volatile uint16_t x=0; x<65535;x++){
		asm ("nop");
	}
}


void set_pin_toggle(void){
	
	

	REG_CKGR_MOR |= (CKGR_MOR_KEY_PASSWD) | (CKGR_MOR_MOSCRCF_8_MHz);
	
	//enable the periferal clock for PIOC
	REG_PMC_PCER0 |= (PMC_PCDR0_PID13);
	
	//set the multiplyer and divider
	//Here i cannot go more than 6????
	REG_CKGR_PLLBR |= CKGR_PLLBR_MULB(6) | CKGR_PLLBR_DIVB(1);
	
	//select PLLB as the master clock
	REG_PMC_MCKR |= PMC_MCKR_CSS_PLLB_CLK;
	
	//enable PIOC controller for pin 30
	REG_PIOC_PER |= PIO_PER_P30;
	
	//set as output
	REG_PIOC_OER |= PIO_PER_P30;
	
}



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

	
	while (1) 
    {
		
		//Set Output Data Register
		REG_PIOC_SODR |= PIO_PER_P30;
		
		
		//clear Output Data Register
		REG_PIOC_CODR |= PIO_PER_P30;
		
		
		
    }
}

 

This topic has a solution.
Last Edited: Sat. May 2, 2020 - 05:19 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Why are you using read-modify-write on write-only registers?

 

Cortex-M4 has pretty good output drivers.   But the Compiler might appreciate -O2, -O3, ...

As a general rule,  you need to be careful with the speed of external electronics when above M0.  e.g. M3, M4, M7, ...

 

David.

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

Thanks David. Amateur mistake from my side. If i understand you correctly the OR= operation causes a read from a write only register. I have changed the code by deleting the OR operation. I also change the MULB to 15 and the RC oscillator to 8MHz so i get a 120MHz clk frequency. Measuring the PIO with my logic analyser i am getting 25MHz. Which seams reasonable? Im assuming there are a few CPU CLK cycles used to set registers.

 

Thanks for the headsup on being careful with the M4. Could you possible elaborate on this? I am being very careful in terms of static. Not too sure what you mean.

 

 

/*
 * ATSAM4S_BARE_1.c
 *
 * Created: 4/24/2020 2:54:59 PM
 * Author : Atticus
 */ 


#include "sam.h"

//delay function
void delay (void){
	for (volatile uint16_t x=0; x<65535;x++){
		asm ("nop");
	}
}


void set_pin_toggle(void){
	
	

	REG_CKGR_MOR |= (CKGR_MOR_KEY_PASSWD) | (CKGR_MOR_MOSCRCF_8_MHz);
	
	//enable the periferal clock for PIOC
	REG_PMC_PCER0 |= (PMC_PCDR0_PID13);
	
	//set the multiplyer and divider
	//Here i cannot go more than 6????
	REG_CKGR_PLLBR |= CKGR_PLLBR_MULB(15) | CKGR_PLLBR_DIVB(1);
	
	//select PLLB as the master clock
	REG_PMC_MCKR |= PMC_MCKR_CSS_PLLB_CLK;
	
	//enable PIOC controller for pin 30
	REG_PIOC_PER |= PIO_PER_P30;
	
	//set as output
	REG_PIOC_OER |= PIO_PER_P30;
	
}



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

	
	while (1) 
    {
		
		//Set Output Data Register
		REG_PIOC_SODR = PIO_PER_P30;
		
		//clear Output Data Register
		REG_PIOC_CODR = PIO_PER_P30;

    }
}

 

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

I see i forgot to eliminate all the read modify write instructions on the registers in the code above in the set_pin_toggle() function.

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

Yes,  SODR and CODR are write-only.  

 

If your default is -O0 I bet that -O2 will make a massive difference.

-O0 is not unreasonable with the arm-gcc but is horrific with avr-gcc

 

David.

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

Thanks for the help David. My default is -O1. I changed them around and got the following results:

 

-O0 : Pin does not toggle

-O1 : 25MHz

-O2 : Pin does not toggle

-O3 : 25MHz

 

Strange that -O0 and -O2 dont work. Could you possibly elaborate on what you mean when being careful with this board? Is there a protection difference with the M0's and the higher M's?

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

I would expect the pin to toggle for every Optimisation value.

 

I have probably only used SAMD21 or SAM3X and with Keil and Rowley.

I have used many M4 from ST or NXP and these with Keil and Rowley.

 

Rowley uses ARM-GCC just like AS7.0 so I would expect the same optimisation behaviour.

 

It is simple enough to compare the disassembly for -O0, -O1, -O2, -O3, -Os, -Og

 

Why do you want to toggle GPIO at 25MHz i.e a 20ns + 20ns cycle is faster than much external electronics.

If you want a steady square wave,   you can do it in hardware.   And achieve F_CPU/2 with no software overhead.

 

David.

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

david.prentice wrote:
Why do you want to toggle GPIO at 25MHz
'

 

No reason really. I'm not building anything i'm just trying to understand the clock. I'm messing around seeing what i can and cant do. Thought i would see how fast i can toggle the pins. I have been reading around and it seems i need to become acquainted with wait states if the CPU is clocked at 120MHz.  

 

 

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

i got about 30MHz on a 120MHz chip.  https://forums.adafruit.com/viewtopic.php?f=57&t=133497&hilit=M4#p668379

remember to turn on cache, if appropriate.

 

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

calvingloster wrote:
seems i need to become acquainted with wait states if the CPU is clocked at 120MHz

Indeed you do!

 

And remember to set the wait states before you turn the cock up!

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

or run the code in ITCM