diff options
author | David Crocker <dcrocker@eschertech.com> | 2020-12-24 17:19:27 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2020-12-24 17:19:27 +0300 |
commit | c99c5be037e504775b2531c99be5c78d33f0205d (patch) | |
tree | 32e1df0ffe4c42cc96439e9deed5ddec0ccf71ee | |
parent | 57b094be2156f1128c3992e3c61b9fbff5c3923b (diff) |
Fixed bus off handling and other bugs in SAME70 CAN driver3.2RC2
Also allow temperatures below -5C to be read by low-resistance
thermistors
-rw-r--r-- | src/CAN/CanInterface.cpp | 51 | ||||
-rw-r--r-- | src/Hardware/SAME70/CanDriver.cpp | 31 | ||||
-rw-r--r-- | src/Hardware/SAME70/CanDriver.h | 5 | ||||
-rw-r--r-- | src/Heating/Sensors/Thermistor.cpp | 4 |
4 files changed, 48 insertions, 43 deletions
diff --git a/src/CAN/CanInterface.cpp b/src/CAN/CanInterface.cpp index bb608952..02818e52 100644 --- a/src/CAN/CanInterface.cpp +++ b/src/CAN/CanInterface.cpp @@ -181,7 +181,7 @@ static void configure_mcan() noexcept { mcan_config config_mcan; mcan_get_config_defaults(&config_mcan); - mcan_init(&mcan_instance, MCAN_MODULE, &config_mcan); + mcan_init(&mcan_instance, &config_mcan); mcan_enable_fd_mode(&mcan_instance); mcan_extended_message_filter_element et_filter; @@ -210,7 +210,9 @@ static void configure_mcan() noexcept et_filter.F1.bit.EFT = 2; mcan_set_rx_extended_filter(&mcan_instance, &et_filter, 2); - mcan_enable_interrupt(&mcan_instance, (mcan_interrupt_source)(MCAN_FORMAT_ERROR | MCAN_ACKNOWLEDGE_ERROR | MCAN_BUS_OFF | MCAN_RX_FIFO_0_NEW_MESSAGE | MCAN_RX_FIFO_1_NEW_MESSAGE | MCAN_RX_FIFO_0_FULL | MCAN_RX_FIFO_1_FULL)); + mcan_enable_interrupt(&mcan_instance, (mcan_interrupt_source)(MCAN_FORMAT_ERROR | MCAN_ACKNOWLEDGE_ERROR | MCAN_BUS_OFF + | MCAN_RX_FIFO_0_NEW_MESSAGE | MCAN_RX_FIFO_1_NEW_MESSAGE + | MCAN_RX_FIFO_0_LOST_MESSAGE | MCAN_RX_FIFO_1_MESSAGE_LOST)); NVIC_ClearPendingIRQ(MCanIRQn); NVIC_EnableIRQ(MCanIRQn); @@ -249,15 +251,20 @@ extern "C" void MCAN_INT0_Handler() noexcept #endif } - if (status & MCAN_RX_FIFO_0_NEW_MESSAGE) + if (status & (MCAN_RX_FIFO_0_LOST_MESSAGE | MCAN_RX_FIFO_1_MESSAGE_LOST)) { - mcan_clear_interrupt_status(&mcan_instance, MCAN_RX_FIFO_0_NEW_MESSAGE); + ++messagesLost; + } + + if (status & (MCAN_RX_FIFO_0_NEW_MESSAGE | MCAN_RX_FIFO_0_LOST_MESSAGE)) + { + mcan_clear_interrupt_status(&mcan_instance, (mcan_interrupt_source)(MCAN_RX_FIFO_0_NEW_MESSAGE | MCAN_RX_FIFO_0_LOST_MESSAGE)); TaskBase::GiveFromISR(mcan_instance.taskWaitingOnFifo[0]); } - if (status & MCAN_RX_FIFO_1_NEW_MESSAGE) + if (status & (MCAN_RX_FIFO_1_NEW_MESSAGE | MCAN_RX_FIFO_1_MESSAGE_LOST)) { - mcan_clear_interrupt_status(&mcan_instance, MCAN_RX_FIFO_1_NEW_MESSAGE); + mcan_clear_interrupt_status(&mcan_instance, (mcan_interrupt_source)(MCAN_RX_FIFO_1_NEW_MESSAGE | MCAN_RX_FIFO_1_MESSAGE_LOST)); TaskBase::GiveFromISR(mcan_instance.taskWaitingOnFifo[1]); } @@ -271,12 +278,6 @@ extern "C" void MCAN_INT0_Handler() noexcept mcan_clear_interrupt_status(&mcan_instance, (mcan_interrupt_source)(MCAN_FORMAT_ERROR)); } - if (status & (MCAN_RX_FIFO_0_FULL | MCAN_RX_FIFO_1_FULL)) - { - mcan_clear_interrupt_status(&mcan_instance, (mcan_interrupt_source)(MCAN_RX_FIFO_0_FULL | MCAN_RX_FIFO_1_FULL)); - ++messagesLost; - } - if (status & MCAN_BUS_OFF) { mcan_clear_interrupt_status(&mcan_instance, MCAN_BUS_OFF); @@ -350,6 +351,7 @@ void CanInterface::Init() noexcept (CanId::BoardAddressMask << CanId::DstAddressShift) | CanId::ResponseBit); can0dev->Enable(); #else + mcan_init_once(&mcan_instance, MCAN_MODULE); configure_mcan(); #endif @@ -782,26 +784,25 @@ void CanInterface::SendMessageNoReplyNoFree(CanMessageBuffer *buf) noexcept // The CanReceiver task extern "C" [[noreturn]] void CanReceiverLoop(void *) noexcept { - CanMessageBuffer *buf; - while ((buf = CanMessageBuffer::Allocate()) == nullptr) - { - delay(2); - } - + CanMessageBuffer buf(nullptr); for (;;) { #if USE_NEW_CAN_DRIVER - can0dev->ReceiveMessage(RxBufferIndexRequest, TaskBase::TimeoutUnlimited, buf); + if (can0dev->ReceiveMessage(RxBufferIndexRequest, TaskBase::TimeoutUnlimited, &buf)) #else - GetMessageFromFifo(&mcan_instance, buf, RxFifoIndexRequest, TaskBase::TimeoutUnlimited); - ++messagesReceived; + if (GetMessageFromFifo(&mcan_instance, &buf, RxFifoIndexRequest, TaskBase::TimeoutUnlimited)) #endif - if (reprap.Debug(moduleCan)) { - buf->DebugPrint("Rx0:"); - } +#if !USE_NEW_CAN_DRIVER + ++messagesReceived; +#endif + if (reprap.Debug(moduleCan)) + { + buf.DebugPrint("Rx0:"); + } - CommandProcessor::ProcessReceivedMessage(buf); + CommandProcessor::ProcessReceivedMessage(&buf); + } } } diff --git a/src/Hardware/SAME70/CanDriver.cpp b/src/Hardware/SAME70/CanDriver.cpp index 761f759a..e519e4be 100644 --- a/src/Hardware/SAME70/CanDriver.cpp +++ b/src/Hardware/SAME70/CanDriver.cpp @@ -301,20 +301,9 @@ static void _mcan_enable_peripheral_clock(mcan_module *const module_inst) noexce } } -/** - * \brief initialize can module. - * - * \param module_inst MCAN instance - * \param hw Base address of MCAN. - * \param config default configuration . - */ -void mcan_init(mcan_module *const module_inst, Mcan *hw, struct mcan_config *config) noexcept +// One-time initialisation. Do not call this to reset after a bus_off condition. +void mcan_init_once(mcan_module *const module_inst, Mcan *hw) noexcept { - /* Sanity check arguments */ - Assert(module_inst); - Assert(hw); - Assert(config); - /* Associate the software module instance with the hardware module */ module_inst->hw = hw; module_inst->taskWaitingOnFifo[0] = module_inst->taskWaitingOnFifo[1] = nullptr; @@ -327,6 +316,18 @@ void mcan_init(mcan_module *const module_inst, Mcan *hw, struct mcan_config *con /* Enable peripheral clock */ _mcan_enable_peripheral_clock(module_inst); +} + +/** + * \brief initialize can module. + * + * \param module_inst MCAN instance + * \param hw Base address of MCAN. + * \param config default configuration . + */ +void mcan_init(mcan_module *const module_inst, struct mcan_config *config) noexcept +{ + Mcan * const hw = module_inst->hw; /* Configuration Change Enable. */ hw->MCAN_CCCR |= MCAN_CCCR_CCE; @@ -750,11 +751,11 @@ bool GetMessageFromFifo(mcan_module *const module_inst, CanMessageBuffer *buf, u mcan_rx_element elem; if (fifoNumber == 1) { - mcan_get_rx_fifo_1_element(module_inst, &elem, getIndex); // copy the data (TODO use our own driver, avoid double copying) + mcan_get_rx_fifo_1_element(module_inst, &elem, getIndex); // copy the data (TODO use our own driver, avoid double copying) } else { - mcan_get_rx_fifo_0_element(module_inst, &elem, getIndex); // copy the data (TODO use our own driver, avoid double copying) + mcan_get_rx_fifo_0_element(module_inst, &elem, getIndex); // copy the data (TODO use our own driver, avoid double copying) } fifoRegisters[1] = getIndex; // acknowledge it, release the FIFO entry diff --git a/src/Hardware/SAME70/CanDriver.h b/src/Hardware/SAME70/CanDriver.h index bd505233..20b20b27 100644 --- a/src/Hardware/SAME70/CanDriver.h +++ b/src/Hardware/SAME70/CanDriver.h @@ -534,7 +534,7 @@ enum mcan_nonmatching_frames_action { struct mcan_module { Mcan *hw; - TaskHandle taskWaitingOnFifo[2]; + volatile TaskHandle taskWaitingOnFifo[2]; }; /** @@ -674,7 +674,8 @@ static inline void mcan_get_config_defaults(struct mcan_config *const config) no config->tx_event_fifo_watermark = 0; } -void mcan_init(mcan_module *const module_inst, Mcan *hw, mcan_config *config) noexcept; +void mcan_init_once(mcan_module *const module_inst, Mcan *hw) noexcept; +void mcan_init(mcan_module *const module_inst, mcan_config *config) noexcept; void mcan_start(mcan_module *const module_inst) noexcept; void mcan_stop(mcan_module *const module_inst) noexcept; void mcan_enable_fd_mode(mcan_module *const module_inst) noexcept; diff --git a/src/Heating/Sensors/Thermistor.cpp b/src/Heating/Sensors/Thermistor.cpp index 4fa8e1e0..873e4325 100644 --- a/src/Heating/Sensors/Thermistor.cpp +++ b/src/Heating/Sensors/Thermistor.cpp @@ -324,7 +324,9 @@ void Thermistor::Poll() noexcept const float recipT = shA + shB * logResistance + shC * logResistance * logResistance * logResistance; const float temp = (recipT > 0.0) ? (1.0/recipT) + ABS_ZERO : BadErrorTemperature; - if (temp < MinimumConnectedTemperature) + // It's hard to distinguish between an open circuit and a cold high-resistance thermistor. + // So we treat a temperature below -5C as an open circuit, unless we are using a low-resistance thermistor. The E3D thermistor has a resistance of about 470k @ -5C. + if (temp < MinimumConnectedTemperature && resistance > seriesR * 100) { // Assume thermistor is disconnected SetResult(ABS_ZERO, TemperatureError::openCircuit); |