Hi Fiona & Alice,
This is a weird problem, I added volatile to many places, it still doesn't work. Let me explain here:
The Can Mem Map structure is redefined as:
typedef struct {
volatile uint32_t CS;
volatile uint32_t ID;
volatile uint32_t WORD0;
volatile uint32_t WORD1;
} MBox, *PMBox;
typedef struct CanMemMap {
uint32_t MCR;
//omitted...
volatile MBox MB[16];
uint8_t RESERVED_3[1792];
uint32_t RXIMR[16];
} volatile *CanMemMapPtr;
//for CanReadTask: -I replaced MB[index] with a pointer. It works OK.
void CanRead_Task(uint32_t param) {
PMBox pMB= (PMBox)&(g_pCanReg->MB[RX_MB_num]); //not even use volatile
while (1) {
if (_lwevent_wait_ticks(&lwEvent, 1 << RX_MB_num, FALSE, 0) != MQX_OK) {
pMB->CS;
dwID = -1;
dwDLen = pMB->CS & CAN_CS_DLC_MASK;
dwDLC = dwDLen >> CAN_CS_DLC_SHIFT;
if (dwFormat == FLEXCAN_STANDARD) {
dwID = ((pMB->ID & CAN_ID_STD_MASK) >> CAN_ID_STD_SHIFT);
bCode = (uint8_t) (pMB->CS >> CAN_CS_CODE_SHIFT);
if (bCode == CAN_RX_MSG_BUFFER_FULL) {
dwData0 = pMB->WORD0 ;
dwData1 = pMB->WORD1 ;
}
pMB->WORD0 = 0;
pMB->WORD1 = 0;
pMB->CS &= ~(CAN_CS_CODE_MASK);
pMB->CS |= (CAN_CS_CODE(CAN_RX_MSG_BUFFER_EMPTY) | dwDLen);
g_pCanReg->TIMER; //FLEXCAN_Unlock_mailbox(CAN_DEVICE);
FLEXCAN_Request_message(CAN_DEVICE, RX_remote_MB_num, dwFormat);
_time_delay(1);
}
}
//for CanTxTask -
void CanWrite_Task(uint32_t param) {
volatile PMBox volatile pTxMB= (PMBox)&(g_pCanReg->MB[TX_MB_num]);
while (1) {
dwTxDLC = (dwTxDlen << CAN_CS_DLC_SHIFT);
pTxMB->CS |= CAN_CS_CODE(CAN_TX_MSG_BUFFER_NOT_ACTIVE);
pTxMB->WORD0 = g_aCanTxBuf[bCanTxBufTail].WORD0;
pTxMB->WORD1 = g_aCanTxBuf[bCanTxBufTail].WORD1;
pTxMB->CS |= (CAN_CS_CODE(CAN_MESSAGE_TRANSMIT_ONCE) | dwTxDLC);
dwRTRBit = pTxMB->CS; // check for RTR bit
if ((dwRTRBit & CAN_CS_CODE(CAN_TX_MSG_BUFFER_NOT_ACTIVE))==
CAN_CS_CODE(CAN_TX_MSG_BUFFER_NOT_ACTIVE)) {
//volatile PMBox pTxMBx= (PMBox)&(g_pCanReg->MB[TX_MB_num]);
pTxMB->CS &= ~(CAN_CS_CODE_MASK); //LineA
pTxMB->CS |= (CAN_CS_CODE(CAN_MESSAGE_TRANSMIT_RESPONED) | dwTxDLC);//LineB
//g_pCanReg->MB[TX_MB_num].CS &= ~(CAN_CS_CODE_MASK);//LineC
//g_pCanReg->MB[TX_MB_num].CS |= (CAN_CS_CODE(CAN_MESSAGE_TRANSMIT_RESPONED) | dwTxDLC);//LineD
_time_delay(1);
}
}
Note: (both tasks are based on FlexCan/test.c in the example folder. some code is omitted for clearness.)
If pTxMBx is defined, and LineA and LineB are pTxMBx->, then it transmits CAN messages. (OK)
if use LineC, and LineD to replace LineA and LineB, it also works.
I checked pTxMB address, it points to the right memory. It never changes. But only LineA and LineB can not use pTxMB pointer. Otherwise, it doesn't transmit CAN messages. (or may have one message transmitted).
Thank you,
David