Getting Weird Characters on Bray++ Terminal while sending data configuring USART

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

Hello All,

 

I am using Microchip SAME54 Xplained PRO evaluation kit and have configured USART in asynchronous mode as shown in the code below. 

Now when I am evaluating the test_rx_char in the watch window under Atmel Studio 7 platform it displays different hex value everytime instead of the correct value of the character sent through getchar() function call. While, I see correct value being displayed in the Bray++ terminal when sent through the terminal. This is weird behaviour in itself which I have observed. 

Do I need to add something in the code below to solve this issue. Please, do let me know.

 

#include "sam.h"

#include <peripheral_clk_config.h>
#include <utils.h>
#include <hal_init.h>

#include <hal_atomic.h>
#include <hal_delay.h>
#include <hal_gpio.h>
#include <hal_init.h>
#include <hal_io.h>
#include <hal_sleep.h>

#define PC23 GPIO(GPIO_PORTC, 23)
#define PC22 GPIO(GPIO_PORTC, 22)

void SERCOM1_Init(void)
{
	MCLK->APBAMASK.reg |= MCLK_APBAMASK_SERCOM1;

	GCLK->PCHCTRL[8].reg = (GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(0));		// PCHCTRL[23] stands for GCLK_SERCOM2_CORE Clock for SERCOM2 

	gpio_set_pin_function(PC23, PINMUX_PC23C_SERCOM1_PAD1);

	gpio_set_pin_function(PC22, PINMUX_PC22C_SERCOM1_PAD0);

	gpio_set_pin_direction(PC23, GPIO_DIRECTION_IN);
	gpio_set_pin_direction(PC22, GPIO_DIRECTION_OUT);

	gpio_set_pin_level(PC22,
	// <y> Initial level
	// <id> pad_initial_level
	// <false"> Low
	// <true"> High
	true);

	gpio_set_pin_level(PC23,
	// <y> Initial level
	// <id> pad_initial_level
	// <false"> Low
	// <true"> High
	true);

	PORT->Group[2].WRCONFIG.reg = (uint32_t)(PORT_WRCONFIG_HWSEL | PORT_WRCONFIG_WRPINCFG | PORT_WRCONFIG_WRPMUX | PORT_WRCONFIG_PINMASK(1<<6)|PORT_WRCONFIG_PMUXEN|PORT_WRCONFIG_PMUX(2));   //PC22
	PORT->Group[2].WRCONFIG.reg = (uint32_t)(PORT_WRCONFIG_HWSEL | PORT_WRCONFIG_WRPINCFG | PORT_WRCONFIG_WRPMUX | PORT_WRCONFIG_PINMASK(1<<7)|PORT_WRCONFIG_PMUXEN|PORT_WRCONFIG_PMUX(2));	 // PC23

	// - Disable USART (required for configuration)
	while(SERCOM1->USART.SYNCBUSY.bit.ENABLE);
	SERCOM1->USART.CTRLA.bit.ENABLE = 0 ;
	while(SERCOM1->USART.SYNCBUSY.bit.ENABLE);
	// - Set UART clock as internal clock
	SERCOM1->USART.CTRLA.bit.MODE = 1;
	// - Set asynchronous communication mode
	SERCOM1->USART.CTRLA.bit.CMODE = 0;
	// - Set RX pin to PAD[1]
	SERCOM1->USART.CTRLA.bit.RXPO = 1;
	// - Set TX pin to PAD[0]
	SERCOM1->USART.CTRLA.bit.TXPO = 0;
	// - Set character size to 8bit
	SERCOM1->USART.CTRLB.bit.CHSIZE = 0;
	// - Set Data order to MSB first
	SERCOM1->USART.CTRLA.bit.DORD = 0;
	// - Set No Parity
	SERCOM1->USART.CTRLA.bit.FORM = 0;
	// - Set Number of Stop bit to 1
	SERCOM1->USART.CTRLB.bit.SBMODE = 0;

	// - Set Baud-rate
	SERCOM1->USART.CTRLA.bit.SAMPR = 0;   // S = 16
	SERCOM1->USART.BAUD.bit.BAUD = 63019; // 65536 * (1 - 16 * (115200 /48000000))

	while(SERCOM1->USART.SYNCBUSY.bit.CTRLB);
	// - Enable TX and RX
	SERCOM1->USART.CTRLB.bit.TXEN = 1;
	SERCOM1->USART.CTRLB.bit.RXEN = 1;
	// - Enable USART
	while(SERCOM1->USART.SYNCBUSY.bit.ENABLE);
	SERCOM1->USART.CTRLA.bit.ENABLE = 1 ;
	while(SERCOM1->USART.SYNCBUSY.bit.ENABLE);
}

char SERCOM1_USART_getc()
{
	// - Wait for UART reception flag
	while(!(SERCOM1->USART.INTFLAG.bit.RXC));
	// - Return RX register content
	return  (char) SERCOM1->USART.DATA.reg;
}

void SERCOM1_USART_putc(char Char)
{

	// - Wait until Data register empty
	while(!(SERCOM1->USART.INTFLAG.bit.DRE) );
	// - Copy data to send in TX register
	SERCOM1->USART.DATA.reg = Char;
}

int main(void)
{
	unsigned char test_rx_char;
    /* Initialize the SAM system */
    SystemInit();
	SERCOM1_Init();
    /* Replace with your application code */
    while (1)
    {

		test_rx_char = SERCOM1_USART_getc();
			SERCOM1_USART_putc(test_rx_char);
			delay_ms(100);
    }
}

USART Configuration:- 115200 baud rate, 8 character bit, no parity, 1 stop bit, Asynchronous communication, internal clock selected. SERCOM1 used - Pins PC22 and PC23.

 

Present scenario:-  I am getting weird different hex value of a character sent. For example, if I sent '1' through bray++ terminal then I observed different hex value in test_rx_char above when observed through watch window. What could be added in the above code to resolve this issue ??

 

Thanks.

 

This topic has a solution.
Last Edited: Thu. Dec 19, 2019 - 08:41 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is the correct character being echoed to Bray's terminal? 

 

My guess is test_rx_char is stored in a register, and the register gets used elsewhere. So what you're observing is expected. You might try declaring test_rx_char as volatile to force the compiler to put it into ram.

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

Hi @Kartman, Yes, correct character being echoed to the Bray's terminal. I have tried declaring the variable as volatile as per your suggestion but with no success. 

 

The test_rx_char variable still showing wrong hex values when we observe it under watch window in Atmel Studio 7. I have not seen this type of behaviour earlier wondering what might be the issue. 

 

Regards.

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

Hello All,

 

Does anyone facing the same issue in their PC for above code and know the solution then do let me know.

 

Thanks.

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

Hi @Kartman, Changing data order (DORD ) bit to 1 i.e. LSB transmitted first resolved my issue. 

 

The problem is due to system using LSB settings. So, if we read the data, with DORD (set to 0) , you see the mirror image of the received data. This is the response which I got from Microchip Technical support team.

 

Thanks and Regards.