summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/arch/arm/src')
-rwxr-xr-xnuttx/arch/arm/src/lpc17xx/lpc17_can.c57
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_can.h8
-rwxr-xr-xnuttx/arch/arm/src/stm32/stm32_can.c61
3 files changed, 86 insertions, 40 deletions
diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_can.c b/nuttx/arch/arm/src/lpc17xx/lpc17_can.c
index 0494904cf..409785d29 100755
--- a/nuttx/arch/arm/src/lpc17xx/lpc17_can.c
+++ b/nuttx/arch/arm/src/lpc17xx/lpc17_can.c
@@ -745,20 +745,39 @@ static int can_remoterequest(FAR struct can_dev_s *dev, uint16_t id)
static int can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg)
{
FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->cd_priv;
- uint32_t tid = CAN_ID(msg->cm_hdr);
- uint32_t tfi = CAN_DLC(msg->cm_hdr) << 16;
+ uint32_t tid = (uint32_t)msg->cm_hdr.ch_id;
+ uint32_t tfi = (uint32_t)msg->cm_hdr.ch_dlc << 16;
uint32_t regval;
irqstate_t flags;
int ret = OK;
- canvdbg("CAN%d ID: %d DLC: %d\n",
- priv->port, CAN_ID(msg->cm_hdr), CAN_DLC(msg->cm_hdr));
+ canvdbg("CAN%d ID: %d DLC: %d\n", priv->port, msg->cm_hdr.ch_id, msg->cm_hdr.ch_dlc);
- if (CAN_RTR(msg->cm_hdr))
+ if (msg->cm_hdr.ch_rtr)
{
tfi |= CAN_TFI_RTR;
}
+ /* Set the FF bit in the TFI register if this message should be sent with
+ * the extended frame format (and 29-bit extened ID).
+ */
+
+#ifdef CONFIG_CAN_EXTID
+ if (msg->cm_hdr.ch_extid)
+ {
+ /* The provided ID should be 29 bits */
+
+ DEBUGASSERT((tid & ~CAN_TID_ID29_MASK) == 0);
+ tfi |= CAN_TFI_FF;
+ }
+ else
+#endif
+ {
+ /* The provided ID should be 11 bits */
+
+ DEBUGASSERT((tid & ~CAN_TID_ID11_MASK) == 0);
+ }
+
flags = irqsave();
/* Pick a transmit buffer */
@@ -927,14 +946,11 @@ static bool can_txempty(FAR struct can_dev_s *dev)
static void can_interrupt(FAR struct can_dev_s *dev)
{
FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->cd_priv;
+ struct can_hdr_s hdr;
uint32_t data[2];
uint32_t rfs;
uint32_t rid;
uint32_t regval;
- uint16_t hdr;
- uint16_t id;
- uint16_t dlc;
- uint16_t rtr;
/* Read the interrupt and capture register (also clearing most status bits) */
@@ -956,14 +972,23 @@ static void can_interrupt(FAR struct can_dev_s *dev)
/* Construct the CAN header */
- id = rid & CAN_RID_ID11_MASK;
- dlc = (rfs & CAN_RFS_DLC_MASK) >> CAN_RFS_DLC_SHIFT;
- rtr = ((rfs & CAN_RFS_RTR) != 0);
- hdr = CAN_HDR(id, rtr, dlc);
-
- /* Process the received CAN packet */
+ hdr.ch_id = rid;
+ hdr.ch_rtr = ((rfs & CAN_RFS_RTR) != 0);
+ hdr.ch_dlc = (rfs & CAN_RFS_DLC_MASK) >> CAN_RFS_DLC_SHIFT;
+#ifdef CONFIG_CAN_EXTID
+ hdr.ch_extid = ((rfs & CAN_RFS_FF) != 0);
+#else
+ if ((rfs & CAN_RFS_FF) != 0)
+ {
+ canlldbg("ERROR: Received message with extended identifier. Dropped\n");
+ }
+ else
+#endif
+ {
+ /* Process the received CAN packet */
- can_receive(dev, hdr, (uint8_t *)data);
+ can_receive(dev, &hdr, (uint8_t *)data);
+ }
}
/* Check for TX buffer 1 complete */
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32_can.h b/nuttx/arch/arm/src/stm32/chip/stm32_can.h
index b8a0eee91..6eb757263 100644
--- a/nuttx/arch/arm/src/stm32/chip/stm32_can.h
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_can.h
@@ -367,8 +367,8 @@
#define CAN_TIR_TXRQ (1 << 0) /* Bit 0: Transmit Mailbox Request */
#define CAN_TIR_RTR (1 << 1) /* Bit 1: Remote Transmission Request */
#define CAN_TIR_IDE (1 << 2) /* Bit 2: Identifier Extension */
-#define CAN_TIR_EXID_SHIFT (3) /* Bit 3-20: Extended Identifier */
-#define CAN_TIR_EXID_MASK (0x0003ffff << CAN_TIR_EXID_SHIFT)
+#define CAN_TIR_EXID_SHIFT (3) /* Bit 3-31: Extended Identifier */
+#define CAN_TIR_EXID_MASK (0x1fffffff << CAN_TIR_EXID_SHIFT)
#define CAN_TIR_STID_SHIFT (21) /* Bits 21-31: Standard Identifier */
#define CAN_TIR_STID_MASK (0x07ff << CAN_TIR_STID_SHIFT)
@@ -406,8 +406,8 @@
#define CAN_RIR_RTR (1 << 1) /* Bit 1: Remote Transmission Request */
#define CAN_RIR_IDE (1 << 2) /* Bit 2: Identifier Extension */
-#define CAN_RIR_EXID_SHIFT (3) /* Bit 3-20: Extended Identifier */
-#define CAN_RIR_EXID_MASK (0x0003ffff << CAN_RIR_EXID_SHIFT)
+#define CAN_RIR_EXID_SHIFT (3) /* Bit 3-31: Extended Identifier */
+#define CAN_RIR_EXID_MASK (0x1fffffff << CAN_RIR_EXID_SHIFT)
#define CAN_RIR_STID_SHIFT (21) /* Bits 21-31: Standard Identifier */
#define CAN_RIR_STID_MASK (0x07ff << CAN_RIR_STID_SHIFT)
diff --git a/nuttx/arch/arm/src/stm32/stm32_can.c b/nuttx/arch/arm/src/stm32/stm32_can.c
index 8f5a6b8b1..5df6de4f7 100755
--- a/nuttx/arch/arm/src/stm32/stm32_can.c
+++ b/nuttx/arch/arm/src/stm32/stm32_can.c
@@ -783,8 +783,7 @@ static int can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg)
int dlc;
int txmb;
- canllvdbg("CAN%d ID: %d DLC: %d\n",
- priv->port, CAN_ID(msg->cm_hdr), CAN_DLC(msg->cm_hdr));
+ canllvdbg("CAN%d ID: %d DLC: %d\n", priv->port, msg->cm_hdr.ch_id, msg->cm_hdr.ch_dlc);
/* Select one empty transmit mailbox */
@@ -813,20 +812,29 @@ static int can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg)
regval &= ~(CAN_TIR_TXRQ | CAN_TIR_RTR | CAN_TIR_IDE | CAN_TIR_EXID_MASK | CAN_TIR_STID_MASK);
can_putreg(priv, STM32_CAN_TIR_OFFSET(txmb), regval);
- /* Set up the ID. Only standard (11-bit) CAN identifiers are supported
- * (the STM32 supports extended, 29-bit identifiers, but this method does
- * not).
- *
- * Get the 11-bit identifier from the header bits 0-7 and 13-15.
- */
+ /* Set up the ID, standard 11-bit or extended 29-bit. */
+#ifdef CONFIG_CAN_EXTID
+ regval &= ~CAN_TIR_EXID_MASK;
+ if (msg->cm_hdr.ch_extid)
+ {
+ DEBUGASSERT(msg->cm_hdr.ch_id < (1 << 29));
+ regval |= (msg->cm_hdr.ch_id << CAN_TIR_EXID_SHIFT) | CAN_TIR_IDE;
+ }
+ else
+ {
+ DEBUGASSERT(msg->cm_hdr.ch_id < (1 << 11));
+ regval |= msg->cm_hdr.ch_id << CAN_TIR_STID_SHIFT;
+ }
+#else
regval &= ~CAN_TIR_STID_MASK;
- regval |= (uint32_t)CAN_ID(msg->cm_hdr) << CAN_TIR_STID_SHIFT;
+ regval |= (uint32_t)msg->cm_hdr.ch_id << CAN_TIR_STID_SHIFT;
+#endif
can_putreg(priv, STM32_CAN_TIR_OFFSET(txmb), regval);
/* Set up the DLC */
- dlc = CAN_DLC(msg->cm_hdr);
+ dlc = msg->cm_hdr.ch_dlc;
regval = can_getreg(priv, STM32_CAN_TDTR_OFFSET(txmb));
regval &= ~(CAN_TDTR_DLC_MASK | CAN_TDTR_TGT);
regval |= (uint32_t)dlc << CAN_TDTR_DLC_SHIFT;
@@ -989,12 +997,10 @@ static int can_rx0interrupt(int irq, void *context)
{
FAR struct can_dev_s *dev = NULL;
FAR struct stm32_can_s *priv;
+ struct can_hdr_s hdr;
uint8_t data[CAN_MAXDATALEN];
uint32_t regval;
int npending;
- int id;
- int rtr;
- int dlc;
int ret;
#if defined(CONFIG_STM32_CAN1) && defined(CONFIG_STM32_CAN2)
@@ -1029,9 +1035,21 @@ static int can_rx0interrupt(int irq, void *context)
can_dumpmbregs(priv, "RX0 interrupt");
- /* Get the CAN identifier. Only standard 11-bit IDs are supported */
+ /* Get the CAN identifier. */
regval = can_getreg(priv, STM32_CAN_RI0R_OFFSET);
+#ifdef CONFIG_CAN_EXTID
+ if ((regval & CAN_RIR_IDE) != 0)
+ {
+ hdr.ch_id = (regval & CAN_RIR_EXID_MASK) >> CAN_RIR_EXID_SHIFT;
+ hdr.ch_extid = true;
+ }
+ else
+ {
+ hdr.ch_id = (regval & CAN_RIR_STID_MASK) >> CAN_RIR_STID_SHIFT;
+ hdr.ch_extid = false;
+ }
+#else
if ((regval & CAN_RIR_IDE) != 0)
{
canlldbg("ERROR: Received message with extended identifier. Dropped\n");
@@ -1039,16 +1057,17 @@ static int can_rx0interrupt(int irq, void *context)
goto errout;
}
- id = (regval & CAN_RIR_STID_MASK) >> CAN_RIR_STID_SHIFT;
+ hdr.ch_id = (regval & CAN_RIR_STID_MASK) >> CAN_RIR_STID_SHIFT;
+#endif
- /* Get the Remote Transmission Request (RTR) */
+ /* Extract the RTR bit */
- rtr = (regval & CAN_RIR_RTR) != 0 ? 1 : 0;
+ hdr.ch_rtr = (regval & CAN_RIR_RTR) != 0 ? true : false;
/* Get the DLC */
- regval = can_getreg(priv, STM32_CAN_RDT0R_OFFSET);
- dlc = (regval & CAN_RDTR_DLC_MASK) >> CAN_RDTR_DLC_SHIFT;
+ regval = can_getreg(priv, STM32_CAN_RDT0R_OFFSET);
+ hdr.ch_dlc = (regval & CAN_RDTR_DLC_MASK) >> CAN_RDTR_DLC_SHIFT;
/* Save the message data */
@@ -1066,11 +1085,13 @@ static int can_rx0interrupt(int irq, void *context)
/* Provide the data to the upper half driver */
- ret = can_receive(dev, (uint16_t)CAN_HDR(id, rtr, dlc), data);
+ ret = can_receive(dev, &hdr, data);
/* Release the FIFO0 */
+#ifndef CONFIG_CAN_EXTID
errout:
+#endif
regval = can_getreg(priv, STM32_CAN_RF0R_OFFSET);
regval |= CAN_RFR_RFOM;
can_putreg(priv, STM32_CAN_RF0R_OFFSET, regval);