ZHCAEX4 January   2025 F29H850DM , F29H850TU , F29H859TU-Q1 , F29P589DM-Q1 , F29P589DU-Q1

 

  1.   1
  2.   摘要
  3.   商标
  4. 1 简介
  5. 2 EEPROM 与片上闪存的区别
  6. 3 概述
    1. 3.1 基本概念
    2. 3.2 单存储单元方法
    3. 3.3 乒乓方法
    4. 3.4 创建 EEPROM 节(页)和页标识
  7. 4 软件说明
    1. 4.1 软件功能和流程
  8. 5 单存储单元仿真
    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. 6 乒乓仿真
    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. 7 应用集成
  11. 8 闪存 API
    1. 8.1 闪存 API 检查清单
      1. 8.1.1 使用闪存 API 时的注意事项
  12. 9 源文件清单
  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;
        }
    }
}