Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TestVirtualisation Bf_SoftSerial_IR
Revision 15:8d343be3382d, committed 2020-05-15
- Comitter:
- kenjiArai
- Date:
- Fri May 15 04:11:01 2020 +0000
- Parent:
- 14:dc766032cdd6
- Commit message:
- Updated several functions based on SoftSerial library.
Changed in this revision
--- a/SoftSerial_IR.cpp Fri Dec 28 10:03:35 2018 +0000
+++ b/SoftSerial_IR.cpp Fri May 15 04:11:01 2020 +0000
@@ -1,17 +1,19 @@
-// 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"
-SoftSerial_IR::SoftSerial_IR(PinName TX, PinName RX, const char* name) {
+SoftSerial_IR::SoftSerial_IR(PinName TX, PinName RX, const char* name)
+{
tx_en = rx_en = false;
read_buffer = 0;
if (TX != NC) {
+ //tx = new DigitalOut(TX);
tx = new PwmOut(TX);
tx_en = true;
+ tx->period(1.0f / 38000.0f); // PWM = 38kHz
+ //tx->write(1);
tx->write(0.0f);
tx_bit = -1;
- tx->period(1.0f / 38000.0f); // PWM = 38kHz
txticker.attach(this, &SoftSerial_IR::tx_handler);
}
if (RX != NC) {
@@ -19,39 +21,32 @@
rx_en = true;
out_valid = false;
rxticker.attach(this, &SoftSerial_IR::rx_handler);
- rx->fall(this, &SoftSerial_IR::rx_gpio_irq_handler);
+ rx->fall(callback(this, &SoftSerial_IR::rx_gpio_irq_handler));
}
-
+
baud(2400);
format();
- set_parameter();
}
-SoftSerial_IR::~SoftSerial_IR() {
- if (tx_en){
+SoftSerial_IR::~SoftSerial_IR()
+{
+ if (tx_en) {
delete(tx);
}
- if (rx_en){
+ if (rx_en) {
delete(rx);
}
}
-void SoftSerial_IR::baud(int baudrate) {
+void SoftSerial_IR::baud(int baudrate)
+{
bit_period = 1000000 / baudrate;
}
-void SoftSerial_IR::format(int bits, Parity parity, int stop_bits) {
+void SoftSerial_IR::format(int bits, Parity parity, int stop_bits)
+{
_bits = bits;
_parity = parity;
_stop_bits = stop_bits;
- _total_bits = 1 + _bits + _stop_bits + (bool)_parity;
+ _total_bits = 2 + _bits + _stop_bits + (bool)_parity;
}
-
-void SoftSerial_IR::set_parameter(
- uint32_t tick_offset,
- int32_t rx_detect_center_offset
- )
-{
- timestamp_offset = tick_offset;
- overhead_us_IR = rx_detect_center_offset;
-}
--- a/SoftSerial_IR.h Fri Dec 28 10:03:35 2018 +0000
+++ b/SoftSerial_IR.h Fri May 15 04:11:01 2020 +0000
@@ -1,29 +1,54 @@
-// Apply for Infrared LED and IR-Detector
-// Modified by JH1PJL Dec. 28th, 2018
+/*
+ Original Library by Erik- & SonyPony
+ https://os.mbed.com/users/Sissors/code/SoftSerial/
+
+ Modified by K.Arai / JH1PJL May 15th, 2020
-#ifndef SOFTSERIALIR_H
-#define SOFTSERIALIR_H
+ modified functions
+ tx_handler()
+ prepare_tx()
+ prime()
+ rx_gpio_irq_handler() and others
+ */
+
+#ifndef SOFTSERIAL_IR_H
+#define SOFTSERIAL_IR_H
#include "mbed.h"
#include "SoftSerial_Ticker_IR.h"
+#define DEBUG_TIMING 2 // 0=no debug, 1=tx, 2=rx
+
+#if (MBED_MAJOR_VERSION == 2)
+# define YIELD {;}
+#elif (MBED_MAJOR_VERSION == 5)
+# define YIELD {ThisThread::yield();}
+#endif
+
/** A software serial implementation
*
*/
-class SoftSerial_IR: public Stream {
+class SoftSerial_IR: public Stream
+{
public:
/**
* Constructor
*
* @param TX Name of the TX pin, NC for not connected
- * @param RX Name of the RX pin, NC for not connected,
- * must be capable of being InterruptIn
+ * @param RX Name of the RX pin, NC for not connected,
+ * must be capable of being InterruptIn
* @param name Name of the connection
*/
SoftSerial_IR(PinName TX, PinName RX, const char* name = NULL);
virtual ~SoftSerial_IR();
+ /** Set the baud rate of the serial port
+ *
+ * @param baudrate The baudrate of the serial port (default = 2400).
+ */
+ void baud(int baudrate);
+
enum Parity {
None = 0,
Odd,
@@ -41,8 +66,9 @@
*
* @param bits The number of bits in a word (default = 8)
* @param parity The parity used
- * (SerialBase::None, SerialBase::Odd, SerialBase::Even,
- * SerialBase::Forced1, SerialBase::Forced0; default = SerialBase::None)
+ * (SoftSerial_IR::None, SoftSerial_IR::Odd, SoftSerial_IR::Even,
+ * SoftSerial_IR::Forced1, SoftSerial_IR::Forced0;
+ * default = SoftSerial_IR::None)
* @param stop The number of stop bits (default = 1)
*/
void format(int bits=8, Parity parity=SoftSerial_IR::None, int stop_bits=1);
@@ -66,51 +92,43 @@
/** Attach a function to call whenever a serial interrupt is generated
*
* @param fptr A pointer to a void function, or 0 to set as none
- * @param type Which serial interrupt to attach the member function to
- * (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
+ * @param type Which serial interrupt to attach the member function
+ * to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
*/
- void attach(void (*fptr)(void), IrqType type=RxIrq) {
- fpointer[type].attach(fptr);
+ void attach(void (*fptr)(void), IrqType type=RxIrq)
+ {
+ fpointer[type] = Callback<void()>(fptr);
}
- /** Attach a member function to call whenever a serial interrupt
- * is generated
+ /** Attach a member function to call
+ * whenever a serial interrupt is generated
*
* @param tptr pointer to the object to call the member function on
* @param mptr pointer to the member function to be called
* @param type Which serial interrupt to attach the member function
- * to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
+ * to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
*/
template<typename T>
- void attach(T* tptr, void (T::*mptr)(void), IrqType type=RxIrq) {
- fpointer[type].attach(tptr, mptr);
+ void attach(T* tptr, void (T::*mptr)(void), IrqType type=RxIrq)
+ {
+ fpointer[type] = Callback<void()>(tptr, mptr);
}
/** Generate a break condition on the serial line
*/
void send_break();
- /** Set adjust parameter
- *
- * @param tick_offset Due to timestamp offset, need adjust it
- * @param rx_detect_center_offset offset for RX bit Hi&Lo detection timing
- */
- void set_parameter(uint32_t tick_offset = 3550 ,
- int32_t rx_detect_center_offset = -50);
-
protected:
+ //DigitalOut *tx;
PwmOut *tx;
InterruptIn *rx;
-
+
bool tx_en, rx_en;
int bit_period;
int _bits, _stop_bits, _total_bits;
Parity _parity;
-
- FunctionPointer fpointer[2];
- int32_t overhead_us_IR;
- uint32_t timestamp_offset;
+ Callback<void()> fpointer[2];
//rx
void rx_gpio_irq_handler(void);
@@ -119,19 +137,20 @@
volatile int out_buffer;
volatile bool out_valid;
bool rx_error;
- FlexTicker_IR rxticker;
-
+ FlexTicker rxticker;
+
+ bool rx_1st;
+ uint32_t rx_st_time;
+
//tx
void tx_handler(void);
void prepare_tx(int c);
- FlexTicker_IR txticker;
+ FlexTicker txticker;
int _char;
volatile int tx_bit;
virtual int _getc();
virtual int _putc(int c);
-
- void baud(int baudrate);
};
#endif
--- a/SoftSerial_Ticker_IR.h Fri Dec 28 10:03:35 2018 +0000
+++ b/SoftSerial_Ticker_IR.h Fri May 15 04:11:01 2020 +0000
@@ -1,42 +1,47 @@
-// Apply for Infrared LED and IR-Detector
-// Modified by JH1PJL Dec. 28th, 2018
+//A modified version of the regular ticker/timeout libraries
+// to allow us to do timeout without losing accuracy
-// A modified version of the regular ticker/timeout libraries
-// to allow us to do timeout without losing accuracy
+// Modified by K.Arai / JH1PJL May 15th, 2020
-#ifndef FLEXTICKERIR_H
-#define FLEXTICKERIR_H
+#ifndef FLEXTICKER_H
+#define FLEXTICKER_H
#include "mbed.h"
-class FlexTicker_IR: public TimerEvent {
- public:
+class FlexTicker: public TimerEvent
+{
+public:
template<typename T>
- void attach(T* tptr, void (T::*mptr)(void)) {
- _function.attach(tptr, mptr);
+ void attach(T* tptr, void (T::*mptr)(void))
+ {
+ _function = Callback<void()>(tptr, mptr);
}
-
+
/** Detach the function
*/
- void detach() {
+ void detach()
+ {
remove();
}
-
- void setNext(int delay) {
+
+ void setNext(int delay)
+ {
insert(event.timestamp + delay);
}
-
- void prime(uint32_t offset) {
- event.timestamp = us_ticker_read() - offset;
+
+ void prime(int comp_time = 0)
+ {
+ event.timestamp = us_ticker_read() + comp_time;
}
-
+
protected:
- virtual void handler() {
+ virtual void handler()
+ {
_function.call();
}
-
+
unsigned int _delay;
- FunctionPointer _function;
+ Callback<void()> _function;
};
#endif
\ No newline at end of file
--- 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;
}
--- 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);
}