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__); } }
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__); } }
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(); }
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__); } }
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__); } }
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__); } }