/** Program pages starting at defined address * * The pages should not cross multiple sectors. * This function does not do any check for address alignments or if size is aligned to a page size. * @param obj The flash object * @param address The sector starting address * @param data The data buffer to be programmed * @param size The number of bytes to program * @return 0 for success, -1 for error */ int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size) { uint32_t *p_data; p_data = (uint32_t *)data; uint32_t num = 0; int32_t flash_state = 0; flash_unlock(); /* clear FLASH flag */ fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR); if (size % 4) { num = size / 4 + 1; } else { num = size / 4; } for (uint32_t i = 0; i < num; i++) { if (FMC_READY != fmc_word_program(address, *(p_data + i))) { flash_state = -1; break; } address += 4; } flash_lock(); return flash_state; }
/*! \brief write data to sectors of memory \param[in] data: data to be written \param[in] addr: sector address/code \param[in] len: length of data to be written (in bytes) \param[out] none \retval MAL_OK if all operations are OK, MAL_FAIL else */ static void iap_data_write (uint8_t *data, uint32_t addr, uint32_t len) { uint32_t idx = 0; /* check if the address is in protected area */ if (IS_PROTECTED_AREA(addr)) { return; } if (len & 0x03) {/* not an aligned data */ for (idx = len; idx < ((len & 0xFFFC) + 4); idx++) { data[idx] = 0xFF; } } /* data received are word multiple */ for (idx = 0; idx < len; idx += 4) { fmc_word_program(addr, *(uint32_t *)(data + idx)); addr += 4; } }