drivers: can: mcp2515: Fixes for DT SPI cs

Fixed using chipselect with seperate chipselect GPIOs and how they were
referenced from/in DeviceTree.
Also configure the device during initialization so it's ready to go
after init.

Signed-off-by: Karsten Koenig <karsten.koenig.030@gmail.com>
This commit is contained in:
Karsten Koenig 2019-03-31 13:06:01 +02:00 committed by Anas Nashif
commit c9090caad7
5 changed files with 42 additions and 26 deletions

View file

@ -62,12 +62,6 @@ config CAN_MCP2515_INT_THREAD_PRIO
Priority level of the internal thread which is ran for Priority level of the internal thread which is ran for
interrupt handling and incoming packets. interrupt handling and incoming packets.
config CAN_MCP2515_GPIO_SPI_CS
bool "Manage SPI CS through a GPIO pin"
help
This option is useful if one needs to manage SPI CS through a GPIO
pin to by-pass the SPI controller's CS logic.
config CAN_MCP2515_MAX_FILTER config CAN_MCP2515_MAX_FILTER
int "Maximum number of concurrent active filters" int "Maximum number of concurrent active filters"
default 5 default 5

View file

@ -131,7 +131,7 @@ static void mcp2515_convert_zcanframe_to_mcp2515frame(const struct zcan_frame
} }
static void mcp2515_convert_mcp2515frame_to_zcanframe(const u8_t *source, static void mcp2515_convert_mcp2515frame_to_zcanframe(const u8_t *source,
struct zcan_frame *target) struct zcan_frame *target)
{ {
u8_t data_idx = 0U; u8_t data_idx = 0U;
@ -220,6 +220,10 @@ static int mcp2515_configure(struct device *dev, enum can_mode mode,
/* CNF3, CNF2, CNF1, CANINTE */ /* CNF3, CNF2, CNF1, CANINTE */
u8_t config_buf[4]; u8_t config_buf[4];
if (bitrate == 0) {
bitrate = dev_cfg->bus_speed;
}
const u8_t bit_length = 1 + dev_cfg->tq_prop + dev_cfg->tq_bs1 + const u8_t bit_length = 1 + dev_cfg->tq_prop + dev_cfg->tq_bs1 +
dev_cfg->tq_bs2; dev_cfg->tq_bs2;
@ -257,13 +261,17 @@ static int mcp2515_configure(struct device *dev, enum can_mode mode,
const u8_t rx0_ctrl = BIT(6) | BIT(5) | BIT(2); const u8_t rx0_ctrl = BIT(6) | BIT(5) | BIT(2);
const u8_t rx1_ctrl = BIT(6) | BIT(5); const u8_t rx1_ctrl = BIT(6) | BIT(5);
__ASSERT((cfg->tq_sjw >= 1) && (cfg->tq_sjw <= 4), "1 <= SJW <= 4"); __ASSERT((dev_cfg->tq_sjw >= 1) && (dev_cfg->tq_sjw <= 4),
__ASSERT((cfg->tq_prop >= 1) && (cfg->tq_prop <= 8), "1 <= PROP <= 8"); "1 <= SJW <= 4");
__ASSERT((cfg->tq_bs1 >= 1) && (cfg->tq_bs1 <= 8), "1 <= BS1 <= 8"); __ASSERT((dev_cfg->tq_prop >= 1) && (dev_cfg->tq_prop <= 8),
__ASSERT((cfg->tq_bs2 >= 2) && (cfg->tq_bs2 <= 8), "2 <= BS2 <= 8"); "1 <= PROP <= 8");
__ASSERT(cfg->tq_prop + cfg->tq_bs1 >= cfg->tq_bs2, __ASSERT((dev_cfg->tq_bs1 >= 1) && (dev_cfg->tq_bs1 <= 8),
"1 <= BS1 <= 8");
__ASSERT((dev_cfg->tq_bs2 >= 2) && (dev_cfg->tq_bs2 <= 8),
"2 <= BS2 <= 8");
__ASSERT(dev_cfg->tq_prop + dev_cfg->tq_bs1 >= dev_cfg->tq_bs2,
"PROP + BS1 >= BS2"); "PROP + BS1 >= BS2");
__ASSERT(cfg->tq_bs2 > cfg->tq_sjw, "BS2 > SJW"); __ASSERT(dev_cfg->tq_bs2 > dev_cfg->tq_sjw, "BS2 > SJW");
if (CONFIG_CAN_MCP2515_OSC_FREQ % (bit_length * bitrate * 2)) { if (CONFIG_CAN_MCP2515_OSC_FREQ % (bit_length * bitrate * 2)) {
LOG_ERR("Prescaler is not a natural number! " LOG_ERR("Prescaler is not a natural number! "
@ -292,8 +300,8 @@ static int mcp2515_configure(struct device *dev, enum can_mode mode,
mcp2515_convert_canmode_to_mcp2515mode(mode)); mcp2515_convert_canmode_to_mcp2515mode(mode));
} }
int mcp2515_send(struct device *dev, struct zcan_frame *msg, s32_t timeout, int mcp2515_send(struct device *dev, const struct zcan_frame *msg,
can_tx_callback_t callback) s32_t timeout, can_tx_callback_t callback)
{ {
struct mcp2515_data *dev_data = DEV_DATA(dev); struct mcp2515_data *dev_data = DEV_DATA(dev);
u8_t tx_idx = 0U; u8_t tx_idx = 0U;
@ -519,6 +527,7 @@ static int mcp2515_init(struct device *dev)
{ {
const struct mcp2515_config *dev_cfg = DEV_CFG(dev); const struct mcp2515_config *dev_cfg = DEV_CFG(dev);
struct mcp2515_data *dev_data = DEV_DATA(dev); struct mcp2515_data *dev_data = DEV_DATA(dev);
int ret;
k_sem_init(&dev_data->int_sem, 0, UINT_MAX); k_sem_init(&dev_data->int_sem, 0, UINT_MAX);
k_mutex_init(&dev_data->tx_mutex); k_mutex_init(&dev_data->tx_mutex);
@ -539,7 +548,7 @@ static int mcp2515_init(struct device *dev)
return -EINVAL; return -EINVAL;
} }
#ifdef CONFIG_CAN_MCP2515_GPIO_SPI_CS #ifdef DT_MICROCHIP_MCP2515_0_CS_GPIO_PIN
dev_data->spi_cs_ctrl.gpio_dev = dev_data->spi_cs_ctrl.gpio_dev =
device_get_binding(dev_cfg->spi_cs_port); device_get_binding(dev_cfg->spi_cs_port);
if (!dev_data->spi_cs_ctrl.gpio_dev) { if (!dev_data->spi_cs_ctrl.gpio_dev) {
@ -553,7 +562,7 @@ static int mcp2515_init(struct device *dev)
dev_data->spi_cfg.cs = &dev_data->spi_cs_ctrl; dev_data->spi_cfg.cs = &dev_data->spi_cs_ctrl;
#else #else
dev_data->spi_cfg.cs = NULL; dev_data->spi_cfg.cs = NULL;
#endif /* CAN_MCP2515_GPIO_SPI_CS */ #endif /* DT_MICROCHIP_MCP2515_0_CS_GPIO_PIN */
/* Reset MCP2515 */ /* Reset MCP2515 */
if (mcp2515_cmd_soft_reset(dev)) { if (mcp2515_cmd_soft_reset(dev)) {
@ -596,7 +605,9 @@ static int mcp2515_init(struct device *dev)
sizeof(dev_data->filter_response)); sizeof(dev_data->filter_response));
(void)memset(dev_data->filter, 0, sizeof(dev_data->filter)); (void)memset(dev_data->filter, 0, sizeof(dev_data->filter));
return 0; ret = mcp2515_configure(dev, CAN_NORMAL_MODE, dev_cfg->bus_speed);
return ret;
} }
#ifdef CONFIG_CAN_1 #ifdef CONFIG_CAN_1
@ -622,14 +633,15 @@ static const struct mcp2515_config mcp2515_config_1 = {
.int_port = DT_MICROCHIP_MCP2515_0_INT_GPIOS_CONTROLLER, .int_port = DT_MICROCHIP_MCP2515_0_INT_GPIOS_CONTROLLER,
.int_thread_stack_size = CONFIG_CAN_MCP2515_INT_THREAD_STACK_SIZE, .int_thread_stack_size = CONFIG_CAN_MCP2515_INT_THREAD_STACK_SIZE,
.int_thread_priority = CONFIG_CAN_MCP2515_INT_THREAD_PRIO, .int_thread_priority = CONFIG_CAN_MCP2515_INT_THREAD_PRIO,
#ifdef CONFIG_CAN_MCP2515_GPIO_SPI_CS #ifdef DT_MICROCHIP_MCP2515_0_CS_GPIO_PIN
.spi_cs_pin = DT_MICROCHIP_MCP2515_0_CS_GPIOS_PIN, .spi_cs_pin = DT_MICROCHIP_MCP2515_0_CS_GPIO_PIN,
.spi_cs_port = DT_MICROCHIP_MCP2515_0_CS_GPIOS_CONTROLLER, .spi_cs_port = DT_MICROCHIP_MCP2515_0_CS_GPIO_CONTROLLER,
#endif /* CAN_MCP2515_GPIO_SPI_CS */ #endif /* DT_MICROCHIP_MCP2515_0_CS_GPIO_PIN */
.tq_sjw = CONFIG_CAN_SJW, .tq_sjw = CONFIG_CAN_SJW,
.tq_prop = CONFIG_CAN_PROP_SEG, .tq_prop = CONFIG_CAN_PROP_SEG,
.tq_bs1 = CONFIG_CAN_PHASE_SEG1, .tq_bs1 = CONFIG_CAN_PHASE_SEG1,
.tq_bs2 = CONFIG_CAN_PHASE_SEG2, .tq_bs2 = CONFIG_CAN_PHASE_SEG2,
.bus_speed = DT_MICROCHIP_MCP2515_0_BUS_SPEED,
}; };
DEVICE_AND_API_INIT(can_mcp2515_1, DT_MICROCHIP_MCP2515_0_LABEL, &mcp2515_init, DEVICE_AND_API_INIT(can_mcp2515_1, DT_MICROCHIP_MCP2515_0_LABEL, &mcp2515_init,

View file

@ -26,9 +26,9 @@ struct mcp2515_data {
/* spi device data */ /* spi device data */
struct device *spi; struct device *spi;
struct spi_config spi_cfg; struct spi_config spi_cfg;
#ifdef CONFIG_CAN_MCP2515_GPIO_SPI_CS #ifdef DT_MICROCHIP_MCP2515_0_CS_GPIO_PIN
struct spi_cs_control spi_cs_ctrl; struct spi_cs_control spi_cs_ctrl;
#endif #endif /* DT_MICROCHIP_MCP2515_0_CS_GPIO_PIN */
/* interrupt data */ /* interrupt data */
struct device *int_gpio; struct device *int_gpio;
@ -70,6 +70,7 @@ struct mcp2515_config {
u8_t tq_prop; u8_t tq_prop;
u8_t tq_bs1; u8_t tq_bs1;
u8_t tq_bs2; u8_t tq_bs2;
u32_t bus_speed;
}; };
/* MCP2515 Opcodes */ /* MCP2515 Opcodes */

View file

@ -6,13 +6,15 @@
&spi1 { &spi1 {
status = "ok"; status = "ok";
cs-gpios = <&gpioa 4 GPIO_DIR_OUT>;
mcp2515@0 { mcp2515@0 {
compatible = "microchip,mcp2515"; compatible = "microchip,mcp2515";
spi-port-name = "SPI_1"; spi-port-name = "SPI_1";
spi-max-frequency = <1000000>; spi-max-frequency = <1000000>;
int-gpios = <&gpiob 4 GPIO_INT_ACTIVE_LOW>; int-gpios = <&gpioa 0 GPIO_INT_ACTIVE_LOW>;
status = "ok"; status = "ok";
label = "CAN_1"; label = "CAN_1";
reg = <0>; reg = <0>;
bus-speed = <250000>;
}; };
}; };

View file

@ -3,4 +3,11 @@ CONFIG_SPI=y
CONFIG_CAN=y CONFIG_CAN=y
CONFIG_CAN_INIT_PRIORITY=80 CONFIG_CAN_INIT_PRIORITY=80
CONFIG_CAN_1=y CONFIG_CAN_1=y
CONFIG_CAN_MCP2515=y CONFIG_CAN_STM32=n
CONFIG_CAN_MCP2515=y
CONFIG_GPIO_LED_DEV="GPIOB"
CONFIG_PIN_LED_1=3
CONFIG_GPIO_BUTTON_DEV="GPIOB"
CONFIG_PIN_USER_BUTTON=4
CONFIG_LOG=y
CONFIG_CAN_LOG_LEVEL=4