Skip to main content
WNguy.1
Associate II
January 22, 2020
Solved

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

  • January 22, 2020
  • 2 replies
  • 2096 views

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.
Best answer by Trevor Jones

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;
			}
	}
}

2 replies

WNguy.1
WNguy.1Author
Associate II
January 22, 2020

Here is a zip to the project file for config files

WNguy.1
WNguy.1Author
Associate II
January 22, 2020

..

Trevor Jones
Trevor JonesBest answer
Senior
January 23, 2020

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;
			}
	}
}