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 **IDLE**

app ->  hal : HAL_UCPD_Start
app <-- hal : HAL_OK

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

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 **ACTIVE**

...

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 **ACTIVE**

== 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: **ACTIVE**

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 **ACTIVE** 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: **ACTIVE** 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 **ACTIVE**

==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 **ACTIVE**
@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: