From 757f8101186ecffe09d3ae0f28bdb81b662f0646 Mon Sep 17 00:00:00 2001 From: Wouter Symons Date: Fri, 31 Jan 2020 15:18:16 +0100 Subject: [PATCH] drivers/mcp2515: complete driver + adapt to 2020 RIOT API --- CODEOWNERS | 1 + drivers/Makefile.dep | 5 + drivers/include/candev_mcp2515.h | 32 ++- drivers/mcp2515/Makefile | 2 - drivers/mcp2515/Makefile.include | 2 + drivers/mcp2515/candev_mcp2515.c | 331 +++++++++++++++++------ drivers/mcp2515/include/mcp2515_params.h | 44 ++- drivers/mcp2515/mcp2515.c | 194 ++++++++----- drivers/mcp2515/mcp2515.h | 59 ++-- drivers/mcp2515/mcp2515_defines.h | 143 +++++----- drivers/mcp2515/mcp2515_spi.c | 76 ++++-- drivers/mcp2515/mcp2515_spi.h | 7 +- sys/auto_init/can/auto_init_mcp2515.c | 13 +- 13 files changed, 591 insertions(+), 318 deletions(-) create mode 100644 drivers/mcp2515/Makefile.include diff --git a/CODEOWNERS b/CODEOWNERS index 7c9c75952d..bf4cf07f28 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -77,6 +77,7 @@ /drivers/dose/ @jue89 /drivers/ds18/ @leandrolanzieri /drivers/itg320x/ @gschorcht +/drivers/mcp2515/ @wosym /drivers/mrf24j40/ @bergzand /drivers/pca9685/ @gschorcht /drivers/sht3x/ @gschorcht diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep index 5000976fb3..7d6bf7f359 100644 --- a/drivers/Makefile.dep +++ b/drivers/Makefile.dep @@ -72,6 +72,11 @@ ifneq (,$(filter ltc4150_%,$(USEMODULE))) USEMODULE += ltc4150 endif +ifneq (,$(filter mcp2515,$(USEMODULE))) + USEMODULE += xtimer + FEATURES_REQUIRED += periph_gpio periph_spi periph_gpio_irq +endif + ifneq (,$(filter mhz19_%,$(USEMODULE))) USEMODULE += mhz19 endif diff --git a/drivers/include/candev_mcp2515.h b/drivers/include/candev_mcp2515.h index 5d01ccde64..880622db91 100644 --- a/drivers/include/candev_mcp2515.h +++ b/drivers/include/candev_mcp2515.h @@ -19,6 +19,7 @@ * * @author Toon Stegen * @author Vincent Dupont + * @author Wouter Symons */ #ifndef CANDEV_MCP2515_H @@ -37,6 +38,20 @@ extern "C" { #endif +/** + * Default CAN bitrate + */ +#ifndef CANDEV_MCP2515_DEFAULT_BITRATE +#define CANDEV_MCP2515_DEFAULT_BITRATE 125000 +#endif + +/** + * Default sampling point setup + */ +#ifndef CANDEV_MCP2515_DEFAULT_SPT +#define CANDEV_MCP2515_DEFAULT_SPT 875 +#endif + /** * Number of transmit mailboxes */ @@ -75,13 +90,13 @@ typedef struct candev_mcp2515 candev_mcp2515_t; * @brief MCP2515 configuration descriptor */ typedef struct candev_mcp2515_conf { - spi_t spi; /**< SPI bus */ - spi_mode_t spi_mode; /**< SPI mode */ - spi_clk_t spi_clk; /**< SPI clock speed */ - gpio_t cs_pin; /**< Slave select pin */ - gpio_t rst_pin; /**< Reset pin */ - gpio_t int_pin; /**< Interrupt pin */ - uint32_t clk; /**< External clock frequency */ + spi_t spi; /**< SPI bus */ + spi_mode_t spi_mode; /**< SPI mode */ + spi_clk_t spi_clk; /**< SPI clock speed */ + gpio_t cs_pin; /**< Slave select pin */ + gpio_t rst_pin; /**< Reset pin */ + gpio_t int_pin; /**< Interrupt pin */ + uint32_t clk; /**< External clock frequency */ } candev_mcp2515_conf_t; /** @@ -111,7 +126,8 @@ struct candev_mcp2515 { * @param[out] dev mcp2515 device descriptor * @param[in] conf mcp2515 configuration */ -void candev_mcp2515_init(candev_mcp2515_t *dev, const candev_mcp2515_conf_t *conf); +void candev_mcp2515_init(candev_mcp2515_t *dev, + const candev_mcp2515_conf_t *conf); #ifdef __cplusplus } diff --git a/drivers/mcp2515/Makefile b/drivers/mcp2515/Makefile index d686bef0e4..48422e909a 100644 --- a/drivers/mcp2515/Makefile +++ b/drivers/mcp2515/Makefile @@ -1,3 +1 @@ -MODULE = mcp2515 - include $(RIOTBASE)/Makefile.base diff --git a/drivers/mcp2515/Makefile.include b/drivers/mcp2515/Makefile.include new file mode 100644 index 0000000000..9ee0af8162 --- /dev/null +++ b/drivers/mcp2515/Makefile.include @@ -0,0 +1,2 @@ +USEMODULE_INCLUDES_mcp2515 := $(LAST_MAKEFILEDIR)/include +USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_mcp2515) diff --git a/drivers/mcp2515/candev_mcp2515.c b/drivers/mcp2515/candev_mcp2515.c index 449bc453c3..a4cd52d03d 100644 --- a/drivers/mcp2515/candev_mcp2515.c +++ b/drivers/mcp2515/candev_mcp2515.c @@ -7,7 +7,7 @@ */ /** - * @ingroup drivers_mcp2515 Stand-Alone CAN Controller With SPI Interface + * @ingroup drivers_mcp2515 * @{ * * @file @@ -15,38 +15,30 @@ * * @author Toon Stegen * @author Vincent Dupont + * @author Wouter Symons * @} */ -#include #include #include -#include +#include +#include #include "candev_mcp2515.h" #include "can/common.h" #include "can/device.h" #include "mcp2515.h" +#include "mutex.h" #include "periph_conf.h" #include "thread.h" #include "sched.h" -#include "mutex.h" +#include "xtimer.h" #define ENABLE_DEBUG (0) #include "debug.h" -#define MAILBOX_USED 1 -#define MAILBOX_EMPTY 0 - -#define MAILBOX_TO_INTR(mailbox) (INT_RX0 + (mailbox)) - -#ifndef CANDEV_MCP2515_DEFAULT_BITRATE -#define CANDEV_MCP2515_DEFAULT_BITRATE 500000 -#endif - -#ifndef CANDEV_MCP2515_DEFAULT_SPT -#define CANDEV_MCP2515_DEFAULT_SPT 875 -#endif +static mutex_t _mcp_mutex; +static int _neednewisr = 0; static int _init(candev_t *candev); static int _send(candev_t *candev, const struct can_frame *frame); @@ -54,15 +46,16 @@ static void _isr(candev_t *candev); static int _set(candev_t *candev, canopt_t opt, void *value, size_t value_len); static int _get(candev_t *candev, canopt_t opt, void *value, size_t max_len); static int _abort(candev_t *candev, const struct can_frame *frame); -static int _set_filter(candev_t *dev, const struct can_filter * filter); -static int _remove_filter(candev_t *dev, const struct can_filter * filter); +static int _set_filter(candev_t *dev, const struct can_filter *filter); +static int _remove_filter(candev_t *dev, const struct can_filter *filter); static void _irq_rx(candev_mcp2515_t *dev, int handle); static void _irq_tx(candev_mcp2515_t *dev, int handle); static void _irq_error(candev_mcp2515_t *dev); static void _irq_message_error(candev_mcp2515_t *dev); static void _irq_wakeup(const candev_mcp2515_t *dev); -static void _send_event(const candev_mcp2515_t *dev, candev_event_t event, void *arg); +static void _send_event(const candev_mcp2515_t *dev, candev_event_t event, + void *arg); static const candev_driver_t candev_mcp2515_driver = { .send = _send, @@ -76,14 +69,14 @@ static const candev_driver_t candev_mcp2515_driver = { }; static const struct can_bittiming_const bittiming_const = { - .tseg1_min = 3, - .tseg1_max = 16, - .tseg2_min = 2, - .tseg2_max = 8, - .sjw_max = 4, - .brp_min = 1, - .brp_max = 64, - .brp_inc = 1, + .tseg1_min = 3, /**< Time segment 1 = prop_seg + phase_seg1, min value */ + .tseg1_max = 16, /**< Time segment 1, max value */ + .tseg2_min = 2, /**< Time segment 2 = phase_seg2, min value */ + .tseg2_max = 8, /**< Time segment 2, max value */ + .sjw_max = 4, /**< Synchronisation jump width */ + .brp_min = 1, /**< Bit-rate prescaler, min value */ + .brp_max = 64, /**< Bit-rate prescaler, max value */ + .brp_inc = 1, /**< Bit-rate prescaler, increment */ }; static inline int _max_filters(int mailbox) @@ -91,13 +84,17 @@ static inline int _max_filters(int mailbox) return mailbox == 0 ? MCP2515_FILTERS_MB0 : MCP2515_FILTERS_MB1; } -void candev_mcp2515_init(candev_mcp2515_t *dev, const candev_mcp2515_conf_t *conf) +void candev_mcp2515_init(candev_mcp2515_t *dev, + const candev_mcp2515_conf_t *conf) { memset(dev, 0, sizeof(*dev)); dev->candev.driver = &candev_mcp2515_driver; struct can_bittiming timing = { .bitrate = CANDEV_MCP2515_DEFAULT_BITRATE, - .sample_point = CANDEV_MCP2515_DEFAULT_SPT }; + .sample_point = + CANDEV_MCP2515_DEFAULT_SPT }; + + /* f_quantum = f_osc / 2 */ can_device_calc_bittiming(conf->clk / 2, &bittiming_const, &timing); memcpy(&dev->candev.bittiming, &timing, sizeof(timing)); @@ -114,7 +111,8 @@ void candev_mcp2515_init(candev_mcp2515_t *dev, const candev_mcp2515_conf_t *con static void _mcp2515_irq_handler(void *arg) { - candev_mcp2515_t *candev = (candev_mcp2515_t *) arg; + candev_mcp2515_t *candev = (candev_mcp2515_t *)arg; + _send_event(candev, CANDEV_EVENT_ISR, NULL); } @@ -131,15 +129,23 @@ static int _init(candev_t *candev) mcp2515_configure_bittiming(dev); mcp2515_init_irqs(dev); - /* configure filters to be closed */ - for (int mailbox = 0; mailbox < MCP2515_RX_MAILBOXES; mailbox++) { - mcp2515_set_mask(dev, mailbox, dev->masks[mailbox]); - for (int filter = 0; filter < _max_filters(mailbox); filter++) { - mcp2515_set_filter(dev, mailbox * MCP2515_FILTERS_MB0 + filter, - dev->filter_ids[mailbox][filter]); + if (mutex_trylock(&_mcp_mutex)) { + /* configure filters to be closed */ + for (int mailbox = 0; mailbox < MCP2515_RX_MAILBOXES; mailbox++) { + mcp2515_set_mask(dev, mailbox, dev->masks[mailbox]); + for (int filter = 0; filter < _max_filters(mailbox); filter++) { + mcp2515_set_filter(dev, mailbox * MCP2515_FILTERS_MB0 + filter, + dev->filter_ids[mailbox][filter]); + } } + res = mcp2515_set_mode(dev, MODE_NORMAL); + mutex_unlock(&_mcp_mutex); + } + else { + /* locking failed */ + DEBUG("failed to lock mutex_init"); + return -1; } - res = mcp2515_set_mode(dev, MODE_NORMAL); return res; } @@ -147,11 +153,24 @@ static int _send(candev_t *candev, const struct can_frame *frame) { candev_mcp2515_t *dev = (candev_mcp2515_t *)candev; int box; + int ret = 0; enum mcp2515_mode mode; - mode = mcp2515_get_mode(dev); + if (frame->can_id > 0x1FFFFFFF) { + DEBUG("Illegal CAN-ID!\n"); + return -EINVAL; + } + + if (mutex_trylock(&_mcp_mutex)) { + mode = mcp2515_get_mode(dev); + mutex_unlock(&_mcp_mutex); + } + else { + DEBUG("failed to lock mutex_send\n"); + return -1; + } if (mode != MODE_NORMAL && mode != MODE_LOOPBACK) { - return -EINVAL; + return -EINVAL; } DEBUG("Inside mcp2515 send\n"); @@ -168,7 +187,23 @@ static int _send(candev_t *candev, const struct can_frame *frame) dev->tx_mailbox[box] = frame; - mcp2515_send(dev, frame, box); + if (mutex_trylock(&_mcp_mutex)) { + ret = mcp2515_send(dev, frame, box); + mutex_unlock(&_mcp_mutex); + } + else { + DEBUG("send_failed to lock mutex\n"); + return -1; + } + if (ret < 0) { + return -1; + } + + if (_neednewisr) { + DEBUG("Calling _isr() again on request\n"); + _isr(candev); + _neednewisr = 0; + } return box; } @@ -190,7 +225,14 @@ static int _abort(candev_t *candev, const struct can_frame *frame) return -EBUSY; } - mcp2515_abort(dev, box); + if (mutex_trylock(&_mcp_mutex)) { + mcp2515_abort(dev, box); + mutex_unlock(&_mcp_mutex); + } + else { + DEBUG("abort_Failed to lock mutex\n"); + return -1; + } dev->tx_mailbox[box] = NULL; return 0; @@ -201,7 +243,17 @@ static void _isr(candev_t *candev) uint8_t flag; candev_mcp2515_t *dev = (candev_mcp2515_t *)candev; - while((flag = mcp2515_get_irq(dev))) { + if (mutex_trylock(&_mcp_mutex)) { + flag = mcp2515_get_irq(dev); + mutex_unlock(&_mcp_mutex); + } + else { + DEBUG("isr: Failed to lock mutex\n"); + _neednewisr = 1; + return; + } + + while ((flag)) { if (flag & INT_WAKEUP) { if (dev->wakeup_src == MCP2515_WKUP_SRC_INTERNAL) { dev->wakeup_src = 0; @@ -232,8 +284,26 @@ static void _isr(candev_t *candev) _irq_message_error(dev); } + if (mutex_trylock(&_mcp_mutex)) { + flag = mcp2515_get_irq(dev); + mutex_unlock(&_mcp_mutex); + } + else { + DEBUG("isr2: Failed to lock mutex\n"); + _neednewisr = 1; + return; + } + /* clear all flags except for RX flags, which are cleared by receiving */ - mcp2515_clear_irq(dev, flag & ~INT_RX0 & ~INT_RX1); + if (mutex_trylock(&_mcp_mutex)) { + mcp2515_clear_irq(dev, flag & ~(INT_RX0 | INT_RX1)); + mutex_unlock(&_mcp_mutex); + } + else { + DEBUG("isr3: failed to lock mutex\n"); + _neednewisr = 1; + return; + } } } @@ -264,14 +334,35 @@ static int _set(candev_t *candev, canopt_t opt, void *value, size_t value_len) else { switch (*((canopt_state_t *)value)) { case CANOPT_STATE_LISTEN_ONLY: - res = mcp2515_set_mode(dev, MODE_LISTEN_ONLY); + if (mutex_trylock(&_mcp_mutex)) { + res = mcp2515_set_mode(dev, MODE_LISTEN_ONLY); + mutex_unlock(&_mcp_mutex); + } + else { + DEBUG("set1_Failed to lock mutex\n"); + return -1; + } break; case CANOPT_STATE_OFF: case CANOPT_STATE_SLEEP: - res = mcp2515_set_mode(dev, MODE_SLEEP); + if (mutex_trylock(&_mcp_mutex)) { + res = mcp2515_set_mode(dev, MODE_SLEEP); + mutex_unlock(&_mcp_mutex); + } + else { + DEBUG("set2_Failed to lock mutex\n"); + return -1; + } break; case CANOPT_STATE_ON: - res = mcp2515_set_mode(dev, MODE_NORMAL); + if (mutex_trylock(&_mcp_mutex)) { + res = mcp2515_set_mode(dev, MODE_NORMAL); + mutex_unlock(&_mcp_mutex); + } + else { + DEBUG("set3_Failed to lock mutex\n"); + return -1; + } break; default: res = -ENOTSUP; @@ -307,7 +398,8 @@ static int _get(candev_t *candev, canopt_t opt, void *value, size_t max_len) res = -EOVERFLOW; } else { - res = 1; + /* Not implemented (yet...) */ + res = -ENOTSUP; } break; case CANOPT_BITTIMING_CONST: @@ -339,19 +431,28 @@ static int _get(candev_t *candev, canopt_t opt, void *value, size_t max_len) static int _set_filter(candev_t *dev, const struct can_filter *filter) { DEBUG("inside _set_filter of MCP2515\n"); - int filter_added = -1; + bool filter_added = true; struct can_filter f = *filter; int res = -1; enum mcp2515_mode mode; - candev_mcp2515_t *dev_mcp = (candev_mcp2515_t *) dev; + candev_mcp2515_t *dev_mcp = (candev_mcp2515_t *)dev; if (f.can_mask == 0) { return -EINVAL; /* invalid mask */ } - mode = mcp2515_get_mode(dev_mcp); - res = mcp2515_set_mode(dev_mcp, MODE_CONFIG); + if (mutex_trylock(&_mcp_mutex)) { + mode = mcp2515_get_mode(dev_mcp); + res = mcp2515_set_mode(dev_mcp, MODE_CONFIG); + + mutex_unlock(&_mcp_mutex); + } + else { + DEBUG("setfilt_Failed to lock mutex\n"); + return -1; + } + if (res != MODE_CONFIG) { return -1; } @@ -365,20 +466,22 @@ static int _set_filter(candev_t *dev, const struct can_filter *filter) /* Browse on each mailbox to find an empty space */ int mailbox_index = 0; - while (mailbox_index < MCP2515_RX_MAILBOXES && filter_added == -1) { + + while (mailbox_index < MCP2515_RX_MAILBOXES && !filter_added) { /* mask unused */ if (dev_mcp->masks[mailbox_index] == 0) { /* set mask */ mcp2515_set_mask(dev_mcp, mailbox_index, f.can_mask); /* set filter */ - mcp2515_set_filter(dev_mcp, MCP2515_FILTERS_MB0 * mailbox_index, f.can_id); + mcp2515_set_filter(dev_mcp, MCP2515_FILTERS_MB0 * mailbox_index, + f.can_id); /* save filter */ dev_mcp->masks[mailbox_index] = f.can_mask; dev_mcp->filter_ids[mailbox_index][0] = f.can_id; /* function succeeded */ - filter_added = 1; + filter_added = true; } /* mask existed and same mask */ @@ -394,19 +497,35 @@ static int _set_filter(candev_t *dev, const struct can_filter *filter) /* an empty space is found */ if (filter_pos < _max_filters(mailbox_index)) { /* set filter on this memory space */ - mcp2515_set_filter(dev_mcp, MCP2515_FILTERS_MB0 * mailbox_index + filter_pos, f.can_id); + if (mutex_trylock(&_mcp_mutex)) { + mcp2515_set_filter(dev_mcp, + MCP2515_FILTERS_MB0 * mailbox_index + filter_pos, + f.can_id); + mutex_unlock(&_mcp_mutex); + } + else { + DEBUG("setfilt2_Failed to lock mutex"); + return -1; + } /* save filter */ dev_mcp->filter_ids[mailbox_index][filter_pos] = f.can_id; /* function succeeded */ - filter_added = 1; + filter_added = true; } } mailbox_index++; } - mcp2515_set_mode(dev_mcp, mode); + if (mutex_trylock(&_mcp_mutex)) { + mcp2515_set_mode(dev_mcp, mode); + mutex_unlock(&_mcp_mutex); + } + else { + DEBUG("setfilt3_Failed to lock mutex"); + return -1; + } return filter_added; } @@ -414,20 +533,28 @@ static int _set_filter(candev_t *dev, const struct can_filter *filter) static int _remove_filter(candev_t *dev, const struct can_filter *filter) { DEBUG("inside _remove_filter of MCP2515\n"); - int filter_removed = -1; + bool filter_removed; struct can_filter f = *filter; int res = 0; enum mcp2515_mode mode; - candev_mcp2515_t *dev_mcp = (candev_mcp2515_t *) dev; + candev_mcp2515_t *dev_mcp = (candev_mcp2515_t *)dev; if (f.can_mask == 0) { return -1; /* invalid mask */ } - mode = mcp2515_get_mode(dev_mcp); - res = mcp2515_set_mode(dev_mcp, MODE_CONFIG); - if(res < 0) { + if (mutex_trylock(&_mcp_mutex)) { + mode = mcp2515_get_mode(dev_mcp); + res = mcp2515_set_mode(dev_mcp, MODE_CONFIG); + mutex_unlock(&_mcp_mutex); + } + else { + DEBUG("remfilt_Failed to lock mutex\n"); + return -1; + } + + if (res < 0) { return -1; } @@ -439,8 +566,9 @@ static int _remove_filter(candev_t *dev, const struct can_filter *filter) } int mailbox_index = 0; + /* Browse on each mailbox to find the right filter id */ - while (mailbox_index < MCP2515_RX_MAILBOXES && filter_removed == -1) { + while (mailbox_index < MCP2515_RX_MAILBOXES && !filter_removed) { /* same mask */ if (dev_mcp->masks[mailbox_index] == f.can_mask) { int filter_pos = 0; @@ -453,7 +581,16 @@ static int _remove_filter(candev_t *dev, const struct can_filter *filter) /* filter id found */ if (filter_pos < _max_filters(mailbox_index)) { /* remove filter */ - mcp2515_set_filter(dev_mcp, MCP2515_FILTERS_MB0 * mailbox_index + filter_pos, CAN_EFF_MASK); + if (mutex_trylock(&_mcp_mutex)) { + mcp2515_set_filter(dev_mcp, + MCP2515_FILTERS_MB0 * mailbox_index + filter_pos, + CAN_EFF_MASK); + mutex_unlock(&_mcp_mutex); + } + else { + DEBUG("remfilt2_Failed to lock mutex\n"); + return -1; + } /* save modification */ dev_mcp->filter_ids[mailbox_index][filter_pos] = 0; @@ -478,7 +615,14 @@ static int _remove_filter(candev_t *dev, const struct can_filter *filter) } mailbox_index++; } - mcp2515_set_mode(dev_mcp, mode); + if (mutex_trylock(&_mcp_mutex)) { + mcp2515_set_mode(dev_mcp, mode); + mutex_unlock(&_mcp_mutex); + } + else { + DEBUG("remfilt3_Failed to lock mutex\n"); + return -1; + } return filter_removed; } @@ -487,7 +631,14 @@ static void _irq_rx(candev_mcp2515_t *dev, int box) { DEBUG("Inside mcp2515 rx irq, box=%d\n", box); - mcp2515_receive(dev, &dev->rx_buf[box], box); + if (mutex_trylock(&_mcp_mutex)) { + mcp2515_receive(dev, &dev->rx_buf[box], box); + mutex_unlock(&_mcp_mutex); + } + else { + DEBUG("irqrx_Failed to lock mutex\n"); + return; + } _send_event(dev, CANDEV_EVENT_RX_INDICATION, &dev->rx_buf[box]); } @@ -496,6 +647,7 @@ static void _irq_tx(candev_mcp2515_t *dev, int box) { DEBUG("Inside mcp2515 tx irq\n"); const struct can_frame *frame = dev->tx_mailbox[box]; + dev->tx_mailbox[box] = NULL; _send_event(dev, CANDEV_EVENT_TX_CONFIRMATION, (void *)frame); @@ -504,23 +656,31 @@ static void _irq_tx(candev_mcp2515_t *dev, int box) static void _irq_error(candev_mcp2515_t *dev) { uint8_t err; + DEBUG("Inside mcp2515 error irq\n"); - err = mcp2515_get_errors(dev); + if (mutex_trylock(&_mcp_mutex)) { + err = mcp2515_get_errors(dev); + mutex_unlock(&_mcp_mutex); + } + else { + DEBUG("erqerr_Failed to lock mutex\n"); + return; + } - if(err & (ERR_WARNING | ERR_RX_WARNING | ERR_TX_WARNING)) { + if (err & (ERR_WARNING | ERR_RX_WARNING | ERR_TX_WARNING)) { DEBUG("Error Warning\n"); _send_event(dev, CANDEV_EVENT_ERROR_WARNING, NULL); } - else if(err & (ERR_RX_PASSIVE | ERR_TX_PASSIVE)) { + else if (err & (ERR_RX_PASSIVE | ERR_TX_PASSIVE)) { DEBUG("Error Passive\n"); _send_event(dev, CANDEV_EVENT_ERROR_PASSIVE, NULL); } - else if(err & ERR_TX_BUS_OFF) { - DEBUG("Buss Off\n"); + else if (err & ERR_TX_BUS_OFF) { + DEBUG("Bus Off\n"); _send_event(dev, CANDEV_EVENT_BUS_OFF, NULL); } - else if(err & (ERR_RX_0_OVERFLOW | ERR_RX_1_OVERFLOW)) { + else if (err & (ERR_RX_0_OVERFLOW | ERR_RX_1_OVERFLOW)) { DEBUG("RX overflow\n"); _send_event(dev, CANDEV_EVENT_RX_ERROR, NULL); } @@ -528,8 +688,6 @@ static void _irq_error(candev_mcp2515_t *dev) static void _irq_message_error(candev_mcp2515_t *dev) { - (void) dev; -#if(0) int box; DEBUG("Inside mcp2515 message error irq\n"); @@ -538,19 +696,19 @@ static void _irq_message_error(candev_mcp2515_t *dev) if (mcp2515_tx_err_occurred(dev, box)) { DEBUG("Box: %d\n", box); - mutex_lock(&dev->tx_mutex); - mcp2515_abort(dev, box); - xtimer_remove(&dev->tx_mailbox[box].timer); - mutex_unlock(&dev->tx_mutex); + if (mutex_trylock(&_mcp_mutex)) { + mcp2515_abort(dev, box); + mutex_unlock(&_mcp_mutex); + } + else { + DEBUG("irqmsg_Failed to lock mutex\n"); + return; + } + _send_event(dev, CANDEV_EVENT_TIMEOUT_TX_CONF, + NULL); - _send_event(dev, CANDEV_EVENT_TIMEOUT_TX_CONF, (void *) dev->tx_mailbox[box].pkt); - - mutex_lock(&dev->tx_mutex); - dev->tx_mailbox[box].pkt = NULL; - mutex_unlock(&dev->tx_mutex); } } -#endif } static void _irq_wakeup(const candev_mcp2515_t *dev) @@ -560,9 +718,10 @@ static void _irq_wakeup(const candev_mcp2515_t *dev) _send_event(dev, CANDEV_EVENT_WAKE_UP, NULL); } -static void _send_event(const candev_mcp2515_t *dev, candev_event_t event, void *arg) +static void _send_event(const candev_mcp2515_t *dev, candev_event_t event, + void *arg) { - candev_t *candev = (candev_t *) dev; + candev_t *candev = (candev_t *)dev; if (candev->event_callback) { candev->event_callback(candev, event, arg); diff --git a/drivers/mcp2515/include/mcp2515_params.h b/drivers/mcp2515/include/mcp2515_params.h index bb2362edba..f465706119 100644 --- a/drivers/mcp2515/include/mcp2515_params.h +++ b/drivers/mcp2515/include/mcp2515_params.h @@ -1,3 +1,23 @@ +/* + * Copyright (C) 2016 OTA keys S.A. + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup drivers_mcp2515 + * @{ + * + * @file + * @brief Parameters for the CAN driver implementation + * + * @author Vincent Dupont + * @author Wouter Symons + * @} + */ + #ifndef MCP2515_PARAMS_H #define MCP2515_PARAMS_H @@ -10,6 +30,10 @@ extern "C" { #include "board.h" +/** + * @name Set default configuration parameters for the MCP2515 + * @{ + */ #ifndef MCP2515_PARAM_SPI #define MCP2515_PARAM_SPI SPI_DEV(0) #endif @@ -23,7 +47,7 @@ extern "C" { #endif #ifndef MCP2515_PARAM_CS -#define MCP2515_PARAM_CS SPI_HWCS(0) +#define MCP2515_PARAM_CS GPIO_PIN(1, 9) #endif #ifndef MCP2515_PARAM_RST @@ -31,11 +55,12 @@ extern "C" { #endif #ifndef MCP2515_PARAM_INT -#define MCP2515_PARAM_INT GPIO_PIN(0, 1) +#define MCP2515_PARAM_INT GPIO_PIN(1, 8) #endif #ifndef MCP2515_PARAM_CLK -#define MCP2515_PARAM_CLK (8000000ul) +#define MCP2515_PARAM_CLK (8000000ul) /**< External clock frequency */ + #endif #define MCP2515_DEFAULT_CONFIG \ @@ -48,14 +73,21 @@ extern "C" { .int_pin = MCP2515_PARAM_INT, \ .clk = MCP2515_PARAM_CLK, \ } +/**@*/ -const static candev_mcp2515_conf_t candev_mcp2515_conf[] = { +/** + * @brief Set default configuration + */ +static const candev_mcp2515_conf_t candev_mcp2515_conf[] = { MCP2515_DEFAULT_CONFIG }; -const static candev_params_t candev_mcp2515_params[] = { +/** + * @brief set candev parameters + */ +static const candev_params_t candev_mcp2515_params[] = { { - .name = "can_cmp2515_0", + .name = "can_mcp2515_0", }, }; diff --git a/drivers/mcp2515/mcp2515.c b/drivers/mcp2515/mcp2515.c index eee7fc3908..b5beea6280 100644 --- a/drivers/mcp2515/mcp2515.c +++ b/drivers/mcp2515/mcp2515.c @@ -14,12 +14,13 @@ * @brief mcp2515 can spi driver * * @author Toon Stegen + * @author Wouter Symons * @} */ -#include "xtimer.h" #include +#include "xtimer.h" #include "mcp2515.h" #include "mcp2515_spi.h" #include "mcp2515_defines.h" @@ -30,18 +31,21 @@ #include "debug.h" /* reset delay should be at least 2 microseconds */ -#define RESET_DELAY 2 +#define RESET_DELAY_US 2 /* size of transmission and reception buffers in mcp2515 */ #define BUFFER_SIZE 13 /* macros for getting the TX and RX control registers */ -#define TX_CTRL(mailbox) ((MCP2515_TXB0CTRL) + ((mailbox) << 4)) -#define RX_CTRL(mailbox) ((MCP2515_RXB0CTRL) + ((mailbox) << 4)) +#define MCP2515_TX_CTRL(mailbox) ((MCP2515_TXB0CTRL) + ((mailbox) << 4)) +#define MCP2515_RX_CTRL(mailbox) ((MCP2515_RXB0CTRL) + ((mailbox) << 4)) + +/* length of the fixed part of a can message: 4 bytes can_id + 1 byte can_dlc */ +#define CAN_FIXED_LEN 5 /* oscillator startup time * 128 cycles @ clock freq + some extra */ -static inline uint32_t ost_delay(candev_mcp2515_t *dev) +static inline uint32_t _osc_startup(candev_mcp2515_t *dev) { return (128 / (dev->conf->clk / 1000000) + 2); } @@ -55,7 +59,7 @@ static inline uint32_t ost_delay(candev_mcp2515_t *dev) * @return 0 on success * @return <0 on error */ -static int mcp2515_enable_irq(candev_mcp2515_t *dev, uint8_t irq); +static int _mcp2515_enable_irq(candev_mcp2515_t *dev, uint8_t irq); /** * @brief Fill tx/rx standard buffer instruction from filter identifier @p id @@ -73,27 +77,40 @@ static int mcp2515_enable_irq(candev_mcp2515_t *dev, uint8_t irq); * @param[in] id filter identifier in the MCP2515 mailbox * @param|out] bytebuf buffer instruction */ -static void fill_standard_id(uint32_t id, uint8_t *bytebuf); +static void _fill_standard_id(uint32_t id, uint8_t *bytebuf); /** * @brief Fill tx/rx extended buffer instruction from filter identifier @p id * - * for more details see fill_standard_id. + * for more details see _fill_standard_id. * * @param[in] id filter identifier in the MCP2515 mailbox * @param|out] bytebuf buffer instruction */ -static void fill_extended_id(uint32_t id, uint8_t *bytebuf); +static void _fill_extended_id(uint32_t id, uint8_t *bytebuf); -int mcp2515_init(candev_mcp2515_t *dev, void(*irq_handler_cb)(void*)) +int mcp2515_init(candev_mcp2515_t *dev, void (*irq_handler_cb)(void *)) { int res; - gpio_init_int(dev->conf->int_pin, GPIO_IN_PU, GPIO_FALLING, (gpio_cb_t)irq_handler_cb, (void *)dev); + + res = gpio_init_int(dev->conf->int_pin, GPIO_IN_PU, GPIO_FALLING, + (gpio_cb_t)irq_handler_cb, (void *)dev); + if (res != 0) { + DEBUG("Error setting interrupt pin!\n"); + return -1; + } gpio_init(dev->conf->rst_pin, GPIO_OUT); - /*the CS pin should be initialized & set in board.c to avoid conflict with other SPI devices */ res = mcp2515_spi_init(dev); - if (res < 0){ + if (res < 0) { + return -1; + } + + uint8_t cmd = MCP2515_RXB0CTRL_MODE_RECV_ALL; + + res = mcp2515_spi_write(dev, MCP2515_RXB0CTRL, &cmd, 1); + if (res < 0) { + DEBUG("failed to set acceptance mode\n"); return -1; } return 0; @@ -102,57 +119,73 @@ int mcp2515_init(candev_mcp2515_t *dev, void(*irq_handler_cb)(void*)) void mcp2515_reset(candev_mcp2515_t *dev) { gpio_clear(dev->conf->rst_pin); - xtimer_usleep(RESET_DELAY); + xtimer_usleep(RESET_DELAY_US); gpio_set(dev->conf->rst_pin); - xtimer_usleep(ost_delay(dev)); + xtimer_usleep(_osc_startup(dev)); } -static void fill_standard_id(uint32_t id, uint8_t *bytebuf) +static void _fill_standard_id(uint32_t id, uint8_t *bytebuf) { - bytebuf[0] = (uint8_t) ((id & 0x000007F8UL) >> 3); /* T/RXBnSIDH */ - bytebuf[1] = (uint8_t) ((id & 0x00000007UL) << 5); /* T/RXBnSIDL */ - bytebuf[2] = (uint8_t) ((id & 0xFF000000UL) >> 24); /* T/RXBnEID8 */ - bytebuf[3] = (uint8_t) ((id & 0x00FF0000UL) >> 16); /* T/RXBnEID0 */ + bytebuf[0] = (uint8_t)((id & 0x000007F8UL) >> 3); /* T/RXBnSIDH */ + bytebuf[1] = (uint8_t)((id & 0x00000007UL) << 5); /* T/RXBnSIDL */ + bytebuf[2] = (uint8_t)((id & 0xFF000000UL) >> 24); /* T/RXBnEID8 */ + bytebuf[3] = (uint8_t)((id & 0x00FF0000UL) >> 16); /* T/RXBnEID0 */ } -static void fill_extended_id(uint32_t id, uint8_t *bytebuf) +static void _fill_extended_id(uint32_t id, uint8_t *bytebuf) { - bytebuf[0] = (uint8_t) ((id & 0x1FE00000UL) >> 21); /* T/RXBnSIDH */ - bytebuf[1] = (uint8_t) ((id & 0x001C0000UL) >> 12) - | (uint8_t) ((id & 0x00030000UL) >> 16) | 0x08; /* T/RXBnSIDL */ - bytebuf[2] = (uint8_t) ((id & 0x0000FF00UL) >> 8); /* T/RXBnEID8 */ - bytebuf[3] = (uint8_t) (id & 0x000000FFUL); /* T/RXBnEID0 */ + bytebuf[0] = (uint8_t)((id & 0x1FE00000UL) >> 21); /* T/RXBnSIDH */ + bytebuf[1] = (uint8_t)((id & 0x001C0000UL) >> 13) + | (uint8_t)((id & 0x00030000UL) >> 16) | 0x08; /* T/RXBnSIDL */ + bytebuf[2] = (uint8_t)((id & 0x0000FF00UL) >> 8); /* T/RXBnEID8 */ + bytebuf[3] = (uint8_t)(id & 0x000000FFUL); /* T/RXBnEID0 */ } -int mcp2515_send(candev_mcp2515_t *dev, const struct can_frame *frame, int mailbox) +int mcp2515_send(candev_mcp2515_t *dev, const struct can_frame *frame, + int mailbox) { - uint8_t prio = 1; /* TODO: adjust priority */ + uint8_t prio = 1; uint8_t outbuf[BUFFER_SIZE]; uint8_t ctrl; - //TODO: for speedup, remove this check - mcp2515_spi_read(dev, TX_CTRL(mailbox), &ctrl, 1); + struct can_frame framebuf; + + if (frame->can_dlc > CAN_MAX_DLEN) { + return -1; + } + + framebuf.can_id = frame->can_id; + framebuf.can_dlc = frame->can_dlc; + for (int i = 0; i < framebuf.can_dlc; i++) { + framebuf.data[i] = frame->data[i]; + } + + mcp2515_spi_read(dev, MCP2515_TX_CTRL(mailbox), &ctrl, 1); if (ctrl & MCP2515_TXBCTRL_TXREQ) { DEBUG("Mailbox in use, TXB%dCTRL: 0x%02x\n", mailbox, ctrl); return -1; } - if ((frame->can_id & CAN_EFF_FLAG) == CAN_EFF_FLAG) { - fill_extended_id(frame->can_id, outbuf); + if (framebuf.can_id > CAN_SFF_MASK) { + framebuf.can_id |= CAN_EFF_FLAG; + } + + if ((framebuf.can_id & CAN_EFF_FLAG) == CAN_EFF_FLAG) { + _fill_extended_id(framebuf.can_id, outbuf); } else { - fill_standard_id(frame->can_id, outbuf); + _fill_standard_id(framebuf.can_id, outbuf); } - outbuf[4] = frame->can_dlc; - memcpy(outbuf+5, frame->data, frame->can_dlc); + outbuf[4] = framebuf.can_dlc; + memcpy(&outbuf[CAN_FIXED_LEN], framebuf.data, framebuf.can_dlc); /* set mailbox priority */ - mcp2515_spi_write(dev, TX_CTRL(mailbox), &prio, 1); + mcp2515_spi_write(dev, MCP2515_TX_CTRL(mailbox), &prio, 1); - mcp2515_spi_write_txbuf(dev, mailbox, outbuf, 5 + frame->can_dlc); - mcp2515_enable_irq(dev, MCP2515_CANINTE_TX0IE << mailbox); - //mcp2515_spi_bitmod(dev, TX_CTRL(mailbox), MCP2515_TXBCTRL_TXREQ, MCP2515_TXBCTRL_TXREQ); + mcp2515_spi_write_txbuf(dev, mailbox, outbuf, + CAN_FIXED_LEN + framebuf.can_dlc); + _mcp2515_enable_irq(dev, MCP2515_CANINTE_TX0IE << mailbox); mcp2515_spi_rts(dev, mailbox); return mailbox; @@ -166,17 +199,18 @@ int mcp2515_receive(candev_mcp2515_t *dev, struct can_frame *frame, int mailbox) /* extended id */ if (inbuf[1] & MCP2515_RX_IDE) { - frame->can_id = (inbuf[0] << 21) + - (((uint32_t)inbuf[1] & 0xE0) << 13) + - (((uint32_t)inbuf[1] & 0x03) << 16) + - ((uint32_t)inbuf[2] << 8) + - inbuf[3]; + frame->can_id = ((uint32_t)inbuf[0] << 21) + + (((uint32_t)inbuf[1] & 0xE0) << 13) + + (((uint32_t)inbuf[1] & 0x03) << 16) + + ((uint32_t)inbuf[2] << 8) + + inbuf[3]; frame->can_id |= CAN_EFF_FLAG; } /* standard id */ else { - frame->can_id = ((uint32_t)inbuf[0] << 3) + (((uint32_t)inbuf[1] & 0xE0) >> 5); + frame->can_id = ((uint32_t)inbuf[0] << 3) + + (((uint32_t)inbuf[1] & 0xE0) >> 5); } frame->can_dlc = inbuf[4]; @@ -186,7 +220,7 @@ int mcp2515_receive(candev_mcp2515_t *dev, struct can_frame *frame, int mailbox) int mcp2515_abort(candev_mcp2515_t *dev, int mailbox) { - return mcp2515_spi_bitmod(dev, TX_CTRL(mailbox), MCP2515_TXBCTRL_TXREQ, 0); + return mcp2515_spi_bitmod(dev, MCP2515_TX_CTRL(mailbox), MCP2515_TXBCTRL_TXREQ, 0); } enum mcp2515_mode mcp2515_get_mode(candev_mcp2515_t *dev) @@ -195,9 +229,9 @@ enum mcp2515_mode mcp2515_get_mode(candev_mcp2515_t *dev) uint8_t mode; int res = mcp2515_spi_read(dev, MCP2515_CANSTAT, &mode, 1); + if (res == 0) { - //TODO: error handling of extra information in mode result - result = (enum mcp2515_mode) mode & MCP2515_CANSTAT_OPMOD_MASK; + result = (enum mcp2515_mode)mode & MCP2515_CANSTAT_OPMOD_MASK; } DEBUG("mcp2515_get_mode: mode=%x\n", result); @@ -205,7 +239,8 @@ enum mcp2515_mode mcp2515_get_mode(candev_mcp2515_t *dev) return result; } -enum mcp2515_mode mcp2515_set_mode(candev_mcp2515_t *dev, enum mcp2515_mode mode) +enum mcp2515_mode mcp2515_set_mode(candev_mcp2515_t *dev, + enum mcp2515_mode mode) { DEBUG("mcp2515_set_mode: mode=%x\n", mode); @@ -214,6 +249,7 @@ enum mcp2515_mode mcp2515_set_mode(candev_mcp2515_t *dev, enum mcp2515_mode mode } enum mcp2515_mode cur_mode = mcp2515_get_mode(dev); + if (cur_mode == mode) { return mode; } @@ -221,8 +257,11 @@ enum mcp2515_mode mcp2515_set_mode(candev_mcp2515_t *dev, enum mcp2515_mode mode mcp2515_wake_up(dev); } - mcp2515_spi_bitmod(dev, MCP2515_CANCTRL, MCP2515_CANCTRL_REQOP_MASK, (uint8_t) mode); + mcp2515_spi_bitmod(dev, MCP2515_CANCTRL, MCP2515_CANCTRL_REQOP_MASK, + (uint8_t)mode); int cnt = 0; + + /* allow for two retries to set the mode */ while (cur_mode != mode && cnt++ < 2) { cur_mode = mcp2515_get_mode(dev); } @@ -232,10 +271,12 @@ enum mcp2515_mode mcp2515_set_mode(candev_mcp2515_t *dev, enum mcp2515_mode mode void mcp2515_wake_up(candev_mcp2515_t *dev) { dev->wakeup_src = MCP2515_WKUP_SRC_INTERNAL; - mcp2515_spi_bitmod(dev, MCP2515_CANINTF, MCP2515_CANINTF_WAKIF, MCP2515_CANINTF_WAKIF); - xtimer_usleep(ost_delay(dev)); + mcp2515_spi_bitmod(dev, MCP2515_CANINTF, MCP2515_CANINTF_WAKIF, + MCP2515_CANINTF_WAKIF); + xtimer_usleep(_osc_startup(dev)); uint8_t flag = mcp2515_get_irq(dev); + if (flag & INT_WAKEUP) { DEBUG("wakeup, irq raised\n"); dev->wakeup_src = 0; @@ -243,7 +284,7 @@ void mcp2515_wake_up(candev_mcp2515_t *dev) } } -static int mcp2515_enable_irq(candev_mcp2515_t *dev, uint8_t irq) +static int _mcp2515_enable_irq(candev_mcp2515_t *dev, uint8_t irq) { return mcp2515_spi_bitmod(dev, MCP2515_CANINTE, irq, irq); } @@ -256,7 +297,8 @@ int mcp2515_configure_bittiming(candev_mcp2515_t *dev) enum mcp2515_mode mode; DEBUG("mcp2515_configure_bittiming: brp=%" PRIu32 ", prop_seg=%" PRIu32 - ", phase_seg1=%" PRIu32 ", phase_seg2=%" PRIu32 "\n", tim->brp, tim->prop_seg, + ", phase_seg1=%" PRIu32 ", phase_seg2=%" PRIu32 "\n", tim->brp, + tim->prop_seg, tim->phase_seg1, tim->phase_seg2); mode = mcp2515_get_mode(dev); @@ -266,14 +308,17 @@ int mcp2515_configure_bittiming(candev_mcp2515_t *dev) } } + /* set Synchronization Jump Width Length */ c = ((tim->brp - 1) & 0x3F) | ((tim->sjw - 1) << 6); mcp2515_spi_write(dev, MCP2515_CNF1, &c, 1); mcp2515_spi_bitmod(dev, MCP2515_CNF2, MCP2515_CNF2_PRSEG_MASK | MCP2515_CNF2_PHSEG_MASK | MCP2515_CNF2_BTLMODE, - MCP2515_CNF2_BTLMODE | (tim->prop_seg - 1) | ((tim->phase_seg1 - 1) << 3)); - mcp2515_spi_bitmod(dev, MCP2515_CNF3, MCP2515_CNF3_PHSEG_MASK | MCP2515_CNF3_WAKFIL, + MCP2515_CNF2_BTLMODE | (tim->prop_seg - 1) | + ((tim->phase_seg1 - 1) << 3)); + mcp2515_spi_bitmod(dev, MCP2515_CNF3, + MCP2515_CNF3_PHSEG_MASK | MCP2515_CNF3_WAKFIL, (tim->phase_seg2 - 1) | MCP2515_CNF3_WAKFIL); if (mode != MODE_CONFIG) { @@ -285,27 +330,24 @@ int mcp2515_configure_bittiming(candev_mcp2515_t *dev) int mcp2515_init_irqs(candev_mcp2515_t *dev) { - return mcp2515_enable_irq(dev, - MCP2515_CANINTE_RX0IE | - MCP2515_CANINTE_RX1IE | - //MCP2515_CANINTE_TX0IE | - //MCP2515_CANINTE_TX1IE | - //MCP2515_CANINTE_TX2IE | - MCP2515_CANINTE_ERRIE | - //MCP2515_CANINTE_MERRE | - MCP2515_CANINTE_WAKIE); + return _mcp2515_enable_irq(dev, + MCP2515_CANINTE_RX0IE | + MCP2515_CANINTE_RX1IE | + MCP2515_CANINTE_ERRIE | + MCP2515_CANINTE_WAKIE); } enum mcp2515_interrupt mcp2515_get_irq(candev_mcp2515_t *dev) { uint8_t flag; + mcp2515_spi_read(dev, MCP2515_CANINTF, &flag, 1); - return (enum mcp2515_interrupt) flag; + return (enum mcp2515_interrupt)flag; } int mcp2515_clear_irq(candev_mcp2515_t *dev, enum mcp2515_interrupt irq) { - if(!irq) { /* no irq's to be cleared */ + if (!irq) { /* no irq's to be cleared */ return 0; } else { @@ -316,7 +358,8 @@ int mcp2515_clear_irq(candev_mcp2515_t *dev, enum mcp2515_interrupt irq) int mcp2515_tx_err_occurred(candev_mcp2515_t *dev, int mailbox) { uint8_t ctrl_reg; - mcp2515_spi_read(dev, TX_CTRL(mailbox), &ctrl_reg, 1); + + mcp2515_spi_read(dev, MCP2515_TX_CTRL(mailbox), &ctrl_reg, 1); if (ctrl_reg & MCP2515_TXBCTRL_TXERR) { return 1; } @@ -328,6 +371,7 @@ int mcp2515_tx_err_occurred(candev_mcp2515_t *dev, int mailbox) uint8_t mcp2515_get_errors(candev_mcp2515_t *dev) { uint8_t eflg; + mcp2515_spi_read(dev, MCP2515_EFLG, &eflg, 1); return eflg; } @@ -336,29 +380,31 @@ int mcp2515_set_filter(candev_mcp2515_t *dev, int filter_id, uint32_t filter) { uint8_t buf[4]; uint8_t reg; + if ((filter & CAN_EFF_FLAG) == CAN_EFF_FLAG) { - fill_extended_id(filter, buf); + _fill_extended_id(filter, buf); } else { - fill_standard_id(filter, buf); + _fill_standard_id(filter, buf); } - if(filter_id < 3) { + if (filter_id < 3) { reg = MCP2515_RXF0SIDH + (filter_id << 2); } else { reg = MCP2515_RXF3SIDH + ((filter_id - 3) << 2); } - return mcp2515_spi_write(dev, reg, buf, 4); + return mcp2515_spi_write(dev, reg, buf, sizeof(buf)); } int mcp2515_set_mask(candev_mcp2515_t *dev, int mailbox, uint32_t mask) { uint8_t buf[4]; + if ((mask & CAN_EFF_FLAG) == CAN_EFF_FLAG) { - fill_extended_id(mask, buf); + _fill_extended_id(mask, buf); } else { - fill_standard_id(mask, buf); + _fill_standard_id(mask, buf); } return mcp2515_spi_write(dev, MCP2515_RXM0SIDH + (mailbox << 2), buf, 4); } diff --git a/drivers/mcp2515/mcp2515.h b/drivers/mcp2515/mcp2515.h index 5941750d11..62cc31137d 100644 --- a/drivers/mcp2515/mcp2515.h +++ b/drivers/mcp2515/mcp2515.h @@ -32,40 +32,40 @@ extern "C" { * @brief MCP2515 mode */ enum mcp2515_mode { - MODE_NORMAL = MCP2515_CANSTAT_OPMOD_NORMAL, - MODE_SLEEP = MCP2515_CANSTAT_OPMOD_SLEEP, - MODE_LOOPBACK = MCP2515_CANSTAT_OPMOD_LOOPBACK, - MODE_LISTEN_ONLY = MCP2515_CANSTAT_OPMOD_LISTEN_ONLY, - MODE_CONFIG = MCP2515_CANSTAT_OPMOD_CONFIGURATION, - MODE_UNKNOWN = -1 + MODE_NORMAL = MCP2515_CANSTAT_OPMOD_NORMAL, + MODE_SLEEP = MCP2515_CANSTAT_OPMOD_SLEEP, + MODE_LOOPBACK = MCP2515_CANSTAT_OPMOD_LOOPBACK, + MODE_LISTEN_ONLY = MCP2515_CANSTAT_OPMOD_LISTEN_ONLY, + MODE_CONFIG = MCP2515_CANSTAT_OPMOD_CONFIGURATION, + MODE_UNKNOWN = -1 }; /** * @brief MCP2515 interrupt */ enum mcp2515_interrupt { - INT_RX0 = MCP2515_CANINTF_RX0IF, - INT_RX1 = MCP2515_CANINTF_RX1IF, - INT_TX0 = MCP2515_CANINTF_TX0IF, - INT_TX1 = MCP2515_CANINTF_TX1IF, - INT_TX2 = MCP2515_CANINTF_TX2IF, - INT_ERROR = MCP2515_CANINTF_ERRIF, - INT_WAKEUP = MCP2515_CANINTF_WAKIF, - INT_MESSAGE_ERROR = MCP2515_CANINTF_MERRF, + INT_RX0 = MCP2515_CANINTF_RX0IF, + INT_RX1 = MCP2515_CANINTF_RX1IF, + INT_TX0 = MCP2515_CANINTF_TX0IF, + INT_TX1 = MCP2515_CANINTF_TX1IF, + INT_TX2 = MCP2515_CANINTF_TX2IF, + INT_ERROR = MCP2515_CANINTF_ERRIF, + INT_WAKEUP = MCP2515_CANINTF_WAKIF, + INT_MESSAGE_ERROR = MCP2515_CANINTF_MERRF, }; /** * @brief MCP2515 error */ enum mcp2515_error { - ERR_WARNING = MCP2515_EFLG_EWARN, - ERR_RX_WARNING = MCP2515_EFLG_RXWAR, - ERR_TX_WARNING = MCP2515_EFLG_TXWAR, - ERR_RX_PASSIVE = MCP2515_EFLG_RXEP, - ERR_TX_PASSIVE = MCP2515_EFLG_TXEP, - ERR_TX_BUS_OFF = MCP2515_EFLG_TXBO, - ERR_RX_0_OVERFLOW = MCP2515_EFLG_RX0OVR, - ERR_RX_1_OVERFLOW = MCP2515_EFLG_RX1OVR, + ERR_WARNING = MCP2515_EFLG_EWARN, + ERR_RX_WARNING = MCP2515_EFLG_RXWAR, + ERR_TX_WARNING = MCP2515_EFLG_TXWAR, + ERR_RX_PASSIVE = MCP2515_EFLG_RXEP, + ERR_TX_PASSIVE = MCP2515_EFLG_TXEP, + ERR_TX_BUS_OFF = MCP2515_EFLG_TXBO, + ERR_RX_0_OVERFLOW = MCP2515_EFLG_RX0OVR, + ERR_RX_1_OVERFLOW = MCP2515_EFLG_RX1OVR, }; /** Wake up source */ @@ -74,7 +74,7 @@ enum mcp2515_error { /** * @brief Initialize pins and SPI interface * - * The device descriptor contains all informations related to pins and SPI + * The device descriptor contains all information related to pins and SPI * interface. This function initialize all corresponding fields and relies * the @p irq_cb callback function to the pin interruption. The pin * interruption should be configured in the device descriptor. @@ -87,7 +87,7 @@ enum mcp2515_error { * @return 0 on success * @return <0 on error */ -int mcp2515_init(candev_mcp2515_t *dev, void(*irq_cb)(void*)); +int mcp2515_init(candev_mcp2515_t *dev, void (*irq_cb)(void *)); /** * @brief Reset MCP2515 device with dedicated pin @@ -118,7 +118,8 @@ int mcp2515_init_irqs(candev_mcp2515_t *dev); * @return 0 on success * @return <0 on error */ -int mcp2515_send(candev_mcp2515_t *dev, const struct can_frame *frame, int mailbox); +int mcp2515_send(candev_mcp2515_t *dev, const struct can_frame *frame, + int mailbox); /** * @brief Receive frame from the corresponding rx @p mailbox. @@ -130,7 +131,8 @@ int mcp2515_send(candev_mcp2515_t *dev, const struct can_frame *frame, int mailb * @return 0 on success * @return <0 on error */ -int mcp2515_receive(candev_mcp2515_t *dev, struct can_frame *frame, int mailbox); +int mcp2515_receive(candev_mcp2515_t *dev, struct can_frame *frame, + int mailbox); /** * @brief Abort communication. @@ -160,7 +162,8 @@ enum mcp2515_mode mcp2515_get_mode(candev_mcp2515_t *dev); * * @return The mode actually set */ -enum mcp2515_mode mcp2515_set_mode(candev_mcp2515_t *dev, enum mcp2515_mode mode); +enum mcp2515_mode mcp2515_set_mode(candev_mcp2515_t *dev, + enum mcp2515_mode mode); /** * @brief Wake up MCP2515 @@ -203,7 +206,7 @@ int mcp2515_tx_err_occurred(candev_mcp2515_t *dev, int mailbox); /** * @brief Configure the bit timing of the MCP2515. * - * The informations about the bit timing should be contained in dev descriptor. + * The information about the bit timing should be contained in dev descriptor. * * @param[in] dev device descriptor * diff --git a/drivers/mcp2515/mcp2515_defines.h b/drivers/mcp2515/mcp2515_defines.h index e615ea5360..bf9cb641c8 100644 --- a/drivers/mcp2515/mcp2515_defines.h +++ b/drivers/mcp2515/mcp2515_defines.h @@ -28,28 +28,6 @@ extern "C" { #endif -/** - * User configuration - * @{ - */ -#define CAN_SPI_CS_PORTBIT BIT4 -#define CAN_SPI_CS_PORTOUT P2OUT -#define CAN_SPI_CS_PORTDIR P2DIR - -#define CAN_IRQ_PORTBIT BIT3 -#define CAN_IRQ_PORTOUT P1OUT -#define CAN_IRQ_PORTDIR P1DIR -#define CAN_IRQ_PORTREN P1REN -#define CAN_IRQ_PORTIES P1IES -#define CAN_IRQ_PORTIE P1IE -#define CAN_IRQ_PORTIFG P1IFG -/** @} */ - -/** - * BoosterPack contains 8MHz crystal w/ 22pF load caps - */ -#define CAN_OSC_FREQUENCY 8000000 - /** * @name MCP2515 Register Memory Map * { @@ -214,12 +192,13 @@ extern "C" { #define MCP2515_CANSTAT_ICOD_MASK 0x0E -#define MCP2515_CANSTAT_OPMOD_MASK 0xE0 +#define MCP2515_CANSTAT_OPMOD_MASK 0xE0 #define MCP2515_CANSTAT_OPMOD_CONFIGURATION MCP2515_CANSTAT_OPMOD2 -#define MCP2515_CANSTAT_OPMOD_NORMAL 0x00 -#define MCP2515_CANSTAT_OPMOD_SLEEP MCP2515_CANSTAT_OPMOD0 -#define MCP2515_CANSTAT_OPMOD_LOOPBACK MCP2515_CANSTAT_OPMOD1 -#define MCP2515_CANSTAT_OPMOD_LISTEN_ONLY (MCP2515_CANSTAT_OPMOD1 | MCP2515_CANSTAT_OPMOD0) +#define MCP2515_CANSTAT_OPMOD_NORMAL 0x00 +#define MCP2515_CANSTAT_OPMOD_SLEEP MCP2515_CANSTAT_OPMOD0 +#define MCP2515_CANSTAT_OPMOD_LOOPBACK MCP2515_CANSTAT_OPMOD1 +#define MCP2515_CANSTAT_OPMOD_LISTEN_ONLY (MCP2515_CANSTAT_OPMOD1 | \ + MCP2515_CANSTAT_OPMOD0) #define MCP2515_CANCTRL_CLKPRE0 0x01 #define MCP2515_CANCTRL_CLKPRE1 0x02 @@ -230,14 +209,16 @@ extern "C" { #define MCP2515_CANCTRL_REQOP1 0x40 #define MCP2515_CANCTRL_REQOP2 0x80 -#define MCP2515_CANCTRL_CLKPRE_MASK (MCP2515_CANCTRL_CLKPRE1 | MCP2515_CANCTRL_CLKPRE0) +#define MCP2515_CANCTRL_CLKPRE_MASK (MCP2515_CANCTRL_CLKPRE1 | \ + MCP2515_CANCTRL_CLKPRE0) -#define MCP2515_CANCTRL_REQOP_MASK 0xE0 +#define MCP2515_CANCTRL_REQOP_MASK 0xE0 #define MCP2515_CANCTRL_REQOP_CONFIGURATION MCP2515_CANCTRL_REQOP2 -#define MCP2515_CANCTRL_REQOP_NORMAL 0x00 -#define MCP2515_CANCTRL_REQOP_SLEEP MCP2515_CANCTRL_REQOP0 -#define MCP2515_CANCTRL_REQOP_LOOPBACK MCP2515_CANCTRL_REQOP1 -#define MCP2515_CANCTRL_REQOP_LISTEN_ONLY (MCP2515_CANCTRL_REQOP1 | MCP2515_CANCTRL_REQOP0) +#define MCP2515_CANCTRL_REQOP_NORMAL 0x00 +#define MCP2515_CANCTRL_REQOP_SLEEP MCP2515_CANCTRL_REQOP0 +#define MCP2515_CANCTRL_REQOP_LOOPBACK MCP2515_CANCTRL_REQOP1 +#define MCP2515_CANCTRL_REQOP_LISTEN_ONLY (MCP2515_CANCTRL_REQOP1 | \ + MCP2515_CANCTRL_REQOP0) #define MCP2515_CNF3_PHSEG20 0x01 #define MCP2515_CNF3_PHSEG21 0x02 @@ -315,27 +296,29 @@ extern "C" { #define MCP2515_TXBCTRL_MLOA 0x20 #define MCP2515_TXBCTRL_ABTF 0x40 -#define MCP2515_RXB0CTRL_FILHIT0 0x01 -#define MCP2515_RXB0CTRL_BUKT1 0x02 -#define MCP2515_RXB0CTRL_BUKT 0x04 -#define MCP2515_RXB0CTRL_RXRTR 0x08 -#define MCP2515_RXB0CTRL_RXM0 0x20 -#define MCP2515_RXB0CTRL_RXM1 0x40 -#define MCP2515_RXB0CTRL_MODE_RECV_STD_OR_EXT 0x00 -#define MCP2515_RXB0CTRL_MODE_RECV_STD MCP2515_RXB0CTRL_RXM0 -#define MCP2515_RXB0CTRL_MODE_RECV_EXT MCP2515_RXB0CTRL_RXM1 -#define MCP2515_RXB0CTRL_MODE_RECV_ALL (MCP2515_RXB0CTRL_RXM1 | MCP2515_RXB0CTRL_RXM0) +#define MCP2515_RXB0CTRL_FILHIT0 0x01 +#define MCP2515_RXB0CTRL_BUKT1 0x02 +#define MCP2515_RXB0CTRL_BUKT 0x04 +#define MCP2515_RXB0CTRL_RXRTR 0x08 +#define MCP2515_RXB0CTRL_RXM0 0x20 +#define MCP2515_RXB0CTRL_RXM1 0x40 +#define MCP2515_RXB0CTRL_MODE_RECV_STD_OR_EXT 0x00 +#define MCP2515_RXB0CTRL_MODE_RECV_STD MCP2515_RXB0CTRL_RXM0 +#define MCP2515_RXB0CTRL_MODE_RECV_EXT MCP2515_RXB0CTRL_RXM1 +#define MCP2515_RXB0CTRL_MODE_RECV_ALL (MCP2515_RXB0CTRL_RXM1 | \ + MCP2515_RXB0CTRL_RXM0) -#define MCP2515_RXB1CTRL_FILHIT0 0x01 -#define MCP2515_RXB1CTRL_FILHIT1 0x02 -#define MCP2515_RXB1CTRL_FILHIT2 0x04 -#define MCP2515_RXB1CTRL_RXRTR 0x08 -#define MCP2515_RXB1CTRL_RXM0 0x20 -#define MCP2515_RXB1CTRL_RXM1 0x40 -#define MCP2515_RXB1CTRL_MODE_RECV_STD_OR_EXT 0x00 -#define MCP2515_RXB1CTRL_MODE_RECV_STD MCP2515_RXB1CTRL_RXM0 -#define MCP2515_RXB1CTRL_MODE_RECV_EXT MCP2515_RXB1CTRL_RXM1 -#define MCP2515_RXB1CTRL_MODE_RECV_ALL (MCP2515_RXB1CTRL_RXM1 | MCP2515_RXB1CTRL_RXM0) +#define MCP2515_RXB1CTRL_FILHIT0 0x01 +#define MCP2515_RXB1CTRL_FILHIT1 0x02 +#define MCP2515_RXB1CTRL_FILHIT2 0x04 +#define MCP2515_RXB1CTRL_RXRTR 0x08 +#define MCP2515_RXB1CTRL_RXM0 0x20 +#define MCP2515_RXB1CTRL_RXM1 0x40 +#define MCP2515_RXB1CTRL_MODE_RECV_STD_OR_EXT 0x00 +#define MCP2515_RXB1CTRL_MODE_RECV_STD MCP2515_RXB1CTRL_RXM0 +#define MCP2515_RXB1CTRL_MODE_RECV_EXT MCP2515_RXB1CTRL_RXM1 +#define MCP2515_RXB1CTRL_MODE_RECV_ALL (MCP2515_RXB1CTRL_RXM1 | \ + MCP2515_RXB1CTRL_RXM0) /** @} */ /** @@ -357,51 +340,51 @@ extern "C" { * @name MCP2515 RX buffer id * { */ -#define MCP2515_RXBUF_RXB0SIDH 0x00 -#define MCP2515_RXBUF_RXB0D0 0x02 -#define MCP2515_RXBUF_RXB1SIDH 0x04 -#define MCP2515_RXBUF_RXB1D0 0x06 +#define MCP2515_RXBUF_RXB0SIDH 0x00 +#define MCP2515_RXBUF_RXB0D0 0x02 +#define MCP2515_RXBUF_RXB1SIDH 0x04 +#define MCP2515_RXBUF_RXB1D0 0x06 /** @} */ /** * @name MCP2515 TX buffer id * { */ -#define MCP2515_TXBUF_TXB0SIDH 0x00 -#define MCP2515_TXBUF_TXB0D0 0x01 -#define MCP2515_TXBUF_TXB1SIDH 0x02 -#define MCP2515_TXBUF_TXB1D0 0x03 -#define MCP2515_TXBUF_TXB2SIDH 0x04 -#define MCP2515_TXBUF_TXB2D0 0x05 +#define MCP2515_TXBUF_TXB0SIDH 0x00 +#define MCP2515_TXBUF_TXB0D0 0x01 +#define MCP2515_TXBUF_TXB1SIDH 0x02 +#define MCP2515_TXBUF_TXB1D0 0x03 +#define MCP2515_TXBUF_TXB2SIDH 0x04 +#define MCP2515_TXBUF_TXB2D0 0x05 /** @} */ /** * @name MCP2515 option ID for ioctl function * { */ -#define MCP2515_OPTION_ROLLOVER 1 -#define MCP2515_OPTION_ONESHOT 2 -#define MCP2515_OPTION_ABORT 3 -#define MCP2515_OPTION_CLOCKOUT 4 -#define MCP2515_OPTION_LOOPBACK 5 -#define MCP2515_OPTION_LISTEN_ONLY 6 -#define MCP2515_OPTION_SLEEP 7 -#define MCP2515_OPTION_MULTISAMPLE 8 -#define MCP2515_OPTION_SOFOUT 9 -#define MCP2515_OPTION_WAKE_GLITCH_FILTER 10 -#define MCP2515_OPTION_WAKE 11 +#define MCP2515_OPTION_ROLLOVER 1 +#define MCP2515_OPTION_ONESHOT 2 +#define MCP2515_OPTION_ABORT 3 +#define MCP2515_OPTION_CLOCKOUT 4 +#define MCP2515_OPTION_LOOPBACK 5 +#define MCP2515_OPTION_LISTEN_ONLY 6 +#define MCP2515_OPTION_SLEEP 7 +#define MCP2515_OPTION_MULTISAMPLE 8 +#define MCP2515_OPTION_SOFOUT 9 +#define MCP2515_OPTION_WAKE_GLITCH_FILTER 10 +#define MCP2515_OPTION_WAKE 11 /** @} */ /** * @name MCP2515 IRQ handling * { */ -#define MCP2515_IRQ_FLAGGED 0x80 -#define MCP2515_IRQ_HANDLED 0x40 -#define MCP2515_IRQ_RX 0x01 -#define MCP2515_IRQ_TX 0x02 -#define MCP2515_IRQ_ERROR 0x04 -#define MCP2515_IRQ_WAKEUP 0x08 +#define MCP2515_IRQ_FLAGGED 0x80 +#define MCP2515_IRQ_HANDLED 0x40 +#define MCP2515_IRQ_RX 0x01 +#define MCP2515_IRQ_TX 0x02 +#define MCP2515_IRQ_ERROR 0x04 +#define MCP2515_IRQ_WAKEUP 0x08 /** @} */ /** diff --git a/drivers/mcp2515/mcp2515_spi.c b/drivers/mcp2515/mcp2515_spi.c index 2eff521b4c..0a48d0f919 100644 --- a/drivers/mcp2515/mcp2515_spi.c +++ b/drivers/mcp2515/mcp2515_spi.c @@ -1,4 +1,3 @@ - /* * Copyright (C) 2016 OTA keys * @@ -35,11 +34,12 @@ int mcp2515_spi_init(const candev_mcp2515_t *dev) { int res; + /* Configure SPI */ res = spi_init_cs(dev->conf->spi, dev->conf->cs_pin); if (res != SPI_OK) { DEBUG("spi_init_master: error initializing SPI_%i device (code %i)\n", - dev->conf->spi, res); + dev->conf->spi, res); return -1; } return 0; @@ -47,8 +47,10 @@ int mcp2515_spi_init(const candev_mcp2515_t *dev) int mcp2515_spi_reset(const candev_mcp2515_t *dev) { - spi_acquire(dev->conf->spi, dev->conf->cs_pin, dev->conf->spi_mode, dev->conf->spi_clk); - spi_transfer_byte(dev->conf->spi, dev->conf->cs_pin, false, MCP2515_SPI_RESET); + spi_acquire(dev->conf->spi, dev->conf->cs_pin, dev->conf->spi_mode, + dev->conf->spi_clk); + spi_transfer_byte(dev->conf->spi, dev->conf->cs_pin, false, + MCP2515_SPI_RESET); spi_release(dev->conf->spi); return 0; } @@ -56,9 +58,12 @@ int mcp2515_spi_reset(const candev_mcp2515_t *dev) int mcp2515_spi_read(const candev_mcp2515_t *dev, uint8_t addr, uint8_t *buf, unsigned int len) { - spi_acquire(dev->conf->spi, dev->conf->cs_pin, dev->conf->spi_mode, dev->conf->spi_clk); - spi_transfer_byte(dev->conf->spi, dev->conf->cs_pin, true, MCP2515_SPI_READ); - spi_transfer_regs(dev->conf->spi, dev->conf->cs_pin, addr, NULL, (void *)buf, len); + spi_acquire(dev->conf->spi, dev->conf->cs_pin, dev->conf->spi_mode, + dev->conf->spi_clk); + spi_transfer_byte(dev->conf->spi, dev->conf->cs_pin, true, + MCP2515_SPI_READ); + spi_transfer_regs(dev->conf->spi, dev->conf->cs_pin, addr, NULL, + (void *)buf, len); spi_release(dev->conf->spi); return 0; } @@ -66,9 +71,13 @@ int mcp2515_spi_read(const candev_mcp2515_t *dev, uint8_t addr, uint8_t *buf, int mcp2515_spi_read_rxbuf(const candev_mcp2515_t *dev, uint8_t mailbox, void *buf, uint8_t len) { - spi_acquire(dev->conf->spi, dev->conf->cs_pin, dev->conf->spi_mode, dev->conf->spi_clk); - spi_transfer_byte(dev->conf->spi, dev->conf->cs_pin, true, MCP2515_SPI_READ_RXBUF | (mailbox << 2)); - spi_transfer_bytes(dev->conf->spi, dev->conf->cs_pin, false, NULL, (void *)buf, len); + /* See TABLE 12-1:SPI INSTRUCTION SET in mcp2515 datasheet */ + spi_acquire(dev->conf->spi, dev->conf->cs_pin, dev->conf->spi_mode, + dev->conf->spi_clk); + spi_transfer_byte(dev->conf->spi, dev->conf->cs_pin, true, + MCP2515_SPI_READ_RXBUF | (mailbox << 2)); + spi_transfer_bytes(dev->conf->spi, dev->conf->cs_pin, false, NULL, + (void *)buf, len); spi_release(dev->conf->spi); return 0; } @@ -76,9 +85,12 @@ int mcp2515_spi_read_rxbuf(const candev_mcp2515_t *dev, uint8_t mailbox, int mcp2515_spi_write(const candev_mcp2515_t *dev, uint8_t addr, uint8_t *buf, unsigned int len) { - spi_acquire(dev->conf->spi, dev->conf->cs_pin, dev->conf->spi_mode, dev->conf->spi_clk); - spi_transfer_byte(dev->conf->spi, dev->conf->cs_pin, true, MCP2515_SPI_WRITE); - spi_transfer_regs(dev->conf->spi, dev->conf->cs_pin, addr, (void *)buf, NULL, len); + spi_acquire(dev->conf->spi, dev->conf->cs_pin, dev->conf->spi_mode, + dev->conf->spi_clk); + spi_transfer_byte(dev->conf->spi, dev->conf->cs_pin, true, + MCP2515_SPI_WRITE); + spi_transfer_regs(dev->conf->spi, dev->conf->cs_pin, addr, (void *)buf, + NULL, len); spi_release(dev->conf->spi); return 0; } @@ -86,17 +98,22 @@ int mcp2515_spi_write(const candev_mcp2515_t *dev, uint8_t addr, uint8_t *buf, int mcp2515_spi_write_txbuf(const candev_mcp2515_t *dev, uint8_t mailbox, void *buf, uint8_t len) { - spi_acquire(dev->conf->spi, dev->conf->cs_pin, dev->conf->spi_mode, dev->conf->spi_clk); - spi_transfer_byte(dev->conf->spi, dev->conf->cs_pin, true, MCP2515_SPI_LOAD_TXBUF | (mailbox << 1)); - spi_transfer_bytes(dev->conf->spi, dev->conf->cs_pin, false, (void *)buf, NULL, len); + spi_acquire(dev->conf->spi, dev->conf->cs_pin, dev->conf->spi_mode, + dev->conf->spi_clk); + spi_transfer_byte(dev->conf->spi, dev->conf->cs_pin, true, + MCP2515_SPI_LOAD_TXBUF | (mailbox << 1)); + spi_transfer_bytes(dev->conf->spi, dev->conf->cs_pin, false, (void *)buf, + NULL, len); spi_release(dev->conf->spi); return 0; } int mcp2515_spi_rts(const candev_mcp2515_t *dev, uint8_t mailbox) { - spi_acquire(dev->conf->spi, dev->conf->cs_pin, dev->conf->spi_mode, dev->conf->spi_clk); - spi_transfer_byte(dev->conf->spi, dev->conf->cs_pin, false, MCP2515_SPI_RTS | (1 << mailbox)); + spi_acquire(dev->conf->spi, dev->conf->cs_pin, dev->conf->spi_mode, + dev->conf->spi_clk); + spi_transfer_byte(dev->conf->spi, dev->conf->cs_pin, false, + MCP2515_SPI_RTS | (1 << mailbox)); spi_release(dev->conf->spi); return 0; } @@ -104,8 +121,11 @@ int mcp2515_spi_rts(const candev_mcp2515_t *dev, uint8_t mailbox) uint8_t mcp2515_spi_read_status(const candev_mcp2515_t *dev) { uint8_t status; - spi_acquire(dev->conf->spi, dev->conf->cs_pin, dev->conf->spi_mode, dev->conf->spi_clk); - spi_transfer_byte(dev->conf->spi, dev->conf->cs_pin, true, MCP2515_SPI_READ_STATUS); + + spi_acquire(dev->conf->spi, dev->conf->cs_pin, dev->conf->spi_mode, + dev->conf->spi_clk); + spi_transfer_byte(dev->conf->spi, dev->conf->cs_pin, true, + MCP2515_SPI_READ_STATUS); status = spi_transfer_byte(dev->conf->spi, dev->conf->cs_pin, false, 0); spi_release(dev->conf->spi); return status; @@ -114,8 +134,11 @@ uint8_t mcp2515_spi_read_status(const candev_mcp2515_t *dev) int mcp2515_spi_rx_status(const candev_mcp2515_t *dev) { uint8_t status; - spi_acquire(dev->conf->spi, dev->conf->cs_pin, dev->conf->spi_mode, dev->conf->spi_clk); - spi_transfer_byte(dev->conf->spi, dev->conf->cs_pin, true, MCP2515_SPI_RX_STATUS); + + spi_acquire(dev->conf->spi, dev->conf->cs_pin, dev->conf->spi_mode, + dev->conf->spi_clk); + spi_transfer_byte(dev->conf->spi, dev->conf->cs_pin, true, + MCP2515_SPI_RX_STATUS); status = spi_transfer_byte(dev->conf->spi, dev->conf->cs_pin, false, 0); spi_release(dev->conf->spi); return status; @@ -126,13 +149,16 @@ int mcp2515_spi_bitmod(const candev_mcp2515_t *dev, uint8_t addr, uint8_t mask, { uint8_t msg[2]; - spi_acquire(dev->conf->spi, dev->conf->cs_pin, dev->conf->spi_mode, dev->conf->spi_clk); - spi_transfer_byte(dev->conf->spi, dev->conf->cs_pin, true, MCP2515_SPI_BITMOD); + spi_acquire(dev->conf->spi, dev->conf->cs_pin, dev->conf->spi_mode, + dev->conf->spi_clk); + spi_transfer_byte(dev->conf->spi, dev->conf->cs_pin, true, + MCP2515_SPI_BITMOD); msg[0] = mask; msg[1] = buf; - spi_transfer_regs(dev->conf->spi, dev->conf->cs_pin, addr, (const void*)msg, NULL, sizeof(msg)); + spi_transfer_regs(dev->conf->spi, dev->conf->cs_pin, addr, + (const void *)msg, NULL, sizeof(msg)); spi_release(dev->conf->spi); return 0; } diff --git a/drivers/mcp2515/mcp2515_spi.h b/drivers/mcp2515/mcp2515_spi.h index 30726197c6..e7b8a9762b 100644 --- a/drivers/mcp2515/mcp2515_spi.h +++ b/drivers/mcp2515/mcp2515_spi.h @@ -31,7 +31,7 @@ extern "C" { /** * @brief Initialize SPI interface * - * The device descriptor contains all informations related to the SPI interface. + * The device descriptor contains all information related to the SPI interface. * * @param[out] dev device descriptor * @@ -127,8 +127,7 @@ int mcp2515_spi_rts(const candev_mcp2515_t *dev, uint8_t mailbox); * * @param[in] dev device descriptor * - * @return 0 on success - * @return <0 on error + * @return the read status */ uint8_t mcp2515_spi_read_status(const candev_mcp2515_t *dev); @@ -153,7 +152,7 @@ int mcp2515_spi_rx_status(const candev_mcp2515_t *dev); * @param[in] dev device descriptor * @param[in] addr register address * @param[in] mask mask to modify individual bit - * @param[in] buf regsiter value + * @param[in] buf register value * * @return 0 on success * @return <0 on error diff --git a/sys/auto_init/can/auto_init_mcp2515.c b/sys/auto_init/can/auto_init_mcp2515.c index 90527eeaea..f7e892aa43 100644 --- a/sys/auto_init/can/auto_init_mcp2515.c +++ b/sys/auto_init/can/auto_init_mcp2515.c @@ -7,7 +7,7 @@ */ /** - * @ingroup auto_init + * @ingroup sys_auto_init * @{ * @file * @brief initializes mcp2515 can device @@ -20,7 +20,7 @@ #include "can/device.h" #include "mcp2515_params.h" -#define CANDEV_MCP2515_NUMOF ((sizeof(candev_mcp2515_params) / sizeof(candev_params_t))) +#define CANDEV_MCP2515_NUMOF ((ARRAY_SIZE(candev_mcp2515_params) / ARRAY_SIZE(candev_params_t))) #ifndef CANDEV_MCP2515_STACKSIZE #define CANDEV_MCP2515_STACKSIZE (THREAD_STACKSIZE_DEFAULT + THREAD_EXTRA_STACKSIZE_PRINTF) @@ -40,7 +40,7 @@ void auto_init_can_mcp2515(void) { candev_mcp2515_init(&candev_mcp2515[i], &candev_mcp2515_conf[i]); candev_dev_mcp2515[i].dev = (candev_t *)&candev_mcp2515[i]; candev_dev_mcp2515[i].name = candev_mcp2515_params[i].name; -#ifdef MODULE_TRX +#ifdef MODULE_CAN_TRX candev_dev_mcp2515[i].trx = candev_mcp2515_params[i].trx; #endif #ifdef MODULE_CAN_PM @@ -48,8 +48,11 @@ void auto_init_can_mcp2515(void) { candev_dev_mcp2515[i].tx_wakeup_timeout = candev_mcp2515_params[i].tx_wakeup_timeout; #endif - can_device_init(_can_mcp2515_stacks[i], CANDEV_MCP2515_STACKSIZE, CANDEV_MCP2515_BASE_PRIORITY + i, - candev_mcp2515_params[i].name, &candev_dev_mcp2515[i]); + can_device_init(_can_mcp2515_stacks[i], + CANDEV_MCP2515_STACKSIZE, + CANDEV_MCP2515_BASE_PRIORITY + i, + candev_mcp2515_params[i].name, + &candev_dev_mcp2515[i]); } } #else