/******************************************************************************/
//
// Name: 	NAND FLASH interface with ADSP-21161
//
/******************************************************************************

(C) Copyright 2005 - Analog Devices, Inc.  All rights reserved.

File Name:		main.c

Date Modified:	20/06/05 - AV	-	Rev 1.0

Software:       VisualDSP++4.0

Purpose:		To demonstrate NAND FLASH Interface with ADSP-21161 DSP on its external port
				
*******************************************************************************/

#include <def21161.h>
#include <Cdef21161.h>
#include <signal.h>
//External function delcaration
extern void FLASH_BLOCK_Erase_Command(int rw0, int rw1, int rw2);
extern void FLASH_READ_Command(int clmn, int rw0, int rw1, int rw2, int* RdData);
extern void FLASH_PROGRAM_Command(int clmn, int rw0, int rw1, int rw2, int* WrData);
//

//Function declarations
void ExtIrq(int c); //IRQ0 Interrupt function / handler declaration
void ExtMemoryIntfcPara();//External memory interface parameters configuration
void SetUpInt();//Setting up edge sensitive interrupt - IRQ0, also clear up any spurious pending interrupt
void SetUpFlag();//Setting up FLAG3 as Output - used to assert CS# for NAND FLASH
	

//Preparing pointers for NAND FLASH memory in Bank0 address space	
int* FlshBankCMDptr = (int*) 0x00200001;//"A0" asserted "HI" when this location is accessed = CLE
int* FlshBankALEptr = (int*) 0x00200002;//"A1" asserted "HI" when this location is accessed = ALE
int* FlshBankRDptr  = (int*) 0x00200000;//"A0" and "A1" both "LO" = RD# or WR# access
int* FlshBankWRptr  = (int*) 0x00200000;//"A0" and "A1" both "LO" = RD# or WR# access


//Internal memory buffers
int	pageREAD[528];//Array contains READ back values from FLASH memory
int pageWRITE[528];//Array contains values to be written to FLASH memory


//FLASH memory access parameters -> Column, Row0,1 and 2
int COLUMN;
int ROW0, ROW1, ROW2;
		
void main(void)
{
	int i;
	
	SetUpFlag();//set-up FLAG3 as output - used as CS# for the FLASH
	SetUpInt(); //set-up external interrupt here - IRQ0
	
	//set-up external memory parameters
	ExtMemoryIntfcPara();
	
	//Delay
	for (i = 0; i<=0x100; i++)
	{
		asm("nop;");
	}
	
	//Init pageWRITE data in internal memory
	for (i = 0; i<= 527; i++)
	{
		pageWRITE[i] = i;
	}	
	
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	//FLASH should be erased "All 0xFF" before programing
	/* Before calling block erase function ROWs should be initialized with
	   the address of block that needs to be erased.
	   ROW0 <- row0 address
	   ROW1 <- row1 address
	   ROW2 <- row2 address
	*/
	//parameter passing for block erase fucntion
	ROW0 = 0;
	ROW1 = 0;
	ROW2 = 0;
	FLASH_BLOCK_Erase_Command(ROW0, ROW1, ROW2);
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	
	
	
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	/* Before calling flash program function, R12, R13, R14 and R15 should be initialized with
	   the address of column and rows
	   COLUMN <- column address
	   ROW0 <- row0 address
	   ROW1 <- row1 address
	   ROW2 <- row2 address
	*/
	//parameter passing for program command
	COLUMN = 0;
	ROW0 = 0;
	ROW1 = 0;
	ROW2 = 0;
	//FLASH_PROGRAM_Command(COLUMN, ROW0, ROW1, ROW2, &pageWRITE[0]);
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	
	
	
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	/* Before calling flash read function, R12, R13, R14 and R15 should be initialized with
	   the address of column and rows
	   COLUMN <- column address
	   ROW0 <- row0 address
	   ROW1 <- row1 address
	   ROW2 <- row2 address
	*/
	//Set-up the pointer to internal memory
	FLASH_READ_Command(COLUMN, ROW0, ROW1, ROW2, &pageREAD[0]);
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

	asm("nop;");
	while(1)
	{
	}



}

/*	Busy signal (R/B#) is passed through an inverter and connected to IRQ0 of 
	ADSP-21161. Once this signal goes "HI" after completion of task, an interrupt
	is generated. Until the task is complete the core remains in "idle;" state.See
	individual FLASH fucntions for details.

*/
void ExtIrq(int c)
{
	return;
}
	

void ExtMemoryIntfcPara()
{
	asm("#include <def21161.h>");
	asm("ustat1 = dm(WAIT);");
	asm("bit set ustat1 EB0WS7;"); //WAIT states = 7, HOLD cycle for bank0
	asm("dm(WAIT) = ustat1;");
	return;
}
	
void SetUpInt()
{
	asm("#include <def21161.h>");
	//set-up external interrupt mode - edge sensitive
	asm("bit set MODE2 IRQ0E;"); //Configure this interrupt as edge sensitive
	asm("bit clr IRPTL IRQ0I;"); //Clear any spurious interrupt
	interrupt(SIG_IRQ0, ExtIrq); //Set-up interrupt handler
	return;
}

void SetUpFlag()
{
	asm("#include <def21161.h>");
	//set-up FLAG3 as output - used as CS# for the FLASH
	asm("bit set MODE2 FLG3O;");
	asm("bit set FLAGS FLG3;"); //set this to "HI" this is connected to the CS# of FLASH
	return;	
}
