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.

MSP430F5528: How do i declare a 20 bit pointer so i can access the upper memory locations

I'm writing a simple custom bootloader program that needs to write to all of flash.  I'm using a pointer to write to flash but I can't access anything past 0xFFFF b/c the ptr is declared with 16 bits.  How do i declare a 20 bit pointer so i can access the upper memory locations.

  • Accessing the address space above 64 k requires usage of the extended instruction set 430X. On CPUs with more than 64k address range, the registers are 20 bit and a bunch of instructions has been added to deal with 20 bit values. The original isntructions are still available, as they are usually faster and require less space.

    To use 20 bit pointers, you need to use an assembler or comile rthat supports the 430X instruction set . I fnot, you can still program these devices, but you are stuck on teh lower 64K.

    The 430X instructions use 20 bit address values (partially stored in an extra prefix word) and offer an additional data mode .A (in addition to .B and .W). '.A' moves a 20 bit value from a register to a 32 bit memory location and back. So to load a 20 bit pointer from a long int memory location into a register, the instruction would be MOVX.A &longpointer, R15

    If using a compiler capable of 430X, the compiler should automatically detect when a reference points into 'upper' memory and generate the proper instructions. Maybe it will always generate 20 bit instructions, which wastes memory, maybe only if needed. How to use a 'manual' pointer depends on the compiler. Maybe using a long int atomatically generates the proper code, maybe the pointe rneeds to be declares 'far' (as on the PC 16 bit systems), maybe it is done somehow else or not at all. You should find information about this in the compiler documentation.

    One important thing: when using indirect indexed mode (e.g. 2(R8) ), the resulting address will not cross the 0xffff boundary. If the register holds a value below 0x10000, then the result of this indexed addressing ins always 16 bit. If the register contains a 20 bit address, the result is 20 bit too. This wraparound is for compatibility reasons, since there is no flag that tells wheter the register has been loaded as 16 or 20 bit register by old 430 or new 430X instructions. So the old trick for the HMA segment on PCs, where you load 0xffff into a segment register and can access 64k above the normal 1MB area, won't work on MSPs.

     

  • To add to Jean's post, you can also accomplish this in C by initializing the pointer to an address that is above 0xFFFF. See the example below.

    void wrt_Bank1(void)
      unsigned int i;
      char * Flash_ptr = (char *)0x10000;       // Initialize Flash pointer

      FCTL3 = FWKEY;                            // Clear Lock bit
      FCTL1 = FWKEY+WRT;                        // Set WRT bit for write operation
      for(i = 0; i < 256; i++)
      {
        *Flash_ptr++ = value++;                   // Write a word to flash
      }
      FCTL1 = FWKEY;                            // Clear WRT bit
      FCTL3 = FWKEY+LOCK;                       // Set LOCK bit
    }

     

     

     

     

  • William Goh said:

    To add to Jean's post, you can also accomplish this in C by initializing the pointer to an address that is above 0xFFFF.

      char * Flash_ptr = (char *)0x10000;       // Initialize Flash pointer

    That is what I'm unsure of. He didn't mention the compiler he uses (if any). 0x10000 is a long int constant. char* might be just a short int pointer. It depends on how and if the compiler handles the extended address range.

    On MSPGCC, the constant had to be 0x10000L and with older versions of that compiler, it would be still be truncated to 0 when cast to (char*), while using a reference of data in upper flash (e.g. the string constant in sprintf) would put a 32 bit pointer on stack. On old 16 bit PC, it had to be (char far *) to get a 32 bit pointer (actually a 16/16 overlapping 20 bit pointer). So it depends on the compiler (which in case of the MSP will usually support the other plain 16 bit MCUs too) how this is handled. It might 'just' work, but this is not for certain.

  • Additional information in answer to this question.

    I’m using IAR as my compiler.  In the project ‘options’ there’s a category called general options.  You have to select a Data Model of ‘large’.  This will allow the compiler to declare a 20 bit pointer.

    There is also the ability to use the keyword __data20 when declaring a variable/pointer.

  • To write a flash MSP430f55xx, use the following command
    __data20_write_char (addr, data); for IAR compiler
    __write_extended_byte (addr, data); Crossworks

**Attention** This is a public forum