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.

CC2538: Mass erase sequence

Part Number: CC2538
Other Parts Discussed in Thread: SMARTRF06EBK, TMDSEMU200-U, FLASH-PROGRAMMER, UNIFLASH

Hello,

I am trying to issue a JTAG mass erase as described in document swru319c, sections 6.6.1 and 8.7.1 with no effect.

Configuration:
- Debugger hardware: Olimex ARM-USB-OCD-H
- Debugger software: OpenOCD

1) Command used to open a JTAG session with OpenOCD:
$> openocd -f interface/ftdi/olimex-arm-usb-ocd-h.cfg -f target/cc2538.cfg

2) I can successfully access various registers on the chip, showing that the setup is correct and the TAP chain is well configured.
For information :
$> scan_chain
   TapName             Enabled  IdCode     Expected   IrLen IrCap IrMask
-- ------------------- -------- ---------- ---------- ----- ----- ------
 0 cc2538.cpu             Y     0x00000000 0x8b96402f     4 0x01  0x0f
 1 cc2538.jrc             Y     0x8b96402f 0x*b96402f     6 0x01  0x3f

Note that the flash currently contains a simple LED blinking application that allows me to see quickly if flash has been erased or not.

3) I execute the following procedure to issue a mass erase, closely following swru319c:

proc icepick_mass_erase {jrc} {
    # Connect to the ICEPick (0x07 IR followed by 0x89 DR)
    irscan $jrc 0x07 -endstate IRPAUSE
    drscan $jrc 8 0x89 -endstate DRPAUSE
    
    # Scan private connect (0x1F IR followed by 0x01 DR)
    irscan $jrc 0x1F -endstate IRPAUSE
    drscan $jrc 1 0x01 -endstate DRPAUSE
    
    # Issue mass erase command (0x0D IR followed by 0x0E IR)
    irscan $jrc 0x0D -endstate IRPAUSE
    irscan $jrc 0x0E -endstate IRPAUSE

    # Monitor the status register (0x0E IR data register)
    set drvalue 0
    while {($drvalue & 0x7F) != 0x5F} {
        set drvalue 0x[drscan $jrc 32 0x00000000 -endstate DRPAUSE]
        echo "DR value = $drvalue"
        irscan $jrc 0x0E -endstate IRPAUSE
    }

    # Clear the debug unlock command (0x3E IR)
    irscan $jrc 0x3E -endstate RUN/IDLE

    # Finally reset the board to access unlocked DAP.
    echo "Resetting ..."
    reset
}

When executing this function ($> icepick_mass_erase cc2538.jrc), it falls in an infinite loop having the status register always equal to 0. I never see bit 6 of data register for 0x0E IR set. This probably mean that the mass erase is not triggered at all.

I have elaborated this function using the following sources:
    - swru319c, section 6.6.1
    - swru319c, section 8.7.1
    - e2e.ti.com/.../828403
    - e2e.ti.com/.../664704

My questions:
    - What part of the mass erase process through JTAG am I missing ?
    - Are there more detailed documents about mass erase (and ICEPick registers in general) available to help ?
    - How long does it take approximatively to perform the mass erase ? May I use a delay instead of the status monitoring step ?

