From 563ec45c6e69080b06446a1461d277564f47cac3 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Mon, 12 Oct 2015 04:07:13 +0300 Subject: [PATCH] LPC11C24 auto bit rate detection is sort of working --- .../lpc11c24/driver/src/c_can.hpp | 2 +- libuavcan_drivers/lpc11c24/driver/src/can.cpp | 58 +++++++++++-------- 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/libuavcan_drivers/lpc11c24/driver/src/c_can.hpp b/libuavcan_drivers/lpc11c24/driver/src/c_can.hpp index fe2ef1ccf2..cbeb035ea5 100644 --- a/libuavcan_drivers/lpc11c24/driver/src/c_can.hpp +++ b/libuavcan_drivers/lpc11c24/driver/src/c_can.hpp @@ -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(0x40050000); +volatile Type& CAN = *reinterpret_cast(0x40050000); /* diff --git a/libuavcan_drivers/lpc11c24/driver/src/can.cpp b/libuavcan_drivers/lpc11c24/driver/src/can.cpp index cc8aadd53d..0ab31fc3d6 100644 --- a/libuavcan_drivers/lpc11c24/driver/src/can.cpp +++ b/libuavcan_drivers/lpc11c24/driver/src/can.cpp @@ -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)