This is the mail archive of the ecos-patches@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

STM32 flash driver fixes


Fixes two bugs in the STM32 flash driver. stm32_flash_get_block_info() now computes correct block base address. HSI is enabled for flash erase/program as stated in the manual. Also done some cleanup.

Simon

diff --git a/packages/devs/flash/cortexm/stm32/current/ChangeLog b/packages/devs/flash/cortexm/stm32/current/ChangeLog
index 4586fa3..819faf2 100644
--- a/packages/devs/flash/cortexm/stm32/current/ChangeLog
+++ b/packages/devs/flash/cortexm/stm32/current/ChangeLog
@@ -1,3 +1,10 @@
+2009-04-06  Simon Kallweit  <simon.kallweit@intefo.ch>
+
+	* src/stm32_flash.c:
+	stm32_flash_get_block_info() now computes correct block base
+	address. HSI is enabled for flash erase/program as stated in the
+	manual. Some cleanup.
+
 2008-12-19  Simon Kallweit  <simon.kallweit@intefo.ch>
 
 	* src/stm32_flash.c:
diff --git a/packages/devs/flash/cortexm/stm32/current/src/stm32_flash.c b/packages/devs/flash/cortexm/stm32/current/src/stm32_flash.c
index 2412fd1..d427674 100644
--- a/packages/devs/flash/cortexm/stm32/current/src/stm32_flash.c
+++ b/packages/devs/flash/cortexm/stm32/current/src/stm32_flash.c
@@ -83,6 +83,8 @@ typedef cyg_uint16 STM32_TYPE;
 // ----------------------------------------------------------------------------
 // Forward declarations for functions that need to be placed in RAM:
 
+static int stm32_enable_hsi(void);
+static void stm32_disable_hsi(void);
 static int stm32_flash_hw_erase(cyg_flashaddr_t addr) __attribute__((section (".2ram.stm32_flash_hw_erase")));
 static int stm32_flash_hw_program( volatile STM32_TYPE* addr, const cyg_uint16* buf, cyg_uint32 count) __attribute__((section (".2ram.stm32_flash_hw_program")));
     
@@ -180,13 +182,14 @@ stm32_flash_get_block_info(struct cyg_flash_dev* dev, const cyg_flashaddr_t addr
 {
     size_t          offset  = addr - dev->start;
     
-    *block_start    = dev->start + (offset & (dev->block_info[0].block_size-1));
+    *block_start    = dev->start + (offset & ~(dev->block_info[0].block_size-1));
     *block_size     = dev->block_info[0].block_size;
 }
 
 // ----------------------------------------------------------------------------
 
-static int stm32_flash_decode_error( int sr )
+static int
+stm32_flash_decode_error( int sr )
 {
     int result = CYG_FLASH_ERR_OK;
 
@@ -199,6 +202,35 @@ static int stm32_flash_decode_error( int sr )
     return result;
 }
 
+static int
+stm32_enable_hsi(void)
+{
+    CYG_ADDRESS rcc = CYGHWR_HAL_STM32_RCC;
+    cyg_uint32 cr;
+    
+    HAL_READ_UINT32( rcc+CYGHWR_HAL_STM32_RCC_CR, cr );
+    if( cr & CYGHWR_HAL_STM32_RCC_CR_HSIRDY )
+        return 0;
+    
+    cr |= CYGHWR_HAL_STM32_RCC_CR_HSION;
+    HAL_WRITE_UINT32( rcc+CYGHWR_HAL_STM32_RCC_CR, cr );
+    while( cr & CYGHWR_HAL_STM32_RCC_CR_HSIRDY )
+        HAL_READ_UINT32( rcc+CYGHWR_HAL_STM32_RCC_CR, cr );
+    
+    return 1;
+}
+
+static void
+stm32_disable_hsi(void)
+{
+    CYG_ADDRESS rcc = CYGHWR_HAL_STM32_RCC;
+    cyg_uint32 cr;
+    
+    HAL_READ_UINT32( rcc+CYGHWR_HAL_STM32_RCC_CR, cr );
+    cr &= ~(CYGHWR_HAL_STM32_RCC_CR_HSION | CYGHWR_HAL_STM32_RCC_CR_HSIRDY);
+    HAL_WRITE_UINT32( rcc+CYGHWR_HAL_STM32_RCC_CR, cr );
+}
+
 // ----------------------------------------------------------------------------
 // Erase a single sector. There is no API support for chip-erase. The
 // generic code operates one sector at a time, invoking the driver for
@@ -246,8 +278,6 @@ stm32_flash_hw_program( volatile STM32_TYPE* addr, const cyg_uint16* buf, cyg_ui
     cr |= CYGHWR_HAL_STM32_FLASH_CR_PG;
     HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_CR, cr );
 
-    stf_diag("cr %08x\n", cr );
-    
     while( count-- )
     {
         cyg_uint32 timeout = 100000;
@@ -260,14 +290,11 @@ stm32_flash_hw_program( volatile STM32_TYPE* addr, const cyg_uint16* buf, cyg_ui
         do
         {
             HAL_READ_UINT32( base+CYGHWR_HAL_STM32_FLASH_SR, sr );
-//            stf_diag("sr %08x\n", sr );
         } while( (sr & CYGHWR_HAL_STM32_FLASH_SR_BSY) && timeout-- > 0 );
     }
 
     HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_CR, 0 );
 
-    stf_diag("cr %08x sr %08x\n", cr, sr );
-    
     return sr;    
 }
 
