Problems to configure the SAMC clock

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

Hello guys, I am having a set of problems trying to make my ATSAMC21E18A run at 48Mhz. To start off I have a custom board and an external XT of 16Mhz. I know it is not possible to directly feed the DPLL with 16Mhz so I tried to prescale its output using one of the GCLKlines and feed it to the DPLL, but it did not work.

 

I also have tried to use the internal 48Mhz RC with no DPLL to run the micro at 48Mhz but it did not work out, even with the biggest start up time and the clock have never got stable.

Here are some samples of my code:

 

void externalXtClock(void){
	struct system_clock_source_xosc_config xosc_conf;
	system_clock_source_xosc_get_config_defaults(&xosc_conf);

	xosc_conf.external_clock    = CONF_CLOCK_XOSC_EXTERNAL_CRYSTAL;
	xosc_conf.startup_time      = CONF_CLOCK_XOSC_STARTUP_TIME;
	xosc_conf.auto_gain_control = CONF_CLOCK_XOSC_AUTO_GAIN_CONTROL;
	xosc_conf.frequency         = 16000000UL;
	xosc_conf.on_demand         = CONF_CLOCK_XOSC_ON_DEMAND;
	xosc_conf.run_in_standby    = CONF_CLOCK_XOSC_RUN_IN_STANDBY;
	xosc_conf.clock_failure_detector_prescaler = CONF_CLOCK_XOSC_FAILURE_DETECTOR_PRE;
	xosc_conf.enable_clock_failure_detector    = CONF_CLOCK_XOSC_FAILURE_DETECTOR_ENABLE;
	xosc_conf.enable_clock_failure_detector_event_outut = CONF_CLOCK_XOSC_FAILURE_DETECTOR_EVENT_OUTPUT_ENABLE;
	xosc_conf.enable_clock_switch_back = CONF_CLOCK_XOSC_FAILURE_SWITCH_BACK_ENABLE;

	system_clock_source_xosc_set_config(&xosc_conf);
	system_clock_source_enable(SYSTEM_CLOCK_SOURCE_XOSC);
			
	Assert(CONF_CLOCK_XOSC_ENABLE);

	struct system_gclk_gen_config config_gclock_gen;
	system_gclk_gen_get_config_defaults(&config_gclock_gen);
	config_gclock_gen.source_clock = SYSTEM_CLOCK_SOURCE_XOSC;
	config_gclock_gen.division_factor = 16;
	system_gclk_gen_set_config(GCLK_GENERATOR_0, &config_gclock_gen);
}
void rc48MhzClock(void){
// 	struct system_clock_source_osc48m_config osc48m_conf;
// 	system_clock_source_osc48m_get_config_defaults(&osc48m_conf);
	OSCCTRL->OSC48MSTUP.reg = 0x07;
	OSCCTRL->OSC48MDIV.reg = OSCCTRL_OSC48MDIV_DIV(SYSTEM_OSC48M_DIV_1);		//by 1 does not work, by 2 it does
	while(OSCCTRL->OSC48MSYNCBUSY.reg);
	
// 	struct system_gclk_gen_config config_gclock_gen;
// 	system_gclk_gen_get_config_defaults(&config_gclock_gen);
// 	config_gclock_gen.source_clock = SYSTEM_CLOCK_SOURCE_OSC48M;
// 	config_gclock_gen.division_factor = 1;
// 	system_gclk_gen_set_config(GCLK_GENERATOR_0, &config_gclock_gen);
}
void dpll48MhzClock(void){
		struct system_clock_source_dpll_config dpll_config;
		system_clock_source_dpll_get_config_defaults(&dpll_config);
		
		dpll_config.on_demand        = true;
		dpll_config.run_in_standby   = true;
		dpll_config.lock_bypass      = CONF_CLOCK_DPLL_LOCK_BYPASS;
		dpll_config.wake_up_fast     = CONF_CLOCK_DPLL_WAKE_UP_FAST;
		dpll_config.low_power_enable = CONF_CLOCK_DPLL_LOW_POWER_ENABLE;

		dpll_config.filter           = CONF_CLOCK_DPLL_FILTER;

		dpll_config.reference_clock     = SYSTEM_CLOCK_SOURCE_DPLL_REFERENCE_CLOCK_GCLK;
		dpll_config.reference_frequency = 1000000;
		dpll_config.reference_divider   = 1;
		dpll_config.output_frequency    = 48000000;
		dpll_config.prescaler           = SYSTEM_CLOCK_SOURCE_DPLL_DIV_1;
		
		
		system_clock_source_dpll_set_config(&dpll_config);
		
// 		OSCCTRL->DPLLCTRLB.reg &= 0x‭F800FFFF‬;
// 		OSCCTRL->DPLLCTRLB.reg |= 0x‭00030000‬;
		
		system_clock_source_enable(SYSTEM_CLOCK_SOURCE_DPLL);
		while(!system_clock_source_is_ready(SYSTEM_CLOCK_SOURCE_DPLL)); //
		
// 		struct system_gclk_gen_config config_gclock_gen;
// 		system_gclk_gen_get_config_defaults(&config_gclock_gen);
// 		config_gclock_gen.source_clock = SYSTEM_CLOCK_SOURCE_DPLL;
// 		config_gclock_gen.division_factor = 1;
// 		system_gclk_gen_set_config(GCLK_GENERATOR_0, &config_gclock_gen);
}

 

