SAMA5 CAN: Fix a data alignment problem

This commit is contained in:
Gregory Nutt 2013-11-03 10:41:24 -06:00
parent 93aae8c2c5
commit b9130ff601
3 changed files with 48 additions and 9 deletions

View File

@ -5955,5 +5955,5 @@
write so that the device is complete before WRDI is sent. From
David Sidrane (2013-11-2).
* configs/sama5/src/sam_can.c: Add CAN initialization logic
(2013-11-3).
and fix a data alignment problem (2013-11-3).

View File

@ -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 */

View File

@ -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.