OpenCores
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);
}

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.