/****************************************************************** * Function: TestFlash * * Purpose: Opens the specified flash device. If the mode * parameter is TEST, the function finds an erased * block, then tests it. If the mode parameter is * SHOWMAP, the function lists all blocks in the flash and * indicates which ones are erased. The flash is closed * at the end of the function. * ******************************************************************/ static void TestFlash(int mode) { alt_flash_fd* fd; int number_of_regions; int block; flash_region* regions; int ret_code = 0x0; alt_u8 entry[3]; char ch = 23; alt_u8 flashname[30]; ret_code = GetFlashName(flashname); fd = alt_flash_open_dev(flashname); if (fd) { printf(" -Successfully opened %s\n", flashname); /* Get some useful info about the flash */ ret_code = alt_get_flash_info(fd, ®ions, &number_of_regions); if (!ret_code) { printf(" -Region 0 contains %d blocks.\n", regions->number_of_blocks); block = FlashFindErasedBlocks(fd, regions, number_of_regions, mode); /* If we're in TEST mode, ask if this block is okay to test. */ if(mode == TEST) { printf(" -Block %d, at address 0x%X is erased.\n", block, (regions->offset + (block * regions->block_size))); printf(" -Would you like to test this block? (y/n)"); fgets(entry, sizeof(entry), stdin); if(sscanf(entry, "%c\n", &ch)) { if (ch == 'y') { /* Test that Flash! */ FlashRunTests(fd, block, regions); printf(" -Closing flash device \"%s\".\n", flashname); alt_flash_close_dev(fd); } } } } } else { printf(" -ERROR: Could not open %s\n", flashname); } }
FLASH_HANDLE Flash_Open(char *pFlashName){ int error_code; bool bSuccess = FALSE; FLASH_INFO *pFlash=NULL; pFlash = (FLASH_INFO *)malloc(sizeof(FLASH_INFO)); pFlash->fd_flash = alt_flash_open_dev(pFlashName); if (pFlash->fd_flash){ error_code = alt_get_flash_info(pFlash->fd_flash,&pFlash->regions_flash,&pFlash->number_of_regions_flash); if (error_code == 0){ bSuccess = TRUE; } } if (!bSuccess){ free(pFlash); pFlash= NULL; } return pFlash; }
alt_u32 Flash_Size(char *pFlashName){ alt_u32 FlashSize = 0; flash_region *regions, *nextreg; alt_flash_fd* fd; int number_of_regions; int ret_code, i; /* Set write_data to all 0xa */ fd = alt_flash_open_dev(pFlashName); if (fd){ ret_code = alt_get_flash_info(fd,®ions,&number_of_regions); if (ret_code == 0 && number_of_regions >= 1){ nextreg = regions; for(i=0;i<number_of_regions;i++){ FlashSize += nextreg->region_size; nextreg++; } } alt_flash_close_dev(fd); } return FlashSize; }
int FindLastFlashSectorOffset( alt_u32 *pLastFlashSectorOffset) { alt_flash_fd *fd; flash_region *regions; int numRegions; flash_region *pLastRegion; int lastFlashSectorOffset; int n; int error = 0; /* Open the flash device. */ fd = alt_flash_open_dev(EXT_FLASH_NAME); if (fd <= 0) error = -1; /* Get the flash info. */ if (!error) error = alt_get_flash_info(fd, ®ions, &numRegions); /* Find the last flash sector. */ if (!error) { pLastRegion = &(regions[0]); for (n = 1; n < numRegions; n++) { if (regions[n].offset > pLastRegion->offset) pLastRegion = &(regions[n]); } lastFlashSectorOffset = pLastRegion->offset + pLastRegion->region_size - pLastRegion->block_size; } /* Return results. */ if (!error) *pLastFlashSectorOffset = lastFlashSectorOffset; return (error); }
bool Flash_InfoDump(char *pFlashName){ bool bSuccess = FALSE; flash_region *regions, *nextreg; alt_flash_fd* fd; int number_of_regions; int ret_code; /* Set write_data to all 0xa */ FLASH_DEBUG(("Flash_InfoDump\r\n")); fd = alt_flash_open_dev(pFlashName); if (fd){ ret_code = alt_get_flash_info(fd,®ions,&number_of_regions); if (ret_code == 0){ int i; bSuccess = TRUE; nextreg = regions; FLASH_DEBUG(("number_of_regsion:%d\r\n", number_of_regions)); for(i=0;i<number_of_regions;i++){ FLASH_DEBUG(("regsion[%d]\r\n", i)); FLASH_DEBUG((" offset:%d\r\n", nextreg->offset)); FLASH_DEBUG((" region_size:%d\r\n", nextreg->region_size)); FLASH_DEBUG((" number_of_blocks:%d\r\n", nextreg->number_of_blocks)); FLASH_DEBUG((" block_size;:%d\r\n", nextreg->block_size)); nextreg++; } }else{ FLASH_DEBUG(("alt_get_flash_info error, ret_code:%d fail\r\n", ret_code)); } alt_flash_close_dev(fd); }else{ FLASH_DEBUG(("alt_flash_open_dev fail\r\n")); } if (!bSuccess) FLASH_DEBUG(("Flash_InfoDump fail\r\n")); 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: FlashErase * * Purpose: Erases 1 or all blocks in the specified flash device. * ******************************************************************/ static void FlashErase(void) { alt_flash_fd* fd; int test_offset; int ret_code; flash_region* regions; int number_of_regions; alt_u8 entry[3]; alt_u8 flashname[30]; unsigned int block; /* Get the name of the flash we are erasing */ ret_code = GetFlashName(flashname); fd = alt_flash_open_dev(flashname); if (fd) { /* Find out some useful stuff about the flash */ ret_code = alt_get_flash_info(fd, ®ions, &number_of_regions); if (!ret_code) { printf(" -Region has %d blocks.\n", regions->number_of_blocks); printf(" -Which block would you like to erase?\n"); printf(" -> "); fgets(entry, sizeof(entry), stdin); if(entry[0] == 'a') { printf(" -Erase ALL blocks? (y/n) "); fgets(entry, sizeof(entry), stdin); if(entry[0] == 'y') { /* Erase all blocks */ printf(" -Erasing %d blocks. Please Wait.\n", (regions->number_of_blocks)); for(block = 0; block < regions->number_of_blocks; block++) { /* Dont erase it if it's already erased silly. */ if ((FlashCheckIfBlockErased(fd->base_addr, block, regions)) == 0) { test_offset = (regions->offset + (block * regions->block_size)); alt_erase_flash_block(fd, test_offset, regions->block_size); } /* Just a simple progress meter so we dont get bored waiting for the flash to erase. */ printf("."); if(((block + 1) % 80) == 0) { printf("\n"); } } printf("\n -All Blocks Erased.\n"); } else { printf("Erased zero blocks.\n"); } } /* Just erase one block */ if(sscanf(entry, "%d\n", &block)) { if ((block >= 0) && (block <= (regions->number_of_blocks - 1))) { test_offset = (regions->offset + (block * regions->block_size)); alt_erase_flash_block(fd, test_offset, regions->block_size); printf(" -Block %d erased.\n", block); } else { printf(" -Block number entered is %d\n", block); printf(" -Block number must be between 0 and %d.\n", (regions->number_of_blocks - 1)); } } } printf(" -Closing flash \"%s\".\n", flashname); alt_flash_close_dev(fd); } }