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.

Need MSP-FET430UIF power down to also disconnect reset pin.

Other Parts Discussed in Thread: MSP430G2553, MSP-FLASHER

We're using MSP-FET430UIF on our manufacturing line to program a MSP430G2553.  We're using MSP430Flasher.exe to do the programming. 

Programming works fine.

However, after programming we need to power off the target device.  

We've tried using the various combinations of the MSP430Flasher.exe -z exit specification command line options to attempt this.  These options correctly set the output voltage on pin 2 of the target connector of the MSP-FET430UIF.  However, the reset pin (pin 1 of the target connector) continues to be driven high, preventing our target device from fully powering down.

When the MSP-FET430UIF powers down the target, we need it to also drive pin 1 drive low, or go hi-Z.

Is there a way to accomplish this?

Thanks!

  • The brute force method would be to have a small board between the FET and the target with tri-state buffer on the reset line. Controlled by state of power on pin 2.
  • Hi Brian,

    Thanks for the reply.

    Alas, we're trying to avoid the need to rework the test stations.

    Looking at the schematic for the MSP-FET430UIF (p. 178 of MSP430 Hardware Tools User's Guide SLAU278Y), the driver in question has an output enable that can be controlled by the firmware.

    A firmware update to disable that output on power-down would be a very desirable solution.

    Thanks again!

    Bruce
  • Or an external controlled relay board between FET and target board.
  • Or to not use MSP-FET430UIF & MSP-Flasher for this at all.

    Bruce Olney said:

    However, after programming we need to power off the target device.  

    Why?

  • TI doesn't provide the source code for the FET.
  • There is other other circuitry on the device that needs to be completely powered down to change modes.  The partial power coming from the MSP-FET430UIF prevents this.

  • Looks like there was a function in v2 MSP430.DLL that was called MSP430_FET_SetSignals() but was removed from the v3 version. This may have been able to do what you want, assuming you modified and compiled a custom version of MSPFlasher.
  • That might work. I'll give it a try.

    I just downloaded 'MSP430.DLL_Developer_Package_Rev_2.04.09.001.zip.'

    Do you know the acceptable values for the MSP430_FET_SetSignals() parameters SigMask and SigState? I suppose I can do some experimentation/trial&error. But, it would be better to find some documentation.
  • Brian Boorman said:
    TI doesn't provide the source code for the FET.

    Bruce Olney said:
    Do you know the acceptable values for the MSP430_FET_SetSignals() parameters SigMask and SigState? I suppose I can do some experimentation/trial&error. But, it would be better to find some documentation.

    FET, UIF and ezFET-Lite firmware is open source and it can be found inside MSPDS-OPEN-SOURCE ...

    http://www.ti.com/tool/mspds

  • I spent some time trying this approach. Alas, I had trouble downgrading the firmware in the MSP-FET430UIF to v2. Eventually I bricked it. To recover I'll have to reprogram using JTAG. Can't do it using USB methods.

    Zrno Soli provided a link to FET firmware. I'll try that approach instead. I'll have questsions. Stay tuned.
  • First question.

    The IAR project post-build step (.\Bios\tools\convertEzFetTxt.bat) invokes the tools sed.exe and srec_cat.exe.

    These tools were not included. Anyone know where to get the correct versions of these tools? Which versions I should use?
  • FWIW, I would still maintain you'd be better off pursuing putting a small board in-line with the ribbon cable that has a tri-state buffer on the RESET signal. I think the software method is a big rabbit hole.
  • Thanks Brian, Those links helped me find the needed tools. I'm now able to build the firmware.
  • Here is updated status, in case anyone is following this.

    Thanks to help from Zrno and Brian, I was able to track down source code to the MSP-FET430UIF firmware and modify it to also drive the RESET pin (pin 1 of target connector) low when powering down the target.  This resolves our problem.

    I've attached the file I modified (./Bios/src/hil/uifv1/hilGeneric.c) in case anyone wants to duplicate the same.

    Here is the patch:

    Tue-09:02$g diff -v d4d49268cec0c0e143b5552b6c51c954d9e01002 Bios/src/hil/uifv1/hilGeneric.c
    diff --git a/Bios/src/hil/uifv1/hilGeneric.c b/Bios/src/hil/uifv1/hilGeneric.c
    index 53da939..d1301de 100644
    --- a/Bios/src/hil/uifv1/hilGeneric.c
    +++ b/Bios/src/hil/uifv1/hilGeneric.c
    @@ -246,6 +246,12 @@ short _hilGeneric_SetVcc(unsigned short Vcc)
             IHIL_Close();
             bVccOn = 0;
             bPowerUp = 1;
    +
    +        //   Drive RESET low.
    +        //
    +        P2OUT &= ~BIT5;                 //   Assert SELT.
    +        P5OUT &= ~(BIT0 | BIT1 | BIT3); //   Drive TCK, TMS and TDI low.
    +        P4OUT &= ~BIT2;                 //   Assert ENI20#.
         }
         return 0;
     }
    

    hilGeneric.c
    /*
     * \ingroup MODULHIL
     *
     * \file hilGeneric.c
     *
     * \brief Hardware Independent Layer Interface
     *
     *
     * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
     *
     *  Redistribution and use in source and binary forms, with or without
     *  modification, are permitted provided that the following conditions
     *  are met:
     *
     *    Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     *    Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the
     *    distribution.
     *
     *    Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    #include "arch.h"
    #include "hw_compiler_specific.h"
    #include "edt.h"
    #include "hilDelays.h"
    #include "HalGlobalVars.h"
    #include "stream.h"
    
    volatile unsigned char VFSettleFlag = 0;
    unsigned short bVccOn;
    extern unsigned char *tstctrl_port_;
    
    const unsigned short ADC_MV[4] = { 5905, 5905, 6934, 5905 };  // input voltages included the scale by resitors
    const unsigned short ADC_CONV_RANGE = 4096;                   // 1 Bit error, because div is with 4096 faster
    const unsigned short ADC_AVERAGES = 4;
    const unsigned short DAC_CONV_RANGE = 4095;
    
    unsigned short _hilGeneric_ConvertAD(unsigned short channel)
    {
        unsigned long tmp;
        unsigned short ret_mv = 0;
    
        if(channel < 4 )
        {
            tmp = *((unsigned short*)&ADC12MEM0+channel) +
            *((unsigned short*)&ADC12MEM4+channel) +
            *((unsigned short*)&ADC12MEM8+channel) +
            *((unsigned short*)&ADC12MEM12+channel);
            tmp *= ADC_MV[channel];
            tmp /= ADC_CONV_RANGE * ADC_AVERAGES;
            ret_mv = tmp;
        }
        return(ret_mv);
    }
    
    /*----------------------------------------------------------------------------
       This function performs a single AD conversion on the selected pin.
       Uses internal reference 2.5V (VR+ = VREF+, VR- = AVSS).
       Only used for SetTargetVcc() and Selftest().
       Arguments: word pinmask (bit position of selected analog input Ax)
       Result:    word (12 bit ADC conversion result)
    */
    short  _hilGeneric_ConvertAD_(short channel)
    {
    // select channel and do conversion
      ADC12CTL0  &= ~ENC;                   // Disable conversion, write controls
      ADC12MCTL0  = 0x10 + channel;         // select Vref and analog channel Ax
      ADC12CTL0  |= ENC;                    // Enable conversions
      ADC12CTL0  |= ADC12SC;                // Start conversions
      while ((ADC12IFG & BIT0) == 0);       // wait until conversion is done
      return(ADC12MEM0);                    // return conversion result from MEM0
    }
    
    unsigned short last_vcc;
    
    #pragma optimize = none
    void  _hilGeneric_SetDac(unsigned short vcc)
    {
        signed short nomDac;
        signed short corr;
    
        if(last_vcc != vcc)
        {
            nomDac = (unsigned short)(ConvRange - (vcc - minVCCT));      // calculate approximated value
            nomDac += (85 - (vcc/20));                 // error reduction of approximated value
            if(nomDac > ConvRange)
            {
                nomDac = ConvRange;
            }
            if(nomDac < 0)
            {
                nomDac = 0;
            }
            DAC12_0DAT = nomDac;                  // set voltage
            DAC12_0CTL |= DAC12ENC;               // enable DAC12
            last_vcc = vcc;
        }
        else
        {
            corr =  _hilGeneric_ConvertAD(VCCTCHN);
            if(corr > (vcc+10))
            {
                if(DAC12_0DAT < 4095)
                {
                    DAC12_0DAT++;
                }
            }
            else if(corr < (vcc-10))
            {
                if(DAC12_0DAT)
                {
                    DAC12_0DAT--;
                }
            }
        }
    }
    
    // -----------------------------------------------------------------------------
    void _hilGeneric_Init( void )
    {
        // Setup ADC12
           // Setup ADC12
        ADC12CTL0  &= ~ENC;					  // Disable conversions, write controls
        ADC12CTL0  = ADC12ON | REFON | REF2_5V | MSC | SHT0_2 | SHT1_2;  // Turn on ADC12, VREF = 2.5v, set samp. time
        ADC12CTL1  = SHP | CONSEQ_3;					  // Use sampling timer, CstartAddr = MEM0
        // four time averaging on each channel
        ADC12MCTL0  = 0x10 | 0;           // select Vref and cannel
        ADC12MCTL1  = 0x10 | 1;           // select Vref and cannel
        ADC12MCTL2  = 0x10 | 2;           // select Vref and cannel
        ADC12MCTL3  = 0x10 | 3;           // select Vref and cannel
        ADC12MCTL4  = 0x10 | 0;           // select Vref and cannel
        ADC12MCTL5  = 0x10 | 1;           // select Vref and cannel
        ADC12MCTL6  = 0x10 | 2;           // select Vref and cannel
        ADC12MCTL7  = 0x10 | 3;           // select Vref and cannel
        ADC12MCTL8  = 0x10 | 0;           // select Vref and cannel
        ADC12MCTL9  = 0x10 | 1;           // select Vref and cannel
        ADC12MCTL10 = 0x10 | 2;           // select Vref and cannel
        ADC12MCTL11 = 0x10 | 3;           // select Vref and cannel
        ADC12MCTL12 = 0x10 | 0;           // select Vref and cannel
        ADC12MCTL13 = 0x10 | 1;           // select Vref and cannel
        ADC12MCTL14 = 0x10 | 2;           // select Vref and cannel
        ADC12MCTL15 = 0x10 | 3;           // select Vref and cannel
    
        ADC12CTL0  |= ENC;                    // Enable conversions
        // ADCs run free
        ADC12CTL0  |= ADC12SC;                // Start conversions
    
        DAC12_0DAT = VCCTmin;                           // set voltage to MIN ~0
        DAC12_0CTL = DAC12CALON + DAC12IR + DAC12AMP_5; // Internal ref gain 1
    
        // Init SPI for JTAG
        UCTL1 |= SWRST;
        UCTL1 = CHAR | SYNC | MM | SWRST;
        UTCTL1 = CKPL | SSEL0 | STC | TXEPT;
        UBR01  = 2;                          // Load SPI frequency divider 2
        UBR11  = 0x00;
        UMCTL1 = 0x00;						// Clear Modulation Register
        UCTL1 &= ~SWRST;
        ME2   |= USPIE1;					// Enable SPI module
    }
    
    void _hilGeneric_SetJtagSpeed(unsigned short speed, unsigned short sbwSpeed)
    {
        if(speed)
        {
            UBR01  = 2;				        // Load SPI frequency divider
        }
    }
    
    // -----------------------------------------------------------------------------
    short _hilGeneric_GetVcc(double* Vcc, double* ExtVcc)
    {
        if(P4OUT & BIT3)
        {
            *Vcc = _hilGeneric_ConvertAD(VCCTCHN);
        }
        else
        {
            *Vcc = 0;
        }
        *ExtVcc = _hilGeneric_ConvertAD(VCCICHN);
        return 0;
    }
    
    #ifdef ARCH_MSP432
    void VCCTon()
    {
        P4OUT |= BIT3;
    }
    void VCCToff()
    {
        P4OUT &= ~BIT3;
    }
    #endif
    
    // -----------------------------------------------------------------------------
    #pragma optimize = medium
    short _hilGeneric_SetVcc(unsigned short Vcc)
    {
        static unsigned char bPowerUp = 1;
    
        if(Vcc)
        {
            //This workaround is necessary to set TCK to a defined low level before
            //applying Vcc to the target device
            //otherwise the target will not power up correctly and the UIF can't
            //establish a SBW communication
            if(bPowerUp)
            {
                P5OUT &= ~BIT3;
                P2OUT &= ~BIT5; //(*_Jtag.RST_PORT) &= ~(_Jtag._SELT);
                bVccOn = Vcc;
                _hilGeneric_SetDac(Vcc+50);
                VCCTon();
                _hil_Delay_1ms(1);
                bPowerUp = 0;
            }
            else
            {
                bVccOn = Vcc;
                _hilGeneric_SetDac(Vcc+50);
                VCCTon();
            }
        }
        else
        {
            VCCToff();
            IHIL_Close();
            bVccOn = 0;
            bPowerUp = 1;
    
            //   Drive RESET low.
            //
            P2OUT &= ~BIT5;                 //   Assert SELT.
            P5OUT &= ~(BIT0 | BIT1 | BIT3); //   Drive TCK, TMS and TDI low.
            P4OUT &= ~BIT2;                 //   Assert ENI20#.
        }
        return 0;
    }
    
    
    // *****************************************************************************
    // Icc Monitor
    char bIccMonitorOn;                 // Initialization in HalGlobalVars.c
    char bHighCurrent;                  // Initialization in HalGlobalVars.c
    signed short last_ext_vcc;          // Initialization in HalGlobalVars.c
    unsigned short over_current_count;   // Initialization in HalGlobalVars.c
    
    short IccMonitor_Process(unsigned short flags)
    {
        signed short ext_vcc;
        signed short int_vcc;
        signed short rint_vcc;
    
        ext_vcc = _hilGeneric_ConvertAD(VCCICHN);          // convert channel
        int_vcc = _hilGeneric_ConvertAD(VCCTCHN);          // convert channel
        rint_vcc = _hilGeneric_ConvertAD(VCCRCHN);
    
        if(ext_vcc >= ExtLimit) // external voltage in the range 1.7V >=
        {
            if((ext_vcc < (last_ext_vcc-10)) || ext_vcc > (last_ext_vcc+10))
            {
                last_ext_vcc = ext_vcc;
            }
            _hilGeneric_SetDac(last_ext_vcc);               // let's hace a look at the external supply pin
        }
        else
        {
            if(bVccOn != 0)
            {
              _hilGeneric_SetVcc(bVccOn);
            }
        }
    
        if(bVccOn && bIccMonitorOn)
        {
            if((rint_vcc - int_vcc) > 150) // eqivalent to > 100mA
            {
                over_current_count++;
                if(over_current_count > 400)
                {
                    bHighCurrent = 1;
                    IHIL_Close();
                    P4OUT &= ~BIT3;                             // turn off target VCC
                    bVccOn = 0;
                    STREAM_biosLedOff(1);
                }
            }
            else
            {
                over_current_count = 0;
            }
        }
        else
        {
            over_current_count = 0;
        }
        return 0;
    }
    
    // -----------------------------------------------------------------------------
    #pragma vector=TIMERA0_VECTOR
    __interrupt void TA_CCR0_ISR (void)
    {
        static unsigned char cnt  = 0;
    
        short x;
        cnt++;
        if(cnt == 10)
        {
            cnt   = 0;     // reset pulse counter
            TACTL = 0;     // stop Timer A
            x = _hilGeneric_ConvertAD_(VFCHN);
            if(x < 0xFFF)   // 12-bit A/D thus value must exceed maximum measureable value (+-6.6V)
            {
                TACTL = (TASSEL_1 + TACLR + MC_1);      // start Timer A again and produce pulses
            }
            else
            {
                VFSettleFlag = 0;        // send message to main program
            }
        }
    }
    
    

**Attention** This is a public forum