Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Crocker <dcrocker@eschertech.com>2020-12-24 17:19:27 +0300
committerDavid Crocker <dcrocker@eschertech.com>2020-12-24 17:19:27 +0300
commitc99c5be037e504775b2531c99be5c78d33f0205d (patch)
tree32e1df0ffe4c42cc96439e9deed5ddec0ccf71ee
parent57b094be2156f1128c3992e3c61b9fbff5c3923b (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.cpp51
-rw-r--r--src/Hardware/SAME70/CanDriver.cpp31
-rw-r--r--src/Hardware/SAME70/CanDriver.h5
-rw-r--r--src/Heating/Sensors/Thermistor.cpp4
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);