diff --git a/arch/arm/src/samv7/hardware/sam_mcan.h b/arch/arm/src/samv7/hardware/sam_mcan.h index 28ff965c626..c6829f6453a 100644 --- a/arch/arm/src/samv7/hardware/sam_mcan.h +++ b/arch/arm/src/samv7/hardware/sam_mcan.h @@ -38,11 +38,13 @@ /* 0x0000-0x0004 Reserved */ #define SAM_MCAN_CUST_OFFSET 0x0008 /* Customer Register */ -#define SAM_MCAN_FBTP_OFFSET 0x000c /* Fast Bit Timing and Prescaler Register */ +#define SAM_MCAN_REVA_FBTP_OFFSET 0x000c /* Fast Bit Timing and Prescaler Register (rev A) */ +#define SAM_MCAN_DBTP_OFFSET 0x000c /* Data Bit Timing and Prescaler Register (rev B) */ #define SAM_MCAN_TEST_OFFSET 0x0010 /* Test Register */ #define SAM_MCAN_RWD_OFFSET 0x0014 /* RAM Watchdog Register */ #define SAM_MCAN_CCCR_OFFSET 0x0018 /* CC Control Register */ -#define SAM_MCAN_BTP_OFFSET 0x001c /* Bit Timing and Prescaler Register */ +#define SAM_MCAN_REVA_BTP_OFFSET 0x001c /* Bit Timing and Prescaler Register (rev A) */ +#define SAM_MCAN_NBTP_OFFSET 0x001c /* Nominal Bit Timing and Prescaler Register (rev B) */ #define SAM_MCAN_TSCC_OFFSET 0x0020 /* Timestamp Counter Configuration Register */ #define SAM_MCAN_TSCV_OFFSET 0x0024 /* Timestamp Counter Value Register */ #define SAM_MCAN_TOCC_OFFSET 0x0028 /* Timeout Counter Configuration Register */ @@ -88,120 +90,44 @@ #define SAM_MCAN_TXEFA_OFFSET 0x00f8 /* Transmit Event FIFO Acknowledge Register */ /* 0x00fc Reserved */ -/* MCAN register addresses **************************************************/ - -#define SAM_MCAN0_CUST (SAM_MCAN0_BASE+SAM_MCAN_CUST_OFFSET) -#define SAM_MCAN0_FBTP (SAM_MCAN0_BASE+SAM_MCAN_FBTP_OFFSET) -#define SAM_MCAN0_TEST (SAM_MCAN0_BASE+SAM_MCAN_TEST_OFFSET) -#define SAM_MCAN0_RWD (SAM_MCAN0_BASE+SAM_MCAN_RWD_OFFSET) -#define SAM_MCAN0_CCCR (SAM_MCAN0_BASE+SAM_MCAN_CCCR_OFFSET) -#define SAM_MCAN0_BTP (SAM_MCAN0_BASE+SAM_MCAN_BTP_OFFSET) -#define SAM_MCAN0_TSCC (SAM_MCAN0_BASE+SAM_MCAN_TSCC_OFFSET) -#define SAM_MCAN0_TSCV (SAM_MCAN0_BASE+SAM_MCAN_TSCV_OFFSET) -#define SAM_MCAN0_TOCC (SAM_MCAN0_BASE+SAM_MCAN_TOCC_OFFSET) -#define SAM_MCAN0_TOCV (SAM_MCAN0_BASE+SAM_MCAN_TOCV_OFFSET) -#define SAM_MCAN0_ECR (SAM_MCAN0_BASE+SAM_MCAN_ECR_OFFSET) -#define SAM_MCAN0_PSR (SAM_MCAN0_BASE+SAM_MCAN_PSR_OFFSET) -#define SAM_MCAN0_IR (SAM_MCAN0_BASE+SAM_MCAN_IR_OFFSET) -#define SAM_MCAN0_IE (SAM_MCAN0_BASE+SAM_MCAN_IE_OFFSET) -#define SAM_MCAN0_ILS (SAM_MCAN0_BASE+SAM_MCAN_ILS_OFFSET) -#define SAM_MCAN0_ILE (SAM_MCAN0_BASE+SAM_MCAN_ILE_OFFSET) -#define SAM_MCAN0_GFC (SAM_MCAN0_BASE+SAM_MCAN_GFC_OFFSET) -#define SAM_MCAN0_SIDFC (SAM_MCAN0_BASE+SAM_MCAN_SIDFC_OFFSET) -#define SAM_MCAN0_XIDFC (SAM_MCAN0_BASE+SAM_MCAN_XIDFC_OFFSET) -#define SAM_MCAN0_XIDAM (SAM_MCAN0_BASE+SAM_MCAN_XIDAM_OFFSET) -#define SAM_MCAN0_HPMS (SAM_MCAN0_BASE+SAM_MCAN_HPMS_OFFSET) -#define SAM_MCAN0_NDAT1 (SAM_MCAN0_BASE+SAM_MCAN_NDAT1_OFFSET) -#define SAM_MCAN0_NDAT2 (SAM_MCAN0_BASE+SAM_MCAN_NDAT2_OFFSET) -#define SAM_MCAN0_RXF0C (SAM_MCAN0_BASE+SAM_MCAN_RXF0C_OFFSET) -#define SAM_MCAN0_RXF0S (SAM_MCAN0_BASE+SAM_MCAN_RXF0S_OFFSET) -#define SAM_MCAN0_RXF0A (SAM_MCAN0_BASE+SAM_MCAN_RXF0A_OFFSET) -#define SAM_MCAN0_RXBC (SAM_MCAN0_BASE+SAM_MCAN_RXBC_OFFSET) -#define SAM_MCAN0_RXF1C (SAM_MCAN0_BASE+SAM_MCAN_RXF1C_OFFSET) -#define SAM_MCAN0_RXF1S (SAM_MCAN0_BASE+SAM_MCAN_RXF1S_OFFSET) -#define SAM_MCAN0_RXF1A (SAM_MCAN0_BASE+SAM_MCAN_RXF1A_OFFSET) -#define SAM_MCAN0_RXESC (SAM_MCAN0_BASE+SAM_MCAN_RXESC_OFFSET) -#define SAM_MCAN0_TXBC (SAM_MCAN0_BASE+SAM_MCAN_TXBC_OFFSET) -#define SAM_MCAN0_TXFQS (SAM_MCAN0_BASE+SAM_MCAN_TXFQS_OFFSET) -#define SAM_MCAN0_TXESC (SAM_MCAN0_BASE+SAM_MCAN_TXESC_OFFSET) -#define SAM_MCAN0_TXBRP (SAM_MCAN0_BASE+SAM_MCAN_TXBRP_OFFSET) -#define SAM_MCAN0_TXBAR (SAM_MCAN0_BASE+SAM_MCAN_TXBAR_OFFSET) -#define SAM_MCAN0_TXBCR (SAM_MCAN0_BASE+SAM_MCAN_TXBCR_OFFSET) -#define SAM_MCAN0_TXBTO (SAM_MCAN0_BASE+SAM_MCAN_TXBTO_OFFSET) -#define SAM_MCAN0_TXBCF (SAM_MCAN0_BASE+SAM_MCAN_TXBCF_OFFSET) -#define SAM_MCAN0_TXBTIE (SAM_MCAN0_BASE+SAM_MCAN_TXBTIE_OFFSET) -#define SAM_MCAN0_TXBCIE (SAM_MCAN0_BASE+SAM_MCAN_TXBCIE_OFFSET) -#define SAM_MCAN0_TXEFC (SAM_MCAN0_BASE+SAM_MCAN_TXEFC_OFFSET) -#define SAM_MCAN0_TXEFS (SAM_MCAN0_BASE+SAM_MCAN_TXEFS_OFFSET) -#define SAM_MCAN0_TXEFA (SAM_MCAN0_BASE+SAM_MCAN_TXEFA_OFFSET) - -#define SAM_MCAN1_CUST (SAM_MCAN1_BASE+SAM_MCAN_CUST_OFFSET) -#define SAM_MCAN1_FBTP (SAM_MCAN1_BASE+SAM_MCAN_FBTP_OFFSET) -#define SAM_MCAN1_TEST (SAM_MCAN1_BASE+SAM_MCAN_TEST_OFFSET) -#define SAM_MCAN1_RWD (SAM_MCAN1_BASE+SAM_MCAN_RWD_OFFSET) -#define SAM_MCAN1_CCCR (SAM_MCAN1_BASE+SAM_MCAN_CCCR_OFFSET) -#define SAM_MCAN1_BTP (SAM_MCAN1_BASE+SAM_MCAN_BTP_OFFSET) -#define SAM_MCAN1_TSCC (SAM_MCAN1_BASE+SAM_MCAN_TSCC_OFFSET) -#define SAM_MCAN1_TSCV (SAM_MCAN1_BASE+SAM_MCAN_TSCV_OFFSET) -#define SAM_MCAN1_TOCC (SAM_MCAN1_BASE+SAM_MCAN_TOCC_OFFSET) -#define SAM_MCAN1_TOCV (SAM_MCAN1_BASE+SAM_MCAN_TOCV_OFFSET) -#define SAM_MCAN1_ECR (SAM_MCAN1_BASE+SAM_MCAN_ECR_OFFSET) -#define SAM_MCAN1_PSR (SAM_MCAN1_BASE+SAM_MCAN_PSR_OFFSET) -#define SAM_MCAN1_IR (SAM_MCAN1_BASE+SAM_MCAN_IR_OFFSET) -#define SAM_MCAN1_IE (SAM_MCAN1_BASE+SAM_MCAN_IE_OFFSET) -#define SAM_MCAN1_ILS (SAM_MCAN1_BASE+SAM_MCAN_ILS_OFFSET) -#define SAM_MCAN1_ILE (SAM_MCAN1_BASE+SAM_MCAN_ILE_OFFSET) -#define SAM_MCAN1_GFC (SAM_MCAN1_BASE+SAM_MCAN_GFC_OFFSET) -#define SAM_MCAN1_SIDFC (SAM_MCAN1_BASE+SAM_MCAN_SIDFC_OFFSET) -#define SAM_MCAN1_XIDFC (SAM_MCAN1_BASE+SAM_MCAN_XIDFC_OFFSET) -#define SAM_MCAN1_XIDAM (SAM_MCAN1_BASE+SAM_MCAN_XIDAM_OFFSET) -#define SAM_MCAN1_HPMS (SAM_MCAN1_BASE+SAM_MCAN_HPMS_OFFSET) -#define SAM_MCAN1_NDAT1 (SAM_MCAN1_BASE+SAM_MCAN_NDAT1_OFFSET) -#define SAM_MCAN1_NDAT2 (SAM_MCAN1_BASE+SAM_MCAN_NDAT2_OFFSET) -#define SAM_MCAN1_RXF0C (SAM_MCAN1_BASE+SAM_MCAN_RXF0C_OFFSET) -#define SAM_MCAN1_RXF0S (SAM_MCAN1_BASE+SAM_MCAN_RXF0S_OFFSET) -#define SAM_MCAN1_RXF0A (SAM_MCAN1_BASE+SAM_MCAN_RXF0A_OFFSET) -#define SAM_MCAN1_RXBC (SAM_MCAN1_BASE+SAM_MCAN_RXBC_OFFSET) -#define SAM_MCAN1_RXF1C (SAM_MCAN1_BASE+SAM_MCAN_RXF1C_OFFSET) -#define SAM_MCAN1_RXF1S (SAM_MCAN1_BASE+SAM_MCAN_RXF1S_OFFSET) -#define SAM_MCAN1_RXF1A (SAM_MCAN1_BASE+SAM_MCAN_RXF1A_OFFSET) -#define SAM_MCAN1_RXESC (SAM_MCAN1_BASE+SAM_MCAN_RXESC_OFFSET) -#define SAM_MCAN1_TXBC (SAM_MCAN1_BASE+SAM_MCAN_TXBC_OFFSET) -#define SAM_MCAN1_TXFQS (SAM_MCAN1_BASE+SAM_MCAN_TXFQS_OFFSET) -#define SAM_MCAN1_TXESC (SAM_MCAN1_BASE+SAM_MCAN_TXESC_OFFSET) -#define SAM_MCAN1_TXBRP (SAM_MCAN1_BASE+SAM_MCAN_TXBRP_OFFSET) -#define SAM_MCAN1_TXBAR (SAM_MCAN1_BASE+SAM_MCAN_TXBAR_OFFSET) -#define SAM_MCAN1_TXBCR (SAM_MCAN1_BASE+SAM_MCAN_TXBCR_OFFSET) -#define SAM_MCAN1_TXBTO (SAM_MCAN1_BASE+SAM_MCAN_TXBTO_OFFSET) -#define SAM_MCAN1_TXBCF (SAM_MCAN1_BASE+SAM_MCAN_TXBCF_OFFSET) -#define SAM_MCAN1_TXBTIE (SAM_MCAN1_BASE+SAM_MCAN_TXBTIE_OFFSET) -#define SAM_MCAN1_TXBCIE (SAM_MCAN1_BASE+SAM_MCAN_TXBCIE_OFFSET) -#define SAM_MCAN1_TXEFC (SAM_MCAN1_BASE+SAM_MCAN_TXEFC_OFFSET) -#define SAM_MCAN1_TXEFS (SAM_MCAN1_BASE+SAM_MCAN_TXEFS_OFFSET) -#define SAM_MCAN1_TXEFA (SAM_MCAN1_BASE+SAM_MCAN_TXEFA_OFFSET) - /* MCAN register bit definitions ********************************************/ /* Customer Register (32-bit value) */ -/* Fast Bit Timing and Prescaler Register */ +/* Fast Bit Timing and Prescaler Register (rev A) */ -#define MCAN_FBTP_FSJW_SHIFT (0) /* Bits 0-1: Fast (Re) Synchronization Jump Width */ -#define MCAN_FBTP_FSJW_MASK (3 << MCAN_FBTP_FSJW_SHIFT) -# define MCAN_FBTP_FSJW(n) ((uint32_t)(n) << MCAN_FBTP_FSJW_SHIFT) -#define MCAN_FBTP_FTSEG2_SHIFT (4) /* Bits 4-6: Fast Time Segment After Sample Point */ -#define MCAN_FBTP_FTSEG2_MASK (7 << MCAN_FBTP_FTSEG2_SHIFT) -# define MCAN_FBTP_FTSEG2(n) ((uint32_t)(n) << MCAN_FBTP_FTSEG2_SHIFT) -#define MCAN_FBTP_FTSEG1_SHIFT (8) /* Bits 8-11: Fast Time Segment Before Sample Point */ -#define MCAN_FBTP_FTSEG1_MASK (15 << MCAN_FBTP_FTSEG1_SHIFT) -# define MCAN_FBTP_FTSEG1(n) ((uint32_t)(n) << MCAN_FBTP_FTSEG1_SHIFT) -#define MCAN_FBTP_FBRP_SHIFT (16) /* Bits 16-20: Fast Baud Rate Prescaler */ -#define MCAN_FBTP_FBRP_MASK (31 << MCAN_FBTP_FBRP_SHIFT) -# define MCAN_FBTP_FBRP(n) ((uint32_t)(n) << MCAN_FBTP_FBRP_SHIFT) -#define MCAN_FBTP_TDC (1 << 23) /* Bit: 23: Transceiver Delay Compensation */ -#define MCAN_FBTP_TDCO_SHIFT (24) /* Bits 24-28: Transceiver Delay Compensation Offset */ -#define MCAN_FBTP_TDCO_MASK (31 << MCAN_FBTP_TDC_SHIFT) -# define MCAN_FBTP_TDCO(n) ((uint32_t)(n) << MCAN_FBTP_TDC_SHIFT) +#define MCAN_REVA_FBTP_FSJW_SHIFT (0) /* Bits 0-1: Fast (Re) Synchronization Jump Width */ +#define MCAN_REVA_FBTP_FSJW_MASK (0x3 << MCAN_REVA_FBTP_FSJW_SHIFT) +# define MCAN_REVA_FBTP_FSJW(n) ((uint32_t)(n) << MCAN_REVA_FBTP_FSJW_SHIFT) +#define MCAN_REVA_FBTP_FTSEG2_SHIFT (4) /* Bits 4-6: Fast Time Segment After Sample Point */ +#define MCAN_REVA_FBTP_FTSEG2_MASK (0x7 << MCAN_REVA_FBTP_FTSEG2_SHIFT) +# define MCAN_REVA_FBTP_FTSEG2(n) ((uint32_t)(n) << MCAN_REVA_FBTP_FTSEG2_SHIFT) +#define MCAN_REVA_FBTP_FTSEG1_SHIFT (8) /* Bits 8-11: Fast Time Segment Before Sample Point */ +#define MCAN_REVA_FBTP_FTSEG1_MASK (0xf << MCAN_REVA_FBTP_FTSEG1_SHIFT) +# define MCAN_REVA_FBTP_FTSEG1(n) ((uint32_t)(n) << MCAN_REVA_FBTP_FTSEG1_SHIFT) +#define MCAN_REVA_FBTP_FBRP_SHIFT (16) /* Bits 16-20: Fast Baud Rate Prescaler */ +#define MCAN_REVA_FBTP_FBRP_MASK (0x1f << MCAN_REVA_FBTP_FBRP_SHIFT) +# define MCAN_REVA_FBTP_FBRP(n) ((uint32_t)(n) << MCAN_REVA_FBTP_FBRP_SHIFT) +#define MCAN_REVA_FBTP_TDC (1 << 23) /* Bit: 23: Transceiver Delay Compensation */ +#define MCAN_REVA_FBTP_TDCO_SHIFT (24) /* Bits 24-28: Transceiver Delay Compensation Offset */ +#define MCAN_REVA_FBTP_TDCO_MASK (0x1f << MCAN_REVA_FBTP_TDC_SHIFT) +# define MCAN_REVA_FBTP_TDCO(n) ((uint32_t)(n) << MCAN_REVA_FBTP_TDC_SHIFT) + +/* Data Bit Timing and Prescaler Register (rev B) */ + +#define MCAN_DBTP_DSJW_SHIFT (0) /* Bits 0-2: Data (Re) Synchronization Jump Width */ +#define MCAN_DBTP_DSJW_MASK (0x7 << MCAN_DBTP_DSJW_SHIFT) +# define MCAN_DBTP_DSJW(n) ((uint32_t)(n) << MCAN_DBTP_DSJW_SHIFT) +#define MCAN_DBTP_DTSEG2_SHIFT (4) /* Bits 4-7: Data Time Segment After Sample Point */ +#define MCAN_DBTP_DTSEG2_MASK (0xf << MCAN_DBTP_DTSEG2_SHIFT) +# define MCAN_DBTP_DTSEG2(n) ((uint32_t)(n) << MCAN_DBTP_DTSEG2_SHIFT) +#define MCAN_DBTP_DTSEG1_SHIFT (8) /* Bits 8-11: Data Time Segment Before Sample Point */ +#define MCAN_DBTP_DTSEG1_MASK (0x1f << MCAN_DBTP_DTSEG1_SHIFT) +# define MCAN_DBTP_DTSEG1(n) ((uint32_t)(n) << MCAN_DBTP_DTSEG1_SHIFT) +#define MCAN_DBTP_DBRP_SHIFT (16) /* Bits 16-20: Data Baud Rate Prescaler */ +#define MCAN_DBTP_DBRP_MASK (0x1f << MCAN_DBTP_DBRP_SHIFT) +# define MCAN_DBTP_DBRP(n) ((uint32_t)(n) << MCAN_DBTP_DBRP_SHIFT) +#define MCAN_DBTP_TDC (1 << 23) /* Bit: 23: Transceiver Delay Compensation */ /* Test Register */ @@ -214,9 +140,6 @@ # define MCAN_TEST_TX_RECESSIVE (3 << MCAN_TEST_TX_SHIFT) /* Recessive (1) at CANTX. */ #define MCAN_TEST_RX (1 << 7) /* Bit 7: Receive Pin */ -#define MCAN_TEST_TDCV_SHIFT (8) /* Bits 8-13: Transceiver Delay Compensation Value */ -#define MCAN_TEST_TDCV_MASK (0x3f << MCAN_TEST_TDCV_SHIFT) -# define MCAN_TEST_TDCV(n) ((uint32_t)(n) << MCAN_TEST_TDCV_SHIFT) /* RAM Watchdog Register */ @@ -237,37 +160,56 @@ #define MCAN_CCCR_MON (1 << 5) /* Bit 5: Bus Monitoring Mode */ #define MCAN_CCCR_DAR (1 << 6) /* Bit 6: Disable Automatic Retransmission */ #define MCAN_CCCR_TEST (1 << 7) /* Bit 7: Test Mode Enable */ -#define MCAN_CCCR_CME_SHIFT (8) /* Bits 8-9: CAN Mode Enable */ +#define MCAN_CCCR_CME_SHIFT (8) /* Bits 8-9: CAN Mode Enable (rev A) */ #define MCAN_CCCR_CME_MASK (3 << MCAN_CCCR_CME_SHIFT) # define MCAN_CCCR_CME_ISO11898_1 (0 << MCAN_CCCR_CME_SHIFT) /* CAN operation according to ISO11898-1 enabled */ # define MCAN_CCCR_CME_FD (1 << MCAN_CCCR_CME_SHIFT) /* CAN FD operation enabled */ # define MCAN_CCCR_CME_FD_BSW (2 << MCAN_CCCR_CME_SHIFT) /* CAN FD operation with bit rate switching enabled */ -#define MCAN_CCCR_CMR_SHIFT (10) /* Bits 10-11: CAN Mode Request */ +#define MCAN_CCCR_FDOE (1 << 8) /* Bit 8: CAN FD Operation Enable (rev B) */ +#define MCAN_CCCR_BRSE (1 << 9) /* Bit 9: Bit Rate Switching Enable (rev B) */ +#define MCAN_CCCR_CMR_SHIFT (10) /* Bits 10-11: CAN Mode Request (rev A)*/ #define MCAN_CCCR_CMR_MASK (3 << MCAN_CCCR_CMR_SHIFT) # define MCAN_CCCR_CMR_NOCHG (0 << MCAN_CCCR_CMR_SHIFT) /* No mode change */ # define MCAN_CCCR_CMR_FD (1 << MCAN_CCCR_CMR_SHIFT) /* Request CAN FD operation */ # define MCAN_CCCR_CMR_FD_BSW (2 << MCAN_CCCR_CMR_SHIFT) /* Request CAN FD operation with bit rate switching */ # define MCAN_CCCR_CMR_ISO11898_1 (3 << MCAN_CCCR_CMR_SHIFT) /* Request CAN operation according ISO11898-1 */ -#define MCAN_CCCR_FDO (1 << 12) /* Bit 12: CAN FD Operation */ +#define MCAN_CCCR_FDO (1 << 12) /* Bit 12: CAN FD Operation (rev A) */ +#define MCAN_CCCR_PXHD (1 << 12) /* Bit 12: Protocol Exception Event Handling (rev B) */ #define MCAN_CCCR_FDBS (1 << 13) /* Bit 13: CAN FD Bit Rate Switching */ +#define MCAN_CCCR_EFBI (1 << 13) /* Bit 13: Edge Filtering during Bus Integration */ #define MCAN_CCCR_TXP (1 << 14) /* Bit 14: Transmit Pause */ +#define MCAN_CCCR_NISO (1 << 15) /* Bit 15: Non-ISO Operation (Bosch FD)*/ -/* Bit Timing and Prescaler Register */ +/* Bit Timing and Prescaler Register (rev A) */ -#define MCAN_BTP_SJW_SHIFT (0) /* Bits 0-3: (Re) Synchronization Jump Width */ -#define MCAN_BTP_SJW_MASK (15 << MCAN_BTP_SJW_SHIFT) -# define MCAN_BTP_SJW(n) ((uint32_t)(n) << MCAN_BTP_SJW_SHIFT) -#define MCAN_BTP_TSEG2_SHIFT (4) /* Bits 4-7: Time Segment After Sample Point */ -#define MCAN_BTP_TSEG2_MASK (15 << MCAN_BTP_TSEG2_SHIFT) -# define MCAN_BTP_TSEG2(n) ((uint32_t)(n) << MCAN_BTP_TSEG2_SHIFT) -#define MCAN_BTP_TSEG1_SHIFT (8) /* Bits 8-13: Time Segment Before Sample Point */ -#define MCAN_BTP_TSEG1_MASK (0x3f << MCAN_BTP_TSEG1_SHIFT) -# define MCAN_BTP_TSEG1(n) ((uint32_t)(n) << MCAN_BTP_TSEG1_SHIFT) -#define MCAN_BTP_BRP_SHIFT (16) /* Bits 16-25: Baud Rate Prescaler */ -#define MCAN_BTP_BRP_MASK (0x3ff << MCAN_BTP_BRP_SHIFT) -# define MCAN_BTP_BRP(n) ((uint32_t)(n) << MCAN_BTP_BRP_SHIFT) +#define MCAN_REVA_BTP_SJW_SHIFT (0) /* Bits 0-3: (Re) Synchronization Jump Width */ +#define MCAN_REVA_BTP_SJW_MASK (0xf << MCAN_REVA_BTP_SJW_SHIFT) +# define MCAN_REVA_BTP_SJW(n) ((uint32_t)(n) << MCAN_REVA_BTP_SJW_SHIFT) +#define MCAN_REVA_BTP_TSEG2_SHIFT (4) /* Bits 4-7: Time Segment After Sample Point */ +#define MCAN_REVA_BTP_TSEG2_MASK (0xf << MCAN_REVA_BTP_TSEG2_SHIFT) +# define MCAN_REVA_BTP_TSEG2(n) ((uint32_t)(n) << MCAN_REVA_BTP_TSEG2_SHIFT) +#define MCAN_REVA_BTP_TSEG1_SHIFT (8) /* Bits 8-13: Time Segment Before Sample Point */ +#define MCAN_REVA_BTP_TSEG1_MASK (0x3f << MCAN_REVA_BTP_TSEG1_SHIFT) +# define MCAN_REVA_BTP_TSEG1(n) ((uint32_t)(n) << MCAN_REVA_BTP_TSEG1_SHIFT) +#define MCAN_REVA_BTP_BRP_SHIFT (16) /* Bits 16-25: Baud Rate Prescaler */ +#define MCAN_REVA_BTP_BRP_MASK (0x3ff << MCAN_REVA_BTP_BRP_SHIFT) +# define MCAN_REVA_BTP_BRP(n) ((uint32_t)(n) << MCAN_REVA_BTP_BRP_SHIFT) + +/* Nominal Bit Timing and Prescaler Register (rev B) */ +#define MCAN_NBTP_NTSEG2_SHIFT (0) /* Bits 0-6: Nominal Time Segment After Sample Point */ +#define MCAN_NBTP_NTSEG2_MASK (0x7f << MCAN_NBTP_NTSEG2_SHIFT) +# define MCAN_NBTP_NTSEG2(n) ((uint32_t)(n) << MCAN_NBTP_NTSEG2_SHIFT) +#define MCAN_NBTP_NTSEG1_SHIFT (8) /* Bits 8-15: Nominal Time Segment Before Sample Point */ +#define MCAN_NBTP_NTSEG1_MASK (0xff << MCAN_NBTP_NTSEG1_SHIFT) +# define MCAN_NBTP_NTSEG1(n) ((uint32_t)(n) << MCAN_NBTP_NTSEG1_SHIFT) +#define MCAN_NBTP_NBRP_SHIFT (16) /* Bits 16-24: Nominal Bit Rate Prescaler */ +#define MCAN_NBTP_NBRP_MASK (0x1ff << MCAN_NBTP_NBRP_SHIFT) +# define MCAN_NBTP_NBRP(n) ((uint32_t)(n) << MCAN_NBTP_NBRP_SHIFT) +#define MCAN_NBTP_NSJW_SHIFT (25) /* Bits 25-31: Nominal (Re) Synchronization Jump Width */ +#define MCAN_NBTP_NSJW_MASK (0x7f << MCAN_NBTP_NSJW_SHIFT) +# define MCAN_NBTP_NSJW(n) ((uint32_t)(n) << MCAN_NBTP_NSJW_SHIFT) /* Timestamp Counter Configuration Register */ @@ -330,7 +272,7 @@ #define MCAN_PSR_EC_NO_CHANGE (7) /* No CAN bus event was detected since last read */ #define MCAN_PSR_LEC_SHIFT (0) /* Bits 0-2: Last Error Code */ -#define MCAN_PSR_LEC_MASK (7 << MCAN_PSR_LEC_SHIFT) +#define MCAN_PSR_LEC_MASK (0x7 << MCAN_PSR_LEC_SHIFT) # define MCAN_PSR_LEC(n) ((uint32_t)(n) << MCAN_PSR_LEC_SHIFT) /* See error codes above */ #define MCAN_PSR_ACT_SHIFT (3) /* Bits 3-4: Activity */ @@ -343,16 +285,25 @@ #define MCAN_PSR_EP (1 << 5) /* Bit 5: Error Passive */ #define MCAN_PSR_EW (1 << 6) /* Bit 6: Warning Status */ #define MCAN_PSR_BO (1 << 7) /* Bit 7: Bus_Off Status */ -#define MCAN_PSR_FLEC_SHIFT (8) /* Bits 8-10: Fast Last Error Code */ -#define MCAN_PSR_FLEC_MASK (7 << MCAN_PSR_FLEC_SHIFT) +#define MCAN_PSR_FLEC_SHIFT (8) /* Bits 8-10: Fast Last Error Code (rev A) */ +#define MCAN_PSR_FLEC_MASK (0x7 << MCAN_PSR_FLEC_SHIFT) # define MCAN_PSR_FLEC(n) ((uint32_t)(n) << MCAN_PSR_FLEC_SHIFT) /* See error codes above */ +#define MCAN_PSR_DLEC_SHIFT (8) /* Bits 8-10: Data Last Error Code (rev B) */ +#define MCAN_PSR_DLEC_MASK (0x7 << MCAN_PSR_DLEC_SHIFT) +# define MCAN_PSR_DLEC(n) ((uint32_t)(n) << MCAN_PSR_DLEC_SHIFT) /* See error codes above */ + #define MCAN_PSR_RESI (1 << 11) /* Bit 11: ESI Flag of Last Received CAN FD Message */ #define MCAN_PSR_RBRS (1 << 12) /* Bit 12: BRS Flag of Last Received CAN FD Message */ -#define MCAN_PSR_REDL (1 << 13) /* Bit 13: Received a CAN FD Message */ +#define MCAN_PSR_REDL (1 << 13) /* Bit 13: Received a CAN FD Message (rev A) */ +#define MCAN_PSR_RFDF (1 << 13) /* Bit 13: Received a CAN FD Message (rev B) */ +#define MCAN_PSR_PXE (1 << 14) /* Bit 14: Protocol Exception Event (rev B) */ +#define MCAN_PSR_TDCV_SHIFT (16) /* Bits 16-22: Transmitter Delay Compensation Value (rev B) */ +#define MCAN_PSR_TDCV_MASK (0x7f << MCAN_PSR_TDCV_SHIFT) +# define MCAN_PSR_TDCV(n) ((uint32_t)(n) << MCAN_PSR_TDCV_SHIFT) /* Common bit definitions for Interrupt Register, Interrupt Enable Register, - * Interrupt Line Select Register + * Interrupt, Line Select Register */ #define MCAN_INT_RF0N (1 << 0) /* Bit 0: Receive FIFO 0 New Message */ @@ -380,13 +331,17 @@ #define MCAN_INT_EW (1 << 24) /* Bit 24: Warning Status */ #define MCAN_INT_BO (1 << 25) /* Bit 25: Bus_Off Status */ #define MCAN_INT_WDI (1 << 26) /* Bit 26: Watchdog Interrupt */ -#define MCAN_INT_CRCE (1 << 27) /* Bit 27: Receive CRC Error */ -#define MCAN_INT_BE (1 << 28) /* Bit 28: Bit Error */ -#define MCAN_INT_ACKE (1 << 29) /* Bit 29: Acknowledge Error */ -#define MCAN_INT_FOE (1 << 30) /* Bit 30: Format Error */ -#define MCAN_INT_STE (1 << 31) /* Bit 31: Stuff Error */ +#define MCAN_INT_CRCE (1 << 27) /* Bit 27: Receive CRC Error (rev A) */ +#define MCAN_INT_PEA (1 << 27) /* Bit 27: Protocol Error in Arbitration Phase (rev B) */ +#define MCAN_INT_BE (1 << 28) /* Bit 28: Bit Error (rev A) */ +#define MCAN_INT_PED (1 << 28) /* Bit 28: Protocol Error in Data Phase (rev B) */ +#define MCAN_INT_ACKE (1 << 29) /* Bit 29: Acknowledge Error (rev A) */ +#define MCAN_INT_ARA (1 << 29) /* Bit 29: Access to Reserved Address (rev B) */ +#define MCAN_INT_FOE (1 << 30) /* Bit 30: Format Error (rev A) */ +#define MCAN_INT_STE (1 << 31) /* Bit 31: Stuff Error (rev A) */ -#define MCAN_INT_ALL (0xffcfffff) +#define MCAN_REVA_INT_ALL (0xffcfffff) +#define MCAN_REVB_INT_ALL (0x3fcfffff) /* Interrupt Line Enable Register */ @@ -632,7 +587,7 @@ /* Transmit Buffer Cancellation Finished Interrupt Enable Register */ -#define MCAN_TXBTIE(n) (1 << (n)) /* Cancellation finished interrupt enable for transmit buffer n, n=0-31 */ +#define MCAN_TXBCIE(n) (1 << (n)) /* Cancellation finished interrupt enable for transmit buffer n, n=0-31 */ /* Transmit Event FIFO Configuration Register */ @@ -695,8 +650,10 @@ #define BUFFER_R1_DLC_SHIFT (16) /* Bits 16-19: Date length code */ #define BUFFER_R1_DLC_MASK (15 << BUFFER_R1_DLC_SHIFT) # define BUFFER_R1_DLC(n) ((uint32_t)(n) << BUFFER_R1_DLC_SHIFT) -#define BUFFER_R1_BRS (1 << 20) /* Bit 20: Bit Rate Switch */ -#define BUFFER_R1_EDL (1 << 21) /* Bit 21: Extended Data Length */ +#define BUFFER_R1_BRS_SHIFT (20) +#define BUFFER_R1_EDL_SHIFT (21) +#define BUFFER_R1_BRS (1 << BUFFER_R1_BRS_SHIFT) /* Bit 20: Bit Rate Switch */ +#define BUFFER_R1_EDL (1 << BUFFER_R1_EDL_SHIFT) /* Bit 21: Extended Data Length */ /* RX buffer/RX FIFOs */ @@ -807,8 +764,4 @@ * Public Data ****************************************************************************/ -/**************************************************************************** - * Public Functions Prototypes - ****************************************************************************/ - #endif /* __ARCH_ARM_SRC_SAMV7_HARDWARE_SAM_MCAN_H */ diff --git a/arch/arm/src/samv7/sam_mcan.c b/arch/arm/src/samv7/sam_mcan.c index ead4a511c81..3d23705fa8c 100644 --- a/arch/arm/src/samv7/sam_mcan.c +++ b/arch/arm/src/samv7/sam_mcan.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -49,6 +48,7 @@ #include "arm_arch.h" #include "hardware/sam_matrix.h" +#include "hardware/sam_chipid.h" #include "hardware/sam_pinmap.h" #include "sam_periphclks.h" #include "sam_gpio.h" @@ -138,30 +138,30 @@ # define MCAN0_SJW (CONFIG_SAMV7_MCAN0_FSJW - 1) # if MCAN0_TSEG1 > 63 -# error Invalid MCAN0 TSEG1 +# error Invalid MCAN0 NTSEG1 # endif # if MCAN0_TSEG2 > 15 -# error Invalid MCAN0 TSEG2 +# error Invalid MCAN0 NTSEG2 # endif # if MCAN0_SJW > 15 -# error Invalid MCAN0 SJW +# error Invalid MCAN0 NSJW # endif -# define MCAN0_FTSEG1 (CONFIG_SAMV7_MCAN0_FPROPSEG + CONFIG_SAMV7_MCAN0_FPHASESEG1) -# define MCAN0_FTSEG2 (CONFIG_SAMV7_MCAN0_FPHASESEG2) -# define MCAN0_FBRP ((uint32_t)(((float) SAMV7_MCANCLK_FREQUENCY / \ - ((float)(MCAN0_FTSEG1 + MCAN0_FTSEG2 + 3) * \ +# define MCAN0_DTSEG1 (CONFIG_SAMV7_MCAN0_FPROPSEG + CONFIG_SAMV7_MCAN0_FPHASESEG1) +# define MCAN0_DTSEG2 (CONFIG_SAMV7_MCAN0_FPHASESEG2) +# define MCAN0_DBRP ((uint32_t)(((float) SAMV7_MCANCLK_FREQUENCY / \ + ((float)(MCAN0_DTSEG1 + MCAN0_DTSEG2 + 3) * \ (float)CONFIG_SAMV7_MCAN0_FBITRATE)) - 1)) -# define MCAN0_FSJW (CONFIG_SAMV7_MCAN0_FFSJW - 1) +# define MCAN0_DSJW (CONFIG_SAMV7_MCAN0_FFSJW - 1) -# if MCAN0_FTSEG1 > 15 -# error Invalid MCAN0 FTSEG1 +# if MCAN0_DTSEG1 > 15 +# error Invalid MCAN0 DTSEG1 # endif -# if MCAN0_FTSEG2 > 7 -# error Invalid MCAN0 FTSEG2 +# if MCAN0_DTSEG2 > 7 +# error Invalid MCAN0 DTSEG2 # endif -# if MCAN0_FSJW > 3 -# error Invalid MCAN0 FSJW +# if MCAN0_DSJW > 3 +# error Invalid MCAN0 DSJW # endif /* MCAN0 RX FIFO0 element size */ @@ -422,31 +422,31 @@ (float)CONFIG_SAMV7_MCAN1_BITRATE)) - 1)) # define MCAN1_SJW (CONFIG_SAMV7_MCAN1_FSJW - 1) -# if MCAN1_TSEG1 > 63 -# error Invalid MCAN1 TSEG1 +# if MCAN1_NTSEG1 > 63 +# error Invalid MCAN1 NTSEG1 # endif -# if MCAN1_TSEG2 > 15 -# error Invalid MCAN1 TSEG2 +# if MCAN1_NTSEG2 > 15 +# error Invalid MCAN1 NTSEG2 # endif -# if MCAN1_SJW > 15 -# error Invalid MCAN1 SJW +# if MCAN1_NSJW > 15 +# error Invalid MCAN1 NSJW # endif -# define MCAN1_FTSEG1 (CONFIG_SAMV7_MCAN1_FPROPSEG + CONFIG_SAMV7_MCAN1_FPHASESEG1) -# define MCAN1_FTSEG2 (CONFIG_SAMV7_MCAN1_FPHASESEG2) -# define MCAN1_FBRP ((uint32_t)(((float) SAMV7_MCANCLK_FREQUENCY / \ - ((float)(MCAN1_FTSEG1 + MCAN1_FTSEG2 + 3) * \ +# define MCAN1_DTSEG1 (CONFIG_SAMV7_MCAN1_FPROPSEG + CONFIG_SAMV7_MCAN1_FPHASESEG1) +# define MCAN1_DTSEG2 (CONFIG_SAMV7_MCAN1_FPHASESEG2) +# define MCAN1_DBRP ((uint32_t)(((float) SAMV7_MCANCLK_FREQUENCY / \ + ((float)(MCAN1_DTSEG1 + MCAN1_DTSEG2 + 3) * \ (float)CONFIG_SAMV7_MCAN1_FBITRATE)) - 1)) -# define MCAN1_FSJW (CONFIG_SAMV7_MCAN1_FFSJW - 1) +# define MCAN1_DSJW (CONFIG_SAMV7_MCAN1_FFSJW - 1) -#if MCAN1_FTSEG1 > 15 -# error Invalid MCAN1 FTSEG1 +#if MCAN1_DTSEG1 > 15 +# error Invalid MCAN1 DTSEG1 #endif -#if MCAN1_FTSEG2 > 7 -# error Invalid MCAN1 FTSEG2 +#if MCAN1_DTSEG2 > 7 +# error Invalid MCAN1 DTSEG2 #endif -#if MCAN1_FSJW > 3 -# error Invalid MCAN1 FSJW +#if MCAN1_DSJW > 3 +# error Invalid MCAN1 DSJW #endif /* MCAN1 RX FIFO0 element size */ @@ -726,22 +726,30 @@ * * MCAN_INT_DRX - Message stored to Dedicated Receive Buffer * - * Mode-independent RX-related interrupts + * Mode-independent RX-related interrupts for revision A * * MCAN_INT_CRCE - Receive CRC Error * MCAN_INT_FOE - Format Error * MCAN_INT_STE - Stuff Error + * + * Mode-independent RX-related interrupts for revision B + * + * MCAN_INT_PEA - Protocol Error in Arbitration Phase + * MCAN_INT_PED - Protocol Error in Data Phase */ -#define MCAN_RXCOMMON_INTS (MCAN_INT_CRCE | MCAN_INT_FOE | MCAN_INT_STE) -#define MCAN_RXFIFO0_INTS (MCAN_INT_RF0N | MCAN_INT_RF0W | MCAN_INT_RF0L) -#define MCAN_RXFIFO1_INTS (MCAN_INT_RF1N | MCAN_INT_RF1W | MCAN_INT_RF1L) -#define MCAN_RXFIFO_INTS (MCAN_RXFIFO0_INTS | MCAN_RXFIFO1_INTS | \ - MCAN_INT_HPM | MCAN_RXCOMMON_INTS) -#define MCAN_RXDEDBUF_INTS (MCAN_INT_DRX | MCAN_RXCOMMON_INTS) +#define MCAN_RXCOMMON_INTS_REVA (MCAN_INT_CRCE | MCAN_INT_FOE | MCAN_INT_STE) +#define MCAN_RXCOMMON_INTS (MCAN_INT_PEA | MCAN_INT_PED) +#define MCAN_RXFIFO0_INTS (MCAN_INT_RF0N | MCAN_INT_RF0W | MCAN_INT_RF0L) +#define MCAN_RXFIFO1_INTS (MCAN_INT_RF1N | MCAN_INT_RF1W | MCAN_INT_RF1L) +#define MCAN_RXFIFO_INTS (MCAN_RXFIFO0_INTS | MCAN_RXFIFO1_INTS | \ + MCAN_INT_HPM | MCAN_RXCOMMON_INTS) +#define MCAN_RXDEDBUF_INTS (MCAN_INT_DRX | MCAN_RXCOMMON_INTS) -#define MCAN_RXERR_INTS (MCAN_INT_RF0L | MCAN_INT_RF1L | MCAN_INT_CRCE | \ - MCAN_INT_FOE | MCAN_INT_STE) +#define MCAN_RXERR_INTS_REVA (MCAN_INT_RF0L | MCAN_INT_RF1L | MCAN_INT_CRCE | \ + MCAN_INT_FOE | MCAN_INT_STE) +#define MCAN_RXERR_INTS (MCAN_INT_RF0L | MCAN_INT_RF1L | MCAN_INT_PEA | \ + MCAN_INT_PED) /* TX FIFOQ mode interrupts * @@ -758,18 +766,20 @@ * * MCAN_INT_TC - Transmission Completed * MCAN_INT_TCF - Transmission Cancellation Finished - * MCAN_INT_BE - Bit Error - * MCAN_INT_ACKE - Acknowledge Error + * MCAN_INT_BE - Bit Error (rev A) + * MCAN_INT_ACKE - Acknowledge Error (rev A) + * MCAN_INT_PEA - Protocol Error in Arbitration Phase (rev B) + * MCAN_INT_PED - Protocol Error in Data Phase (rev B) */ -#define MCAN_TXCOMMON_INTS (MCAN_INT_TC | MCAN_INT_TCF | MCAN_INT_BE | \ - MCAN_INT_ACKE) +#define MCAN_TXCOMMON_INTS (MCAN_INT_TC | MCAN_INT_TCF | MCAN_INT_PEA | \ + MCAN_INT_PED) #define MCAN_TXFIFOQ_INTS (MCAN_INT_TFE | MCAN_TXCOMMON_INTS) #define MCAN_TXEVFIFO_INTS (MCAN_INT_TEFN | MCAN_INT_TEFW | MCAN_INT_TEFF | \ MCAN_INT_TEFL) #define MCAN_TXDEDBUF_INTS MCAN_TXCOMMON_INTS -#define MCAN_TXERR_INTS (MCAN_INT_TEFL | MCAN_INT_BE | MCAN_INT_ACKE) +#define MCAN_TXERR_INTS (MCAN_INT_TEFL | MCAN_INT_PEA | MCAN_INT_PED) /* Common-, TX- and RX-Error-Mask */ @@ -835,6 +845,9 @@ struct sam_config_s uint32_t baud; /* Configured baud */ uint32_t btp; /* Bit timing/prescaler register setting */ uint32_t fbtp; /* Fast bit timing/prescaler register setting */ + uint32_t nbtp; /* Nominal Bit timing/prescaler register setting */ + uint32_t dbtp; /* Data bit timing/prescaler register setting */ + uint8_t rev; /* Chip revision (0: A, 1: B) */ uint8_t port; /* MCAN port number (1 or 2) */ uint8_t pid; /* MCAN peripheral ID */ uint8_t irq0; /* MCAN peripheral IRQ number for interrupt line 0 */ @@ -884,6 +897,7 @@ struct sam_mcan_s uint32_t fbtp; /* Current fast bit timing */ uint32_t rxints; /* Configured RX interrupts */ uint32_t txints; /* Configured TX interrupts */ + uint8_t rev; /* Chip revision (0: A, 1: B) */ #ifdef CONFIG_CAN_EXTID uint32_t extfilters[2]; /* Extended filter bit allocator. 2*32=64 */ @@ -991,27 +1005,35 @@ static const struct can_ops_s g_mcanops = static uint32_t g_mcan0_msgram[MCAN0_MSGRAM_WORDS] #ifdef CONFIG_ARMV7M_DCACHE - aligned_data(MCAN_ALIGN); + __attribute__((aligned(MCAN_ALIGN))); #else ; #endif /* Constant configuration */ -static const struct sam_config_s g_mcan0const = +static struct sam_config_s g_mcan0const = { .rxpinset = GPIO_MCAN0_RX, .txpinset = GPIO_MCAN0_TX, .base = SAM_MCAN0_BASE, .baud = CONFIG_SAMV7_MCAN0_BITRATE, - .btp = MCAN_BTP_BRP(MCAN0_BRP) | - MCAN_BTP_TSEG1(MCAN0_TSEG1) | - MCAN_BTP_TSEG2(MCAN0_TSEG2) | - MCAN_BTP_SJW(MCAN0_SJW), - .fbtp = MCAN_FBTP_FBRP(MCAN0_FBRP) | - MCAN_FBTP_FTSEG1(MCAN0_FTSEG1) | - MCAN_FBTP_FTSEG2(MCAN0_FTSEG2) | - MCAN_FBTP_FSJW(MCAN0_FSJW), + .btp = MCAN_REVA_BTP_BRP(MCAN0_BRP) | + MCAN_REVA_BTP_TSEG1(MCAN0_TSEG1) | + MCAN_REVA_BTP_TSEG2(MCAN0_TSEG2) | + MCAN_REVA_BTP_SJW(MCAN0_SJW), + .fbtp = MCAN_REVA_FBTP_FBRP(MCAN0_DBRP) | + MCAN_REVA_FBTP_FTSEG1(MCAN0_DTSEG1) | + MCAN_REVA_FBTP_FTSEG2(MCAN0_DTSEG2) | + MCAN_REVA_FBTP_FSJW(MCAN0_DSJW), + .nbtp = MCAN_NBTP_NBRP(MCAN0_BRP) | + MCAN_NBTP_NTSEG1(MCAN0_TSEG1) | + MCAN_NBTP_NTSEG2(MCAN0_TSEG2) | + MCAN_NBTP_NSJW(MCAN0_SJW), + .dbtp = MCAN_DBTP_DBRP(MCAN0_DBRP) | + MCAN_DBTP_DTSEG1(MCAN0_DTSEG1) | + MCAN_DBTP_DTSEG2(MCAN0_DTSEG2) | + MCAN_DBTP_DSJW(MCAN0_DSJW), .port = 0, .pid = SAM_PID_MCAN00, .irq0 = SAM_IRQ_MCAN00, @@ -1071,27 +1093,35 @@ static struct can_dev_s g_mcan0dev; static uint32_t g_mcan1_msgram[MCAN1_MSGRAM_WORDS] #ifdef CONFIG_ARMV7M_DCACHE - aligned_data(MCAN_ALIGN); + __attribute__((aligned(MCAN_ALIGN))); #else ; #endif /* MCAN1 constant configuration */ -static const struct sam_config_s g_mcan1const = +static struct sam_config_s g_mcan1const = { .rxpinset = GPIO_MCAN1_RX, .txpinset = GPIO_MCAN1_TX, .base = SAM_MCAN1_BASE, .baud = CONFIG_SAMV7_MCAN1_BITRATE, - .btp = MCAN_BTP_BRP(MCAN1_BRP) | - MCAN_BTP_TSEG1(MCAN1_TSEG1) | - MCAN_BTP_TSEG2(MCAN1_TSEG2) | - MCAN_BTP_SJW(MCAN1_SJW), - .fbtp = MCAN_FBTP_FBRP(MCAN1_FBRP) | - MCAN_FBTP_FTSEG1(MCAN1_FTSEG1) | - MCAN_FBTP_FTSEG2(MCAN1_FTSEG2) | - MCAN_FBTP_FSJW(MCAN1_FSJW), + .btp = MCAN_REVA_BTP_BRP(MCAN1_BRP) | + MCAN_REVA_BTP_TSEG1(MCAN1_TSEG1) | + MCAN_REVA_BTP_TSEG2(MCAN1_TSEG2) | + MCAN_REVA_BTP_SJW(MCAN1_SJW), + .fbtp = MCAN_REVA_FBTP_FBRP(MCAN1_DBRP) | + MCAN_REVA_FBTP_FTSEG1(MCAN1_DTSEG1) | + MCAN_REVA_FBTP_FTSEG2(MCAN1_DTSEG2) | + MCAN_REVA_FBTP_FSJW(MCAN1_DSJW), + .nbtp = MCAN_NBTP_NBRP(MCAN1_BRP) | + MCAN_NBTP_NTSEG1(MCAN1_TSEG1) | + MCAN_NBTP_NTSEG2(MCAN1_TSEG2) | + MCAN_NBTP_NSJW(MCAN1_SJW), + .dbtp = MCAN_DBTP_DBRP(MCAN1_DBRP) | + MCAN_DBTP_DTSEG1(MCAN1_DTSEG1) | + MCAN_DBTP_DTSEG2(MCAN1_DTSEG2) | + MCAN_DBTP_DSJW(MCAN1_DSJW), .port = 1, .pid = SAM_PID_MCAN10, .irq0 = SAM_IRQ_MCAN10, @@ -1289,17 +1319,17 @@ static void mcan_dumpregs(FAR struct sam_mcan_s *priv, FAR const char *msg) FAR const struct sam_config_s *config = priv->config; caninfo("MCAN%d Registers: %s\n", config->port, msg); - caninfo(" Base: %08x\n", config->base); + caninfo(" Base: %08x\n", config->base); - caninfo(" CUST: %08x FBTP: %08x TEST: %08x RWD: %08x\n", + caninfo(" CUST: %08x DBTP: %08x TEST: %08x RWD: %08x\n", getreg32(config->base + SAM_MCAN_CUST_OFFSET), - getreg32(config->base + SAM_MCAN_FBTP_OFFSET), + getreg32(config->base + SAM_MCAN_DBTP_OFFSET), getreg32(config->base + SAM_MCAN_TEST_OFFSET), getreg32(config->base + SAM_MCAN_RWD_OFFSET)); - caninfo(" CCCR: %08x BTP: %08x TSCC: %08x TSCV: %08x\n", + caninfo(" CCCR: %08x NBTP: %08x TSCC: %08x TSCV: %08x\n", getreg32(config->base + SAM_MCAN_CCCR_OFFSET), - getreg32(config->base + SAM_MCAN_BTP_OFFSET), + getreg32(config->base + SAM_MCAN_NBTP_OFFSET), getreg32(config->base + SAM_MCAN_TSCC_OFFSET), getreg32(config->base + SAM_MCAN_TSCV_OFFSET)); @@ -2672,18 +2702,37 @@ static int mcan_ioctl(FAR struct can_dev_s *dev, int cmd, unsigned long arg) DEBUGASSERT(bt != NULL); - regval = mcan_getreg(priv, SAM_MCAN_BTP_OFFSET); - bt->bt_sjw = ((regval & MCAN_BTP_SJW_MASK) >> - MCAN_BTP_SJW_SHIFT) + 1; - bt->bt_tseg1 = ((regval & MCAN_BTP_TSEG1_MASK) >> - MCAN_BTP_TSEG1_SHIFT) + 1; - bt->bt_tseg2 = ((regval & MCAN_BTP_TSEG2_MASK) >> - MCAN_BTP_TSEG2_SHIFT) + 1; + regval = mcan_getreg(priv, SAM_MCAN_NBTP_OFFSET); + + if (priv->rev == 0) + { + /* Revision A */ + + bt->bt_sjw = ((regval & MCAN_REVA_BTP_SJW_MASK) >> + MCAN_REVA_BTP_SJW_SHIFT) + 1; + bt->bt_tseg1 = ((regval & MCAN_REVA_BTP_TSEG1_MASK) >> + MCAN_REVA_BTP_TSEG1_SHIFT) + 1; + bt->bt_tseg2 = ((regval & MCAN_REVA_BTP_TSEG2_MASK) >> + MCAN_REVA_BTP_TSEG2_SHIFT) + 1; + brp = ((regval & MCAN_REVA_BTP_BRP_MASK) >> + MCAN_REVA_BTP_BRP_SHIFT) + 1; + } + else + { + /* Revision B */ + + bt->bt_sjw = ((regval & MCAN_NBTP_NSJW_MASK) >> + MCAN_NBTP_NSJW_SHIFT) + 1; + bt->bt_tseg1 = ((regval & MCAN_NBTP_NTSEG1_MASK) >> + MCAN_NBTP_NTSEG1_SHIFT) + 1; + bt->bt_tseg2 = ((regval & MCAN_NBTP_NTSEG2_MASK) >> + MCAN_NBTP_NTSEG2_SHIFT) + 1; + brp = ((regval & MCAN_NBTP_NBRP_MASK) >> + MCAN_NBTP_NBRP_SHIFT) + 1; + } - brp = ((regval & MCAN_BTP_BRP_MASK) >> - MCAN_BTP_BRP_SHIFT) + 1; bt->bt_baud = SAMV7_MCANCLK_FREQUENCY / brp / - (bt->bt_tseg1 + bt->bt_tseg2 + 1); + (bt->bt_tseg1 + bt->bt_tseg2 + 1); ret = OK; } break; @@ -2736,8 +2785,18 @@ static int mcan_ioctl(FAR struct can_dev_s *dev, int cmd, unsigned long arg) /* Save the value of the new bit timing register */ flags = enter_critical_section(); - priv->btp = MCAN_BTP_BRP(brp) | MCAN_BTP_TSEG1(tseg1) | - MCAN_BTP_TSEG2(tseg2) | MCAN_BTP_SJW(sjw); + if (priv->rev == 0) + { + priv->btp = MCAN_REVA_BTP_BRP(brp) | + MCAN_REVA_BTP_TSEG1(tseg1) | + MCAN_REVA_BTP_TSEG2(tseg2) | + MCAN_REVA_BTP_SJW(sjw); + } + else + { + priv->btp = MCAN_NBTP_NBRP(brp) | MCAN_NBTP_NTSEG1(tseg1) | + MCAN_NBTP_NTSEG2(tseg2) | MCAN_NBTP_NSJW(sjw); + } /* We need to reset to instantiate the new timing. Save * current state information so that recover to this @@ -2988,7 +3047,7 @@ static int mcan_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg) /* Format the TX FIFOQ entry * - * Format word T1: + * Format word T0: * Transfer message ID (ID) - Value from message structure * Remote Transmission Request (RTR) - Value from message structure * Extended Identifier (XTD) - Depends on configuration. @@ -3024,6 +3083,19 @@ static int mcan_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg) */ txbuffer[1] = BUFFER_R1_DLC(msg->cm_hdr.ch_dlc); + +#ifdef CONFIG_CAN_FD + if (msg->cm_hdr.ch_edl) + { + txbuffer[1] |= BUFFER_R1_EDL; + } + + if (msg->cm_hdr.ch_brs) + { + txbuffer[1] |= BUFFER_R1_BRS; + } +#endif + reginfo("T1: %08x\n", txbuffer[1]); /* Followed by the amount of data corresponding to the DLC (T2..) */ @@ -3261,6 +3333,8 @@ static void mcan_error(FAR struct can_dev_s *dev, uint32_t status) uint16_t errbits; uint8_t data[CAN_ERROR_DLC]; int ret; + uint32_t lec; + uint32_t dlec; /* Encode error bits */ @@ -3339,43 +3413,54 @@ static void mcan_error(FAR struct can_dev_s *dev, uint32_t status) data[1] |= CAN_ERROR1_UNSPEC; } - if ((status & MCAN_INT_CRCE) != 0) + if ((status & (MCAN_INT_PEA | MCAN_INT_CRCE)) != 0) { - /* Receive CRC Error */ + lec = psr & MCAN_PSR_LEC_MASK; + dlec = (psr & MCAN_PSR_DLEC_MASK) >> MCAN_PSR_DLEC_SHIFT; - errbits |= CAN_ERROR_PROTOCOL; - data[3] |= (CAN_ERROR3_CRCSEQ | CAN_ERROR3_CRCDEL); - } + if ((lec == MCAN_PSR_EC_CRC_ERROR) || (dlec == MCAN_PSR_EC_CRC_ERROR)) + { + /* Receive CRC Error */ - if ((status & MCAN_INT_BE) != 0) - { - /* Bit Error */ + errbits |= CAN_ERROR_PROTOCOL; + data[3] |= (CAN_ERROR3_CRCSEQ | CAN_ERROR3_CRCDEL); + } - errbits |= CAN_ERROR_PROTOCOL; - data[2] |= CAN_ERROR2_BIT; - } + if ((lec == MCAN_PSR_EC_BIT0_ERROR) || \ + (lec == MCAN_PSR_EC_BIT1_ERROR) || \ + (dlec == MCAN_PSR_EC_BIT0_ERROR) || \ + (dlec == MCAN_PSR_EC_BIT1_ERROR)) + { + /* Bit Error */ - if ((status & MCAN_INT_ACKE) != 0) - { - /* Acknowledge Error */ + errbits |= CAN_ERROR_PROTOCOL; + data[2] |= CAN_ERROR2_BIT; + } - errbits |= CAN_ERROR_NOACK; - } + if ((lec == MCAN_PSR_EC_ACK_ERROR) || (dlec == MCAN_PSR_EC_ACK_ERROR)) + { + /* Acknowledge Error */ - if ((status & MCAN_INT_FOE) != 0) - { - /* Format Error */ + errbits |= CAN_ERROR_NOACK; + } - errbits |= CAN_ERROR_PROTOCOL; - data[2] |= CAN_ERROR2_FORM; - } + if ((lec == MCAN_PSR_EC_FORM_ERROR) || \ + (dlec == MCAN_PSR_EC_FORM_ERROR)) + { + /* Format Error */ - if ((status & MCAN_INT_STE) != 0) - { - /* Stuff Error */ + errbits |= CAN_ERROR_PROTOCOL; + data[2] |= CAN_ERROR2_FORM; + } - errbits |= CAN_ERROR_PROTOCOL; - data[2] |= CAN_ERROR2_STUFF; + if ((lec == MCAN_PSR_EC_STUFF_ERROR) || \ + (dlec == MCAN_PSR_EC_STUFF_ERROR)) + { + /* Stuff Error */ + + errbits |= CAN_ERROR_PROTOCOL; + data[2] |= CAN_ERROR2_STUFF; + } } if (errbits != 0) @@ -3490,6 +3575,11 @@ static void mcan_receive(FAR struct can_dev_s *dev, FAR uint32_t *rxbuffer, hdr.ch_dlc = (regval & BUFFER_R1_DLC_MASK) >> BUFFER_R1_DLC_SHIFT; +#ifdef CONFIG_CAN_FD + hdr.ch_edl = (regval >> BUFFER_R1_EDL_SHIFT) & 1u; + hdr.ch_brs = (regval >> BUFFER_R1_BRS_SHIFT) & 1u; +#endif + /* And provide the CAN message to the upper half logic */ ret = can_receive(dev, &hdr, (FAR uint8_t *)rxbuffer); @@ -3525,6 +3615,7 @@ static int mcan_interrupt(int irq, void *context, FAR void *arg) unsigned int nelem; unsigned int ndx; bool handled; + uint32_t psr; DEBUGASSERT(dev != NULL); priv = dev->cd_priv; @@ -3551,8 +3642,9 @@ static int mcan_interrupt(int irq, void *context, FAR void *arg) if ((pending & MCAN_CMNERR_INTS) != 0) { - canerr("ERROR: Common %08"PRIx32"\n", - pending & MCAN_CMNERR_INTS); + psr = mcan_getreg(priv, SAM_MCAN_PSR_OFFSET); + canerr("ERROR: Common %08"PRIx32", PSR %08"PRIx32"\n", + pending & MCAN_CMNERR_INTS, psr); /* Clear the error indications */ @@ -3563,7 +3655,9 @@ static int mcan_interrupt(int irq, void *context, FAR void *arg) if ((pending & MCAN_TXERR_INTS) != 0) { - canerr("ERROR: TX %08"PRIx32"\n", pending & MCAN_TXERR_INTS); + psr = mcan_getreg(priv, SAM_MCAN_PSR_OFFSET); + canerr("ERROR: TX %08"PRIx32", PSR %08"PRIx32"\n", + pending & MCAN_TXERR_INTS, psr); /* An Acknowledge-Error will occur if for example the device * is not connected to the bus. @@ -3571,11 +3665,19 @@ static int mcan_interrupt(int irq, void *context, FAR void *arg) * The CAN-Standard states that the Chip has to retry the * message forever, which will produce an ACKE every time. * To prevent this Interrupt-Flooding and the high CPU-Load - * we disable the ACKE here as long we didn't transfer at + * we disable the all errors here as long we didn't transfer at * least one message successfully (see MCAN_INT_TC below). */ - ie &= ~MCAN_INT_ACKE; + if (priv->rev == 0) + { + ie &= ~MCAN_INT_ACKE; + } + else + { + ie &= ~(MCAN_INT_PEA | MCAN_INT_PED); + } + mcan_putreg(priv, SAM_MCAN_IE_OFFSET, ie); /* Clear the error indications */ @@ -3597,7 +3699,9 @@ static int mcan_interrupt(int irq, void *context, FAR void *arg) if ((pending & MCAN_RXERR_INTS) != 0) { - canerr("ERROR: RX %08"PRIx32"\n", pending & MCAN_RXERR_INTS); + psr = mcan_getreg(priv, SAM_MCAN_PSR_OFFSET); + canerr("ERROR: RX %08"PRIx32", PSR %08"PRIx32"\n", + pending & MCAN_RXERR_INTS, psr); /* To prevent Interrupt-Flooding the current active * RX error interrupts are disabled. After successfully @@ -3634,11 +3738,17 @@ static int mcan_interrupt(int irq, void *context, FAR void *arg) * re-enable the error interrupt here again. */ - if ((ie & MCAN_INT_ACKE) == 0) + if ((priv->rev == 0) && ((ie & MCAN_INT_ACKE) == 0)) { ie |= MCAN_INT_ACKE; mcan_putreg(priv, SAM_MCAN_IE_OFFSET, ie); } + else if ((priv->rev == 1) && \ + ((ie & (MCAN_INT_PEA | MCAN_INT_PED)) == 0)) + { + ie |= MCAN_INT_PEA | MCAN_INT_PED; + mcan_putreg(priv, SAM_MCAN_IE_OFFSET, ie); + } /* Clear the pending TX completion interrupt (and all * other TX-related interrupts) @@ -3847,7 +3957,7 @@ static int mcan_hw_initialize(struct sam_mcan_s *priv) FAR uint32_t *msgram; uint32_t regval; uint32_t cntr; - uint32_t cmr; + uint32_t cmr = 0; caninfo("MCAN%d\n", config->port); @@ -3905,12 +4015,27 @@ static int mcan_hw_initialize(struct sam_mcan_s *priv) /* Clear all pending interrupts. */ - mcan_putreg(priv, SAM_MCAN_IR_OFFSET, MCAN_INT_ALL); + if (priv->rev == 0) + { + mcan_putreg(priv, SAM_MCAN_IR_OFFSET, MCAN_REVA_INT_ALL); + } + else + { + mcan_putreg(priv, SAM_MCAN_IR_OFFSET, MCAN_REVB_INT_ALL); + } /* Configure MCAN bit timing */ - mcan_putreg(priv, SAM_MCAN_BTP_OFFSET, priv->btp); - mcan_putreg(priv, SAM_MCAN_FBTP_OFFSET, priv->fbtp); + if (priv->rev == 0) + { + mcan_putreg(priv, SAM_MCAN_REVA_BTP_OFFSET, priv->btp); + mcan_putreg(priv, SAM_MCAN_REVA_FBTP_OFFSET, priv->fbtp); + } + else + { + mcan_putreg(priv, SAM_MCAN_NBTP_OFFSET, priv->btp); + mcan_putreg(priv, SAM_MCAN_DBTP_OFFSET, priv->fbtp); + } /* Configure message RAM starting addresses and sizes. */ @@ -3989,25 +4114,49 @@ static int mcan_hw_initialize(struct sam_mcan_s *priv) */ regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET); - regval &= ~(MCAN_CCCR_CME_MASK | MCAN_CCCR_CMR_MASK); + if (priv->rev == 0) + { + regval &= ~(MCAN_CCCR_CME_MASK | MCAN_CCCR_CMR_MASK); + } + else + { + regval &= ~(MCAN_CCCR_FDOE | MCAN_CCCR_BRSE | MCAN_CCCR_NISO); + } switch (config->mode) { default: case MCAN_ISO11898_1_MODE: - regval |= MCAN_CCCR_CME_ISO11898_1; - cmr = MCAN_CCCR_CMR_ISO11898_1; + if (priv->rev == 0) + { + regval |= MCAN_CCCR_CME_ISO11898_1; + cmr = MCAN_CCCR_CMR_ISO11898_1; + } break; #ifdef CONFIG_CAN_FD case MCAN_FD_MODE: - regval |= MCAN_CCCR_CME_FD; - cmr = MCAN_CCCR_CMR_FD; + if (priv->rev == 0) + { + regval |= MCAN_CCCR_CME_FD; + cmr = MCAN_CCCR_CMR_FD; + } + else + { + regval |= MCAN_CCCR_FDOE; + } break; case MCAN_FD_BSW_MODE: - regval |= MCAN_CCCR_CME_FD_BSW; - cmr = MCAN_CCCR_CMR_FD_BSW; + if (priv->rev == 0) + { + regval |= MCAN_CCCR_CME_FD_BSW; + cmr = MCAN_CCCR_CMR_FD_BSW; + } + else + { + regval |= (MCAN_CCCR_FDOE | MCAN_CCCR_BRSE); + } break; #endif } @@ -4016,10 +4165,13 @@ static int mcan_hw_initialize(struct sam_mcan_s *priv) mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval); - /* Request the mode change */ + if (priv->rev == 0) + { + /* Request the mode change */ - regval |= cmr; - mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval); + regval |= cmr; + mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval); + } #if 0 /* Not necessary in initialization mode */ /* Wait for the mode to take effect */ @@ -4195,12 +4347,34 @@ FAR struct can_dev_s *sam_mcan_initialize(int port) memset(priv, 0, sizeof(struct sam_mcan_s)); priv->config = config; + /* Get the revision of the chip (A or B ) */ + + regval = getreg32(SAM_CHIPID_CIDR); + priv->rev = regval & CHIPID_CIDR_VERSION_MASK; + /* Set the initial bit timing. This might change subsequently * due to IOCTL command processing. */ - priv->btp = config->btp; - priv->fbtp = config->fbtp; + if (priv->rev == 0) + { + /* Revision A */ + + priv->btp = config->btp; + priv->fbtp = config->fbtp; + } + else if (priv->rev == 1) + { + /* Revision B */ + + priv->btp = config->nbtp; + priv->fbtp = config->dbtp; + } + else + { + canerr("ERROR: Incorrect chip revision: %d\n", priv->rev); + return NULL; + } /* Initialize semaphores */