void main(void) {.... prog_eeprom_WORD(0x0c00, 0); /* clear 0x0c00..0x0c07 */ prog_eeprom_WORD(0x0c02, 0); prog_eeprom_WORD(0x0c04, 0); prog_eeprom_WORD(0x0c06, 0); prog_eeprom_WORD(0x0c02, 0x104f); /* try to write 0x104f to 0x0c02 (will be 0xffff) */ prog_eeprom_WORD(0x0c06, 0x1234); /* try to write something to 0x0c06 (succeeds but 0x0c04 will be 0x104f) */......} /* Note that low_level_WriteWORD does NOT erase nor verify the EEPROM for erased state */ /* the timer interrupt must be disabled during this time (parameters in EEPROM are not accessable during this operation) */void low_level_WriteWORD(WORD addr, WORD data16) { BYTE iflag; if (*(volatile WORD *) addr == data16) return; /* no need to program */ if (ESTAT_CBEIF == 0) { /* Command Buffer not empty— */ int_err |= 2; /* flag an OnChip EEPROM internal error */ return; }// keep the interrupts enabled, to prevent SCI OverRuns, just disable the Modulus Counter Interrupt iflag = MCCTL_MCZI – 1 : 0; MCCTL_MCZI = 0; /* Disable Modulus Counter Interrupt */ ESTAT = 0x30; /* writing a 1 to the error flags PVIOL and ACCERR resets them */ *(volatile WORD *) addr = data16; /* Array address and program data */ ECMD = WORD_Program; /* WORD program command */ ESTAT_CBEIF = 1; /* Clear flag command buffer empty */ if (ESTAT_PVIOL || ESTAT_ACCERR) { int_err |= 4; /* flag an OnChip EEPROM internal error */ goto ww_exit; } while (ESTAT_CBEIF == 0); /* Wait to buffer empty */ while (ESTAT_CCIF == 0); /* Wait for command completition */ww_exit: if (iflag) MCCTL_MCZI = 1; /* Reenable Modulus Counter Interrupt */ return;} /* the timer interrupt must be disabled during this time (parameters in EEPROM are not accessable during this operation) */void low_level_WriteSector(WORD sect_addr, DWORD data32) { BYTE iflag; if (*(volatile DWORD *) sect_addr == data32) return; /* no need to program */ if (ESTAT_CBEIF == 0) { /* Command Buffer not empty˜ */ int_err |= 2; /* flag an OnChip EEPROM internal error */ return; }// keep the interrupts enabled, to prevent SCI OverRuns, just disable the Modulus Counter Interrupt iflag = MCCTL_MCZI ™ 1 : 0; MCCTL_MCZI = 0; /* Disable Modulus Counter Interrupt */ ESTAT = 0x30; /* writing a 1 to the error flags PVIOL and ACCERR resets them */ *(volatile WORD *) sect_addr = (WORD)(data32 >> 16); /* Array address and program data - higher part */ ECMD = Sector_Modify; /* Sector modify command */ ESTAT_CBEIF = 1; /* Clear flag command buffer empty */ if (ESTAT_PVIOL || ESTAT_ACCERR) { int_err |= 4; /* flag an OnChip EEPROM internal error */ goto ws_exit; } while (ESTAT_CBEIF == 0); /* Wait to buffer empty */ low_level_WriteWORD(sect_addr + 2, (WORD) data32); /* Write lower part */ws_exit: if (iflag) MCCTL_MCZI = 1; /* Reenable Modulus Counter Interrupt */ return;} /* program one word in the internal EEPROM */ /* - if the bytes fall into different sectors */ /* - program the word as two bytes */ /* - else if the word is aligned and erased */ /* - just program that word */ /* else */ /* - read the 4-byte sector it belongs to */ /* - erase the sector */ /* - program back the modified sector */void prog_eeprom_WORD(WORD Addr, WORD Data) { union { BYTE b[4]; WORD w[2]; DWORD l; } backup; BYTE idx = Addr & 0x0003; if (*(volatile WORD *) Addr == Data) return; /* no need to program */ if (Addr < EEPROM_START || Addr > EEPROM_END) { /* Is given address out of EEPROM area array */ *(WORD *) Addr = Data; return; } if (idx == 3) { // the word spans over two segments prog_eeprom_BYTE(Addr, Data >> 8); prog_eeprom_BYTE(Addr + 1, Data & 0xff); } else if ((Addr & 1) == 0 && *(volatile WORD *) Addr == 0xFFFF) low_level_WriteWORD(Addr, Data); /* Write new content directly if word aligned and already erased */ else { /* Not erased or not word aligned */ backup.l = *(volatile DWORD *) (Addr & 0xFFFC); /* Load sector to variable backup (from sector-aligned address) */ backup.b[idx] = Data >> 8; /* Store data to variable backup */ backup.b[idx + 1] = Data & 0xff; low_level_WriteSector(Addr & 0xFFFC, backup.l); /* Erase sector and write new content */ }}
ESTAT_CBEIF = 1; /* Clear flag command buffer empty */ if (ESTAT_PVIOL || ESTAT_ACCERR) { ... }