Using both USART channels on AVR64DD28 - Page 1
Forum section: electronics / general

author: jezel123
author_rank: Contributor
timestamp: July 05, 2023, 09:13:37 am
content: This is my codeCode:#include "driverAVR64DD28.h"int main(void){initInternalHFClock(0,0);initUsart0Full(9600);initUsart1Full(9600);_delay_ms(100);transmitUsart0('S');_delay_ms(10);transmitUsart0('t');_delay_ms(10);transmitUsart0('a');_delay_ms(10);transmitUsart0('r');_delay_ms(10);transmitUsart0('t');uint16_t buffer = 0;while (1){while (!(USART1.STATUS & 0x80));buffer = receiveUsart1();transmitUsart0(buffer);}}Now those are the definitions for usart functions:Code:void initUsart0Full(uint64_t baudrate){usart0OutputPins(0x2);uint16_t baud = (double)FREQUENCY*1000000/baudrate*4;USART0.BAUDL = baud;USART0.BAUDH = baud>>8;USART0.CTRLC = 0b00001011;PORTA.DIRSET = 0b00000100;USART0.CTRLB |= 0b11000100;}void transmitUsart0(uint16_t data){USART0.TXDATAH = data>>8;USART0.TXDATAL = data;while (!(USART0.STATUS & 0b01000000));}uint16_t receiveUsart0(void){return (USART0.RXDATAH&1)<<8 | USART0.RXDATAL;}void initUsart1Full(uint64_t baudrate){usart1OutputPins(0x2);uint16_t baud = (double)FREQUENCY*1000000/baudrate*4;USART1.BAUDL = baud;USART1.BAUDH = baud>>8;USART1.CTRLC = 0b00001011;PORTD.DIRSET = 0b01000000;USART1.CTRLB |= 0b11000000;}void transmitUsart1(uint16_t data){USART1.TXDATAH = data>>8;USART1.TXDATAL = data;while (!(USART1.STATUS & 0b01000000));}uint16_t receiveUsart1(void){return (USART1.RXDATAH&1)<<8 | USART1.RXDATAL;}void usart0OutputPins(uint8_t val){CCP = 0xD8;PORTMUX.USARTROUTEA = val;}void usart1OutputPins(uint8_t val){uint8_t buffer = val << 3;CCP = 0xD8;PORTMUX.USARTROUTEA = buffer;}Now if I change the order of initializing USARTs (first 1 than 0) i get the desired output from USART0 but USART1 doesnt register input. if I do it like in the code i get no output on USART0 but it registers input on USART1. Can someone help me?

author: ArdWar
author_rank: Frequent Contributor
timestamp: July 05, 2023, 10:32:31 am
content: Quote from: jezel123 on July 05, 2023, 09:13:37 amYou're overwriting previous register setting. Use the usual|=assignment instead.Although the way you're taking the parameter here is very prone to unexpected values.

author: jezel123
author_rank: Contributor
timestamp: July 05, 2023, 10:38:27 am
content: THANK YOU! I knew i did something wrong. Would a switch case be a better way to process the parameter?

author: cv007
author_rank: Frequent Contributor
timestamp: July 05, 2023, 10:22:26 pm
content: With multiple uarts (and possibly more than 2 if you move to another similar avr with more pins), it is nice to get something in place that can handle all the uarts and all the possible pins. It then becomes code which is created one time only and allows for easier changing of uarts/pins. These newer avr's are ideal for doing this since the peripherals are an 'instance' type (register layout is the same for each instance of a peripheral).Something such as-https://godbolt.org/z/f5axdPjWjThere are various ways to go about doing this, and this version is one way to do it. The use of print/scan is optional and can be bypassed (I rarely use scanf, so just added it to show it can also be done similar to the print function). The use of print (printf) will simplify uart output in a big way, and for the avr it costs about 1.5k of code but is a one time cost (once used, use everywhere you can). If you end up going to buffer use (interrupts), its not much more work to get the code to deal with a buffer instead of directly accessing the rx/txdata registers (isr code will deal with the buffer).Using C++ is a little nicer for various reasons, but if not your thing you just live without it-https://godbolt.org/z/89Pjfvzcvfyi- portmux is not CCP protected.edit- the scanf code is wrong as it is using non-blocking uart reads (with -1 meaning no data available), but scanf has no provision for non-blocking reads so would need to provide a FILE.get function that blocks on rx data available.