Also, If you are using the CodeWarrior BDM to debug, by default the BDM
does not read the contents of the the Flash / EEPROM when stopped /
single stepping. This means you will only see the original values of the
EEPROM, not your updated ones.
You can change this by editing the debugging memory map, and changing
the entry for EEPROM to allow refresh memory when halting.
David
Dan White wrote: >
>
>
>
> You don't want to read-modify-write the ESTAT because writing a one
clears
> the flags so change that to
>
> ESTAT = ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK;
>
> And
>
> ESTAT = ESTAT_CBEIF_MASK;
>
>
>
> I do a SECTOR ERASE and then two WORD PROGRAM commands.
>
>
>
> Also, I've been burned by the ECLKDIV register. Make sure you ONLY WRITE
TO
> ECLKDIV ONCE.
>
>
>
>
>
> _____
>
> From: 6... [mailto:6...] On Behalf Of
> Tennies, Joseph C.
> Sent: Friday, December 04, 2009 1:58 PM
> To: 6...
> Subject: [68HC12] Problems with EEPROM Writes on HC9S12XD256
>
>
>
>
>
> I have been trying to write to the EEPROM on the HC9S12XD256 processor
> and have been having problems getting it to write.
>
> The OSC is 12 MHz, but we run the PLL to bring it up to 48 MHz. Our
> EDIV is set to 60 (with no PRDIV8).
>
> The following code is on FreeScale CodeWarrior 4.7. Is there something
> blatently obvious that I'm doing wrong? (I know I need timeouts
instead
> of infinite while loops.) Currently this code does not write anything
> to the EEPROM.
>
> void write_eeprom( uint16_t addr, uint16_t data)
> {
> uint16_t *sectorBaseAddr;
> uint16_t loWord;
> uint16_t hiWord;
> uint16_t tickNow;
> uint8_t eepromStatus;
>
> if ( ECLKDIV | ECLKDIV_EDIVLD_MASK )
> {
> while( !(ESTAT & ESTAT_CBEIF_MASK) );
>
> if ( ESTAT & (ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK) )
> {
> ESTAT |= (ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK);
> }
> //*********************************************************************
> // Preserve other bytes in sector
>
> //*********************************************************************
>
> /* Get the base address of the sector to erase */
> sectorBaseAddr = (uint16_t *)(addr & ~0x03);
>
> if ( !( sectorBaseAddr >= (uint16_t *)0xE00 && sectorBaseAddr <
> (uint16_t *)0xF00 ) )
> {
> pet_watchdog();
> return;
> }
>
> /* Preserve the current sector contents */
> loWord = sectorBaseAddr[0];
> hiWord = sectorBaseAddr[1];
> //*********************************************************************
> // Determine which word the new data occupies
>
> //*********************************************************************
> if((addr & 0x02) == 0)
> {
> loWord = data;
> }
> else
> {
> hiWord = data;
> }
>
> /* Write first word */
> sectorBaseAddr[0] = loWord;
> ECMD = EEPROM_CMD_SECTOR_MODIFY;
> ESTAT |= ESTAT_CBEIF_MASK;
> while ( !(ESTAT & ESTAT_CCIF_MASK) );
>
> /* write second word */
> while( !(ESTAT & ESTAT_CBEIF_MASK) );
> if ( ESTAT & (ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK) )
> {
> ESTAT |= (ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK);
> }
> /* Write second word */
> sectorBaseAddr[1] = hiWord;
> ECMD = EEPROM_CMD_WORD_PROGRAM;
> ESTAT |= ESTAT_CBEIF_MASK;
> while ( !(ESTAT & ESTAT_CCIF_MASK) );
>
> /* write second word */
>
> while( !(ESTAT & ESTAT_CBEIF_MASK) );
>
> if ( ESTAT & (ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK) )
> {
> ESTAT |= (ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK);
> }
> }
> /* Reset the watchdog */
> pet_watchdog();
>
> } // end of write_eeprom
> Programmers work long hours trying to design stuff that keeps them from
> having to work long hours. -David Allen "Making It All Work"
>
> Joseph Tennies
>
> Senior Software Engineer
>
> Esterline Control Systems - AVISTA
>
>
>
Reply by Dan White●December 4, 20092009-12-04
You don't want to read-modify-write the ESTAT because writing a one
clears
the flags so change that to
ESTAT = ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK;
And
ESTAT = ESTAT_CBEIF_MASK;
I do a SECTOR ERASE and then two WORD PROGRAM commands.
Also, I've been burned by the ECLKDIV register. Make sure you ONLY WRITE
TO
ECLKDIV ONCE.
_____
From: 6... [mailto:6...] On Behalf Of
Tennies, Joseph C.
Sent: Friday, December 04, 2009 1:58 PM
To: 6...
Subject: [68HC12] Problems with EEPROM Writes on HC9S12XD256
I have been trying to write to the EEPROM on the HC9S12XD256 processor
and have been having problems getting it to write.
The OSC is 12 MHz, but we run the PLL to bring it up to 48 MHz. Our
EDIV is set to 60 (with no PRDIV8).
The following code is on FreeScale CodeWarrior 4.7. Is there something
blatently obvious that I'm doing wrong? (I know I need timeouts instead
of infinite while loops.) Currently this code does not write anything
to the EEPROM.
if ( ESTAT & (ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK) )
{
ESTAT |= (ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK);
}
//*********************************************************************
// Preserve other bytes in sector
/* Preserve the current sector contents */
loWord = sectorBaseAddr[0];
hiWord = sectorBaseAddr[1];
//*********************************************************************
// Determine which word the new data occupies
/* Write first word */
sectorBaseAddr[0] = loWord;
ECMD = EEPROM_CMD_SECTOR_MODIFY;
ESTAT |= ESTAT_CBEIF_MASK;
while ( !(ESTAT & ESTAT_CCIF_MASK) );
/* write second word */
while( !(ESTAT & ESTAT_CBEIF_MASK) );
if ( ESTAT & (ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK) )
{
ESTAT |= (ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK);
}
/* Write second word */
sectorBaseAddr[1] = hiWord;
ECMD = EEPROM_CMD_WORD_PROGRAM;
ESTAT |= ESTAT_CBEIF_MASK;
while ( !(ESTAT & ESTAT_CCIF_MASK) );
/* write second word */
while( !(ESTAT & ESTAT_CBEIF_MASK) );
if ( ESTAT & (ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK) )
{
ESTAT |= (ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK);
}
}
/* Reset the watchdog */
pet_watchdog();
} // end of write_eeprom
Programmers work long hours trying to design stuff that keeps them from
having to work long hours. -David Allen "Making It All Work"
Joseph Tennies
Senior Software Engineer
Esterline Control Systems - AVISTA
Reply by Robert●December 4, 20092009-12-04
I don't see an erase before the write.
-rob
Reply by "Tennies, Joseph C."●December 4, 20092009-12-04
I have been trying to write to the EEPROM on the HC9S12XD256 processor
and have been having problems getting it to write.
The OSC is 12 MHz, but we run the PLL to bring it up to 48 MHz. Our
EDIV is set to 60 (with no PRDIV8).
The following code is on FreeScale CodeWarrior 4.7. Is there something
blatently obvious that I'm doing wrong? (I know I need timeouts instead
of infinite while loops.) Currently this code does not write anything
to the EEPROM.
/* Write first word */
sectorBaseAddr[0] = loWord;
ECMD = EEPROM_CMD_SECTOR_MODIFY;
ESTAT |= ESTAT_CBEIF_MASK;
while ( !(ESTAT & ESTAT_CCIF_MASK) );
/* write second word */
while( !(ESTAT & ESTAT_CBEIF_MASK) );
if ( ESTAT & (ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK) )
{
ESTAT |= (ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK);
}
/* Write second word */
sectorBaseAddr[1] = hiWord;
ECMD = EEPROM_CMD_WORD_PROGRAM;
ESTAT |= ESTAT_CBEIF_MASK;
while ( !(ESTAT & ESTAT_CCIF_MASK) );
/* write second word */
while( !(ESTAT & ESTAT_CBEIF_MASK) );
if ( ESTAT & (ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK) )
{
ESTAT |= (ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK);
}
}
/* Reset the watchdog */
pet_watchdog();
} // end of write_eeprom
Programmers work long hours trying to design stuff that keeps them from
having to work long hours. -David Allen "Making It All Work"