ZHCADD5A November   2023  – April 2024 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. 软件说明
    1. 4.1 软件功能和流程
  8. 乒乓仿真
    1. 5.1 用户配置
      1. 5.1.1 EEPROM_PingPong_Config.h
      2. 5.1.2 F28P65x_EEPROM_PingPong.c
    2. 5.2 EEPROM 函数
      1. 5.2.1  EEPROM_Config_Check
      2. 5.2.2  Configure_Protection_Masks
      3. 5.2.3  EEPROM_Write
      4. 5.2.4  EEPROM_Read
      5. 5.2.5  EEPROM_Erase
        1. 5.2.5.1 Erase_Bank
      6. 5.2.6  EEPROM_GetValidBank
      7. 5.2.7  EEPROM_UpdateBankStatus
      8. 5.2.8  EEPROM_UpdatePageStatus
      9. 5.2.9  EEPROM_UpdatePageData
      10. 5.2.10 EEPROM_Get_64_Bit_Data_Address
      11. 5.2.11 EEPROM_Program_64_Bits
      12. 5.2.12 EEPROM_CheckStatus
      13. 5.2.13 ClearFSMStatus
    3. 5.3 测试示例
  9. 单存储单元仿真
    1. 6.1 用户配置
      1. 6.1.1 EEPROM_Config.h
      2. 6.1.2 F28P65x_EEPROM.c
    2. 6.2 EEPROM 函数
      1. 6.2.1  EEPROM_Config_Check
      2. 6.2.2  Configure_Protection_Masks
      3. 6.2.3  EEPROM_Write
      4. 6.2.4  EEPROM_Read
      5. 6.2.5  EEPROM_Erase
      6. 6.2.6  EEPROM_GetValidBank
      7. 6.2.7  EEPROM_Get_64_Bit_Data_Address
      8. 6.2.8  EEPROM_UpdateBankStatus
      9. 6.2.9  EEPROM_UpdatePageStatus
      10. 6.2.10 EEPROM_UpdatePageData
      11. 6.2.11 EEPROM_Get_64_Bit_Data_Address
      12. 6.2.12 EEPROM_Program_64_Bits
      13. 6.2.13 EEPROM_CheckStatus
      14. 6.2.14 ClearFSMStatus
    3. 6.3 测试示例
  10. 应用集成
  11. 适配其他第 3 代 C2000 MCU
  12. 闪存 API
    1. 9.1 闪存 API 检查清单
      1. 9.1.1 使用闪存 API 时的注意事项
  13. 10源文件清单
  14. 11故障排除
    1. 11.1 常见问题
  15. 12结语
  16. 13参考资料
  17. 14修订历史记录

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 it 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 will 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();