CAN: Add CAN FD mode as a configuration option

This commit is contained in:
Gregory Nutt 2015-08-05 13:56:48 -06:00
parent 36d4559ee8
commit 4b58990362
3 changed files with 118 additions and 4 deletions

2
arch

@ -1 +1 @@
Subproject commit 478948e2fd0c1621bce15195c6f207df4156fbe6
Subproject commit b331b89caf5aa68bc8b8e585b35e10777f469e1c

View File

@ -99,13 +99,20 @@ menuconfig CAN
See include/nuttx/can.h for further CAN driver information.
if CAN
config CAN_EXTID
bool "CAN extended IDs"
default n
---help---
Enables support for the 29-bit extended ID. Default Standard 11-bit
Enables support for the 28-bit extended ID. Default Standard 11-bit
IDs.
config CAN_FD
bool "CAN FD"
default n
---help---
Enables support for the CAN_FD mode.
config CAN_FIFOSIZE
int "CAN driver I/O buffer size"
default 8

View File

@ -89,6 +89,15 @@
* Private Function Prototypes
****************************************************************************/
/* CAN helpers */
static uint8_t can_dlc2bytes(uint8_t dlc);
#if 0 /* Not used */
static uint8_t can_bytes2dlc(uint8_t nbytes);
#endif
/* Character driver methods */
static int can_open(FAR struct file *filep);
static int can_close(FAR struct file *filep);
static ssize_t can_read(FAR struct file *filep, FAR char *buffer,
@ -125,6 +134,101 @@ static const struct file_operations g_canops =
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: can_dlc2bytes and can_bytes2dlc
*
* Description:
* In the CAN FD format, the coding of the DLC differs from the standard
* CAN format. The DLC codes 0 to 8 have the same coding as in standard
* CAN. But the codes 9 to 15 all imply a data field of 8 bytes with
* standard CAN. In CAN FD mode, the values 9 to 15 are encoded to values
* in the range 12 to 64.
*
* Input Parameter:
* dlc - the DLC to convert to a byte count, OR
* nbytes - the byte count to convert to a DLC
*
* Returned Value:
* The converted value
*
****************************************************************************/
static uint8_t can_dlc2bytes(uint8_t dlc)
{
if (dlc > 8)
{
#ifdef CONFIG_CAN_FD
switch (dlc)
{
case 9:
return 12;
case 10:
return 16;
case 11:
return 20;
case 12:
return 24;
case 13:
return 32;
case 14:
return 48;
default:
case 15:
return 64;
}
#else
return 8;
#endif
}
return dlc;
}
#if 0 /* Not used */
static uint8_t can_bytes2dlc(FAR struct sam_can_s *priv, uint8_t nbytes)
{
if (nbytes <= 8)
{
return nbytes;
}
#ifdef CONFIG_CAN_FD
else if (nbytes <= 12)
{
return 9;
}
else if (nbytes <= 16)
{
return 10;
}
else if (nbytes <= 20)
{
return 11;
}
else if (nbytes <= 24)
{
return 12;
}
else if (nbytes <= 32)
{
return 13;
}
else if (nbytes <= 48)
{
return 14;
}
else /* if (nbytes <= 64) */
{
return 15;
}
#else
else
{
return 8;
}
#endif
}
#endif
/****************************************************************************
* Name: can_open
*
@ -351,7 +455,8 @@ static ssize_t can_read(FAR struct file *filep, FAR char *buffer,
/* Will the next message in the FIFO fit into the user buffer? */
FAR struct can_msg_s *msg = &dev->cd_recv.rx_buffer[dev->cd_recv.rx_head];
int msglen = CAN_MSGLEN(msg->cm_hdr.ch_dlc);
int nbytes = can_dlc2bytes(msg->cm_hdr.ch_dlc);
int msglen = CAN_MSGLEN(nbytes);
if (nread + msglen > buflen)
{
@ -472,6 +577,7 @@ static ssize_t can_write(FAR struct file *filep, FAR const char *buffer,
ssize_t nsent = 0;
irqstate_t flags;
int nexttail;
int nbytes;
int msglen;
int ret = 0;
@ -562,7 +668,8 @@ static ssize_t can_write(FAR struct file *filep, FAR const char *buffer,
*/
msg = (FAR struct can_msg_s *)&buffer[nsent];
msglen = CAN_MSGLEN(msg->cm_hdr.ch_dlc);
nbytes = can_dlc2bytes(msg->cm_hdr.ch_dlc);
msglen = CAN_MSGLEN(nbytes);
memcpy(&fifo->tx_buffer[fifo->tx_tail], msg, msglen);
/* Increment the tail of the circular buffer */