Manchester
Revision 2:de778df5892c, committed 2017-05-17
- Comitter:
- hudakz
- Date:
- Wed May 17 21:02:49 2017 +0000
- Parent:
- 1:11292d238e50
- Child:
- 3:03109c995123
- Commit message:
- Updated.
Changed in this revision
--- a/Manchester.cpp Wed May 17 08:17:13 2017 +0000
+++ b/Manchester.cpp Wed May 17 21:02:49 2017 +0000
@@ -2,7 +2,7 @@
******************************************************************************
* @file Manchester.cpp
* @author Zoltan Hudak
- * @version
+ * @version
* @date 16-May-2017
* @brief Manchester code for mbed
******************************************************************************
@@ -25,7 +25,6 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-
#include "Manchester.h"
#include "ManchesterMsg.h"
@@ -35,17 +34,12 @@
* @param txPin Pin name of transmitter line
* rxPin Pin name of receiver line
* speed Communication bit rate in bits per second
- * tol Pulse width tolerance (+/-) in %
+ * tol Pulse width tolerance in %
* @retval
*/
-Manchester::Manchester
- (
- PinName txPin,
- PinName rxPin,
- uint32_t speed /* = 1200 bps */,
- uint8_t tol /* = 20% */
- ) :
- _tx(txPin), _rx(rxPin) {
+Manchester::Manchester(PinName txPin, PinName rxPin, uint32_t speed /* = 1200 bps */, uint8_t tol /* = 20% */ ) :
+ _tx(txPin),
+ _rx(rxPin) {
_state = IDLE;
_midBitTime = 1000000 / speed / 2; // mid-bit time [us]
_minPulseWidth = (_midBitTime * 2 * (100 - tol)) / 100; // [us]
@@ -87,9 +81,11 @@
*/
void Manchester::transmission(void) {
static uint8_t encodeByte;
- static uint32_t byteIndex;
+ static size_t byteIndex;
static uint8_t bitIndex;
+ _timeout.attach_us(callback(this, &Manchester::txTimeout), _maxPulseWidth * 4);
+
switch(_state) {
case SYNCH_START:
_tx = 0; // pull the line low to start synch pulse
@@ -101,7 +97,7 @@
break;
case SYNCH_END:
- _tx = 1; // bring line hight for end of sych pulse
+ _tx = 1; // bring line high for end of sych pulse
byteIndex = 0;
encodeByte = _data[byteIndex];
bitIndex = 0;
@@ -117,7 +113,7 @@
break;
case TRANSITION:
- _tx = (encodeByte & 0x01) ^ 0x01; // set line appropriately for transition
+ _tx = (encodeByte & 0x01) ^ 0x01; // set line appropriately for transition
if(++bitIndex < 8) {
encodeByte = (encodeByte >> 1);
_state = SETUP;
@@ -134,19 +130,33 @@
break;
case COMPLETE:
- _tx = 1; // transition is complete, bring line high
+ _tx = 1; // transmission is complete, bring line high
_state = IDLE;
break;
case IDLE:
default:
+ _timeout.detach();
return;
}
}
/**
+ * @brief ISR handling 'transmission timeout'
+ * @note Called when transmitter is stuck.
+ * Signals 'end of transmission' by setting state to IDLE
+ * @param None
+ * @retval None
+ */
+void Manchester::txTimeout(void) {
+ _timeout.detach();
+ _state = IDLE;
+}
+
+/**
* @brief Receives message
- * @note
+ * @note Waits until a message is received
+ * or receive timeout occured
* @param msg Container to store the received message
* @retval true On success
* false Otherwise
@@ -186,8 +196,8 @@
}
/**
- * @brief ISR to handle reception
- * @note Called on signal rise or fall on receiver line
+ * @brief ISR handling reception
+ * @note Called on signal change (rise or fall) on receiver line
* @param
* @retval
*/
@@ -198,29 +208,28 @@
static uint8_t decodeByte;
static uint8_t bitIndex;
+ _timeout.attach_us(callback(this, &Manchester::rxTimeout), _maxPulseWidth * 4);
+
switch(_state) {
case LISTEN:
begin = now;
- if(_rx == 0) {
+ if(_rx == 0)
_state = SYNCH_START;
- _rxTimeout.attach_us(callback(this, &Manchester::rxTimeout), _maxPulseWidth * 2);
- }
else
_state = ERROR;
break;
case SYNCH_START:
pulseWidth = now - begin;
- if((pulseWidth > _maxPulseWidth) | (_rx == 0))
- _state = ERROR;
- else {
+ if((_minPulseWidth <= pulseWidth) && (pulseWidth <= _maxPulseWidth) && (_rx == 1)) {
begin = now;
decodeByte = 0;
+ bitIndex = 0;
_len = 0;
- bitIndex = 0;
_state = DECODE;
- _rxTimeout.attach_us(callback(this, &Manchester::rxTimeout), _maxPulseWidth * 2);
}
+ else
+ _state = ERROR; // It isn't a synch pulse => error
break;
case DECODE:
@@ -239,35 +248,32 @@
}
}
- if(pulseWidth > _maxPulseWidth) {
- _state = ERROR;
- }
- else
- _rxTimeout.attach_us(callback(this, &Manchester::rxTimeout), _maxPulseWidth * 2);
+ if(pulseWidth > _maxPulseWidth)
+ _state = ERROR; // Pulse width out of limit => error
break;
case IDLE:
case ERROR:
default:
+ _timeout.detach();
break;
}
}
/**
- * @brief ISR to handle receive timeout
- * @note Signals end of transmission by setting state to IDLE
- * or timeout error by setting state to ERROR.
+ * @brief ISR handling 'receive timeout'
+ * @note Called when receiver line rxPin is idle longer than limit.
+ * Signals 'end of transmission' by setting state to IDLE
+ * or 'timeout error' by setting state to ERROR.
* @param None
* @retval None
*/
void Manchester::rxTimeout(void) {
- _rxTimeout.detach();
+ _timeout.detach();
- if(_state == DECODE)
+ if((_state == DECODE) && (_rx == 1))
_state = IDLE; // End of transmission
else
_state = ERROR; // Incomplete transmission
}
-
-
--- a/Manchester.h Wed May 17 08:17:13 2017 +0000
+++ b/Manchester.h Wed May 17 21:02:49 2017 +0000
@@ -2,7 +2,7 @@
******************************************************************************
* @file Manchester.h
* @author Zoltan Hudak
- * @version
+ * @version
* @date 16-May-2017
* @brief Manchester code for mbed
******************************************************************************
@@ -25,7 +25,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-
+
#ifndef MANCHESTER_H
#define MANCHESTER_H
@@ -47,35 +47,37 @@
DECODE,
ERROR
};
-
+
public:
Manchester
(
PinName txPin, /* transmitter pin name */
PinName rxPin, /* receiver pin name */
- uint32_t speed = 1200 /* speed in bits per second */,
- uint8_t tol = 20 /* pulse width tolerance (+/-) in % */
+ uint32_t speed = 1200 /* speed in bits per second */,
+ uint8_t tol = 20 /* pulse width tolerance (+/-) in % */
);
- ~Manchester(void) { };
+ ~Manchester(void) { }
void transmit(ManchesterMsg& msg);
bool receive(ManchesterMsg& msg);
-
+
private:
DigitalOut _tx; // transmitter line
InterruptIn _rx; // receiver line
Ticker _txTicker; // transmitter ticker
- Timeout _rxTimeout; // receiver timeout
+ Timeout _timeout; // timeout (watchdog)
uint32_t _midBitTime; // mid-bit time [us]
uint32_t _minPulseWidth; // minimum pulse width [us]
uint32_t _maxPulseWidth; // maximum pulse width [us]
State _state; // state
char* _data; // data array
- uint8_t _len; // data length in bytes
- uint8_t _maxLen; // maximum length
-
+ size_t _len; // data length in bytes
+ size_t _maxLen; // maximum length
+
void transmission(void);
void reception(void);
+ void txTimeout(void);
void rxTimeout(void);
};
#endif // MANCHESTER_H
+
--- a/ManchesterMsg.h Wed May 17 08:17:13 2017 +0000
+++ b/ManchesterMsg.h Wed May 17 21:02:49 2017 +0000
@@ -2,7 +2,7 @@
******************************************************************************
* @file ManchesterMsg.h
* @author Zoltan Hudak
- * @version
+ * @version
* @date 16-May-2017
* @brief Message container
******************************************************************************
@@ -25,7 +25,6 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-
#ifndef MANCHESTERMSG_H
#define MANCHESTERMSG_H
@@ -35,42 +34,36 @@
*/
class ManchesterMsg
{
- unsigned char _max; // Max length (capacity) of data field in bytes
+ size_t _max; // Max length (capacity) of data field in bytes
public:
- char* data; // Data field
- unsigned char len; // Length of data in bytes
+ char* data; // Data field
+ size_t len; // Length of data in bytes
/** Creates empty Manchester message of specified capacity.
*/
- ManchesterMsg(unsigned char max) :
- _max(max),
- data(new char[max]) { len = 0; }
+ ManchesterMsg(size_t max) : _max(max), data(new char[max]) { len = 0; }
- ~ManchesterMsg(void) { delete[] data; }
+ ~ ManchesterMsg(void) { delete[] data; }
- /** Copy constructor.
+ /** Copy constructor.
*/
- ManchesterMsg(const ManchesterMsg& msg) {
- len = msg.len;
- memcpy(data, msg.data, msg.len);
- }
-
-
+ ManchesterMsg(const ManchesterMsg& msg) { len = msg.len; memcpy(data, msg.data, msg.len); }
+
/** Returns message maximum length (capacity)
*/
- unsigned char maxLen(void) { return _max; }
+ size_t maxLen(void) { return _max; }
/** Clears message content
*/
- void clear(void) { len = 0; memset(data, 0, _max); }
+ void clear(void) { len = 0; memset(data, 0, _max); }
/** Inserter operator: Appends data (value) to Manchester message
*/
template<class T>
ManchesterMsg &operator<<(const T val) {
if(len + sizeof(T) <= _max) {
- *reinterpret_cast <T*> (&data[len]) = val;
+ *reinterpret_cast < T * > (&data[len]) = val;
len += sizeof(T);
}
@@ -85,10 +78,10 @@
/** Inserter operator: Appends string of char to Manchester message
*/
ManchesterMsg &operator<<(const char* str) {
- unsigned char strLen = strlen(str);
+ size_t strLen = strlen(str);
if(len + strLen + 1 <= _max) {
memcpy(data + len, (char*)str, strLen);
- len += strLen;
+ len += strLen;
data[len++] = '\0';
}
@@ -105,7 +98,7 @@
template<class T>
ManchesterMsg &operator>>(T& val) {
if(sizeof(T) <= len) {
- val = *reinterpret_cast <T*> (&data[0]);
+ val = *reinterpret_cast < T * > (&data[0]);
len -= sizeof(T);
memcpy(data, data + sizeof(T), len);
}
@@ -117,10 +110,11 @@
#endif
return *this;
}
+
/** Extractor operator: Extracts string of char from CAN message
*/
ManchesterMsg &operator>>(char* str) {
- unsigned char strLen = strlen(data);
+ size_t strLen = strlen(data);
if(strLen <= len) {
memcpy(str, data, strLen + 1);
len -= (strLen + 1);