(ENG) Freemaster CAN connection (NTBMS Board)

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

(ENG) Freemaster CAN connection (NTBMS Board)

Jump to solution
3,758 Views
seyoung
Contributor II

Hello
NTBMS trial version is being tested.
Connection with FreeMaster is successful through UART communication, but CAN communication does not connect.
An error occurs as shown in the attached picture.
(The CAN converter uses Peak CAN-USB.)
(Should I use it as CAN-FD?)

help me please..

The source code provided by the link below was used, and only the CAN part was modified.
https://www.nxp.com/webapp/sps/download/preDownload.jsp?render=true

 

-Changed source code-

main.c (line 113)
INT_SYS_InstallHandler(CAN0_ORed_0_15_MB_IRQn, FMSTR_Isr, NULL );
//INT_SYS_InstallHandler(LPUART2_RxTx_IRQn, FMSTR_Isr, NULL );

peripherals_init.c (line 88)
//INT_SYS_EnableIRQ(LPTMR0_IRQn);
INT_SYS_EnableIRQ(CAN0_ORed_0_15_MB_IRQn);

freemaster_cfg.h (line 25)
#define FMSTR_LONG_INTR 0 /* Complete message processing in interrupt */
#define FMSTR_SHORT_INTR 1 /* SCI FIFO-queuing done in interrupt */
#define FMSTR_POLL_DRIVEN 0 /* No interrupt needed, polling only */
#define FMSTR_SCI_BASE 0x4006C000UL /* LPUART1 base on S32K14x */
#define FMSTR_CAN_BASE 0x40024000UL /* FlexCAN0 base on S32K14x */

#define FMSTR_DISABLE 0 

#define FMSTR_USE_LPUART 0 
#define FMSTR_USE_FLEXCAN 1 
//#define FMSTR_USE_LPUART 1 
//#define FMSTR_USE_FLEXCAN 0 

0 Kudos
1 Solution
3,672 Views
iulian_stan
NXP Employee
NXP Employee

Hi @seyoung,

After downloading the BMS application I noticed that CAN0 is already in use - it cannot be used by both FreeMASTER and the main application - I think that's what is causing your issue.

I am not a BMS engineer (not familiar with this application) so cannot give you the best way to work around this. Just as a suggestion - you may use another CAN instance.

I attached a FreeMASTER demo app working over CAN - you'll see that the changes are similar to what you described so I guess the issue is not related to your configuration but the original application.

Hope this helps.

View solution in original post

8 Replies
3,732 Views
iulian_stan
NXP Employee
NXP Employee

Hi @seyoung,

Did you configure the CAN peripheral as well ? Please note that the changes from your code snippets only instruct FreeMASTER which communication interface to use, the configuration should be done by the developer.

This post could provide some more info on this topic.

Iulian

3,720 Views
seyoung
Contributor II

My CAN setup is written as below.
Call FLEXCAN_Enable(), FLEXCAN_EnterFreezeMode(), FLEXCAN_Init() in the CAN_Init() function.

I am not good at English. Thank you for your understanding.

 