Thanks,
Nicolas Mardegan

  • Hello Nicolas,

    Are you using a custom PCB or TI EVM for the hardware setup?  Have you been able to program/mass erase the CC2538 device using a SMARTRF06EBK, XDS100, or TMDSEMU200-U with UNIFLASH, FLASH-PROGRAMMER, or the IAR EWARM IDE?  Are you using the correct OpenOCD version?

    Regards,
    Ryan

  • Hello Ryan,

    I am using a custom PCB, the wiring is as follow:

    The only debugger I have is the ARM-USB-OCD-H, driven by the latest "official" openOCD version 0.10.0.

    Using the configuration files shipped with openOCD, I am able to:

    • Read CPU registers
    • Read RAM addresses
    • Read / erase the CCA page

    This official version already includes basic support for IcePick router and also cJtag => Jtag switch sequence.

    For programming / erasing, I am currently using the ROM bootloader (+ python script) and it is working fine => I have never programmed / mass-erase the chip using a JTAG programmer. However I use the programmer to erase the CCA page and thus invalidate the program to reach the bootloader again when necessary.

    Actually, I want to use the OpenOCD version you pointed out to do flash programming via JTAG but before playing too much with the CCA page, I wanted to ensure that I am able to recover from a lock of the debug interface. Jim's openOCD fork proposes a RAM loader that calls behind the scene the ROM API to do flash / erase. There is no, to what I have read, any native mass erase support through IcePick.

    Therefore, my goal is to be able to issue the mass-erase sequence to the IcePick router (via OpenOCD) to later be confident that I can recover in case of bad CCA flash page manipulation.

    Regards,

    Nicolas

  • Hello Nicolas,

    I have never used the Olimex ARM-USB-OCD-H or OpenOCD tools before but the ability read device information seems to imply that the hardware connection is valid, have you tried contacting the OpenOCD community for further assistance?

    Regards,
    Ryan

  • Hello Ryan,

    I understand your point and am not asking TI to help me on OpenOCD usage. I would like to know if there are additional documents about the CC2538 mass erase sequence and how it is accessible with IcePick TAP commands ?

    For now, I can only rely on:

    • CC2538 User's Guide (swru319c)
    • IcePick Reference Guide (spruh35)

    The first one briefly describes the sequence relying on undocumented TAP instructions : the 0x1F 'Scan Private Connect', 0x0D ?, 0x0E ?, 0x3E ?.

    The second focuses on IcePick router commands and not on the CC2538 specific mass-erase feature.

    I feel that the mass-erase sequence described in CC2538 User's Guide is mostly right but incomplete in its description: this prevent me from using it.

    I gave the OpenOCD script as a support to discuss the logic of the sequence. Open underlying questions are:

    • Is there an initial state to ensure prior to executing the sequence ? Should the CM3 be connected or disconnected from the scan chain ?
    • What are the data register lengths associated with the undocumented instructions 0x1F, 0x0D, 0x0E, 0x3E ?
    • Is it possible to shift DR multiple times without re-asserting 0x0E IR during the status monitoring step ?
    • Are the JTAG intermediate states used (IRPAUSE / DRPAUSE) those expected by the IcePick ? Maybe I should go to IDLE state in-between ?
    • How long does it take to see bit 6 set ? Immediate or need several TCK cycles ? How much ?
    • How long does it take to complete the mass erase ? milliseconds ? seconds ?

    There may be some TI's document I have missed that relate all those things.

    Regards,

    Nicolas

  • Hi,

    Please refer to CC26x0 User Guide SWCU117 for more information about JTAG interface.

    Even though it is for CC26x0, it still valid for CC2538.

    Thanks,

    PM

  • Hello,

    I spent some time experimenting with the IcePick-C commands and found that I had to get rid of '-endstate IRPAUSE / DRPAUSE' in order to let the controller execute the commands and also refresh the data register in case of reads.

    Furthermore, polling to much may also prevent the controller to execute its tasks, so I added a small delay.

    That being fixed, I am able to read the mass erase status and after less than one second it always return 0x0000001F. This is not the value I was expected as the end of the mass erase process since the doc indicates: "Look for bits [0:4] & [6] being high and bit [5] being low" which leads to 0x0000005F.

    Nonetheless, the flash is correctly erase and so I cannot explain the final status mismatch.

    I attach the updated script for reference :

    proc icepick_c_mass_erase {jrc} {
        # Variables
        set status 0

        # Connect to the ICEPick (0x07 IR followed by 0x89 DR)
        irscan $jrc 0x07
        drscan $jrc 8 0x89

        # Scan private connect (0x1F IR followed by 0x01 DR)
        irscan $jrc 0x1F
        drscan $jrc 1 0x01

        # Issue mass erase command (0x0D IR followed by 0x0E IR)
        irscan $jrc 0x0D

        # Monitor the status register (0x0E IR data register)
        while {($status & 0x3F) != 0x1F} {
            irscan $jrc 0x0E
            set status 0x[drscan $jrc 32 0x00000000]
            sleep 10
        }

        # Clear the debug unlock command (0x3E IR)
        irscan $jrc 0x3E

        # Apply external reset.
    }

    Any idea concerning the status mismatch is welcome.

    Regards,

    Nicolas

  • Hi Nicolas,

    We're redirecting this internally to get it to the right people (it's currently assigned to HW but moving to SW). Be patient and we'll be able to give you a good answer.

    Best,

    Nate

  • Hello Nicolas,

    I apologize for the delay in response.  We are still working towards finding a TI expert to assist your needs.  Has the status changed any since your last post?  Have you found any issues with the mass erase procedure you currently have, and can you read the device memory to verify that the mass erase performs the expected operation?

    Regards,
    Ryan