Skip to main content
WNguy.1
Associate II
Jan 22, 2020 10:45 PM UTC
Solved

NUCLEO-F413ZH both CAN 2 or CAN 3 not receiving or transmitting (University Student help!)

Hi,

I've made a code that sends the same CAN message but different IDs, I'm using a USB - to - CAN logger to see the communication between these three CANS (1,2,3). I'm running into a problem where the code compiles fine, builds fine, and debugs successfully into the Nucleo board but doesn't transmits/receives any messages through CAN 2 & 3. CAN 1 works fine and receives (works because there's an RX interrupt as well -> LED Blinks) . These are the measures I've taken in trying to figure out what's happening:

-Re-initialized the CANS through the CUBE interface software

-Disconnected each CANL & CANH pin in figuring out one by one which ones were working

-CANS are all the same parameters and matched accordingly to reference, CAN1 works, so I'm just puzzled as to why CAN2,3 are not?? Note: CAN2 is a slave, CAN3 is a master

Given:

-Can bus (120 Ohms terminating bus)

-GND

-Power to each 3x Transciever

-Pins connected accordingly to Tx/Rx of the IC transciever

-CANL/CANHs are connected fine

-Code is attached below

-A JPG is attached below, indicating CAN1's messege is recieved by my logger as well as an interrupt happening through RX of CAN1, although I did enable interrupts for CAN2,3 , they don't work (Physically disconnected the CANL/CANH pins per canbus to pinpoint)

Any help would be greatly appreciated!

This topic has been closed for replies.
Trevor Jones
Trevor JonesBest answer
Senior
Jan 23, 2020 6:39 AM UTC

You should get the Rx running first to set your timing bits correctly to the external dongle you have.

then you can send with TX

Rx

void checkCanRxFifos(void) {
	
 int readCanBytecount;
	canTrafficCounter++;
	
 char canFifo1FullFlag = CAN->RF1R & CAN_RF1R_FMP1;
 if (canFifo1FullFlag) {
 {
 readCanBytecount = (CAN->sFIFOMailBox[1].RDTR & 0x0f);	
 
 canRxMsgBottomWord[canRxMsgIN]	= CAN->sFIFOMailBox[1].RDLR;
 canRxMsgTopWord[canRxMsgIN]	= CAN->sFIFOMailBox[1].RDHR;
 
 canRxMsgID[canRxMsgIN] = CAN->sFIFOMailBox[1].RIR >> 21;
 CAN->RF1R |= CAN_RF1R_RFOM1; 						// release FIFO 
 
 canRxMsgLength[canRxMsgIN] =	readCanBytecount; 
 
 canRxMsgIN++;
 canRxMsgIN &= 0x3F; 	// 64 entries only
 canRxMsgTableEMPTY = false;
 if (canRxMsgIN == canRxMsgOUT) canRxMsgTableFULL = true;
 }
 CAN->IER |= CAN_IER_FMPIE1; 		 				 // (11)		Set FIFO1 message pending IT enable 
 }
 
 char canFifo0FullFlag = CAN->RF0R & CAN_RF0R_FMP0;
 if (canFifo0FullFlag) {
 {
 readCanBytecount 		= (CAN->sFIFOMailBox[0].RDTR & 0x0f);	
 
 canRxMsgBottomWord[canRxMsgIN]	= CAN->sFIFOMailBox[0].RDLR;
 canRxMsgTopWord[canRxMsgIN]	= CAN->sFIFOMailBox[0].RDHR;
 
 uint32_t canRxmsgID = CAN->sFIFOMailBox[0].RIR >> 21;
 CAN->RF0R |= CAN_RF0R_RFOM0; 						// release FIFO 
 
 if(canRxMsgTableFULL) {	
 canRxMsgTableOverflow = true; // now dump new frame...
 }else {
 canRxMsgID[canRxMsgIN] = canRxmsgID;
 canRxMsgLength[canRxMsgIN] = readCanBytecount; 		// to signify FIFO0
 canRxMsgIN++;
 canRxMsgIN &= 0x3F; 	// 64 entries only
 canRxMsgTableEMPTY = false;
 if (canRxMsgIN == canRxMsgOUT)
 canRxMsgTableFULL = true;
 }
//	 int length;
// length = sprintf(string + length,"%08X, %08X :W",canFifoBuf.d32[0],canFifoBuf.d32[1]);
// 			for( int i = 0; i < readCanBytecount; i++){			
// 				canRxBuffer[canRxpointerIN++] = canFifoBuf.d8[i];			
// 				canRxpointerIN &= 0xFF;
// 				if (canRxpointerIN == canRxpointerOUT )		CanRxbufferOverrun = true;
// 				//length += sprintf(string + length,"%02X, ",canFifoBuf.d8[i]);
// 			}
// sprintf(string + length -2,"\n\r");		// remove 2 bytes, the last comma and space
 
 }
 CAN->IER |= CAN_IER_FMPIE0; 		// (11)		Set FIFO1 message pending IT enable 
 }
 //			if (length >0) puts(string);
 
}

TX

void checkCanTxMsgs(void) { // this is modified only to send the very freshest data.
	// this is a non-ordered packet transmitter.
	//int canMsgCounter =0;
	if(!canTxMsgTableEMPTY) 
	{
		
		//if ((canTxMsgOUT != canTxMsgIN) || canTxMsgTableFULL) // non-ordered packet transmitter
			{ 	 
				if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) 	// (1) 
					{
						canTrafficCounter++;
						canTxMsgOUT = (canTxMsgIN - 1) & 0x3F;
						if (showRxCanFrames)
							sendCanTxFrametoConsole();
						// adjusting to the last saved frame
 
						CAN->sTxMailBox[0].TDTR = canTxMsgLength[canTxMsgOUT]; // (2) length
						CAN->sTxMailBox[0].TDLR = canTxMsgBottomWord[canTxMsgOUT]; // (3) 4bytes
						CAN->sTxMailBox[0].TDHR = canTxMsgTopWord[canTxMsgOUT]; // (3) 4bytes
						CAN->sTxMailBox[0].TIR = ((uint32_t)canTxMsgID[canTxMsgOUT] << 21 | CAN_TI0R_TXRQ); // (4)	// send it now if the line is idle
 
						// destroy old data to be sure we only transmit fresh data
						// not needed
						canTxMsgLength[canTxMsgOUT] 	= 0;			
						canTxMsgBottomWord[canTxMsgOUT] = 0; 	
						canTxMsgTopWord[canTxMsgOUT]	= 0; 		
						canTxMsgID[canTxMsgOUT++]		= 0;
					
						canTxMsgOUT &= 0x3F; // 64 buffer elements
						canTxMsgTableFULL = false;
						canTxMsgOverrun = false;				
					}
 
//				if ((canTxMsgOUT != canTxMsgIN) || canTxMsgTableFULL) 
//					if ((CAN->TSR & CAN_TSR_TME1) == CAN_TSR_TME1) 	// (1) 
//						{
//							if (showRxCanFrames)
//								sendCanTxFrametoConsole();				
//							CAN->sTxMailBox[1].TDTR = canTxMsgLength[canTxMsgOUT]; // (2) length
//							CAN->sTxMailBox[1].TDLR = canTxMsgBottomWord[canTxMsgOUT]; // (3) 4bytes
//							CAN->sTxMailBox[1].TDHR = canTxMsgTopWord[canTxMsgOUT]; // (3) 4bytes
//							CAN->sTxMailBox[1].TIR = ((uint32_t) canTxMsgID[canTxMsgOUT] << 21 | CAN_TI1R_TXRQ); 	// (4)	// send it now if the line is idle
//
//				// destroy old data to be sure we only transmit fresh data
//				// not needed
//				 canTxMsgLength[canTxMsgOUT] 	= 0;			
//							canTxMsgBottomWord[canTxMsgOUT] = 0; 	
//							canTxMsgTopWord[canTxMsgOUT]	= 0; 		
//							canTxMsgID[canTxMsgOUT++]		= 0;
//					
//							canTxMsgOUT &= 0x3F; 	// 64 buffer depth
//							canTxMsgOverrun = false;
//							canTxMsgTableFULL = false;
//							//canMsgCounter ++;
//						}
//				if ((canTxMsgOUT != canTxMsgIN) || canTxMsgTableFULL) 
//					if ((CAN->TSR & CAN_TSR_TME2) == CAN_TSR_TME2) // (1) 
//						{
//							if (showRxCanFrames)
//								sendCanTxFrametoConsole();				
//							CAN->sTxMailBox[2].TDTR = canTxMsgLength[canTxMsgOUT]; // (2) length
//							CAN->sTxMailBox[2].TDLR = canTxMsgBottomWord[canTxMsgOUT]; // (3) 4bytes
//							CAN->sTxMailBox[2].TDHR = canTxMsgTopWord[canTxMsgOUT]; // (3) 4bytes
//							CAN->sTxMailBox[2].TIR = ((uint32_t) canTxMsgID[canTxMsgOUT] << 21 | CAN_TI2R_TXRQ);	// (4)	// send it now if the line is idle
//
//				// destroy old data to be sure we only transmit fresh data
//				// not needed
//				 canTxMsgLength[canTxMsgOUT] 	= 0;			
//							canTxMsgBottomWord[canTxMsgOUT] = 0; 	
//							canTxMsgTopWord[canTxMsgOUT]	= 0; 		
//							canTxMsgID[canTxMsgOUT++]		= 0;
//					
//
//							canTxMsgOUT &= 0x3F; 		// 64 buffer elements
//							canTxMsgOverrun = false;
//							canTxMsgTableFULL = false;
//							//canMsgCounter ++;
//						}
				if (canTxMsgOUT == canTxMsgIN)	canTxMsgTableEMPTY = true;
			}
	}
}

