write some data to virtual EEPROM
| 175 | |
| 176 | // write some data to virtual EEPROM |
| 177 | bool AP_FlashStorage::write(uint16_t offset, uint16_t length) |
| 178 | { |
| 179 | if (write_error) { |
| 180 | return false; |
| 181 | } |
| 182 | //debug("write at %u for %u write_offset=%u\n", offset, length, write_offset); |
| 183 | |
| 184 | while (length > 0) { |
| 185 | uint8_t n = max_write; |
| 186 | #if AP_FLASHSTORAGE_TYPE != AP_FLASHSTORAGE_TYPE_H7 && AP_FLASHSTORAGE_TYPE != AP_FLASHSTORAGE_TYPE_G4 |
| 187 | if (length < n) { |
| 188 | n = length; |
| 189 | } |
| 190 | #endif |
| 191 | |
| 192 | const uint32_t space_available = flash_sector_size - write_offset; |
| 193 | const uint32_t space_required = sizeof(struct block_header) + max_write + reserved_space; |
| 194 | if (space_available < space_required) { |
| 195 | if (!switch_sectors()) { |
| 196 | if (!flash_erase_ok()) { |
| 197 | return false; |
| 198 | } |
| 199 | if (!switch_full_sector()) { |
| 200 | return false; |
| 201 | } |
| 202 | } |
| 203 | } |
| 204 | |
| 205 | struct PACKED { |
| 206 | struct block_header header; |
| 207 | uint8_t data[max_write]; |
| 208 | } blk; |
| 209 | |
| 210 | blk.header.state = BLOCK_STATE_WRITING; |
| 211 | blk.header.block_num = offset / block_size; |
| 212 | blk.header.num_blocks_minus_one = ((n + (block_size - 1)) / block_size)-1; |
| 213 | |
| 214 | uint16_t block_ofs = blk.header.block_num*block_size; |
| 215 | uint16_t block_nbytes = (blk.header.num_blocks_minus_one+1)*block_size; |
| 216 | |
| 217 | memcpy(blk.data, &mem_buffer[block_ofs], block_nbytes); |
| 218 | |
| 219 | #if AP_FLASHSTORAGE_TYPE == AP_FLASHSTORAGE_TYPE_F4 |
| 220 | if (!flash_write(current_sector, write_offset, (uint8_t*)&blk.header, sizeof(blk.header))) { |
| 221 | return false; |
| 222 | } |
| 223 | if (!flash_write(current_sector, write_offset+sizeof(blk.header), blk.data, block_nbytes)) { |
| 224 | return false; |
| 225 | } |
| 226 | blk.header.state = BLOCK_STATE_VALID; |
| 227 | if (!flash_write(current_sector, write_offset, (uint8_t*)&blk.header, sizeof(blk.header))) { |
| 228 | return false; |
| 229 | } |
| 230 | #elif AP_FLASHSTORAGE_TYPE == AP_FLASHSTORAGE_TYPE_F1 |
| 231 | blk.header.state = BLOCK_STATE_VALID; |
| 232 | if (!flash_write(current_sector, write_offset, (uint8_t*)&blk, sizeof(blk.header) + block_nbytes)) { |
| 233 | return false; |
| 234 | } |