diff --git a/arch/arm/src/sama5/chip/sam_can.h b/arch/arm/src/sama5/chip/sam_can.h index 00632eb43d..18f6bf4fab 100644 --- a/arch/arm/src/sama5/chip/sam_can.h +++ b/arch/arm/src/sama5/chip/sam_can.h @@ -326,8 +326,44 @@ #define CAN_MSR_MRDY (1 << 23) /* Bit 23: Mailbox Ready */ #define CAN_MSR_MMI (1 << 24) /* Bit 24: Mailbox Message Ignored */ -/* Mailbox Data Low Register (32-bit data low value) */ -/* Mailbox Data High Register (32-bit data high value) */ +/* Mailbox Data Low Register and Mailbox Data High Register. + * Bytes are received/sent on the bus in the following order: + * + * 1. CAN_MDL[7:0] + * 2. CAN_MDL[15:8] + * 3. CAN_MDL[23:16] + * 4. CAN_MDL[31:24] + * 5. CAN_MDH[7:0] + * 6. CAN_MDH[15:8] + * 7. CAN_MDH[23:16] + * 8. CAN_MDH[31:24] + */ + +#define CAN_MDL0_SHIFT (0) /* Bits 0-7: Byte 0 */ +#define CAN_MDL0_MASK (0xff << CAN_MDL0_SHIFT) +# define CAN_MDL0(n) ((uint32_t)(n) << CAN_MDL0_SHIFT) +#define CAN_MDL1_SHIFT (8) /* Bits 8-15: Byte 1 */ +#define CAN_MDL1_MASK (0xff << CAN_MDL1_SHIFT) +# define CAN_MDL1(n) ((uint32_t)(n) << CAN_MDL1_SHIFT) +#define CAN_MDL2_SHIFT (16) /* Bits 16-23: Byte 2 */ +#define CAN_MDL2_MASK (0xff << CAN_MDL2_SHIFT) +# define CAN_MDL2(n) ((uint32_t)(n) << CAN_MDL2_SHIFT) +#define CAN_MDL3_SHIFT (24) /* Bits 24-31: Byte 3 */ +#define CAN_MDL3_MASK (0xff << CAN_MDL3_SHIFT) +# define CAN_MDL3(n) ((uint32_t)(n) << CAN_MDL3_SHIFT) + +#define CAN_MDH4_SHIFT (0) /* Bits 0-7: Byte 4 */ +#define CAN_MDH4_MASK (0xff << CAN_MDH4_SHIFT) +# define CAN_MDH4(n) ((uint32_t)(n) << CAN_MDH4_SHIFT) +#define CAN_MDH5_SHIFT (8) /* Bits 8-15: Byte 5 */ +#define CAN_MDH5_MASK (0xff << CAN_MDH5_SHIFT) +# define CAN_MDH5(n) ((uint32_t)(n) << CAN_MDH5_SHIFT) +#define CAN_MDH6_SHIFT (16) /* Bits 16-23: Byte 6 */ +#define CAN_MDH6_MASK (0xff << CAN_MDH6_SHIFT) +# define CAN_MDH6(n) ((uint32_t)(n) << CAN_MDH6_SHIFT) +#define CAN_MDH7_SHIFT (24) /* Bits 24-31: Byte 7 */ +#define CAN_MDH7_MASK (0xff << CAN_MDH7_SHIFT) +# define CAN_MDH7(n) ((uint32_t)(n) << CAN_MDH7_SHIFT) /* Mailbox Control Register */ diff --git a/arch/arm/src/sama5/sam_can.c b/arch/arm/src/sama5/sam_can.c index 5bd302fb0e..5a79a9ec49 100644 --- a/arch/arm/src/sama5/sam_can.c +++ b/arch/arm/src/sama5/sam_can.c @@ -1087,7 +1087,7 @@ 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 sam_can_s *priv; - FAR uint32_t *md; + FAR uint8_t *ptr; uint32_t regval; int mbndx; @@ -1159,11 +1159,14 @@ static int can_send(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg) # warning REVISIT #endif - DEBUGASSERT(((uintptr_t)msg->cm_data & 3) == 0); - md = (FAR uint32_t *)msg->cm_data; + /* The message buffer is probably not properaly aligned for 32-bit accesses */ - can_putreg(priv, SAM_CAN_MnDL_OFFSET(mbndx), md[0]); - can_putreg(priv, SAM_CAN_MnDH_OFFSET(mbndx), md[1]); + ptr = msg->cm_data; + regval = CAN_MDL0(ptr[0]) | CAN_MDL1(ptr[1]) | CAN_MDL2(ptr[1]) | CAN_MDL3(ptr[1]); + can_putreg(priv, SAM_CAN_MnDL_OFFSET(mbndx), regval); + + regval = CAN_MDH4(ptr[4]) | CAN_MDH5(ptr[5]) | CAN_MDH6(ptr[6]) | CAN_MDH7(ptr[7]); + can_putreg(priv, SAM_CAN_MnDH_OFFSET(mbndx), regval); /* Set the DLC value in the CAN_MCRx register. Set the MTCR register * clearing MRDY, and indicating that the message is ready to be sent. @@ -1501,7 +1504,7 @@ static void can_interrupt(FAR struct can_dev_s *dev) * - Sleep interrupt: This interrupt is generated after a Low-power Mode * enable once all pending messages in transmission have been sent. * - Internal timer counter overflow interrupt: This interrupt is - * generated when the internal timer rolls over. + * generated when the internal timer rolls over. * - Timestamp interrupt: This interrupt is generated after the reception * or the transmission of a start of frame or an end of frame. The value * of the internal counter is copied in the CAN_TIMESTP register.