/*
*************************************************************************************************
*	  					NAND FLASH driver for PIC24 (16-bit)using PMP Module  
*										All Rights Reserved
* File name		: HY27US08561A.h
* Programmer 	: John Leung, TechToys Co. Hong Kong
* Web presence  : www.TechToys.com.hk
* Language		: C30 complier version 3.01, MPLAB v7.60
* Hardware		: PIC24-Eval Rev C + TY280T-240320-BO Rev 1B
* Disclaimer	: THIS DRIVER IS PROVIDED "AS IS" WITH NO WARRANTY
*                 WHATSOEVER AND TECHTOYS COMPANY SPECIFICALLY DISCLAIMS ANY
*                 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
*                 A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT.
*
*                 Copyright @2008 TECHTOYS COMPANY 
*                 All rights researved
*
* Rev			  Author	  		Date				Comment
* ---			  ------			----				-------
* 1.0a			 John Leung			22 Jan 2009			Initial Release
*************************************************************************************************
*										DESCRIPTION
*
* This module provides an interface to NAND Flash Hynix HY27US08561A for PIC24FJ128GA010 (PIM)
* Only basic I/O function is supported in this version. Therefore, no FAT is supported!
*
* Connect UART2 of the board to any standard RS232 monitoring program like hyperterminal
* Set the baud rate to be 19200bps, 8-data bit, 1-stop bit, no parity with no handshake.
* Follow the instruction on screen you will be able to write different content to the first
* block of the nand Flash at your wish.
*
* Remarks:  it is important to note that prior to writing to a block, 
*			block erase has to be performed; otherwise, inaccurate data would be written to the
*			same block. One may experiment with it with different procedures than 1-2-3-4.
*************************************************************************************************
*/
#ifndef _HY27US08561A_H_
#define _HY27US08561A_H_

typedef unsigned char 		INT8U;
typedef unsigned int		INT16U;
typedef unsigned char		BOOLEAN;


/*
*************************************************************************************************
*										PIN INTERFACE
* Use PMP module for interface
* Function		mcu pins		nandFlash pins
* ==========	========		====================
* DATA LINES	PMD[7:0]		I/O[7:0]
* RB			RC1				READY/BUSY OUTPUT
* CE			RD10			CHIP ENABLE
* CLE			RG12			COMMAND LATCH ENABLE 
* ALE			RG14			ADDRESS LATCH ENABLE
* WP			RC2				WRITE PROTECT
* WR STROBE		RD4/PMPWR		/WR
* RD STROBE		RD5/PMPRD		/RD
*************************************************************************************************
*/

#define NAND_RB_TRIS	TRISCbits.TRISC1
#define NAND_RB_PORT	PORTCbits.RC1
#define NAND_CE_TRIS	TRISDbits.TRISD10
#define NAND_CE_LAT		LATDbits.LATD10
#define NAND_CLE_TRIS	TRISGbits.TRISG12
#define NAND_CLE_LAT	LATGbits.LATG12
#define NAND_ALE_TRIS	TRISGbits.TRISG14
#define NAND_ALE_LAT	LATGbits.LATG14
#define NAND_WP_TRIS	TRISCbits.TRISC2
#define NAND_WP_LAT		LATCbits.LATC2
/*
#define NAND_RD_TRIS_BIT		TRISDbits.TRISD5
#define NAND_RD_LAT_BIT			LATDbits.LATD5
#define NAND_WR_TRIS_BIT		TRISDbits.TRISD4
#define NAND_WR_LAT_BIT			LATDbits.LATD4

#define NAND_PORT		PORTE				
#define NAND_DATA		LATE
#define NAND_DATA_TRIS	TRISE
*/
#define NAND_DATA		PMDIN1				//data buffer for PMP module

#define INPUT			1
#define OUTPUT			0
#define LOW				0
#define HIGH			1

/*
*************************************************************************************************
*										LIST OF COMMANDS
*************************************************************************************************
*/
#define NAND_READ0			0x00		//for 1st half array from 0-255 byte of the same page
#define NAND_READ1			0x01		//for 2nd half array from 256-511 byte of the same page
#define NAND_READ2			0x50		//for spare array from 512-527 byte
#define NAND_READ_ID		0x90
#define NAND_RST			0xFF
#define NAND_PAGE_PROG_C1	0x80
#define	NAND_PAGE_PROG_C2	0x10
#define NAND_COPYPROG_C1	0x00
#define NAND_COPYPROG_C2	0x8A
#define NAND_BLOCKERASE_C1	0x60
#define NAND_BLOCKERASE_C2	0xD0
#define NAND_READSTATUS		0x70

/*
*************************************************************************************************
*										NAND FLASH INFORMATION
*************************************************************************************************
*/
#define NAND_PAGE_SIZE_BYTE	512
#define NAND_PAGE_PER_BLOCK	32
#define NAND_BLOCK_COUNT	2048

/*
*************************************************************************************************
*							NAND STATUS READ RESULT and TIMING PARAMETERS
*************************************************************************************************
*/
#define NAND_RS_SUCCESS		0	//0 after Read Status command -> successful
#define NAND_RS_FAIL		1	//1 after Read Status command -> fail
#define NAND_RB_TIMEOUT		2	//RB pin is used to monitor if an operation has completed
								//a timeout error indicates problem with hardware 
/*
*************************************************************************************************
*										FUNCTION PROTOTYPES
*************************************************************************************************
*/


/*
*************************************************************************************************
*                         			  NAND FLASH INITIALIZATION
*
* Description : This function initializes pin direction & PMP module (PIC24 series only)		
* Arguments   : none
*			
* Returns     : none
* Note		  : This function should be called once before any of the other functions
*				The WRITE PROTECT pin enabled in this function
*************************************************************************************************
*/
void 	nandInit(void);

