Jump to content
43oh

Bricked CC430F6137 (Chronos watch)


Recommended Posts

I've been working on a Chronos altimeter app. But after some code changes suddenly my Chronos is not recognized by the FET. I got another, same story - programmed my code and it is bricked. I did not change the BSL address (so it should not be locked). The hex file of the code that kills the cc430f6137: http://dmitry.gr/ChronosAlt.hex

 

Here is the session whewre I flash it and the part dies. It should not be a complier issue, since no opcode shoudl disable debugging, but in case it matters: mspgcc to compile&link, mspdebug to program the code.

 

I verified that the FET is functional byt trying it with another chronos as well as this one before it bricked. I verified the chronos is bricked b y trying it with other FETs. Ideas?



mspdebug rf2500 "prog ChronosAlt.hex"
MSPDebug version 0.21 - debugging tool for MSP430 MCUs
Copyright (C) 2009-2012 Daniel Beer <dlbeer@gmail.com>
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
Trying to open interface 1 on 020
rf2500: warning: can't detach kernel driver: No data available
Initializing FET...
FET protocol version is 30001000
Set Vcc: 3000 mV
Configured for Spy-Bi-Wire
Device ID: 0x6137
  Code start address: 0x8000
  Code size         : 32768 byte = 32 kb
  RAM  start address: 0x1c00
  RAM  end   address: 0x2bff
  RAM  size         : 4096 byte = 4 kb
Device: CC430F6137
Number of breakpoints: 3
fet: FET returned NAK
warning: device does not support power profiling
Chip ID data: 61 37 12
Erasing...
Programming...
Writing 4096 bytes at c800...
Writing 2576 bytes at d800...
Writing   48 bytes at ffd0...
Done, 6720 bytes total
dmitrygr@vwm64:/mnt/hgfs/D/msp430/Chronos-Altimeter$ mspdebug
You need to specify a driver. Try --help for a list.
dmitrygr@vwm64:/mnt/hgfs/D/msp430/Chronos-Altimeter$ mspdebug rf2500
MSPDebug version 0.21 - debugging tool for MSP430 MCUs
Copyright (C) 2009-2012 Daniel Beer <dlbeer@gmail.com>
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
Trying to open interface 1 on 020
rf2500: warning: can't detach kernel driver: No data available
Initializing FET...
FET protocol version is 30001000
Set Vcc: 3000 mV
Configured for Spy-Bi-Wire
fet: FET returned error code 11 (Could not reset device)
fet: command C_IDENT1 failed
fet: identify failed
Trying again...
Initializing FET...
FET protocol version is 30001000
Set Vcc: 3000 mV
Configured for Spy-Bi-Wire
Sending reset...
fet: FET returned error code 11 (Could not reset device)
warning: fet: reset failed
fet: FET returned error code 11 (Could not reset device)
fet: command C_IDENT1 failed
fet: identify failed
dmitrygr@vwm64:/mnt/hgfs/D/msp430/Chronos-Altimeter$
Link to post
Share on other sites

The BSL area doesn't really matter unless you are doing serial programming of the device.  SBW doesn't use it, as far as I know.

 

What has happened to me once or twice is that, erroneously, the JTAG fuse gets blown.  That seems like it is what is happening here, although I use CCS, so the error codes and descriptions are different.

 

If you search the TI e2e communities for "JTAG fuse blown" I do recall there is someone who was able to fix it.  The fix might not work on the Chronos though, because in order to do the fix you do need to access the BSL serial line, and that might not be easily available on the Chronos.

Link to post
Share on other sites

I have the watch open and can access any lines, but how can the fuse at 0x17fC get blown when it was never touched by the programmer (as per programmer output)

 

