AnsweredAssumed Answered

Testing CAN loopback mode on LPC11C24

Question asked by AINHOA CORTES on Mar 30, 2017
Latest reply on May 31, 2017 by Kerry Zhou

Hello All,

 

I have a problem testing the loop back mode for CAN controller on LPC11C24. I am using the can example of LPCopen. This example uses the on-chip CAN API mentioned in UM10398. I do not know how to configure the source code in order to work in loopback mode only as a first test. In fact, I'm not sure if the example is or not in this mode. When I debug the example, the system enters in the CAN_error callback. So, nothing is transmitted nor received. If the on-chip CAN is not in loopback mode, it's normal because I do not have connected any CAN node. But then, how can I configure the on-chip CAN registers to work in loopback mode using this on-chip CAN API? 

 

The code is this:

 

#include "board.h"
#include "cr_section_macros.h"

/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/

#define TEST_CCAN_BAUD_RATE 500000

//reserve CAN ROM-RAM 0x1000 0050 - 0x1000 00B9
__BSS(RESERVED) char CAN_driver_memory[0xC0];

/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/

#define TEST_CCAN_BAUD_RATE 500000

CCAN_MSG_OBJ_T msg_obj;
volatile unsigned short rx_counter=0; //receive counter
volatile unsigned short tx_counter=0; //transmit counter
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/

/*****************************************************************************
* Private functions
****************************************************************************/
void baudrateCalculate(uint32_t baud_rate, uint32_t *can_api_timing_cfg)
{
uint32_t pClk, div, quanta, segs, seg1, seg2, clk_per_bit, can_sjw;
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_CAN);
pClk = Chip_Clock_GetMainClockRate();

clk_per_bit = pClk / baud_rate;

for (div = 0; div <= 15; div++) {
for (quanta = 1; quanta <= 32; quanta++) {
for (segs = 3; segs <= 17; segs++) {
if (clk_per_bit == (segs * quanta * (div + 1))) {
segs -= 3;
seg1 = segs / 2;
seg2 = segs - seg1;
can_sjw = seg1 > 3 ? 3 : seg1;
can_api_timing_cfg[0] = div;
can_api_timing_cfg[1] =
((quanta - 1) & 0x3F) | (can_sjw & 0x03) << 6 | (seg1 & 0x0F) << 8 | (seg2 & 0x07) << 12;
return;
}
}
}
}
}

/* CAN receive callback */
/* Function is executed by the Callback handler after
a CAN message has been received */
void CAN_rx(uint8_t msg_obj_num) {
rx_counter++;
/* Determine which CAN message has been received */
msg_obj.msgobj = msg_obj_num;
/* Now load up the msg_obj structure with the CAN message */
LPC_CCAN_API->can_receive(&msg_obj);
if (msg_obj_num == 1) {
/* Simply transmit CAN frame (echo) with with ID +0x100 via buffer 2 */
msg_obj.msgobj = 2;
msg_obj.mode_id += 0x100;
LPC_CCAN_API->can_transmit(&msg_obj);
}
return;
}

/* CAN transmit callback */
/* Function is executed by the Callback handler after
a CAN message has been transmitted */
void CAN_tx(uint8_t msg_obj_num) {

tx_counter++;
return;
}

/* CAN error callback */
/* Function is executed by the Callback handler after
an error has occured on the CAN bus */
void CAN_error(uint32_t error_info) {
return;
}

/**
* @brief CCAN Interrupt Handler
* @return Nothing
* @note The CCAN interrupt handler must be provided by the user application.
* It's function is to call the isr() API located in the ROM
*/
void CAN_IRQHandler(void) {
LPC_CCAN_API->isr();
}

/*****************************************************************************
* Public functions
****************************************************************************/

/**
* @brief Main routine for CCAN_ROM example
* @return Nothing
*/
int main(void)
{
volatile unsigned int i,counter=0;
uint32_t CanApiClkInitTable[2];
/* Publish CAN Callback Functions */
CCAN_CALLBACKS_T callbacks = {
CAN_rx,
CAN_tx,
CAN_error,
NULL,
NULL,
NULL,
NULL,
NULL,
};
SystemCoreClockUpdate();
Board_Init();
baudrateCalculate(TEST_CCAN_BAUD_RATE, CanApiClkInitTable);

LPC_CCAN_API->init_can(&CanApiClkInitTable[0], TRUE);
/* Configure the CAN callback functions */
LPC_CCAN_API->config_calb(&callbacks);
//set loop back mode
//LPC_CAN->CNTL |= (1<<7);
//LPC_CCAN->TEST |= (1<<4);

/* Enable the CAN Interrupt */
NVIC_EnableIRQ(CAN_IRQn);

/* Send a simple one time CAN message */
msg_obj.msgobj = 0;
msg_obj.mode_id = 0x345; 
msg_obj.mask = 0x7F0;
msg_obj.dlc = 4;
msg_obj.data[0] = 'T'; // 0x54
msg_obj.data[1] = 'E'; // 0x45
msg_obj.data[2] = 'S'; // 0x53
msg_obj.data[3] = 'T'; // 0x54
LPC_CCAN_API->can_transmit(&msg_obj);

/* Configure message object 1 to receive all 11-bit messages 0x400-0x4FF */
msg_obj.msgobj = 1;
msg_obj.mode_id = 0x300;
msg_obj.mask = 0x7F0;
LPC_CCAN_API->config_rxmsgobj(&msg_obj);

while (1) {
__WFI(); /* Go to Sleep */
}
}

 

I do not find any helpful information. I have found another kind of problems related to on-chip CAN but it seems that people achieve working in loopback mode but not using on-chip CAN API.

 

Could anybody help me with this issue?

 

Thanks.

Outcomes