diff --git a/arch/arm/src/lpc17xx/lpc17_can.c b/arch/arm/src/lpc17xx/lpc17_can.c index 0494904cf9..409785d290 100755 --- a/arch/arm/src/lpc17xx/lpc17_can.c +++ b/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); + 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 */ - /* 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/arch/arm/src/stm32/chip/stm32_can.h b/arch/arm/src/stm32/chip/stm32_can.h index b8a0eee91c..6eb757263d 100644 --- a/arch/arm/src/stm32/chip/stm32_can.h +++ b/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/arch/arm/src/stm32/stm32_can.c b/arch/arm/src/stm32/stm32_can.c index 8f5a6b8b1e..5df6de4f71 100755 --- a/arch/arm/src/stm32/stm32_can.c +++ b/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);