Software UART program using Infra-Red LED and IR-Detector
Dependents: TestVirtualisation Bf_SoftSerial_IR
Diff: SoftSerial_rx_IR.cpp
- Revision:
- 15:8d343be3382d
- Parent:
- 14:dc766032cdd6
diff -r dc766032cdd6 -r 8d343be3382d SoftSerial_rx_IR.cpp --- 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; }