HAL FDCAN Use Cases

Prerequisite

@startuml

skinparam backgroundColor #FFFFFF
' To add a number by line
'autonumber

' Fix order of each column
participant "User Application" as App
participant System

== Prerequisite ==

App -> System:HAL_Init()
note right
Configure the Flash prefetch, the time base source and the NVIC
end note

System --> App:<color green> HAL_OK

App -> System:SystemClock_Config()
note right
Configure system clock
end note
App <-- System:

@enduml

Full FDCAN Initialization Sequence

@startuml

participant "User application" as App
participant "<font color=black><b>HAL FDCAN"  as FDCAN #19DD3A
participant "System driver" as System

== FDCAN HAL Initialization  ==
App -> FDCAN:HAL_FDCAN_Init()
note right
Initialize the FDCAN handle and associate an instance
end note
alt if (USE_HAL_FDCAN_CLK_ENABLE_MODEL > HAL_CLK_ENABLE_NO)
FDCAN -> System:Enable the FDCAN clock
FDCAN <-- System:
end
App <-- FDCAN:<font color=green>HAL_OK
hnote over FDCAN
<font color=green>Driver state is INIT
end note

alt if (USE_HAL_FDCAN_CLK_ENABLE_MODEL == HAL_CLK_ENABLE_NO)
App-> System:Enable the FDCAN clock
note right
The application is free to enable the FDCAN clock before or after initialization
end note
App <-- System:
end

== FDCAN System Initialization==
Note over FDCAN#lightyellow:  FDCAN System initialization can be called before\nFDCAN HAL initialization

alt#darkgrey #lightgrey  If Interrupts needed
App-> System : Enable needed Interrupts
System-->App
end

alt#darkgrey #lightgrey  If GPIO(s) needed
App-> System : Initialization of GPIOs
System-->App
end

== FDCAN Configuration==
App -> FDCAN : HAL_FDCAN_SetConfig()
Note right#lightyellow: Configure the FDCAN according to the application requirements
App <-- FDCAN:<font color=green>HAL_OK
hnote over FDCAN
<font color=green>Driver state is IDLE
end note

@enduml

Functions called:

Full FDCAN Initialization and Configuration Sequence

@startuml

participant "User application" as App
participant "<font color=black><b>HAL FDCAN"  as FDCAN #19DD3A

== FDCAN HAL Initialization  ==
App -> FDCAN: HAL_FDCAN_Init()
note right
Initialize the FDCAN handle and associate an instance
end note
App <-- FDCAN:<color green>HAL_OK
hnote over FDCAN
<font color=green>Driver state is INIT
end note

== FDCAN Global configuration  ==
App -> FDCAN : HAL_FDCAN_SetConfig()
Note right#lightyellow: Configure the FDCAN according to the application requirements
App <-- FDCAN:<color green>HAL_OK
note over App
<color orange><b> The application can start any process or execute any unitary configuration</b>
end note
hnote over FDCAN
<font color=green>Driver state is IDLE
end note

== FDCAN unitary configurations  ==
App-> FDCAN: HAL_FDCAN_Set/Get<Item>()
FDCAN --> App:<color green>HAL_OK
App-> FDCAN: HAL_FDCAN_Enable/Disable<Item>()
FDCAN --> App:<color green>HAL_OK

@enduml

Functions called:

Full FDCAN Deinitialization Sequence

@startuml

participant "User application" as App
participant "<font color=black><b>HAL FDCAN"  as FDCAN #19DD3A
participant "System driver" as System

== FDCAN HAL DeInitialization  ==
App-> FDCAN : HAL_FDCAN_DeInit()
note right
Clear the interrupt lines, error code and user data
end note
App<--FDCAN:
hnote over FDCAN
<font color=green>Driver state is RESET
end note

== FDCAN System DeInitialization  ==
App-> System : Disable NVIC
note right
When using interrupt
end note

App-> System : DeInitialization of GPIOs
note right
When using GPIOs
end note
App-> System : Disable FDCAN clock

@enduml

Functions called:

FDCAN Transmit Message Polling Mode Using HAL_FDCAN_GetTxFifoFreeLevel

@startuml

participant "User application" as App#AliceBlue
participant "<font color=black><b>HAL FDCAN"  as FDCAN #19DD3A

== Full FDCAN initialization and configuration sequence  ==

App-> FDCAN: HAL_FDCAN_Start(&hfdcan)
FDCAN --> App:<color green>HAL_OK
Note over App#lightyellow: The application builds the Tx Header and Tx Data structure\n and buffer of the message to be transmitted.

== FDCAN HAL Message Transmit  ==
App-> FDCAN: HAL_FDCAN_ReqTransmitMsgFromFIFOQ(&hfdcan, &TxHeader, TxData)
FDCAN --> App:<color green>HAL_OK

