ZHCAEX4 January   2025 F29H850TU , F29H859TU-Q1

 

  1.   1
  2.   摘要
  3.   商标
  4. 简介
  5. EEPROM 与片上闪存的区别
  6. 概述
    1. 3.1 基本概念
    2. 3.2 单存储单元方法
    3. 3.3 乒乓方法
    4. 3.4 创建 EEPROM 节(页)和页标识
  7. 软件说明
    1. 4.1 软件功能和流程
  8. 单存储单元仿真
    1. 5.1 用户配置
      1. 5.1.1 EEPROM_Config.h
      2. 5.1.2 F29H85x_EEPROM.c
    2. 5.2 EEPROM 函数
      1. 5.2.1 初始化和设置函数
        1. 5.2.1.1 Configure_Device
        2. 5.2.1.2 EEPROM_Config_Check
      2. 5.2.2 页面模式函数
        1. 5.2.2.1 EEPROM_GetValidBank
        2. 5.2.2.2 EEPROM_UpdateBankStatus
        3. 5.2.2.3 EEPROM_UpdatePageStatus
        4. 5.2.2.4 EEPROM_UpdatePageData
        5. 5.2.2.5 EEPROM_Write_Page
      3. 5.2.3 64 位模式函数
        1. 5.2.3.1 EEPROM_64_Bit_Mode_Check_EOS
        2. 5.2.3.2 EEPROM_Write_64_Bits
      4. 5.2.4 两种模式下使用的函数
        1. 5.2.4.1 EEPROM_Erase
        2. 5.2.4.2 EEPROM_Read
      5. 5.2.5 实用功能
        1. 5.2.5.1 EEPROM_Write_Buffer
        2. 5.2.5.2 Erase_Bank
        3. 5.2.5.3 Set_Protection_Masks
        4. 5.2.5.4 Configure_Protection_Masks
        5. 5.2.5.5 Fill_Buffer
        6. 5.2.5.6 ClearFSMStatus
    3. 5.3 测试示例
  9. 乒乓仿真
    1. 6.1 用户配置
      1. 6.1.1 EEPROM_PingPong_Config.h
      2. 6.1.2 F29H85x_EEPROM_PingPong.c
    2. 6.2 EEPROM 函数
      1. 6.2.1 初始化和设置函数
        1. 6.2.1.1 Configure_Device
        2. 6.2.1.2 EEPROM_Config_Check
      2. 6.2.2 页面模式函数
        1. 6.2.2.1 EEPROM_GetValidBank
        2. 6.2.2.2 EEPROM_UpdateBankStatus
        3. 6.2.2.3 EEPROM_UpdatePageStatus
        4. 6.2.2.4 EEPROM_UpdatePageData
        5. 6.2.2.5 EEPROM_Write_Page
      3. 6.2.3 64 位模式函数
        1. 6.2.3.1 EEPROM_64_Bit_Mode_Check_EOS
        2. 6.2.3.2 EEPROM_Write_64_Bits
      4. 6.2.4 两种模式下使用的函数
        1. 6.2.4.1 EEPROM_Erase_Inactive_Unit
        2. 6.2.4.2 EEPROM_Read
        3. 6.2.4.3 EEPROM_Erase_All
      5. 6.2.5 实用功能
        1. 6.2.5.1 EEPROM_Write_Buffer
        2. 6.2.5.2 Erase_Bank
        3. 6.2.5.3 Configure_Protection_Masks
        4. 6.2.5.4 Set_Protection_Masks
        5. 6.2.5.5 Fill_Buffer
        6. 6.2.5.6 ClearFSMStatus
    3. 6.3 测试示例
  10. 应用集成
  11. 闪存 API
    1. 8.1 闪存 API 检查清单
      1. 8.1.1 使用闪存 API 时的注意事项
  12. 源文件清单
  13. 10故障排除
    1. 10.1 一般
  14. 11结语
  15. 12参考资料

EEPROM_Config_Check

EEPROM_Config_Check() 函数提供一般错误检查并配置闪存 API 所需的写入/擦除保护掩码。应在对仿真 EEPROM 单元进行编程或读取之前调用此函数。

第一,该函数验证选择用于 EEPROM 仿真的闪存组是否有效。只有数据存储体是 F29x 上的有效选择。

if (FLASH_BANK_SELECT != C29FlashBankFR4RP0StartAddress)
{
    return 0xFFFF;
}