@@ -279,22 +306,24 @@ static int
 stm32_flash_erase(struct cyg_flash_dev* dev, cyg_flashaddr_t dest)
 {
     int                     (*erase_fn)(cyg_uint32);
-    volatile STM32_TYPE*    uncached;
     cyg_flashaddr_t         block_start;
     size_t                  block_size;
     int                     result;
+    int                     hsi;
     STM32_INTSCACHE_STATE;
 
-    stf_diag("dest %p\n", dest);
+    stf_diag("dest %p\n", (void *) dest);
     CYG_CHECK_DATA_PTR(dev, "valid flash device pointer required");
     CYG_ASSERT((dest >= dev->start) && (dest <= dev->end), "flash address out of device range");
-
+    
     stm32_flash_get_block_info(dev, dest, &block_start, &block_size);
+    stf_diag("block_start %p block_size %d\n", (void *) block_start, block_size);
     CYG_ASSERT(dest == block_start, "erase address should be the start of a flash block");
 
-    uncached    = STM32_UNCACHED_ADDRESS(dest);
     erase_fn    = (int (*)(cyg_uint32)) cyg_flash_anonymizer( & stm32_flash_hw_erase );
-
+    
+    hsi = stm32_enable_hsi();
+    
     STM32_INTSCACHE_BEGIN();    
 
     result = (*erase_fn)(block_start);
@@ -302,6 +331,9 @@ stm32_flash_erase(struct cyg_flash_dev* dev, cyg_flashaddr_t dest)
     
     STM32_INTSCACHE_END();
     
+    if (hsi)
+        stm32_disable_hsi();
+    
     return result;
 }
 
@@ -318,10 +350,11 @@ stm32_flash_program(struct cyg_flash_dev* dev, cyg_flashaddr_t dest, const void*
     const cyg_uint16*       data;
     size_t                  to_write;
     int                     result  = CYG_FLASH_ERR_OK;
+    int                     hsi;
 
     STM32_INTSCACHE_STATE;
 
-    stf_diag("dest %p src %p len %p(%d)\n", dest, src, len, len);
+    stf_diag("dest %p src %p len %p(%d)\n", (void *) dest, src, (void *) len, len);
     CYG_CHECK_DATA_PTR(dev, "valid flash device pointer required");
     CYG_ASSERT((dest >= dev->start) && ((CYG_ADDRESS)dest <= dev->end), "flash address out of device range");
 
@@ -335,6 +368,8 @@ stm32_flash_program(struct cyg_flash_dev* dev, cyg_flashaddr_t dest, const void*
     to_write    = len / sizeof(STM32_TYPE);      // Number of words, not bytes
     program_fn  = (int (*)(volatile STM32_TYPE*, const cyg_uint16*, cyg_uint32)) cyg_flash_anonymizer( & stm32_flash_hw_program );
 
+    hsi = stm32_enable_hsi();
+
     STM32_INTSCACHE_BEGIN();
     while (to_write > 0)
     {
@@ -359,6 +394,10 @@ stm32_flash_program(struct cyg_flash_dev* dev, cyg_flashaddr_t dest, const void*
         }
     }
     STM32_INTSCACHE_END();
+    
+    if (hsi)
+        stm32_disable_hsi();
+    
     return result;
 }
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]