I would appreciate any help.

Regards!
FS.

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

For one of my projects I am using the following clock initialization:

void ClocksInit(void) {
    // Set flash wait states for operation at 48 MHz @ 5V
    NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_RWS(1) | NVMCTRL_CTRLB_MANW;        //
     while ((OSCCTRL->STATUS.reg & OSCCTRL_STATUS_OSC48MRDY) == 0 );       // Wait until ready
 
    // Default setting for OSC48M
    OSCCTRL->OSC48MCTRL.reg = OSCCTRL_OSC48MCTRL_ONDEMAND | OSCCTRL_OSC48MCTRL_ENABLE;
    OSCCTRL->OSC48MDIV.reg = OSCCTRL_OSC48MDIV_DIV(1 - 1) | OSCCTRL_OSC48MCTRL_RUNSTDBY;   // 48MHz

    REG_OSCCTRL_OSC48MSTUP = 0x07;              // ~21uS startup
    while (OSCCTRL->OSC48MSYNCBUSY.reg);        // Wait until synced
    while ((OSCCTRL->STATUS.reg & OSCCTRL_STATUS_OSC48MRDY) == 0 );        // Wait until ready

    // Default setting for GEN0 (DIV => 0 & 1 are both 1)
    GCLK->GENCTRL[0].reg = GCLK_GENCTRL_SRC_OSC48M | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_DIV(1);    // 48MHz
    GCLK->GENCTRL[2].reg = GCLK_GENCTRL_SRC_OSC48M | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_DIV(6);    // 8MHz
}

 

Edit: I am not using START or ASF...

David

Last Edited: Mon. Aug 21, 2017 - 07:19 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for your help, I will try it and give you the feedback...

About ASF, I have been programming Atxmegas for almost 3 years without ASF. Now we are migrating to ARMs and I have decided to give ASF a try, but almost everything is a headache! I have spent 3 days trying to put I2C to work but nothing...

Regards!
FS.

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

I haven't used I2C on the ARMs. Thus far all of my requirements have been for SPI...

David

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

Your solution works nicely!

Thank you.

Regards!
FS.

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

Glad I could help!

David

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

Hi David,

 

I have started with Example code of USB CDC as device in SAM4L Xplained Pro board. Example is attached here - USB_Device_CDC_Example.zip

In that, I have modified

 

//#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_PLL0                   // Originally in example code
#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_DFLL                     // For my custom board as it does not have 12MHz external crystal.

 

#define CONFIG_DFLL0_SOURCE         GENCLK_SRC_RC32K                    // DFLL source is internal 32KHz oscillator

 

#define CONFIG_DFLL0_FREQ           48000000UL
#define CONFIG_DFLL0_MUL            ((4 * CONFIG_DFLL0_FREQ) / BOARD_OSC32_HZ)
#define CONFIG_DFLL0_DIV            4

 

 

//#define CONFIG_USBCLK_SOURCE        USBCLK_SRC_PLL0                 // Originally in example code
#define CONFIG_USBCLK_SOURCE          USBCLK_SRC_DFLL                 // For my custom board

 

Original Conf_clock.h from example is also attached here - conf_clock.h.

 

In this example code also, HSEN is not enabled - PS is not set to 2! But still when usb cable from PC is connected to SAM4L USB connector of explained Pro board, it is detected as "Communication Device Class ASF example (COMx)"

 

SAME CODE IS NOT WORKING IN MY CUSTOM BOARD!!!! :(

 

Kindly help.....

 

Thanks in advance.

 

 

 

Attachment(s): 

P D Chauhan

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

In hurry, I missed to write my objective:

I need to set 48MHz CPU Frequency of my MCU - ATSAM4LC2A - in my custom board. Maximum I can set 40MHz, but as USB requires 48 MHz, 40MHz will not work. at 40MHz, board is detected but it shows error in device manager "Device Descriptor Request Failed"

P D Chauhan

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

Hi All,

My problem is resolved. On my board having SAM4LC2A, PA02 was NC and VDDOUT and VDDCORE are connected via an inductor.

But actually as per this "http://www.atmel.com/Images/Atme...", voltage regulator mode (Switching and Linear) is decided by PA02 and connection between VDDOUT and VDDCORE. So, here it was not correct. I have pull-up the PA02 pin, but still example code was not working. So, then I have directly connected VDDOUT and VDDCORE and pull-down PA02 (Linear mode of Voltage Regulator). This made example code working!

Regards,

P D Chauhan

P D Chauhan