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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
__ASSERT(rx_idx < MCP2515_RX_CNT, "rx_idx < MCP2515_RX_CNT");
|
||||
|
||||
struct zcan_frame msg;
|
||||
u8_t rx_frame[MCP2515_FRAME_LEN];
|
||||
u8_t addr_rx_ctrl = MCP2515_ADDR_RXB0CTRL +
|
||||
(rx_idx * MCP2515_ADDR_OFFSET_FRAME2FRAME);
|
||||
u8_t nm;
|
||||
|
||||
/* Address Pointer selection */
|
||||
nm = 2 * rx_idx;
|
||||
|
||||
/* Fetch rx buffer */
|
||||
mcp2515_cmd_read_reg(dev,
|
||||
addr_rx_ctrl + MCP2515_ADDR_OFFSET_CTRL2FRAME,
|
||||
rx_frame, sizeof(rx_frame));
|
||||
mcp2515_cmd_read_rx_buffer(dev, nm, rx_frame, sizeof(rx_frame));
|
||||
mcp2515_convert_mcp2515frame_to_zcanframe(rx_frame, &msg);
|
||||
mcp2515_rx_filter(dev, &msg);
|
||||
}
|
||||
|
@ -611,10 +650,16 @@ static void mcp2515_handle_interrupts(struct device *dev)
|
|||
|
||||
if (canintf & MCP2515_CANINTF_RX0IF) {
|
||||
mcp2515_rx(dev, 0);
|
||||
|
||||
/* RX0IF flag cleared automatically during read */
|
||||
canintf &= ~MCP2515_CANINTF_RX0IF;
|
||||
}
|
||||
|
||||
if (canintf & MCP2515_CANINTF_RX1IF) {
|
||||
mcp2515_rx(dev, 1);
|
||||
|
||||
/* RX1IF flag cleared automatically during read */
|
||||
canintf &= ~MCP2515_CANINTF_RX1IF;
|
||||
}
|
||||
|
||||
if (canintf & MCP2515_CANINTF_TX0IF) {
|
||||
|
@ -633,9 +678,11 @@ static void mcp2515_handle_interrupts(struct device *dev)
|
|||
mcp2515_handle_errors(dev);
|
||||
}
|
||||
|
||||
/* clear the flags we handled */
|
||||
mcp2515_cmd_bit_modify(dev, MCP2515_ADDR_CANINTF, canintf,
|
||||
~canintf);
|
||||
if (canintf != 0) {
|
||||
/* Clear remaining flags */
|
||||
mcp2515_cmd_bit_modify(dev, MCP2515_ADDR_CANINTF,
|
||||
canintf, ~canintf);
|
||||
}
|
||||
|
||||
/* Break from loop if INT pin is no longer low */
|
||||
ret = gpio_pin_read(dev_data->int_gpio, dev_cfg->int_pin, &pin);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <drivers/can.h>
|
||||
|
||||
#define MCP2515_RX_CNT 2
|
||||
#define MCP2515_TX_CNT 3
|
||||
#define MCP2515_FRAME_LEN 13
|
||||
|
||||
|
@ -84,6 +85,7 @@ struct mcp2515_config {
|
|||
#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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue