Software UART program using Infra-Red LED and IR-Detector

Dependents:   TestVirtualisation Bf_SoftSerial_IR

Revision:
15:8d343be3382d
Parent:
14:dc766032cdd6
--- 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);
 }