diff options
| author | Jeff Epler <jepler@gmail.com> | 2020-10-06 09:18:53 -0500 |
|---|---|---|
| committer | Jeff Epler <jepler@gmail.com> | 2020-10-06 20:11:58 -0500 |
| commit | e5a0af9216a6d868fad9105a4eb44e0889f54e29 (patch) | |
| tree | 6a3c2ad0c1543c4c566c046f98b51972b9b84062 /ports/stm | |
| parent | a7dccb39a487cdd2e65d9b9b588829818de1d16f (diff) | |
stm32: canio: When Tx mailboxes are full, cancel an old message
.. also add the 8ms wait for transmission that the atmel sam port
has
Diffstat (limited to 'ports/stm')
| -rw-r--r-- | ports/stm/common-hal/canio/CAN.c | 18 | ||||
| -rw-r--r-- | ports/stm/common-hal/canio/CAN.h | 1 |
2 files changed, 19 insertions, 0 deletions
diff --git a/ports/stm/common-hal/canio/CAN.c b/ports/stm/common-hal/canio/CAN.c index 244cc037c..8ff91aaca 100644 --- a/ports/stm/common-hal/canio/CAN.c +++ b/ports/stm/common-hal/canio/CAN.c @@ -225,10 +225,28 @@ void common_hal_canio_can_send(canio_can_obj_t *self, mp_obj_t message_in) .RTR = rtr ? CAN_RTR_REMOTE : CAN_RTR_DATA, .DLC = message->size, }; + uint32_t free_level = HAL_CAN_GetTxMailboxesFreeLevel(&self->handle); + if (free_level == 0) { + // There's no free Tx mailbox. We need to cancel some message without + // transmitting it, because once the bus returns to active state it's + // preferable to transmit the newest messages instead of older messages. + // + // We don't strictly guarantee that we abort the oldest Tx request, + // rather we just abort a different index each time. This permits us + // to avoid tracking this information altogether. + HAL_CAN_AbortTxRequest(&self->handle, 1 << (self->cancel_mailbox)); + self->cancel_mailbox = (self->cancel_mailbox + 1) % 3; + } HAL_StatusTypeDef status = HAL_CAN_AddTxMessage(&self->handle, &header, message->data, &mailbox); if (status != HAL_OK) { mp_raise_OSError(MP_ENOMEM); } + + // wait 8ms (hard coded for now) for TX to occur + uint64_t deadline = port_get_raw_ticks(NULL) + 8; + while (port_get_raw_ticks(NULL) < deadline && HAL_CAN_IsTxMessagePending(&self->handle, 1 << mailbox)) { + RUN_BACKGROUND_TASKS; + } } bool common_hal_canio_can_silent_get(canio_can_obj_t *self) { diff --git a/ports/stm/common-hal/canio/CAN.h b/ports/stm/common-hal/canio/CAN.h index bffc0f65f..94d7e99a8 100644 --- a/ports/stm/common-hal/canio/CAN.h +++ b/ports/stm/common-hal/canio/CAN.h @@ -54,6 +54,7 @@ typedef struct canio_can_obj { bool fifo0_in_use:1; bool fifo1_in_use:1; uint8_t periph_index:2; + uint8_t cancel_mailbox; uint8_t start_filter_bank; uint8_t end_filter_bank; long filter_in_use; // bitmask for the 28 filter banks |
