I have modified the example flex can 2.0 code
My requirement is to get the code working with CAN1 routed through PTC7/6 on Sk32144LQPF100
THe code is as follows. I modified it a little bit so that it would be generic to work with all the CAN bus.
/* FlexCAN.c (c) 2016 NXP
* Descriptions: S32K144 CAN 2.0 A/B example..
* 2016 Jul 16 S. Mihalik: Initial version
* 2016 Sep 12 SM: Updated with SBC init, Node A - B communication
* 2016 Oct 31 SM: Updated for new header symbols for PCCn
*/
#include "S32K144.h" /* include peripheral declarations S32K144 */
#include "can.h"
#include <stddef.h>
uint32_t RxCODE; /* Received message buffer code */
uint32_t RxID; /* Received message ID */
uint32_t RxLENGTH; /* Recieved message number of data bytes */
uint32_t RxDATA[2]; /* Received message data (2 words) */
uint32_t RxTIMESTAMP; /* Received message time */
static inline CAN_Type* get_can_bus_base_ptr(can_bus_type type) {
CAN_Type *bus_ptr = NULL;
switch (type) {
case BATTERY_CAN_BUS:
bus_ptr = (CAN_Type*)CAN_BUS_BATTERY_BASE_PTR;
break;
case SERVICE_CAN_BUS:
bus_ptr = (CAN_Type*)CAN_BUS_SERVICE_BASE_PTR;
break;
case VEHICLE_CAN_BUS:
bus_ptr = (CAN_Type*)CAN_BUS_VEHICLE_BASE_PTR;
break;
default:
break;
}
return bus_ptr;
}
void FLEXCAN_init(can_bus_type type) {
#define MSG_BUF_SIZE 4 /* Msg Buffer Size. (CAN 2.0AB: 2 hdr + 2 data= 4 words) */
uint32_t i=0;
CAN_Type *base = get_can_bus_base_ptr(type);
PCC->PCCn[PCC_PORTC_INDEX] |= PCC_PCCn_CGC_MASK; /* Enable clock for PORTC */
//PCC->PCCn[PCC_PORTE_INDEX] |= PCC_PCCn_CGC_MASK; /* Enable clock for PORTC */
PORTC->PCR[6] |= PORT_PCR_MUX(3); /* Port C6: MUX = ALT3, CAN1_RX */
PORTC->PCR[7] |= PORT_PCR_MUX(3); /* Port C7: MUX = ALT3, CAN1_TX */
//PORTE->PCR[4] |= PORT_PCR_MUX(5); /* Port C6: MUX = ALT3, CAN1_RX */
//PORTE->PCR[5] |= PORT_PCR_MUX(5); /* Port C7: MUX = ALT3, CAN1_TX */
PCC->PCCn[PCC_FlexCAN1_INDEX] |= PCC_PCCn_CGC_MASK; /* CGC=1: enable clock to FlexCAN0 */
//PCC->PCCn[PCC_FlexCAN0_INDEX] |= PCC_PCCn_CGC_MASK; /* CGC=1: enable clock to FlexCAN0 */
base->MCR |= CAN_MCR_MDIS_MASK; /* MDIS=1: Disable module before selecting clock */
base->CTRL1 &= ~CAN_CTRL1_CLKSRC_MASK; /* CLKSRC=0: Clock Source = oscillator (8 MHz) */
base->MCR &= ~CAN_MCR_MDIS_MASK; /* MDIS=0; Enable module config. (Sets FRZ, HALT)*/
while (!((base->MCR & CAN_MCR_FRZACK_MASK) >> CAN_MCR_FRZACK_SHIFT)) {}
/* Good practice: wait for FRZACK=1 on freeze mode entry/exit */
base->CTRL1 = 0x00DB0006; /* Configure for 500 KHz bit time */
/* Time quanta freq = 16 time quanta x 500 KHz bit time= 8MHz */
/* PRESDIV+1 = Fclksrc/Ftq = 8 MHz/8 MHz = 1 */
/* so PRESDIV = 0 */
/* PSEG2 = Phase_Seg2 - 1 = 4 - 1 = 3 */
/* PSEG1 = PSEG2 = 3 */
/* PROPSEG= Prop_Seg - 1 = 7 - 1 = 6 */
/* RJW: since Phase_Seg2 >=4, RJW+1=4 so RJW=3. */
/* SMP = 1: use 3 bits per CAN sample */
/* CLKSRC=0 (unchanged): Fcanclk= Fosc= 8 MHz */
for(i=0; i<64; i++ ) { /* base: clear 32 msg bufs x 4 words/msg buf = 128 words*/
base->RAMn[i] = 0; /* Clear msg buf word */
}
for(i=0; i<16; i++ ) { /* In FRZ mode, init CAN0 16 msg buf filters */
base->RXIMR[i] = 0xFFFFFFFF; /* Check all ID bits for incoming messages */
}
base->RXMGMASK = 0x1FFFFFFF; /* Global acceptance mask: check all ID bits */
base->RAMn[ 4*MSG_BUF_SIZE + 0] = 0x04000000; /* Msg Buf 4, word 0: Enable for reception */
/* EDL,BRS,ESI=0: CANFD not used */
/* CODE=4: MB set to RX inactive */
/* IDE=0: Standard ID */
/* SRR, RTR, TIME STAMP = 0: not applicable */
#ifdef NODE_A /* Node A receives msg with std ID 0x511 */
base->RAMn[ 4*MSG_BUF_SIZE + 1] = 0x14440000; /* Msg Buf 4, word 1: Standard ID = 0x111 */
#else /* Node B to receive msg with std ID 0x555 */
base->RAMn[ 4*MSG_BUF_SIZE + 1] = 0x15540000; /* Msg Buf 4, word 1: Standard ID = 0x555 */
#endif
/* PRIO = 0: CANFD not used */
base->MCR = 0x0000001F; /* Negate FlexCAN 1 halt state for 32 MBs */
while ((base->MCR && CAN_MCR_FRZACK_MASK) >> CAN_MCR_FRZACK_SHIFT) {}
/* Good practice: wait for FRZACK to clear (not in freeze mode) */
while ((base->MCR && CAN_MCR_NOTRDY_MASK) >> CAN_MCR_NOTRDY_SHIFT) {}
/* Good practice: wait for NOTRDY to clear (module ready) */
}
void FLEXCAN_transmit_msg(can_bus_type type) { /* Assumption: Message buffer CODE is INACTIVE */
CAN_Type *base = get_can_bus_base_ptr(type);
base->IFLAG1 = 0x00000001; /* Clear CAN 0 MB 0 flag without clearing others*/
base->RAMn[ 0*MSG_BUF_SIZE + 2] = 0xA5112233; /* MB0 word 2: data word 0 */
base->RAMn[ 0*MSG_BUF_SIZE + 3] = 0x44556677; /* MB0 word 3: data word 1 */
#ifdef NODE_A
base->RAMn[ 0*MSG_BUF_SIZE + 1] = 0x15540000; /* MB0 word 1: Tx msg with STD ID 0x555 */
#else
base->RAMn[ 0*MSG_BUF_SIZE + 1] = 0x14440000; /* MB0 word 1: Tx msg with STD ID 0x511 */
#endif
base->RAMn[ 0*MSG_BUF_SIZE + 0] = 0x0C400000 | 8 <<CAN_WMBn_CS_DLC_SHIFT; /* MB0 word 0: */
/* EDL,BRS,ESI=0: CANFD not used */
/* CODE=0xC: Activate msg buf to transmit */
/* IDE=0: Standard ID */
/* SRR=1 Tx frame (not req'd for std ID) */
/* RTR = 0: data, not remote tx request frame*/
/* DLC = 8 bytes */
}
void FLEXCAN_receive_msg(can_bus_type type) { /* Receive msg from ID 0x556 using msg buffer 4 */
uint8_t j;
uint32_t dummy;
CAN_Type *base = get_can_bus_base_ptr(BATTERY_CAN_BUS);
RxCODE = (base->RAMn[ 4*MSG_BUF_SIZE + 0] & 0x07000000) >> 24; /* Read CODE field */
RxID = (base->RAMn[ 4*MSG_BUF_SIZE + 1] & CAN_WMBn_ID_ID_MASK) >> CAN_WMBn_ID_ID_SHIFT ;
RxLENGTH = (base->RAMn[ 4*MSG_BUF_SIZE + 0] & CAN_WMBn_CS_DLC_MASK) >> CAN_WMBn_CS_DLC_SHIFT;
for (j=0; j<2; j++) { /* Read two words of data (8 bytes) */
RxDATA[j] = base->RAMn[ 4*MSG_BUF_SIZE + 2 + j];
}
RxTIMESTAMP = (base->RAMn[ 0*MSG_BUF_SIZE + 0] & 0x000FFFF);
dummy = base->TIMER; /* Read TIMER to unlock message buffers */
base->IFLAG1 = 0x00000010; /* Clear CAN 0 MB 4 flag without clearing others*/
}
essentially i am replacing CAN0 pointer ith an argument to retrive base pointr based upon my mapping. When argument for CAN0 is passed it works fine. Howeer with CAN1 i get errors on can bus when connected tot he PC via PCAN.
How is can 1 initialization different from 0 . I believe i made the chages to the code. Could you please advise
@saurabhkarnik did it work on A12/A13? same issue here using and external transceiver but cant get CAN0, and CAN1 working together!
您好,这个can能接收吗,您调通了吗,我也是遇到can问题,可以发送,但是接收不到报文,能加个QQ不,357929237,谢谢!
Are you using the S32K144 evaluation board? Are you using a 12V power supply? With that you need to use 12V and change the jumper on J107 to 1-2 to get power from 12V. Then CAN will work.
Hi ,
yes i did do the 12V power supply with the jumper however i am getting error packets conituously on the CAN 1 bus. Whenever i switch to can 0 it works perfectly.
Hi,
if you are using the S32K144 EVB, how do you connect C6/C7 pins to the transceiver?
Do you use on-board transceiver or the external one? CAN0 TX/RX (E4/E5) is connected to on-board SBC transceiver.
Note the C6/C7 pins are directly connected to the on-board MK20 to serve serial port. So CAN lines can be affected.
So if external transceiver is used you can try CAN1 TX/RX signals on A12/A13 pins.
BR, Petr
I was usingg C6/C7 and with an external trans receiver. Will try the pins
A12/A13. If pins A12/13 work highly suggest to mention that in the errata
sheet if not already mentioned
Regards
Saurabh