I'm working with ATxmega16D4 and I'm configuring the USART (actually UART) interface on port C.
The purpose is to transmit/receive the data on RS232 interface (currently using a converter to USB port of my PC).
- The USARTC0 is setup up as Asynchronous, interrupt-driven.
- The datarate is set to 115200 baud (but the problem exists also on 9600), double speed
- 8 bit, no parity, 1 stop bit
I can receive the data from PC to the micro, but I cannot send it.
The code is partly taken from Atmel USART driver:
void uart_init() { // setting TX/RX ports directions PORTC_set_pin_dir(2, PORT_DIR_IN); PORTC_set_pin_output_pull_mode(2, PORT_CONFIGURATION_TOTEM); PORTC_set_pin_dir(3, PORT_DIR_OUT); PORTC_set_pin_level(3, false); int8_t exp; uint32_t div; uint32_t limit; uint32_t ratio; uint32_t min_rate; uint32_t max_rate; uint32_t cpu_hz = F_CPU; uint32_t baud = UART_BAUDRATE; <--- CODE REMOVED FOR CLEANUP, it sets "div" and "exp" --> USARTC0.BAUDCTRLB = (uint8_t)(((div >> 8) & 0X0F) | (exp << 4)); USARTC0.BAUDCTRLA = (uint8_t)div; // Low Level interrupts USARTC0.CTRLA = USART_RXCINTLVL_LO_gc | USART_TXCINTLVL_LO_gc | USART_DREINTLVL_LO_gc; PMIC.CTRL |= PMIC_LOLVLEN_bm; USARTC0.CTRLC = USART_PMODE_DISABLED_gc // No Parity | 0 << USART_SBMODE_bp // Stop Bit Mode: disabled | USART_CHSIZE_8BIT_gc // Character size: 8 bit | 0 << USART_CHSIZE2_bp // SPI Master Mode, Data Order: disabled | 1 << USART_CHSIZE1_bp // SPI Master Mode, Clock Phase: enabled | USART_CMODE_ASYNCHRONOUS_gc; // Asynchronous Mode USARTC0.CTRLB = 1 << USART_CLK2X_bp // Double transmission speed: enabled | 0 << USART_MPCM_bp // Multi-processor Communication Mode: disabled | 1 << USART_RXEN_bp // Receiver Enable: enabled | 1 << USART_TXEN_bp; // Transmitter Enable: enabled }
The main:
ISR(USARTC0_RXC_vect) { // This works! I can read the received data uint8_t received = USARTC0.DATA; } ISR(USARTC0_TXC_vect) { // This not! The interrupt is never called } ISR(USARTC0_DRE_vect) { // This works as expected } int main(void) { <--- initializes system.... ---> uart_init(); // ...and the uart ENABLE_INTERRUPTS(); uint8_t send = 0; while (1) { _delay_ms(100); // wait for sending... while (!(USARTC0.STATUS & USART_DREIF_bm)); USARTC0.DATA = (send++); } }
The main just loops sending to my PC the byte, increased.
If I send 1 char from my PC, I correctly receive it in the ISR so I believe everything is ok at my host application.
Instead, setting "USARTC0.DATA = (send++);" does not seem to send anything. In depth, if I debug it using the I/O tool on Atmel Studio, the value of DATA does not change right after that line (or maybe is it expected and the data is immediately moved to the TX register?).
Can you help me understanding? Thanks