#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>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>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(); }