Skip to main content
Visitor II
June 27, 2024
Solved

UCPD sink on STM32G4

  • June 27, 2024
  • 2 replies
  • 1375 views

Is it possible to implement UCPD sink on a stm32G4 without RTOS. What all does that entail? What are the pros and cons?

    This topic has been closed for replies.
    Best answer by FBL

    Hi @RMas 

    However, consider that we do not recommend building applications without RTOS in case full compliance with USB PD and Type-C specifications is required. And the code should be 

    for (port = 0; port < USBPD_PORT_COUNT; port++)
     {
     if ((HAL_GetTick() - DPM_Sleep_start[port]) >= DPM_Sleep_time[port])
     {
     DPM_Sleep_time[port] =
    #ifdef _DRP
     USBPD_PE_StateMachine_DRP(port);
    #elif _SRC
     USBPD_PE_StateMachine_SRC(port);
    #elif _SNK
     USBPD_PE_StateMachine_SNK(port);
    #endif /* _DRP */
     DPM_Sleep_start[port] = HAL_GetTick() + 1;
     }
     }

     

    2 replies

    Technical Moderator
    July 1, 2024

    Hi @RMas 

    The following wiki application is based on FreeRTOS STM32StepByStep:Getting started with USB-Power Delivery Sink - stm32mcu and here is the associated example using G4 x-cube-tcpp/Projects/NUCLEO-G474RE/Applications/USB_PD/SNK1M1_Sink at main · STMicroelectronics/x-cube-tcpp (github.com)

    Without an RTOS, you would typically have a main loop that continuously polls various functions and manages state transitions manually. 

    void USBPD_DPM_Run(void)
    {
     // The following code is executed in an infinite loop
     do {
     // Call the Type-C and USB PD stack to handle any CAD (Cable Attachment Detection) events
     (void)USBPD_CAD_Process();
    
     // Check if the time elapsed since the last Policy Engine (PE) process run is greater than the defined sleep time
     if ((HAL_GetTick() - DPM_Sleep_start[USB_PD_PORT_0]) > DPM_Sleep_time[USB_PD_PORT_0]) {
     // Depending on the role of the device (DRP, Source, or Sink), run the appropriate PE state machine
    
     USBPD_PE_StateMachine_SNK(USB_PD_PORT_0);
    
     // Update the start time for the next PE process run
     DPM_Sleep_start[USB_PD_PORT_0] = HAL_GetTick();
     }
    
     // Execute user-defined code, which could include handling application-specific logic
     USBPD_DPM_UserExecute(NULL);
    
     // Process any pending USB PD trace data for transmission
     (void)USBPD_TRACE_TX_Process();
    
     // Continue looping indefinitely
     } while (1u == 1u);
    }

    Caution: LIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY may need to be adjusted as it may causes the code execution to get stuck in the vPortValidateInterruptPriority function due to overlapping interrupt priorities with kernel operations.

    FBLAnswer
    Technical Moderator
    July 23, 2024

    Hi @RMas 

    However, consider that we do not recommend building applications without RTOS in case full compliance with USB PD and Type-C specifications is required. And the code should be 

    for (port = 0; port < USBPD_PORT_COUNT; port++)
     {
     if ((HAL_GetTick() - DPM_Sleep_start[port]) >= DPM_Sleep_time[port])
     {
     DPM_Sleep_time[port] =
    #ifdef _DRP
     USBPD_PE_StateMachine_DRP(port);
    #elif _SRC
     USBPD_PE_StateMachine_SRC(port);
    #elif _SNK
     USBPD_PE_StateMachine_SNK(port);
    #endif /* _DRP */
     DPM_Sleep_start[port] = HAL_GetTick() + 1;
     }
     }