USB composite device example program, drag-and-drop flash writer.

Dependencies:   SWD USBDevice mbed BaseDAP

Committer:
va009039
Date:
Sat Sep 28 03:21:14 2013 +0000
Revision:
1:ea8e179320d7
Parent:
0:2385683c867a
add USBMSD_Drop class. add CDC(Virtual COM) and HID(for example CMSIS-DAP), but KL25Z not work.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:2385683c867a 1 // Flash.cpp 2013/9/16
va009039 0:2385683c867a 2 #include "Flash.h"
va009039 0:2385683c867a 3 #include "Target2.h"
va009039 0:2385683c867a 4 #include "mydebug.h"
va009039 0:2385683c867a 5
va009039 0:2385683c867a 6 #define SYSMEMREMAP 0x40048000
va009039 0:2385683c867a 7 #define MAINCLKSEL 0x40048070
va009039 0:2385683c867a 8 #define MAINCLKUEN 0x40048074
va009039 0:2385683c867a 9 #define SYSAHBCLKDIV 0x40048078
va009039 0:2385683c867a 10
va009039 0:2385683c867a 11 Flash::Flash(Target2* target, Serial* usbpc) :_target(target),_pc(usbpc)
va009039 0:2385683c867a 12 {
va009039 0:2385683c867a 13 _setup();
va009039 0:2385683c867a 14 }
va009039 0:2385683c867a 15
va009039 0:2385683c867a 16 void Flash::_setup()
va009039 0:2385683c867a 17 {
va009039 0:2385683c867a 18 _target->halt();
va009039 0:2385683c867a 19 _target->wait_status(TARGET_HALTED);
va009039 0:2385683c867a 20 _target->prog_status();
va009039 0:2385683c867a 21 }
va009039 0:2385683c867a 22
va009039 0:2385683c867a 23 bool Flash::init()
va009039 0:2385683c867a 24 {
va009039 0:2385683c867a 25 _pc->printf("Initializing.");
va009039 0:2385683c867a 26 if (_target->idcode == 0x0bb11477) { // LPC1114FN28
va009039 0:2385683c867a 27 _target->writeMemory(MAINCLKSEL, 0); // Select Internal RC Oscillator
va009039 0:2385683c867a 28 _target->writeMemory(MAINCLKUEN, 1); // Update Main Clock Source
va009039 0:2385683c867a 29 _target->writeMemory(MAINCLKUEN, 0); // Toggle Update Register
va009039 0:2385683c867a 30 _target->writeMemory(MAINCLKUEN, 1);
va009039 0:2385683c867a 31 uint32_t data = _target->readMemory(MAINCLKUEN); // Wait until updated
va009039 0:2385683c867a 32 if (!(data & 1)) {
va009039 0:2385683c867a 33 _pc->printf("\nerror MAINCLKUEN=%08x\n", data);
va009039 0:2385683c867a 34 return false;
va009039 0:2385683c867a 35 }
va009039 0:2385683c867a 36 _target->writeMemory(SYSAHBCLKDIV, 1);// Set Main Clock divider to 1
va009039 0:2385683c867a 37 _target->writeMemory(SYSMEMREMAP, 2); // User Flash Mode
va009039 0:2385683c867a 38 } else {
va009039 0:2385683c867a 39 _pc->printf("\nerror idcode=%08x\n", _target->idcode);
va009039 0:2385683c867a 40 return false;
va009039 0:2385683c867a 41 }
va009039 0:2385683c867a 42 _pc->printf("passed.\n");
va009039 0:2385683c867a 43 return true;
va009039 0:2385683c867a 44 }
va009039 0:2385683c867a 45
va009039 0:2385683c867a 46 bool Flash::write(const char* filename)
va009039 0:2385683c867a 47 {
va009039 0:2385683c867a 48 FILE* fp = fopen(filename, "rb");
va009039 0:2385683c867a 49 if (fp == NULL) {
va009039 0:2385683c867a 50 _pc->printf("file open error [%s]\n", filename);
va009039 0:2385683c867a 51 return false;
va009039 0:2385683c867a 52 }
va009039 0:2385683c867a 53 _pc->printf("Writing.");
va009039 0:2385683c867a 54 uint8_t buf[512];
va009039 0:2385683c867a 55 bool passed = false;
va009039 0:2385683c867a 56 for(int addr = 0; addr < 0x8000; addr += sizeof(buf)) {
va009039 0:2385683c867a 57 int ret = fread(buf, 1, sizeof(buf), fp);
va009039 0:2385683c867a 58 if (!_patch(buf, sizeof(buf), addr)) {
va009039 0:2385683c867a 59 break;
va009039 0:2385683c867a 60 }
va009039 0:2385683c867a 61 if (!write(addr, buf, sizeof(buf))) {
va009039 0:2385683c867a 62 break;
va009039 0:2385683c867a 63 }
va009039 0:2385683c867a 64 _pc->printf(".");
va009039 0:2385683c867a 65 if (ret < sizeof(buf)) {
va009039 0:2385683c867a 66 passed = true;
va009039 0:2385683c867a 67 break;
va009039 0:2385683c867a 68 }
va009039 0:2385683c867a 69 }
va009039 0:2385683c867a 70 fclose(fp);
va009039 0:2385683c867a 71 if (passed) {
va009039 0:2385683c867a 72 _pc->printf("passed.\n");
va009039 0:2385683c867a 73 }
va009039 0:2385683c867a 74 return passed;
va009039 0:2385683c867a 75 }
va009039 0:2385683c867a 76
va009039 0:2385683c867a 77 bool Flash::write(int addr, const uint8_t* data, int size)
va009039 0:2385683c867a 78 {
va009039 0:2385683c867a 79 const int ram = 0x10000200;
va009039 0:2385683c867a 80 const int ram_size = 256;
va009039 0:2385683c867a 81 for(int i = 0; i < size; i += ram_size) {
va009039 0:2385683c867a 82 if (!_write_to_ram(ram, ram_size, data+i)) {
va009039 0:2385683c867a 83 _pc->printf("faild. write to ram %08x\n", ram);
va009039 0:2385683c867a 84 return false;
va009039 0:2385683c867a 85 }
va009039 0:2385683c867a 86 if (remoteIAP(PREPARE_SECTOR, _sector(addr+i), _sector(addr+i)) != CMD_SUCCESS) {
va009039 0:2385683c867a 87 _pc->printf("faild. PREPARE_SECTOR %d %d\n", _sector(addr+i), _sector(addr+i));
va009039 0:2385683c867a 88 return false;
va009039 0:2385683c867a 89 }
va009039 0:2385683c867a 90 if (remoteIAP(COPY_RAM_TO_FLASH, addr+i, ram, ram_size, IAP_CCLK) != CMD_SUCCESS) {
va009039 0:2385683c867a 91 _pc->printf("faild. COPY_RAM_TO_FLASH %d %d %d %dn", addr+i, ram, ram_size);
va009039 0:2385683c867a 92 return false;
va009039 0:2385683c867a 93 }
va009039 0:2385683c867a 94 if (remoteIAP(COMPARE, addr+i, ram, ram_size) != CMD_SUCCESS) {
va009039 0:2385683c867a 95 _pc->printf("faild. COMPARE %d %d %d", addr+i, ram, ram_size);
va009039 0:2385683c867a 96 return false;
va009039 0:2385683c867a 97 }
va009039 0:2385683c867a 98 }
va009039 0:2385683c867a 99 return true;
va009039 0:2385683c867a 100 }
va009039 0:2385683c867a 101
va009039 0:2385683c867a 102 bool Flash::eraseAll()
va009039 0:2385683c867a 103 {
va009039 0:2385683c867a 104 _pc->printf("Erasing.");
va009039 0:2385683c867a 105 for(int sector = 0; sector <= 7; sector++) {
va009039 0:2385683c867a 106 IAP_STATUS status = remoteIAP(PREPARE_SECTOR, sector, sector);
va009039 0:2385683c867a 107 if (status != CMD_SUCCESS) {
va009039 0:2385683c867a 108 _pc->printf("faild. PREPARE_SECTOR %d %d status=%d\n", sector, sector, status);
va009039 0:2385683c867a 109 return false;
va009039 0:2385683c867a 110 }
va009039 0:2385683c867a 111 if (remoteIAP(ERASE_SECTOR, sector, sector, IAP_CCLK) != CMD_SUCCESS) {
va009039 0:2385683c867a 112 _pc->printf("faild. ERASE_SECTOR %d %d %d\n", sector, sector, IAP_CCLK);
va009039 0:2385683c867a 113 return false;
va009039 0:2385683c867a 114 }
va009039 0:2385683c867a 115 if (remoteIAP(BLANK_CHECK, sector, sector, IAP_CCLK) != CMD_SUCCESS) {
va009039 0:2385683c867a 116 _pc->printf("faild. BLANK_CHECK %d %d %d\n", sector, sector, IAP_CCLK);
va009039 0:2385683c867a 117 return false;
va009039 0:2385683c867a 118 }
va009039 0:2385683c867a 119 _pc->printf(".");
va009039 0:2385683c867a 120 }
va009039 0:2385683c867a 121 _pc->printf("passed.\n");
va009039 0:2385683c867a 122 return true;
va009039 0:2385683c867a 123 }
va009039 0:2385683c867a 124
va009039 0:2385683c867a 125 bool Flash::_write_to_ram(int addr, int size, const uint8_t* buf)
va009039 0:2385683c867a 126 {
va009039 0:2385683c867a 127 _target->writeMemory(addr, (uint32_t*)buf, size / sizeof(uint32_t));
va009039 0:2385683c867a 128 return true;
va009039 0:2385683c867a 129 }
va009039 0:2385683c867a 130
va009039 0:2385683c867a 131 int Flash::_sector(int addr)
va009039 0:2385683c867a 132 {
va009039 0:2385683c867a 133 return addr / 4096;
va009039 0:2385683c867a 134 }
va009039 0:2385683c867a 135
va009039 0:2385683c867a 136 static uint32_t LD32(uint8_t* buf)
va009039 0:2385683c867a 137 {
va009039 0:2385683c867a 138 return buf[0] | buf[1]<<8 | buf[2]<<16 | buf[3]<<24;
va009039 0:2385683c867a 139 }
va009039 0:2385683c867a 140
va009039 0:2385683c867a 141 bool Flash::_patch(uint8_t* buf, int size, int addr)
va009039 0:2385683c867a 142 {
va009039 0:2385683c867a 143 const int crp_start = 0x2fc; // Code Read Protection location
va009039 0:2385683c867a 144 if (crp_start >= addr && crp_start < addr+size) {
va009039 0:2385683c867a 145 uint32_t pat = LD32(crp_start-addr+buf);
va009039 0:2385683c867a 146 if (pat != 0xffffffff) { // NO_CRP ?
va009039 0:2385683c867a 147 _pc->printf("\nCAUTION: CRP Pattern is not NO_CRP; %08x\n", pat);
va009039 0:2385683c867a 148 return false;
va009039 0:2385683c867a 149 }
va009039 0:2385683c867a 150 }
va009039 0:2385683c867a 151 return true;
va009039 0:2385683c867a 152 }
va009039 0:2385683c867a 153
va009039 0:2385683c867a 154 Flash::IAP_STATUS Flash::remoteIAP(Flash::IAP_CMD cmd, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3)
va009039 0:2385683c867a 155 {
va009039 0:2385683c867a 156 struct {
va009039 0:2385683c867a 157 uint32_t bkpt; // +0
va009039 0:2385683c867a 158 struct { // IAP Structure
va009039 0:2385683c867a 159 uint32_t cmd; // +4 Command
va009039 0:2385683c867a 160 uint32_t par[4]; // +8 Parameters
va009039 0:2385683c867a 161 uint32_t stat; // +24 Status
va009039 0:2385683c867a 162 uint32_t res[4]; // +28 Result
va009039 0:2385683c867a 163 } IAP; // +44
va009039 0:2385683c867a 164 } ram;
va009039 0:2385683c867a 165
va009039 0:2385683c867a 166 ram.bkpt = 0xe00abe00; // bpkt #00
va009039 0:2385683c867a 167 ram.IAP.cmd = cmd;
va009039 0:2385683c867a 168 ram.IAP.par[0] = p0;
va009039 0:2385683c867a 169 ram.IAP.par[1] = p1;
va009039 0:2385683c867a 170 ram.IAP.par[2] = p2;
va009039 0:2385683c867a 171 ram.IAP.par[3] = p3;
va009039 0:2385683c867a 172 _target->halt();
va009039 0:2385683c867a 173 _target->wait_status(TARGET_HALTED);
va009039 0:2385683c867a 174 const uint32_t ram_addr = 0x10000100;
va009039 0:2385683c867a 175 _target->writeMemory(ram_addr, (uint32_t*)&ram, sizeof(ram)/sizeof(uint32_t));
va009039 0:2385683c867a 176 _target->r0 = ram_addr + 4; // command addr
va009039 0:2385683c867a 177 _target->r1 = ram_addr + 24; // status addr
va009039 0:2385683c867a 178 _target->sp = 0x10000400-32; // IAP use ram top 32bytes
va009039 0:2385683c867a 179 _target->lr = ram_addr + 1; // return to bkpt
va009039 0:2385683c867a 180 _target->pc = 0x1fff1ff1; // IAP_Call
va009039 0:2385683c867a 181 _target->resume();
va009039 0:2385683c867a 182 _target->wait_status(TARGET_HALTED);
va009039 0:2385683c867a 183 return (IAP_STATUS)_target->readMemory(ram_addr + 24);
va009039 0:2385683c867a 184 }
va009039 0:2385683c867a 185
va009039 0:2385683c867a 186 bool Flash::verify(const char* filename)
va009039 0:2385683c867a 187 {
va009039 0:2385683c867a 188 FILE* fp = fopen(filename, "rb");
va009039 0:2385683c867a 189 if (fp == NULL) {
va009039 0:2385683c867a 190 _pc->printf("file open error [%s]\n", filename);
va009039 0:2385683c867a 191 return false;
va009039 0:2385683c867a 192 }
va009039 0:2385683c867a 193 _pc->printf("Verifying.");
va009039 0:2385683c867a 194 uint8_t buf[256];
va009039 0:2385683c867a 195 bool passed = false;
va009039 0:2385683c867a 196 for(int addr = 0; addr < 0x8000; addr++) {
va009039 0:2385683c867a 197 int c = fgetc(fp);
va009039 0:2385683c867a 198 if (c == EOF) {
va009039 0:2385683c867a 199 passed = true;
va009039 0:2385683c867a 200 break;
va009039 0:2385683c867a 201 }
va009039 0:2385683c867a 202 if ((addr % sizeof(buf)) == 0) {
va009039 0:2385683c867a 203 _target->readMemory(addr, (uint32_t*)buf, sizeof(buf)/sizeof(uint32_t));
va009039 0:2385683c867a 204 _pc->printf(".");
va009039 0:2385683c867a 205 }
va009039 0:2385683c867a 206 if (c != buf[addr % sizeof(buf)]) {
va009039 0:2385683c867a 207 _pc->printf("\nError at %08x(%02x:%02x)\n", addr, c, buf[addr % sizeof(buf)]);
va009039 0:2385683c867a 208 break;
va009039 0:2385683c867a 209 }
va009039 0:2385683c867a 210 }
va009039 0:2385683c867a 211 fclose(fp);
va009039 0:2385683c867a 212 if (passed) {
va009039 0:2385683c867a 213 _pc->printf("passed.\n");
va009039 0:2385683c867a 214 }
va009039 0:2385683c867a 215 return passed;
va009039 0:2385683c867a 216 }