#ifndef _mcp2515_h_ #define _mcp2515_h_ #include #include #include #include #include #include #include #include #include #include /***** Register Map *******/ typedef __u32 canid_t; /* special address description flags for the CAN_ID */ #define CAN_EFF_FLAG 0x80000000UL /* EFF/SFF is set in the MSB */ #define CAN_RTR_FLAG 0x40000000UL /* remote transmission request */ #define CAN_ERR_FLAG 0x20000000UL /* error message frame */ /* valid bits in CAN ID for frame formats */ #define CAN_SFF_MASK 0x000007FFUL /* standard frame format (SFF) */ #define CAN_EFF_MASK 0x1FFFFFFFUL /* extended frame format (EFF) */ #define CAN_ERR_MASK 0x1FFFFFFFUL /* omit EFF, RTR, ERR flags */ #define CAN_MAX_DLEN 8 /**************** mcp2515 frequency define ********************/ /* * Speed 8M */ #define MCP_8MHz_1000kBPS_CFG1 (0x00) #define MCP_8MHz_1000kBPS_CFG2 (0x80) #define MCP_8MHz_1000kBPS_CFG3 (0x80) #define MCP_8MHz_500kBPS_CFG1 (0x00) #define MCP_8MHz_500kBPS_CFG2 (0x90) #define MCP_8MHz_500kBPS_CFG3 (0x82) #define MCP_8MHz_250kBPS_CFG1 (0x00) #define MCP_8MHz_250kBPS_CFG2 (0xB1) #define MCP_8MHz_250kBPS_CFG3 (0x85) #define MCP_8MHz_200kBPS_CFG1 (0x00) #define MCP_8MHz_200kBPS_CFG2 (0xB4) #define MCP_8MHz_200kBPS_CFG3 (0x86) #define MCP_8MHz_125kBPS_CFG1 (0x01) #define MCP_8MHz_125kBPS_CFG2 (0xB1) #define MCP_8MHz_125kBPS_CFG3 (0x85) #define MCP_8MHz_100kBPS_CFG1 (0x01) #define MCP_8MHz_100kBPS_CFG2 (0xB4) #define MCP_8MHz_100kBPS_CFG3 (0x86) #define MCP_8MHz_80kBPS_CFG1 (0x01) #define MCP_8MHz_80kBPS_CFG2 (0xBF) #define MCP_8MHz_80kBPS_CFG3 (0x87) #define MCP_8MHz_50kBPS_CFG1 (0x03) #define MCP_8MHz_50kBPS_CFG2 (0xB4) #define MCP_8MHz_50kBPS_CFG3 (0x86) #define MCP_8MHz_40kBPS_CFG1 (0x03) #define MCP_8MHz_40kBPS_CFG2 (0xBF) #define MCP_8MHz_40kBPS_CFG3 (0x87) #define MCP_8MHz_33k3BPS_CFG1 (0x47) #define MCP_8MHz_33k3BPS_CFG2 (0xE2) #define MCP_8MHz_33k3BPS_CFG3 (0x85) #define MCP_8MHz_31k25BPS_CFG1 (0x07) #define MCP_8MHz_31k25BPS_CFG2 (0xA4) #define MCP_8MHz_31k25BPS_CFG3 (0x84) #define MCP_8MHz_20kBPS_CFG1 (0x07) #define MCP_8MHz_20kBPS_CFG2 (0xBF) #define MCP_8MHz_20kBPS_CFG3 (0x87) #define MCP_8MHz_10kBPS_CFG1 (0x0F) #define MCP_8MHz_10kBPS_CFG2 (0xBF) #define MCP_8MHz_10kBPS_CFG3 (0x87) #define MCP_8MHz_5kBPS_CFG1 (0x1F) #define MCP_8MHz_5kBPS_CFG2 (0xBF) #define MCP_8MHz_5kBPS_CFG3 (0x87) /* * speed 16M */ #define MCP_16MHz_1000kBPS_CFG1 (0x00) #define MCP_16MHz_1000kBPS_CFG2 (0xD0) #define MCP_16MHz_1000kBPS_CFG3 (0x82) #define MCP_16MHz_500kBPS_CFG1 (0x00) #define MCP_16MHz_500kBPS_CFG2 (0xF0) #define MCP_16MHz_500kBPS_CFG3 (0x86) #define MCP_16MHz_250kBPS_CFG1 (0x41) #define MCP_16MHz_250kBPS_CFG2 (0xF1) #define MCP_16MHz_250kBPS_CFG3 (0x85) #define MCP_16MHz_200kBPS_CFG1 (0x01) #define MCP_16MHz_200kBPS_CFG2 (0xFA) #define MCP_16MHz_200kBPS_CFG3 (0x87) #define MCP_16MHz_125kBPS_CFG1 (0x03) #define MCP_16MHz_125kBPS_CFG2 (0xF0) #define MCP_16MHz_125kBPS_CFG3 (0x86) #define MCP_16MHz_100kBPS_CFG1 (0x03) #define MCP_16MHz_100kBPS_CFG2 (0xFA) #define MCP_16MHz_100kBPS_CFG3 (0x87) #define MCP_16MHz_95kBPS_CFG1 (0x03) #define MCP_16MHz_95kBPS_CFG2 (0xAD) #define MCP_16MHz_95kBPS_CFG3 (0x07) #define MCP_16MHz_83k3BPS_CFG1 (0x03) #define MCP_16MHz_83k3BPS_CFG2 (0xBE) #define MCP_16MHz_83k3BPS_CFG3 (0x07) #define MCP_16MHz_80kBPS_CFG1 (0x03) #define MCP_16MHz_80kBPS_CFG2 (0xFF) #define MCP_16MHz_80kBPS_CFG3 (0x87) #define MCP_16MHz_50kBPS_CFG1 (0x07) #define MCP_16MHz_50kBPS_CFG2 (0xFA) #define MCP_16MHz_50kBPS_CFG3 (0x87) #define MCP_16MHz_40kBPS_CFG1 (0x07) #define MCP_16MHz_40kBPS_CFG2 (0xFF) #define MCP_16MHz_40kBPS_CFG3 (0x87) #define MCP_16MHz_33k3BPS_CFG1 (0x4E) #define MCP_16MHz_33k3BPS_CFG2 (0xF1) #define MCP_16MHz_33k3BPS_CFG3 (0x85) #define MCP_16MHz_20kBPS_CFG1 (0x0F) #define MCP_16MHz_20kBPS_CFG2 (0xFF) #define MCP_16MHz_20kBPS_CFG3 (0x87) #define MCP_16MHz_10kBPS_CFG1 (0x1F) #define MCP_16MHz_10kBPS_CFG2 (0xFF) #define MCP_16MHz_10kBPS_CFG3 (0x87) #define MCP_16MHz_5kBPS_CFG1 (0x3F) #define MCP_16MHz_5kBPS_CFG2 (0xFF) #define MCP_16MHz_5kBPS_CFG3 (0x87) /* * speed 20M */ #define MCP_20MHz_1000kBPS_CFG1 (0x00) #define MCP_20MHz_1000kBPS_CFG2 (0xD9) #define MCP_20MHz_1000kBPS_CFG3 (0x82) #define MCP_20MHz_500kBPS_CFG1 (0x00) #define MCP_20MHz_500kBPS_CFG2 (0xFA) #define MCP_20MHz_500kBPS_CFG3 (0x87) #define MCP_20MHz_250kBPS_CFG1 (0x41) #define MCP_20MHz_250kBPS_CFG2 (0xFB) #define MCP_20MHz_250kBPS_CFG3 (0x86) #define MCP_20MHz_200kBPS_CFG1 (0x01) #define MCP_20MHz_200kBPS_CFG2 (0xFF) #define MCP_20MHz_200kBPS_CFG3 (0x87) #define MCP_20MHz_125kBPS_CFG1 (0x03) #define MCP_20MHz_125kBPS_CFG2 (0xFA) #define MCP_20MHz_125kBPS_CFG3 (0x87) #define MCP_20MHz_100kBPS_CFG1 (0x04) #define MCP_20MHz_100kBPS_CFG2 (0xFA) #define MCP_20MHz_100kBPS_CFG3 (0x87) #define MCP_20MHz_83k3BPS_CFG1 (0x04) #define MCP_20MHz_83k3BPS_CFG2 (0xFE) #define MCP_20MHz_83k3BPS_CFG3 (0x87) #define MCP_20MHz_80kBPS_CFG1 (0x04) #define MCP_20MHz_80kBPS_CFG2 (0xFF) #define MCP_20MHz_80kBPS_CFG3 (0x87) #define MCP_20MHz_50kBPS_CFG1 (0x09) #define MCP_20MHz_50kBPS_CFG2 (0xFA) #define MCP_20MHz_50kBPS_CFG3 (0x87) #define MCP_20MHz_40kBPS_CFG1 (0x09) #define MCP_20MHz_40kBPS_CFG2 (0xFF) #define MCP_20MHz_40kBPS_CFG3 (0x87) #define MCP_20MHz_33k3BPS_CFG1 (0x0B) #define MCP_20MHz_33k3BPS_CFG2 (0xFF) #define MCP_20MHz_33k3BPS_CFG3 (0x87) /**************** mcp2515 flag typedef ********************/ typedef enum{ CANCTRL_REQOP = 0xE0, CANCTRL_ABAT = 0x10, CANCTRL_OSM = 0x08, CANCTRL_CLKEN = 0x04, CANCTRL_CLKPRE = 0x03 }canctrl_flags; typedef enum { MCP_20MHZ, MCP_16MHZ, MCP_8MHZ }CAN_CLOCK; typedef enum { CAN_5KBPS, CAN_10KBPS, CAN_20KBPS, CAN_31K25BPS, CAN_33KBPS, CAN_40KBPS, CAN_50KBPS, CAN_80KBPS, CAN_83K3BPS, CAN_95KBPS, CAN_100KBPS, CAN_125KBPS, CAN_200KBPS, CAN_250KBPS, CAN_500KBPS, CAN_1000KBPS }CAN_SPEED; typedef enum { ERROR_OK = 0, ERROR_FAIL = 1, ERROR_ALLTXBUSY = 2, ERROR_FAILINIT = 3, ERROR_FAILTX = 4, ERROR_NOMSG = 5 }ERROR; typedef enum { MASK0, MASK1 }MASK; typedef enum { RXF0 = 0, RXF1 = 1, RXF2 = 2, RXF3 = 3, RXF4 = 4, RXF5 = 5 }RXF; typedef enum { RXB0 = 0, RXB1 = 1 }RXBn; typedef enum { TXB0 = 0, TXB1 = 1, TXB2 = 2 }TXBn; typedef enum { CANINTF_RX0IF = 0x01, CANINTF_RX1IF = 0x02, CANINTF_TX0IF = 0x04, CANINTF_TX1IF = 0x08, CANINTF_TX2IF = 0x10, CANINTF_ERRIF = 0x20, CANINTF_WAKIF = 0x40, CANINTF_MERRF = 0x80 }CANINTF; typedef enum{ EFLG_RX1OVR = (1<<7), EFLG_RX0OVR = (1<<6), EFLG_TXBO = (1<<5), EFLG_TXEP = (1<<4), EFLG_RXEP = (1<<3), EFLG_TXWAR = (1<<2), EFLG_RXWAR = (1<<1), EFLG_EWARN = (1<<0) }EFLG; typedef enum{ INSTRUCTION_WRITE = 0x02, INSTRUCTION_READ = 0x03, INSTRUCTION_BITMOD = 0x05, INSTRUCTION_LOAD_TX0 = 0x40, INSTRUCTION_LOAD_TX1 = 0x42, INSTRUCTION_LOAD_TX2 = 0x44, INSTRUCTION_RTS_TX0 = 0x81, INSTRUCTION_RTS_TX1 = 0x82, INSTRUCTION_RTS_TX2 = 0x84, INSTRUCTION_RTS_ALL = 0x87, INSTRUCTION_READ_RX0 = 0x90, INSTRUCTION_READ_RX1 = 0x94, INSTRUCTION_READ_STATUS = 0xA0, INSTRUCTION_RX_STATUS = 0xB0, INSTRUCTION_RESET = 0xC0 }INSTRUCTION; typedef enum { MCP_RXF0SIDH = 0x00, MCP_RXF0SIDL = 0x01, MCP_RXF0EID8 = 0x02, MCP_RXF0EID0 = 0x03, MCP_RXF1SIDH = 0x04, MCP_RXF1SIDL = 0x05, MCP_RXF1EID8 = 0x06, MCP_RXF1EID0 = 0x07, MCP_RXF2SIDH = 0x08, MCP_RXF2SIDL = 0x09, MCP_RXF2EID8 = 0x0A, MCP_RXF2EID0 = 0x0B, MCP_CANSTAT = 0x0E, MCP_CANCTRL = 0x0F, MCP_RXF3SIDH = 0x10, MCP_RXF3SIDL = 0x11, MCP_RXF3EID8 = 0x12, MCP_RXF3EID0 = 0x13, MCP_RXF4SIDH = 0x14, MCP_RXF4SIDL = 0x15, MCP_RXF4EID8 = 0x16, MCP_RXF4EID0 = 0x17, MCP_RXF5SIDH = 0x18, MCP_RXF5SIDL = 0x19, MCP_RXF5EID8 = 0x1A, MCP_RXF5EID0 = 0x1B, MCP_TEC = 0x1C, MCP_REC = 0x1D, MCP_RXM0SIDH = 0x20, MCP_RXM0SIDL = 0x21, MCP_RXM0EID8 = 0x22, MCP_RXM0EID0 = 0x23, MCP_RXM1SIDH = 0x24, MCP_RXM1SIDL = 0x25, MCP_RXM1EID8 = 0x26, MCP_RXM1EID0 = 0x27, MCP_CNF3 = 0x28, MCP_CNF2 = 0x29, MCP_CNF1 = 0x2A, MCP_CANINTE = 0x2B, MCP_CANINTF = 0x2C, MCP_EFLG = 0x2D, MCP_TXB0CTRL = 0x30, MCP_TXB0SIDH = 0x31, MCP_TXB0SIDL = 0x32, MCP_TXB0EID8 = 0x33, MCP_TXB0EID0 = 0x34, MCP_TXB0DLC = 0x35, MCP_TXB0DATA = 0x36, MCP_TXB1CTRL = 0x40, MCP_TXB1SIDH = 0x41, MCP_TXB1SIDL = 0x42, MCP_TXB1EID8 = 0x43, MCP_TXB1EID0 = 0x44, MCP_TXB1DLC = 0x45, MCP_TXB1DATA = 0x46, MCP_TXB2CTRL = 0x50, MCP_TXB2SIDH = 0x51, MCP_TXB2SIDL = 0x52, MCP_TXB2EID8 = 0x53, MCP_TXB2EID0 = 0x54, MCP_TXB2DLC = 0x55, MCP_TXB2DATA = 0x56, MCP_RXB0CTRL = 0x60, MCP_RXB0SIDH = 0x61, MCP_RXB0SIDL = 0x62, MCP_RXB0EID8 = 0x63, MCP_RXB0EID0 = 0x64, MCP_RXB0DLC = 0x65, MCP_RXB0DATA = 0x66, MCP_RXB1CTRL = 0x70, MCP_RXB1SIDH = 0x71, MCP_RXB1SIDL = 0x72, MCP_RXB1EID8 = 0x73, MCP_RXB1EID0 = 0x74, MCP_RXB1DLC = 0x75, MCP_RXB1DATA = 0x76 }REGISTER; typedef enum{ N_TXBUFFERS=3, N_RXBUFFERS=2 }buffers_flag; typedef enum{ RXBnCTRL_RXM_STD = 0x20, RXBnCTRL_RXM_EXT = 0x40, RXBnCTRL_RXM_STDEXT = 0x00, RXBnCTRL_RXM_MASK = 0x60, RXBnCTRL_RTR = 0x08, RXB0CTRL_BUKT = 0x04, RXB0CTRL_FILHIT_MASK = 0x03, RXB1CTRL_FILHIT_MASK = 0x07, RXB0CTRL_FILHIT = 0x00, RXB1CTRL_FILHIT = 0x01 }RXBnCTRLFlag; typedef enum { CANCTRL_REQOP_NORMAL = 0x00, CANCTRL_REQOP_SLEEP = 0x20, CANCTRL_REQOP_LOOPBACK = 0x40, CANCTRL_REQOP_LISTENONLY = 0x60, CANCTRL_REQOP_CONFIG = 0x80, CANCTRL_REQOP_POWERUP = 0xE0 }CANCTRL_REQOP_MODE; typedef enum { TXB_EXIDE_MASK = 0x08, DLC_MASK = 0x0F, RTR_MASK = 0x40 }mcp_mask_flag; typedef enum { MCP_SIDL = 1, MCP_SIDH = 0, MCP_EID8 = 2, MCP_EID0 = 3, MCP_DLC = 4, MCP_DATA = 5, }mcp_flag; typedef enum{ CANSTAT_OPMOD = 0xE0, CANSTAT_ICOD = 0x0E }canstat_flag; struct TXBn_REGS { REGISTER CTRL; REGISTER SIDH; REGISTER DATA; }; struct RXBn_REGS { REGISTER CTRL; REGISTER SIDH; REGISTER DATA; CANINTF CANINTF_RXnIF; }; extern const struct TXBn_REGS TXB[N_TXBUFFERS]; extern const struct RXBn_REGS RXB[N_RXBUFFERS]; typedef enum { TXB_ABTF = 0x40, TXB_MLOA = 0x20, TXB_TXERR = 0x10, TXB_TXREQ = 0x08, TXB_TXIE = 0x04, TXB_TXP = 0x03 }TXBnCTRL; typedef enum { STAT_RX0IF = (1<<0), STAT_RX1IF = (1<<1) }STAT; typedef struct mcp2515_dev mcp2515_dev; typedef struct spi_description spi_description; // defined mcp2515 feature typedef struct mcp2515_dev { spi_description* spi_dev; }mcp2515_dev; // defined spi description typedef struct spi_description { char *spidev_path; uint8_t fd; uint8_t mode; uint8_t bits; uint32_t speed; }spi_description; // constructor mcp2515_dev* new_mcp2515_dev(char *); // Open and initial mcp2515 int mcp2515_initial(mcp2515_dev*); uint8_t mcp2515_setMode(mcp2515_dev *mcp2515_device,const CANCTRL_REQOP_MODE mode); uint8_t mcp2515_setConfigMode(mcp2515_dev *mcp2515_device); void mcp2515_prepareId(uint8_t *buffer, const uint8_t ext, const uint32_t id); int mcp2515_setFillter(mcp2515_dev *mcp2515_device,const RXF num, const uint8_t ext, const uint32_t ulData); int mcp2515_setFilterMask(mcp2515_dev *mcp2515_device,const MASK mask, const uint8_t ext, const uint32_t ulData); int mcp2515_reset(mcp2515_dev *mcp2515_device); int mcp2515_can_speed(mcp2515_dev *mcp2515_device, const CAN_SPEED canSpeed, CAN_CLOCK canClock); // Send Data to MCP2515 int mcp2515_write_register(mcp2515_dev*,uint8_t,uint8_t*,int8_t); int mcp2515_write_register_once(mcp2515_dev *mcp2515_device, uint8_t register_address, uint8_t data); // Receive Data from MCP2515 void mcp2515_read_register(mcp2515_dev *mcp2515_device, uint8_t register_address, uint8_t values[], uint8_t data_length); uint8_t mcp2515_read_register_once(mcp2515_dev *mcp2515_device, uint8_t register_address); // MCP2515 mode setting int mcp2515_set_mode(mcp2515_dev*); uint8_t mcp2515_read_status(mcp2515_dev*); // mcp2515 bit modify void mcp2515_modify_bit(mcp2515_dev*, uint8_t, uint8_t, uint8_t); // mcp2515 speed select int mcp2515_sendMessage(mcp2515_dev *mcp2515_device, uint32_t can_id, uint8_t* data, uint8_t data_length); int mcp2515_sendMessageT(mcp2515_dev *mcp2515_device, const TXBn txbn, uint32_t can_id, uint8_t* data, uint8_t data_length); int mcp2515_readMessage(mcp2515_dev *mcp2515_device,canid_t* can_id, uint8_t* data, uint8_t* data_length); int mcp2515_readMessageT(mcp2515_dev *mcp2515_device,const RXBn rxbn,canid_t* can_id, uint8_t* data, uint8_t* data_length); #endif