Skip to content

Commit 03639b4

Browse files
committed
changed read/receive part so that it is polled in the update function as well; fixed some things in example
1 parent 21e4036 commit 03639b4

File tree

3 files changed

+101
-112
lines changed

3 files changed

+101
-112
lines changed

examples/stm32f4_discovery/can_m2515/main.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,17 @@ modm::Mcp2515<SpiMaster, Cs, Int> mcp2515;
4545
class MyTask : modm::pt::Protothread
4646
{
4747
public:
48-
MyTask() : message_{0x123456}
49-
{
50-
mcp2515.initialize<8_MHz, 125_kbps>();
51-
mcp2515.setFilter(modm::accessor::asFlash(canFilter));
52-
}
48+
MyTask() : message_{0x123456}{}
5349

5450
bool
5551
run()
5652
{
5753
PT_BEGIN();
5854

55+
// Configure MCP2515 and set the filters
56+
mcp2515.initialize<8_MHz, 125_kbps>();
57+
mcp2515.setFilter(modm::accessor::asFlash(canFilter));
58+
5959
// send a new message
6060
message_.length = 2;
6161
message_.data[0] = 0xab;
@@ -94,8 +94,7 @@ main()
9494
Cs::setOutput();
9595
Int::setInput(Gpio::InputType::PullUp);
9696

97-
// Configure MCP2515 and set the filters
98-
mcp2515.initialize<8_MHz, 125_kbps>();
99-
100-
while (true) { task.run(); }
97+
while (true) {
98+
task.run();
99+
}
101100
}

src/modm/driver/can/mcp2515.hpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -199,19 +199,19 @@ namespace modm
199199
};
200200

201201
static void
202-
mcp2515interrupt();
202+
mcp2515Interrupt();
203203

204-
static bool
205-
mcp2515readMessage(can::Message& message);
204+
modm::ResumableResult<bool>
205+
mcp2515ReadMessage(can::Message& message, uint8_t status = 0xff);
206206

207207
bool
208-
mcp2515isReadyToSend(uint8_t status);
208+
mcp2515IsReadyToSend(uint8_t status);
209209

210210
modm::ResumableResult<bool>
211-
mcp2515isReadyToSend();
211+
mcp2515IsReadyToSend();
212212

213213
modm::ResumableResult<bool>
214-
mcp2515sendMessage(const can::Message& message, const uint8_t status = 0xff);
214+
mcp2515SendMessage(const can::Message& message, uint8_t status = 0xff);
215215

216216
static void
217217
writeRegister(uint8_t address, uint8_t data);
@@ -225,13 +225,10 @@ namespace modm
225225
modm::ResumableResult<uint8_t>
226226
readStatus(uint8_t type);
227227

228-
static uint8_t
229-
readStatusBlocking(uint8_t type);
230-
231228
inline modm::ResumableResult<void>
232229
writeIdentifier(const uint32_t& identifier, bool isExtendedFrame);
233230

234-
static inline bool
231+
inline modm::ResumableResult<bool>
235232
readIdentifier(uint32_t& identifier);
236233

237234
protected:

src/modm/driver/can/mcp2515_impl.hpp

Lines changed: 86 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
#include "mcp2515_definitions.hpp"
2121
#include <modm/architecture/driver/atomic/queue.hpp>
2222
#include <modm/architecture/interface/assert.hpp>
23-
#include <modm/architecture/interface/interrupt.hpp>
24-
#include <modm/platform/exti/exti.hpp>
2523

2624
#undef MODM_LOG_LEVEL
2725
#define MODM_LOG_LEVEL modm::log::DISABLED
@@ -42,9 +40,12 @@ INT modm::Mcp2515<SPI, CS, INT>::interruptPin;
4240
static uint8_t statusBuffer_;
4341
static uint8_t addressBuffer_;
4442
static uint8_t dataBuffer_;
43+
static modm::can::Message messageBuffer_;
4544
static uint8_t i_;
4645
static uint8_t a_;
46+
static uint8_t b_;
4747
static bool temp_;
48+
static bool temp2_;
4849
static bool hasSend_;
4950
static modm::ShortTimeout delay_;
5051

