can't get uart comm going on nano curiosity (w/ mega4809)

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

I'm trying to get things going on a Microchip nano curiosity board w/ atmega4809 chip.

 

Code is posted below (where compile line includes -DBAUDRATE=9600). 

I first run a little "wait for user to press button" function, and later add a watchdog so if something goes amiss I can get the board back. 

The UART code sets up for 8 bits no parity, 2 stop bits.  I "putchar" by polling for "data register ready" then send.  

On the (Linux) host side I'm using "minicom -b 9600 -D /dev/ttyACM0".
To run the program I do

1) $ cp main.hex /media/mattrw/CURIOSITY

2) $ minicom -b 9600 -D /dev/ttyACM0

3) push button on board

I get to the LED blinking loop in main, but I don't see any characters in the minicom window.  Why?

 

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <util/delay.h>

/* wait for button press-release */
void button_wait() {
  uint8_t st = 1, lt;

  TCB0.CCMP = 333;			/* 0.1 ms period */
  TCB0.CTRLA = 0x01;			/* use CLK_PER, ENABLE */
  PORTF.DIRSET = PIN5_bm;		/* LED output */
  
  while (st) {
    if (lt++ == 0) PORTF.OUTTGL = PIN5_bm;
    switch (st) {
    case 1: if ((PORTF.IN & PIN6_bm) == 0) st = 2; break;
    case 2: if ((PORTF.IN & PIN6_bm) != 0) st = 0; break;
    }
    while ((TCB0.INTFLAGS & 0x01) == 0); /* wait ~0.1 ms */
    TCB0.INTFLAGS = 0x01;
  }

  PORTF.DIRCLR = PIN5_bm;
  TCB0.CTRLA = 0x00;			/* DISABLE */
  TCB0.CCMP = 0;
}


#define BAUD_FROM_RATE(RATE) ((4UL * (F_CPU))/(RATE))

void uart_on(void) {
  USART0.BAUD = BAUD_FROM_RATE(BAUDRATE);
  USART0.CTRLC = USART_SBMODE_2BIT_gc | USART_CHSIZE_8BIT_gc;
  USART0.CTRLB = USART_TXEN_bm;		/* enable TX */
}

void uart_off(void) {
  USART0.CTRLB &= ~USART_TXEN_bm;
}

void uart_putchar(char c) {
  loop_until_bit_is_set(USART0.STATUS, USART_DREIF_bp);
  USART0.TXDATAL = c;
}

char uart_getchar(void) {
  loop_until_bit_is_set(USART0.STATUS, USART_RXCIF_bp);
  return USART0.RXDATAL;
}


int main(void) {
  uint8_t i, n;

  /* Wait for user button-click. */
  button_wait();

  /* Set up watchdog timer */
  CCP = CCP_IOREG_gc;
  WDT.CTRLA = WDT_PERIOD_8KCLK_gc;

  PORTF.DIRSET = PIN5_bm;

  uart_on();
  uart_putchar('h');
  uart_putchar('i');
  uart_putchar('\r');
  uart_putchar('\n');
  
  while (1) {
    PORTF.OUTCLR = PIN5_bm;
    _delay_ms(200);
    PORTF.OUTSET = PIN5_bm;
    _delay_ms(800);

    wdt_reset();
  }
}

 

This topic has a solution.
Last Edited: Tue. Nov 26, 2019 - 02:43 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't trust the USB/serial translation on this board. In my hands it doesn't work reliably on Windows, maybe it isn't reliable on Linux either?

 

I would check the Tx pin directly with a scope or logic analyzer to make sure if the data is being transmitted or not.

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

Thanks.   Scope is not convenient now, but will try later.  

 

I did notice that the Curiosity documentation shows the CDC USB hooked up to PB0/PB1 and the 4809 48-pin datasheet says that is USART3.  I changed USART0 to USART3 but it didn't help.

 

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

You have to take care of the tx pin direction, and set portmux if needed. (usart3 is on default pins, and is used for cdc).

 

The virtual com port on these inexpensive debuggers is not really worth the trouble. Will work, but will also disappear each time you program.

 

I have a snap, and its virtual com port has the same problem, so it seems to be something they are not willing to do- keep the virtual com port going while programming.

 

To use the uart, just hook up something reliable- any usb-uart adapter you have. I have an Omega2 board that I use to see the uart output from the mega- ssh into Omega2 and I'm at a terminal connected to the mega. It stays up for weeks without a problem. Any ordinary usb-uart would do the same.

Last Edited: Mon. Nov 25, 2019 - 11:07 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don't be put off - the Curiosity CDC works just fine when programming (perhaps better on Windows than Linux?)

I took your code into Studio and tweaked it until it worked, repeatedly programming the board, and not once did i have to remove and reinsert it.  

A few gotchas like the default clock and pin pull-up and output enable.

#define F_CPU 20000000
#include <avr/io.h>
#include <util/delay.h>

#define BAUDRATE 9600
#define BAUD_FROM_RATE(RATE) ((4UL * (F_CPU))/(RATE))

void uart_init(void)
{
	USART3.BAUD = BAUD_FROM_RATE(BAUDRATE);
	USART3.CTRLC = USART_SBMODE_2BIT_gc | USART_CHSIZE_8BIT_gc;
}

void uart_on(void)
{
	// Enable TX
	USART3.CTRLB = USART_TXEN_bm;
	// TX pin to output
	PORTB.DIRSET = (1 << 0);
}

void uart_off(void)
{
	// Disable TX
	USART3.CTRLB &= ~USART_TXEN_bm;
}

void uart_putchar(char c)
{
	// Wait for space
	while (!(USART3.STATUS & USART_DREIF_bm))
		;
	USART3.TXDATAL = c;
}

int main(void)
{
	// TX pin pullup enable
	PORTB.PIN0CTRL = PORT_PULLUPEN_bm;

	// Button pullup
	PORTF.PIN6CTRL = PORT_PULLUPEN_bm;

	// Setup 20MHz clock
	_PROTECTED_WRITE((CLKCTRL.MCLKCTRLB), (0 << CLKCTRL_PEN_bp));

	// UART init
	uart_init();

	while (1) {
		// Wait for button
		while (PORTF.IN & (1 << 6))
			;

		uart_on();
		uart_putchar('h');
		uart_putchar('i');
		uart_putchar('\r');
		uart_putchar('\n');
		uart_off();
		_delay_ms(100);
	}
}

 

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

A couple more tips:

- be sure to keep your Nano's debugger firmware up to date - there have been some CDC issues which were fixed...

- use the PDF links on the kit window that pops up in Studio/MPLAB (or just update your copy).  The Curiosity Nano schematics include some info on the front page (like which USART the CDC is connected to) which previously required some digging.

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

mraardvark wrote:

Don't be put off - the Curiosity CDC works just fine when programming (perhaps better on Windows than Linux?)

I took your code into Studio and tweaked it until it worked, repeatedly programming the board, and not once did i have to remove and reinsert it.  

A few gotchas like the default clock and pin pull-up and output enable.

#define F_CPU 20000000

 

Thanks.  Your posted code is working for me.  I did not enable the TX pullup I guess.  (According to documentation the switch has an external pullup btw.)

 

Also, I don't use Studio or MPLABx ordinarily.  I have MPLABx installed -- I will see if that can update the firmware.   I have

$ cat /media/mattrw/CURIOSITY/KIT-INFO.TXT 
Firmware:       01.02.0106
Kit:            ATmega4809 Curiosity Nano                                   
Serial:         ATML3094051800001774
Device:         ATmega4809                      
$