Skip to content

Commit 2036196

Browse files
committed
stm32/can: Improve can.recv() so it checks for events, eg ctrl-C.
This patch provides a custom (and simple) function to receive data on the CAN bus, instead of the HAL function. This custom version calls mp_handle_pending() while waiting for messages, which, among other things, allows to interrupt the recv() method via KeyboardInterrupt.
1 parent 22a9158 commit 2036196

File tree

1 file changed

+41
-6
lines changed

1 file changed

+41
-6
lines changed

ports/stm32/can.c

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* The MIT License (MIT)
55
*
6-
* Copyright (c) 2014 Damien P. George
6+
* Copyright (c) 2014-2018 Damien P. George
77
*
88
* Permission is hereby granted, free of charge, to any person obtaining a copy
99
* of this software and associated documentation files (the "Software"), to deal
@@ -172,6 +172,43 @@ STATIC void can_clearfilter(uint32_t f) {
172172
HAL_CAN_ConfigFilter(NULL, &filter);
173173
}
174174

175+
STATIC int can_receive(CAN_TypeDef *can, int fifo, CanRxMsgTypeDef *msg, uint32_t timeout_ms) {
176+
volatile uint32_t *rfr;
177+
if (fifo == CAN_FIFO0) {
178+
rfr = &can->RF0R;
179+
} else {
180+
rfr = &can->RF1R;
181+
}
182+
183+
// Wait for a message to become available, with timeout
184+
uint32_t start = HAL_GetTick();
185+
while ((*rfr & 3) == 0) {
186+
MICROPY_EVENT_POLL_HOOK
187+
if (HAL_GetTick() - start >= timeout_ms) {
188+
return -MP_ETIMEDOUT;
189+
}
190+
}
191+
192+
// Read message data
193+
CAN_FIFOMailBox_TypeDef *box = &can->sFIFOMailBox[fifo];
194+
msg->IDE = box->RIR & 4;
195+
if (msg->IDE == CAN_ID_STD) {
196+
msg->StdId = box->RIR >> 21;
197+
} else {
198+
msg->ExtId = box->RIR >> 3;
199+
}
200+
msg->RTR = box->RIR & 2;
201+
msg->DLC = box->RDTR & 0xf;
202+
msg->FMI = box->RDTR >> 8 & 0xff;
203+
*(uint32_t*)&msg->Data[0] = box->RDLR;
204+
*(uint32_t*)&msg->Data[4] = box->RDHR;
205+
206+
// Release (free) message from FIFO
207+
*rfr |= CAN_RF0R_RFOM0;
208+
209+
return 0; // success
210+
}
211+
175212
// We have our own version of CAN transmit so we can handle Timeout=0 correctly.
176213
STATIC HAL_StatusTypeDef CAN_Transmit(CAN_HandleTypeDef *hcan, uint32_t Timeout) {
177214
uint32_t transmitmailbox;
@@ -530,11 +567,9 @@ STATIC mp_obj_t pyb_can_recv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
530567

531568
// receive the data
532569
CanRxMsgTypeDef rx_msg;
533-
self->can.pRxMsg = self->can.pRx1Msg = &rx_msg;
534-
HAL_StatusTypeDef status = HAL_CAN_Receive(&self->can, args[0].u_int, args[1].u_int);
535-
536-
if (status != HAL_OK) {
537-
mp_hal_raise(status);
570+
int ret = can_receive(self->can.Instance, args[0].u_int, &rx_msg, args[1].u_int);
571+
if (ret < 0) {
572+
mp_raise_OSError(-ret);
538573
}
539574

540575
// Manage the rx state machine

0 commit comments

Comments
 (0)