You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

258 lines
8.8 KiB
C

/******************************************************************************************************************************************
* : GD25Q21.c
* : GD25Q21 SPI Flash
* : http://www.synwit.com.cn/e/tool/gbook/?bid=1
* :
* : V1.0.0 20171026
* :
*******************************************************************************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
* -ECTION WITH THEIR PRODUCTS.
*
* COPYRIGHT 2012 Synwit Technology
*******************************************************************************************************************************************/
#include "SWM221.h"
#include "GD25Q21.h"
/******************************************************************************************************************************************
* : GD25Q21_Init()
* : GD25Q21使SPIIDGD25Q21
* :
* :
* :
******************************************************************************************************************************************/
void GD25Q21_Init(void)
{
uint16_t chip_id;
uint8_t manufacture_id, device_id;
SPI_InitStructure SPI_initStruct;
GPIO_Init(GPIOB, PIN15, 1, 0, 0, 0);
#define GD25Q21_Assert() GPIO_ClrBit(GPIOB, PIN15)
#define GD25Q21_Deassert() GPIO_SetBit(GPIOB, PIN15)
GD25Q21_Deassert();
PORT_Init(PORTB, PIN10, PORTB_PIN10_SPI0_SCLK, 0);
PORT_Init(PORTB, PIN13, PORTB_PIN13_SPI0_MOSI, 0);
PORT_Init(PORTB, PIN14, PORTB_PIN14_SPI0_MISO, 1);
SPI_initStruct.clkDiv = SPI_CLKDIV_32;
SPI_initStruct.FrameFormat = SPI_FORMAT_SPI;
SPI_initStruct.SampleEdge = SPI_FIRST_EDGE;
SPI_initStruct.IdleLevel = SPI_LOW_LEVEL;
SPI_initStruct.WordSize = 8;
SPI_initStruct.Master = 1;
SPI_initStruct.RXThreshold = 0;
SPI_initStruct.RXThresholdIEn = 0;
SPI_initStruct.TXThreshold = 0;
SPI_initStruct.TXThresholdIEn = 0;
SPI_initStruct.TXCompleteIEn = 0;
SPI_Init(SPI0, &SPI_initStruct);
SPI_Open(SPI0);
chip_id = GD25Q21_ReadChipID();
manufacture_id = chip_id >> 8;
device_id = chip_id & 0xFF;
if((manufacture_id == GD25Q21_MANUFACTOR_ID) && (device_id == GD25Q21_DEVICE_ID))
{
printf("GD25Q21 found\r\n");
}
else
{
printf("Manufactor ID: %02X, Device ID: %02X, fail to identify\r\n", manufacture_id, device_id);
}
}
/******************************************************************************************************************************************
* : GD25Q21_ReadChipID()
* : ID
* :
* : uint16_t ID168ID8Device ID
* :
******************************************************************************************************************************************/
uint16_t GD25Q21_ReadChipID(void)
{
uint8_t manufacture_id, device_id;
GD25Q21_Assert();
SPI_ReadWrite(SPI0, GD25Q21_CMD_READ_CHIP_ID);
SPI_ReadWrite(SPI0, 0x00);
SPI_ReadWrite(SPI0, 0x00);
SPI_ReadWrite(SPI0, 0x00);
manufacture_id = SPI_ReadWrite(SPI0, 0xFF);
device_id = SPI_ReadWrite(SPI0, 0xFF);
GD25Q21_Deassert();
return (manufacture_id << 8) | device_id;
}
/******************************************************************************************************************************************
* : GD25Q21_ReadStatus()
* :
* :
* : uint16_t
* :
******************************************************************************************************************************************/
uint16_t GD25Q21_ReadStatus(void)
{
uint16_t status;
GD25Q21_Assert();
SPI_ReadWrite(SPI0, GD25Q21_CMD_READ_STATUS_L);
status = SPI_ReadWrite(SPI0, 0xFF);
GD25Q21_Deassert();
GD25Q21_Assert();
SPI_ReadWrite(SPI0, GD25Q21_CMD_READ_STATUS_H);
status |= SPI_ReadWrite(SPI0, 0xFF) << 8;
GD25Q21_Deassert();
return status;
}
/******************************************************************************************************************************************
* : GD25Q21_IsBusy()
* :
* :
* : uint32_t 1 0
* :
******************************************************************************************************************************************/
uint32_t GD25Q21_IsBusy(void)
{
return (GD25Q21_ReadStatus() & GD25Q21_STATUS_WIP_Msk) ? 1 : 0;
}
/******************************************************************************************************************************************
* : GD25Q21_QuadSwitch()
* : 4线
* : uint32_t 1 4线 0 4线
* : uint16_t
* :
******************************************************************************************************************************************/
void GD25Q21_QuadSwitch(uint32_t on)
{
uint16_t status = GD25Q21_ReadStatus();
if(on)
status |= (1 << GD25Q21_STATUS_QE_Pos);
else
status &= ~(1 << GD25Q21_STATUS_QE_Pos);
GD25Q21_Assert();
SPI_ReadWrite(SPI0, GD25Q21_CMD_WRITE_ENABLE);
GD25Q21_Deassert();
GD25Q21_Assert();
SPI_ReadWrite(SPI0, GD25Q21_CMD_WRITE_STATUS);
SPI_ReadWrite(SPI0, (status >> 0) & 0xFF);
SPI_ReadWrite(SPI0, (status >> 8) & 0xFF);
GD25Q21_Deassert();
}
/******************************************************************************************************************************************
* : GD25Q21_EraseSector()
* :
* : uint32_t addr 4K
* :
* :
******************************************************************************************************************************************/
void GD25Q21_EraseSector(uint32_t addr)
{
GD25Q21_Assert();
SPI_ReadWrite(SPI0, GD25Q21_CMD_WRITE_ENABLE);
GD25Q21_Deassert();
GD25Q21_Assert();
SPI_ReadWrite(SPI0, GD25Q21_CMD_ERASE_SECTOR);
SPI_ReadWrite(SPI0, (addr >> 16) & 0xFF);
SPI_ReadWrite(SPI0, (addr >> 8) & 0xFF);
SPI_ReadWrite(SPI0, (addr >> 0) & 0xFF);
GD25Q21_Deassert();
}
/******************************************************************************************************************************************
* : GD25Q21_ReadData()
* : GD25Q21
* : uint32_t addr GD25Q21
* uint8_t buff[] buff
* uint32_t cnt
* :
* :
******************************************************************************************************************************************/
void GD25Q21_ReadData(uint32_t addr, uint8_t buff[], uint32_t cnt)
{
uint32_t i;
GD25Q21_Assert();
SPI_ReadWrite(SPI0, GD25Q21_CMD_READ_DATA);
SPI_ReadWrite(SPI0, (addr >> 16) & 0xFF);
SPI_ReadWrite(SPI0, (addr >> 8) & 0xFF);
SPI_ReadWrite(SPI0, (addr >> 0) & 0xFF);
for(i = 0; i < cnt; i++)
{
buff[i] = SPI_ReadWrite(SPI0, 0xFF);
}
GD25Q21_Deassert();
}
/******************************************************************************************************************************************
* : GD25Q21_WritePage()
* : GD25Q21
* : uint32_t addr GD25Q21
* uint8_t data[]
* uint16_t cnt 256
* :
* :
******************************************************************************************************************************************/
void GD25Q21_WritePage(uint32_t addr, uint8_t data[], uint16_t cnt)
{
uint32_t i;
GD25Q21_Assert();
SPI_ReadWrite(SPI0, GD25Q21_CMD_WRITE_ENABLE);
GD25Q21_Deassert();
GD25Q21_Assert();
SPI_ReadWrite(SPI0, GD25Q21_CMD_WRITE_PAGE);
SPI_ReadWrite(SPI0, (addr >> 16) & 0xFF);
SPI_ReadWrite(SPI0, (addr >> 8) & 0xFF);
SPI_ReadWrite(SPI0, (addr >> 0) & 0xFF);
for(i = 0; i < cnt; i++)
{
SPI_ReadWrite(SPI0, data[i]);
}
GD25Q21_Deassert();
}