@@ -39,6 +39,15 @@ CS modm::Mcp2515<SPI, CS, INT>::chipSelect;
39
39
template <typename SPI, typename CS, typename INT>
40
40
INT modm::Mcp2515<SPI, CS, INT>::interruptPin;
41
41
42
+ static uint8_t statusBuffer_;
43
+ static uint8_t addressBuffer_;
44
+ static uint8_t dataBuffer_;
45
+ static uint8_t i_;
46
+ static uint8_t a_;
47
+ static bool temp_;
48
+ static bool hasSend_;
49
+ static modm::ShortTimeout delay_;
50
+
42
51
// ----------------------------------------------------------------------------
43
52
44
53
template <typename SPI, typename CS, typename INT>
258
267
modm::Mcp2515<SPI, CS, INT>::mcp2515readMessage(can::Message& message){
259
268
using namespace mcp2515 ;
260
269
261
- uint8_t status = readStatus ( RX_STATUS);
270
+ uint8_t status = readStatusBlocking (SpiCommand:: RX_STATUS);
262
271
uint8_t address;
263
272
264
273
if (status & FLAG_RXB0_FULL) {
@@ -294,93 +303,123 @@ modm::Mcp2515<SPI, CS, INT>::mcp2515readMessage(can::Message& message){
294
303
}
295
304
296
305
template <typename SPI, typename CS, typename INT>
297
- bool
306
+ modm::ResumableResult< bool >
298
307
modm::Mcp2515<SPI, CS, INT>::update(){
299
308
// / todo
300
309
// / this should be a timer interrupt
301
310
using namespace mcp2515 ;
302
311
303
- bool hasSend = false ;
312
+ RF_BEGIN ();
313
+ hasSend_ = false ;
304
314
// / check if device accepts messages and start emptying the transmit queue if not empty
305
315
if (txQueue.isNotEmpty ())
306
316
{
307
- if (mcp2515isReadyToSend ()){
308
- hasSend = mcp2515sendMessage (txQueue.get ());
317
+ statusBuffer_ = RF_CALL (readStatus (READ_STATUS));
318
+ if (mcp2515isReadyToSend (statusBuffer_)){
319
+ hasSend_ = RF_CALL (mcp2515sendMessage (txQueue.get (), statusBuffer_));
309
320
txQueue.pop ();
310
321
}
311
322
}
312
- return hasSend ;
323
+ RF_END_RETURN (hasSend_) ;
313
324
}
314
325
315
326
// ----------------------------------------------------------------------------
316
327
317
328
template <typename SPI, typename CS, typename INT>
318
- bool
329
+ modm::ResumableResult< bool >
319
330
modm::Mcp2515<SPI, CS, INT>::mcp2515isReadyToSend()
320
331
{
321
332
using namespace mcp2515 ;
322
333
323
- if ((readStatus (READ_STATUS) & (TXB2CNTRL_TXREQ | TXB1CNTRL_TXREQ | TXB0CNTRL_TXREQ)) ==
334
+ RF_BEGIN ();
335
+
336
+ temp_ = true ;
337
+ statusBuffer_ = RF_CALL (readStatus (READ_STATUS));
338
+ if (( statusBuffer_& (TXB2CNTRL_TXREQ | TXB1CNTRL_TXREQ | TXB0CNTRL_TXREQ)) ==
324
339
(TXB2CNTRL_TXREQ | TXB1CNTRL_TXREQ | TXB0CNTRL_TXREQ))
325
340
{
326
341
// all buffers currently in use
327
- return false ;
342
+ temp_ = false ;
328
343
}
329
- else {
330
- return true ;
344
+
345
+ RF_END_RETURN (temp_);
346
+ }
347
+ template <typename SPI, typename CS, typename INT>
348
+ bool
349
+ modm::Mcp2515<SPI, CS, INT>::mcp2515isReadyToSend(uint8_t status)
350
+ {
351
+ using namespace mcp2515 ;
352
+ bool ready = true ;
353
+ if ((status & (TXB2CNTRL_TXREQ | TXB1CNTRL_TXREQ | TXB0CNTRL_TXREQ)) ==
354
+ (TXB2CNTRL_TXREQ | TXB1CNTRL_TXREQ | TXB0CNTRL_TXREQ))
355
+ {
356
+ // all buffers currently in use
357
+ ready = false ;
331
358
}
359
+
360
+ return ready;
332
361
}
333
362
334
363
// ----------------------------------------------------------------------------
335
364
336
365
template <typename SPI, typename CS, typename INT>
337
- bool
338
- modm::Mcp2515<SPI, CS, INT>::mcp2515sendMessage(const can::Message& message)
366
+ modm::ResumableResult< bool >
367
+ modm::Mcp2515<SPI, CS, INT>::mcp2515sendMessage(const can::Message& message, const uint8_t status )
339
368
{
340
- using namespace mcp2515 ;
369
+ using namespace modm ::mcp2515;
370
+ RF_BEGIN ();
341
371
342
- uint8_t status = readStatus (READ_STATUS);
343
- uint8_t address;
344
- if ((status & TXB0CNTRL_TXREQ) == 0 ) {
345
- address = 0x00 ; // TXB0SIDH
372
+ // / dont read status again if we have been provided one
373
+ if (status == 0xff ){
374
+ statusBuffer_ = RF_CALL (readStatus (READ_STATUS));
346
375
}
347
- else if ((status & TXB1CNTRL_TXREQ) == 0 ) {
348
- address = 0x02 ; // TXB1SIDH
376
+ else {
377
+ statusBuffer_ = status;
349
378
}
350
- else if ((status & TXB2CNTRL_TXREQ) == 0 ) {
351
- address = 0x04 ; // TXB2SIDH
352
- }
353
- else {
379
+
380
+ if ((statusBuffer_ & TXB0CNTRL_TXREQ) == 0 )
381
+ {
382
+ addressBuffer_ = 0x00 ; // TXB0SIDH
383
+ } else if ((statusBuffer_ & TXB1CNTRL_TXREQ) == 0 )
384
+ {
385
+ addressBuffer_ = 0x02 ; // TXB1SIDH
386
+ } else if ((statusBuffer_ & TXB2CNTRL_TXREQ) == 0 )
387
+ {
388
+ addressBuffer_ = 0x04 ; // TXB2SIDH
389
+ } else
390
+ {
354
391
// all buffer are in use => could not send the message
355
- return false ;
356
392
}
357
393
358
- chipSelect.reset ();
359
- spi.transferBlocking (WRITE_TX | address);
360
- writeIdentifier (message.identifier , message.flags .extended );
394
+ if (addressBuffer_ == 0x00 || addressBuffer_ == 0x02 || addressBuffer_ == 0x04 )
395
+ {
396
+ chipSelect.reset ();
397
+ RF_CALL (spi.transfer (WRITE_TX | addressBuffer_));
398
+ RF_CALL (writeIdentifier (message.identifier , message.flags .extended ));
361
399
362
- // if the message is a rtr-frame, is has a length but no attached data
363
- if (message.flags .rtr ) {
364
- spi.transferBlocking (MCP2515_RTR | message.length );
365
- }
366
- else {
367
- spi.transferBlocking (message.length );
400
+ // if the message is a rtr-frame, is has a length but no attached data
401
+ if (message.flags .rtr )
402
+ {
403
+ RF_CALL (spi.transfer (MCP2515_RTR | message.length ));
404
+ } else
405
+ {
406
+ RF_CALL (spi.transfer (message.length ));
368
407
369
- for (uint8_t i = 0 ; i < message.length ; ++i) {
370
- spi.transferBlocking (message.data [i]);
408
+ for (i_ = 0 ; i_ < message.length ; ++i_) {
409
+ RF_CALL (spi.transfer (message.data [i_]));
410
+ }
371
411
}
372
- }
373
- chipSelect.set ();
374
-
375
- modm::delay_us (1 );
376
-
377
- // send message via RTS command
378
- chipSelect.reset ();
379
- address = (address == 0 ) ? 1 : address; // 0 2 4 => 1 2 4
380
- spi.transferBlocking (RTS | address);
381
- chipSelect.set ();
412
+ delay_.restart (1ms);
413
+ chipSelect.set ();
414
+ RF_WAIT_UNTIL (delay_.isExpired ());
382
415
383
- return static_cast <bool >(address);
416
+ // send message via RTS command
417
+ chipSelect.reset ();
418
+ addressBuffer_ = (addressBuffer_ == 0 ) ? 1 : addressBuffer_; // 0 2 4 => 1 2 4
419
+ RF_CALL (spi.transfer (RTS | addressBuffer_));
420
+ chipSelect.set ();
421
+ }
422
+ RF_END_RETURN (static_cast <bool >(addressBuffer_));
384
423
}
385
424
386
425
// ----------------------------------------------------------------------------
@@ -428,51 +467,62 @@ modm::Mcp2515<SPI, CS, INT>::bitModify(uint8_t address, uint8_t mask, uint8_t da
428
467
}
429
468
430
469
template <typename SPI, typename CS, typename INT>
431
- uint8_t
470
+ modm::ResumableResult< uint8_t >
432
471
modm::Mcp2515<SPI, CS, INT>::readStatus(uint8_t type)
433
472
{
473
+ RF_BEGIN ();
474
+
434
475
chipSelect.reset ();
476
+ dataBuffer_ = RF_CALL (spi.transfer (type));
477
+ RF_CALL (spi.transfer (0xff ));
478
+ chipSelect.set ();
435
479
436
- spi. transferBlocking (type );
437
- uint8_t data = spi. transferBlocking ( 0xff );
480
+ RF_END_RETURN (dataBuffer_ );
481
+ }
438
482
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 );
439
490
chipSelect.set ();
440
-
441
491
return data;
442
492
}
443
493
494
+
444
495
// ----------------------------------------------------------------------------
445
496
446
497
template <typename SPI, typename CS, typename INT>
447
- void
498
+ modm::ResumableResult< void >
448
499
modm::Mcp2515<SPI, CS, INT>::writeIdentifier(const uint32_t & identifier,
449
500
bool isExtendedFrame)
450
501
{
451
502
using namespace mcp2515 ;
452
-
453
503
const uint32_t *ptr = &identifier;
454
504
505
+ RF_BEGIN ();
506
+
455
507
if (isExtendedFrame)
456
508
{
457
- spi.transferBlocking (*((uint16_t *) ptr + 1 ) >> 5 );
509
+ RF_CALL ( spi.transfer (*((uint16_t *)ptr + 1 ) >> 5 ) );
458
510
459
511
// calculate the next values
460
- uint8_t temp;
461
- temp = (*((uint8_t *) ptr + 2 ) << 3 ) & 0xe0 ;
462
- temp |= MCP2515_IDE;
463
- temp |= (*((uint8_t *) ptr + 2 )) & 0x03 ;
464
-
465
- spi.transferBlocking (temp);
466
- spi.transferBlocking (*((uint8_t *) ptr + 1 ));
467
- spi.transferBlocking (*((uint8_t *) ptr));
468
- }
469
- else
512
+ a_ = (*((uint8_t *)ptr + 2 ) << 3 ) & 0xe0 ;
513
+ a_ |= MCP2515_IDE;
514
+ a_ |= (*((uint8_t *)ptr + 2 )) & 0x03 ;
515
+ RF_CALL (spi.transfer (a_));
516
+ RF_CALL (spi.transfer (*((uint8_t *)ptr + 1 )));
517
+ RF_CALL (spi.transfer (*((uint8_t *)ptr)));
518
+ } else
470
519
{
471
- spi.transferBlocking (*((uint16_t *) ptr) >> 3 );
472
- spi.transferBlocking (*((uint8_t *) ptr) << 5 );
473
- spi.transferBlocking ( 0 );
474
- spi.transferBlocking ( 0 );
520
+ RF_CALL ( spi.transfer (*((uint16_t *)ptr) >> 3 ) );
521
+ RF_CALL ( spi.transfer (*((uint8_t *)ptr) << 5 ) );
522
+ RF_CALL ( spi.transfer ( 0 ) );
523
+ RF_CALL ( spi.transfer ( 0 ) );
475
524
}
525
+ RF_END ();
476
526
}
477
527
478
528
template <typename SPI, typename CS, typename INT>
0 commit comments