-
Notifications
You must be signed in to change notification settings - Fork 153
changed mcp2515 driver to use nonblocking spi #817
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
base: develop
Are you sure you want to change the base?
Changes from 23 commits
148e788
10b0e46
33db784
21e4036
03639b4
bf7b0fa
9584f22
8e6a52f
bda5887
7c9065d
5357bc2
c177db3
d737638
f94d31a
6f773fc
33a621f
ed406ca
ec7cf30
a34f35d
6c79bc2
6e6e359
49091cf
dadd55f
5ac11f4
2b5b355
5aa143e
4d7df65
2e4ad3b
5906e17
0ff3eef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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/platform/spi/spi_master_2.hpp> | ||
#include <modm/processing/protothread.hpp> | ||
#include <modm/driver/can/mcp2515.hpp> | ||
|
||
#define SENDER 1 | ||
|
||
// 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}, | ||
i_{0}, | ||
j_{0} | ||
kikass13 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{} | ||
|
||
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_); | ||
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_]; | ||
} | ||
MODM_LOG_INFO << modm::endl; | ||
mcp2515.sendMessage(message_); | ||
PT_CALL(mcp2515.update()); | ||
} | ||
#endif | ||
|
||
PT_END(); | ||
} | ||
|
||
private: | ||
modm::can::Message message_; | ||
bool initialized_; | ||
modm::ShortTimeout wait_; | ||
uint8_t i_, j_; | ||
}; | ||
|
||
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(); | ||
} | ||
} |
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> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wrong path. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not used in the example. Remove. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
<module>modm:build:scons</module> | ||
|
||
<module>modm:processing:protothread</module> | ||
<module>modm:processing:timer</module> | ||
<module>modm:driver:mcp2515</module> | ||
|
||
</modules> | ||
</library> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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" | ||
|
@@ -115,15 +120,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_{}, delayR_{}, 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, | ||
|
@@ -132,25 +146,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(); | ||
|
||
/* | ||
|
@@ -161,18 +175,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<bool> | ||
update(); | ||
|
||
|
||
public: | ||
// Extended Functionality | ||
|
||
/* | ||
* Fixme: Empty implementation, required by connector | ||
*/ | ||
static BusState | ||
BusState | ||
getBusState() { | ||
return BusState::Connected; | ||
} | ||
|
||
protected: | ||
private: | ||
enum SpiCommand | ||
{ | ||
RESET = 0xC0, | ||
|
@@ -186,28 +209,61 @@ 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::atomic::Queue<modm::can::Message, 32> txQueue; | ||
inline static modm::atomic::Queue<modm::can::Message, 32> rxQueue; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Queue sizes should be lbuild options. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
|
||
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 tempR_ = false; | ||
bool tempS_ = false; | ||
bool temp_ = false; | ||
bool receiveSuccess_ = false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Postfixing class members with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. well hmk |
||
}; | ||
} | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.