Author Topic: problems with UART on SAMD21  (Read 6711 times)

0 Members and 1 Guest are viewing this topic.

Offline DavedenHaanTopic starter

  • Contributor
  • Posts: 23
  • Country: nl
problems with UART on SAMD21
« on: November 17, 2020, 10:17:09 am »
Hello,

For a project I'm currently working with the SAMD21J18A and I'm for this it is necessary to send DATA over USART.

This for both debugging and application purposes.

I configured the UART according to the SAMD21 datasheet.

The pin on which I have a data analyzer connected are PB30 for TX and PB31 for RX which have the SERCOM 5 on D.

The issue is that I'm not getting the message on the data analyzer that I'm trying to send over UART communication.

Pin Initialization
Code: [Select]
HAL_GPIO_PIN(UART_TX, B, 30)
HAL_GPIO_PIN(UART_RX, B, 31)

USART Initialization
Code: [Select]
static void uart_init2(uint32_t baud)
{
uint64_t baudrate = (uint64_t)65536 * (8000000 - 16 * baud) / 8000000;

HAL_GPIO_UART_TX_out();
HAL_GPIO_UART_TX_pmuxen(PORT_PMUX_PMUXE_D_Val);
HAL_GPIO_UART_RX_in();
HAL_GPIO_UART_RX_pmuxen(PORT_PMUX_PMUXE_D_Val);

PM->APBCMASK.reg |= PM_APBCMASK_SERCOM5;

GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(SERCOM5_GCLK_ID_CORE) |
GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0);

SERCOM5->USART.CTRLA.reg =
SERCOM_USART_CTRLA_DORD | SERCOM_USART_CTRLA_MODE_USART_INT_CLK |
SERCOM_USART_CTRLA_RXPO(0x1) | SERCOM_USART_CTRLA_TXPO(0x0);

SERCOM5->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN |
SERCOM_USART_CTRLB_CHSIZE(0);

SERCOM5->USART.BAUD.reg = (uint16_t)baudrate+1;

SERCOM5->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
}

Writing and main:
Code: [Select]
static void uart_putc(char c)
{
while (!(SERCOM5->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_DRE));
SERCOM5->USART.DATA.reg = c;
}

static void uart_puts(char *s)
{
while (*s)
uart_putc(*s++);
}

int main(void)
{
SystemInit();
GPIO_Init();
TMR_Init();

uart_init2(115200);

uart_puts("Hello, world!");

   
    while (1)
    {

    }
}


The attachment show the output of the code that is used.

The usart start whos the output from the start of the code and the rest are screenshots of the remaining output.
The baudrate im trying to communicate on is 115200.


« Last Edit: November 17, 2020, 01:15:26 pm by DavedenHaan »
 

Offline DavedenHaanTopic starter

  • Contributor
  • Posts: 23
  • Country: nl
Re: problems with UART on SAMD21
« Reply #1 on: November 17, 2020, 03:17:56 pm »
It could have to do something with the timers and Clock that is connected I will add that as well.
In case someone has a suggestion

Code: [Select]

#define TC3_PRESCALER 4

#define TC3_PER_10MS (80000/TC3_PRESCALER)-50

#define GLOBAL_TMR_TO_100MS 10
#define GLOBAL_TMR_TO_1000MS 100

extern uint32_t GlobalTick;

#define GLOBAL_TMR_SET(x) (x+GlobalTick)
#define GLOBAL_TMR_IS_EXPIRED(x) (x <= GlobalTick)

void TC3_Handler(void)
{
TC3->COUNT16.INTFLAG.reg = TC_INTFLAG_OVF;
GlobalTick++;

}


void TMR_Init(void)
{
PM->APBCMASK.reg |= PM_APBCMASK_TC3; //Provide power to TC3
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(TC3_GCLK_ID) |
GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0); //Provide Clock to TC3, from generator 0

TC3->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16 | // Configuring TC3 to 16-bit operation
TC_CTRLA_WAVEGEN_MFRQ | // Match frequency wit CC0
TC_CTRLA_PRESCALER_DIV4 | // Prescaler to 4
TC_CTRLA_PRESCSYNC_RESYNC; // Reload or reset the counter on next generic clock. Reset the prescaler counter

TC3->COUNT16.CC[0].reg = TC3_PER_10MS; // Set overflow value
TC3->COUNT16.COUNT.reg = 0; // Clear Counter

TC3->COUNT16.INTFLAG.reg = TC_INTFLAG_OVF;  // Clear interrupt flag of timer overflow
TC3->COUNT16.INTENSET.reg = TC_INTENSET_OVF; // Enable interrupt on overflow
NVIC_EnableIRQ(TC3_IRQn); // Enable Global Interrupt for the Peripheral
TC3->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE; // Start Timer*/

}
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12498
  • Country: us
    • Personal site
