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