SPRADE8 November 2023 TMS320F28P650DH , TMS320F28P650DK , TMS320F28P650SH , TMS320F28P650SK , TMS320F28P659DH-Q1 , TMS320F28P659DK-Q1 , TMS320F28P659SH-Q1
The EEPROM_Config_Check() function provides general error-checking and configures Write/Erase protection masks required by the Flash API. This function should be called before programming or reading from the emulated EEPROM Unit(s).
First, the function verifies that the Flash Bank selected for EEPROM Emulation is valid. A valid Flash Bank selection must not select Bank 0 for emulation and must be supported by the specific device variant. For example, only some F28p65x variants have Flash Banks 2-4, while others do not. To verify this information, see the device-specific data sheet.
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
}
Second, the validity of Flash Sectors selected for emulation is examined. This function checks for:
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;
}
}
If using Page Mode, the following will also be checked for
// 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;
}
It also warns you with the appropriate return code if one of the following conditions is detected:
// 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;
}
If using sectors in the 32-127 range (for F28P65x devices) and not using all eight sectors allocated to a single bit in the Write/Erase Protection Mask, a warning is issued. Any unused sectors within the eight designed by a single bit cannot be properly be protected from erase. For more information on how the Write/Erase Protection Masks correspond to sectors, see the TMS320F28P65x Flash API Version 3.00.00.00 Reference Guide.
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;
}
}
}
}
This function also prepares Flash for Emulation by erasing the Sectors to be used for programming.
// 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();
Finally, Write/Erase Protection masks are configured for the Active EEPROM Unit.
// 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;