2024-07-23 10:56 AM - last edited on 2024-07-24 12:57 AM by SofLit
Hi,
i am using STM32H753z i try to switching FDCAN GPIO is PD0, PD1 to UART tx and rx (same pins)
now i changed FDCAN to UART tx side is fine but in Rx side i face issue ( no data is receiving to receive buffer).
#define CAN_AFR 0x99
#define UART_AFR 0x88
#define CHANGING_PORT 0xFFFFFFFA
void switch_UART_TO_CAN(void)
{
if(HAL_UART_DeInit(&huart4) != HAL_OK)
{
Error_Handler();
}
GPIOD->AFR[0] = CAN_AFR;
GPIOD->MODER=CHANGING_PORT;
MX_FDCAN1_Init(&hfdcan1);
}
void switch_CAN_TO_UART(void)
{
if(HAL_FDCAN_DeInit(&hfdcan1)!= HAL_OK)
{
Error_Handler();
}
GPIOD->MODER=CHANGING_PORT;
GPIOD->AFR[0] = UART_AFR;
HAL_UART_Init(&huart4);
MX_UART4_Init();
}
Solved! Go to Solution.
2024-07-24 02:27 AM - edited 2024-07-24 02:34 AM
It's a bad idea to share the same pins between UART and FDCAN. Externally, the HW is not the same: CAN transceiver + a RS232 driver or STlink virtual comport.
So need to separate the pins.
2024-07-24 12:20 AM - edited 2024-07-24 12:57 AM
Hello,
You share USART4 and FDCAN1 pins, this supposes that FDCAN1 is seeing USART HW on its pins where you are switching to it! which is not recommended. You need to have free pins for FDCAN.
Which board are you using? Could you please share your schematics?
Also you have two UART4 init call which I couldn't understand:
HAL_UART_Init(&huart4);
MX_UART4_Init();
2024-07-24 02:23 AM
Method 1:
void switch_UART_TO_CAN(void)
{
if(HAL_UART_DeInit(&huart4) != HAL_OK)
{
Error_Handler();
}
GPIOD->AFR[0] = CAN_AFR;
GPIOD->MODER=CHANGING_PORT;
MX_FDCAN1_Init(&hfdcan1);
}
//
void switch_CAN_TO_UART(void)
{
if(HAL_FDCAN_DeInit(&hfdcan1)!= HAL_OK)
{
Error_Handler();
}
GPIOD->MODER=CHANGING_PORT;
GPIOD->AFR[0] = UART_AFR;
MX_UART4_Init();
}
Method 2:
void Switch_CAN_to_UART(void)
{
// Deinitialize FDCAN
if (HAL_FDCAN_DeInit(&hfdcan1) != HAL_OK)
{
Error_Handler();
}
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_UART4;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
// Initialize UART
MX_UART4_Init();
}
void Switch_UART_to_CAN(void)
{
// Deinitialize UART
if (HAL_UART_DeInit(&huart4) != HAL_OK)
{
Error_Handler();
}
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
// Initialize CAN
MX_FDCAN1_Init();
}
i am transfer is happened in UART4 but in receive side HAL_UART_Receive() thought time out error, issue
2024-07-24 02:27 AM - edited 2024-07-24 02:34 AM
It's a bad idea to share the same pins between UART and FDCAN. Externally, the HW is not the same: CAN transceiver + a RS232 driver or STlink virtual comport.
So need to separate the pins.
2024-07-24 02:40 AM
Hi SofL,
Thank you quick response,
actually my requirement is work both FDCAN AND UART IN same pin but different time based commend from GUI(application ) when GUI start they select CAN or UART at one time only
to meet this requirement, i am going in this way.
2024-07-24 02:51 AM
As stated before it's a bad idea to share the pins even one peripheral is used at a time. The FDCAN transceiver will disturb UART and seemingly UART HW (RS232 driver, STLINK VCOM or whatever attached) will disturb the FDCAN communication.
So need to separate the pins and dedicate pins for each interface or use a MUX on these pins.
2024-07-24 02:57 AM
Hi,
Thank you so mech, for quick response,
i have only one way is pin mux , can you please help me UART receive APis send time out error .
2024-07-24 03:22 AM
Sorry, I didn't understand this statement:,
i have only one way is pin mux , can you please help me UART receive APis send time out error .
But I think it's another subject related to UART usage itself not the pins sharing between the two interfaces. In that case please open a new thread.
Thank you.
2024-07-24 03:25 AM
It's a little bit sad that nobody explains why this is not working...
The probable cause is a problem not related to the STM32:
When connecting 2 low impedance / push-pull outputs, one output "shorts" the other one.
This might only work with open-drain / open-collector outputs.
2024-07-24 04:01 AM - edited 2024-07-24 04:05 AM
I think there is no need for this statement:
@LCE wrote:
It's a little bit sad that nobody explains why this is not working...
It's not a probable cause but it's definitely not related to the STM32.
@LCE wrote:
The probable cause is a problem not related to the STM32:
When connecting 2 low impedance / push-pull outputs, one output "shorts" the other one.
This might only work with open-drain / open-collector outputs.
Moreover, even in the inverse case (no output shorts), there will be an issue with CAN_Tx & UART_Rx / CAN_Rx & UART_Tx sharing the same pins because the external transceiver/driver will force its output at a level that will disturb the current peripheral not using the driver/transceiver.
Conclusion: in both cases it's a bad idea to share the pins as stated above. So need to MUX them by an external HW.