|
3 | 3 | * |
4 | 4 | * The MIT License (MIT) |
5 | 5 | * |
6 | | - * Copyright (c) 2014 Damien P. George |
| 6 | + * Copyright (c) 2014-2018 Damien P. George |
7 | 7 | * |
8 | 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
9 | 9 | * of this software and associated documentation files (the "Software"), to deal |
@@ -172,6 +172,43 @@ STATIC void can_clearfilter(uint32_t f) { |
172 | 172 | HAL_CAN_ConfigFilter(NULL, &filter); |
173 | 173 | } |
174 | 174 |
|
| 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 | + |
175 | 212 | // We have our own version of CAN transmit so we can handle Timeout=0 correctly. |
176 | 213 | STATIC HAL_StatusTypeDef CAN_Transmit(CAN_HandleTypeDef *hcan, uint32_t Timeout) { |
177 | 214 | 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 * |
530 | 567 |
|
531 | 568 | // receive the data |
532 | 569 | 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); |
538 | 573 | } |
539 | 574 |
|
540 | 575 | // Manage the rx state machine |
|
0 commit comments