3 replies

WNguy.1
WNguy.1Author
Associate II
Jan 22, 2020 11:01 PM UTC

Here is a zip to the project file for config files

WNguy.1
WNguy.1Author
Associate II
Jan 22, 2020 11:20 PM UTC

..

Trevor Jones
Trevor JonesBest answer
Senior
Jan 23, 2020 6:39 AM UTC

You should get the Rx running first to set your timing bits correctly to the external dongle you have.

then you can send with TX

Rx

void checkCanRxFifos(void) {
	
 int readCanBytecount;
	canTrafficCounter++;
	
 char canFifo1FullFlag = CAN->RF1R & CAN_RF1R_FMP1;
 if (canFifo1FullFlag) {
 {
 readCanBytecount = (CAN->sFIFOMailBox[1].RDTR & 0x0f);	
 
 canRxMsgBottomWord[canRxMsgIN]	= CAN->sFIFOMailBox[1].RDLR;
 canRxMsgTopWord[canRxMsgIN]	= CAN->sFIFOMailBox[1].RDHR;
 
 canRxMsgID[canRxMsgIN] = CAN->sFIFOMailBox[1].RIR >> 21;
 CAN->RF1R |= CAN_RF1R_RFOM1; 						// release FIFO 
 
 canRxMsgLength[canRxMsgIN] =	readCanBytecount; 
 
 canRxMsgIN++;
 canRxMsgIN &= 0x3F; 	// 64 entries only
 canRxMsgTableEMPTY = false;
 if (canRxMsgIN == canRxMsgOUT) canRxMsgTableFULL = true;
 }
 CAN->IER |= CAN_IER_FMPIE1; 		 				 // (11)		Set FIFO1 message pending IT enable 
 }
 
 char canFifo0FullFlag = CAN->RF0R & CAN_RF0R_FMP0;
 if (canFifo0FullFlag) {
 {
 readCanBytecount 		= (CAN->sFIFOMailBox[0].RDTR & 0x0f);	
 
 canRxMsgBottomWord[canRxMsgIN]	= CAN->sFIFOMailBox[0].RDLR;
 canRxMsgTopWord[canRxMsgIN]	= CAN->sFIFOMailBox[0].RDHR;
 
 uint32_t canRxmsgID = CAN->sFIFOMailBox[0].RIR >> 21;
 CAN->RF0R |= CAN_RF0R_RFOM0; 						// release FIFO 
 
 if(canRxMsgTableFULL) {	
 canRxMsgTableOverflow = true; // now dump new frame...
 }else {
 canRxMsgID[canRxMsgIN] = canRxmsgID;
 canRxMsgLength[canRxMsgIN] = readCanBytecount; 		// to signify FIFO0
 canRxMsgIN++;
 canRxMsgIN &= 0x3F; 	// 64 entries only
 canRxMsgTableEMPTY = false;
 if (canRxMsgIN == canRxMsgOUT)
 canRxMsgTableFULL = true;
 }
//	 int length;
// length = sprintf(string + length,"%08X, %08X :W",canFifoBuf.d32[0],canFifoBuf.d32[1]);
// 			for( int i = 0; i < readCanBytecount; i++){			
// 				canRxBuffer[canRxpointerIN++] = canFifoBuf.d8[i];			
// 				canRxpointerIN &= 0xFF;
// 				if (canRxpointerIN == canRxpointerOUT )		CanRxbufferOverrun = true;
// 				//length += sprintf(string + length,"%02X, ",canFifoBuf.d8[i]);
// 			}
// sprintf(string + length -2,"\n\r");		// remove 2 bytes, the last comma and space
 
 }
 CAN->IER |= CAN_IER_FMPIE0; 		// (11)		Set FIFO1 message pending IT enable 
 }
 //			if (length >0) puts(string);
 
}

