From 148e788cf543d1b6ab7d3751a50aff3ba439f05b Mon Sep 17 00:00:00 2001 From: kikass13 Date: Tue, 1 Feb 2022 12:16:17 +0100 Subject: [PATCH 01/29] changed mcp2515 driver to use rx and tx buffers as well as uphold the standard modm::can api --- ext/adamgreen/crashcatcher | 2 +- src/modm/driver/can/mcp2515.hpp | 23 ++++++- src/modm/driver/can/mcp2515.lb | 2 + src/modm/driver/can/mcp2515_impl.hpp | 95 +++++++++++++++++++++++++--- 4 files changed, 112 insertions(+), 10 deletions(-) diff --git a/ext/adamgreen/crashcatcher b/ext/adamgreen/crashcatcher index 4b210c8aa7..8c13b1f16f 160000 --- a/ext/adamgreen/crashcatcher +++ b/ext/adamgreen/crashcatcher @@ -1 +1 @@ -Subproject commit 4b210c8aa7191a228ebe6f285eef828f74b9374f +Subproject commit 8c13b1f16fc7bad386f2ed4aed9e0c5fbec9b397 diff --git a/src/modm/driver/can/mcp2515.hpp b/src/modm/driver/can/mcp2515.hpp index 9abaefa317..172eb293ea 100644 --- a/src/modm/driver/can/mcp2515.hpp +++ b/src/modm/driver/can/mcp2515.hpp @@ -143,7 +143,7 @@ namespace modm isMessageAvailable(); static bool - getMessage(can::Message& message); + getMessage(can::Message& message, uint8_t *filter_id=nullptr); /* * The CAN controller has a free slot to send a new message. @@ -161,6 +161,15 @@ namespace modm static bool sendMessage(const can::Message& message); + /* + * Poll the transmit buffer (shoudl be called periodically) + * + * \return true if a message was send this cycle, false otherwise + */ + static bool + update(); + + public: // Extended Functionality @@ -186,6 +195,18 @@ namespace modm BIT_MODIFY = 0x05 }; + static void + mcp2515interrupt(); + + static bool + mcp2515readMessage(can::Message& message); + + static bool + mcp2515isReadyToSend(); + + static bool + mcp2515sendMessage(const can::Message& message); + static void writeRegister(uint8_t address, uint8_t data); diff --git a/src/modm/driver/can/mcp2515.lb b/src/modm/driver/can/mcp2515.lb index 845784d7b1..6054896d5f 100644 --- a/src/modm/driver/can/mcp2515.lb +++ b/src/modm/driver/can/mcp2515.lb @@ -31,6 +31,8 @@ def prepare(module, options): ":architecture:can", ":architecture:clock", ":architecture:delay", + ":architecture:interrupt", + ":platform:exti", ":debug") return True diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index 9b705897b5..ac73aebe6c 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -16,15 +16,19 @@ #ifndef MODM_MCP2515_HPP #error "Don't include this file directly, use 'mcp2515.hpp' instead!" #endif - #include "mcp2515_bit_timings.hpp" #include "mcp2515_definitions.hpp" +#include #include - +#include +#include #undef MODM_LOG_LEVEL #define MODM_LOG_LEVEL modm::log::DISABLED +static modm::atomic::Queue txQueue; +static modm::atomic::Queue rxQueue; + // ---------------------------------------------------------------------------- template SPI modm::Mcp2515::spi; @@ -119,6 +123,12 @@ modm::Mcp2515::initialize() { using Timings = modm::CanBitTimingMcp2515; + // initialize interrrupt on INT pin + + modm::platform::Exti::connect(modm::platform::Exti::Trigger::FallingEdge, [](uint8_t){ + mcp2515interrupt(); + }); + return initializeWithPrescaler( Timings::getPrescaler(), Timings::getSJW(), @@ -186,22 +196,73 @@ modm::Mcp2515::setMode(Can::Mode mode) } // ---------------------------------------------------------------------------- + template bool modm::Mcp2515::isMessageAvailable() { - return !interruptPin.read(); + return rxQueue.isNotEmpty(); +} + +template +bool +modm::Mcp2515::getMessage(can::Message& message, uint8_t* /*filter_id*/) +{ + if (rxQueue.isEmpty()) + { + // no message in the receive buffer + return false; + } + else { + auto& rxMessage = rxQueue.get(); + memcpy(&message, &rxMessage, sizeof(message)); + rxQueue.pop(); + return true; + } } // ---------------------------------------------------------------------------- template bool -modm::Mcp2515::getMessage(can::Message& message) +modm::Mcp2515::isReadyToSend() { + return txQueue.isNotFull(); +} + +// ---------------------------------------------------------------------------- +template +bool +modm::Mcp2515::sendMessage(const can::Message& message) +{ + if (not modm_assert_continue_ignore(txQueue.push(message), "mcp2515.can.tx", + "CAN transmit software buffer overflowed!", 1)) { + return false; + } + return true; +} + +// ---------------------------------------------------------------------------- +template +void +modm::Mcp2515::mcp2515interrupt(){ + using namespace mcp2515; + + can::Message message; + bool success = mcp2515readMessage(message); + if(success){ + modm_assert_continue_ignore(rxQueue.push(message), "mcp2515.can.rx.sw0", + "CAN receive software buffer overflowed!", 1); + } +} + +template +bool +modm::Mcp2515::mcp2515readMessage(can::Message& message){ using namespace mcp2515; uint8_t status = readStatus(RX_STATUS); uint8_t address; + if (status & FLAG_RXB0_FULL) { address = READ_RX; // message in buffer 0 } @@ -231,15 +292,33 @@ modm::Mcp2515::getMessage(can::Message& message) // RX0IF or RX1IF respectivly were already cleared automatically by rising CS. // See section 12.4 in datasheet. - return true; } +template +bool +modm::Mcp2515::update(){ + /// todo + /// this should be a timer interrupt + using namespace mcp2515; + + bool hasSend = false; + /// check if device accepts messages and start emptying the transmit queue if not empty + if (txQueue.isNotEmpty()) + { + if(mcp2515isReadyToSend()){ + hasSend = mcp2515sendMessage(txQueue.get()); + txQueue.pop(); + } + } + return hasSend; +} + // ---------------------------------------------------------------------------- template bool -modm::Mcp2515::isReadyToSend() +modm::Mcp2515::mcp2515isReadyToSend() { using namespace mcp2515; @@ -258,7 +337,7 @@ modm::Mcp2515::isReadyToSend() template bool -modm::Mcp2515::sendMessage(const can::Message& message) +modm::Mcp2515::mcp2515sendMessage(const can::Message& message) { using namespace mcp2515; @@ -303,7 +382,7 @@ modm::Mcp2515::sendMessage(const can::Message& message) spi.transferBlocking(RTS | address); chipSelect.set(); - return address; + return static_cast(address); } // ---------------------------------------------------------------------------- From 10b0e465e41f60a5528ba56f0cc423f1f4f9dfba Mon Sep 17 00:00:00 2001 From: kikass13 Date: Tue, 1 Feb 2022 12:23:17 +0100 Subject: [PATCH 02/29] added example; small line cleanup --- examples/stm32f4_discovery/can_m2515/main.cpp | 99 +++++++++++++++++++ .../stm32f4_discovery/can_m2515/project.xml | 18 ++++ src/modm/driver/can/mcp2515_impl.hpp | 4 +- 3 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 examples/stm32f4_discovery/can_m2515/main.cpp create mode 100644 examples/stm32f4_discovery/can_m2515/project.xml diff --git a/examples/stm32f4_discovery/can_m2515/main.cpp b/examples/stm32f4_discovery/can_m2515/main.cpp new file mode 100644 index 0000000000..882f687175 --- /dev/null +++ b/examples/stm32f4_discovery/can_m2515/main.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013, Kevin Läufer + * Copyright (c) 2013-2017, Niklas Hauser + * Copyright (c) 2016, Raphael Lehmann + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#include +#include +#include + +// If you use a different SPI instance, you may have to also choose different +// GPIOs to connect to. +using Int = GpioOutputB11; +using Cs = GpioOutputB12; +using Sck = GpioOutputB13; +using Mosi = GpioOutputB15; +using Miso = GpioInputB14; +using SpiMaster = SpiMaster2; +// Note that you can also use a bit-banged SPI driver as a drop-in replacement +// using SpiMaster = BitBangSpiMaster; + +// Default filters to receive any extended CAN frame +FLASH_STORAGE(uint8_t canFilter[]) = { + MCP2515_FILTER_EXTENDED(0), // Filter 0 + MCP2515_FILTER_EXTENDED(0), // Filter 1 + + MCP2515_FILTER_EXTENDED(0), // Filter 2 + MCP2515_FILTER_EXTENDED(0), // Filter 3 + MCP2515_FILTER_EXTENDED(0), // Filter 4 + MCP2515_FILTER_EXTENDED(0), // Filter 5 + + MCP2515_FILTER_EXTENDED(0), // Mask 0 + MCP2515_FILTER_EXTENDED(0), // Mask 1 +}; + +modm::Mcp2515 mcp2515; + +class MyTask : modm::pt::Protothread +{ +public: + MyTask() : message_{0x123456} + { + mcp2515.initialize<8_MHz, 125_kbps>(); + mcp2515.setFilter(modm::accessor::asFlash(canFilter)); + } + + bool + run() + { + PT_BEGIN(); + while (true) + { + // send a new message + message_.length = 2; + message_.data[0] = 0xab; + message_.data[1] = 0xcd; + mcp2515.sendMessage(message_); + + if (mcp2515.isMessageAvailable()) + { + mcp2515.getMessage(message_); + MODM_LOG_INFO << "Received message: " << message_.identifier << modm::endl; + } + } + PT_END(); + } + +private: + modm::can::Message message_; +}; + +MyTask task; + +int +main() +{ + Board::initialize(); + + // Initialize SPI interface and the other pins + // needed by the MCP2515 + SpiMaster::connect(); + /// we initialize a higher baud rate then n the avr example, dunnow hats the mcp2515 is capable + /// of + SpiMaster::initialize(); + Cs::setOutput(); + Int::setInput(Gpio::InputType::PullUp); + + // Configure MCP2515 and set the filters + mcp2515.initialize<8_MHz, 125_kbps>(); + + while (true) { task.run(); } +} \ No newline at end of file diff --git a/examples/stm32f4_discovery/can_m2515/project.xml b/examples/stm32f4_discovery/can_m2515/project.xml new file mode 100644 index 0000000000..e7196364d5 --- /dev/null +++ b/examples/stm32f4_discovery/can_m2515/project.xml @@ -0,0 +1,18 @@ + + modm:disco-f407vg + + + + + modm:platform:gpio + modm:platform:spi.bitbang + modm:platform:spi:2 + modm:build:scons + + + modm:processing:protothread + modm:processing:timer + modm:driver:mcp2515 + + + \ No newline at end of file diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index ac73aebe6c..4cb9017596 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -124,7 +124,6 @@ modm::Mcp2515::initialize() using Timings = modm::CanBitTimingMcp2515; // initialize interrrupt on INT pin - modm::platform::Exti::connect(modm::platform::Exti::Trigger::FallingEdge, [](uint8_t){ mcp2515interrupt(); }); @@ -146,8 +145,7 @@ modm::Mcp2515::setFilter(accessor::Flash filter) // change to configuration mode bitModify(CANCTRL, 0xe0, REQOP2); - while ((readRegister(CANSTAT) & 0xe0) != REQOP2) - ; + while ((readRegister(CANSTAT) & 0xe0) != REQOP2); writeRegister(RXB0CTRL, BUKT); writeRegister(RXB1CTRL, 0); From 33db784e6cc4b5ab261b5d2ebf0996e379bc702a Mon Sep 17 00:00:00 2001 From: kikass13 Date: Tue, 1 Feb 2022 12:33:45 +0100 Subject: [PATCH 03/29] added update function to example, change build out dir --- examples/stm32f4_discovery/can_m2515/main.cpp | 1 + examples/stm32f4_discovery/can_m2515/project.xml | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/stm32f4_discovery/can_m2515/main.cpp b/examples/stm32f4_discovery/can_m2515/main.cpp index 882f687175..1856733bad 100644 --- a/examples/stm32f4_discovery/can_m2515/main.cpp +++ b/examples/stm32f4_discovery/can_m2515/main.cpp @@ -68,6 +68,7 @@ class MyTask : modm::pt::Protothread mcp2515.getMessage(message_); MODM_LOG_INFO << "Received message: " << message_.identifier << modm::endl; } + mcp2515.update(); } PT_END(); } diff --git a/examples/stm32f4_discovery/can_m2515/project.xml b/examples/stm32f4_discovery/can_m2515/project.xml index e7196364d5..33e222c2f2 100644 --- a/examples/stm32f4_discovery/can_m2515/project.xml +++ b/examples/stm32f4_discovery/can_m2515/project.xml @@ -1,7 +1,7 @@ modm:disco-f407vg - + modm:platform:gpio @@ -9,7 +9,6 @@ modm:platform:spi:2 modm:build:scons - modm:processing:protothread modm:processing:timer modm:driver:mcp2515 From 21e4036755d342922061bf90eaf108607ac9ac40 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Tue, 1 Feb 2022 13:52:48 +0100 Subject: [PATCH 04/29] added nonblocking stuff for can send api part; the read is still blocking, which should be fine because it is controlled via interrupt --- examples/stm32f4_discovery/can_m2515/main.cpp | 15 +- src/modm/driver/can/mcp2515.hpp | 25 ++- src/modm/driver/can/mcp2515.lb | 2 + src/modm/driver/can/mcp2515_impl.hpp | 186 +++++++++++------- 4 files changed, 145 insertions(+), 83 deletions(-) diff --git a/examples/stm32f4_discovery/can_m2515/main.cpp b/examples/stm32f4_discovery/can_m2515/main.cpp index 1856733bad..992fd02862 100644 --- a/examples/stm32f4_discovery/can_m2515/main.cpp +++ b/examples/stm32f4_discovery/can_m2515/main.cpp @@ -55,20 +55,21 @@ class MyTask : modm::pt::Protothread run() { PT_BEGIN(); + + // send a new message + message_.length = 2; + message_.data[0] = 0xab; + message_.data[1] = 0xcd; + mcp2515.sendMessage(message_); + while (true) { - // send a new message - message_.length = 2; - message_.data[0] = 0xab; - message_.data[1] = 0xcd; - mcp2515.sendMessage(message_); - if (mcp2515.isMessageAvailable()) { mcp2515.getMessage(message_); MODM_LOG_INFO << "Received message: " << message_.identifier << modm::endl; } - mcp2515.update(); + PT_CALL(mcp2515.update()); } PT_END(); } diff --git a/src/modm/driver/can/mcp2515.hpp b/src/modm/driver/can/mcp2515.hpp index 172eb293ea..a0cc047315 100644 --- a/src/modm/driver/can/mcp2515.hpp +++ b/src/modm/driver/can/mcp2515.hpp @@ -20,6 +20,9 @@ #include #include #include +#include +#include +#include #include #include "mcp2515_definitions.hpp" @@ -115,7 +118,7 @@ namespace modm template < typename SPI, typename CS, typename INT > - class Mcp2515 : public ::modm::Can + class Mcp2515 : public ::modm::Can, modm::NestedResumable<4> { public: template @@ -158,7 +161,7 @@ namespace modm * * \return true if the message was send, false otherwise */ - static bool + bool sendMessage(const can::Message& message); /* @@ -166,7 +169,7 @@ namespace modm * * \return true if a message was send this cycle, false otherwise */ - static bool + modm::ResumableResult update(); @@ -201,11 +204,14 @@ namespace modm static bool mcp2515readMessage(can::Message& message); - static bool + bool + mcp2515isReadyToSend(uint8_t status); + + modm::ResumableResult mcp2515isReadyToSend(); - static bool - mcp2515sendMessage(const can::Message& message); + modm::ResumableResult + mcp2515sendMessage(const can::Message& message, const uint8_t status = 0xff); static void writeRegister(uint8_t address, uint8_t data); @@ -216,10 +222,13 @@ namespace modm static void bitModify(uint8_t address, uint8_t mask, uint8_t data); - static uint8_t + modm::ResumableResult readStatus(uint8_t type); - static inline void + static uint8_t + readStatusBlocking(uint8_t type); + + inline modm::ResumableResult writeIdentifier(const uint32_t& identifier, bool isExtendedFrame); static inline bool diff --git a/src/modm/driver/can/mcp2515.lb b/src/modm/driver/can/mcp2515.lb index 6054896d5f..f0c9fcfbb1 100644 --- a/src/modm/driver/can/mcp2515.lb +++ b/src/modm/driver/can/mcp2515.lb @@ -32,6 +32,8 @@ def prepare(module, options): ":architecture:clock", ":architecture:delay", ":architecture:interrupt", + ":processing:protothread", + ":processing:timer", ":platform:exti", ":debug") return True diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index 4cb9017596..a6403fada8 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -39,6 +39,15 @@ CS modm::Mcp2515::chipSelect; template INT modm::Mcp2515::interruptPin; +static uint8_t statusBuffer_; +static uint8_t addressBuffer_; +static uint8_t dataBuffer_; +static uint8_t i_; +static uint8_t a_; +static bool temp_; +static bool hasSend_; +static modm::ShortTimeout delay_; + // ---------------------------------------------------------------------------- template @@ -258,7 +267,7 @@ bool modm::Mcp2515::mcp2515readMessage(can::Message& message){ using namespace mcp2515; - uint8_t status = readStatus(RX_STATUS); + uint8_t status = readStatusBlocking(SpiCommand::RX_STATUS); uint8_t address; if (status & FLAG_RXB0_FULL) { @@ -294,93 +303,123 @@ modm::Mcp2515::mcp2515readMessage(can::Message& message){ } template -bool +modm::ResumableResult modm::Mcp2515::update(){ /// todo /// this should be a timer interrupt using namespace mcp2515; - bool hasSend = false; + RF_BEGIN(); + hasSend_ = false; /// check if device accepts messages and start emptying the transmit queue if not empty if (txQueue.isNotEmpty()) { - if(mcp2515isReadyToSend()){ - hasSend = mcp2515sendMessage(txQueue.get()); + statusBuffer_ = RF_CALL(readStatus(READ_STATUS)); + if(mcp2515isReadyToSend(statusBuffer_)){ + hasSend_ = RF_CALL(mcp2515sendMessage(txQueue.get(), statusBuffer_)); txQueue.pop(); } } - return hasSend; + RF_END_RETURN(hasSend_); } // ---------------------------------------------------------------------------- template -bool +modm::ResumableResult modm::Mcp2515::mcp2515isReadyToSend() { using namespace mcp2515; - if ((readStatus(READ_STATUS) & (TXB2CNTRL_TXREQ | TXB1CNTRL_TXREQ | TXB0CNTRL_TXREQ)) == + RF_BEGIN(); + + temp_ = true; + statusBuffer_ = RF_CALL(readStatus(READ_STATUS)); + if (( statusBuffer_& (TXB2CNTRL_TXREQ | TXB1CNTRL_TXREQ | TXB0CNTRL_TXREQ)) == (TXB2CNTRL_TXREQ | TXB1CNTRL_TXREQ | TXB0CNTRL_TXREQ)) { // all buffers currently in use - return false; + temp_ = false; } - else { - return true; + + RF_END_RETURN(temp_); +} +template +bool +modm::Mcp2515::mcp2515isReadyToSend(uint8_t status) +{ + using namespace mcp2515; + bool ready = true; + if ((status & (TXB2CNTRL_TXREQ | TXB1CNTRL_TXREQ | TXB0CNTRL_TXREQ)) == + (TXB2CNTRL_TXREQ | TXB1CNTRL_TXREQ | TXB0CNTRL_TXREQ)) + { + // all buffers currently in use + ready = false; } + + return ready; } // ---------------------------------------------------------------------------- template -bool -modm::Mcp2515::mcp2515sendMessage(const can::Message& message) +modm::ResumableResult +modm::Mcp2515::mcp2515sendMessage(const can::Message& message, const uint8_t status) { - using namespace mcp2515; + using namespace modm::mcp2515; + RF_BEGIN(); - uint8_t status = readStatus(READ_STATUS); - uint8_t address; - if ((status & TXB0CNTRL_TXREQ) == 0) { - address = 0x00; // TXB0SIDH + /// dont read status again if we have been provided one + if(status == 0xff){ + statusBuffer_ = RF_CALL(readStatus(READ_STATUS)); } - else if ((status & TXB1CNTRL_TXREQ) == 0) { - address = 0x02; // TXB1SIDH + else{ + statusBuffer_ = status; } - else if ((status & TXB2CNTRL_TXREQ) == 0) { - address = 0x04; // TXB2SIDH - } - else { + + if ((statusBuffer_ & TXB0CNTRL_TXREQ) == 0) + { + addressBuffer_ = 0x00; // TXB0SIDH + } else if ((statusBuffer_ & TXB1CNTRL_TXREQ) == 0) + { + addressBuffer_ = 0x02; // TXB1SIDH + } else if ((statusBuffer_ & TXB2CNTRL_TXREQ) == 0) + { + addressBuffer_ = 0x04; // TXB2SIDH + } else + { // all buffer are in use => could not send the message - return false; } - chipSelect.reset(); - spi.transferBlocking(WRITE_TX | address); - writeIdentifier(message.identifier, message.flags.extended); + if (addressBuffer_ == 0x00 || addressBuffer_ == 0x02 || addressBuffer_ == 0x04) + { + chipSelect.reset(); + RF_CALL(spi.transfer(WRITE_TX | addressBuffer_)); + RF_CALL(writeIdentifier(message.identifier, message.flags.extended)); - // if the message is a rtr-frame, is has a length but no attached data - if (message.flags.rtr) { - spi.transferBlocking(MCP2515_RTR | message.length); - } - else { - spi.transferBlocking(message.length); + // if the message is a rtr-frame, is has a length but no attached data + if (message.flags.rtr) + { + RF_CALL(spi.transfer(MCP2515_RTR | message.length)); + } else + { + RF_CALL(spi.transfer(message.length)); - for (uint8_t i = 0; i < message.length; ++i) { - spi.transferBlocking(message.data[i]); + for (i_ = 0; i_ < message.length; ++i_) { + RF_CALL(spi.transfer(message.data[i_])); + } } - } - chipSelect.set(); - - modm::delay_us(1); - - // send message via RTS command - chipSelect.reset(); - address = (address == 0) ? 1 : address; // 0 2 4 => 1 2 4 - spi.transferBlocking(RTS | address); - chipSelect.set(); + delay_.restart(1ms); + chipSelect.set(); + RF_WAIT_UNTIL(delay_.isExpired()); - return static_cast(address); + // send message via RTS command + chipSelect.reset(); + addressBuffer_ = (addressBuffer_ == 0) ? 1 : addressBuffer_; // 0 2 4 => 1 2 4 + RF_CALL(spi.transfer(RTS | addressBuffer_)); + chipSelect.set(); + } + RF_END_RETURN(static_cast(addressBuffer_)); } // ---------------------------------------------------------------------------- @@ -428,51 +467,62 @@ modm::Mcp2515::bitModify(uint8_t address, uint8_t mask, uint8_t da } template -uint8_t +modm::ResumableResult modm::Mcp2515::readStatus(uint8_t type) { + RF_BEGIN(); + chipSelect.reset(); + dataBuffer_ = RF_CALL(spi.transfer(type)); + RF_CALL(spi.transfer(0xff)); + chipSelect.set(); - spi.transferBlocking(type); - uint8_t data = spi.transferBlocking(0xff); + RF_END_RETURN(dataBuffer_); +} +template +uint8_t +modm::Mcp2515::readStatusBlocking(uint8_t type) +{ + chipSelect.reset(); + uint8_t data = spi.transferBlocking(type); + spi.transferBlocking(0xff); chipSelect.set(); - return data; } + // ---------------------------------------------------------------------------- template -void +modm::ResumableResult modm::Mcp2515::writeIdentifier(const uint32_t& identifier, bool isExtendedFrame) { using namespace mcp2515; - const uint32_t *ptr = &identifier; + RF_BEGIN(); + if (isExtendedFrame) { - spi.transferBlocking(*((uint16_t *) ptr + 1) >> 5); + RF_CALL(spi.transfer(*((uint16_t *)ptr + 1) >> 5)); // calculate the next values - uint8_t temp; - temp = (*((uint8_t *) ptr + 2) << 3) & 0xe0; - temp |= MCP2515_IDE; - temp |= (*((uint8_t *) ptr + 2)) & 0x03; - - spi.transferBlocking(temp); - spi.transferBlocking(*((uint8_t *) ptr + 1)); - spi.transferBlocking(*((uint8_t *) ptr)); - } - else + a_ = (*((uint8_t *)ptr + 2) << 3) & 0xe0; + a_ |= MCP2515_IDE; + a_ |= (*((uint8_t *)ptr + 2)) & 0x03; + RF_CALL(spi.transfer(a_)); + RF_CALL(spi.transfer(*((uint8_t *)ptr + 1))); + RF_CALL(spi.transfer(*((uint8_t *)ptr))); + } else { - spi.transferBlocking(*((uint16_t *) ptr) >> 3); - spi.transferBlocking(*((uint8_t *) ptr) << 5); - spi.transferBlocking(0); - spi.transferBlocking(0); + RF_CALL(spi.transfer(*((uint16_t *)ptr) >> 3)); + RF_CALL(spi.transfer(*((uint8_t *)ptr) << 5)); + RF_CALL(spi.transfer(0)); + RF_CALL(spi.transfer(0)); } + RF_END(); } template From 03639b486f0311da600ee03217888ca4147dc9ab Mon Sep 17 00:00:00 2001 From: kikass13 Date: Tue, 1 Feb 2022 21:08:17 +0100 Subject: [PATCH 05/29] changed read/receive part so that it is polled in the update function as well; fixed some things in example --- examples/stm32f4_discovery/can_m2515/main.cpp | 17 +- src/modm/driver/can/mcp2515.hpp | 17 +- src/modm/driver/can/mcp2515_impl.hpp | 179 +++++++++--------- 3 files changed, 101 insertions(+), 112 deletions(-) diff --git a/examples/stm32f4_discovery/can_m2515/main.cpp b/examples/stm32f4_discovery/can_m2515/main.cpp index 992fd02862..23d735f0cb 100644 --- a/examples/stm32f4_discovery/can_m2515/main.cpp +++ b/examples/stm32f4_discovery/can_m2515/main.cpp @@ -45,17 +45,17 @@ modm::Mcp2515 mcp2515; class MyTask : modm::pt::Protothread { public: - MyTask() : message_{0x123456} - { - mcp2515.initialize<8_MHz, 125_kbps>(); - mcp2515.setFilter(modm::accessor::asFlash(canFilter)); - } + MyTask() : message_{0x123456}{} bool run() { PT_BEGIN(); + // Configure MCP2515 and set the filters + mcp2515.initialize<8_MHz, 125_kbps>(); + mcp2515.setFilter(modm::accessor::asFlash(canFilter)); + // send a new message message_.length = 2; message_.data[0] = 0xab; @@ -94,8 +94,7 @@ main() Cs::setOutput(); Int::setInput(Gpio::InputType::PullUp); - // Configure MCP2515 and set the filters - mcp2515.initialize<8_MHz, 125_kbps>(); - - while (true) { task.run(); } + while (true) { + task.run(); + } } \ No newline at end of file diff --git a/src/modm/driver/can/mcp2515.hpp b/src/modm/driver/can/mcp2515.hpp index a0cc047315..e25f857d23 100644 --- a/src/modm/driver/can/mcp2515.hpp +++ b/src/modm/driver/can/mcp2515.hpp @@ -199,19 +199,19 @@ namespace modm }; static void - mcp2515interrupt(); + mcp2515Interrupt(); - static bool - mcp2515readMessage(can::Message& message); + modm::ResumableResult + mcp2515ReadMessage(can::Message& message, uint8_t status = 0xff); bool - mcp2515isReadyToSend(uint8_t status); + mcp2515IsReadyToSend(uint8_t status); modm::ResumableResult - mcp2515isReadyToSend(); + mcp2515IsReadyToSend(); modm::ResumableResult - mcp2515sendMessage(const can::Message& message, const uint8_t status = 0xff); + mcp2515SendMessage(const can::Message& message, uint8_t status = 0xff); static void writeRegister(uint8_t address, uint8_t data); @@ -225,13 +225,10 @@ namespace modm modm::ResumableResult readStatus(uint8_t type); - static uint8_t - readStatusBlocking(uint8_t type); - inline modm::ResumableResult writeIdentifier(const uint32_t& identifier, bool isExtendedFrame); - static inline bool + inline modm::ResumableResult readIdentifier(uint32_t& identifier); protected: diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index a6403fada8..c9253f7df7 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -20,8 +20,6 @@ #include "mcp2515_definitions.hpp" #include #include -#include -#include #undef MODM_LOG_LEVEL #define MODM_LOG_LEVEL modm::log::DISABLED @@ -42,9 +40,12 @@ INT modm::Mcp2515::interruptPin; static uint8_t statusBuffer_; static uint8_t addressBuffer_; static uint8_t dataBuffer_; +static modm::can::Message messageBuffer_; static uint8_t i_; static uint8_t a_; +static uint8_t b_; static bool temp_; +static bool temp2_; static bool hasSend_; static modm::ShortTimeout delay_; @@ -132,11 +133,6 @@ modm::Mcp2515::initialize() { using Timings = modm::CanBitTimingMcp2515; - // initialize interrrupt on INT pin - modm::platform::Exti::connect(modm::platform::Exti::Trigger::FallingEdge, [](uint8_t){ - mcp2515interrupt(); - }); - return initializeWithPrescaler( Timings::getPrescaler(), Timings::getSJW(), @@ -250,56 +246,52 @@ modm::Mcp2515::sendMessage(const can::Message& message) // ---------------------------------------------------------------------------- template -void -modm::Mcp2515::mcp2515interrupt(){ +modm::ResumableResult +modm::Mcp2515::mcp2515ReadMessage(can::Message& message, uint8_t status) +{ using namespace mcp2515; - can::Message message; - bool success = mcp2515readMessage(message); - if(success){ - modm_assert_continue_ignore(rxQueue.push(message), "mcp2515.can.rx.sw0", - "CAN receive software buffer overflowed!", 1); - } -} - -template -bool -modm::Mcp2515::mcp2515readMessage(can::Message& message){ - using namespace mcp2515; + RF_BEGIN(); - uint8_t status = readStatusBlocking(SpiCommand::RX_STATUS); - uint8_t address; + temp_ = true; + // dont read status again if we have been provided one + if(status == 0xff){ + status = RF_CALL(readStatus(READ_STATUS)); + } if (status & FLAG_RXB0_FULL) { - address = READ_RX; // message in buffer 0 + addressBuffer_ = READ_RX; // message in buffer 0 } else if (status & FLAG_RXB1_FULL) { - address = READ_RX | 0x04; // message in buffer 1 (RXB1SIDH) + addressBuffer_ = READ_RX | 0x04; // message in buffer 1 (RXB1SIDH) } else { - return false; // Error: no message available + temp_ = false; // Error: no message available } - chipSelect.reset(); - spi.transferBlocking(address); + if(temp_) + { + chipSelect.reset(); + RF_CALL(spi.transfer(addressBuffer_)); - message.flags.extended = readIdentifier(message.identifier); - if (status & FLAG_RTR) { - message.flags.rtr = true; - } - else { - message.flags.rtr = false; - } - message.length = spi.transferBlocking(0xff) & 0x0f; + message.flags.extended = RF_CALL(readIdentifier(message.identifier)); + if (status & FLAG_RTR) { + message.flags.rtr = true; + } + else { + message.flags.rtr = false; + } + message.length = RF_CALL(spi.transfer(0xff)) & 0x0f; - for (uint8_t i = 0; i < message.length; ++i) { - message.data[i] = spi.transferBlocking(0xff); - } - chipSelect.set(); + for (i_ = 0; i_ < message.length; ++i_) { + message.data[i_] = RF_CALL(spi.transfer(0xff)); + } + chipSelect.set(); + } // RX0IF or RX1IF respectivly were already cleared automatically by rising CS. // See section 12.4 in datasheet. - return true; + RF_END_RETURN(temp_); } template @@ -310,24 +302,38 @@ modm::Mcp2515::update(){ using namespace mcp2515; RF_BEGIN(); - hasSend_ = false; + + // read status flag of the device + statusBuffer_ = RF_CALL(readStatus(READ_STATUS)); + + // check if the device has received a message(pin = LOW) + // if yes: read it and put it into the rxQueue + if(!interruptPin.read()){ + if(RF_CALL(mcp2515ReadMessage(messageBuffer_, statusBuffer_))) + { + if(not modm_assert_continue_ignore(rxQueue.push(messageBuffer_), "mcp2515.can.tx", + "CAN transmit software buffer overflowed!", 1)){ + /// ignore + } + } + } + /// check if device accepts messages and start emptying the transmit queue if not empty if (txQueue.isNotEmpty()) { - statusBuffer_ = RF_CALL(readStatus(READ_STATUS)); - if(mcp2515isReadyToSend(statusBuffer_)){ - hasSend_ = RF_CALL(mcp2515sendMessage(txQueue.get(), statusBuffer_)); + if(mcp2515IsReadyToSend(statusBuffer_)){ + hasSend_ = RF_CALL(mcp2515SendMessage(txQueue.get(), statusBuffer_)); txQueue.pop(); } } - RF_END_RETURN(hasSend_); + RF_END(); } // ---------------------------------------------------------------------------- template modm::ResumableResult -modm::Mcp2515::mcp2515isReadyToSend() +modm::Mcp2515::mcp2515IsReadyToSend() { using namespace mcp2515; @@ -346,7 +352,7 @@ modm::Mcp2515::mcp2515isReadyToSend() } template bool -modm::Mcp2515::mcp2515isReadyToSend(uint8_t status) +modm::Mcp2515::mcp2515IsReadyToSend(uint8_t status) { using namespace mcp2515; bool ready = true; @@ -364,26 +370,23 @@ modm::Mcp2515::mcp2515isReadyToSend(uint8_t status) template modm::ResumableResult -modm::Mcp2515::mcp2515sendMessage(const can::Message& message, const uint8_t status) +modm::Mcp2515::mcp2515SendMessage(const can::Message& message, uint8_t status) { using namespace modm::mcp2515; RF_BEGIN(); - /// dont read status again if we have been provided one + // dont read status again if we have been provided one if(status == 0xff){ - statusBuffer_ = RF_CALL(readStatus(READ_STATUS)); - } - else{ - statusBuffer_ = status; + status = RF_CALL(readStatus(READ_STATUS)); } - if ((statusBuffer_ & TXB0CNTRL_TXREQ) == 0) + if ((status & TXB0CNTRL_TXREQ) == 0) { addressBuffer_ = 0x00; // TXB0SIDH - } else if ((statusBuffer_ & TXB1CNTRL_TXREQ) == 0) + } else if ((status & TXB1CNTRL_TXREQ) == 0) { addressBuffer_ = 0x02; // TXB1SIDH - } else if ((statusBuffer_ & TXB2CNTRL_TXREQ) == 0) + } else if ((status & TXB2CNTRL_TXREQ) == 0) { addressBuffer_ = 0x04; // TXB2SIDH } else @@ -480,18 +483,6 @@ modm::Mcp2515::readStatus(uint8_t type) RF_END_RETURN(dataBuffer_); } -template -uint8_t -modm::Mcp2515::readStatusBlocking(uint8_t type) -{ - chipSelect.reset(); - uint8_t data = spi.transferBlocking(type); - spi.transferBlocking(0xff); - chipSelect.set(); - return data; -} - - // ---------------------------------------------------------------------------- template @@ -525,42 +516,44 @@ modm::Mcp2515::writeIdentifier(const uint32_t& identifier, RF_END(); } -template -bool -modm::Mcp2515::readIdentifier(uint32_t& identifier) +template +modm::ResumableResult +modm::Mcp2515::readIdentifier(uint32_t &identifier) { using namespace mcp2515; + const uint32_t *ptr = &identifier; + + RF_BEGIN(); - uint32_t *ptr = &identifier; + a_ = RF_CALL(spi.transfer(0xff)); + b_ = RF_CALL(spi.transfer(0xff)); - uint8_t first = spi.transferBlocking(0xff); - uint8_t second = spi.transferBlocking(0xff); + temp2_ = false; - if (second & MCP2515_IDE) + if (b_ & MCP2515_IDE) { - *((uint16_t *) ptr + 1) = (uint16_t) first << 5; - *((uint8_t *) ptr + 1) = spi.transferBlocking(0xff); + *((uint16_t *)ptr + 1) = (uint16_t)a_ << 5; + *((uint8_t *)ptr + 1) = RF_CALL(spi.transfer(0xff)); - *((uint8_t *) ptr + 2) |= (second >> 3) & 0x1C; - *((uint8_t *) ptr + 2) |= second & 0x03; + *((uint8_t *)ptr + 2) |= (b_ >> 3) & 0x1C; + *((uint8_t *)ptr + 2) |= b_ & 0x03; - *((uint8_t *) ptr) = spi.transferBlocking(0xff); + *((uint8_t *)ptr) = RF_CALL(spi.transfer(0xff)); - return true; - } - else + temp2_ = true; + } else { - spi.transferBlocking(0xff); - - *((uint8_t *) ptr + 3) = 0; - *((uint8_t *) ptr + 2) = 0; + RF_CALL(spi.transfer(0xff)); - *((uint16_t *) ptr) = (uint16_t) first << 3; + *((uint8_t *)ptr + 3) = 0; + *((uint8_t *)ptr + 2) = 0; - spi.transferBlocking(0xff); + *((uint16_t *)ptr) = (uint16_t)a_ << 3; - *((uint8_t *) ptr) |= second >> 5; + RF_CALL(spi.transfer(0xff)); - return false; + *((uint8_t *)ptr) |= b_ >> 5; } -} + + RF_END_RETURN(temp2_); +} \ No newline at end of file From bf7b0faf52cdf0553e876856887ca46af8639a80 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Thu, 3 Feb 2022 14:48:41 +0100 Subject: [PATCH 06/29] the should now be non static (the rx/tx queues as well); a modm::SpiDevice is now used internally for aquiring / releasing the bus whenever accessed --- src/modm/driver/can/mcp2515.hpp | 47 +++++++++++-------- src/modm/driver/can/mcp2515_impl.hpp | 69 +++++++++++++++++----------- 2 files changed, 69 insertions(+), 47 deletions(-) diff --git a/src/modm/driver/can/mcp2515.hpp b/src/modm/driver/can/mcp2515.hpp index e25f857d23..1e620ecd4f 100644 --- a/src/modm/driver/can/mcp2515.hpp +++ b/src/modm/driver/can/mcp2515.hpp @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include #include @@ -118,15 +120,17 @@ namespace modm template < typename SPI, typename CS, typename INT > - class Mcp2515 : public ::modm::Can, modm::NestedResumable<4> + class Mcp2515 : public ::modm::Can, + public ::modm::SpiDevice, + protected ::modm::NestedResumable<4> { public: template - static inline bool + bool initialize(); private: - static inline bool + bool initializeWithPrescaler( uint8_t prescaler, uint8_t sjw, @@ -135,17 +139,17 @@ namespace modm uint8_t ps2); public: - static void + void setFilter(accessor::Flash filter); - static void + void setMode(Can::Mode mode); - static inline bool + inline bool isMessageAvailable(); - static bool + bool getMessage(can::Message& message, uint8_t *filter_id=nullptr); /* @@ -153,7 +157,7 @@ namespace modm * * \return true if a slot is available, false otherwise */ - static inline bool + bool isReadyToSend(); /* @@ -179,12 +183,12 @@ namespace modm /* * Fixme: Empty implementation, required by connector */ - static BusState + BusState getBusState() { return BusState::Connected; } - protected: + private: enum SpiCommand { RESET = 0xC0, @@ -198,7 +202,7 @@ namespace modm BIT_MODIFY = 0x05 }; - static void + void mcp2515Interrupt(); modm::ResumableResult @@ -213,28 +217,31 @@ namespace modm modm::ResumableResult mcp2515SendMessage(const can::Message& message, uint8_t status = 0xff); - static void + void writeRegister(uint8_t address, uint8_t data); - static uint8_t + uint8_t readRegister(uint8_t address); - static void + void bitModify(uint8_t address, uint8_t mask, uint8_t data); modm::ResumableResult readStatus(uint8_t type); - inline modm::ResumableResult + modm::ResumableResult writeIdentifier(const uint32_t& identifier, bool isExtendedFrame); - inline modm::ResumableResult + modm::ResumableResult readIdentifier(uint32_t& identifier); - protected: - static SPI spi; - static CS chipSelect; - static INT interruptPin; + private: + modm::atomic::Queue txQueue; + modm::atomic::Queue rxQueue; + + SPI spi; + CS chipSelect; + INT interruptPin; }; } diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index c9253f7df7..fdf7030ced 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -18,24 +18,13 @@ #endif #include "mcp2515_bit_timings.hpp" #include "mcp2515_definitions.hpp" -#include #include #undef MODM_LOG_LEVEL #define MODM_LOG_LEVEL modm::log::DISABLED -static modm::atomic::Queue txQueue; -static modm::atomic::Queue rxQueue; // ---------------------------------------------------------------------------- -template -SPI modm::Mcp2515::spi; - -template -CS modm::Mcp2515::chipSelect; - -template -INT modm::Mcp2515::interruptPin; static uint8_t statusBuffer_; static uint8_t addressBuffer_; @@ -81,6 +70,7 @@ modm::Mcp2515::initializeWithPrescaler( using namespace mcp2515; + while(!this->acquireMaster()){}; // software reset for the mcp2515, after this the chip is back in the // configuration mode chipSelect.reset(); @@ -101,7 +91,9 @@ modm::Mcp2515::initializeWithPrescaler( // enable interrupts spi.transferBlocking(RX1IE | RX0IE); chipSelect.set(); - + if(this->releaseMaster()){ + chipSelect.set(); + } // set TXnRTS pins as inwrites writeRegister(TXRTSCTRL, 0); @@ -155,6 +147,7 @@ modm::Mcp2515::setFilter(accessor::Flash filter) writeRegister(RXB0CTRL, BUKT); writeRegister(RXB1CTRL, 0); + while(!this->acquireMaster()){}; uint8_t i, j; for (i = 0; i < 0x30; i += 0x10) { @@ -171,7 +164,9 @@ modm::Mcp2515::setFilter(accessor::Flash filter) } chipSelect.set(); } - + if(this->releaseMaster()){ + chipSelect.set(); + } bitModify(CANCTRL, 0xe0, 0); } @@ -271,6 +266,7 @@ modm::Mcp2515::mcp2515ReadMessage(can::Message& message, uint8_t s if(temp_) { + RF_WAIT_UNTIL(this->acquireMaster()); chipSelect.reset(); RF_CALL(spi.transfer(addressBuffer_)); @@ -286,8 +282,9 @@ modm::Mcp2515::mcp2515ReadMessage(can::Message& message, uint8_t s for (i_ = 0; i_ < message.length; ++i_) { message.data[i_] = RF_CALL(spi.transfer(0xff)); } - chipSelect.set(); - + if(this->releaseMaster()){ + chipSelect.set(); + } } // RX0IF or RX1IF respectivly were already cleared automatically by rising CS. // See section 12.4 in datasheet. @@ -396,6 +393,7 @@ modm::Mcp2515::mcp2515SendMessage(const can::Message& message, uin if (addressBuffer_ == 0x00 || addressBuffer_ == 0x02 || addressBuffer_ == 0x04) { + RF_WAIT_UNTIL(this->acquireMaster()); chipSelect.reset(); RF_CALL(spi.transfer(WRITE_TX | addressBuffer_)); RF_CALL(writeIdentifier(message.identifier, message.flags.extended)); @@ -420,8 +418,11 @@ modm::Mcp2515::mcp2515SendMessage(const can::Message& message, uin chipSelect.reset(); addressBuffer_ = (addressBuffer_ == 0) ? 1 : addressBuffer_; // 0 2 4 => 1 2 4 RF_CALL(spi.transfer(RTS | addressBuffer_)); - chipSelect.set(); + if(this->releaseMaster()){ + chipSelect.set(); + } } + RF_END_RETURN(static_cast(addressBuffer_)); } @@ -431,27 +432,28 @@ template void modm::Mcp2515::writeRegister(uint8_t address, uint8_t data) { + while(!this->acquireMaster()){}; chipSelect.reset(); - spi.transferBlocking(WRITE); spi.transferBlocking(address); spi.transferBlocking(data); - - chipSelect.set(); + if(this->releaseMaster()){ + chipSelect.set(); + } } template uint8_t modm::Mcp2515::readRegister(uint8_t address) { + while(!this->acquireMaster()){}; chipSelect.reset(); - spi.transferBlocking(READ); spi.transferBlocking(address); uint8_t data = spi.transferBlocking(0xff); - - chipSelect.set(); - + if(this->releaseMaster()){ + chipSelect.set(); + } return data; } @@ -459,14 +461,15 @@ template void modm::Mcp2515::bitModify(uint8_t address, uint8_t mask, uint8_t data) { + while(!this->acquireMaster()){}; chipSelect.reset(); - spi.transferBlocking(BIT_MODIFY); spi.transferBlocking(address); spi.transferBlocking(mask); spi.transferBlocking(data); - - chipSelect.set(); + if(this->releaseMaster()){ + chipSelect.set(); + } } template @@ -475,10 +478,13 @@ modm::Mcp2515::readStatus(uint8_t type) { RF_BEGIN(); + RF_WAIT_UNTIL(this->acquireMaster()); chipSelect.reset(); dataBuffer_ = RF_CALL(spi.transfer(type)); RF_CALL(spi.transfer(0xff)); - chipSelect.set(); + if(this->releaseMaster()) { + chipSelect.set(); + } RF_END_RETURN(dataBuffer_); } @@ -495,6 +501,7 @@ modm::Mcp2515::writeIdentifier(const uint32_t& identifier, RF_BEGIN(); + RF_WAIT_UNTIL(this->acquireMaster()); if (isExtendedFrame) { RF_CALL(spi.transfer(*((uint16_t *)ptr + 1) >> 5)); @@ -513,6 +520,10 @@ modm::Mcp2515::writeIdentifier(const uint32_t& identifier, RF_CALL(spi.transfer(0)); RF_CALL(spi.transfer(0)); } + if(this->releaseMaster()) { + chipSelect.set(); + } + RF_END(); } @@ -525,6 +536,7 @@ modm::Mcp2515::readIdentifier(uint32_t &identifier) RF_BEGIN(); + RF_WAIT_UNTIL(this->acquireMaster()); a_ = RF_CALL(spi.transfer(0xff)); b_ = RF_CALL(spi.transfer(0xff)); @@ -554,6 +566,9 @@ modm::Mcp2515::readIdentifier(uint32_t &identifier) *((uint8_t *)ptr) |= b_ >> 5; } + if(this->releaseMaster()){ + chipSelect.set(); + } RF_END_RETURN(temp2_); } \ No newline at end of file From 9584f2228f9fc704854cd80838e7ff93bff27f04 Mon Sep 17 00:00:00 2001 From: Christopher Durand Date: Wed, 2 Feb 2022 00:40:01 +0100 Subject: [PATCH 07/29] WIP: Add SPI user configuration handler for speed reconfiguration --- .../architecture/interface/spi_device.hpp | 25 ++++++++++++++----- src/modm/platform/spi/stm32/spi_hal.hpp.in | 3 +++ .../platform/spi/stm32/spi_hal_impl.hpp.in | 6 +++++ src/modm/platform/spi/stm32/spi_master.cpp.in | 4 +-- src/modm/platform/spi/stm32/spi_master.hpp.in | 19 +++++++++++++- 5 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/modm/architecture/interface/spi_device.hpp b/src/modm/architecture/interface/spi_device.hpp index 89ac49b7b4..2f92c5f4e3 100644 --- a/src/modm/architecture/interface/spi_device.hpp +++ b/src/modm/architecture/interface/spi_device.hpp @@ -30,25 +30,38 @@ namespace modm template < class SpiMaster > class SpiDevice { - Spi::ConfigurationHandler configuration; + Spi::ConfigurationHandler configuration{nullptr}; + Spi::ConfigurationHandler userConfiguration{nullptr}; public: - SpiDevice() - : configuration(nullptr) + void inline + attachConfigurationHandler(Spi::ConfigurationHandler handler) { + configuration = handler; } void inline - attachConfigurationHandler(Spi::ConfigurationHandler handler) + attachUserConfigurationHandler(Spi::ConfigurationHandler handler) { - configuration = handler; + userConfiguration = handler; } + inline Spi::ConfigurationHandler + configurationHandler() { return configuration; } + + inline Spi::ConfigurationHandler + userConfigurationHandler() { return userConfiguration; } + protected: bool inline acquireMaster() { - return (SpiMaster::acquire(this, configuration) != 0); + const auto handler = +[](void* context) { + const auto& device = *static_cast(context); + if (device.configuration) device.configuration(); + if (device.userConfiguration) device.userConfiguration(); + }; + return (SpiMaster::acquire(this, handler) != 0); } bool inline diff --git a/src/modm/platform/spi/stm32/spi_hal.hpp.in b/src/modm/platform/spi/stm32/spi_hal.hpp.in index cac0022289..9662c9fce2 100644 --- a/src/modm/platform/spi/stm32/spi_hal.hpp.in +++ b/src/modm/platform/spi/stm32/spi_hal.hpp.in @@ -68,6 +68,9 @@ public: static void setMasterSelection(MasterSelection masterSelection); + static void + setPrescaler(Prescaler prescaler); + %% if "fifo" in features static void setRxFifoThreshold(RxFifoThreshold threshold); diff --git a/src/modm/platform/spi/stm32/spi_hal_impl.hpp.in b/src/modm/platform/spi/stm32/spi_hal_impl.hpp.in index c75a7667c7..d0be238559 100644 --- a/src/modm/platform/spi/stm32/spi_hal_impl.hpp.in +++ b/src/modm/platform/spi/stm32/spi_hal_impl.hpp.in @@ -63,6 +63,12 @@ modm::platform::SpiHal{{ id }}::initialize(Prescaler prescaler, SPI{{ id }}->CR1 |= SPI_CR1_SPE; } +void inline +modm::platform::SpiHal{{ id }}::setPrescaler(Prescaler prescaler) +{ + SPI{{ id }}->CR1 = (SPI{{ id }}->CR1 & ~SPI_CR1_BR_Msk) | static_cast(prescaler); +} + void inline modm::platform::SpiHal{{ id }}::setDataMode(DataMode dataMode) { diff --git a/src/modm/platform/spi/stm32/spi_master.cpp.in b/src/modm/platform/spi/stm32/spi_master.cpp.in index b31a39c0de..a02150b4ad 100644 --- a/src/modm/platform/spi/stm32/spi_master.cpp.in +++ b/src/modm/platform/spi/stm32/spi_master.cpp.in @@ -27,8 +27,6 @@ modm::platform::SpiMaster{{ id }}::count(0); void * modm::platform::SpiMaster{{ id }}::context(nullptr); -modm::Spi::ConfigurationHandler -modm::platform::SpiMaster{{ id }}::configuration(nullptr); // ---------------------------------------------------------------------------- uint8_t @@ -41,7 +39,7 @@ modm::platform::SpiMaster{{ id }}::acquire(void *ctx, ConfigurationHandler handl // if handler is not nullptr and is different from previous configuration if (handler and configuration != handler) { configuration = handler; - configuration(); + configuration(ctx); } return 1; } diff --git a/src/modm/platform/spi/stm32/spi_master.hpp.in b/src/modm/platform/spi/stm32/spi_master.hpp.in index 94bd6887f4..3a956dbb2f 100644 --- a/src/modm/platform/spi/stm32/spi_master.hpp.in +++ b/src/modm/platform/spi/stm32/spi_master.hpp.in @@ -41,7 +41,11 @@ class SpiMaster{{ id }} : public modm::SpiMaster static uint8_t state; static uint8_t count; static void *context; - static ConfigurationHandler configuration; + + // HACK override handler type, for demo only + using ConfigurationHandler = void(*)(void*); + + static inline ConfigurationHandler configuration; public: using Hal = SpiHal{{ id }}; @@ -99,6 +103,19 @@ public: state = 0; } + template< class SystemClock, baudrate_t baudrate, percent_t tolerance=pct(5) > + static void + setBaudrate() + { + constexpr auto result = modm::Prescaler::from_power(SystemClock::Spi{{ id }}, baudrate, 2, 256); + assertBaudrateInTolerance< result.frequency, baudrate, tolerance >(); + + // translate the prescaler into the bitmapping + constexpr SpiHal{{ id }}::Prescaler prescaler{result.index << SPI_CR1_BR_Pos}; + + SpiHal{{ id }}::setPrescaler(prescaler); + } + static modm_always_inline void setDataMode(DataMode mode) { From 8e6a52f2f370f77758293599390f70acf35de652 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Thu, 3 Feb 2022 15:17:56 +0100 Subject: [PATCH 08/29] added configurationHanlder for spi device, which should also change the spi clock frequency when master is acquired --- examples/stm32f4_discovery/can_m2515/main.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/stm32f4_discovery/can_m2515/main.cpp b/examples/stm32f4_discovery/can_m2515/main.cpp index 23d735f0cb..16a34f56d7 100644 --- a/examples/stm32f4_discovery/can_m2515/main.cpp +++ b/examples/stm32f4_discovery/can_m2515/main.cpp @@ -53,6 +53,12 @@ class MyTask : modm::pt::Protothread PT_BEGIN(); // Configure MCP2515 and set the filters + mcp2515.attachConfigurationHandler([]() { + SpiMaster::setDataMode(SpiMaster::DataMode::Mode0); + SpiMaster::setDataOrder(SpiMaster::DataOrder::MsbFirst); + /// @chris-durand + SpiMaster::setBaudrate(); + }); mcp2515.initialize<8_MHz, 125_kbps>(); mcp2515.setFilter(modm::accessor::asFlash(canFilter)); From bda5887913dceb9723434883d0d1e31824c53d2c Mon Sep 17 00:00:00 2001 From: kikass13 Date: Fri, 4 Feb 2022 01:46:51 +0100 Subject: [PATCH 09/29] moved example to nucleo_f439; fixed example to work properly --- .../can_m2515/main.cpp | 63 +++++++++++++------ .../can_m2515/project.xml | 3 +- src/modm/driver/can/mcp2515.hpp | 6 +- src/modm/driver/can/mcp2515.lb | 1 + src/modm/driver/can/mcp2515_impl.hpp | 13 ++-- 5 files changed, 56 insertions(+), 30 deletions(-) rename examples/{stm32f4_discovery => nucleo_f439zi}/can_m2515/main.cpp (62%) rename examples/{stm32f4_discovery => nucleo_f439zi}/can_m2515/project.xml (85%) diff --git a/examples/stm32f4_discovery/can_m2515/main.cpp b/examples/nucleo_f439zi/can_m2515/main.cpp similarity index 62% rename from examples/stm32f4_discovery/can_m2515/main.cpp rename to examples/nucleo_f439zi/can_m2515/main.cpp index 16a34f56d7..1cd6a943f7 100644 --- a/examples/stm32f4_discovery/can_m2515/main.cpp +++ b/examples/nucleo_f439zi/can_m2515/main.cpp @@ -12,17 +12,26 @@ // ---------------------------------------------------------------------------- #include +#include +#include #include #include + +#define SENDER 0 + +// Set the log level +#undef MODM_LOG_LEVEL +#define MODM_LOG_LEVEL modm::log::DISABLED + // If you use a different SPI instance, you may have to also choose different // GPIOs to connect to. -using Int = GpioOutputB11; -using Cs = GpioOutputB12; -using Sck = GpioOutputB13; -using Mosi = GpioOutputB15; -using Miso = GpioInputB14; -using SpiMaster = SpiMaster2; +using Cs = GpioOutputA4; +using Mosi = GpioOutputB5; +using Miso = GpioInputB4; +using Sck = GpioOutputB3; +using Int = GpioInputC7; +using SpiMaster = SpiMaster1; // Note that you can also use a bit-banged SPI driver as a drop-in replacement // using SpiMaster = BitBangSpiMaster; @@ -45,43 +54,58 @@ modm::Mcp2515 mcp2515; class MyTask : modm::pt::Protothread { public: - MyTask() : message_{0x123456}{} + MyTask() : message_{0x1337}{} bool run() { PT_BEGIN(); + MODM_LOG_INFO << "Initializing mcp2515 ..." << modm::endl; // Configure MCP2515 and set the filters mcp2515.attachConfigurationHandler([]() { - SpiMaster::setDataMode(SpiMaster::DataMode::Mode0); + SpiMaster::setDataMode(SpiMaster::DataMode::Mode3); SpiMaster::setDataOrder(SpiMaster::DataOrder::MsbFirst); /// @chris-durand - SpiMaster::setBaudrate(); + // SpiMaster::setBaudrate(); }); - mcp2515.initialize<8_MHz, 125_kbps>(); + initialized_ = mcp2515.initialize<8_MHz, 125_kbps>(); + MODM_LOG_INFO << "Success: " << initialized_ << modm::endl; mcp2515.setFilter(modm::accessor::asFlash(canFilter)); - - // send a new message - message_.length = 2; - message_.data[0] = 0xab; - message_.data[1] = 0xcd; - mcp2515.sendMessage(message_); - - while (true) + MODM_LOG_INFO << "Running ... " << modm::endl; +#if SENDER == 0 + while (initialized_) { + // receive messages if (mcp2515.isMessageAvailable()) { + MODM_LOG_INFO << "Message Available ... " << modm::endl; mcp2515.getMessage(message_); - MODM_LOG_INFO << "Received message: " << message_.identifier << modm::endl; + MODM_LOG_INFO << "Received message: " << modm::hex << message_.identifier << modm::endl; } PT_CALL(mcp2515.update()); } +#else + while (initialized_) + { + wait_.restart(500ms); + PT_WAIT_UNTIL(wait_.isExpired()); + message_.length = 2; + message_.data[0] = 0xab; + message_.data[1] = 0xcd; + MODM_LOG_INFO << "Sending Message ... "<< modm::endl; + mcp2515.sendMessage(message_); + PT_CALL(mcp2515.update()); + } +#endif + PT_END(); } private: modm::can::Message message_; + bool initialized_; + modm::ShortTimeout wait_; }; MyTask task; @@ -91,6 +115,7 @@ main() { Board::initialize(); + MODM_LOG_INFO << "Hello" << modm::endl; // Initialize SPI interface and the other pins // needed by the MCP2515 SpiMaster::connect(); diff --git a/examples/stm32f4_discovery/can_m2515/project.xml b/examples/nucleo_f439zi/can_m2515/project.xml similarity index 85% rename from examples/stm32f4_discovery/can_m2515/project.xml rename to examples/nucleo_f439zi/can_m2515/project.xml index 33e222c2f2..c1433fb0c7 100644 --- a/examples/stm32f4_discovery/can_m2515/project.xml +++ b/examples/nucleo_f439zi/can_m2515/project.xml @@ -1,11 +1,12 @@ - modm:disco-f407vg + modm:nucleo-f439zi modm:platform:gpio modm:platform:spi.bitbang + modm:platform:spi:1 modm:platform:spi:2 modm:build:scons diff --git a/src/modm/driver/can/mcp2515.hpp b/src/modm/driver/can/mcp2515.hpp index 1e620ecd4f..c39efb8dbb 100644 --- a/src/modm/driver/can/mcp2515.hpp +++ b/src/modm/driver/can/mcp2515.hpp @@ -120,9 +120,9 @@ namespace modm template < typename SPI, typename CS, typename INT > - class Mcp2515 : public ::modm::Can, - public ::modm::SpiDevice, - protected ::modm::NestedResumable<4> + class Mcp2515 : public modm::Can, + public modm::SpiDevice, + protected modm::NestedResumable<4> { public: template diff --git a/src/modm/driver/can/mcp2515.lb b/src/modm/driver/can/mcp2515.lb index f0c9fcfbb1..124835cfac 100644 --- a/src/modm/driver/can/mcp2515.lb +++ b/src/modm/driver/can/mcp2515.lb @@ -32,6 +32,7 @@ def prepare(module, options): ":architecture:clock", ":architecture:delay", ":architecture:interrupt", + ":architecture:spi.device", ":processing:protothread", ":processing:timer", ":platform:exti", diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index fdf7030ced..28f0fed61e 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -20,15 +20,14 @@ #include "mcp2515_definitions.hpp" #include -#undef MODM_LOG_LEVEL -#define MODM_LOG_LEVEL modm::log::DISABLED - +// Set the log level +#undef MODM_LOG_LEVEL +#define MODM_LOG_LEVEL modm::log::DISABLED // ---------------------------------------------------------------------------- static uint8_t statusBuffer_; static uint8_t addressBuffer_; -static uint8_t dataBuffer_; static modm::can::Message messageBuffer_; static uint8_t i_; static uint8_t a_; @@ -142,8 +141,8 @@ modm::Mcp2515::setFilter(accessor::Flash filter) // change to configuration mode bitModify(CANCTRL, 0xe0, REQOP2); - while ((readRegister(CANSTAT) & 0xe0) != REQOP2); + while ((readRegister(CANSTAT) & 0xe0) != REQOP2); writeRegister(RXB0CTRL, BUKT); writeRegister(RXB1CTRL, 0); @@ -480,13 +479,13 @@ modm::Mcp2515::readStatus(uint8_t type) RF_WAIT_UNTIL(this->acquireMaster()); chipSelect.reset(); - dataBuffer_ = RF_CALL(spi.transfer(type)); + statusBuffer_ = RF_CALL(spi.transfer(type)); RF_CALL(spi.transfer(0xff)); if(this->releaseMaster()) { chipSelect.set(); } - RF_END_RETURN(dataBuffer_); + RF_END_RETURN(statusBuffer_); } // ---------------------------------------------------------------------------- From 7c9065df196acb6ec367713ade208ba9ad9b8309 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Fri, 4 Feb 2022 10:57:07 +0100 Subject: [PATCH 10/29] re-enable debug messages in main --- examples/nucleo_f439zi/can_m2515/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/nucleo_f439zi/can_m2515/main.cpp b/examples/nucleo_f439zi/can_m2515/main.cpp index 1cd6a943f7..fca568b789 100644 --- a/examples/nucleo_f439zi/can_m2515/main.cpp +++ b/examples/nucleo_f439zi/can_m2515/main.cpp @@ -22,7 +22,7 @@ // Set the log level #undef MODM_LOG_LEVEL -#define MODM_LOG_LEVEL modm::log::DISABLED +#define MODM_LOG_LEVEL modm::log::DEBUG // If you use a different SPI instance, you may have to also choose different // GPIOs to connect to. From 5357bc2c66b49a12116b8354d718bd25b0b55040 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Fri, 4 Feb 2022 11:23:25 +0100 Subject: [PATCH 11/29] re-enable @chris-durand hack for changing bus clock speed in configurationHandler in example; changes canbdaudrate to 500kbps --- examples/nucleo_f439zi/can_m2515/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/nucleo_f439zi/can_m2515/main.cpp b/examples/nucleo_f439zi/can_m2515/main.cpp index fca568b789..0decc7bfd3 100644 --- a/examples/nucleo_f439zi/can_m2515/main.cpp +++ b/examples/nucleo_f439zi/can_m2515/main.cpp @@ -67,9 +67,9 @@ class MyTask : modm::pt::Protothread SpiMaster::setDataMode(SpiMaster::DataMode::Mode3); SpiMaster::setDataOrder(SpiMaster::DataOrder::MsbFirst); /// @chris-durand - // SpiMaster::setBaudrate(); + SpiMaster::setBaudrate(); }); - initialized_ = mcp2515.initialize<8_MHz, 125_kbps>(); + initialized_ = mcp2515.initialize<8_MHz, 500_kbps>(); MODM_LOG_INFO << "Success: " << initialized_ << modm::endl; mcp2515.setFilter(modm::accessor::asFlash(canFilter)); MODM_LOG_INFO << "Running ... " << modm::endl; From c177db33ec01965740f4b56df217d773aa05dd83 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Fri, 4 Feb 2022 15:52:13 +0100 Subject: [PATCH 12/29] whitespaces --- src/modm/driver/can/mcp2515.hpp | 2 +- src/modm/driver/can/mcp2515_impl.hpp | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/modm/driver/can/mcp2515.hpp b/src/modm/driver/can/mcp2515.hpp index c39efb8dbb..f5fe3df2f1 100644 --- a/src/modm/driver/can/mcp2515.hpp +++ b/src/modm/driver/can/mcp2515.hpp @@ -169,7 +169,7 @@ namespace modm sendMessage(const can::Message& message); /* - * Poll the transmit buffer (shoudl be called periodically) + * Poll the transmit buffer (should be called periodically) * * \return true if a message was send this cycle, false otherwise */ diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index 28f0fed61e..6091fe8327 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -293,8 +293,6 @@ modm::Mcp2515::mcp2515ReadMessage(can::Message& message, uint8_t s template modm::ResumableResult modm::Mcp2515::update(){ - /// todo - /// this should be a timer interrupt using namespace mcp2515; RF_BEGIN(); From d737638eb1b466584fc5a3efd22d880a7e75da48 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Fri, 4 Feb 2022 16:37:23 +0100 Subject: [PATCH 13/29] removed @chris-durand hack again and put the configuration handler into the mcp2515 driver, because it should not be in user code --- examples/nucleo_f439zi/can_m2515/main.cpp | 6 ----- .../architecture/interface/spi_device.hpp | 25 +++++-------------- src/modm/driver/can/mcp2515_impl.hpp | 5 ++++ src/modm/platform/spi/stm32/spi_hal.hpp.in | 3 --- .../platform/spi/stm32/spi_hal_impl.hpp.in | 6 ----- src/modm/platform/spi/stm32/spi_master.cpp.in | 4 ++- src/modm/platform/spi/stm32/spi_master.hpp.in | 19 +------------- 7 files changed, 15 insertions(+), 53 deletions(-) diff --git a/examples/nucleo_f439zi/can_m2515/main.cpp b/examples/nucleo_f439zi/can_m2515/main.cpp index 0decc7bfd3..b31026b1f5 100644 --- a/examples/nucleo_f439zi/can_m2515/main.cpp +++ b/examples/nucleo_f439zi/can_m2515/main.cpp @@ -63,12 +63,6 @@ class MyTask : modm::pt::Protothread MODM_LOG_INFO << "Initializing mcp2515 ..." << modm::endl; // Configure MCP2515 and set the filters - mcp2515.attachConfigurationHandler([]() { - SpiMaster::setDataMode(SpiMaster::DataMode::Mode3); - SpiMaster::setDataOrder(SpiMaster::DataOrder::MsbFirst); - /// @chris-durand - SpiMaster::setBaudrate(); - }); initialized_ = mcp2515.initialize<8_MHz, 500_kbps>(); MODM_LOG_INFO << "Success: " << initialized_ << modm::endl; mcp2515.setFilter(modm::accessor::asFlash(canFilter)); diff --git a/src/modm/architecture/interface/spi_device.hpp b/src/modm/architecture/interface/spi_device.hpp index 2f92c5f4e3..89ac49b7b4 100644 --- a/src/modm/architecture/interface/spi_device.hpp +++ b/src/modm/architecture/interface/spi_device.hpp @@ -30,38 +30,25 @@ namespace modm template < class SpiMaster > class SpiDevice { - Spi::ConfigurationHandler configuration{nullptr}; - Spi::ConfigurationHandler userConfiguration{nullptr}; + Spi::ConfigurationHandler configuration; public: - void inline - attachConfigurationHandler(Spi::ConfigurationHandler handler) + SpiDevice() + : configuration(nullptr) { - configuration = handler; } void inline - attachUserConfigurationHandler(Spi::ConfigurationHandler handler) + attachConfigurationHandler(Spi::ConfigurationHandler handler) { - userConfiguration = handler; + configuration = handler; } - inline Spi::ConfigurationHandler - configurationHandler() { return configuration; } - - inline Spi::ConfigurationHandler - userConfigurationHandler() { return userConfiguration; } - protected: bool inline acquireMaster() { - const auto handler = +[](void* context) { - const auto& device = *static_cast(context); - if (device.configuration) device.configuration(); - if (device.userConfiguration) device.userConfiguration(); - }; - return (SpiMaster::acquire(this, handler) != 0); + return (SpiMaster::acquire(this, configuration) != 0); } bool inline diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index 6091fe8327..b5b929f1b7 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -123,6 +123,11 @@ bool modm::Mcp2515::initialize() { using Timings = modm::CanBitTimingMcp2515; + + this->attachConfigurationHandler([]() { + SpiMaster::setDataMode(SpiMaster::DataMode::Mode3); + SpiMaster::setDataOrder(SpiMaster::DataOrder::MsbFirst); + }); return initializeWithPrescaler( Timings::getPrescaler(), diff --git a/src/modm/platform/spi/stm32/spi_hal.hpp.in b/src/modm/platform/spi/stm32/spi_hal.hpp.in index 9662c9fce2..cac0022289 100644 --- a/src/modm/platform/spi/stm32/spi_hal.hpp.in +++ b/src/modm/platform/spi/stm32/spi_hal.hpp.in @@ -68,9 +68,6 @@ public: static void setMasterSelection(MasterSelection masterSelection); - static void - setPrescaler(Prescaler prescaler); - %% if "fifo" in features static void setRxFifoThreshold(RxFifoThreshold threshold); diff --git a/src/modm/platform/spi/stm32/spi_hal_impl.hpp.in b/src/modm/platform/spi/stm32/spi_hal_impl.hpp.in index d0be238559..c75a7667c7 100644 --- a/src/modm/platform/spi/stm32/spi_hal_impl.hpp.in +++ b/src/modm/platform/spi/stm32/spi_hal_impl.hpp.in @@ -63,12 +63,6 @@ modm::platform::SpiHal{{ id }}::initialize(Prescaler prescaler, SPI{{ id }}->CR1 |= SPI_CR1_SPE; } -void inline -modm::platform::SpiHal{{ id }}::setPrescaler(Prescaler prescaler) -{ - SPI{{ id }}->CR1 = (SPI{{ id }}->CR1 & ~SPI_CR1_BR_Msk) | static_cast(prescaler); -} - void inline modm::platform::SpiHal{{ id }}::setDataMode(DataMode dataMode) { diff --git a/src/modm/platform/spi/stm32/spi_master.cpp.in b/src/modm/platform/spi/stm32/spi_master.cpp.in index a02150b4ad..b31a39c0de 100644 --- a/src/modm/platform/spi/stm32/spi_master.cpp.in +++ b/src/modm/platform/spi/stm32/spi_master.cpp.in @@ -27,6 +27,8 @@ modm::platform::SpiMaster{{ id }}::count(0); void * modm::platform::SpiMaster{{ id }}::context(nullptr); +modm::Spi::ConfigurationHandler +modm::platform::SpiMaster{{ id }}::configuration(nullptr); // ---------------------------------------------------------------------------- uint8_t @@ -39,7 +41,7 @@ modm::platform::SpiMaster{{ id }}::acquire(void *ctx, ConfigurationHandler handl // if handler is not nullptr and is different from previous configuration if (handler and configuration != handler) { configuration = handler; - configuration(ctx); + configuration(); } return 1; } diff --git a/src/modm/platform/spi/stm32/spi_master.hpp.in b/src/modm/platform/spi/stm32/spi_master.hpp.in index 3a956dbb2f..94bd6887f4 100644 --- a/src/modm/platform/spi/stm32/spi_master.hpp.in +++ b/src/modm/platform/spi/stm32/spi_master.hpp.in @@ -41,11 +41,7 @@ class SpiMaster{{ id }} : public modm::SpiMaster static uint8_t state; static uint8_t count; static void *context; - - // HACK override handler type, for demo only - using ConfigurationHandler = void(*)(void*); - - static inline ConfigurationHandler configuration; + static ConfigurationHandler configuration; public: using Hal = SpiHal{{ id }}; @@ -103,19 +99,6 @@ public: state = 0; } - template< class SystemClock, baudrate_t baudrate, percent_t tolerance=pct(5) > - static void - setBaudrate() - { - constexpr auto result = modm::Prescaler::from_power(SystemClock::Spi{{ id }}, baudrate, 2, 256); - assertBaudrateInTolerance< result.frequency, baudrate, tolerance >(); - - // translate the prescaler into the bitmapping - constexpr SpiHal{{ id }}::Prescaler prescaler{result.index << SPI_CR1_BR_Pos}; - - SpiHal{{ id }}::setPrescaler(prescaler); - } - static modm_always_inline void setDataMode(DataMode mode) { From f94d31aefc52e377080b418bf4fb3a393686cd9e Mon Sep 17 00:00:00 2001 From: kikass13 Date: Fri, 4 Feb 2022 20:25:21 +0100 Subject: [PATCH 14/29] small fixes for ci --- examples/nucleo_f439zi/can_m2515/main.cpp | 2 +- src/modm/driver/can/mcp2515.hpp | 11 +++++++++++ src/modm/driver/can/mcp2515.lb | 1 - src/modm/driver/can/mcp2515_impl.hpp | 19 +++---------------- 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/examples/nucleo_f439zi/can_m2515/main.cpp b/examples/nucleo_f439zi/can_m2515/main.cpp index b31026b1f5..cb656f2f46 100644 --- a/examples/nucleo_f439zi/can_m2515/main.cpp +++ b/examples/nucleo_f439zi/can_m2515/main.cpp @@ -14,8 +14,8 @@ #include #include #include -#include #include +#include #define SENDER 0 diff --git a/src/modm/driver/can/mcp2515.hpp b/src/modm/driver/can/mcp2515.hpp index f5fe3df2f1..df26f59d44 100644 --- a/src/modm/driver/can/mcp2515.hpp +++ b/src/modm/driver/can/mcp2515.hpp @@ -242,6 +242,17 @@ namespace modm SPI spi; CS chipSelect; INT interruptPin; + + uint8_t statusBuffer_; + uint8_t addressBuffer_; + modm::can::Message messageBuffer_; + uint8_t i_; + uint8_t a_; + uint8_t b_; + bool temp_; + bool temp2_; + bool hasSend_; + modm::ShortTimeout delay_; }; } diff --git a/src/modm/driver/can/mcp2515.lb b/src/modm/driver/can/mcp2515.lb index 124835cfac..1abbf51e47 100644 --- a/src/modm/driver/can/mcp2515.lb +++ b/src/modm/driver/can/mcp2515.lb @@ -35,7 +35,6 @@ def prepare(module, options): ":architecture:spi.device", ":processing:protothread", ":processing:timer", - ":platform:exti", ":debug") return True diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index b5b929f1b7..302cd6cff9 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -26,19 +26,6 @@ // ---------------------------------------------------------------------------- -static uint8_t statusBuffer_; -static uint8_t addressBuffer_; -static modm::can::Message messageBuffer_; -static uint8_t i_; -static uint8_t a_; -static uint8_t b_; -static bool temp_; -static bool temp2_; -static bool hasSend_; -static modm::ShortTimeout delay_; - -// ---------------------------------------------------------------------------- - template bool modm::Mcp2515::initializeWithPrescaler( @@ -123,10 +110,10 @@ bool modm::Mcp2515::initialize() { using Timings = modm::CanBitTimingMcp2515; - + this->attachConfigurationHandler([]() { - SpiMaster::setDataMode(SpiMaster::DataMode::Mode3); - SpiMaster::setDataOrder(SpiMaster::DataOrder::MsbFirst); + SPI::setDataMode(SPI::DataMode::Mode3); + SPI::setDataOrder(SPI::DataOrder::MsbFirst); }); return initializeWithPrescaler( From 6f773fc4cd100847a585c22822f7ddd610da83c7 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Fri, 4 Feb 2022 22:58:07 +0100 Subject: [PATCH 15/29] removed unnecessary function --- src/modm/driver/can/mcp2515.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/modm/driver/can/mcp2515.hpp b/src/modm/driver/can/mcp2515.hpp index df26f59d44..9183702698 100644 --- a/src/modm/driver/can/mcp2515.hpp +++ b/src/modm/driver/can/mcp2515.hpp @@ -202,9 +202,6 @@ namespace modm BIT_MODIFY = 0x05 }; - void - mcp2515Interrupt(); - modm::ResumableResult mcp2515ReadMessage(can::Message& message, uint8_t status = 0xff); From 33a621f842209a4e83cb26da664fb6077c99cdb3 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Sun, 6 Feb 2022 13:57:04 +0100 Subject: [PATCH 16/29] tried to keep the external api static, this means nonblocking initialize and no SpiDevice bus mutex because SpiDevice only allows to be inherited from (protected api) ... this is a little better, because now you can call the driver from wherever (static) but it internally allows/needs instantiation and update polls for controllign the context the driver runs in --- src/modm/driver/can/mcp2515.hpp | 33 +++++++++++++++++----------- src/modm/driver/can/mcp2515_impl.hpp | 20 +++-------------- 2 files changed, 23 insertions(+), 30 deletions(-) diff --git a/src/modm/driver/can/mcp2515.hpp b/src/modm/driver/can/mcp2515.hpp index 9183702698..8c1d8b5cef 100644 --- a/src/modm/driver/can/mcp2515.hpp +++ b/src/modm/driver/can/mcp2515.hpp @@ -125,12 +125,19 @@ namespace modm protected modm::NestedResumable<4> { public: + Mcp2515(){ + this->attachConfigurationHandler([]() { + SPI::setDataMode(SPI::DataMode::Mode3); + SPI::setDataOrder(SPI::DataOrder::MsbFirst); + }); + } + template - bool + static bool initialize(); private: - bool + static bool initializeWithPrescaler( uint8_t prescaler, uint8_t sjw, @@ -146,10 +153,10 @@ namespace modm setMode(Can::Mode mode); - inline bool + static inline bool isMessageAvailable(); - bool + static bool getMessage(can::Message& message, uint8_t *filter_id=nullptr); /* @@ -157,7 +164,7 @@ namespace modm * * \return true if a slot is available, false otherwise */ - bool + static bool isReadyToSend(); /* @@ -165,7 +172,7 @@ namespace modm * * \return true if the message was send, false otherwise */ - bool + static bool sendMessage(const can::Message& message); /* @@ -214,10 +221,10 @@ namespace modm modm::ResumableResult mcp2515SendMessage(const can::Message& message, uint8_t status = 0xff); - void + static void writeRegister(uint8_t address, uint8_t data); - uint8_t + static uint8_t readRegister(uint8_t address); void @@ -233,12 +240,12 @@ namespace modm readIdentifier(uint32_t& identifier); private: - modm::atomic::Queue txQueue; - modm::atomic::Queue rxQueue; + inline static modm::atomic::Queue txQueue; + inline static modm::atomic::Queue rxQueue; - SPI spi; - CS chipSelect; - INT interruptPin; + static SPI spi; + static CS chipSelect; + static INT interruptPin; uint8_t statusBuffer_; uint8_t addressBuffer_; diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index 302cd6cff9..265885d2ce 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -56,7 +56,6 @@ modm::Mcp2515::initializeWithPrescaler( using namespace mcp2515; - while(!this->acquireMaster()){}; // software reset for the mcp2515, after this the chip is back in the // configuration mode chipSelect.reset(); @@ -77,9 +76,7 @@ modm::Mcp2515::initializeWithPrescaler( // enable interrupts spi.transferBlocking(RX1IE | RX0IE); chipSelect.set(); - if(this->releaseMaster()){ - chipSelect.set(); - } + // set TXnRTS pins as inwrites writeRegister(TXRTSCTRL, 0); @@ -111,11 +108,6 @@ modm::Mcp2515::initialize() { using Timings = modm::CanBitTimingMcp2515; - this->attachConfigurationHandler([]() { - SPI::setDataMode(SPI::DataMode::Mode3); - SPI::setDataOrder(SPI::DataOrder::MsbFirst); - }); - return initializeWithPrescaler( Timings::getPrescaler(), Timings::getSJW(), @@ -421,28 +413,22 @@ template void modm::Mcp2515::writeRegister(uint8_t address, uint8_t data) { - while(!this->acquireMaster()){}; chipSelect.reset(); spi.transferBlocking(WRITE); spi.transferBlocking(address); spi.transferBlocking(data); - if(this->releaseMaster()){ - chipSelect.set(); - } + chipSelect.set(); } template uint8_t modm::Mcp2515::readRegister(uint8_t address) { - while(!this->acquireMaster()){}; chipSelect.reset(); spi.transferBlocking(READ); spi.transferBlocking(address); uint8_t data = spi.transferBlocking(0xff); - if(this->releaseMaster()){ - chipSelect.set(); - } + chipSelect.set(); return data; } From ed406ca65e3138d4a395671e8574a917b774d7f8 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Sun, 6 Feb 2022 22:25:52 +0100 Subject: [PATCH 17/29] memory error when reading messages, --- examples/stm32f4_discovery/can2/main.cpp | 17 ++--------------- examples/stm32f4_discovery/can2/project.xml | 2 +- src/modm/driver/can/mcp2515.hpp | 21 +++++++++++---------- src/modm/driver/can/mcp2515_impl.hpp | 17 +++++++++-------- 4 files changed, 23 insertions(+), 34 deletions(-) diff --git a/examples/stm32f4_discovery/can2/main.cpp b/examples/stm32f4_discovery/can2/main.cpp index c8fc1d9538..a014e3aa3f 100644 --- a/examples/stm32f4_discovery/can2/main.cpp +++ b/examples/stm32f4_discovery/can2/main.cpp @@ -24,15 +24,6 @@ * Tested in hardware (F4) on 2018-08-16 by Sebastian Birke. */ -// Create an IODeviceWrapper around the Uart Peripheral we want to use -modm::IODeviceWrapper< Usart2, modm::IOBuffer::BlockIfFull > loggerDevice; - -// Set all four logger streams to use the UART -modm::log::Logger modm::log::debug(loggerDevice); -modm::log::Logger modm::log::info(loggerDevice); -modm::log::Logger modm::log::warning(loggerDevice); -modm::log::Logger modm::log::error(loggerDevice); - // Set the log level #undef MODM_LOG_LEVEL #define MODM_LOG_LEVEL modm::log::DEBUG @@ -75,16 +66,12 @@ main() Board::LedGreen::set(); - // Initialize Usart - Usart2::connect(); - Usart2::initialize(); - MODM_LOG_INFO << "CAN Test Program" << modm::endl; MODM_LOG_INFO << "Initializing Can ..." << modm::endl; // Initialize Can - Can1::connect(Gpio::InputType::PullUp); - Can1::initialize(9); + Can1::connect(Gpio::InputType::PullUp); + bool success = Can1::initialize(9); MODM_LOG_INFO << "Setting up Filter for Can ..." << modm::endl; // Receive every message diff --git a/examples/stm32f4_discovery/can2/project.xml b/examples/stm32f4_discovery/can2/project.xml index a822d27aac..f9af0509db 100644 --- a/examples/stm32f4_discovery/can2/project.xml +++ b/examples/stm32f4_discovery/can2/project.xml @@ -1,5 +1,5 @@ - modm:disco-f407vg + modm:nucleo-f439zi diff --git a/src/modm/driver/can/mcp2515.hpp b/src/modm/driver/can/mcp2515.hpp index 8c1d8b5cef..fd29be0bbf 100644 --- a/src/modm/driver/can/mcp2515.hpp +++ b/src/modm/driver/can/mcp2515.hpp @@ -125,7 +125,7 @@ namespace modm protected modm::NestedResumable<4> { public: - Mcp2515(){ + Mcp2515() : messageBuffer_{}, delay_{} { this->attachConfigurationHandler([]() { SPI::setDataMode(SPI::DataMode::Mode3); SPI::setDataOrder(SPI::DataOrder::MsbFirst); @@ -210,7 +210,7 @@ namespace modm }; modm::ResumableResult - mcp2515ReadMessage(can::Message& message, uint8_t status = 0xff); + mcp2515ReadMessage(uint8_t status = 0xff); bool mcp2515IsReadyToSend(uint8_t status); @@ -247,16 +247,17 @@ namespace modm static CS chipSelect; static INT interruptPin; - uint8_t statusBuffer_; - uint8_t addressBuffer_; modm::can::Message messageBuffer_; - uint8_t i_; - uint8_t a_; - uint8_t b_; - bool temp_; - bool temp2_; - bool hasSend_; modm::ShortTimeout delay_; + uint8_t statusBuffer_ = 0; + uint8_t addressBuffer_ = 0; + uint8_t i_, j_ = 0; + uint8_t a_ = 0; + uint8_t b_ = 0; + uint8_t data_ = 0; + bool temp_ = false; + bool temp2_ = false; + bool hasSend_ = false; }; } diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index 265885d2ce..f2c2c156cd 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -225,7 +225,7 @@ modm::Mcp2515::sendMessage(const can::Message& message) // ---------------------------------------------------------------------------- template modm::ResumableResult -modm::Mcp2515::mcp2515ReadMessage(can::Message& message, uint8_t status) +modm::Mcp2515::mcp2515ReadMessage(uint8_t status) { using namespace mcp2515; @@ -253,17 +253,18 @@ modm::Mcp2515::mcp2515ReadMessage(can::Message& message, uint8_t s chipSelect.reset(); RF_CALL(spi.transfer(addressBuffer_)); - message.flags.extended = RF_CALL(readIdentifier(message.identifier)); + messageBuffer_.flags.extended = RF_CALL(readIdentifier(messageBuffer_.identifier)); if (status & FLAG_RTR) { - message.flags.rtr = true; + messageBuffer_.flags.rtr = true; } else { - message.flags.rtr = false; + messageBuffer_.flags.rtr = false; } - message.length = RF_CALL(spi.transfer(0xff)) & 0x0f; + messageBuffer_.length = RF_CALL(spi.transfer(0xff)) & 0x0f; - for (i_ = 0; i_ < message.length; ++i_) { - message.data[i_] = RF_CALL(spi.transfer(0xff)); + for (j_ = 0; j_ < messageBuffer_.length; ++j_) { + data_ = RF_CALL(spi.transfer(0xff)); + messageBuffer_.data[j_] = data_; } if(this->releaseMaster()){ chipSelect.set(); @@ -287,7 +288,7 @@ modm::Mcp2515::update(){ // check if the device has received a message(pin = LOW) // if yes: read it and put it into the rxQueue if(!interruptPin.read()){ - if(RF_CALL(mcp2515ReadMessage(messageBuffer_, statusBuffer_))) + if(RF_CALL(mcp2515ReadMessage(statusBuffer_))) { if(not modm_assert_continue_ignore(rxQueue.push(messageBuffer_), "mcp2515.can.tx", "CAN transmit software buffer overflowed!", 1)){ From ec7cf304e8503e419578da1b008cc2766da731e3 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Mon, 7 Feb 2022 16:55:31 +0100 Subject: [PATCH 18/29] fixed bug in receiveMessage part, where status register was not read properly which lead to infinite interrupts; added some more buffers for the different more or less concurrent read/write variables; added stuff to example; --- examples/nucleo_f439zi/can_m2515/main.cpp | 28 +++-- src/modm/driver/can/mcp2515.hpp | 19 +++- src/modm/driver/can/mcp2515_impl.hpp | 133 ++++++++++------------ 3 files changed, 94 insertions(+), 86 deletions(-) diff --git a/examples/nucleo_f439zi/can_m2515/main.cpp b/examples/nucleo_f439zi/can_m2515/main.cpp index cb656f2f46..97f15afbfa 100644 --- a/examples/nucleo_f439zi/can_m2515/main.cpp +++ b/examples/nucleo_f439zi/can_m2515/main.cpp @@ -17,8 +17,7 @@ #include #include - -#define SENDER 0 +#define SENDER 1 // Set the log level #undef MODM_LOG_LEVEL @@ -54,7 +53,11 @@ modm::Mcp2515 mcp2515; class MyTask : modm::pt::Protothread { public: - MyTask() : message_{0x1337}{} + MyTask() : + message_{0x1337}, + i_{0}, + j_{0} + {} bool run() @@ -75,19 +78,29 @@ class MyTask : modm::pt::Protothread { MODM_LOG_INFO << "Message Available ... " << modm::endl; mcp2515.getMessage(message_); - MODM_LOG_INFO << "Received message: " << modm::hex << message_.identifier << modm::endl; + for(i_ = 0; i_ < message_.length; ++i_){ + MODM_LOG_INFO << modm::hex<< " 0x" << message_.data[i_]; + } + MODM_LOG_INFO << modm::endl; + MODM_LOG_INFO << "Received message [" << j_ << "]: " << modm::hex << message_.identifier << modm::endl; + j_+=1; + MODM_LOG_INFO << modm::endl; } PT_CALL(mcp2515.update()); } #else while (initialized_) { - wait_.restart(500ms); + wait_.restart(1000ms); PT_WAIT_UNTIL(wait_.isExpired()); message_.length = 2; - message_.data[0] = 0xab; - message_.data[1] = 0xcd; + message_.data[0] = i_++; + message_.data[1] = i_++; MODM_LOG_INFO << "Sending Message ... "<< modm::endl; + for(j_ = 0; j_ < message_.length; ++j_){ + MODM_LOG_INFO << modm::hex<< " 0x" << message_.data[j_]; + } + MODM_LOG_INFO << modm::endl; mcp2515.sendMessage(message_); PT_CALL(mcp2515.update()); } @@ -100,6 +113,7 @@ class MyTask : modm::pt::Protothread modm::can::Message message_; bool initialized_; modm::ShortTimeout wait_; + uint8_t i_, j_; }; MyTask task; diff --git a/src/modm/driver/can/mcp2515.hpp b/src/modm/driver/can/mcp2515.hpp index fd29be0bbf..9b6e1290cf 100644 --- a/src/modm/driver/can/mcp2515.hpp +++ b/src/modm/driver/can/mcp2515.hpp @@ -125,7 +125,7 @@ namespace modm protected modm::NestedResumable<4> { public: - Mcp2515() : messageBuffer_{}, delay_{} { + Mcp2515() : messageBuffer_{}, delayR_{}, delayS_{} { this->attachConfigurationHandler([]() { SPI::setDataMode(SPI::DataMode::Mode3); SPI::setDataOrder(SPI::DataOrder::MsbFirst); @@ -210,7 +210,7 @@ namespace modm }; modm::ResumableResult - mcp2515ReadMessage(uint8_t status = 0xff); + mcp2515ReadMessage(); bool mcp2515IsReadyToSend(uint8_t status); @@ -219,7 +219,7 @@ namespace modm mcp2515IsReadyToSend(); modm::ResumableResult - mcp2515SendMessage(const can::Message& message, uint8_t status = 0xff); + mcp2515SendMessage(const can::Message& message); static void writeRegister(uint8_t address, uint8_t data); @@ -248,16 +248,23 @@ namespace modm static INT interruptPin; modm::can::Message messageBuffer_; - modm::ShortTimeout delay_; + modm::ShortTimeout delayR_; + modm::ShortTimeout delayS_; uint8_t statusBuffer_ = 0; - uint8_t addressBuffer_ = 0; + uint8_t statusBufferR_ = 0; + uint8_t statusBufferS_ = 0; + uint8_t statusBufferReady_ = 0; + uint8_t addressBufferR_ = 0; + uint8_t addressBufferS_ = 0; uint8_t i_, j_ = 0; uint8_t a_ = 0; uint8_t b_ = 0; uint8_t data_ = 0; + bool tempR_ = false; + bool tempS_ = false; bool temp_ = false; - bool temp2_ = false; bool hasSend_ = false; + bool receiveSuccess_ = false; }; } diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index f2c2c156cd..988b25c3d0 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -22,7 +22,7 @@ // Set the log level #undef MODM_LOG_LEVEL -#define MODM_LOG_LEVEL modm::log::DISABLED +#define MODM_LOG_LEVEL modm::log::DEBUG // ---------------------------------------------------------------------------- @@ -147,9 +147,9 @@ modm::Mcp2515::setFilter(accessor::Flash filter) } chipSelect.set(); } - if(this->releaseMaster()){ - chipSelect.set(); - } + while(!this->releaseMaster()); + chipSelect.set(); + bitModify(CANCTRL, 0xe0, 0); } @@ -225,54 +225,53 @@ modm::Mcp2515::sendMessage(const can::Message& message) // ---------------------------------------------------------------------------- template modm::ResumableResult -modm::Mcp2515::mcp2515ReadMessage(uint8_t status) +modm::Mcp2515::mcp2515ReadMessage() { using namespace mcp2515; RF_BEGIN(); - temp_ = true; - // dont read status again if we have been provided one - if(status == 0xff){ - status = RF_CALL(readStatus(READ_STATUS)); - } + // read status flag of the device + statusBufferR_ = RF_CALL(readStatus(RX_STATUS)); - if (status & FLAG_RXB0_FULL) { - addressBuffer_ = READ_RX; // message in buffer 0 + tempR_ = true; + if (statusBufferR_ & FLAG_RXB0_FULL) { + addressBufferR_ = READ_RX; // message in buffer 0 } - else if (status & FLAG_RXB1_FULL) { - addressBuffer_ = READ_RX | 0x04; // message in buffer 1 (RXB1SIDH) + else if (statusBufferR_ & FLAG_RXB1_FULL) { + addressBufferR_ = READ_RX | 0x04; // message in buffer 1 (RXB1SIDH) } else { - temp_ = false; // Error: no message available + tempR_ = false; // Error: no message available } - if(temp_) + if(tempR_) { RF_WAIT_UNTIL(this->acquireMaster()); chipSelect.reset(); - RF_CALL(spi.transfer(addressBuffer_)); + RF_CALL(spi.transfer(addressBufferR_)); messageBuffer_.flags.extended = RF_CALL(readIdentifier(messageBuffer_.identifier)); - if (status & FLAG_RTR) { + if (statusBufferR_ & FLAG_RTR) { messageBuffer_.flags.rtr = true; } else { messageBuffer_.flags.rtr = false; } + messageBuffer_.length = RF_CALL(spi.transfer(0xff)) & 0x0f; for (j_ = 0; j_ < messageBuffer_.length; ++j_) { data_ = RF_CALL(spi.transfer(0xff)); messageBuffer_.data[j_] = data_; } - if(this->releaseMaster()){ - chipSelect.set(); - } + RF_WAIT_UNTIL(this->releaseMaster()); + chipSelect.set(); } // RX0IF or RX1IF respectivly were already cleared automatically by rising CS. // See section 12.4 in datasheet. - RF_END_RETURN(temp_); + + RF_END_RETURN(tempR_); } template @@ -282,13 +281,10 @@ modm::Mcp2515::update(){ RF_BEGIN(); - // read status flag of the device - statusBuffer_ = RF_CALL(readStatus(READ_STATUS)); - // check if the device has received a message(pin = LOW) // if yes: read it and put it into the rxQueue if(!interruptPin.read()){ - if(RF_CALL(mcp2515ReadMessage(statusBuffer_))) + if(RF_CALL(mcp2515ReadMessage())) { if(not modm_assert_continue_ignore(rxQueue.push(messageBuffer_), "mcp2515.can.tx", "CAN transmit software buffer overflowed!", 1)){ @@ -300,10 +296,8 @@ modm::Mcp2515::update(){ /// check if device accepts messages and start emptying the transmit queue if not empty if (txQueue.isNotEmpty()) { - if(mcp2515IsReadyToSend(statusBuffer_)){ - hasSend_ = RF_CALL(mcp2515SendMessage(txQueue.get(), statusBuffer_)); - txQueue.pop(); - } + hasSend_ = RF_CALL(mcp2515SendMessage(txQueue.get())); + txQueue.pop(); } RF_END(); } @@ -318,16 +312,16 @@ modm::Mcp2515::mcp2515IsReadyToSend() RF_BEGIN(); - temp_ = true; - statusBuffer_ = RF_CALL(readStatus(READ_STATUS)); - if (( statusBuffer_& (TXB2CNTRL_TXREQ | TXB1CNTRL_TXREQ | TXB0CNTRL_TXREQ)) == + tempS_ = true; + statusBufferReady_ = RF_CALL(readStatus(READ_STATUS)); + if (( statusBufferReady_& (TXB2CNTRL_TXREQ | TXB1CNTRL_TXREQ | TXB0CNTRL_TXREQ)) == (TXB2CNTRL_TXREQ | TXB1CNTRL_TXREQ | TXB0CNTRL_TXREQ)) { // all buffers currently in use - temp_ = false; + tempS_ = false; } - RF_END_RETURN(temp_); + RF_END_RETURN(tempS_); } template bool @@ -349,35 +343,35 @@ modm::Mcp2515::mcp2515IsReadyToSend(uint8_t status) template modm::ResumableResult -modm::Mcp2515::mcp2515SendMessage(const can::Message& message, uint8_t status) +modm::Mcp2515::mcp2515SendMessage(const can::Message& message) { using namespace modm::mcp2515; RF_BEGIN(); - // dont read status again if we have been provided one - if(status == 0xff){ - status = RF_CALL(readStatus(READ_STATUS)); - } + statusBufferS_ = RF_CALL(readStatus(READ_STATUS)); + + /// wait for ready to send status flags + RF_WAIT_UNTIL(mcp2515IsReadyToSend(statusBufferS_)); - if ((status & TXB0CNTRL_TXREQ) == 0) + if ((statusBufferS_ & TXB0CNTRL_TXREQ) == 0) { - addressBuffer_ = 0x00; // TXB0SIDH - } else if ((status & TXB1CNTRL_TXREQ) == 0) + addressBufferS_ = 0x00; // TXB0SIDH + } else if ((statusBufferS_ & TXB1CNTRL_TXREQ) == 0) { - addressBuffer_ = 0x02; // TXB1SIDH - } else if ((status & TXB2CNTRL_TXREQ) == 0) + addressBufferS_ = 0x02; // TXB1SIDH + } else if ((statusBufferS_ & TXB2CNTRL_TXREQ) == 0) { - addressBuffer_ = 0x04; // TXB2SIDH + addressBufferS_ = 0x04; // TXB2SIDH } else { // all buffer are in use => could not send the message } - if (addressBuffer_ == 0x00 || addressBuffer_ == 0x02 || addressBuffer_ == 0x04) + if (addressBufferS_ == 0x00 || addressBufferS_ == 0x02 || addressBufferS_ == 0x04) { RF_WAIT_UNTIL(this->acquireMaster()); chipSelect.reset(); - RF_CALL(spi.transfer(WRITE_TX | addressBuffer_)); + RF_CALL(spi.transfer(WRITE_TX | addressBufferS_)); RF_CALL(writeIdentifier(message.identifier, message.flags.extended)); // if the message is a rtr-frame, is has a length but no attached data @@ -392,20 +386,19 @@ modm::Mcp2515::mcp2515SendMessage(const can::Message& message, uin RF_CALL(spi.transfer(message.data[i_])); } } - delay_.restart(1ms); + delayS_.restart(1ms); chipSelect.set(); - RF_WAIT_UNTIL(delay_.isExpired()); + RF_WAIT_UNTIL(delayS_.isExpired()); // send message via RTS command chipSelect.reset(); - addressBuffer_ = (addressBuffer_ == 0) ? 1 : addressBuffer_; // 0 2 4 => 1 2 4 - RF_CALL(spi.transfer(RTS | addressBuffer_)); - if(this->releaseMaster()){ - chipSelect.set(); - } + addressBufferS_ = (addressBufferS_ == 0) ? 1 : addressBufferS_; // 0 2 4 => 1 2 4 + RF_CALL(spi.transfer(RTS | addressBufferS_)); + RF_WAIT_UNTIL(this->releaseMaster()); + chipSelect.set(); } - RF_END_RETURN(static_cast(addressBuffer_)); + RF_END_RETURN(static_cast(addressBufferS_)); } // ---------------------------------------------------------------------------- @@ -443,9 +436,8 @@ modm::Mcp2515::bitModify(uint8_t address, uint8_t mask, uint8_t da spi.transferBlocking(address); spi.transferBlocking(mask); spi.transferBlocking(data); - if(this->releaseMaster()){ - chipSelect.set(); - } + while(!this->releaseMaster()){} + chipSelect.set(); } template @@ -456,11 +448,10 @@ modm::Mcp2515::readStatus(uint8_t type) RF_WAIT_UNTIL(this->acquireMaster()); chipSelect.reset(); - statusBuffer_ = RF_CALL(spi.transfer(type)); - RF_CALL(spi.transfer(0xff)); - if(this->releaseMaster()) { - chipSelect.set(); - } + RF_CALL(spi.transfer(type)); + statusBuffer_ = RF_CALL(spi.transfer(0xff)); + RF_WAIT_UNTIL(this->releaseMaster()); + chipSelect.set(); RF_END_RETURN(statusBuffer_); } @@ -496,9 +487,7 @@ modm::Mcp2515::writeIdentifier(const uint32_t& identifier, RF_CALL(spi.transfer(0)); RF_CALL(spi.transfer(0)); } - if(this->releaseMaster()) { - chipSelect.set(); - } + RF_WAIT_UNTIL(this->releaseMaster()); RF_END(); } @@ -516,7 +505,7 @@ modm::Mcp2515::readIdentifier(uint32_t &identifier) a_ = RF_CALL(spi.transfer(0xff)); b_ = RF_CALL(spi.transfer(0xff)); - temp2_ = false; + temp_ = false; if (b_ & MCP2515_IDE) { @@ -528,7 +517,7 @@ modm::Mcp2515::readIdentifier(uint32_t &identifier) *((uint8_t *)ptr) = RF_CALL(spi.transfer(0xff)); - temp2_ = true; + temp_ = true; } else { RF_CALL(spi.transfer(0xff)); @@ -542,9 +531,7 @@ modm::Mcp2515::readIdentifier(uint32_t &identifier) *((uint8_t *)ptr) |= b_ >> 5; } - if(this->releaseMaster()){ - chipSelect.set(); - } + RF_WAIT_UNTIL(this->releaseMaster()); - RF_END_RETURN(temp2_); + RF_END_RETURN(temp_); } \ No newline at end of file From a34f35d29c7e59e6da727367ddb6568ccfb33075 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Mon, 7 Feb 2022 18:49:52 +0100 Subject: [PATCH 19/29] accidentally commited stuff that was not supposed to be in here --- examples/stm32f4_discovery/can2/main.cpp | 17 +++++++++++++++-- examples/stm32f4_discovery/can2/project.xml | 2 +- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/examples/stm32f4_discovery/can2/main.cpp b/examples/stm32f4_discovery/can2/main.cpp index a014e3aa3f..c8fc1d9538 100644 --- a/examples/stm32f4_discovery/can2/main.cpp +++ b/examples/stm32f4_discovery/can2/main.cpp @@ -24,6 +24,15 @@ * Tested in hardware (F4) on 2018-08-16 by Sebastian Birke. */ +// Create an IODeviceWrapper around the Uart Peripheral we want to use +modm::IODeviceWrapper< Usart2, modm::IOBuffer::BlockIfFull > loggerDevice; + +// Set all four logger streams to use the UART +modm::log::Logger modm::log::debug(loggerDevice); +modm::log::Logger modm::log::info(loggerDevice); +modm::log::Logger modm::log::warning(loggerDevice); +modm::log::Logger modm::log::error(loggerDevice); + // Set the log level #undef MODM_LOG_LEVEL #define MODM_LOG_LEVEL modm::log::DEBUG @@ -66,12 +75,16 @@ main() Board::LedGreen::set(); + // Initialize Usart + Usart2::connect(); + Usart2::initialize(); + MODM_LOG_INFO << "CAN Test Program" << modm::endl; MODM_LOG_INFO << "Initializing Can ..." << modm::endl; // Initialize Can - Can1::connect(Gpio::InputType::PullUp); - bool success = Can1::initialize(9); + Can1::connect(Gpio::InputType::PullUp); + Can1::initialize(9); MODM_LOG_INFO << "Setting up Filter for Can ..." << modm::endl; // Receive every message diff --git a/examples/stm32f4_discovery/can2/project.xml b/examples/stm32f4_discovery/can2/project.xml index f9af0509db..a822d27aac 100644 --- a/examples/stm32f4_discovery/can2/project.xml +++ b/examples/stm32f4_discovery/can2/project.xml @@ -1,5 +1,5 @@ - modm:nucleo-f439zi + modm:disco-f407vg From 6c79bc2260970bd95ff33bb712a020d81eb57037 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Mon, 7 Feb 2022 18:52:16 +0100 Subject: [PATCH 20/29] merge other modm stuff --- ext/adamgreen/crashcatcher | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/adamgreen/crashcatcher b/ext/adamgreen/crashcatcher index 8c13b1f16f..4b210c8aa7 160000 --- a/ext/adamgreen/crashcatcher +++ b/ext/adamgreen/crashcatcher @@ -1 +1 @@ -Subproject commit 8c13b1f16fc7bad386f2ed4aed9e0c5fbec9b397 +Subproject commit 4b210c8aa7191a228ebe6f285eef828f74b9374f From 6e6e35992ba4d87217678b834e86e1c02a5a9649 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Tue, 8 Feb 2022 17:17:30 +0100 Subject: [PATCH 21/29] removed debug log because ci will fail for avr if we leave the log level intact --- src/modm/driver/can/mcp2515_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index 988b25c3d0..583d44f6d7 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -22,7 +22,7 @@ // Set the log level #undef MODM_LOG_LEVEL -#define MODM_LOG_LEVEL modm::log::DEBUG +#define MODM_LOG_LEVEL modm::log::DISABLED // ---------------------------------------------------------------------------- From 49091cf948d8f2ac9ea014aec2e18f32553560ea Mon Sep 17 00:00:00 2001 From: kikass13 Date: Fri, 11 Feb 2022 15:56:53 +0100 Subject: [PATCH 22/29] small acquire/release spi master fix for blocking setFilter and bitModify() --- src/modm/driver/can/mcp2515_impl.hpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index 583d44f6d7..163caafdd5 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -123,6 +123,8 @@ modm::Mcp2515::setFilter(accessor::Flash filter) { using namespace mcp2515; + while(!this->acquireMaster()){}; + // change to configuration mode bitModify(CANCTRL, 0xe0, REQOP2); @@ -130,7 +132,6 @@ modm::Mcp2515::setFilter(accessor::Flash filter) writeRegister(RXB0CTRL, BUKT); writeRegister(RXB1CTRL, 0); - while(!this->acquireMaster()){}; uint8_t i, j; for (i = 0; i < 0x30; i += 0x10) { @@ -147,10 +148,10 @@ modm::Mcp2515::setFilter(accessor::Flash filter) } chipSelect.set(); } - while(!this->releaseMaster()); chipSelect.set(); - bitModify(CANCTRL, 0xe0, 0); + + while(!this->releaseMaster()); } // ---------------------------------------------------------------------------- @@ -430,13 +431,11 @@ template void modm::Mcp2515::bitModify(uint8_t address, uint8_t mask, uint8_t data) { - while(!this->acquireMaster()){}; chipSelect.reset(); spi.transferBlocking(BIT_MODIFY); spi.transferBlocking(address); spi.transferBlocking(mask); spi.transferBlocking(data); - while(!this->releaseMaster()){} chipSelect.set(); } From dadd55f9d2aab2e9ae7b31304ee4090c3728705c Mon Sep 17 00:00:00 2001 From: kikass13 Date: Wed, 23 Feb 2022 21:37:25 +0100 Subject: [PATCH 23/29] small send rearrange, The send function will now skip sending a packet (aka NOT attempting to send it) if the mcp is not readyToSend() instead of waiting for it to be ready, which defeats the point of buffering packets indefiniteley --- src/modm/driver/can/mcp2515.hpp | 1 - src/modm/driver/can/mcp2515_impl.hpp | 92 +++++++++++++++------------- 2 files changed, 48 insertions(+), 45 deletions(-) diff --git a/src/modm/driver/can/mcp2515.hpp b/src/modm/driver/can/mcp2515.hpp index 9b6e1290cf..476237e54a 100644 --- a/src/modm/driver/can/mcp2515.hpp +++ b/src/modm/driver/can/mcp2515.hpp @@ -263,7 +263,6 @@ namespace modm bool tempR_ = false; bool tempS_ = false; bool temp_ = false; - bool hasSend_ = false; bool receiveSuccess_ = false; }; } diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index 163caafdd5..4ff453fb1e 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -216,11 +216,13 @@ template bool modm::Mcp2515::sendMessage(const can::Message& message) { + bool success = true; if (not modm_assert_continue_ignore(txQueue.push(message), "mcp2515.can.tx", "CAN transmit software buffer overflowed!", 1)) { - return false; + /// buffer full, could not send + success = false; } - return true; + return success; } // ---------------------------------------------------------------------------- @@ -297,8 +299,9 @@ modm::Mcp2515::update(){ /// check if device accepts messages and start emptying the transmit queue if not empty if (txQueue.isNotEmpty()) { - hasSend_ = RF_CALL(mcp2515SendMessage(txQueue.get())); - txQueue.pop(); + if(RF_CALL(mcp2515SendMessage(txQueue.get()))){ + txQueue.pop(); + } } RF_END(); } @@ -336,12 +339,10 @@ modm::Mcp2515::mcp2515IsReadyToSend(uint8_t status) // all buffers currently in use ready = false; } - return ready; } // ---------------------------------------------------------------------------- - template modm::ResumableResult modm::Mcp2515::mcp2515SendMessage(const can::Message& message) @@ -351,52 +352,55 @@ modm::Mcp2515::mcp2515SendMessage(const can::Message& message) statusBufferS_ = RF_CALL(readStatus(READ_STATUS)); - /// wait for ready to send status flags - RF_WAIT_UNTIL(mcp2515IsReadyToSend(statusBufferS_)); - - if ((statusBufferS_ & TXB0CNTRL_TXREQ) == 0) - { - addressBufferS_ = 0x00; // TXB0SIDH - } else if ((statusBufferS_ & TXB1CNTRL_TXREQ) == 0) - { - addressBufferS_ = 0x02; // TXB1SIDH - } else if ((statusBufferS_ & TXB2CNTRL_TXREQ) == 0) - { - addressBufferS_ = 0x04; // TXB2SIDH - } else - { - // all buffer are in use => could not send the message - } + addressBufferS_ = static_cast(false); - if (addressBufferS_ == 0x00 || addressBufferS_ == 0x02 || addressBufferS_ == 0x04) + // /// send if ready, else return that nothing was sent + if(mcp2515IsReadyToSend(statusBufferS_)) { - RF_WAIT_UNTIL(this->acquireMaster()); - chipSelect.reset(); - RF_CALL(spi.transfer(WRITE_TX | addressBufferS_)); - RF_CALL(writeIdentifier(message.identifier, message.flags.extended)); - - // if the message is a rtr-frame, is has a length but no attached data - if (message.flags.rtr) + if ((statusBufferS_ & TXB0CNTRL_TXREQ) == 0) { - RF_CALL(spi.transfer(MCP2515_RTR | message.length)); + addressBufferS_ = 0x00; // TXB0SIDH + } else if ((statusBufferS_ & TXB1CNTRL_TXREQ) == 0) + { + addressBufferS_ = 0x02; // TXB1SIDH + } else if ((statusBufferS_ & TXB2CNTRL_TXREQ) == 0) + { + addressBufferS_ = 0x04; // TXB2SIDH } else { - RF_CALL(spi.transfer(message.length)); + // all buffer are in use => could not send the message + } - for (i_ = 0; i_ < message.length; ++i_) { - RF_CALL(spi.transfer(message.data[i_])); + if (addressBufferS_ == 0x00 || addressBufferS_ == 0x02 || addressBufferS_ == 0x04) + { + RF_WAIT_UNTIL(this->acquireMaster()); + chipSelect.reset(); + RF_CALL(spi.transfer(WRITE_TX | addressBufferS_)); + RF_CALL(writeIdentifier(message.identifier, message.flags.extended)); + + // if the message is a rtr-frame, is has a length but no attached data + if (message.flags.rtr) + { + RF_CALL(spi.transfer(MCP2515_RTR | message.length)); + } else + { + RF_CALL(spi.transfer(message.length)); + + for (i_ = 0; i_ < message.length; ++i_) { + RF_CALL(spi.transfer(message.data[i_])); + } } + delayS_.restart(1ms); + chipSelect.set(); + RF_WAIT_UNTIL(delayS_.isExpired()); + + // send message via RTS command + chipSelect.reset(); + addressBufferS_ = (addressBufferS_ == 0) ? 1 : addressBufferS_; // 0 2 4 => 1 2 4 + RF_CALL(spi.transfer(RTS | addressBufferS_)); + RF_WAIT_UNTIL(this->releaseMaster()); + chipSelect.set(); } - delayS_.restart(1ms); - chipSelect.set(); - RF_WAIT_UNTIL(delayS_.isExpired()); - - // send message via RTS command - chipSelect.reset(); - addressBufferS_ = (addressBufferS_ == 0) ? 1 : addressBufferS_; // 0 2 4 => 1 2 4 - RF_CALL(spi.transfer(RTS | addressBufferS_)); - RF_WAIT_UNTIL(this->releaseMaster()); - chipSelect.set(); } RF_END_RETURN(static_cast(addressBufferS_)); From 5ac11f47ebb1b245744f20280c4a4ab6d9ec0af8 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Thu, 24 Feb 2022 22:22:14 +0100 Subject: [PATCH 24/29] fixed some things related to comments from @rleh; cleanup of exmaple code; minor style changes to mcp2515 driver impl --- examples/nucleo_f439zi/can_m2515/main.cpp | 93 ++++++++++++----------- src/modm/driver/can/mcp2515.hpp | 2 +- src/modm/driver/can/mcp2515.lb | 1 - src/modm/driver/can/mcp2515_impl.hpp | 17 ++--- 4 files changed, 55 insertions(+), 58 deletions(-) diff --git a/examples/nucleo_f439zi/can_m2515/main.cpp b/examples/nucleo_f439zi/can_m2515/main.cpp index 97f15afbfa..b1cf68927e 100644 --- a/examples/nucleo_f439zi/can_m2515/main.cpp +++ b/examples/nucleo_f439zi/can_m2515/main.cpp @@ -17,8 +17,6 @@ #include #include -#define SENDER 1 - // Set the log level #undef MODM_LOG_LEVEL #define MODM_LOG_LEVEL modm::log::DEBUG @@ -36,27 +34,28 @@ using SpiMaster = SpiMaster1; // Default filters to receive any extended CAN frame FLASH_STORAGE(uint8_t canFilter[]) = { - MCP2515_FILTER_EXTENDED(0), // Filter 0 - MCP2515_FILTER_EXTENDED(0), // Filter 1 + MCP2515_FILTER_EXTENDED(0), // Filter 0 + MCP2515_FILTER_EXTENDED(0), // Filter 1 - MCP2515_FILTER_EXTENDED(0), // Filter 2 - MCP2515_FILTER_EXTENDED(0), // Filter 3 - MCP2515_FILTER_EXTENDED(0), // Filter 4 - MCP2515_FILTER_EXTENDED(0), // Filter 5 + MCP2515_FILTER(0), // Filter 2 + MCP2515_FILTER(0), // Filter 3 + MCP2515_FILTER(0), // Filter 4 + MCP2515_FILTER(0), // Filter 5 - MCP2515_FILTER_EXTENDED(0), // Mask 0 - MCP2515_FILTER_EXTENDED(0), // Mask 1 + MCP2515_MASK_EXTENDED(0), // Mask 0 + MCP2515_MASK(0), // Mask 1 }; modm::Mcp2515 mcp2515; -class MyTask : modm::pt::Protothread +class CanThread : modm::pt::Protothread { public: - MyTask() : - message_{0x1337}, - i_{0}, - j_{0} + CanThread() : + message_{}, + wait_{1s}, + i{0}, + j{0} {} bool @@ -65,75 +64,77 @@ class MyTask : modm::pt::Protothread PT_BEGIN(); MODM_LOG_INFO << "Initializing mcp2515 ..." << modm::endl; - // Configure MCP2515 and set the filters - initialized_ = mcp2515.initialize<8_MHz, 500_kbps>(); - MODM_LOG_INFO << "Success: " << initialized_ << modm::endl; + // Configure MCP2515 + while (!mcp2515.initialize<8_MHz, 500_kbps>()){ + PT_WAIT_UNTIL(wait_.isExpired()); + wait_.restart(); + } + /// Set filters of MCP2515 + MODM_LOG_INFO << "Setting filters of mcp2515 ..." << modm::endl; mcp2515.setFilter(modm::accessor::asFlash(canFilter)); MODM_LOG_INFO << "Running ... " << modm::endl; -#if SENDER == 0 - while (initialized_) + while (true) { // receive messages if (mcp2515.isMessageAvailable()) { MODM_LOG_INFO << "Message Available ... " << modm::endl; mcp2515.getMessage(message_); - for(i_ = 0; i_ < message_.length; ++i_){ - MODM_LOG_INFO << modm::hex<< " 0x" << message_.data[i_]; + MODM_LOG_INFO << "Received message: " << modm::hex << message_.identifier << modm::endl; + for(i = 0; i < message_.length; ++i){ + MODM_LOG_INFO << modm::hex<< " 0x" << message_.data[i]; } MODM_LOG_INFO << modm::endl; - MODM_LOG_INFO << "Received message [" << j_ << "]: " << modm::hex << message_.identifier << modm::endl; - j_+=1; MODM_LOG_INFO << modm::endl; } - PT_CALL(mcp2515.update()); - } -#else - while (initialized_) - { - wait_.restart(1000ms); - PT_WAIT_UNTIL(wait_.isExpired()); - message_.length = 2; - message_.data[0] = i_++; - message_.data[1] = i_++; - MODM_LOG_INFO << "Sending Message ... "<< modm::endl; - for(j_ = 0; j_ < message_.length; ++j_){ - MODM_LOG_INFO << modm::hex<< " 0x" << message_.data[j_]; + + if(wait_.isExpired()) + { + wait_.restart(1000ms); + message_.identifier = 0xAA; + message_.length = 2; + message_.data[0] = 13; + message_.data[1] = 37; + MODM_LOG_INFO << "Sending Message ... "<< modm::endl; + for(j = 0; j < message_.length; ++j){ + MODM_LOG_INFO << modm::hex<< " 0x" << message_.data[j]; + } + MODM_LOG_INFO << modm::endl; + MODM_LOG_INFO << "Success: " << mcp2515.sendMessage(message_) << modm::endl; } - MODM_LOG_INFO << modm::endl; - mcp2515.sendMessage(message_); + + /// process internal mcp2515 queues PT_CALL(mcp2515.update()); + PT_YIELD(); } -#endif PT_END(); } private: modm::can::Message message_; - bool initialized_; modm::ShortTimeout wait_; - uint8_t i_, j_; + uint8_t i, j; }; -MyTask task; +CanThread canThread; int main() { Board::initialize(); - MODM_LOG_INFO << "Hello" << modm::endl; + MODM_LOG_INFO << "Mcp2515 Example" << modm::endl; // Initialize SPI interface and the other pins // needed by the MCP2515 SpiMaster::connect(); /// we initialize a higher baud rate then n the avr example, dunnow hats the mcp2515 is capable /// of - SpiMaster::initialize(); + SpiMaster::initialize(); Cs::setOutput(); Int::setInput(Gpio::InputType::PullUp); while (true) { - task.run(); + canThread.run(); } } \ No newline at end of file diff --git a/src/modm/driver/can/mcp2515.hpp b/src/modm/driver/can/mcp2515.hpp index 476237e54a..e22b1478e9 100644 --- a/src/modm/driver/can/mcp2515.hpp +++ b/src/modm/driver/can/mcp2515.hpp @@ -260,7 +260,7 @@ namespace modm uint8_t a_ = 0; uint8_t b_ = 0; uint8_t data_ = 0; - bool tempR_ = false; + bool readTemp_ = false; bool tempS_ = false; bool temp_ = false; bool receiveSuccess_ = false; diff --git a/src/modm/driver/can/mcp2515.lb b/src/modm/driver/can/mcp2515.lb index 1abbf51e47..a4cf69f276 100644 --- a/src/modm/driver/can/mcp2515.lb +++ b/src/modm/driver/can/mcp2515.lb @@ -31,7 +31,6 @@ def prepare(module, options): ":architecture:can", ":architecture:clock", ":architecture:delay", - ":architecture:interrupt", ":architecture:spi.device", ":processing:protothread", ":processing:timer", diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index 4ff453fb1e..aa0e9805e4 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -216,13 +216,12 @@ template bool modm::Mcp2515::sendMessage(const can::Message& message) { - bool success = true; if (not modm_assert_continue_ignore(txQueue.push(message), "mcp2515.can.tx", "CAN transmit software buffer overflowed!", 1)) { /// buffer full, could not send - success = false; + return false; } - return success; + return true; } // ---------------------------------------------------------------------------- @@ -237,7 +236,7 @@ modm::Mcp2515::mcp2515ReadMessage() // read status flag of the device statusBufferR_ = RF_CALL(readStatus(RX_STATUS)); - tempR_ = true; + readTemp_ = true; if (statusBufferR_ & FLAG_RXB0_FULL) { addressBufferR_ = READ_RX; // message in buffer 0 } @@ -245,10 +244,10 @@ modm::Mcp2515::mcp2515ReadMessage() addressBufferR_ = READ_RX | 0x04; // message in buffer 1 (RXB1SIDH) } else { - tempR_ = false; // Error: no message available + readTemp_ = false; // Error: no message available } - if(tempR_) + if(readTemp_) { RF_WAIT_UNTIL(this->acquireMaster()); chipSelect.reset(); @@ -274,7 +273,7 @@ modm::Mcp2515::mcp2515ReadMessage() // RX0IF or RX1IF respectivly were already cleared automatically by rising CS. // See section 12.4 in datasheet. - RF_END_RETURN(tempR_); + RF_END_RETURN(readTemp_); } template @@ -290,9 +289,7 @@ modm::Mcp2515::update(){ if(RF_CALL(mcp2515ReadMessage())) { if(not modm_assert_continue_ignore(rxQueue.push(messageBuffer_), "mcp2515.can.tx", - "CAN transmit software buffer overflowed!", 1)){ - /// ignore - } + "CAN transmit software buffer overflowed!", 1)){} } } From 2b5b355f23290f38541bca2a32d1c4c9af40c0e3 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Sat, 26 Feb 2022 14:43:36 +0100 Subject: [PATCH 25/29] @rleh: added rx & tx queue options to lbuild + mcp2515 driver; removed unused project xml things; cleaned up unused headers; changed mcp2515 driver class attributes to not have _ underscore postfix --- examples/nucleo_f439zi/can_m2515/main.cpp | 1 - examples/nucleo_f439zi/can_m2515/project.xml | 9 +- src/modm/driver/can/mcp2515.hpp | 41 ++++--- src/modm/driver/can/mcp2515.lb | 15 +++ src/modm/driver/can/mcp2515_impl.hpp | 120 +++++++++---------- src/modm/driver/can/mcp2515_options.hpp.in | 22 ++++ 6 files changed, 120 insertions(+), 88 deletions(-) create mode 100644 src/modm/driver/can/mcp2515_options.hpp.in diff --git a/examples/nucleo_f439zi/can_m2515/main.cpp b/examples/nucleo_f439zi/can_m2515/main.cpp index b1cf68927e..8dcfd41538 100644 --- a/examples/nucleo_f439zi/can_m2515/main.cpp +++ b/examples/nucleo_f439zi/can_m2515/main.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include diff --git a/examples/nucleo_f439zi/can_m2515/project.xml b/examples/nucleo_f439zi/can_m2515/project.xml index c1433fb0c7..150e1be193 100644 --- a/examples/nucleo_f439zi/can_m2515/project.xml +++ b/examples/nucleo_f439zi/can_m2515/project.xml @@ -1,18 +1,15 @@ modm:nucleo-f439zi - + + + - modm:platform:gpio - modm:platform:spi.bitbang modm:platform:spi:1 - modm:platform:spi:2 modm:build:scons - modm:processing:protothread modm:processing:timer modm:driver:mcp2515 - \ No newline at end of file diff --git a/src/modm/driver/can/mcp2515.hpp b/src/modm/driver/can/mcp2515.hpp index e22b1478e9..13bd0ab0f6 100644 --- a/src/modm/driver/can/mcp2515.hpp +++ b/src/modm/driver/can/mcp2515.hpp @@ -21,13 +21,13 @@ #include #include #include -#include #include #include #include #include #include "mcp2515_definitions.hpp" +#include "mcp2515_options.hpp" /** * \name Restructure filter and mask bits for the MCP2515 @@ -125,7 +125,7 @@ namespace modm protected modm::NestedResumable<4> { public: - Mcp2515() : messageBuffer_{}, delayR_{}, delayS_{} { + Mcp2515() : messageBuffer{}, delayS{} { this->attachConfigurationHandler([]() { SPI::setDataMode(SPI::DataMode::Mode3); SPI::setDataOrder(SPI::DataOrder::MsbFirst); @@ -240,30 +240,29 @@ namespace modm readIdentifier(uint32_t& identifier); private: - inline static modm::atomic::Queue txQueue; - inline static modm::atomic::Queue rxQueue; + inline static modm::mcp2515::options::TX_QUEUE txQueue; + inline static modm::mcp2515::options::RX_QUEUE rxQueue; static SPI spi; static CS chipSelect; static INT interruptPin; - modm::can::Message messageBuffer_; - modm::ShortTimeout delayR_; - modm::ShortTimeout delayS_; - uint8_t statusBuffer_ = 0; - uint8_t statusBufferR_ = 0; - uint8_t statusBufferS_ = 0; - uint8_t statusBufferReady_ = 0; - uint8_t addressBufferR_ = 0; - uint8_t addressBufferS_ = 0; - uint8_t i_, j_ = 0; - uint8_t a_ = 0; - uint8_t b_ = 0; - uint8_t data_ = 0; - bool readTemp_ = false; - bool tempS_ = false; - bool temp_ = false; - bool receiveSuccess_ = false; + modm::can::Message messageBuffer; + modm::ShortTimeout delayS; + uint8_t statusBuffer = 0; + uint8_t statusBufferR = 0; + uint8_t statusBufferS = 0; + uint8_t statusBufferReady = 0; + uint8_t addressBufferR = 0; + uint8_t addressBufferS = 0; + uint8_t i, j = 0; + uint8_t a = 0; + uint8_t b = 0; + uint8_t data = 0; + bool readTemp = false; + bool tempS = false; + bool temp = false; + bool receiveSuccess = false; }; } diff --git a/src/modm/driver/can/mcp2515.lb b/src/modm/driver/can/mcp2515.lb index a4cf69f276..1eff76bb2a 100644 --- a/src/modm/driver/can/mcp2515.lb +++ b/src/modm/driver/can/mcp2515.lb @@ -25,6 +25,19 @@ def prepare(module, options): "is selected according to the clock speed.", default="16MHz")) + module.add_option( + NumericOption( + name="buffer.tx", + description="", + minimum=1, maximum=2 ** 16 - 2, + default=32)) + module.add_option( + NumericOption( + name="buffer.rx", + description="", + minimum=1, maximum=2 ** 16 - 2, + default=32)) + module.depends( ":architecture:accessor", ":architecture:assert", @@ -44,3 +57,5 @@ def build(env): env.copy("mcp2515_bit_timings.hpp") env.copy("mcp2515_definitions.hpp") env.template("mcp2515.cpp.in") + env.template("mcp2515_options.hpp.in") + diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index aa0e9805e4..6dbcf4f7fa 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -17,7 +17,7 @@ #error "Don't include this file directly, use 'mcp2515.hpp' instead!" #endif #include "mcp2515_bit_timings.hpp" -#include "mcp2515_definitions.hpp" +#include "mcp2515_options.hpp" #include // Set the log level @@ -234,38 +234,38 @@ modm::Mcp2515::mcp2515ReadMessage() RF_BEGIN(); // read status flag of the device - statusBufferR_ = RF_CALL(readStatus(RX_STATUS)); + statusBufferR = RF_CALL(readStatus(RX_STATUS)); - readTemp_ = true; - if (statusBufferR_ & FLAG_RXB0_FULL) { - addressBufferR_ = READ_RX; // message in buffer 0 + readTemp = true; + if (statusBufferR & FLAG_RXB0_FULL) { + addressBufferR = READ_RX; // message in buffer 0 } - else if (statusBufferR_ & FLAG_RXB1_FULL) { - addressBufferR_ = READ_RX | 0x04; // message in buffer 1 (RXB1SIDH) + else if (statusBufferR & FLAG_RXB1_FULL) { + addressBufferR = READ_RX | 0x04; // message in buffer 1 (RXB1SIDH) } else { - readTemp_ = false; // Error: no message available + readTemp = false; // Error: no message available } - if(readTemp_) + if(readTemp) { RF_WAIT_UNTIL(this->acquireMaster()); chipSelect.reset(); - RF_CALL(spi.transfer(addressBufferR_)); + RF_CALL(spi.transfer(addressBufferR)); - messageBuffer_.flags.extended = RF_CALL(readIdentifier(messageBuffer_.identifier)); - if (statusBufferR_ & FLAG_RTR) { - messageBuffer_.flags.rtr = true; + messageBuffer.flags.extended = RF_CALL(readIdentifier(messageBuffer.identifier)); + if (statusBufferR & FLAG_RTR) { + messageBuffer.flags.rtr = true; } else { - messageBuffer_.flags.rtr = false; + messageBuffer.flags.rtr = false; } - messageBuffer_.length = RF_CALL(spi.transfer(0xff)) & 0x0f; + messageBuffer.length = RF_CALL(spi.transfer(0xff)) & 0x0f; - for (j_ = 0; j_ < messageBuffer_.length; ++j_) { - data_ = RF_CALL(spi.transfer(0xff)); - messageBuffer_.data[j_] = data_; + for (j = 0; j < messageBuffer.length; ++j) { + data = RF_CALL(spi.transfer(0xff)); + messageBuffer.data[j] = data; } RF_WAIT_UNTIL(this->releaseMaster()); chipSelect.set(); @@ -273,7 +273,7 @@ modm::Mcp2515::mcp2515ReadMessage() // RX0IF or RX1IF respectivly were already cleared automatically by rising CS. // See section 12.4 in datasheet. - RF_END_RETURN(readTemp_); + RF_END_RETURN(readTemp); } template @@ -288,7 +288,7 @@ modm::Mcp2515::update(){ if(!interruptPin.read()){ if(RF_CALL(mcp2515ReadMessage())) { - if(not modm_assert_continue_ignore(rxQueue.push(messageBuffer_), "mcp2515.can.tx", + if(not modm_assert_continue_ignore(rxQueue.push(messageBuffer), "mcp2515.can.tx", "CAN transmit software buffer overflowed!", 1)){} } } @@ -313,16 +313,16 @@ modm::Mcp2515::mcp2515IsReadyToSend() RF_BEGIN(); - tempS_ = true; - statusBufferReady_ = RF_CALL(readStatus(READ_STATUS)); - if (( statusBufferReady_& (TXB2CNTRL_TXREQ | TXB1CNTRL_TXREQ | TXB0CNTRL_TXREQ)) == + tempS = true; + statusBufferReady = RF_CALL(readStatus(READ_STATUS)); + if (( statusBufferReady& (TXB2CNTRL_TXREQ | TXB1CNTRL_TXREQ | TXB0CNTRL_TXREQ)) == (TXB2CNTRL_TXREQ | TXB1CNTRL_TXREQ | TXB0CNTRL_TXREQ)) { // all buffers currently in use - tempS_ = false; + tempS = false; } - RF_END_RETURN(tempS_); + RF_END_RETURN(tempS); } template bool @@ -347,32 +347,32 @@ modm::Mcp2515::mcp2515SendMessage(const can::Message& message) using namespace modm::mcp2515; RF_BEGIN(); - statusBufferS_ = RF_CALL(readStatus(READ_STATUS)); + statusBufferS = RF_CALL(readStatus(READ_STATUS)); - addressBufferS_ = static_cast(false); + addressBufferS = static_cast(false); // /// send if ready, else return that nothing was sent - if(mcp2515IsReadyToSend(statusBufferS_)) + if(mcp2515IsReadyToSend(statusBufferS)) { - if ((statusBufferS_ & TXB0CNTRL_TXREQ) == 0) + if ((statusBufferS & TXB0CNTRL_TXREQ) == 0) { - addressBufferS_ = 0x00; // TXB0SIDH - } else if ((statusBufferS_ & TXB1CNTRL_TXREQ) == 0) + addressBufferS = 0x00; // TXB0SIDH + } else if ((statusBufferS & TXB1CNTRL_TXREQ) == 0) { - addressBufferS_ = 0x02; // TXB1SIDH - } else if ((statusBufferS_ & TXB2CNTRL_TXREQ) == 0) + addressBufferS = 0x02; // TXB1SIDH + } else if ((statusBufferS & TXB2CNTRL_TXREQ) == 0) { - addressBufferS_ = 0x04; // TXB2SIDH + addressBufferS = 0x04; // TXB2SIDH } else { // all buffer are in use => could not send the message } - if (addressBufferS_ == 0x00 || addressBufferS_ == 0x02 || addressBufferS_ == 0x04) + if (addressBufferS == 0x00 || addressBufferS == 0x02 || addressBufferS == 0x04) { RF_WAIT_UNTIL(this->acquireMaster()); chipSelect.reset(); - RF_CALL(spi.transfer(WRITE_TX | addressBufferS_)); + RF_CALL(spi.transfer(WRITE_TX | addressBufferS)); RF_CALL(writeIdentifier(message.identifier, message.flags.extended)); // if the message is a rtr-frame, is has a length but no attached data @@ -383,24 +383,24 @@ modm::Mcp2515::mcp2515SendMessage(const can::Message& message) { RF_CALL(spi.transfer(message.length)); - for (i_ = 0; i_ < message.length; ++i_) { - RF_CALL(spi.transfer(message.data[i_])); + for (i = 0; i < message.length; ++i) { + RF_CALL(spi.transfer(message.data[i])); } } - delayS_.restart(1ms); + delayS.restart(1ms); chipSelect.set(); - RF_WAIT_UNTIL(delayS_.isExpired()); + RF_WAIT_UNTIL(delayS.isExpired()); // send message via RTS command chipSelect.reset(); - addressBufferS_ = (addressBufferS_ == 0) ? 1 : addressBufferS_; // 0 2 4 => 1 2 4 - RF_CALL(spi.transfer(RTS | addressBufferS_)); + addressBufferS = (addressBufferS == 0) ? 1 : addressBufferS; // 0 2 4 => 1 2 4 + RF_CALL(spi.transfer(RTS | addressBufferS)); RF_WAIT_UNTIL(this->releaseMaster()); chipSelect.set(); } } - RF_END_RETURN(static_cast(addressBufferS_)); + RF_END_RETURN(static_cast(addressBufferS)); } // ---------------------------------------------------------------------------- @@ -449,11 +449,11 @@ modm::Mcp2515::readStatus(uint8_t type) RF_WAIT_UNTIL(this->acquireMaster()); chipSelect.reset(); RF_CALL(spi.transfer(type)); - statusBuffer_ = RF_CALL(spi.transfer(0xff)); + statusBuffer = RF_CALL(spi.transfer(0xff)); RF_WAIT_UNTIL(this->releaseMaster()); chipSelect.set(); - RF_END_RETURN(statusBuffer_); + RF_END_RETURN(statusBuffer); } // ---------------------------------------------------------------------------- @@ -474,10 +474,10 @@ modm::Mcp2515::writeIdentifier(const uint32_t& identifier, RF_CALL(spi.transfer(*((uint16_t *)ptr + 1) >> 5)); // calculate the next values - a_ = (*((uint8_t *)ptr + 2) << 3) & 0xe0; - a_ |= MCP2515_IDE; - a_ |= (*((uint8_t *)ptr + 2)) & 0x03; - RF_CALL(spi.transfer(a_)); + a = (*((uint8_t *)ptr + 2) << 3) & 0xe0; + a |= MCP2515_IDE; + a |= (*((uint8_t *)ptr + 2)) & 0x03; + RF_CALL(spi.transfer(a)); RF_CALL(spi.transfer(*((uint8_t *)ptr + 1))); RF_CALL(spi.transfer(*((uint8_t *)ptr))); } else @@ -502,22 +502,22 @@ modm::Mcp2515::readIdentifier(uint32_t &identifier) RF_BEGIN(); RF_WAIT_UNTIL(this->acquireMaster()); - a_ = RF_CALL(spi.transfer(0xff)); - b_ = RF_CALL(spi.transfer(0xff)); + a = RF_CALL(spi.transfer(0xff)); + b = RF_CALL(spi.transfer(0xff)); - temp_ = false; + temp = false; - if (b_ & MCP2515_IDE) + if (b & MCP2515_IDE) { - *((uint16_t *)ptr + 1) = (uint16_t)a_ << 5; + *((uint16_t *)ptr + 1) = (uint16_t)a << 5; *((uint8_t *)ptr + 1) = RF_CALL(spi.transfer(0xff)); - *((uint8_t *)ptr + 2) |= (b_ >> 3) & 0x1C; - *((uint8_t *)ptr + 2) |= b_ & 0x03; + *((uint8_t *)ptr + 2) |= (b >> 3) & 0x1C; + *((uint8_t *)ptr + 2) |= b & 0x03; *((uint8_t *)ptr) = RF_CALL(spi.transfer(0xff)); - temp_ = true; + temp = true; } else { RF_CALL(spi.transfer(0xff)); @@ -525,13 +525,13 @@ modm::Mcp2515::readIdentifier(uint32_t &identifier) *((uint8_t *)ptr + 3) = 0; *((uint8_t *)ptr + 2) = 0; - *((uint16_t *)ptr) = (uint16_t)a_ << 3; + *((uint16_t *)ptr) = (uint16_t)a << 3; RF_CALL(spi.transfer(0xff)); - *((uint8_t *)ptr) |= b_ >> 5; + *((uint8_t *)ptr) |= b >> 5; } RF_WAIT_UNTIL(this->releaseMaster()); - RF_END_RETURN(temp_); + RF_END_RETURN(temp); } \ No newline at end of file diff --git a/src/modm/driver/can/mcp2515_options.hpp.in b/src/modm/driver/can/mcp2515_options.hpp.in new file mode 100644 index 0000000000..c058a9377d --- /dev/null +++ b/src/modm/driver/can/mcp2515_options.hpp.in @@ -0,0 +1,22 @@ + +#ifndef MODM_MCP2515_OPTIONS_HPP +#define MODM_MCP2515_OPTIONS_HPP + +#include + +namespace modm{ +namespace mcp2515{ +namespace options{ + +%% if options["buffer.tx"] > 0 +using TX_QUEUE = modm::atomic::Queue; +%% endif +%% if options["buffer.rx"] > 0 +using RX_QUEUE = modm::atomic::Queue; +%% endif + +} // end namespace options +} // end namespace mcp2515 +} // end namespace modm + +#endif // MODM_MCP2515_OPTIONS_HPP From 5aa143e15aa23c2b7d301f07b0b963dd0e974207 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Sun, 27 Feb 2022 17:42:08 +0100 Subject: [PATCH 26/29] remove useless / harmful modm log level overwrite + debug logs from prescaler --- src/modm/driver/can/mcp2515_impl.hpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index 6dbcf4f7fa..0bb81358f6 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -20,10 +20,6 @@ #include "mcp2515_options.hpp" #include -// Set the log level -#undef MODM_LOG_LEVEL -#define MODM_LOG_LEVEL modm::log::DISABLED - // ---------------------------------------------------------------------------- template @@ -42,18 +38,10 @@ modm::Mcp2515::initializeWithPrescaler( static constexpr uint8_t CNF1_idx = 2; static constexpr uint8_t CNF2_idx = 1; static constexpr uint8_t CNF3_idx = 0; - - MODM_LOG_DEBUG.printf("SJW: %d\nProp: %d\nPS1: %d\nPS2: %d\nprescaler: %d\n", - sjw, prop, ps1, ps2, prescaler); - cnf[CNF1_idx] = ((sjw - 1) << 6) | ((prescaler / 2 - 1) & 0x3f); - cnf[CNF2_idx] = (1 << 7) | ( (ps1 - 1) << 3) | ( (prop - 1) << 0); - cnf[CNF3_idx] = (ps2 - 1); - MODM_LOG_DEBUG.printf("CNF1 %02x, CNF2 %02x, CNF3 %02x\n", cnf[CNF1_idx], cnf[CNF2_idx], cnf[CNF3_idx]); - using namespace mcp2515; // software reset for the mcp2515, after this the chip is back in the From 2e4ad3b59fa8a099026a71c5248cd7008ee5ee34 Mon Sep 17 00:00:00 2001 From: Nick Fiege Date: Wed, 16 Mar 2022 17:26:23 +0100 Subject: [PATCH 27/29] Update src/modm/driver/can/mcp2515_options.hpp.in Co-authored-by: Raphael Lehmann --- src/modm/driver/can/mcp2515_options.hpp.in | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/modm/driver/can/mcp2515_options.hpp.in b/src/modm/driver/can/mcp2515_options.hpp.in index c058a9377d..72bdbb665b 100644 --- a/src/modm/driver/can/mcp2515_options.hpp.in +++ b/src/modm/driver/can/mcp2515_options.hpp.in @@ -4,9 +4,8 @@ #include -namespace modm{ -namespace mcp2515{ -namespace options{ +namespace modm::mcp2515::options +{ %% if options["buffer.tx"] > 0 using TX_QUEUE = modm::atomic::Queue; From 5906e1749bfb8ef7b86b267cec62ebbf2dd5fe6d Mon Sep 17 00:00:00 2001 From: Nick Fiege Date: Wed, 16 Mar 2022 17:27:15 +0100 Subject: [PATCH 28/29] Update src/modm/driver/can/mcp2515_impl.hpp Co-authored-by: Raphael Lehmann --- src/modm/driver/can/mcp2515_impl.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index 0bb81358f6..64877af55f 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -17,6 +17,7 @@ #error "Don't include this file directly, use 'mcp2515.hpp' instead!" #endif #include "mcp2515_bit_timings.hpp" +#include "mcp2515_definitions.hpp" #include "mcp2515_options.hpp" #include From 0ff3eef450e984d349a842c040fe92d345a1a709 Mon Sep 17 00:00:00 2001 From: kikass13 Date: Wed, 16 Mar 2022 18:00:44 +0100 Subject: [PATCH 29/29] fixed some minor pedantic things --- examples/nucleo_f439zi/can_m2515/project.xml | 2 -- src/modm/driver/can/mcp2515.hpp | 9 +++---- src/modm/driver/can/mcp2515_impl.hpp | 27 ++++++++++---------- src/modm/driver/can/mcp2515_options.hpp.in | 12 +++------ 4 files changed, 20 insertions(+), 30 deletions(-) diff --git a/examples/nucleo_f439zi/can_m2515/project.xml b/examples/nucleo_f439zi/can_m2515/project.xml index 150e1be193..9be0b96d5f 100644 --- a/examples/nucleo_f439zi/can_m2515/project.xml +++ b/examples/nucleo_f439zi/can_m2515/project.xml @@ -2,8 +2,6 @@ modm:nucleo-f439zi - - modm:platform:spi:1 diff --git a/src/modm/driver/can/mcp2515.hpp b/src/modm/driver/can/mcp2515.hpp index 136ad057b7..6401c9bb5f 100644 --- a/src/modm/driver/can/mcp2515.hpp +++ b/src/modm/driver/can/mcp2515.hpp @@ -181,7 +181,7 @@ namespace modm * * \return true if a message was send this cycle, false otherwise */ - modm::ResumableResult + modm::ResumableResult update(); @@ -260,10 +260,9 @@ namespace modm uint8_t a = 0; uint8_t b = 0; uint8_t data = 0; - bool readTemp = false; - bool tempS = false; - bool temp = false; - bool receiveSuccess = false; + bool readSuccessfulFlag = false; + bool isReadyToSendFlag = false; + bool readIdentifierSuccessfulFlag = false; }; } diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index 64877af55f..6efc79ce6a 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -225,7 +225,7 @@ modm::Mcp2515::mcp2515ReadMessage() // read status flag of the device statusBufferR = RF_CALL(readStatus(RX_STATUS)); - readTemp = true; + readSuccessfulFlag = true; if (statusBufferR & FLAG_RXB0_FULL) { addressBufferR = READ_RX; // message in buffer 0 } @@ -233,10 +233,10 @@ modm::Mcp2515::mcp2515ReadMessage() addressBufferR = READ_RX | 0x04; // message in buffer 1 (RXB1SIDH) } else { - readTemp = false; // Error: no message available + readSuccessfulFlag = false; // Error: no message available } - if(readTemp) + if(readSuccessfulFlag) { RF_WAIT_UNTIL(this->acquireMaster()); chipSelect.reset(); @@ -262,11 +262,11 @@ modm::Mcp2515::mcp2515ReadMessage() // RX0IF or RX1IF respectivly were already cleared automatically by rising CS. // See section 12.4 in datasheet. - RF_END_RETURN(readTemp); + RF_END_RETURN(readSuccessfulFlag); } template -modm::ResumableResult +modm::ResumableResult modm::Mcp2515::update(){ using namespace mcp2515; @@ -302,30 +302,29 @@ modm::Mcp2515::mcp2515IsReadyToSend() RF_BEGIN(); - tempS = true; + isReadyToSendFlag = true; statusBufferReady = RF_CALL(readStatus(READ_STATUS)); if (( statusBufferReady& (TXB2CNTRL_TXREQ | TXB1CNTRL_TXREQ | TXB0CNTRL_TXREQ)) == (TXB2CNTRL_TXREQ | TXB1CNTRL_TXREQ | TXB0CNTRL_TXREQ)) { // all buffers currently in use - tempS = false; + isReadyToSendFlag = false; } - RF_END_RETURN(tempS); + RF_END_RETURN(isReadyToSendFlag); } template bool modm::Mcp2515::mcp2515IsReadyToSend(uint8_t status) { using namespace mcp2515; - bool ready = true; if ((status & (TXB2CNTRL_TXREQ | TXB1CNTRL_TXREQ | TXB0CNTRL_TXREQ)) == (TXB2CNTRL_TXREQ | TXB1CNTRL_TXREQ | TXB0CNTRL_TXREQ)) { // all buffers currently in use - ready = false; + return false; } - return ready; + return true; } // ---------------------------------------------------------------------------- @@ -494,7 +493,7 @@ modm::Mcp2515::readIdentifier(uint32_t &identifier) a = RF_CALL(spi.transfer(0xff)); b = RF_CALL(spi.transfer(0xff)); - temp = false; + readIdentifierSuccessfulFlag = false; if (b & MCP2515_IDE) { @@ -506,7 +505,7 @@ modm::Mcp2515::readIdentifier(uint32_t &identifier) *((uint8_t *)ptr) = RF_CALL(spi.transfer(0xff)); - temp = true; + readIdentifierSuccessfulFlag = true; } else { RF_CALL(spi.transfer(0xff)); @@ -522,5 +521,5 @@ modm::Mcp2515::readIdentifier(uint32_t &identifier) } RF_WAIT_UNTIL(this->releaseMaster()); - RF_END_RETURN(temp); + RF_END_RETURN(readIdentifierSuccessfulFlag); } \ No newline at end of file diff --git a/src/modm/driver/can/mcp2515_options.hpp.in b/src/modm/driver/can/mcp2515_options.hpp.in index 72bdbb665b..8353a7b15b 100644 --- a/src/modm/driver/can/mcp2515_options.hpp.in +++ b/src/modm/driver/can/mcp2515_options.hpp.in @@ -7,15 +7,9 @@ namespace modm::mcp2515::options { -%% if options["buffer.tx"] > 0 -using TX_QUEUE = modm::atomic::Queue; -%% endif -%% if options["buffer.rx"] > 0 -using RX_QUEUE = modm::atomic::Queue; -%% endif +using TX_QUEUE = modm::atomic::Queue; +using RX_QUEUE = modm::atomic::Queue; -} // end namespace options -} // end namespace mcp2515 -} // end namespace modm +} // namespace modm::mcp2515::options #endif // MODM_MCP2515_OPTIONS_HPP