Manchester
Diff: Manchester.cpp
- Revision:
- 2:de778df5892c
- Parent:
- 1:11292d238e50
- Child:
- 3:03109c995123
--- 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
}
-
-