/*
 * w25qflash.h
 *
 * Created: 12/06/2018 16:29:05
 *  Author: Ledo
 */ 


#ifndef W25QFLASH_H_
#define W25QFLASH_H_

#include "asf.h"

#define W25P_WriteEnable 0x06
#define W25P_WriteDisable 0x04
#define W25P_ReadStatusReg 0x05
#define W25P_WriteStatusReg 0x01
#define W25P_ReadData  0x03
#define W25P_FastReadData 0x0B
#define W25P_PageProgram 0x02
#define W25P_SectorErase 0xD8 // 64KB
#define W25P_ChipErase  0xC7
#define W25P_PowerDown  0xB9
#define W25P_ReleasePowerDown 0xAB
#define W25P_DeviceID  0xAB
#define W25P_ManufactDeviceID 0x90
#define R_JEDEC_ID	0x9f	//read JEDEC ID = Manuf+ID (suggested)


//#define chip_select()     {spi_set_peripheral_chip_select_value(SPI, 0x0E);}
//#define chip_deselect()   {spi_set_peripheral_chip_select_value(SPI, 0x0F);}
#define chip_select()     {pio_set_pin_low(PIO_PA11_IDX);}
#define chip_deselect()   {pio_set_pin_high(PIO_PA11_IDX);}
	
#define chip_protect()    {pio_set_pin_low(PIO_PD23_IDX);}
#define chip_unprotect()  {pio_set_pin_high(PIO_PD23_IDX);}

typedef enum partNumber
{
	W25Q80 = 1,
	W25Q16 = 2,
	W25Q32 = 4,
	W25Q64 = 8,
	W25Q128 = 16
}partNumber;


typedef struct
{
	partNumber pn;
	uint16_t id;
	uint32_t bytes;
	uint16_t pages;
	uint16_t sectors;
	uint16_t blocks;
}pnListType;

static const pnListType pnList[]  =
{
	{ W25Q80, 0x4014,1048576, 4096, 256, 16  },
	{ W25Q16, 0x4015,2097152, 8192, 512, 32  },
	{ W25Q32, 0x4016,4194304, 16384,1024,64  },
	{ W25Q64, 0x4017,8388608, 32768,2048,128 },
	{ W25Q128,0x4018,16777216,65536,4096,256 }
};


uint8_t tx_buff[2];
uint8_t  temp_buffer[256];

    void w25q_SPI_init(uint32_t freq);
    uint8_t w25q_spi_master_transfer(uint8_t byte);
	void w25q_IO_Send_Byte(uint8_t out);
	uint8_t w25q_IO_Get_Byte();
	void w25q_IO_Wait_Busy();
	uint8_t w25q_IO_Read_StatusReg();  //Reads the status register of the serial flash
	void w25q_IO_Write_StatusReg(uint8_t byte);//Performs a write to the status register
	void w25q_IO_Write_Enable();	//Write enables the serial flash
	void w25q_IO_PowerDown();
	void w25q_IO_ReleasePowerDown();
	uint8_t w25q_IO_Read_ID1();//Reads the device ID using the instruction 0xAB
	uint16_t w25q_IO_Read_ID2(uint8_t ID_Addr);//Reads the manufacturer ID and device ID with 0x90
	uint8_t w25q_IO_Read_Byte(unsigned long Dst_Addr);//Reads one byte from the serial flash and returns byte(max of 40 MHz CLK frequency)
	void w25q_IO_Read_nBytes(unsigned long Dst_Addr, uint16_t nBytes_128);//Reads multiple bytes(max of 40 MHz CLK frequency)
	uint16_t w25q_IO_Read_word(unsigned long Dst_Addr);
	uint8_t w25q_IO_FastRead_Byte(unsigned long Dst_Addr);//Reads one byte from the serial flash and returns byte(max of 80 MHz CLK frequency)
	void w25q_IO_FastRead_nBytes(unsigned long Dst_Addr, uint16_t nBytes_128);//Reads multiple bytes(max of 80 MHz CLK frequency)
	void w25q_IO_Write_Byte(unsigned long Dst_Addr, uint8_t byte);//Program one byte to the serial flash
	void w25q_IO_Write_nBytes(unsigned long Dst_Addr, uint16_t nBytes_128);//Program n bytes to the serial flash, n<=256
	void w25q_IO_Erase_Chip();//Erases entire serial flash
	void w25q_IO_Erase_Sector(unsigned long Dst_Addr);//Erases one sector (64 KB) of the serial flash
	void w25q_Verify(uint8_t byte, uint8_t cor_byte);
	void w25q_IO_Write_Disable();//Write disables the serial flash
	uint16_t w25q_IO_Read_ID3();

#endif /* W25QFLASH_H_ */