12 #if UAVCAN_KINETIS_NUTTX 13 # include <nuttx/arch.h> 14 # include <nuttx/irq.h> 15 # include <arch/board/board.h> 26 #if UAVCAN_KINETIS_NUM_IFACES > 1 27 static int can1_irq(
const int irq,
void*,
void*
args);
42 CanIface* ifaces[UAVCAN_KINETIS_NUM_IFACES] =
45 #if UAVCAN_KINETIS_NUM_IFACES > 1 100 if (
out_ >= capacity_)
115 if (
out_ >= capacity_)
141 if (target_bitrate < 1)
171 const int max_quanta_per_bit = 17;
181 if (prescaler > nbt_prescaler)
186 if ((0 == nbt_prescaler % prescaler) && (nbt_prescaler / prescaler) < max_quanta_per_bit)
207 return ((out_timings.
pseg1 <= 8) && (out_timings.
pseg2 <= 8) && (out_timings.
propseg <= 8)) ? 0 :
234 CriticalSectionLocker lock;
249 while (mbi < NumTxMesgBuffers)
253 can_->IFLAG1 = mb_bit;
260 if (mbi == NumTxMesgBuffers)
296 TxItem& txi = pending_tx_[mbi];
304 can_->IMASK1 |= mb_bit;
314 CriticalSectionLocker lock;
315 if (rx_queue_.getLength() == 0)
319 rx_queue_.pop(out_frame, utc_usec, out_flags);
328 if (num_configs <= NumFilters)
330 CriticalSectionLocker lock;
332 if (!waitFreezeAckChange(
true))
341 if (num_configs == 0)
344 for (
uint8_t i = 0; i < NumFilters; i++)
348 can_->RXIMR[i].w = 0;
354 for (
uint8_t i = 0; i < NumFilters; i++)
387 filter.
w = 0xffffffff;
401 const unsigned Timeout = 1000;
402 for (
unsigned wait_ack = 0; wait_ack < Timeout; wait_ack++)
404 const bool state = (can_->MCR & mask) != 0;
405 if (state == target_state)
435 CriticalSectionLocker lock;
475 can_->MB[i].mb.CS.w = 0x0;
476 can_->MB[i].mb.ID.w = 0x0;
477 can_->MB[i].mb.data.l = 0x0;
478 can_->MB[i].mb.data.h = 0x0;
484 can_->CTRL2 = flexcan::numberFIFOFilters |
491 can_->RXIMR[i].w = 0x0;
493 can_->RX14MASK = 0x3FFFFFFF;
494 can_->RX15MASK = 0x3FFFFFFF;
495 can_->RXMGMASK = 0x3FFFFFFF;
496 can_->RXFGMASK = 0x0;
505 if (!setEnable(
false))
518 if (!setEnable(
true))
530 served_aborts_cnt_ = 0;
532 peak_tx_mailbox_index_ = 0;
533 had_activity_ =
false;
539 const int timings_res = computeTimings(bitrate, timings);
548 unsigned(timings.
pseg2));
588 can_->RXIMR[mb].w = 0;
592 can_->IMASK1 = FIFO_IFLAG1;
602 had_activity_ = had_activity_ || txok;
604 TxItem& txi = pending_tx_[mailbox_index];
626 if (moreAborts & bit)
630 pending_tx_[mb].pending = TxItem::free;
631 served_aborts_cnt_++;
635 tx_iflags &= ~aborts;
636 pending_aborts_ &= ~aborts;
645 if (tx_iflags & mbBit)
647 can_->IFLAG1 = mbBit;
650 handleTxMailboxInterrupt(mbi, txok, utc_usec);
655 update_event_.signalFromInterrupt();
657 pollErrorFlagsFromISR();
667 if ((rx_iflags & FIFO_IFLAG1) == 0)
722 can_->IFLAG1 = flexcan::CAN_FIFO_NE;
727 rx_queue_.push(frame, utc_usec, 0);
728 had_activity_ =
true;
729 update_event_.signalFromInterrupt();
733 pollErrorFlagsFromISR();
749 for (
int i = 0; i < NumTxMesgBuffers; i++)
751 TxItem& txi = pending_tx_[i];
757 can_->IFLAG1 = iflag1;
758 pending_aborts |= iflag1;;
762 pending_aborts_ = pending_aborts;
769 CriticalSectionLocker lock;
770 for (
int mbi = 0; mbi < NumTxMesgBuffers; mbi++)
772 TxItem& txi = pending_tx_[mbi];
801 CriticalSectionLocker lock;
803 for (
int mbi = 0; mbi < NumTxMesgBuffers; mbi++)
805 if (pending_tx_[mbi].pending == TxItem::busy && !frame.
priorityHigherThan(pending_tx_[mbi].frame))
816 CriticalSectionLocker lock;
817 return rx_queue_.getLength() == 0;
822 CriticalSectionLocker lock;
823 return error_cnt_ + rx_queue_.getOverflowCount();
828 CriticalSectionLocker lock;
829 return rx_queue_.getLength();
834 CriticalSectionLocker lock;
835 const bool ret = had_activity_;
836 had_activity_ =
false;
848 msk.
read = if0_.isRxBufferEmpty() ? 0 : 1;
852 msk.
write = if0_.canAcceptNewTxFrame(*pending_tx[0]) ? 1 : 0;
856 #if UAVCAN_KINETIS_NUM_IFACES > 1 857 if (!if1_.isRxBufferEmpty())
864 if (if1_.canAcceptNewTxFrame(*pending_tx[1]))
875 #if UAVCAN_KINETIS_NUM_IFACES == 1 876 return !if0_.isRxBufferEmpty();
877 #elif UAVCAN_KINETIS_NUM_IFACES == 2 878 return !if0_.isRxBufferEmpty() || !if1_.isRxBufferEmpty();
880 # error UAVCAN_KINETIS_NUM_IFACES 891 if0_.discardTimedOutTxMailboxes(time);
893 CriticalSectionLocker cs_locker;
894 if0_.pollErrorFlagsFromISR();
897 #if UAVCAN_KINETIS_NUM_IFACES > 1 898 if1_.discardTimedOutTxMailboxes(time);
900 CriticalSectionLocker cs_locker;
901 if1_.pollErrorFlagsFromISR();
905 inout_masks = makeSelectMasks(pending_tx);
906 if ((inout_masks.
read & in_masks.
read) != 0 ||
912 (void)update_event_.wait(blocking_deadline - time);
913 inout_masks = makeSelectMasks(pending_tx);
924 CriticalSectionLocker lock;
925 modifyreg32(KINETIS_SIM_SCGC6, 0, SIM_SCGC6_FLEXCAN0);
926 #if UAVCAN_KINETIS_NUM_IFACES > 1 927 modifyreg32(KINETIS_SIM_SCGC3, 0, SIM_SCGC3_FLEXCAN1);
934 #define IRQ_ATTACH(irq, handler) \ 936 const int res = irq_attach(irq, handler, NULL); \ 939 up_enable_irq(irq); \ 942 #if UAVCAN_KINETIS_NUM_IFACES > 1 952 UAVCAN_KINETIS_LOG(
"Bitrate %lu mode %d", static_cast<unsigned long>(bitrate), static_cast<int>(mode));
954 static bool initialized_once =
false;
955 if (!initialized_once)
957 initialized_once =
true;
967 res = if0_.init(bitrate, mode);
978 #if UAVCAN_KINETIS_NUM_IFACES > 1 981 res = if1_.init(bitrate, mode);
1002 if (iface_index < UAVCAN_KINETIS_NUM_IFACES)
1004 return ifaces[iface_index];
1011 bool ret = if0_.hadActivity();
1012 #if UAVCAN_KINETIS_NUM_IFACES > 1 1013 ret |= if1_.hadActivity();
1037 handleRxInterrupt(cif, flags);
1040 flags = flex->
IFLAG1 & MB_IFLAG1;
1043 handleTxInterrupt(cif, flags);
1049 #if UAVCAN_KINETIS_NUM_IFACES > 1 1051 static int can1_irq(
const int irq,
void*,
void*)
1062 handleRxInterrupt(cif, flags);
1065 flags = flex->
IFLAG1 & MB_IFLAG1;
1068 handleTxInterrupt(cif, flags);
uint32_t id
CAN ID with flags (above)
virtual uavcan::uint64_t getErrorCount() const
constexpr unsigned long ESR1_FRMERR
constexpr unsigned long CTRL2_TASD_MASK
bool isRemoteTransmissionRequest() const
virtual uavcan::int16_t select(uavcan::CanSelectMasks &inout_masks, const uavcan::CanFrame *(&pending_tx)[uavcan::MaxCanIfaces], uavcan::MonotonicTime blocking_deadline)
#define UAVCAN_KINETIS_LOG(fmt,...)
constexpr unsigned long MCR_FRZACK
const uavcan::uint32_t canclk
void handleRxInterrupt(uavcan::uint32_t rx_iflags, uavcan::uint64_t utc_usec)
constexpr unsigned long MCR_FRZ
void setMCR(uavcan::uint32_t mask, bool target_state)
static const uavcan::int16_t ErrMcrFRZACKAckNotSet
MCR_FRZACK bit of the MCR register is not 1.
static UtcTime fromUSec(uint64_t us)
static const uint32_t MaskExtID
constexpr unsigned long CTRL1_ROPSEG_SHIFT
static const uint32_t FlagEFF
Extended frame format.
virtual uavcan::int16_t send(const uavcan::CanFrame &frame, uavcan::MonotonicTime tx_deadline, uavcan::CanIOFlags flags)
constexpr unsigned long MCR_SRXDIS
constexpr unsigned long MCR_MAXMB_MASK
bool waitMCRChange(uavcan::uint32_t mask, bool target_state)
int init(const uavcan::uint32_t bitrate, const CanIface::OperatingMode mode)
constexpr unsigned long MCR_MDIS
constexpr unsigned long CAN_FIFO_NE
uint8_t dlc
Data Length Code.
constexpr unsigned long CTRL2_TASD_SHIFT
virtual uavcan::int16_t configureFilters(const uavcan::CanFilterConfig *filter_configs, uavcan::uint16_t num_configs)
constexpr unsigned long CTRL1_RJW_SHIFT
static const CanIOFlags CanIOFlagAbortOnError
uavcan::int16_t doReset(Timings timings)
void pop(uavcan::CanFrame &out_frame, uavcan::uint64_t &out_utc_usec, uavcan::CanIOFlags &out_flags)
static const uint32_t MaskStdID
uavcan::MonotonicTime getMonotonic()
constexpr unsigned long CTRL1_TWRNMSK
enum uavcan_kinetis::CanIface::TxItem::@143 pending
uavcan::uint64_t getUtcUSecFromCanInterrupt()
constexpr unsigned long CTRL1_PSEG1_SHIFT
constexpr unsigned long CTRL1_PSEG2_SHIFT
Implicitly convertible to/from uavcan.Timestamp.
int init(const uavcan::uint32_t bitrate, const OperatingMode mode)
UAVCAN_EXPORT const T & max(const T &a, const T &b)
constexpr unsigned long MCR_IRMQ
bool waitFreezeAckChange(bool target_state)
constexpr unsigned long ESR1_BIT1ERR
bool setEnable(bool enable_true)
static const uint32_t FlagRTR
Remote transmission request.
constexpr unsigned long MCR_SUPV
int computeTimings(uavcan::uint32_t target_bitrate, Timings &out_timings)
void discardTimedOutTxMailboxes(uavcan::MonotonicTime current_time)
constexpr unsigned long CTRL1_ERRMSK
static const uavcan::int16_t ErrMcrSOFTRSTNotCleared
MCR_SOFTRST bit of the MCR register is not 0.
unsigned getRxQueueLength() const
constexpr unsigned long ESR2_IMB
UAVCAN_EXPORT const T & min(const T &a, const T &b)
const uavcan::uint32_t OSCERCLK
uavcan::uint8_t prescaler
bool priorityHigherThan(const CanFrame &rhs) const
constexpr unsigned long ESR1_CRCERR
const uavcan::uint32_t numberFIFOFilters
Item buf_[UAVCAN_LPC11C24_RX_QUEUE_LEN]
bool canAcceptNewTxFrame(const uavcan::CanFrame &frame) const
constexpr unsigned long ESR1_ACKERR
const uavcan::uint8_t useFIFO
CanType *const Can[UAVCAN_KINETIS_NUM_IFACES]
constexpr unsigned long ESR1_STFERR
static const uavcan::int16_t ErrMcrLPMAckNotSet
MCR_LPMACK bit of the MCR register is not 1.
uavcan::MonotonicTime deadline
virtual uavcan::int16_t receive(uavcan::CanFrame &out_frame, uavcan::MonotonicTime &out_ts_monotonic, uavcan::UtcTime &out_ts_utc, uavcan::CanIOFlags &out_flags)
static const uavcan::int16_t ErrUnsupportedFrame
Frame not supported (e.g. RTR, CAN FD, etc)
bool isErrorFrame() const
static const uavcan::int16_t ErrMcrFRZACKAckNotCleared
MCR_FRZACK bit of the MCR register is not 0.
constexpr unsigned long CTRL2_RFFN_16MB(1U<< CTRL2_RFFN_SHIFT)
const uavcan::uint32_t busclck
void handleTxMailboxInterrupt(uavcan::uint8_t mailbox_index, bool txok, uavcan::uint64_t utc_usec)
void push(const uavcan::CanFrame &frame, const uint64_t &utc_usec, uavcan::CanIOFlags flags)
constexpr unsigned long ESR2_LPTM_MASK
UAVCAN_EXPORT void fill_n(OutputIt first, std::size_t n, const T &value)
constexpr unsigned long MCR_AEN
virtual CanIface * getIface(uavcan::uint8_t iface_index)
constexpr unsigned long CTRL1_RWRNMSK
#define IRQ_ATTACH(irq, handler)
static const uavcan::int16_t ErrInvalidBitRate
Bit rate not supported.
constexpr unsigned long CTRL1_LOM
bool hasReadableInterfaces() const
constexpr unsigned long CAN_FIFO_WARN
static const CanIOFlags CanIOFlagLoopback
static int can0_irq(const int irq, void *, void *args)
constexpr unsigned long ESR1_BIT0ERR
void setFreeze(bool freeze_true)
constexpr unsigned long MCR_MAXMB_SHIFT
static const uavcan::int16_t ErrFilterNumConfigs
Number of filters is more than supported.
constexpr unsigned long MCR_SOFTRST
constexpr unsigned long CTRL1_PRESDIV_SHIFT
constexpr unsigned long MCR_WAKSRC
constexpr unsigned long ESR2_VPS
constexpr unsigned long MCR_RFEN
constexpr unsigned long MCR_WRNEN
constexpr unsigned long MCR_HALT
constexpr unsigned long CTRL2_RRS
constexpr unsigned long MCR_LPMACK
void handleTxInterrupt(uavcan::uint32_t tx_iflags, uavcan::uint64_t utc_usec)
static const uavcan::int16_t ErrMcrLPMAckNotCleared
MCR_LPMACK bit of the MCR register is not 0.
constexpr unsigned long CTRL1_CLKSRC
constexpr unsigned long CAN_FIFO_OV
constexpr unsigned long CTRL2_EACEN
std::uint32_t overflow_cnt_
const uavcan::uint8_t CLOCKSEL
bool isRxBufferEmpty() const
uavcan::CanSelectMasks makeSelectMasks(const uavcan::CanFrame *(&pending_tx)[uavcan::MaxCanIfaces]) const
constexpr unsigned long MCR_SLFWAK
constexpr unsigned long ESR2_LPTM_SHIFT
void pollErrorFlagsFromISR()