STM32: SCE interrupt removed, error handling moved to RX/TX interrupts. This reduced CPU load on NuttX from 18% to 12% (with two active interfaces, only one connected to the bus)

This commit is contained in:
Pavel Kirienko
2014-05-09 00:42:04 +04:00
parent 6be5246101
commit e260fc2ccd
2 changed files with 20 additions and 51 deletions
@@ -112,6 +112,8 @@ class CanIface : public uavcan::ICanIface, uavcan::Noncopyable
virtual uavcan::uint16_t getNumFilters() const { return NumFilters; }
void pollErrorState();
void handleTxMailboxInterrupt(uavcan::uint8_t mailbox_index, bool txok, uavcan::uint64_t utc_usec);
bool waitMsrINakBitStateChange(bool target_state);
@@ -143,7 +145,6 @@ public:
void handleTxInterrupt(uavcan::uint64_t utc_usec);
void handleRxInterrupt(uavcan::uint8_t fifo_index, uavcan::uint64_t utc_usec);
void handleStatusInterrupt();
void discardTimedOutTxMailboxes(uavcan::MonotonicTime current_time);
@@ -94,19 +94,6 @@ inline void handleRxInterrupt(uavcan::uint8_t iface_index, uavcan::uint8_t fifo_
}
}
inline void handleStatusInterrupt(uavcan::uint8_t iface_index)
{
assert(iface_index < UAVCAN_STM32_NUM_IFACES);
if (ifaces[iface_index] != NULL)
{
ifaces[iface_index]->handleStatusInterrupt();
}
else
{
assert(0);
}
}
} // namespace
/*
@@ -384,8 +371,6 @@ int CanIface::init(uavcan::uint32_t bitrate)
(timings.prescaler & 1023);
can_->IER = bxcan::IER_TMEIE | // TX mailbox empty
bxcan::IER_ERRIE | // Error set in ESR register
bxcan::IER_LECIE | // LEC in ESR updated
bxcan::IER_FMPIE0 | // RX FIFO 0 is not empty
bxcan::IER_FMPIE1; // RX FIFO 1 is not empty
@@ -432,6 +417,17 @@ leave:
return res;
}
void CanIface::pollErrorState()
{
const uavcan::uint8_t lec = (can_->ESR & bxcan::ESR_LEC_MASK) >> bxcan::ESR_LEC_SHIFT;
if (lec != 0)
{
last_hw_error_code_ = lec;
can_->ESR = 0;
error_cnt_++;
}
}
void CanIface::handleTxMailboxInterrupt(uavcan::uint8_t mailbox_index, bool txok, const uavcan::uint64_t utc_usec)
{
assert(mailbox_index < NumTxMailboxes);
@@ -443,6 +439,10 @@ void CanIface::handleTxMailboxInterrupt(uavcan::uint8_t mailbox_index, bool txok
{
rx_queue_.push(txi.frame, utc_usec, uavcan::CanIOFlagLoopback);
}
if (!txok)
{
error_cnt_++;
}
txi.pending = false;
}
@@ -467,6 +467,7 @@ void CanIface::handleTxInterrupt(const uavcan::uint64_t utc_usec)
can_->TSR = bxcan::TSR_RQCP2;
handleTxMailboxInterrupt(2, txok, utc_usec);
}
pollErrorState();
update_event_.signalFromInterrupt();
}
@@ -527,16 +528,9 @@ void CanIface::handleRxInterrupt(uavcan::uint8_t fifo_index, uavcan::uint64_t ut
* Store with timeout into the FIFO buffer and signal update event
*/
rx_queue_.push(frame, utc_usec, 0);
update_event_.signalFromInterrupt();
had_activity_ = true;
}
void CanIface::handleStatusInterrupt()
{
last_hw_error_code_ = (can_->ESR & bxcan::ESR_LEC_MASK) >> bxcan::ESR_LEC_SHIFT;
can_->ESR = 0;
can_->MSR = bxcan::MSR_ERRI | bxcan::MSR_WKUI | bxcan::MSR_SLAKI;
error_cnt_++;
pollErrorState();
update_event_.signalFromInterrupt();
}
void CanIface::discardTimedOutTxMailboxes(uavcan::MonotonicTime current_time)
@@ -714,12 +708,10 @@ int CanDriver::init(uavcan::uint32_t bitrate)
IRQ_ATTACH(STM32_IRQ_CAN1TX, can1_irq);
IRQ_ATTACH(STM32_IRQ_CAN1RX0, can1_irq);
IRQ_ATTACH(STM32_IRQ_CAN1RX1, can1_irq);
IRQ_ATTACH(STM32_IRQ_CAN1SCE, can1_irq);
# if UAVCAN_STM32_NUM_IFACES > 1
IRQ_ATTACH(STM32_IRQ_CAN2TX, can2_irq);
IRQ_ATTACH(STM32_IRQ_CAN2RX0, can2_irq);
IRQ_ATTACH(STM32_IRQ_CAN2RX1, can2_irq);
IRQ_ATTACH(STM32_IRQ_CAN2SCE, can2_irq);
# endif
# undef IRQ_ATTACH
#else
@@ -728,12 +720,10 @@ int CanDriver::init(uavcan::uint32_t bitrate)
nvicEnableVector(CAN1_TX_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
nvicEnableVector(CAN1_RX0_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
nvicEnableVector(CAN1_RX1_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
nvicEnableVector(CAN1_SCE_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
# if UAVCAN_STM32_NUM_IFACES > 1
nvicEnableVector(CAN2_TX_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
nvicEnableVector(CAN2_RX0_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
nvicEnableVector(CAN2_RX1_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
nvicEnableVector(CAN2_SCE_IRQn, UAVCAN_STM32_IRQ_PRIORITY_MASK);
# endif
}
#endif
@@ -805,10 +795,6 @@ static int can1_irq(const int irq, void*)
{
uavcan_stm32::handleRxInterrupt(0, 1);
}
else if (irq == STM32_IRQ_CAN1SCE)
{
uavcan_stm32::handleStatusInterrupt(0);
}
else
{
PANIC();
@@ -832,10 +818,6 @@ static int can2_irq(const int irq, void*)
{
uavcan_stm32::handleRxInterrupt(1, 1);
}
else if (irq == STM32_IRQ_CAN2SCE)
{
uavcan_stm32::handleStatusInterrupt(1);
}
else
{
PANIC();
@@ -867,13 +849,6 @@ UAVCAN_STM32_IRQ_HANDLER(CAN1_RX1_IRQHandler)
UAVCAN_STM32_IRQ_EPILOGUE();
}
UAVCAN_STM32_IRQ_HANDLER(CAN1_SCE_IRQHandler)
{
UAVCAN_STM32_IRQ_PROLOGUE();
uavcan_stm32::handleStatusInterrupt(0);
UAVCAN_STM32_IRQ_EPILOGUE();
}
# if UAVCAN_STM32_NUM_IFACES > 1
UAVCAN_STM32_IRQ_HANDLER(CAN2_TX_IRQHandler)
@@ -897,13 +872,6 @@ UAVCAN_STM32_IRQ_HANDLER(CAN2_RX1_IRQHandler)
UAVCAN_STM32_IRQ_EPILOGUE();
}
UAVCAN_STM32_IRQ_HANDLER(CAN2_SCE_IRQHandler)
{
UAVCAN_STM32_IRQ_PROLOGUE();
uavcan_stm32::handleStatusInterrupt(1);
UAVCAN_STM32_IRQ_EPILOGUE();
}
# endif
#endif // UAVCAN_STM32_NUTTX