#ifndef AMDFLASH_h
#define AMDFLASH_h

#include "nios.h"

class AMDFlash
{
public:
	static void Init(void);
	static int await_erase_complete(int entire_chip, volatile unsigned char *addr);		// Wait for the given address to contain 0xFF. Return value: 1 on success, 0 on timeout failure.
	static void wait_at_least_1_us(void);													// This routine actually takes about 3 us on a 33.333MHz Nios32.
	static void unlock_bypass_mode(volatile unsigned char *flash_base);						// Unlock bypass mode, enabling fast writes.
	static void reset_bypass_mode(volatile unsigned char *flash_base);						// Turn bypass mode off, disabling fast writes and enabling normal function.
	static int await_write_complete(volatile unsigned char *addr, const unsigned char correct_value);	// Read the given address until two successive reads yield the same value. Return value: 0 on success, -1 on timeout failure.
	static int nr_flash_write_bypass(volatile unsigned char *flash_base, volatile unsigned char *addr, unsigned char val);	// Write val to the given flash address, in bypass mode (assumes that bypass mode has been enabled already). Return value: 0 on success, -1 on failure.

	static int nr_flash_erase_sector(unsigned long *flash_base, unsigned long *sector_address);	// Erase the flash sector at sector_address. Return value: 0 on success, -1 on failure.
	static int nr_flash_write_buffer(unsigned long *flash_base, unsigned long *start_address, unsigned long *buffer, int size);	// Write a buffer of data to the flash, using bypass mode. Return value: 1 on success, 0 on failure. Note: the integer "size" is given as a number of half-words to write.   How convenient.  We write this 8-bit-wide flash one byte at a time (of course).
	static int amd29lv065d_flash_write_byte(unsigned char *flash_base, unsigned char *addr, unsigned char val); // Writes one byte to Flash
	static int nr_flash_write(unsigned long *flash_base, unsigned long *addr, unsigned long val); // Writes one Value to Flash
    
	static void Clear_Data_FLASH(void);														// Clear the Data Flash;
	static int copy_signal_to_flash(unsigned long *flash_address);
	static void load_signal_from_flash(unsigned long *flash_address);
    
	static void copy_flash_to_planes(void);													// Copy the flash memory to the planes	
	static void copy_flash_to_plane(unsigned long *flash_address, unsigned long *plane);	// Copy one flash to plane
	
	static void Write_Config_Flash(void);													// Write Config to Flash
	static void Read_Config_Flash(void);													// Read Config from Flash
	
	static void Write_TestData_Flash(void);													// Write TestData to Flash
	static void Read_TestData_Flash(void);	                                                // Read TestData from Flash

	static int EraseSector_Flash(unsigned long *flash_address);                                   // Erase a sector on givven address
	static int WriteData_Byte_Flash(unsigned long *flash_address, unsigned char add, unsigned char data);   // Writes a Datablock at given address
	static void ReadData_Prepare_Flash(unsigned long *flash_address);
	static unsigned char ReadData_Byte_Flash(unsigned int add);

	static void Write_Protected_Flash(void);						// Write Protected to Flash
	static void Read_Protected_Flash(void);	                                                // Read Protected from Flash

	static void Write_Protected_Config(void);						//Restore configuration Data

};

#endif 
