Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

changed mcp2515 driver to use nonblocking spi #817

Open
wants to merge 30 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
148e788
changed mcp2515 driver to use rx and tx buffers as well as uphold the…
kikass13 Feb 1, 2022
10b0e46
added example; small line cleanup
kikass13 Feb 1, 2022
33db784
added update function to example, change build out dir
kikass13 Feb 1, 2022
21e4036
added nonblocking stuff for can send api part; the read is still bloc…
kikass13 Feb 1, 2022
03639b4
changed read/receive part so that it is polled in the update function…
kikass13 Feb 1, 2022
bf7b0fa
the should now be non static (the rx/tx queues as well); a modm::SpiD…
kikass13 Feb 3, 2022
9584f22
WIP: Add SPI user configuration handler for speed reconfiguration
chris-durand Feb 1, 2022
8e6a52f
added configurationHanlder for spi device, which should also change t…
kikass13 Feb 3, 2022
bda5887
moved example to nucleo_f439; fixed example to work properly
kikass13 Feb 4, 2022
7c9065d
re-enable debug messages in main
kikass13 Feb 4, 2022
5357bc2
re-enable @chris-durand hack for changing bus clock speed in configur…
kikass13 Feb 4, 2022
c177db3
whitespaces
kikass13 Feb 4, 2022
d737638
removed @chris-durand hack again and put the configuration handler in…
kikass13 Feb 4, 2022
f94d31a
small fixes for ci
kikass13 Feb 4, 2022
6f773fc
removed unnecessary function
kikass13 Feb 4, 2022
33a621f
tried to keep the external api static, this means nonblocking initial…
kikass13 Feb 6, 2022
ed406ca
memory error when reading messages,
kikass13 Feb 6, 2022
ec7cf30
fixed bug in receiveMessage part, where status register was not read …
kikass13 Feb 7, 2022
a34f35d
accidentally commited stuff that was not supposed to be in here
kikass13 Feb 7, 2022
6c79bc2
merge other modm stuff
kikass13 Feb 7, 2022
6e6e359
removed debug log because ci will fail for avr if we leave the log le…
kikass13 Feb 8, 2022
49091cf
small acquire/release spi master fix for blocking setFilter and bitMo…
kikass13 Feb 11, 2022
dadd55f
small send rearrange, The send function will now skip sending a packe…
kikass13 Feb 23, 2022
5ac11f4
fixed some things related to comments from @rleh; cleanup of exmaple …
kikass13 Feb 24, 2022
2b5b355
@rleh: added rx & tx queue options to lbuild + mcp2515 driver; remove…
kikass13 Feb 26, 2022
5aa143e
remove useless / harmful modm log level overwrite + debug logs from p…
kikass13 Feb 27, 2022
4d7df65
Merge branch 'develop' into mcp2515_protothread_update_3
kikass13 Mar 3, 2022
2e4ad3b
Update src/modm/driver/can/mcp2515_options.hpp.in
kikass13 Mar 16, 2022
5906e17
Update src/modm/driver/can/mcp2515_impl.hpp
kikass13 Mar 16, 2022
0ff3eef
fixed some minor pedantic things
kikass13 Mar 16, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 139 additions & 0 deletions examples/nucleo_f439zi/can_m2515/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* 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 <modm/board.hpp>
#include <modm/platform/spi/spi_master_1.hpp>
#include <modm/processing/protothread.hpp>
#include <modm/driver/can/mcp2515.hpp>

// Set the log level
#undef MODM_LOG_LEVEL
#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.
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<Sck, Mosi, Miso>;

// 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(0), // Filter 2
MCP2515_FILTER(0), // Filter 3
MCP2515_FILTER(0), // Filter 4
MCP2515_FILTER(0), // Filter 5

MCP2515_MASK_EXTENDED(0), // Mask 0
MCP2515_MASK(0), // Mask 1
};

modm::Mcp2515<SpiMaster, Cs, Int> mcp2515;

class CanThread : modm::pt::Protothread
{
public:
CanThread() :
message_{},
wait_{1s},
i{0},
j{0}
{}

bool
run()
{
PT_BEGIN();

MODM_LOG_INFO << "Initializing mcp2515 ..." << 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;
while (true)
{
// receive messages
if (mcp2515.isMessageAvailable())
{
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 << modm::endl;
}

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;
}

/// process internal mcp2515 queues
PT_CALL(mcp2515.update());
PT_YIELD();
}

PT_END();
}

private:
modm::can::Message message_;
modm::ShortTimeout wait_;
uint8_t i, j;
};

CanThread canThread;

