LPC54608 Can1 Configuration

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

LPC54608 Can1 Configuration

1,091 Views
fatihozen
Contributor IV

Hello, 

I want to see datas on PIO0_0 and PIO0_1 via canbus. I arranged pin settings as follows.

Then I got confused lil bit. I referenced mcan loopback example in sdk2.0.2. This code works the same system with nxp evaluation board. in sdk's example can0 is used but I'm using can1.

Could anybody help me to configure it correctly ?

uint32_t port0_pin1_config = (/* Pin is configured as CAN1_TD */
IOCON_PIO_FUNC1 |
IOCON_PIO_MODE_PULLUP |
IOCON_PIO_INV_DI |
IOCON_PIO_DIGITAL_EN |
IOCON_PIO_INPFILT_OFF |
IOCON_PIO_SLEW_STANDARD |
IOCON_PIO_OPENDRAIN_DI);
IOCON_PinMuxSet(IOCON, 0U, 1U, port0_pin1_config);

const uint32_t port0_pin0_config = (/* Pin is configured as CAN1_RD */
IOCON_PIO_FUNC1 |
IOCON_PIO_MODE_PULLUP |
IOCON_PIO_INV_DI |
IOCON_PIO_DIGITAL_EN |
IOCON_PIO_INPFILT_OFF |
IOCON_PIO_SLEW_STANDARD |
IOCON_PIO_OPENDRAIN_DI);
IOCON_PinMuxSet(IOCON, 0U, 0U, port0_pin0_config);


void CAN1_IRQ1_IRQHandler(void)
{
MCAN_ClearStatusFlag(CAN1, CAN_IR_RF1N_MASK);
MCAN_ReadRxFifo(CAN1, 1, &rxFrame);
rxComplete = true;
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}

void CAN_getmsg(void)
{
for(int a=0;a<8;a++) {rcv_data[a] = *(rxFrame.data + a);}

MSG[1] = ((rcv_data[3] << 8) | rcv_data[2]);
MSG[2] = ((rcv_data[5] << 8) | rcv_data[4]);
MSG[3] = ((rcv_data[7] << 8) | rcv_data[6]);

Can_get_ID = rxFrame.id>>18U;
PRINTF("GET_ID: %x", Can_get_ID);
PRINTF(" DATA: ");
{PRINTF(" %d %d",rcv_data[0],rcv_data[1]);}
for(int a=1;a<4;a++)
{PRINTF(" %d",MSG[a]);}

}


int main(void)
{

CLOCK_SetClkDiv(kCLOCK_DivCan1Clk, 22U, true); // 180 / 22 = 8,2 mhz. 

BOARD_InitPins();
BOARD_BootClock180M(); // I copied it from another thread. it is working.

MCAN_GetDefaultConfig(&mcanConfig);
MCAN_Init(CAN1, &mcanConfig, CLOCK_GetFreq(kCLOCK_MCAN1));

MCAN_SetMsgRAMBase(CAN1, 0x20010000U);
uint32_t *p=(uint32_t *)(0x20010000U);
memset(p, 0, 0x20U + 0x10U);

rxFilter.address = 0x0;
rxFilter.idFormat = kMCAN_FrameIDStandard;
rxFilter.listSize = 1U;
rxFilter.nmFrame = kMCAN_reject1;
rxFilter.remFrame = kMCAN_rejectFrame;
MCAN_SetFilterConfig(CAN1, &rxFilter);

stdFilter.sfec = kMCAN_storeinFifo1;
stdFilter.sft = kMCAN_dual;
stdFilter.sfid1 = 0x000U;
stdFilter.sfid2 = 0x002U;
MCAN_SetSTDFilterElement(CAN1, &rxFilter, &stdFilter, 0);

rxFifo1.address = 0x10U;
rxFifo1.elementSize = 1U;
rxFifo1.watermark = 0;
rxFifo1.opmode = kMCAN_FifoBlocking;
rxFifo1.datafieldSize = kMCAN_8ByteDatafield;
MCAN_SetRxFifo1Config(CAN1, &rxFifo1);

MCAN_EnableInterrupts(CAN1, 0, CAN_IE_RF1NE_MASK);
EnableIRQ(CAN1_IRQ1_IRQn);

MCAN_EnterNormalMode(CAN1);

while (1)
{
CAN_getmsg();
}
}

Labels (1)
Tags (2)
4 Replies

778 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hello fatih ozen, 

First I recommend you to download the new version (2.4.1) of the SDK, since a lot of improvements and bug fixes were made in this new version.

I modified the example mcan_loopback of the SDK (2.4.1) in order to work with CAN1 instead of CAN0. Here are the modifications I made to the example. 

First, I modified some defines: 

