add w25q64 hardware on bearpi board
This commit is contained in:
343
board/BearPi_STM32L431RC/BSP/Hardware/W25QXX-QSPI/w25qxx.c
Normal file
343
board/BearPi_STM32L431RC/BSP/Hardware/W25QXX-QSPI/w25qxx.c
Normal file
@@ -0,0 +1,343 @@
|
|||||||
|
#include "w25qxx.h"
|
||||||
|
#include "quadspi.h"
|
||||||
|
|
||||||
|
int w25qxx_init(void)
|
||||||
|
{
|
||||||
|
MX_QUADSPI_Init();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int w25qxx_memory_mapped(void)
|
||||||
|
{
|
||||||
|
QSPI_CommandTypeDef cmd = {
|
||||||
|
// Instruction
|
||||||
|
.InstructionMode = QSPI_INSTRUCTION_1_LINE,
|
||||||
|
.Instruction = FAST_READ_DUAL_IO_CMD,
|
||||||
|
// Address
|
||||||
|
.AddressMode = QSPI_ADDRESS_2_LINES,
|
||||||
|
.Address = 0, // NOT USED for memory-mapped mode
|
||||||
|
.AddressSize = QSPI_ADDRESS_24_BITS,
|
||||||
|
// AlternateByte
|
||||||
|
.AlternateByteMode = QSPI_ALTERNATE_BYTES_2_LINES,
|
||||||
|
.AlternateBytes = 0xF0, // M7-M0 should be set to Fxh
|
||||||
|
.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS,
|
||||||
|
// Dummy
|
||||||
|
.DummyCycles = 0,
|
||||||
|
// Data
|
||||||
|
.DataMode = QSPI_DATA_2_LINES,
|
||||||
|
.NbData = 0, // NOT USED for memory-mapped mode
|
||||||
|
// DDR
|
||||||
|
.DdrMode = QSPI_DDR_MODE_DISABLE,
|
||||||
|
};
|
||||||
|
QSPI_MemoryMappedTypeDef cfg = {
|
||||||
|
.TimeOutPeriod = 0,
|
||||||
|
.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE,
|
||||||
|
};
|
||||||
|
if (HAL_QSPI_GetState(&hqspi) != HAL_QSPI_STATE_BUSY_MEM_MAPPED) {
|
||||||
|
if (HAL_QSPI_Abort(&hqspi) != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (HAL_QSPI_MemoryMapped(&hqspi, &cmd, &cfg) != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t w25qxx_read_deviceid(void)
|
||||||
|
{
|
||||||
|
uint8_t recv_buf[2] = {0};
|
||||||
|
uint16_t device_id = 0;
|
||||||
|
QSPI_CommandTypeDef cmd = {
|
||||||
|
// Instruction
|
||||||
|
.InstructionMode = QSPI_INSTRUCTION_1_LINE,
|
||||||
|
.Instruction = ManufactDeviceID_CMD,
|
||||||
|
// Address
|
||||||
|
.AddressMode = QSPI_ADDRESS_1_LINE,
|
||||||
|
.Address = 0,
|
||||||
|
.AddressSize = QSPI_ADDRESS_24_BITS,
|
||||||
|
// AlternateByte
|
||||||
|
.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE,
|
||||||
|
// Dummy
|
||||||
|
.DummyCycles = 0,
|
||||||
|
// Data
|
||||||
|
.DataMode = QSPI_DATA_1_LINE,
|
||||||
|
.NbData = 2,
|
||||||
|
// DDR
|
||||||
|
.DdrMode = QSPI_DDR_MODE_DISABLE,
|
||||||
|
};
|
||||||
|
if (HAL_QSPI_Abort(&hqspi) != HAL_OK) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (HAL_QSPI_Command(&hqspi, &cmd, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (HAL_QSPI_Receive(&hqspi, recv_buf, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
device_id = (recv_buf[0] << 8) | recv_buf[1];
|
||||||
|
return device_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void w25qxx_wait_busy(void)
|
||||||
|
{
|
||||||
|
uint8_t status;
|
||||||
|
QSPI_CommandTypeDef cmd = {
|
||||||
|
// Instruction
|
||||||
|
.InstructionMode = QSPI_INSTRUCTION_1_LINE,
|
||||||
|
.Instruction = READ_STATU_REGISTER_1,
|
||||||
|
// Address
|
||||||
|
.AddressMode = QSPI_ADDRESS_NONE,
|
||||||
|
// AlternateByte
|
||||||
|
.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE,
|
||||||
|
// Dummy
|
||||||
|
.DummyCycles = 0,
|
||||||
|
// Data
|
||||||
|
.DataMode = QSPI_DATA_1_LINE,
|
||||||
|
.NbData = 1,
|
||||||
|
// DDR
|
||||||
|
.DdrMode = QSPI_DDR_MODE_DISABLE,
|
||||||
|
};
|
||||||
|
HAL_QSPI_Command(&hqspi, &cmd, HAL_QSPI_TIMEOUT_DEFAULT_VALUE);
|
||||||
|
do {
|
||||||
|
HAL_QSPI_Receive(&hqspi, &status, HAL_QSPI_TIMEOUT_DEFAULT_VALUE);
|
||||||
|
} while ((status & 0x01) == 0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
int w25qxx_read(uint8_t *buffer, uint32_t start_addr, uint16_t nbytes)
|
||||||
|
{
|
||||||
|
QSPI_CommandTypeDef cmd = {
|
||||||
|
// Instruction
|
||||||
|
.InstructionMode = QSPI_INSTRUCTION_1_LINE,
|
||||||
|
.Instruction = FAST_READ_DUAL_IO_CMD,
|
||||||
|
// Address
|
||||||
|
.AddressMode = QSPI_ADDRESS_2_LINES,
|
||||||
|
.Address = start_addr,
|
||||||
|
.AddressSize = QSPI_ADDRESS_24_BITS,
|
||||||
|
// AlternateByte
|
||||||
|
.AlternateByteMode = QSPI_ALTERNATE_BYTES_2_LINES,
|
||||||
|
.AlternateBytes = 0xF0, // M7-M0 should be set to Fxh
|
||||||
|
.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS,
|
||||||
|
// Dummy
|
||||||
|
.DummyCycles = 0,
|
||||||
|
// Data
|
||||||
|
.DataMode = QSPI_DATA_2_LINES,
|
||||||
|
.NbData = nbytes,
|
||||||
|
// DDR
|
||||||
|
.DdrMode = QSPI_DDR_MODE_DISABLE,
|
||||||
|
};
|
||||||
|
if (HAL_QSPI_Abort(&hqspi) != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (HAL_QSPI_Command(&hqspi, &cmd, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (HAL_QSPI_Receive(&hqspi, buffer, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void w25qxx_write_enable(void)
|
||||||
|
{
|
||||||
|
QSPI_CommandTypeDef cmd = {
|
||||||
|
// Instruction
|
||||||
|
.InstructionMode = QSPI_INSTRUCTION_1_LINE,
|
||||||
|
.Instruction = WRITE_ENABLE_CMD,
|
||||||
|
// Address
|
||||||
|
.AddressMode = QSPI_ADDRESS_NONE,
|
||||||
|
// AlternateByte
|
||||||
|
.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE,
|
||||||
|
// Dummy
|
||||||
|
.DummyCycles = 0,
|
||||||
|
// Data
|
||||||
|
.DataMode = QSPI_DATA_NONE,
|
||||||
|
// DDR
|
||||||
|
.DdrMode = QSPI_DDR_MODE_DISABLE,
|
||||||
|
};
|
||||||
|
HAL_QSPI_Command(&hqspi, &cmd, HAL_QSPI_TIMEOUT_DEFAULT_VALUE);
|
||||||
|
// w25qxx_wait_busy();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void w25qxx_write_disable(void)
|
||||||
|
{
|
||||||
|
QSPI_CommandTypeDef cmd = {
|
||||||
|
// Instruction
|
||||||
|
.InstructionMode = QSPI_INSTRUCTION_1_LINE,
|
||||||
|
.Instruction = WRITE_DISABLE_CMD,
|
||||||
|
// Address
|
||||||
|
.AddressMode = QSPI_ADDRESS_NONE,
|
||||||
|
// AlternateByte
|
||||||
|
.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE,
|
||||||
|
// Dummy
|
||||||
|
.DummyCycles = 0,
|
||||||
|
// Data
|
||||||
|
.DataMode = QSPI_DATA_NONE,
|
||||||
|
// DDR
|
||||||
|
.DdrMode = QSPI_DDR_MODE_DISABLE,
|
||||||
|
};
|
||||||
|
HAL_QSPI_Command(&hqspi, &cmd, HAL_QSPI_TIMEOUT_DEFAULT_VALUE);
|
||||||
|
// w25qxx_wait_busy();
|
||||||
|
}
|
||||||
|
|
||||||
|
int w25qxx_erase_sector(uint32_t sector_addr)
|
||||||
|
{
|
||||||
|
QSPI_CommandTypeDef cmd = {
|
||||||
|
// Instruction
|
||||||
|
.InstructionMode = QSPI_INSTRUCTION_1_LINE,
|
||||||
|
.Instruction = SECTOR_ERASE_CMD,
|
||||||
|
// Address
|
||||||
|
.AddressMode = QSPI_ADDRESS_1_LINE,
|
||||||
|
.Address = sector_addr,
|
||||||
|
.AddressSize = QSPI_ADDRESS_24_BITS,
|
||||||
|
// AlternateByte
|
||||||
|
.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE,
|
||||||
|
// Dummy
|
||||||
|
.DummyCycles = 0,
|
||||||
|
// Data
|
||||||
|
.DataMode = QSPI_DATA_NONE,
|
||||||
|
// DDR
|
||||||
|
.DdrMode = QSPI_DDR_MODE_DISABLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (HAL_QSPI_Abort(&hqspi) != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
w25qxx_wait_busy();
|
||||||
|
|
||||||
|
w25qxx_write_enable();
|
||||||
|
|
||||||
|
if (HAL_QSPI_Command(&hqspi, &cmd, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
w25qxx_wait_busy();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int w25qxx_erase_chip(void)
|
||||||
|
{
|
||||||
|
QSPI_CommandTypeDef cmd = {
|
||||||
|
// Instruction
|
||||||
|
.InstructionMode = QSPI_INSTRUCTION_1_LINE,
|
||||||
|
.Instruction = CHIP_ERASE_CMD,
|
||||||
|
// Address
|
||||||
|
.AddressMode = QSPI_ADDRESS_NONE,
|
||||||
|
// AlternateByte
|
||||||
|
.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE,
|
||||||
|
// Dummy
|
||||||
|
.DummyCycles = 0,
|
||||||
|
// Data
|
||||||
|
.DataMode = QSPI_DATA_NONE,
|
||||||
|
// DDR
|
||||||
|
.DdrMode = QSPI_DDR_MODE_DISABLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (HAL_QSPI_Abort(&hqspi) != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
w25qxx_wait_busy();
|
||||||
|
|
||||||
|
w25qxx_write_enable();
|
||||||
|
|
||||||
|
if (HAL_QSPI_Command(&hqspi, &cmd, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
w25qxx_wait_busy();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int w25qxx_page_program(uint8_t *dat, uint32_t write_addr, uint16_t nbytes)
|
||||||
|
{
|
||||||
|
QSPI_CommandTypeDef cmd = {
|
||||||
|
// Instruction
|
||||||
|
.InstructionMode = QSPI_INSTRUCTION_1_LINE,
|
||||||
|
.Instruction = PAGE_PROGRAM_CMD,
|
||||||
|
// Address
|
||||||
|
.AddressMode = QSPI_ADDRESS_1_LINE,
|
||||||
|
.Address = write_addr,
|
||||||
|
.AddressSize = QSPI_ADDRESS_24_BITS,
|
||||||
|
// AlternateByte
|
||||||
|
.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE,
|
||||||
|
// Dummy
|
||||||
|
.DummyCycles = 0,
|
||||||
|
// Data
|
||||||
|
.DataMode = QSPI_DATA_1_LINE,
|
||||||
|
.NbData = nbytes,
|
||||||
|
// DDR
|
||||||
|
.DdrMode = QSPI_DDR_MODE_DISABLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (HAL_QSPI_Abort(&hqspi) != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
w25qxx_wait_busy();
|
||||||
|
|
||||||
|
w25qxx_write_enable();
|
||||||
|
|
||||||
|
if (HAL_QSPI_Command(&hqspi, &cmd, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (HAL_QSPI_Transmit(&hqspi, dat, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
w25qxx_wait_busy();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int w25qxx_reset(void)
|
||||||
|
{
|
||||||
|
QSPI_CommandTypeDef cmd1 = {
|
||||||
|
// Instruction
|
||||||
|
.InstructionMode = QSPI_INSTRUCTION_1_LINE,
|
||||||
|
.Instruction = ENABLE_RESET_CMD,
|
||||||
|
// Address
|
||||||
|
.AddressMode = QSPI_ADDRESS_NONE,
|
||||||
|
// AlternateByte
|
||||||
|
.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE,
|
||||||
|
// Dummy
|
||||||
|
.DummyCycles = 0,
|
||||||
|
// Data
|
||||||
|
.DataMode = QSPI_DATA_NONE,
|
||||||
|
// DDR
|
||||||
|
.DdrMode = QSPI_DDR_MODE_DISABLE,
|
||||||
|
};
|
||||||
|
QSPI_CommandTypeDef cmd2 = {
|
||||||
|
// Instruction
|
||||||
|
.InstructionMode = QSPI_INSTRUCTION_1_LINE,
|
||||||
|
.Instruction = RESET_DEVICE_CMD,
|
||||||
|
// Address
|
||||||
|
.AddressMode = QSPI_ADDRESS_NONE,
|
||||||
|
// AlternateByte
|
||||||
|
.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE,
|
||||||
|
// Dummy
|
||||||
|
.DummyCycles = 0,
|
||||||
|
// Data
|
||||||
|
.DataMode = QSPI_DATA_NONE,
|
||||||
|
// DDR
|
||||||
|
.DdrMode = QSPI_DDR_MODE_DISABLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (HAL_QSPI_Abort(&hqspi) != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HAL_QSPI_Command(&hqspi, &cmd1, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (HAL_QSPI_Command(&hqspi, &cmd2, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
w25qxx_wait_busy();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
40
board/BearPi_STM32L431RC/BSP/Hardware/W25QXX-QSPI/w25qxx.h
Normal file
40
board/BearPi_STM32L431RC/BSP/Hardware/W25QXX-QSPI/w25qxx.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#ifndef _W25QXX_H_
|
||||||
|
#define _W25QXX_H_
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ManufactDeviceID_CMD = 0x90,
|
||||||
|
READ_STATU_REGISTER_1 = 0x05,
|
||||||
|
READ_STATU_REGISTER_2 = 0x35,
|
||||||
|
WRITE_STATU_REGISTER = 0x01,
|
||||||
|
READ_DATA_CMD = 0x03,
|
||||||
|
FAST_READ_CMD = 0x0B,
|
||||||
|
FAST_READ_DUAL_O_CMD = 0x3B,
|
||||||
|
FAST_READ_DUAL_IO_CMD = 0xBB,
|
||||||
|
FAST_READ_QUAD_O_CMD = 0x6B,
|
||||||
|
FAST_READ_QUAD_IO_CMD = 0xEB,
|
||||||
|
WRITE_ENABLE_CMD = 0x06,
|
||||||
|
WRITE_DISABLE_CMD = 0x04,
|
||||||
|
SECTOR_ERASE_CMD = 0x20,
|
||||||
|
CHIP_ERASE_CMD = 0xc7,
|
||||||
|
PAGE_PROGRAM_CMD = 0x02,
|
||||||
|
QUAD_PAGE_PROGRAM_CMD = 0x32,
|
||||||
|
BLOCK_ERASE_64KB_CMD = 0xD8,
|
||||||
|
BLOCK_ERASE_32KB_CMD = 0x52,
|
||||||
|
ERASE_SUSPEND_CMD = 0x75,
|
||||||
|
ERASE_RESUME_CMD = 0x7A,
|
||||||
|
HIGH_PERFORM_MODE_CMD = 0xA3,
|
||||||
|
ENABLE_RESET_CMD = 0x66,
|
||||||
|
RESET_DEVICE_CMD = 0x99,
|
||||||
|
};
|
||||||
|
|
||||||
|
int w25qxx_init(void);
|
||||||
|
int w25qxx_memory_mapped(void);
|
||||||
|
uint16_t w25qxx_read_deviceid(void);
|
||||||
|
int w25qxx_read(uint8_t* buffer, uint32_t start_addr, uint16_t nbytes);
|
||||||
|
int w25qxx_erase_sector(uint32_t sector_addr);
|
||||||
|
int w25qxx_erase_chip(void);
|
||||||
|
int w25qxx_page_program(uint8_t* dat, uint32_t write_addr, uint16_t nbytes);
|
||||||
|
int w25qxx_reset(void);
|
||||||
|
|
||||||
|
#endif /* _W25QXX_H_ */
|
Reference in New Issue
Block a user