stmflash.h 6.0 KB
/**
 ****************************************************************************************************
 * @file        stmflash.h
 * @author      正点原子团队(ALIENTEK)
 * @version     V1.0
 * @date        2020-04-26
 * @brief       STM32内部FLASH读写 驱动代码
 * @license     Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
 ****************************************************************************************************
 * @attention
 *
 * 实验平台:正点原子 STM32F103开发板
 * 在线视频:www.yuanzige.com
 * 技术论坛:www.openedv.com
 * 公司网址:www.alientek.com
 * 购买地址:openedv.taobao.com
 *
 * 修改说明
 * V1.0 20200426
 * 第一次发布
 *
 ****************************************************************************************************
 */

#ifndef __STMFLASH_H
#define __STMFLASH_H

#include "stm32f1xx_hal.h"
#include "stm32f1xx_hal_flash.h"
#include "stm32f1xx_hal_flash_ex.h"

#include "stdint.h"


#define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) /* Base @ of Sector 0, 1 Kbyte */
#define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08000400) /* Base @ of Sector 1, 1 Kbyte */
#define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08000800) /* Base @ of Sector 2, 1 Kbyte */
#define ADDR_FLASH_SECTOR_3     ((uint32_t)0x08000C00) /* Base @ of Sector 3, 1 Kbyte */
#define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08001000) /* Base @ of Sector 4, 1 Kbyte */
#define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08001400) /* Base @ of Sector 5, 1 Kbyte */
#define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08001800) /* Base @ of Sector 6, 1Kbyte */
#define ADDR_FLASH_SECTOR_7     ((uint32_t)0x08001C00) /* Base @ of Sector 7, 1 Kbyte */
#define ADDR_FLASH_SECTOR_8     ((uint32_t)0x08002000) /* Base @ of Sector 8, 1 Kbyte */
#define ADDR_FLASH_SECTOR_9     ((uint32_t)0x08002400) /* Base @ of Sector 9, 1 Kbyte */
#define ADDR_FLASH_SECTOR_10    ((uint32_t)0x08002800) /* Base @ of Sector 10, 1 Kbyte */
#define ADDR_FLASH_SECTOR_11    ((uint32_t)0x08002C00) /* Base @ of Sector 11, 1 Kbyte */

#define ADDR_FLASH_SECTOR_32    ((uint32_t)0x08008000) /* Base @ of Sector 32, 1 Kbyte */
#define ADDR_FLASH_SECTOR_33    ((uint32_t)0x08008400) /* Base @ of Sector 33, 1 Kbyte */
#define ADDR_FLASH_SECTOR_34    ((uint32_t)0x08008800) /* Base @ of Sector 34, 1 Kbyte */

#define ADDR_FLASH_SECTOR_61    ((uint32_t)0x0800F400) /* Base @ of Sector 62, 1 Kbyte */
#define ADDR_FLASH_SECTOR_62    ((uint32_t)0x0800F800) /* Base @ of Sector 62, 1 Kbyte */
#define ADDR_FLASH_SECTOR_63    ((uint32_t)0x0800FC00) /* Base @ of Sector 63, 1 Kbyte */

/* Error code */
enum {
    FLASHIF_OK = 0,
    FLASHIF_ERASE_ERROR,
    FLASHIF_WRITINGCTRL_ERROR,
    FLASHIF_WRITING_ERROR
};

enum {
    FLASHIF_PROTECTION_NONE = 0,
    FLASHIF_PROTECTION_PCROPENABLED = 0x1,
    FLASHIF_PROTECTION_WRPENABLED = 0x2,
    FLASHIF_PROTECTION_RDPENABLED = 0x4,
};

/* End of the Flash address */
#define FLASH_END_ADDRESS                   0x0800FC00

/* Define the address from where user application will be loaded.
   Note: the 1st sector 0x08000000-0x08007FFF is reserved for the IAP code *///留28k给app
#define APPLICATION_ADDRESS                 ADDR_FLASH_SECTOR_5
#define APPLICATION_ADDRESS_END             (ADDR_FLASH_SECTOR_33 - 1)

/* Define the user application size */
#define APPLICATION_FLASH_SIZE             (APPLICATION_ADDRESS_END - APPLICATION_ADDRESS + 1)

/* Define the address from where user application will be stored in upgrade mode */
#define APPLICATION_STORE_ADDRESS           ADDR_FLASH_SECTOR_33
#define APPLICATION_STORE_ADDRESS_END       (ADDR_FLASH_SECTOR_62-1)//这里多了1K的dji参数存储区,最后2K留给电机参数保存
//#define APPLICATION_STORE_ADDRESS_END       (FLASH_END_ADDRESS)

/* Define the address for param store */
#define APPLICATION_PARAM_STORE_ADDRESS     ADDR_FLASH_SECTOR_4
#define APPLICATION_PARAM_STORE_ADDRESS_END (ADDR_FLASH_SECTOR_5 - 1)

/* Define bitmap representing user flash area that could be write protected (check restricted to pages 8-39). */
#define FLASH_SECTOR_TO_BE_PROTECTED (OB_WRP_SECTOR_0 | OB_WRP_SECTOR_1 | OB_WRP_SECTOR_2 | OB_WRP_SECTOR_3 |\
                                      OB_WRP_SECTOR_4 | OB_WRP_SECTOR_5 | OB_WRP_SECTOR_6 | OB_WRP_SECTOR_7 |\
                                      OB_WRP_SECTOR_8 | OB_WRP_SECTOR_9 | OB_WRP_SECTOR_10 | OB_WRP_SECTOR_11 )






/* FLASH起始地址 */
// stm32f103T8U6
#define STM32_FLASH_SIZE        0x10000         /* STM32 FLASH 总大小 */
#define STM32_FLASH_BASE        0x08000000      /* STM32 FLASH 起始地址 */

 /* STM32F103 扇区大小 */
#if STM32_FLASH_SIZE < 256 * 1024
#define STM32_SECTOR_SIZE   1024                /* 容量小于256K的 F103, 扇区大小为1K字节 */
#else
#define STM32_SECTOR_SIZE   2048                /* 容量大于等于于256K的 F103, 扇区大小为2K字节 */
#endif

/* FLASH解锁键值 */
#define STM32_FLASH_KEY1        0X45670123
#define STM32_FLASH_KEY2        0XCDEF89AB

/* 静态函数(仅限stmflash.c调用) */
static void stmflash_unlock(void);                  /* 解锁STM32 内部FLASH */
static void stmflash_lock(void);                    /* 锁定STM32 内部FLASH */
static uint8_t stmflash_get_error_status(void);     /* 获取FLASH错误状态 */
static uint8_t stmflash_wait_done(uint32_t time);   /* 等待操作完成 */
static uint8_t stmflash_erase_sector(uint32_t saddr);                   /* 擦除扇区 */
static uint8_t stmflash_write_halfword(uint32_t faddr, uint16_t data);  /* FLASH写半字 */

/* 接口函数(外部可调用) */
uint16_t stmflash_read_halfword(uint32_t faddr);                        /* FLASH读半字 */
void stmflash_read(uint32_t raddr, uint16_t *pbuf, uint16_t length);    /* 从指定地址开始读出指定长度的数据 */
void stmflash_write(uint32_t waddr, uint16_t *pbuf, uint16_t length);   /* 在FLASH 指定位置, 写入指定长度的数据(自动擦除) */
uint32_t FLASH_If_Erase(uint32_t startAddress, uint32_t endAddress);

/* 测试函数 */
void test_write(uint32_t waddr, uint16_t wdata);

#endif