CAN clock configuration

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

CAN clock configuration

1,607 Views
anusha_123
Contributor II

Hi, 

We have LPC54606 microcontroller, we're trying to configure CAN1 with default configuration by changing baudrateA=500000, baudrateD=500000 and by disabling both internal and external loop back. But when we check the data in DSO, the data bps is more. 

Please let us know how to control data bps.

 

Regards, 

Anusha 

 

0 Kudos
15 Replies

1,563 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

Thank you for the information, I see that CAN bus of LPC54606 does not support CAN-FD mode, only support standard CAN mode.

Regarding the baud rate of CAN, it is dependent on the CAN driving clock frequency and CAN bit timing, pls refer the section 35.8.4 Nominal bit timing and prescaler register for CAN bit timing.

For the CAN module clock, pls refer to the screenshot:

xiangjun_rong_0-1682213838741.png

 

The CAN driving clock is main_clk by a divider.

If you set the baudrate as 500KHz, the bit cycle of CAN should be 2uS.

Hope it can help you

BR

XiangJun Rong

0 Kudos

1,513 Views
anusha_123
Contributor II

Hi, 

Thank you for your reply, now we're able to do CAN configuration.

I'm transmitting data of 9 bytes. But when i'm receiving data, it is filtering 1st byte and receiving next 8 bytes correctly and we're not doing standard filter configuration for both transmit and receive.

Please let us know how to receive all 9 bytes data.

 

Regards,

Anusha

0 Kudos

1,503 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

Based on CAN protocol, for the standard CAN, one CAN packet can only include 8 bytes at most, for the CAN-FD protocol, one CAN packet can include 64 bytes at most. I suppose that you use standard CAN, you have to transmit/receive 8 bytes in a packet at most.

The LPC54606 only supports standard CAN rather than CAN-FD.

If it is not what you expected, pls tell us if you use standard CAN or CAN-FD.

BR

XiangJun Rong

0 Kudos

1,589 Views
anusha_123
Contributor II

Hi,

We're using LPC54606J256 microcontroller, this doesn't support CANFD and supports CAN2.0 as per the data sheet. So we're configuring it as standard CAN mode. 

 

 

Screenshot (4).png

Regards,

Anusha

0 Kudos

1,592 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

As you know that the CAN bus of LPC546xx supports CAN Flexible Data Rate(CAN_FD), the CAN ID and control bits are in slower bit rate, the Data bits is in higher bit rate. The standard CAN packet includes  8 bytes, but the CAN FD includes 64 bytes at most.

Pls check if you use CAN_FD mode or standard CAN mode.

BR

XiangJun Rong

0 Kudos

1,471 Views
anusha_123
Contributor II

Hi,

Thank you for your reply.

We're not using Standard CAN, we're using customized CAN 2.0 and in our application we want to receive data of 40 bytes without CAN ID.

Please let us know how to configure CAN to receive 40 bytes of data. 

Regards,

Anusha

0 Kudos

1,443 Views
anusha_123
Contributor II

Hi,

In our application we want to receive 9 bytes of data. 9 bytes include one byte of command ID and 8 bytes of data. 

We don't want any command ID filtering and want to receive all the 9 bytes of data. 

We tried disabling the filters but still the first byte is getting filtered out. It will be helpful if you can let us know how to receive all the 9 bytes of data. 

Thanks, 

Anusha

0 Kudos

1,423 Views
frank_m
Senior Contributor III

It seems you did not get the point.

CAN is a standardized protocol.
The standard CAN protocol contains 8 data bytes.
You cannot stuff more into a frame.

If you want a greater data size per frame, use CAN-FD with up to 64 bytes, or CAN-XL with up to 2048 bytes. 
In this case, you need a different MCU.

0 Kudos

1,417 Views
anusha_123
Contributor II
Hi,
We are clear on the standard CAN and CAN FD.
In our application we want to receive the CAN packet which is 9 bytes, first byte is CAN command ID and rest is the data.
E.g. AB 01 02 03 04 05 06 07 08. When we receive the data with our current configuration (Our similar to example code), we are missing the command ID i.e. AB and receiving rest of the data from 01 - 08. Could you please let me know how we can receive the CAN command ID (in this case AB) also along with data.

