Esempio n. 1
0
void RadioReceiveTask::beforeResume() {
	// Don't count suspended time towards timeout!
	_lastMessageReceived = xTaskGetTickCount();

	// Get rid of garbage collected during transmit period (like talk of other radios)
	_clearSerialBuffer();
}
void RadioReceiveTask::task() {
	_clearSerialBuffer();
	_initialiseDiscoveryState();

	// Packet
	byte packetBuffer[RADIO_PACKET_WITH_RSSI_LENGTH];
	uint8_t packetBufferLength = 0;

	#ifdef RADIO_DEBUG_MODE
		uint8_t serialRingBufferHWM = 0;
	#endif

	_wakeUp();

	_currentMessageReceiver = NO_CURRENT_MESSAGE;
	while (true) {
		uint8_t availableBytes = RADIO_SERIAL.available();
		if (availableBytes > 0) {
			pinMode(PIN_LED_RXL, OUTPUT);
			digitalWrite(PIN_LED_RXL, 1);

			#ifdef RADIO_DEBUG_MODE
				if (serialRingBufferHWM < availableBytes) {
					serialRingBufferHWM = availableBytes;
					debug::log("RadioReceiveTask: serialRingBufferHWM=" + String(serialRingBufferHWM));
				}
			#endif

			while (availableBytes > 0) {
				packetBuffer[packetBufferLength] = RADIO_SERIAL.read();
				packetBufferLength++;
				availableBytes--;

				// Only handle one packet at a time
				if (packetBufferLength == RADIO_PACKET_WITH_RSSI_LENGTH) {
					break; // we have enough for one packet
				}
			}

			#ifdef RADIO_DEBUG_MODE_EXTENDED
				debug::log("RadioReceiveTask: Current buffer:");
				debug::logByteArray(packetBuffer, packetBufferLength);
			#endif

			packetBufferLength = _parsePacketBuffer(packetBuffer, packetBufferLength);

			digitalWrite(PIN_LED_RXL, 0);

			_lastMessageReceived = xTaskGetTickCount();
		} else {
			vTaskDelay(RADIO_NO_DATA_SLEEP_DURATION);
		}

		_checkForStateChange();
	}
}
Esempio n. 3
0
inline void RadioTask::_initialiseReceiveState() {
	debug::log("RadioTask: Starting to receive on channel " + String(_bestChannel));

	_enterAtMode();
	RADIO_SERIAL.println("ATZD3");  // output format <payload>|<rssi>
	RADIO_SERIAL.println("ATPK3A"); // 58byte packet length
	RADIO_SERIAL.println("ATCN" + _intToHex(_bestChannel)); // Channel
	RADIO_SERIAL.println("ATAC");   // apply
	RADIO_SERIAL.flush();
	_leaveAtMode();

	_radioState = RADIO_STATE_RECEIVE;

	_clearSerialBuffer();
}
Esempio n. 4
0
void RadioTask::task() {

	// Temporary: Remove me soon!
	_outgoingPacketBuffer[0] = 0x90;
	_outgoingPacketBuffer[1] = 0x03; // ping service
	for (uint8_t i=2; i<RADIO_PACKET_LENGTH; i++) {
		_outgoingPacketBuffer[i] = i - 2;
	}
	_outgoingPacketAvailable = true;

	// Setup radio communitcation
	RADIO_SERIAL.begin(RADIO_SERIAL_BAUD);

	// Setup AT Mode pin
	pinMode(RADIO_AT_MODE_PIN, OUTPUT);

	_clearSerialBuffer();
	_initialiseDiscoveryState();

	// Packet
	byte packetBuffer[RADIO_PACKET_WITH_RSSI_LENGTH];
	uint8_t packetBufferLength = 0;

	_currentMessageReceiver = NO_CURRENT_MESSAGE;
	while (true) {
		uint8_t availableBytes = RADIO_SERIAL.available();
		if (availableBytes > 0) {
			while (availableBytes > 0) {
				packetBuffer[packetBufferLength] = RADIO_SERIAL.read();
				packetBufferLength++;
				availableBytes--;

				// Only handle one packet at a time
				if (packetBufferLength == RADIO_PACKET_WITH_RSSI_LENGTH) {
					break; // we have enough for one packet
				}
			}

			packetBufferLength = _parsePacketBuffer(packetBuffer, packetBufferLength);

			_lastMessageReceived = xTaskGetTickCount();
		}

		_checkForStateChange();
	}
}
Esempio n. 5
0
inline void RadioTask::_initialiseDiscoveryState() {
	debug::log("RadioTask: Starting discovery state");
	_bestRssi = 255;
	_bestChannel = NO_CHANNEL_DISCOVERED;
	_radioState = RADIO_STATE_DISCOVERY;
	_discoveryFinishingTime = xTaskGetTickCount() + RADIO_DISCOVERY_TIME;

	_enterAtMode();
	RADIO_SERIAL.println("ATZD3");  // output format <payload>|<rssi>
	RADIO_SERIAL.println("ATPK08"); // 8byte packet length
	RADIO_SERIAL.println(String("ATCN") + String(RADIO_DISCOVERY_CHANNEL)); // Discovery Channel
	RADIO_SERIAL.println("ATAC");   // apply
	RADIO_SERIAL.flush();
	_leaveAtMode();

	_clearSerialBuffer();
}
inline uint8_t RadioReceiveTask::_parsePacketBuffer(byte packetBuffer[], uint8_t packetBufferLength) {
	// Have we received a whole packet yet?
	bool receivedWholePacket =
		packetBufferLength >= 5 + 1 && // Has to have at least one byte payload
		packetBuffer[packetBufferLength - 1] >= 48 && packetBuffer[packetBufferLength - 1] <= 57 && // Digit
		packetBuffer[packetBufferLength - 2] >= 48 && packetBuffer[packetBufferLength - 2] <= 57 && // Digit
		packetBuffer[packetBufferLength - 3] >= 48 && packetBuffer[packetBufferLength - 3] <= 57 && // Digit
		packetBuffer[packetBufferLength - 4] == '-' &&
		packetBuffer[packetBufferLength - 5] == '|';

	// If the data looks like a packet we can start parsing it
	if (receivedWholePacket) {
		// read rssi and then ignore the packet footer
		_rssi = (packetBuffer[packetBufferLength - 1] - 48) +
			(packetBuffer[packetBufferLength - 2] - 48) * 10 +
			(packetBuffer[packetBufferLength - 3] - 48) * 100;
		packetBufferLength -= 5;

		#ifdef RADIO_DEBUG_MODE
			debug::log("Packet!");
		#endif

		if (_radioState == RADIO_STATE_DISCOVERY) {
			_handleDiscoveryPacket(packetBuffer, packetBufferLength, _rssi);
		} else if (_radioState == RADIO_STATE_RECEIVE) {
			_handleReceivePacket(packetBuffer, packetBufferLength);
		}

		packetBufferLength = 0;
	} else if (packetBufferLength == RADIO_PACKET_WITH_RSSI_LENGTH) {
		#ifdef RADIO_DEBUG_MODE
			debug::log("RadioReceiveTask: Packet does not conform");
			debug::logByteArray(packetBuffer, 58);
		#endif
		// Something's wrong, we received enough bytes but it's not formated correctly.
		// Let's sleep a while and clear the buffer. Hopefully that'll fix it.
		vTaskDelay(7);
		_clearSerialBuffer();
		packetBufferLength = 0;
	}

	return packetBufferLength;
}
inline void RadioReceiveTask::_initialiseReceiveState() {
	debug::log("RadioReceiveTask: Starting to receive on channel " + String(_bestChannel) + " with RSSI " + String(_bestRssi));

	_enterAtMode();
	RADIO_SERIAL.println("ATZD3");  // output format <payload>|<rssi>
	RADIO_SERIAL.println("ATPK3A"); // 58byte packet length
	RADIO_SERIAL.println("ATCN" + Utils::intToHex(_bestChannel)); // Channel
	RADIO_SERIAL.println("ATAC");   // apply
	RADIO_SERIAL.flush();
	_leaveAtMode();

	// This channel might be in transmit phase. Sleep it out.
	if (_bestChannelRemainingTransmitWindow > 0) {
		vTaskDelay(_bestChannelRemainingTransmitWindow);
		_lastMessageReceived = xTaskGetTickCount();
	}

	_radioState = RADIO_STATE_RECEIVE;

	_clearSerialBuffer();
}