#define EXAMPLE_MCAN_IRQHandler CAN1_IRQ0_IRQHandler
#define EXAMPLE_MCAN_IRQn CAN1_IRQ0_IRQn
#define EXAMPLE_MCAN CAN1
#define MCAN_CLK_FREQ CLOCK_GetFreq(kCLOCK_MCAN1)

In the main I modified the functions that enable the interrupt (lines 157 and 158): 

/* Enable RX fifo0 new message interrupt using interrupt line 0. */
MCAN_EnableInterrupts(EXAMPLE_MCAN, 0, (CAN_IE_RF1NE_MASK >> CAN_IE_RF1NE_SHIFT));
EnableIRQ(CAN1_IRQ0_IRQn);

After I modified the handler: 

void CAN1_IRQ0_IRQHandler(void)
{
    MCAN_ClearStzatusFlag(EXAMPLE_MCAN, (CAN_IE_RF1NE_MASK >> CAN_IE_RF1NE_SHIFT));
    MCAN_ReadRxFifo(EXAMPLE_MCAN, 0, &rxFrame);
    rxComplete = true;
    /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
      exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
    __DSB();
#endif
}

And inside the function  BOARD_InitPins() I added P0_1 as CAN1_TD and P0_0 as CAN1_RD. This remains exactly the same to what you put before.

    const uint32_t port0_pin1_config = (/* Pin is configured as CAN1_TD */
                                         IOCON_PIO_FUNC1 |
                                         /* Selects pull-up function */
                                         IOCON_PIO_MODE_PULLUP |
                                         /* Input function is not inverted */
                                         IOCON_PIO_INV_DI |
                                         /* Enables digital function */
                                         IOCON_PIO_DIGITAL_EN |
                                         /* Input filter disabled */
                                         IOCON_PIO_INPFILT_OFF |
                                         /* Standard mode, output slew rate control is enabled */
                                         IOCON_PIO_SLEW_STANDARD |
                                         /* Open drain is disabled */
                                         IOCON_PIO_OPENDRAIN_DI);
    IOCON_PinMuxSet(IOCON, 0U, 1U, port0_pin1_config);

    const uint32_t port0_pin0_config = (/* Pin is configured as CAN1_RD */
                                         IOCON_PIO_FUNC1 |
                                         /* Selects pull-up function */
                                         IOCON_PIO_MODE_PULLUP |
                                         /* Input function is not inverted */
                                         IOCON_PIO_INV_DI |
                                         /* Enables digital function */
                                         IOCON_PIO_DIGITAL_EN |
                                         /* Input filter disabled */
                                         IOCON_PIO_INPFILT_OFF |
                                         /* Standard mode, output slew rate control is enabled */
                                         IOCON_PIO_SLEW_STANDARD |
                                         /* Open drain is disabled */
                                         IOCON_PIO_OPENDRAIN_DI);
    IOCON_PinMuxSet(IOCON, 0U, 0U, port0_pin0_config);
}

Once I made all these changes I didn't face any problem while working with CAN1 instead of CAN0. In the image below I showed the results of the program running with CAN1. 

pastedImage_3.png

Hope it helps!

Victor.

-----------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

-----------------------------------------------------------------------------------------------------------------------

778 Views
fatihozen
Contributor IV

Okay,
It partly works. According to some changes below, example code is working. PIO0_0 and PIO0_1 are configured as CAN1 pins. Till here it is okay but when it comes to my own code datas are all zero. Same code with CAN0 works but doesn't work with CAN1. What could be the reason ?
These all happens on evaluation board. I just put three cables for each 2 situations.
3 cables for cantx, canrx, ground. Where am I putting them ? to Arduino Shield receptacles R4 .
for CAN0, component J10's 2.(can0 RD),4.(can0 TD) and 16.(GND) pins.
for CAN1, component J9's 2.(can1 RD),4.(can1 TD) and 7.(GND) pins. ( I changed can1 tx and can1 rx pins to PIO1_17 and PIO1_18 )


You can also see can0.c and can1.c as attachment.

#define EXAMPLE_MCAN_IRQHandler CAN1_IRQ0_IRQHandler
#define EXAMPLE_MCAN_IRQn CAN1_IRQ0_IRQn
#define EXAMPLE_MCAN CAN1
#define MCAN_CLK_FREQ CLOCK_GetFreq(kCLOCK_MCAN1)
#define STDID_OFFSET 18U
#define MSG_RAM_BASE 0x20010000U
#define STD_FILTER_OFS 0x0
#define RX_FIFO0_OFS 0x10U
#define TX_BUFFER_OFS 0x20U

void CAN1_IRQ0_IRQHandler(void)
{
MCAN_ClearStatusFlag(EXAMPLE_MCAN, CAN_IR_RF1N_MASK);
MCAN_ReadRxFifo(EXAMPLE_MCAN, 1, &rxFrame);
rxComplete = true;
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}

CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
CLOCK_SetClkDiv(kCLOCK_DivCan1Clk, 22U, true);
BOARD_InitPins();
BOARD_BootClock180M();
BOARD_InitDebugConsole();

MCAN_GetDefaultConfig(&mcanConfig);
mcanConfig.enableLoopBackExt = true;
MCAN_Init(EXAMPLE_MCAN, &mcanConfig, MCAN_CLK_FREQ);

MCAN_SetMsgRAMBase(EXAMPLE_MCAN, MSG_RAM_BASE);
uint32_t *p=(uint32_t *)(MSG_RAM_BASE);
memset(p, 0, TX_BUFFER_OFS + 0x10U);

/* STD filter config. */
rxFilter.address = STD_FILTER_OFS;
rxFilter.idFormat = kMCAN_FrameIDStandard;
rxFilter.listSize = 1U;
rxFilter.nmFrame = kMCAN_reject1;
rxFilter.remFrame = kMCAN_rejectFrame;
MCAN_SetFilterConfig(EXAMPLE_MCAN, &rxFilter);

stdFilter.sfec = kMCAN_storeinFifo1;
stdFilter.sft = kMCAN_dual;
stdFilter.sfid1 = 0x000U;
stdFilter.sfid2 = 0x002U;
MCAN_SetSTDFilterElement(EXAMPLE_MCAN, &rxFilter, &stdFilter, 0);

/* RX fifo0 config. */
rxFifo0.address = RX_FIFO0_OFS;
rxFifo0.elementSize = 1U;
rxFifo0.watermark = 0;
rxFifo0.opmode = kMCAN_FifoBlocking;
rxFifo0.datafieldSize = kMCAN_8ByteDatafield;
MCAN_SetRxFifo1Config(EXAMPLE_MCAN, &rxFifo0);

/* TX buffer config. */
txBuffer.address = TX_BUFFER_OFS;
txBuffer.dedicatedSize = 1U;
txBuffer.fqSize = 0;
txBuffer.datafieldSize = kMCAN_8ByteDatafield;
MCAN_SetTxBufferConfig(EXAMPLE_MCAN, &txBuffer);

MCAN_EnableInterrupts(EXAMPLE_MCAN, 0, CAN_IE_RF1NE_MASK);
EnableIRQ(CAN1_IRQ0_IRQn);
MCAN_EnterNormalMode(EXAMPLE_MCAN);

0 Kudos

778 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hello fatih ozen, 

Thanks for attaching the code. I download the can1.c file and I notice the following. In the function Can_Init when you enable the interrupt you have the following lines: 

MCAN_EnableInterrupts(EXAMPLE_MCAN, 0, CAN_IE_RF1NE_MASK);
EnableIRQ(CAN1_IRQ0_IRQn);

Notice that the value of CAN_IE_RF1NE_MASK is 0x10 so you have to make the shift with the CAN_IE_RF1NE_SHIFT define. Your call to the function MCAN_Enable_Interrupts should look like this: 

MCAN_EnableInterrupts(EXAMPLE_MCAN, 0, (CAN_IE_RF1NE_MASK >> CAN_IE_RF1NE_SHIFT));
EnableIRQ(CAN1_IRQ0_IRQn);

And your handler should be like this:

void CAN1_IRQ0_IRQHandler(void)
{
    MCAN_ClearStzatusFlag(EXAMPLE_MCAN, (CAN_IE_RF1NE_MASK >> CAN_IE_RF1NE_SHIFT));
    MCAN_ReadRxFifo(EXAMPLE_MCAN, 0, &rxFrame);
    rxComplete = true;
    /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
      exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
    __DSB();
#endif
}

You mentioned that you are using PIO1_17 and PIO1_18, be sure that you are selecting the correct function for these pins. According to the user manual you should select function 5 for both pins. 

Hope it helps!

Victor.

-----------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

-----------------------------------------------------------------------------------------------------------------------

0 Kudos

778 Views
fatihozen
Contributor IV

Hi victorjimenez‌,

Thank you for quick response. I modified changes as you suggested in 2.4.1 SDK's can loopback example and also did same changes for my own software. Program stuck somewhere.   

" ==MCAN loopback functional example -- Start.== "
After this step I couln't see sent and received datas. What hardware do you use ?
I have my custom board and OM13092 Evaluation board includes LPC54608.

addition:

in your image there is written " MCAN_ClearStatusFlag(MCAN_EXAMPLE,  CAN_IR_RF1N_MASK); " at line 72 but you modified it in text as

MCAN_ClearStzatusFlag(EXAMPLE_MCAN, (CAN_IE_RF1NE_MASK >> CAN_IE_RF1NE_SHIFT));

I tried both, nothing changed. 

0 Kudos