• AVR Freaks

Hot!PIC16F1619 Problem Writing to Configuration Flash (Updating UserId)

Author
joeynovak
New Member
  • Total Posts : 1
  • Reward points : 0
  • Joined: 2020/06/24 12:41:50
  • Location: 0
  • Status: offline
2020/08/12 13:38:43 (permalink)
0

PIC16F1619 Problem Writing to Configuration Flash (Updating UserId)

Hi Guys,
 
First, thanks for taking the time to read this.  I've been working on a bootloader for this chip for a few months at work and I am so close to being done, but there is one feature I can't get to work.  Writing to the config flash.  The documentation has almost nothing on this.  I can write to the rest of flash, I can erase the writeable areas of the config flash but I can't write to it for the life of me.
 
Here is my flash write row method.
 

#define WRITE_FLASH_BLOCKSIZE    32
 
int8_t FLASH_WriteRow(uint16_t rowAddress, uint16_t *flashWordArray)
  {
  FLASH_EraseRow(rowAddress);

  uint8_t GIEBitValue = INTCONbits.GIE; // Save interrupt enable
  uint8_t i;

  INTCONbits.GIE = 0; // Disable interrupts

  // Block write sequence
  if (rowAddress >= 0x8000){
    printf("Writing Config\n", rowAddress);
    PMCON1bits.CFGS = 1; // Select Configuration space
    }
  else
    PMCON1bits.CFGS = 0; // Deselect Configuration space
  
  PMCON1bits.WREN = 1; // Enable writes
  PMCON1bits.LWLO = 1; // Only load write latches

  for (i = 0; i < WRITE_FLASH_BLOCKSIZE; i++)
    {
    if(rowAddress > 0x800F) //Areas above 8004 are not writeable
      break;
    // Load lower 8 bits of write address
    PMADRL = (rowAddress & 0xFF);
    // Load upper 6 bits of write address
    PMADRH = ((rowAddress & 0xFF00) >> 8);

    // Load data in current address
    PMDATL = flashWordArray[i] & 0xFF;
    PMDATH = ((flashWordArray[i] & 0xFF00) >> 8);

    if (i == (WRITE_FLASH_BLOCKSIZE - 1))
      {
      // Start Flash program memory write
      PMCON1bits.LWLO = 0;
      }

    PMCON2 = 0x55;
    PMCON2 = 0xAA;
    PMCON1bits.WR = 1;
    NOP();
    NOP();

    rowAddress++;
    }

  PMCON1bits.WREN = 0; // Disable writes
  INTCONbits.GIE = GIEBitValue; // Restore interrupt enable

  return 0;
  }

 
Any thoughts?
 
Thanks!
 
Joey
#1