第二,检查选择用于仿真的闪存扇区的有效性。该函数检查:

  • FIRST_AND_LAST_SECTOR 是否指示两个单元具有两个不同数量的闪存扇区
    uint32_t NUM_EEPROM_SECTORS_1 = FIRST_AND_LAST_SECTOR[0][1] - FIRST_AND_LAST_SECTOR[0][0] + 1;
    uint32_t NUM_EEPROM_SECTORS_2 = FIRST_AND_LAST_SECTOR[1][1] - FIRST_AND_LAST_SECTOR[1][0] + 1;
    
    if (NUM_EEPROM_SECTORS_1 != NUM_EEPROM_SECTORS_2)
    {
        return 0xEEEE;
    }
  • 选择用于仿真的闪存扇区数量是否多于闪存组中可用的扇区数量
    if (NUM_EEPROM_SECTORS > NUM_FLASH_SECTORS || NUM_EEPROM_SECTORS == 0)
    {
        return 0xEEEE;
    }
  • 选择用于仿真的第一个和最后一个扇区的组合是否无效
    if (NUM_EEPROM_SECTORS > 1)
    {
        if (FIRST_AND_LAST_SECTOR[0][1] <= FIRST_AND_LAST_SECTOR[0][0])
        {
            return 0xEEEE;
        }
    
        if (FIRST_AND_LAST_SECTOR[1][1] <= FIRST_AND_LAST_SECTOR[1][0])
        {
            return 0xEEEE;
        }
    
        if (FIRST_AND_LAST_SECTOR[0][1] > NUM_FLASH_SECTORS - 1 || FIRST_AND_LAST_SECTOR[0][1] < 1)
        {
            return 0xEEEE;
        }
    
        if (FIRST_AND_LAST_SECTOR[1][1] > NUM_FLASH_SECTORS - 1 || FIRST_AND_LAST_SECTOR[1][1] < 1)
        {
            return 0xEEEE;
        }
    }
    else if (FIRST_AND_LAST_SECTOR[0][0] > NUM_FLASH_SECTORS - 1 ||
             FIRST_AND_LAST_SECTOR[1][0] > NUM_FLASH_SECTORS - 1)
    {
            return 0xEEEE;
    }
  • 两个单元之间是否存在重叠扇区
if (FIRST_AND_LAST_SECTOR[0][0] <= FIRST_AND_LAST_SECTOR[1][1] &&
    FIRST_AND_LAST_SECTOR[1][0] <= FIRST_AND_LAST_SECTOR[0][1])
{ 
    return 0xEEEE; 
}
  • 如果使用页面模式,请检查 EEPROM 组 + 页面的总大小是否适合所选的闪存扇区。
    Bank_Size = WRITE_SIZE_BYTES*2 + 
                ((EEPROM_PAGE_DATA_SIZE + WRITE_SIZE_BYTES*2) * NUM_EEPROM_PAGES);
    
    uint32_t Available_Words = NUM_EEPROM_SECTORS * FLASH_SECTOR_SIZE;
    
    if (Bank_Size * NUM_EEPROM_BANKS > Available_Words)
    {
        return 0xCCCC;
    }
  • 验证两个 EEPROM 单元是否没有重叠的保护掩码
    uint64_t WE_Protection_AB_Sectors_Unit_0 = Configure_Protection_Masks(FIRST_AND_LAST_SECTOR[0], 
                                                                        NUM_EEPROM_SECTORS);
    uint64_t WE_Protection_AB_Sectors_Unit_1 = Configure_Protection_Masks(FIRST_AND_LAST_SECTOR[1], 
                                                                        NUM_EEPROM_SECTORS);
    if (WE_Protection_AB_Sectors_Unit_0 & WE_Protection_AB_Sectors_Unit_1)
    {
        return 0xEEEE;
    }
    

如果检测到以下非致命条件之一,则会发出警告。每个标志对应于函数返回值中的位:

  • 配置 EEPROM 组和页面大小后,闪存中会保留一个或多个 EEPROM 组的空间
    if (Available_Words - (Bank_Size * NUM_EEPROM_BANKS ) >= Bank_Size)
    {
        Warning_Flags += 1;
    }
  • 如果每个页面包含的位少于或等于 64(8 个字节)(这会浪费空间,因为无需状态代码即可使用 64 位模式)
    if (EEPROM_PAGE_DATA_SIZE <= WRITE_SIZE_BYTES)
    {
        Warning_Flags += 2;
    }

如果使用 32-127 范围内的扇区(对于 F29H85x 器件)并且未使用分配给写入/擦除保护掩码中单个位的全部八个扇区,则会发出警告。由 single-bit 设计的八个扇区中任何未使用的扇区都无法受到适当的擦除保护。有关写入/擦除保护掩码如何与扇区对应的更多信息,请参阅 F29H85x 闪存 API 参考指南

uint8_t i;
for (i = 0; i < 2; i++)
{
    // If using any sectors > 31
    if (FIRST_AND_LAST_SECTOR[i][1] > 31)
    {
        // If all sectors are > 31 (use protection mask B)
        if (FIRST_AND_LAST_SECTOR[i][0] > 31)
        {
            // If using < 8 sectors (will be clearing more than necessary)
            if (NUM_EEPROM_SECTORS < 8)
            {
                Warning_Flags += 4;
                break;
            }
            // if sector isn't a multiple of 8 (will be clearing more than necessary)
            else if ((FIRST_AND_LAST_SECTOR[i][0] % 8) != 0 ||
                     (FIRST_AND_LAST_SECTOR[i][1] + 1) % 8 != 0)
            {
                Warning_Flags += 4;
                break;
            }
        }
        // if sector isn't a multiple of 8 (will be clearing more than necessary)
        else if ((FIRST_AND_LAST_SECTOR[i][1] + 1) % 8 != 0)
        {
            Warning_Flags += 4;
            break;
        }
    }
}