Software UART program using Infra-Red LED and IR-Detector
Dependents: TestVirtualisation Bf_SoftSerial_IR
Diff: SoftSerial_tx_IR.cpp
- Revision:
- 15:8d343be3382d
- Parent:
- 14:dc766032cdd6
diff -r dc766032cdd6 -r 8d343be3382d SoftSerial_tx_IR.cpp --- a/SoftSerial_tx_IR.cpp Fri Dec 28 10:03:35 2018 +0000 +++ b/SoftSerial_tx_IR.cpp Fri May 15 04:11:01 2020 +0000 @@ -1,91 +1,124 @@ -// Apply for Infrared LED and IR-Detector -// Modified by JH1PJL Dec. 28th, 2018 +// Modified by K.Arai / JH1PJL May 15th, 2020 #include "SoftSerial_IR.h" +// please make a constructor in main.cpp if you use below pc & led +#if DEBUG_TIMING == 1 + extern Serial pc; + extern DigitalOut test_point; +# define TP_ON {test_point = 1;} +# define TP_OFF {test_point = 0;} +# define DBG_PRINTF(...) pc.printf(__VA_ARGS__) +#else +# define TP_ON {;} +# define TP_OFF {;} +# define DBG_PRINTF(...) {;} +#endif + int SoftSerial_IR::_putc(int c) { - while(!writeable()); + while(!writeable()) { + YIELD; + } prepare_tx(c); tx_bit = 0; - txticker.prime(timestamp_offset); + //tx->write(1); + tx->write(0.0f); // output 1 + txticker.prime(); tx_handler(); return 0; } void SoftSerial_IR::send_break(void) { - while(!writeable()); + while(!writeable()) { + YIELD; + } //Just to make sure it appears as non-writable to other threads/IRQs - tx_bit = 0; + tx_bit = 0; + //tx->write(0); tx->write(0.5f); // output 0 wait_us((bit_period * _total_bits * 3) / 2); + //tx->write(1); tx->write(0.0f); // output 1 tx_bit = -1; } int SoftSerial_IR::writeable(void) { - if (!tx_en) + if (!tx_en) { return false; - if (tx_bit == -1) + } + if (tx_bit == -1) { return true; + } return false; } void SoftSerial_IR::tx_handler(void) { + TP_ON; if (tx_bit == _total_bits) { tx_bit = -1; + //tx->write(1); + tx->write(0.0f); // output 1 fpointer[TxIrq].call(); + TP_OFF; return; } - - //Flip output - float tx_out = tx->read(); - int cur_out = 0; - if (tx_out == 0.5f){ // current duty 50% - cur_out = 0; // current = 0 - tx->write(0.0f); // output port 0 to 1 + if (tx_bit == 0){ + //tx->write(1); + tx->write(0.0f); // output 1 + txticker.setNext(10); } else { - cur_out = 1; // current = 1 - tx->write(0.5f); // output port 1 to 0 + int bitchk = _char >> tx_bit; + if (bitchk & 1) { + //tx->write(1); + tx->write(0.0f); // output 1 + } else { + //tx->write(0); + tx->write(0.5f); // output 0 + } + txticker.setNext(bit_period); } - - //Calculate when to do it again - int count = bit_period; tx_bit++; - while(((_char >> tx_bit) & 0x01) == !cur_out) { - count+=bit_period; - tx_bit++; - } - - txticker.setNext(count); + TP_OFF; } void SoftSerial_IR::prepare_tx(int c) { - _char = c << 1; + _char = c << 2; // set start bit as bit1 and dummy as bit0 bool parity; switch (_parity) { case Forced1: _char |= 1 << (_bits + 1); + break; case Even: parity = false; for (int i = 0; i<_bits; i++) { - if (((_char >> i) & 0x01) == 1) + if (((_char >> i) & 0x01) == 1) { parity = !parity; + } } _char |= parity << (_bits + 1); + break; case Odd: parity = true; for (int i = 0; i<_bits; i++) { - if (((_char >> i) & 0x01) == 1) + if (((_char >> i) & 0x01) == 1) { parity = !parity; + } } _char |= parity << (_bits + 1); + break; + case Forced0: + case None: + default: + ; } - - _char |= 0xFFFF << (1 + _bits + (bool)_parity); - _char &= ~(1<<_total_bits); + // added one dummy at LSB bit + int num = 1 + _bits + (bool)_parity + 1; + _char |= 0xffffffff << num; + _char |= 1UL; + _char &= ~(1 << _total_bits); }