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 15 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
125 changes: 125 additions & 0 deletions examples/nucleo_f439zi/can_m2515/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* 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/platform/spi/spi_master_2.hpp>
#include <modm/processing/protothread.hpp>
#include <modm/driver/can/mcp2515.hpp>


#define SENDER 0

// 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_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<SpiMaster, Cs, Int> mcp2515;

class MyTask : modm::pt::Protothread
kikass13 marked this conversation as resolved.
Show resolved Hide resolved
{
public:
MyTask() : message_{0x1337}{}

bool
run()
{
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;
mcp2515.setFilter(modm::accessor::asFlash(canFilter));
MODM_LOG_INFO << "Running ... " << modm::endl;
#if SENDER == 0
while (initialized_)
kikass13 marked this conversation as resolved.
Show resolved Hide resolved
{
// 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;
}
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;

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

MODM_LOG_INFO << "Hello" << modm::endl;
kikass13 marked this conversation as resolved.
Show resolved Hide resolved
// 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, 20_MHz>();
kikass13 marked this conversation as resolved.
Show resolved Hide resolved
Cs::setOutput();
Int::setInput(Gpio::InputType::PullUp);

while (true) {
task.run();
}
}
18 changes: 18 additions & 0 deletions examples/nucleo_f439zi/can_m2515/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<library>
<extends>modm:nucleo-f439zi</extends>
<options>
<option name="modm:build:build.path">../../../build/stm32f4_discovery/mcp2515</option>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong path.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

</options>
<modules>
<module>modm:platform:gpio</module>
<module>modm:platform:spi.bitbang</module>
<module>modm:platform:spi:1</module>
<module>modm:platform:spi:2</module>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not used in the example. Remove.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<module>modm:platform:spi:1</module> is still used, but rest is gone

<module>modm:build:scons</module>

<module>modm:processing:protothread</module>
<module>modm:processing:timer</module>
<module>modm:driver:mcp2515</module>

</modules>
</library>
86 changes: 64 additions & 22 deletions src/modm/driver/can/mcp2515.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
#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/architecture/driver/atomic/queue.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"
Expand Down Expand Up @@ -115,15 +120,17 @@ 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:
template<frequency_t ExternalClock, bitrate_t bitrate=kbps(125), percent_t tolerance=pct(1) >
static inline bool
bool
initialize();

private:
static inline bool
bool
initializeWithPrescaler(
uint8_t prescaler,
uint8_t sjw,
Expand All @@ -132,47 +139,56 @@ 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
inline bool
isMessageAvailable();

static bool
getMessage(can::Message& message);
bool
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
bool
isReadyToSend();

/*
* Send a message over the CAN.
*
* \return true if the message was send, false otherwise
*/
static bool
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<bool>
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 @@ -186,28 +202,54 @@ namespace modm
BIT_MODIFY = 0x05
};

static void
modm::ResumableResult<bool>
mcp2515ReadMessage(can::Message& message, uint8_t status = 0xff);

bool
mcp2515IsReadyToSend(uint8_t status);

modm::ResumableResult<bool>
mcp2515IsReadyToSend();

modm::ResumableResult<bool>
mcp2515SendMessage(const can::Message& message, uint8_t status = 0xff);

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

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:
static SPI spi;
static CS chipSelect;
static INT interruptPin;
private:
modm::atomic::Queue<modm::can::Message, 32> txQueue;
modm::atomic::Queue<modm::can::Message, 32> rxQueue;

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

Expand Down
4 changes: 4 additions & 0 deletions src/modm/driver/can/mcp2515.lb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ def prepare(module, options):
":architecture:can",
":architecture:clock",
":architecture:delay",
":architecture:interrupt",
kikass13 marked this conversation as resolved.
Show resolved Hide resolved
":architecture:spi.device",
":processing:protothread",
":processing:timer",
":debug")
return True

Expand Down
Loading