Thanks,
Anusha
0 Kudos

1,405 Views
frank_m
Senior Contributor III

> In our application we want to receive the CAN packet which is 9 bytes, first byte is CAN command ID and rest is the data.

With standard CAN, this is not possible.

As said, the protocol itself is standardized.
Compared to other serial protocols like RS232, SPI or I2C, CAN is rather complex.
As a result, most MCU vendors have licenced the Bosch IP for their CAN peripheral, which automatically handles all protocol adminstration (bit timing, error checking, address arbitration, etc.).
No recent MCU I know has the capability to send and receive such non-standard packets you want.

Alternatively to CAN-FD, you can take a look at higher-level protocol like ISO-TP or CANopen, which have provisions for block transfers of arbitrary size.

0 Kudos

1,402 Views
anusha_123
Contributor II
Hi,
Based on the CAN example(Given in LPC54606J256 SDK), the txFrame.id and rxFrame.id is what we want to recieve, but it is filtering. we're not trying to receive more than 8 bytes of data. we just want to receive the data with the txFrame.id. In the above example that is referred as AB.

Our customer has deigned an USB to CAN converter(LPC CAN controller converter) data is received through USB and converted it to CAN.

Thanks,
Anusha
0 Kudos

1,397 Views
frank_m
Senior Contributor III

While I deal a lot with CAN bus devices, I never tried a LPC5xxx in this regard.
Thus I have no experience with that specific SDK / MCU.

> Based on the CAN example(Given in LPC54606J256 SDK), the txFrame.id and rxFrame.id is what we want to recieve, but it is filtering.

So you would need to change the SDK example, and remove any filtering.

You don't "receive the rxFrame.id" - the ID (or address) is part of the CAN frame, and returned to you in the "id" variable of a struct.
The CAN bus arbitration in general is based upon this IDs/addresses, and every node always received every correct frame on the bus. But depending on set filter rules inside the node, it might discard frames before they are transferred to the message buffer, thus the MCU does not see it.

0 Kudos

1,392 Views
anusha_123
Contributor II
In our case, we are receiving the data, but the ID/address is filtered. We tried commenting the filters, still no progress.
0 Kudos

1,381 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

Based on CAN protocol, in the CAN packet, the destination ID is included, so you can get the actual  ID on the CAN receiver side.

This is the CAN receiving packet structure:

typedef struct _mcan_rx_buffer_frame
{
struct
{
uint32_t id : 29; /*!< CAN Frame Identifier. */
uint32_t rtr : 1; /*!< CAN Frame Type(DATA or REMOTE). */
uint32_t xtd : 1; /*!< CAN Frame Type(STD or EXT). */
uint32_t esi : 1; /*!< CAN Frame Error State Indicator. */
};
struct
{
uint32_t rxts : 16; /*!< Rx Timestamp. */
uint32_t dlc : 4; /*!< Data Length Code 9 10 11 12 13 14 15
Number of data bytes 12 16 20 24 32 48 64 */
uint32_t brs : 1; /*!< Bit Rate Switch. */
uint32_t fdf : 1; /*!< CAN FD format. */
uint32_t : 2; /*!< Reserved. */
uint32_t fidx : 7; /*!< Filter Index. */
uint32_t anmf : 1; /*!< Accepted Non-matching Frame. */
};
uint8_t *data;
uint8_t size; /*!< classical CAN is 8(bytes), FD is 12/64 such. */
} mcan_rx_buffer_frame_t;

 

I copy the code based on CAN example.

