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.
This commit is contained in:
parent
22a9158ced
commit
2036196d71
@ -3,7 +3,7 @@
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 Damien P. George
|
||||
* Copyright (c) 2014-2018 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@ -172,6 +172,43 @@ STATIC void can_clearfilter(uint32_t f) {
|
||||
HAL_CAN_ConfigFilter(NULL, &filter);
|
||||
}
|
||||
|
||||
STATIC int can_receive(CAN_TypeDef *can, int fifo, CanRxMsgTypeDef *msg, uint32_t timeout_ms) {
|
||||
volatile uint32_t *rfr;
|
||||
if (fifo == CAN_FIFO0) {
|
||||
rfr = &can->RF0R;
|
||||
} else {
|
||||
rfr = &can->RF1R;
|
||||
}
|
||||
|
||||
// Wait for a message to become available, with timeout
|
||||
uint32_t start = HAL_GetTick();
|
||||
while ((*rfr & 3) == 0) {
|
||||
MICROPY_EVENT_POLL_HOOK
|
||||
if (HAL_GetTick() - start >= timeout_ms) {
|
||||
return -MP_ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
// Read message data
|
||||
CAN_FIFOMailBox_TypeDef *box = &can->sFIFOMailBox[fifo];
|
||||
msg->IDE = box->RIR & 4;
|
||||
if (msg->IDE == CAN_ID_STD) {
|
||||
msg->StdId = box->RIR >> 21;
|
||||
} else {
|
||||
msg->ExtId = box->RIR >> 3;
|
||||
}
|
||||
msg->RTR = box->RIR & 2;
|
||||
msg->DLC = box->RDTR & 0xf;
|
||||
msg->FMI = box->RDTR >> 8 & 0xff;
|
||||
*(uint32_t*)&msg->Data[0] = box->RDLR;
|
||||
*(uint32_t*)&msg->Data[4] = box->RDHR;
|
||||
|
||||
// Release (free) message from FIFO
|
||||
*rfr |= CAN_RF0R_RFOM0;
|
||||
|
||||
return 0; // success
|
||||
}
|
||||
|
||||
// We have our own version of CAN transmit so we can handle Timeout=0 correctly.
|
||||
STATIC HAL_StatusTypeDef CAN_Transmit(CAN_HandleTypeDef *hcan, uint32_t Timeout) {
|
||||
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 *
|
||||
|
||||
// receive the data
|
||||
CanRxMsgTypeDef rx_msg;
|
||||
self->can.pRxMsg = self->can.pRx1Msg = &rx_msg;
|
||||
HAL_StatusTypeDef status = HAL_CAN_Receive(&self->can, args[0].u_int, args[1].u_int);
|
||||
|
||||
if (status != HAL_OK) {
|
||||
mp_hal_raise(status);
|
||||
int ret = can_receive(self->can.Instance, args[0].u_int, &rx_msg, args[1].u_int);
|
||||
if (ret < 0) {
|
||||
mp_raise_OSError(-ret);
|
||||
}
|
||||
|
||||
// Manage the rx state machine
|
||||
|
Loading…
x
Reference in New Issue
Block a user