20
20
#include " mcp2515_definitions.hpp"
21
21
#include < modm/architecture/driver/atomic/queue.hpp>
22
22
#include < modm/architecture/interface/assert.hpp>
23
- #include < modm/architecture/interface/interrupt.hpp>
24
- #include < modm/platform/exti/exti.hpp>
25
23
26
24
#undef MODM_LOG_LEVEL
27
25
#define MODM_LOG_LEVEL modm::log::DISABLED
@@ -42,9 +40,12 @@ INT modm::Mcp2515<SPI, CS, INT>::interruptPin;
42
40
static uint8_t statusBuffer_;
43
41
static uint8_t addressBuffer_;
44
42
static uint8_t dataBuffer_;
43
+ static modm::can::Message messageBuffer_;
45
44
static uint8_t i_;
46
45
static uint8_t a_;
46
+ static uint8_t b_;
47
47
static bool temp_;
48
+ static bool temp2_;
48
49
static bool hasSend_;
49
50
static modm::ShortTimeout delay_;
50
51
@@ -132,11 +133,6 @@ modm::Mcp2515<SPI, CS, INT>::initialize()
132
133
{
133
134
using Timings = modm::CanBitTimingMcp2515<externalClockFrequency, bitrate>;
134
135
135
- // initialize interrrupt on INT pin
136
- modm::platform::Exti::connect<INT>(modm::platform::Exti::Trigger::FallingEdge, [](uint8_t ){
137
- mcp2515interrupt ();
138
- });
139
-
140
136
return initializeWithPrescaler (
141
137
Timings::getPrescaler (),
142
138
Timings::getSJW (),
@@ -250,56 +246,52 @@ modm::Mcp2515<SPI, CS, INT>::sendMessage(const can::Message& message)
250
246
251
247
// ----------------------------------------------------------------------------
252
248
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
+ {
255
252
using namespace mcp2515 ;
256
253
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 ();
269
255
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
+ }
272
261
273
262
if (status & FLAG_RXB0_FULL) {
274
- address = READ_RX; // message in buffer 0
263
+ addressBuffer_ = READ_RX; // message in buffer 0
275
264
}
276
265
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)
278
267
}
279
268
else {
280
- return false ; // Error: no message available
269
+ temp_ = false ; // Error: no message available
281
270
}
282
271
283
- chipSelect.reset ();
284
- spi.transferBlocking (address);
272
+ if (temp_)
273
+ {
274
+ chipSelect.reset ();
275
+ RF_CALL (spi.transfer (addressBuffer_));
285
276
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 ;
294
285
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 ();
299
290
291
+ }
300
292
// RX0IF or RX1IF respectivly were already cleared automatically by rising CS.
301
293
// See section 12.4 in datasheet.
302
- return true ;
294
+ RF_END_RETURN (temp_) ;
303
295
}
304
296
305
297
template <typename SPI, typename CS, typename INT>
@@ -310,24 +302,38 @@ modm::Mcp2515<SPI, CS, INT>::update(){
310
302
using namespace mcp2515 ;
311
303
312
304
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
+
314
321
// / check if device accepts messages and start emptying the transmit queue if not empty
315
322
if (txQueue.isNotEmpty ())
316
323
{
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_));
320
326
txQueue.pop ();
321
327
}
322
328
}
323
- RF_END_RETURN (hasSend_ );
329
+ RF_END ( );
324
330
}
325
331
326
332
// ----------------------------------------------------------------------------
327
333
328
334
template <typename SPI, typename CS, typename INT>
329
335
modm::ResumableResult<bool >
330
- modm::Mcp2515<SPI, CS, INT>::mcp2515isReadyToSend ()
336
+ modm::Mcp2515<SPI, CS, INT>::mcp2515IsReadyToSend ()
331
337
{
332
338
using namespace mcp2515 ;
333
339
@@ -346,7 +352,7 @@ modm::Mcp2515<SPI, CS, INT>::mcp2515isReadyToSend()
346
352
}
347
353
template <typename SPI, typename CS, typename INT>
348
354
bool
349
- modm::Mcp2515<SPI, CS, INT>::mcp2515isReadyToSend (uint8_t status)
355
+ modm::Mcp2515<SPI, CS, INT>::mcp2515IsReadyToSend (uint8_t status)
350
356
{
351
357
using namespace mcp2515 ;
352
358
bool ready = true ;
@@ -364,26 +370,23 @@ modm::Mcp2515<SPI, CS, INT>::mcp2515isReadyToSend(uint8_t status)
364
370
365
371
template <typename SPI, typename CS, typename INT>
366
372
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)
368
374
{
369
375
using namespace modm ::mcp2515;
370
376
RF_BEGIN ();
371
377
372
- // / dont read status again if we have been provided one
378
+ // dont read status again if we have been provided one
373
379
if (status == 0xff ){
374
- statusBuffer_ = RF_CALL (readStatus (READ_STATUS));
375
- }
376
- else {
377
- statusBuffer_ = status;
380
+ status = RF_CALL (readStatus (READ_STATUS));
378
381
}
379
382
380
- if ((statusBuffer_ & TXB0CNTRL_TXREQ) == 0 )
383
+ if ((status & TXB0CNTRL_TXREQ) == 0 )
381
384
{
382
385
addressBuffer_ = 0x00 ; // TXB0SIDH
383
- } else if ((statusBuffer_ & TXB1CNTRL_TXREQ) == 0 )
386
+ } else if ((status & TXB1CNTRL_TXREQ) == 0 )
384
387
{
385
388
addressBuffer_ = 0x02 ; // TXB1SIDH
386
- } else if ((statusBuffer_ & TXB2CNTRL_TXREQ) == 0 )
389
+ } else if ((status & TXB2CNTRL_TXREQ) == 0 )
387
390
{
388
391
addressBuffer_ = 0x04 ; // TXB2SIDH
389
392
} else
@@ -480,18 +483,6 @@ modm::Mcp2515<SPI, CS, INT>::readStatus(uint8_t type)
480
483
RF_END_RETURN (dataBuffer_);
481
484
}
482
485
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
-
495
486
// ----------------------------------------------------------------------------
496
487
497
488
template <typename SPI, typename CS, typename INT>
@@ -525,42 +516,44 @@ modm::Mcp2515<SPI, CS, INT>::writeIdentifier(const uint32_t& identifier,
525
516
RF_END ();
526
517
}
527
518
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)
531
522
{
532
523
using namespace mcp2515 ;
524
+ const uint32_t *ptr = &identifier;
525
+
526
+ RF_BEGIN ();
533
527
534
- uint32_t *ptr = &identifier;
528
+ a_ = RF_CALL (spi.transfer (0xff ));
529
+ b_ = RF_CALL (spi.transfer (0xff ));
535
530
536
- uint8_t first = spi.transferBlocking (0xff );
537
- uint8_t second = spi.transferBlocking (0xff );
531
+ temp2_ = false ;
538
532
539
- if (second & MCP2515_IDE)
533
+ if (b_ & MCP2515_IDE)
540
534
{
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 ) );
543
537
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 ;
546
540
547
- *((uint8_t *) ptr) = spi.transferBlocking (0xff );
541
+ *((uint8_t *)ptr) = RF_CALL ( spi.transfer (0xff ) );
548
542
549
- return true ;
550
- }
551
- else
543
+ temp2_ = true ;
544
+ } else
552
545
{
553
- spi.transferBlocking (0xff );
554
-
555
- *((uint8_t *) ptr + 3 ) = 0 ;
556
- *((uint8_t *) ptr + 2 ) = 0 ;
546
+ RF_CALL (spi.transfer (0xff ));
557
547
558
- *((uint16_t *) ptr) = (uint16_t ) first << 3 ;
548
+ *((uint8_t *)ptr + 3 ) = 0 ;
549
+ *((uint8_t *)ptr + 2 ) = 0 ;
559
550
560
- spi. transferBlocking ( 0xff ) ;
551
+ *(( uint16_t *)ptr) = ( uint16_t )a_ << 3 ;
561
552
562
- *(( uint8_t *) ptr) |= second >> 5 ;
553
+ RF_CALL (spi. transfer ( 0xff )) ;
563
554
564
- return false ;
555
+ *(( uint8_t *)ptr) |= b_ >> 5 ;
565
556
}
566
- }
557
+
558
+ RF_END_RETURN (temp2_);
559
+ }
0 commit comments