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

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

File Name:		main.asm

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>
//External function delcaration
.extern FLASH_BLOCK_Erase_Command;
.extern FLASH_READ_Command;
.extern FLASH_PROGRAM_Command;


.section/pm seg_rth;
	nop;nop;nop;nop;nop;jump start;
	
.section/pm seg_ext_irq;
	jump ExtIrq; rti;rti;rti;
	
	
.section/dm seg_dmda;
	.var pageREAD[528];
	.var pageWRITE[528];
		
.section/pm seg_pmco;
start:	

	//set-up FLAG3 as output - used as CS# for the FLASH
	bit set MODE2 FLG3O;
	bit set FLAGS FLG3; //set this to "HI" this is connected to the CS# of FLASH
	
	//set-up external interrupt here
	bit set MODE2 IRQ0E; //Configure this interrupt as edge sensitive
	bit set IMASK  IRQ0I;//Set mask for IRQ0 - external interrupt
	bit clr IRPTL IRQ0I; //Clear any spurious interrupt
	bit set MODE1 IRPTEN;//Globally enable all interrupts
	nop;nop;
	//

	//set-up external memory parameters
	ustat1 = dm(WAIT);
	bit set ustat1 EB0WS7; //WAIT states = 7, HOLD cycle for bank0
	dm(WAIT) = ustat1;
	
	
	
	lcntr = 0x100; do wait_while until lce;
	wait_while: nop;
	//Init pageWRITE data in internal memory
	i2 = pageWRITE;
	m2 = 1;
	r2 = 0;
	
	lcntr = 528, do pageWRITE_init until lce;
	dm(i2,m2) = r2;
	r2 = r2+1;
pageWRITE_init: nop;	
	//Initialization of data in internal memory OVER

		
	m0=1;//modifier for NAND FLASH READ/PROGRAM - this modifier is for internal memory buffers only
	
	
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	//FLASH should be erased "All 0xFF" before programing
	/* Before calling block erase function, R13, R14 and R15 should be initialized with
	   the address of block that needs to be erased.
	   R13 <- row0 address
	   R14 <- row1 address
	   R15 <- row2 address
	*/
	//parameter passing for block erase fucntion
	r13 = 0x0; r14 = 0x0; r15 = 0x0;
	CALL FLASH_BLOCK_Erase_Command;
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	
	
	
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	/* Before calling flash program function, R12, R13, R14 and R15 should be initialized with
	   the address of column and rows
	   R12 <- column address
	   R13 <- row0 address
	   R14 <- row1 address
	   R15 <- row2 address
	*/
	//parameter passing for program command
	r12 = 0x0; r13 = 0x0; r14 = 0x0; r15 = 0x0;
	//Set-up the pointer to internal memory
	i1 = pageWRITE;//buffer points to internal memory - data to WRITE/PROGRAM is picked up from here
	CALL FLASH_PROGRAM_Command;
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	
	
	
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	/* Before calling flash read function, R12, R13, R14 and R15 should be initialized with
	   the address of column and rows
	   R12 <- column address
	   R13 <- row0 address
	   R14 <- row1 address
	   R15 <- row2 address
	*/
	//parameter passing for program command
	r12 = 0x0; r13 = 0x0; r14 = 0x0; r15 = 0x0;
	//Set-up the pointer to internal memory
	i0 = pageREAD;//buffer points to internal memory - READ data from FLASH is stored here
	CALL FLASH_READ_Command;
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

	
	jump (pc,0);



	

/*	Busy signal (R/B#) is inverted and connected to IRQ0 of the DSP. Once the task is 
	complete, this signal generates an interrupt to DSP. Therefore, whenever 
	BUSY# condition needs to be checked, "idle;" instruction is inserted in the 
	code.

*/
ExtIrq:
	nop;nop;nop;nop;
	rti;
	
	

	
	

