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.

Help with compiler pointer format

Guru 15580 points


CCSv5.3

C5515 DSP

I am trying to program a 512 kbyte nor flash device via the EMIF on a C5515. I can successfully program the first 32768 bytes, but cannot program beyond that point. I am using some sample code from TI that has the format below:

// Write data to device
((volatile unsigned short*)NorFlashBaseAddr)[offset] = data;

I am not familiar with this pointer format. Can someone explain what it does (or direct me to a user guide)? It appears as though "offset" is limited to 16 bits.

  • I assume NorFlashBaseAddr is a literal constant. That line is just accessing an array of shorts whose base address is at NorFlashBaseAddr.

    No expert on the C5000 series. Purely book knowledge on my part. On the C5000, int is signed 16-bits. Assuming offset is int, NorFlashBaseAddr should cover +-32Kwords or +-64KB from the base address. The architecture itself limits indexed addressing to signed 16-bit offsets. You could try to use an auto-increment pointer instead of array + incrementing index. Pointers are limited to 16 bits in small memory mode and 23 bits in large memory mode. You are probably already in large mode to the access EMIF memory range. The huge memory model implies objects larger than 64KB are possible but with consequences.

  • Norman,

    Thank you for your thoughts.

    I should have included more of the code. Here 'tis:

    int flashWrite(unsigned short data, unsigned long offset)
    {
    unsigned long status;
    Uint32 addr;
    int i;

    // flash "Reset" command
    ((volatile unsigned short*)NorFlashBaseAddr)[0] = FLASH_RESET_CMD1;
    for(i=0; i< 5; i++);
    ((volatile unsigned short*)NorFlashBaseAddr)[0x555] = FLASH_PROGRAM_CMD1;
    ((volatile unsigned short*)NorFlashBaseAddr)[0x2AA] = FLASH_PROGRAM_CMD2;
    ((volatile unsigned short*)NorFlashBaseAddr)[0x555] = FLASH_PROGRAM_CMD3;

    // Write data to device
    ((volatile unsigned short*)NorFlashBaseAddr)[offset] = data;

    // Wait for programming to finish
    status = flashToggle();
    if (status != FLASH_STATUS_OK)
    {
    return (FLASH_STATUS_ERROR);
    }

    return (FLASH_STATUS_OK);
    }

    So, as you can see, "offset" is an unsigned long, which should allow it to address beyond my current 32k limit. And, yes the calling function also uses a 32bit address:

    UInt16 nor_flash_write_n_words(UInt32 address, UInt16 *buffer, UInt16 count)
    {
    int i;

    for (i=0; i<count; i++)
    {
    flashWrite(*buffer++, address++);
    }
    return (0);
    }

    I suspect you are correct about the architecture limiting indexing to 16 bits, but I'm not quite sure how to implement the "auto-incrementing pointer" you mentioned.

    And, yes I am using a Large memory model.

    Thanks again for your thoughts.

  • I am guessing that you will have to do your own pointer arithmetic. The function flashWrite(() conveniently already has an addr variable. Replace

      ((volatile unsigned short*)NorFlashBaseAddr)[offset] = data;

    with

     addr  = NorFlashBaseAddr;
     addr += offset;
     ((volatile unsigned short*)addr) = data;

    I've assumed everything is using word addressing. If you are using byte addressing, you might have to multiply offset by 2 before adding.

  • Norman,

    Thanks again for the assistance.

    However, I had actually already tried what you suggested but get the following compile error:

    #138 expression must be a modifiable lvalue

       ((volatile unsigned short*)addr) = data;

    This may have something to do with the way the original NorFlashBaseAddr was defined:

    #define NOR_FLASH_BASE_ADDRESS_CS2 0x400000

    /* NOR-Flash Base-Address */
    const Uint32 NorFlashBaseAddrTable[4] = { NOR_FLASH_BASE_ADDRESS_CS2, NOR_FLASH_BASE_ADDRESS_CS3,
    NOR_FLASH_BASE_ADDRESS_CS4, NOR_FLASH_BASE_ADDRESS_CS5 };
    Uint32 NorFlashBaseAddr = NOR_FLASH_BASE_ADDRESS_CS2;

  • Oops. My error. Once I removed the array "[]", I have to add a pointer "*".

    (*(volatile unsigned short*)addr) = data;

  • Norman,

    Yes, that did allow me to compile. Unfortunately the 32k limit still happens. Perhaps it has something to do with the following:

  • That bit of doc would suggest that pointer access should work in large memory model. As long as all code is large memory model. Is your NOR flash sectored? How big are the sectors? My memory is a bit fuzzy on this. I vaguely remember some flash commands have to written to an address in the particular sector.

  • I'm going to have to go do some homework on the flash sector issue. This appears to be the problem. I'll let you know what I find. Thanks again!

  • Norman,

    As it turns out, my flashwrite function was actually working properly, across sector boundaries. It was my flashread function that is not working at the sector boundary (I am using flashread to compare the written code to the read code for error checking). I've not yet debugged this read issue, but at least the flashwrite mystery has been solved.

    Thanks again,