#include "system.h"
#include <io.h>





//Register access commands

//Applicable for all flashes

int read_device_id(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x0000489F);
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);			// start operation
	return IORD(GFILSH_AVL_CSR_BASE,0xc);
}
int read_status_register(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x00001805);
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);			// start operation
	return IORD(GFILSH_AVL_CSR_BASE,0xc);
}
int read_flag_status_register(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x00001870);
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);			// start operation
	return IORD(GFILSH_AVL_CSR_BASE,0xc);
}
void write_enable(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x00000006);
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);			// start operation
	IOWR(GFILSH_AVL_CSR_BASE,0xA,1);
}

void enter_4byte_addressing_mode(){				// No this resigter in EPCQL256
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x000000B7);
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);			// start operation
	IOWR(GFILSH_AVL_CSR_BASE,0xA,1);
}
void clear_flag_status_register(){				// No this resigter in EPCQL256
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x00000050);
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);		// start operation
	IOWR(GFILSH_AVL_CSR_BASE,0xA,1);
}

//Applicable only for cypress flash

int read_bank_register(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x00001816);
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);		// start operation
	return IORD(GFILSH_AVL_CSR_BASE,0xc);
}
//for cypress flash to enter four byte addr
void write_bank_register_enter4byte(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x00001017);	// Flash Command Setting Register
	IOWR(GFILSH_AVL_CSR_BASE,0xA,0x00000080);	// Flash Command write data 0 Register
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);			// Flash Command control Register
}
//for cypress flash to enter 3 byte addr
void write_bank_register_exit4byte(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x00001017);
	IOWR(GFILSH_AVL_CSR_BASE,0xA,0x00000000);
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);			// start operation
}
//to check cypress flash in dual or quad mode
int read_config_register(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x00001835);
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);			// start operation
	return IORD(GFILSH_AVL_CSR_BASE,0xc);		// Flash Command Read Data 0 Register
}
//for cypress flash to enter quad mode
void write_config_register(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x00002001);
	IOWR(GFILSH_AVL_CSR_BASE,0xA,0x00000200);
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);			// start operation
}
//exit p_err & e_err mode
void clear_status_register(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x00001030);
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);			// start operation
	IOWR(GFILSH_AVL_CSR_BASE,0xA,1);
}

//Applicable only for micron flash//

//for micron flash to enter quad SPI mode
void write_evcr_quad(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x00001061);
	IOWR(GFILSH_AVL_CSR_BASE,0xA,0x0000005f);
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);			// start operation
}
//for micron flash to enter dual SPI mode
void write_evcr_dual(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x00001061);
	IOWR(GFILSH_AVL_CSR_BASE,0xA,0x0000009f);
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);			// start operation
}

//Erase Commands//

void erase_sector_cypress(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x000003D8);
	IOWR(GFILSH_AVL_CSR_BASE,0x9,0x00000000);	// Flash Command Address Register
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);			// start operation
}

void erase_sector_intel(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x000004D8);	// 4 byte address
	IOWR(GFILSH_AVL_CSR_BASE,0x9,0x00000000);	// start address
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);			// start operation
}

void erase_sector_micron(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x00000420);
	IOWR(GFILSH_AVL_CSR_BASE,0x9,0x00000000);
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);			// start operation
}

//Read Memory Commands

int read_memory(long offset){
	IOWR(GFILSH_AVL_CSR_BASE,0x4,0x00000000);	// Operating Protocols Setting Register
	IOWR(GFILSH_AVL_CSR_BASE,0x0,0x00000101);	// Control Register
	IOWR(GFILSH_AVL_CSR_BASE,0x5,0x00000003);
	return IORD(GFILSH_AVL_MEM_BASE,0x00000000 + offset);
}
int read_memory_3byte(){
	IOWR(GFILSH_AVL_CSR_BASE,0x4,0x00000000);
	IOWR(GFILSH_AVL_CSR_BASE,0x0,0x00000001);
	IOWR(GFILSH_AVL_CSR_BASE,0x5,0x00000003);
	return IORD(GFILSH_AVL_MEM_BASE,0x00000000);
}
//cypress 4 byte fast read (0C)
int cypress_four_byte_fast_read(){
	IOWR(GFILSH_AVL_CSR_BASE,0x4,0x00000000);
	IOWR(GFILSH_AVL_CSR_BASE,0x0,0x00000101);
	IOWR(GFILSH_AVL_CSR_BASE,0x5,0x000080C);
	return IORD(GFILSH_AVL_MEM_BASE,0x00000000);
}