/*
*************************************************************************************************
*                         				READ DEVICE ID ROUTINE
*
* Description : Every NAND Flash contains a product identification.
*				This function reads the device ID by writing 0x90(NAND_READ_ID) to the command 
*				register, followed by an address input of 0x00. Two read cycles sequentially
*				output the manufacture code (0xAD) for Hynix, and the device code (0x75) resp 
*				after a waiting time of tAR defined as Nop() under HY27US08561A.h file		
* Arguments   : none
*			
* Returns     : Device ID of the NAND Flash
* Note		  : The manufacturer code varies from every semiconductor supplier. For Samsung, it 
*				is 0xEC instead of 0xAD
*				This function is a device specific function as PMP Read feature has been used.
*************************************************************************************************
*/
INT16U 	nandChkID(void);

/*
*************************************************************************************************
*                         				READ STATUS FUNCTION
*
* Description : The NAND Flash contains a Status Register which may be read to find out whether
*				read, program or erase operation is completed, and whether the program or erase
*				operation has been completed successfully. 
*				After writing command NAND_READSTATUS(0x70) to the command register, a read cycle
*				outputs the content of the Status Register to the I/O pins on the falling edge
*				of CE or RE (PMRD) whichever occurs last.
*				  	
* Arguments   : none
*			
* Returns     : Result of an operation. Please refer to definition above for these
*				NAND_RS_SUCCESS
*				NAND_RS_FAIL
* Note		  : 
*************************************************************************************************
*/
INT8U	nandRdStatus(void);

/*
*************************************************************************************************
*                         				BLOCK ERASE FUNCTION
*
* Description : This erase operation is done on a block (16k byte) basis! 
*				A page is (512+16spare)bytes, and 32 pages comprises a Block.
*				This function writes NAND_BLOCKERASE1 (0x60) being the Block Erase Command 1st 
*				cycle then the block address; finally the NAND_BLOCKERASE2 (0xD0) to initiate
*				the erase process. This function erases (returns all bytes to 0xFF) for the whole
*				block
* Arguments   : 'INT16U' block denotes the block address to erase
*			
* Returns     : Result of operation
*				NAND_RS_SUCCESS
*				NAND_RS_FAIL
*				NAND_RB_TIMEOUT
*
* Note		  : It is a MUST to unlock the WRITE PROTECT prior to block erase.
*				This function lock the WRITE PROTECT upon exit
*************************************************************************************************
*/
INT8U 	nandEraseBlk(INT16U block);

/*
*************************************************************************************************
*                         				PAGE WRITE FUNCTION
*
* Description : This function writes a NAND Flash page.
*
* Arguments   : block		- the block to program
*				page 		- programming starts from this page address. There are 64k pages in our 
*							  NAND Flash model
*				col  		- programming starts from this column address. There are 512+16 columns
*				* buffer	- data buffer with data to be programmed to NAND Flash
*
* Returns     : Result of operation
*				NAND_RS_SUCCESS
*				NAND_RS_FAIL
*				NAND_RB_TIMEOUT
*
* Note		  : It is a MUST to unlock the WRITE PROTECT prior to block erase.
*				Prior to program a particular page, it is required to perform a block erase first
*				This function lock the WRITE PROTECT upon exit
*************************************************************************************************
*/
INT8U 	nandWrPage(INT16U block, INT16U page, INT16U col, INT8U* buffer);


/*
*************************************************************************************************
*                         				PAGE READ FUNCTION
*
* Description : This function reads from a NAND Flash page.
*
* Arguments   : block		- the block to read from
*				page 		- programming starts from this page address. There are 64k pages in our 
*							  NAND Flash model
*				col  		- programming starts from this column address. There are 512+16 columns
*				* buffer	- data buffer for data read from NAND ARRAYs
*
* Returns     : None
*************************************************************************************************
*/
void 	nandRdPage(INT16U block, INT16U page, INT16U col, INT8U* buffer);

/*
*************************************************************************************************
*                         				WAIT STATE DEFINITION
*************************************************************************************************
*/	
#define PMPDelay()  	Nop();						//PMPDelay for nandWrAddr() & nandWrCmd()

/*
*************************************************************************************************
*                         			NAND FLASH COMMAND WRITE
*
* Description : This function writes command to NAND Flash via PMD[7:0]	
* Arguments   : none
*			
* Returns     : none
* Note		  : CLE input controls the activating path for commands sent to the command register.
*				When active high, commands are latched on rising WE signal, i.e. on rising PMWR
*************************************************************************************************
*/
#define nandWrCmd(cmd) NAND_CLE_LAT = HIGH; NAND_DATA = cmd; PMPDelay();  NAND_CLE_LAT = LOW;


/*
*************************************************************************************************
*                         			NAND FLASH ADDRESS WRITE
*
* Description : This function writes address to NAND Flash via PMD[7:0]	
* Arguments   : none
*			
* Returns     : none
* Note		  : ALE input controls the activating path for address to the internal address register.
*				When active high, addresses are latched on rising WE signal, i.e. on rising PMWR 
*************************************************************************************************
*/
#define nandWrAddr(addr) NAND_ALE_LAT = HIGH; NAND_DATA = addr; PMPDelay(); NAND_ALE_LAT = LOW;


/*
*************************************************************************************************
*                         				NAND FLASH DATA WRITE
*
* Description : This function writes data to NAND Flash via PMD[7:0]	
* Arguments   : none
*			
* Returns     : none
* Note		  : When ALE & CLE are both low, data written to data buffer on rising WE signal
*				when CE is low
*************************************************************************************************
*/
#define nandWrDat(dat) NAND_DATA = dat;

#endif
