diff --git a/hal/src/main/native/athena/DutyCycle.cpp b/hal/src/main/native/athena/DutyCycle.cpp index 49f39d9a86..4df14cb936 100644 --- a/hal/src/main/native/athena/DutyCycle.cpp +++ b/hal/src/main/native/athena/DutyCycle.cpp @@ -111,24 +111,12 @@ int32_t HAL_GetDutyCycleHighTime(HAL_DutyCycleHandle dutyCycleHandle, // TODO Handle Overflow unsigned char overflow = 0; - uint32_t freq0 = dutyCycle->dutyCycle->readFrequency(&overflow, status); - uint32_t output = dutyCycle->dutyCycle->readOutput(&overflow, status); - uint32_t freq1 = dutyCycle->dutyCycle->readFrequency(&overflow, status); + uint32_t highTime = dutyCycle->dutyCycle->readHighTicks(&overflow, status); if (*status != 0) { return 0; } - if (freq0 != freq1) { - // Frequency rolled over. Reread output - output = dutyCycle->dutyCycle->readOutput(&overflow, status); - if (*status != 0) { - return 0; - } - } - if (freq1 == 0) { - return 0; - } // Output will be at max 4e7, so x25 will still fit in a 32 bit signed int. - return (output / freq1) * 25; + return highTime * 25; } int32_t HAL_GetDutyCycleOutputScaleFactor(HAL_DutyCycleHandle dutyCycleHandle, diff --git a/hal/src/main/native/athena/FRCDriverStation.cpp b/hal/src/main/native/athena/FRCDriverStation.cpp index 0f0b734b76..db37872142 100644 --- a/hal/src/main/native/athena/FRCDriverStation.cpp +++ b/hal/src/main/native/athena/FRCDriverStation.cpp @@ -171,6 +171,38 @@ static int32_t HAL_GetMatchInfoInternal(HAL_MatchInfo* info) { return status; } +namespace { +struct TcpCache { + TcpCache() { std::memset(this, 0, sizeof(*this)); } + void Update(uint32_t mask); + void CloneTo(TcpCache* other) { std::memcpy(other, this, sizeof(*this)); } + + HAL_MatchInfo matchInfo; + HAL_JoystickDescriptor descriptors[HAL_kMaxJoysticks]; +}; +static_assert(std::is_standard_layout_v); +} // namespace + +static std::atomic_uint32_t tcpMask{0xFFFFFFFF}; +static TcpCache tcpCache; +static TcpCache tcpCurrent; +static wpi::mutex tcpCacheMutex; + +constexpr uint32_t combinedMatchInfoMask = kTcpRecvMask_MatchInfoOld | + kTcpRecvMask_MatchInfo | + kTcpRecvMask_GameSpecific; + +void TcpCache::Update(uint32_t mask) { + if ((mask & combinedMatchInfoMask) != 0) { + HAL_GetMatchInfoInternal(&matchInfo); + } + for (int i = 0; i < HAL_kMaxJoysticks; i++) { + if ((mask & (1 << i)) != 0) { + HAL_GetJoystickDescriptorInternal(i, &descriptors[i]); + } + } +} + namespace hal::init { void InitializeFRCDriverStation() { std::memset(&newestControlWord, 0, sizeof(newestControlWord)); @@ -339,11 +371,16 @@ void HAL_GetAllJoystickData(HAL_JoystickAxes* axes, HAL_JoystickPOVs* povs, int32_t HAL_GetJoystickDescriptor(int32_t joystickNum, HAL_JoystickDescriptor* desc) { - return HAL_GetJoystickDescriptorInternal(joystickNum, desc); + CHECK_JOYSTICK_NUMBER(joystickNum); + std::scoped_lock lock{tcpCacheMutex}; + *desc = tcpCurrent.descriptors[joystickNum]; + return 0; } int32_t HAL_GetMatchInfo(HAL_MatchInfo* info) { - return HAL_GetMatchInfoInternal(info); + std::scoped_lock lock{tcpCacheMutex}; + *info = tcpCurrent.matchInfo; + return 0; } HAL_AllianceStationID HAL_GetAllianceStation(int32_t* status) { @@ -388,7 +425,6 @@ void HAL_FreeJoystickName(char* name) { } int32_t HAL_GetJoystickAxisType(int32_t joystickNum, int32_t axis) { - CHECK_JOYSTICK_NUMBER(joystickNum); HAL_JoystickDescriptor joystickDesc; if (HAL_GetJoystickDescriptor(joystickNum, &joystickDesc) < 0) { return -1; @@ -431,13 +467,14 @@ void HAL_ObserveUserProgramTest(void) { // Constant number to be used for our occur handle constexpr int32_t refNumber = 42; +constexpr int32_t tcpRefNumber = 94; -static void newDataOccur(uint32_t refNum) { - // Since we could get other values, require our specific handle - // to signal our threads - if (refNum != refNumber) { - return; - } +static void tcpOccur(void) { + uint32_t mask = FRC_NetworkCommunication_getNewTcpRecvMask(); + tcpMask.fetch_or(mask); +} + +static void udpOccur(void) { cacheToUpdate->Update(); { std::scoped_lock lock{cacheMutex}; @@ -447,6 +484,22 @@ static void newDataOccur(uint32_t refNum) { driverStation->newDataEvents.Wakeup(); } +static void newDataOccur(uint32_t refNum) { + switch (refNum) { + case refNumber: + udpOccur(); + break; + + case tcpRefNumber: + tcpOccur(); + break; + + default: + std::printf("Unknown occur %u\n", refNum); + break; + } +} + void HAL_RefreshDSData(void) { HAL_ControlWord controlWord; std::memset(&controlWord, 0, sizeof(controlWord)); @@ -458,6 +511,13 @@ void HAL_RefreshDSData(void) { currentCache->updated = false; } newestControlWord = controlWord; + + uint32_t mask = tcpMask.exchange(0); + if (mask != 0) { + tcpCache.Update(mask); + std::scoped_lock tcpLock(tcpCacheMutex); + tcpCache.CloneTo(&tcpCurrent); + } } void HAL_ProvideNewDataEventHandle(WPI_EventHandle handle) { @@ -481,5 +541,6 @@ void InitializeDriverStation() { NetCommRPCProxy_SetOccurFuncPointer(newDataOccur); // Set up our occur reference number setNewDataOccurRef(refNumber); + FRC_NetworkCommunication_setNewTcpDataOccurRef(tcpRefNumber); } } // namespace hal diff --git a/shared/config.gradle b/shared/config.gradle index e11443caf3..86f84ec2f9 100644 --- a/shared/config.gradle +++ b/shared/config.gradle @@ -13,7 +13,7 @@ nativeUtils.withCrossLinuxArm64() nativeUtils { wpi { configureDependencies { - niLibVersion = "2023.1.0" + niLibVersion = "2023.2.0" opencvVersion = "4.6.0-3" googleTestVersion = "1.12.1-1" }