Linux like CAN frame struct

This commit is contained in:
Dmitry
2016-01-06 19:11:40 +03:00
parent a9cbfcbf66
commit a250acba70
4 changed files with 79 additions and 37 deletions
+45
View File
@@ -0,0 +1,45 @@
#ifndef CAN_H_
#define CAN_H_
#include <stdint.h>
typedef unsigned char __u8;
typedef unsigned short __u16;
typedef unsigned long __u32;
/* 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 */
/*
* Controller Area Network Identifier structure
*
* bit 0-28 : CAN identifier (11/29 bit)
* bit 29 : error message frame flag (0 = data frame, 1 = error message)
* bit 30 : remote transmission request flag (1 = rtr frame)
* bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)
*/
typedef __u32 canid_t;
#define CAN_SFF_ID_BITS 11
#define CAN_EFF_ID_BITS 29
/* CAN payload length and DLC definitions according to ISO 11898-1 */
#define CAN_MAX_DLC 8
#define CAN_MAX_DLEN 8
struct can_frame {
canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
__u8 can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
__u8 data[CAN_MAX_DLEN] __attribute__((aligned(8)));
};
#endif /* CAN_H_ */
+29 -25
View File
@@ -52,11 +52,11 @@ uint8_t MCP_CAN::readRegister(const REGISTER reg)
** Function name: readRegisterS
** Descriptions: read registerS
******************************************************************************/
void MCP_CAN::readRegisterS(const REGISTER address, uint8_t values[], const uint8_t n)
void MCP_CAN::readRegisterS(const REGISTER reg, uint8_t values[], const uint8_t n)
{
startSPI();
SPI.transfer(INSTRUCTION_READ);
SPI.transfer(address);
SPI.transfer(reg);
// mcp2515 has auto-increment of address-pointer
for (uint8_t i=0; i<n; i++) {
values[i] = SPI.transfer(0x00);
@@ -427,9 +427,9 @@ MCP_CAN::ERROR MCP_CAN::initFilt(const RXF num, const bool ext, const uint32_t u
return res;
}
MCP_CAN::ERROR MCP_CAN::sendMessage(const uint32_t id, const bool ext, const bool rtr, const uint8_t len, const uint8_t *buf)
MCP_CAN::ERROR MCP_CAN::sendMessage(const struct can_frame *frame)
{
if (len > CAN_MAX_CHAR_IN_MESSAGE) {
if (frame->can_dlc > CAN_MAX_CHAR_IN_MESSAGE) {
return ERROR_FAILTX;
}
@@ -449,20 +449,25 @@ MCP_CAN::ERROR MCP_CAN::sendMessage(const uint32_t id, const bool ext, const boo
uint8_t data[13];
bool ext = frame->can_id & CAN_EFF_FLAG;
bool rtr = frame->can_id & CAN_RTR_FLAG;
uint32_t id = frame->can_id & (ext ? CAN_EFF_MASK : CAN_SFF_MASK);
prepareId(data, ext, id);
data[MCP_DLC] = rtr ? len | RTR_MASK : len;
data[MCP_DLC] = rtr ? frame->can_dlc | RTR_MASK : frame->can_dlc;
memcpy(&data[MCP_DATA], buf, len);
memcpy(&data[MCP_DATA], frame->data, frame->can_dlc);
setRegisterS(txbuf->SIDH, data, 5 + len);
setRegisterS(txbuf->SIDH, data, 5 + frame->can_dlc);
modifyRegister(txbuf->CTRL, TXB_TXREQ, TXB_TXREQ);
return ERROR_OK;
}
MCP_CAN::ERROR MCP_CAN::readMessage(const RXBn rxbn, uint32_t *id, uint8_t *dlc, uint8_t buf[], bool *rtr, bool *ext)
//MCP_CAN::ERROR MCP_CAN::readMessage(const RXBn rxbn, uint32_t *id, uint8_t *dlc, uint8_t buf[], bool *rtr, bool *ext)
MCP_CAN::ERROR MCP_CAN::readMessage(const RXBn rxbn, struct can_frame *frame)
{
const struct RXBn_REGS *rxb = &RXB[rxbn];
@@ -470,30 +475,29 @@ MCP_CAN::ERROR MCP_CAN::readMessage(const RXBn rxbn, uint32_t *id, uint8_t *dlc,
readRegisterS(rxb->SIDH, tbufdata, 5);
*id = (tbufdata[MCP_SIDH]<<3) + (tbufdata[MCP_SIDL]>>5);
uint32_t id = (tbufdata[MCP_SIDH]<<3) + (tbufdata[MCP_SIDL]>>5);
if ( (tbufdata[MCP_SIDL] & TXB_EXIDE_MASK) == TXB_EXIDE_MASK ) {
*id = (*id<<2) + (tbufdata[MCP_SIDL] & 0x03);
*id = (*id<<8) + tbufdata[MCP_EID8];
*id = (*id<<8) + tbufdata[MCP_EID0];
*ext = true;
} else {
*ext = false;
id = (id<<2) + (tbufdata[MCP_SIDL] & 0x03);
id = (id<<8) + tbufdata[MCP_EID8];
id = (id<<8) + tbufdata[MCP_EID0];
id |= CAN_EFF_FLAG;
}
*dlc = tbufdata[MCP_DLC] & DLC_MASK;
if (*dlc > CAN_MAX_CHAR_IN_MESSAGE) {
uint8_t dlc = tbufdata[MCP_DLC] & DLC_MASK;
if (dlc > CAN_MAX_CHAR_IN_MESSAGE) {
return ERROR_FAIL;
}
uint8_t ctrl = readRegister(rxb->CTRL);
if (ctrl & 0x08) {
*rtr = true;
} else {
*rtr = false;
if (ctrl & RXBnCTRL_RTR) {
id |= CAN_RTR_FLAG;
}
readRegisterS(rxb->DATA, buf, *dlc);
frame->can_id = id;
frame->can_dlc = dlc;
readRegisterS(rxb->DATA, frame->data, dlc);
switch (rxbn) {
case RXB0:
@@ -507,15 +511,15 @@ MCP_CAN::ERROR MCP_CAN::readMessage(const RXBn rxbn, uint32_t *id, uint8_t *dlc,
return ERROR_OK;
}
MCP_CAN::ERROR MCP_CAN::readMessage(uint32_t *id, uint8_t *dlc, uint8_t buf[], bool *rtr, bool *ext)
MCP_CAN::ERROR MCP_CAN::readMessage(struct can_frame *frame)
{
ERROR rc;
uint8_t stat = getStatus();
if ( stat & STAT_RX0IF ) {
rc = readMessage(RXB0, id, dlc, buf, rtr, ext);
rc = readMessage(RXB0, frame);
} else if ( stat & STAT_RX1IF ) {
rc = readMessage(RXB1, id, dlc, buf, rtr, ext);
rc = readMessage(RXB1, frame);
} else {
rc = ERROR_NOMSG;
}
+5 -3
View File
@@ -2,6 +2,7 @@
#define _MCP2515_H_
#include <SPI.h>
#include "can.h"
/*
* speed 16M
@@ -143,6 +144,7 @@ class MCP_CAN
static const uint8_t RXBnCTRL_RXM_EXT = 0x40;
static const uint8_t RXBnCTRL_RXM_STDEXT = 0x00;
static const uint8_t RXBnCTRL_RXM_MASK = 0x60;
static const uint8_t RXBnCTRL_RTR = 0x80;
static const uint8_t RXB0CTRL_BUKT = 0x40;
static const uint8_t MCP_SIDH = 0;
@@ -338,9 +340,9 @@ class MCP_CAN
ERROR begin(const CAN_SPEED speedset);
ERROR initMask(const uint8_t num, const bool ext, const uint32_t ulData);
ERROR initFilt(const RXF num, const bool ext, const uint32_t ulData);
ERROR sendMessage(const uint32_t id, const bool ext, const bool rtr, const uint8_t len, const uint8_t *buf);
ERROR readMessage(const RXBn rxbn, uint32_t *id, uint8_t *dlc, uint8_t buf[], bool *rtr, bool *ext);
ERROR readMessage(uint32_t *id, uint8_t *dlc, uint8_t buf[], bool *rtr, bool *ext);
ERROR sendMessage(const struct can_frame *frame);
ERROR readMessage(const RXBn rxbn, struct can_frame *frame);
ERROR readMessage(struct can_frame *frame);
bool checkReceive(void);
bool checkError(void);
uint8_t getInterrupts(void);
-9
View File
@@ -1,9 +0,0 @@
#ifndef _MCP2515DFS_H_
#define _MCP2515DFS_H_
/*
* Begin mt
*/
#endif