while (1)
{
if ((node_type == 'A') || (node_type == 'a'))
{
GETCHAR();
/* Config TX frame data. */
memset(tx_data, 0, sizeof(uint8_t) * CAN_DATASIZE);
for (cnt = 0; cnt < CAN_DATASIZE; cnt++)
{
tx_data[cnt] = cnt;
}
tx_data[0] += numMessage++;
txFrame.xtd = kMCAN_FrameIDStandard;
txFrame.rtr = kMCAN_FrameTypeData;
txFrame.fdf = 0;
txFrame.brs = 0;
txFrame.dlc = 8U;
txFrame.id = txIdentifier << STDID_OFFSET;
txFrame.data = tx_data;
txFrame.size = CAN_DATASIZE;
#if (defined(USE_CANFD) && USE_CANFD)
txFrame.fdf = 1;
txFrame.brs = 1;
txFrame.dlc = DLC;
#endif
txXfer.frame = &txFrame;
txXfer.bufferIdx = 0;
MCAN_TransferSendNonBlocking(EXAMPLE_MCAN, &mcanHandle, &txXfer);

while (!txComplete)
{
}
txComplete = false;

/* Start receive data through Rx FIFO 0. */
memset(rx_data, 0, sizeof(uint8_t) * CAN_DATASIZE);
/* the MCAN engine can't auto to get rx payload size, we need set it. */
rxFrame.size = CAN_DATASIZE;
rxXfer.frame = &rxFrame;
MCAN_TransferReceiveFifoNonBlocking(EXAMPLE_MCAN, 0, &mcanHandle, &rxXfer);

/* Wait until message received. */
while (!rxComplete)
{
}
rxComplete = false;

/* After call the API of rMCAN_TransferReceiveFifoNonBlocking success, we can
* only get a point (rxFrame.data) to the fifo reading entrance.
* Copy the received frame data from the FIFO by the pointer(rxFrame.data). */
memcpy(rx_data, rxFrame.data, rxFrame.size);

PRINTF("Received Frame ID: 0x%x\r\n", rxFrame.id >> STDID_OFFSET);
PRINTF("Received Frame DATA: ");
cnt = 0;
while (cnt < rxFrame.size)
{
PRINTF("0x%x ", rx_data[cnt++]);
}
PRINTF("\r\n");
PRINTF("Press any key to trigger the next transmission!\r\n\r\n");
}
else
{
memset(rx_data, 0, sizeof(uint8_t) * CAN_DATASIZE);
/* the MCAN engine can't auto to get rx payload size, we need set it. */
rxFrame.size = CAN_DATASIZE;
rxXfer.frame = &rxFrame;
MCAN_TransferReceiveFifoNonBlocking(EXAMPLE_MCAN, 0, &mcanHandle, &rxXfer);

while (!rxComplete)
{
}
rxComplete = false;

/* After call the API of rMCAN_TransferReceiveFifoNonBlocking success, we can
* only get a point (rxFrame.data) to the fifo reading entrance.
* Copy the received frame data from the FIFO by the pointer(rxFrame.data). */
memcpy(rx_data, rxFrame.data, rxFrame.size);

//Rong wrote:
uint32_t tempID;
tempID=rxFrame.id;

PRINTF("Received Frame ID: 0x%x\r\n", rxFrame.id >> STDID_OFFSET);
PRINTF("Received Frame DATA: ");

cnt = 0;
while (cnt < rxFrame.size)
{
PRINTF("0x%x ", rx_data[cnt++]);
}
PRINTF("\r\n");

/* Copy received frame data to tx frame. */
memcpy(tx_data, rx_data, CAN_DATASIZE);

txFrame.xtd = rxFrame.xtd;
txFrame.rtr = rxFrame.rtr;
txFrame.fdf = rxFrame.fdf;
txFrame.brs = rxFrame.brs;
txFrame.dlc = rxFrame.dlc;
txFrame.id = txIdentifier << STDID_OFFSET;
txFrame.data = tx_data;
txFrame.size = rxFrame.size;
txXfer.frame = &txFrame;
txXfer.bufferIdx = 0;

MCAN_TransferSendNonBlocking(EXAMPLE_MCAN, &mcanHandle, &txXfer);

while (!txComplete)
{
}
txComplete = false;
PRINTF("Wait Node A to trigger the next transmission!\r\n\r\n");
}
}
}

Hope it can help you

BR

XiangJun Rong

0 Kudos

1,382 Views
frank_m
Senior Contributor III

As said, I have not worked with CAN on LPC5xxx MCUs yet.
Perhaps you can post some of your code here, pretty sure soemone can help you.

Browsing through a MCAN example in a SDK for the LPC54628 I have, this seems to be confined to the functions MCAN_SetFilterConfig()MCAN_SetSTDFilterElement() and MCAN_SetEXTFilterElement() in the source file fsl_mcan.c.

0 Kudos