STM32G4: Add support for FDCAN
Add stm32g4 support for FDCAN peripheral. Normal / FDCAN operation supported, bitrate switching and filtering supported via API. Timestamping and transmit event buffer support in API are TBD. Originally tracked as: https://github.com/libopencm3/libopencm3/pull/1317 Reviewed-by: Karl Palsson <karlp@tweak.net.au>
This commit is contained in:
committed by
Karl Palsson
parent
a9cc695381
commit
458250dc61
892
include/libopencm3/stm32/fdcan.h
Normal file
892
include/libopencm3/stm32/fdcan.h
Normal file
@@ -0,0 +1,892 @@
|
||||
/** @defgroup fdcan_defines FDCAN Defines
|
||||
|
||||
@ingroup STM32G_defines
|
||||
|
||||
@brief <b>libopencm3 Defined Constants and Types for STM32 FD-CAN</b>
|
||||
|
||||
@author @htmlonly © @endhtmlonly 2021 Eduard Drusa <ventyl8 at netkosice dot sk>
|
||||
|
||||
LGPL License Terms @ref lgpl_license
|
||||
*/
|
||||
/*
|
||||
* This file is part of the libopencm3 project.
|
||||
*
|
||||
* Copyright (C) 2021 Eduard Drusa <ventyl86@netkosice.sk>
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef LIBOPENCM3_FDCAN_H
|
||||
#define LIBOPENCM3_FDCAN_H
|
||||
|
||||
#include <libopencm3/stm32/memorymap.h>
|
||||
#include <libopencm3/cm3/common.h>
|
||||
|
||||
/** @{ */
|
||||
|
||||
/* FDCAN block base addresses. Used in functions to identify FDCAN block being manipulated. */
|
||||
|
||||
/** @defgroup fdcan_block FDCAN block base addresses
|
||||
* @{
|
||||
*/
|
||||
#define CAN1 FDCAN1_BASE
|
||||
#define CAN2 FDCAN2_BASE
|
||||
#define CAN3 FDCAN3_BASE
|
||||
/**@}*/
|
||||
|
||||
|
||||
/** @defgroup fdcan_fifo Named constants for FIFOs
|
||||
* @{
|
||||
*/
|
||||
#define FDCAN_FIFO0 0
|
||||
#define FDCAN_FIFO1 1
|
||||
/**@}*/
|
||||
|
||||
|
||||
/** @defgroup FDCAN registers file in each FDCAN block. */
|
||||
|
||||
#define FDCAN_CREL(can_base) MMIO32(can_base + 0x0000)
|
||||
#define FDCAN_ENDN(can_base) MMIO32(can_base + 0x0004)
|
||||
#define FDCAN_DBTP(can_base) MMIO32(can_base + 0x000C)
|
||||
#define FDCAN_TEST(can_base) MMIO32(can_base + 0x0010)
|
||||
#define FDCAN_RWD(can_base) MMIO32(can_base + 0x0014)
|
||||
#define FDCAN_CCCR(can_base) MMIO32(can_base + 0x0018)
|
||||
#define FDCAN_NBTP(can_base) MMIO32(can_base + 0x001C)
|
||||
#define FDCAN_TSCC(can_base) MMIO32(can_base + 0x0020)
|
||||
#define FDCAN_TSCV(can_base) MMIO32(can_base + 0x0024)
|
||||
#define FDCAN_TOCC(can_base) MMIO32(can_base + 0x0028)
|
||||
#define FDCAN_TOCV(can_base) MMIO32(can_base + 0x002C)
|
||||
#define FDCAN_ECR(can_base) MMIO32(can_base + 0x0040)
|
||||
#define FDCAN_PSR(can_base) MMIO32(can_base + 0x0044)
|
||||
#define FDCAN_TDCR(can_base) MMIO32(can_base + 0x0048)
|
||||
#define FDCAN_IR(can_base) MMIO32(can_base + 0x0050)
|
||||
#define FDCAN_IE(can_base) MMIO32(can_base + 0x0054)
|
||||
#define FDCAN_ILS(can_base) MMIO32(can_base + 0x0058)
|
||||
#define FDCAN_ILE(can_base) MMIO32(can_base + 0x005C)
|
||||
#define FDCAN_RXGFC(can_base) MMIO32(can_base + 0x0080)
|
||||
#define FDCAN_XIDAM(can_base) MMIO32(can_base + 0x0084)
|
||||
#define FDCAN_HPMS(can_base) MMIO32(can_base + 0x0088)
|
||||
|
||||
/** Generic access to Rx FIFO status registers.
|
||||
* @param can_base FDCAN block base address @ref fdcan_block
|
||||
* @param fifo_id ID of FIFO, 0 or 1
|
||||
*/
|
||||
#define FDCAN_RXFIS(can_base, fifo_id) MMIO32(can_base + 0x0090 + (8 * fifo_id))
|
||||
#define FDCAN_RXF0S(can_base) FDCAN_RXFIS(can_base, 0)
|
||||
#define FDCAN_RXF1S(can_base) FDCAN_RXFIS(can_base, 1)
|
||||
|
||||
/** Generic access to Rx FIFO acknowledge registers.
|
||||
* @param can_base FDCAN block base address @ref fdcan_block
|
||||
* @param fifo_id ID of FIFO, 0 or 1
|
||||
*/
|
||||
#define FDCAN_RXFIA(can_base, fifo_id) MMIO32(can_base + 0x0094 + (8 * fifo_id))
|
||||
#define FDCAN_RXF0A(can_base) FDCAN_RXFIA(can_base, 0)
|
||||
#define FDCAN_RXF1A(can_base) FDCAN_RXFIA(can_base, 1)
|
||||
|
||||
#define FDCAN_TXBC(can_base) MMIO32(can_base + 0x00C0)
|
||||
#define FDCAN_TXFQS(can_base) MMIO32(can_base + 0x00C4)
|
||||
#define FDCAN_TXBRP(can_base) MMIO32(can_base + 0x00C8)
|
||||
#define FDCAN_TXBAR(can_base) MMIO32(can_base + 0x00CC)
|
||||
#define FDCAN_TXBCR(can_base) MMIO32(can_base + 0x00D0)
|
||||
#define FDCAN_TXBTO(can_base) MMIO32(can_base + 0x00D4)
|
||||
#define FDCAN_TXBCF(can_base) MMIO32(can_base + 0x00D8)
|
||||
#define FDCAN_TXBTIE(can_base) MMIO32(can_base + 0x00DC)
|
||||
#define FDCAN_TXBCIE(can_base) MMIO32(can_base + 0x00E0)
|
||||
#define FDCAN_TXEFS(can_base) MMIO32(can_base + 0x00E4)
|
||||
#define FDCAN_TXEFA(can_base) MMIO32(can_base + 0x00E8)
|
||||
#define FDCAN_CKDIV(can_base) MMIO32(can_base + 0x0100)
|
||||
|
||||
/* DAY[7:0]: FDCAN core revision date */
|
||||
#define FDCAN_CREL_DAY_SHIFT 0
|
||||
#define FDCAN_CREL_DAY_MASK 0xFF
|
||||
|
||||
/* MON[7:0]: FDCAN core revision month */
|
||||
#define FDCAN_CREL_MON_SHIFT 8
|
||||
#define FDCAN_CREL_MON_MASK 0xFF
|
||||
|
||||
/* YEAR[3:0]: FDCAN core revision year */
|
||||
#define FDCAN_CREL_YEAR_SHIFT 16
|
||||
#define FDCAN_CREL_YEAR_MASK 0xF
|
||||
|
||||
/* SUBSTEP[3:0]: FDCAN core release sub stepping */
|
||||
#define FDCAN_CREL_SUBSTEP_SHIFT 20
|
||||
#define FDCAN_CREL_SUBSTEP_MASK 0xF
|
||||
|
||||
/* STEP[3:0]: FDCAN core release stepping */
|
||||
#define FDCAN_CREL_STEP_SHIFT 24
|
||||
#define FDCAN_CREL_STEP_MASK 0xF
|
||||
|
||||
/* REL[3:0]: FDCAN core release number */
|
||||
#define FDCAN_CREL_REL_SHIFT 28
|
||||
#define FDCAN_CREL_REL_MASK 0xF
|
||||
|
||||
|
||||
/* DSJW[3:0]: Synchronization jump width */
|
||||
#define FDCAN_DBTP_DSJW_SHIFT 0
|
||||
#define FDCAN_DBTP_DSJW_MASK 0xF
|
||||
|
||||
/* DTSEG2[3:0]: Data time segment after sample point */
|
||||
#define FDCAN_DBTP_DTSEG2_SHIFT 4
|
||||
#define FDCAN_DBTP_DTSEG2_MASK 0xF
|
||||
|
||||
/* DTSEG1[4:0]: Data time segment before sample point */
|
||||
#define FDCAN_DBTP_DTSEG1_SHIFT 8
|
||||
#define FDCAN_DBTP_DTSEG1_MASK 0x1F
|
||||
|
||||
/* DBRP[4:0]: Data bit rate prescaler */
|
||||
#define FDCAN_DBTP_DBRP_SHIFT 16
|
||||
#define FDCAN_DBTP_DBRP_MASK 0x1F
|
||||
|
||||
#define FDCAN_DBTP_TDC (1 << 23)
|
||||
|
||||
#define FDCAN_TEST_LBCK (1 << 4)
|
||||
/* TX[1:0]: Control of transmit pin */
|
||||
#define FDCAN_TEST_TX_SHIFT 5
|
||||
#define FDCAN_TEST_TX_MASK 0x3
|
||||
|
||||
#define FDCAN_TEST_RX (1 << 7)
|
||||
|
||||
/* WDC[7:0]: RAM watchdog configuration */
|
||||
#define FDCAN_RWD_WDC_SHIFT 0
|
||||
#define FDCAN_RWD_WDC_MASK 0xFF
|
||||
|
||||
/* WDV[7:0]: RAM watchdog actual value */
|
||||
#define FDCAN_RWD_WDV_SHIFT 7
|
||||
#define FDCAN_RWD_WDV_MASK 0xFF
|
||||
|
||||
/** @defgroup fdcan_cccr FDCAN CC control register bits
|
||||
* @{
|
||||
*/
|
||||
#define FDCAN_CCCR_INIT (1 << 0)
|
||||
#define FDCAN_CCCR_CCE (1 << 1)
|
||||
#define FDCAN_CCCR_ASM (1 << 2)
|
||||
#define FDCAN_CCCR_CSA (1 << 3)
|
||||
#define FDCAN_CCCR_CSR (1 << 4)
|
||||
#define FDCAN_CCCR_MON (1 << 5)
|
||||
#define FDCAN_CCCR_DAR (1 << 6)
|
||||
#define FDCAN_CCCR_TEST (1 << 7)
|
||||
#define FDCAN_CCCR_FDOE (1 << 8)
|
||||
#define FDCAN_CCCR_BRSE (1 << 9)
|
||||
#define FDCAN_CCCR_PXHD (1 << 12)
|
||||
#define FDCAN_CCCR_EFBI (1 << 13)
|
||||
#define FDCAN_CCCR_TXP (1 << 14)
|
||||
#define FDCAN_CCCR_NISO (1 << 15)
|
||||
/**@}*/
|
||||
|
||||
/** Timeout for FDCAN_CCCR register INIT bit to accept set value.
|
||||
*
|
||||
* This timeout is required because FDCAN uses two different clocks
|
||||
* feeding two different portions of block. There can be slight delay
|
||||
* based on how clocks are set up. While amount of FDCAN_clk /
|
||||
* FDCAN_pclk combinations is high and clock speeds may vary a lot,
|
||||
* following value has been choosen as sane default. You are free to
|
||||
* use any timeout value you want.
|
||||
*/
|
||||
#define FDCAN_CCCR_INIT_TIMEOUT 0x0000FFFF
|
||||
|
||||
/* NTSEG2[6:0]: Nominal timing segment after sample point length */
|
||||
#define FDCAN_NBTP_NTSEG2_SHIFT 0
|
||||
#define FDCAN_NBTP_NTSEG2_MASK 0x7F
|
||||
|
||||
/* NTSEG1[7:0]: Nominal timing segment before sample point length */
|
||||
#define FDCAN_NBTP_NTSEG1_SHIFT 8
|
||||
#define FDCAN_NBTP_NTSEG1_MASK 0xFF
|
||||
|
||||
/* NBRP[8:0]: Norminal timing bit rate prescaler */
|
||||
#define FDCAN_NBTP_NBRP_SHIFT 16
|
||||
#define FDCAN_NBTP_NBRP_MASK 0x1FF
|
||||
|
||||
/* NSJW[6:0]: Norminal timing resynchronization jumb width*/
|
||||
#define FDCAN_NBTP_NSJW_SHIFT 25
|
||||
#define FDCAN_NBTP_NSJW_MASK 0x7F
|
||||
|
||||
/* TSS[1:0]: Timestamp select */
|
||||
#define FDCAN_TSCC_TSS_SHIFT 0
|
||||
#define FDCAN_TSCC_TSS_MASK 0x3
|
||||
|
||||
/* TCP[3:0]: Timestamp counter prescaler */
|
||||
#define FDCAN_TSCC_TCP_SHIFT 16
|
||||
#define FDCAN_TSCC_TCP_MASK 0xF
|
||||
|
||||
|
||||
/* TSC[15:0]: Timestamp counter value */
|
||||
#define FDCAN_TSCV_TSC_SHIFT 0
|
||||
#define FDCAN_TSCV_TSC_MASK 0xFFFF
|
||||
|
||||
#define FDCAN_TOCC_ETOC (1 << 0)
|
||||
/* TOS[1:0]: Timeout select */
|
||||
#define FDCAN_TOCC_TOS_SHIFT 1
|
||||
#define FDCAN_TOCC_TOS_MASK 0x3
|
||||
|
||||
/* TOP[15:0]: Timeout period */
|
||||
#define FDCAN_TOCC_TOP_SHIFT 16
|
||||
#define FDCAN_TOCC_TOP_MASK 0xFFFF
|
||||
|
||||
/* TOC[15:0]: Timeout counter */
|
||||
#define FDCAN_TOCV_TOC_SHIFT 0
|
||||
#define FDCAN_TOCV_TOC_MASK 0xFFFF
|
||||
|
||||
/* TEC[7:0]: Transmit error counter */
|
||||
#define FDCAN_ECR_TEC_SHIFT 0
|
||||
#define FDCAN_ECR_TEC_MASK 0xFF
|
||||
|
||||
/* REC[6:0]: Receive error counter */
|
||||
#define FDCAN_ECR_REC_SHIFT 8
|
||||
#define FDCAN_ECR_REC_MASK 0x7F
|
||||
|
||||
#define FDCAN_ECR_RP (1 << 15)
|
||||
/* CEL[7:0]: CAN error logging */
|
||||
#define FDCAN_ECR_CEL_SHIFT 16
|
||||
#define FDCAN_ECR_CEL_MASK 0xFF
|
||||
|
||||
|
||||
/* LEC[2:0]: Last error code */
|
||||
#define FDCAN_PSR_LEC_SHIFT 0
|
||||
#define FDCAN_PSR_LEC_MASK 0x7
|
||||
|
||||
/* ACT[1:0]: CAN block activity */
|
||||
#define FDCAN_PSR_ACT_SHIFT 3
|
||||
#define FDCAN_PSR_ACT_MASK 0x3
|
||||
|
||||
#define FDCAN_PSR_EP (1 << 5)
|
||||
#define FDCAN_PSR_EW (1 << 6)
|
||||
#define FDCAN_PSR_BO (1 << 7)
|
||||
/* DLEC[2:0]: Last error code in data section */
|
||||
#define FDCAN_PSR_DLEC_SHIFT 8
|
||||
#define FDCAN_PSR_DLEC_MASK 0x7
|
||||
|
||||
#define FDCAN_PSR_RESI (1 << 11)
|
||||
|
||||
/* the what? */
|
||||
#define FDCAN_PSR_RBRSRESI1 (1 << 12)
|
||||
#define FDCAN_PSR_REDL (1 << 13)
|
||||
#define FDCAN_PSR_PXE (1 << 14)
|
||||
|
||||
/* TDCV[6:0]: Transmitter delay compensation value */
|
||||
#define FDCAN_PSR_TDCV_SHIFT 16
|
||||
#define FDCAN_PSR_TDCV_MASK 0x7F
|
||||
|
||||
/* TDCF[6:0]: Transmitter delay compensation filter window length */
|
||||
#define FDCAN_TDCR_TDCF_SHIFT 0
|
||||
#define FDCAN_TDCR_TDCF_MASK 0x7F
|
||||
|
||||
/* TDCO[6:0]: Transmitter delay compensation offset */
|
||||
#define FDCAN_TDCR_TDCO_SHIFT 8
|
||||
#define FDCAN_TDCR_TDCO_MASK 0x7F
|
||||
|
||||
/** @defgroup fdcan_ir FDCAN interrupt register flags
|
||||
* @{
|
||||
*/
|
||||
#define FDCAN_IR_RF0N (1 << 0)
|
||||
#define FDCAN_IR_RF0F (1 << 1)
|
||||
#define FDCAN_IR_RF0L (1 << 2)
|
||||
#define FDCAN_IR_RF1N (1 << 3)
|
||||
#define FDCAN_IR_RF1F (1 << 4)
|
||||
#define FDCAN_IR_RF1L (1 << 5)
|
||||
#define FDCAN_IR_HPM (1 << 6)
|
||||
#define FDCAN_IR_TC (1 << 7)
|
||||
#define FDCAN_IR_TCF (1 << 8)
|
||||
#define FDCAN_IR_TFE (1 << 9)
|
||||
#define FDCAN_IR_TEFN (1 << 10)
|
||||
#define FDCAN_IR_TEFF (1 << 11)
|
||||
#define FDCAN_IR_TEFL (1 << 12)
|
||||
#define FDCAN_IR_TSW (1 << 13)
|
||||
#define FDCAN_IR_MRAF (1 << 14)
|
||||
#define FDCAN_IR_TOO (1 << 15)
|
||||
#define FDCAN_IR_ELO (1 << 16)
|
||||
#define FDCAN_IR_EP (1 << 17)
|
||||
#define FDCAN_IR_EW (1 << 18)
|
||||
#define FDCAN_IR_BO (1 << 19)
|
||||
#define FDCAN_IR_WDI (1 << 20)
|
||||
#define FDCAN_IR_PEA (1 << 21)
|
||||
#define FDCAN_IR_PED (1 << 22)
|
||||
#define FDCAN_IR_ARA (1 << 23)
|
||||
/**@}*/
|
||||
|
||||
/** @defgroup fdcan_ie FDCAN interrupt enable flags
|
||||
* @{
|
||||
*/
|
||||
#define FDCAN_IE_RF0NE (1 << 0)
|
||||
#define FDCAN_IE_RF0FE (1 << 1)
|
||||
#define FDCAN_IE_RF0LE (1 << 2)
|
||||
#define FDCAN_IE_RF1NE (1 << 3)
|
||||
#define FDCAN_IE_RF1FE (1 << 4)
|
||||
#define FDCAN_IE_RF1LE (1 << 5)
|
||||
#define FDCAN_IE_HPME (1 << 6)
|
||||
#define FDCAN_IE_TCE (1 << 7)
|
||||
#define FDCAN_IE_TCFE (1 << 8)
|
||||
#define FDCAN_IE_TFEE (1 << 9)
|
||||
#define FDCAN_IE_TEFNE (1 << 10)
|
||||
#define FDCAN_IE_TEFFE (1 << 11)
|
||||
#define FDCAN_IE_TEFLE (1 << 12)
|
||||
#define FDCAN_IE_TSWE (1 << 13)
|
||||
#define FDCAN_IE_MRAFE (1 << 14)
|
||||
#define FDCAN_IE_TOOE (1 << 15)
|
||||
#define FDCAN_IE_ELOE (1 << 16)
|
||||
#define FDCAN_IE_EPE (1 << 17)
|
||||
#define FDCAN_IE_EWE (1 << 18)
|
||||
#define FDCAN_IE_BOE (1 << 19)
|
||||
#define FDCAN_IE_WDIE (1 << 20)
|
||||
#define FDCAN_IE_PEAE (1 << 21)
|
||||
#define FDCAN_IE_PEDE (1 << 22)
|
||||
#define FDCAN_IE_ARAE (1 << 23)
|
||||
/**@}*/
|
||||
|
||||
/** @defgroup fdcan_ils FDCAN_ILS interrupt line select flags
|
||||
* @{
|
||||
*/
|
||||
#define FDCAN_ILS_RxFIFO0 (1 << 0)
|
||||
#define FDCAN_ILS_RxFIFO1 (1 << 1)
|
||||
#define FDCAN_ILS_SMSG (1 << 2)
|
||||
#define FDCAN_ILS_TFERR (1 << 3)
|
||||
#define FDCAN_ILS_MISC (1 << 4)
|
||||
#define FDCAN_ILS_BERR (1 << 5)
|
||||
#define FDCAN_ILS_PERR (1 << 6)
|
||||
/**@}*/
|
||||
|
||||
#define FDCAN_ILE_INT0 (1 << 0)
|
||||
#define FDCAN_ILE_INT1 (1 << 1)
|
||||
|
||||
#define FDCAN_RXGFC_RRFE (1 << 0)
|
||||
#define FDCAN_RXGFC_RRFS (1 << 1)
|
||||
/* ANFE[1:0]: Accept non-matching frames w/ extended ID */
|
||||
#define FDCAN_RXGFC_ANFE_SHIFT 2
|
||||
#define FDCAN_RXGFC_ANFE_MASK 0x3
|
||||
|
||||
/* ANFS[1:0]: Accept non-matching frames w/ standard ID */
|
||||
#define FDCAN_RXGFC_ANFS_SHIFT 4
|
||||
#define FDCAN_RXGFC_ANFS_MASK 0x3
|
||||
|
||||
#define FDCAN_RXGFC_F1OM (1 << 8)
|
||||
#define FDCAN_RXGFC_F0OM (1 << 9)
|
||||
/* LSS[4:0]: List size of standard ID filters */
|
||||
#define FDCAN_RXGFC_LSS_SHIFT 16
|
||||
#define FDCAN_RXGFC_LSS_MASK 0x1F
|
||||
|
||||
/* LSE[3:0]: List size of extended ID filters */
|
||||
#define FDCAN_RXGFC_LSE_SHIFT 24
|
||||
#define FDCAN_RXGFC_LSE_MASK 0xF
|
||||
|
||||
|
||||
/* EIDM[28:0]: Extended ID mask for filtering */
|
||||
#define FDCAN_XIDAM_EIDM_SHIFT 0
|
||||
#define FDCAN_XIDAM_EIDM_MASK 0x1FFFFFFF
|
||||
|
||||
|
||||
/* BIDX[2:0]: Buffer index */
|
||||
#define FDCAN_HPMS_BIDX_SHIFT 0
|
||||
#define FDCAN_HPMS_BIDX_MASK 0x7
|
||||
|
||||
/* MSI[1:0]: Message storage indicator */
|
||||
#define FDCAN_HPMS_MSI_SHIFT 6
|
||||
#define FDCAN_HPMS_MSI_MASK 0x3
|
||||
|
||||
/* FIDX[4:0]: Filter index */
|
||||
#define FDCAN_HPMS_FIDX_SHIFT 8
|
||||
#define FDCAN_HPMS_FIDX_MASK 0x1F
|
||||
|
||||
#define FDCAN_HPMS_FLS (1 << 15)
|
||||
|
||||
/* Fill level of Rx FIFOs */
|
||||
#define FDCAN_RXFIFO_FL_SHIFT 0
|
||||
#define FDCAN_RXFIFO_FL_MASK 0xF
|
||||
|
||||
/* Get index of Rx FIFOs */
|
||||
#define FDCAN_RXFIFO_GI_SHIFT 8
|
||||
#define FDCAN_RXFIFO_GI_MASK 0x3
|
||||
|
||||
/* Put index of Rx FIFOs */
|
||||
#define FDCAN_RXFIFO_PI_SHIFT 16
|
||||
#define FDCAN_RXFIFO_PI_MASK 0x3
|
||||
|
||||
#define FDCAN_RXFIFO_FF (1 << 24)
|
||||
#define FDCAN_RXFIFO_RFL (1 << 25)
|
||||
|
||||
/* F0FL[3:0]: Fill level of Rx FIFO 0 */
|
||||
#define FDCAN_RXF0S_F0FL_SHIFT FDCAN_RXFIFO_FL_SHIFT
|
||||
#define FDCAN_RXF0S_F0FL_MASK FDCAN_RXFIFO_FL_MASK
|
||||
|
||||
/* F0GI[1:0]: Get index of Rx FIFO 0 */
|
||||
#define FDCAN_RXF0S_F0GI_SHIFT FDCAN_RXFIFO_GI_SHIFT
|
||||
#define FDCAN_RXF0S_F0GI_MASK FDCAN_RXFIFO_GI_MASK
|
||||
|
||||
/* F0PI[1:0]: Put index of Rx FIFO 0 */
|
||||
#define FDCAN_RXF0S_F0PI_SHIFT FDCAN_RXFIFO_PI_SHIFT
|
||||
#define FDCAN_RXF0S_F0PI_MASK FDCAN_RXFIFO_PI_MASK
|
||||
|
||||
#define FDCAN_RXF0S_F0F FDCAN_RXFIFO_FF
|
||||
#define FDCAN_RXF0S_RF0L FDCAN_RXFIFO_RFL
|
||||
|
||||
/* Rx FIFOs acknowledge index */
|
||||
#define FDCAN_RXFIFO_AI_SHIFT 0
|
||||
#define FDCAN_RXFIFO_AI_MASK 0x7
|
||||
|
||||
/* R0AI[2:0]: Rx FIFO 0 acknowledge index */
|
||||
#define FDCAN_RXF0A_R0AI_SHIFT FDCAN_RXFIFO_AI_SHIFT
|
||||
#define FDCAN_RXF0A_R0AI_MASK FDCAN_RXFIFO_AI_MASK
|
||||
|
||||
/* F1FL[3:1]: Fill level of Rx FIFO 1 */
|
||||
#define FDCAN_RXF1S_F1FL_SHIFT FDCAN_RXFIFO_FL_SHIFT
|
||||
#define FDCAN_RXF1S_F1FL_MASK FDCAN_RXFIFO_FL_MASK
|
||||
|
||||
/* F1GI[1:1]: Get index of Rx FIFO 1 */
|
||||
#define FDCAN_RXF1S_F1GI_SHIFT FDCAN_RXFIFO_GI_SHIFT
|
||||
#define FDCAN_RXF1S_F1GI_MASK FDCAN_RXFIFO_GI_MASK
|
||||
|
||||
/* F1PI[1:1]: Put index of Rx FIFO 1 */
|
||||
#define FDCAN_RXF1S_F1PI_SHIFT FDCAN_RXFIFO_PI_SHIFT
|
||||
#define FDCAN_RXF1S_F1PI_MASK FDCAN_RXFIFO_PI_MASK
|
||||
|
||||
#define FDCAN_RXF1S_F1F FDCAN_RXFIFO_FF
|
||||
#define FDCAN_RXF1S_RF1L FDCAN_RXFIFO_RFL
|
||||
|
||||
/* R1AI[2:0]: Rx FIFO 1 acknowledge index */
|
||||
#define FDCAN_RXF1A_R1AI_SHIFT FDCAN_RXFIFO_AI_SHIFT
|
||||
#define FDCAN_RXF1A_R1AI_MASK FDCAN_RXFIFO_AI_MASK
|
||||
|
||||
#define FDCAN_TXBC_TFQM (1 << 24)
|
||||
|
||||
/* TFFL[2:0]: Tx FIFO free level */
|
||||
#define FDCAN_TXFQS_TFFL_SHIFT 0
|
||||
#define FDCAN_TXFQS_TFFL_MASK 0x7
|
||||
|
||||
/* TFGI[1:0]: Tx FIFO get index */
|
||||
#define FDCAN_TXFQS_TFGI_SHIFT 0
|
||||
#define FDCAN_TXFQS_TFGI_MASK 0x3
|
||||
|
||||
/* TFQPI[1:0]: Tx FIFO put index */
|
||||
#define FDCAN_TXFQS_TFQPI_SHIFT 0
|
||||
#define FDCAN_TXFQS_TFQPI_MASK 0x3
|
||||
|
||||
#define FDCAN_TXFQS_TFQF (1 << 0)
|
||||
|
||||
/** @defgroup fdcan_txbrp FDCAN_TXBRP Transmit request pending bits
|
||||
* @{
|
||||
*/
|
||||
#define FDCAN_TXBRP_TRP0 (1 << 0)
|
||||
#define FDCAN_TXBRP_TRP1 (1 << 1)
|
||||
#define FDCAN_TXBRP_TRP2 (1 << 2)
|
||||
/**@}*/
|
||||
|
||||
/** @defgroup fdcan_txbar FDCAN_TXBAR Transmit buffer add request bits
|
||||
* @{
|
||||
*/
|
||||
#define FDCAN_TXBAR_AR0 (1 << 0)
|
||||
#define FDCAN_TXBAR_AR1 (1 << 1)
|
||||
#define FDCAN_TXBAR_AR2 (1 << 2)
|
||||
/**@}*/
|
||||
|
||||
/** @defgroup fdcan_txbcr FDCAN_TXBCR Transmit buffer cancel request bits
|
||||
* @{
|
||||
*/
|
||||
#define FDCAN_TXBCR_CR0 (1 << 0)
|
||||
#define FDCAN_TXBCR_CR1 (1 << 1)
|
||||
#define FDCAN_TXBCR_CR2 (1 << 2)
|
||||
/**@}*/
|
||||
|
||||
/** @defgroup fdcan_txbto FDCAN_TXBTO Transmit buffer transfer occured bits
|
||||
* @{
|
||||
*/
|
||||
#define FDCAN_TXBTO_TO0 (1 << 0)
|
||||
#define FDCAN_TXBTO_TO1 (1 << 1)
|
||||
#define FDCAN_TXBTO_TO2 (1 << 2)
|
||||
/**@}*/
|
||||
|
||||
/** @defgroup fdcan_txbcf FDCAN_TXBCF Transmit buffer cancellation finished bits
|
||||
* @{
|
||||
*/
|
||||
#define FDCAN_TXBCF_CF0 (1 << 0)
|
||||
#define FDCAN_TXBCF_CF1 (1 << 1)
|
||||
#define FDCAN_TXBCF_CF2 (1 << 2)
|
||||
/**@}*/
|
||||
|
||||
/** @defgroup fdcan_txbtie FDCAN_TXBTIE Transmit interrupt enable bits
|
||||
*
|
||||
* Each bit enables or disables transmit interrupt for transmit buffer
|
||||
* slot.
|
||||
* @{
|
||||
*/
|
||||
#define FDCAN_TXBTIE_TIE0 (1 << 0)
|
||||
#define FDCAN_TXBTIE_TIE1 (1 << 1)
|
||||
#define FDCAN_TXBTIE_TIE2 (1 << 2)
|
||||
/**@}*/
|
||||
|
||||
/** @defgroup fdcan_txbcie FDCAN_TXBCIE Transmit cancelled interrupt enable bits
|
||||
*
|
||||
* Each bit enables or disables transmit cancelled interrupt for transmit buffer
|
||||
* slot.
|
||||
* @{
|
||||
*/
|
||||
#define FDCAN_TXBCIE_CFIE0 (1 << 0)
|
||||
#define FDCAN_TXBCIE_CFIE1 (1 << 1)
|
||||
#define FDCAN_TXBCIE_CFIE2 (1 << 2)
|
||||
/**@}*/
|
||||
|
||||
/* EFFL[2:0]: Event FIFO fill level*/
|
||||
#define FDCAN_TXEFS_EFFL_SHIFT 0
|
||||
#define FDCAN_TXEFS_EFFL_MASK 0x7
|
||||
|
||||
/* EFG[1:0]: Event FIFO get index */
|
||||
#define FDCAN_TXEFS_EFGI_SHIFT 8
|
||||
#define FDCAN_TXEFS_EFGI_MASK 0x3
|
||||
|
||||
/* EFPI[1:0]: Event FIFO put index */
|
||||
#define FDCAN_TXEFS_EFPI_SHIFT 16
|
||||
#define FDCAN_TXEFS_EFPI_MASK 0x3
|
||||
|
||||
#define FDCAN_TXEFS_EFF (1 << 24)
|
||||
#define FDCAN_TXEFS_TEF (1 << 25)
|
||||
|
||||
/* EFAI[1:0]: Event FIFO acknowledge index */
|
||||
#define FDCAN_TXEFA_EFAI_SHIFT 0
|
||||
#define FDCAN_TXEFA_EFAI_MASK 0x3
|
||||
|
||||
|
||||
/* PDIV[3:0]: Input clock divider */
|
||||
#define FDCAN_CKDIV_PDIV_SHIFT 0
|
||||
#define FDCAN_CKDIV_PDIV_MASK 0xF
|
||||
|
||||
/* --- FD-CAN memory block defines------------------------------------------ */
|
||||
|
||||
/** Structure describing standard ID filter.
|
||||
* Standard ID filter is composed of one 32bit value.
|
||||
* This region of memory cannot be accessed in quantities less than 32bits.
|
||||
*/
|
||||
struct fdcan_standard_filter {
|
||||
/** Aggregate of filter type, filter action and two IDs */
|
||||
uint32_t type_id1_conf_id2;
|
||||
};
|
||||
|
||||
#define FDCAN_SFT_SHIFT 30
|
||||
#define FDCAN_SFT_MASK 0x3
|
||||
|
||||
/** @defgroup fdcan_sft Standard ID filter match type
|
||||
*
|
||||
* Matching strategy for standard ID filters.
|
||||
* @{
|
||||
*/
|
||||
/** Filter matches all messages in range from id1 to id2. */
|
||||
#define FDCAN_SFT_RANGE 0x0
|
||||
|
||||
/** Filter matches messages with id1 or id2 */
|
||||
#define FDCAN_SFT_DUAL 0x1
|
||||
|
||||
/** Filter matches messages which match id1 after being unmasked
|
||||
* using id2. */
|
||||
#define FDCAN_SFT_ID_MASK 0x2
|
||||
|
||||
/** Disable this filter. */
|
||||
#define FDCAN_SFT_DISABLE 0x3
|
||||
/**@}*/
|
||||
|
||||
#define FDCAN_SFEC_SHIFT 27
|
||||
#define FDCAN_SFEC_MASK 0x7
|
||||
|
||||
/** @defgroup fdcan_sfec Standard ID filter action
|
||||
*
|
||||
* Defines possible actions for standard ID filters. All actions except
|
||||
* of @ref FDCAN_SFEC_PRIO cause filter matching to terminate immediately
|
||||
* with desired outcome. FDCAN_SFEC_PRIO sets priority flag for message
|
||||
* and continues processing remaining filters.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Filter is disabled. No matchin occurrs. */
|
||||
#define FDCAN_SFEC_DISABLE 0x0
|
||||
|
||||
/** Put message into FIFO0 */
|
||||
#define FDCAN_SFEC_FIFO0 0x1
|
||||
|
||||
/** Put message into FIFO1 */
|
||||
#define FDCAN_SFEC_FIFO1 0x2
|
||||
|
||||
/** Reject message */
|
||||
#define FDCAN_SFEC_REJECT 0x3
|
||||
|
||||
/** Treat message as priority message (and continue processing further rules) */
|
||||
#define FDCAN_SFEC_PRIO 0x4
|
||||
|
||||
/** Treat message as priority and put it into FIFO0 */
|
||||
#define FDCAN_SFEC_PRIO_FIFO0 0x5
|
||||
|
||||
/** Treat message as priority and put it into FIFO1 */
|
||||
#define FDCAN_SFEC_PRIO_FIFO1 0x6
|
||||
/**@}*/
|
||||
|
||||
/** Amount of standard filters allocated in Message RAM
|
||||
* This number may vary between devices. 28 is value valid
|
||||
* for STM32G4
|
||||
**/
|
||||
#define FDCAN_SFT_MAX_NR 28
|
||||
|
||||
/* SFEC = 0x7 is unused */
|
||||
|
||||
#define FDCAN_SFID1_SHIFT 16
|
||||
#define FDCAN_SFID1_MASK 0x7FF
|
||||
|
||||
#define FDCAN_SFID2_SHIFT 0
|
||||
#define FDCAN_SFID2_MASK 0x7FF
|
||||
|
||||
/** Structure describing extended ID filters.
|
||||
* Extended ID filter is composed of two 32bit values.
|
||||
* This region of memory cannot be accessed in quantities less than 32bits.
|
||||
*/
|
||||
struct fdcan_extended_filter {
|
||||
/** Aggregate of filter action and extended ID */
|
||||
uint32_t conf_id1;
|
||||
/** Aggregate of filter type and extended ID or mask */
|
||||
uint32_t type_id2;
|
||||
};
|
||||
|
||||
#define FDCAN_EFEC_SHIFT 29
|
||||
#define FDCAN_EFEC_MASK 0x7
|
||||
|
||||
/** @defgroup fdcan_efec Extended ID filter action
|
||||
*
|
||||
* These are possible actions, extended filter can have. If filter is
|
||||
* disabled, then no matching is performed. All other actions except of
|
||||
* @ref FDCAN_EFEC_PRIO cause matching to terminate with required outcome.
|
||||
* FDCAN_EFEC_PRIO marks message as priority and continues matching.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Disable this filter. */
|
||||
#define FDCAN_EFEC_DISABLE 0x0
|
||||
|
||||
/** Put message into FIFO0 */
|
||||
#define FDCAN_EFEC_FIFO0 0x1
|
||||
|
||||
/** Put message into FIFO1 */
|
||||
#define FDCAN_EFEC_FIFO1 0x2
|
||||
|
||||
/** Reject message */
|
||||
#define FDCAN_EFEC_REJECT 0x3
|
||||
|
||||
/** Treat message as priority message (and continue processing further rules) */
|
||||
#define FDCAN_EFEC_PRIO 0x4
|
||||
|
||||
/** Treat message as priority and put it into FIFO0 */
|
||||
#define FDCAN_EFEC_PRIO_FIFO0 0x5
|
||||
|
||||
/** Treat message as priority and put it into FIFO1 */
|
||||
#define FDCAN_EFEC_PRIO_FIFO1 0x6
|
||||
/**@}*/
|
||||
|
||||
#define FDCAN_EFID1_SHIFT 0
|
||||
#define FDCAN_EFID1_MASK 0x1FFFFFFF
|
||||
|
||||
#define FDCAN_EFT_SHIFT 30
|
||||
#define FDCAN_EFT_MASK 0x3
|
||||
|
||||
/** @defgroup fdcan_eft Extended ID filter match type
|
||||
*
|
||||
* Matching strategy for extended ID filters.
|
||||
* @{
|
||||
*/
|
||||
/** Filter matches all messages in range from id1 to id2. */
|
||||
#define FDCAN_EFT_RANGE 0x0
|
||||
|
||||
/** Filter matches messages with id1 or id2 */
|
||||
#define FDCAN_EFT_DUAL 0x1
|
||||
|
||||
/** Filter matches messages which match id1 after being unmasked
|
||||
* using id2. */
|
||||
#define FDCAN_EFT_ID_MASK 0x2
|
||||
|
||||
/** Similar to @ref FDCAN_EFT_RANGE except of ignoring global mask
|
||||
* set using @ref FDCAN_XIDAM register.
|
||||
*/
|
||||
#define FDCAN_EFT_RANGE_NOXIDAM 0x3
|
||||
/**@}*/
|
||||
|
||||
#define FDCAN_EFID2_SHIFT 0
|
||||
#define FDCAN_EFID2_MASK 0x1FFFFFFF
|
||||
|
||||
/** Amount of extended filters allocated in Message RAM
|
||||
* This number may vary between devices. 8 is value valid
|
||||
* for STM32G4
|
||||
**/
|
||||
#define FDCAN_EFT_MAX_NR 8
|
||||
|
||||
/** Structure describing receive FIFO element.
|
||||
* Receive FIFO element consists of 2 32bit values for header
|
||||
* and 16 32bit values for message payload.
|
||||
* This area of memory can only be accessed in 32bit quantities
|
||||
*/
|
||||
struct fdcan_rx_fifo_element {
|
||||
/** Aggregate of message identifier and flags. */
|
||||
uint32_t identifier_flags;
|
||||
/** Aggregate of filter match ID, transfer format, DLC and timestamp */
|
||||
uint32_t filt_fmt_dlc_ts;
|
||||
/** Message payload data */
|
||||
uint32_t data[64 / sizeof(uint32_t)];
|
||||
};
|
||||
|
||||
/** Structure describing transmit event element.
|
||||
* Transmit event element consists of 2 32bit values.
|
||||
* This area of memory can only be accessed in 32bit quantities
|
||||
*/
|
||||
struct fdcan_tx_event_element {
|
||||
/** Aggregate of message identifier and flags. */
|
||||
uint32_t identifier_flags;
|
||||
|
||||
/** Aggregate of event ID, transfer format, DLC and timestamp */
|
||||
uint32_t evt_fmt_dlc_ts;
|
||||
};
|
||||
|
||||
/** Structure describing transmit buffer element.
|
||||
* Transmit buffer consists of 2 32bit values for header
|
||||
* and 16 32bit values for message payload.
|
||||
* This area of memory can only be accessed in 32bit quantities
|
||||
*/
|
||||
struct fdcan_tx_buffer_element {
|
||||
/** Aggregate of message identifier and flags. */
|
||||
uint32_t identifier_flags;
|
||||
|
||||
/** Aggregate of event ID, transfer format and DLC */
|
||||
uint32_t evt_fmt_dlc_res;
|
||||
/** Message payload data */
|
||||
uint32_t data[64 / sizeof(uint32_t)];
|
||||
};
|
||||
|
||||
/** @defgroup fdcan_fifo_flags FIFO / buffer flags
|
||||
* @{
|
||||
*/
|
||||
#define FDCAN_FIFO_ESI (1 << 31)
|
||||
#define FDCAN_FIFO_XTD (1 << 20)
|
||||
#define FDCAN_FIFO_RTR (1 << 29)
|
||||
#define FDCAN_FIFO_EFC (1 << 23)
|
||||
#define FDCAN_FIFO_FDF (1 << 21)
|
||||
#define FDCAN_FIFO_BRS (1 << 20)
|
||||
/**@}*/
|
||||
|
||||
#define FDCAN_FIFO_EID_SHIFT 0
|
||||
#define FDCAN_FIFO_EID_MASK 0x1FFFFFFF
|
||||
|
||||
#define FDCAN_FIFO_SID_SHIFT 18
|
||||
#define FDCAN_FIFO_SID_MASK 0x7FF
|
||||
|
||||
#define FDCAN_FIFO_DLC_SHIFT 16
|
||||
#define FDCAN_FIFO_DLC_MASK 0xF
|
||||
|
||||
#define FDCAN_FIFO_MM_SHIFT 24
|
||||
#define FDCAN_FIFO_MM_MASK 0xFF
|
||||
|
||||
#define FDCAN_FIFO_ANMF (1 << 31)
|
||||
#define FDCAN_FIFO_FIDX_SHIFT 24
|
||||
#define FDCAN_FIFO_FIDX_MASK 0x7F
|
||||
|
||||
#define FDCAN_FIFO_RXTS_SHIFT 0
|
||||
#define FDCAN_FIFO_RXTS_MASK 0xFFFF
|
||||
|
||||
/** Message RAM layout for one FDCAN block.
|
||||
* There are as many memory blocks as there are FDCAN blocks
|
||||
*/
|
||||
struct fdcan_message_ram {
|
||||
/* List of standard ID filters */
|
||||
struct fdcan_standard_filter lfssa[FDCAN_SFT_MAX_NR];
|
||||
|
||||
/* List of extended ID filters */
|
||||
struct fdcan_extended_filter lfesa[FDCAN_EFT_MAX_NR];
|
||||
|
||||
/* Buffer area for two receive FIFOs each having space for three messages */
|
||||
struct fdcan_rx_fifo_element rx_fifo[2][3];
|
||||
|
||||
/* Buffer area for transmit event buffers */
|
||||
struct fdcan_tx_event_element tx_event[3];
|
||||
|
||||
/* Buffer area for transmitted messages. May act either as FIFO or as queue
|
||||
* depending on configuration
|
||||
*/
|
||||
struct fdcan_tx_buffer_element tx_buffer[3];
|
||||
};
|
||||
|
||||
|
||||
/* --- FD-CAN error returns ------------------------------------------------- */
|
||||
|
||||
/** FDCAN error return values
|
||||
*/
|
||||
enum fdcan_error {
|
||||
/** No error. Operation finished successfully */
|
||||
FDCAN_E_OK,
|
||||
|
||||
/** Value provided was out of range */
|
||||
FDCAN_E_OUTOFRANGE,
|
||||
|
||||
/** Timeout waiting for FDCAN block to accept INIT bit change */
|
||||
FDCAN_E_TIMEOUT,
|
||||
|
||||
/** Value provided was invalid (FIFO index, FDCAN block base address, length, etc.) */
|
||||
FDCAN_E_INVALID,
|
||||
|
||||
/** Device is busy: Transmit buffer is full, unable to queue additional message or device
|
||||
* is outside of INIT mode and cannot perform desired operation. */
|
||||
FDCAN_E_BUSY,
|
||||
|
||||
/** Receive buffer is empty, unable to read any new message */
|
||||
FDCAN_E_NOTAVAIL
|
||||
};
|
||||
|
||||
/**@}*/
|
||||
|
||||
/* --- FD-CAN functions ----------------------------------------------------- */
|
||||
|
||||
BEGIN_DECLS
|
||||
|
||||
int fdcan_init(uint32_t canport, uint32_t timeout);
|
||||
|
||||
void fdcan_set_can(uint32_t canport, bool auto_retry_disable, bool rx_fifo_locked,
|
||||
bool tx_queue_mode, bool silent, uint32_t n_sjw, uint32_t n_ts1, uint32_t n_ts2,
|
||||
uint32_t n_br_presc);
|
||||
|
||||
void fdcan_set_fdcan(uint32_t canport, bool brs_enable, bool fd_op_enable,
|
||||
uint32_t f_sjw, uint32_t f_ts1, uint32_t f_ts2, uint32_t f_br_presc);
|
||||
|
||||
void fdcan_set_test(uint32_t canport, bool testing, bool loopback);
|
||||
|
||||
void fdcan_init_filter(uint32_t canport, uint8_t std_filt, uint8_t ext_filt);
|
||||
|
||||
int fdcan_start(uint32_t canport, uint32_t timeout);
|
||||
|
||||
int fdcan_get_init_state(uint32_t canport);
|
||||
|
||||
void fdcan_set_std_filter(uint32_t canport, uint32_t nr,
|
||||
uint8_t id_list_mode, uint32_t id1, uint32_t id2,
|
||||
uint8_t action);
|
||||
|
||||
void fdcan_set_ext_filter(uint32_t canport, uint32_t nr,
|
||||
uint8_t id_list_mode, uint32_t id1, uint32_t id2,
|
||||
uint8_t action);
|
||||
|
||||
void fdcan_enable_irq(uint32_t canport, uint32_t irq);
|
||||
void fdcan_disable_irq(uint32_t canport, uint32_t irq);
|
||||
|
||||
int fdcan_transmit(uint32_t canport, uint32_t id, bool ext, bool rtr,
|
||||
bool fdcan_fmt, bool btr_switch, uint8_t length, const uint8_t *data);
|
||||
|
||||
int fdcan_receive(uint32_t canport, uint8_t fifo, bool release, uint32_t *id,
|
||||
bool *ext, bool *rtr, uint8_t *fmi, uint8_t *length,
|
||||
uint8_t *data, uint16_t *timestamp);
|
||||
|
||||
void fdcan_release_fifo(uint32_t canport, uint8_t fifo);
|
||||
|
||||
bool fdcan_available_tx(uint32_t canport);
|
||||
bool fdcan_available_rx(uint32_t canport, uint8_t fifo);
|
||||
|
||||
END_DECLS
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user