void flash_wrsector(int addr, char *data, int size) { int i; restart: printf("Writing 0x%06x .. 0x%06x:", addr, addr+size-1); fflush(stdout); printf(" [erasing]"); fflush(stdout); flash_write_enable(); flash_erase_64kB(addr); flash_wait(); if (size == 0) { printf("\n"); fflush(stdout); return; } printf(" [writing"); fflush(stdout); for (i = 0; i < size; i += 256) { if (i % 4096 == 0) { printf("."); fflush(stdout); } flash_write_enable(); flash_write(addr+i, data+i, size-i < 256 ? size-i : 256); flash_wait(); } printf("] [readback"); fflush(stdout); for (i = 0; i < size; i += 256) { if (i % 4096 == 0) { printf("."); fflush(stdout); } char buffer[256]; flash_read(addr+i, buffer, size-i < 256 ? size-i : 256); if (memcmp(buffer, data+i, size-i < 256 ? size-i : 256)) { printf("ERROR\n"); fflush(stdout); goto restart; } } printf("]\n"); fflush(stdout); }
UBYTE flash_put(UDWORD address, UBYTE data) { UBYTE buff_addr; UDWORD page; //make address correct buff_addr=address & 0xFF; page=address & FLASH_MAX_PAGES; page=page<<1; //addr=addr | buff_addr; //read page into buffer //transfer main memory into buffer #1 FLASH_CS(0); //drive chip select low spi_write(0x53); spi_write(MAKE8(page,2)); spi_write(MAKE8(page,1)); spi_write(buff_addr); FLASH_CS(1); flash_wait(); //write byte to buffer FLASH_CS(0); //drive chip select low spi_write(0x84); spi_write(0); spi_write(0); spi_write(buff_addr); spi_write(data); FLASH_CS(1); delay_ms(1); flash_wait(); //we need to write buffer to page FLASH_CS(0); //drive chip select low spi_write(0x83); spi_write((page>>16) & 0xFF); spi_write((page>>8) & 0xFF); spi_write((page) & 0xFF); FLASH_CS(1); delay_ms(20); flash_wait(); return 0; }
UBYTE flash_read(UDWORD addr) { UBYTE buff_addr; UDWORD page; //make address correct buff_addr=addr & 0xFF; page=addr & FLASH_MAX_PAGES; page=page<<1; //printf_P(PSTR("addr %lX page %lX %X\n\r",addr,page,buff_addr); //send read command flash_wait(); FLASH_CS(0); spi_write(0xD2); spi_write(MAKE8(page,2)); spi_write(MAKE8(page,1)); spi_write(buff_addr); //send 4 don't care bytes spi_write(0); spi_write(0); spi_write(0); spi_write(0); buff_addr=spi_write(0); FLASH_CS(1); return buff_addr; }
static int lm3s_erasePage(struct KBlock *blk, uint32_t addr) { FLASH_FCMISC_R = FLASH_FCMISC_AMISC; FLASH_FMA_R = (volatile uint32_t)addr; FLASH_FMC_R = FLASH_FMC_WRKEY | FLASH_FMC_ERASE; return flash_wait(blk, FLASH_FMC_ERASE); }
static int lm3s_writeWord(struct KBlock *blk, uint32_t addr, uint32_t data) { FLASH_FCMISC_R = FLASH_FCMISC_AMISC; FLASH_FMA_R = (volatile uint32_t)addr; FLASH_FMD_R = (volatile uint32_t)data; FLASH_FMC_R = FLASH_FMC_WRKEY | FLASH_FMC_WRITE; return flash_wait(blk, FLASH_FMC_WRITE); }
static bool stm32_eraseAll(struct KBlock *blk) { EMB_FLASH->CR |= CR_MER_SET; EMB_FLASH->CR |= CR_STRT_SET; if (!flash_wait(blk)) return false; EMB_FLASH->CR &= CR_MER_RESET; return true; }
static bool stm32_erasePage(struct KBlock *blk, uint32_t page_add) { EMB_FLASH->CR |= CR_PER_SET; EMB_FLASH->AR = page_add; EMB_FLASH->CR |= CR_STRT_SET; if (!flash_wait(blk)) return false; EMB_FLASH->CR &= CR_PER_RESET; return true; }
/* Wait until a flash write is completed and check for errors. */ void checkFlashWrite() { uchar state; // Flash state. // Error checking. state = flash_wait(); if(state & FLASH_BLOCK_LOCKED) { drawErrorWindow(&errErrorFlashLocked); return 0; } if(state & FLASH_PROGRAM_ERROR) { drawErrorWindow(&errErrorFlashWrite); return 0; } }
INLINE bool stm32_writeWord(struct KBlock *blk, uint32_t addr, uint16_t data) { ASSERT(!(addr % 2)); EMB_FLASH->CR |= CR_PG_SET; *(reg16_t *)addr = data; if (!flash_wait(blk)) return false; EMB_FLASH->CR &= CR_PG_RESET; return true; }
//Erases all of flash memory UBYTE flash_erase_page(UWORD page) { UWORD temp; //first send the erase opcode; FLASH_CS(0); spi_write(0x81); temp=page<<1;; spi_write((temp>>8) & 0xff); spi_write(temp & 0xff); spi_write(0x00); FLASH_CS(1); delay_us(10); //now lets wait for the status to say all is good. flash_wait(); return 0; //no error }
byte flash_sector_erase_int(WORD sector) { int i; // printk("Flash erase sector number:%d\n",sector); for( i = 0; i < 3; i++ ) { flash_command(FLASH_SERASE, sector, 0, 0); if(flashFamily==FLASH_MXIC) { if (flash_wait_erase(sector, 0, 0xffff) == STATUS_READY) break; } else if (flash_wait(sector, 0, 0xffff) == STATUS_READY) break; } return(1); }
static int flash_write(WORD sector, int offset, byte *buf, int nbytes) { UINT16 *src; src = (UINT16 *)buf; if ((nbytes | offset) & 1) { return -1; } flash_command(FLASH_UB, 0, 0, 0); while (nbytes > 0) { flash_command(FLASH_PROG, sector, offset, *src); if (flash_wait(sector, offset, *src) != STATUS_READY) break; offset +=2; nbytes -=2; src++; } flash_command(FLASH_UBRESET, 0, 0, 0); return (byte*)src - buf; }
/******************************************************************* * FUNCTION: Flash_serial_program * AUTHOR = TRAMPAS STERN * FILE = flash.c * DATE = 1/26/2003 5:17:39 PM * * PARAMETERS: Destination address * * DESCRIPTION: gets xmodem packet and programs to flash * * RETURNS: 0 - pass, * 1 - Flash write failed * * * *******************************************************************/ UBYTE Flash_serial_program(UDWORD address) { UWORD i; UBYTE data[XMODEM_PACKET_SIZE]; UBYTE ret; UBYTE done; UBYTE packet; UBYTE buff_addr; UDWORD page; UDWORD bytes; packet=1; //first packet is 1 bytes=0; //make address correct buff_addr=MAKE8(address,0); page=address & FLASH_MAX_PAGES; page=page<<1; //addr=addr | buff_addr; //read page into buffer //transfer main memory into buffer #1 FLASH_CS(1); spi_write(0x53); spi_write(MAKE8(page,2)); spi_write(MAKE8(page,1)); spi_write(buff_addr); FLASH_CS(1); flash_wait(); //send request to start transimission // we will retry 40 times for slow users i=0; done=0; do { Xmodem_start(); ret=Xmodem_get_packet(data,packet); //Get a packet of information }while(ret==XERROR_SOH && i++<300); while(!done) { UBYTE i; //then we need to program the data into flash for(i=0; i<XMODEM_PACKET_SIZE; i++) { //write each byte to buffer FLASH_CS(0); spi_write(0x84); spi_write(0); spi_write(0); spi_write(buff_addr); spi_write(data[i]); FLASH_CS(1); flash_wait(); buff_addr++; //if buffer full write buffer to page // and read next buffer if (buff_addr==0x00) { //we need to write buffer to page FLASH_CS(0); spi_write(0x83); spi_write(MAKE8(page,2)); spi_write(MAKE8(page,1)); spi_write(buff_addr); FLASH_CS(1); delay_ms(20); flash_wait(); //read next page into buffer page=page+0x00200; FLASH_CS(0); spi_write(0x53); spi_write(MAKE8(page,2)); spi_write(MAKE8(page,1)); spi_write(buff_addr); FLASH_CS(1); flash_wait(); } bytes++; } packet++; //send request for next packet if (ret==NO_ERRORS) { Xmodem_send_next(); ret=Xmodem_get_packet(data,packet); //Get a packet of information }else { Xmodem_goodbye(); done=1; } }; //we need to write buffer to page FLASH_CS(0); spi_write(0x83); spi_write(MAKE8(page,2)); spi_write(MAKE8(page,1)); spi_write(buff_addr); FLASH_CS(1); delay_ms(20); flash_wait(); if (ret==NO_ERRORS || ret==RECV_EOT) { Xmodem_goodbye(); delay_ms(500); printf_P(PSTR("\n\rFlashed %lu Bytes\n\r"),bytes); printf_P(PSTR("Flash Program completed\n\r")); return NO_ERRORS; } Xmodem_send_cancel(); //tell host to cancel delay_ms(1000); //wait for host to give up while(uart_kbhit()) uart_getchar(); printf_P(PSTR("Flash Program ERROR %X packet=%d\n\r"),ret,packet); //printf_P(PSTR("Packet expect %d, got %d comp %d\n\r",expected,Xpacket,Xpacket_comp); printf_P(PSTR("Press x to exit\n\r")); while( uart_getchar()!='x'); return ret; //else lets return the xmodem error }
/* NOTE: Automatic deduction of the number of blocks, that need to be erased has not been tested extensive. */ void upload() { uint size; // Image size. uint step; // Progress bar step size. uint cval; // Current progress value. // Clear screen. cls(); // User Upload Menu. drawWindow(&wUpload); // Upload Initialization. drawMessage(&wUpload, &msgUploadWait); pbUpload.val = 0; drawProgressBar(&wUpload, &pbUpload); // Receive 4 bytes of size data. for(uchar i=0; i < 4; i++) { size <<= 8; size += rs232_receive(); } // Check for image size to fit into flash. if(size > FLASH_BLOCK_SIZE * FLASH_BLOCKS) { drawErrorWindow(&errErrorFlashSize); return 0; } // Flash Clean Up. drawMessage(&wUpload, &msgUploadErase); pbUpload.val = 0; // Reset progress bar. drawProgressBar(&wUpload, &pbUpload); // Erase affected flash blocks. for(uint i=0; i < (size / FLASH_BLOCK_SIZE) + 1; i++) { flash_block_erase(i * FLASH_BLOCK_SIZE); // Update the Progress Bar. pbUpload.val = (i >> 1); drawProgressBar(&wUpload, &pbUpload); // Check for errors while erasing. if(flash_wait() & FLASH_ERASE_ERROR) { drawErrorWindow(&errErrorFlashErase); return 0; } } // Write image size at flash address 0x0. for(uchar i=0; i<4; i++) { flash_write(i, size >> ((3-i) * 8) ); checkFlashWrite(); } // Upload data. drawMessage(&wUpload, &msgUploadWrite); pbUpload.val = 0; // Reset progress bar. step = size / 64; // Calculate progress step size. cval = step; // Echoing received image size. for(uchar i=0; i<4; i++) { rs232_transmit( size >> ((3-i) * 8) ); } // Write each single byte to Flash. for(uint i=0; i < size; i++) { flash_write(i + 4, rs232_receive()); // Update status bar. if(i == cval) { pbUpload.val++; drawProgressBar(&wUpload, &pbUpload); cval += step; } checkFlashWrite(); } // Go back to main menu. boot(); }
/* Wait for completed flash initialization. Set up main menu box. */ int main() { uchar s; // Clear screen. cls(); // Wait for flash hardware initialization end. s = flash_wait(); // Flash not ready. if( !(s & FLASH_READY) ) { drawErrorWindow(&errFlashNotReady); return 0; } // Flash command error. if(s & FLASH_CMD_ERROR) { drawErrorWindow(&errFlashState); flash_clear_sr(); //boot(); return 0; } // User Main Menu. drawWindow(&wBoot); while(TRUE) { switch(getc()->chr) { case KEY_ARROWD: menuKeyDown(&wBoot, &menu); break; case KEY_ARROWU: menuKeyUp(&wBoot, &menu); break; case KEY_ENTER: switch(menu.index) { case OPTION_UPLOAD: upload(); break; case OPTION_MEMORY: view_memories(); break; case OPTION_START: load(1, flash_read(0)); start(); break; default: break; } break; default: break; } } }