zephyr/drivers/can/can_mcp2515.h
Henrik Brix Andersen 6d08944ac1 drivers: can: mcp2515: abort transfers before entering configuration mode
Abort any pending transmissions before entering configuration mode and
notify the senders.

Poll for mode change completion instead of assuming mode changes take
immediate effect. This is needed for successfully entering configuration
mode with recently aborted transmissions.

Fixes: #50545

Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
2022-09-23 17:25:01 +00:00

163 lines
4.8 KiB
C

/*
* Copyright (c) 2018 Karsten Koenig
*
* SPDX-License-Identifier: Apache-2.0
*
*/
#ifndef _MCP2515_H_
#define _MCP2515_H_
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/can.h>
#define MCP2515_RX_CNT 2
/* Reduce the number of Tx buffers to 1 in order to avoid priority inversion. */
#define MCP2515_TX_CNT 1
#define MCP2515_FRAME_LEN 13
struct mcp2515_tx_cb {
can_tx_callback_t cb;
void *cb_arg;
};
struct mcp2515_data {
/* interrupt data */
struct gpio_callback int_gpio_cb;
struct k_thread int_thread;
k_thread_stack_t *int_thread_stack;
struct k_sem int_sem;
/* tx data */
struct k_sem tx_sem;
struct mcp2515_tx_cb tx_cb[MCP2515_TX_CNT];
uint8_t tx_busy_map;
/* filter data */
uint32_t filter_usage;
can_rx_callback_t rx_cb[CONFIG_CAN_MAX_FILTER];
void *cb_arg[CONFIG_CAN_MAX_FILTER];
struct can_filter filter[CONFIG_CAN_MAX_FILTER];
can_state_change_callback_t state_change_cb;
void *state_change_cb_data;
/* general data */
struct k_mutex mutex;
enum can_state old_state;
uint8_t mcp2515_mode;
bool started;
uint8_t sjw;
};
struct mcp2515_config {
/* spi configuration */
struct spi_dt_spec bus;
/* interrupt configuration */
struct gpio_dt_spec int_gpio;
size_t int_thread_stack_size;
int int_thread_priority;
/* CAN timing */
uint8_t tq_sjw;
uint8_t tq_prop;
uint8_t tq_bs1;
uint8_t tq_bs2;
uint32_t bus_speed;
uint32_t osc_freq;
uint16_t sample_point;
/* CAN transceiver */
const struct device *phy;
uint32_t max_bitrate;
};
/*
* Startup time of 128 OSC1 clock cycles at 1MHz (minimum clock in frequency)
* see MCP2515 datasheet section 8.1 Oscillator Start-up Timer
*/
#define MCP2515_OSC_STARTUP_US 128U
/* MCP2515 Opcodes */
#define MCP2515_OPCODE_WRITE 0x02
#define MCP2515_OPCODE_READ 0x03
#define MCP2515_OPCODE_BIT_MODIFY 0x05
#define MCP2515_OPCODE_LOAD_TX_BUFFER 0x40
#define MCP2515_OPCODE_RTS 0x80
#define MCP2515_OPCODE_READ_RX_BUFFER 0x90
#define MCP2515_OPCODE_READ_STATUS 0xA0
#define MCP2515_OPCODE_RESET 0xC0
/* MCP2515 Registers */
#define MCP2515_ADDR_CANSTAT 0x0E
#define MCP2515_ADDR_CANCTRL 0x0F
#define MCP2515_ADDR_TEC 0x1C
#define MCP2515_ADDR_REC 0x1D
#define MCP2515_ADDR_CNF3 0x28
#define MCP2515_ADDR_CNF2 0x29
#define MCP2515_ADDR_CNF1 0x2A
#define MCP2515_ADDR_CANINTE 0x2B
#define MCP2515_ADDR_CANINTF 0x2C
#define MCP2515_ADDR_EFLG 0x2D
#define MCP2515_ADDR_TXB0CTRL 0x30
#define MCP2515_ADDR_TXB1CTRL 0x40
#define MCP2515_ADDR_TXB2CTRL 0x50
#define MCP2515_ADDR_RXB0CTRL 0x60
#define MCP2515_ADDR_RXB1CTRL 0x70
#define MCP2515_ADDR_OFFSET_FRAME2FRAME 0x10
#define MCP2515_ADDR_OFFSET_CTRL2FRAME 0x01
/* MCP2515 Operation Modes */
#define MCP2515_MODE_NORMAL 0x00
#define MCP2515_MODE_LOOPBACK 0x02
#define MCP2515_MODE_SILENT 0x03
#define MCP2515_MODE_CONFIGURATION 0x04
/* MCP2515_FRAME_OFFSET */
#define MCP2515_FRAME_OFFSET_SIDH 0
#define MCP2515_FRAME_OFFSET_SIDL 1
#define MCP2515_FRAME_OFFSET_EID8 2
#define MCP2515_FRAME_OFFSET_EID0 3
#define MCP2515_FRAME_OFFSET_DLC 4
#define MCP2515_FRAME_OFFSET_D0 5
/* MCP2515_CANINTF */
#define MCP2515_CANINTF_RX0IF BIT(0)
#define MCP2515_CANINTF_RX1IF BIT(1)
#define MCP2515_CANINTF_TX0IF BIT(2)
#define MCP2515_CANINTF_TX1IF BIT(3)
#define MCP2515_CANINTF_TX2IF BIT(4)
#define MCP2515_CANINTF_ERRIF BIT(5)
#define MCP2515_CANINTF_WAKIF BIT(6)
#define MCP2515_CANINTF_MERRF BIT(7)
#define MCP2515_INTE_RX0IE BIT(0)
#define MCP2515_INTE_RX1IE BIT(1)
#define MCP2515_INTE_TX0IE BIT(2)
#define MCP2515_INTE_TX1IE BIT(3)
#define MCP2515_INTE_TX2IE BIT(4)
#define MCP2515_INTE_ERRIE BIT(5)
#define MCP2515_INTE_WAKIE BIT(6)
#define MCP2515_INTE_MERRE BIT(7)
#define MCP2515_EFLG_EWARN BIT(0)
#define MCP2515_EFLG_RXWAR BIT(1)
#define MCP2515_EFLG_TXWAR BIT(2)
#define MCP2515_EFLG_RXEP BIT(3)
#define MCP2515_EFLG_TXEP BIT(4)
#define MCP2515_EFLG_TXBO BIT(5)
#define MCP2515_EFLG_RX0OVR BIT(6)
#define MCP2515_EFLG_RX1OVR BIT(7)
#define MCP2515_TXCTRL_TXREQ BIT(3)
#define MCP2515_CANSTAT_MODE_POS 5
#define MCP2515_CANSTAT_MODE_MASK (0x07 << MCP2515_CANSTAT_MODE_POS)
#define MCP2515_CANCTRL_MODE_POS 5
#define MCP2515_CANCTRL_MODE_MASK (0x07 << MCP2515_CANCTRL_MODE_POS)
#define MCP2515_TXBNCTRL_TXREQ_POS 3
#define MCP2515_TXBNCTRL_TXREQ_MASK (0x01 << MCP2515_TXBNCTRL_TXREQ_POS)
#endif /*_MCP2515_H_*/