Files
QD4C-firmware/libraries/zf_device/zf_device_w25q32.c

402 lines
16 KiB
C
Raw Normal View History

2023-12-11 21:45:06 +08:00
/*********************************************************************************************************************
* CH32V307VCT6 Opensourec Library <EFBFBD><EFBFBD><EFBFBD><EFBFBD>CH32V307VCT6 <EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڹٷ<EFBFBD> SDK <EFBFBD>ӿڵĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD>
* Copyright (c) 2022 SEEKFREE <EFBFBD><EFBFBD><EFBFBD>ɿƼ<EFBFBD>
*
* <EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>CH32V307VCT6 <EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* CH32V307VCT6 <EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ը<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> GPL<EFBFBD><EFBFBD>GNU General Public License<EFBFBD><EFBFBD><EFBFBD><EFBFBD> GNUͨ<EFBFBD>ù<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> GPL <EFBFBD>ĵ<EFBFBD>3<EFBFBD><EFBFBD><EFBFBD> GPL3.0<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD>κκ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>İ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD>
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>κεı<EFBFBD>֤
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ի<EFBFBD><EFBFBD>ʺ<EFBFBD><EFBFBD>ض<EFBFBD><EFBFBD><EFBFBD>;<EFBFBD>ı<EFBFBD>֤
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>μ<EFBFBD> GPL
*
* <EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬʱ<EFBFBD>յ<EFBFBD>һ<EFBFBD><EFBFBD> GPL <EFBFBD>ĸ<EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD>У<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><https://www.gnu.org/licenses/>
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD> GPL3.0 <EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤Э<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD>İ
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӣ<EFBFBD>İ<EFBFBD><EFBFBD><EFBFBD> libraries/doc <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD> GPL3_permission_statement.txt <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> libraries <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD> LICENSE <EFBFBD>ļ<EFBFBD>
* <EFBFBD><EFBFBD>ӭ<EFBFBD><EFBFBD>λʹ<EFBFBD>ò<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɿƼ<EFBFBD><EFBFBD>İ<EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> zf_device_w25q32
* <EFBFBD><EFBFBD>˾<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>ɶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɿƼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>޹<EFBFBD>˾
* <EFBFBD><EFBFBD><EFBFBD>Ϣ <EFBFBD> libraries/doc <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> version <EFBFBD>ļ<EFBFBD> <EFBFBD>˵<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MounRiver Studio V1.8.1
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ̨ CH32V307VCT6
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> https://seekfree.taobao.com/
*
* <EFBFBD>޸ļ<EFBFBD>¼
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>ע
* 2022-09-15 <EFBFBD><EFBFBD>W first version
********************************************************************************************************************/
/*********************************************************************************************************************
* <EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD><EFBFBD>
* ------------------------------------
* ģ<EFBFBD><EFBFBD><EFBFBD>ܽ<EFBFBD> <EFBFBD><EFBFBD>Ƭ<EFBFBD><EFBFBD><EFBFBD>ܽ<EFBFBD>
* //------------------Ӳ<><D3B2> SPI <20><><EFBFBD><EFBFBD>------------------//
* SPC <EFBFBD> zf_device_w25q32.h <EFBFBD><EFBFBD> W25Q32_SPC_PIN <EFBFBD><EFBFBD><EFBFBD>
* SDI <EFBFBD> zf_device_w25q32.h <EFBFBD><EFBFBD> W25Q32_SDI_PIN <EFBFBD><EFBFBD><EFBFBD>
* SDO <EFBFBD> zf_device_w25q32.h <EFBFBD><EFBFBD> W25Q32_SDO_PIN <EFBFBD><EFBFBD><EFBFBD>
* CS <EFBFBD> zf_device_w25q32.h <EFBFBD><EFBFBD> W25Q32_CS_PIN <EFBFBD><EFBFBD><EFBFBD>
* //------------------Ӳ<><D3B2> SPI <20><><EFBFBD><EFBFBD>------------------//
* <EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* VCC 3.3V<EFBFBD><EFBFBD>Դ
* GND <EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD>
* ------------------------------------
********************************************************************************************************************/
#include "zf_device_w25q32.h"
static uint8 w25q32_read_dat()
{
// W25Q32_CS(0);
uint8 dat = spi_read_8bit(W25Q32_SPI);
// W25Q32_CS(1);
return dat;
}
static void w25q32_read_dats(uint8 *dat, uint32 len)
{
// W25Q32_CS(0);
spi_read_8bit_array(W25Q32_SPI, dat, len);
// W25Q32_CS(1);
}
static void w25q32_write_dat(uint8 dat)
{
// W25Q32_CS(0);
spi_write_8bit(W25Q32_SPI, dat);
// W25Q32_CS(1);
}
static void w25q32_write_dats(uint8 *dat, uint32 len)
{
// W25Q32_CS(0);
spi_write_8bit_array(W25Q32_SPI, dat, len);
// W25Q32_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> дʹ<D0B4><CAB9> <20>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> void
// <20><><EFBFBD>ز<EFBFBD><D8B2><EFBFBD> void
//-------------------------------------------------------------------------------------------------------------------
static void w25q32_write_enable(void)
{
W25Q32_CS(0);
w25q32_write_dat(W25Q32_WRITE_ENABLE); //<2F><><EFBFBD><EFBFBD>дʹ<D0B4><CAB9>
W25Q32_CS(1);
}
////-------------------------------------------------------------------------------------------------------------------
//// @brief дʧ<D0B4><CAA7> <20>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD>
//// @param void
//// @return void
////-------------------------------------------------------------------------------------------------------------------
//static void w25q32_write_disable(void)
//{
// W25Q32_CS(0);
// w25q32_write_dat(W25Q32_WRITE_DISABLE); //<2F><><EFBFBD><EFBFBD>д<EFBFBD><D0B4>ָֹ<D6B9><D6B8>
// W25Q32_CS(1);
//}
//-------------------------------------------------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȡ״̬ <20>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> void
// <20><><EFBFBD>ز<EFBFBD><D8B2><EFBFBD> uint8 <20>Ĵ<EFBFBD><C4B4><EFBFBD>״ֵ̬
// BIT7 6 5 4 3 2 1 0
// SPR RV TB BP2 BP1 BP0 WEL BUSY
// Sample usage:
//-------------------------------------------------------------------------------------------------------------------
static uint8 w25q32_read_state(void)
{
uint8 byte=0;
W25Q32_CS(0);
//<2F><><EFBFBD>Ͷ<EFBFBD>ȡ״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><>ȡһ<C8A1><D2BB><EFBFBD>ֽ<EFBFBD>
w25q32_write_dat(W25Q32_READ_STATUS_REG_1); // <20><><EFBFBD>Ͷ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
byte = w25q32_read_dat(); // <20><>ȡһ<C8A1><D2BB><EFBFBD>ֽ<EFBFBD>
W25Q32_CS(1);
return byte;
}
//-------------------------------------------------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȴ<EFBFBD><C8B4><EFBFBD>æ <20>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> void
// <20><><EFBFBD>ز<EFBFBD><D8B2><EFBFBD> void
//-------------------------------------------------------------------------------------------------------------------
static void w25q32_wait_busy(void)
{
while ((w25q32_read_state()&0x01)==0x01); // <20>ȴ<EFBFBD>BUSY<53><59>λ
}
//-------------------------------------------------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>оƬid <20>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> void
// <20><><EFBFBD>ز<EFBFBD><D8B2><EFBFBD> uint16 IDֵ
// Sample usage:
//-------------------------------------------------------------------------------------------------------------------
static uint16 w25q32_read_device_id(void)
{
uint8 send_dat[4] = {W25Q32_DEVICE_ID, 0x00, 0x00, 0x00};
uint8 read_dat[2] = {0};
W25Q32_CS(0);
w25q32_write_dats(send_dat, 4);
w25q32_read_dats(read_dat, 2);
W25Q32_CS(1);
return read_dat[0] << 8 | read_dat[1];
}
//-------------------------------------------------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>W25Q32<33><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><>Ҫ<EFBFBD>ȴ<EFBFBD>20<32><30>)
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> void
// <20><><EFBFBD>ز<EFBFBD><D8B2><EFBFBD> void
//-------------------------------------------------------------------------------------------------------------------
void w25q32_erase_chip(void)
{
w25q32_wait_busy();
W25Q32_CS(0); //ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
w25q32_write_dat(W25Q32_CHIP_ERASE); //<2F><><EFBFBD><EFBFBD>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
W25Q32_CS(1); //ȡ<><C8A1>Ƭѡ
w25q32_wait_busy(); //<2F>ȴ<EFBFBD>оƬ<D0BE><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
//-------------------------------------------------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȡһ<C8A1><D2BB><EFBFBD>ֽ<EFBFBD> <20>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> uint32 <20><>ȡ<EFBFBD><C8A1>ַ24bit
// <20><><EFBFBD>ز<EFBFBD><D8B2><EFBFBD> uint8 <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ֵ
// @since v1.0
// ʹ<><CAB9>ʾ<EFBFBD><CABE> w25q32_read_byte(0x000001);
//-------------------------------------------------------------------------------------------------------------------
static uint8 w25q32_read_byte(uint32 addr)
{
uint8 temp;
W25Q32_CS(0);
w25q32_write_dat(W25Q32_READ_DATA); // <20><><EFBFBD>Ͷ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
w25q32_write_dat((uint8)((addr)>>16)); // <20><><EFBFBD><EFBFBD>24bit<69><74>ַ
w25q32_write_dat((uint8)((addr)>>8));
w25q32_write_dat((uint8)addr);
temp = w25q32_read_dat(); // <20><>ȡһ<C8A1><D2BB><EFBFBD>ֽ<EFBFBD>
W25Q32_CS(1);
return temp;
}
//-------------------------------------------------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> У<><D0A3>w25q32<33>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> block_num <20><>Ҫд<D2AA><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ W25Q32_BLOCK_00 - W25Q32_BLOCK_63
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> sector_num <20><>Ҫд<D2AA><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ W25Q32_SECTION_00 - W25Q32_SECTION_15
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> page_num <20><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>ҳ<EFBFBD>ı<EFBFBD><C4B1><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ W25Q32_PAGE_00 - W25Q32_PAGE_15
// <20><><EFBFBD>ز<EFBFBD><D8B2><EFBFBD> <20><><EFBFBD><EFBFBD>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD><30><C3BB><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><D0B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// @since v1.0
// ʹ<><CAB9>ʾ<EFBFBD><CABE> w25q32_check(W25Q32_BLOCK_63, W25Q32_SECTION_15, W25Q32_PAGE_00);
//-------------------------------------------------------------------------------------------------------------------
uint8 w25q32_check (w25q32_block_enum block_num, w25q32_section_enum sector_num, w25q32_page_enum page_num)
{
uint16 temp_loop;
uint32 addr = (W25Q32_BASE_ADDR +
W25Q32_BLOCK_SIZE*block_num +
W25Q32_SECTION_SIZE*sector_num +
W25Q32_PAGE_SIZE*page_num); // <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0>ַ
for(temp_loop = 0; temp_loop < W25Q32_PAGE_SIZE; temp_loop++) // ѭ<><D1AD><EFBFBD><EFBFBD>ȡ Flash <20><>ֵ
{
if( w25q32_read_byte(addr + temp_loop) != 0xff ) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0xff <20>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD>ֵ
return 1;
}
return 0;
}
//-------------------------------------------------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> block_num <20><>Ҫд<D2AA><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ W25Q32_BLOCK_00 - W25Q32_BLOCK_63
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> sector_num <20><>Ҫд<D2AA><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ W25Q32_SECTION_00 - W25Q32_SECTION_15
// <20><><EFBFBD>ز<EFBFBD><D8B2><EFBFBD>
// @since v1.0
// ʹ<><CAB9>ʾ<EFBFBD><CABE> w25q32_erase_sector(W25Q32_BLOCK_63, W25Q32_SECTION_15);
//-------------------------------------------------------------------------------------------------------------------
uint8 w25q32_erase_sector(w25q32_block_enum block_num, w25q32_section_enum sector_num)
{
uint32 addr = (W25Q32_BASE_ADDR +
W25Q32_BLOCK_SIZE*block_num +
W25Q32_SECTION_SIZE*sector_num +
W25Q32_PAGE_SIZE*0); // <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0>ַ
W25Q32_CS(0);
w25q32_write_dat(W25Q32_SECTOR_ERASE); // <20><><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
w25q32_write_dat((uint8)((addr)>>16)); // <20><><EFBFBD><EFBFBD>24bit<69><74>ַ
w25q32_write_dat((uint8)((addr)>>8));
w25q32_write_dat((uint8)addr);
W25Q32_CS(1);
w25q32_wait_busy(); // <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return 0;
}
//-------------------------------------------------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ӹõ<D3B8>ַ<EFBFBD><D6B7>ʼ<EFBFBD><CABC>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD> <20>ڲ<EFBFBD>ʹ<EFBFBD><CAB9>
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> addr <20><>ʼ<EFBFBD><CABC>ȡ<EFBFBD>ĵ<EFBFBD>ַ24bit
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> buff <20><><EFBFBD>ݴ洢<DDB4><E6B4A2>
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> len Ҫ<><D2AA>ȡ<EFBFBD>ij<EFBFBD><C4B3><EFBFBD>(<28><><EFBFBD><EFBFBD>65535)
// <20><><EFBFBD>ز<EFBFBD><D8B2><EFBFBD>
// @since v1.0
// ʹ<><CAB9>ʾ<EFBFBD><CABE> w25q32_erase_sector(0x000001, buf, 16);
//-------------------------------------------------------------------------------------------------------------------
static void w25q32_read_addr_dats(uint32 addr, uint8 *buff, uint16 len)
{
W25Q32_CS(0);
w25q32_write_dat(W25Q32_FAST_READ); // <20><><EFBFBD>Ͷ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
w25q32_write_dat((uint8)((addr)>>16)); // <20><><EFBFBD><EFBFBD>24bit<69><74>ַ
w25q32_write_dat((uint8)((addr)>>8));
w25q32_write_dat((uint8)addr);
w25q32_read_dat(); // <20><><EFBFBD>ٶ<EFBFBD>ȡҪ<C8A1><D2AA><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ֽ<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>ֽڡ<D6BD>
w25q32_read_dats(buff, len);
W25Q32_CS(1);//ȡ<><C8A1>Ƭѡ
}
//-------------------------------------------------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ӹõ<D3B8>ַ<EFBFBD><D6B7>ʼд<CABC><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ڲ<EFBFBD>ʹ<EFBFBD><CAB9>
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> addr <20><>ʼд<CABC><D0B4><EFBFBD>ĵ<EFBFBD>ַ24bit
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> buff <20><><EFBFBD>ݴ洢<DDB4><E6B4A2>
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> len Ҫд<D2AA><D0B4><EFBFBD>ij<EFBFBD><C4B3><EFBFBD>(<28><><EFBFBD><EFBFBD>256,<2C><>len<65><6E><EFBFBD>ܳ<EFBFBD><DCB3><EFBFBD><EFBFBD><EFBFBD>ҳʣ<D2B3><CAA3><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>)
// <20><><EFBFBD>ز<EFBFBD><D8B2><EFBFBD>
// @since v1.0
// ʹ<><CAB9>ʾ<EFBFBD><CABE> w25q32_write_addr_dats(0x000001, buf, 16);
//-------------------------------------------------------------------------------------------------------------------
static void w25q32_write_addr_dats(uint32 addr, uint8 *buff, uint16 len)
{
W25Q32_CS(0);
w25q32_write_dat(W25Q32_PAGE_PROGRAM); // <20><><EFBFBD><EFBFBD>дҳ<D0B4><D2B3><EFBFBD><EFBFBD>
w25q32_write_dat((uint8)((addr)>>16)); // <20><><EFBFBD><EFBFBD>24bit<69><74>ַ
w25q32_write_dat((uint8)((addr)>>8));
w25q32_write_dat((uint8)addr);
w25q32_write_dats(buff, len);
W25Q32_CS(1);
w25q32_wait_busy(); // <20>ȴ<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
//-------------------------------------------------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȡһҳ
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> block_num <20><>Ҫ<EFBFBD><D2AA>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ W25Q32_BLOCK_00 - W25Q32_BLOCK_63
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> sector_num <20><>Ҫ<EFBFBD><D2AA>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ W25Q32_SECTION_00 - W25Q32_SECTION_15
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> page_num <20><>Ҫ<EFBFBD><D2AA>ȡ<EFBFBD><C8A1>ҳ<EFBFBD><D2B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ W25Q32_PAGE_00 - W25Q32_PAGE_15
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> buf <20><>Ҫ<EFBFBD><D2AA>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ַ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͱ<EFBFBD><CDB1><EFBFBD>Ϊuint8 *
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> len <20><>Ҫ<EFBFBD><D2AA>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ 1-256
// <20><><EFBFBD>ز<EFBFBD><D8B2><EFBFBD> NULL
// @since v1.0
// <20><>ע<EFBFBD><D7A2>Ϣ
//-------------------------------------------------------------------------------------------------------------------
void w25q32_read_page(w25q32_block_enum block_num, w25q32_section_enum sector_num, w25q32_page_enum page_num,
uint8 *buf, uint16 len)
{
uint32 addr = (W25Q32_BASE_ADDR +
W25Q32_BLOCK_SIZE*block_num +
W25Q32_SECTION_SIZE*sector_num +
W25Q32_PAGE_SIZE*page_num); // <20><>ȡ<EFBFBD><C8A1>ǰ Flash <20><>ַ
w25q32_read_addr_dats(addr, buf, len);
}
//-------------------------------------------------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> д<><D0B4>һҳ
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> block_num <20><>Ҫ<EFBFBD><D2AA>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ W25Q32_BLOCK_00 - W25Q32_BLOCK_63
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> sector_num <20><>Ҫ<EFBFBD><D2AA>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ W25Q32_SECTION_00 - W25Q32_SECTION_15
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> page_num <20><>Ҫ<EFBFBD><D2AA>ȡ<EFBFBD><C8A1>ҳ<EFBFBD><D2B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ W25Q32_PAGE_00 - W25Q32_PAGE_15
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> buf <20><>Ҫ<EFBFBD><D2AA>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ַ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͱ<EFBFBD><CDB1><EFBFBD>Ϊuint8 *
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> len <20><>Ҫ<EFBFBD><D2AA>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ 1-256
// <20><><EFBFBD>ز<EFBFBD><D8B2><EFBFBD> NULL
// @since v1.0
// <20><>ע<EFBFBD><D7A2>Ϣ
//-------------------------------------------------------------------------------------------------------------------
void w25q32_write_page(w25q32_block_enum block_num, w25q32_section_enum sector_num, w25q32_page_enum page_num,
uint8 *buf, uint16 len)
{
uint32 flash_addr = (W25Q32_BASE_ADDR +
W25Q32_BLOCK_SIZE*block_num +
W25Q32_SECTION_SIZE*sector_num +
W25Q32_PAGE_SIZE*page_num); // <20><>ȡ<EFBFBD><C8A1>ǰ Flash <20><>ַ
w25q32_write_addr_dats(flash_addr, buf, len);
}
//-------------------------------------------------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Լ<EFBFBD> <20>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> void
// <20><><EFBFBD>ز<EFBFBD><D8B2><EFBFBD> void
//-------------------------------------------------------------------------------------------------------------------
static uint8 w25q32_self_check(void)
{
uint8 ret = 0;
uint16 dat = 0;
volatile int16 timeout_count = W25Q32_TIMEOUT_COUNT;
///* Winbond SPIFalsh ID */
//#define W25Q80 0XEF13
//#define W25Q16 0XEF14
//#define W25Q32 0XEF15
//#define W25Q64 0XEF16
//#define W25Q128 0XEF17
while(((dat & 0xEF10) != 0xEF10) && timeout_count) // <20>ж<EFBFBD> ID <20>Ƿ<EFBFBD><C7B7><EFBFBD>ȷ
{
timeout_count--;
dat = w25q32_read_device_id();
system_delay_ms(1);
}
if(timeout_count < 0)
{
ret = 1;
}
else
{
ret = 0;
}
return ret;
}
//-------------------------------------------------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ʼ<EFBFBD><CABC> W25Q32
// <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5> void
// <20><><EFBFBD>ز<EFBFBD><D8B2><EFBFBD> uint8 1-<2D><>ʼ<EFBFBD><CABC>ʧ<EFBFBD><CAA7> 0-<2D><>ʼ<EFBFBD><CABC><EFBFBD>ɹ<EFBFBD>
// Sample usage:
//-------------------------------------------------------------------------------------------------------------------
uint8 w25q32_init(void)
{
spi_init(W25Q32_SPI, SPI_MODE0, W25Q32_SPI_SPEED, W25Q32_SPC_PIN, W25Q32_SDI_PIN, W25Q32_SDO_PIN, W25Q32_CS_PIN);
if( w25q32_self_check() )
{
zf_log(0, "W25Q32 self check error.");
return 1;
}
w25q32_write_enable(); // дʹ<D0B4><CAB9>
return 0;
}