bool Flash_Write(FLASH_HANDLE Handle, alt_u32 offset, alt_u8 *szData, alt_u32 size){ FLASH_INFO *pFlash = (FLASH_INFO *)Handle; bool bSuccess = TRUE; int error_code; if (!pFlash->fd_flash) return FALSE; //FLASH_DEBUG(("Flash_Write, offset=%d, size=%d\r\n", offset, size)); #if 0 error_code = alt_write_flash(fd_flash, offset, szData, size); // note. !!!! it will erase flash block content before write data if (error_code == 0){ bSuccess = TRUE; }else{ FLASH_DEBUG(("alt_write_flash fail, error_code=%d\r\n", error_code)); } #else int block_offset, block_size, write_count, this_write_size, r, i;//, first_offset; flash_region *nextreg = pFlash->regions_flash; block_offset = 0; write_count = 0; for(r=0;r<pFlash->number_of_regions_flash && bSuccess;r++){ for(i=0;i<nextreg->number_of_blocks && bSuccess;i++){ block_size = nextreg->block_size; // FLASH_DEBUG(("block_offset=%d, block_size=%d\r\n", block_offset, block_size)); // if ((offset >= block_offset) && ((offset+size) <= (block_offset + block_size))){ if (((offset+write_count) >= block_offset) && (write_count < size)){ // write this_write_size = size - write_count; if (write_count == 0){ // first block if (this_write_size > (block_offset + block_size - offset)) this_write_size = block_offset + block_size - offset; }else{ // block aligement if (this_write_size > block_size) this_write_size = block_size; } error_code = alt_write_flash_block(pFlash->fd_flash, block_offset, offset+write_count, szData+write_count, this_write_size); //FLASH_DEBUG(("alt_write_flash_block, block_offset:%d, offset:%d, len:%d, this block_size:%d\r\n", block_offset, offset+write_count, this_write_size, block_size)); if (error_code != 0){ bSuccess = FALSE; FLASH_DEBUG(("alt_write_flash_block fail, error_code=%d\r\n", error_code)); } write_count += this_write_size; } block_offset += block_size; } nextreg++; } #endif /* error_code = alt_write_flash(fd_flash, offset, szData, size); // it will erase flash block content before write data // error_code = alt_write_flash_block(fd_flash, offset, offset+size, szData, size); // it will preserve flash content if (error_code == 0) return TRUE; */ return bSuccess; }
/****************************************************************** * Function: ProgFlash * * Purpose: This function asks for the name of a flash device, * a pointer to a data buffer, and the size of the data buffer. * ******************************************************************/ int ProgFlash(struct flash_inf_struct *flash_info, int target_addr, char* data, int data_len) { // Flash device variables alt_flash_fd* fd; int number_of_regions; flash_region* regions; alt_u8 flashname[40]; /* Be conservative on the size of the string. */ alt_u8* flashname_ptr = (alt_u8*) &flashname; int new_flash_block = -1; // General purpose variables unsigned int sw_offset = 0; int ret_code = 0x0; /* * flash_info->device contains the flash device name * from the multipart form. * - If you want your flash name to be an option, you must change the * upload_image form in index.html to include your flash device's name * in the pick list. */ flashname_ptr += sprintf( flashname_ptr, "/dev/%s", flash_info->device ); *(flashname_ptr+1) = '\0'; fd = alt_flash_open_dev(flashname); if (fd) { /* Get some useful info about the flash */ ret_code = alt_get_flash_info(fd, ®ions, &number_of_regions); /* To which flash block is the SREC data destined? */ /* new_flash_block = target_addr / regions->block_size; */ /* Ahhh, but what happens if a line spans the end of one block and the * beginning of another? * - Better to handle this case well...as well! */ new_flash_block = (target_addr + data_len) / regions->block_size; if( current_flash_block == -1 ) { /* Output various flash information when programming the first line. */ printf( "\nFlash Name is %s.\nBlock size is %d bytes.\n\nProgramming Flash...\n", flashname, regions->block_size ); } /* if it's a new block, we need to erase it first. */ if(new_flash_block != current_flash_block) { printf("\nFlash Block %d", new_flash_block); /* Blindly erase the new flash block */ alt_erase_flash_block(fd, (new_flash_block * regions->block_size), regions->block_size); current_flash_block = new_flash_block; } alt_write_flash_block(fd, (current_flash_block * regions->block_size), target_addr, data, data_len); /* This just gives us some zippy dots so we know hard work is being done */ if ((target_addr - sw_offset) % (regions->block_size / 8) < data_len) { printf("\n 0x%8.8X: ", (target_addr & 0xFFFFFF00)); } /*if ((target_addr - sw_offset) % (regions->block_size / 256) < data_len) { printf("."); }*/ } else { printf("Error Opening flash device. Exiting."); } alt_flash_close_dev(fd); return (ret_code); }
/****************************************************************** * Function: FlashTestBlockWrite * * Purpose: Tests that the function alt_write_flash_block is * is working properly. * ******************************************************************/ static int FlashTestBlockWrite(int block, int *error, alt_flash_fd* fd, flash_region* regions) { int i; int ret_code = 0x0; int test_offset; alt_u8 *data_written; alt_u8 *data_read; /* Get a couple buffers for the test */ data_written = malloc(100); data_read = malloc(100); test_offset = (regions->offset + (block * regions->block_size)); /* Fill write buffer with 100 values (incremented by 3) */ for(i=0; i < 100; i++) *(data_written + i) = (i * 3); /* Write the buffer to flash starting 0x40 bytes from the beginning of the block. */ printf(" -Testing \"alt_write_flash_block\"."); ret_code = alt_write_flash_block(fd, test_offset, (test_offset + 0x40), data_written, 100); if (!ret_code) { /* Now read it back into the read_buffer */ ret_code = alt_read_flash(fd, (test_offset + 0x40), data_read, 100); if(!ret_code) { /* See if they match */ if (memcmp(data_written, data_read, 100)) { printf(" FAILED.\n"); *error++; } else printf(" passed.\n"); } } /* Test unaligned writes */ if(!ret_code) { /* Erase the block */ ret_code = alt_erase_flash_block(fd, test_offset, regions->block_size); /* Write the buffer to flash on an unaligned address. */ printf(" -Testing unaligned writes."); ret_code = alt_write_flash_block(fd, test_offset, (test_offset + 0x43), data_written, 100); if (!ret_code) { /* Now read it back into the read_buffer */ ret_code = alt_read_flash(fd, (test_offset + 0x43), data_read, 100); if(!ret_code) { /* See if they match */ if (memcmp(data_written, data_read, 100)) { printf(" FAILED.\n"); *error++; } else printf(" passed.\n"); } } } /* Free up the buffers we allocated. */ free(data_written); free(data_read); return ret_code; }