void main(){ int i; uint16 data0 = 0x0000; uint16 data1 = 0x1000; uint16 data2 = 0x2000; uint16 data3 = 0x3000; uint16 data4 = 0x1000; uint16 data5 = 0x5000; uint32 address = 0x000000; uint16 blockRead[32]; uint16 blockWrite0[16]; uint16 blockWrite1[16]; uint16 blockWrite2[16]; uint16 blockWrite3[16]; uint16 blockWrite5[64]; uint16 incomingData[4]; for(i = 0 ; i < 16 ; i++){ blockWrite0[i] = data0; data0++; } for(i = 0 ; i < 16 ; i++){ blockWrite1[i] = data1; data1++; } for(i = 0 ; i < 16 ; i++){ blockWrite2[i] = data2; data2++; } for(i = 0 ; i < 16 ; i++){ blockWrite3[i] = data3; data3++; } for(i = 0 ; i < 64 ; i++){ blockWrite5[i] = data5; data5++; } trisInit(); enter_HVP(); bulkErase(); enableWrite(); flashWriteBlock(blockWrite0, blockWrite1, 1); flashWriteBlock(blockWrite2, blockWrite3, 2); flashReadBlock(blockRead, 64, 1); flashReadBlock(blockRead, 64, 2); flashWriteData(blockWrite5, 64, 0); flashReadBlock(blockRead, 64, 1); flashReadBlock(blockRead, 64, 2); exit_HVP(); while(1){} }
int flashWrite(flashaddr_t address, const char* buffer, size_t size) { /* Unlock flash for write access */ if (flashUnlock() == CH_FAILED) return FLASH_RETURN_NO_PERMISSION; /* Wait for any busy flags */ flashWaitWhileBusy(); /* Setup parallelism before any program/erase */ FLASH->CR &= ~FLASH_CR_PSIZE_MASK; FLASH->CR |= FLASH_CR_PSIZE_VALUE; /* Check if the flash address is correctly aligned */ size_t alignOffset = address % sizeof(flashdata_t); // print("flash alignOffset=%d\r\n", alignOffset); if (alignOffset != 0) { /* Not aligned, thus we have to read the data in flash already present * and update them with buffer's data */ /* Align the flash address correctly */ flashaddr_t alignedFlashAddress = address - alignOffset; /* Read already present data */ flashdata_t tmp = *(volatile flashdata_t*) alignedFlashAddress; /* Compute how much bytes one must update in the data read */ size_t chunkSize = sizeof(flashdata_t) - alignOffset; if (chunkSize > size) chunkSize = size; // this happens when both address and address + size are not aligned /* Update the read data with buffer's data */ memcpy((char*) &tmp + alignOffset, buffer, chunkSize); /* Write the new data in flash */ flashWriteData(alignedFlashAddress, tmp); /* Advance */ address += chunkSize; buffer += chunkSize; size -= chunkSize; } /* Now, address is correctly aligned. One can copy data directly from * buffer's data to flash memory until the size of the data remaining to be * copied requires special treatment. */ while (size >= sizeof(flashdata_t)) { // print("flash write size=%d\r\n", size); flashWriteData(address, *(const flashdata_t*) buffer); address += sizeof(flashdata_t); buffer += sizeof(flashdata_t); size -= sizeof(flashdata_t); } /* Now, address is correctly aligned, but the remaining data are to * small to fill a entier flashdata_t. Thus, one must read data already * in flash and update them with buffer's data before writing an entire * flashdata_t to flash memory. */ if (size > 0) { flashdata_t tmp = *(volatile flashdata_t*) address; memcpy(&tmp, buffer, size); flashWriteData(address, tmp); } /* Lock flash again */ flashLock() ; return FLASH_RETURN_SUCCESS; }