@@ -132,11 +133,6 @@ modm::Mcp2515<SPI, CS, INT>::initialize()
132133
{
133134
using Timings = modm::CanBitTimingMcp2515<externalClockFrequency, bitrate>;
134135

135-
// initialize interrrupt on INT pin
136-
modm::platform::Exti::connect<INT>(modm::platform::Exti::Trigger::FallingEdge, [](uint8_t){
137-
mcp2515interrupt();
138-
});
139-
140136
return initializeWithPrescaler(
141137
Timings::getPrescaler(),
142138
Timings::getSJW(),
@@ -250,56 +246,52 @@ modm::Mcp2515<SPI, CS, INT>::sendMessage(const can::Message& message)
250246

251247
// ----------------------------------------------------------------------------
252248
template <typename SPI, typename CS, typename INT>
253-
void
254-
modm::Mcp2515<SPI, CS, INT>::mcp2515interrupt(){
249+
modm::ResumableResult<bool>
250+
modm::Mcp2515<SPI, CS, INT>::mcp2515ReadMessage(can::Message& message, uint8_t status)
251+
{
255252
using namespace mcp2515;
256253

257-
can::Message message;
258-
bool success = mcp2515readMessage(message);
259-
if(success){
260-
modm_assert_continue_ignore(rxQueue.push(message), "mcp2515.can.rx.sw0",
261-
"CAN receive software buffer overflowed!", 1);
262-
}
263-
}
264-
265-
template <typename SPI, typename CS, typename INT>
266-
bool
267-
modm::Mcp2515<SPI, CS, INT>::mcp2515readMessage(can::Message& message){
268-
using namespace mcp2515;
254+
RF_BEGIN();
269255

270-
uint8_t status = readStatusBlocking(SpiCommand::RX_STATUS);
271-
uint8_t address;
256+
temp_ = true;
257+
// dont read status again if we have been provided one
258+
if(status == 0xff){
259+
status = RF_CALL(readStatus(READ_STATUS));
260+
}
272261

273262
if (status & FLAG_RXB0_FULL) {
274-
address = READ_RX; // message in buffer 0
263+
addressBuffer_ = READ_RX; // message in buffer 0
275264
}
276265
else if (status & FLAG_RXB1_FULL) {
277-
address = READ_RX | 0x04; // message in buffer 1 (RXB1SIDH)
266+
addressBuffer_ = READ_RX | 0x04; // message in buffer 1 (RXB1SIDH)
278267
}
279268
else {
280-
return false; // Error: no message available
269+
temp_ = false; // Error: no message available
281270
}
282271

283-
chipSelect.reset();
284-
spi.transferBlocking(address);
272+
if(temp_)
273+
{
274+
chipSelect.reset();
275+
RF_CALL(spi.transfer(addressBuffer_));
285276

286-
message.flags.extended = readIdentifier(message.identifier);
287-
if (status & FLAG_RTR) {
288-
message.flags.rtr = true;
289-
}
290-
else {
291-
message.flags.rtr = false;
292-
}
293-
message.length = spi.transferBlocking(0xff) & 0x0f;
277+
message.flags.extended = RF_CALL(readIdentifier(message.identifier));
278+
if (status & FLAG_RTR) {
279+
message.flags.rtr = true;
280+
}
281+
else {
282+
message.flags.rtr = false;
283+
}
284+
message.length = RF_CALL(spi.transfer(0xff)) & 0x0f;
294285

295-
for (uint8_t i = 0; i < message.length; ++i) {
296-
message.data[i] = spi.transferBlocking(0xff);
297-
}
298-
chipSelect.set();
286+
for (i_ = 0; i_ < message.length; ++i_) {
287+
message.data[i_] = RF_CALL(spi.transfer(0xff));
288+
}
289+
chipSelect.set();
299290

291+
}
300292
// RX0IF or RX1IF respectivly were already cleared automatically by rising CS.
301293
// See section 12.4 in datasheet.
302-
return true;
294+
RF_END_RETURN(temp_);
303295
}
304296

305297
template <typename SPI, typename CS, typename INT>
@@ -310,24 +302,38 @@ modm::Mcp2515<SPI, CS, INT>::update(){
310302
using namespace mcp2515;
311303

312304
RF_BEGIN();
313-
hasSend_ = false;
305+
306+
// read status flag of the device
307+
statusBuffer_ = RF_CALL(readStatus(READ_STATUS));
308+
309+
// check if the device has received a message(pin = LOW)
310+
// if yes: read it and put it into the rxQueue
311+
if(!interruptPin.read()){
312+
if(RF_CALL(mcp2515ReadMessage(messageBuffer_, statusBuffer_)))
313+
{
314+
if(not modm_assert_continue_ignore(rxQueue.push(messageBuffer_), "mcp2515.can.tx",
315+
"CAN transmit software buffer overflowed!", 1)){
316+
/// ignore
317+
}
318+
}
319+
}
320+
314321
/// check if device accepts messages and start emptying the transmit queue if not empty
315322
if (txQueue.isNotEmpty())
316323
{
317-
statusBuffer_ = RF_CALL(readStatus(READ_STATUS));
318-
if(mcp2515isReadyToSend(statusBuffer_)){
319-
hasSend_ = RF_CALL(mcp2515sendMessage(txQueue.get(), statusBuffer_));
324+
if(mcp2515IsReadyToSend(statusBuffer_)){
325+
hasSend_ = RF_CALL(mcp2515SendMessage(txQueue.get(), statusBuffer_));
320326
txQueue.pop();
321327
}
322328
}
323-
RF_END_RETURN(hasSend_);
329+
RF_END();
324330
}
325331

326332
// ----------------------------------------------------------------------------
327333

328334
template <typename SPI, typename CS, typename INT>
329335
modm::ResumableResult<bool>
330-
modm::Mcp2515<SPI, CS, INT>::mcp2515isReadyToSend()
336+
modm::Mcp2515<SPI, CS, INT>::mcp2515IsReadyToSend()
331337
{
332338
using namespace mcp2515;
333339

@@ -346,7 +352,7 @@ modm::Mcp2515<SPI, CS, INT>::mcp2515isReadyToSend()
346352
}
347353
template <typename SPI, typename CS, typename INT>
348354
bool
349-
modm::Mcp2515<SPI, CS, INT>::mcp2515isReadyToSend(uint8_t status)
355+
modm::Mcp2515<SPI, CS, INT>::mcp2515IsReadyToSend(uint8_t status)
350356
{
351357
using namespace mcp2515;
352358
bool ready = true;
@@ -364,26 +370,23 @@ modm::Mcp2515<SPI, CS, INT>::mcp2515isReadyToSend(uint8_t status)
364370

365371
template <typename SPI, typename CS, typename INT>
366372
modm::ResumableResult<bool>
367-
modm::Mcp2515<SPI, CS, INT>::mcp2515sendMessage(const can::Message& message, const uint8_t status)
373+
modm::Mcp2515<SPI, CS, INT>::mcp2515SendMessage(const can::Message& message, uint8_t status)
368374
{
369375
using namespace modm::mcp2515;
370376
RF_BEGIN();
371377

372-
/// dont read status again if we have been provided one
378+
// dont read status again if we have been provided one
373379
if(status == 0xff){
374-
statusBuffer_ = RF_CALL(readStatus(READ_STATUS));
375-
}
376-
else{
377-
statusBuffer_ = status;
380+
status = RF_CALL(readStatus(READ_STATUS));
378381
}
379382

380-
if ((statusBuffer_ & TXB0CNTRL_TXREQ) == 0)
383+
if ((status & TXB0CNTRL_TXREQ) == 0)
381384
{
382385
addressBuffer_ = 0x00; // TXB0SIDH
383-
} else if ((statusBuffer_ & TXB1CNTRL_TXREQ) == 0)
386+
} else if ((status & TXB1CNTRL_TXREQ) == 0)
384387
{
385388
addressBuffer_ = 0x02; // TXB1SIDH
386-
} else if ((statusBuffer_ & TXB2CNTRL_TXREQ) == 0)
389+
} else if ((status & TXB2CNTRL_TXREQ) == 0)
387390
{
388391
addressBuffer_ = 0x04; // TXB2SIDH
389392
} else
@@ -480,18 +483,6 @@ modm::Mcp2515<SPI, CS, INT>::readStatus(uint8_t type)
480483
RF_END_RETURN(dataBuffer_);
481484
}
482485

483-
template <typename SPI, typename CS, typename INT>
484-
uint8_t
485-
modm::Mcp2515<SPI, CS, INT>::readStatusBlocking(uint8_t type)
486-
{
487-
chipSelect.reset();
488-
uint8_t data = spi.transferBlocking(type);
489-
spi.transferBlocking(0xff);
490-
chipSelect.set();
491-
return data;
492-
}
493-
494-
495486
// ----------------------------------------------------------------------------
496487

497488
template <typename SPI, typename CS, typename INT>
@@ -525,42 +516,44 @@ modm::Mcp2515<SPI, CS, INT>::writeIdentifier(const uint32_t& identifier,
525516
RF_END();
526517
}
527518

528-
template <typename SPI, typename CS, typename INT>
529-
bool
530-
modm::Mcp2515<SPI, CS, INT>::readIdentifier(uint32_t& identifier)
519+
template<typename SPI, typename CS, typename INT>
520+
modm::ResumableResult<bool>
521+
modm::Mcp2515<SPI, CS, INT>::readIdentifier(uint32_t &identifier)
531522
{
532523
using namespace mcp2515;
524+
const uint32_t *ptr = &identifier;
525+
526+
RF_BEGIN();
533527

534-
uint32_t *ptr = &identifier;
528+
a_ = RF_CALL(spi.transfer(0xff));
529+
b_ = RF_CALL(spi.transfer(0xff));
535530

536-
uint8_t first = spi.transferBlocking(0xff);
537-
uint8_t second = spi.transferBlocking(0xff);
531+
temp2_ = false;
538532

539-
if (second & MCP2515_IDE)
533+
if (b_ & MCP2515_IDE)
540534
{
541-
*((uint16_t *) ptr + 1) = (uint16_t) first << 5;
542-
*((uint8_t *) ptr + 1) = spi.transferBlocking(0xff);
535+
*((uint16_t *)ptr + 1) = (uint16_t)a_ << 5;
536+
*((uint8_t *)ptr + 1) = RF_CALL(spi.transfer(0xff));
543537

544-
*((uint8_t *) ptr + 2) |= (second >> 3) & 0x1C;
545-
*((uint8_t *) ptr + 2) |= second & 0x03;
538+
*((uint8_t *)ptr + 2) |= (b_ >> 3) & 0x1C;
539+
*((uint8_t *)ptr + 2) |= b_ & 0x03;
546540

547-
*((uint8_t *) ptr) = spi.transferBlocking(0xff);
541+
*((uint8_t *)ptr) = RF_CALL(spi.transfer(0xff));
548542

549-
return true;
550-
}
551-
else
543+
temp2_ = true;
544+
} else
552545
{
553-
spi.transferBlocking(0xff);
554-
555-
*((uint8_t *) ptr + 3) = 0;
556-
*((uint8_t *) ptr + 2) = 0;
546+
RF_CALL(spi.transfer(0xff));
557547

558-
*((uint16_t *) ptr) = (uint16_t) first << 3;
548+
*((uint8_t *)ptr + 3) = 0;
549+
*((uint8_t *)ptr + 2) = 0;
559550

560-
spi.transferBlocking(0xff);
551+
*((uint16_t *)ptr) = (uint16_t)a_ << 3;
561552

562-
*((uint8_t *) ptr) |= second >> 5;
553+
RF_CALL(spi.transfer(0xff));
563554

564-
return false;
555+
*((uint8_t *)ptr) |= b_ >> 5;
565556
}
566-
}
557+
558+
RF_END_RETURN(temp2_);
559+
}

0 commit comments

Comments
 (0)