Hello,
I've just started using TMS570LS1227 on a Demo board and have a problem with receiving CAN messages. Init code is generated by HALCoGen. CAN has all the standard settings except sending with ID1 from Messagebox1 and receiving ID1 to Messagebox2.
I'm using a USB - CAN tool to send and receive messages to/from the board. Sending from board to computer works fine. But the board doesn't seem to receive CAN messages from the computer. I have scoped the signals, and I can see that the messages are sent from the computer, and that they are acknowledged by the board. But the function canIsRxMessageArrived() (or canGetData()) always returns 0. I have stepped through those functions, see that they poll a bit in the NWDATx register to know. I have extended the polling to all bit in several registers in the following code. But they all remain 0.
canInit();
//canEnableloopback(canREG1, External_Lbk);
while(1)
{
uint8_t i = 0;
uint32_t temp = canREG1->NWDATX;
temp |= canREG1->INTPNDX;
temp |= canREG1->TXRQX;
for (i = 0; i < 4; i++)
{
temp |= canREG1->NWDATx[i];
temp |= canREG1->INTPNDx[i];
temp |= canREG1->TXRQx[i];
}
if (temp != 0)
{
temp = 0;
}
}
This is the init function generated by HALCoGen:
void canInit(void)
{
/* USER CODE BEGIN (4) */
/* USER CODE END */
/** @b Initialize @b CAN1: */
/** - Setup control register
* - Disable automatic wakeup on bus activity
* - Local power down mode disabled
* - Disable DMA request lines
* - Enable global Interrupt Line 0 and 1
* - Disable debug mode
* - Release from software reset
* - Enable/Disable parity or ECC
* - Enable/Disable auto bus on timer
* - Setup message completion before entering debug state
* - Setup normal operation mode
* - Request write access to the configuration registers
* - Setup automatic retransmission of messages
* - Disable error interrupts
* - Disable status interrupts
* - Enter initialization mode
*/
canREG1->CTL = (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)((uint32)0x00000005U << 10U)
| (uint32)0x00020043U;
/** - Clear all pending error flags and reset current status */
canREG1->ES |= 0xFFFFFFFFU;
/** - Assign interrupt level for messages */
canREG1->INTMUXx[0U] = (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U;
canREG1->INTMUXx[1U] = (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U
| (uint32)0x00000000U;
/** - Setup auto bus on timer period */
canREG1->ABOTR = (uint32)0U;
/** - Initialize message 1
* - Wait until IF1 is ready for use
* - Set message mask
* - Set message control word
* - Set message arbitration
* - Set IF1 control byte
* - Set IF1 message number
*/
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
while ((canREG1->IF1STAT & 0x80U) ==0x80U)
{
} /* Wait */
canREG1->IF1MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x000007FFU & (uint32)0x1FFFFFFFU) << (uint32)0U);
canREG1->IF1ARB = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x20000000U | (uint32)((uint32)((uint32)1U & (uint32)0x1FFFFFFFU) << (uint32)0U);
canREG1->IF1MCTL = 0x00001080U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
canREG1->IF1CMD = (uint8) 0xF8U;
canREG1->IF1NO = 1U;
/** - Initialize message 2
* - Wait until IF2 is ready for use
* - Set message mask
* - Set message control word
* - Set message arbitration
* - Set IF2 control byte
* - Set IF2 message number
*/
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
while ((canREG1->IF2STAT & 0x80U) ==0x80U)
{
} /* Wait */
canREG1->IF2MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x000007FFU & (uint32)0x1FFFFFFFU) << (uint32)0U);
canREG1->IF2ARB = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x00000000U | (uint32)((uint32)((uint32)5U & (uint32)0x1FFFFFFFU) << (uint32)0U);
canREG1->IF2MCTL = 0x00001080U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
canREG1->IF2CMD = (uint8) 0xF8U;
canREG1->IF2NO = 2U;
/** - Setup IF1 for data transmission
* - Wait until IF1 is ready for use
* - Set IF1 control byte
*/
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
while ((canREG1->IF1STAT & 0x80U) ==0x80U)
{
} /* Wait */
canREG1->IF1CMD = 0x87U;
/** - Setup IF2 for reading data
* - Wait until IF1 is ready for use
* - Set IF1 control byte
*/
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
while ((canREG1->IF2STAT & 0x80U) ==0x80U)
{
} /* Wait */
canREG1->IF2CMD = 0x17U;
/** - Setup bit timing
* - Setup baud rate prescaler extension
* - Setup TSeg2
* - Setup TSeg1
* - Setup sample jump width
* - Setup baud rate prescaler
*/
canREG1->BTR = (uint32)((uint32)0U << 16U) |
(uint32)((uint32)(3U - 1U) << 12U) |
(uint32)((uint32)((5U + 3U) - 1U) << 8U) |
(uint32)((uint32)(3U - 1U) << 6U) |
(uint32)14U;
/** - CAN1 Port output values */
canREG1->TIOC = (uint32)((uint32)1U << 18U )
| (uint32)((uint32)0U << 17U )
| (uint32)((uint32)0U << 16U )
| (uint32)((uint32)1U << 3U )
| (uint32)((uint32)1U << 2U )
| (uint32)((uint32)1U << 1U );
canREG1->RIOC = (uint32)((uint32)1U << 18U )
| (uint32)((uint32)0U << 17U )
| (uint32)((uint32)0U << 16U )
| (uint32)((uint32)1U << 3U )
| (uint32)((uint32)0U << 2U )
| (uint32)((uint32)0U <<1U );
/** - Leave configuration and initialization mode */
canREG1->CTL &= ~(uint32)(0x00000041U);
/** @note This function has to be called before the driver can be used.\n
* This function has to be executed in privileged mode.\n
*/
/* USER CODE BEGIN (5) */
/* USER CODE END */
}
I am able to receive CAN messages sent by the uC itself through external loopback if I activate that feature. That is why I initially was looking for the problem with the oscilloscope. But since the messages are acked by the uC, it seems like the peripheral is working in that regard, it's just that it doesn't seem to set any bits in the NWDATx registers, when not using loopback.
What am I doing wrong?
How to solve this?