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.

[参考译文] MSP430F5505:LPM3中的USB消耗太多电量

Guru**** 1127450 points
Other Parts Discussed in Thread: MSP430F5505, CC2640
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1090321/msp430f5505-usb-drawing-too-much-power-in-lpm3

部件号:MSP430F5505
主题中讨论的其他部件: CC2640MSP-TS430RGC64USB

祝你好。

我在使用MSP430F5505启用USB子系统(但未将任何设备插入USB端口)时,很难让LPM3显著降低电流消耗。

导致过大电流消耗的代码的简化版本是:

WDT_A_hold(WDT_A_BASE); // Stop watchdog timer
PMM_setVCore(PMM_CORE_LEVEL_2);

USBHAL_initPorts();           // Config GPIOS for low-power (output low)
USBHAL_initClocks(8000000);   // Config clocks. MCLK=SMCLK=FLL=8MHz; ACLK=REFO=32kHz
USB_init( );

while( 1 )
{
    __bis_SR_register(LPM3_bits + GIE);
    _NOP();
}

如果我注释掉USB_init(),MCU的电流比未注释时的电流值低1mA。

在USB_init()内,对USB_determineXT2Freq()的调用是导致较高电流消耗的原因,大概是因为它启动XT2振荡器。  XT2引脚上有一个12MHz的晶体。

 在调用USB_init()后,我甚至尝试调用USB_disconnect()和USB_disable(),但它没有帮助。

如何减少LPM3中的电流消耗?

谢谢你

Scott Wild

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Scott:

    USB电源系统(3.3V LDO,1.8V LDO)和USBPLL的多个部分会影响总功耗。  USBPLL是迄今为止最大的,高达7mA。  那么您要做什么呢?  您正在尝试初始化USB,但不希望XT2运行? 也许有关应用程序的更多详细信息可能会有所帮助。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好,Dennis。

    此应用程序适用于电池供电的BLE无线传感器,该传感器还具有USB端口,以防有人想通过USB电缆进行通信(并为电池充电)。  BLE处理器是CC2640。  MSP430 主要是USB到串行转换器,通过UART与CC2640通信。 有关  我们的无线传感器产品线,请参阅pasco.com。

    我们以前使用NXP LPC11U14作为USB处理器,但由于NXP芯片短缺,我们正在使用MSP430进行重新设计。

    我的USB通信正常工作,但不幸的是,闲置的USB处理器的1mA电流消耗(即没有插入USB电缆)对于我们的小电池来说有点过大。  NXP部件空闲时仅消耗数十uA。

    MSP430规范规定LPM3只能绘制几个uA。  我只是想知道当USB端口断开时如何实现这一点。  您的文档说明  ,在移除VBus时调用USB_disconnect()和USB_disable()应该会在进入LPM3后将USB IP置于低功耗状态,但我看不到这一点。  我的示例代码只是复制问题的最简单的例子。

    谢谢你

    Scott Wild

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Scott:

    明白了。  我以为这是一个电池供电的应用程序。

    好的,请参阅SLAA457中的第16页“开始使用MSP430进行USB设计”,您将如何描述您的电源配置?

    您显然是通过电池作为主要电源来工作的,所以我假设您拥有MSP430 DVCC的LDO,对吗?

    仅当检测到与USB主机的连接时,才启用3.3V LDO和1.8V LDO,正确吗?

    连接到主机时,您是否将电池的电源切换至MSP430 的VUSB (+3.3V)?

    USB_DISABLE功能显示它确实禁用PLL。  因此,如果您调用此函数,您不会看到当前的大幅下降?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    此外,请随时发布您的代码,我可以查看一下。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好,Dennis。

    您回答正确。  我有一个3.7V LiPO,驱动3.3V LDO,该LDO始终驱动AVCC/DVCC引脚。   即使我插入USB电缆(即 VBUS =+5V)--我不使用VUSB LDO输出。

    在我的真实代码中,我在powerup调用usb_setup( false,true ),调用usb_init(),但不调用usb_enable()。  当我检测到VBUS时,我调用USB_enable()和USB_connect()开始通信。  当我检测到VBUS删除时,我调用USB_disconnect()和USB_disable()关闭USB核心。

    插入USB电缆时,电流测量不是很有用,因为它会开始为电池充电,这会给我带来较大的负电流读数。  如果USB电缆未插入(VBUS = 0V),则无论 是否调用了USB_disable()或USB_enable(),电流消耗都略低于1mA。

    这是我的实际代码(正在进行的工作...)

    #include <string.h>
    
    #include "driverlib.h"
    
    #include "USB_config/descriptors.h"
    #include "USB_API/USB_Common/device.h"
    #include "USB_API/USB_Common/usb.h"                 // USB-specific functions
    #include "USB_API/USB_Common/defMSP430USB.h"
    #include "PascoUSBSensor.h"
    #include <msp430.h>
    
    /*
     * NOTE: Modify hal.h to select a specific evaluation board and customize for
     * your own board.
     */
    #include "hal.h"
    
    // Global flags set by events
    volatile uint8_t bCDCDataReceived_event = FALSE;  // Flag set by event handler to 
                                                   // indicate data has been 
                                                   // received into USB buffer
    
    #define VERSION_MAJOR 2
    #define VERSION_MINOR 0
    
    //#define BUFFER_SIZE 256
    //char dataBuffer[BUFFER_SIZE] = "";
    //char nl[2] = "\n";
    //uint16_t count;
    
    #define EP0_BUF_SIZE 0x400
    uint8_t usbEP0Buf[EP0_BUF_SIZE];
    
    // Endpoint descriptors
    extern __no_init tEDB __data16 tInputEndPointDescriptorBlock[];
    extern __no_init tEDB __data16 tOutputEndPointDescriptorBlock[];
    tEDB *ep2in = &tInputEndPointDescriptorBlock[1];
    tEDB *ep3out = &tOutputEndPointDescriptorBlock[2];
    uint8_t *ep2inBuf = (uint8_t *)START_OF_USB_BUFFER;
    uint8_t *ep3outBuf = (uint8_t *)(START_OF_USB_BUFFER + MAX_PACKET_SIZE);
    
    bool allowSync = false;
    bool doVendorRequest = false;
    int DoVendorRequest( );
    
    #define UART_FIFO_SIZE                  0x100
    #define MAX_UART_PACKET_SIZE            0x50
    #define PACKET_HDR_REQUEST              0x6d
    #define PACKET_HDR_ACK                  0x3e
    #define PACKET_CMD_DATA                 0x01    // Send OUT packet to BLE module or recv IN data from BLE module
    #define PACKET_CMD_SYNC                 0x02    // Send current USB frame to BLE module
    #define PACKET_CMD_PRODUCT_ID           0x03    // Module tells us what its product ID is
    
    unsigned char uartFifoBuf[UART_FIFO_SIZE];
    unsigned char uartPacketBuf[MAX_UART_PACKET_SIZE + 10];
    #define uartRecvCmd uartPacketBuf[1]
    #define uartRecvSize uartPacketBuf[2]
    uint8_t uartPacketCount = 0;
    bool uartTxdAvailable = true;   // True if we can send a new packet to the BLE module
    bool uartRxdAvailable = false;  // True if we have recvd a packet from the BLE module
    uint8_t *uartFifoTail = uartFifoBuf;
    uint8_t *uartFifoWrap = uartFifoBuf + UART_FIFO_SIZE;
    
    bool doingBleBootloadRequest = false;
    bool bleBootloadWaitForAck = false;
    bool bleBootloadGotAck = false;
    int bleBootloadResponseSize = 0;
    int bleBootloadResponseSoFar = 0;
    int bleBootloadChecksum = 0;
    volatile uint32_t tickCountMS = 0;
    uint32_t uartAckTimeout = 0;
    
    bool isConnectedToPascoApp = false;
    bool hasVBus = false;
    
    uint8_t OnVendorOutDone(void);
    void PollUsbInterrupt( );
    void PollForTransfer( );
    void PollForUartPackets( );
    void ResetBLEModule( bool bootMode );
    
    #define LED_PIN GPIO_PORT_P1, GPIO_PIN1
    #define CONN_PIN GPIO_PORT_P6, GPIO_PIN3
    #define BT_RESET_PIN GPIO_PORT_P1, GPIO_PIN7
    #define FORCE_BOOT_PIN GPIO_PORT_P1, GPIO_PIN2
    #define UART_TX_PIN GPIO_PORT_P4, GPIO_PIN4
    #define UART_RX_PIN GPIO_PORT_P4, GPIO_PIN5
    #define SetForceBootLoad( mode ) if( mode ) GPIO_setOutputHighOnPin( FORCE_BOOT_PIN ); else GPIO_setOutputLowOnPin( FORCE_BOOT_PIN )
    #define DriveResetPin( drive ) if( drive ) GPIO_setAsOutputPin( BT_RESET_PIN ); else GPIO_setAsInputPinWithPullUpResistor( BT_RESET_PIN )
    #define SetIsUsbConnected( connected ) if( connected ) GPIO_setOutputHighOnPin( CONN_PIN ); else GPIO_setOutputLowOnPin( CONN_PIN )
    #define SetLED( on ) if( on ) GPIO_setAsOutputPin( LED_PIN ); else GPIO_setAsInputPin( LED_PIN )
    
    #define CONN_PIN_OBSOLETE GPIO_PORT_P6, GPIO_PIN0
    #define SetConnObsolete( mode ) if( mode ) GPIO_setOutputHighOnPin( CONN_PIN_OBSOLETE ); else GPIO_setOutputLowOnPin( CONN_PIN_OBSOLETE )
    
    //**************************************************************************************
    //
    //**************************************************************************************
    void main (void)
    {
        WDT_A_hold(WDT_A_BASE); // Stop watchdog timer
    
        // Minimum Vcore setting required for the USB API is PMM_CORE_LEVEL_2 .
        PMM_setVCore(PMM_CORE_LEVEL_2);
    
        USBHAL_initPorts();           // Config GPIOS for low-power (output low)
        USBHAL_initClocks(8000000);   // Config clocks. MCLK=SMCLK=FLL=16MHz; ACLK=REFO=32kHz
    
        // Init USB & events, but don't connect until we detect Vbus
        USB_setup( false, true );
    
        // Set up UART for 8N1 500KBaud
        #define BRG_PRE 2
        #define BRG_MOD1 0
        #define BRG_MOD2 0
        USCI_A_UART_initParam params = {USCI_A_UART_CLOCKSOURCE_SMCLK, BRG_PRE, BRG_MOD1, BRG_MOD2, USCI_A_UART_NO_PARITY, USCI_A_UART_LSB_FIRST,
                                        USCI_A_UART_ONE_STOP_BIT, USCI_A_UART_MODE, USCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION};
        USCI_A_UART_init( USCI_A1_BASE, &params );
        USCI_A_UART_enableInterrupt( USCI_A1_BASE, USCI_A_UART_RECEIVE_INTERRUPT );
        USCI_A_UART_enable( USCI_A1_BASE );
        GPIO_setAsPeripheralModuleFunctionOutputPin( UART_TX_PIN );
        GPIO_setAsPeripheralModuleFunctionInputPin( UART_RX_PIN );
    
        // Set up initial GPIO
        GPIO_setAsOutputPin( CONN_PIN );
        GPIO_setAsOutputPin( FORCE_BOOT_PIN );
        GPIO_setDriveStrength( LED_PIN, GPIO_FULL_OUTPUT_DRIVE_STRENGTH );
        GPIO_setOutputLowOnPin( BT_RESET_PIN ); // for simulating open-drain by switching port direction.
        GPIO_setOutputLowOnPin( LED_PIN );
        SetForceBootLoad( false );
        SetLED( false );
        SetIsUsbConnected( false );
        DriveResetPin( false );
    
        GPIO_setAsOutputPin( CONN_PIN_OBSOLETE );
        SetConnObsolete( true );
    
        // Set up DMA to continuously transfer recvd data into the uart recv fifo
        DMA1SAL = (uint16_t)&UCA1RXBUF; //__data16_write_addr( (unsigned short)&DMA1SA, (unsigned long)&UCA0RXBUF );   // DMA from the UART Rx register
        DMA1DAL = (uint16_t)uartFifoBuf; // __data16_write_addr( (unsigned short)&DMA1DA, (unsigned long)uartFifoBuf );  // DMA to the UART fifo buffer
        DMA1SZ = UART_FIFO_SIZE;
        DMACTL0 |= DMA1TSEL__USCIA1RX; // DMA channel 1 triggers on UART Receive
        DMA1CTL = DMAEN | DMADT2 | DMASRCBYTE | DMADSTBYTE | DMADSTINCR_3 | DMALEVEL; // Enable byte xfers with stationary src ptr and auto-incrementing dest ptr and level triggered
    
        // Set up Timer A to count up every ms
        TA0CTL = TASSEL__SMCLK | MC__UP | ID__8 | TAIE; // SMCLK, Count up to CCR0, div 8 (2MHz count),
        TA0CCTL0 = CCIE; // Compare interrupt
        TA0CCR0 = 2000; // 1ms interrupt @ 2 MHz count
    
        // Set up USB EP2IN and ep3OUT for USB to Serial
        ep2in->bEPCNF = EPCNF_UBME; // Enable EP2 single buffer
        ep3out->bEPCNF = EPCNF_UBME; // Enable EP2 single buffer
    
        __enable_interrupt();  // Enable interrupts globally
    
        while (1)
        {
            // Check the USB state and directly main loop accordingly
            int connState = USB_getConnectionState();
            switch (connState)
            {
                // This case is executed while your device is enumerated on the USB host
                case ST_ENUM_ACTIVE:
                    PollForUartPackets( );
                    PollForTransfer( );
    
                    // Handle vendor requests in main loop context
                    if( doVendorRequest )
                    {
                        int result = DoVendorRequest( );
    
                        // Errors will stall the endpoint
                        if( result == -1 )
                            usbStallEndpoint0();
                        // If returning data on an IN endpoint, do it here
                        else if( result > 0 )
                            usbSendDataPacketOnEP0( usbEP0Buf );
                        // If processing an OUT transaction, return status IN packet when done
                        else if( !(tSetupPacket.bmRequestType & USB_REQ_TYPE_INPUT) )
                            usbSendZeroLengthPacketOnIEP0( );
                        doVendorRequest = false;
                    }
                    break;
                    
                // These cases are executed while your device is disconnected from
                // the host (meaning, not enumerated); enumerated but suspended
                // by the host, or connected to a powered hub without a USB host
                // present.
                case ST_PHYS_DISCONNECTED:
                case ST_ENUM_SUSPENDED:
                case ST_PHYS_CONNECTED_NOENUM_SUSP:
                    break;
    
                // The default is executed for the momentary state
                // ST_ENUM_IN_PROGRESS.  Usually, this state only last a few
                // seconds.  Be sure not to enter LPM3 in this state; USB
                // communication is taking place here, and therefore the mode must
                // be LPM0 or active-CPU.
                case ST_ENUM_IN_PROGRESS:
                default:;
            }
    
            // If we connected or disconnected from USB cable, let BM10 know.
            if( connState == ST_PHYS_DISCONNECTED && hasVBus )
            {
                hasVBus = false;
                SetIsUsbConnected( false );
                USB_disconnect( );
                USB_disable( );
            }
            else if( connState != ST_PHYS_DISCONNECTED && !hasVBus )
            {
                hasVBus = true;
                USB_enable( );
                USB_reset( );
                USB_connect( );
                SetIsUsbConnected( true );
            }
    
            // If VBus is removed, we can go to sleep
            if( !hasVBus )
            {
                __bis_SR_register(LPM3_bits + GIE);
                _NOP();
            }
    
        }  //while(1)
    }
    
    //**************************************************************************************
    // 1ms Timer handler
    //**************************************************************************************
    #pragma vector=TIMER0_A0_VECTOR
    __interrupt void HandleTimerAInterrupt( void )
    {
        tickCountMS++;
    
        // Blink green LED to indicate running bootloader
    //    if( (tickCountMS & 0xff) == 0 )
    //        SetLED( false );
    //    else if( (tickCountMS & 0xff) == 0x80 )
    //        SetLED( true );
    
        TA0CTL &= ~TAIFG;
    }
    
    //***************************************************************************
    // wait the requested number of ms
    //***************************************************************************
    void Delay_MS( int ms )
    {
        uint32_t timeout = tickCountMS + ms;
        while( tickCountMS < timeout )
            continue;
    }
    
    //***************************************************************************
    // Does a blocking write to the UART
    //***************************************************************************
    void UartWrite( const void *dataIn, int len )
    {
        const uint8_t *data = (const uint8_t *)dataIn;
        while( len-- )
            USCI_A_UART_transmitData( USCI_A1_BASE, *data++ );
    }
    
    //***************************************************************************
    // Called when EP0 OUT data transfer has completed
    //***************************************************************************
    uint8_t OnVendorOutDone(void)
    {
        // We can now process the request since we have al of the data
        doVendorRequest = true;
        return true;
    }
    
    //***************************************************************************
    // Handles the reception of a SETUP packet in interrupt context
    //***************************************************************************
    uint8_t HandleVendorSetupRequest( void )
    {
        // If EP0 IN (read) request
        if( tSetupPacket.bmRequestType & USB_REQ_TYPE_INPUT )
        {
            // Zero-byte reads are invalid
            if( tSetupPacket.wLength == 0 )
                usbStallEndpoint0();
            else // Return the read data in the main loop context
                doVendorRequest = true;
        }
        // If zero-data EP0 OUT (write), we are ready to process it
        else if( tSetupPacket.wLength == 0 )
            doVendorRequest = true;
        // Make sure the write isn't too big
        else if( tSetupPacket.wLength > EP0_BUF_SIZE )
            usbStallEndpoint0();
        else // Fetch the data being written
            usbReceiveDataPacketOnEP0( usbEP0Buf );
        return true;
    }
    
    //**************************************************************************************
    // UART packet parser
    //**************************************************************************************
    void PollForUartPackets( )
    {
        uint8_t *uartFifoHead = (uint8_t *)DMA1DA + UART_FIFO_SIZE - DMA1SZ;
        int count = (uartFifoHead - uartFifoTail) & (UART_FIFO_SIZE - 1);
    
        // Safety check
        if( count > 0x100 || count < 0 )
            return;
    
        // If we got a recv data byte
        while( count-- )
        {
            uint8_t data = *uartFifoTail++;
            if( uartFifoTail >= uartFifoWrap )
                uartFifoTail = uartFifoBuf;
    
            // If we are processing CC26XX ROM bootloader responses
            if( doingBleBootloadRequest )
            {
                // If waiting for an ACK to the last packet we sent
                if( bleBootloadWaitForAck )
                {
                    if( data == 0xcc || data == 0x33 )
                    {
                        bleBootloadWaitForAck = false;
                        bleBootloadGotAck = (data == 0xcc);
                    }
                }
                else // Looking for a response packet
                {
                    // The first non-zero byte of the packet is its size
                    if( bleBootloadResponseSize == 0 && data != 0 )
                        bleBootloadResponseSize = data;
    
                    // If we are expecting more data in the packet, place it in the USB EP0 buffer
                    if( bleBootloadResponseSize != 0 && bleBootloadResponseSoFar < bleBootloadResponseSize )
                    {
                        if( bleBootloadResponseSoFar >= 2 )
                            bleBootloadChecksum += data;
                        usbEP0Buf[bleBootloadResponseSoFar++] = data;
                    }
                }
            }
            else // This is a Pasco BLE/USB packet
            {
                // If we have not yet started a packet, look for the packet header signature byte
                if( uartPacketCount == 0 )
                {
                    // If we got an ACK for the last packet we sent to the BLE module
                    if( data == PACKET_HDR_ACK )
                    {
                        uartTxdAvailable = true;
                        continue;
                    }
                    // Ignore everything until we get to the beginning of a packet
                    else if( data != PACKET_HDR_REQUEST )
                        continue;
                }
    
                if( uartPacketCount < MAX_UART_PACKET_SIZE )
                {
                    uartPacketBuf[uartPacketCount++] = data;
    
                    // If we got a complete packet
                    if( uartPacketCount >= 3 && uartPacketCount >= uartRecvSize + 3 )
                    {
                        uartPacketCount = 0;
                        uartRxdAvailable = true;
                    }
                }
                else // Something is wrong, look for a new packet
                    uartPacketCount = 0;
            }
        }
    }
    
    //***************************************************************************
    // See if any packets need to be transferred between
    //***************************************************************************
    void PollForTransfer( )
    {
        // If we have not received an ACK within 100ms of our last packet
        // sent to the BLE module, assume there is a problem and ignore it
        if( !uartTxdAvailable && tickCountMS > uartAckTimeout )
            uartTxdAvailable = true;
    
        // If we are able to send a new packet to the BLE module
        if( uartTxdAvailable )
        {
            // If we have a new USB packet to send to the BLE module
            if( ep3out->bEPBCTX & EPBCNT_NAK )
            {
                // Get the received USB packet size
                uint16_t actual = ep3out->bEPBCTX & EPBCNT_BYTECNT_MASK;
                if( actual > 0 )
                {
                    if( actual > MAX_UART_PACKET_SIZE - 3 )
                        actual = MAX_UART_PACKET_SIZE - 3;
    
                    // Forward the packet to the BLE module
                    uartTxdAvailable = false;
                    uint8_t hdr[3] = { PACKET_HDR_REQUEST, PACKET_CMD_DATA, actual };
                    UartWrite( hdr, 3 );
                    UartWrite( ep3outBuf, actual );
                    ep3out->bEPBCTX = 0;
    
                    // Wait up to 100ms for ACK
                    uartAckTimeout = tickCountMS + 100;
                }
    
                // Prepare to read another USB packet from EP3OUT
                ep3out->bEPBCTX = 0;
            }
        }
    
        // If we have recvd a new packet from the BLE module
        if( uartRxdAvailable )
        {
            // If the BLE module is sending us packets, it can accept periodic sync packets
            allowSync = true;
    
            // Indicate that we've processed the packet from the BLE module
            uartRxdAvailable = false;
    
            // If we recvd a BLE packet that needs to be sent to the host via USB
            if( uartRecvCmd == PACKET_CMD_DATA )
            {
                // If the USB IN endpoint can accept new data
                if( ep2in->bEPBCTX & EPBCNT_NAK )
                {
                    // Give data to the USB host
                    memcpy( ep2inBuf, &uartPacketBuf[3], uartRecvSize );
                    ep2in->bEPBCTX = uartRecvSize;
                }
                else // Cannot send data to host, so keep trying until we can
                    uartRxdAvailable = true;
            }
            // Tell the BLE module that we've processed the packet and can now accept a new one
            if( !uartRxdAvailable )
            {
                uint8_t ack = PACKET_HDR_ACK;
                UartWrite( &ack, 1 );
            }
        }
    }
    
    //***************************************************************************
    //
    //***************************************************************************
    void ResetBLEModule( bool bootMode )
    {
        // Setting these pins high will force the BM10 into its ROM bootloader so we can upgrade firmware.
        SetForceBootLoad( bootMode );
    
        // Toggle reset to BM10 by driving the reset pin and then tri-stating it
        DriveResetPin( true );
        Delay_MS( 10 );
        DriveResetPin( false );
        Delay_MS( 500 );
    
        // Clear the force-bootloader pins
        SetForceBootLoad( false );
    }
    
    //***************************************************************************
    //
    //***************************************************************************
    static void SetUsbIsConnected( bool isConnected )
    {
        // Set the signal telling the BM10 whether we are communicating via USB
        SetIsUsbConnected( isConnected );
    
        // Give the BM10 a little time to prepare for USB communications and send a
        // no-op over to flush out any left over UART chars.
        if( isConnected )
        {
            uint8_t zero[10];
            memset( zero, 0, sizeof( zero ) );
            Delay_MS( 10 );
            UartWrite( zero, sizeof( zero ) );
            Delay_MS( 10 );
        }
    }
    
    //**************************************************************************************
    //
    //**************************************************************************************
    int DoVendorRequest( )
    {
        // Get actual product ID
        if( tSetupPacket.bRequest == PASCO_USB_SENSOR_GET_FAUX_USB_PRODUCT_ID )
        {
            *(uint16_t *)usbEP0Buf = 1029; // *DEBUG* Wireless Smart Cart
            return 2;
        }
    
        // Get USB Bridge firmware version
        else if( tSetupPacket.bRequest == PASCO_USB_SENSOR_GET_FIRMWARE_VERSION )
        {
            strcpy( (char *)usbEP0Buf, "  FUsbBridge2 " __DATE__ " " __TIME__ );
            usbEP0Buf[0] = VERSION_MAJOR;
            usbEP0Buf[1] = VERSION_MINOR;
            return strlen( (const char *)&usbEP0Buf[2] ) + 2;
        }
    
        // Read/Write memory
        else if( tSetupPacket.bRequest == PASCO_USB_SENSOR_LOAD_FIRMWARE )
        {
            unsigned long addr = tSetupPacket.wValue | ((unsigned long)tSetupPacket.wIndex << 16);
    
            // If reading memory
            if( tSetupPacket.bmRequestType & USB_REQ_TYPE_INPUT )
            {
                // Prepare a packet of data to be sent to the host
                memcpy( usbEP0Buf, (const void *)addr, tSetupPacket.wLength );
                return tSetupPacket.wLength;
            }
            else // Writing memory
            {
                // Get the data that was sent by the host
                memcpy( (void *)addr, usbEP0Buf, tSetupPacket.wLength );
                return 0;
            }
        }
    
        // Miscellaneous requests
        else if( tSetupPacket.bRequest == PASCO_USB_SENSOR_ACCESS_HARDWARE )
        {
            int subRequest = tSetupPacket.wIndex >> 8;
    
            // Allow app to tell BM10 whether it wants to communicate via USB
            if( subRequest == PASPORT_HW_SET_USB_BLE_ENABLE )
            {
                SetUsbIsConnected( tSetupPacket.wValue == 0 );
                return 0;
            }
    
            // Complete a USB IN request to unblock any readers
            else if( subRequest == PASPORT_HW_COMPLETE_USB_IN )
            {
                ep2in->bEPBCTX = 0;
                ep2in->bEPBCTY = 0;
                return 0;
            }
    
            // Go into the bootloader
            else if( subRequest == PASPORT_HW_GO_BOOT_LOADER )
            {
                allowSync = false;
    
                // Go into our own bootloader
                if( tSetupPacket.wValue == 0 )
                {
    // todo: figure this out
    //                #define RAM_BASE_ADDR 0x10000000
    //                *(uint32_t *)RAM_BASE_ADDR = FORCE_BOOT_SIG;
    //                UsbDisconnect( );
    //                NVIC_SystemReset( );
    //                result = 0;
                }
    
                // Try forcing the BLE module into CC26xx ROM bootloader mode as force boot mode
                else if( tSetupPacket.wValue == 2 )
                {
                    ResetBLEModule( true );
                    return 0;
                }
            }
    
            // Reset the BLE module to run its main firmware
            else if( subRequest == PASPORT_HW_RESET_BOARD )
            {
                ResetBLEModule( false );
                return 0;
            }
    
            // Read/write the CC26XX ROM bootlader via the UART to write firmware to the CC26XX
            else if( subRequest == PASPORT_HW_RW_TI_BOOTLOADER )
            {
                allowSync = false;
    
                // Reading response from CC26xx ROM bootloader
                if( tSetupPacket.bmRequestType & USB_REQ_TYPE_INPUT )
                {
                    if( tSetupPacket.wLength > bleBootloadResponseSize )
                        tSetupPacket.wLength = bleBootloadResponseSize;
                    return tSetupPacket.wLength;
                }
                else
                {
                    //todo: Need to find a way to stall the endpoint upon failure
                    bool success = true;
    
                    // Prep for request and response
                    bleBootloadResponseSize = 0;
                    bleBootloadResponseSoFar = 0;
                    doingBleBootloadRequest = true;
                    bleBootloadWaitForAck = true;
                    bleBootloadGotAck = false;
                    bleBootloadChecksum = 0;
    
                    // Send the request to the CC26xx ROM bootloader
                    UartWrite( usbEP0Buf, tSetupPacket.wLength );
    
                    // Wait up to 0.5 second for an ack
                    uint32_t timeout = tickCountMS + 500;
                    while( tickCountMS < timeout )
                        if( !bleBootloadWaitForAck )
                            break;
    
                    // If we didn't get an ACK, indicate an error occurred
                    if( bleBootloadWaitForAck || !bleBootloadGotAck )
                        success = false;
    
                    // If we got an ACK and we are expecting a response, wait for the response
                    else if( tSetupPacket.wValue != 0 )
                    {
                        // Wait up to 0.5 second for a response
                        uint32_t timeout = tickCountMS + 500;
                        while( tickCountMS < timeout )
                            if( bleBootloadResponseSize && bleBootloadResponseSoFar == bleBootloadResponseSize )
                                break;
    
                        bool timedOut = tickCountMS >= timeout;
                        bool checksumValid = bleBootloadResponseSize > 2 && (bleBootloadChecksum & 0xff) == usbEP0Buf[1];
    
                        // If we got a response, ack/nack it based on checksum validity
                        if( !timedOut )
                        {
                            unsigned char ack = checksumValid ? 0xcc : 0x33;
                            UartWrite( &ack, 1 );
                        }
    
                        // Indicate error if we timed out waiting for a response
                        success = (!timedOut && checksumValid);
                    }
                    else // No response requested, so we're good to go
                        success = true;
    
                    doingBleBootloadRequest = false;
    
                    return success ? 0 : -1;
                }
            }
        }
    
        return -1;
    }
    
    //**************************************************************************************
    //
    //**************************************************************************************
    uint8_t HandleEP2InInterrupt( void )
    {
        return FALSE;
    }
    
    //**************************************************************************************
    //
    //**************************************************************************************
    uint8_t HandleEP3OutInterrupt( void )
    {
        return FALSE;
    }
    
    //**************************************************************************************
    // NMI handler
    //**************************************************************************************
    #if defined(__TI_COMPILER_VERSION__) || (__IAR_SYSTEMS_ICC__)
    #pragma vector = UNMI_VECTOR
    __interrupt void UNMI_ISR (void)
    #elif defined(__GNUC__) && (__MSP430__)
    void __attribute__ ((interrupt(UNMI_VECTOR))) UNMI_ISR (void)
    #else
    #error Compiler not found!
    #endif
    {
        switch (__even_in_range(SYSUNIV, SYSUNIV_BUSIFG ))
        {
            case SYSUNIV_NONE:
                __no_operation();
                break;
            case SYSUNIV_NMIIFG:
                __no_operation();
                break;
            case SYSUNIV_OFIFG:
                UCS_clearFaultFlag(UCS_XT2OFFG);
                UCS_clearFaultFlag(UCS_DCOFFG);
                SFR_clearInterrupt(SFR_OSCILLATOR_FAULT_INTERRUPT);
                break;
            case SYSUNIV_ACCVIFG:
                __no_operation();
                break;
            case SYSUNIV_BUSIFG:
                // If the CPU accesses USB memory while the USB module is
                // suspended, a "bus error" can occur.  This generates an NMI.  If
                // USB is automatically disconnecting in your software, set a
                // breakpoint here and see if execution hits it.  See the
                // Programmer's Guide for more information.
                SYSBERRIV = 0; // clear bus error flag
                USB_disable(); // Disable
        }
    }
    
    //Released_Version_5_20_06_02
    

    谢谢你

    Scott

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    又你好

    作为一个附加数据点,当我在MSP-TS430RGC64USB评估板上执行相同的实验时,我看到了相同的东西。  当USB已初始化但未启用(USB_init(),USB_disable())时,我看到LPM3中的~700uA电流消耗。  当我不调用USB_init()时,我只在LPM3中看到170uA。

    谢谢你

    Scott

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    再次您好

    另外一个数据点:

    如果我在USB_init()之后尝试关闭USB LDO和XT2振荡器,电流会稍有下降(~500uA),但当我根本不调用USB_Init()时,不会返回到我看到的~170uA。

        USB_init();                    // Init USB & events; if a host is present, connect
    
        // Disable USB LDOs
        USBKEYPID  = 0x9628;
        USBPWRCTL  = 0;
        USBKEYPID  = 0x9600;
    
        // Turn of XT2
        HWREG16(UCS_BASE + OFS_UCSCTL6) |= XT2OFF;
    

    此外,看起来对于LPM3来说,170uA仍然相当高,因为数据表显示它应该< 10uA。  有什么想法,我可能做错了什么?

    谢谢你

    Scott

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Scott:

    如果您在调试模式下运行代码,您将看到大约170-180uA贡献。 如果我不调用USB_init()直接进入LPM3,我测量5uA。  当我禁用3.3 模块(LDO_PL=OFF和LDO_PLL 1.8 = OFF),XT2关闭和关闭时,我看到没有调试器的500uA。  我正在研究这个问题。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好,Dennis。

    看起来XT2是一种红色鲱鱼。  出现该问题是因为 USB_determineXT2Freq()在检测完XT2频率后未禁用计时器。  一旦我添加 了TIME_CTL =0,到检测回路的末尾,电流消耗下降了大约500uA。

    感谢你的帮助

    Scott