/****************************************************************************/
/* Copyright 2010, © Bendor Research Pty. Ltd. All rights reserved.			*/
/* Permission is granted to use this software for any purpose whatsoever	*/
/* as long as this copyright notice is preserved. The code is provided		*/
/* "as is", with no explicit, implicit or implied warranty or guarantee		*/
/* of any kind and Bendor Research Pty. Ltd. can not be held liable for		*/
/* any loss or damages arising out of the use of this software.				*/
/****************************************************************************/
/*																			*/
/*	Include file describing the Atmel AT45DBxxx flash chips in SPI mode		*/
/*	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~		*/
/*																			*/
/*	2010 May	ZK		Original											*/
/*																			*/
/****************************************************************************/

#ifndef _AT45_COMMON_H
#define	_AT45_COMMON_H

/****************************************************************************/
/*							Buffer commands									*/
/****************************************************************************/

#define	AT45_CMD_BUF1_READ_SLOW		0xd1	// Read from buffer, slow clock
#define	AT45_CMD_BUF1_READ_FAST		0xd4	// Read from buffer, fast clock
#define	AT45_CMD_BUF1_WRITE			0x84	// Write from buffer
#define	AT45_CMD_BUF1_LOAD			0x53	// Load buffer from FLASH array
#define	AT45_CMD_BUF1_STORE_CLR		0x83	// Store buffer in FLASH with erase
#define	AT45_CMD_BUF1_STORE_RAW		0x88	// Store buffer in FLASH, no erase
#define	AT45_CMD_BUF1_PROGRAM		0x88	// WRITE + STORE_CLR
#define	AT45_CMD_BUF1_VERIFY		0x60	// Compare buffer to FLASH array
#define	AT45_CMD_BUF1_REFRESH		0x58	// Auto rewrite through buffer

#define	AT45_CMD_BUF2_READ_SLOW		0xd3	// Read from buffer, slow clock
#define	AT45_CMD_BUF2_READ_FAST		0xd6	// Read from buffer, fast clock
#define	AT45_CMD_BUF2_WRITE			0x87	// Write from buffer
#define	AT45_CMD_BUF2_LOAD			0x55	// Load buffer from FLASH array
#define	AT45_CMD_BUF2_STORE_CLR		0x86	// Store buffer in FLASH with erase
#define	AT45_CMD_BUF2_STORE_RAW		0x89	// Store buffer in FLASH, no erase
#define	AT45_CMD_BUF2_PROGRAM		0x85	// WRITE + STORE_CLR
#define	AT45_CMD_BUF2_VERIFY		0x61	// Compare buffer to FLASH array
#define	AT45_CMD_BUF2_REFRESH		0x59	// Auto rewrite through buffer

/****************************************************************************/
/*							Direct read commands							*/
/****************************************************************************/

#define	AT45_CMD_READ_PAGE			0xd2	// Read a FLASH page
#define	AT45_CMD_READ_CONT_SLOW		0x03	// Read the FLASH array, slow clock
#define	AT45_CMD_READ_CONT_FAST		0x0b	// Read the FLASH array, fast clock

/****************************************************************************/
/*							Erase commands									*/
/****************************************************************************/

#define	AT45_CMD_ERASE_CHIP_0		0xc7	// Erase the chip, 1st byte
#define	AT45_ADR_ERASE_CHIP_1		0x94	// Erase the chip, 2nd byte
#define	AT45_ADR_ERASE_CHIP_2		0x80	// Erase the chip, 3rd byte
#define	AT45_ADR_ERASE_CHIP_3		0x9a	// Erase the chip, 4th byte
#define	AT45_CMD_ERASE_SECTOR		0x7c	// Erase a sector
#define	AT45_CMD_ERASE_BLOCK		0x50	// Erase a block (8 pages)
#define	AT45_CMD_ERASE_PAGE			0x81	// Erase a page

/****************************************************************************/
/*							Other commands									*/
/****************************************************************************/

#define	AT45_CMD_READ_STAT			0xd7	// Read the status register
#define	AT45_CMD_READ_DEVID			0x9f	// Read device and manufacturer ID
#define	AT45_CMD_DEEP_PDOWN			0xb9	// Deep power-down mode
#define	AT45_CMD_WAKE_UP			0xab	// Wake up from deep power-down
#define	AT45_CMD_BINARY_MODE_0		0x3d	// Set binary mode, 1st byte
#define	AT45_CMD_BINARY_MODE_1		0x2a	// Set binary mode, 2nd byte
#define	AT45_CMD_BINARY_MODE_2		0x80	// Set binary mode, 3rd byte
#define	AT45_CMD_BINARY_MODE_3		0xa6	// Set binary mode, 4th byte

// FIXME: Security and sector protection commands

#define	AT45_CMD_

/****************************************************************************/
/*							Status register bits							*/
/****************************************************************************/

#define	AT45_STAT_READY				0x80	// Chip is ready (not busy)
#define	AT45_STAT_MATCH				0x40	// Comparison matched
#define	AT45_STAT_SPROT				0x02	// Sector protection is enabled
#define	AT45_STAT_PSIZE				0x01	// Page size is power of two
#define	AT45_STAT_DSIZE				0x3c	// Device size mask
#define	AT45_STAT_DSIZE_1Mb			0x0c	// Device size is  1Mb
#define	AT45_STAT_DSIZE_64Mb		0x3c	// Device size is 64Mb

/****************************************************************************/
/*							Other definitions								*/
/****************************************************************************/

/*
*	Calculates the address bytes when the chip is used with native page size
*	(i.e. not a power-of-2). The 'page' argument is the page, the 'offs'
*	argument is the offset within the page (or 0, if not needed) and the 'byte'
*	argument is 1, 2 or 3 for the first, second or third byte of the address
*	in the SPI command sequence. That is, you should do someting like this:
*
*		spi_buffer[ 0 ] = AT45_CMD_A_COMMAND
*		spi_buffer[ 1 ] = AT45_ADDR( the_page, the_offset, 1 );
*		spi_buffer[ 2 ] = AT45_ADDR( the_page, the_offset, 2 );
*		spi_buffer[ 3 ] = AT45_ADDR( the_page, the_offset, 3 );
*
*		DoSpiTransfer( spi_buff, ... );
*
*	This macro relies on the AT45_PAGE_SHIFT macro being defined, it gets
*	defined in the individual chip header.
*/

#define	AT45_ADDR( page, offs, byte )	\
	((((((page)<<AT45_PAGE_SHIFT))+(offs))>>((3-(byte))<<3))&255)

#endif

