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

Dependents:   TestVirtualisation Bf_SoftSerial_IR

Revision:
15:8d343be3382d
Parent:
14:dc766032cdd6
--- a/SoftSerial_rx_IR.cpp	Fri Dec 28 10:03:35 2018 +0000
+++ b/SoftSerial_rx_IR.cpp	Fri May 15 04:11:01 2020 +0000
@@ -1,44 +1,100 @@
-// 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"
 
-//extern DigitalOut  myled;    // Debug
+//------------------------------------------------------------------------------
+#if     defined(TARGET_NUCLEO_L152RE)
+#       define MAGIC_NUM        (-560)
+#elif   defined(TARGET_NUCLEO_F401RE)
+#       define MAGIC_NUM        (-205)
+#elif   defined(TARGET_NUCLEO_F411RE)
+#       define MAGIC_NUM        (-180)
+#elif   defined(TARGET_NUCLEO_F446RE)
+#       define MAGIC_NUM        (-115)
+#elif   defined(TARGET_NUCLEO_L432KC)
+#       define MAGIC_NUM        (-50)
+#elif   defined(TARGET_NUCLEO_L476RG)
+#       define MAGIC_NUM        (-50)
+#elif   defined(TARGET_K64F)
+#       define MAGIC_NUM        (0)
+#else
+#       warning "you need to tune MAGIC_NUM! in SoftSerial_rx_IR.cpp"
+#       define MAGIC_NUM        (0)
+#endif
+//------------------------------------------------------------------------------
 
-int SoftSerial_IR::_getc( void ) {
-    while(!readable());
+
+// please make a constructor in main.cpp if you use below pc & led
+#if DEBUG_TIMING == 2
+    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::_getc( void )
+{
+    while(!readable()) {
+        YIELD;
+    }
     out_valid = false;
     return out_buffer;
 }
 
-int SoftSerial_IR::readable(void) {
+int SoftSerial_IR::readable(void)
+{
     return out_valid;
 }
 
 //Start receiving byte
-void SoftSerial_IR::rx_gpio_irq_handler(void) {
-    //myled = !myled; // Debug
-    rxticker.prime(timestamp_offset);
-    rxticker.setNext(bit_period + (bit_period >> 1) - overhead_us_IR);
+void SoftSerial_IR::rx_gpio_irq_handler(void)
+{
+    TP_ON;
+    rxticker.prime(MAGIC_NUM);
     rx->fall(NULL);
     rx_bit = 0;
     rx_error = false;
-};    
+    // dummy setting for 1st timer interrupt
+    rx_1st = true;
+    rx_st_time = us_ticker_read();
+    rxticker.setNext(10);
+    TP_OFF;
+};
 
-void SoftSerial_IR::rx_handler(void) {
-    //myled = !myled; // Debug
+void SoftSerial_IR::rx_handler(void)
+{
+    TP_ON;
+    // dummy IRQ for 1st shot
+    if (rx_1st) {
+        rx_1st = false;
+        int next_preiod = us_ticker_read() - rx_st_time;
+        next_preiod = bit_period + (bit_period >> 1) - next_preiod;
+        if (next_preiod > 0) {
+            rxticker.setNext(next_preiod);
+        } else {
+            rxticker.setNext(5);
+        }
+        TP_OFF;
+        return;
+    }
     //Receive data
     int val = rx->read();
- 
+
     rxticker.setNext(bit_period);
     rx_bit++;
-    
-    
+
     if (rx_bit <= _bits) {
         read_buffer |= val << (rx_bit - 1);
+        TP_OFF;
         return;
     }
-    
+
     //Receive parity
     bool parity_count;
     if (rx_bit == _bits + 1) {
@@ -63,26 +119,31 @@
                 if ((!parity_count) && (_parity == Odd))
                     rx_error = true;
                 return;
+            case None:
+            default:
+                ;
         }
     }
-    
+
     //Receive stop
     if (rx_bit < _bits + (bool)_parity + _stop_bits) {
         if (!val)
             rx_error = true;
+        TP_OFF;
         return;
-    }    
-    
+    }
+
     //The last stop bit
     if (!val)
         rx_error = true;
-    
+
     if (!rx_error) {
         out_valid = true;
         out_buffer = read_buffer;
         fpointer[RxIrq].call();
     }
     read_buffer = 0;
-    rxticker.detach(); 
-    rx->fall(this, &SoftSerial_IR::rx_gpio_irq_handler);
+    rxticker.detach();
+    rx->fall(callback(this, &SoftSerial_IR::rx_gpio_irq_handler));
+    TP_OFF;
 }