.
ROMSLOT_LPC1768.cpp@2:ecbff7f1e453, 2016-04-09 (annotated)
- Committer:
- va009039
- Date:
- Sat Apr 09 15:30:12 2016 +0900
- Revision:
- 2:ecbff7f1e453
- Parent:
- 1:dee9fae0c0c4
add Nucleo-F401RE.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 |
2:ecbff7f1e453 | 1 | // ROMSLOT_LPC1768.cpp 2016/4/9 |
va009039 |
1:dee9fae0c0c4 | 2 | #if defined(TARGET_LPC1768) |
va009039 |
1:dee9fae0c0c4 | 3 | #include "ROMSLOT.h" |
va009039 |
1:dee9fae0c0c4 | 4 | |
va009039 |
2:ecbff7f1e453 | 5 | static const uint32_t FLASH_SECTOR_BASE = 0x10000; |
va009039 |
2:ecbff7f1e453 | 6 | static const uint32_t FLASH_SECTOR_SIZE = 0x8000; // 32 Kbytes |
va009039 |
2:ecbff7f1e453 | 7 | |
va009039 |
1:dee9fae0c0c4 | 8 | #if defined(IAP_DEBUG) |
va009039 |
1:dee9fae0c0c4 | 9 | #define IAP_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");} while(0) |
va009039 |
1:dee9fae0c0c4 | 10 | #else |
va009039 |
1:dee9fae0c0c4 | 11 | #define IAP_DBG(...) while(0) |
va009039 |
1:dee9fae0c0c4 | 12 | #endif |
va009039 |
1:dee9fae0c0c4 | 13 | #define IAP_ASSERT(A) MBED_ASSERT(A) |
va009039 |
1:dee9fae0c0c4 | 14 | |
va009039 |
1:dee9fae0c0c4 | 15 | #define IAP_LOCATION 0x1fff1ff1 |
va009039 |
1:dee9fae0c0c4 | 16 | typedef void (*IAP)(uint32_t* command, uint32_t* result); |
va009039 |
1:dee9fae0c0c4 | 17 | |
va009039 |
1:dee9fae0c0c4 | 18 | uint32_t iap(uint32_t cmd, uint32_t p0 = 0, uint32_t p1 = 0, uint32_t p2 = 0, uint32_t p3 = 0) { |
va009039 |
1:dee9fae0c0c4 | 19 | uint32_t command[5] = {cmd, p0, p1, p2, p3}; |
va009039 |
1:dee9fae0c0c4 | 20 | uint32_t result[4]; |
va009039 |
1:dee9fae0c0c4 | 21 | IAP iap_entry = (IAP)IAP_LOCATION; |
va009039 |
1:dee9fae0c0c4 | 22 | IAP_DBG("command: %x %x %x %x %x\n", command[0], command[1], command[2], command[3], command[4]); |
va009039 |
1:dee9fae0c0c4 | 23 | iap_entry(command, result); |
va009039 |
1:dee9fae0c0c4 | 24 | IAP_DBG("result: %x %x %x %x\n", result[0], result[1], result[2], result[3]); |
va009039 |
1:dee9fae0c0c4 | 25 | return result[0]; |
va009039 |
1:dee9fae0c0c4 | 26 | } |
va009039 |
1:dee9fae0c0c4 | 27 | |
va009039 |
2:ecbff7f1e453 | 28 | ROMSLOT::ROMSLOT() { |
va009039 |
2:ecbff7f1e453 | 29 | base = FLASH_SECTOR_BASE; |
va009039 |
2:ecbff7f1e453 | 30 | } |
va009039 |
2:ecbff7f1e453 | 31 | |
va009039 |
2:ecbff7f1e453 | 32 | uint32_t ROMSLOT::New(uint32_t size) { |
va009039 |
2:ecbff7f1e453 | 33 | uint32_t addr = base; |
va009039 |
2:ecbff7f1e453 | 34 | base += (size + FLASH_SECTOR_SIZE - 1) / FLASH_SECTOR_SIZE * FLASH_SECTOR_SIZE; |
va009039 |
2:ecbff7f1e453 | 35 | return addr; |
va009039 |
2:ecbff7f1e453 | 36 | } |
va009039 |
2:ecbff7f1e453 | 37 | |
va009039 |
2:ecbff7f1e453 | 38 | static bool is_base(uint32_t addr) { |
va009039 |
2:ecbff7f1e453 | 39 | return addr % FLASH_SECTOR_SIZE == 0; |
va009039 |
2:ecbff7f1e453 | 40 | } |
va009039 |
2:ecbff7f1e453 | 41 | |
va009039 |
2:ecbff7f1e453 | 42 | static uint32_t sector(uint32_t addr) { |
va009039 |
2:ecbff7f1e453 | 43 | MBED_ASSERT(addr >= FLASH_SECTOR_BASE); |
va009039 |
2:ecbff7f1e453 | 44 | uint32_t s = (addr - FLASH_SECTOR_BASE) / FLASH_SECTOR_SIZE + 16; |
va009039 |
2:ecbff7f1e453 | 45 | return s; |
va009039 |
2:ecbff7f1e453 | 46 | } |
va009039 |
2:ecbff7f1e453 | 47 | |
va009039 |
1:dee9fae0c0c4 | 48 | bool ROMSLOT::Write(uint32_t addr, const uint8_t buf[], uint32_t size) { |
va009039 |
1:dee9fae0c0c4 | 49 | IAP_ASSERT(addr%256 == 0); |
va009039 |
1:dee9fae0c0c4 | 50 | IAP_ASSERT(size == 256); |
va009039 |
1:dee9fae0c0c4 | 51 | if (memcmp((uint8_t*)addr, buf, size) == 0) { // skip ? |
va009039 |
1:dee9fae0c0c4 | 52 | return true; |
va009039 |
1:dee9fae0c0c4 | 53 | } |
va009039 |
1:dee9fae0c0c4 | 54 | uint8_t temp[256]; |
va009039 |
1:dee9fae0c0c4 | 55 | memcpy(temp, buf, sizeof(temp)); |
va009039 |
1:dee9fae0c0c4 | 56 | IAP_ASSERT(addr >= 0x10000); |
va009039 |
2:ecbff7f1e453 | 57 | uint32_t sectorNo = sector(addr); |
va009039 |
2:ecbff7f1e453 | 58 | IAP_ASSERT(sectorNo >= 16); |
va009039 |
1:dee9fae0c0c4 | 59 | uint32_t cclk = SystemCoreClock / 1000; |
va009039 |
2:ecbff7f1e453 | 60 | if (is_base(addr)) { |
va009039 |
2:ecbff7f1e453 | 61 | if (iap(50, sectorNo, sectorNo) != 0) { // prepare |
va009039 |
1:dee9fae0c0c4 | 62 | return false; |
va009039 |
1:dee9fae0c0c4 | 63 | } |
va009039 |
2:ecbff7f1e453 | 64 | if (iap(52, sectorNo, sectorNo, cclk) != 0) { // erase |
va009039 |
1:dee9fae0c0c4 | 65 | return false; |
va009039 |
1:dee9fae0c0c4 | 66 | } |
va009039 |
1:dee9fae0c0c4 | 67 | } |
va009039 |
2:ecbff7f1e453 | 68 | if (iap(50, sectorNo, sectorNo) != 0) { // prepare |
va009039 |
1:dee9fae0c0c4 | 69 | return false; |
va009039 |
1:dee9fae0c0c4 | 70 | } |
va009039 |
2:ecbff7f1e453 | 71 | if (iap(51, addr, (uint32_t)temp, size, cclk) != 0) { // Copy RAM to flash |
va009039 |
1:dee9fae0c0c4 | 72 | return false; |
va009039 |
1:dee9fae0c0c4 | 73 | } |
va009039 |
2:ecbff7f1e453 | 74 | if (iap(56, addr, (uint32_t)temp, size) != 0) { // Compare |
va009039 |
1:dee9fae0c0c4 | 75 | return false; |
va009039 |
1:dee9fae0c0c4 | 76 | } |
va009039 |
1:dee9fae0c0c4 | 77 | return true; |
va009039 |
1:dee9fae0c0c4 | 78 | } |
va009039 |
1:dee9fae0c0c4 | 79 | #endif // TARGET_LPC1768 |
va009039 |
1:dee9fae0c0c4 | 80 |