CAN: Add CAN FD mode as a configuration option
This commit is contained in:
parent
36d4559ee8
commit
4b58990362
2
arch
2
arch
@ -1 +1 @@
|
||||
Subproject commit 478948e2fd0c1621bce15195c6f207df4156fbe6
|
||||
Subproject commit b331b89caf5aa68bc8b8e585b35e10777f469e1c
|
@ -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
|
||||
|
111
drivers/can.c
111
drivers/can.c
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user