HAL UCPD Use Cases

Full UCPD Initialization Sequence

@startuml



participant "User application" as app

participant "HAL UCPD driver"  as hal

participant "System Driver"    as sys



note over hal : Driver state is **RESET**



== UCPD HAL Initialization  ==



app -> hal : HAL_UCPD_Init

alt #whitesmoke If USE_HAL_UCPD_ENABLE_MODEL > HAL_CLK_ENABLE_NO



hal ->  sys : Enable the UCPD clock

sys --> hal

end

app <-- hal : HAL_OK



== UCPD System Initialization==

note over hal : UCPD System initialization can be called\nbefore UCPD HAL initialization



app ->  sys : Initialization of DMA

sys --> app



alt #whitesmoke If GPIO(s) needed

app ->  sys : Initialization of GPIOs

sys --> app

end



alt #whitesmoke If USE_HAL_UCPD_ENABLE_MODEL > HAL_CLK_ENABLE_NO

app ->  sys : Enable the UCPD clock

sys --> app

end



== UCPD Static Configuration==

app ->  hal : HAL_UCPD_SetConfig

app <-- hal : HAL_OK



app ->  hal : [Any static configuration function]

app <-- hal : HAL_OK



note over hal : Driver state is **CONFIGURED**



app ->  hal : HAL_UCPD_Start

app <-- hal : HAL_OK



note over hal : Driver state is **IDLE**



app ->  hal : [Any dynamic configuration or control function]

app <-- hal : HAL_OK



@enduml

Called functions:

Full UCPD De-initialization Sequence

@startuml



participant "User application" as app

participant "HAL UCPD driver"  as hal

participant "System Driver"    as sys



note over hal : Driver state: any state



== UCPD HAL DeInitialization  ==

app ->  hal : HAL_UCPD_DeInit

app <-- hal : HAL_OK



== UCPD System DeInitialization  ==



app ->  sys : DeInitialization of DMA

sys --> app



alt #whitesmoke If GPIO(s) needed

app ->  sys : DeInitialization of GPIOs

sys --> app

end



app ->  sys : Disable the UCPD clock

sys --> app



note over hal : Driver state is **RESET**



@enduml

Called functions:

Simple Receive DMA - Without GoodCRC Transmission

@startuml

participant "User application" as app

participant "HAL UCPD driver"  as hal

participant "UCPDx_IRQHandler" as irqucpd

participant "HAL DMA driver"   as dma

participant "DMAx_IRQHandler"  as irq



== UCPD HAL Receive DMA ==

app ->  hal : HAL_UCPD_Receive_DMA

note over hal : Driver state is **RX**

hal ->  dma : HAL_DMA_StartPeriphXfer_Opt (HAL_DMA_OPT_NONE)

dma --> hal : HAL_OK

hal --> app : HAL_OK



alt successful case

irq <-      : DMAx complete interrupt

irq ->  dma : HAL_DMA_IRQHandler

dma ->  hal : UCPD_DMAReceiveCplt

hal --> dma

dma --> irq

irq -->



else error

irq <-      : DMAx error interrupt

irq ->  dma : HAL_DMA_IRQHandler

dma ->  hal : UCPD_DMAError

hal ->  app : HAL_UCPD_ErrorCallback

hal --> dma

dma --> irq

irq -->

end



note over hal : Driver state is **IDLE**



...



irqucpd <-      : UCPDx Receive message end (RXMSGEND)



note over irqucpd : In case DMA was configured to receive a larger \n\

message than actually received, RXMSGEND interrupt \n\

will rise before the end of DMA transfer callback.



irqucpd ->  hal : HAL_UCPD_IRQHandler

hal     ->  app : HAL_UCPD_RxCpltCallback

app     --> hal

hal     --> irqucpd

irqucpd -->



@enduml

Called functions:

Receive DMA - Followed by GoodCRC Transmission

@startuml

participant "User application" as app

participant "HAL UCPD driver"  as hal

participant "UCPDx_IRQHandler" as irqucpd

participant "HAL DMA driver"   as dma

participant "DMAx_IRQHandler"  as irq



note over hal : Driver state is **IDLE**



== UCPD HAL Receive DMA ==



note over app : Reception is started with the maximum size \n\

because actual Rx frame size is unknown.



app ->  hal : **HAL_UCPD_Receive_DMA**

note over hal : Driver state is **RX**



note over hal : DMA transfer is started for both Rx and Tx \n\

to prepare for quick GoodCRC transmission.



hal ->  dma : HAL_DMA_StartPeriphXfer_Opt (HAL_DMA_OPT_NONE)

dma --> hal : HAL_OK



hal --> app : HAL_OK



...



irqucpd <-      : UCPDx Receive message end (RXMSGEND)



note over irqucpd : In case DMA was configured to receive a larger \n\

