ZHCADD5B November   2023  – August 2025 F28377D-SEP , F29H850TU , F29H859TU-Q1 , TMS320F28P650DH , TMS320F28P650DK , TMS320F28P650SH , TMS320F28P650SK , TMS320F28P659DH-Q1 , TMS320F28P659DK-Q1 , TMS320F28P659SH-Q1

 

  1.   1
  2.   摘要
  3.   商标
  4. 简介
  5. EEPROM 与片上闪存的区别
  6. 概述
    1. 3.1 基本概念
    2. 3.2 单存储单元方法
    3. 3.3 乒乓方法
    4. 3.4 创建 EEPROM 节(页)和页标识
  7. 软件说明
  8. 乒乓仿真
    1. 5.1 用户配置
      1. 5.1.1 EEPROM_PingPong_Config.h
      2. 5.1.2 F28P65x_EEPROM_PingPong.c
    2. 5.2 测试示例
  9. EEPROM 函数
    1. 6.1  EEPROM_Config_Check
    2. 6.2  Configure_Protection_Masks
    3. 6.3  EEPROM_Write
    4. 6.4  EEPROM_Read
    5. 6.5  EEPROM_Erase
      1. 6.5.1 Erase_Bank
    6. 6.6  EEPROM_GetValidBank
    7. 6.7  EEPROM_UpdateBankStatus
    8. 6.8  EEPROM_UpdatePageStatus
    9. 6.9  EEPROM_UpdatePageData
    10. 6.10 EEPROM_Get_64_Bit_Data_Address
    11. 6.11 EEPROM_Program_64_Bits
    12. 6.12 EEPROM_CheckStatus
    13. 6.13 ClearFSMStatus
  10. 单存储单元仿真
    1. 7.1 用户配置
      1. 7.1.1 EEPROM_Config.h
      2. 7.1.2 F28P65x_EEPROM.c
    2. 7.2 EEPROM 函数
      1. 7.2.1  EEPROM_Config_Check
      2. 7.2.2  Configure_Protection_Masks
      3. 7.2.3  EEPROM_Write
      4. 7.2.4  EEPROM_Read
      5. 7.2.5  EEPROM_Erase
      6. 7.2.6  EEPROM_GetValidBank
      7. 7.2.7  EEPROM_Get_64_Bit_Data_Address
      8. 7.2.8  EEPROM_UpdateBankStatus
      9. 7.2.9  EEPROM_UpdatePageStatus
      10. 7.2.10 EEPROM_UpdatePageData
      11. 7.2.11 EEPROM_Get_64_Bit_Data_Address
      12. 7.2.12 EEPROM_Program_64_Bits
      13. 7.2.13 EEPROM_CheckStatus
      14. 7.2.14 ClearFSMStatus
    3. 7.3 测试示例
  11. 应用集成
    1. 8.1 软件功能和流程
  12. 适配其他第 3 代 C2000 MCU
  13. 10闪存 API
    1. 10.1 闪存 API 检查清单
      1. 10.1.1 使用闪存 API 时的注意事项
  14. 11源文件清单
  15. 12排查
    1. 12.1 通用
  16. 13结语
  17. 14参考资料
  18. 15修订历史记录

EEPROM_Config_Check

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

第一,该函数验证选择用于 EEPROM 仿真的闪存组是否有效。有效的闪存组选择不得选择组 0 进行仿真,并且必须受特定器件型号的支持。例如,只有特定的 F28p65x 型号具有闪存组 2-4。要验证该信息,请参阅特定于器件的数据表。

if (FLASH_BANK_SELECT == FlashBank0StartAddress)
{
    return 0xFFFF;
}

if (FLASH_BANK_SELECT == FlashBank2StartAddress)
{
#if !defined(F28P65xDKx) && !defined(F28P65xSKx) && !defined(F28P65xSHx)   
        return 0xFFFF;
#endif
} else if (FLASH_BANK_SELECT == FlashBank3StartAddress) // If using Bank 3
{
#if !defined(F28P65xDKx) && !defined(F28P65xSKx)   
        return 0xFFFF;
#endif
} else if (FLASH_BANK_SELECT == FlashBank4StartAddress) 
{
#if !defined(F28P65xDKx) && !defined(F28P65xSKx) && !defined(F28P65xSHx)   
        return 0xFFFF;
#endif
}

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

  • 选择用于仿真的闪存扇区数量是否多于闪存组中可用的扇区数量
