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.

CC13xx: FlashSectorErase (0)

Other Parts Discussed in Thread: SEGGER

I need to replace firmware in application, so I need to erase also first sector of flash. It seems that this sector is somehow blocked from erasing - when I do erasing in loop sector by sector, first sector remains unerased but other sectors are erased. FlashSectorErase returns always 0 so it should be successful.

VIMS cache mode is disabled. Sectors are not protected. Update functions are executed from RAM. I use Keil IDE and J-link.

Is there anything I should take care of to erase the first sector of flash?

  • Perhaps the drivers prevent you from erasing the first sector because that would delete the interrupt table, and that somehow breaks something?

    I tried disassembling the ROM function (which I believe is at address 0x100013f7), but there is too much going on there to easily tell if sector = 0 is a special case. This SectorErase ROM function calls 14 other ROM functions! Of course it doesn't help that flash functionality is completely undocumented in the reference manual.

    0x100013f7: push {r4, r5, r6, lr}
    0x100013f9: mov r4, r0
    0x100013fb: bl 0x100010ae
    0x100013ff: bl 0x100005a6
    0x10001403: mov r5, r0
    0x10001405: bl 0x1000059c
    0x10001409: subs r0, r5, r0
    0x1000140b: cmp r4, r0
    0x1000140d: bhi.n 0x10001418
    0x1000140f: bl 0x1000059c
    0x10001413: subs r0, r0, #1
    0x10001415: tst r0, r4
    0x10001417: beq.n 0x10001420
    0x10001419: bl 0x100012ce
    0x1000141d: movs r0, #3
    0x1000141f: pop {r4, r5, r6, pc}
    0x10001421: movs r0, #16
    0x10001423: bl 0x10000d64
    0x10001427: bl 0x1000059c
    0x1000142b: udiv r1, r4, r0
    0x1000142f: and.w r0, r1, #31
    0x10001433: movs r2, #1
    0x10001435: lsl.w r0, r2, r0
    0x10001439: ldr r2, [pc, #360] ; (0x100015a4)
    0x1000143b: movs r3, #5
    0x1000143d: str.w r3, [r2, #648] ; 0x288
    0x10001441: cmp r1, #32
    0x10001443: mvn.w r0, r0
    0x10001447: ite cc
    0x10001449: strcc.w r0, [r2, #704] ; 0x2c0
    0x1000144d: strcs.w r0, [r2, #708] ; 0x2c4
    0x10001451: movs r0, #2
    0x10001453: str.w r0, [r2, #648] ; 0x288
    0x10001457: add.w r0, r4, #528482304 ; 0x1f800000
    0x1000145b: str.w r0, [r2, #272] ; 0x110
    0x1000145f: movs r0, #6
    0x10001461: bl 0x10000d64
    0x10001465: bl 0x100005c4
    0x10001469: cmp r0, #1
    0x1000146b: beq.n 0x10001464
    0x1000146d: bl 0x100005b6
    0x10001471: mov r5, r0
    0x10001473: bl 0x100012ce
    0x10001477: bl 0x100005a6
    0x1000147b: mov r6, r0
    0x1000147d: bl 0x1000059c
    0x10001481: subs r0, r6, r0
    0x10001483: cmp r0, r4
    0x10001485: bne.n 0x1000149a
    0x10001487: movs r2, #20
    0x10001489: addw r1, r4, #4056 ; 0xfd8
    0x1000148d: ldr r0, [pc, #292] ; (0x100015b4)
    0x1000148f: bl 0x100012f8
    0x10001493: cbz r0, 0x1000149a
    0x10001495: cmp r5, #0
    0x10001497: it eq
    0x10001499: moveq r5, r0
    0x1000149b: mov r0, r5
    0x1000149d: pop {r4, r5, r6, pc}
  • Hi,

    this is strange since you claim that erasing other pages works. I've tried to reproduce your issue with the following code using the TI compiler:

        /* Disable flash cache */
        VIMSModeSet(VIMS_BASE, VIMS_MODE_DISABLED);
        while (VIMSModeGet(VIMS_BASE) != VIMS_MODE_DISABLED);
    
        /* Call erase function in ROM */
        uint32_t result = FlashSectorErase(0);
    
        /* Re-enable flash cache */
        VIMSModeSet(VIMS_BASE, VIMS_MODE_ENABLED);

    This works as expected and the first page is erased. You don't need to put the above code into RAM since FlashSectorErase() is a ROM function. Are you sure that the first page is not protected? Can you try to run your code with CCS? Maybe extract only the erase part and put it into a simple TI-RTOS example application. 

  • Thanks for both answers.
    ROM function check was one of things I did - it seems that it checks if address is not greater than flash size and if address is aligned to sector/block start (4KB).
    The block 0 is not protected, at least ROM_FlashProtectionGet returns also 0, which is FLASH_NO_PROTECT.
    My function must be in RAM because whole flash gets erased so after calling FlashSectorErase it could happen that calling code disappears :-)
    The question is if connected debugger (J-link) can somehow block erasure of just one sector...? I will try the same code in CCS as soon as possible...
  • Hi Hynek,
    I don't have this particular debugger, but in general I can't imagine that such a limitation exists. How do you check whether the first sector is erased? Could it be that the debugger shows wrong values? Cann you double-check in the application by reading from flash or did you do that already?
  • Flash is checked by user code because I can not rely on debugger memory viewer. Code reads always the first 32-bit word of block so I can se if it is 0xFFFFFFFF or something else.
    To eliminate debugger influence, I want to try running the code without debugger - but it will take some mor time to prepare UART debug output to see what happened...
  • After more study solved finally.
    Remarks:
    1. Unfortunately, disabling VIMS is not enough, there was still missing disabling flash line buffers (VIMS.CTL.IDCODE_LB_DIS and SYSBUS_LB_DIS bits). Without doing this, LDR instruction - even after executing ROM erase function - got still old flash data which was confusing.
    2. Moreover, Keil memory viewer behaves really strange: if there is code in flash, viewer always shows original code regardless of real flash data; in case of empty/unused flash, viewer shows changed data correctly. Because tested code is less than 4KB, first flash block shows always original data even for erase flash but other blocks show data programmed or erased correctly.
  • Hi Hynek,
    I'm glad that you solved it. I will forward your remark to the Driver developers, because disabling flash line buffers is currently not considered in the TI-RTOS NVS driver (work-in-progress) where I took the above code from.

    Regarding your debugger: I can only imagine that this is an optimization. As long as you don't touch the flash, the content does not change and extracting the content from the binary is way faster than reading it from flash. Could you maybe ask Segger whether this is the expected behaviour?

    Thank you
  • I use Keil IDE and this is oviously IDE "feature" ;-) because unused flash is viewed correctly. I remember similar problem on Keil IDE with STM32 and U-link debugger - so I was aware of believing to the memory viewer. But forgotten flash buffers confused me enough - I believed that LDR instructions should read real flash data...
  • I created small project to copy Flash pages from one area of flash to another. I used CCS and build code using only driverlib no RTOS for FlashProgram and FlashSectorErase. It takes so far about 2K of flash. How to pass control to code in RAM after I can copy it there ? Where to copy code, what address in RAM? What would happen to interrupt vectors ?
  • You have to look for example how to mark Your function to run in RAM: e.g. http://processors.wiki.ti.com/index.php/Placing_functions_in_RAM

    If You need to keep something running while writing to flash, vector table and all used functions have to be placed in RAM as well. You must be careful when using functions linked from libraries as they are placed to Flash automatically. The easiest (and often usable) solution is to disable interrupts and wait in RAM function for flash programming finished.

    Regarding RAM function placement: linker does all the job for You; usually You don't need to take care of RAM function placement.