TX

void checkCanTxMsgs(void) { // this is modified only to send the very freshest data.
	// this is a non-ordered packet transmitter.
	//int canMsgCounter =0;
	if(!canTxMsgTableEMPTY) 
	{
		
		//if ((canTxMsgOUT != canTxMsgIN) || canTxMsgTableFULL) // non-ordered packet transmitter
			{ 	 
				if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) 	// (1) 
					{
						canTrafficCounter++;
						canTxMsgOUT = (canTxMsgIN - 1) & 0x3F;
						if (showRxCanFrames)
							sendCanTxFrametoConsole();
						// adjusting to the last saved frame
 
						CAN->sTxMailBox[0].TDTR = canTxMsgLength[canTxMsgOUT]; // (2) length
						CAN->sTxMailBox[0].TDLR = canTxMsgBottomWord[canTxMsgOUT]; // (3) 4bytes
						CAN->sTxMailBox[0].TDHR = canTxMsgTopWord[canTxMsgOUT]; // (3) 4bytes
						CAN->sTxMailBox[0].TIR = ((uint32_t)canTxMsgID[canTxMsgOUT] << 21 | CAN_TI0R_TXRQ); // (4)	// send it now if the line is idle
 
						// destroy old data to be sure we only transmit fresh data
						// not needed
						canTxMsgLength[canTxMsgOUT] 	= 0;			
						canTxMsgBottomWord[canTxMsgOUT] = 0; 	
						canTxMsgTopWord[canTxMsgOUT]	= 0; 		
						canTxMsgID[canTxMsgOUT++]		= 0;
					
						canTxMsgOUT &= 0x3F; // 64 buffer elements
						canTxMsgTableFULL = false;
						canTxMsgOverrun = false;				
					}
 
//				if ((canTxMsgOUT != canTxMsgIN) || canTxMsgTableFULL) 
//					if ((CAN->TSR & CAN_TSR_TME1) == CAN_TSR_TME1) 	// (1) 
//						{
//							if (showRxCanFrames)
//								sendCanTxFrametoConsole();				
//							CAN->sTxMailBox[1].TDTR = canTxMsgLength[canTxMsgOUT]; // (2) length
//							CAN->sTxMailBox[1].TDLR = canTxMsgBottomWord[canTxMsgOUT]; // (3) 4bytes
//							CAN->sTxMailBox[1].TDHR = canTxMsgTopWord[canTxMsgOUT]; // (3) 4bytes
//							CAN->sTxMailBox[1].TIR = ((uint32_t) canTxMsgID[canTxMsgOUT] << 21 | CAN_TI1R_TXRQ); 	// (4)	// send it now if the line is idle
//
//				// destroy old data to be sure we only transmit fresh data
//				// not needed
//				 canTxMsgLength[canTxMsgOUT] 	= 0;			
//							canTxMsgBottomWord[canTxMsgOUT] = 0; 	
//							canTxMsgTopWord[canTxMsgOUT]	= 0; 		
//							canTxMsgID[canTxMsgOUT++]		= 0;
//					
//							canTxMsgOUT &= 0x3F; 	// 64 buffer depth
//							canTxMsgOverrun = false;
//							canTxMsgTableFULL = false;
//							//canMsgCounter ++;
//						}
//				if ((canTxMsgOUT != canTxMsgIN) || canTxMsgTableFULL) 
//					if ((CAN->TSR & CAN_TSR_TME2) == CAN_TSR_TME2) // (1) 
//						{
//							if (showRxCanFrames)
//								sendCanTxFrametoConsole();				
//							CAN->sTxMailBox[2].TDTR = canTxMsgLength[canTxMsgOUT]; // (2) length
//							CAN->sTxMailBox[2].TDLR = canTxMsgBottomWord[canTxMsgOUT]; // (3) 4bytes
//							CAN->sTxMailBox[2].TDHR = canTxMsgTopWord[canTxMsgOUT]; // (3) 4bytes
//							CAN->sTxMailBox[2].TIR = ((uint32_t) canTxMsgID[canTxMsgOUT] << 21 | CAN_TI2R_TXRQ);	// (4)	// send it now if the line is idle
//
//				// destroy old data to be sure we only transmit fresh data
//				// not needed
//				 canTxMsgLength[canTxMsgOUT] 	= 0;			
//							canTxMsgBottomWord[canTxMsgOUT] = 0; 	
//							canTxMsgTopWord[canTxMsgOUT]	= 0; 		
//							canTxMsgID[canTxMsgOUT++]		= 0;
//					
//
//							canTxMsgOUT &= 0x3F; 		// 64 buffer elements
//							canTxMsgOverrun = false;
//							canTxMsgTableFULL = false;
//							//canMsgCounter ++;
//						}
				if (canTxMsgOUT == canTxMsgIN)	canTxMsgTableEMPTY = true;
			}
	}
}