mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 00:14:22 +08:00
CAN: Add CAN FD mode as a configuration option
This commit is contained in:
+1
-1
Submodule arch updated: 478948e2fd...b331b89caf
+8
-1
@@ -99,13 +99,20 @@ menuconfig CAN
|
|||||||
See include/nuttx/can.h for further CAN driver information.
|
See include/nuttx/can.h for further CAN driver information.
|
||||||
|
|
||||||
if CAN
|
if CAN
|
||||||
|
|
||||||
config CAN_EXTID
|
config CAN_EXTID
|
||||||
bool "CAN extended IDs"
|
bool "CAN extended IDs"
|
||||||
default n
|
default n
|
||||||
---help---
|
---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.
|
IDs.
|
||||||
|
|
||||||
|
config CAN_FD
|
||||||
|
bool "CAN FD"
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
Enables support for the CAN_FD mode.
|
||||||
|
|
||||||
config CAN_FIFOSIZE
|
config CAN_FIFOSIZE
|
||||||
int "CAN driver I/O buffer size"
|
int "CAN driver I/O buffer size"
|
||||||
default 8
|
default 8
|
||||||
|
|||||||
+109
-2
@@ -89,6 +89,15 @@
|
|||||||
* Private Function Prototypes
|
* 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_open(FAR struct file *filep);
|
||||||
static int can_close(FAR struct file *filep);
|
static int can_close(FAR struct file *filep);
|
||||||
static ssize_t can_read(FAR struct file *filep, FAR char *buffer,
|
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
|
* 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
|
* 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? */
|
/* 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];
|
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)
|
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;
|
ssize_t nsent = 0;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
int nexttail;
|
int nexttail;
|
||||||
|
int nbytes;
|
||||||
int msglen;
|
int msglen;
|
||||||
int ret = 0;
|
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];
|
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);
|
memcpy(&fifo->tx_buffer[fifo->tx_tail], msg, msglen);
|
||||||
|
|
||||||
/* Increment the tail of the circular buffer */
|
/* Increment the tail of the circular buffer */
|
||||||
|
|||||||
Reference in New Issue
Block a user