硬汉嵌入式论坛

 找回密码
 立即注册
查看: 882|回复: 3
收起左侧

[SPI/QSPI] 自制STM32H750 QSPI W25Q128 MDK算法下载问题

[复制链接]

1

主题

12

回帖

15

积分

新手上路

积分
15
发表于 2024-12-11 10:38:45 | 显示全部楼层 |阅读模式
求助:

我自己制作了一个W25Q28,QSPI接口的MDK下载算法。但是使用的时候出现下面的错误。
No Algorithm found for: 08000000H - 08005BAFH
Erase skipped!
Error: Flash Download failed  -  "Cortex-M7"
Flash Load finished at 10:32:07
这是怎么回事呢。 我已经验证过我的W25Q128芯片的驱动,能正常的读,写,映射。

具体代码如下
/**************************************************************************//**
* @file     FlashPrg.c
* @brief    Flash Programming Functions adapted for New Device Flash
* @version  V1.0.0
* @date     10. January 2018
******************************************************************************/
/*
* Copyright (c) 2010-2018 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "FlashOS.h"        // FlashOS Structures
#include "bsp_gpio.h"
#include "w25qxxx_qspi.h"
#include "bsp_system.h"
#include "bsp_rcc.h"
#include "bsp_power.h"

#include "system_config.h"

/*
   必需的闪存编程函数(由FlashOS调用):
                int Init        (unsigned long adr,           // 初始化闪存,参数adr为闪存起始地址
                                 unsigned long clk,          // 时钟信号相关参数(具体取决于硬件,可能是时钟频率等)
                                 unsigned long fnc);         // 功能相关参数(具体含义依实际情况而定)
                int UnInit      (unsigned long fnc);          // 反初始化闪存,参数fnc用于指定相关功能
                int EraseSector (unsigned long adr);          // 擦除扇区函数,参数adr为要擦除扇区的起始地址
                int ProgramPage (unsigned long adr,           // 编程页函数,参数adr为要编程页的起始地址
                                 unsigned long sz,          // 编程数据的大小(以字节等为单位,依实际而定)
                                 unsigned char *buf);         // 指向要写入闪存数据缓冲区的指针

   可选的闪存编程函数(由FlashOS调用):
                int BlankCheck  (unsigned long adr,           // 空白检查,参数adr为要检查区域的起始地址
                                 unsigned long sz,          // 要检查区域的大小(字节等单位)
                                 unsigned char pat);         // 空白检查时对比的模式(比如全0xFF等,依闪存特性而定)
                int EraseChip   (void);                       // 擦除整个设备(闪存芯片)
      unsigned long Verify      (unsigned long adr,           // 验证函数,参数adr为要验证区域的起始地址
                                 unsigned long sz,          // 要验证区域的大小
                                 unsigned char *buf);         // 指向用于验证对比数据缓冲区的指针

       - 如果闪存空间未映射到CPU内存空间,那么空白检查(BlankCheck)函数就是必需的。
       - 如果闪存空间未映射到CPU内存空间,那么验证(Verify)函数就是必需的。
       - 如果未提供擦除整个芯片(EraseChip)函数,那么将会调用针对所有扇区的擦除扇区(EraseSector)函数。
*/


//初始化系统
void bsp_system_init(void)
{               
        System_ClockSource sys_config;
        RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
        RCC_PLLInitTypeDef PLL_Config;
        //
        NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
        //1.初始化电源
        bsp_pwr_ex_config_supply(PWR_LDO_SUPPLY);
        bsp_pwr_set_stop_mode_regul_voltage_scaling(PWR_REGULATOR_VOLTAGE_SCALE1);
        bsp_pwr_voltage_scaling_config(PWR_REGULATOR_VOLTAGE_SCALE1);
        while(!bsp_pwr_is_active_flag_VOS());
       
        //2.初始化时钟
        bsp_rcc_APB4_GRP1_enable_clock(APB4_GRP1_PERIPH_SYSCFG);
        bsp_pwr_voltage_scaling_config(PWR_REGULATOR_VOLTAGE_SCALE0);
        while(!bsp_pwr_is_active_flag_VOS());

        sys_config.source = SYSTEM_SOURCE_PLL;
        sys_config.PLL.PLLSource = PLL_CLOCK_SOURCE;
        sys_config.PLL.PLLFRACN = 0;
        sys_config.PLL.PLLM = PLL1_M;
        sys_config.PLL.PLLN = PLL1_N;
        sys_config.PLL.PLLP = PLL1_P;
        sys_config.PLL.PLLQ = PLL1_Q;
        sys_config.PLL.PLLR = PLL1_R;
        bsp_rcc_system_clock_init(&sys_config);
       
        PLL_Config.PLLM = PLL2_M;
        PLL_Config.PLLN = PLL2_N;
        PLL_Config.PLLP = PLL2_P;
        PLL_Config.PLLQ = PLL2_Q;
        PLL_Config.PLLR = PLL2_R;
        PLL_Config.PLLFRACN = 0;
        PLL_Config.PLLSource = PLL_CLOCK_SOURCE;
        bsp_rcc_PLL2_config(&PLL_Config);
       
        PLL_Config.PLLM = PLL3_M;
        PLL_Config.PLLN = PLL3_N;
        PLL_Config.PLLP = PLL3_P;
        PLL_Config.PLLQ = PLL3_Q;
        PLL_Config.PLLR = PLL3_R;
        PLL_Config.PLLFRACN = 0;
        PLL_Config.PLLSource = PLL_CLOCK_SOURCE;
        bsp_rcc_PLL3_config(&PLL_Config);
       
        RCC_ClkInitStruct.ClockType =         RCC_CLOCKTYPE_HCLK                |
                                                                        RCC_CLOCKTYPE_SYSCLK        |
                                                                        RCC_CLOCKTYPE_PCLK1                |
                                                                        RCC_CLOCKTYPE_PCLK2                |
                                                                        RCC_CLOCKTYPE_D3PCLK1        |
                                                                        RCC_CLOCKTYPE_D1PCLK1;
                                                                                                                         
        RCC_ClkInitStruct.SYSCLKSource = SYSTEM_SOURCE_PLL;
        RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
        RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
        RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
        RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
        RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
        RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;

        bsp_rcc_clock_init(&RCC_ClkInitStruct);

        SCB_EnableICache();                                                                                                                                                /* 使能 I-Cache */
        SCB_EnableDCache();                                                                                                                                                /* 使能 D-Cache */
       
}