status_t CAN_Init(can_instance_t instance, const can_user_config_t *config)
{
status_t status = STATUS_ERROR;
uint8_t index = 0;

/* Define CAN PAL over FLEXCAN */
#if (defined (CAN_OVER_FLEXCAN))
if ((uint8_t)instance <= FLEXCAN_HIGH_INDEX)
{
flexcan_user_config_t flexcanConfig;

/* Clear Rx FIFO state */
s_flexcanRxFifoState[instance].rxFifoEn = false;

/* Configure features implemented by PAL */
flexcanConfig.max_num_mb = config->maxBuffNum;
flexcanConfig.flexcanMode = (flexcan_operation_modes_t) config->mode;
flexcanConfig.fd_enable = config->enableFD;
flexcanConfig.payload = (flexcan_fd_payload_size_t) config->payloadSize;

flexcanConfig.bitrate.phaseSeg1 = config->nominalBitrate.phaseSeg1;
flexcanConfig.bitrate.phaseSeg2 = config->nominalBitrate.phaseSeg2;
flexcanConfig.bitrate.preDivider = config->nominalBitrate.preDivider;
flexcanConfig.bitrate.propSeg = config->nominalBitrate.propSeg;
flexcanConfig.bitrate.rJumpwidth = config->nominalBitrate.rJumpwidth;

flexcanConfig.bitrate_cbt.phaseSeg1 = config->dataBitrate.phaseSeg1;
flexcanConfig.bitrate_cbt.phaseSeg2 = config->dataBitrate.phaseSeg2;
flexcanConfig.bitrate_cbt.preDivider = config->dataBitrate.preDivider;
flexcanConfig.bitrate_cbt.propSeg = config->dataBitrate.propSeg;
flexcanConfig.bitrate_cbt.rJumpwidth = config->dataBitrate.rJumpwidth;

#if FEATURE_CAN_HAS_PE_CLKSRC_SELECT
flexcan_clk_source_t flexcanPEClkNames[FEATURE_CAN_PE_CLK_NUM] = FLEXCAN_PE_CLOCK_NAMES;
flexcanConfig.pe_clock = flexcanPEClkNames[0];
#endif

/* If extension is used, configure Rx FIFO */
if (config->extension != NULL)
{
flexcanConfig.is_rx_fifo_needed = true;
flexcanConfig.num_id_filters = ((extension_flexcan_rx_fifo_t *)
(config->extension))->numIdFilters;
flexcanConfig.rxFifoDMAChannel = 0U;
flexcanConfig.transfer_type = FLEXCAN_RXFIFO_USING_INTERRUPTS;

/* Compute maximum number of virtual buffers */
flexcanConfig.max_num_mb += CAN_GetVirtualBuffIdx(flexcanConfig.num_id_filters);

/* Update Rx FIFO state */
s_flexcanRxFifoState[instance].rxFifoEn = true;
s_flexcanRxFifoState[instance].numIdFilters = flexcanConfig.num_id_filters;
}
else
{
flexcanConfig.is_rx_fifo_needed = false;
flexcanConfig.num_id_filters = FLEXCAN_RX_FIFO_ID_FILTERS_8;
flexcanConfig.rxFifoDMAChannel = 0U;
flexcanConfig.transfer_type = FLEXCAN_RXFIFO_USING_INTERRUPTS;
}


/* Allocate one of the FLEXCAN state structure for this instance */
index = CAN_AllocateState(s_flexcanStateIsAllocated,
s_flexcanStateInstanceMapping,
instance,
NO_OF_FLEXCAN_INSTS_FOR_CAN);
/* Initialize FLEXCAN instance */
status = FLEXCAN_DRV_Init((uint8_t)instance, &s_flexcanState[index], &flexcanConfig);

/* Configure Rx FIFO if needed */
if ((status == STATUS_SUCCESS) && (s_flexcanRxFifoState[instance].rxFifoEn == true))
{
FLEXCAN_DRV_ConfigRxFifo(
(uint8_t) instance,
((extension_flexcan_rx_fifo_t *) (config->extension))->idFormat,
((extension_flexcan_rx_fifo_t *) (config->extension))->idFilterTable);
}
}
#endif

return status;
}

 

void FLEXCAN_Enable(CAN_Type * base)
{
/* Check for low power mode */
if(((base->MCR & CAN_MCR_LPMACK_MASK) >> CAN_MCR_LPMACK_SHIFT) == 1U)
{
/* Enable clock */
base->MCR = (base->MCR & ~CAN_MCR_MDIS_MASK) | CAN_MCR_MDIS(0U);
base->MCR = (base->MCR & ~CAN_MCR_FRZ_MASK) | CAN_MCR_FRZ(0U);
base->MCR = (base->MCR & ~CAN_MCR_HALT_MASK) | CAN_MCR_HALT(0U);
/* Wait until enabled */
while (((base->MCR & CAN_MCR_LPMACK_MASK) >> CAN_MCR_LPMACK_SHIFT) != 0U) {}
}
}

 

void FLEXCAN_EnterFreezeMode(CAN_Type * base)
{
base->MCR = (base->MCR & ~CAN_MCR_FRZ_MASK) | CAN_MCR_FRZ(1U);
base->MCR = (base->MCR & ~CAN_MCR_HALT_MASK) | CAN_MCR_HALT(1U);

/* Wait for entering the freeze mode */
while (((base->MCR & CAN_MCR_FRZACK_MASK) >> CAN_MCR_FRZACK_SHIFT) == 0U) {}
}

 

