update w5500 w25q

This commit is contained in:
2026-02-03 12:01:38 +08:00
parent f56744ad7a
commit 270141591e
12 changed files with 6823 additions and 0 deletions

View File

@@ -0,0 +1,241 @@
#include "bsp_w25q.h"
#include "spi.h"
#include "main.h"
/* spi flash Ƭѡ<C6AC><D1A1><EFBFBD><EFBFBD> - pb12 */
#define W25Q32_CS_LOW() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET)
#define W25Q32_CS_HIGH() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET)
/* spi <20><><EFBFBD><EFBFBD><E4BAAF> */
static void w25q32_spi_transmit(uint8_t *data, uint16_t size) {
HAL_SPI_Transmit(&hspi2, data, size, HAL_MAX_DELAY);
}
static void w25q32_spi_receive(uint8_t *data, uint16_t size) {
HAL_SPI_Receive(&hspi2, data, size, HAL_MAX_DELAY);
}
static uint8_t w25q32_spi_transmit_receive(uint8_t data) {
uint8_t rx_data;
HAL_SPI_TransmitReceive(&hspi2, &data, &rx_data, 1, HAL_MAX_DELAY);
return rx_data;
}
/* <20>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
static void w25q32_init(void);
static void w25q32_read(uint32_t addr, uint8_t *data, uint32_t len);
static void w25q32_write(uint32_t addr, uint8_t *data, uint32_t len);
static void w25q32_chip_erase(void);
static void w25q32_write_enable(void);
static void w25q32_write_disable(void);
static uint8_t w25q32_read_status_reg(void);
static void w25q32_wait_for_write_end(void);
static void w25q32_sector_erase(uint32_t sector_addr);
static void w25q32_block_erase(uint32_t block_addr);
static void w25q32_page_write(uint32_t addr, uint8_t *data, uint16_t len);
static uint8_t w25q32_read_id(void);
static void w25q32_power_down(void);
static void w25q32_wake_up(void);
/* w25q32 <20><><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5> */
w25q32_t w25q32 = {
.init = w25q32_init,
.read = w25q32_read,
.write = w25q32_write,
.chip_erase = w25q32_chip_erase,
};
/* <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
static void w25q32_init(void) {
W25Q32_CS_HIGH(); /* <20><>ʼʱƬѡ<C6AC><D1A1><EFBFBD><EFBFBD> */
w25q32_wake_up(); /* <20><><EFBFBD><EFBFBD>оƬ */
}
/* <20><>ȡоƬid */
static uint8_t w25q32_read_id(void) {
uint8_t id = 0;
uint8_t cmd = W25Q32_JEDEC_ID;
W25Q32_CS_LOW();
w25q32_spi_transmit(&cmd, 1);
w25q32_spi_receive(&id, 1); /* <20><><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD> */
w25q32_spi_receive(&id, 1);
w25q32_spi_receive(&id, 1); /* <20>豸id<69>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD> */
W25Q32_CS_HIGH();
return id;
}
/* дʹ<D0B4><CAB9> */
static void w25q32_write_enable(void) {
uint8_t cmd = W25Q32_WRITE_ENABLE;
W25Q32_CS_LOW();
w25q32_spi_transmit(&cmd, 1);
W25Q32_CS_HIGH();
}
/* д<><D0B4>ֹ */
static void w25q32_write_disable(void) {
uint8_t cmd = W25Q32_WRITE_DISABLE;
W25Q32_CS_LOW();
w25q32_spi_transmit(&cmd, 1);
W25Q32_CS_HIGH();
}
/* <20><>ȡ״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD> */
static uint8_t w25q32_read_status_reg(void) {
uint8_t status;
uint8_t cmd = W25Q32_READ_STATUS_REG1;
W25Q32_CS_LOW();
w25q32_spi_transmit(&cmd, 1);
status = w25q32_spi_transmit_receive(0x00);
W25Q32_CS_HIGH();
return status;
}
/* <20>ȴ<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
static void w25q32_wait_for_write_end(void) {
while (w25q32_read_status_reg() & W25Q32_STATUS_BUSY) {
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>Ź<EFBFBD>ι<EFBFBD><CEB9> */
}
}
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (4kb) */
static void w25q32_sector_erase(uint32_t sector_addr) {
uint8_t cmd[4];
/* ȷ<><C8B7><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>4k<34><6B><EFBFBD><EFBFBD> */
sector_addr &= ~(W25Q32_SECTOR_SIZE - 1);
w25q32_write_enable();
cmd[0] = W25Q32_SECTOR_ERASE;
cmd[1] = (sector_addr >> 16) & 0xFF;
cmd[2] = (sector_addr >> 8) & 0xFF;
cmd[3] = sector_addr & 0xFF;
W25Q32_CS_LOW();
w25q32_spi_transmit(cmd, 4);
W25Q32_CS_HIGH();
w25q32_wait_for_write_end();
}
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (64kb) */
static void w25q32_block_erase(uint32_t block_addr) {
uint8_t cmd[4];
/* ȷ<><C8B7><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>64k<34><6B><EFBFBD><EFBFBD> */
block_addr &= ~(W25Q32_BLOCK_SIZE - 1);
w25q32_write_enable();
cmd[0] = W25Q32_BLOCK_ERASE_64K;
cmd[1] = (block_addr >> 16) & 0xFF;
cmd[2] = (block_addr >> 8) & 0xFF;
cmd[3] = block_addr & 0xFF;
W25Q32_CS_LOW();
w25q32_spi_transmit(cmd, 4);
W25Q32_CS_HIGH();
w25q32_wait_for_write_end();
}
/* <20><>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD> */
static void w25q32_chip_erase(void) {
uint8_t cmd = W25Q32_CHIP_ERASE;
w25q32_write_enable();
W25Q32_CS_LOW();
w25q32_spi_transmit(&cmd, 1);
W25Q32_CS_HIGH();
w25q32_wait_for_write_end();
}
/* ҳд<D2B3><D0B4> (<28><><EFBFBD><EFBFBD>256<35>ֽ<EFBFBD>) */
static void w25q32_page_write(uint32_t addr, uint8_t *data, uint16_t len) {
uint8_t cmd[4];
if (len > W25Q32_PAGE_SIZE) {
len = W25Q32_PAGE_SIZE;
}
w25q32_write_enable();
cmd[0] = W25Q32_PAGE_PROGRAM;
cmd[1] = (addr >> 16) & 0xFF;
cmd[2] = (addr >> 8) & 0xFF;
cmd[3] = addr & 0xFF;
W25Q32_CS_LOW();
w25q32_spi_transmit(cmd, 4);
w25q32_spi_transmit(data, len);
W25Q32_CS_HIGH();
w25q32_wait_for_write_end();
}
/* <20><><EFBFBD><EFBFBD><E2B3A4>д<EFBFBD><D0B4> */
static void w25q32_write(uint32_t addr, uint8_t *data, uint32_t len) {
uint32_t page_remaining;
uint32_t offset = 0;
while (len > 0) {
/* <20><><EFBFBD>㵱ǰҳʣ<D2B3><CAA3><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD> */
page_remaining = W25Q32_PAGE_SIZE - (addr % W25Q32_PAGE_SIZE);
/* <20><><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD>ij<EFBFBD><C4B3><EFBFBD> */
uint32_t write_len = (len < page_remaining) ? len : page_remaining;
/* д<><D0B4>һҳ<D2BB><D2B3><EFBFBD><EFBFBD> */
w25q32_page_write(addr, &data[offset], write_len);
/* <20><><EFBFBD>µ<EFBFBD>ַ<EFBFBD><D6B7>ƫ<EFBFBD><C6AB> */
addr += write_len;
offset += write_len;
len -= write_len;
}
}
/* <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD> */
static void w25q32_read(uint32_t addr, uint8_t *data, uint32_t len) {
uint8_t cmd[4];
cmd[0] = W25Q32_READ_DATA;
cmd[1] = (addr >> 16) & 0xFF;
cmd[2] = (addr >> 8) & 0xFF;
cmd[3] = addr & 0xFF;
W25Q32_CS_LOW();
w25q32_spi_transmit(cmd, 4);
w25q32_spi_receive(data, len);
W25Q32_CS_HIGH();
}
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ */
static void w25q32_power_down(void) {
uint8_t cmd = W25Q32_POWER_DOWN;
W25Q32_CS_LOW();
w25q32_spi_transmit(&cmd, 1);
W25Q32_CS_HIGH();
}
/* <20><><EFBFBD><EFBFBD>оƬ */
static void w25q32_wake_up(void) {
uint8_t cmd = W25Q32_RELEASE_POWER_DOWN;
W25Q32_CS_LOW();
w25q32_spi_transmit(&cmd, 1);
W25Q32_CS_HIGH();
HAL_Delay(5); /* <20>ȴ<EFBFBD>оƬ<D0BE><C6AC><EFBFBD><EFBFBD> */
}