void w25q128_init(void)
{
        QSPI_Pin_Config pins = {0};
        pins.CLK_pin =         QSPI_CLK_PIN;
        pins.CLK_port = QSPI_CLK_PORT;
       
        pins.IO0_pin =         QSPI_SD0_PIN;
        pins.IO0_port = QSPI_SD0_PORT;
       
        pins.IO1_pin =         QSPI_SD1_PIN;
        pins.IO1_port = QSPI_SD1_PORT;
       
        pins.IO2_pin =         QSPI_SD2_PIN;
        pins.IO2_port = QSPI_SD2_PORT;
       
        pins.IO3_pin =         QSPI_SD3_PIN;
        pins.IO3_port = QSPI_SD3_PORT;
       
        pins.NCS_pin =         QSPI_CS_PIN;
        pins.NCS_port = QSPI_CS_PORT;

        w25qxxx_qspi_init(&pins, 0);
}




/*
*  Initialize Flash Programming Functions
*    Parameter:      adr:  Device Base Address
*                    clk:  Clock Frequency (Hz)
*                    fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
*    Return Value:   0 - OK,  1 - Failed
*/

int Init (unsigned long adr, unsigned long clk, unsigned long fnc)
{

        bsp_system_init();
        w25q128_init();
        return (0);                                  // Finished without Errors
}


/*
*  De-Initialize Flash Programming Functions
*    Parameter:      fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
*    Return Value:   0 - OK,  1 - Failed
*/

int UnInit (unsigned long fnc) {

  /* Add your Code */
  return (0);                                  // Finished without Errors
}


/*
*  Erase complete Flash Memory
*    Return Value:   0 - OK,  1 - Failed
*/

int EraseChip (void) {

  /* Add your Code */
        w25q128_eraser_chip();
  return (0);                                  // Finished without Errors
}


/*
*  Erase Sector in Flash Memory
*    Parameter:      adr:  Sector Address
*    Return Value:   0 - OK,  1 - Failed
*/

int EraseSector (unsigned long adr) {

  /* Add your Code */
        unsigned int addr = adr - 0x90000000;
        if(addr < 16 * 1024 * 1024 && addr > 0)       
                w25q128_qspi_erase_block_64K(addr);
        else
                return 1;
        return (0);                                  // Finished without Errors
}


/*
*  Program Page in Flash Memory
*    Parameter:      adr:  Page Start Address
*                    sz:   Page Size
*                    buf:  Page Data
*    Return Value:   0 - OK,  1 - Failed
*/

int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) {

  /* Add your Code */
                unsigned int addr = adr - 0x90000000;
        if(addr < 16 * 1024 * 1024 && addr > 0)       
                w25q128_qspi_write_buffer(buf,addr,sz);
        else
                return 1;
  return (0);                                  // Finished without Errors
}

int BlankCheck  (unsigned long adr,           // 空白检查,参数adr为要检查区域的起始地址
                                        unsigned long sz,          // 要检查区域的大小(字节等单位)
                                        unsigned char pat)         // 空白检查时对比的模式(比如全0xFF等,依闪存特性而定)
{
        unsigned int *addr = (unsigned int *)(adr - 0x90000000);

        w25q128_qspi_memory_mapped();
       
        for(int i = 0; i < sz/4; i++)
        {
                if(*addr != 0xffffffff)
                        return 1;
                addr++;
        }
       
        return 0;
}

unsigned long Verify      (unsigned long adr,           // 验证函数,参数adr为要验证区域的起始地址
                                                 unsigned long sz,          // 要验证区域的大小
                                                 unsigned char *buf)         // 指向用于验证对比数据缓冲区的指针
{
        unsigned char *addr = (unsigned char *)(adr - 0x90000000);

        w25q128_qspi_memory_mapped();
       
        for(int i = 0; i < sz; i++)
        {
                if(*addr != buf)
                        return 1;
                addr++;
        }
       
       
        return 0;
}





























回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2024-12-12 09:29:54 | 显示全部楼层
这个提示No Algorithm found for: 08000000H - 08005BAFH

是你下载的是否没有添加内部Flash下载算法文件
回复

使用道具 举报

1

主题

12

回帖

15

积分

新手上路

积分
15
 楼主| 发表于 2024-12-19 13:14:30 | 显示全部楼层
我把添加算法的截图添加到附件上了。麻烦大佬 帮我看看我这么添加哪里有错误。 为啥我的这个RMA  for Algorithm 的size 不能修改。谢谢
无标题.png
回复

使用道具 举报

692

主题

3576

回帖

5677

积分

论坛元老

积分
5677
发表于 2024-12-19 19:39:26 | 显示全部楼层
cuijunling00 发表于 2024-12-19 13:14
我把添加算法的截图添加到附件上了。麻烦大佬 帮我看看我这么添加哪里有错误。 为啥我的这个RMA  for Algor ...


No Algorithm found for: 08000000H - 08005BAFH  这个貌似是芯片自带的内部 falsh 也需要加上试试看吧
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-14 03:37 , Processed in 0.044093 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表