Re: problems with UART on SAMD21
« Reply #2 on: November 17, 2020, 05:17:41 pm »
You are not showing any timings on your traces. Is your logic analyzer decoder actually configured for 115200? It does not look like it.
Alex
 

Offline DavedenHaanTopic starter

  • Contributor
  • Posts: 23
  • Country: nl
Re: problems with UART on SAMD21
« Reply #3 on: November 17, 2020, 05:29:53 pm »
Currently I have it set on 115200.

I included all the settings that the UART let me do.
The last screenshot shows the total time of the message.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12498
  • Country: us
    • Personal site
Re: problems with UART on SAMD21
« Reply #4 on: November 17, 2020, 05:36:27 pm »
Those timings are super hard to read. I'm not sure why logic analyzer authors keep making them this way.

Do this. Send  just one character - "U" and capture the result and a real close up of the whole transfer. Or better yet, attach the actual log instead of screen captures.

Is your system clock actually 8 MHz?
Alex
 

Offline DavedenHaanTopic starter

  • Contributor
  • Posts: 23
  • Country: nl
Re: problems with UART on SAMD21
« Reply #5 on: November 17, 2020, 05:41:14 pm »
Included are the setting for the system clock.

I will try your suggestion with the single character and the entire log from the analyzer.
 

Offline DavedenHaanTopic starter

  • Contributor
  • Posts: 23
  • Country: nl
Re: problems with UART on SAMD21
« Reply #6 on: November 17, 2020, 05:47:32 pm »
There are few options for exporting the analyzer output.

The first attachment shows the available options, which one should I do?
If this isn't what u meant I haven't used many logic analyzer like this so I'm still learning the possiblities

The other attachment is the output when sending just an 'U' the output is in HEX atm.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12498
  • Country: us
    • Personal site
Re: problems with UART on SAMD21
« Reply #7 on: November 17, 2020, 05:49:38 pm »
Included are the setting for the system clock.
This is not a setting, this is just a variable. Do you actually have the code that configures it to be 8 MHz?
« Last Edit: November 17, 2020, 05:53:06 pm by ataradov »
Alex
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12498
  • Country: us
    • Personal site
Re: problems with UART on SAMD21
« Reply #8 on: November 17, 2020, 05:51:42 pm »
Your baudrate is definitely not correct. You can see the character U (0x55) begin send, but the logic analyzer interprets each bit as a new byte.

Don't do export, just do save. I nave PulseView, I can open those files in its native format. But in this case there is no need for a log, the situation is pretty clear.
Alex
 

Offline DavedenHaanTopic starter

  • Contributor
  • Posts: 23
  • Country: nl
Re: problems with UART on SAMD21
« Reply #9 on: November 17, 2020, 05:55:46 pm »
Nothing extra no, I thought this sets the system clock by including sytem_init() into the main.

The only clock setting that are done are included in the first post for the timer and the GLCK that is done in the uart_init();
timer:
« Last Edit: November 17, 2020, 06:08:04 pm by DavedenHaan »
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12498
  • Country: us
    • Personal site
Re: problems with UART on SAMD21
« Reply #10 on: November 17, 2020, 05:57:53 pm »
It has nothing to do with the timer. There is no need to copy that code here.

I have no idea what sytem_init() does. You seem to be just pulling random code from different places without looking at it. This is not a good idea.

Just take my sys_init() from the same place you took the UART code.
Alex
 

Offline DavedenHaanTopic starter

  • Contributor
  • Posts: 23
  • Country: nl
Re: problems with UART on SAMD21
« Reply #11 on: November 17, 2020, 06:07:38 pm »
the system_init(); was created by Atmel itself when I started the project for the the SAMD21;

It was included in the device startup.

I have included the output of the pulseview.

The sys_init(); for the 8MHz clock is included instead of the system_init();

I had to include it as ZIP because it doesn't let me upload otherwise
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12498
  • Country: us
    • Personal site
Re: problems with UART on SAMD21
« Reply #12 on: November 17, 2020, 06:23:02 pm »
This capture looks like it was done with a very low sampling rate on the analyzer or the frequency on the output jumped up a lot.

What version of the sys_init() did you include? Can you share the entire project?
Alex
 

Offline DavedenHaanTopic starter

  • Contributor
  • Posts: 23
  • Country: nl
Re: problems with UART on SAMD21
« Reply #13 on: November 17, 2020, 06:42:38 pm »
I dont have a github set up will do that soon so its easier to read through

Code: [Select]
HAL_GPIO_PIN(UART_TX, B, 30)
HAL_GPIO_PIN(UART_RX, B, 31)

