0
\$\begingroup\$

I'm trying to write the EEPROM (DFM) on a PIC18F27Q83. I copied the sequence from the datasheet exactly and it still fails. The device id is 0x9909 and revision id is 0xA45.

        // Save interrupt enable bit value
    unsigned char GIEBitValue = INTCON0bits.GIE;
        // Load NVMADR with the target address of the byte
    NVMADR = 0x380000;
    NVMDATL = outgoing_data.data_bytes[0]; // Load NVMDAT with the desired value
    NVMCON1bits.CMD = 0x04; // Set the byte write command and post increment
    INTCON0bits.GIE = 0; // Disable interrupts
        //????????? Required Unlock Sequence ?????????
    NVMLOCK = 0x55;
    NVMLOCK = 0xAA;
    NVMCON0bits.GO = 1; // Start byte write
        //???????????????????????????????????????????????
    while (NVMCON0bits.GO); // Wait for the write operation to complete
        // Verify byte write operation success and call the recovery function if needed
    if (NVMCON1bits.WRERR)
    {
        INTCON0bits.GIE = GIEBitValue; // Restore interrupt enable bit value
        NVMCON1bits.CMD = 0;
        return false;
    }

After the GO bit goes to zero meaning the operation has completed the WRERR bit stays at 1 meaning the operation failed. I have watched the WRERR bit and it is just 1 all the time. I assume that once a successful write occurs it should go to zero.

The chip is running on a 10MHz external oscillator and OFSC is 40MHz. All of that has been verified and I have UART comms with the chip no problem.

Data Sheet

\$\endgroup\$
4
  • \$\begingroup\$ Why do you only restore INTCON0bits.GIE when NVMCON1bits.WRERR is asserted? \$\endgroup\$
    – Velvet
    Commented Jan 10 at 14:03
  • \$\begingroup\$ Why don't you use the EEPROM macros for read and write? \$\endgroup\$
    – Mike
    Commented Jan 10 at 14:07
  • \$\begingroup\$ @Velvet this is just a code snippet. There are more writes that happen after this. GIE gest restored on error or when exiting. \$\endgroup\$
    – vini_i
    Commented Jan 10 at 14:51
  • \$\begingroup\$ @Mike Where can I find information about these macros? \$\endgroup\$
    – vini_i
    Commented Jan 10 at 14:57

1 Answer 1

0
\$\begingroup\$

Your write sequence looks similar to what the datasheet proposes:

// Code sequence to write one byte to a DFM
// DFM target address is specified by DFM_ADDR
// Target data are specified by ByteValue

// Save interrupt enable bit value
uint8_t GIEBitValue = INTCON0bits.GIE;
// Load NVMADR with the target address of the byte
NVMADR = DFM_ADDR;
NVMDATL = ByteValue; // Load NVMDAT with the desired value
NVMCON1bits.CMD = 0x03; // Set the byte write command
INTCON0bits.GIE = 0; // Disable interrupts
//––––––––– Required Unlock Sequence –––––––––
NVMLOCK = 0x55;
NVMLOCK = 0xAA;
NVMCON0bits.GO = 1; // Start byte write
//–––––––––––––––––––––––––––––––––––––––––––––––
INTCON0bits.GIE = GIEBitValue; // Restore interrupt enable bit value (if interrupts are desired during DFM write)
while (NVMCON0bits.GO); // Wait for the write operation to complete

// Verify byte write operation success and call the recovery function if needed
if (NVMCON1bits.WRERR){
    WRITE_FAULT_RECOVERY();
}

NVMCON1bits.CMD = 0; // Disable writes to memory

The reasons for WRERR to be asserted are:

  1. A write operation was interrupted by a Reset,
  2. or a write or erase operation was attempted on a write-protected area,
  3. or a write or erase operation was attempted on an unimplemented area,
  4. or a write or erase operation was attempted while locked,
  5. or a page operation was directed to a DFM area

Reason 1 isn't the probable cause, and reasons 3, 4 and 5 can be ruled out.

The most likely reason is that the Data EEPROM is write-protected.

Check the CONFIG8 register to exclude or confirm this possibility:

enter image description here

\$\endgroup\$
4
  • \$\begingroup\$ Write protection on the EEPROM is set to off. #pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not Write protected) This is from my config file. \$\endgroup\$
    – vini_i
    Commented Jan 10 at 14:56
  • \$\begingroup\$ If I just ignore the WRERR register the write occurs successfully. I'm not sure if there is some type of timing mismatch between GO and WRERR. Or perhaps for EEPROM writes this bit does not work. \$\endgroup\$
    – vini_i
    Commented Jan 10 at 17:05
  • \$\begingroup\$ I wouldn't assume that WRERR can be ignored. The datasheet specifies "If the DFM is write-protected or if NVMADR points at an invalid address location, attempts to set the GO bit will fail and the WRERR bit will be set.". \$\endgroup\$
    – Velvet
    Commented Jan 10 at 17:15
  • \$\begingroup\$ Have you tried to use the command to manually increment the address, as per datasheet example? (NVMCON1bits.CMD = 0x03) \$\endgroup\$
    – Velvet
    Commented Jan 10 at 17:15

Not the answer you're looking for? Browse other questions tagged or ask your own question.