loop#darkgrey #lightgrey until  x == FREE_TX_BUFFER
App-> FDCAN: HAL_FDCAN_GetTxFifoFreeLevel(&hfdcan)
FDCAN --> App: x
Note over App#lightyellow: Up to three Tx buffers can be set up for message\n transmission (FREE_TX_BUFFER = 3)
end

@enduml

Functions called:

FDCAN Transmit Message Polling Mode Using HAL_FDCAN_GetTxBufferMessageStatus

@startuml

participant "User application" as App
participant "<font color=black><b>HAL FDCAN"  as FDCAN #19DD3A

== HAL FDCAN2 Transmit a message using FIFO/Queue ==

Note over App #lightyellow: The application builds the header and data structures\nof the message to be transmitted.

hnote over FDCAN
   <font color=green>Driver state is IDLE
end hnote

App -> FDCAN: HAL_FDCAN_Start()
FDCAN --> App: <font color=green>HAL_OK

hnote over FDCAN
   <font color=green>Driver state is ACTIVE
end hnote

loop For each message to transmit
   App -> FDCAN: HAL_FDCAN_ReqTransmitMsgFromFIFOQ()
   note right
      Add a message to the Tx FIFO/Queue and activate the transmission request
   end note
   FDCAN --> App: <font color=green>HAL_OK
end

loop While HAL_FDCAN_BUFFER_PENDING on a specific FIFO/Queue buffer
   App -> FDCAN: HAL_FDCAN_GetTxBufferMessageStatus()
   note right
      The application checks if the message has been transmitted from the FIFO/Queue.
   end note

   alt Message not yet transmitted
      FDCAN --> App: HAL_FDCAN_BUFFER_PENDING
      note right
         The transmit buffer is not empty - message still pending
      end note
   else Message transmitted
      FDCAN --> App: HAL_FDCAN_BUFFER_NOT_PENDING
      note right
         The transmit buffer is empty - message sent
      end note
      destroy App
   end
end

@enduml

Functions called:

FDCAN Reading Message Polling Mode Using HAL_FDCAN_GetRxFifoFillLevel

@startuml

participant "User application" as App#AliceBlue
participant "<font color=black><b>HAL FDCAN"  as FDCAN #19DD3A
participant "System Driver" as Driver#AliceBlue

== HAL FDCAN Polling Message Receive  ==
Note over App#lightyellow: The acceptance filters have been configured.

hnote over FDCAN
   <font color=green>Diver state is ACTIVE
end note

App -> Driver: HAL_GetTick()
note right
   Get the current time
endnote
Driver --> App: starting_time

loop#darkgrey  if fifo_level != 1
   Note over App #lightyellow: Because one single message is expected, the number of element stored\nin Rx FIFO 0 is 1.
   App -> FDCAN: HAL_FDCAN_GetRxFifoFillLevel()
   note right
      Retrieve the Rx FIFO fill level
   endnote

   Driver --> App: fifo_level
   App -> Driver: HAL_GetTick()
   Note over App#lightyellow: The timeout will trigger if the elapsed time\n is more than the MAX_TIMEOUT value defined by the application.
   alt current_time - starting_time < MAX_TIMEOUT
      Driver --> App: current_time
   else timeout occured
      Driver-->App: break
      destroy App
   end
end

App -> FDCAN: HAL_FDCAN_GetReceivedMessage()
note right
   Retrieve an FDCAN frame from the Rx FIFO
endnote

FDCAN --> App:<color green>HAL_OK
note left
   The application can process the received data or error
end note

@enduml

Functions called:

FDCAN Transmission with IT Using Tx Complete/Tx Cancellation Interrupts

@startuml
participant "User application" as App#AliceBlue
participant "<font color=black><b>HAL FDCAN"  as FDCAN #19DD3A
participant "FDCAN_IRQHandler" as IRQHandler#AliceBlue

== Full FDCAN initialization and configuration sequence  ==
App -> FDCAN:  HAL_FDCAN_Start(handle)
FDCAN --> App:<color green>HAL_OK

== FDCAN HAL Message Transmit on IT  ==
Note over App#lightyellow: This sequence diagram shows how Tx Complete or Tx Abort events from Tx Buffer 0 trigger interrupts on Line 1. Both interrupts are part of HAL_FDCAN_IT_GROUP_STATUS_MSG group.
FDCAN --> App:<color green>HAL_OK
App -> FDCAN: HAL_FDCAN_EnableInterruptLines(handle, HAL_FDCAN_IT_LINE_1)
FDCAN --> App:<color green>HAL_OK
App -> FDCAN: HAL_FDCAN_EnableInterrupts(handle, HAL_FDCAN_IT_TX_COMPLETE | HAL_FDCAN_IT_TX_ABORT_COMPLETE)
FDCAN --> App:<color green>HAL_OK

