rcbench
Servo and ESC test bench: panel, IOmcu and shared C
Loading...
Searching...
No Matches
mcp2515.h
1/*
2 * The MCP2515's register map and frame layout, from the datasheet.
3 *
4 * Everything here is arithmetic or a constant: no SPI (Serial Peripheral
5 * Interface), no pins, no delays. It is host-tested, and the driver that
6 * touches hardware stays thin.
7 *
8 * The identifier is the part that needs the tests. A 29-bit extended
9 * identifier is spread across four registers with a three-bit gap in the
10 * second: the register layout is the 11-bit one, with the extended bits
11 * fitted around it. A wrong packing puts the frame on the bus under a
12 * different identifier, and on a bus that arbitrates by identifier the wrong
13 * frame wins.
14 *
15 * SPDX-License-Identifier: MIT
16 */
17
18#ifndef RCBENCH_MCP2515_H
19#define RCBENCH_MCP2515_H
20
21#include <stdbool.h>
22#include <stdint.h>
23
24#include "link_can.h"
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30/* SPI commands. */
31#define MCP2515_CMD_RESET 0xC0u
32#define MCP2515_CMD_READ 0x03u
33#define MCP2515_CMD_WRITE 0x02u
34#define MCP2515_CMD_RTS_TXB0 0x81u
35#define MCP2515_CMD_READ_STATUS 0xA0u
36#define MCP2515_CMD_RX_STATUS 0xB0u
37#define MCP2515_CMD_BIT_MODIFY 0x05u
38
39/* Registers this driver touches. */
40#define MCP2515_CANSTAT 0x0Eu
41#define MCP2515_CANCTRL 0x0Fu
42#define MCP2515_CANINTE 0x2Bu
43#define MCP2515_CANINTF 0x2Cu
44#define MCP2515_EFLG 0x2Du
45#define MCP2515_TEC 0x1Cu
46#define MCP2515_REC 0x1Du
47
48#define MCP2515_TXB0CTRL 0x30u
49#define MCP2515_TXB0SIDH 0x31u
50#define MCP2515_RXB0CTRL 0x60u
51#define MCP2515_RXB0SIDH 0x61u
52#define MCP2515_RXB1CTRL 0x70u
53#define MCP2515_RXB1SIDH 0x71u
54#define MCP2515_RXM0SIDH 0x20u
55#define MCP2515_RXF0SIDH 0x00u
56
57/* CANCTRL request modes, in the top three bits. */
58#define MCP2515_MODE_NORMAL 0x00u
59#define MCP2515_MODE_SLEEP 0x20u
60#define MCP2515_MODE_LOOPBACK 0x40u
61#define MCP2515_MODE_LISTEN 0x60u
62#define MCP2515_MODE_CONFIG 0x80u
63#define MCP2515_MODE_MASK 0xE0u
64
65/* CANINTF bits worth naming. */
66#define MCP2515_INTF_RX0 0x01u
67#define MCP2515_INTF_RX1 0x02u
68#define MCP2515_INTF_TX0 0x04u
69#define MCP2515_INTF_ERR 0x20u
70
71/* EFLG. The two overflow bits are set when a frame arrives with both receive
72 * buffers full; they are sticky and the MCU (microcontroller unit) clears
73 * them. They are the record of a frame lost with nothing wrong on the
74 * wire. */
75#define MCP2515_EFLG_RX0OVR 0x40u
76#define MCP2515_EFLG_RX1OVR 0x80u
77#define MCP2515_EFLG_TXBO 0x20u
78#define MCP2515_EFLG_OVR (MCP2515_EFLG_RX0OVR | MCP2515_EFLG_RX1OVR)
79
80/* RXB0CTRL / RXB1CTRL receive-mode field. */
81#define MCP2515_RXM_ANY 0x60u
82#define MCP2515_RXM_EXT_ONLY 0x40u
84#define MCP2515_BUKT 0x04u
85
87#define MCP2515_SIDL_EXIDE 0x08u
88
95bool mcp2515_pack_id(uint32_t id, uint8_t out[4]);
96
104bool mcp2515_unpack_id(const uint8_t in[4], uint32_t *id);
105
107#define MCP2515_RX_BUFFERS 2u
108
113typedef bool (*mcp2515_fetch_fn)(void *ctx, uint8_t buf[13]);
114
122bool mcp2515_decode_rx(const uint8_t buf[13], link_can_frame_t *f);
123
133bool mcp2515_recv_next(mcp2515_fetch_fn fetch, void *ctx, link_can_frame_t *f,
134 uint32_t *refused);
135
136#ifdef __cplusplus
137}
138#endif
139
140#endif /* RCBENCH_MCP2515_H */