ZHCADD5A November 2023 – April 2024 TMS320F28P650DH , TMS320F28P650DK , TMS320F28P650SH , TMS320F28P650SK , TMS320F28P659DH-Q1 , TMS320F28P659DK-Q1 , TMS320F28P659SH-Q1
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
}
第二,检查选择用于仿真的闪存扇区的有效性。该函数检查:
uint16 NUM_EEPROM_SECTORS_1 = FIRST_AND_LAST_SECTOR[0][1] - FIRST_AND_LAST_SECTOR[0][0] + 1;
uint16 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)
{
// Check if FIRST_AND_LAST_SECTOR is sorted in increasing order
// and doesn't have duplicates
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;
}
// Check if FIRST_AND_LAST_SECTOR contains invalid sector
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 only using 1 sector
{
// Verify that only sector is valid
if (FIRST_AND_LAST_SECTOR[0][0] > NUM_FLASH_SECTORS - 1 ||
FIRST_AND_LAST_SECTOR[1][0] > NUM_FLASH_SECTORS - 1) {
return 0xEEEE;
}
}
如果使用页面模式,还将检查以下各项
// 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; }
// Verify that the two EEPROM units do not have overlapping protection
// masks
// First, get sectors for both units
uint64 WE_Protection_AB_Sectors_Unit_0 = Configure_Protection_Masks(FIRST_AND_LAST_SECTOR[0], NUM_EEPROM_SECTORS);
uint64 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;
}
如果检测到以下情况之一,该函数还会通过相应的返回代码发出警告:
// Notify for extra space (more than one EEPROM bank leftover)
if (Available_Words - (Bank_Size * NUM_EEPROM_BANKS ) >= Bank_Size)
{
Warning_Flags += 1;
}
if (EEPROM_PAGE_DATA_SIZE < 5)
{
Warning_Flags += 2;
}
如果使用 32-127 范围内的扇区(对于 F28P65x 器件)并且未使用分配给写入/擦除保护掩码中单个位的全部八个扇区,则会发出警告。由 single-bit 设计的八个扇区中任何未使用的扇区都无法受到适当的擦除保护。有关写入/擦除保护掩码如何与扇区对应的更多信息,请参阅 TMS320F28P65x 闪存 API 版本 3.02.00.00 参考指南。
uint16 i;
for (i = 0; i < 2; i++)
{
// If using any sectors from 32-127
if (FIRST_AND_LAST_SECTOR[i][1] > 31) {
// If all sectors use protection mask B
if (FIRST_AND_LAST_SECTOR[i][0] > 31)
{
// If using less than 8 sectors
if (NUM_EEPROM_SECTORS < 8)
{
Warning_Flags += 4;
break;
} else {
// If sectors are multiples of 8
if ((FIRST_AND_LAST_SECTOR[i][0] % 8) != 0 ||
((FIRST_AND_LAST_SECTOR[i][1] + 1) % 8 != 0))
{
Warning_Flags += 4;
break;
}
}
} else { // If only last sector is using protection mask B
// If not a multiple of 8
if ((FIRST_AND_LAST_SECTOR[i][1] + 1) % 8 != 0) {
Warning_Flags += 4;
break;
}
}
}
}
该函数还通过擦除要用于编程的扇区来为仿真准备好闪存。
// Combine sectors from both units and separate them by which
// protection register they use (A or B)
uint32 Combined_WE_Protection_A_Sectors =
(uint32)WE_Protection_AB_Sectors_Unit_0 |
(uint32)WE_Protection_AB_Sectors_Unit_1;
uint32 Combined_WE_Protection_B_Sectors =
WE_Protection_AB_Sectors_Unit_0 >> 32 |
WE_Protection_AB_Sectors_Unit_1 >> 32;
// Create protection masks accordingly
WE_Protection_A_Mask = 0xFFFFFFFF ^ Combined_WE_Protection_A_Sectors;
WE_Protection_B_Mask = 0x00000FFF ^ Combined_WE_Protection_B_Sectors;
Erase_Bank();
最后,为活动 EEPROM 单元配置写入/擦除保护掩码。
// Configure Write/Erase Protection Masks used by the Flash API
uint64 WE_Protection_AB_Mask = Configure_Protection_Masks(FIRST_AND_LAST_SECTOR[EEPROM_ACTIVE_UNIT], NUM_EEPROM_SECTORS);
WE_Protection_A_Mask = 0xFFFFFFFF ^ (uint32)WE_Protection_AB_Mask;
WE_Protection_B_Mask = 0x00000FFF ^ WE_Protection_AB_Mask >> 32;