rocketpi_w25qxx
按 Winbond 资料,早期的 W25Q16 系列(如 W25Q16BV/BL)确实没有实现 SFDP;只有较新的 W25Qxx 系列(例如 W25Q16JV 及之后的 JV/LM、FW 系列)才在状态寄存器里新增了 SFDP 支持。所以如果你的器件是常见的 W25Q16BV/BL,那读取 SFDP 得到全 0xFF 是正常现象,它本身就没有这块表。
W25Q16BV 是 Winbond 早期的 16 Mbit 器件,不带 SFDP 表,因此读 SFDP 得到全 0xFF 是正常现象(芯片压根没有实现 JESD216)。这类器件也只支持标准 SPI,虽然能进入 Dual/Quad 模式,但很多高版本驱动才用得到。
| w25qxx: chip is Winbond W25QXX.
w25qxx: manufacturer is Winbond.
w25qxx: interface is SPI QSPI.
w25qxx: driver version is 1.0.
w25qxx: min supply voltage is 2.7V.
w25qxx: max supply voltage is 3.6V.
w25qxx: max current is 25.00mA.
w25qxx: max temperature is 85.0C.
w25qxx: min temperature is -40.0C.
w25qxx: start register test.
w25qxx: w25qxx_set_type/w25qxx_get_type test.
w25qxx: set type W25Q80.
w25qxx: check chip type ok.
w25qxx: set type W25Q16.
w25qxx: check chip type ok.
w25qxx: set type W25Q32.
w25qxx: check chip type ok.
w25qxx: set type W25Q64.
w25qxx: check chip type ok.
w25qxx: set type W25Q128.
w25qxx: check chip type ok.
w25qxx: set type W25Q256.
w25qxx: check chip type ok.
w25qxx: w25qxx_set_interface/w25qxx_get_interface test.
w25qxx: set interface SPI.
w25qxx: check chip interface ok.
w25qxx: set interface QSPI.
w25qxx: check chip interface ok.
w25qxx: w25qxx_get_manufacturer_device_id test.
w25qxx: manufacturer is 0xEF, device id is 0x14.
w25qxx: w25qxx_get_jedec_id test.
w25qxx: manufacturer is 0xEF, device id is 0x40 0x15.
w25qxx: w25qxx_get_unique_id test.
w25qxx: unique id 0xC4 0x69 0xC4 0x32 0xCF 0x25 0x33 0x33.
w25qxx: w25qxx_set_status1/w25qxx_get_status1 test.
w25qxx: status1 is 0x00.
w25qxx: w25qxx_set_status2/w25qxx_get_status2 test.
w25qxx: status2 is 0x00.
w25qxx: w25qxx_set_status3/w25qxx_get_status3 test.
w25qxx: status3 is 0x00.
w25qxx: w25qxx_enable_write test.
w25qxx: check enable write ok.
w25qxx: w25qxx_disable_write test.
w25qxx: check disable write ok.
w25qxx: w25qxx_enable_write test.
w25qxx: check enable sr write ok.
w25qxx: w25qxx_erase_program_suspend test.
w25qxx: check erase program suspend ok.
w25qxx: w25qxx_erase_program_suspend test.
w25qxx: check erase program resume ok.
w25qxx: w25qxx_global_block_lock test.
w25qxx: check global block lock ok.
w25qxx: w25qxx_global_block_unlock test.
w25qxx: check global block unlock ok.
w25qxx: w25qxx_individual_block_lock test.
w25qxx: check individual block lock ok.
w25qxx: w25qxx_read_block_lock test.
w25qxx: check read block lock ok with 0.
w25qxx: w25qxx_individual_block_unlock test.
w25qxx: check individual block unlock ok.
w25qxx: w25qxx_set_burst_with_wrap test.
w25qxx: check set burst with wrap ok.
w25qxx: w25qxx_power_down test.
w25qxx: w25qxx_release_power_down test.
w25qxx: w25qxx_enable_reset test.
w25qxx: w25qxx_reset_device test.
w25qxx: finish register test.
w25qxx: chip is Winbond W25QXX.
w25qxx: manufacturer is Winbond.
w25qxx: interface is SPI QSPI.
w25qxx: driver version is 1.0.
w25qxx: min supply voltage is 2.7V.
w25qxx: max supply voltage is 3.6V.
w25qxx: max current is 25.00mA.
w25qxx: max temperature is 85.0C.
w25qxx: min temperature is -40.0C.
w25qxx: start read test.
w25qxx: w25qxx_write/w25qxx_read test.
w25qxx: 0x00000000/0x00200000 successful.
w25qxx: 0x00020000/0x00200000 successful.
w25qxx: 0x00040000/0x00200000 successful.
w25qxx: 0x00060000/0x00200000 successful.
w25qxx: 0x00080000/0x00200000 successful.
w25qxx: 0x000A0000/0x00200000 successful.
w25qxx: 0x000C0000/0x00200000 successful.
w25qxx: 0x000E0000/0x00200000 successful.
w25qxx: 0x00100000/0x00200000 successful.
w25qxx: 0x00120000/0x00200000 successful.
w25qxx: 0x00140000/0x00200000 successful.
w25qxx: 0x00160000/0x00200000 successful.
w25qxx: 0x00180000/0x00200000 successful.
w25qxx: 0x001A0000/0x00200000 successful.
w25qxx: 0x001C0000/0x00200000 successful.
w25qxx: 0x001E0000/0x00200000 successful.
w25qxx: w25qxx_sector_erase_4k test with address 0x4000.
w25qxx: only spi read test passed.
w25qxx: fast read test passed.
w25qxx: w25qxx_block_erase_32k test with address 0x18000.
w25qxx: only spi read test passed.
w25qxx: fast read test passed.
w25qxx: w25qxx_block_erase_64k test with address 0x80000.
w25qxx: only spi read test passed.
w25qxx: fast read test passed.
w25qxx: get sfdp.
w25qxx: sdfp[0-7] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[8-15] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[16-23] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[24-31] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[32-39] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[40-47] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[48-55] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[56-63] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[64-71] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[72-79] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[80-87] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[88-95] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[96-103] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[104-111] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[112-119] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[120-127] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[128-135] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[136-143] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[144-151] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[152-159] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[160-167] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[168-175] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[176-183] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[184-191] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[192-199] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[200-207] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[208-215] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[216-223] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[224-231] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[232-239] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[240-247] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: sdfp[248-255] is 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF.
w25qxx: security register1 write and read test.
w25qxx: write read check failed.
|
驱动以及测试代码
Core/Src/main.c
| /* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "spi.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "driver_w25qxx_read_test.h"
#include "driver_w25qxx_register_test.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_SPI2_Init();
/* USER CODE BEGIN 2 */
w25qxx_register_test(W25Q16,W25QXX_INTERFACE_SPI,W25QXX_BOOL_FALSE);
w25qxx_read_test(W25Q16,W25QXX_INTERFACE_SPI,W25QXX_BOOL_FALSE);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 84;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
|
Core/Src/stm32f4xx_it.c
| /* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32f4xx_it.c
* @brief Interrupt Service Routines.
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/******************************************************************************/
/* Cortex-M4 Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
* @brief This function handles Non maskable interrupt.
*/
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
/* USER CODE END NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
while (1)
{
}
/* USER CODE END NonMaskableInt_IRQn 1 */
}
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
/**
* @brief This function handles Memory management fault.
*/
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
/* USER CODE END MemoryManagement_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
/* USER CODE END W1_MemoryManagement_IRQn 0 */
}
}
/**
* @brief This function handles Pre-fetch fault, memory access fault.
*/
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */
/* USER CODE END BusFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
/* USER CODE END W1_BusFault_IRQn 0 */
}
}
/**
* @brief This function handles Undefined instruction or illegal state.
*/
void UsageFault_Handler(void)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */
/* USER CODE END UsageFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
/* USER CODE END W1_UsageFault_IRQn 0 */
}
}
/**
* @brief This function handles System service call via SWI instruction.
*/
void SVC_Handler(void)
{
/* USER CODE BEGIN SVCall_IRQn 0 */
/* USER CODE END SVCall_IRQn 0 */
/* USER CODE BEGIN SVCall_IRQn 1 */
/* USER CODE END SVCall_IRQn 1 */
}
/**
* @brief This function handles Debug monitor.
*/
void DebugMon_Handler(void)
{
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
/* USER CODE END DebugMonitor_IRQn 0 */
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
/* USER CODE END DebugMonitor_IRQn 1 */
}
/**
* @brief This function handles Pendable request for system service.
*/
void PendSV_Handler(void)
{
/* USER CODE BEGIN PendSV_IRQn 0 */
/* USER CODE END PendSV_IRQn 0 */
/* USER CODE BEGIN PendSV_IRQn 1 */
/* USER CODE END PendSV_IRQn 1 */
}
/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
/******************************************************************************/
/* STM32F4xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32f4xx.s). */
/******************************************************************************/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
|