URL
https://opencores.org/ocsvn/usb_nand_reader/usb_nand_reader/trunk
Subversion Repositories usb_nand_reader
[/] [usb_nand_reader/] [trunk/] [pc/] [nand_vendors.c] - Rev 2
Compare with Previous | Blame | View Log
#include <stdlib.h> #include <string.h> #include <stdio.h> #include <ctype.h> #include "include/nand_vendors.h" int get_nand_configuration(pnand_t nand) { int result = 0; printf("Getting configuration\n"); if(NULL != nand->onfiParameterPage) { nand->manufacturer = strndup((char*)nand->onfiParameterPage + 32, 12); nand->device = strndup((char*)nand->onfiParameterPage + 44, 20); nand->bytesPerPage = *(int*)(nand->onfiParameterPage + 80); nand->oobPerPage = (int)*(short*)(nand->onfiParameterPage + 84); nand->pagesPerBlock = *(int*)(nand->onfiParameterPage + 92); nand->planesPerLun = 1; nand->blocksPerPlane = *(int*)(nand->onfiParameterPage + 96); nand->numLuns = (int)*(nand->onfiParameterPage +100); nand->addressCycles = (*(nand->onfiParameterPage + 101) & 0x0f) + ((*(nand->onfiParameterPage + 101) >> 4) & 0x0f); nand->busWidth = 8 << (*(nand->onfiParameterPage + 6) & 0x01); result = 1; } else { switch(nand->id[0]) { case 0x2c: // Micron printf("Micron NAND flash detected\n"); nand->manufacturer = strdup("Micron"); if(nand->id[1] == 0xa1) nand->device = strdup("MT29F1G08ABBDA"); else if(nand->id[1] == 0xaa) nand->device = strdup("MT29F2G08ABBEA"); else if(nand->id[1] == 0xb1) nand->device = strdup("MT29F1G16ABBDA"); else if(nand->id[1] == 0xba) nand->device = strdup("MT29F2G16ABBEA"); else if(nand->id[1] == 0xca) nand->device = strdup("MT29F2G16ABAEA"); else if(nand->id[1] == 0xda) nand->device = strdup("MT29F2G08ABAEA"); else { printf("Unknown device\n"); break; } if((nand->id[3] & 3) == 1) nand->bytesPerPage = 2048; else { printf("Could not get number of bytes per page\n"); break; } if((nand->id[3] & 4) == 4) nand->oobPerPage = 64; else { printf("Could not get number of OOB bytes per page\n"); break; } nand->pagesPerBlock = ((64 << ((nand->id[3] >> 4) & 3)) * 1024) / nand->bytesPerPage; nand->busWidth = 8 << ((nand->id[3] >> 4) & 1); nand->numLuns = 1; nand->planesPerLun = 1 << ((nand->id[4] >> 2) & 3); nand->blocksPerPlane = (((1024 * 1024 * 1024) / 8) << ((nand->id[4] >> 4) & 7)) / (nand->pagesPerBlock * nand->bytesPerPage); nand->addressCycles = 5; result = 1; break; case 0x98: // Toshiba printf("Toshiba NAND flash detected (JEDEC ID: %02X%02X%02X%02X%02X)\n", nand->id[0], nand->id[1], nand->id[2], nand->id[3], nand->id[4]); nand->manufacturer = strdup("Toshiba"); if(nand->id[1] == 0xda) { nand->device = strdup("TC58NVG1S3HTA00"); nand->busWidth = 8; nand->bytesPerPage = 2048; nand->oobPerPage = 128; nand->pagesPerBlock = 64; nand->numLuns = 1; nand->planesPerLun = 1; nand->blocksPerPlane = 2048; nand->addressCycles = 5; result = 1; } else break; break; default: printf("Device manufacturer %02x could not be identified.\n", nand->id[0]); break; } } if(result) nand->pageBuffer = (unsigned char*)malloc(sizeof(unsigned char) * (nand->bytesPerPage + nand->oobPerPage)); return result; } void free_nand_info(pnand_t* nand) { if(NULL == nand || NULL == *nand) return; if(NULL != (*nand)->manufacturer) free((*nand)->manufacturer); if(NULL != (*nand)->device) free((*nand)->device); if(NULL != (*nand)->onfiParameterPage) free((*nand)->onfiParameterPage); if(NULL != (*nand)->pageBuffer) free((*nand)->pageBuffer); free(*nand); *nand = NULL; } void print_nand_configuration(pnand_t nand) { printf("\n***********************************\n"); printf("***** NAND configuration data *****\n"); printf("***********************************\n"); printf("Manufacturer: %s\n", nand->manufacturer); printf("Device: %s\n", nand->device); printf("ID: %02x %02x %02x %02x %02x\n", nand->id[0], nand->id[1], nand->id[2], nand->id[3], nand->id[4]); printf("ONFI compliant: %s\n", (NULL == nand->onfiParameterPage)? "No" : "Yes"); printf("Data bus width: %d\n", nand->busWidth); printf("Bytes per page: %d bytes\n", nand->bytesPerPage); printf("OOB per page: %d bytes\n", nand->oobPerPage); printf("Pages per block: %d\n", nand->pagesPerBlock); printf("Blocks per plane: %d\n", nand->blocksPerPlane); printf("Planes per LUN: %d\n", nand->planesPerLun); printf("Number of LUNs: %d\n", nand->numLuns); printf("Address cycles: %d\n", nand->addressCycles); printf("ONFI signature bytes: %02x %02x %02x %02x\n\n", nand->onfiSignature[0], nand->onfiSignature[1], nand->onfiSignature[2], nand->onfiSignature[3]); } void dump_page(pnand_t nand) { int i, j; for(i = 0; i < nand->bytesPerPage + nand->oobPerPage; i += 16) { for(j = 0; j < 16; j++) { printf("%02x ", nand->pageBuffer[i + j]); } printf("\t\t"); for(j = 0; j < 16; j++) { if(isprint(nand->pageBuffer[i + j])) printf("%c", nand->pageBuffer[i + j]); else printf("."); } printf("\n"); } } void store_page(FILE* f, pnand_t nand) { fwrite(nand->pageBuffer, nand->bytesPerPage + nand->oobPerPage, 1, f); }