message than actually received, RXMSGEND interrupt \n\

will rise before the end of DMA transfer callback.



irqucpd ->  hal : HAL_UCPD_IRQHandler

hal     ->  app : HAL_UCPD_RxCpltCallback



note over app : The user must compute and prepare the \n\

GoodCRC data to be sent.



app     ->  hal : HAL_UCPD_SetGoodCRCData

app    <--  hal



app     --> hal



note over hal : For timing constraints, GoodCRC \n\

transfer is automatically started in \n\

interrupt context after end of reception.



hal     --> irqucpd

irqucpd -->



alt successful case

irq <-      : DMAX complete interrupt

irq ->  dma : HAL_DMA_IRQHandler

dma ->  hal : UCPD_DMATransmitCplt

hal ->  hal : Enable UCPDx Transmit message sent IRQ (TXMSGSENT)

hal --> dma

dma --> irq

irq -->



else error

irq <-      : DMAx error interrupt

irq ->  dma : HAL_DMA_IRQHandler

dma ->  hal : UCPD_DMAError

hal ->  app : HAL_UCPD_ErrorCallback

hal --> dma

dma --> irq

irq -->

end



...



irqucpd <-      : UCPDx Transmit message sent (TXMSGSENT)

irqucpd ->  hal : HAL_UCPD_IRQHandler



note over hal : Driver state is back to \nprevious state: **IDLE**



hal     ->  app : HAL_UCPD_TxGoodCRCCpltCallback

app     --> hal

hal     --> irqucpd

irqucpd -->



...



note over app : Remaining Rx DMA reception can be \n\

aborted with HAL_UCPD_Abort_IT



@enduml

Called functions:

Transmit DMA

@startuml

participant "User application" as app

participant "HAL UCPD driver"  as hal

participant "UCPDx_IRQHandler" as irqucpd

participant "HAL DMA driver"   as dma

participant "DMAx_IRQHandler"  as irq



note over hal : Driver state is **IDLE** or **RX**



== UCPD HAL Transmit DMA ==

app ->  hal : HAL_UCPD_Transmit_DMA

note over hal : Driver state is **TX**\nPrevious state is saved

hal ->  dma : HAL_DMA_StartPeriphXfer_Opt (HAL_DMA_OPT_NONE)

dma --> hal : HAL_OK

hal --> app : HAL_OK



alt successful case

irq <-      : DMAX complete interrupt

irq ->  dma : HAL_DMA_IRQHandler

dma ->  hal : UCPD_DMATransmitCplt

hal ->  hal : Enable UCPDx Transmit message sent IRQ (TXMSGSENT)

hal --> dma

dma --> irq

irq -->



else error

irq <-      : DMAx error interrupt

irq ->  dma : HAL_DMA_IRQHandler

dma ->  hal : UCPD_DMAError

hal ->  app : HAL_UCPD_ErrorCallback

hal --> dma

dma --> irq

irq -->

end



...



irqucpd <-      : UCPDx Transmit message sent (TXMSGSENT)

irqucpd ->  hal : HAL_UCPD_IRQHandler



note over hal : Driver state is back to \nprevious state: **IDLE** or **RX**



hal     ->  app : HAL_UCPD_TxCpltCallback

app     --> hal

hal     --> irqucpd

irqucpd -->



@enduml

Called functions:

Process ABORT IT

@startuml



participant "User application" as app

participant "HAL UCPD driver"  as hal

participant "HAL DMA driver"   as dma

participant "DMAx_IRQHandler"  as irqdma



==UCPD HAL process==



app ->  hal : HAL_UCPD_Transmit_DMA or \nHAL_UCPD_Receive_DMA

app <-- hal : HAL_OK



note over hal : Driver state is **RX** or **TX**



==UCPD HAL Abort IT: case of Rx abort==



app ->  hal : HAL_UCPD_Abort_IT

hal ->  dma : HAL_DMA_Abort_IT

note over hal : Driver state is **ABORT**

hal <-- dma : HAL_OK



app <-- hal : HAL_OK

...

irqdma <-         : DMAx interrupt

dma    <-  irqdma : HAL_DMA_IRQHandler

hal    <-  dma    : UCPD_DMARxAbortCallback

app    <-  hal    : HAL_UCPD_AbortCpltCallback

app    --> hal

hal    --> dma

dma    --> irqdma

irqdma -->





note over hal : Driver state is **IDLE**



==UCPD HAL Abort IT: case of Tx abort==



app ->  hal : HAL_UCPD_Abort_IT

hal ->  dma : HAL_DMA_Abort_IT

note over hal : Driver state is **ABORT**

hal <-- dma : HAL_OK



app <-- hal : HAL_OK

...

irqdma <-         : DMAx interrupt

dma    <-  irqdma : HAL_DMA_IRQHandler

hal    <-  dma    : UCPD_DMATxAbortCallback



