This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Writiing to Flash in the MSP430G2332

Other Parts Discussed in Thread: MSP430F2012, MSP430G2332

Dear Developers:

Recently I have changed the MSP430 micro I am using from the MSP430F2012 to the MSP430G2332 to utilize more memory.  My operating F2012 code writes and reads the flash just fine.  When I compile it for the G2332 it hangs looking for the Flash busy bit to be reset in FCTL3. 

Does anyone have a suggestion as to the problem?  The datasheet and user guide are the same for both where the flash is concerned.

Thank you in advance

Al McBride

  • This is E2E forum for Zigbee, 6LowPAN&802.15.4. You can post MSP related questions at e2e.ti.com/.../f.
  • Al,

    could you please post your source code for that?

    Dennis
  • Al McBride said:
    My operating F2012 code writes and reads the flash just fine.  When I compile it for the G2332 it hangs looking for the Flash busy bit to be reset in FCTL3.

    F2xx an G2xx devices have the same flash. Because of this my msp-gang like flasher is able to flash (block write) mixed F2xx and and G2xx in parallel together.

    http://i.imgur.com/HlSdtof.gif

  • Dennis:

    Here is my code that works fine on the F2012 but hangs on the G2332.  Also note that the IAR Workbench debugger shows the memory at 0x1000 to be alternating 0xFF and 0x3F through ox10FF after the

    dummy write.

    Thanks

    Al

    void write_SegD (void)
    {
      // changed 10/17/14 to union struct and array
      char *Flash_ptr;                          // Flash pointer
      int i;
      char *ptr;
      ptr = &str.Turn_on_Dimlevel;
      WDTCTL = 0x5A0C;  // turn on wdt in case write hangs
     
      while (FCTL3 & 0x0001) {};                // check busy bit
      // erase segmentD
      Flash_ptr = (char *) 0x1000;              // Initialize Flash pointer
      FCTL2 = FWKEY + 0x0042;                   // MCLK divided by 2+1=3 or 333kHz
      FCTL3 = FWKEY;                            // Clear lock bit
      FCTL1 = FWKEY + ERASE;                    // Set Erase bit
      *Flash_ptr = 0;                           // Dummy write to erase Flash segment D
      while (FCTL3 & 0x0001) {};                // check busy bit
     
      // write feature bytes into flash
      for (i=0;i <= 12;i++) // 11/07/14
      { 
         FCTL1 = FWKEY + WRT;        // Set WRT bit for write operation
        *Flash_ptr++ = *ptr++;       // Write value to flash
        while (FCTL3 & 0x0001) {};   // check busy bit
       }

     FCTL1 = FWKEY;                  // Clear WRT bit
     FCTL3 = FWKEY + LOCK;       // Set LOCK bit
     
     WDTCTL = 0x5A84;             // Stop watchdog timer, ACLK source, no counter clear 
    }

  • Al, please open only one thread for one topic. You already have one here.

    Dennis

  • First: Have you tried what happens when you disable the watchdog?
  • Let us go on in this thread.

    Dennis

  • Dennis:
    Thanks for yur suggestion. I turned the wdt off and still have the issues. Below is the code as it stands now. The sympton of the failure is first all of the info memory is reset even Segment A. NExt all the even addresses are erased to 0xff and the odd o nes to 0x3F. Right after dummy write erase the system does a reset or PUC.
    here is my codevoid write_SegD (void){
    // changed 10/17/14 to union struct and array
    char *Flash_ptr; // Flash pointer int i; char *ptr;
    ptr = &str.Turn_on_Dimlevel;
    //WDTCTL = 0x5A84; // Stop watchdog timer, ACLK source, no counter clear
    WDTCTL = 0x5A80; // Stop watchdog timer
    while (FCTL3 & 0x0001) {}; // check busy bit // erase segmentD
    Flash_ptr = (char *) 0x1000; // Initialize Flash pointer for segment D
    FCTL1 = FWKEY + ERASE; // Set Erase bit and clear Meras to erase segment
    FCTL2 = FWKEY + 0x0042; // MCLK divided by 2+1=3 or 333kHz
    FCTL3 = FWKEY; // does not clear lockA and but does segment lock bit
    *Flash_ptr = 0; // Dummy write to erase Flash segment D
    //while (FCTL3 & 0x0001) {}; // check busy bit
    // erase complete // write feature bytes into flash
    for (i=0;i <= 14;i++) // 11/07/14 {
    FCTL1 = FWKEY + WRT; // Set WRT bit for write operation
    *Flash_ptr++ = *ptr++; // Write value to flash
    while (FCTL3 & 0x0001) {}; // check busy bit }
    FCTL1 = FWKEY; // Clear WRT bit
    FCTL3 = FWKEY + LOCK; // Set LOCK bit
    //WDTCTL = 0x5A0C; // turn on watchdog timer}
  • If function write_SegD is executed from flash (not from RAM) there is no need for testing BUSY bit, because program will not continue until operation on flash memory is finished. It is more clear if in source are used constants names, and not numbers. There are working examples for writing to info memory for MSP340x2xx devices, slac080 (or similar) "msp430x20x3_flashwrite_01.c", and there you can find right way how it should be done.
  • Here are some functions I use for writing/reading bytes to/from flash (not for InfoA):

    void flash_delete_segment( uint16_t segment ) // Argument is an address in desired segment
    {
      uint8_t *flash_ptr;
    
      flash_ptr = (uint8_t*) segment; // Initialize pointer
      FCTL3 = FWKEY;                  // Clear lock-bit
      FCTL1 = (FWKEY | ERASE);        // Set erase-bit
      *flash_ptr = 0;                 // Dummy-write to delete segment - CPU hold
      FCTL3 = (FWKEY | LOCK);         // Set lock-bit
    }
    
    void flash_write_byte( uint16_t address, uint8_t byte )
    {
      uint8_t *flash_ptr;
    
      flash_ptr = (uint8_t*) address; // Initialize pointer
      FCTL3 = FWKEY;                  // Clear lock-bit
      FCTL1 = (FWKEY | WRT);          // Set write-bit
      *flash_ptr = byte;              // Write byte - CPU hold
      FCTL1 = FWKEY;                  // Clear write-bit
      FCTL3 = (FWKEY | LOCK);         // Set lock-bit
    }
    
    uint8_t flash_read_byte( uint16_t address )
    {
      uint8_t *flash_ptr;
    
      flash_ptr = (uint8_t*) address; // Initialize pointer
    
      return *flash_ptr;              // Return byte
    }
    
    void flash_write_byte_array( uint16_t address, uint8_t *source_buffer, uint8_t source_buffer_start_byte, uint8_t byte_count )
    {
      uint8_t counter;
    
      for( counter = 0; counter < byte_count; counter++ )
      {
        flash_write_byte( (address + counter), source_buffer[(source_buffer_start_byte + counter)] );
      }
    }
    
    void flash_read_byte_array( uint16_t address, uint8_t *dest_buffer, uint8_t dest_buffer_start_byte, uint8_t byte_count )
    {
      uint8_t counter;
    
      for( counter = 0; counter < byte_count; counter++ )
      {
        dest_buffer[(dest_buffer_start_byte + counter)] = flash_read_byte( (address + counter) );
      }
    }

    Dennis

**Attention** This is a public forum