int
main()
{
Board::initialize();

MODM_LOG_INFO << "Mcp2515 Example" << modm::endl;
// Initialize SPI interface and the other pins
// needed by the MCP2515
SpiMaster::connect<Miso::Miso, Mosi::Mosi, Sck::Sck>();
/// we initialize a higher baud rate then n the avr example, dunnow hats the mcp2515 is capable
/// of
SpiMaster::initialize<Board::SystemClock, 10_MHz>();
Cs::setOutput();
Int::setInput(Gpio::InputType::PullUp);

while (true) {
canThread.run();
}
}
13 changes: 13 additions & 0 deletions examples/nucleo_f439zi/can_m2515/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<library>
<extends>modm:nucleo-f439zi</extends>
<options>
<option name="modm:build:build.path">../../../build/nucleo-f439zi/mcp2515</option>
</options>
<modules>
<module>modm:platform:spi:1</module>
<module>modm:build:scons</module>
<module>modm:processing:protothread</module>
<module>modm:processing:timer</module>
<module>modm:driver:mcp2515</module>
</modules>
</library>
82 changes: 68 additions & 14 deletions src/modm/driver/can/mcp2515.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@
#include <modm/architecture/interface/accessor.hpp>
#include <modm/architecture/interface/delay.hpp>
#include <modm/architecture/interface/can.hpp>
#include <modm/architecture/interface/spi_device.hpp>
#include <modm/processing/protothread.hpp>
#include <modm/processing/resumable.hpp>
#include <modm/processing/timer.hpp>
#include <modm/debug/logger.hpp>

#include "mcp2515_definitions.hpp"
#include "mcp2515_options.hpp"

#ifdef __DOXYGEN__

Expand Down Expand Up @@ -116,15 +121,24 @@ namespace modm
template < typename SPI,
typename CS,
typename INT >
class Mcp2515 : public ::modm::Can
class Mcp2515 : public modm::Can,
public modm::SpiDevice<SPI>,
protected modm::NestedResumable<4>
{
public:
Mcp2515() : messageBuffer{}, delayS{} {
this->attachConfigurationHandler([]() {
SPI::setDataMode(SPI::DataMode::Mode3);
SPI::setDataOrder(SPI::DataOrder::MsbFirst);
});
}

template<frequency_t ExternalClock, bitrate_t bitrate=kbps(125), percent_t tolerance=pct(1) >
static inline bool
static bool
initialize();

private:
static inline bool
static bool
initializeWithPrescaler(
uint8_t prescaler,
uint8_t sjw,
Expand All @@ -133,25 +147,25 @@ namespace modm
uint8_t ps2);

public:
static void
void
setFilter(accessor::Flash<uint8_t> filter);

static void
void
setMode(Can::Mode mode);


static inline bool
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.
*
* \return true if a slot is available, false otherwise
*/
static inline bool
static bool
isReadyToSend();

/*
Expand All @@ -162,18 +176,27 @@ namespace modm
static bool
sendMessage(const can::Message& message);

/*
* Poll the transmit buffer (should be called periodically)
*
* \return true if a message was send this cycle, false otherwise
*/
modm::ResumableResult<void>
update();


public:
// Extended Functionality

/*
* Fixme: Empty implementation, required by connector
*/
static BusState
BusState
getBusState() {
return BusState::Connected;
}

protected:
private:
enum SpiCommand
{
RESET = 0xC0,
Expand All @@ -187,28 +210,59 @@ namespace modm
BIT_MODIFY = 0x05
};

modm::ResumableResult<bool>
mcp2515ReadMessage();

bool
mcp2515IsReadyToSend(uint8_t status);

modm::ResumableResult<bool>
mcp2515IsReadyToSend();

modm::ResumableResult<bool>
mcp2515SendMessage(const can::Message& message);

static void
writeRegister(uint8_t address, uint8_t data);

static uint8_t
readRegister(uint8_t address);

static void
void
bitModify(uint8_t address, uint8_t mask, uint8_t data);

static uint8_t
modm::ResumableResult<uint8_t>
readStatus(uint8_t type);

static inline void
modm::ResumableResult<void>
writeIdentifier(const uint32_t& identifier, bool isExtendedFrame);

static inline bool
modm::ResumableResult<bool>
readIdentifier(uint32_t& identifier);

protected:
private:
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 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 readSuccessfulFlag = false;
bool isReadyToSendFlag = false;
bool readIdentifierSuccessfulFlag = false;
};
}

Expand Down
18 changes: 18 additions & 0 deletions src/modm/driver/can/mcp2515.lb
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,28 @@ 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",
":architecture:can",
":architecture:clock",
":architecture:delay",
":architecture:spi.device",
":processing:protothread",
":processing:timer",
":debug")
return True

Expand All @@ -41,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")

Loading