drivers: can: Implement MCP25xxFD driver
Implementation for Microchip MCP2517FD/MCP2518FD SPI based CAN-FD controller. Signed-off-by: Abram Early <abram.early@gmail.com>
This commit is contained in:
parent
d44e96e486
commit
33277f9b48
6 changed files with 1723 additions and 0 deletions
|
@ -10,6 +10,7 @@ zephyr_library_sources_ifdef(CONFIG_CAN_FAKE can_fake.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_CAN_LOOPBACK can_loopback.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CAN_MCAN can_mcan.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CAN_MCP2515 can_mcp2515.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CAN_MCP25XXFD can_mcp25xxfd.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CAN_MCUX_FLEXCAN can_mcux_flexcan.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CAN_SAM can_sam.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CAN_SAM0 can_sam0.c)
|
||||
|
|
|
@ -100,6 +100,7 @@ source "drivers/can/Kconfig.kvaser"
|
|||
source "drivers/can/Kconfig.fake"
|
||||
source "drivers/can/Kconfig.nxp_s32"
|
||||
source "drivers/can/Kconfig.tcan4x5x"
|
||||
source "drivers/can/Kconfig.mcp25xxfd"
|
||||
|
||||
source "drivers/can/transceiver/Kconfig"
|
||||
|
||||
|
|
56
drivers/can/Kconfig.mcp25xxfd
Normal file
56
drivers/can/Kconfig.mcp25xxfd
Normal file
|
@ -0,0 +1,56 @@
|
|||
# MCP25XXFD CAN configuration options
|
||||
|
||||
# Copyright (c) 2020 Abram Early
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
DT_COMPAT_MICROCHIP_MCP25XXFD_CAN := microchip,mcp25xxfd
|
||||
|
||||
config CAN_MCP25XXFD
|
||||
bool "MCP25XXFD CAN Driver"
|
||||
default $(dt_compat_enabled,$(DT_COMPAT_MICROCHIP_MCP25XXFD_CAN))
|
||||
depends on SPI
|
||||
select CAN_AUTO_BUS_OFF_RECOVERY
|
||||
select CAN_HAS_CANFD
|
||||
select CAN_HAS_RX_TIMESTAMP
|
||||
help
|
||||
Enable MCP25XXFD CAN Driver
|
||||
|
||||
if CAN_MCP25XXFD
|
||||
|
||||
config CAN_MCP25XXFD_MAX_TX_QUEUE
|
||||
int "Maximum number of queued messages"
|
||||
default 4
|
||||
range 1 31
|
||||
help
|
||||
Defines the array size of transmit callback pointers and semaphores,
|
||||
as well as the number of TX FIFOs allocated on the MCP25XXFD.
|
||||
|
||||
config CAN_MCP25XXFD_INT_THREAD_STACK_SIZE
|
||||
int "Stack size for interrupt handler"
|
||||
default 768
|
||||
help
|
||||
Size of the stack used for internal thread which is ran for
|
||||
interrupt handling and incoming packets.
|
||||
|
||||
config CAN_MCP25XXFD_INT_THREAD_PRIO
|
||||
int "Priority for interrupt handler"
|
||||
default 2
|
||||
help
|
||||
Priority level of the internal thread which is ran for
|
||||
interrupt handling and incoming packets.
|
||||
|
||||
config CAN_MAX_FILTER
|
||||
int "Maximum number of concurrent active filters"
|
||||
default 5
|
||||
range 1 31
|
||||
help
|
||||
Defines the array size of the callback/msgq pointers.
|
||||
Must be at least the size of concurrent reads.
|
||||
|
||||
config CAN_MCP25XXFD_INIT_PRIORITY
|
||||
int "Init priority"
|
||||
default 80
|
||||
help
|
||||
MCP25XXFD driver initialization priority, must be higher than SPI.
|
||||
|
||||
endif # CAN_MCP25XXFD
|
1088
drivers/can/can_mcp25xxfd.c
Normal file
1088
drivers/can/can_mcp25xxfd.c
Normal file
File diff suppressed because it is too large
Load diff
537
drivers/can/can_mcp25xxfd.h
Normal file
537
drivers/can/can_mcp25xxfd.h
Normal file
|
@ -0,0 +1,537 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Abram Early
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_DRIVERS_CAN_MICROCHIP_MCP25XXFD_H_
|
||||
#define ZEPHYR_DRIVERS_CAN_MICROCHIP_MCP25XXFD_H_
|
||||
|
||||
#include <drivers/can.h>
|
||||
|
||||
#define DEV_CFG(dev) ((const struct mcp25xxfd_config *const)(dev)->config)
|
||||
#define DEV_DATA(dev) ((struct mcp25xxfd_data *const)(dev)->data)
|
||||
|
||||
#define MCP25XXFD_RAM_SIZE 2048
|
||||
#define MCP25XXFD_PAYLOAD_SIZE CLAMP(ROUND_UP(CAN_MAX_DLEN, 4), 8, 64)
|
||||
#if defined(CONFIG_CAN_TX_TIMESTAMP)
|
||||
/* Note: This will be implemented with a future can_send overhaul */
|
||||
#define MCP25XXFD_TEF_SIZE (CONFIG_CAN_MCP25XXFD_MAX_TX_QUEUE * (4 + 8))
|
||||
#else
|
||||
#define MCP25XXFD_TEF_SIZE (CONFIG_CAN_MCP25XXFD_MAX_TX_QUEUE * (0 + 8))
|
||||
#endif
|
||||
#define MCP25XXFD_TXFIFOS_SIZE (CONFIG_CAN_MCP25XXFD_MAX_TX_QUEUE * (8 + MCP25XXFD_PAYLOAD_SIZE))
|
||||
#define MCP25XXFD_RXFIFO_MAX \
|
||||
((MCP25XXFD_RAM_SIZE - (MCP25XXFD_TEF_SIZE + MCP25XXFD_TXFIFOS_SIZE)))
|
||||
#if defined(CONFIG_CAN_RX_TIMESTAMP)
|
||||
#define MCP25XXFD_RXFIFO_ELEMENT_SIZE (4 + 8 + MCP25XXFD_PAYLOAD_SIZE)
|
||||
#else
|
||||
#define MCP25XXFD_RXFIFO_ELEMENT_SIZE (0 + 8 + MCP25XXFD_PAYLOAD_SIZE)
|
||||
#endif
|
||||
#define MCP25XXFD_RXFIFO_LENGTH \
|
||||
MIN(MCP25XXFD_RXFIFO_MAX / MCP25XXFD_RXFIFO_ELEMENT_SIZE, 32)
|
||||
#define MCP25XXFD_RXFIFO_SIZE (MCP25XXFD_RXFIFO_LENGTH * MCP25XXFD_RXFIFO_ELEMENT_SIZE)
|
||||
#define MCP25XXFD_TXFIFOS CONFIG_CAN_MCP25XXFD_MAX_TX_QUEUE
|
||||
#define MCP25XXFD_RXFIFO_IDX CONFIG_CAN_MCP25XXFD_MAX_TX_QUEUE
|
||||
BUILD_ASSERT(MCP25XXFD_RXFIFO_LENGTH >= 1,
|
||||
"Cannot fit RX FIFO into MCP25xxFD RAM");
|
||||
|
||||
struct mcp25xxfd_mailbox {
|
||||
can_tx_callback_t cb;
|
||||
void *cb_arg;
|
||||
struct k_sem tx_sem;
|
||||
};
|
||||
|
||||
struct mcp25xxfd_data {
|
||||
/* SPI Data */
|
||||
const struct device *spi;
|
||||
struct spi_config spi_cfg;
|
||||
#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0)
|
||||
struct spi_cs_control spi_cs_ctrl;
|
||||
#endif /* DT_INST_SPI_DEV_HAS_CS_GPIOS(0) */
|
||||
|
||||
/* Interrupt Data */
|
||||
const struct device *int_gpio;
|
||||
struct gpio_callback int_gpio_cb;
|
||||
struct k_thread int_thread;
|
||||
k_thread_stack_t *int_thread_stack;
|
||||
struct k_sem int_sem;
|
||||
uint8_t int_pin;
|
||||
|
||||
/* General */
|
||||
enum can_state state;
|
||||
can_state_change_isr_t state_change_isr;
|
||||
struct k_mutex mutex;
|
||||
struct k_sem mode_sem;
|
||||
|
||||
/* TX Callback */
|
||||
struct k_sem tx_sem;
|
||||
uint32_t mailbox_usage;
|
||||
struct mcp25xxfd_mailbox mailbox[CONFIG_CAN_MCP25XXFD_MAX_TX_QUEUE];
|
||||
|
||||
/* Filter Data */
|
||||
uint64_t filter_usage;
|
||||
struct zcan_filter filter[CONFIG_CAN_MAX_FILTER];
|
||||
can_rx_callback_t rx_cb[CONFIG_CAN_MAX_FILTER];
|
||||
void *cb_arg[CONFIG_CAN_MAX_FILTER];
|
||||
};
|
||||
|
||||
struct mcp25xxfd_config {
|
||||
/* SPI Config */
|
||||
const char *spi_port;
|
||||
uint32_t spi_freq;
|
||||
uint8_t spi_slave;
|
||||
uint8_t spi_cs_pin;
|
||||
uint8_t spi_cs_flags;
|
||||
const char *spi_cs_port;
|
||||
|
||||
/* Interrupt Config */
|
||||
uint8_t int_pin;
|
||||
const char *int_port;
|
||||
size_t int_thread_stack_size;
|
||||
int int_thread_priority;
|
||||
uint32_t osc_freq;
|
||||
|
||||
/* CAN Timing */
|
||||
uint8_t tq_sjw;
|
||||
uint8_t tq_prop;
|
||||
uint8_t tq_bs1;
|
||||
uint8_t tq_bs2;
|
||||
uint32_t bus_speed;
|
||||
uint16_t sample_point;
|
||||
|
||||
/* IO Config */
|
||||
bool sof_on_clko;
|
||||
uint8_t clko_div;
|
||||
|
||||
#if defined(CONFIG_CAN_FD_MODE)
|
||||
/* CAN-FD Timing */
|
||||
uint8_t tq_sjw_data;
|
||||
uint8_t tq_prop_data;
|
||||
uint8_t tq_bs1_data;
|
||||
uint8_t tq_bs2_data;
|
||||
uint32_t bus_speed_data;
|
||||
uint16_t sample_point_data;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* MCP25XXFD Opcodes */
|
||||
#define MCP25XXFD_OPCODE_RESET 0x00
|
||||
#define MCP25XXFD_OPCODE_WRITE 0x02
|
||||
#define MCP25XXFD_OPCODE_READ 0x03
|
||||
|
||||
/* MCP25XXFD Operation Modes */
|
||||
#define MCP25XXFD_OPMODE_NORMAL_CANFD 0b000
|
||||
#define MCP25XXFD_OPMODE_SLEEP 0b001
|
||||
#define MCP25XXFD_OPMODE_INT_LOOPBACK 0b010
|
||||
#define MCP25XXFD_OPMODE_LISTEN_ONLY 0b011
|
||||
#define MCP25XXFD_OPMODE_CONFIGURATION 0b100
|
||||
#define MCP25XXFD_OPMODE_EXT_LOOPBACK 0b101
|
||||
#define MCP25XXFD_OPMODE_NORMAL_CAN2 0b110
|
||||
#define MCP25XXFD_OPMODE_RESTRICTED 0b110
|
||||
|
||||
#define MCP25XXFD_WFT_T00FILTER 0b00
|
||||
#define MCP25XXFD_WFT_T01FILTER 0b01
|
||||
#define MCP25XXFD_WFT_T10FILTER 0b10
|
||||
#define MCP25XXFD_WFT_T11FILTER 0b11
|
||||
|
||||
#define MCP25XXFD_TDCMOD_AUTO 0b10
|
||||
#define MCP25XXFD_TDCMOD_MANUAL 0b01
|
||||
#define MCP25XXFD_TDCMOD_DISABLED 0b00
|
||||
|
||||
/* MCP25XXFD Registers */
|
||||
|
||||
#define MCP25XXFD_REG_CON 0x000
|
||||
union mcp25xxfd_con {
|
||||
struct {
|
||||
uint32_t DNCNT : 5; /* Device Net Filter Bit Number */
|
||||
uint32_t ISOCRCEN : 1; /* Enable ISO CRC in CAN FD Frames */
|
||||
uint32_t PXEDIS : 1; /* Protocol Exception Event Detection Disabled */
|
||||
uint32_t res0 : 1;
|
||||
uint32_t WAKFIL : 1; /* Enable CAN Bus Line Wake-up Filter */
|
||||
uint32_t WFT : 2; /* Selectable Wake-up Filter Time */
|
||||
uint32_t BUSY : 1; /* CAN Module is Busy */
|
||||
uint32_t BRSDIS : 1; /* Bit Rate Switching Disable */
|
||||
uint32_t res1 : 3;
|
||||
uint32_t RTXAT : 1; /* Restrict Retransmission Attempts */
|
||||
uint32_t ESIGM : 1; /* Transmit ESI in Gateway Mode */
|
||||
uint32_t SERR2LOM : 1; /* Transition to Listen Only Mode on System Error */
|
||||
uint32_t STEF : 1; /* Store in Transmit Event FIFO */
|
||||
uint32_t TXQEN : 1; /* Enable Transmit Queue */
|
||||
uint32_t OPMOD : 3; /* Operation Mode Status */
|
||||
uint32_t REQMOD : 3; /* Request Operation Mode */
|
||||
uint32_t ABAT : 1; /* Abort All Pending Transmissions */
|
||||
uint32_t TXBWS : 4; /* Transmit Bandwidth Sharing */
|
||||
};
|
||||
uint32_t word;
|
||||
uint8_t byte[4];
|
||||
};
|
||||
|
||||
#define MCP25XXFD_REG_NBTCFG 0x004
|
||||
union mcp25xxfd_nbtcfg {
|
||||
struct {
|
||||
uint32_t SJW : 7; /* Synchronization Jump Width */
|
||||
uint32_t res0 : 1;
|
||||
uint32_t TSEG2 : 7; /* Time Segment 2 (Phase Segment 2) */
|
||||
uint32_t res1 : 1;
|
||||
uint32_t TSEG1 : 8; /* Time Segment 1 (Propagation Segment + Phase Segment 1) */
|
||||
uint32_t BRP : 8; /* Baud Rate Prescaler */
|
||||
};
|
||||
uint32_t word;
|
||||
uint8_t byte[4];
|
||||
};
|
||||
|
||||
#define MCP25XXFD_REG_DBTCFG 0x008
|
||||
union mcp25xxfd_dbtcfg {
|
||||
struct {
|
||||
uint32_t SJW : 4; /* Synchronization Jump Width */
|
||||
uint32_t res0 : 4;
|
||||
uint32_t TSEG2 : 4; /* Time Segment 2 (Phase Segment 2) */
|
||||
uint32_t res1 : 4;
|
||||
uint32_t TSEG1 : 5; /* Time Segment 1 (Propagation Segment + Phase Segment 1) */
|
||||
uint32_t res2 : 3;
|
||||
uint32_t BRP : 8; /* Baud Rate Prescaler */
|
||||
};
|
||||
uint32_t word;
|
||||
uint8_t byte[4];
|
||||
};
|
||||
|
||||
#define MCP25XXFD_REG_TDC 0x00C
|
||||
union mcp25xxfd_tdc {
|
||||
struct {
|
||||
uint32_t TDCV : 6; /* Transmitter Delay Compensation Value */
|
||||
uint32_t res0 : 2;
|
||||
uint32_t TDCO : 7; /* Transmitter Delay Compensation Offset */
|
||||
uint32_t res1 : 1;
|
||||
uint32_t TDCMOD : 2; /* Transmitter Delay Compensation Mode */
|
||||
uint32_t res2 : 6;
|
||||
uint32_t SID11EN : 1; /* Enable 12-Bit SID in CAN FD Base Format Messages */
|
||||
uint32_t EDGFLTEN : 1; /* Enable Edge Filtering during Bus Integration state */
|
||||
};
|
||||
uint32_t word;
|
||||
uint8_t byte[4];
|
||||
};
|
||||
|
||||
#define MCP25XXFD_REG_TSCON 0x014
|
||||
union mcp25xxfd_tscon {
|
||||
struct {
|
||||
uint32_t TBCPRE : 10; /* Time Base Counter Prescaler */
|
||||
uint32_t res0 : 6;
|
||||
uint32_t TBCEN : 1; /* Time Base Counter Enable */
|
||||
uint32_t TSEOF : 1; /* 0: Beginning (See TSREF) / 1: Frame is considered valid */
|
||||
uint32_t TSRES : 1; /* Timestamp Sample Point Bit (0: SP of SOF / 1: SP of bit following FDF on FD frames) */
|
||||
uint32_t res1 : 13;
|
||||
};
|
||||
uint32_t word;
|
||||
uint8_t bytes[4];
|
||||
};
|
||||
|
||||
#define MCP25XXFD_REG_VEC 0x018
|
||||
union mcp25xxfd_vec {
|
||||
struct {
|
||||
uint32_t ICODE : 7; /* Interrupt Flag Code */
|
||||
uint32_t res0 : 1;
|
||||
uint32_t FILHIT : 5; /* Filter Hit Number */
|
||||
uint32_t res1 : 3;
|
||||
uint32_t TXCODE : 7; /* Transmit Interrupt Flag Code */
|
||||
uint32_t res2 : 1;
|
||||
uint32_t RXCODE : 7; /* Receive Interrupt Flag Code */
|
||||
uint32_t res3 : 1;
|
||||
};
|
||||
uint32_t word;
|
||||
uint8_t byte[4];
|
||||
};
|
||||
|
||||
#define MCP25XXFD_REG_INT 0x01C
|
||||
union mcp25xxfd_int {
|
||||
struct {
|
||||
uint32_t TXIF : 1; /* Transmit FIFO Interrupt Flag */
|
||||
uint32_t RXIF : 1; /* Receive FIFO Interrupt Flag */
|
||||
uint32_t TCBIF : 1; /* Time Base Counter Interrupt Flag */
|
||||
uint32_t MODIF : 1; /* Mode Change Interrupt Flag */
|
||||
uint32_t TEFIF : 1; /* Transmit Event FIFO Interrupt Flag */
|
||||
uint32_t res0 : 3;
|
||||
uint32_t ECCIF : 1; /* ECC Error Interrupt Flag */
|
||||
uint32_t SPICRCIF : 1; /* SPI CRC Error Interrupt Flag */
|
||||
uint32_t TXATIF : 1; /* Transmit Attempt Interrupt Flag */
|
||||
uint32_t RXOVIF : 1; /* Receive FIFO Overflow Interrupt Flag */
|
||||
uint32_t SERRIF : 1; /* System Error Interrupt Flag */
|
||||
uint32_t CERRIF : 1; /* CAN Bus Error Interrupt Flag */
|
||||
uint32_t WAKIF : 1; /* Bus Wake Up Interrupt Flag */
|
||||
uint32_t IVMIF : 1; /* Invalid Message Interrupt Flag */
|
||||
uint32_t TXIE : 1; /* Transmit FIFO Interrupt Enable */
|
||||
uint32_t RXIE : 1; /* Receive FIFO Interrupt Enable */
|
||||
uint32_t TBCIE : 1; /* Time Base Counter Interrupt Enable */
|
||||
uint32_t MODIE : 1; /* Mode Change Interrupt Enable */
|
||||
uint32_t TEFIE : 1; /* Transmit Event FIFO Interrupt Enable */
|
||||
uint32_t res1 : 3;
|
||||
uint32_t ECCIE : 1; /* ECC Error Interrupt Enable */
|
||||
uint32_t SPICRCIE : 1; /* SPI CRC Error Interrupt Enable */
|
||||
uint32_t TXATIE : 1; /* Transmit Attempt Interrupt Enable */
|
||||
uint32_t RXOVIE : 1; /* Receive FIFO Overflow Interrupt Enable */
|
||||
uint32_t SERRIE : 1; /* System Error Interrupt Enable */
|
||||
uint32_t CERRIE : 1; /* CAN Bus Error Interrupt Enable */
|
||||
uint32_t WAKIE : 1; /* Bus Wake Up Interrupt Enable */
|
||||
uint32_t IVMIE : 1; /* Invalid Message Interrupt Enable */
|
||||
};
|
||||
uint32_t word;
|
||||
uint8_t byte[4];
|
||||
};
|
||||
|
||||
#define MCP25XXFD_REG_INTREGS MCP25XXFD_REG_VEC
|
||||
union mcp25xxfd_intregs {
|
||||
struct {
|
||||
union mcp25xxfd_vec vec; /* Interrupt Vector Codes */
|
||||
union mcp25xxfd_int ints; /* Interrupt Enables/Flags */
|
||||
uint32_t rxif; /* FIFO RXIF Interrupt Flags */
|
||||
uint32_t txif; /* FIFO TXIF Interrupt Flags */
|
||||
uint32_t rxovif; /* FIFO RXOVIF Interrupt Flags */
|
||||
uint32_t txatif; /* FIFO TXATIF Interrupt Flags */
|
||||
};
|
||||
uint32_t words[6];
|
||||
};
|
||||
|
||||
#define MCP25XXFD_REG_TREC 0x034
|
||||
|
||||
union mcp25xxfd_trec {
|
||||
struct {
|
||||
uint32_t REC : 8; /* Receive Error Counter */
|
||||
uint32_t TEC : 8; /* Transmit Error Counter */
|
||||
uint32_t EWARN : 1; /* Transmitter or Receiver is in Error Warning State */
|
||||
uint32_t RXWARN : 1; /* Receiver is in Error Warning State */
|
||||
uint32_t TXWARN : 1; /* Transmitter is in Error Warning State */
|
||||
uint32_t RXBP : 1; /* Receiver in Error Passive State */
|
||||
uint32_t TXBP : 1; /* Transmitter in Error Passive State bit */
|
||||
uint32_t TXBO : 1; /* Transmitter in Bus Off State */
|
||||
uint32_t res0 : 10;
|
||||
};
|
||||
uint32_t word;
|
||||
uint8_t bytes[4];
|
||||
};
|
||||
|
||||
#define MCP25XXFD_REG_BDIAG1 0x3C
|
||||
union mcp25xxfd_bdiag1 {
|
||||
struct {
|
||||
uint32_t EFMSGCNT : 16;
|
||||
uint32_t NBIT0ERR : 1;
|
||||
uint32_t NBIT1ERR : 1;
|
||||
uint32_t NACKERR : 1;
|
||||
uint32_t NFORMERR : 1;
|
||||
uint32_t NSTUFERR : 1;
|
||||
uint32_t NCRCERR : 1;
|
||||
uint32_t res0 : 1;
|
||||
uint32_t TXBOERR : 1;
|
||||
uint32_t DBIT0ERR : 1;
|
||||
uint32_t DBIT1ERR : 1;
|
||||
uint32_t res1 : 1;
|
||||
uint32_t DFORMERR : 1;
|
||||
uint32_t DSTUFERR : 1;
|
||||
uint32_t DCRCERR : 1;
|
||||
uint32_t ESI : 1;
|
||||
uint32_t DLCMM : 1;
|
||||
};
|
||||
uint32_t word;
|
||||
uint8_t byte[4];
|
||||
};
|
||||
|
||||
/* The FIFOCON, FIFOSTA, and FIFOUA registers are almost identical to their TEF and TXQ counterparts. */
|
||||
|
||||
#define MCP25XXFD_REG_TEFCON 0x040
|
||||
#define MCP25XXFD_REG_TXQCON 0x050
|
||||
#define MCP25XXFD_REG_FIFOCON(m) (MCP25XXFD_REG_TXQCON + (m) * 0xC)
|
||||
|
||||
union mcp25xxfd_fifocon {
|
||||
struct {
|
||||
uint32_t FNEIE : 1; /* FIFO Not Full/Not Empty Interrupt Enable */
|
||||
uint32_t FHIE : 1; /* FIFO Half Empty/Full Interrupt Enable */
|
||||
uint32_t FFIE : 1; /* FIFO Empty/Full Interrupt Enable */
|
||||
uint32_t OVIE : 1; /* FIFO Overflow Interrupt Enable */
|
||||
uint32_t TXATIE : 1; /* FIFO TX Attempts Exhuasted Interrupt Enable */
|
||||
uint32_t TSEN : 1; /* FIFO Timestamp Enable */
|
||||
uint32_t RTREN : 1; /* FIFO Auto RTR Enable */
|
||||
uint32_t TXEN : 1; /* FIFO Transmit Enable */
|
||||
uint32_t UINC : 1; /* FIFO Increment Head */
|
||||
uint32_t TXREQ : 1; /* FIFO Message Send Request */
|
||||
uint32_t FRESET : 1; /* FIFO Reset */
|
||||
uint32_t res0 : 5;
|
||||
uint32_t TXPRI : 5; /* Transmit Priority */
|
||||
uint32_t TXAT : 2; /* Retransmission Attempts */
|
||||
uint32_t res1 : 1;
|
||||
uint32_t FSIZE : 5; /* FIFO Size */
|
||||
uint32_t PLSIZE : 3; /* Payload Size */
|
||||
};
|
||||
uint32_t word;
|
||||
uint8_t bytes[4];
|
||||
};
|
||||
|
||||
#define MCP25XXFD_REG_TEFSTA 0x044
|
||||
#define MCP25XXFD_REG_TXQSTA 0x054
|
||||
#define MCP25XXFD_REG_FIFOSTA(m) (MCP25XXFD_REG_TXQSTA + (m) * 0xC)
|
||||
|
||||
union mcp25xxfd_fifosta {
|
||||
struct {
|
||||
uint32_t FNEIF : 1; /* FIFO Not Full/Not Empty Interrupt Flag */
|
||||
uint32_t FHIF : 1; /* FIFO Half Empty/Full Interrupt Flag */
|
||||
uint32_t FFIF : 1; /* FIFO Empty/Full Interrupt Flag */
|
||||
uint32_t OVIF : 1; /* FIFO Overflow Interrupt Flag */
|
||||
uint32_t TXATIF : 1; /* FIFO TX Attempts Exhuasted Interrupt Flag */
|
||||
uint32_t TXERR : 1; /* Transmission Error Status */
|
||||
uint32_t TXLARB : 1; /* Message Lost Arbitration Status */
|
||||
uint32_t TXABT : 1; /* Message Aborted Status */
|
||||
uint32_t FIFOCI : 5; /* FIFO Message Index */
|
||||
};
|
||||
uint32_t word;
|
||||
uint8_t bytes[4];
|
||||
};
|
||||
|
||||
#define MCP25XXFD_REG_TEFUA 0x048
|
||||
#define MCP25XXFD_REG_TXQUA 0x058
|
||||
#define MCP25XXFD_REG_FIFOUA(m) (MCP25XXFD_REG_TXQUA + (m) * 0xC)
|
||||
|
||||
union mcp25xxfd_fifo {
|
||||
struct {
|
||||
union mcp25xxfd_fifocon con; /* FIFO Control Register */
|
||||
union mcp25xxfd_fifosta sta; /* FIFO Status Register */
|
||||
uint32_t ua; /* FIFO User Address Register */
|
||||
};
|
||||
uint32_t words[3];
|
||||
};
|
||||
|
||||
#define MCP21518FD_REG_FLTCON(m) (0x1D0 + m)
|
||||
union mcp25xxfd_fltcon {
|
||||
struct {
|
||||
uint32_t FLTBP : 5;
|
||||
uint32_t res : 2;
|
||||
uint32_t FLTEN : 1;
|
||||
};
|
||||
uint32_t word;
|
||||
uint8_t byte[4];
|
||||
};
|
||||
|
||||
#define MCP25XXFD_REG_FLTOBJ(m) (0x1F0 + ((m) * 8))
|
||||
union mcp25xxfd_fltobj {
|
||||
struct {
|
||||
uint32_t SID : 11;
|
||||
uint32_t EID : 18;
|
||||
uint32_t SID11 : 1;
|
||||
uint32_t EXIDE : 1;
|
||||
uint32_t res0 : 1;
|
||||
};
|
||||
uint32_t word;
|
||||
uint8_t byte[4];
|
||||
};
|
||||
|
||||
#define MCP25XXFD_REG_MASK(m) (0x1F4 + ((m) * 8))
|
||||
union mcp25xxfd_mask {
|
||||
struct {
|
||||
uint32_t MSID : 11;
|
||||
uint32_t MEID : 18;
|
||||
uint32_t MSID11 : 1;
|
||||
uint32_t MIDE : 1;
|
||||
uint32_t res0 : 1;
|
||||
};
|
||||
uint32_t word;
|
||||
uint8_t byte[4];
|
||||
};
|
||||
|
||||
#define MCP25XXFD_REG_OSC 0xE00
|
||||
union mcp25xxfd_osc {
|
||||
struct {
|
||||
uint32_t PLLEN : 1; /* PLL Enable (0: Clock from XTAL, 1: Clock from 10x PLL) */
|
||||
uint32_t res0 : 1;
|
||||
uint32_t OSCDIS : 1; /* Clock (Oscillator) Disable */
|
||||
uint32_t LPMEN : 1; /* Low Power Mode (LPM) Enable */
|
||||
uint32_t SCLKDIV : 1; /* System Clock Divisor (0: 1/1, 1: 1/2) */
|
||||
uint32_t CLKODIV : 2; /* Clock Output Divisor (0: 1/1, 1: 1/2, 2: 1/4, 3: 1/10) */
|
||||
uint32_t res1 : 1;
|
||||
uint32_t PLLRDY : 1; /* PLL Ready (0: Not Ready, 1: Locked) */
|
||||
uint32_t res2 : 1;
|
||||
uint32_t OSCRDY : 1; /* Clock Ready (0: Not Ready/Off, 1: Running/Stable) */
|
||||
uint32_t res3 : 1;
|
||||
uint32_t SCLKRDY : 1; /* Synchronized SCLKDIV Bit (0: SCLKDIV 0, 1: SCLKDIV 1) */
|
||||
uint32_t res4 : 19;
|
||||
};
|
||||
|
||||
uint32_t word;
|
||||
uint8_t byte[4];
|
||||
};
|
||||
|
||||
#define MCP25XXFD_REG_IOCON 0xE04
|
||||
union mcp25xxfd_iocon {
|
||||
struct {
|
||||
uint32_t TRIS0 : 1; /* GPIO0 Data Direction (0: Output, 1: Input) */
|
||||
uint32_t TRIS1 : 1; /* GPIO1 Data Direction (0: Output, 1: Input) */
|
||||
uint32_t res0 : 4;
|
||||
uint32_t XSTBYEN : 1; /* Enable Transiever Standby Pin Control */
|
||||
uint32_t res1 : 1;
|
||||
uint32_t LAT0 : 1; /* GPIO0 Latch (0: Low, 1: High) */
|
||||
uint32_t LAT1 : 1; /* GPIO1 Latch (0: Low, 1: High) */
|
||||
uint32_t res2 : 6;
|
||||
uint32_t GPIO0 : 1; /* GPIO0 Status (0: < VIL, 1: > VIH) */
|
||||
uint32_t GPIO1 : 1; /* GPIO1 Status (0: < VIL, 1: > VIH) */
|
||||
uint32_t res3 : 6;
|
||||
uint32_t PM0 : 1; /* GPIO0 Pin Mode (0: INT0, 1: GPIO0) */
|
||||
uint32_t PM1 : 1; /* GPIO1 Pin Mode (0: INT1, 1: GPIO1) */
|
||||
uint32_t res4 : 2;
|
||||
uint32_t TXCANOD : 1; /* TXCAN Drive Mode (0: Push/Pull, 1: Open Drain) */
|
||||
uint32_t SOF : 1; /* Start-Of-Frame Signal (0: Clock on CLKO, 1: SOF on CLKO) */
|
||||
uint32_t INTOD : 1; /* Interrupt Pins Drive Mode (0: Push/Pull, 1: Open Drain) */
|
||||
uint32_t res5 : 1;
|
||||
};
|
||||
|
||||
uint32_t word;
|
||||
uint8_t byte[4];
|
||||
};
|
||||
|
||||
/* MCP25XXFD Objects */
|
||||
|
||||
struct mcp25xxfd_txobj {
|
||||
uint32_t SID : 11;
|
||||
uint32_t EID : 18;
|
||||
uint32_t SID11 : 1;
|
||||
uint32_t res0 : 2;
|
||||
uint32_t DLC : 4; /* Data Length Code */
|
||||
uint32_t IDE : 1; /* Indentifier Extension Flag */
|
||||
uint32_t RTR : 1; /* Remote Transmission Request */
|
||||
uint32_t BRS : 1; /* Bit Rate Switch Enable */
|
||||
uint32_t FDF : 1; /* FD Frame */
|
||||
uint32_t ESI : 1; /* Error Status Indicator */
|
||||
uint32_t SEQ : 23;
|
||||
uint8_t DATA[CAN_MAX_DLEN];
|
||||
};
|
||||
|
||||
struct mcp25xxfd_rxobj {
|
||||
uint32_t SID : 11;
|
||||
uint32_t EID : 18;
|
||||
uint32_t SID11 : 1;
|
||||
uint32_t res0 : 2;
|
||||
uint32_t DLC : 4; /* Data Length Code */
|
||||
uint32_t IDE : 1; /* Indentifier Extension Flag */
|
||||
uint32_t RTR : 1; /* Remote Transmission Request */
|
||||
uint32_t BRS : 1; /* Bit Rate Switch Enable */
|
||||
uint32_t FDF : 1; /* FD Frame */
|
||||
uint32_t ESI : 1; /* Error Status Indicator */
|
||||
uint32_t res1 : 2;
|
||||
uint32_t FILHIT : 5;
|
||||
uint32_t res2 : 16;
|
||||
#if defined(CONFIG_CAN_RX_TIMESTAMP)
|
||||
uint32_t RXMSGTS : 32;
|
||||
#endif
|
||||
uint8_t DATA[CAN_MAX_DLEN];
|
||||
};
|
||||
|
||||
struct mcp25xxfd_tefobj {
|
||||
uint32_t SID : 11;
|
||||
uint32_t EID : 18;
|
||||
uint32_t SID11 : 1;
|
||||
uint32_t res0 : 2;
|
||||
uint32_t DLC : 4; /* Data Length Code */
|
||||
uint32_t IDE : 1; /* Indentifier Extension Flag */
|
||||
uint32_t RTR : 1; /* Remote Transmission Request */
|
||||
uint32_t BRS : 1; /* Bit Rate Switch Enable */
|
||||
uint32_t FDF : 1; /* FD Frame */
|
||||
uint32_t ESI : 1; /* Error Status Indicator */
|
||||
uint32_t SEQ : 23;
|
||||
};
|
||||
|
||||
#endif /* ZEPHYR_DRIVERS_CAN_MICROCHIP_MCP25XXFD_H_ */
|
40
dts/bindings/can/microchip,mcp25xxfd.yaml
Normal file
40
dts/bindings/can/microchip,mcp25xxfd.yaml
Normal file
|
@ -0,0 +1,40 @@
|
|||
# Copyright (c) 2020 Abram Early
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: MCP25XXFD SPI CAN-FD controller
|
||||
|
||||
compatible: "microchip,mcp25xxfd"
|
||||
|
||||
include: [spi-device.yaml, can-fd-controller.yaml]
|
||||
|
||||
properties:
|
||||
osc-freq:
|
||||
type: int
|
||||
required: true
|
||||
description: Frequency of the external oscillator
|
||||
int-gpios:
|
||||
type: phandle-array
|
||||
required: true
|
||||
description: >
|
||||
Interrupt pin.
|
||||
|
||||
This pin signals active low when produced by the controller. The
|
||||
property value should ensure the flags properly describe the signal
|
||||
that is presented to the driver.
|
||||
reg:
|
||||
type: array
|
||||
required: true
|
||||
sof-on-clko:
|
||||
type: boolean
|
||||
required: false
|
||||
description: Output SOF signal on CLKO pin
|
||||
clko-div:
|
||||
type: int
|
||||
required: false
|
||||
description: The factor to divide the system clock for CLKO
|
||||
default: 10
|
||||
enum:
|
||||
- 1
|
||||
- 2
|
||||
- 4
|
||||
- 10
|
Loading…
Add table
Add a link
Reference in a new issue