Sigh. The DIP boards have the RX and TX pins swapped at the ATmega side. A crossover works ("Hello World!" !!), and it's less relevant if you're not using particular USB/Serial module I'm using, but it's annoying. I could swear I had checked that carefully :-(
void uart_init() {
VPORTA.DIR |= 1<<4; // set TX pin to output
VPORTA.OUT |= 1<<4; // and "1" as per datasheet
PORTMUX.USARTROUTEA = 1; // alternate pinout to use PA4/5
USART0.BAUD = (64ULL * F_CPU)/(16UL*BAUDRATE);
USART0.DBGCTRL = 1; // run during debug
USART0.CTRLC = (USART_CHSIZE_gm & USART_CHSIZE_8BIT_gc); // Async, Parity Disabled, 1 StopBit
USART0.CTRLA = 0; // Interrupts: all off
USART0.CTRLB = USART_RXEN_bm | USART_TXEN_bm;
}
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.
Made exactly the same mistake on my BOB PID board. Welcome to to club. rx and tx are stupid symbols. It should be ho and hi (host out and host in) or ho and pi (host out, peripheral in). Or anything that doesn't depend on point of view.
Are you sure? yes | no
Oh, I've done it before as well (on the Z80 board, IIRC.) The annoying thing is that this time I was sure that I had CHECKED!
Are you sure? yes | no
Yes, the 4809 is set up more like an XMega chip; the peripherals are different, and prefer the structure-based definitions rather than individual #defines for each register. There are a couple of advantages to the structure-based approach:
1) If you have multiple identical peripherals, you can treat them as such. All the code above that references USART0 could equally reference USART1. Or an abstracted USART via a pointer (myuart->BAUD = ...) (this also gets rid of the rather silly (IMO) redundant defines: UCSR0A and UCSR1A or even PORTB1 and PORTD1...)
2) Since the peripherals are mostly in RAM space, code that accesses multiple registers in a peripheral will end up loading a base address into an index register and using smaller indexed-addressing instructions to get to the individual registers (compared to the LDS instructions it would need to access each register individually. gcc isn't smart enough to optimize loads from 0x804, 0x805, and 0x806 into a load of 0x800 and indexed addressing instructions. This will USUALLY result in shorter faster code.)
(The VPorts are still in IO space, so they can still be accessed with SBI/CBI for setting individual bits.)
Note that there is no disadvantage here. The compiler IS smart enough to optimize a single access to a structure reference to the appropriate LDS/STS instruction.)
3) This is the way "the big boys" have done peripheral access for ages. ARM, PIC32, X86, PPC, 68k, PDP11... It's a natural for anything with memory-mapped peripherals and indexed addressing...
Are you sure? yes | no
That is different than the mega's I have looked at, I guess those defines are more or less how xmega was done. So this may be relevant:
http://ww1.microchip.com/downloads/en/AppNotes/doc8075.pdf
I am confused with the virtual port stuff (e.g., "VPORTA.OUT" vs. "PORTA_OUT"). Does it have an advantage over the flattened fully qualified defines? I don't see PORTA_OUT4_bp in the iom4809 header; it would seem that some of the ideas got dropped.
Are you sure? yes | no