void FLEXCAN_Init(CAN_Type * base)
{
/* Reset the FLEXCAN */
base->MCR = (base->MCR & ~CAN_MCR_SOFTRST_MASK) | CAN_MCR_SOFTRST(1U);

/* Wait for reset cycle to complete */
while (((base->MCR & CAN_MCR_SOFTRST_MASK) >> CAN_MCR_SOFTRST_SHIFT) != 0U) {}

/* Clear FlexCAN memory */
FLEXCAN_ClearRAM(base);

/* Rx global mask*/
(base->RXMGMASK) = (((uint32_t)(((uint32_t)(CAN_RXMGMASK_MG_MASK)) << CAN_ID_EXT_SHIFT)) & (CAN_ID_STD_MASK | CAN_ID_EXT_MASK));

/* Rx reg 14 mask*/
(base->RX14MASK) = (((uint32_t)(((uint32_t)(CAN_RX14MASK_RX14M_MASK)) << CAN_ID_EXT_SHIFT)) & (CAN_ID_STD_MASK | CAN_ID_EXT_MASK));

/* Rx reg 15 mask*/
(base->RX15MASK) = (((uint32_t)(((uint32_t)(CAN_RX15MASK_RX15M_MASK)) << CAN_ID_EXT_SHIFT)) & (CAN_ID_STD_MASK | CAN_ID_EXT_MASK));

/* Disable all MB interrupts */
(base->IMASK1) = 0x0;
/* Clear all MB interrupt flags */
(base->IFLAG1) = CAN_IMASK1_BUF31TO0M_MASK;
#if FEATURE_CAN_MAX_MB_NUM > 32U
(base->IMASK2) = 0x0;
(base->IFLAG2) = CAN_IMASK2_BUF63TO32M_MASK;
#endif
#if FEATURE_CAN_MAX_MB_NUM > 64U
(base->IMASK3) = 0x0;
(base->IFLAG3) = CAN_IMASK3_BUF95TO64M_MASK;
#endif
}

0 Kudos
3,702 Views
iulian_stan
NXP Employee
NXP Employee

I guess these are SDK functions - you did not change them and just call CAN_Init in your custom code. Is that right ? (Just a tip - you don't need to share this code, a print screen of your configuration from ProcessorExpert and SDK version should provide all the info so I can reproduce it on my side).

Could you check MCR[AEN] flag after CAN initialization is done ?

Capture.PNG

If it's set to 1 you need to disable it as I mentioned in the other post.

If not - could you tell me what version of S32DS and SDK versions are you using so I can check it on my side.

3,697 Views
seyoung
Contributor II

I guess these are SDK functions - you did not change them and just call CAN_Init in your custom code. Is that right ?

--> I can't confirm if this has changed. I have downloaded the source provided by NXP and am using it.
(Downloaded from the link below.)

https://www.nxp.com/webapp/sps/download/preDownload.jsp?render=true


     

Could you check MCR[AEN] flag after CAN initialization is done ?

 --> Yes, AEN resolves to zero.

figure1.JPG

 

I will check my S32, SDK version.

S32 Design Studio for ARM Version: 2018.R1

SDK Version : S32SDK_S32K14x_EAR_0.8.6 (I'm not sure if this is the version info.)

 

 

0 Kudos
3,673 Views
iulian_stan
NXP Employee
NXP Employee

Hi @seyoung,

After downloading the BMS application I noticed that CAN0 is already in use - it cannot be used by both FreeMASTER and the main application - I think that's what is causing your issue.

I am not a BMS engineer (not familiar with this application) so cannot give you the best way to work around this. Just as a suggestion - you may use another CAN instance.

I attached a FreeMASTER demo app working over CAN - you'll see that the changes are similar to what you described so I guess the issue is not related to your configuration but the original application.

Hope this helps.

3,639 Views
seyoung
Contributor II

Dear iulian_stan
We thank you for your help, and we will try the attached application.
Thanks again for your kind help.

0 Kudos
3,729 Views
seyoung
Contributor II

Yes. I have set the CAN settings as shown in the figure below.

seyoung_3-1635148332625.png

 

Interrupt method: It does not go to the ISR function.

seyoung_2-1635148219030.png

 

Polling method: FMSTR_ProcessCanRx(), Tx() function is not executed.

seyoung_4-1635148403905.png

 

 

0 Kudos
3,714 Views
seyoung
Contributor II

The pin mux settings are as follows.

figure1.JPG

0 Kudos