//intel 4 byte fast read (0C)
int intel_four_byte_fast_read(){
	IOWR(GFILSH_AVL_CSR_BASE,0x4,0x00000000);
	IOWR(GFILSH_AVL_CSR_BASE,0x0,0x00000101);
	IOWR(GFILSH_AVL_CSR_BASE,0x5,0x000080C);
	return IORD(GFILSH_AVL_MEM_BASE,0x00000000);
}


//Page Program Commands

//4byte addr page program
void write_memory(){
	IOWR(GFILSH_AVL_CSR_BASE,0x4,0x00000000);
	IOWR(GFILSH_AVL_CSR_BASE,0x0,0x00000101);
	IOWR(GFILSH_AVL_CSR_BASE,0x6,0x00007002);		// write instruction register
	IOWR(GFILSH_AVL_MEM_BASE,0x00000000,0xabcd1234);
}
void write_memory_3byte(){
	IOWR(GFILSH_AVL_CSR_BASE,0x4,0x00000000);
	IOWR(GFILSH_AVL_CSR_BASE,0x0,0x00000001);
	IOWR(GFILSH_AVL_CSR_BASE,0x6,0x00000502);
	IOWR(GFILSH_AVL_MEM_BASE,0x00000000,0xabcd1234);
}

void write_memory_4byte(){
	IOWR(GFILSH_AVL_CSR_BASE,0x4,0x00000000);
	IOWR(GFILSH_AVL_CSR_BASE,0x0,0x00000001);
	IOWR(GFILSH_AVL_CSR_BASE,0x6,0x00000502);
	IOWR(GFILSH_AVL_MEM_BASE,0x00000000,0xabcd1234);
}

//Sector Protection Commands

//Applicable for cypress flash only

//Bit 5 & Bit 3 set of configuration register set to 1; Sector 0 of memory array is protected(TB-BP2-BP1-BP0:1-0-0-1) in status register;
void write_register_for_sector_protect_cypress(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x00002001);
	IOWR(GFILSH_AVL_CSR_BASE,0xA,0x0000201c);
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);				// start operation
}

void write_register_for_sector_unprotect_cypress(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x00002001);
	IOWR(GFILSH_AVL_CSR_BASE,0xA,0x00002000);
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);				// start operation
}

//Applicable for micron flash only

void write_register_for_sector_unprotect_micron(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x00001001);
	IOWR(GFILSH_AVL_CSR_BASE,0xA,0x00000000);
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);				// start operation
}

//Sector 0 of memory array is protected; (TB-BP3-BP2-BP1-BP0:1-0-0-0-1)
void write_status_register_for_block_protect_micron(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x00001001);
	IOWR(GFILSH_AVL_CSR_BASE,0xA,0x0000007c);
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);				// start operation
}

// intel

//Bit 5 & Bit 3 set of configuration register set to 1; Sector 0 of memory array is protected(TB-BP2-BP1-BP0:1-0-0-1) in status register;
void write_register_for_sector_protect_intel(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x00002001);
	IOWR(GFILSH_AVL_CSR_BASE,0xA,0x0000201c);
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);				// start operation
}

//Sector 0 of memory array is protected; (TB-BP3-BP2-BP1-BP0:1-0-0-0-1)
void write_status_register_for_block_protect_intel(){
	IOWR(GFILSH_AVL_CSR_BASE,0x7,0x00001001);
	IOWR(GFILSH_AVL_CSR_BASE,0xA,0x0000007c);
	IOWR(GFILSH_AVL_CSR_BASE,0x8,0x1);				// start operation
}


