Files
FireAlarmCtrlCn/FW/Core/my_src/W25Qxx_iodrv.c
2026-04-06 19:02:09 +08:00

564 lines
10 KiB
C

#include "main.h"
#define W25Q128_FLASH_SIZE 0x01000000
#define W25Q128_ADDR_BIT_NUM 24
#define NOR_FLASH_SIZE W25Q128_FLASH_SIZE
#define NOR_FLASH_ADDR_BIT_NUM W25Q128_ADDR_BIT_NUM
#define FLASH_WP_H() LL_GPIO_SetOutputPin(GPIOG,LL_GPIO_PIN_13)
#define FLASH_WP_L() LL_GPIO_ResetOutputPin(GPIOG,LL_GPIO_PIN_13)
#define FLASH_HOLD_H() LL_GPIO_SetOutputPin(GPIOE,LL_GPIO_PIN_2)
#define FLASH_HOLD_L() LL_GPIO_ResetOutputPin(GPIOE,LL_GPIO_PIN_2)
#define xSPI_CS_HI() LL_GPIO_SetOutputPin(GPIOA,LL_GPIO_PIN_15)
#define xSPI_CS_LO() LL_GPIO_ResetOutputPin(GPIOA,LL_GPIO_PIN_15)
#define xSPI_CLK_HI() LL_GPIO_SetOutputPin(GPIOG,LL_GPIO_PIN_11)
#define xSPI_CLK_LO() LL_GPIO_ResetOutputPin(GPIOG,LL_GPIO_PIN_11)
#define xSPI_SET_MISO_INPUT() GPIOG->MODER&=~0x000C0000
#define xSPI_SET_MISO_OUTPUT() GPIOG->MODER|=0x00040000
#define xSPI_SET_MOSI_INPUT() GPIOD->MODER&=~0x0000C000
#define xSPI_SET_MOSI_OUTPUT() GPIOD->MODER|=0x00004000
#define xSPI_GET_MISO() LL_GPIO_IsInputPinSet(GPIOG,LL_GPIO_PIN_9)
#define xSPI_MOSI_HI() GPIOD->ODR|=(1<<7)
#define xSPI_MOSI_LO() GPIOD->ODR&=~(1<<7)
#define xSPI_SET_DATA_INPUT() (GPIOG->MODER&=~0x0C0C0000,GPIOE->MODER&=~0x00000030,GPIOD->MODER&=~0x0000C000)
#define xSPI_SET_DATA_OUTPUT() (GPIOG->MODER|=0x04040000,GPIOE->MODER|=0x00000010,GPIOD->MODER|=0x00004000)
#define xSPI_DIN() (((GPIOE->IDR&0x0004)<<1)|((GPIOG->IDR&0x2000)>>11)|((GPIOG->IDR&0x0200)>>8)|((GPIOD->IDR&0x0080)>>7))
#define xSPI_D0_HI() LL_GPIO_SetOutputPin(GPIOD,LL_GPIO_PIN_7)
#define xSPI_D0_LO() LL_GPIO_ResetOutputPin(GPIOD,LL_GPIO_PIN_7)
#define xSPI_D1_HI() LL_GPIO_SetOutputPin(GPIOG,LL_GPIO_PIN_9)
#define xSPI_D1_LO() LL_GPIO_ResetOutputPin(GPIOG,LL_GPIO_PIN_9)
#define xSPI_D2_HI() LL_GPIO_SetOutputPin(GPIOG,LL_GPIO_PIN_13)
#define xSPI_D2_LO() LL_GPIO_ResetOutputPin(GPIOG,LL_GPIO_PIN_13)
#define xSPI_D3_HI() LL_GPIO_SetOutputPin(GPIOE,LL_GPIO_PIN_2)
#define xSPI_D3_LO() LL_GPIO_ResetOutputPin(GPIOE,LL_GPIO_PIN_2)
static void flash_reset(void);
static void flash_write_enable(void);
static void flash_write_disable(void);
static void flash_quad_enable(void);
static void flash_quad_disable(void);
static uint8_t flash_read_sr1(void);
static uint8_t flash_read_sr2(void);
static void wait(void)
{
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
}
void w25q_IO_setup(void)
{
static uint8_t val = 0;
uint32_t i = 0;
/*
LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOC);
LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOD);
//PD6 PC10 12 13 14 15
GPIOC->MODER &=~0xFF300000;
GPIOD->MODER &=~0x00003000;
GPIOC->MODER |= 0x00100000;
GPIOD->MODER |= 0x00001000; //PD6,PC10 GPIO Output Mode
GPIOC->OTYPER &=~0x0000F400; //Output push-pull
GPIOD->OTYPER &=~0x00000040;
GPIOC->OSPEEDR |= 0xFF300000; //Very High speed
GPIOD->OSPEEDR |= 0x00003000;
*/
xSPI_CS_HI();
xSPI_CLK_LO();
xSPI_SET_DATA_OUTPUT();
FLASH_WP_H();
FLASH_HOLD_H();
for(i=0;i<10000;i++);
flash_write_enable();
xSPI_SET_DATA_INPUT();
flash_reset();
xSPI_SET_DATA_OUTPUT();
FLASH_WP_H();
FLASH_HOLD_H();
for(i=0;i<10000;i++);
flash_write_enable();
xSPI_SET_DATA_INPUT();
do
{
val = flash_read_sr1();
}while(val&0x01);
val = flash_read_sr2();
if(!(val&0x02))
{
do
{
flash_quad_enable();
val = flash_read_sr2();
}while(!(val&0x02));
}
}
uint8_t QSPI_D0123_read(void)
{
return(xSPI_DIN());
}
void QSPI_D0123_write(uint8_t x)
{
if(x&0x01)
{
xSPI_D0_HI();
}
else
{
xSPI_D0_LO();
}
if(x&0x02)
{
xSPI_D1_HI();
}
else
{
xSPI_D1_LO();
}
if(x&0x04)
{
xSPI_D2_HI();
}
else
{
xSPI_D2_LO();
}
if(x&0x08)
{
xSPI_D3_HI();
}
else
{
xSPI_D3_LO();
}
}
void xspi_write_byte(uint8_t data)
{
uint32_t i;
xSPI_SET_MOSI_OUTPUT();
for(i=0;i<8;i++)
{
if(data & 0x80)xSPI_MOSI_HI();
else xSPI_MOSI_LO();
xSPI_CLK_HI();
xSPI_CLK_LO();
data<<=1;
}
xSPI_MOSI_LO();
xSPI_SET_MOSI_INPUT();
}
uint8_t xspi_read_byte(void)
{
uint32_t i;
uint8_t data = 0;
for(i=0;i<8;i++)
{
wait();
data<<=1;
if(xSPI_GET_MISO())data |= 0x01;
xSPI_CLK_HI();
wait();
xSPI_CLK_LO();
}
return data;
}
void xspi_quad_write_byte(uint8_t data)
{
xSPI_SET_DATA_OUTPUT();
QSPI_D0123_write(data>>4);
xSPI_CLK_HI();
wait();
xSPI_CLK_LO();
QSPI_D0123_write(data);
xSPI_CLK_HI();
wait();
xSPI_CLK_LO();
xSPI_SET_DATA_INPUT();
wait();
}
uint8_t xspi_quad_read_byte(void)
{
uint8_t data;
data = QSPI_D0123_read();
xSPI_CLK_HI();
xSPI_CLK_LO();
data<<=4;
data |= QSPI_D0123_read();
xSPI_CLK_HI();
xSPI_CLK_LO();
return data;
}
static void flash_write_enable(void)
{
uint32_t i = 0;
xSPI_CLK_LO();
xSPI_CS_LO();
wait();
xspi_write_byte(0x06);
xSPI_CS_HI();
for(i=0;i<10000;i++);
}
static void flash_write_disable(void)
{
xSPI_CLK_LO();
xSPI_CS_LO();
wait();
xspi_write_byte(0x04);
xSPI_CS_HI();
}
static uint8_t flash_read_sr1(void)
{
uint8_t sr1;
xSPI_CLK_LO();
xSPI_CS_LO();
wait();
xspi_write_byte(0x05);
sr1 = xspi_read_byte();
wait();
xSPI_CS_HI();
return sr1;
}
static uint8_t flash_read_sr2(void)
{
uint8_t sr2;
xSPI_CLK_LO();
xSPI_CS_LO();
wait();
xspi_write_byte(0x35);
sr2 = xspi_read_byte();
wait();
xSPI_CS_HI();
return sr2;
}
void flash_write_sr(uint8_t sr1,uint8_t sr2)
{
flash_write_enable();
xSPI_CLK_LO();
xSPI_CS_LO();
wait();
xspi_write_byte(0x01);
xspi_write_byte(sr1);
xspi_write_byte(sr2);
wait();
xSPI_CS_HI();
flash_write_disable();
}
static void flash_quad_enable(void)
{
flash_write_enable();
flash_write_sr(0x00,0x02);
flash_write_disable();
}
static void flash_quad_disable(void)
{
flash_write_enable();
flash_write_sr(0x00,0x00);
flash_write_disable();
}
uint8_t get_flash_write_status(void)
{
return(flash_read_sr1() & 0x01);
}
unsigned int flash_quad_read_data(unsigned int addr, unsigned char * p_data,unsigned int len)//p_data >=256byte
{
unsigned int i = 0;
if((addr + len) > NOR_FLASH_SIZE)return 1;
xSPI_CLK_LO();
xSPI_CS_LO();
xspi_write_byte(0x6b);
xspi_write_byte((addr>>16)&0xff);
xspi_write_byte((addr>>8)&0xff);
xspi_write_byte(addr&0xff);
xspi_write_byte(0);
for(i=0;i<len;i++)
{
p_data[i] = xspi_quad_read_byte();
}
xSPI_CS_HI();
return 0;
}
uint8_t* flash_quad_read_page(uint32_t addr)
{
uint32_t i = 0;
unsigned int addr_page = addr & 0xFFFFFF00;
static uint8_t p_data[288];
xSPI_CLK_LO();
xSPI_CS_LO();
xspi_write_byte(0x6b);
xspi_write_byte((addr_page>>16)&0xff);
xspi_write_byte((addr_page>>8)&0xff);
xspi_write_byte(addr_page&0xff);
xspi_write_byte(0);
for(i=0;i<256;i++)
{
p_data[i] = xspi_quad_read_byte();
}
xSPI_CS_HI();
return &p_data[0];
}
void flash_quad_program_page(uint32_t addr,uint8_t* p_data)
{
uint32_t i = 0;
unsigned int addr_page = addr & 0xFFFFFF00;
//flash_quad_enable();
//do{
//i = flash_read_sr1();
//}while(i&0x01);
flash_write_enable();
xSPI_CLK_LO();
xSPI_CS_LO();
wait();
xspi_write_byte(0x32);
xspi_write_byte((addr_page>>16)&0xff);
xspi_write_byte((addr_page>>8)&0xff);
xspi_write_byte(addr_page&0xff);
for(i=0;i<256;i++)
{
xspi_quad_write_byte(*p_data);
p_data++;
}
xSPI_CS_HI();
flash_write_disable();
do{
LL_IWDG_ReloadCounter(IWDG1);
i = flash_read_sr1();
}while(i&0x01);
}
void flash_quad_program_page_no_wait(uint32_t addr,uint8_t* p_data)
{
uint32_t i = 0;
unsigned int addr_page = addr & 0xFFFFFF00;
flash_write_enable();
xSPI_CLK_LO();
xSPI_CS_LO();
wait();
xspi_write_byte(0x32);
xspi_write_byte((addr_page>>16)&0xff);
xspi_write_byte((addr_page>>8)&0xff);
xspi_write_byte(addr_page&0xff);
for(i=0;i<256;i++)
{
xspi_quad_write_byte(*p_data);
p_data++;
}
xSPI_CS_HI();
flash_write_disable();
}
unsigned int flash_quad_program_no_wait(uint32_t addr,uint8_t* p_data,unsigned int len)
{
uint32_t i = 0;
if(((addr&0xFF) + len) > 0x100)return 1;
flash_write_enable();
xSPI_CLK_LO();
xSPI_CS_LO();
wait();
xspi_write_byte(0x32);
xspi_write_byte((addr>>16)&0xff);
xspi_write_byte((addr>>8)&0xff);
xspi_write_byte(addr&0xff);
for(i=0;i<len;i++)
{
xspi_quad_write_byte(*p_data);
p_data++;
}
xSPI_CS_HI();
flash_write_disable();
return 0;
}
void flash_sector_erase(uint32_t addr)
{
unsigned char val = 1;
unsigned int i = 0;
unsigned int addr_sector = addr & 0xFFFFF000;
flash_write_enable();
xSPI_CLK_LO();
xSPI_CS_LO();
wait();
xspi_write_byte(0x20);
xspi_write_byte((addr_sector&0x00FF0000)>>16);
xspi_write_byte((addr_sector&0x0000FF00)>>8);
xspi_write_byte(addr_sector&0x000000FF);
xSPI_CS_HI();
flash_write_disable();
while(val)
{
LL_IWDG_ReloadCounter(IWDG1);
val = (flash_read_sr1() & 0x01);
}
for(i=0;i<10000;i++)__nop();
}
void flash_sector_erase_no_wait(uint32_t addr)
{
unsigned char val = 1;
unsigned int i = 0;
unsigned int addr_sector = addr & 0xFFFFF000;
flash_write_enable();
xSPI_CLK_LO();
xSPI_CS_LO();
wait();
xspi_write_byte(0x20);
xspi_write_byte((addr_sector&0x00FF0000)>>16);
xspi_write_byte((addr_sector&0x0000FF00)>>8);
xspi_write_byte(addr_sector&0x000000FF);
xSPI_CS_HI();
flash_write_disable();
wait();
}
void flash_full_chip_erase(void) // erase chip
{
uint8_t val = 1;
flash_write_enable();
xSPI_CLK_LO();
xSPI_CS_LO();
wait();
xspi_write_byte(0x60);
xSPI_CS_HI();
while(val)
{
LL_IWDG_ReloadCounter(IWDG1);
val = (flash_read_sr1() & 0x01);
}
}
void flash_full_chip_erase_no_wait(void) // erase chip
{
uint8_t val = 1;
flash_write_enable();
xSPI_CLK_LO();
xSPI_CS_LO();
wait();
xspi_write_byte(0x60);
xSPI_CS_HI();
wait();
}
static void flash_reset(void)
{
xSPI_CLK_LO();
xSPI_CS_LO();
wait();
xspi_write_byte(0x66);
xSPI_CS_HI();
xSPI_CLK_LO();
xSPI_CS_LO();
wait();
xspi_write_byte(0x99);
xSPI_CS_HI();
HAL_Delay(5);
}
void flash_read_id(uint8_t *p_ddata)
{
xSPI_CLK_LO();
xSPI_CS_LO();
wait();
wait();
xspi_write_byte(0x90); // cmd
xspi_write_byte(0); // h
xspi_write_byte(0); // m
xspi_write_byte(0); // l
*p_ddata = xspi_read_byte();
p_ddata++;
*p_ddata = xspi_read_byte();
//wait();
xSPI_CS_HI();
}
void flash_quad_read_id(uint8_t *p_ddata)
{
xSPI_CLK_LO();
xSPI_CS_LO();
wait();
xspi_write_byte(0x94); // cmd
xspi_quad_write_byte(0); // h
xspi_quad_write_byte(0); // m
xspi_quad_write_byte(0); // l
xspi_quad_write_byte(0xff); // h
xspi_quad_write_byte(0); // m
xspi_quad_write_byte(0);
*p_ddata = xspi_quad_read_byte();
p_ddata++;
*p_ddata = xspi_quad_read_byte();
wait();
xSPI_CS_HI();
}