コード例 #1
0
bool transportInit() {
    // Reset the state machine
    _dev.begin(MY_RS485_BAUD_RATE);
    _serialReset();
#if defined(MY_RS485_DE_PIN)
    pinMode(MY_RS485_DE_PIN, OUTPUT);
    digitalWrite(MY_RS485_DE_PIN, LOW);
#endif
    return true;
}
コード例 #2
0
// This is the main reception state machine.  Progress through the states
// is keyed on either special control characters, or counted number of bytes
// received.  If all the data is in the right format, and the calculated
// checksum matches the received checksum, AND the destination station is
// our station ID, then look for a registered command that matches the
// command code.  If all the above is true, execute the command's
// function.
bool _serialProcess()
{
	char inch;
	unsigned char i;
	if (!_dev.available()) {
		return false;
	}

	while(_dev.available()) {
		inch = _dev.read();

		switch(_recPhase) {

		// Case 0 looks for the header.  Bytes arrive in the serial interface and get
		// shifted through a header buffer.  When the start and end characters in
		// the buffer match the SOH/STX pair, and the destination station ID matches
		// our ID, save the header information and progress to the next state.
		case 0:
			memcpy(&_header[0],&_header[1],5);
			_header[5] = inch;
			if ((_header[0] == SOH) && (_header[5] == STX) && (_header[1] != _header[2])) {
				_recCalcCS = 0;
				_recStation = _header[1];
				_recSender = _header[2];
				_recCommand = _header[3];
				_recLen = _header[4];

				for (i=1; i<=4; i++) {
					_recCalcCS += _header[i];
				}
				_recPhase = 1;
				_recPos = 0;

				//Check if we should process this message
				//We reject the message if we are the sender
				//We reject if we are not the receiver and message is not a broadcast
				if ((_recSender == _nodeId) ||
				        (_recStation != _nodeId &&
				         _recStation != BROADCAST_ADDRESS)) {
					_serialReset();
					break;
				}

				if (_recLen == 0) {
					_recPhase = 2;
				}

			}
			break;

		// Case 1 receives the data portion of the packet.  Read in "_recLen" number
		// of bytes and store them in the _data array.
		case 1:
			_data[_recPos++] = inch;
			_recCalcCS += inch;
			if (_recPos == _recLen) {
				_recPhase = 2;
			}
			break;

		// After the data comes a single ETX character.  Do we have it?  If not,
		// reset the state machine to default and start looking for a new header.
		case 2:
			// Packet properly terminated?
			if (inch == ETX) {
				_recPhase = 3;
			} else {
				_serialReset();
			}
			break;

		// Next comes the checksum.  We have already calculated it from the incoming
		// data, so just store the incoming checksum byte for later.
		case 3:
			_recCS = inch;
			_recPhase = 4;
			break;

		// The final state - check the last character is EOT and that the checksum matches.
		// If that test passes, then look for a valid command callback to execute.
		// Execute it if found.
		case 4:
			if (inch == EOT) {
				if (_recCS == _recCalcCS) {
					// First, check for system level commands.  It is possible
					// to register your own callback as well for system level
					// commands which will be called after the system default
					// hook.

					switch (_recCommand) {
					case ICSC_SYS_PACK:
						_packet_from = _recSender;
						_packet_len = _recLen;
						_packet_received = true;
						break;
					}
				}
			}
			//Clear the data
			_serialReset();
			//Return true, we have processed one command
			return true;
			break;
		}
	}
	return true;
}