uint16_t flags[VROM_SECT_APP_BLOCK_CNT];
};
+#define VROM_SFLAGS_USED (1 << 0) /*!< Block in use */
+
/*!
* Return the address of a virtual EEPROM sector header.
*/
static const struct vrom_data_block_t* vrom_get_block(
uint8_t sector, uint8_t block)
{
- const void* sector_hdr = (const void*)
- vrom_get_sector_hdr(sector);
return (const struct vrom_data_block_t*)(
- sector_hdr + (VROM_BLOCK_SZ
- * ((block % VROM_SECT_APP_BLOCK_CNT)+1)));
+ (void*)vrom_get_sector_hdr(sector)
+ + (VROM_BLOCK_SZ * (block + 1)));
}
/*!
/* This sector has been formatted before */
cycles_remain = sector->cycles_remain - 1;
- if (FLASH_EraseSector(sector_num, VoltageRange_3))
+ if (FLASH_EraseSector(sector_num + 1, VoltageRange_3))
/* Erase failed */
return -EIO;
}
}
/*!
- * Mark a block as being obsolete
+ * Set flags for a block
*/
-static int vrom_mark_obsolete(const struct vrom_data_block_t* block)
+static int vrom_set_flags(const struct vrom_data_block_t* block,
+ uint16_t flags)
{
const struct vrom_sector_idx_t* sector =
vrom_get_sector_hdr(vrom_sector_num(block));
uint8_t block_num = vrom_block_num(block);
+ /* Compute the new flags settings */
+ flags = sector->flags[block_num] & ~flags;
+
+ /* Write them */
+ if (FLASH_ProgramHalfWord(
+ (uint32_t)(&(sector->flags[block_num])),
+ flags) != FLASH_COMPLETE)
+ return -EIO;
+ return 0;
+}
+
+/*!
+ * Mark a block as being obsolete
+ */
+static int vrom_mark_obsolete(const struct vrom_data_block_t* block)
+{
/* Blank out the CRC */
if (FLASH_ProgramWord((uint32_t)(&(block->header.crc32)), 0)
!= FLASH_COMPLETE)
!= FLASH_COMPLETE)
return -EIO;
/* Blank out the flags */
- if (FLASH_ProgramHalfWord(
- (uint32_t)(&(sector->flags[block_num])), 0)
- != FLASH_COMPLETE)
- return -EIO;
- return 0;
+ return vrom_set_flags(block, -1);
}
/*!
/* Find a new home for the block */
const struct vrom_data_block_t* block = vrom_find_free(0);
struct vrom_data_block_t new_block;
- uint8_t* out = (uint8_t*)(&block);
+ uint8_t* out = (uint8_t*)(block);
uint32_t rem = sizeof(new_block);
+ int res;
+
+ if (!block)
+ return -ENOSPC;
/* Prepare the new block */
memset(&new_block, 0xff, sizeof(new_block));
/* Start writing out the block */
in = (uint8_t*)(&new_block);
+ rem = VROM_BLOCK_SZ;
while(rem) {
- if (*in != *out) {
+ if (*out != *in) {
if (FLASH_ProgramByte((uint32_t)out, *in)
!= FLASH_COMPLETE)
/* Failed! */
out++;
rem--;
}
+ res = vrom_set_flags(block, VROM_SFLAGS_USED);
+ if (res < 0)
+ return res;
return size;
}
{
int res;
FLASH_Unlock();
+ FLASH_ClearFlag(FLASH_FLAG_EOP
+ | FLASH_FLAG_OPERR
+ | FLASH_FLAG_WRPERR
+ | FLASH_FLAG_PGAERR
+ | FLASH_FLAG_PGPERR
+ | FLASH_FLAG_PGSERR);
res = vrom_write_internal(rom, offset, size, in);
FLASH_Lock();
return res;
{
int sector, block;
FLASH_Unlock();
-
+ FLASH_ClearFlag(FLASH_FLAG_EOP
+ | FLASH_FLAG_OPERR
+ | FLASH_FLAG_WRPERR
+ | FLASH_FLAG_PGAERR
+ | FLASH_FLAG_PGPERR
+ | FLASH_FLAG_PGSERR);
for (sector = 0; sector < VROM_SECT_CNT; sector++) {
const struct vrom_sector_idx_t* sect_hdr
= vrom_get_sector_hdr(sector);