Micron MT29F NAND driver
|
00001 00030 #include <string.h> 00031 00032 #ifdef TIMEOUT_SUPPORT 00033 #include <time.h> 00034 #endif 00035 00036 #include "nand_MT29F_lld.h" 00037 00038 /* uncomment this line to show the address translation */ 00039 /* #define DEBUG_PRINT_ADDRESS */ 00040 00041 /* state of the driver */ 00042 MT_uint8 driver_status = DRIVER_STATUS_NOT_INITIALIZED; 00043 00044 /* global structure with device info */ 00045 struct parameter_page_t device_info; 00046 00047 /****************************************************************************** 00048 * Internal functions, not API 00049 *****************************************************************************/ 00050 00051 /* Address comparison constants */ 00052 #define ADDR_A_EQ_B 0 /* A = B */ 00053 #define ADDR_A_LT_B 1 /* A < B */ 00054 #define ADDR_A_GT_B 2 /* A > B */ 00055 00056 /* Internal functions */ 00057 MT_uint16 __as_uint16(MT_uint8 byte0, MT_uint8 byte1); 00058 MT_uint32 __as_uint32(MT_uint8 byte0, MT_uint8 byte1, MT_uint8 byte2, MT_uint8 byte3); 00059 void __as_string(MT_uint8 *src_ptr, char *dest_ptr, int start, int stop); 00060 MT_uint8 __wait_for_ready(); 00061 MT_uint8 __is_valid_addr(nand_addr_t addr); 00062 MT_uint8 __compare_addr(nand_addr_t first_addr, nand_addr_t second_addr); 00063 void __build_cycle_addr(nand_addr_t addr, MT_uint8 *addr_cycle_stream); 00064 00065 /****************************************************************************** 00066 * NAND Low Level Driver Functions 00067 *****************************************************************************/ 00068 00084 MT_uint8 Init_Driver(void) { 00085 flash_width onfi_signature[ONFI_SIGNATURE_LENGHT]; 00086 00087 /* check if the driver is previously initialized */ 00088 if(DRIVER_STATUS_INITIALIZED == driver_status) 00089 return DRIVER_STATUS_INITIALIZED; 00090 00091 /* initialize platform */ 00092 PLATFORM_Init(); 00093 00094 /* reset at startup is mandatory */ 00095 NAND_Reset(); 00096 00097 /* read if this device is ONFI complaint */ 00098 NAND_Read_ID_ONFI(onfi_signature); 00099 00100 /* verify ONFI signature in the first field of parameter page */ 00101 if(strcmp((const char *)onfi_signature, "ONFI") && 00102 (NAND_BAD_PARAMETER_PAGE != NAND_Read_Param_Page(&device_info))) 00103 driver_status = DRIVER_STATUS_INITIALIZED; 00104 00105 return driver_status; 00106 } 00107 00108 00123 MT_uint8 NAND_Reset(void) { 00124 MT_uint8 ret; 00125 00126 /* init board transfer */ 00127 PLATFORM_Open(); 00128 00129 /* send command and/or address */ 00130 PLATFORM_SendCmd(CMD_RESET); 00131 00132 /* wait (see datasheet for details) */ 00133 PLATFORM_Wait(TIME_WB); 00134 ret = __wait_for_ready(); 00135 00136 /* close board transfer */ 00137 PLATFORM_Close(); 00138 00139 return ret; 00140 } 00141 00160 MT_uint8 NAND_Read_ID(flash_width *buffer) { 00161 int i; 00162 00163 /* verify if driver is initialized */ 00164 if(DRIVER_STATUS_INITIALIZED != driver_status) 00165 return DRIVER_STATUS_NOT_INITIALIZED; 00166 00167 /* init board transfer */ 00168 PLATFORM_Open(); 00169 00170 /* send command and/or address */ 00171 PLATFORM_SendCmd(CMD_READID); 00172 PLATFORM_SendAddr(ADDR_READ_ID); 00173 00174 /* wait (see datasheet for details) */ 00175 PLATFORM_Wait(TIME_WHR); 00176 00177 /* read output */ 00178 for(i=0; i<NUM_OF_READID_BYTES; i++) 00179 buffer[i] = PLATFORM_ReadData(); 00180 00181 /* close board transfer */ 00182 PLATFORM_Close(); 00183 00184 return NAND_SUCCESS; 00185 } 00186 00205 MT_uint8 NAND_Read_ID_ONFI(flash_width *buffer) { 00206 MT_uint32 i; 00207 00208 /* init board transfer */ 00209 PLATFORM_Open(); 00210 00211 /* send command and/or address */ 00212 PLATFORM_SendCmd(CMD_READID); 00213 PLATFORM_SendAddr(ADDR_READ_ID_ONFI); 00214 00215 /* wait (see datasheet for details) */ 00216 PLATFORM_Wait(TIME_WHR); 00217 00218 /* read output */ 00219 for(i=0; i<NUM_OF_READIDONFI_BYTES; i++) 00220 buffer[i] = PLATFORM_ReadData(); 00221 00222 /* close board transfer */ 00223 PLATFORM_Close(); 00224 00225 return NAND_SUCCESS; 00226 } 00227 00249 MT_uint8 NAND_Read_Param_Page(param_page_t *ppage) { 00250 MT_uint8 rbuf[NUM_OF_PPAGE_BYTES]; 00251 MT_uint8 ret; 00252 MT_uint32 i; 00253 00254 /* init board transfer */ 00255 PLATFORM_Open(); 00256 00257 /* send command and/or address */ 00258 PLATFORM_SendCmd(CMD_READ_PARAM_PAGE); 00259 PLATFORM_SendAddr(ADDR_PARAM_PAGE); 00260 00261 /* wait (see datasheet for details) */ 00262 PLATFORM_Wait(TIME_WB); 00263 ret = __wait_for_ready(); 00264 00265 /* return if timeout */ 00266 if (NAND_SUCCESS != ret) 00267 return ret; 00268 00269 /* read output */ 00270 for(i=0; i<NUM_OF_PPAGE_BYTES; i++) 00271 rbuf[i] = PLATFORM_ReadData(); 00272 00273 /* close board transfer */ 00274 PLATFORM_Close(); 00275 00276 /* 00277 * Fill the parameter page data structure in the right way 00278 */ 00279 00280 /* Parameter page signature (ONFI) */ 00281 __as_string(rbuf, ppage->signature, 0, 3); 00282 00283 /* check if the buffer contains a valid ONFI parameter page */ 00284 if (strcmp(ppage->signature, "ONFI")) 00285 return NAND_BAD_PARAMETER_PAGE; 00286 00287 /* Revision number */ 00288 ppage->rev_num = __as_uint16(rbuf[4], rbuf[5]); 00289 00290 /* Features supported */ 00291 ppage->feature = __as_uint16(rbuf[6], rbuf[7]); 00292 00293 /* Optional commands supported */ 00294 ppage->command = __as_uint16(rbuf[8], rbuf[9]); 00295 00296 /* Device manufacturer */ 00297 __as_string(rbuf, ppage->manufacturer, 32, 43); 00298 00299 /* Device part number */ 00300 __as_string(rbuf, ppage->model, 44, 63); 00301 00302 /* Manufacturer ID (Micron = 2Ch) */ 00303 ppage->jedec_id = rbuf[64]; 00304 00305 /* Date code */ 00306 ppage->date_code = __as_uint16(rbuf[65], rbuf[66]); 00307 00308 /* Number of data bytes per page */ 00309 ppage->data_bytes_per_page = __as_uint32(rbuf[80], rbuf[81], rbuf[82], rbuf[83]); 00310 00311 /* Number of spare bytes per page */ 00312 ppage->spare_bytes_per_page = __as_uint16(rbuf[84], rbuf[85]); 00313 00314 /* Number of data bytes per partial page */ 00315 ppage->data_bytes_per_partial_page = __as_uint32(rbuf[86], rbuf[87], rbuf[88], rbuf[89]); 00316 00317 /* Number of spare bytes per partial page */ 00318 ppage->spare_bytes_per_partial_page = __as_uint16(rbuf[90], rbuf[91]); 00319 00320 /* Number of pages per block */ 00321 ppage->pages_per_block = __as_uint32(rbuf[92], rbuf[93], rbuf[94], rbuf[95]); 00322 00323 /* Number of blocks per unit */ 00324 ppage->blocks_per_lun = __as_uint32(rbuf[96], rbuf[97], rbuf[98], rbuf[99]); 00325 00326 /* Number of logical units (LUN) per chip enable */ 00327 ppage->luns_per_ce = rbuf[100]; 00328 00329 /* Number of address cycles */ 00330 ppage->num_addr_cycles = rbuf[101]; 00331 00332 /* Number of bits per cell (1 = SLC; >1= MLC) */ 00333 ppage->bit_per_cell = rbuf[102]; 00334 00335 /* Bad blocks maximum per unit */ 00336 ppage->max_bad_blocks_per_lun = __as_uint16(rbuf[103], rbuf[104]); 00337 00338 /* Block endurance */ 00339 ppage->block_endurance = __as_uint16(rbuf[105], rbuf[106]); 00340 00341 /* Guaranteed valid blocks at beginning of target */ 00342 ppage->guarenteed_valid_blocks = rbuf[107]; 00343 00344 /* Block endurance for guaranteed valid blocks */ 00345 ppage->guarenteed_valid_blocks = __as_uint16(rbuf[108], rbuf[109]); 00346 00347 /* Number of programs per page */ 00348 ppage->num_programs_per_page = rbuf[110]; 00349 00350 /* Partial programming attributes */ 00351 ppage->partial_prog_attr = rbuf[111]; 00352 00353 /* Number of bits ECC bits */ 00354 ppage->num_ECC_bits_correctable = rbuf[112]; 00355 00356 /* Number of interleaved address bits */ 00357 ppage->num_interleaved_addr_bits = rbuf[113]; 00358 00359 /* Interleaved operation attributes */ 00360 ppage->interleaved_op_attr = rbuf[114]; 00361 00362 return ret; 00363 } 00364 00387 MT_uint8 NAND_Set_Feature(flash_width feature_address, flash_width subfeature) { 00388 MT_uint8 ret; 00389 00390 /* verify if driver is initialized */ 00391 if(DRIVER_STATUS_INITIALIZED != driver_status) 00392 return DRIVER_STATUS_NOT_INITIALIZED; 00393 00394 /* check if this feature/command is supported */ 00395 if ((device_info.command & OPTIONAL_CMD_GET_FEATURES_AND_SET_FEATURES) == 0) 00396 return NAND_UNSUPPORTED; 00397 00398 /* init board transfer */ 00399 PLATFORM_Open(); 00400 00401 /* send command and/or address */ 00402 PLATFORM_SendCmd(CMD_SET_FEATURE); 00403 PLATFORM_SendAddr(feature_address); 00404 00405 /* wait (see datasheet for details) */ 00406 PLATFORM_Wait(TIME_ADL); 00407 00408 /* send sub-feature parameter */ 00409 PLATFORM_SendData(subfeature); /* p0 */ 00410 PLATFORM_SendData(0x00); /* p1 reserved */ 00411 PLATFORM_SendData(0x00); /* p2 reserved */ 00412 PLATFORM_SendData(0x00); /* p3 reserved */ 00413 00414 PLATFORM_Wait(TIME_WB); 00415 ret = __wait_for_ready(); 00416 00417 /* return if timeout */ 00418 if (NAND_SUCCESS != ret) 00419 return ret; 00420 00421 /* close board transfer */ 00422 PLATFORM_Close(); 00423 00424 return ret; 00425 } 00426 00448 MT_uint8 NAND_Get_Feature(flash_width feature_address, flash_width *subfeature) { 00449 flash_width ret; 00450 00451 /* verify if driver is initialized */ 00452 if(DRIVER_STATUS_INITIALIZED != driver_status) 00453 return DRIVER_STATUS_NOT_INITIALIZED; 00454 00455 /* check if this feature/command is supported */ 00456 if ((device_info.command & OPTIONAL_CMD_GET_FEATURES_AND_SET_FEATURES) == 0) 00457 return NAND_UNSUPPORTED; 00458 00459 /* init board transfer */ 00460 PLATFORM_Open(); 00461 00462 /* send command and/or address */ 00463 PLATFORM_SendCmd(CMD_GET_FEATURE); 00464 PLATFORM_SendAddr(feature_address); 00465 00466 /* wait (see datasheet for details) */ 00467 PLATFORM_Wait(TIME_WB); 00468 ret = __wait_for_ready(); 00469 00470 /* return if timeout */ 00471 if (NAND_SUCCESS != ret) 00472 return ret; 00473 00474 /* send sub-feature parameter */ 00475 *subfeature = PLATFORM_ReadData(); /* p0 */ 00476 /* 00477 * skip p1, p2 and p3 because they are reserved and their value are 00h 00478 */ 00479 00480 /* close board transfer */ 00481 PLATFORM_Close(); 00482 00483 return ret; 00484 } 00485 00501 flash_width NAND_Read_Status() { 00502 flash_width ret; 00503 00504 /* verify if driver is initialized */ 00505 if(DRIVER_STATUS_INITIALIZED != driver_status) 00506 return DRIVER_STATUS_NOT_INITIALIZED; 00507 00508 /* init board transfer */ 00509 PLATFORM_Open(); 00510 00511 /* send command and/or address */ 00512 PLATFORM_SendCmd(CMD_READ_STATUS); 00513 00514 /* wait */ 00515 PLATFORM_Wait(TIME_WHR); 00516 00517 /* read value */ 00518 ret = PLATFORM_ReadData(); 00519 00520 /* close board transfer */ 00521 PLATFORM_Close(); 00522 00523 return ret; 00524 } 00525 00543 flash_width NAND_Read_Status_Enhanced(nand_addr_t addr) { 00544 flash_width ret; 00545 MT_uint8 row_address[5]; 00546 00547 /* verify if driver is initialized */ 00548 if(DRIVER_STATUS_INITIALIZED != driver_status) 00549 return DRIVER_STATUS_NOT_INITIALIZED; 00550 00551 /* check input parameters */ 00552 if(NAND_SUCCESS != __is_valid_addr(addr)) 00553 return NAND_INVALID_NAND_ADDRESS; 00554 00555 /* check if this feature/command is supported */ 00556 if ((device_info.command & OPTIONAL_CMD_READ_STATUS_ENHANCED) == 0) 00557 return NAND_UNSUPPORTED; 00558 00559 __build_cycle_addr(addr, row_address); 00560 00561 /* init board transfer */ 00562 PLATFORM_Open(); 00563 00564 /* send command */ 00565 PLATFORM_SendCmd(CMD_READ_STATUS_ENHANCED); 00566 00567 /* send row address (3rd, 4th, 5th cycle) */ 00568 PLATFORM_SendAddr(row_address[2]); 00569 PLATFORM_SendAddr(row_address[3]); 00570 PLATFORM_SendAddr(row_address[4]); 00571 00572 /* wait */ 00573 PLATFORM_Wait(TIME_WHR); 00574 00575 /* read value */ 00576 ret = PLATFORM_ReadData(); 00577 00578 /* close board transfer */ 00579 PLATFORM_Close(); 00580 00581 return ret; 00582 } 00583 00605 MT_uint8 NAND_Block_Erase(nand_addr_t addr) { 00606 MT_uint8 row_address[5]; 00607 MT_uint8 status_reg; 00608 MT_uint8 ret; 00609 00610 /* verify if driver is initialized */ 00611 if(DRIVER_STATUS_INITIALIZED != driver_status) 00612 return DRIVER_STATUS_NOT_INITIALIZED; 00613 00614 /* check input parameters */ 00615 if(NAND_SUCCESS != __is_valid_addr(addr)) 00616 return NAND_INVALID_NAND_ADDRESS; 00617 00618 __build_cycle_addr(addr, row_address); 00619 00620 /* init board transfer */ 00621 PLATFORM_Open(); 00622 00623 /* send command */ 00624 PLATFORM_SendCmd(CMD_ERASE_BLOCK); 00625 00626 /* send row address (3rd, 4th, 5th cycle) */ 00627 PLATFORM_SendAddr(row_address[2]); 00628 PLATFORM_SendAddr(row_address[3]); 00629 PLATFORM_SendAddr(row_address[4]); 00630 00631 /* send confirm command */ 00632 PLATFORM_SendCmd(CMD_ERASE_BLOCK_CONFIRM); 00633 00634 /* wait */ 00635 PLATFORM_Wait(TIME_WB); 00636 ret = __wait_for_ready(); 00637 00638 /* return if timeout occurs */ 00639 if (NAND_SUCCESS != ret) 00640 return ret; 00641 00642 status_reg = NAND_Read_Status(); 00643 00644 /* close board transfer */ 00645 PLATFORM_Close(); 00646 00647 /* check if erase is good */ 00648 if(!(status_reg & STATUS_WRITE_PROTECTED)) 00649 return NAND_ERASE_FAILED_WRITE_PROTECT; 00650 00651 if(status_reg & STATUS_FAIL) 00652 return NAND_ERASE_FAILED; 00653 00654 return ret; 00655 } 00656 00683 MT_uint8 NAND_Page_Read(nand_addr_t addr, flash_width *buffer, MT_uint32 lenght) { 00684 MT_uint8 row_address[5]; 00685 MT_uint8 status_reg; 00686 MT_uint8 ret; 00687 int i; 00688 00689 /* verify if driver is initialized */ 00690 if(DRIVER_STATUS_INITIALIZED != driver_status) 00691 return DRIVER_STATUS_NOT_INITIALIZED; 00692 00693 /* check input parameters */ 00694 if(NAND_SUCCESS != __is_valid_addr(addr)) 00695 return NAND_INVALID_NAND_ADDRESS; 00696 00697 /* x16 */ 00698 if((device_info.feature & SUPPORTED_16_BIT_DATA_BUS_WIDTH) != 0) { 00699 if(lenght > (device_info.data_bytes_per_page >> 1) ) 00700 return NAND_INVALID_LENGHT; 00701 } 00702 00703 /* x8 */ 00704 if(lenght > device_info.data_bytes_per_page) 00705 return NAND_INVALID_LENGHT; 00706 00707 __build_cycle_addr(addr, row_address); 00708 00709 /* init board transfer */ 00710 PLATFORM_Open(); 00711 00712 /* send command */ 00713 PLATFORM_SendCmd(CMD_READ_MODE); 00714 00715 /* send address */ 00716 for(i=0; i<NUM_OF_ADDR_CYCLE; i++) 00717 PLATFORM_SendAddr(row_address[i]); 00718 00719 /* return to read mode */ 00720 PLATFORM_SendCmd(CMD_READ_CONFIRM); 00721 00722 /* wait */ 00723 ret = __wait_for_ready(); 00724 00725 /* return if timeout */ 00726 if (NAND_SUCCESS != ret) 00727 return ret; 00728 00729 /* read data */ 00730 for(i=0; i<lenght; i++) 00731 buffer[i] = PLATFORM_ReadData(); 00732 00733 /* read status register on exit */ 00734 status_reg = NAND_Read_Status(); 00735 00736 /* close board transfer */ 00737 PLATFORM_Close(); 00738 00739 if(status_reg & STATUS_FAIL) 00740 return NAND_READ_FAILED; 00741 00742 return ret; 00743 } 00744 00773 MT_uint8 NAND_Page_Program(nand_addr_t addr, flash_width *buffer, MT_uint32 lenght) { 00774 MT_uint8 address[5]; 00775 MT_uint8 status_reg; 00776 MT_uint32 k; 00777 int i; 00778 00779 /* verify if driver is initialized */ 00780 if(DRIVER_STATUS_INITIALIZED != driver_status) 00781 return DRIVER_STATUS_NOT_INITIALIZED; 00782 00783 /* check input parameters */ 00784 if(NAND_SUCCESS != __is_valid_addr(addr)) 00785 return NAND_INVALID_NAND_ADDRESS; 00786 00787 /* x16 */ 00788 if((device_info.feature & SUPPORTED_16_BIT_DATA_BUS_WIDTH) != 0) { 00789 if(lenght > (device_info.data_bytes_per_page >> 1) ) 00790 return NAND_INVALID_LENGHT; 00791 } 00792 00793 /* x8 */ 00794 if(lenght > device_info.data_bytes_per_page) 00795 return NAND_INVALID_LENGHT; 00796 00797 __build_cycle_addr(addr, address); 00798 00799 /* init board transfer */ 00800 PLATFORM_Open(); 00801 00802 /* send command */ 00803 PLATFORM_SendCmd(CMD_PAGE_PROGRAM); 00804 00805 /* send address */ 00806 for(i=0; i<NUM_OF_ADDR_CYCLE; i++) 00807 PLATFORM_SendAddr(address[i]); 00808 00809 /* send data */ 00810 for(k=0; k<lenght; k++) 00811 PLATFORM_SendData(buffer[k]); 00812 00813 /* send command */ 00814 PLATFORM_SendCmd(CMD_PAGE_PROGRAM_CONFIRM); 00815 00816 status_reg = NAND_Read_Status(); 00817 00818 /* close board transfer */ 00819 PLATFORM_Close(); 00820 00821 /* check if program is good */ 00822 if(!(status_reg & STATUS_WRITE_PROTECTED)) 00823 return NAND_PROGRAM_FAILED_WRITE_PROTECT; 00824 00825 if(status_reg & STATUS_FAIL) 00826 return NAND_PROGRAM_FAILED; 00827 00828 return NAND_SUCCESS; 00829 } 00830 00858 MT_uint8 NAND_Spare_Read(nand_addr_t addr, flash_width *buffer, MT_uint32 lenght) { 00859 MT_uint8 row_address[5]; 00860 MT_uint8 status_reg; 00861 MT_uint8 ret; 00862 MT_uint32 k; 00863 int i; 00864 00865 /* verify if driver is initialized */ 00866 if(DRIVER_STATUS_INITIALIZED != driver_status) 00867 return DRIVER_STATUS_NOT_INITIALIZED; 00868 00869 /* check input parameters */ 00870 if(NAND_SUCCESS != __is_valid_addr(addr)) 00871 return NAND_INVALID_NAND_ADDRESS; 00872 00873 if((device_info.feature & SUPPORTED_16_BIT_DATA_BUS_WIDTH) != 0) { 00874 /* x16 */ 00875 if(lenght > (device_info.spare_bytes_per_page >> 1) ) 00876 return NAND_INVALID_LENGHT; 00877 } 00878 00879 /* x8 */ 00880 if(lenght > device_info.spare_bytes_per_page) 00881 return NAND_INVALID_LENGHT; 00882 00883 /* spare area starts after last main area byte */ 00884 if((device_info.feature & SUPPORTED_16_BIT_DATA_BUS_WIDTH) == 0) 00885 /* x8 bus width */ 00886 addr.column=device_info.data_bytes_per_page; 00887 else 00888 /* x16 bus width */ 00889 addr.column=device_info.data_bytes_per_page >> 1; 00890 00891 __build_cycle_addr(addr, row_address); 00892 00893 /* init board transfer */ 00894 PLATFORM_Open(); 00895 00896 /* send command */ 00897 PLATFORM_SendCmd(CMD_READ_MODE); 00898 00899 /* send address */ 00900 for(i=0; i<NUM_OF_ADDR_CYCLE; i++) 00901 PLATFORM_SendAddr(row_address[i]); 00902 00903 /* return to read mode */ 00904 PLATFORM_SendCmd(CMD_READ_CONFIRM); 00905 00906 /* wait */ 00907 ret = __wait_for_ready(); 00908 00909 /* return if timeout */ 00910 if (NAND_SUCCESS != ret) 00911 return ret; 00912 00913 /* read data */ 00914 for(k=0; k<lenght; k++) 00915 buffer[k] = PLATFORM_ReadData(); 00916 00917 /* read status register on exit */ 00918 status_reg = NAND_Read_Status(); 00919 00920 /* close board transfer */ 00921 PLATFORM_Close(); 00922 00923 if(status_reg & STATUS_FAIL) 00924 return NAND_READ_FAILED; 00925 00926 return ret; 00927 } 00928 00956 MT_uint8 NAND_Spare_Program(nand_addr_t addr, flash_width *buffer, MT_uint32 lenght) { 00957 MT_uint8 address[5]; 00958 MT_uint8 status_reg; 00959 MT_uint32 k; 00960 int i; 00961 00962 /* verify if driver is initialized */ 00963 if(DRIVER_STATUS_INITIALIZED != driver_status) 00964 return DRIVER_STATUS_NOT_INITIALIZED; 00965 00966 /* check input parameters */ 00967 if(NAND_SUCCESS != __is_valid_addr(addr)) 00968 return NAND_INVALID_NAND_ADDRESS; 00969 00970 if((device_info.feature & SUPPORTED_16_BIT_DATA_BUS_WIDTH) != 0) { 00971 /* x16 */ 00972 if(lenght > (device_info.spare_bytes_per_page >> 1) ) 00973 return NAND_INVALID_LENGHT; 00974 } 00975 00976 /* x8 */ 00977 if(lenght > device_info.spare_bytes_per_page) 00978 return NAND_INVALID_LENGHT; 00979 00980 /* spare area starts after last main area byte */ 00981 if((device_info.feature & SUPPORTED_16_BIT_DATA_BUS_WIDTH) == 0) 00982 /* x8 bus width */ 00983 addr.column=device_info.data_bytes_per_page; 00984 else 00985 /* x16 bus width */ 00986 addr.column=device_info.data_bytes_per_page >> 1; 00987 00988 __build_cycle_addr(addr, address); 00989 00990 /* init board transfer */ 00991 PLATFORM_Open(); 00992 00993 /* send command */ 00994 PLATFORM_SendCmd(CMD_PAGE_PROGRAM); 00995 00996 /* send address */ 00997 for(i=0; i<NUM_OF_ADDR_CYCLE; i++) 00998 PLATFORM_SendAddr(address[i]); 00999 01000 /* send data */ 01001 for(k=0; k<lenght; k++) 01002 PLATFORM_SendData(buffer[k]); 01003 01004 /* send command */ 01005 PLATFORM_SendCmd(CMD_PAGE_PROGRAM_CONFIRM); 01006 01007 status_reg = NAND_Read_Status(); 01008 01009 /* close board transfer */ 01010 PLATFORM_Close(); 01011 01012 /* check if program is good */ 01013 if(!(status_reg & STATUS_WRITE_PROTECTED)) 01014 return NAND_PROGRAM_FAILED_WRITE_PROTECT; 01015 01016 if(status_reg & STATUS_FAIL) 01017 return NAND_PROGRAM_FAILED; 01018 01019 return NAND_SUCCESS; 01020 } 01021 01022 /* 01023 * NAND_Read_Unique_Id 01024 */ 01025 MT_uint8 NAND_Read_Unique_Id(flash_width *buffer) { 01026 01027 int i; 01028 MT_uint8 ret; 01029 01030 /* verify if driver is initialized */ 01031 if(DRIVER_STATUS_INITIALIZED != driver_status) 01032 return DRIVER_STATUS_NOT_INITIALIZED; 01033 01034 /* init board transfer */ 01035 PLATFORM_Open(); 01036 01037 /* send command and/or address */ 01038 PLATFORM_SendCmd(CMD_READ_UNIQ_ID); 01039 PLATFORM_SendAddr(ADDR_READ_UNIQ_ID); 01040 01041 /* wait (see datasheet for details) */ 01042 PLATFORM_Wait(TIME_WB); 01043 01044 ret = __wait_for_ready(); 01045 01046 /* return if timeout */ 01047 if (NAND_SUCCESS != ret) 01048 return ret; 01049 01050 /* read output */ 01051 for(i=0; i<NUM_OF_UNIQUEID_BYTES; i++) 01052 buffer[i] = (MT_uint8) PLATFORM_ReadData(); 01053 01054 /* close board transfer */ 01055 PLATFORM_Close(); 01056 01057 return NAND_SUCCESS; 01058 01059 } 01060 01090 MT_uint8 NAND_Copy_Back(nand_addr_t src_addr, nand_addr_t dest_addr) { 01091 MT_uint8 src_address_stream[NUM_OF_ADDR_CYCLE]; 01092 MT_uint8 dest_address_stream[NUM_OF_ADDR_CYCLE]; 01093 MT_uint8 status_reg; 01094 MT_uint8 ret; 01095 MT_uint32 k; 01096 int i; 01097 01098 /* verify if driver is initialized */ 01099 if(DRIVER_STATUS_INITIALIZED != driver_status) 01100 return driver_status; 01101 01102 /* check if this feature/command is supported */ 01103 if ((device_info.command & OPTIONAL_CMD_COPYBACK) == 0) 01104 return NAND_UNSUPPORTED; 01105 01106 /* check input parameters */ 01107 if((NAND_SUCCESS != __is_valid_addr(src_addr)) || (NAND_SUCCESS != __is_valid_addr(dest_addr))) 01108 return NAND_INVALID_NAND_ADDRESS; 01109 01110 /* check if the source and destination address are the same */ 01111 if(!__compare_addr(src_addr, dest_addr)) 01112 return NAND_INVALID_NAND_ADDRESS; 01113 01114 /* check if odd to even copy back is supported */ 01115 if ((device_info.command & SUPPORTED_ODD_TO_EVEN_PAGE_COPYBACK) == 0) { 01116 if(((src_addr.page & 1) != 0) && ((dest_addr.page & 1) == 0)) 01117 return NAND_INVALID_NAND_ADDRESS; 01118 if(((src_addr.page & 1) == 0) && ((dest_addr.page & 1) != 0)) 01119 return NAND_INVALID_NAND_ADDRESS; 01120 } 01121 01122 /* copy back allows to move data from one page to another on the same plane */ 01123 if(((src_addr.block & 1) != 0) && ((dest_addr.block & 1) == 0)) 01124 return NAND_INVALID_NAND_ADDRESS; 01125 if(((src_addr.block & 1) == 0) && ((dest_addr.block & 1) != 0)) 01126 return NAND_INVALID_NAND_ADDRESS; 01127 01128 /* copy back is allowed only at the start of a page (ignoring column) */ 01129 src_addr.column = 0; 01130 dest_addr.column = 0; 01131 01132 /* build address cycles for source and destination address */ 01133 __build_cycle_addr(src_addr, src_address_stream); 01134 __build_cycle_addr(dest_addr, dest_address_stream); 01135 01136 /* init board transfer */ 01137 PLATFORM_Open(); 01138 01139 /* send command */ 01140 PLATFORM_SendCmd(CMD_READ_MODE); 01141 01142 /* send source address */ 01143 for(i=0; i<NUM_OF_ADDR_CYCLE; i++) 01144 PLATFORM_SendAddr(src_address_stream[i]); 01145 01146 /* read for internal data move */ 01147 01148 /* send command */ 01149 PLATFORM_SendCmd(CMD_READ_INTERNAL_DATA_MOVE); 01150 01151 /* wait (see datasheet for details) */ 01152 PLATFORM_Wait(TIME_WB); 01153 ret = __wait_for_ready(); 01154 01155 /* return if timeout */ 01156 if (NAND_SUCCESS != ret) 01157 return ret; 01158 01159 /* program for internal data move */ 01160 01161 /* send command */ 01162 PLATFORM_SendCmd(CMD_PROGRAM_INTERNAL_DATA_MOVE); 01163 01164 /* send destination address */ 01165 for(i=0; i<NUM_OF_ADDR_CYCLE; i++) 01166 PLATFORM_SendAddr(dest_address_stream[i]); 01167 01168 PLATFORM_SendCmd(CMD_PAGE_PROGRAM_CONFIRM); 01169 01170 /* wait (see datasheet for details) */ 01171 PLATFORM_Wait(TIME_WB); 01172 ret = __wait_for_ready(); 01173 01174 /* return if timeout */ 01175 if (NAND_SUCCESS != ret) 01176 return ret; 01177 01178 status_reg = NAND_Read_Status(); 01179 01180 /* close board transfer */ 01181 PLATFORM_Close(); 01182 01183 /* check if program is good */ 01184 if(!(status_reg & STATUS_WRITE_PROTECTED)) 01185 return NAND_PROGRAM_FAILED_WRITE_PROTECT; 01186 01187 if(status_reg & STATUS_FAIL) 01188 return NAND_PROGRAM_FAILED; 01189 01190 return ret; 01191 } 01192 01193 /* 01194 * NAND_Multiplane_Copy_Back 01195 */ 01196 MT_uint8 NAND_Multiplane_Copy_Back(void) { 01197 01198 /* 01199 * TO BE IMPLEMENTED 01200 * 01201 * Please contact Micron support for any request 01202 */ 01203 01204 return NAND_UNIMPLEMENTED; 01205 01206 } 01207 01208 /* 01209 * NAND_Cache_Read 01210 */ 01211 MT_uint8 NAND_Cache_Read(void) { 01212 01213 /* 01214 * TO BE IMPLEMENTED 01215 * 01216 * Please contact Micron support for any request 01217 */ 01218 01219 return NAND_UNIMPLEMENTED; 01220 01221 } 01222 01223 /* 01224 * NAND_Cache_Program 01225 */ 01226 MT_uint8 NAND_Cache_Program(void) { 01227 01228 /* 01229 * TO BE IMPLEMENTED 01230 * 01231 * Please contact Micron support for any request 01232 */ 01233 01234 return NAND_UNIMPLEMENTED; 01235 01236 } 01237 01238 /* 01239 * NAND_Multiplane_Page_Program 01240 */ 01241 MT_uint8 NAND_Multiplane_Page_Program(void) { 01242 01243 /* 01244 * TO BE IMPLEMENTED 01245 * 01246 * Please contact Micron support for any request 01247 */ 01248 01249 return NAND_UNIMPLEMENTED; 01250 01251 } 01252 01253 /* 01254 * NAND_Multiplane_Block_Erase 01255 */ 01256 MT_uint8 NAND_Multiplane_Block_Erase(void) { 01257 01258 /* 01259 * TO BE IMPLEMENTED 01260 * 01261 * Please contact Micron support for any request 01262 */ 01263 01264 return NAND_UNIMPLEMENTED; 01265 01266 } 01267 01281 MT_uint8 NAND_Lock(void) { 01282 01283 /* verify if driver is initialized */ 01284 if(DRIVER_STATUS_INITIALIZED != driver_status) 01285 return DRIVER_STATUS_NOT_INITIALIZED; 01286 01287 /* init board transfer */ 01288 PLATFORM_Open(); 01289 01290 /* send command */ 01291 PLATFORM_SendCmd(CMD_LOCK); 01292 01293 /* close board transfer */ 01294 PLATFORM_Close(); 01295 01296 return NAND_SUCCESS; 01297 } 01298 01320 MT_uint8 NAND_Unlock(nand_addr_t start_block, nand_addr_t end_block) { 01321 MT_uint8 start_address_stream[NUM_OF_ADDR_CYCLE]; 01322 MT_uint8 end_address_stream[NUM_OF_ADDR_CYCLE]; 01323 01324 /* verify if driver is initialized */ 01325 if(DRIVER_STATUS_INITIALIZED != driver_status) 01326 return DRIVER_STATUS_NOT_INITIALIZED; 01327 01328 /* check input parameters */ 01329 if((NAND_SUCCESS != __is_valid_addr(start_block)) || (NAND_SUCCESS != __is_valid_addr(end_block))) 01330 return NAND_INVALID_NAND_ADDRESS; 01331 01332 /* verify if start_block < end_block */ 01333 if(ADDR_A_GT_B == __compare_addr(start_block, end_block) ) 01334 return NAND_INVALID_NAND_ADDRESS; 01335 01336 /* build address cycles for start and end block */ 01337 __build_cycle_addr(start_block, start_address_stream); 01338 __build_cycle_addr(end_block, end_address_stream); 01339 01340 /* init board transfer */ 01341 PLATFORM_Open(); 01342 01343 /* send command */ 01344 PLATFORM_SendCmd(CMD_BLOCK_UNLOCK_LOW); 01345 01346 /* send row address (3rd, 4th, 5th cycle) */ 01347 PLATFORM_SendAddr(start_address_stream[2]); 01348 PLATFORM_SendAddr(start_address_stream[3]); 01349 PLATFORM_SendAddr(start_address_stream[4]); 01350 01351 /* send command */ 01352 PLATFORM_SendCmd(CMD_BLOCK_UNLOCK_HIGH); 01353 01354 /* send row address (3rd, 4th, 5th cycle) */ 01355 PLATFORM_SendAddr(end_address_stream[2]); 01356 PLATFORM_SendAddr(end_address_stream[3]); 01357 PLATFORM_SendAddr(end_address_stream[4]); 01358 01359 /* close board transfer */ 01360 PLATFORM_Close(); 01361 01362 return NAND_SUCCESS; 01363 01364 } 01365 01381 MT_uint8 NAND_Read_Lock_Status(nand_addr_t block_addr) { 01382 MT_uint8 block_addr_stream[NUM_OF_ADDR_CYCLE]; 01383 MT_uint8 block_lock_status_reg; 01384 01385 /* verify if driver is initialized */ 01386 if(DRIVER_STATUS_INITIALIZED != driver_status) 01387 return DRIVER_STATUS_NOT_INITIALIZED; 01388 01389 /* check input parameters */ 01390 if(NAND_SUCCESS != __is_valid_addr(block_addr)) 01391 return NAND_INVALID_NAND_ADDRESS; 01392 01393 /* build address cycles for block address */ 01394 __build_cycle_addr(block_addr, block_addr_stream); 01395 01396 /* init board transfer */ 01397 PLATFORM_Open(); 01398 01399 /* send command*/ 01400 PLATFORM_SendCmd(CMD_BLOCK_LOCK_READ_STATUS); 01401 01402 /* send row address (3rd, 4th, 5th cycle) */ 01403 PLATFORM_SendAddr(block_addr_stream[2]); 01404 PLATFORM_SendAddr(block_addr_stream[3]); 01405 PLATFORM_SendAddr(block_addr_stream[4]); 01406 01407 block_lock_status_reg = PLATFORM_ReadData(); 01408 01409 /* close board transfer */ 01410 PLATFORM_Close(); 01411 01412 /* return the value of block status register */ 01413 return block_lock_status_reg; 01414 01415 } 01416 01417 /* 01418 * NAND_Lock_Down 01419 */ 01420 MT_uint8 NAND_Lock_Down(void) { 01421 01422 /* 01423 * TO BE IMPLEMENTED 01424 * 01425 * Please contact Micron support for any request 01426 */ 01427 01428 return NAND_UNIMPLEMENTED; 01429 01430 } 01431 01432 /* 01433 * NAND_Unlock_Down 01434 */ 01435 MT_uint8 NAND_Unlock_Down(void) { 01436 01437 /* 01438 * TO BE IMPLEMENTED 01439 * 01440 * Please contact Micron support for any request 01441 */ 01442 01443 return NAND_UNIMPLEMENTED; 01444 01445 } 01446 01447 /* 01448 * NAND_Enter_OTP_Mode 01449 */ 01450 01470 MT_uint8 NAND_OTP_Mode_Enter(void) { 01471 MT_uint8 ret; 01472 flash_width subfeature; 01473 01474 /* check if driver is in a valid state */ 01475 if(DRIVER_STATUS_INITIALIZED != driver_status) 01476 return DRIVER_STATUS_NOT_INITIALIZED; 01477 01478 /* check if device is NOT in OTP status */ 01479 ret = NAND_Get_Feature(ADDR_FEATURE_ARRAY_OPMODE, &subfeature); 01480 01481 if((FEATURE_ARRAY_NORMAL != subfeature) && (FEATURE_ARRAY_OTP_PROTECTION != subfeature)) 01482 return NAND_GENERIC_FAIL; 01483 01484 /* set OTP status */ 01485 ret = NAND_Set_Feature(ADDR_FEATURE_ARRAY_OPMODE, FEATURE_ARRAY_OTP_OPERATION); 01486 01487 /* return with error if a fail occurs */ 01488 if(NAND_SUCCESS != ret) 01489 return ret; 01490 01491 /* check if device is in OTP status */ 01492 ret = NAND_Get_Feature(ADDR_FEATURE_ARRAY_OPMODE, &subfeature); 01493 01494 /* return with error if a fail occurs */ 01495 if(NAND_SUCCESS != ret) 01496 return ret; 01497 01498 if(FEATURE_ARRAY_OTP_OPERATION != subfeature) 01499 return NAND_GENERIC_FAIL; 01500 01501 return NAND_SUCCESS; 01502 } 01503 01518 MT_uint8 NAND_OTP_Mode_Exit(void) { 01519 MT_uint8 ret; 01520 flash_width subfeature; 01521 01522 /* check if driver is in a valid state */ 01523 if(DRIVER_STATUS_INITIALIZED != driver_status) 01524 return DRIVER_STATUS_NOT_INITIALIZED; 01525 01526 /* check if device is NOT in normal status */ 01527 ret = NAND_Get_Feature(ADDR_FEATURE_ARRAY_OPMODE, &subfeature); 01528 01529 if((FEATURE_ARRAY_OTP_OPERATION != subfeature) && (FEATURE_ARRAY_OTP_PROTECTION != subfeature)) 01530 return NAND_GENERIC_FAIL; 01531 01532 /* exit OTP status */ 01533 ret = NAND_Set_Feature(ADDR_FEATURE_ARRAY_OPMODE, FEATURE_ARRAY_NORMAL); 01534 01535 /* return with error if a fail occurs */ 01536 if(NAND_SUCCESS != ret) 01537 return ret; 01538 01539 /* check if device is in normal status */ 01540 ret = NAND_Get_Feature(ADDR_FEATURE_ARRAY_OPMODE, &subfeature); 01541 01542 /* return with error if a fail occurs */ 01543 if(NAND_SUCCESS != ret) 01544 return ret; 01545 01546 if(FEATURE_ARRAY_NORMAL != subfeature) 01547 return NAND_GENERIC_FAIL; 01548 01549 return NAND_SUCCESS; 01550 } 01551 01569 MT_uint8 NAND_OTP_Mode_Protect(nand_addr_t addr) { 01570 MT_uint8 ret; 01571 flash_width subfeature; 01572 flash_width write_buf[device_info.data_bytes_per_page + device_info.spare_bytes_per_page]; 01573 01574 /* check if driver is in a valid state */ 01575 if(DRIVER_STATUS_INITIALIZED != driver_status) 01576 return DRIVER_STATUS_NOT_INITIALIZED; 01577 01578 /* check if device is NOT in normal status */ 01579 ret = NAND_Get_Feature(ADDR_FEATURE_ARRAY_OPMODE, &subfeature); 01580 01581 if(FEATURE_ARRAY_OTP_OPERATION != subfeature) 01582 return NAND_GENERIC_FAIL; 01583 01584 /* issue protect OTP area command */ 01585 ret = NAND_Set_Feature(ADDR_FEATURE_ARRAY_OPMODE, FEATURE_ARRAY_OTP_PROTECTION); 01586 01587 /* return with error if a fail occurs */ 01588 if(NAND_SUCCESS != ret) 01589 return ret; 01590 01591 /* check if device is in normal status */ 01592 ret = NAND_Get_Feature(ADDR_FEATURE_ARRAY_OPMODE, &subfeature); 01593 01594 /* return with error if a fail occurs */ 01595 if(NAND_SUCCESS != ret) 01596 return ret; 01597 01598 if(FEATURE_ARRAY_OTP_PROTECTION != subfeature) 01599 return NAND_GENERIC_FAIL; 01600 01601 /* issue the PROGRAM command to lock permanently the page */ 01602 01603 /* data buffer is filled with 0x00 */ 01604 memset(write_buf, 0x00, device_info.data_bytes_per_page); 01605 01606 /* x8 */ 01607 if((device_info.feature & SUPPORTED_16_BIT_DATA_BUS_WIDTH) == 0) 01608 ret = NAND_OTP_Page_Program(addr, write_buf, device_info.data_bytes_per_page); 01609 /* x16 */ 01610 else 01611 ret = NAND_OTP_Page_Program(addr, write_buf, (device_info.data_bytes_per_page>>2)); 01612 01613 if(NAND_SUCCESS != ret) { 01614 /* in case of program error, exit in OTP mode */ 01615 NAND_OTP_Mode_Enter(); 01616 return NAND_GENERIC_FAIL; 01617 } 01618 01619 /* restore OTP mode before return */ 01620 ret = NAND_OTP_Mode_Enter(); 01621 01622 if(NAND_SUCCESS != ret) 01623 return NAND_GENERIC_FAIL; 01624 01625 return NAND_SUCCESS; 01626 } 01627 01657 MT_uint8 NAND_OTP_Page_Program(nand_addr_t addr, flash_width *buffer, MT_uint32 lenght) { 01658 MT_uint8 address[5]; 01659 MT_uint8 status_reg; 01660 MT_uint32 k; 01661 int i; 01662 01663 /* verify if driver is initialized */ 01664 if(DRIVER_STATUS_INITIALIZED != driver_status) 01665 return DRIVER_STATUS_NOT_INITIALIZED; 01666 01667 /* x16 */ 01668 if((device_info.feature & SUPPORTED_16_BIT_DATA_BUS_WIDTH) != 0) { 01669 if(lenght > (device_info.data_bytes_per_page >> 1) ) 01670 return NAND_INVALID_LENGHT; 01671 } 01672 01673 /* x8 */ 01674 if(lenght > device_info.data_bytes_per_page) 01675 return NAND_INVALID_LENGHT; 01676 01677 __build_cycle_addr(addr, address); 01678 01679 /* init board transfer */ 01680 PLATFORM_Open(); 01681 01682 /* send command */ 01683 PLATFORM_SendCmd(CMD_PAGE_PROGRAM); 01684 01685 /* send address */ 01686 for(i=0; i<NUM_OF_ADDR_CYCLE; i++) 01687 PLATFORM_SendAddr(address[i]); 01688 01689 /* send data */ 01690 for(k=0; k<lenght; k++) 01691 PLATFORM_SendData(buffer[k]); 01692 01693 /* send command */ 01694 PLATFORM_SendCmd(CMD_PAGE_PROGRAM_CONFIRM); 01695 01696 status_reg = NAND_Read_Status(); 01697 01698 /* close board transfer */ 01699 PLATFORM_Close(); 01700 01701 return NAND_SUCCESS; 01702 } 01703 01732 MT_uint8 NAND_OTP_Spare_Program(nand_addr_t addr, flash_width *buffer, MT_uint32 lenght) { 01733 MT_uint8 address[5]; 01734 MT_uint8 status_reg; 01735 MT_uint32 k; 01736 int i; 01737 01738 /* verify if driver is initialized */ 01739 if(DRIVER_STATUS_INITIALIZED != driver_status) 01740 return DRIVER_STATUS_NOT_INITIALIZED; 01741 01742 /* x16 */ 01743 if((device_info.feature & SUPPORTED_16_BIT_DATA_BUS_WIDTH) != 0) { 01744 if(lenght > (device_info.spare_bytes_per_page >> 1) ) 01745 return NAND_INVALID_LENGHT; 01746 } 01747 01748 /* x8 */ 01749 if(lenght > device_info.spare_bytes_per_page) 01750 return NAND_INVALID_LENGHT; 01751 01752 /* spare area starts after last main area byte */ 01753 if((device_info.feature & SUPPORTED_16_BIT_DATA_BUS_WIDTH) == 0) 01754 /* x8 bus width */ 01755 addr.column=device_info.data_bytes_per_page; 01756 else 01757 /* x16 bus width */ 01758 addr.column=device_info.data_bytes_per_page >> 1; 01759 01760 __build_cycle_addr(addr, address); 01761 01762 /* init board transfer */ 01763 PLATFORM_Open(); 01764 01765 /* send command */ 01766 PLATFORM_SendCmd(CMD_PAGE_PROGRAM); 01767 01768 /* send address */ 01769 for(i=0; i<NUM_OF_ADDR_CYCLE; i++) 01770 PLATFORM_SendAddr(address[i]); 01771 01772 /* send data */ 01773 for(k=0; k<lenght; k++) 01774 PLATFORM_SendData(buffer[k]); 01775 01776 /* send command */ 01777 PLATFORM_SendCmd(CMD_PAGE_PROGRAM_CONFIRM); 01778 01779 status_reg = NAND_Read_Status(); 01780 01781 /* close board transfer */ 01782 PLATFORM_Close(); 01783 01784 /* check if program is good */ 01785 if(status_reg & STATUS_FAIL) 01786 return NAND_PROGRAM_FAILED; 01787 01788 return NAND_SUCCESS; 01789 } 01790 01818 MT_uint8 NAND_OTP_Page_Read(nand_addr_t addr, flash_width *buffer, MT_uint32 lenght) { 01819 MT_uint8 row_address[5]; 01820 MT_uint8 status_reg; 01821 MT_uint8 ret; 01822 int i; 01823 01824 /* verify if driver is initialized */ 01825 if(DRIVER_STATUS_INITIALIZED != driver_status) 01826 return DRIVER_STATUS_NOT_INITIALIZED; 01827 01828 /* x16 */ 01829 if((device_info.feature & SUPPORTED_16_BIT_DATA_BUS_WIDTH) != 0) { 01830 if(lenght > (device_info.data_bytes_per_page >> 1) ) 01831 return NAND_INVALID_LENGHT; 01832 } 01833 01834 /* x8 */ 01835 if(lenght > device_info.data_bytes_per_page) 01836 return NAND_INVALID_LENGHT; 01837 01838 __build_cycle_addr(addr, row_address); 01839 01840 /* init board transfer */ 01841 PLATFORM_Open(); 01842 01843 /* send command */ 01844 PLATFORM_SendCmd(CMD_READ_MODE); 01845 01846 /* send address */ 01847 for(i=0; i<NUM_OF_ADDR_CYCLE; i++) 01848 PLATFORM_SendAddr(row_address[i]); 01849 01850 /* return to read mode */ 01851 PLATFORM_SendCmd(CMD_READ_CONFIRM); 01852 01853 /* wait */ 01854 ret = __wait_for_ready(); 01855 01856 /* return if timeout */ 01857 if (NAND_SUCCESS != ret) 01858 return ret; 01859 01860 /* read data */ 01861 for(i=0; i<lenght; i++) 01862 buffer[i] = PLATFORM_ReadData(); 01863 01864 /* read status register on exit */ 01865 status_reg = NAND_Read_Status(); 01866 01867 /* close board transfer */ 01868 PLATFORM_Close(); 01869 01870 if(status_reg & STATUS_FAIL) 01871 return NAND_READ_FAILED; 01872 01873 return ret; 01874 } 01875 01904 MT_uint8 NAND_OTP_Spare_Read(nand_addr_t addr, flash_width *buffer, MT_uint32 lenght) { 01905 MT_uint8 row_address[5]; 01906 MT_uint8 status_reg; 01907 MT_uint8 ret; 01908 MT_uint32 k; 01909 int i; 01910 01911 /* verify if driver is initialized */ 01912 if(DRIVER_STATUS_INITIALIZED != driver_status) 01913 return DRIVER_STATUS_NOT_INITIALIZED; 01914 01915 if((device_info.feature & SUPPORTED_16_BIT_DATA_BUS_WIDTH) != 0) { 01916 /* x16 */ 01917 if(lenght > (device_info.spare_bytes_per_page >> 1) ) 01918 return NAND_INVALID_LENGHT; 01919 } 01920 01921 /* x8 */ 01922 if(lenght > device_info.spare_bytes_per_page) 01923 return NAND_INVALID_LENGHT; 01924 01925 /* spare area starts after last main area byte */ 01926 if((device_info.feature & SUPPORTED_16_BIT_DATA_BUS_WIDTH) == 0) 01927 /* x8 bus width */ 01928 addr.column=device_info.data_bytes_per_page; 01929 else 01930 /* x16 bus width */ 01931 addr.column=device_info.data_bytes_per_page >> 1; 01932 01933 __build_cycle_addr(addr, row_address); 01934 01935 /* init board transfer */ 01936 PLATFORM_Open(); 01937 01938 /* send command */ 01939 PLATFORM_SendCmd(CMD_READ_MODE); 01940 01941 /* send address */ 01942 for(i=0; i<NUM_OF_ADDR_CYCLE; i++) 01943 PLATFORM_SendAddr(row_address[i]); 01944 01945 /* return to read mode */ 01946 PLATFORM_SendCmd(CMD_READ_CONFIRM); 01947 01948 /* wait */ 01949 ret = __wait_for_ready(); 01950 01951 /* return if timeout */ 01952 if (NAND_SUCCESS != ret) 01953 return ret; 01954 01955 /* read data */ 01956 for(k=0; k<lenght; k++) 01957 buffer[k] = PLATFORM_ReadData(); 01958 01959 /* read status register on exit */ 01960 status_reg = NAND_Read_Status(); 01961 01962 /* close board transfer */ 01963 PLATFORM_Close(); 01964 01965 if(status_reg & STATUS_FAIL) 01966 return NAND_READ_FAILED; 01967 01968 return ret; 01969 } 01970 01971 /****************************************************************************** 01972 * Internal functions, not API 01973 *****************************************************************************/ 01974 01975 /* 01976 * This function is used internally from the driver in order to know when 01977 * an operation (program or erase) is completed. 01978 */ 01979 01980 #define BIT_USED_TO_POLL STATUS_RDY 01981 01982 #ifdef TIMEOUT_SUPPORT 01983 #define NUM_OF_TICKS_TO_TIMEOUT (TIME_OUT_SECOND * CLOCKS_PER_SEC) 01984 #endif 01985 01986 MT_uint8 __wait_for_ready() { 01987 MT_uint8 ret; 01988 01989 #ifdef TIMEOUT_SUPPORT 01990 MT_uint32 clock_start = (MT_uint32) clock(); 01991 #endif 01992 01993 PLATFORM_SendCmd(CMD_READ_STATUS); 01994 01995 #ifndef TIMEOUT_SUPPORT 01996 01997 while (BIT_USED_TO_POLL != (BIT_USED_TO_POLL & PLATFORM_ReadData())) 01998 { /* do nothing */ } 01999 02000 PLATFORM_SendCmd(CMD_READ_MODE); 02001 return SUCCESS; 02002 02003 #else 02004 02005 while ( (BIT_USED_TO_POLL != (BIT_USED_TO_POLL & PLATFORM_ReadData())) \ 02006 && ((MT_uint32) clock() < (MT_uint32) (clock_start + NUM_OF_TICKS_TO_TIMEOUT)) ) 02007 { /* do nothing */ } 02008 02009 /* check exit condition */ 02010 if(clock() >= clock_start + NUM_OF_TICKS_TO_TIMEOUT) 02011 ret = NAND_TIMEOUT; 02012 else 02013 ret = NAND_SUCCESS; 02014 02015 PLATFORM_SendCmd(CMD_READ_MODE); 02016 return ret; 02017 02018 #endif 02019 02020 } 02021 02022 /* 02023 * Verify that an address is valid with the current 02024 * device size 02025 */ 02026 MT_uint8 __is_valid_addr(nand_addr_t addr) { 02027 if((addr.column < device_info.data_bytes_per_page) && 02028 (addr.page < device_info.pages_per_block) && 02029 (addr.block < device_info.blocks_per_lun) && 02030 (addr.lun < device_info.luns_per_ce)) 02031 return NAND_SUCCESS; 02032 return NAND_INVALID_NAND_ADDRESS; 02033 } 02034 02035 /* 02036 * Compare two address 02037 */ 02038 MT_uint8 __compare_addr(nand_addr_t first_addr, nand_addr_t second_addr) { 02039 02040 /* first_addr = second_addr */ 02041 if((first_addr.lun == second_addr.lun) && \ 02042 (first_addr.block == second_addr.block) && \ 02043 (first_addr.page == second_addr.page) && \ 02044 (first_addr.column == first_addr.column)) 02045 return ADDR_A_EQ_B; 02046 02047 /* first_addr > second_addr */ 02048 if((first_addr.lun > second_addr.lun) && \ 02049 (first_addr.block > second_addr.block) && \ 02050 (first_addr.page > second_addr.page) && \ 02051 (first_addr.column > first_addr.column)) 02052 return ADDR_A_GT_B; 02053 02054 /* first_addr < second_addr */ 02055 return ADDR_A_LT_B; 02056 } 02057 02058 /* 02059 * __as_uint16 02060 */ 02061 MT_uint16 __as_uint16(MT_uint8 byte1, MT_uint8 byte0) { 02062 #ifdef LITTLE_ENDIAN 02063 return ((MT_uint16) ((byte0 << 8) | byte1)); 02064 #endif 02065 #ifdef BIG_ENDIAN 02066 return ((MT_uint16) ((byte1 << 8) | byte0)); 02067 #endif 02068 } 02069 02070 /* 02071 * __as_uint32 02072 */ 02073 MT_uint32 __as_uint32(MT_uint8 byte3, MT_uint8 byte2, MT_uint8 byte1, MT_uint8 byte0) { 02074 #ifdef LITTLE_ENDIAN 02075 return ((MT_uint32) ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3)); 02076 #endif 02077 #ifdef BIG_ENDIAN 02078 return ((MT_uint32) ((byte3 << 24) | (byte2 << 16) | (byte1 << 8) | byte0)); 02079 #endif 02080 } 02081 /* 02082 * __as_string 02083 */ 02084 void __as_string(MT_uint8 *src_ptr, char *dest_ptr, int start, int stop) { 02085 #ifdef LITTLE_ENDIAN 02086 strncpy((char *)dest_ptr, (const char *)src_ptr+start, stop-start+1); 02087 dest_ptr[stop-start+1] = '\0'; 02088 #endif 02089 #ifdef BIG_ENDIAN 02090 strncpy((char *)dest_ptr, (const char *)src_ptr+start, stop-start+1); 02091 dest_ptr[stop-start+1] = '\0'; 02092 #endif 02093 } 02094 02095 /* 02096 * __build_cycle_addr 02097 */ 02098 void __build_cycle_addr(nand_addr_t addr, MT_uint8 *addr_cycle_stream) { 02099 #define LOW 0 02100 #define HIGH 1 02101 02102 /* extract n-th bit from a value */ 02103 #define CHECK_BIT(val, n) ((val & (1 << n)) >> n) 02104 02105 /* extract from column address */ 02106 #define COL(n) CHECK_BIT(addr.column, n) 02107 02108 /* extract from page address */ 02109 #define PAGE(n) CHECK_BIT(addr.page, n) 02110 02111 /* extract from block address */ 02112 #define BLOCK(n) CHECK_BIT(addr.block, n) 02113 02114 /* extract from lun number */ 02115 #define LUN(n) CHECK_BIT(addr.lun, n) 02116 02117 /* build a single row of address cycle */ 02118 #define BUILD_ADDR_ROW(i_07, i_06, i_05, i_04, i_03, i_02, i_01, i_00) (\ 02119 ((i_07) << 7) \ 02120 | ((i_06) << 6) \ 02121 | ((i_05) << 5) \ 02122 | ((i_04) << 4) \ 02123 | ((i_03) << 3) \ 02124 | ((i_02) << 2) \ 02125 | ((i_01) << 1) \ 02126 | ((i_00) << 0) \ 02127 ); 02128 02129 int cycle; 02130 02131 /* build the address cycle stream (64 pages per block) */ 02132 if (64 == device_info.pages_per_block) { 02133 02134 /* Col 1 - I cycle */ 02135 addr_cycle_stream[0] = 02136 (MT_uint8) BUILD_ADDR_ROW(COL(7), COL(6), COL(5), COL(4), COL(3), COL(2), COL(1), COL(0)); 02137 02138 /* Col 2 - II cycle */ 02139 addr_cycle_stream[1] = 02140 (MT_uint8) BUILD_ADDR_ROW(LOW, LOW, COL(13), COL(12), COL(11), COL(10),COL(9),COL(8)); 02141 02142 /* Row 1 - III cycle */ 02143 addr_cycle_stream[2] = 02144 (MT_uint8) BUILD_ADDR_ROW(BLOCK(1), BLOCK(0), PAGE(5), PAGE(4), PAGE(3), PAGE(2), PAGE(1), PAGE(0)); 02145 02146 /* Row 2 - IV cycle */ 02147 addr_cycle_stream[3] = 02148 (MT_uint8) BUILD_ADDR_ROW(BLOCK(9), BLOCK(8), BLOCK(7), BLOCK(6), BLOCK(5), BLOCK(4), BLOCK(3), BLOCK(2)); 02149 02150 /* Row 3 - V cycle */ 02151 addr_cycle_stream[4] = 02152 (MT_uint8) BUILD_ADDR_ROW(LOW, LOW, LOW, LOW, LUN(0), BLOCK(12), BLOCK(11), BLOCK(10)); 02153 02154 } 02155 02156 /* build the address cycle stream (128 pages per block) */ 02157 if (128 == device_info.pages_per_block) { 02158 02159 /* Col 1 - I cycle */ 02160 addr_cycle_stream[0] = 02161 (MT_uint8) BUILD_ADDR_ROW(COL(7), COL(6), COL(5), COL(4), COL(3), COL(2), COL(1), COL(0)); 02162 02163 /* Col 2 - II cycle */ 02164 addr_cycle_stream[1] = 02165 (MT_uint8) BUILD_ADDR_ROW(LOW, LOW, COL(13), COL(12), COL(11), COL(10),COL(9),COL(8)); 02166 02167 /* Row 1 - III cycle */ 02168 addr_cycle_stream[2] = 02169 (MT_uint8) BUILD_ADDR_ROW(BLOCK(0), PAGE(6), PAGE(5), PAGE(4), PAGE(3), PAGE(2), PAGE(1), PAGE(0)); 02170 02171 /* Row 2 - IV cycle */ 02172 addr_cycle_stream[3] = 02173 (MT_uint8) BUILD_ADDR_ROW(BLOCK(8), BLOCK(7), BLOCK(6), BLOCK(5), BLOCK(4), BLOCK(3), BLOCK(2), BLOCK(1)); 02174 02175 /* Row 3 - V cycle */ 02176 addr_cycle_stream[4] = 02177 (MT_uint8) BUILD_ADDR_ROW(LOW, LOW, LOW, LOW, LUN(0), BLOCK(11), BLOCK(10), BLOCK(9)); 02178 02179 } 02180 02181 #ifdef DEBUG_PRINT_ADDRESS 02182 printf("DEBUG: addr: LUN=%x, BLOCK=%x, PAGE=%x, COL=%x\n", \ 02183 addr.lun, addr.block, addr.page, addr.column); 02184 printf("DEBUG: addr_cycl = I=%x II=%x III=%x IV=%x V=%x\n", \ 02185 addr_cycle_stream[0], addr_cycle_stream[1], addr_cycle_stream[2], addr_cycle_stream[3], addr_cycle_stream[4]); 02186 #endif 02187 }