/** * Write data to eeprom * @param addr The eeprom memory address * @param buf It is the buffer of bytes that will be written to the eeprom * @param size It is the number of byte to write */ void eeprom_write(eeprom_addr_t addr, unsigned char *buf, int size) { unsigned int i = 0; unsigned int curaddr; curaddr = addr; for(i = 0; i < size; i++) { /* If we are writing the first byte or are on a EE_PAGEMASK page boundary we have to start a new write. */ if(i == 0 || (curaddr & EE_PAGEMASK) == 0) { i2c_start(); i2c_write(EE_HW_ADDRESS | 0x0); /* Write the new address to the bus. */ i2c_write((curaddr & 0xFF00) >> 8); i2c_write(curaddr & 0xFF); } /* Write byte. */ i2c_write(buf[i] & 0xFF); /* If we are writing the last byte totally or of a 32b page generate a stop condition */ if(i == size - 1 || (curaddr & EE_PAGEMASK) == EE_PAGEMASK) { i2c_stop(); eeprom_wait(); } curaddr++; }
void flashFirmware(uint8_t* source, uint32_t size){ __disable_irq(); // Disable ALL interrupts. Can only be executed in Privileged modes. setLed(RED); eeprom_unlock(); if(size > (16+16+64+128)*1024){ eeprom_erase_sector(FLASH_Sector_6); toggleLed(); // inline } if(size > (16+16+64)*1024){ eeprom_erase_sector(FLASH_Sector_5); toggleLed(); } if(size > (16+16)*1024){ eeprom_erase_sector(FLASH_Sector_4); toggleLed(); } if(size > 16*1024){ eeprom_erase_sector(FLASH_Sector_3); toggleLed(); } eeprom_erase_sector(FLASH_Sector_2); toggleLed(); eeprom_write_block(ADDR_FLASH_SECTOR_2, source, size); eeprom_lock(); eeprom_wait(); NVIC_SystemReset(); // (static inline) }
int eeprom_write_block(uint32_t address, void* data, uint32_t size){ volatile uint32_t* dest = (volatile uint32_t*)address; uint32_t* src = (uint32_t*)data; FLASH_Status status = eeprom_wait(); for(uint32_t i=0; i<size && status == FLASH_COMPLETE; i+=4){ /* when the previous operation is completed, proceed to program the new data */ FLASH->CR &= CR_PSIZE_MASK; FLASH->CR |= FLASH_PSIZE_WORD; FLASH->CR |= FLASH_CR_PG; *dest++ = *src++; /* Wait for last operation to be completed */ status = eeprom_wait(); /* if the program operation is completed, disable the PG Bit */ FLASH->CR &= (~FLASH_CR_PG); /* Wait for last operation to be completed */ status = eeprom_wait(); } return status == FLASH_COMPLETE ? 0 : -1; }
int eeprom_erase_sector(uint32_t sector) { /* Wait for last operation to be completed */ FLASH_Status status = eeprom_wait(); if(status == FLASH_COMPLETE){ /* if the previous operation is completed, proceed to erase the sector */ FLASH->CR &= CR_PSIZE_MASK; FLASH->CR |= FLASH_PSIZE_WORD; FLASH->CR &= EEPROM_SECTOR_MASK; FLASH->CR |= FLASH_CR_SER | sector; FLASH->CR |= FLASH_CR_STRT; /* Wait for last operation to be completed */ status = eeprom_wait(); /* When the erase operation is completed, disable the SER Bit */ FLASH->CR &= (~FLASH_CR_SER); FLASH->CR &= EEPROM_SECTOR_MASK; /* Wait for last operation to be completed */ status = eeprom_wait(); } /* Return the Erase Status */ return status == FLASH_COMPLETE ? 0 : -1; }