OpenCores
URL https://opencores.org/ocsvn/usb_nand_reader/usb_nand_reader/trunk

Subversion Repositories usb_nand_reader

[/] [usb_nand_reader/] [trunk/] [pc/] [actions.c] - Rev 5

Go to most recent revision | Compare with Previous | Blame | View Log

 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libusb-1.0/libusb.h>
#include "include/opcodes.h"
#include "include/actions.h"
#include "include/nand_vendors.h"
 
unsigned char ioBuffer[64];
int dataTransfered;
 
int
usb_write(libusb_device_handle* usb, unsigned char* data, int len)
{
	int ds;
	int i = 0;
	int l = (len < 64)? 64 : len;
 
	while(i < l)
	{
		libusb_bulk_transfer(usb, 0x01, data + i, l - i, &ds, 1000);
		i += ds;
	}
	return i;
}
 
int 
usb_read(libusb_device_handle* usb, unsigned char* data, int len)
{
	int ds;
	int i = 0, r;
	if(len % 64 != 0)
	{
		fprintf(stderr, "\nIncorrect read length\n");
		return 0;
	}
	while(i < len)
	{
		if(0 > (r = libusb_bulk_transfer(usb, 0x81, data + i, len - i, &ds, 10000)))
		{
			fprintf(stderr, "libusb_bulk_transfer() returned %d\n", r);
			//exit(-4);
		}
		i += ds;
		if(0 == ds)
			exit(-3);
	}
	return i;
}
 
USB_ACTION(nand_reset)
{
	ioBuffer[0] = NAND_CHIP_RESET;
	usb_write(usb, ioBuffer, 1);
	return 0;
}
 
USB_ACTION(nand_enable, int dieIndex)
{
	ioBuffer[0] = NAND_CHIP_ENABLE;
	ioBuffer[1] = (unsigned char)(dieIndex & 3);
	usb_write(usb, ioBuffer, 2);
	return 0;
}
 
USB_ACTION(nand_disble)
{
	ioBuffer[0] = NAND_CHIP_DISABLE;
	usb_write(usb, ioBuffer, 1);
	return 0;
}
 
USB_ACTION(nand_read_id, unsigned char* idBuffer)
{
	ioBuffer[0] = NAND_CHIP_READ_ID;
	usb_write(usb, ioBuffer, 1);
	usb_read(usb, ioBuffer, 64);
	memcpy(idBuffer, ioBuffer, 5);
	return 0;
}
 
USB_ACTION(nand_is_onfi, unsigned char* signature)
{
	ioBuffer[0] = NAND_CHIP_READ_ID_ONFI;
	usb_write(usb, ioBuffer, 1);
	usb_read(usb, ioBuffer, 64);
	memcpy(signature, ioBuffer, 4);
	if(ioBuffer[0] == 'O' && ioBuffer[1] == 'N' && ioBuffer[2] == 'F' && ioBuffer[3] == 'I')
		return 1;
	return 0;
}
 
USB_ACTION(nand_read_onfi_param_page, unsigned char* paramPageBuffer)
{
	ioBuffer[0] = NAND_CHIP_READ_PARAM_PAGE;
	usb_write(usb, ioBuffer, 1);
	usb_read(usb, paramPageBuffer, 256);
	return 0;
}
 
USB_ACTION(nand_set_config_data, pnand_t nand)
{
	ioBuffer[0] = NAND_SET_CONFIG_DATA;
	*(int*)(&ioBuffer[1]) = nand->bytesPerPage + nand->oobPerPage;
	ioBuffer[5] = (unsigned char)(nand->addressCycles & 0xff);
	ioBuffer[6] = (unsigned char)(nand->busWidth);
	usb_write(usb, ioBuffer, 6);
	return 0;
}
 
USB_ACTION(nand_read_page, unsigned int pageAddress, pnand_t nand)
{
	//struct timespec start = {0, 0}, end = {0, 0};
	ioBuffer[0] = NAND_CHIP_READ_PAGE;
	ioBuffer[1] = ioBuffer[2] = 0;
	*(unsigned int*)(&ioBuffer[3]) = (pageAddress & 0x00ffffff);
	//clock_gettime(CLOCK_MONOTONIC, &start);
	usb_write(usb, ioBuffer, 64);
	//printf("read %d bytes\n", usb_read(usb, nand->pageBuffer, nand->bytesPerPage + nand->oobPerPage));
 
	usb_read(usb, nand->pageBuffer, nand->bytesPerPage + nand->oobPerPage);
	//clock_gettime(CLOCK_MONOTONIC, &end);
	//printf("\r\tPage read in %.10f seconds.", ((double)end.tv_sec + 1.0e-9 * end.tv_nsec) - ((double)start.tv_sec + 1.0e-9 * start.tv_nsec));
	//fflush(stdout);
	return 0;
}
 
