Skip to content
Permalink
Browse files

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>
  • Loading branch information...
karstenkoenig authored and nashif committed Mar 31, 2019
1 parent bf52bfe commit c9090caad7c6d42e7a98927a22d3fb933a8a196a
@@ -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
@@ -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,
@@ -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 */
@@ -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>;
}; };
}; };
@@ -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

0 comments on commit c9090ca

Please sign in to comment.
You can’t perform that action at this time.