@@ -514,7 +514,29 @@ static int erase_sector(const struct device *dev, int offset)
514514{
515515 int rc ;
516516 struct flash_stm32_sector_t sector = get_sector (dev , offset );
517-
517+ #if defined(CONFIG_FLASH_STM32_ASYNC )
518+ FLASH_STM32_PRIV (dev )-> async_complete = false;
519+ FLASH_STM32_PRIV (dev )-> async_error = false;
520+ FLASH_EraseInitTypeDef erase_init = {
521+ .TypeErase = FLASH_TYPEERASE_SECTORS ,
522+ .Banks = sector .bank ,
523+ .Sector = sector .sector_index ,
524+ .NbSectors = 1 ,
525+ .VoltageRange = FLASH_VOLTAGE_RANGE_4 ,
526+ };
527+ HAL_FLASHEx_Erase_IT (& erase_init );
528+ k_sem_take (& FLASH_STM32_PRIV (dev )-> async_sem , K_FOREVER );
529+ if (FLASH_STM32_PRIV (dev )-> async_complete ) {
530+ LOG_DBG ("Flash erase successful. Erased %lu bytes at 0x%x" ,
531+ FLASH_SECTOR_SIZE , FLASH_STM32_PRIV (dev )-> async_ret );
532+ rc = 0 ;
533+ } else {
534+ if (FLASH_STM32_PRIV (dev )-> async_error ) {
535+ LOG_ERR ("Flash erase failed %d" , FLASH_STM32_PRIV (dev )-> async_ret );
536+ }
537+ rc = - EIO ;
538+ }
539+ #else
518540 if (sector .bank == 0 ) {
519541
520542 LOG_ERR ("Offset %ld does not exist" , (long )offset );
@@ -539,7 +561,7 @@ static int erase_sector(const struct device *dev, int offset)
539561
540562 rc = flash_stm32_wait_flash_idle (dev );
541563 * (sector .cr ) &= ~(FLASH_CR_SER | FLASH_CR_SNB );
542-
564+ #endif
543565 return rc ;
544566}
545567
@@ -557,6 +579,7 @@ int flash_stm32_block_erase_loop(const struct device *dev, unsigned int offset,
557579 return rc ;
558580}
559581
582+ #if !defined(CONFIG_FLASH_STM32_ASYNC )
560583static int wait_write_queue (const struct flash_stm32_sector_t * sector )
561584{
562585 int64_t timeout_time = k_uptime_get () + 100 ;
@@ -570,11 +593,32 @@ static int wait_write_queue(const struct flash_stm32_sector_t *sector)
570593
571594 return 0 ;
572595}
596+ #endif /* !CONFIG_FLASH_STM32_ASYNC */
573597
574598static int write_ndwords (const struct device * dev , off_t offset , const uint64_t * data , uint8_t n )
575599{
600+ int rc = 0 ;
601+ #if defined(CONFIG_FLASH_STM32_ASYNC )
602+ for (size_t i = 0 ; i < n ; i += FLASH_NB_32BITWORD_IN_FLASHWORD ) {
603+ FLASH_STM32_PRIV (dev )-> async_complete = false;
604+ FLASH_STM32_PRIV (dev )-> async_error = false;
605+ uint32_t wordAddr = (uint32_t )& data [i ];
606+
607+ HAL_FLASH_Program_IT (FLASH_TYPEPROGRAM_FLASHWORD ,
608+ offset + FLASH_STM32_BASE_ADDRESS , wordAddr );
609+ k_sem_take (& FLASH_STM32_PRIV (dev )-> async_sem , K_FOREVER );
610+ if (FLASH_STM32_PRIV (dev )-> async_complete ) {
611+ LOG_DBG ("Flash write successful. Wrote %u bytes to 0x%x" ,
612+ FLASH_STM32_WRITE_BLOCK_SIZE , FLASH_STM32_PRIV (dev )-> async_ret );
613+ } else {
614+ if (FLASH_STM32_PRIV (dev )-> async_error ) {
615+ LOG_ERR ("Flash write failed %d" , FLASH_STM32_PRIV (dev )-> async_ret );
616+ }
617+ rc = - EIO ;
618+ }
619+ }
620+ #else
576621 volatile uint64_t * flash = (uint64_t * )(offset + FLASH_STM32_BASE_ADDRESS );
577- int rc ;
578622 int i ;
579623 struct flash_stm32_sector_t sector = get_sector (dev , offset );
580624
@@ -623,7 +667,7 @@ static int write_ndwords(const struct device *dev, off_t offset, const uint64_t
623667
624668 /* Clear the PG bit */
625669 * (sector .cr ) &= (~FLASH_CR_PG );
626-
670+ #endif
627671 return rc ;
628672}
629673
@@ -812,6 +856,10 @@ static int flash_stm32h7_read(const struct device *dev, off_t offset, void *data
812856
813857 LOG_DBG ("Read offset: %ld, len: %zu" , (long )offset , len );
814858
859+ #if defined(CONFIG_FLASH_STM32_ASYNC )
860+ k_sem_take (& FLASH_STM32_PRIV (dev )-> async_sem , K_FOREVER );
861+ #endif /* CONFIG_FLASH_STM32_ASYNC */
862+
815863 /* During the read we mask bus errors and only allow NMI.
816864 *
817865 * If the flash has a double ECC error then there is normally
@@ -832,6 +880,10 @@ static int flash_stm32h7_read(const struct device *dev, off_t offset, void *data
832880 barrier_isync_fence_full ();
833881 irq_unlock (irq_lock_key );
834882
883+ #if defined(CONFIG_FLASH_STM32_ASYNC )
884+ k_sem_give (& FLASH_STM32_PRIV (dev )-> async_sem );
885+ #endif /* CONFIG_FLASH_STM32_ASYNC */
886+
835887 return flash_stm32_check_status (dev );
836888}
837889
@@ -927,6 +979,31 @@ static DEVICE_API(flash, flash_stm32h7_api) = {
927979#endif
928980};
929981
982+ #if defined(CONFIG_FLASH_STM32_ASYNC )
983+ static struct flash_stm32_priv * flash_dev ;
984+
985+ /* IRQ handler function for async flash mode */
986+ void flash_stm32_irq_handler (void )
987+ {
988+ HAL_FLASH_IRQHandler ();
989+ if (flash_dev -> async_complete || flash_dev -> async_error ) {
990+ k_sem_give (& flash_dev -> async_sem );
991+ }
992+ }
993+
994+ /* cube hal functions for end of a async flash operation */
995+ void HAL_FLASH_EndOfOperationCallback (uint32_t op_ret_val )
996+ {
997+ flash_dev -> async_complete = true;
998+ flash_dev -> async_ret = op_ret_val ;
999+ }
1000+ void HAL_FLASH_OperationErrorCallback (uint32_t op_ret_val )
1001+ {
1002+ flash_dev -> async_error = true;
1003+ flash_dev -> async_ret = op_ret_val ;
1004+ }
1005+ #endif /* CONFIG_FLASH_STM32_ASYNC */
1006+
9301007static int stm32h7_flash_init (const struct device * dev )
9311008{
9321009#if DT_NODE_HAS_PROP (DT_INST (0 , st_stm32h7_flash_controller ), clocks )
@@ -946,6 +1023,12 @@ static int stm32h7_flash_init(const struct device *dev)
9461023 }
9471024#endif
9481025 flash_stm32_sem_init (dev );
1026+ #if defined(CONFIG_FLASH_STM32_ASYNC )
1027+ flash_dev = FLASH_STM32_PRIV (dev );
1028+ flash_stm32_async_sem_init (dev );
1029+ IRQ_CONNECT (FLASH_IRQn , 0 , flash_stm32_irq_handler , NULL , 0 );
1030+ irq_enable (FLASH_IRQn );
1031+ #endif /* CONFIG_FLASH_STM32_ASYNC */
9491032
9501033 LOG_DBG ("Flash initialized. BS: %zu" , flash_stm32h7_parameters .write_block_size );
9511034
0 commit comments