i did think of this and googled around. everyone seems to say that once the fuse is blown the chip is ROM and i am SOL.  but two chips..identically... :-(

Link to post
Share on other sites

I have the watch open and can access any lines, but how can the fuse at 0x17fC get blown when it was never touched by the programmer (as per programmer output)

 

i did think of this and googled around. everyone seems to say that once the fuse is blown the chip is ROM and i am SOL.  but two chips..identically... :-(

I can't tell you how exactly it can happen, but I can tell you that it has happened.  My only guess is that the FET implementation has some bugs, and certain sequences of binary must cause mis-timings that result in the fuse being blown.

Link to post
Share on other sites

I can't tell you how exactly it can happen, but I can tell you that it has happened.  My only guess is that the FET implementation has some bugs, and certain sequences of binary must cause mis-timings that result in the fuse being blown.

 

How could that be?  The eZ430-RF USB debugging interface lacks the JTAG security fuse blow capability (quoting from slau227e).

 

In prior cases (with the FRAM devices) this would happen when the soft-fuse in an "unused" part of the vector table was overwritten (and in those cases mspdebug would emit a diagnostic stating that the fuse was blown, which has not happened here).  BSL could often (but not always) be used to reset the soft-fuse, but I don't believe non-FRAM devices have that.

 

There's probably something else going on.  mspdebug is often supported through the mspgcc-users mailing list, or contact the author directly.

Link to post
Share on other sites

Programming it into an MSP430G2553 has no catastrophic effect; mspdebug can still access the chip, and disassemble what was downloaded.

 

It is odd, though, since that hex file can't be for any MSP430 device although it does seem to have MSP430 object code in it.  No devices have an interrupt table that starts at 0xffd0 and runs for 48 bytes, and none have flash starting at 0xc800.  Vectors of the CC430F6137 start at 0xFF80, and flash at 0x8000.

Link to post
Share on other sites

flash in my chip starts at 0x8000, but i wanted the code to start at 0xc800, so that i can use all preceding flash for storage (later)

vectors "start" at 0xff80, but no vectors are defined in the cc430f6137 until 0xffd0,  so i saw no use to writing previous values. neither of those should produce issues AFAIK (it wouldnt on avr,pic,arm)

is msp different?

Link to post
Share on other sites

sidenote:  if you enter mspdebug and try to read the BSL, do you see any code?

In each of these devices, as they were shipped to me from TI, when i did "md 0x1000 2048" i just saw a bunch of "0x3FFF" instead of code. is this intended? the msp doc says that reading memory that does not exist produces this value (whereas erased flash would be 0xFFFF). 

Link to post
Share on other sites

I believe the BSL memory is only accessible when the BSL entry sequence has been performed; otherwise it's in an unmapped block of memory.   See http://www.ti.com/lit/ug/slau319e/slau319e.pdf.

This is interesting and would explain a lot, but I do not see that in the linked doc. am i missing something?

If i wanted to flash the proper BSL onto a device how would I do it using the FET?

 

 

edit: found it in the chip doc slau259e, page 72

Link to post
Share on other sites

The plot thickens....

I got the chip on the chronos replaced with a new one from TI. the device is now programmable. i rolled back the last change i made to my codebase and flashed with my fingers crossed. device did not die. re-applied the change. device died....

 

here is the code of my hwrInit() function, with the deadly part marked off....why does it kill chips?

#include <cc430x613x.h>
#include <signal.h>
#include "hwr.h"



static void __delay_cycles(unsigned short n)
{
    __asm__ __volatile__ (
        "1: \n"
        " dec    %[n] \n"
        " jne    1b \n"
        : [n] "+r"(n));
}

void SetVCoreUp (unsigned char level);

void hwrInit(void)
{
    //WDT off
    {
        WDTCTL = WDTPW + WDTHOLD;
    }
    
    /*    --enabling this kills chips 100% why????
    SetVCore(3);
    
    // Set global high power request enable
    PMMCTL0_H  = 0xA5;
    PMMCTL0_L |= PMMHPMRE;
    PMMCTL0_H  = 0x00;    
    */
    
    //enable 32KHz crystal (X1)
    {
        P5SEL |= 0x03;                            // Select XIN, XOUT on P5.0 and P5.1
        UCSCTL6 &= ~XT1OFF;                  // XT1 On, Highest drive strength
        UCSCTL6 |= XCAP_3;                        // Internal load cap
    }
    
    //set X1 system clock source and provide it as all clocks
    {
        UCSCTL4 = SELA0 | SELM0 | SELS0;
        UCSCTL5 = DIVA0 | DIVM0 | DIVS0;
    }

    //set PLLed 8MHz clock for MCLK (CPU)
    {
        _BIS_SR(SCG0);        //disable FLL control loop
        UCSCTL0 = 0;        //as per doc
        UCSCTL1 = 0x60;        //dismod = 0 is ok? 6 is as per doc
        UCSCTL2 = 0x203D;    //DCOCLK = 7.995392 MHz, DCOCLKDIV = 1.998848 MHz
        UCSCTL3 = 0;        //FLL uses XT1 as source, source is not divided before being used
        UCSCTL5 = 0;        //al clocks have no post-dividers
        UCSCTL6 = 0x010E;    //XT1 on, caps highest val, lowest drive, SMCLK off
        _BIC_SR(SCG0);        //re-enable the FLL control loop
        
        __delay_cycles(2500);
        
        do
        {
            UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
            SFRIFG1 &= ~OFIFG;                      // Clear fault flags
        } while ((SFRIFG1 & OFIFG));
        
        //after lock:
        UCSCTL4 = 0x0033;    //ACLK is 32.768KHz; MCLK is 7.995392MHz; SMCLK is off but configured for 7.995392MHz
    }
    
    //set lowest core voltage
    {
        while(PMMCTL0 & 3) {
            PMMCTL0 = ((PMMCTL0 & 0xFF) - 1) |  PMMPW;
            PMMIFG &= ~(SVMLVLRIFG + SVMLIFG);          // Clear already set flags
            if ((PMMIFG & SVMLIFG))
                while (!(PMMIFG & SVMLVLRIFG));     // Wait till level is reached
        }
    }
    
    //set pin mapping
    {
        volatile unsigned char *ptr;
        
        // Get write-access to port mapping registers:
        PMAPPWD = 0x02D52;
        // Allow reconfiguration during runtime:
        PMAPCTL = PMAPRECFG;
    
        // P2.7 = TA0CCR1A or TA1CCR0A output (buzzer output)
        ptr  = &P2MAP0;
        *(ptr+7) = PM_TA1CCR0A;
        P2OUT &= ~BIT7;
        P2DIR |= BIT7;
    
        // P1.5 = SPI MISO input
        ptr  = &P1MAP0;
        *(ptr+5) = PM_UCA0SOMI;
        // P1.6 = SPI MOSI output
        *(ptr+6) = PM_UCA0SIMO;
        // P1.7 = SPI CLK output
        *(ptr+7) = PM_UCA0CLK;
    
        // Disable write-access to port mapping registers:
        PMAPPWD = 0;
    }
    
    //setup timer 0 for timing. we run in based off ACLK
    {
        TA0CCR0 = 0xFFFF;        //top is top
        TA0EX0 = 0;            //divide by 1
        TA0CTL = 0x0114;        //timer counts up and is reset
    }
    
    //config the port for external interrupts and buttons
    {
        P2SEL &=~ 0x7F;            //pins are I/O
        P2DIR &=~ 0x7F;            //pins are input
        P2REN |= 0x7F;            //pullup/down is on
        P2OUT &=~ 0x7F;            //pulldown on
        P2DS &=~ 0x7F;            //low drive strength
        P2IFG = 0;            //clear ints
        P2IES = 0x7F;            //trigger on edges up
        P2IE = 0x7F;            //ints on
    }
}

void SetVCoreUp (unsigned char level)        // Note: change level by one step only
{
  PMMCTL0_H = 0xA5;                         // Open PMM module registers for write access
 
  SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level;     // Set SVS/M high side to new level

  SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level;     // Set SVM new Level    
  while ((PMMIFG & SVSMLDLYIFG) == 0);      // Wait till SVM is settled (Delay)
  PMMCTL0_L = PMMCOREV0 * level;            // Set VCore to x
  PMMIFG &= ~(SVMLVLRIFG + SVMLIFG);        // Clear already set flags
  if ((PMMIFG & SVMLIFG))
    while ((PMMIFG & SVMLVLRIFG) == 0);     // Wait till level is reached
 
  SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level;     // Set SVS/M Low side to new level
  PMMCTL0_H = 0x00;                         // Lock PMM module registers for write access
}



//****************************************************************************//
// Set VCore down
//****************************************************************************//
void SetVCoreDown (unsigned char level)
{
  PMMCTL0_H = 0xA5;                         // Open PMM module registers for write access
  SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level;     // Set SVS/M Low side to new level
  while ((PMMIFG & SVSMLDLYIFG) == 0);      // Wait till SVM is settled (Delay)
  PMMCTL0_L = (level * PMMCOREV0);          // Set VCore to 1.85 V for Max Speed.
  PMMCTL0_H = 0x00;                         // Lock PMM module registers for write access
}

void SetVCore (unsigned char level)        // Note: change level by one step only
{
  unsigned char actLevel;
  do {
    actLevel = PMMCTL0_L & PMMCOREV_3;
    if (actLevel < level)
      SetVCoreUp(++actLevel);               // Set VCore (step by step)
    if (actLevel > level)
      SetVCoreDown(--actLevel);             // Set VCore (step by step)
  }while (actLevel != level);
}

i copied that code fromTI's sample code since without it the radio kept giving me the voltage too low error....

nonetheless, why does such simple code permanently kill a device?

Link to post
Share on other sites

Could be that it programs the PMM to supply too high an internal voltage.  That you're using your own __delay_cycles() instead of the intrinsic suggests you might be using an outdated version of mspgcc; those had bugs related to shift operations that might have written invalid configuration values to the PMM registers.

 

BTW: It is highly recommended that you use the defined constants from the MCU header to configure peripheral registers rather than assigning hex literals like UCSCTL2 = 0x203D.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...