void WriteFlashBytesCommand(void) { u8 buf[16]; int addr; int len; ParseWriteParameters("Flash write", &addr, FlashSize(), buf, &len); if (len) {WriteFlash(addr, buf, len);} }
// Communicates with a 16-bit flash device to verify that it is there. Fills // the Flash data struct with the size, block size, block address mask, and // base address. // // Returns TRUE if successful, FALSE if no device is detected. BOOL QueryDevice16(uint8 *addr, Flash *pFlash) { volatile uint8 *ptr; int numBlocks; char QRY[3]; ptr = addr; // Enter read query mode SEND_FLASH16(ptr, FLASH_CMD_READ_QUERY); QRY[0] = READ_FLASH16(ptr, 0x10); QRY[1] = READ_FLASH16(ptr, 0x11); QRY[2] = READ_FLASH16(ptr, 0x12); if(!(QRY[0] == 'Q' && QRY[1] == 'R' && QRY[2] == 'Y')) return FALSE; pFlash->addr = addr; // Query flash size pFlash->size = FlashSize(READ_FLASH16(ptr, 0x27)); // Query number of blocks numBlocks = ((READ_FLASH16(ptr, 0x2E) << 8) | READ_FLASH16(ptr, 0x2D)) + 1; pFlash->blockSize = pFlash->size / numBlocks; // Create block mask for generating block addresses pFlash->blockMask = ~(pFlash->blockSize - 1); // Restore read array mode SEND_FLASH16(ptr, FLASH_CMD_READ_ARRAY); return TRUE; }
void DumpFlashWordsCommand(void) { int length = 128; // Default byte count to display ParseDumpParameters("dump flash words", FlashSize(), &FWaddr, &length); u8 buf[length]; DwReadFlash(FWaddr, length, buf); DumpWords(FWaddr, length, buf); FWaddr += length; }
void WriteFlash(u16 addr, const u8 *buf, int length) { Assert(addr + length <= FlashSize()); Assert(length >= 0); if (length == 0) return; DwGetRegs(0, R, 2); // Cache R0 and R1 int pageOffsetMask = PageSize()-1; int pageBaseMask = ~ pageOffsetMask; if (addr & pageOffsetMask) { // buf starts in the middle of a page int partBase = addr & pageBaseMask; int partOffset = addr & pageOffsetMask; int partLength = min(PageSize()-partOffset, length); DwReadFlash(partBase, PageSize(), pageBuffer); memcpy(pageBuffer+partOffset, buf, partLength); WriteFlashPage(partBase, pageBuffer); addr += partLength; buf += partLength; length -= partLength; } Assert(length == 0 || ((addr & pageOffsetMask) == 0)); // Write whole pages while (length >= PageSize()) { WriteFlashPage(addr, buf); addr += PageSize(); buf += PageSize(); length -= PageSize(); } // Write any remaining partial page if (length) { Assert(length > 0); Assert(length < PageSize()); Assert((addr & pageOffsetMask) == 0); DwReadFlash(addr, PageSize(), pageBuffer); memcpy(pageBuffer, buf, length); WriteFlashPage(addr, pageBuffer); } Ws(" \r"); // Restore cached registers R0 and R1 DwSetRegs(0, R, 2); }
void UnassembleCommand(void) { int count = 8; // Default instruction count to display Sb(); if (IsDwDebugNumeric(NextCh())) {Uaddr = ReadInstructionAddress("U"); Wl();} Sb(); if (IsDwDebugNumeric(NextCh())) {count = ReadNumber(0);} Sb(); if (!DwEoln()) {Wsl("Unrecognised parameters on unassemble command.");} int firstByte = Uaddr; int limitByte = min(firstByte + count*4, FlashSize()); // Allow for up to 2 words per instruction int length = limitByte - firstByte; if (length <= 0) {Fail("Nothing to disassemble.");} u8 buf[length+2]; DwReadFlash(firstByte, length, buf); buf[length] = 0; buf[length+1] = 0; while (1) { Uaddr += DisassembleInstruction(Uaddr, &buf[Uaddr-firstByte]); count--; if (count <= 0 || Uaddr >= FlashSize()) {return;} Wl(); } }
void DwReadFlash(int addr, int len, u8 *buf) { int limit = addr + len; if (limit > FlashSize()) {Fail("Attempt to read beyond end of flash.");} while (addr < limit) { int length = min(limit-addr, 64); // Read no more than 64 bytes at a time so PC remains in valid address space. DwSetZ(addr); // Z := First address to read DwSetPC(BootSect()); // Set PC that allows access to all of flash DwSetBP(BootSect()+2*length); // Set BP to load length bytes DwSend(Bytes(0x66, 0xC2, 0x02, 0x20)); // Set flash read mode and start reading DwReceive(buf, length); addr += length; buf += length; } }
void DumpConfig(void) { u8 cb; u8 hfuse; u8 efuse; // Show Known device info Ws(Name()); Wsl("."); Ws("IO regs: "); Wx(32,2); Ws(".."); Wx(IoregSize()+31,2); Ws(" ("); Wd(IoregSize(),1); Wsl(" bytes)."); Ws("SRAM: "); Wx(IoregSize()+32,3); Ws(".."); Wx(31 + IoregSize() + SramSize(), 3); Ws(" ("); Wd(SramSize(),1); Wsl(" bytes)."); Ws("Flash: 0000.."); Wx(FlashSize()-1, 4); Ws(" ("); Wd(FlashSize(),1); Wsl(" bytes)."); Ws("EEPROM: 000.."); Wx(EepromSize()-1, 3); Ws(" ("); Wd(EepromSize(),1); Wsl(" bytes)."); // Dump uninterpreted fuse and lock bit values ReadConfigBits(0, &cb); Ws("Fuses: low "); Wx(cb,2); Wflush(); ReadConfigBits(3, &hfuse); Ws(", high "); Wx(hfuse,2); Wflush(); ReadConfigBits(2, &efuse); Ws(", extended "); Wx(efuse,2); Wflush(); ReadConfigBits(1, &cb); Ws(", lock bits "); Wx(cb,2); Wsl("."); // Interpret boot sector information if (BootFlags()) { int bootsize = 0; int bootvec = 0; switch (BootFlags()) { case 1: bootsize = 128 << (3 - ((efuse/2) & 3)); bootvec = efuse & 1; break; // atmega88 & 168 case 2: bootsize = 256 << (3 - ((hfuse/2) & 3)); bootvec = hfuse & 1; break; // atmega328 default: Fail("Invalid BootFlags global data setting."); } bootsize *= 2; // Bootsize is in words but we report in bytes. Ws(" Boot space: "); Wx(FlashSize()-bootsize, 4); Ws(".."); Wx(FlashSize()-1, 4); Ws(" ("); Wd(bootsize,1); Wsl(" bytes)."); Ws(" Vectors: "); if (bootvec) Wsl("0."); else {Wx(FlashSize()-bootsize, 4); Wsl(".");} } }
void WBL_info() { uprintf("\n\n"); uprintf(WBR_BANNER); uprintf("Running on a %s Evaluation Board\n", "W90P710"); uprintf("Board Revision %s, %s Processor\n", "1.0", "ARM7TDMI"); uprintf("Memory Size is 0x%x Bytes, Flash Size is 0x%x Bytes\n",memory_size, FlashSize()); uprintf("Board designed by %s\n", "Winbond"); uprintf("Hardware support provided at %s\n", "Winbond"); uprintf("Copyright (c) Winbond Limited 2001 - 2003. All rights reserved.\n"); uprintf("\n\nFor help on the available commands type 'h'\n\n"); }
void DwReconnect(void) { DwSend(Bytes(0xF0)); // Request current PC PC = (2 * (DwReadWord() - 1) % FlashSize()); DwGetRegs(28, R+28, 4); // Cache r28 through r31 }