hal ->  hal : Enable UCPDx Transmit message sent IRQ (TXMSGSENT)



note over hal : The UCPD peripheral continues to send the \n\

remaining data but will ensure the CRC is \n\

incorrect, so that the receiver can end the \n\

reception and discard the message.



hal --> dma

dma --> irq

irq -->



irqucpd <-      : UCPDx Transmit message sent (TXMSGSENT)

irqucpd ->  hal : HAL_UCPD_IRQHandler



app    <-  hal    : HAL_UCPD_AbortCpltCallback



note over app : At receiver side, the RXERR interrupt will \n\

be raised and message will be discarded.



app    --> hal

hal    --> dma

dma    --> irqdma

irqdma -->





note over hal : Driver state is **IDLE**

@enduml

Called functions:

Interrupts

@startuml



participant "User application"     as app

participant "HAL UCPD driver"      as hal

participant "UCPD peripheral"      as ucpd



====



app ->  hal   : HAL_UCPD_Transmit_DMA

app <-- hal   : HAL_OK

hal --> ucpd  : LL_UCPD_EnableIT_X (X = TXMSGSENT, TXUND, TXMSGABT,\nTXMSGDISC, TXIS)

note over hal : TXMSGSENT is enabled in the DMA Tx complete callback "UCPD_DMATransmitCplt"

====

app ->  hal   : HAL_UCPD_Receive_DMA

app <-- hal   : HAL_OK

hal --> ucpd  : LL_UCPD_EnableIT_X (X = RXMSGEND, RXOVR, RXNE)

====

app ->  hal   : HAL_UCPD_EnableFRS_Rx

app <-- hal   : HAL_OK

hal --> ucpd  : LL_UCPD_EnableIT_FRS

note over hal : FRSEVT is enabled in the configuration function

====

app ->  hal   : HAL_UCPD_SendHardReset

app <-- hal   : HAL_OK

hal --> ucpd  : LL_UCPD_EnableIT_TxMSGSENT

note over hal : HRSTSENT and HRSTDISC are enabled in the control function

====

app ->  hal   : HAL_UCPD_SendCableReset

app <-- hal   : HAL_OK

hal --> ucpd  : LL_UCPD_EnableIT_TxHRSTSENT

note over hal : TXMSGSENT is enabled in the control function

====

app ->  hal   : HAL_UCPD_EnableTypeCDetectorCCx

app <-- hal   : HAL_OK

hal --> ucpd  : LL_UCPD_EnableIT_TypeCEventCC(X)

note over hal : TYPECEVT1 or TYPECEVT2 is enabled in the configuration function

====

app ->  hal   : HAL_UCPD_SetRxOrderedSet

app <-- hal   : HAL_OK

hal --> ucpd  : LL_UCPD_EnableIT_RxOrderSet

note over hal : RXORDDET is enabled in the configuration function

====

app ->  hal   : HAL_UCPD_EnableHardReset_Rx

app <-- hal   : HAL_OK

hal --> ucpd  : LL_UCPD_EnableIT_RxHRST

note over hal : RXHRSTDET is enabled in the configuration function



@enduml

Called functions:

Acquire/Release Bus

@startuml

!define USER_A_COLOR blue

!define USER_B_COLOR green

!define USER_A <font color=USER_A_COLOR>User A</font>

!define USER_B <font color=USER_B_COLOR>User B</font>



participant "USER_A" as app1

participant "USER_B" as app2

participant "HAL UCPD driver" as hal

participant "HAL OS wrapper"  as oswp



app1 -[#USER_A_COLOR]>  hal : <color #USER_A_COLOR>HAL_UCPD_AcquireBus</color>

hal  -[#USER_A_COLOR]>  oswp :<color #USER_A_COLOR>HAL_OS_SemaphoreTake</color>

hal  <-[#USER_A_COLOR]- oswp

app1 <-[#USER_A_COLOR]- hal : <color #USER_A_COLOR>HAL_OK</color>



note over hal : Bus acquired by USER_A. Any Process can be executed.



app2 -[#USER_B_COLOR]> hal : <color #USER_B_COLOR>HAL_UCPD_AcquireBus</color>

hal  -[#USER_B_COLOR]> oswp :<color #USER_B_COLOR>HAL_OS_SemaphoreTake</color>



app1 -[#USER_A_COLOR]>  hal : <color #USER_A_COLOR>HAL_UCPD_ReleaseBus</color>

app1 <-[#USER_A_COLOR]- hal : <color #USER_A_COLOR>HAL_OK</color>



hal  <-[#USER_B_COLOR]- oswp

app2 <-[#USER_B_COLOR]- hal : <color #USER_B_COLOR>HAL_OK</color>



note over hal : Bus acquired by USER_B. Any Process can be executed.

@enduml

Called functions: