STM32: iface activity indication

This commit is contained in:
Pavel Kirienko
2014-04-07 15:17:58 +04:00
parent d3f76c5c16
commit 377d2f7d7f
3 changed files with 49 additions and 4 deletions
@@ -114,6 +114,7 @@ class CanIface : public uavcan::ICanIface, uavcan::Noncopyable
TxItem pending_tx_[NumTxMailboxes];
uavcan::uint8_t last_hw_error_code_;
const uavcan::uint8_t self_index_;
bool had_activity_;
int computeTimings(uavcan::uint32_t target_bitrate, Timings& out_timings);
@@ -141,11 +142,13 @@ public:
, update_event_(update_event)
, last_hw_error_code_(0)
, self_index_(self_index)
, had_activity_(false)
{
assert(self_index_ < UAVCAN_STM32_NUM_IFACES);
}
/**
* Initializes the hardware CAN controller.
* Assumes:
* - Iface clock is enabled
* - Iface has been resetted via RCC
@@ -163,8 +166,22 @@ public:
bool isTxBufferFull() const;
bool isRxBufferEmpty() const;
/**
* Total number of hardware failures.
* May increase continuously if the interface is not connected to the bus.
*/
virtual uavcan::uint64_t getErrorCount() const;
/**
* Returns last hardware error code (LEC field in the register ESR)
*/
uavcan::uint8_t yieldLastHardwareErrorCode();
/**
* Whether this iface had at least one successful IO since previous call of this method.
* This is designed for use with iface activity LEDs.
*/
bool hadActivity();
};
/**
@@ -199,6 +216,12 @@ public:
virtual CanIface* getIface(uavcan::uint8_t iface_index);
virtual uavcan::uint8_t getNumIfaces() const { return UAVCAN_STM32_NUM_IFACES; }
/**
* Whether at least one iface had at least one successful IO since previous call of this method.
* This is designed for use with iface activity LEDs.
*/
bool hadActivity();
};
/**
@@ -381,6 +381,9 @@ leave:
void CanIface::handleTxMailboxInterrupt(uavcan::uint8_t mailbox_index, bool txok, const uavcan::uint64_t utc_usec)
{
assert(mailbox_index < NumTxMailboxes);
had_activity_ = had_activity_ || txok;
TxItem& txi = pending_tx_[mailbox_index];
if (txi.loopback && txok && txi.pending)
{
@@ -471,6 +474,7 @@ void CanIface::handleRxInterrupt(uavcan::uint8_t fifo_index, uavcan::uint64_t ut
*/
rx_queue_.push(frame, utc_usec, 0);
update_event_.signalFromInterrupt();
had_activity_ = true;
}
void CanIface::handleStatusInterrupt()
@@ -522,6 +526,14 @@ uavcan::uint8_t CanIface::yieldLastHardwareErrorCode()
return val;
}
bool CanIface::hadActivity()
{
CriticalSectionLocker lock;
const bool ret = had_activity_;
had_activity_ = false;
return ret;
}
/*
* CanDriver
*/
@@ -640,6 +652,15 @@ CanIface* CanDriver::getIface(uavcan::uint8_t iface_index)
return NULL;
}
bool CanDriver::hadActivity()
{
bool ret = if0_.hadActivity();
#if UAVCAN_STM32_NUM_IFACES > 1
ret |= if1_.hadActivity();
#endif
return ret;
}
} // namespace uavcan_stm32
/*
@@ -140,10 +140,11 @@ int main()
while (true)
{
app::ledSet(false);
sleep(1);
app::ledSet(true);
sleep(1);
for (int i = 0; i < 200; i++)
{
app::ledSet(app::can.driver.hadActivity());
::usleep(25000);
}
const uavcan::UtcTime utc = uavcan_stm32::clock::getUtc();
lowsyslog("UTC %lu sec, %li corr, %lu jumps\n",