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.

TMP104 MSP430 reference Code

Other Parts Discussed in Thread: TMP104

Where can we find MSP430 code example of TMP104EVM? Thanks.

  • Hi Regina,

     

    TMP104 EVM software was developed with LabVIEW and you can find the source code online:

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

     

    If you are looking for MSP430 code in particular to interface with TMP104 device itself, I'm sorry but we don’t have such source. Although we are starting to realize there is a need for such a library and management is looking at the possibility of allocating some resources toward this direction. But it might be a bit late for your project.

     

    Maybe you could find any MSP430 communication code as a reference, and adapt it for TMP104, which is really easy to use.

     

    Regards,

    Guang-Apps Sensing Products

  • Guang, thanks.

    We're helping with the code jobs and meet below problems, would pls kindly help? Thanks in advance.

    1 Global address assignment. TMP104EVM board is used, and the return value is 0x94, but actually there are only 4 devices in the line. It looks like the return value is the address of the last device PLUS one. So how we explain this result?

    2 Global reading. In the datasheet, host can send global read command, and each device will response and send corresponding data. My question is how can we match the RX data with device, or what's the timing sequence of data send for multiple devices.

    3 Interrupt. When an interrupt occurs, how can the host know which device in the line generates this interrupt?

    Regina

  • Hi Regina,

     

    1 This is a quote from the data sheet. The returned value is "last device+1”.

    2 The first TMP104 on the bus transmits first, the last goes last.

    3 The host cannot distinguish which TMP104 on the bus is issuing interrupt. To clear the interrupt event, a Global Interrupt Clear command has to be used.

     

    Regards,

    Guang-Apps Sensing Products

  • Hello all. We are having a lot of trouble with this sensor as well (probably because there seem to be some typos in the datasheet- for instance table 3) We can't seem to get reliable communication with it. Does anyone has an example of a code communicating with it? I know there is a LabView example but I can't open those files.

    Thanks,

    Nick

  • Hi Nick,

    Thank you for your inquiry. Someone will get back to you shortly.

    Aaron
  • 0363.main.c
    /* --COPYRIGHT--,BSD
     * Copyright (c) 2013, Texas Instruments Incorporated
     * All rights reserved.
     *
     * 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.
     * --/COPYRIGHT--*/
    
    #include <stdio.h>
    #include "msp430g2553.h"
    #include "grlib.h"
    #include "LcdDriver/Sharp96x96.h"
    
    
    // Function Prototypes
    void clockInit(void);
    void boardInit(void);
    void timerInit(void);
    void flashInit(void);
    void timerInit(void);
    void uartInit(void);
    void Delay_long(void);
    void Delay_short(void);
    
    // Global variables
    tContext g_sContext;
    
    void main(void)
    {
        // Stop WDT
        WDTCTL = WDTPW + WDTHOLD;
    
        // Initialize the boards
        boardInit();
        clockInit();
        timerInit();
        flashInit();
        uartInit();
    
        __bis_SR_register(GIE);
    
        // Set up the LCD
        Sharp96x96_LCDInit();
        GrContextInit(&g_sContext, &g_sharp96x96LCD);
        GrContextForegroundSet(&g_sContext, ClrBlack);
        GrContextBackgroundSet(&g_sContext, ClrWhite);
        GrContextFontSet(&g_sContext, &g_sFontFixed6x8);
        GrClearDisplay(&g_sContext);
        GrFlush(&g_sContext);
    
        unsigned short i;
        unsigned short sensor_cnt;
        unsigned short line_cnt;
        char buf[20];
        char msg[20];
    while(1){
    
        while (!(IFG2&UCA0TXIFG));                // USCI_A0 TX buffer ready?
        UCA0TXBUF = 0x55;
        while (!(IFG2&UCA0TXIFG));                // USCI_A0 TX buffer ready?
        UCA0TXBUF = 0x8C;
        while (!(IFG2&UCA0TXIFG));                // USCI_A0 TX buffer ready?
        UCA0TXBUF = 0x90;
    
        while (!(IFG2&UCA0RXIFG));
        buf[0] = UCA0RXBUF;
        while (!(IFG2&UCA0RXIFG));
        buf[1] = UCA0RXBUF;
        while (!(IFG2&UCA0RXIFG));
        buf[2] = UCA0RXBUF;
        sensor_cnt = buf[2] - 0x90;
        line_cnt = sensor_cnt;
        if (line_cnt & 1) {
        	line_cnt++;
        }
        line_cnt = line_cnt >> 1;
    
    
        while (!(IFG2&UCA0TXIFG));
        UCA0TXBUF = 0x55;
        while (!(IFG2&UCA0TXIFG));
        UCA0TXBUF = 0xF1;
    
        while (!(IFG2&UCA0RXIFG));
        buf[0] = UCA0RXBUF;
        while (!(IFG2&UCA0RXIFG));
        buf[1] = UCA0RXBUF;
        for(i=0; i<sensor_cnt; i++) {
        	while (!(IFG2&UCA0RXIFG));
        	buf[i] = UCA0RXBUF;
        }
    
        GrClearDisplay(&g_sContext);
        GrStringDrawCentered(&g_sContext,"TMP104",AUTO_STRING_LENGTH,48,4,TRANSPARENT_TEXT);
        for(i=0; i<line_cnt; i++) {
        	if ((i==line_cnt-1)&(sensor_cnt & 1)) {
        		sprintf(msg, "%x: %dC        ",i*2,buf[i*2]);
        	}
        	else{
        		sprintf(msg, "%x: %dC  %x: %dC",i*2,buf[i*2],(i*2)+1,buf[(i*2)+1]);
        	}
        	GrStringDrawCentered(&g_sContext,msg,AUTO_STRING_LENGTH,48,i*8+4+8,TRANSPARENT_TEXT);
        }
        GrFlush(&g_sContext);
        Delay_long();
    }
    
    }
    
    void clockInit(void)
    {
        // Set DCO frequency at 8MHz
        // ACLK	= VLO/1
        // SMCLK= DCO/1
        // MCLK	= DCO/1
        // If calibration constant erased
        if (CALBC1_8MHZ==0xFF)
        {
            // do not load, trap CPU!!
           while(1);
        }
        DCOCTL = 0;
        BCSCTL1 = CALBC1_8MHZ;
        DCOCTL = CALDCO_8MHZ;
        BCSCTL3 |= LFXT1S_2;
    }
    
    void boardInit()
    {
        // Set all port as outputs and drive pins low
        P1OUT = 0;
        P2OUT = 0;
        P3OUT = 0;
        P1DIR = 0xFF;
        P2DIR = 0xFF;
        P3DIR = 0xFF;
    }
    
    void flashInit()
    {
        // Configure flash memory timing
        // MCLK/18 for Flash Timing Generator
        // 8MHz/(16+1+1) =  444.44 KHz
        FCTL2 = FWKEY + FSSEL0 + FN4 + FN0;
    
    }
    
    void timerInit()
    {
    	TA0CTL = TASSEL_2 +ID_3+ MC_1+ TAIE +TACLR;
    	TA0CCTL0 |= CCIE;
    	TA0CCR0 = 32000-1;
    }
    
    void uartInit()
    {
    	P1SEL = BIT1 + BIT2 ;                     // P1.1 = RXD, P1.2=TXD
    	P1SEL2 = BIT1 + BIT2;
    	UCA0CTL1 |= UCSSEL_2;                     // SMCLK
    	UCA0BR0 = 69;                              // 1MHz 115200
    	UCA0BR1 = 0;                              // 1MHz 115200
    	UCA0MCTL = UCBRS2; //+ UCBRS0;               // Modulation UCBRSx = 5
    	UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
    	//IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt
    	//IE2 |= UCA0RXIE + UCA0TXIE;               // Enable USCI_A0 TX/RX interrupt
    	//UCABRx and UCBRSx reconfigured based on slau144 page 424 table
    	//produces 115200 baud rate with 8MHz core clock used in grlib demo
    }
    
    void Delay_long()
    {
        __delay_cycles(SYSTEM_CLOCK_SPEED * 4);
    }
    
    
    void Delay_short()
    {
        __delay_cycles(SYSTEM_CLOCK_SPEED * 0.25);
    }
    
    
    
    #pragma vector=TIMER0_A0_VECTOR
    __interrupt void TIMER0_A0_ISR(void)
    {
    	Sharp96x96_SendToggleVCOMCommand();
    	TA0CCR0 += 32000-1;
    	TA0CTL &= ~TAIFG;
    
    }
    

    Please see attachment. I apologize for the lack of comments. This code was written and tested on a value line launchpad MSP-EXP430G2 with Sharp LCD boosterpack 430BOOST-SHARP96. 

    The following section of code is very basic (or crude) way of writing to the UART:

       while (!(IFG2&UCA0TXIFG));                // USCI_A0 TX buffer ready?

       UCA0TXBUF = 0x55;

       while (!(IFG2&UCA0TXIFG));                // USCI_A0 TX buffer ready?

       UCA0TXBUF = 0x8C;

       while (!(IFG2&UCA0TXIFG));                // USCI_A0 TX buffer ready?

       UCA0TXBUF = 0x90;

    The response from the TMP104 is collected below:

       while (!(IFG2&UCA0RXIFG));

       buf[0] = UCA0RXBUF;

       while (!(IFG2&UCA0RXIFG));

       buf[1] = UCA0RXBUF;

       while (!(IFG2&UCA0RXIFG));

       buf[2] = UCA0RXBUF;

    The number of devices in the chain is decoded (note that buf0 and buf1 should contain the echo of 0x55 and 0x8C, respectively):

       sensor_cnt = buf[2] - 0x90;

    You can read on in the attachment to see transmit of global temperature read command, receive of all temperature bytes, and decoding of temperature data.

    A better way to write the UART comm in MSP430 would be to take advantage of the ISR of the UART peripheral. There are examples of this available in the MSP430 materials. Specific questions about MSP430 UART would be better directed to MSP430 forums, as those of us managing the Temp Sensor forums are not MSP430 experts.

    Thanks,

    Ren

  • This is good, Thank you very much Ren.