drivers: CAN: MCP2515: Add and use Read RX Buffer instruction
Reduces SPI RX buffer read overhead by a byte and further reduces the SPI use by automatically clearing the associated receive flag RXxIF. Signed-off-by: Nick Ward <nix.ward@gmail.com>
This commit is contained in:
parent
d5a5d960e6
commit
0c5ef3e156
2 changed files with 57 additions and 8 deletions
|
@ -139,6 +139,43 @@ static int mcp2515_cmd_read_reg(struct device *dev, u8_t reg_addr,
|
||||||
&tx, &rx);
|
&tx, &rx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read RX Buffer instruction
|
||||||
|
*
|
||||||
|
* When reading a receive buffer, reduces the overhead of a normal READ
|
||||||
|
* command by placing the Address Pointer at one of four locations selected by
|
||||||
|
* parameter nm:
|
||||||
|
* 0: Receive Buffer 0, Start at RXB0SIDH (0x61)
|
||||||
|
* 1: Receive Buffer 0, Start at RXB0D0 (0x66)
|
||||||
|
* 2: Receive Buffer 1, Start at RXB1SIDH (0x71)
|
||||||
|
* 3: Receive Buffer 1, Start at RXB1D0 (0x76)
|
||||||
|
*/
|
||||||
|
static int mcp2515_cmd_read_rx_buffer(struct device *dev, u8_t nm,
|
||||||
|
u8_t *buf_data, u8_t buf_len)
|
||||||
|
{
|
||||||
|
__ASSERT(nm <= 0x03, "nm <= 0x03");
|
||||||
|
|
||||||
|
u8_t cmd_buf[] = { MCP2515_OPCODE_READ_RX_BUFFER | (nm << 1) };
|
||||||
|
|
||||||
|
struct spi_buf tx_buf[] = {
|
||||||
|
{ .buf = cmd_buf, .len = sizeof(cmd_buf) },
|
||||||
|
{ .buf = NULL, .len = buf_len }
|
||||||
|
};
|
||||||
|
const struct spi_buf_set tx = {
|
||||||
|
.buffers = tx_buf, .count = ARRAY_SIZE(tx_buf)
|
||||||
|
};
|
||||||
|
struct spi_buf rx_buf[] = {
|
||||||
|
{ .buf = NULL, .len = sizeof(cmd_buf) },
|
||||||
|
{ .buf = buf_data, .len = buf_len }
|
||||||
|
};
|
||||||
|
const struct spi_buf_set rx = {
|
||||||
|
.buffers = rx_buf, .count = ARRAY_SIZE(rx_buf)
|
||||||
|
};
|
||||||
|
|
||||||
|
return spi_transceive(DEV_DATA(dev)->spi, &DEV_DATA(dev)->spi_cfg,
|
||||||
|
&tx, &rx);
|
||||||
|
}
|
||||||
|
|
||||||
static u8_t mcp2515_convert_canmode_to_mcp2515mode(enum can_mode mode)
|
static u8_t mcp2515_convert_canmode_to_mcp2515mode(enum can_mode mode)
|
||||||
{
|
{
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
@ -499,15 +536,17 @@ static void mcp2515_rx_filter(struct device *dev, struct zcan_frame *msg)
|
||||||
|
|
||||||
static void mcp2515_rx(struct device *dev, u8_t rx_idx)
|
static void mcp2515_rx(struct device *dev, u8_t rx_idx)
|
||||||
{
|
{
|
||||||
|
__ASSERT(rx_idx < MCP2515_RX_CNT, "rx_idx < MCP2515_RX_CNT");
|
||||||
|
|
||||||
struct zcan_frame msg;
|
struct zcan_frame msg;
|
||||||
u8_t rx_frame[MCP2515_FRAME_LEN];
|
u8_t rx_frame[MCP2515_FRAME_LEN];
|
||||||
u8_t addr_rx_ctrl = MCP2515_ADDR_RXB0CTRL +
|
u8_t nm;
|
||||||
(rx_idx * MCP2515_ADDR_OFFSET_FRAME2FRAME);
|
|
||||||
|
/* Address Pointer selection */
|
||||||
|
nm = 2 * rx_idx;
|
||||||
|
|
||||||
/* Fetch rx buffer */
|
/* Fetch rx buffer */
|
||||||
mcp2515_cmd_read_reg(dev,
|
mcp2515_cmd_read_rx_buffer(dev, nm, rx_frame, sizeof(rx_frame));
|
||||||
addr_rx_ctrl + MCP2515_ADDR_OFFSET_CTRL2FRAME,
|
|
||||||
rx_frame, sizeof(rx_frame));
|
|
||||||
mcp2515_convert_mcp2515frame_to_zcanframe(rx_frame, &msg);
|
mcp2515_convert_mcp2515frame_to_zcanframe(rx_frame, &msg);
|
||||||
mcp2515_rx_filter(dev, &msg);
|
mcp2515_rx_filter(dev, &msg);
|
||||||
}
|
}
|
||||||
|
@ -611,10 +650,16 @@ static void mcp2515_handle_interrupts(struct device *dev)
|
||||||
|
|
||||||
if (canintf & MCP2515_CANINTF_RX0IF) {
|
if (canintf & MCP2515_CANINTF_RX0IF) {
|
||||||
mcp2515_rx(dev, 0);
|
mcp2515_rx(dev, 0);
|
||||||
|
|
||||||
|
/* RX0IF flag cleared automatically during read */
|
||||||
|
canintf &= ~MCP2515_CANINTF_RX0IF;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canintf & MCP2515_CANINTF_RX1IF) {
|
if (canintf & MCP2515_CANINTF_RX1IF) {
|
||||||
mcp2515_rx(dev, 1);
|
mcp2515_rx(dev, 1);
|
||||||
|
|
||||||
|
/* RX1IF flag cleared automatically during read */
|
||||||
|
canintf &= ~MCP2515_CANINTF_RX1IF;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canintf & MCP2515_CANINTF_TX0IF) {
|
if (canintf & MCP2515_CANINTF_TX0IF) {
|
||||||
|
@ -633,9 +678,11 @@ static void mcp2515_handle_interrupts(struct device *dev)
|
||||||
mcp2515_handle_errors(dev);
|
mcp2515_handle_errors(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clear the flags we handled */
|
if (canintf != 0) {
|
||||||
mcp2515_cmd_bit_modify(dev, MCP2515_ADDR_CANINTF, canintf,
|
/* Clear remaining flags */
|
||||||
~canintf);
|
mcp2515_cmd_bit_modify(dev, MCP2515_ADDR_CANINTF,
|
||||||
|
canintf, ~canintf);
|
||||||
|
}
|
||||||
|
|
||||||
/* Break from loop if INT pin is no longer low */
|
/* Break from loop if INT pin is no longer low */
|
||||||
ret = gpio_pin_read(dev_data->int_gpio, dev_cfg->int_pin, &pin);
|
ret = gpio_pin_read(dev_data->int_gpio, dev_cfg->int_pin, &pin);
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <drivers/can.h>
|
#include <drivers/can.h>
|
||||||
|
|
||||||
|
#define MCP2515_RX_CNT 2
|
||||||
#define MCP2515_TX_CNT 3
|
#define MCP2515_TX_CNT 3
|
||||||
#define MCP2515_FRAME_LEN 13
|
#define MCP2515_FRAME_LEN 13
|
||||||
|
|
||||||
|
@ -84,6 +85,7 @@ struct mcp2515_config {
|
||||||
#define MCP2515_OPCODE_BIT_MODIFY 0x05
|
#define MCP2515_OPCODE_BIT_MODIFY 0x05
|
||||||
#define MCP2515_OPCODE_LOAD_TX_BUFFER 0x40
|
#define MCP2515_OPCODE_LOAD_TX_BUFFER 0x40
|
||||||
#define MCP2515_OPCODE_RTS 0x80
|
#define MCP2515_OPCODE_RTS 0x80
|
||||||
|
#define MCP2515_OPCODE_READ_RX_BUFFER 0x90
|
||||||
#define MCP2515_OPCODE_READ_STATUS 0xA0
|
#define MCP2515_OPCODE_READ_STATUS 0xA0
|
||||||
#define MCP2515_OPCODE_RESET 0xC0
|
#define MCP2515_OPCODE_RESET 0xC0
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue