LPC11C24: CanDriver::detectBitRate() - NOT TESTED, NOT FINISHED

This commit is contained in:
Pavel Kirienko
2015-08-24 19:44:47 +03:00
parent dedefdc6a8
commit d75e76555d
3 changed files with 61 additions and 1 deletions
@@ -29,6 +29,15 @@ public:
*/
static CanDriver& instance() { return self; }
/**
* Attempts to detect bit rate of the CAN bus.
* This function may block for up to X seconds, where X is the number of bit rates to try.
* This function is NOT guaranteed to reset the CAN controller upon return.
* @return On success: detected bit rate, in bits per second.
* On failure: zero.
*/
static uavcan::uint32_t detectBitRate(void (*idle_callback)() = nullptr);
/**
* Returns negative value if the requested baudrate can't be used.
* Returns zero if OK.
@@ -98,7 +98,7 @@ static_assert(offsetof(Type, IF[0].DB2) == 0x048, "C_CAN offset");
static_assert(offsetof(Type, IF[1].DB2) == 0x0A8, "C_CAN offset");
Type* const Can = reinterpret_cast<Type*>(0x40050000);
Type& Can = *reinterpret_cast<Type*>(0x40050000);
/*
@@ -156,6 +156,57 @@ BitTimingSettings computeBitTimings(std::uint32_t bitrate)
CanDriver CanDriver::self;
uavcan::uint32_t CanDriver::detectBitRate(void (*idle_callback)())
{
static constexpr uavcan::uint32_t BitRatesToTry[] =
{
1000000,
500000,
250000,
125000
};
const auto ListeningDuration = uavcan::MonotonicDuration::fromMSec(1050);
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_CAN);
for (auto bitrate : BitRatesToTry)
{
// Computing bit timings
const auto bit_timings = computeBitTimings(bitrate);
if (!bit_timings.isValid())
{
return 0;
}
// Configuring the CAN controller
{
CriticalSectionLocker locker;
c_can::Can.CNTL = c_can::CNTL_DAR | c_can::CNTL_CCE;
c_can::Can.BT = bit_timings.canbtr;
c_can::Can.CLKDIV = bit_timings.canclkdiv;
c_can::Can.TEST = c_can::TEST_SILENT;
c_can::Can.CNTL = c_can::CNTL_DAR;
}
// Listening
const auto deadline = clock::getMonotonic() + ListeningDuration;
while (clock::getMonotonic() < deadline)
{
if (idle_callback != nullptr)
{
idle_callback();
}
}
}
return 0;
}
int CanDriver::init(uavcan::uint32_t bitrate)
{
CriticalSectionLocker locker;