NUM_EEPROM_SECTORS = FIRST_AND_LAST_SECTOR[1] - FIRST_AND_LAST_SECTOR[0] + 1;
if (NUM_EEPROM_SECTORS > NUM_FLASH_SECTORS || NUM_EEPROM_SECTORS == 0)
{
    return 0xEEEE;
}
  • 选择用于仿真的第一个和最后一个扇区的组合是否无效
if (NUM_EEPROM_SECTORS > 1)
{
    if (FIRST_AND_LAST_SECTOR[1] <= FIRST_AND_LAST_SECTOR[0])
    {
        return 0xEEEE;
     }
     // Check if SECTOR_NUMBERS contains invalid sector
    if (FIRST_AND_LAST_SECTOR[0] > NUM_FLASH_SECTORS - 1)
    {
        return 0xEEEE;
    }
    if (FIRST_AND_LAST_SECTOR[1] > NUM_FLASH_SECTORS - 1 || FIRST_AND_LAST_SECTOR[1] < 1)
    {
        return 0xEEEE;
    }
} else // If only one sector, validate the sector is input properly
{

// Verify that the only sector is valid
if (FIRST_AND_LAST_SECTOR[0] > NUM_FLASH_SECTORS - 1) {
    return 0xEEEE;
}

如果使用页面模式,还需检查以下各项

  • 检查 EEPROM 组 + 页面的总大小是否适合所选的闪存扇区
// Calculate size of each EEPROM Bank (16 bit words)
Bank_Size = 8 + ((EEPROM_PAGE_DATA_SIZE + 8) * NUM_EEPROM_PAGES);

// Calculate amount of available space (16 bit words)
uint32 Available_Words = NUM_EEPROM_SECTORS * FLASH_SECTOR_SIZE;

// Check if size of EEPROM Banks and Pages fit in EEPROM sectors
if (Bank_Size * NUM_EEPROM_BANKS > Available_Words)
{
    return 0xCCCC;
}

如果检测到以下情况之一,该代码还会通过相应的代码向用户发出警告:

  • 配置 EEPROM 组和页面大小后,闪存中会保留一个或多个 EEPROM 组的空间
// Notify for extra space (more than one bank leftover)
if (Available_Words - (Bank_Size * NUM_EEPROM_BANKS ) >= Bank_Size)
{
    Warning_Flags += 1;
}
  • 如果每个页面包含少于 5 个 16 位字(这会浪费空间,因为无需状态代码即可使用 64 位模式)
if (EEPROM_PAGE_DATA_SIZE < 5)
{
    Warning_Flags += 2;
}
  • 如果使用 32-127 范围内的扇区(对于 F28P65x 器件)并且未使用分配给写入保护掩码中 single-bit 的全部八个扇区,则会发出警告。由 single-bit 设计的八个扇区中任何未使用的扇区都无法受到适当的擦除保护。有关写保护掩码的更多详细信息,请参阅 TMS320F28P65x 闪存 API 版本 3.02.00.00 参考指南
if (FIRST_AND_LAST_SECTOR[1] > 31) {

    if (FIRST_AND_LAST_SECTOR[0] > 31)
    {

        if (NUM_EEPROM_SECTORS < 8) {
            Warning_Flags += 4;
        } else {

            if ((FIRST_AND_LAST_SECTOR[0] % 8) != 0 || ((FIRST_AND_LAST_SECTOR[1] + 1) % 8 != 0))
            {
                Warning_Flags += 4;
            }
        }
    } else
    { 


        if ((FIRST_AND_LAST_SECTOR[1] + 1) % 8 != 0)
        {
            Warning_Flags += 4;
        }
    }
}

最后,为活动 EEPROM 单元配置写入/擦除保护掩码。该函数还通过擦除要用于编程的扇区来为仿真准备好闪存。

uint64 WE_Protection_AB_Mask = Configure_Protection_Masks(FIRST_AND_LAST_SECTOR, NUM_EEPROM_SECTORS);


WE_Protection_A_Mask = 0xFFFFFFFF ^ (uint32)WE_Protection_AB_Mask;
WE_Protection_B_Mask = 0x00000FFF ^ WE_Protection_AB_Mask >> 32;


EEPROM_Erase();