Hi,
I want to build a bridge that receive byte on USART0( USB) and put this byte on USART1 (Serial sensor) and vice versa. This on my Arduino Mega 2560.
I think to write a sketch that use USART Interrupts on the received byte.
The interrupt occur when i receive a byte and forward this byte on the other USART:
USART0 --> USART1
USART1 --> USART0
I have a problem in the callbacks code; in particular in the code that forward the byte.
This is my sketch.
#include <avr/interrupt.h>
#include <avr/io.h>
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
#define RTS 4
#define CTS 5
#define CONFIG 3
#define RESET 2
//Define Bridge GPIO
#define PIN_BRIDGE_MODE 22
#define PIN_SAK_MODE 23
//Define USARTs
unsigned long baud = 192000;
unsigned long clockspeed = F_CPU; /* F_CPU is a predefined constant equal to the clock speed of the microcontroller.
for the Arduino duomilanove it is 16000000.*/
unsigned long baudPrescale; /* The baud prescale that will be loaded into the
UBRR0H and UBRR0L registers to set the USART baud rate */
//#define UBRR_VALUE 51 // --> UBBR = 51 => BAUD_RATE 19200
volatile byte ReceivedByteUSART0 = 0;
volatile byte ReceivedByteUSART1 = 0; //holds the incoming byte from the receive buffer.
void setup()
{
pinMode(13,OUTPUT);
cli(); //disable interrupts while initializing the USARTs
baudPrescale = (((clockspeed / (baud * 16UL))) - 1);
// Initialize USART0
//
UBRR0H = (uint8_t)(baudPrescale>>8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register
UBRR0L = (uint8_t)baudPrescale; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
/* set transfer complete flag (TXC0 = 1).
* clear Frame Error flag (FE0 = 0).
* clear Data overrun flag (DOR0 = 0).
* clear Parity overrun flag (UPE0 = 0).
* disable doubling of USART transmission speed (U2X0 = 0).
* Disable Multi-Processor Communication Mode-- whatever that is. (MCPM0 = 0) */
sbi(UCSR0A, TXC0);
cbi(UCSR0A, FE0);
cbi(UCSR0A, DOR0);
cbi(UCSR0A, UPE0);
cbi(UCSR0A, U2X0);
cbi(UCSR0A, MPCM0);
/* Enable Receive Interrupt (RXCIE0 = 1).
* Disable Tranmission Interrupt (TXCIE = 0).
* Disable Data Register Empty interrupt (UDRIE0 = 0).
* Enable reception (RXEN0 = 1).
* Enable transmission (TXEN0 = 1).
* Set 8-bit character mode (UCSZ00, UCSZ01, and UCSZ02 together control this,
* But UCSZ00, UCSZ01 are in Register UCSR0C). */
sbi(UCSR0B, RXCIE0);
cbi(UCSR0B, TXCIE0);
cbi(UCSR0B, UDRIE0);
sbi(UCSR0B, RXEN0);
sbi(UCSR0B, TXEN0);
cbi(UCSR0B, UCSZ02);
/* USART Mode select -- UMSEL00 = 0 and UMSEL01 = 0 for asynchronous mode.
* disable parity mode -- UPM00 = 0 and UPM01 = 0.
* Disabilitato: Set USBS = 1 to configure to 2 stop bits per DMX standard. The USART receiver ignores this
* setting anyway, and will only set a frame error flag if the first stop bit is 0.
* But, we have to set it to something.
* Finish configuring for 8 data bits by setting UCSZ00 and UCSZ01 to 1.
* Set clock parity to 0 for asynchronous mode (UCPOL0 = 0). */
cbi(UCSR0C, UMSEL00);
cbi(UCSR0C, UMSEL01);
cbi(UCSR0C, UPM00);
cbi(UCSR0C, UPM01);
cbi(UCSR0C, USBS0);
sbi(UCSR0C, UCSZ00);
sbi(UCSR0C, UCSZ01);
cbi(UCSR0C, UCPOL0);
// Initialize USART1
//
UBRR1H = (uint8_t)(baudPrescale>>8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register
UBRR1L = (uint8_t)baudPrescale; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
/* set transfer complete flag (TXC0 = 1).
* clear Frame Error flag (FE0 = 0).
* clear Data overrun flag (DOR0 = 0).
* clear Parity overrun flag (UPE0 = 0).
* disable doubling of USART transmission speed (U2X0 = 0).
* Disable Multi-Processor Communication Mode-- whatever that is. (MCPM0 = 0) */
sbi(UCSR1A, TXC0);
cbi(UCSR1A, FE0);
cbi(UCSR1A, DOR0);
cbi(UCSR1A, UPE0);
cbi(UCSR1A, U2X0);
cbi(UCSR1A, MPCM0);
/* Enable Receive Interrupt (RXCIE0 = 1).
* Disable Tranmission Interrupt (TXCIE = 0).
* Disable Data Register Empty interrupt (UDRIE0 = 0).
* Enable reception (RXEN0 = 1).
* Enable transmission (TXEN0 = 1).
* Set 8-bit character mode (UCSZ00, UCSZ01, and UCSZ02 together control this,
* But UCSZ00, UCSZ01 are in Register UCSR0C). */
sbi(UCSR1B, RXCIE0);
cbi(UCSR1B, TXCIE0);
cbi(UCSR1B, UDRIE0);
sbi(UCSR1B, RXEN0);
sbi(UCSR1B, TXEN0);
cbi(UCSR1B, UCSZ02);
/* USART Mode select -- UMSEL00 = 0 and UMSEL01 = 0 for asynchronous mode.
* disable parity mode -- UPM00 = 0 and UPM01 = 0.
* Set USBS = 1 to configure to 2 stop bits per DMX standard. The USART receiver ignores this
* setting anyway, and will only set a frame error flag if the first stop bit is 0.
* But, we have to set it to something.
* Finish configuring for 8 data bits by setting UCSZ00 and UCSZ01 to 1.
* Set clock parity to 0 for asynchronous mode (UCPOL0 = 0). */
cbi(UCSR1C, UMSEL00);
cbi(UCSR1C, UMSEL01);
cbi(UCSR1C, UPM00);
cbi(UCSR1C, UPM01);
cbi(UCSR1C, USBS0);
sbi(UCSR1C, UCSZ00);
sbi(UCSR1C, UCSZ01);
cbi(UCSR1C, UCPOL0);
//Enable Interrupts
sei(); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register .
// Configure GPIO
pinMode(RESET,OUTPUT);
pinMode(CONFIG,OUTPUT);
pinMode(RTS,OUTPUT);
pinMode(CTS,OUTPUT);
//Configure Bridge GPIO
pinMode(PIN_BRIDGE_MODE,INPUT);
pinMode(PIN_SAK_MODE,INPUT);
// Delay before enable Radiocraft Modem
delay(100);
digitalWrite(RESET,HIGH);
digitalWrite(CONFIG,HIGH);
}
void loop()
{
}
//Interrupt Callback USART0 RX
ISR(USART0_RX_vect)
{
//digitalWrite(13,HIGH);
ReceivedByteUSART0 = UDR0; //The receive buffer (UDR0) must be read during the reception ISR, or the ISR will just
// execute immediately upon exiting. */
}
//Interrupt Callback USART1 RX
ISR(USART1_RX_vect)
{
ReceivedByteUSART1 = UDR1;
}
In my sketch i configure the USARTs registers and i configure interrupt on the received byte.
Trough the led on pin13 I can test the callback functionality. In fact when i send a byte on USART0 the led blinks. This mean that the callback works.
My problem is: which code I have to write in each callback to put the received byte on the other USART?
For example: I receive a byte on USART0 and I want to put this byte on USART1.
ISR(USART0_RX_vect)
{
ReceivedByteUSART0 = UDR0; // Store the received byte in a volatile variable
???.... which code for put the byte on USART1 ... ????
}
I think that I have to use low level function into the callback.
For a test I insert Serial1.write() into the ISR(USART0_RX_vect) callback but the compiler give me an error.
Could anyone help me?
Thanks in advance!