update w5500 w25q
This commit is contained in:
241
calib_board/usr/bsp/bsp_w25q.c
Normal file
241
calib_board/usr/bsp/bsp_w25q.c
Normal 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> */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user