Hallo,
Can anyone provide the example code for S32K UART with DMA using processor expert(SDK) with PAL or without?
Best Regards,
Sai
Regarding transfer type via INTERRUPTS:
I see the major issue with LPUART_DRV_TxCompleteIrqHandler(instance); and LPUART_DRV_TxEmptyIrqHandler(instance);
1. Some times calling function LPUART_DRV_TxCompleteIrqHandler when txSize not equal to 0
2. Sometimes calling function LPUART_DRV_TxEmptyIrqHandler when txSize is equal to 0
The controller is hanging in the above scenarios. I did not get why it is happening.
I am working with embos RTOS. The sending done in one task and receiving done in other tasks and both tasks working parallel.
Do you think some synchronization problem with NXP os_if Semaphores and our RTOS scheduling(Embos)?
Can I also send and receive data in parallel tasks ? (Is this situation handled in SDK semaphore)
Best Regards,
Sai
Which version of the SDK drivers do you use exactly?
Thanks,
Daniel
Currently, I am using SDK v3.0.0. I installed S32 Design Studio for ARM (Version: 2.2 Build id: 200116) and did not able to install the SDK v4.0.2.
Is there any difference between v3.0.0 and v4.0.2 regarding UART driver?
Is there any possibility to download to get SDK files of v4.0.2 with out installtion?
Best Regards,
Sai
Thanks @saireddy_saredd,
Just regarding the SDK 4.0.2 version, this is not compatible with S32DS 2.2 but 3.4 only.
It does not use Processor Expert anymore but a new configuration tool.
You can also use the S32K1xx RTD drivers.
But we don't have any document that would compare the versions of the drivers, there are just the release notes.
Regards,
Daniel
Hi Daniel,
I am able to get one example and did the configuration according to the example. But, I got the Hard fault in UART receive callback (Storing data into Mailbox) when I use the DMA. The receive callback (Storing data into Mailbox) working fine when I use the interrupts.
Scenario 1: (Attached System view traces in zip file)
.transferType = LPUART_USING_INTERRUPTS
uart receive callback: Receiving data using mail boxes
The receive function is working fine but end up problem with watchdog failure(ISR calls so frequently and not giving time to OS Scheduler, attached the System view screenshot). I try to reduce the priority for ISR to 120 and still the issue not solved and ISR calls frequently.
Scenario 2: (attachment: UART_watchdog_disabled_Hang_In_ISR)
.transferType = LPUART_USING_INTERRUPTS
uart receive callback: Receiving data using mail boxes
Watchdog disabled
The controller completely hanged in ISR only (ISR47 in system view). ISR does not allow the Systick, UART_TX task or UART_RX task.
Why UART hanged in ISR? How can recover from the ISR hanging?
Scenario 3: (Attached CPU registers and Hardfault registers)
transferType = LPUART_USING_DMA
uart receive callback: Receiving data using mail boxes
Got the Impreiserr and Forced (attached screenshots)
How can I fix this Hard fault in uart_callback function(UART RX callback)?
//Receive callback
static void uart_callback(void *driver_state, uart_event_t event, void *user_data)
{
(void) driver_state;
(void) user_data;
if(event == UART_EVENT_RX_FULL){
//memcpy(&uart_buff[cnt],&g_uart_rx_buf[0], 1 );
OS_MAILBOX_Put1(&g_uart_rx_mb,&c);
LPUART_DRV_SetRxBuffer(INST_UART0, g_uart_rx_buf, 1);
}
}
//UART init
void uart_init()
{
OS_MAILBOX_Create(&g_uart_rx_mb, 1, UART_RX_MB_BUFFER_SIZE, g_uart_rx_mb_buffer);
OS_QUEUE_Create(&g_uart_uds_queue, &g_uart_qu_buffer, sizeof(g_uart_qu_buffer));
OS_MUTEX_Create(&g_uart_tx_mutex);
INT_SYS_SetPriority(s_lpuartRxTxIrqId[INST_UART0], UART_IRQ_PRIO);
LPUART_DRV_Init(INST_UART0, &uart0_State, &uart0_InitConfig0);
LPUART_DRV_InstallRxCallback(INST_UART0, uart_callback, NULL);
debug_log_print(LL_DEV, MOD_UART, "Init OK\n");
}
//Send data calling from TX Task
void uart_send_enc_can_frame(uint32_t can_id, uint8_t* can_data, uint8_t can_data_len)
{
uart_enc_can_frame_t enc_can_frame;
memset(&enc_can_frame, 0, sizeof(enc_can_frame));
enc_can_frame.header.sig_0 = UART_HEADER_SIG_0;
enc_can_frame.header.sig_1 = UART_HEADER_SIG_1;
enc_can_frame.header.frame_type = UART_FRAME_TYPE_ENCAPSULATED_CAN_MSG;
enc_can_frame.header.payload_len = sizeof(enc_can_frame.enc_can_payload);
enc_can_frame.enc_can_payload.can_frame_id = can_id;
enc_can_frame.enc_can_payload.can_frame_len = can_data_len;
for(uint8_t i=0; i<can_data_len; i++)
enc_can_frame.enc_can_payload.can_data[i] = can_data[i];
enc_can_frame.footer.crc16 = CRC16_DNP_CalcChecksum(&enc_can_frame.enc_can_payload, sizeof enc_can_frame.enc_can_payload);
if(OS_MUTEX_LockTimed(&g_uart_tx_mutex, UART_TX_MUTEX_TO) == 0){
debug_log_print(LL_ERR, MOD_UART, "TX Enc CAN frame blocked\n");
return;
}
if(LPUART_DRV_SendDataBlocking(INST_UART0, (uint8_t*)&enc_can_frame, sizeof enc_can_frame, UART_TX_TIMEOUT) != STATUS_SUCCESS){
debug_log_print(LL_ERR, MOD_UART, "TX Low Level error\n");
}
OS_MUTEX_Unlock(&g_uart_tx_mutex);
}
//RX Task
static void uart_rx_task()
{
rb_init(&g_uart_rx_rb, g_uart_rx_rb_data, UART_RX_RB_SIZE);
status_t rx_status = STATUS_SUCCESS;
do{
OS_Delay(10);
rx_status = LPUART_DRV_ReceiveData(INST_UART0, g_uart_rx_buf, 1);
}while(rx_status != STATUS_SUCCESS);
debug_log_print(LL_DEV, MOD_UART, "RX Receiving Started\n");
while(1)
{
uart_set_diagnosis_mode();
uint8_t data = 0;
uint32_t bytes_remaining = 0;
status_t s = LPUART_DRV_GetReceiveStatus(INST_UART0, &bytes_remaining);
if(s != STATUS_BUSY){
debug_log_print(LL_ERR, MOD_UART, "RX Failed with code %i\n", s);
s = LPUART_DRV_ReceiveData(INST_UART0, g_uart_rx_buf, 1);
debug_log_print(LL_INFO, MOD_UART, "RX Restarted with code %i\n", s);
}
if(OS_MAILBOX_GetTimed1(&g_uart_rx_mb, (char*) &data, UART_RX_IDLE_TO) != 0)
continue; //BUGFIX for UART RX failing: Restarting RX after being idle too long
/* if (uart_receive_flag == 1)
{
uart_receive_flag = 0;
memcpy(&data, &g_uart_rx_buf[0], 1);
LPUART_DRV_SetRxBuffer(INST_UART0, g_uart_rx_buf, 1);
}
else
{
OS_Delay(1);
continue;
}*/
if(rb_bytes_free(&g_uart_rx_rb) == 0)
rb_pop(&g_uart_rx_rb, 1);
rb_push(&g_uart_rx_rb, &data, 1);
uart_header_t header;
int16_t frame_offset = uart_find_frame(&g_uart_rx_rb, &header);
if(frame_offset == -1)
continue;
if(frame_offset > 0){
rb_pop(&g_uart_rx_rb, frame_offset); //drop everythin before the found frame
debug_log_print(LL_DEV, MOD_UART, "RX Dropped %i bytes before valid frame\n", frame_offset);
}
switch(header.frame_type)
{
case UART_FRAME_TYPE_ENCAPSULATED_CAN_MSG:
{
uart_enc_can_frame_t enc_can_frame;
if(uart_extract_enc_can_frame(&g_uart_rx_rb, &enc_can_frame) == true)
{
if(enc_can_frame.enc_can_payload.can_frame_id == 0x667 &&
enc_can_frame.enc_can_payload.can_frame_len == 2 &&
enc_can_frame.enc_can_payload.can_data[0] == 0xFF &&
enc_can_frame.enc_can_payload.can_data[1] == 0x00)
{
debug_log_print(LL_INFO, MOD_UART, "Reset to Bootloader via UART triggered \n");
SystemSoftwareReset();
}
else
{
uart_rx_unpack_msg(&enc_can_frame);
}
}
//TODO: else?
}
break;
case UART_FRAME_TYPE_UDS_DIAGNOSIS:
{
static uart_uds_frame_t enc_uds_frame;
g_uart_current_mode = UART_DIAGNOSIS_MODE;
OS_Delay(100);
if (g_uart_comm_status == UART_COMM_RUNNING)
{
debug_log_print(LL_DEV, MOD_GPIO, "UDS diagnosis started, UART tx Communication stopped \n");
g_uart_comm_status = UART_COMM_SUSPENDED;
OS_TASK_Suspend(&g_uart_tx_tcb);
}
if(uart_extract_uds_frame(&g_uart_rx_rb, &enc_uds_frame) == true)
{
OS_QUEUE_Put(&g_uart_uds_queue, enc_uds_frame.uds_data, enc_uds_frame.header.payload_len);
/* listening to TESTER PRESENT message from CMx tool */
if(enc_uds_frame.uds_data[0] == UDS_SERVICE_TESTER_PRESENT && enc_uds_frame.uds_data[1] == 0)
{
g_uart_testerpresent_start_time = OS_TIME_GetTicks();
}
}
}
break;
default:
debug_log_print(LL_ERR, MOD_UART, "RX Unknown Frame Type Detected: %i\n", header.frame_type);
break;
}
}
}
Best Regards,
Sai
Hello @saireddy_saredd,
You can make the imprecise fault precise by disabling the write buffer, ACTLR_DISDEFWBUF = 1
https://community.nxp.com/t5/S32K-Knowledge-Base/Fault-handling-on-S32K14x/ta-p/1114447
Then, BFAR should be valid and you should find the PC address of the fault instruction on the stack.
Do you use MPU?
Regards,
Daniel
Hello Sai,
Unfortunately, there is no such example.
Regards,
Daniel