I have searched a lot in the web of how to initialize multiple CAN bus ports in MPC5606B startTRAK dev board. And here is how you do it,
Follow the steps as it is in FSK_TRK_MPC5606B_Training.pdf with one difference,
Initialize additional CAN bus ports using RAPPid init (i.e) Initialize CAN0,CAN1 by checking the boxes (both input & output) if you are in need of 2 CAN ports.Make all additional changes for these CAN ports as well as mentioned in the FSK_TRK_MPC5606B_Training.pdf document.
MPORTANT NOTE: CAN1 is connected to SBC transceiver by default, so I removed those PC10/PC11 jumpers and connected my external transceivers TJA1050 directly to those port pins!
This example is intended to get CAN message from port 1 and pass it to port 0 which automatically sends it to any external device!
Follow all the steps carefully as mentioned in the pdf!!
In step 1=>Select CAN0_TX(PB0) & CAN0_RX(PB1) as well.
In step 2 , 3 , 4 follow the same as usual
In step 5 =>select CAN0 tab and do the same procedure mentioned for CAN1
Then
1.Configure section map
2.Configure code generation
3.Generate code
4.Configure report generation
5.Generate Report
6.verify the report which is generated (Report.htm)
7.Use main.c provided below in the workspace
8.Run codewarrior project
9.Run cwpjmaker utility
10.Create codewarrior project
11. Add the following driver codes to the Sources directory of your codewarrior project. (use the drivers provided in the below workspace)
adc_drv.c
adc_drv.h
CANapi.h
CANcfg.h
CANdrv.c
gpio_drv.c
gpio_drv.h
pot_hld.c
pot_hld.h
sbc_hld.c
sbc_hld.h
UART_drv.c
UART_drv_api.h
UART_drv_cfg.h
12. now build the code
13. Flash the board
All these steps are provided in detail at FSK_TRK_MPC5606B_Training.pdf
NOTE: Changes with respect to main.c , CANdrv.c , CANapi.h must be noted!
In CANdrv.c I have just reused the default CAN funtions by renaming the CAN port number and function name, These functions must be added as global functions with CANapi.h as well
//main.c
/*
*######################################################################
* RAppIDJDP
* Rapid Application Initialization and Documentation Tool
* Freescale Semiconductor Inc.
*
*######################################################################
*
* Project Name : Multiple_can
*
* Project File : Multiple_can.rsp
*
* Revision Number : 1.0
*
* Tool Version : 1.2.1.5
*
* file : main.c
*
* Target Compiler : Codewarrior
*
* Target Part : MPC5606B
*
* Part Errata Fixes : none
*
* Project Last Save Date : 04-Jan-2021 06:16:55
*
* Created on Date : 04-Jan-2021 06:16:55
*
* Brief Description : This file contains main() function call.
*
********************************************************************************
*
* Detail Description : This file contains main() routine which calls system
* initialization routine and interrupt enable routine if defined.
*
********************************************************************************
*
*######################################################################
*/
/******************** Dependent Include files here **********************/
#include "rappid_ref.h"
#include "rappid_utils.h"
#include "sys_init.h"
#include "CANapi.h"
#include "sbc_hld.h"
#include "gpio_drv.h"
#include "UART_drv_api.h"
#include "pot_hld.h"
/********************** Function Prototype here *************************/
void main(void);
void PrintMenu(void);
void ProcessGPIO(void);
void ProcessUART(void);
void ProcessCAN(void);
void ProcessADC(void);
/********************* Initialization Function(s) ************************/
/* CAN messages to transmit */
unsigned char msgOKCAN[8] = {1,1,0,0,0,0,0,0};
unsigned char msgErrorCAN[8] = {1,0xFF,0,0,0,0,0,0};
unsigned char CANcheck[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
/* UART menu string */
unsigned char menuString[] = "Press 1 to turn on and 0 to turn off LED2";
unsigned char newLine[2] = {0x0A, 0x0D};
uint8_t switchState;
uint16_t potValue;
int i;
void main(void)
{
/* ----------------------------------------------------------- */
/* System Initialization Function */
/* ----------------------------------------------------------- */
sys_init_fnc();
SBC_Init_DBG();
/********* Enable External Interrupt *********/
EnableExternalInterrupts();
GPIO_SetState(68, 1);
GPIO_SetState(69, 1);
GPIO_SetState(70, 1);
GPIO_SetState(71, 1);
SetCanRxFilter(1, 0, 0); //CAN_0 receive FILTER
UartBufInit();
PrintMenu();
while(1)
{
ProcessGPIO();
ProcessUART();
ProcessCAN();
ProcessADC();
}
}
/******************************************************************************
* Function: ProcessUART
*
* Description: Process serial messages
*
******************************************************************************/
void ProcessUART(void)
{
unsigned char data;
UartRxFillBuf(); /* Check if serial message received */
if(UartRxBufEmpty() != 1)
{
data = UartRxDataByte(); /* If received data byte is 1, turn on LED2 */
if (data == '1')
{
GPIO_SetState(69, 0);
}
else if (data == '0') /* If received data byte is 0, turn on LED2 */
{
GPIO_SetState(69, 1);
}
PrintMenu();
}
}
/******************************************************************************
* Function: PrintMenu
*
* Description: Sends menu string over UART
*
******************************************************************************/
void PrintMenu(void)
{
UartTxMsg((unsigned char *)newLine, 2);
UartTxMsg((unsigned char *)menuString, 40);
UartTxMsg((unsigned char *)newLine, 2);
}
/******************************************************************************
* Function: ProcessCAN
*
* Description: Process CAN messages
*
******************************************************************************/
void ProcessCAN(void)
{
can_msg_struct msgCanRX;
if (CanRxMbFull(0) == 1) // Check if CAN message received
{
msgCanRX = CanRxMsg(0);
for (i=0;i<=7;i++)
{
CANcheck[i]=msgCanRX.data[i];
//CanTxMsg (2, 1, 8,(uint8_t *)CANcheck, 0);
}
CanTxMsg0 (2, 1, 8,(uint8_t *)CANcheck, 0);
/* if (msgCanRX.data[0] == 0) // If received data byte is 0, turn off LED3 and send positive response
{
GPIO_SetState(70, 1);
CanTxMsg0(2, 1, 8, (uint8_t *)msgOKCAN, 0);
}
else if (msgCanRX.data[0] == 1) // If received data byte is 1, turn on LED3 and send positive response
{
GPIO_SetState(70, 0);
CanTxMsg0(2, 1, 8, (uint8_t *)msgOKCAN, 0);
}
else // If received data byte is not 0 or 1, send a negative response
{
CanTxMsg0(2, 1, 8, (uint8_t *)msgErrorCAN, 0);
}
*/
}
}
/******************************************************************************
* Function: ProcessGPIO
*
* Description: Processes switch input
*
******************************************************************************/
void ProcessGPIO(void)
{
switchState = GPIO_GetState(64); /* Check switch S1 state */
if (switchState) /* If Switch S1 is pressed, turn on LED1, other wise turn off LED1*/
{
GPIO_SetState(68, 0);
}
else
{
GPIO_SetState(68, 1);
}
}
/******************************************************************************
* Function: ProcessADC
*
* Description: Processes ADC input
*
******************************************************************************/
void ProcessADC(void)
{
potValue = Pot_Get_Value();
if(potValue <= 500) /* If Potentiometer input is <= 500 turn on LED4, other wise turn off LED4 */
{
GPIO_SetState(71, 0);
}
else
{
GPIO_SetState(71, 1);
}
}
/*
*######################################################################
* End of File
*######################################################################
*/
This code takes the values from CAN1 and pushes it to CAN0
//CANdrv.c
/*
*######################################################################
* (c) Copyright 2011 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*######################################################################
*
* Project Name : N/A
*
* @Revision Number : 1.0
*
* @File Name : CANdrv.c
*
* Target Compiler : Codewarrior
*
* Target Part : N/A
*
* Part Errata Fixes : none
*
* Created By : John H. Floros
*
* Created on Date : 11-Jan-2011 14:57:10
*
* @Brief Description : Source file for Flex CAN driver
***********************************************************************
*
* Revision History
*
* Date Author Description
* ---------- ------ ------------------------------------
* mm-dd-yyyy X. Z. File Created
*
*######################################################################
*/
/******************************************************************************
* Includes
******************************************************************************/
#include "CANcfg.h"
//#include "jdp.h"
/******************************************************************************
* Constants
******************************************************************************/
/******************************************************************************
* Macros
******************************************************************************/
#define CAN_RX_EMPTY (0x04)
#define CAN_TX_MSG (0x0C)
#define TX_CODE_INACTIVE (0x8)
#define RX_CODE_INACTIVE (0x0)
/******************************************************************************
* Types
******************************************************************************/
/******************************************************************************
* Local Functions
******************************************************************************/
/******************************************************************************
* Global variables
******************************************************************************/
/******************************************************************************
* Static variables
******************************************************************************/
/******************************************************************************
* Global functions
******************************************************************************/
/******************************************************************************
* Function: SetCanRxFilter
*
* Description: This function is called to set up the mailboxes on the specified
* CAN channel and works for standard and extended IDs.
* Caveats:
*
******************************************************************************/
void SetCanRxFilter(uint32_t id, uint8_t mb, uint8_t ext)
{
if (ext)
{
CAN_1.BUF[mb].CS.B.IDE = 1;/* MB for extended ID */
CAN_1.BUF[mb].ID.R = id; /* MB ID */
}
else
{
CAN_1.BUF[mb].CS.B.IDE = 0; /* MB for standard ID */
CAN_1.BUF[mb].ID.B.STD_ID = (uint16_t)id; /* MB ID */
}
CAN_1.BUF[mb].CS.B.CODE = CAN_RX_EMPTY; /* Set rx MB empty */
}
/******************************************************************************
* Function: CanTxMsg
*
* Description: This function is called to transmit a CAN message.
*
* Caveats:
*
******************************************************************************/
void CanTxMsg (uint32_t id, uint8_t mb, uint8_t dlc, uint8_t data[], uint8_t ext)
{
uint8_t i;
if (ext)
{
CAN_1.BUF[mb].CS.B.IDE = 1; /* extended ID */
CAN_1.BUF[mb].ID.R = id; /* Tx ID extended */
}
else
{
CAN_1.BUF[mb].CS.B.IDE = 0; /* standard ID */
CAN_1.BUF[mb].ID.B.STD_ID = (uint16_t)id; /* Tx ID standard */
}
CAN_1.BUF[mb].CS.B.RTR = 0; /* no remote Tx request frame */
CAN_1.BUF[mb].CS.B.LENGTH = dlc; /* # bytes to Tx */
for (i = 0; i < dlc; i++)
{
CAN_1.BUF[mb].DATA.B[i] = data[i]; /* Data to Tx */
}
CAN_1.BUF[mb].CS.B.SRR = 1; /* Tx frame */
CAN_1.BUF[mb].CS.B.CODE = CAN_TX_MSG; /* Send msg */
}
/******************************************************************************
* Function: CanRxMsg
*
* Description: This function is called to receive a CAN message.
*
* Caveats:
*
******************************************************************************/
can_msg_struct CanRxMsg (uint8_t mb)
{
uint8_t i;
uint32_t dummy;
uint32_t flagIFRL = 0;
uint32_t flagIFRH = 0;
can_msg_struct msg;
if (mb < 32)
{
flagIFRL = ((uint32_t)(0x00000001 << mb));
}
else
{
flagIFRH = ((uint32_t)(0x00000001 << (mb - 32)));
}
msg.code = (uint8_t)CAN_1.BUF[mb].CS.B.CODE;
if (CAN_1.BUF[0].CS.B.IDE) /* if extended ID */
{
msg.id = CAN_1.BUF[mb].ID.R;
}
else /* if standard ID */
{
msg.id = (uint16_t)CAN_1.BUF[mb].ID.B.STD_ID;
}
msg.length = (uint8_t)CAN_1.BUF[mb].CS.B.LENGTH;
for (i = 0; i < msg.length; i++)
{
msg.data[i] = CAN_1.BUF[mb].DATA.B[i];
}
dummy = CAN_1.TIMER.R; /* Read TIMER to unlock MB */
CAN_1.IFRL.R = flagIFRL; /* Clear MB flag */
CAN_1.IFRH.R = flagIFRH; /* Clear MB flag */
return (msg);
}
/******************************************************************************
* Function: CanRxMbFull
*
* Description: This function is called to determine if CAN Mail box is full.
*
* Caveats:
*
******************************************************************************/
uint8_t CanRxMbFull (uint8_t mb)
{
uint8_t temp = 0;
uint32_t flagIFRL = 0;
uint32_t flagIFRH = 0;
if (mb < 32)
{
flagIFRL = ((uint32_t)(0x00000001 << mb));
}
else
{
flagIFRH = ((uint32_t)(0x00000001 << (mb - 32)));
}
if (mb < 32)
{
if (CAN_1.IFRL.R & flagIFRL)
{
temp = 1;
}
}
else
{
if (CAN_1.IFRH.R & flagIFRH)
{
temp = 1;
}
}
return (temp);
}
/******************************************************************************
* Function: CanTxMbEmpty
*
* Description: This function is called to determine if CAN Mail box is empty.
*
* Caveats:
*
******************************************************************************/
uint8_t CanTxMbEmpty (uint8_t mb)
{
uint8_t temp = 0;
if (CAN_1.BUF[mb].CS.B.CODE == TX_CODE_INACTIVE ||
CAN_1.BUF[mb].CS.B.CODE == RX_CODE_INACTIVE)
{
temp = 1;
}
return (temp);
}
/**************************************************************************************************************************/
/**************************************CAN0*****************************************/
/******************************************************************************
* Function: SetCanRxFilter
*
* Description: This function is called to set up the mailboxes on the specified
* CAN channel and works for standard and extended IDs.
* Caveats:
*
******************************************************************************/
void SetCanRxFilter0(uint32_t id, uint8_t mb, uint8_t ext)
{
if (ext)
{
CAN_0.BUF[mb].CS.B.IDE = 1;/* MB for extended ID */
CAN_0.BUF[mb].ID.R = id; /* MB ID */
}
else
{
CAN_0.BUF[mb].CS.B.IDE = 0; /* MB for standard ID */
CAN_0.BUF[mb].ID.B.STD_ID = (uint16_t)id; /* MB ID */
}
CAN_0.BUF[mb].CS.B.CODE = CAN_RX_EMPTY; /* Set rx MB empty */
}
/******************************************************************************
* Function: CanTxMsg
*
* Description: This function is called to transmit a CAN message.
*
* Caveats:
*
******************************************************************************/
void CanTxMsg0 (uint32_t id, uint8_t mb, uint8_t dlc, uint8_t data[], uint8_t ext)
{
uint8_t i;
if (ext)
{
CAN_0.BUF[mb].CS.B.IDE = 1; /* extended ID */
CAN_0.BUF[mb].ID.R = id; /* Tx ID extended */
}
else
{
CAN_0.BUF[mb].CS.B.IDE = 0; /* standard ID */
CAN_0.BUF[mb].ID.B.STD_ID = (uint16_t)id; /* Tx ID standard */
}
CAN_0.BUF[mb].CS.B.RTR = 0; /* no remote Tx request frame */
CAN_0.BUF[mb].CS.B.LENGTH = dlc; /* # bytes to Tx */
for (i = 0; i < dlc; i++)
{
CAN_0.BUF[mb].DATA.B[i] = data[i]; /* Data to Tx */
}
CAN_0.BUF[mb].CS.B.SRR = 1; /* Tx frame */
CAN_0.BUF[mb].CS.B.CODE = CAN_TX_MSG; /* Send msg */
}
/******************************************************************************
* Function: CanRxMsg
*
* Description: This function is called to receive a CAN message.
*
* Caveats:
*
******************************************************************************/
can_msg_struct CanRxMsg0 (uint8_t mb)
{
uint8_t i;
uint32_t dummy;
uint32_t flagIFRL = 0;
uint32_t flagIFRH = 0;
can_msg_struct msg;
if (mb < 32)
{
flagIFRL = ((uint32_t)(0x00000001 << mb));
}
else
{
flagIFRH = ((uint32_t)(0x00000001 << (mb - 32)));
}
msg.code = (uint8_t)CAN_0.BUF[mb].CS.B.CODE;
if (CAN_0.BUF[0].CS.B.IDE) /* if extended ID */
{
msg.id = CAN_0.BUF[mb].ID.R;
}
else /* if standard ID */
{
msg.id = (uint16_t)CAN_0.BUF[mb].ID.B.STD_ID;
}
msg.length = (uint8_t)CAN_0.BUF[mb].CS.B.LENGTH;
for (i = 0; i < msg.length; i++)
{
msg.data[i] = CAN_0.BUF[mb].DATA.B[i];
}
dummy = CAN_0.TIMER.R; /* Read TIMER to unlock MB */
CAN_0.IFRL.R = flagIFRL; /* Clear MB flag */
CAN_0.IFRH.R = flagIFRH; /* Clear MB flag */
return (msg);
}
/******************************************************************************
* Function: CanRxMbFull
*
* Description: This function is called to determine if CAN Mail box is full.
*
* Caveats:
*
******************************************************************************/
uint8_t CanRxMbFull0 (uint8_t mb)
{
uint8_t temp = 0;
uint32_t flagIFRL = 0;
uint32_t flagIFRH = 0;
if (mb < 32)
{
flagIFRL = ((uint32_t)(0x00000001 << mb));
}
else
{
flagIFRH = ((uint32_t)(0x00000001 << (mb - 32)));
}
if (mb < 32)
{
if (CAN_0.IFRL.R & flagIFRL)
{
temp = 1;
}
}
else
{
if (CAN_0.IFRH.R & flagIFRH)
{
temp = 1;
}
}
return (temp);
}
/******************************************************************************
* Function: CanTxMbEmpty
*
* Description: This function is called to determine if CAN Mail box is empty.
*
* Caveats:
*
******************************************************************************/
uint8_t CanTxMbEmpty0 (uint8_t mb)
{
uint8_t temp = 0;
if (CAN_0.BUF[mb].CS.B.CODE == TX_CODE_INACTIVE ||
CAN_0.BUF[mb].CS.B.CODE == RX_CODE_INACTIVE)
{
temp = 1;
}
return (temp);
}
In the following file , I created a new function with a different name for CAN_0
//CANapi.h
/*
*######################################################################
* (c) Copyright 2011 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*######################################################################
*
* Project Name : N/A
*
* @Revision Number : 1.0
*
* @File Name : CANapi.c
*
* Target Compiler : Codewarrior
*
* Target Part : N/A
*
* Part Errata Fixes : none
*
* Created By : John H. Floros
*
* Created on Date : 11-Jan-2011 14:57:10
*
* @Brief Description : Application Interface file for Flex CAN driver
***********************************************************************
*
* Revision History
*
* Date Author Description
* ---------- ------ ------------------------------------
* mm-dd-yyyy X. Z. File Created
*
*######################################################################
*/
/******************************************************************************
* Includes
******************************************************************************/
/******************************************************************************
* Constants
******************************************************************************/
/******************************************************************************
* Macros
******************************************************************************/
/******************************************************************************
* Types
******************************************************************************/
typedef struct
{
uint32_t id; /* CAN message ID */
uint8_t data[8]; /* CAN data byte */
uint8_t length; /* bytes, length of data */
uint8_t code; /* Message Code */
uint8_t ext; /* Extended id 1 = yes; 0 = no */
} can_msg_struct;
/******************************************************************************
* Local Functions
******************************************************************************/
/******************************************************************************
* Global variables
******************************************************************************/
/******************************************************************************
* Static variables
******************************************************************************/
/******************************************************************************
* Global functions
******************************************************************************/
void SetCanRxFilter(uint32_t, uint8_t, uint8_t);
void CanTxMsg (uint32_t, uint8_t, uint8_t, uint8_t[], uint8_t);
can_msg_struct CanRxMsg (uint8_t);
uint8_t CanRxMbFull (uint8_t);
uint8_t CanTxMbEmpty (uint8_t);
void SetCanRxFilter0(uint32_t, uint8_t, uint8_t);
void CanTxMsg0 (uint32_t, uint8_t, uint8_t, uint8_t[], uint8_t);
can_msg_struct CanRxMsg0 (uint8_t);
uint8_t CanRxMbFull0 (uint8_t);
uint8_t CanTxMbEmpty0 (uint8_t);
Included the newly created functions for CAN_0 in CANapi.h as global functions.
Solved! Go to Solution.
Hi,
yes, this is done by matching process. See chapters 25.5.5 and 25.5.6 of the RM; https://www.nxp.com/webapp/Download?colCode=MPC5607BRM
BR, Petr
Hi,
what is planned operation?
From main function I see CAN1 MB0 is set up to wait for message with std ID=1, using SetCanRxFilter(1, 0, 0);
ProcessCAN() is checking CAN1 MB0 flag, if set, send message using CAN0 MB1.
On TRK-MPC5606B board CAN1 (PC10/PC11 pins) is connected to the SBC transceiver. How do you have CAN0 connected? Do you use some external CAN transceiver connected to PB0/PB1 pins?
Did you also init FlexCAN module? I do not see you call flexcan_init_fnc or individual functions in your code, assume in sys_init_fnc.
BR, Petr
Can you please also tell me what is meant by mail box?
mail box is message buffer, MB.
In order to transmit/receive a CAN frame, the CPU must prepare a Message Buffer for transmission/reception. See the RM's chapters 25.5.x for more info.
BR, Petr
Hi had a look at MPC5606B datasheet. I have a doubt whether is it possible to use the same CAN port , receive can messages from different IDs and store it in different mail boxes relating to the ID from which the message came?
Thank you
Hi,
yes, this is done by matching process. See chapters 25.5.5 and 25.5.6 of the RM; https://www.nxp.com/webapp/Download?colCode=MPC5607BRM
BR, Petr
Thank you so much
If you can provide me with link it would be very helpful!
thank you in advance!
I did not init flexcan , is there any function used for it seperately? for me both the CAN bus works!
IMPORTANT NOTE: Yes CAN1 is connected to SBC transceiver by default, so I removed those PC10/PC11 jumpers and connected my external transceivers TJA1050 directly to those port pins!
This example is intended to get CAN message from port 1 and pass it to port 0 which automatically sends it to any external device!
Hi,
I overlooked flexcan_init_fnc calling in sys_init_fnc, so yes FlexCAN modules should be initialized.
If you wrote "both CAN bus works" where is the issue?
The connection is not clear to me. You are not using SBC's transceiver, so you have 2 external transceivers? One connected to PC10/PC11 and second to PB0/PB1?
BR, Petr
Yes , I used an external transceiver for PB0/PB1 and PC10/PC11. This is not any issue , it is just a simple guide to use multiple CAN bus for MPC5606B as there is no documentation for this purpose. And also can you please tell me how to send signed integer and float thru CAN bus?
I see, this is your guide how to achieve this...I misunderstood it.
Up to 8 bytes can be sent in CAN message, it is up to a user how this payload it created.
BR, Petr
Thanks, Because i wasnt able to send float and signed int. May be creating an offset would be helpful i guess.