HAL NAND Use Cases

Prerequisite: Initialization and configuration

@startuml

participant App as "User application"
participant system as "System"
participant "GPIO Driver"      as GPIO
participant "RCC Driver"       as RCC

participant "<font color=green><b>HAL NAND Driver</b></font>" as NAND

== HAL NAND initialization ==

App->NAND : HAL_NAND_Init()
note right:  <b> Initialize the NAND handle and associate an instance.

note over NAND 	#CCCCFF
Global state = <font color=blue> <b>INIT</b>
end note
  group #lightgrey Alt
    NAND->RCC : HAL_RCC_FMC_EnableClock()
    note right: If <b>USE_FMC_CLK_ENABLE_MODEL > HAL_CLK_ENABLE_NO
  end

NAND --> App : hal status : <font color=#49b170>HAL_OK</font> or <font color=#8c0078>HAL_INVALID_PARAM</font>
note right:  Return
== NAND system initialization ==
Note over NAND : NAND System initialization can be called before\nHAL NAND initialization
   group #lightgrey Alt
      App->RCC : Enable FMC Clock
      note right: If <b>USE_FMC_CLK_ENABLE_MODEL == HAL_CLK_ENABLE_NO
   end
group #lightblue Hardware resource initialization
   App->GPIO : NAND HW Initialisation
   note right:  Initialize GPIO
   GPIO --> App
end
== Configuration ==

App->NAND : HAL_NAND_SetConfig
note right: Set the static configuration for the FMC peripheral

note over NAND 	#CCCCFF
Global state = <font color=green> <b>CONFIGURED</b>
end note

NAND --> App: hal status : <font color=#49b170>HAL_OK</font> or <font color=#8c0078>HAL_INVALID_PARAM</font>
note right:  return

App->NAND : HAL_NAND_SetConfigMemory
note right:  Set the NAND memory parameters

note over NAND 	#CCCCFF
Global state = <font color=green> <b>MEMORY_CONFIGURED</b>
end note

NAND --> App: hal status : <font color=#49b170>HAL_OK</font> or <font color=#8c0078>HAL_INVALID_PARAM</font>
note right:  return

group #orange optional Configuration

   App->NAND : HAL_NAND_SetLastWriteAccessTiming()
   note right of NAND
  Can be called optionally to set the timinig of the last write access when it differs from previous timing accesses
   end note
   note over NAND 	#CCCCFF
   Global state = <font color=green> <b>MEMORY_CONFIGURED</b>
   end note
NAND --> App: hal status : <font color=#49b170>HAL_OK</font> or <font color=#8c0078>HAL_INVALID_PARAM</font>
note right:  return
end

group #orange optional Reset

   App->NAND : HAL_NAND_Reset()
   note right of NAND
  First command after power-on for <b>some NAND devices</b>.
  Once needed, it must be called before HAL_NAND_SetConfigPartitionONFI() API.
   end note
   note over NAND 	#CCCCFF
   Global state = <font color=green> <b>IDLE</b>
   end note
NAND --> App: hal status : <font color=#49b170>HAL_OK</font> or <font color=#8c0078>HAL_INVALID_PARAM</font>
note right:  return
end
App->NAND : HAL_NAND_SetConfigPartition
note right:  Set the partition configuration

note over NAND 	#CCCCFF
Global state = <font color=green> <b>IDLE</b>
end note

NAND --> App: hal status : <font color=#49b170>HAL_OK</font> or <font color=#8c0078>HAL_INVALID_PARAM</font>
note right:  return

@enduml

Called functions:

NAND deinitialization sequence

@startuml
participant App as "User application"
participant "<font color=green><b>HAL NAND</b></font>" as NAND
participant "HAL RCC" as RCC
participant "HAL GPIO" as GPIO

==NAND DeInitialisation==
App->NAND : HAL_NAND_DeInit

note over NAND 	#CCCCFF
Global state = <font color=gray> <b>RESET</b>
end note

App<--NAND

==NAND system DeInitalization==

alt#grey #lightgrey If GPIO(s) needed
App->GPIO : DeInitialization of GPIOs
GPIO-->App
end

App->RCC : Disable the NAND clock
RCC --> App
@enduml

Called functions:

Use case 1: Starting a read/write operation in polling mode

@startuml

== Prerequisite: Initialisation and configuration ==
participant "User Application" as part1
participant "<font color=green><b>HAL NAND</b></font>"   as part2
== Process ==
part1->part2 : HAL_NAND_EraseBlock()
note right: ** Erase a block in NAND memory
part2->part1: hal_status : HAL_OK or HAL_BUSY or HAL_INVALID_PARAM
note right: ** Return the status of the NAND erase operation

part1->part2 : HAL_NAND_ProgramPage()
note right: ** Program a page in the NAND memory
part2->part1: hal_status : HAL_OK or HAL_BUSY or HAL_INVALID_PARAM
note right: ** Return

part1->part2 : HAL_NAND_ReadPage()
note right: ** Read a page in the NAND memory
part2->part1: hal_status : HAL_OK or HAL_BUSY or HAL_INVALID_PARAM
note right: ** Return

