@@ -35,6 +35,12 @@ LOG_MODULE_REGISTER(can_mcp2515, CONFIG_CAN_LOG_LEVEL);
35
35
#error You must either set a sampling-point or timings (phase-seg* and prop-seg)
36
36
#endif
37
37
38
+ /* Timeout for changing mode */
39
+ #define MCP2515_MODE_CHANGE_TIMEOUT_USEC 1000
40
+ #define MCP2515_MODE_CHANGE_RETRIES 100
41
+ #define MCP2515_MODE_CHANGE_DELAY \
42
+ K_USEC(MCP2515_MODE_CHANGE_TIMEOUT_USEC / MCP2515_MODE_CHANGE_RETRIES)
43
+
38
44
static int mcp2515_cmd_soft_reset (const struct device * dev )
39
45
{
40
46
const struct mcp2515_config * dev_cfg = dev -> config ;
@@ -271,22 +277,44 @@ static void mcp2515_convert_mcp2515frame_to_canframe(const uint8_t *source,
271
277
272
278
const int mcp2515_set_mode_int (const struct device * dev , uint8_t mcp2515_mode )
273
279
{
280
+ int retries = MCP2515_MODE_CHANGE_RETRIES ;
274
281
uint8_t canstat ;
275
282
276
283
mcp2515_cmd_bit_modify (dev , MCP2515_ADDR_CANCTRL ,
277
284
MCP2515_CANCTRL_MODE_MASK ,
278
285
mcp2515_mode << MCP2515_CANCTRL_MODE_POS );
279
286
mcp2515_cmd_read_reg (dev , MCP2515_ADDR_CANSTAT , & canstat , 1 );
280
287
281
- if (((canstat & MCP2515_CANSTAT_MODE_MASK ) >> MCP2515_CANSTAT_MODE_POS )
282
- != mcp2515_mode ) {
283
- LOG_ERR ("Failed to set MCP2515 operation mode" );
284
- return - EIO ;
288
+ while (((canstat & MCP2515_CANSTAT_MODE_MASK ) >> MCP2515_CANSTAT_MODE_POS )
289
+ != mcp2515_mode ) {
290
+ if (-- retries < 0 ) {
291
+ LOG_ERR ("Timeout trying to set MCP2515 operation mode" );
292
+ return - EIO ;
293
+ }
294
+
295
+ k_sleep (MCP2515_MODE_CHANGE_DELAY );
296
+ mcp2515_cmd_read_reg (dev , MCP2515_ADDR_CANSTAT , & canstat , 1 );
285
297
}
286
298
287
299
return 0 ;
288
300
}
289
301
302
+ static void mcp2515_tx_done (const struct device * dev , uint8_t tx_idx , int status )
303
+ {
304
+ struct mcp2515_data * dev_data = dev -> data ;
305
+ can_tx_callback_t callback = dev_data -> tx_cb [tx_idx ].cb ;
306
+
307
+ if (callback != NULL ) {
308
+ callback (dev , status , dev_data -> tx_cb [tx_idx ].cb_arg );
309
+ dev_data -> tx_cb [tx_idx ].cb = NULL ;
310
+
311
+ k_mutex_lock (& dev_data -> mutex , K_FOREVER );
312
+ dev_data -> tx_busy_map &= ~BIT (tx_idx );
313
+ k_mutex_unlock (& dev_data -> mutex );
314
+ k_sem_give (& dev_data -> tx_sem );
315
+ }
316
+ }
317
+
290
318
static int mcp2515_get_core_clock (const struct device * dev , uint32_t * rate )
291
319
{
292
320
const struct mcp2515_config * dev_cfg = dev -> config ;
@@ -457,13 +485,26 @@ static int mcp2515_stop(const struct device *dev)
457
485
const struct mcp2515_config * dev_cfg = dev -> config ;
458
486
struct mcp2515_data * dev_data = dev -> data ;
459
487
int ret ;
488
+ int i ;
460
489
461
490
if (!dev_data -> started ) {
462
491
return - EALREADY ;
463
492
}
464
493
465
494
k_mutex_lock (& dev_data -> mutex , K_FOREVER );
466
495
496
+ /* Abort any pending transmissions before entering configuration mode */
497
+ mcp2515_cmd_bit_modify (dev , MCP2515_ADDR_TXB0CTRL ,
498
+ MCP2515_TXBNCTRL_TXREQ_MASK , 0 );
499
+ #if MCP2515_TX_CNT == 2
500
+ mcp2515_cmd_bit_modify (dev , MCP2515_ADDR_TXB1CTRL ,
501
+ MCP2515_TXBNCTRL_TXREQ_MASK , 0 );
502
+ #endif /* MCP2515_TX_CNT == 2 */
503
+ #if MCP2515_TX_CNT == 3
504
+ mcp2515_cmd_bit_modify (dev , MCP2515_ADDR_TXB2CTRL ,
505
+ MCP2515_TXBNCTRL_TXREQ_MASK , 0 );
506
+ #endif /* MCP2515_TX_CNT == 3 */
507
+
467
508
ret = mcp2515_set_mode_int (dev , MCP2515_MODE_CONFIGURATION );
468
509
if (ret < 0 ) {
469
510
LOG_ERR ("Failed to enter configuration mode [%d]" , ret );
@@ -475,6 +516,10 @@ static int mcp2515_stop(const struct device *dev)
475
516
476
517
k_mutex_unlock (& dev_data -> mutex );
477
518
519
+ for (i = 0 ; i < MCP2515_TX_CNT ; i ++ ) {
520
+ mcp2515_tx_done (dev , i , - ENETDOWN );
521
+ }
522
+
478
523
if (dev_cfg -> phy != NULL ) {
479
524
ret = can_transceiver_disable (dev_cfg -> phy );
480
525
if (ret != 0 ) {
@@ -678,19 +723,6 @@ static void mcp2515_rx(const struct device *dev, uint8_t rx_idx)
678
723
mcp2515_rx_filter (dev , & frame );
679
724
}
680
725
681
- static void mcp2515_tx_done (const struct device * dev , uint8_t tx_idx )
682
- {
683
- struct mcp2515_data * dev_data = dev -> data ;
684
-
685
- dev_data -> tx_cb [tx_idx ].cb (dev , 0 , dev_data -> tx_cb [tx_idx ].cb_arg );
686
- dev_data -> tx_cb [tx_idx ].cb = NULL ;
687
-
688
- k_mutex_lock (& dev_data -> mutex , K_FOREVER );
689
- dev_data -> tx_busy_map &= ~BIT (tx_idx );
690
- k_mutex_unlock (& dev_data -> mutex );
691
- k_sem_give (& dev_data -> tx_sem );
692
- }
693
-
694
726
static int mcp2515_get_state (const struct device * dev , enum can_state * state ,
695
727
struct can_bus_err_cnt * err_cnt )
696
728
{
@@ -805,15 +837,15 @@ static void mcp2515_handle_interrupts(const struct device *dev)
805
837
}
806
838
807
839
if (canintf & MCP2515_CANINTF_TX0IF ) {
808
- mcp2515_tx_done (dev , 0 );
840
+ mcp2515_tx_done (dev , 0 , 0 );
809
841
}
810
842
811
843
if (canintf & MCP2515_CANINTF_TX1IF ) {
812
- mcp2515_tx_done (dev , 1 );
844
+ mcp2515_tx_done (dev , 1 , 0 );
813
845
}
814
846
815
847
if (canintf & MCP2515_CANINTF_TX2IF ) {
816
- mcp2515_tx_done (dev , 2 );
848
+ mcp2515_tx_done (dev , 2 , 0 );
817
849
}
818
850
819
851
if (canintf & MCP2515_CANINTF_ERRIF ) {
0 commit comments