2626
2727#include "imp.h"
2828#include <helper/binarybuffer.h>
29+ #include <helper/time_support.h>
2930#include <target/algorithm.h>
3031#include <target/armv7m.h>
3132#include <target/cortex_m.h>
3233
3334#define EFM_FAMILY_ID_GIANT_GECKO 72
3435#define EFM_FAMILY_ID_LEOPARD_GECKO 74
3536
36- #define EFM32_FLASH_ERASE_TMO 100
37- #define EFM32_FLASH_WDATAREADY_TMO 100
38- #define EFM32_FLASH_WRITE_TMO 100
37+ /* Datasheet specifies ~22ms for page erase on first chip generation. 100ms
38+ * provides reasonable margin.
39+ */
40+ #define EFM32_FLASH_OPERATION_TIMEOUT 100
3941
4042#define EFM32_FLASH_BASE 0
4143
@@ -420,25 +422,25 @@ static int efm32_msc_lock(struct flash_bank *bank, int lock)
420422 (lock ? 0 : EFM32_MSC_LOCK_LOCKKEY ));
421423}
422424
423- static int efm32_wait_status (struct flash_bank * bank , int timeout ,
424- uint32_t wait_mask , int wait_for_set )
425+ static int efm32_wait_status (struct flash_bank * bank , int timeout_ms ,
426+ uint32_t wait_mask , bool wait_for_set )
425427{
426- int ret = 0 ;
428+ int64_t start_ms = timeval_ms () ;
427429 uint32_t status = 0 ;
428430
429431 while (1 ) {
430- ret = efm32_read_reg_u32 (bank , EFM32_MSC_REG_STATUS , & status );
432+ int ret = efm32_read_reg_u32 (bank , EFM32_MSC_REG_STATUS , & status );
431433 if (ret != ERROR_OK )
432- break ;
434+ return ret ;
433435
434436 LOG_DEBUG ("status: 0x%" PRIx32 , status );
435437
436- if ((status & wait_mask ) == 0 && wait_for_set == 0 )
438+ if (! (status & wait_mask ) && ! wait_for_set )
437439 break ;
438- else if ((status & wait_mask ) != 0 && wait_for_set )
440+ if ((status & wait_mask ) && wait_for_set )
439441 break ;
440442
441- if (timeout -- <= 0 ) {
443+ if (timeval_ms () - start_ms > timeout_ms ) {
442444 LOG_ERROR ("timed out waiting for MSC status" );
443445 return ERROR_FAIL ;
444446 }
@@ -449,7 +451,7 @@ static int efm32_wait_status(struct flash_bank *bank, int timeout,
449451 if (status & EFM32_MSC_STATUS_ERASEABORTED_MASK )
450452 LOG_WARNING ("page erase was aborted" );
451453
452- return ret ;
454+ return ERROR_OK ;
453455}
454456
455457static int efm32_erase_page (struct flash_bank * bank , uint32_t addr )
@@ -494,8 +496,8 @@ static int efm32_erase_page(struct flash_bank *bank, uint32_t addr)
494496 if (ret != ERROR_OK )
495497 return ret ;
496498
497- return efm32_wait_status (bank , EFM32_FLASH_ERASE_TMO ,
498- EFM32_MSC_STATUS_BUSY_MASK , 0 );
499+ return efm32_wait_status (bank , EFM32_FLASH_OPERATION_TIMEOUT ,
500+ EFM32_MSC_STATUS_BUSY_MASK , false );
499501}
500502
501503static int efm32_erase (struct flash_bank * bank , unsigned int first ,
@@ -939,8 +941,8 @@ static int efm32_write_word(struct flash_bank *bank, uint32_t addr,
939941 return ERROR_FAIL ;
940942 }
941943
942- ret = efm32_wait_status (bank , EFM32_FLASH_WDATAREADY_TMO ,
943- EFM32_MSC_STATUS_WDATAREADY_MASK , 1 );
944+ ret = efm32_wait_status (bank , EFM32_FLASH_OPERATION_TIMEOUT ,
945+ EFM32_MSC_STATUS_WDATAREADY_MASK , true );
944946 if (ret != ERROR_OK ) {
945947 LOG_ERROR ("Wait for WDATAREADY failed" );
946948 return ret ;
@@ -959,8 +961,8 @@ static int efm32_write_word(struct flash_bank *bank, uint32_t addr,
959961 return ret ;
960962 }
961963
962- ret = efm32_wait_status (bank , EFM32_FLASH_WRITE_TMO ,
963- EFM32_MSC_STATUS_BUSY_MASK , 0 );
964+ ret = efm32_wait_status (bank , EFM32_FLASH_OPERATION_TIMEOUT ,
965+ EFM32_MSC_STATUS_BUSY_MASK , false );
964966 if (ret != ERROR_OK ) {
965967 LOG_ERROR ("Wait for BUSY failed" );
966968 return ret ;
0 commit comments