uchar SPI_FlushPage(unsigned long address, uchar pollvalue) { SPI_Transmit(0x4C); SPI_Transmit(address >> 9); SPI_Transmit(address >> 1); SPI_Transmit(0); if (pollvalue == 0xFF) { clockWait(15); return 0; } else { /* polling flash */ uchar counter = 30; TIMER1 = 0; while (counter != 0) { if (SPI_ReadFlash(address) != 0xFF) { return 0; } if (TIMER1 > CLOCK_T_320us) { TIMER1 = 0; counter--; } } return 1; /* error */ } }
void main(void) { int len, i, j, off, sec; char *addr = (char *)SDRAM_BASE + (1 << 20); /* download at + 1MB */ char *addr2 = (char *)SDRAM_BASE + (2 << 20); /* readback to + 2MB */ SPI_InitFlash(); printf("Waiting for data\n"); while ((len = xmodem_rx(addr)) == -1) continue; printf("Writing %u bytes at %u\n", len, OFFSET); for (i = 0; i < len; i+= FLASH_PAGE_SIZE) { off = i + OFFSET; for (j = 0; j < 10; j++) { SPI_WriteFlash(off, addr + i, FLASH_PAGE_SIZE); SPI_ReadFlash(off, addr2 + i, FLASH_PAGE_SIZE); if (p_memcmp(addr + i, addr2 + i, FLASH_PAGE_SIZE) == 0) break; } if (j >= 10) printf("Bad Readback at %u\n", i); } sec = GetSeconds() + 2; while (sec <= GetSeconds()) continue; printf("Done\n"); reset(); }
static void LoadKernelFromSpi(char *addr) { int i, off; for (i = 0; i < KERNEL_LEN; i+= FLASH_PAGE_SIZE) { off = i + KERNEL_OFFSET; SPI_ReadFlash(off, addr + i, FLASH_PAGE_SIZE); } }
uchar SPI_WriteFlash(unsigned long address, uchar data, uchar pollmode) { // We're not guarenteed that there was a chip erase, so we can't // skip programming of 0xFF... /* 0xFF is value after chip erase, so skip programming if (data == 0xFF) { return 0; } */ SPI_Transmit(0x40 | ((address & 1) << 3)); SPI_Transmit(address >> 9); SPI_Transmit(address >> 1); SPI_Transmit(data); if (pollmode == 0) return 0; if (data == 0x7F) { clockWait(15); // wait 4,8 ms return 0; } else { // Poll flash for (30 * 320 uS) uchar counter = 30; TIMER1 = 0; while (counter != 0) { if (SPI_ReadFlash(address) != 0x7F) { return 0; }; if (TIMER1 > CLOCK_T_320us) { TIMER1 = 0; counter--; } } return 1; /* error */ } }