예제 #1
0
void TICC1100::initChip()
{
	try
	{
		if(_fileDescriptor->descriptor == -1)
		{
			_out.printError("Error: Could not initialize TI CC1100. The spi device's file descriptor is not valid.");
			return;
		}
		reset();

		int32_t index = 0;
		for(std::vector<uint8_t>::const_iterator i = _config.begin(); i != _config.end(); ++i)
		{
			if(writeRegister((Registers::Enum)index, *i, true) != *i)
			{
				closeDevice();
				return;
			}
			index++;
		}
		if(writeRegister(Registers::Enum::FSTEST, 0x59, true) != 0x59)
		{
			closeDevice();
			return;
		}
		if(writeRegister(Registers::Enum::TEST2, 0x81, true) != 0x81) //Determined by SmartRF Studio
		{
			closeDevice();
			return;
		}
		if(writeRegister(Registers::Enum::TEST1, 0x35, true) != 0x35) //Determined by SmartRF Studio
		{
			closeDevice();
			return;
		}
		if(writeRegister(Registers::Enum::PATABLE, _settings->txPowerSetting, true) != _settings->txPowerSetting)
		{
			closeDevice();
			return;
		}

		sendCommandStrobe(CommandStrobes::Enum::SFRX);
		usleep(20);

		enableRX(true);
	}
    catch(const std::exception& ex)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(BaseLib::Exception& ex)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(...)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
    }
}
예제 #2
0
void TICC1100::endSending()
{
	try
	{
		sendCommandStrobe(CommandStrobes::Enum::SIDLE);
		sendCommandStrobe(CommandStrobes::Enum::SFRX);
		sendCommandStrobe(CommandStrobes::Enum::SRX);
		_sending = false;
		_lastPacketSent = BaseLib::HelperFunctions::getTime();
	}
	catch(const std::exception& ex)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(BaseLib::Exception& ex)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(...)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
    }
}
예제 #3
0
void TICC1100::enableRX(bool flushRXFIFO)
{
	try
	{
		if(_fileDescriptor->descriptor == -1) return;
		_txMutex.lock();
		if(flushRXFIFO) sendCommandStrobe(CommandStrobes::Enum::SFRX);
		sendCommandStrobe(CommandStrobes::Enum::SRX);
	}
    catch(const std::exception& ex)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(BaseLib::Exception& ex)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(...)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
    }
    _txMutex.unlock();
}
예제 #4
0
void TICC1100::reset()
{
	try
	{
		if(_fileDescriptor->descriptor == -1) return;
		sendCommandStrobe(CommandStrobes::Enum::SRES);

		usleep(70); //Measured on HM-CC-VD
	}
    catch(const std::exception& ex)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(BaseLib::Exception& ex)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(...)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
    }
}
예제 #5
0
void TICC1100::mainThread()
{
    try
    {
		int32_t pollResult;
		int32_t bytesRead;
		std::vector<char> readBuffer({'0'});

        while(!_stopCallbackThread && _fileDescriptor->descriptor > -1 && _gpioDescriptors[1]->descriptor > -1)
        {
        	if(_stopped)
        	{
        		std::this_thread::sleep_for(std::chrono::milliseconds(200));
        		continue;
        	}
        	pollfd pollstruct {
				(int)_gpioDescriptors[1]->descriptor,
				(short)(POLLPRI | POLLERR),
				(short)0
			};

			pollResult = poll(&pollstruct, 1, 100);
			/*if(pollstruct.revents & POLLERR)
			{
				_out.printWarning("Warning: Error polling GPIO. Reopening...");
				closeGPIO();
				std::this_thread::sleep_for(std::chrono::milliseconds(1000));
				openGPIO(_settings->gpio1);
			}*/
			if(pollResult > 0)
			{
				if(lseek(_gpioDescriptors[1]->descriptor, 0, SEEK_SET) == -1) throw BaseLib::Exception("Could not poll gpio: " + std::string(strerror(errno)));
				bytesRead = read(_gpioDescriptors[1]->descriptor, &readBuffer[0], 1);
				if(!bytesRead) continue;
				if(readBuffer.at(0) == 0x30)
				{
					if(!_sending) _txMutex.try_lock(); //We are receiving, don't send now
					continue; //Packet is being received. Wait for GDO high
				}
				if(_sending) endSending();
				else
				{
					//sendCommandStrobe(CommandStrobes::Enum::SIDLE);
					std::shared_ptr<MAXPacket> packet;
					if(crcOK())
					{
						uint8_t firstByte = readRegister(Registers::Enum::FIFO);
						std::vector<uint8_t> packetBytes = readRegisters(Registers::Enum::FIFO, firstByte + 1); //Read packet + RSSI
						packetBytes[0] = firstByte;
						if(packetBytes.size() >= 9) packet.reset(new MAXPacket(packetBytes, true, BaseLib::HelperFunctions::getTime()));
						else _out.printWarning("Warning: Too small packet received: " + BaseLib::HelperFunctions::getHexString(packetBytes));
					}
					else _out.printDebug("Debug: MAX! packet received, but CRC failed.");
					if(!_sendingPending)
					{
						sendCommandStrobe(CommandStrobes::Enum::SFRX);
						sendCommandStrobe(CommandStrobes::Enum::SRX);
					}
					if(packet)
					{
						if(_firstPacket) _firstPacket = false;
						else raisePacketReceived(packet);
					}
				}
				_txMutex.unlock(); //Packet sent or received, now we can send again
			}
			else if(pollResult < 0)
			{
				_txMutex.unlock();
				_out.printError("Error: Could not poll gpio: " + std::string(strerror(errno)) + ". Reopening...");
				closeGPIO(1);
				std::this_thread::sleep_for(std::chrono::milliseconds(1000));
				openGPIO(1, true);
			}
			//pollResult == 0 is timeout
        }
    }
    catch(const std::exception& ex)
    {
    	_txMutex.unlock();
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(BaseLib::Exception& ex)
    {
    	_txMutex.unlock();
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(...)
    {
    	_txMutex.unlock();
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
    }
    try
    {
		if(!_stopCallbackThread && (_fileDescriptor->descriptor == -1 || _gpioDescriptors[1]->descriptor == -1))
		{
			_out.printError("Connection to TI CC1101 closed inexpectedly... Trying to reconnect...");
			_stopCallbackThread = true; //Set to true, so that sendPacket aborts
			_txMutex.unlock(); //Make sure _txMutex is unlocked
			std::thread thread(&TICC1100::startListening, this);
			thread.detach();
		}
		else _txMutex.unlock(); //Make sure _txMutex is unlocked
	}
    catch(const std::exception& ex)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(BaseLib::Exception& ex)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(...)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
    }
}
예제 #6
0
void TICC1100::sendPacket(std::shared_ptr<BaseLib::Systems::Packet> packet)
{
	try
	{
		if(!packet)
		{
			_out.printWarning("Warning: Packet was nullptr.");
			return;
		}
		if(_fileDescriptor->descriptor == -1 || _gpioDescriptors[1]->descriptor == -1 || _stopped) return;
		if(packet->payload()->size() > 54)
		{
			_out.printError("Error: Tried to send packet larger than 64 bytes. That is not supported.");
			return;
		}
		std::shared_ptr<MAXPacket> maxPacket(std::dynamic_pointer_cast<MAXPacket>(packet));
		if(!maxPacket) return;
		std::vector<uint8_t> packetBytes = maxPacket->byteArray();

		int64_t timeBeforeLock = BaseLib::HelperFunctions::getTime();
		_sendingPending = true;
		_txMutex.lock();
		_sendingPending = false;
		if(_stopCallbackThread || _fileDescriptor->descriptor == -1 || _gpioDescriptors[1]->descriptor == -1 || _stopped)
		{
			_txMutex.unlock();
			return;
		}
		_sending = true;
		sendCommandStrobe(CommandStrobes::Enum::SIDLE);
		sendCommandStrobe(CommandStrobes::Enum::SFTX);
		_lastPacketSent = BaseLib::HelperFunctions::getTime();
		if(_lastPacketSent - timeBeforeLock > 100)
		{
			_out.printWarning("Warning: Timing problem. Sending took more than 100ms. Do you have enough system resources?");
		}
		if(maxPacket->getBurst())
		{
			sendCommandStrobe(CommandStrobes::Enum::STX);
			usleep(1000000);
		}
		writeRegisters(Registers::Enum::FIFO, packetBytes);
		if(!maxPacket->getBurst()) sendCommandStrobe(CommandStrobes::Enum::STX);

		if(_bl->debugLevel > 3)
		{
			if(packet->timeSending() > 0)
			{
				_out.printInfo("Info: Sending (" + _settings->id + ", WOR: " + (maxPacket->getBurst() ? "yes" : "no") + "): " + packet->hexString() + " Planned sending time: " + BaseLib::HelperFunctions::getTimeString(packet->timeSending()));
			}
			else
			{
				_out.printInfo("Info: Sending (" + _settings->id + ", WOR: " + (maxPacket->getBurst() ? "yes" : "no") + "): " + packet->hexString());
			}
		}

		//Unlocking of _txMutex takes place in mainThread
	}
	catch(const std::exception& ex)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(BaseLib::Exception& ex)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
    }
    catch(...)
    {
        _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
    }
}