S32K UART with DMA using processor expert(SDK) with PAL or without

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

S32K UART with DMA using processor expert(SDK) with PAL or without

1,233 Views
saireddy_saredd
Contributor III

Hallo,

 

Can anyone provide the example code for S32K  UART with DMA using processor expert(SDK) with PAL or without?

 

Best Regards,

Sai

@danielmartynek @PetrS 

Tags (1)
0 Kudos
Reply
7 Replies

978 Views
saireddy_saredd
Contributor III

Hi @danielmartynek 

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

0 Kudos
Reply

958 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Which version of the SDK drivers do you use exactly?

 

Thanks,

Daniel

0 Kudos
Reply

954 Views
saireddy_saredd
Contributor III

Hi @danielmartynek 

 

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?

saireddy_saredd_0-1715782342633.png

 

Best Regards,

Sai

 

0 Kudos
Reply

950 Views
danielmartynek
NXP TechSupport
NXP TechSupport

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.

https://www.nxp.com/design/design-center/software/development-software/s32-design-studio-ide/s32-des...

danielmartynek_0-1715782935460.png

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

 

0 Kudos
Reply

1,183 Views
saireddy_saredd
Contributor III

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

0 Kudos
Reply

1,025 Views
danielmartynek
NXP TechSupport
NXP TechSupport

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

 

0 Kudos
Reply

1,200 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hello Sai,

Unfortunately, there is no such example.

 

Regards,

Daniel

0 Kudos
Reply