@enduml

Called functions:

Use case 2: Invalid program/read operations in polling mode

@startuml
participant "User Application" as part1
participant "<font color=green><b>HAL NAND</b></font>"   as part2
== Prerequisite: Initialisation and configuration ==

== Process ==
"part1"->part2 : HAL_NAND_EraseBlock()
note right: ** Erase a block in NAND memory
part2->"part1": hal_status : HAL_OK or HAL_BUSY or HAL_INVALID_PARAM
note right: ** Return the status of the NAND erase operation

"part1"->part2 : HAL_NAND_ProgramPage()
note right: ** Program a page in the NAND memory
part2->"part1": hal_status : HAL_TIMEOUT or HAL_ERROR
note right: ** Return

"part1"->part2 : HAL_NAND_Reset()
note right: Reset the program operation and clear the status register so that a  new command can be sent
part2 -> "part1": hal status : HAL_OK or HAL_INVALID_PARAM
note right: ** Return

"part1"->part2 : HAL_NAND_ReadPage()
note right: ** Read a page in the NAND memory
part2->"part1": hal_status : HAL_OK or HAL_BUSY or HAL_INVALID_PARAM
note right: ** Return

@enduml

Called functions:

Use case 3: Program/read using general purpose DMA at user level

@startuml

participant "User Application" as part1
participant "System"           as part2
participant "<font color=green><b>HAL NAND</b></font>"   as part3
participant "HAL DMA Driver"   as part4
participant "DMA_IRQHandler"   as part5
participant "STM32 HW"         as part6

== Prerequisite: Initialisation and configuration ==

== Process ==
"part1"->"part3"  : HAL_NAND_EraseBlock()
note right: ** Erase a block in NAND memory
"part3"->"part1": hal_status : HAL_BUSY or HAL_INVALID_PARAM
note right: ** Return the status of the NAND erase operation


"part1"->"part3"  : HAL_NAND_SendProgramPageCmd()
note right: ** Send program page command

"part3"->"part1": hal_status : HAL_BUSY or HAL_INVALID_PARAM
note right: ** Return the status of the NAND program operation



"part1" -> "part4" : HAL_DMA_Start_IT()
note right: ** Start DMA transfer

"part6" -> "part5" : Interrupt
note right: ** DMA transfer complete


"part5" -> "part4" : HAL_DMA_IRQHandler()
note right: ** Call the IRQ Handler to manage the interrupt

"part4" -> "part1" : XferCpltCallback() callback
note right: ** Call the callback

Group #orange XferCpltCallback()

"part1"->"part3"  : HAL_NAND_EndProgramPage()
note right: ** Notify the NAND driver that transfer is complete, so that new commands can be executed**
"part3"->"part1": hal_status : HAL_OK or HAL_INVALID_PARAM
end

"part1"->"part3"  : HAL_NAND_SendReadPageCmd()
note right: ** Send read page command
"part3"->"part1": hal_status : HAL_BUSY or HAL_INVALID_PARAM
note right: ** Return the status of the NAND read operation **

"part1" -> "part4" : HAL_DMA_Start_IT()
note right: ** Start DMA transfer


"part6" -> "part5" : Interrupt
note right: ** DMA transfer complete

"part5" -> "part4" : HAL_DMA_IRQHandler()
note right: ** Call the IRQ Handler to manage the interrupt

"part4" -> "part1" : XferCpltCallback() callback
note right: ** Call the callback

Group #orange XferCpltCallback()

"part1"->"part3"  : HAL_NAND_EndReadPage()
note right: ** Notify the NAND driver that transfer is complete, so that new commands can be executed
"part3"->"part1": hal_status : HAL_OK or HAL_INVALID_PARAM
end



@enduml

Called functions:

Use case 4: ECC management (polling mode)

@startuml

== Prerequisite: Initialisation and configuration ==

== Process ==
"User Application"->"HAL NAND Driver" : HAL_NAND_EraseBlock()
note right: ** Erase a block in NAND memory
"HAL NAND Driver"->"User Application": hal_status : HAL_OK or HAL_BUSY or HAL_INVALID_PARAM
note right: ** Return the status of the NAND erase operation

"User Application"->"HAL NAND Driver" : HAL_NAND_ECC_ProgramPage()
note right: ** Program a page in the NAND memory with ECC computation **
"HAL NAND Driver"->"User Application": hal_status : HAL_OK or HAL_BUSY or HAL_INVALID_PARAM
note right: ** Return **

"User Application" -> "HAL NAND Driver" : HAL_NAND_ECC_ReadPage()
note right: **Read a page in the NAND memory with ECC computation**
"HAL NAND Driver" -> "User Application" : hal_status : HAL_OK or HAL_INVALID_PARAM
note right: **Return**

"User Application" -> "HAL NAND Driver" : HAL_NAND_ECC_GetErrors()
note right: ** Read the ECC decoding results **
"HAL NAND Driver" -> "User Application" : ECC decoding results
 note right: **Return**

@enduml

Called functions: