当前位置:网站首页>GD32 RT-Thread flash驱动函数
GD32 RT-Thread flash驱动函数
2022-06-30 09:37:00 【Sky_Lannister】
GD32 flash驱动函数
驱动函数需要添加一个文件drv_flash.c、修改一个文件fmc_operation.c,使用BSP_USING_ON_CHIP_FLASH进行开启关闭,移植注意事项参见 移植完整版RT-Thread到GD32F4XX(详细) 中关于flash移植相关内容,移植完成后使用及验证方法同stm32
drv_flash.c
/** ****************************************************************************** * @file drv_flash.c * @author yangFei * @brief 按照GD32库实现flash驱动 * * @version V1.0.0 * @date 2022.06.08 * @verbatim * * @endverbatim ****************************************************************************** * @note 依赖fmc_operation.c文件(标准库未提供,位于F4XX的FMC例程中) * @attention * * Change Logs: * Date Author Notes * 2022.06.08 yangFei 适用芯片为GD32f4xx,使用官方提供标准库,例程移植自https://github.com/RT-Thread/rt-thread/tree/master/bsp/gd32/gd32407v-start * ****************************************************************************** */
#ifdef BSP_USING_ON_CHIP_FLASH
#include "drv_flash.h"
#if defined(PKG_USING_FAL)
#include "fal.h"
#endif
//#define DRV_DEBUG
#define LOG_TAG "drv.flash"
#include <drv_log.h>
#if defined(PKG_USING_FAL)
static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size);
static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size);
static int fal_flash_erase(long offset, size_t size);
const struct fal_flash_dev gd32_onchip_flash = {
"onchip_flash", GD32_FLASH_START_ADRESS, GD32_FLASH_SIZE, SIZE_4KB, {
NULL, fal_flash_read, fal_flash_write, fal_flash_erase}};
static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size)
{
return fmc_read_8bit_data(gd32_onchip_flash.addr + offset, size, (int8_t*)buf);
}
static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size)
{
return fmc_write_8bit_data(gd32_onchip_flash.addr + offset, size, (int8_t*)buf);
}
static int fal_flash_erase(long offset, size_t size)
{
uint32_t first_page = 0, last_pages = 0;
if ((gd32_onchip_flash.addr + offset + size) > GD32_FLASH_END_ADDRESS)
{
LOG_E("ERROR: erase outrange flash size! addr is (0x%p)\n", (void*)(gd32_onchip_flash.addr + offset + size));
return -RT_EINVAL;
}
fmc_unlock();
/* clear pending flags */
fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);
/* Get the 1st page to erase */
first_page = get_page(gd32_onchip_flash.addr + offset);
/* Get the number of pages to erase from 1st page */
last_pages = get_page(gd32_onchip_flash.addr + offset + size - 1) + 1;
// /* erase page */
for(uint32_t i = first_page; i < last_pages; i++)
{
/* wait the erase operation complete*/
if(FMC_READY != fmc_page_erase(i)){
while(1);
}
}
/* lock the flash program erase controller */
fmc_lock();
return size;
}
#endif
#endif /* BSP_USING_ON_CHIP_FLASH */
/************************ (C) COPYRIGHT *****END OF FILE****/
fmc_operation.c
//主要修改fmc_write_8bit_data和fmc_read_8bit_data函数,添加了错误判断、删除了写前擦除动作(将擦除单拿出来了)、加大了读回数据长度,如果使用半字或字写入,修改方式类似
//添加了向FMC OTP区域写入数据的函数,和向FMC 1M flash区域写入稍微不同,涉及到一个上锁,具体描述可查看用户手册
/*! \brief write 8 bit length data to a given address \param[in] address: a given address(0x08000000~0x082FFFFF) \param[in] length: data length \param[in] data_8: data pointer \param[out] none \retval none */
int fmc_write_8bit_data(uint32_t address, uint16_t length, int8_t* data_8)
{
uint32_t i;
if ((address + length) > GD32_FLASH_END_ADDRESS)
{
printf("read outrange flash size! addr is (0x%p)", (void*)(address + length));
return -RT_EINVAL;
}
if(length % 4 != 0)
{
printf("write addr must be 4-byte alignment");
return -RT_EINVAL;
}
// printf("\r\nFMC half_word program operation:\n");
/* unlock the flash program erase controller */
fmc_unlock();
/* clear pending flags */
fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);
/* write data_8 to the corresponding address */
for(i=0; i<length; i++){
if(FMC_READY == fmc_byte_program(address, data_8[i])){
address++;
}else{
while(1);
}
}
/* lock the flash program erase controller */
fmc_lock();
// printf("\r\nWrite complete!\n");
// printf("\r\n");
return length;
}
/*! \brief read 8 bit length data to a given address \param[in] address: a given address(0x08000000~0x082FFFFF) \param[in] length: data length \param[in] data_8: data pointer \param[out] none \retval none */
int fmc_read_8bit_data(uint32_t address, uint16_t length, int8_t* data_8)
{
uint32_t i;
// printf("\r\nRead data from 0x%02X\n", address);
// printf("\r\n");
if ((address + length) > GD32_FLASH_END_ADDRESS)
{
printf("read outrange flash size! addr is (0x%p)", (void*)(address + length));
return -RT_EINVAL;
}
for(i=0; i<length; i++){
data_8[i] = *(__IO int8_t*)address;
// printf("0x%02X ", data_8[i]);
address++;
}
// printf("\r\nRead end\n");
// printf("\r\n");
return length;
}
/*! \brief write 8 bit length data to OTP \param[in] address: a given address(0x1FFF7800U - 0x1FFF79FFU ) \param[in] length: data length \param[in] data_8: data pointer \param[out] none \retval 写完自动锁住对应的otp区域 */
#define FlashGetU64(addr) *((uint64_t*)(addr))
#define OTP_BASE_ADDRESS (0x1FFF7800U) //16个32字节
int fmc_write_8bit_otp(uint32_t address, uint16_t length, int8_t* data_8)
{
#define OTP_FLASH_SIZE (16*32)
#define OTP_LOCK_ADDRESS 0x1FFF7A00U //0x1FFF7A00U - 0x1FFF7A0FU 7A00-7A0F 16个字节
#define LOCK 0xff
#define UNLOCK 0
uint32_t i;
uint32_t lock_address = address;
if ((address + length) > (OTP_BASE_ADDRESS + OTP_FLASH_SIZE))
{
printf("read outrange flash size! addr is (0x%p)", (void*)(address + length));
return -RT_EINVAL;
}
if(length % 4 != 0)
{
printf("write addr must be 4-byte alignment");
return -RT_EINVAL;
}
/* unlock the flash program erase controller */
fmc_unlock();
/* write clear pending flags */
fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);
/* write data_8 to the corresponding address */
for(i=0; i<length; i++){
if(FMC_READY == fmc_byte_program(address, data_8[i])){
address++;
}else{
while(1);
}
}
/*lock clear pending flags */
fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);
length = length / 4;
lock_address = OTP_LOCK_ADDRESS + (lock_address - OTP_BASE_ADDRESS) / 32;
/* write data_8 to the corresponding address */
for(i=0; i<length; i++){
if(FMC_READY == fmc_byte_program(lock_address, (uint8_t)LOCK)){
lock_address++;
}else{
while(1);
}
}
/* lock the flash program erase controller */
fmc_lock();
return length;
}
边栏推荐
- A brief introduction to database mysql
- JS obtient la chaîne spécifiée spécifiant la position du caractère & sous - chaîne spécifiant la plage de position du caractère 【 détails simples 】
- 【JVM】G1垃圾回收器簡述
- 9.缓存优化
- Basic MySQL operation commands of database
- 100个句子记完7000个雅思词汇,实际只有1043个词汇(包括 I and you 等简单词汇)
- Appium自动化测试基础 — 12.APPium自动化测试框架介绍
- Nlopt -- Nonlinear Optimization -- principle introduction and application method
- Questions about cookies and sessions
- Appium automation test foundation - 12 Introduction to appium automated testing framework
猜你喜欢