static void uart_init2(uint32_t baud) // Uart init for SERCOM 5 pins
{
uint64_t br = (uint64_t)65536 * (8000000 - 16 * baud) / 8000000;

HAL_GPIO_UART_TX_out();
HAL_GPIO_UART_TX_pmuxen(PORT_PMUX_PMUXE_D_Val);
HAL_GPIO_UART_RX_in();
HAL_GPIO_UART_RX_pmuxen(PORT_PMUX_PMUXE_D_Val);

PM->APBCMASK.reg |= PM_APBCMASK_SERCOM5;

GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(SERCOM5_GCLK_ID_CORE) |
GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0);

SERCOM5->USART.CTRLA.reg =
SERCOM_USART_CTRLA_DORD | SERCOM_USART_CTRLA_MODE_USART_INT_CLK |
SERCOM_USART_CTRLA_RXPO(0x1) | SERCOM_USART_CTRLA_TXPO(0x0);

SERCOM5->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN |
SERCOM_USART_CTRLB_CHSIZE(0/*8 bits*/);

SERCOM5->USART.BAUD.reg = (uint16_t)br+1;

SERCOM5->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
}

static void sys_init(void)
{
// Switch to 8MHz clock (disable prescaler)
SYSCTRL->OSC8M.bit.PRESC = 0;
}

static void uart_putc(char c)
{
while (!(SERCOM5->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_DRE));
SERCOM5->USART.DATA.reg = c;
}

static void uart_puts(char *s)
{
while (*s)
uart_putc(*s++);
}


Main
Code: [Select]
int main(void)
{
sys_init();
GPIO_Init();
TMR_Init();


uart_init2(115200);

uart_puts("U");

   
    while (1)
    {
//uart_puts("hello world");

    }
}

these are the settings I'm using now
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12498
  • Country: us
    • Personal site
Re: problems with UART on SAMD21
« Reply #14 on: November 17, 2020, 06:44:07 pm »
There is no need to copy the exact same code twice.

What is in your sys_init()?
Alex
 

Offline DavedenHaanTopic starter

  • Contributor
  • Posts: 23
  • Country: nl
Re: problems with UART on SAMD21
« Reply #15 on: November 17, 2020, 06:46:47 pm »
Code: [Select]
static void sys_init(void)
{
// Switch to 8MHz clock (disable prescaler)
SYSCTRL->OSC8M.bit.PRESC = 0;
}
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12498
  • Country: us
    • Personal site
Re: problems with UART on SAMD21
« Reply #16 on: November 17, 2020, 06:52:34 pm »
Ok, this is good.

Now make sure that you set at least 12 MHz sampling frequency on the logic analyzer. And capture the "U" character again.
Alex
 

Offline DavedenHaanTopic starter

  • Contributor
  • Posts: 23
  • Country: nl
Re: problems with UART on SAMD21
« Reply #17 on: November 17, 2020, 07:05:21 pm »
I used 12MHz sampling and I indeed got a U out from the UART port:

I also tried Hello, world after and got that + some extra.

uart_puts("\r\nHello, world!\r\n"); is what used isntead of U.

The first attachment shows the output on the logic analyzer. (50M samplings, 12MHz samping time)

I also tried just uart_puts("Hello, world!");

the output shows world but Hello does not get decoded: attachment 2 shows output.

 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12498
  • Country: us
    • Personal site
Re: problems with UART on SAMD21
« Reply #18 on: November 17, 2020, 07:14:54 pm »
Your signal looks fine. I think your logic analyzer fails to decode things. Just connect to the real UART receiver.
Alex
 

Offline DavedenHaanTopic starter

  • Contributor
  • Posts: 23
  • Country: nl
Re: problems with UART on SAMD21
« Reply #19 on: November 17, 2020, 07:34:39 pm »
Good to know thank you, once I have the LTM module connected to send data I will do that.

Until then I'm using this to read data from SPI(can bus) and I2C (GPS).

It is my first time setting up the UART this way so I'm curious to how I would use the uart_puts(); in other ways then just hello world

For some outputs I want it to be able to print out a buffer that is filled.
I could only think of a quick arduino example which would look like this: print(buf, HEX) to print the content of buf.

Thankyou so much for the help again you are a lifesaver!
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12498
  • Country: us
    • Personal site
Re: problems with UART on SAMD21
« Reply #20 on: November 17, 2020, 07:44:16 pm »
uart_puts() can print a buffer that is formatted.

I have no idea what that arduino function is actually doing, but if it prints the buffer in hex, then it would look something like this (typed, not compiled, may have errors):
Code: [Select]
void print_buf(uint8_t *buf, int size)
{
  static char hex[] = "0123456789abcdef";
  for (int i = 0; i < size; i++)
  {
    uart_putc(hex[(buf[i] >> 4) & 0xf]);
    uart_putc(hex[buf[i] & 0xf]);
    uart_putc(' ');
  }
}
Alex
 
The following users thanked this post: DavedenHaan


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf

 

- - -
-->