LPC11C24 auto bit rate detection is sort of working

This commit is contained in:
Pavel Kirienko
2015-10-12 04:07:13 +03:00
parent fc2a4527d3
commit 563ec45c6e
2 changed files with 34 additions and 26 deletions
@@ -101,7 +101,7 @@ static_assert(offsetof(Type, IF[0].DB2) == 0x048, "C_CAN offset");
static_assert(offsetof(Type, IF[1].DB2) == 0x0A8, "C_CAN offset");
Type& CAN = *reinterpret_cast<Type*>(0x40050000);
volatile Type& CAN = *reinterpret_cast<volatile Type*>(0x40050000);
/*
+33 -25
View File
@@ -156,9 +156,6 @@ BitTimingSettings computeBitTimings(std::uint32_t bitrate)
CanDriver CanDriver::self;
#if __GNUC__
__attribute__((optimize(1)))
#endif
uavcan::uint32_t CanDriver::detectBitRate(void (*idle_callback)())
{
static constexpr uavcan::uint32_t BitRatesToTry[] =
@@ -172,7 +169,6 @@ uavcan::uint32_t CanDriver::detectBitRate(void (*idle_callback)())
const auto ListeningDuration = uavcan::MonotonicDuration::fromMSec(1050);
NVIC_DisableIRQ(CAN_IRQn);
LPC_SYSCTL->PRESETCTRL |= (1 << RESET_CAN0);
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_CAN);
for (auto bitrate : BitRatesToTry)
@@ -188,24 +184,35 @@ uavcan::uint32_t CanDriver::detectBitRate(void (*idle_callback)())
{
CriticalSectionLocker locker;
c_can::CAN.CNTL = c_can::CNTL_INIT | c_can::CNTL_CCE | c_can::CNTL_TEST;
LPC_SYSCTL->PRESETCTRL |= (1U << RESET_CAN0);
// Entering initialization mode
c_can::CAN.CNTL = c_can::CNTL_INIT | c_can::CNTL_CCE;
while ((c_can::CAN.CNTL & c_can::CNTL_INIT) == 0)
{
; // Nothing to do
}
// Configuring bit rate
c_can::CAN.CLKDIV = bit_timings.canclkdiv;
c_can::CAN.BT = bit_timings.canbtr;
c_can::CAN.BRPE = 0;
c_can::CAN.BRPE = 0;
c_can::CAN.BT = bit_timings.canbtr;
// Configuring silent mode
c_can::CAN.CNTL |= c_can::CNTL_TEST;
c_can::CAN.TEST = c_can::TEST_SILENT;
// Configuring status monitor
c_can::CAN.STAT = (unsigned(c_can::StatLec::Unused) << c_can::STAT_LEC_SHIFT);
c_can::CAN.CNTL = c_can::CNTL_TEST;
}
// Leaving initialization mode
c_can::CAN.CNTL &= ~(c_can::CNTL_INIT | c_can::CNTL_CCE);
// TODO THIS IS TEMPORARY, REMOVE LATER
if (c_can::CAN.BT != bit_timings.canbtr)
{
Chip_UART_SendBlocking(LPC_USART, "BT\r\n", 4);
while ((c_can::CAN.CNTL & c_can::CNTL_INIT) != 0)
{
; // Nothing to do
}
}
// Listening
@@ -220,16 +227,6 @@ uavcan::uint32_t CanDriver::detectBitRate(void (*idle_callback)())
const auto LastErrorCode = (c_can::CAN.STAT >> c_can::STAT_LEC_SHIFT) & c_can::STAT_LEC_MASK;
// TODO THIS IS TEMPORARY, REMOVE LATER
if (LastErrorCode != unsigned(c_can::StatLec::Unused) &&
LastErrorCode != unsigned(c_can::StatLec::NoError))
{
const char txt[] = { 'E', char('0' + LastErrorCode), ' ',
'R', (((c_can::CAN.STAT & c_can::STAT_RXOK) != 0) ? '1' : '0'),
'\r', '\n' };
Chip_UART_SendBlocking(LPC_USART, txt, sizeof(txt));
}
if (LastErrorCode == unsigned(c_can::StatLec::NoError))
{
match_detected = true;
@@ -238,7 +235,18 @@ uavcan::uint32_t CanDriver::detectBitRate(void (*idle_callback)())
}
// De-configuring the CAN controller back to reset state
c_can::CAN.CNTL = c_can::CNTL_INIT;
{
CriticalSectionLocker locker;
c_can::CAN.CNTL = c_can::CNTL_INIT;
while ((c_can::CAN.CNTL & c_can::CNTL_INIT) == 0)
{
; // Nothing to do
}
LPC_SYSCTL->PRESETCTRL &= ~(1U << RESET_CAN0);
}
// Termination condition
if (match_detected)