git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@13389 27425a3e-05d8-49a3-a47f-9c15f0e5edd8

This commit is contained in:
Giovanni Di Sirio 2020-03-05 16:12:24 +00:00
parent e6439900e6
commit b66145bd65
2 changed files with 149 additions and 0 deletions

View File

@ -30,6 +30,62 @@
/* Driver local definitions. */
/*===========================================================================*/
/* Filter Standard Element Size in bytes.*/
#define SRAMCAN_FLS_SIZE (1U * 4U)
/* Filter Extended Element Size in bytes.*/
#define SRAMCAN_FLE_SIZE (2U * 4U)
/* RX FIFO 0 Elements Size in bytes.*/
#define SRAMCAN_RF0_SIZE (18U * 4U)
/* RX FIFO 1 Elements Size in bytes.*/
#define SRAMCAN_RF1_SIZE (18U * 4U)
/* RX Buffer Size in bytes.*/
#define SRAMCAN_RB_SIZE (18U * 4U)
/* TX Event FIFO Elements Size in bytes.*/
#define SRAMCAN_TEF_SIZE (2U * 4U)
/* TX FIFO/Queue Elements Size in bytes.*/
#define SRAMCAN_TB_SIZE (18U * 4U)
/* Filter List Standard Start Address.*/
#define SRAMCAN_FLSSA ((uint32_t)0)
/* Filter List Extended Start Address.*/
#define SRAMCAN_FLESA ((uint32_t)(SRAMCAN_FLSSA + \
(STM32_FDCAN_FLS_NBR * SRAMCAN_FLS_SIZE)))
/* RX FIFO 0 Start Address.*/
#define SRAMCAN_RF0SA ((uint32_t)(SRAMCAN_FLESA + \
(STM32_FDCAN_FLE_NBR * SRAMCAN_FLE_SIZE)))
/* RX FIFO 1 Start Address.*/
#define SRAMCAN_RF1SA ((uint32_t)(SRAMCAN_RF0SA + \
(STM32_FDCAN_RF0_NBR * SRAMCAN_RF0_SIZE)))
/* RX Buffer Start Address.*/
#define SRAMCAN_RBSA ((uint32_t)(SRAMCAN_RF1SA + \
(STM32_FDCAN_RF1_NBR * SRAMCAN_RF1_SIZE)))
/* TX Event FIFO Start Address.*/
#define SRAMCAN_TEFSA ((uint32_t)(SRAMCAN_RBSA + \
(STM32_FDCAN_TEF_NBR * SRAMCAN_RB_SIZE)))
/* TX Buffers Start Address.*/
#define SRAMCAN_TBSA ((uint32_t)(SRAMCAN_TEFSA + \
(STM32_FDCAN_TEF_NBR * SRAMCAN_TEF_SIZE)))
#define SRAMCAN_TMSA ((uint32_t)(SRAMCAN_TBSA + \
(STM32_FDCAN_TB_NBR * SRAMCAN_TB_SIZE)))
/* Message RAM size.*/
#define SRAMCAN_SIZE ((uint32_t)(SRAMCAN_TMSA + \
(STM32_FDCAN_TM_NBR * SRAMCAN_TM_SIZE)))
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
@ -48,6 +104,11 @@ CANDriver CAND2;
/* Driver local variables and types. */
/*===========================================================================*/
static const uint8_t dlc_to_bytes[] = {
0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U,
8U, 12U, 16U, 20U, 24U, 32U, 48U, 64U
};
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
@ -142,6 +203,9 @@ void can_lld_stop(CANDriver *canp) {
*/
bool can_lld_is_tx_empty(CANDriver *canp, canmbx_t mailbox) {
(void)mailbox;
return (bool)((canp->fdcan->TXFQS & FDCAN_TXFQS_TFQF) == 0U);
}
/**
@ -156,7 +220,19 @@ bool can_lld_is_tx_empty(CANDriver *canp, canmbx_t mailbox) {
void can_lld_transmit(CANDriver *canp,
canmbx_t mailbox,
const CANTxFrame *ctfp) {
uint32_t *tx_address;
(void)mailbox;
osalDbgCheck(dlc_to_bytes[ctfp->DLC] <= CAN_MAX_DLC_BYTES);
/* Writing frame.*/
tx_address = canp->ram_base + (SRAMCAN_TBSA / sizeof (uint32_t));
*tx_address++ = ctfp->header32[0];
*tx_address++ = ctfp->header32[1];
for (unsigned i = 0U; i < dlc_to_bytes[ctfp->DLC]; i += 4U) {
*tx_address++ = ctfp->data32[i / 4U];
}
}
/**
@ -173,6 +249,17 @@ void can_lld_transmit(CANDriver *canp,
*/
bool can_lld_is_rx_nonempty(CANDriver *canp, canmbx_t mailbox) {
switch (mailbox) {
case CAN_ANY_MAILBOX:
return can_lld_is_rx_nonempty(canp, 1U) ||
can_lld_is_rx_nonempty(canp, 2U);
case 1:
return (bool)((canp->fdcan->RXF0S & FDCAN_RXF0S_F0FL) != 0U);
case 2:
return (bool)((canp->fdcan->RXF1S & FDCAN_RXF1S_F1FL) != 0U);
default:
return false;
}
}
/**
@ -185,7 +272,59 @@ bool can_lld_is_rx_nonempty(CANDriver *canp, canmbx_t mailbox) {
* @notapi
*/
void can_lld_receive(CANDriver *canp, canmbx_t mailbox, CANRxFrame *crfp) {
uint32_t get_index;
uint32_t *rx_address;
if (mailbox == CAN_ANY_MAILBOX) {
if (can_lld_is_rx_nonempty(canp, 1U)) {
mailbox = 1U;
}
else if (can_lld_is_rx_nonempty(canp, 2U)) {
mailbox = 2U;
}
else {
return;
}
}
/* GET index, add it and the length to the rx_address.*/
get_index = (canp->fdcan->RXF0S & FDCAN_RXF0S_F0GI_Msk) >> FDCAN_RXF0S_F0GI_Pos;
rx_address = canp->ram_base + (SRAMCAN_RF0SA +
(get_index * SRAMCAN_RF0_SIZE)) / sizeof (uint32_t);
crfp->header32[0] = *rx_address++;
crfp->header32[1] = *rx_address++;
/* Copy message from FDCAN peripheral's SRAM to structure. RAM is restricted
to word aligned accesses, so up to 3 extra bytes may be copied.*/
for (unsigned i = 0U; i < dlc_to_bytes[crfp->DLC]; i += 4U) {
crfp->data32[i / 4U] = *rx_address++;
}
/* Acknowledge receipt by writing the get-index to the acknowledge
register RXFxA then re-enable RX FIFO message arrived interrupt once
the FIFO is emptied.*/
if (mailbox == 1U) {
uint32_t rxf0a = canp->fdcan->RXF0A;
rxf0a &= ~FDCAN_RXF0A_F0AI_Msk;
rxf0a |= get_index << FDCAN_RXF0A_F0AI_Pos;
canp->fdcan->RXF0A = rxf0a;
if (!can_lld_is_rx_nonempty(canp, mailbox)) {
// canp->fdcan->IR = FDCAN_IR_RF0N;
canp->fdcan->IE |= FDCAN_IE_RF0NE;
}
}
else {
uint32_t rxf1a = canp->fdcan->RXF1A;
rxf1a &= ~FDCAN_RXF1A_F1AI_Msk;
rxf1a |= get_index << FDCAN_RXF1A_F1AI_Pos;
canp->fdcan->RXF1A = rxf1a;
if (!can_lld_is_rx_nonempty(canp, mailbox)) {
// canp->fdcan->IR = FDCAN_IR_RF1N;
canp->fdcan->IE |= FDCAN_IE_RF1NE;
}
}
}
/**
@ -198,6 +337,8 @@ void can_lld_receive(CANDriver *canp, canmbx_t mailbox, CANRxFrame *crfp) {
*/
void can_lld_abort(CANDriver *canp, canmbx_t mailbox) {
(void)canp;
(void)mailbox;
}
#if CAN_USE_SLEEP_MODE || defined(__DOXYGEN__)

View File

@ -68,6 +68,14 @@
/* CAN attributes.*/
#define STM32_HAS_FDCAN1 TRUE
#define STM32_HAS_FDCAN2 TRUE
#define STM32_FDCAN_FLS_NBR 128U
#define STM32_FDCAN_FLE_NBR 128U
#define STM32_FDCAN_RF0_NBR 64U
#define STM32_FDCAN_RF1_NBR 64U
#define STM32_FDCAN_RB_NBR 64U
#define STM32_FDCAN_TEF_NBR 32U
#define STM32_FDCAN_TB_NBR 32U
#define STM32_FDCAN_TM_NBR 64U
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 TRUE