4 Replies Related Threads

    upand_at_them
    Super Member
    • Total Posts : 649
    • Reward points : 0
    • Joined: 2005/05/16 07:02:38
    • Location: Pennsylvania
    • Status: offline
    Re: PIC16F1619 Problem Writing to Configuration Flash (Updating UserId) 2020/08/13 11:48:34 (permalink)
    +1 (1)
    You can't write to config from a bootloader.
    joeynovakI can erase the writeable areas of the config flash

     
    What does that mean?
     
    The config words are erased/written in Program/Verify mode.  Says so in the datasheet.  You can't do anything to the config words from a bootloader.
    #2
    upand_at_them
    Super Member
    • Total Posts : 649
    • Reward points : 0
    • Joined: 2005/05/16 07:02:38
    • Location: Pennsylvania
    • Status: offline
    Re: PIC16F1619 Problem Writing to Configuration Flash (Updating UserId) 2020/08/13 11:51:51 (permalink)
    +1 (1)
    Wow, that chip has a built-in PID.  Cool.
     
    #3
    davekw7x
    Entropy++
    • Total Posts : 1890
    • Reward points : 0
    • Joined: 2012/01/16 12:01:07
    • Location: Second star on the right, straight on till morning
    • Status: offline
    Re: PIC16F1619 Problem Writing to Configuration Flash (Updating UserId) 2020/08/13 19:01:03 (permalink)
    +1 (1)
    joeynovak
    ...
    Any thoughts?
     



    I'll try to boil it down:

    #define WRITE_FLASH_BLOCKSIZE    32

    int8_t FLASH_WriteRow(uint16_t rowAddress, uint16_t *flashWordArray)
      {
      FLASH_EraseRow(rowAddress);

      // all the stuff up to your loop is OK, assuming your EraseRow works OK

      PMCON1bits.LWLO = 1; // Only load write latches

      for (i = 0; i < WRITE_FLASH_BLOCKSIZE; i++)
        {
        // NOTE: since you break out of the loop  when you reach this count
        //       it never gets to the place where it writes with LWLO = 0 --- OOPS
        if(rowAddress > 0x800F) //Areas above 8004 are not writeable
          break;
          .
          .
          .
         }


    Now, writes in that block above the USER ID words are ignored (and erasing that block only erases the USER ID words), so you might as well just write four words and quit.  In other words, It doesn't hurt to write all 32 (don't break out of the loop early), but it doesn't help either.  Just make sure that the last WR is done with LWLO = 0.

    When I changed your function to go through the loop four times and clear LWLO when the count reaches 3, it works.

    Here's my main() test program

    void main(void)
    {
        uint8_t i;
        uint16_t user_id_wdata[32] = {0};
        uint16_t user_id_rdata[32] = {0};
        init_system();
        LED1_SetHigh();
        // It may reset a time or three during programming.
        // Don't let it start until you are really sure the
        // programming has finished!
        __delay_ms(2000);
        
        read_userid(user_id_rdata);
        printf("Initial USER ID:\r\n");
        for (i = 0; i < 4; i++) {
            printf("  0x%02X: 0x%04X\r\n", i, user_id_rdata[i]);
            // Give it something different to write each time
            user_id_wdata[i] = (user_id_rdata[i] + i + 1) & 0x3fff;
        }
        
        printf("Writing USER ID words");
        for (i = 0; i < 4; i++) {
            printf(" 0x%04X", user_id_wdata[i]);
        }
        printf("\r\n");
        
        FLASH_WriteRow(0x8000, user_id_wdata); // This is your function (modified)
        //write_userid(user_id_wdata); // This is my function
        read_userid(user_id_rdata);
        
        printf("USER ID after writing:\r\n");
        for (i = 0; i < 4; i++) {
            printf("  0x%02X: 0x%04X\r\n", i, user_id_rdata[i]);
        }
        while (1) {
            LED1_Toggle();
            __delay_ms(1000);
        }
    } // End of main()


    Output after programming:
    Compiled on Aug 13 2020 at 18:38:59 by XC8 version 2200
    Initial USER ID:
      0x00: 0x3FFF
      0x01: 0x3FFF
      0x02: 0x3FFF
      0x03: 0x3FFF
    Writing USER ID words 0x0000 0x0001 0x0002 0x0003
    USER ID after writing:
      0x00: 0x0000
      0x01: 0x0001
      0x02: 0x0002
      0x03: 0x0003

    Output after a manual reset:
    Compiled on Aug 13 2020 at 18:38:59 by XC8 version 2200
    Initial USER ID:
      0x00: 0x0000
      0x01: 0x0001
      0x02: 0x0002
      0x03: 0x0003
    Writing USER ID words 0x0001 0x0003 0x0005 0x0007
    USER ID after writing:
      0x00: 0x0001
      0x01: 0x0003
      0x02: 0x0005
      0x03: 0x0007

    Windows 10, MPLABX version 5.40, XC8 version 2.20, PIC16F1619 plugged into my Curiosity board.
     
    Regards,

     Dave
    Footnote:
    The addresses 0x8000 - 0x8003 are Word addresses, not Byte addresses. So it takes exactly four read or write cycles to access them.  Each address holds a 14-bit number.  As my output shows, when these are erased, the 16-bit value is 0x3FFF.  After erasing, you can write any 14-bit number that you want to.  Well, you can try to write 16 bits and it won't give you an error, but the upper two bits won't take.
    post edited by davekw7x - 2020/08/14 05:45:02

    Sometimes I just can't help myself...
    #4
    davekw7x
    Entropy++
    • Total Posts : 1890
    • Reward points : 0
    • Joined: 2012/01/16 12:01:07
    • Location: Second star on the right, straight on till morning
    • Status: offline
    Re: PIC16F1619 Problem Writing to Configuration Flash (Updating UserId) 2020/08/13 19:14:26 (permalink)
    +2 (2)
    upand_at_them
    You can't write to config from a bootloader



    You can erase and write the four words that make up the  USER ID, which is the subject of this thread.  None of the other words in this block is erasable or writable during normal execution.
     
    The attachment is from page 72 of the Data Sheet, DS40001770D
     
    Regards,

    Dave
     
     
    post edited by davekw7x - 2020/08/13 19:29:00

    Attached Image(s)


    Sometimes I just can't help myself...
    #5
    Jump to:
    © 2020 APG vNext Commercial Version 4.5