SoftwareSerial 8-o-1 problem

Hello, I need to use 8O1 using SoftwareSerial. I did like you wrote:

pylon:
Here's the code for the 8o1 variant.

//

// The receive routine called by the interrupt handler
//
void SoftwareSerial::recv()
{

#if GCC_VERSION < 40302
// Work-around for avr-gcc 4.3.0 OSX version bug
// Preserve the registers that the compiler misses
// (courtesy of Arduino forum user etracer)
 asm volatile(
   "push r18 \n\t"
   "push r19 \n\t"
   "push r20 \n\t"
   "push r21 \n\t"
   "push r22 \n\t"
   "push r23 \n\t"
   "push r26 \n\t"
   "push r27 \n\t"
   ::);
#endif

uint8_t d = 0;

// If RX line is high, then we don't see any start bit
 // so interrupt is probably not for us
 if (_inverse_logic ? rx_pin_read() : !rx_pin_read())
 {
   // Wait approximately 1/2 of a bit width to "center" the sample
   tunedDelay(_rx_delay_centering);
   DebugPulse(_DEBUG_PIN2, 1);

// Read each of the 8 bits
   for (uint8_t i=0x1; i; i <<= 1)
   {
     tunedDelay(_rx_delay_intrabit);
     DebugPulse(_DEBUG_PIN2, 1);
     uint8_t noti = ~i;
     if (rx_pin_read())
       d |= i;
     else // else clause added to ensure function timing is ~balanced
       d &= noti;
   }
   // skip the parity bit
   tunedDelay(_rx_delay_stopbit);
   DebugPulse(_DEBUG_PIN2, 1);

// skip the 2 stop bits
   tunedDelay(_rx_delay_stopbit);
   DebugPulse(_DEBUG_PIN2, 1);

if (_inverse_logic)
     d = ~d;

// if buffer full, set the overflow flag and return
   if ((_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF != _receive_buffer_head)
   {
     // save new data in buffer: tail points to where byte goes
     _receive_buffer[_receive_buffer_tail] = d; // save new byte
     _receive_buffer_tail = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
   }
   else
   {
#if _DEBUG // for scope: pulse pin as overflow indictator
     DebugPulse(_DEBUG_PIN1, 1);
#endif
     _buffer_overflow = true;
   }
 }

#if GCC_VERSION < 40302
// Work-around for avr-gcc 4.3.0 OSX version bug
// Restore the registers that the compiler misses
 asm volatile(
   "pop r27 \n\t"
   "pop r26 \n\t"
   "pop r23 \n\t"
   "pop r22 \n\t"
   "pop r21 \n\t"
   "pop r20 \n\t"
   "pop r19 \n\t"
   "pop r18 \n\t"
   ::);
#endif
}




and the write part:



size_t SoftwareSerial::write(uint8_t b)
{
 if (_tx_delay == 0) {
   setWriteError();
   return 0;
 }

uint8_t oldSREG = SREG;
 cli();  // turn off interrupts for a clean txmit

// Write the start bit
 tx_pin_write(_inverse_logic ? HIGH : LOW);
 tunedDelay(_tx_delay + XMIT_START_ADJUSTMENT);
 uint8_t p = 0;
 uint8_t t;
 for (t = 0x80; t; t >>= 1)
   if (b & t) p++;

// Write each of the 8 bits
 if (_inverse_logic)
 {
   for (byte mask = 0x01; mask; mask <<= 1)
   {
     if (b & mask) // choose bit
       tx_pin_write(LOW); // send 1
     else
       tx_pin_write(HIGH); // send 0
   
     tunedDelay(_tx_delay);
   }
   // parity
   if (p & 0x01)
     tx_pin_write(LOW); // send 1
   else
     tx_pin_write(HIGH); // send 0
   tunedDelay(_tx_delay);

tx_pin_write(LOW); // restore pin to natural state
 }
 else
 {
   for (byte mask = 0x01; mask; mask <<= 1)
   {
     if (b & mask) // choose bit
       tx_pin_write(HIGH); // send 1
     else
       tx_pin_write(LOW); // send 0
   
     tunedDelay(_tx_delay);
   }
   // parity
   if (p & 0x01)
     tx_pin_write(HIGH); // send 1
   else
     tx_pin_write(LOW); // send 0
   tunedDelay(_tx_delay);

tx_pin_write(HIGH); // restore pin to natural state
 }

SREG = oldSREG; // turn interrupts back on
 tunedDelay(_tx_delay);
 
 return 1;
}




The compiler errors you get indicate that you're working with MacOS X as the compilation machine. Correct?

I got the compilation error away on my machine by changing the following code too:



inline void SoftwareSerial8o1::tunedDelay(volatile uint16_t delay) {
 volatile uint8_t tmp=0;
 asm volatile("sbiw    %0, 0x01 \n\t"
   "ldi %1, 0xFF \n\t"
   "cpi %A0, 0xFF \n\t"
   "cpc %B0, %1 \n\t"
   "brne .-10 \n\t"
   : "+r" (delay), "+a" (tmp)
   : "0" (delay)
   );
   
}




Note the inserted volatile statements to keep the compiler from optimizing the variables away.

But unfortunately I can't compile my project:

Arduino: 1.6.5 (Windows 7), Board: "Arduino Leonardo"

Build options changed, rebuilding all

Using library SoftwareSerial in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial 



C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=10605 -DARDUINO_AVR_LEONARDO -DARDUINO_ARCH_AVR -DUSB_VID=0x2341 -DUSB_PID=0x8036 -DUSB_MANUFACTURER="Unknown" -DUSB_PRODUCT="Arduino Leonardo" -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\leonardo -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial C:\Users\MateuszS\AppData\Local\Temp\build7824102489584515010.tmp\soft8e1.cpp -o C:\Users\MateuszS\AppData\Local\Temp\build7824102489584515010.tmp\soft8e1.cpp.o 

C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=10605 -DARDUINO_AVR_LEONARDO -DARDUINO_ARCH_AVR -DUSB_VID=0x2341 -DUSB_PID=0x8036 -DUSB_MANUFACTURER="Unknown" -DUSB_PRODUCT="Arduino Leonardo" -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\leonardo -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial\utility C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial\SoftwareSerial.cpp -o C:\Users\MateuszS\AppData\Local\Temp\build7824102489584515010.tmp\SoftwareSerial\SoftwareSerial.cpp.o 

C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial\SoftwareSerial.cpp: In member function 'virtual size_t SoftwareSerial::write(uint8_t)':
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial\SoftwareSerial.cpp:431:26: error: 'XMIT_START_ADJUSTMENT' was not declared in this scope
   tunedDelay(_tx_delay + XMIT_START_ADJUSTMENT);
                          ^
Error compiling.

I erased XMIT_START_ADJUSTMENT,but afterwards I have a lot of errors in compilation:

Enclosed please find my SoftwareSerial.cpp and .h. What should I write more to this file?

SoftwareSerial.cpp (13.5 KB)

SoftwareSerial.h (3.95 KB)