Note over App#lightgreen: For Transmission Completed and Transmission Cancellation Finished interrupts,\na buffer index must be provided to indicate on which buffer the interrupt will occur:\nHAL_FDCAN_TX_IT_BUFFER_0 in the present example.
alt#darkgrey #lightgrey if interrupt = HAL_FDCAN_IT_TX_COMPLETE
App -> FDCAN: HAL_FDCAN_EnableTxBufferCompleteInterrupts(handle, HAL_FDCAN_TX_IT_BUFFER_0)
FDCAN --> App:<color green>HAL_OK
else interrupt = HAL_FDCAN_IT_TX_ABORT_COMPLETE
App -> FDCAN: HAL_FDCAN_EnableTxBufferCancellationInterrupts(handle, HAL_FDCAN_TX_IT_BUFFER_0)
FDCAN --> App:<color green>HAL_OK
end

App -> FDCAN:  HAL_FDCAN_Start(handle)
FDCAN --> App:<color green>HAL_OK
Note over App#lightyellow: The TxHeader and TxData are configured. Because there is only a single\ntx message TX BUFFER 0 will be the default buffer used for transmission.
App -> FDCAN:  HAL_FDCAN_ReqTransmitMsgFromFIFOQ(handle, &TxHeader, &TxData)
FDCAN --> App:<color green>HAL_OK

alt#darkgrey #lightgrey if interrupt = HAL_FDCAN_IT_TX_COMPLETE
App-[hidden]->App
activate App
Note over IRQHandler#lightgreen: The interrupt Tx complete event from the system can be processed by IRQ Handler.
IRQHandler <-  : FDCAN interrupt Tx Complete
IRQHandler -> FDCAN: HAL_FDCAN_IRQHandler
App -> App: wait for an event from Tx Complete callback
FDCAN -> App: HAL_FDCAN_TxBufferCompleteCallback()
App --> FDCAN:
FDCAN --> IRQHandler:
IRQHandler --> :
App-[hidden]->App
deactivate App
else interrupt = HAL_FDCAN_IT_TX_ABORT_COMPLETE
App-[hidden]->App
activate App
Note over IRQHandler#lightgreen: The interrupt Tx cancellation finished event from the system can be processed by IRQ Handler.
IRQHandler <-  : FDCAN interrupt Tx Cancellation Finished
IRQHandler -> FDCAN: HAL_FDCAN_IRQHandler
App -> App: wait for an event from Tx cancellation finished callback
FDCAN -> App: HAL_FDCAN_TxBufferAbortCallback()
App --> FDCAN:
FDCAN --> IRQHandler:
IRQHandler --> :
deactivate App
App-[hidden]->App
end

Note over App#lightgreen: The User application must disable the buffer connected to the interrupt.
alt#darkgrey #lightgrey if interrupt = HAL_FDCAN_IT_TX_COMPLETE
App -> FDCAN: HAL_FDCAN_DisableTxBufferCompleteInterrupts(handle, HAL_FDCAN_TX_IT_BUFFER_0)
FDCAN --> App:<color green>HAL_OK
else interrupt = HAL_FDCAN_IT_TX_ABORT_COMPLETE
App -> FDCAN: HAL_FDCAN_DisableTxBufferCancellationInterrupts(handle, HAL_FDCAN_TX_IT_BUFFER_0)
FDCAN --> App:<color green>HAL_OK
end

App -> FDCAN:  HAL_FDCAN_DisableInterrupts(handle, HAL_FDCAN_IT_TX_COMPLETE | HAL_FDCAN_IT_TX_ABORT_COMPLETE)
FDCAN --> App:<color green>HAL_OK
App -> FDCAN: HAL_FDCAN_DisableInterruptLines(handle, HAL_FDCAN_IT_LINE_1)
FDCAN --> App:<color green>HAL_OK

@enduml

Functions called:

FDCAN Receiving Message Using the Rx High-Priority Message Interrupt (HPME)

@startuml

participant "User application" as App#AliceBlue
participant "<font color=black><b>HAL FDCAN"  as FDCAN #19DD3A
participant "NVIC" as NVIC#AliceBlue

== FDCAN HAL Receive High priority message with IT  ==
hnote over FDCAN
<font color=green>Diver state is IDLE
end note
note over App:  Create filters element to select the Rx High Priority message.
App->FDCAN: HAL_FDCAN_SetFilter()
FDCAN-->App:<color green> HAL_OK

note over App
The application can create specific acceptance rules for the messages selected by the filters
end note
App -> FDCAN: HAL_FDCAN_SetGlobalFilter()
FDCAN --> App:<color green> HAL_OK

