/********************************************************************************************************* ** Function name : flash_write_data ** Descriptions : Write flash memory ,not just in one page memory ** Input parameters : WAddr -- the start address to write ** Output parameters : buf -- the buffer to write the data ** RLength -- the length of the data to write ** Returned value : The operation result. 1 -- sucess, 0 -- false *********************************************************************************************************/ uint8_t flash_write_data (uint32_t WAddr, uint8_t *buf, uint32_t WLength) { uint32_t dealer, remainder; uint32_t i, addr, len = 0; if (WLength == 0) { return 0; } remainder = WAddr % W25X32_PAGE_SIZE; /* * Write the data not enough to one page memory */ if (remainder != 0) { len = W25X32_PAGE_SIZE - remainder; if (len < WLength) { flash_write_sector(WAddr, buf, len); } else { flash_write_sector(WAddr, buf, WLength); return 1; } } /* * Calculate the rest data, then write several packets with whole page memory */ remainder = (WLength - len) % W25X32_PAGE_SIZE; dealer = (WLength - len) / W25X32_PAGE_SIZE; for (i=0; i<dealer; i++) { addr = len + (i * W25X32_PAGE_SIZE); flash_write_sector(WAddr+addr, (uint8_t *)&buf[addr], W25X32_PAGE_SIZE); } /* * Write the last data that not enough to one page memory */ if (remainder != 0) { addr = len + (i * W25X32_PAGE_SIZE); flash_write_sector(WAddr+addr, (uint8_t *)&buf[addr], remainder); } return 1; }
/*********************************************************************** * * Function: mem_to_nand * * Purpose: Moves data from memory to FLASH * * Processing: * See function. * * Parameters: * starting_sector : Starting sector for write * buff : Pointer to buffer to write * bytes : Number of bytes to write * * Outputs: None * * Returns: Nothing * * Notes: None * **********************************************************************/ BOOL_32 mem_to_nand(UNS_32 starting_sector, void *buff, UNS_32 bytes) { BOOL_32 blkchk; UNS_32 block, page, sector, wbytes; UNS_8 str[16], *p8 = (UNS_8 *) buff; if (sysinfo.nandgeom == NULL) { term_dat_out_crlf(noflash_msg); return FALSE; } /* Get block and page for passed sector */ block = starting_sector / sysinfo.nandgeom->pages_per_block; page = starting_sector - (block * sysinfo.nandgeom->pages_per_block); /* Align bytes to a sector boundary */ wbytes = bytes & ~(sysinfo.nandgeom->data_bytes_per_page - 1); if (wbytes < bytes) { bytes = wbytes + sysinfo.nandgeom->data_bytes_per_page; } /* Write data */ blkchk = TRUE; while (bytes > 0) { /* Is a block check needed? */ if ((page == 0) && (blkchk == TRUE)) { if (flash_is_bad_block(block) != FALSE) { /* Goto next block */ term_dat_out(bskip_msg); str_makedec(str, block); term_dat_out_crlf(str); block++; page = 0; } else { /* Block is good */ blkchk = FALSE; } } else { /* Convert to sector */ sector = conv_to_sector(block, page); /* Write sector data */ if (flash_write_sector(sector, p8, NULL) == FALSE) { term_dat_out(writeerr_msg); str_makedec(str, sector); term_dat_out_crlf(str); bytes = 0; return FALSE; } else { p8 += sysinfo.nandgeom->data_bytes_per_page; bytes -= sysinfo.nandgeom->data_bytes_per_page; } /* Next page and block */ page++; if (page >= sysinfo.nandgeom->pages_per_block) { page = 0; block++; blkchk = TRUE; } } } return TRUE; }
/*********************************************************************** * * Function: cfg_save * * Purpose: Save a S1L configuration * * Processing: * See function. * * Parameters: * pCfg : Pointer to config structure to save * * Outputs: None * * Returns: Always returns FALSE * * Notes: None * **********************************************************************/ BOOL_32 cfg_save(S1L_CFG_T *pCfg) { UNS_32 sector, blk = adjusted_num_blocks - 1; const UNS_32 cfg_check_data = CHECK_KEY; UNS_32 pg_sz = sysConfig.nandgeom->data_bytes_per_page; if (cfg_size_check() == FALSE) return FALSE; while (blk < adjusted_num_blocks) { /* This won't erase bad blocks */ if (flash_erase_block(blk) == TRUE) { INT_32 offset = 0, page = 0; INT_32 sz_bcfg = sizeof(s1l_board_cfg); INT_32 sz_cfg = sizeof(*pCfg); UNS_8 *ptr_cfg = (UNS_8 *)pCfg; UNS_8 *ptr_bcfg = (UNS_8 *)&s1l_board_cfg; memcpy(secdat, &cfg_check_data, sizeof(cfg_check_data)); offset += sizeof(cfg_check_data); /* Copy structure by structure */ while (sz_bcfg > 0 || sz_cfg > 0) { /* Copy S1l Configuration structure */ if (sz_cfg > 0) { UNS_32 tmp = sz_cfg > (pg_sz - offset) ? pg_sz - offset : sz_cfg; memcpy((UNS_8 *)secdat + offset, ptr_cfg, tmp); sz_cfg -= tmp; offset += tmp; ptr_cfg += tmp; } /* Copy Board configuration structure */ if (sz_bcfg > 0 && offset < pg_sz) { UNS_32 tmp = sz_bcfg > (pg_sz - offset) ? pg_sz - offset : sz_bcfg; memcpy((UNS_8 *)secdat + offset, ptr_bcfg, tmp); sz_bcfg -= tmp; offset += tmp; ptr_bcfg += tmp; } if (offset >= pg_sz || (sz_bcfg <= 0 && sz_cfg <= 0)) { sector = conv_to_sector(blk, page); if(flash_write_sector(sector, secdat, NULL) < 0) return FALSE; page ++; offset = 0; } } return TRUE; } else { adjusted_num_blocks ++; // sysinfo.sysrtcfg.bl_num_blks = adjusted_num_blocks; } blk ++; } return FALSE; }