mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-25 03:33:35 +08:00
STM32: auto bit rate in silent mode
This commit is contained in:
@@ -56,6 +56,8 @@ class CanIface : public uavcan::ICanIface, uavcan::Noncopyable
|
|||||||
void push(const uavcan::CanFrame& frame, const uint64_t& utc_usec, uavcan::CanIOFlags flags);
|
void push(const uavcan::CanFrame& frame, const uint64_t& utc_usec, uavcan::CanIOFlags flags);
|
||||||
void pop(uavcan::CanFrame& out_frame, uavcan::uint64_t& out_utc_usec, uavcan::CanIOFlags& out_flags);
|
void pop(uavcan::CanFrame& out_frame, uavcan::uint64_t& out_utc_usec, uavcan::CanIOFlags& out_flags);
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
unsigned getLength() const { return len_; }
|
unsigned getLength() const { return len_; }
|
||||||
|
|
||||||
uavcan::uint32_t getOverflowCount() const { return overflow_cnt_; }
|
uavcan::uint32_t getOverflowCount() const { return overflow_cnt_; }
|
||||||
@@ -127,6 +129,12 @@ class CanIface : public uavcan::ICanIface, uavcan::Noncopyable
|
|||||||
public:
|
public:
|
||||||
enum { MaxRxQueueCapacity = 254 };
|
enum { MaxRxQueueCapacity = 254 };
|
||||||
|
|
||||||
|
enum OperatingMode
|
||||||
|
{
|
||||||
|
NormalMode,
|
||||||
|
SilentMode
|
||||||
|
};
|
||||||
|
|
||||||
CanIface(bxcan::CanType* can, BusEvent& update_event, uavcan::uint8_t self_index,
|
CanIface(bxcan::CanType* can, BusEvent& update_event, uavcan::uint8_t self_index,
|
||||||
CanRxItem* rx_queue_buffer, uavcan::uint8_t rx_queue_capacity)
|
CanRxItem* rx_queue_buffer, uavcan::uint8_t rx_queue_capacity)
|
||||||
: rx_queue_(rx_queue_buffer, rx_queue_capacity)
|
: rx_queue_(rx_queue_buffer, rx_queue_capacity)
|
||||||
@@ -149,7 +157,7 @@ public:
|
|||||||
* - Iface has been resetted via RCC
|
* - Iface has been resetted via RCC
|
||||||
* - Caller will configure NVIC by itself
|
* - Caller will configure NVIC by itself
|
||||||
*/
|
*/
|
||||||
int init(uavcan::uint32_t bitrate);
|
int init(const uavcan::uint32_t bitrate, const OperatingMode mode);
|
||||||
|
|
||||||
void handleTxInterrupt(uavcan::uint64_t utc_usec);
|
void handleTxInterrupt(uavcan::uint64_t utc_usec);
|
||||||
void handleRxInterrupt(uavcan::uint8_t fifo_index, uavcan::uint64_t utc_usec);
|
void handleRxInterrupt(uavcan::uint8_t fifo_index, uavcan::uint64_t utc_usec);
|
||||||
@@ -241,7 +249,7 @@ public:
|
|||||||
* Returns zero if OK.
|
* Returns zero if OK.
|
||||||
* Returns negative value if failed (e.g. invalid bitrate).
|
* Returns negative value if failed (e.g. invalid bitrate).
|
||||||
*/
|
*/
|
||||||
int init(uavcan::uint32_t bitrate);
|
int init(const uavcan::uint32_t bitrate, const CanIface::OperatingMode mode);
|
||||||
|
|
||||||
virtual CanIface* getIface(uavcan::uint8_t iface_index);
|
virtual CanIface* getIface(uavcan::uint8_t iface_index);
|
||||||
|
|
||||||
@@ -277,8 +285,6 @@ public:
|
|||||||
* This function can either initialize the driver at a fixed bit rate, or it can perform
|
* This function can either initialize the driver at a fixed bit rate, or it can perform
|
||||||
* automatic bit rate detection. For theory please refer to the CiA application note #801.
|
* automatic bit rate detection. For theory please refer to the CiA application note #801.
|
||||||
*
|
*
|
||||||
* TODO FIXME: During bit rate detection, the CAN controller must be initialized in listen-only mode.
|
|
||||||
*
|
|
||||||
* @param delay_callable A callable entity that suspends execution for strictly more than one second.
|
* @param delay_callable A callable entity that suspends execution for strictly more than one second.
|
||||||
* The callable entity will be invoked without arguments.
|
* The callable entity will be invoked without arguments.
|
||||||
* @ref getRecommendedListeningDelay().
|
* @ref getRecommendedListeningDelay().
|
||||||
@@ -294,7 +300,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (inout_bitrate > 0)
|
if (inout_bitrate > 0)
|
||||||
{
|
{
|
||||||
return driver.init(inout_bitrate);
|
return driver.init(inout_bitrate, CanIface::NormalMode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -310,8 +316,7 @@ public:
|
|||||||
{
|
{
|
||||||
inout_bitrate = StandardBitRates[br];
|
inout_bitrate = StandardBitRates[br];
|
||||||
|
|
||||||
// TODO: listen-only mode
|
const int res = driver.init(inout_bitrate, CanIface::SilentMode);
|
||||||
const int res = driver.init(inout_bitrate);
|
|
||||||
|
|
||||||
delay_callable();
|
delay_callable();
|
||||||
|
|
||||||
@@ -321,7 +326,8 @@ public:
|
|||||||
{
|
{
|
||||||
if (!driver.getIface(iface)->isRxBufferEmpty())
|
if (!driver.getIface(iface)->isRxBufferEmpty())
|
||||||
{
|
{
|
||||||
return res;
|
// Re-initializing in normal mode
|
||||||
|
return driver.init(inout_bitrate, CanIface::NormalMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,6 +160,14 @@ void CanIface::RxQueue::pop(uavcan::CanFrame& out_frame, uavcan::uint64_t& out_u
|
|||||||
else { UAVCAN_ASSERT(0); }
|
else { UAVCAN_ASSERT(0); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CanIface::RxQueue::reset()
|
||||||
|
{
|
||||||
|
in_ = 0;
|
||||||
|
out_ = 0;
|
||||||
|
len_ = 0;
|
||||||
|
overflow_cnt_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CanIface
|
* CanIface
|
||||||
*/
|
*/
|
||||||
@@ -446,10 +454,21 @@ bool CanIface::waitMsrINakBitStateChange(bool target_state)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CanIface::init(uavcan::uint32_t bitrate)
|
int CanIface::init(const uavcan::uint32_t bitrate, const OperatingMode mode)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Object state
|
||||||
|
*/
|
||||||
|
rx_queue_.reset();
|
||||||
|
error_cnt_ = 0;
|
||||||
|
served_aborts_cnt_ = 0;
|
||||||
|
uavcan::fill_n(pending_tx_, NumTxMailboxes, TxItem());
|
||||||
|
last_hw_error_code_ = 0;
|
||||||
|
peak_tx_mailbox_index_ = 0;
|
||||||
|
had_activity_ = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CAN timings for this bitrate
|
* CAN timings for this bitrate
|
||||||
*/
|
*/
|
||||||
@@ -480,7 +499,8 @@ int CanIface::init(uavcan::uint32_t bitrate)
|
|||||||
can_->BTR = ((timings.sjw & 3U) << 24) |
|
can_->BTR = ((timings.sjw & 3U) << 24) |
|
||||||
((timings.bs1 & 15U) << 16) |
|
((timings.bs1 & 15U) << 16) |
|
||||||
((timings.bs2 & 7U) << 20) |
|
((timings.bs2 & 7U) << 20) |
|
||||||
(timings.prescaler & 1023U);
|
(timings.prescaler & 1023U) |
|
||||||
|
((mode == SilentMode) ? bxcan::BTR_SILM : 0);
|
||||||
|
|
||||||
can_->IER = bxcan::IER_TMEIE | // TX mailbox empty
|
can_->IER = bxcan::IER_TMEIE | // TX mailbox empty
|
||||||
bxcan::IER_FMPIE0 | // RX FIFO 0 is not empty
|
bxcan::IER_FMPIE0 | // RX FIFO 0 is not empty
|
||||||
@@ -812,7 +832,7 @@ uavcan::int16_t CanDriver::select(uavcan::CanSelectMasks& inout_masks,
|
|||||||
return 1; // Return value doesn't matter as long as it is non-negative
|
return 1; // Return value doesn't matter as long as it is non-negative
|
||||||
}
|
}
|
||||||
|
|
||||||
int CanDriver::init(uavcan::uint32_t bitrate)
|
int CanDriver::init(const uavcan::uint32_t bitrate, const CanIface::OperatingMode mode)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
@@ -835,7 +855,7 @@ int CanDriver::init(uavcan::uint32_t bitrate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
UAVCAN_STM32_LOG("Initing iface 0...");
|
UAVCAN_STM32_LOG("Initing iface 0...");
|
||||||
res = if0_.init(bitrate);
|
res = if0_.init(bitrate, mode);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
{
|
{
|
||||||
UAVCAN_STM32_LOG("Iface 0 init failed %i", res);
|
UAVCAN_STM32_LOG("Iface 0 init failed %i", res);
|
||||||
@@ -861,7 +881,7 @@ int CanDriver::init(uavcan::uint32_t bitrate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
UAVCAN_STM32_LOG("Initing iface 1...");
|
UAVCAN_STM32_LOG("Initing iface 1...");
|
||||||
res = if1_.init(bitrate);
|
res = if1_.init(bitrate, mode);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
{
|
{
|
||||||
UAVCAN_STM32_LOG("Iface 1 init failed %i", res);
|
UAVCAN_STM32_LOG("Iface 1 init failed %i", res);
|
||||||
|
|||||||
Reference in New Issue
Block a user