This is the mail archive of the
ecos-patches@sourceware.org
mailing list for the eCos project.
STM32 flash driver fixes
- From: Simon Kallweit <simon dot kallweit at intefo dot ch>
- To: eCos Patches List <ecos-patches at ecos dot sourceware dot org>
- Date: Mon, 06 Apr 2009 11:15:31 +0200
- Subject: 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;
}