App -> FDCAN: HAL_FDCAN_EnableInterrupts(handle, HAL_FDCAN_IT_RX_HIGH_PRIORITY_MSG)
FDCAN --> App:<color green> HAL_OK
App -> FDCAN: HAL_FDCAN_SetInterruptGroupsToLine(handle, HAL_FDCAN_IT_GROUP_STATUS_MSG, HAL_FDCAN_IT_LINE_[0|1])
Note right
Assign the interrupt Status Message Group to an interrupt Line.
endnote
FDCAN --> App:<color green> HAL_OK

App -> FDCAN: HAL_FDCAN_EnableInterruptLines(handle, HAL_FDCAN_IT_LINE_[0|1])
FDCAN --> App:<color green> HAL_OK

App -> FDCAN:  HAL_FDCAN_Start()
FDCAN --> App:<color green> HAL_OK
hnote over FDCAN
<font color=green>Diver state is ACTIVE
end note

App[#FFFFFF]-> App
activate App #1000DA
hnote over App
<font color=blue>reception ongoing...
end note
NVIC <-  : FDCAN interrupt High Priority Message received
NVIC -> FDCAN: HAL_FDCAN_IRQHandler
FDCAN -> App: HAL_FDCAN_HighPriorityMessageCallback()
App --> FDCAN:
deactivate App
FDCAN --> NVIC:
NVIC --> :

App -> FDCAN: HAL_FDCAN_GetReceivedMessage()
note right
Retrieve an FDCAN frame from the Rx FIFO
endnote
FDCAN --> App:<color green> HAL_OK

App -> FDCAN: HAL_FDCAN_DisableInterruptLines(handle, HAL_FDCAN_IT_LINE_[0|1])
FDCAN --> App:<color green> HAL_OK

App -> FDCAN:  HAL_FDCAN_DisableInterrupts(handle, HAL_FDCAN_IT_RX_HIGH_PRIORITY_MSG)
FDCAN --> App:<color green> HAL_OK

@enduml

Functions called:

FDCAN Transmit Abort Using Transmission Cancellation Finished Interrupt

@startuml

participant "User application" as App#AliceBlue
participant "<font color=black><b>HAL FDCAN"  as FDCAN #19DD3A
participant "NVIC" as NVIC#AliceBlue

== FDCAN HAL IT Transmit Cancellation complete  ==
Note over App#lightyellow:  The acceptance filters, headers and data structres have been\nconfigured, the driver is initialized and configured
hnote over FDCAN
<font color=green>Driver state is ACTIVE
end note
App -> FDCAN: HAL_FDCAN_EnableInterrupts(handle, HAL_FDCAN_IT_TX_ABORT_COMPLETE)
FDCAN -->App : <color green>HAL_OK
App -> FDCAN: HAL_FDCAN_SetInterruptGroupsToLine(handle, HAL_FDCAN_IT_GROUP_STATUS_MSG, HAL_FDCAN_IT_LINE_[0|1] )
FDCAN -->App : <color green>HAL_OK
App -> FDCAN: HAL_FDCAN_EnableInterruptLines(handle, HAL_FDCAN_IT_LINE_[0|1])
FDCAN -->App : <color green>HAL_OK

App -> FDCAN:  HAL_FDCAN_ReqTransmitMsgFromFIFOQ()
FDCAN -->App : <color green>HAL_OK

Note over App: <color orange><b>The application wants to abort the last message added to the fifo before being sent</b>
App -> FDCAN:  HAL_FDCAN_GetLatestTxFifoQRequestBuffer()
note right
Get the last buffer sent for transmission.
endnote

FDCAN --> App: <color black>selected buffer
App -> FDCAN: HAL_FDCAN_EnableTxBufferCancellationInterrupts(handle, HAL_FDCAN_TX_IT_BUFFER_0)

FDCAN -->App : <color green>HAL_OK
App -> FDCAN : HAL_FDCAN_ReqAbortOfTxBuffer(handle, HAL_FDCAN_TX_IT_BUFFER_0)
FDCAN -->App : <color green>HAL_OK

...

NVIC <- : FDCAN interrupt Transmission Cancellation finished
note left
The cancellation of the selected buffer has just finished
endnote

NVIC -> FDCAN : HAL_FDCAN_IRQHandler
FDCAN -> App  : HAL_FDCAN_TxBufferAbortCallback()
App --> FDCAN :

FDCAN --> NVIC:
NVIC --> :
App -> FDCAN: HAL_FDCAN_DisableTxBufferCancellationInterrupts(handle, HAL_FDCAN_TX_IT_BUFFER_0)

FDCAN -->App : <color green>HAL_OK
App -> FDCAN:  HAL_FDCAN_DisableInterrupts(handle, HAL_FDCAN_IT_TX_ABORT_COMPLETE)
FDCAN -->App : <color green>HAL_OK
App -> FDCAN: HAL_FDCAN_DisableInterruptLines(handle, HAL_FDCAN_IT_LINE_[0|1])
FDCAN -->App : <color green>HAL_OK

@enduml

Functions called: