diff --git a/libuavcan_drivers/stm32/driver/include/uavcan_stm32/can.hpp b/libuavcan_drivers/stm32/driver/include/uavcan_stm32/can.hpp index e58e5775e9..67bdcb1064 100644 --- a/libuavcan_drivers/stm32/driver/include/uavcan_stm32/can.hpp +++ b/libuavcan_drivers/stm32/driver/include/uavcan_stm32/can.hpp @@ -232,6 +232,11 @@ public: */ uavcan::CanSelectMasks makeSelectMasks(const uavcan::CanFrame* (& pending_tx)[uavcan::MaxCanIfaces]) const; + /** + * Whether there's at least one interface where receive() would return a frame. + */ + bool hasReadableInterfaces() const; + /** * Returns zero if OK. * Returns negative value if failed (e.g. invalid bitrate). diff --git a/libuavcan_drivers/stm32/driver/src/uc_stm32_can.cpp b/libuavcan_drivers/stm32/driver/src/uc_stm32_can.cpp index aa8c9c532f..266f5d84ed 100644 --- a/libuavcan_drivers/stm32/driver/src/uc_stm32_can.cpp +++ b/libuavcan_drivers/stm32/driver/src/uc_stm32_can.cpp @@ -706,6 +706,17 @@ uavcan::CanSelectMasks CanDriver::makeSelectMasks(const uavcan::CanFrame* (& pen return msk; } +bool CanDriver::hasReadableInterfaces() const +{ +#if UAVCAN_STM32_NUM_IFACES == 1 + return !if0_.isRxBufferEmpty(); +#elif UAVCAN_STM32_NUM_IFACES == 2 + return !if0_.isRxBufferEmpty() || !if1_.isRxBufferEmpty(); +#else +# error UAVCAN_STM32_NUM_IFACES +#endif +} + uavcan::int16_t CanDriver::select(uavcan::CanSelectMasks& inout_masks, const uavcan::CanFrame* (& pending_tx)[uavcan::MaxCanIfaces], const uavcan::MonotonicTime blocking_deadline) diff --git a/libuavcan_drivers/stm32/driver/src/uc_stm32_thread.cpp b/libuavcan_drivers/stm32/driver/src/uc_stm32_thread.cpp index 88fd0b37ed..cdc54cadd1 100644 --- a/libuavcan_drivers/stm32/driver/src/uc_stm32_thread.cpp +++ b/libuavcan_drivers/stm32/driver/src/uc_stm32_thread.cpp @@ -105,7 +105,7 @@ int BusEvent::poll(::file* filp, ::pollfd* fds, bool setup) * - Transmission complete. This event is edge-triggered. * FIXME Since TX event is edge-triggered, it can be lost between poll() calls. */ - fds->revents |= fds->events & ((can_driver_.makeSelectMasks().read == 0) ? 0 : POLLIN); + fds->revents |= fds->events & (can_driver_.hasReadableInterfaces() ? 0 : POLLIN); if (fds->revents != 0) { (void)sem_post(fds->sem);