USB_ACTION(nand_read_page_cache, unsigned int startPageAddress, int pageCount, FILE* storeTo, pnand_t nand)
{
	int currentPage, blocks = 0;
	unsigned int sa = startPageAddress;
 
	if(0 != pageCount % nand->pagesPerBlock)
		return -1;
 
	while(blocks < pageCount / nand->pagesPerBlock)
	{
		fprintf(stderr,"\rBlock #%d (%0.4f%%)", blocks, (float)blocks / ((float)(pageCount / nand->pagesPerBlock) / 100.0f));
		ioBuffer[0] = NAND_CHIP_READ_CACHE_SEQ;
		ioBuffer[1] = ioBuffer[2] = 0;
		*(unsigned int*)(&ioBuffer[3]) = (sa & 0x00ffffff);
		*(int*)(&ioBuffer[6]) = nand->pagesPerBlock;
		usb_write(usb, ioBuffer, 64);
 
		for(currentPage = 0; currentPage < nand->pagesPerBlock; currentPage++)
		{
			usb_read(usb, nand->pageBuffer, nand->bytesPerPage + nand->oobPerPage);
			if(NULL != storeTo)
				store_page(storeTo, nand);
			//fprintf(stderr,"\rBlock #%d %0.2f%% completed", blocks, (float)currentPage / ((float)nand->pagesPerBlock / 100.0f));
		}
		blocks++;
		sa += nand->pagesPerBlock;
	}
	fprintf(stderr, "\n");
	return 0;
}
 
USB_ACTION(nand_read_status, unsigned char* status)
{
	ioBuffer[0] = NAND_CHIP_READ_STATUS;
	usb_write(usb, ioBuffer, 64);
	usb_read(usb, ioBuffer, 64);
	if(status)
		*status = ioBuffer[0];
	return (int)ioBuffer[0];
}
 
USB_ACTION(nand_read_status_enhanced, unsigned int address, unsigned char* status)
{
	ioBuffer[0] = NAND_CHIP_READ_STATUS;
	*(unsigned int*)(&ioBuffer[1]) = address & 0xffffff;
	usb_write(usb, ioBuffer, 64);
	usb_read(usb, ioBuffer, 64);
	if(status)
		*status = ioBuffer[0];
	return (int)ioBuffer[0];
}
 
USB_ACTION(nand_read_unique_id, unsigned char* uid)
{
	ioBuffer[0] = NAND_CHIP_READ_UNIQUE_ID;
	usb_write(usb, ioBuffer, 64);
	usb_read(usb, ioBuffer, 64);
	memcpy(uid, ioBuffer, 64);
	return 0;
}
 
int nand_check_uid(unsigned char* buffer)
{
	int i;
	for(i = 0; i < 16; i++)
	{
		if(0xFF != (*(buffer + i) ^ *(buffer + i + 16)))
			return 0;
	}
	return 1;
}
 
 
USB_ACTION(nand_block_erase, unsigned int blockAddress)
{
	ioBuffer[0] = NAND_CHIP_BLOCK_ERASE;
	*(unsigned int*)(&ioBuffer[1]) = (blockAddress & 0x00ffffff);
	usb_write(usb, ioBuffer, 64);
	return 0;
}
 
USB_ACTION(nand_toggle_wp)
{
	ioBuffer[0] = NAND_CHIP_TOGGLE_WP;
	usb_write(usb, ioBuffer, 64);
	return 0;
}
 
USB_ACTION(nand_page_program, unsigned int pageAddress, pnand_t nand)
{
	//int i;
 
	ioBuffer[0] = NAND_CHIP_PAGE_PROGRAM;
	ioBuffer[1] = ioBuffer[2] = 0;
	*(unsigned int*)(&ioBuffer[3]) = (pageAddress & 0x00ffffff);
	usb_write(usb, ioBuffer, 64);
	/*
	for(i = 0; i < nand->bytesPerPage + nand->oobPerPage; i += 64)
	{
		fprintf(stderr, "Written %d bytes\n", usb_write(usb, nand->pageBuffer + i, 64));
	}
	 */
 
	fprintf(stderr, "Written %d bytes\n", usb_write(usb, nand->pageBuffer, nand->bytesPerPage + nand->oobPerPage));
	return 0;
}

Go to most recent revision | 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.