USART stopped working after increasing CPU clock speed

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

Hi,

 

I changed my CPU clock speed on my ATSAML21e18b from 4MHz to 48 MHz but the UART seems to have stopped working.

 

I initialize my UART as

void UART_init(void)
{
	/* Configure UART */
    //Initializes the device to predefined defaults
	usart_get_config_defaults(&usart_config);
	usart_config.mux_setting = USART_RX_1_TX_0_XCK_1;
	usart_config.pinmux_pad0 = PINMUX_PA00D_SERCOM1_PAD0;
	usart_config.pinmux_pad1 = PINMUX_PA01D_SERCOM1_PAD1;
	usart_config.pinmux_pad2 = PINMUX_UNUSED;
	usart_config.pinmux_pad3 = PINMUX_UNUSED;
	usart_config.baudrate    = 115200;

	while(usart_init(&usart_module, SERCOM1, &usart_config) != STATUS_OK){
    };
	usart_enable(&usart_module);
}

In my main() function I have a short while loop that runs until all initialization is set up and then it hands some stuff over to Linux before jumping into an infinite while loop. The part that is no longer working is this:

if(!strcmp("cmd_done", (char*)usart_buffer)) {
			usart_write_buffer_wait(&usart_module, (unsigned char*)"Received cmd done\n\r", 19);
			/* Hand over the display to imx6 */
			TFT_Init_RGB(3);
			/* Hand over the backlight control to imx6 */
			port_pin_set_output_level(LCD_BACKLIGHT_PIN, false);
			break;
		}
        else if(!strcmp("fsh_rbpt", (char*)usart_buffer)){
		/*write the block protection bits to zero*/
			usart_write_buffer_wait(&usart_module, (unsigned char*)
								"Writing block protection bits...\n", 33);
        }

When I send the commands to the serial port through Linux and try to cat the response I see nothing.

 

Is the CPU clock somehow interfering with the USART baud rate? My understanding was that increasing the CPU clock would only affect that MAXIMUM baud rate and 115200 is plenty for this application.

 

I used ASF (clocks_config.h) to set up GCLK0 at 48 MHz.

This topic has a solution.

1010001010111101110111

Last Edited: Fri. Jun 4, 2021 - 08:33 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It seems that the malfunction may stem from an error in the clock rate. I am feeding the internal OSC32K as a reference to DFLL and then using DFLL at 48 MHz as the GCLK 0.

 

I think a quick fix here might be to change the SERCOM clock that the USART uses to simply use the SYSTEM_OSC16M_4M. Now I just need to figure out how to actually do that.

1010001010111101110111

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

Mithrandir_ wrote:
I changed my CPU clock speed on my ATSAML21e18b from 4MHz to 48 MHz

Do you need waitstates at that speed ?

 

Mithrandir_ wrote:
the UART seems to have stopped working

Just the UART?  Or is other code still running?

 

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

awneil wrote:
Do you need waitstates at that speed ?

 

Yes, I have configured it.

 

awneil wrote:
Just the UART?  Or is other code still running?

 

Just USART. Code runs, LCD screen loads the boot image (implying SPI works) but it never receives the command from Linux "cmd_done" to jump out of the while loop and hand over the LCD to Linux. I tried to manually echo the command through /dev/ttymxc2 but it doesn't seem to be receiving anything. Complete silence.

 

/* System clock bus configuration */

#  define CONF_CLOCK_CPU_CLOCK_FAILURE_DETECT     false

#  define CONF_CLOCK_FLASH_WAIT_STATES            1 // 48MHz @ 3.3v

I tried everything between 1 and 3, still the same result.

1010001010111101110111

Last Edited: Thu. Jun 3, 2021 - 01:41 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I found this:

https://www.eevblog.com/forum/mi...

 

But I am unable to follow what is really going on.

 

I'd like to change the clock generator ONLY for SERCOM1 that deals with the USART. All the other SERCOMs should remain on GCLK0. 

1010001010111101110111

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have to agree you should not need to change the clock generator of SERCOM1 in this case, something is wrong.

To try the quick fix just look at the documentation for ASF 3 since you are using it. In this case 

https://asf.microchip.com/docs/l...

Change the generator_source after
 

	usart_get_config_defaults(&usart_config);

Change it to another GCLK generator you configure in clocks_config.h (probably just configure it like GCLK0 was set before).

/Lars

 

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

Lajon wrote:
Change the generator_source

 

Well, it worked... Everything works fine now. But now I'm curious _WHY_ it worked :/. I don't know how accurate the OSC32K is, I haven't looked into it. I feel like the processors might be running at a higher speed than it says, I haven't actually confirmed 48MHz with an oscilloscope - I can just see a noticeable difference in the speed that it boots.

 

And thanks yet another timebfor the help, Lars.

1010001010111101110111

Last Edited: Thu. Jun 3, 2021 - 08:32 PM