Would you like to react to this message? Create an account in a few clicks or log in to continue.

You are not connected. Please login or register

USART_UDRE_vect seem to work differently in R941 compared to 0.4.15

2 posters

Go down  Message [Page 1 of 1]

TimFisch

TimFisch

Honestly, I'm not absolutely sure whether the following is a bug, since I have not real hardware to my hand. But it kind of smells like one...

The interrupt vector USART_UDRE_vect of the mega328 seems to work differently in 1.0.0 (up to R941) compared to in SimulIDE 0.4.15 SR9. This vector should be jumped to, once UDR0 is empty and this vector is usually used to send data handled by interrupt.

In SimulIDE 0.4.15 SR9 the interrupt is activated once UDRIE0 is set and UDR0 is empty. This is also initially true.

For SimulIDE 1.0.0 it seems that the register has actively to be set to UDR0 = 0 before setting UDRIE0. Otherwise the interrupt will not get active.

Situation:
  1. insert mega328 (set frequency to 8 MHz)
  2. flash hex (attached)
  3. open serial monitor
  4. run


"Expected" result:
  • in prevoius versions: text "test_one " is output continuously on serial monitor
  • sending letter "r" via serial monitor changes to text "test_two " as continuous output


Shown result:
  • no text output, no output on pins
  • receiving seems to work since byte 0x0118 toggles for send text "r" on serial monitor
  • Writing 0 to UDR0 ahead of the while loop kind of solves the problem. However, this leads to sending an empty message (0x00) in the beginning, which has to be handled on the receiver side.
    This work around can also be seen in the code below, marked in the comments.


EDIT:
Another difference is, that in 1.0.0 the last space of the string str_1/str_2 gets sent twice. Simulide 0.4.15 SR9 sends it (correctly) only once.

Code:
#define F_CPU 8000000L

#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>

#define UART_BUFFER_SIZE 10
#define BAUD_RATE 9600L
#define UBRR_VAL  ((F_CPU+BAUD_RATE*8)/(BAUD_RATE*16)-1)

char uart_tx_buffer[UART_BUFFER_SIZE];      
char str_1[] = "test_one ";
char str_2[] = "test_two ";
uint8_t str_flg = 0;
volatile uint8_t data_tx_finished_flg = 1;      

int main ()
{ // set Baud rate
 UBRR0H = UBRR_VAL >> 8;
 UBRR0L = UBRR_VAL & 0xFF;
 
 // activate send & transmit of 8 bit msgs
 UCSR0B = (1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0);
 UCSR0C = (1<<UCSZ00)| (1<<UCSZ01);
 
// UDR0 = 0; // =============>>  this solves the problem in v1.0.0 <<================

 // start interrupts
 sei();
 while(1)
 { // only in case of finished transfer
 if (data_tx_finished_flg==1 )
 { // reset flag, choose text and activate sending
 data_tx_finished_flg = 0;
 if (str_flg ==0) strcpy(uart_tx_buffer, str_1);
 else strcpy(uart_tx_buffer, str_2);
 UCSR0B |= (1<<UDRIE0);
 }
 }
}

// once RX complete
ISR(USART_RX_vect)
{ // read data register and toogle str flag
 char data = UDR0;
 if (data=='r') str_flg = 1 - str_flg;
}

// once data register is empty
ISR(USART_UDRE_vect)
{ // set pointer to buffer and act_char to next character
 static char* uart_tx_p = uart_tx_buffer;
 char          act_char = *uart_tx_p++;
 
 // if character is 0
 if (act_char==0 )
 { // deactivate sending, reset pointer and set finished flag
 UCSR0B &= ~(1<<UDRIE0);
 uart_tx_p = uart_tx_buffer;
 data_tx_finished_flg = 1;
 } // else set data register
 else UDR0 = act_char;
}
Attachments
USART_UDRE_vect seem to work differently in R941 compared to 0.4.15 AttachmentUART_interrupt.zip
You don't have permission to download attachments.
(1 Kb) Downloaded 1 times



Last edited by arcachofo on Tue Feb 15, 2022 12:33 am; edited 2 times in total (Reason for editing : Mark as solved (green color).)

https://wiki.mexle.hs-heilbronn.de/

arcachofo

arcachofo

The interrupt vector USART_UDRE_vect of the mega328 seems to work differently in 1.0.0 (up to R941) compared to in SimulIDE 0.4.15 SR9. This vector should be jumped to, once UDR0 is empty and this vector is usually used to send data handled by interrupt.
You are right.
If no transmission was initiated, the interrupt will not trigger, but it should whenever interrupt is enabled and buffer empty.
Solved at Rev 951.

Another difference is, that in 1.0.0 the last space of the string str_1/str_2 gets sent twice.
Not yet solved, I'm debugging it.

arcachofo

arcachofo

Another difference is, that in 1.0.0 the last space of the string str_1/str_2 gets sent twice.
Solved at Rev 952.

Sponsored content



Back to top  Message [Page 1 of 1]

Permissions in this forum:
You cannot reply to topics in this forum