Intro:
I have an Arduino mega doing multiple tasks , from which A function Reads data from a sensor using SPI . Every like 10,000 read or something , i get 1 error bit in the SPI data . and I have narrowed down the problem to the Interrupt generated by the Serial Receive library.
So : I want to disable the RX1 interrupt while i deal with the SPI sensor ( about 10us) , then re-enable the RX1 back to normal .
Questions:
1- Shall i use Serial1.end() then Serial1.begin() (source code shown below from arduino GitHub), my assumption is that these functions take too long to perform ( in millis seconds ). and the data in the already received and prepared to be sent in the Hardware buffer gets lost !
void HardwareSerial::begin(unsigned long baud, byte config)
{
// Try u2x mode first
uint16_t baud_setting = (F_CPU / 4 / baud - 1) / 2;
*_ucsra = 1 << U2X0;
// hardcoded exception for 57600 for compatibility with the bootloader
// shipped with the Duemilanove and previous boards and the firmware
// on the 8U2 on the Uno and Mega 2560. Also, The baud_setting cannot
// be > 4095, so switch back to non-u2x mode if the baud rate is too
// low.
if (((F_CPU == 16000000UL) && (baud == 57600)) || (baud_setting >4095))
{
*_ucsra = 0;
baud_setting = (F_CPU / 8 / baud - 1) / 2;
}
// assign the baud_setting, a.k.a. ubrr (USART Baud Rate Register)
*_ubrrh = baud_setting >> 8;
*_ubrrl = baud_setting;
_written = false;
//set the data bits, parity, and stop bits
#if defined(__AVR_ATmega8__)
config |= 0x80; // select UCSRC register (shared with UBRRH)
#endif
*_ucsrc = config;
sbi(*_ucsrb, RXEN0);
sbi(*_ucsrb, TXEN0);
sbi(*_ucsrb, RXCIE0);
cbi(*_ucsrb, UDRIE0);
}
void HardwareSerial::end()
{
// wait for transmission of outgoing data
flush();
cbi(*_ucsrb, RXEN0);
cbi(*_ucsrb, TXEN0);
cbi(*_ucsrb, RXCIE0);
cbi(*_ucsrb, UDRIE0);
// clear any received data
_rx_buffer_head = _rx_buffer_tail;
}
2- Or shall i disable serial1 interrupts manually (as shown below) , then re-enabling them . is this safe from a microcontroller standpoint ?? what happens to data in hardware and software buffer ?
//disable Interrupts
cbi(*_ucsrb, RXEN1);
cbi(*_ucsrb, TXEN1);
cbi(*_ucsrb, RXCIE1);
cbi(*_ucsrb, UDRIE1);
//Do the SPI routine //
//enable interrupts
sbi(*_ucsrb, RXEN1);
sbi(*_ucsrb, TXEN1);
sbi(*_ucsrb, RXCIE1);
cbi(*_ucsrb, UDRIE1);
Option 3:
Disable global Interrupts CLI()
do SPI routine
Enable global intruupts SEI()