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

Dependents:   TestVirtualisation Bf_SoftSerial_IR

Committer:
kenjiArai
Date:
Fri May 15 04:11:01 2020 +0000
Revision:
15:8d343be3382d
Parent:
14:dc766032cdd6
Updated several functions based on SoftSerial library.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 15:8d343be3382d 1 // Modified by K.Arai / JH1PJL May 15th, 2020
kenjiArai 13:2b5649a1278a 2
kenjiArai 12:79d63607bbb1 3 #include "SoftSerial_IR.h"
Sissors 0:8edaa7abe724 4
kenjiArai 15:8d343be3382d 5 //------------------------------------------------------------------------------
kenjiArai 15:8d343be3382d 6 #if defined(TARGET_NUCLEO_L152RE)
kenjiArai 15:8d343be3382d 7 # define MAGIC_NUM (-560)
kenjiArai 15:8d343be3382d 8 #elif defined(TARGET_NUCLEO_F401RE)
kenjiArai 15:8d343be3382d 9 # define MAGIC_NUM (-205)
kenjiArai 15:8d343be3382d 10 #elif defined(TARGET_NUCLEO_F411RE)
kenjiArai 15:8d343be3382d 11 # define MAGIC_NUM (-180)
kenjiArai 15:8d343be3382d 12 #elif defined(TARGET_NUCLEO_F446RE)
kenjiArai 15:8d343be3382d 13 # define MAGIC_NUM (-115)
kenjiArai 15:8d343be3382d 14 #elif defined(TARGET_NUCLEO_L432KC)
kenjiArai 15:8d343be3382d 15 # define MAGIC_NUM (-50)
kenjiArai 15:8d343be3382d 16 #elif defined(TARGET_NUCLEO_L476RG)
kenjiArai 15:8d343be3382d 17 # define MAGIC_NUM (-50)
kenjiArai 15:8d343be3382d 18 #elif defined(TARGET_K64F)
kenjiArai 15:8d343be3382d 19 # define MAGIC_NUM (0)
kenjiArai 15:8d343be3382d 20 #else
kenjiArai 15:8d343be3382d 21 # warning "you need to tune MAGIC_NUM! in SoftSerial_rx_IR.cpp"
kenjiArai 15:8d343be3382d 22 # define MAGIC_NUM (0)
kenjiArai 15:8d343be3382d 23 #endif
kenjiArai 15:8d343be3382d 24 //------------------------------------------------------------------------------
Sissors 10:236fce2e5b8c 25
kenjiArai 15:8d343be3382d 26
kenjiArai 15:8d343be3382d 27 // please make a constructor in main.cpp if you use below pc & led
kenjiArai 15:8d343be3382d 28 #if DEBUG_TIMING == 2
kenjiArai 15:8d343be3382d 29 extern Serial pc;
kenjiArai 15:8d343be3382d 30 extern DigitalOut test_point;
kenjiArai 15:8d343be3382d 31 # define TP_ON {test_point = 1;}
kenjiArai 15:8d343be3382d 32 # define TP_OFF {test_point = 0;}
kenjiArai 15:8d343be3382d 33 # define DBG_PRINTF(...) pc.printf(__VA_ARGS__)
kenjiArai 15:8d343be3382d 34 #else
kenjiArai 15:8d343be3382d 35 # define TP_ON {;}
kenjiArai 15:8d343be3382d 36 # define TP_OFF {;}
kenjiArai 15:8d343be3382d 37 # define DBG_PRINTF(...) {;}
kenjiArai 15:8d343be3382d 38 #endif
kenjiArai 15:8d343be3382d 39
kenjiArai 15:8d343be3382d 40
kenjiArai 15:8d343be3382d 41 int SoftSerial_IR::_getc( void )
kenjiArai 15:8d343be3382d 42 {
kenjiArai 15:8d343be3382d 43 while(!readable()) {
kenjiArai 15:8d343be3382d 44 YIELD;
kenjiArai 15:8d343be3382d 45 }
Sissors 1:f8b4b764ace7 46 out_valid = false;
Sissors 1:f8b4b764ace7 47 return out_buffer;
Sissors 1:f8b4b764ace7 48 }
Sissors 0:8edaa7abe724 49
kenjiArai 15:8d343be3382d 50 int SoftSerial_IR::readable(void)
kenjiArai 15:8d343be3382d 51 {
Sissors 1:f8b4b764ace7 52 return out_valid;
Sissors 1:f8b4b764ace7 53 }
Sissors 1:f8b4b764ace7 54
Sissors 1:f8b4b764ace7 55 //Start receiving byte
kenjiArai 15:8d343be3382d 56 void SoftSerial_IR::rx_gpio_irq_handler(void)
kenjiArai 15:8d343be3382d 57 {
kenjiArai 15:8d343be3382d 58 TP_ON;
kenjiArai 15:8d343be3382d 59 rxticker.prime(MAGIC_NUM);
Sissors 1:f8b4b764ace7 60 rx->fall(NULL);
Sissors 1:f8b4b764ace7 61 rx_bit = 0;
Sissors 1:f8b4b764ace7 62 rx_error = false;
kenjiArai 15:8d343be3382d 63 // dummy setting for 1st timer interrupt
kenjiArai 15:8d343be3382d 64 rx_1st = true;
kenjiArai 15:8d343be3382d 65 rx_st_time = us_ticker_read();
kenjiArai 15:8d343be3382d 66 rxticker.setNext(10);
kenjiArai 15:8d343be3382d 67 TP_OFF;
kenjiArai 15:8d343be3382d 68 };
Sissors 1:f8b4b764ace7 69
kenjiArai 15:8d343be3382d 70 void SoftSerial_IR::rx_handler(void)
kenjiArai 15:8d343be3382d 71 {
kenjiArai 15:8d343be3382d 72 TP_ON;
kenjiArai 15:8d343be3382d 73 // dummy IRQ for 1st shot
kenjiArai 15:8d343be3382d 74 if (rx_1st) {
kenjiArai 15:8d343be3382d 75 rx_1st = false;
kenjiArai 15:8d343be3382d 76 int next_preiod = us_ticker_read() - rx_st_time;
kenjiArai 15:8d343be3382d 77 next_preiod = bit_period + (bit_period >> 1) - next_preiod;
kenjiArai 15:8d343be3382d 78 if (next_preiod > 0) {
kenjiArai 15:8d343be3382d 79 rxticker.setNext(next_preiod);
kenjiArai 15:8d343be3382d 80 } else {
kenjiArai 15:8d343be3382d 81 rxticker.setNext(5);
kenjiArai 15:8d343be3382d 82 }
kenjiArai 15:8d343be3382d 83 TP_OFF;
kenjiArai 15:8d343be3382d 84 return;
kenjiArai 15:8d343be3382d 85 }
Sissors 10:236fce2e5b8c 86 //Receive data
Sissors 10:236fce2e5b8c 87 int val = rx->read();
kenjiArai 15:8d343be3382d 88
Sissors 6:517082212c00 89 rxticker.setNext(bit_period);
Sissors 1:f8b4b764ace7 90 rx_bit++;
kenjiArai 15:8d343be3382d 91
Sissors 1:f8b4b764ace7 92 if (rx_bit <= _bits) {
Sissors 1:f8b4b764ace7 93 read_buffer |= val << (rx_bit - 1);
kenjiArai 15:8d343be3382d 94 TP_OFF;
Sissors 1:f8b4b764ace7 95 return;
Sissors 1:f8b4b764ace7 96 }
kenjiArai 15:8d343be3382d 97
Sissors 1:f8b4b764ace7 98 //Receive parity
Sissors 1:f8b4b764ace7 99 bool parity_count;
Sissors 1:f8b4b764ace7 100 if (rx_bit == _bits + 1) {
Sissors 1:f8b4b764ace7 101 switch (_parity) {
Sissors 1:f8b4b764ace7 102 case Forced1:
Sissors 1:f8b4b764ace7 103 if (val == 0)
Sissors 1:f8b4b764ace7 104 rx_error = true;
Sissors 1:f8b4b764ace7 105 return;
Sissors 1:f8b4b764ace7 106 case Forced0:
Sissors 1:f8b4b764ace7 107 if (val == 1)
Sissors 1:f8b4b764ace7 108 rx_error = true;
Sissors 1:f8b4b764ace7 109 return;
Sissors 1:f8b4b764ace7 110 case Even:
Sissors 1:f8b4b764ace7 111 case Odd:
Sissors 1:f8b4b764ace7 112 parity_count = val;
Sissors 1:f8b4b764ace7 113 for (int i = 0; i<_bits; i++) {
Sissors 1:f8b4b764ace7 114 if (((read_buffer >> i) & 0x01) == 1)
Sissors 1:f8b4b764ace7 115 parity_count = !parity_count;
Sissors 1:f8b4b764ace7 116 }
Sissors 1:f8b4b764ace7 117 if ((parity_count) && (_parity == Even))
Sissors 1:f8b4b764ace7 118 rx_error = true;
Sissors 1:f8b4b764ace7 119 if ((!parity_count) && (_parity == Odd))
Sissors 1:f8b4b764ace7 120 rx_error = true;
Sissors 1:f8b4b764ace7 121 return;
kenjiArai 15:8d343be3382d 122 case None:
kenjiArai 15:8d343be3382d 123 default:
kenjiArai 15:8d343be3382d 124 ;
Sissors 1:f8b4b764ace7 125 }
Sissors 1:f8b4b764ace7 126 }
kenjiArai 15:8d343be3382d 127
Sissors 1:f8b4b764ace7 128 //Receive stop
Sissors 1:f8b4b764ace7 129 if (rx_bit < _bits + (bool)_parity + _stop_bits) {
Sissors 1:f8b4b764ace7 130 if (!val)
Sissors 1:f8b4b764ace7 131 rx_error = true;
kenjiArai 15:8d343be3382d 132 TP_OFF;
Sissors 1:f8b4b764ace7 133 return;
kenjiArai 15:8d343be3382d 134 }
kenjiArai 15:8d343be3382d 135
Sissors 1:f8b4b764ace7 136 //The last stop bit
Sissors 1:f8b4b764ace7 137 if (!val)
Sissors 1:f8b4b764ace7 138 rx_error = true;
kenjiArai 15:8d343be3382d 139
Sissors 1:f8b4b764ace7 140 if (!rx_error) {
Sissors 1:f8b4b764ace7 141 out_valid = true;
Sissors 1:f8b4b764ace7 142 out_buffer = read_buffer;
Sissors 4:c010265ed202 143 fpointer[RxIrq].call();
Sissors 1:f8b4b764ace7 144 }
Sissors 1:f8b4b764ace7 145 read_buffer = 0;
kenjiArai 15:8d343be3382d 146 rxticker.detach();
kenjiArai 15:8d343be3382d 147 rx->fall(callback(this, &SoftSerial_IR::rx_gpio_irq_handler));
kenjiArai 15:8d343be3382d 148 TP_OFF;
Sissors 1:f8b4b764ace7 149 }