MySQL index, transaction and storage engine of database (2)

开源了!文心大模型ERNIE-Tiny轻量化技术,又准又快,效果全开

Great Wall digital art digital collection platform releases the creation Badge
![JS get the substring of the specified character position and the specified character position interval of the specified string [simple and detailed]](/img/01/6829e85bf28431eb06e70b87ceaaff.jpg)
JS get the substring of the specified character position and the specified character position interval of the specified string [simple and detailed]
![[JVM] brief introduction to CMS](/img/4e/df4a193eed39438f808059f67f19a1.png)
[JVM] brief introduction to CMS

著名画家史国良《丰收时节》数字藏品上线长城数艺

Shell script multi loop experiment

陈颢天 荣获第七届少儿模特明星盛典全国总决赛 全国总冠军

Why can't you rob scientists of NFT

2022 Season 6 perfect children's model toxon division finals came to a successful conclusion
随机推荐
South China Industrial Group launched digital economy and successfully held the city chain technology conference
Highlight display of Jinbei LB box, adhering to mini special effects
KOREANO ESSENTIAL打造气质职场范
9.缓存优化
基于强化学习的股票量化交易Automated-Stock-Trading-Ensemble-Strategy
Eth is not connected to the ore pool
Oracle creates a stored procedure successfully, but the compilation fails
About the split and join operations of strings
Theme Studio
Applying applet container technology to IOT ecological construction
Deployment of efficient and versatile clusters lvs+kept highly available clusters
Some domestic image sources
Appium automation test foundation - 12 Introduction to appium automated testing framework
栈题目:字符串解码
1033 To Fill or Not to Fill
Why can't you rob scientists of NFT
JS get the substring of the specified character position and the specified character position interval of the specified string [simple and detailed]
Appium automation test foundation - ADB shell command
UAV project tracking record 83 -- PCB diagram completion
乡村振兴公益基金启动暨古茶树非遗保护公益行发布