2024-12-09 06:28 PM
Hi everyone,
So, I have FDCAN working in internal and external loop back but when I connect it to an external CAN bus and switch it to standard operation I get nothing. I know there are messages on the CAN bus because I have a CAN scanner on the bus that is showing activity. However, the RX interrupt never goes off. My first debugging step was to remove the H7 from the bus and just see using an oscilloscope if the H7 was outputting anything (for loop with HAL_FDCAN_AddMessageToTxFifoQ and a 50ms delay) , I'm aware that two devices are needed for communication but from my understanding the FDCAN controller should still transmit until it reaches the ACK?
I then plugged in my CAN to USB converter connected directly to the H750B Discovery, I had a look at the signals before and after connecting the H750B and there was no change in the packets, they were the same if there was the single device (the CAN to USB converter) or if there was two devices, both the H7 and the CAN to USB converter. So it seams to me that the H7 is not ACKing or receiving the packet sent by the CAN to USB converter at all. This also seams to answer my previous question about what happens when there is only a singe device on the CAN bus, through I would not be surprised if my converter is doing something strange.
I'm very new to CAN and fairly inexperienced with embedded Dev as a whole, I did have CAN working well off a G474 nucleo with an external transceiver but that had less options to mess up in cubeMX.
I would apprecaite any help that could be thrown my way!
Cheers,
Michael
2024-12-10 01:20 AM
Hello,
I didn't understand the case. Could you please be less verbose but more concise?
What mode are you using: Normal or Loopback mode when you connect H750B Discovery to the CAN bus?
What issue you are facing: on transmit or on receive?
Could you please establish a simple sketch of the different nodes nodes with the CAN bus?
You can also refer to this article it may help you: STM32 FDCAN running at 8 Mb/s on NUCLEO boards
2024-12-11 05:23 PM
Hello sofLit,
I apologies about the state of my previous post, my head was not in the game! I'll outline my test procedures and provide code bellow.
FDCAN (Classic Frame Format) Relevant Code and Calculations:
CAN FreeRTOS Task, please ignore the terrible style and naming conventions, it is a work in progress!
void CANBuadDetectTask(void *argument) {
CANTaskConfig_t *config = (CANTaskConfig_t*) argument;
stringStruct_t termnialBuffer;
sprintf(termnialBuffer.string, "Starting CAN Scan!\n");
xQueueSend(CANTerminalTextQueueHandle,&termnialBuffer,0);
//TODO: Baud Rate Detect
if(HAL_FDCAN_Start(&hfdcan1)!= HAL_OK)
{
Error_Handler();
}
if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
{
/* Notification Error */
Error_Handler();
}
FDCAN_TxHeaderTypeDef TxHeader1;
uint8_t TxData1[12] = {0};
TxHeader1.Identifier = 0x00;
TxHeader1.IdType = FDCAN_STANDARD_ID;
TxHeader1.TxFrameType = FDCAN_DATA_FRAME;
TxHeader1.DataLength = 8;
TxHeader1.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
TxHeader1.BitRateSwitch = FDCAN_BRS_OFF;
TxHeader1.FDFormat = FDCAN_CLASSIC_CAN;
TxHeader1.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
TxHeader1.MessageMarker = 0;
for (;;) {
if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader1, TxData1) != HAL_OK)
{
Error_Handler();
}
osDelay(50);
}
}
4. CAN Callback
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
FDCAN_RxHeaderTypeDef RxHeader;
uint8_t RxData[12];
if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET)
{
/* Retreive Rx messages from RX FIFO0 */
if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
{
/* Reception Error */
Error_Handler();
}
if (HAL_FDCAN_ActivateNotification(hfdcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
{
/* Notification Error */
Error_Handler();
}
stringStruct_t termnialBuffer;
sprintf(termnialBuffer.string, "Recived CAN Packet\n");
xQueueSendFromISR(CANTerminalTextQueueHandle,&termnialBuffer,0);
}
}
Test 1 Reading CAN form USB to CAN tool using oscilloscope:
First test was to get an idea of what I would expect to see when a single node is transmitting and to make sure I had my oscilloscope set correctly. Watching CAN LOW.
Test 2 CAN Loop Back:
Set up using the CubeMX above, I press a button on the GUI to start the transmit and then prints a message to GUI when a CAN frame is received. Works as Excepted, except noting is seen on scope. From my understanding of external mode RX still transmits out of the controller so should be visible on scope, it just won't receive any external messages? That's the first sign of the problem. By this point I'm leaning towards I've somehow damaged the transceiver, but It's got ESD protection so I'm not sure.
Test 3 CAN TO USB connected to H750B:
This time I connected the MCU to the USB to CAN tool with the hopes of seeing the messages from the CAN Controller only modification is changing the mode to normal in MX. Termination was enabled on both sides. I first started the CAN on the H7 with the CAN tool not sending anything. Nothing was received on the H7 as expected but it also did not transmit anything.
I then started Transmitting from the CAN tool. There were lots more frames I did not recognize this time but none of them were ACKed nor did the H7 receive anything.
Here are some resources I used for reference while working on this:
https://controllerstech.com/stm32-fdcan-in-loopback-mode/
https://controllerstech.com/fdcan-normal-mode-stm32/
I hope this is more helpful, again sorry about my previous post, not the standard I like to work too.
Cheers,
Michael
2024-12-11 11:59 PM - edited 2024-12-12 03:43 AM
Hello @Michael_GetElectronic ,
At this stage, please start with a very simple project using only CAN communication, need to remove all the complex middlewares: TouchGFX, FreeRTOS etc .. need to focus on the CAN function.
Try to inspire from this example (it's using STM32H745-DISCO board): https://github.com/STMicroelectronics/STM32CubeH7/tree/master/Projects/STM32H745I-DISCO/Examples/FDCAN/FDCAN_Classic_Frame_Networking
For External Loopback probe directly on Tx pin not on the CAN_H and CAN_L.
Also remove printf from the callback as the callback is called from an interrupt context.
Remove this call from the Rx callback as I think it's already called elsewhere mainly in CAN initialization:
if (HAL_FDCAN_ActivateNotification(hfdcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
{
/* Notification Error */
Error_Handler();
}