Jump to content
43oh

One last BMP085 Project...


Recommended Posts

Ok, so the MSP-EXP430F5529 dev board may not provide me with optimal hardware I/O for my greenhouse controller. Basically, I'd want the power/speed of the F5529 without the accelerometer. If I were rebuilding this board, I'd move the LCD SPI over to UCA1 and free up UCB1 for an I2C channel. UCB0 is being used for the RF2500t interface. So...

 

My solution (for now) is to use a standalone G2553 as an I2C to UART translator. It actually works out well but not my optimal hardware configuration. This project may not be useful for many but some might find bits of the code helpful. The kicker, though, is I configured all of the hardware using Grace. :crazy:

 

If you have a BMP085, you can open a terminal on your launchpad port and receive temperature and barometric pressure.

 

/****************************************************************/
/* Greg Whitmore												*/
/* greg@gwdeveloper.net											*/
/* www.gwdeveloper.net									*/
/****************************************************************/
/* released under the "Use at your own risk" license			*/
/* use it how you want, where you want and have fun				*/
/* debugging the code.											*/
/* MSP-EXP430G2553												*/
/****************************************************************/

/* includes */
#include 
#include 
#include 

#include "itoa.h"

/* bmp085 defines */
#define BMP085_ADDR		0x77
#define BMP085_CTRL_REG 0xF4
#define BMP085_TEMP_REG 0x2E
#define BMP085_PRESSURE_REG 0x34		// oss =0
//#define BMP085_PRESSURE_REG_OSS1 0x74	// oss =1, longer delays needed 7.5ms
//#define BMP085_PRESSURE_REG_OSS2 0xB4 	// oss =2, 13.5ms
//#define BMP085_PRESSURE_REG_OSS3 0xF4 	// oss =3, 25.5ms
#define BMP085_MSB_REG	0xF6
#define BMP085_LSB_REG	0xF7
#define BMP085_CONV_REG_XLSB 0xF8

/* prototypes */
// bmp085
void bmp085_cal(void);
unsigned int bmp085_ut(void);
unsigned long bmp085_up(void);
void get_bmp085(void);

// iic
void iic_init(void);
void iic_tx_init(void);
void iic_rx_init(void);
void start_TX(void);
void start_RX(void);
int sendByte_getBytes(unsigned char reg_2_read, int bytes_to_rx);

//uart
void TXString( char* string, int length );

/* variables */
// bmp085
// cal data
int ac1;
int ac2;
int ac3;
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1;
int b2;
int mb;
int mc;
int md;
// true temp
long ut;
long x1;
long x2;
long b5;
int bmp_temp = 0;
//true pressure
long up;
long x3;
long b3;
unsigned long b4;
long b6;
unsigned long b7;
long p;
long bmp_pres = 0;
// adjusters
long b6Temp;
long x1Temp;

//unsigned int i;

unsigned char temp_buffer[8];
unsigned char pres_buffer[8];

// tx constants
const unsigned char utTxData[] = { BMP085_CTRL_REG, BMP085_TEMP_REG };    // uncomp temp reg
const unsigned char upTxData[] = { BMP085_CTRL_REG, BMP085_PRESSURE_REG }; // oss =0 see bmp085.h
const unsigned char msbData[] = { BMP085_MSB_REG };

// iic
unsigned char *PTxData;                     	// Pointer to TX data
unsigned char TXByteCtr;

unsigned char *PRxData;                     	// Pointer to RX data
unsigned char RXByteCtr;
volatile unsigned char RxBuffer[3];       		// Allocate 3 byte of RAM

void main(void)
{
   CSL_init();                     // Activate Grace-generated configuration
   __enable_interrupt();           // Set global interrupt enable

   bmp085_cal(); 					// load calibration data

get_bmp085();					// loop to collect temp & pressure
								//  and TX via UART

}

// store PROM data into usable variables
void bmp085_cal(void)
{  
   ac1 = sendByte_getBytes(0xAA, 2);
   __delay_cycles(1000);
   ac2 = sendByte_getBytes(0xAC, 2);
   __delay_cycles(1000);
   ac3 = sendByte_getBytes(0xAE, 2);
   __delay_cycles(1000);    
   ac4 = sendByte_getBytes(0xB0, 2);
   __delay_cycles(1000);
   ac5 = sendByte_getBytes(0xB2, 2);
   __delay_cycles(1000);
   ac6 = sendByte_getBytes(0xB4, 2);
   __delay_cycles(1000);
   b1 =  sendByte_getBytes(0xB6, 2);
   __delay_cycles(1000);
   b2 =  sendByte_getBytes(0xB8, 2);
   __delay_cycles(1000);
   mb =  sendByte_getBytes(0xBA, 2);
   __delay_cycles(1000);
   mc =  sendByte_getBytes(0xBC, 2);
   __delay_cycles(1000);
   md =  sendByte_getBytes(0xBE, 2);
   __delay_cycles(1000);

}

// read uncompensated temperature and return msb & lsb
unsigned int bmp085_ut(void)
{
iic_tx_init();

__delay_cycles(1000);

PTxData = (unsigned char *)utTxData;		// send control reg and temp reg
TXByteCtr = 2;              				// Load TX byte counter

start_TX();

__delay_cycles(200000);   // long delay here or it hangs on the valueline mcus

return (sendByte_getBytes(BMP085_MSB_REG, 2));

}

// read uncompensated pressure and return msb, lsb & xlsb
unsigned long bmp085_up(void)
{
iic_tx_init();

__delay_cycles(1000);

PTxData = (unsigned char *)upTxData;		// send control reg and temp reg
TXByteCtr = 2;              				// Load TX byte counter

start_TX();

__delay_cycles(200000);			// long delay here or it hangs on the valueline mcus

   PTxData = (unsigned char *)msbData;		// send msb read register
TXByteCtr = 1;

start_TX();

iic_rx_init();						// set RX interrupt

   __delay_cycles(200000);			// long delay here or it hangs on the valueline mcus

   PRxData = (unsigned char *)RxBuffer;    // rx buffer
   RXByteCtr = 3;     			// number of bytes to receive

   start_RX();

   // returning longs instead of ints to allow 2^16 shifts
   // sendByte_getBytes not used here due to long shifts
   return ( (( (long)RxBuffer[0] << 16) | ( (long)RxBuffer[1] << 8) | (long)RxBuffer[2]) >> 8);

}

// collect uncompensated temp and pressure
// calculate compensated temp and pressure then transmit via UART
void get_bmp085()
{

while (1){

ut = bmp085_ut();
up = bmp085_up();

// calc true temp
x1 = ((long)ut - ac6) * ac5 >> 15;
   x2 = ((long)mc << 11) / (x1 + md);
   b5 = x1 + x2;
   bmp_temp = (b5 + 8) >> 4;

   // itoa function added
   itoa(bmp_temp, (char*)temp_buffer);			// move integer into char buffer

	// calc true pressure
   b6 = b5 - 4000;

//x1 = (b2 * (b6 * b6) >> 12) >> 11; // won't work this way on the value line LSR_23 error
b6Temp = b6 * b6;
x1Temp = b2 * b6Temp;
x1Temp = x1Temp >> 12;
x1 = x1Temp >> 11;

x2 = (ac2 * b6) >> 11;
x3 = x1 + x2;

b3 = ((long)ac1 * 4 + x3 + 2) >> 2;  // ????  so many 'corrections' on the web this one works though

x1 = ac3 * b6 >> 13;
x2 = (b1 * ((b6 * b6) >> 12)) >> 16;
x3 = ((x1 + x2) + 2) >> 2;
b4 = (ac4 * (unsigned long)(x3 + 32768)) >> 15;
b7 = ((unsigned long)up - b3) * 50000;

if (b7  < 0x80000000)
{ p = (b7 * 2) / b4;}
else {p = (b7 / b4) *2;}

x1 = (p >> 8) * (p >> 8);
x1 = (x1 * 3038) >> 16;
x2 = (-7357 * p) >> 16;
bmp_pres = p + ((x1 + x2 + 3791) >> 4);

   // ltoa part of stdlib.h
   ltoa(bmp_pres, (char*)pres_buffer);

   TXString((char*)temp_buffer, sizeof temp_buffer);
   TXString("\r\n", 2);
   TXString((char*)pres_buffer, sizeof pres_buffer);
   TXString("\r\n", 2);

  	__delay_cycles(500000);

}
}

void iic_tx_init()
{
UCB0I2CSA = BMP085_ADDR;
UCB0I2CIE |= UCB0TXIE;                       	// Enable TX interrupt
}
void iic_rx_init(void)
{
UCB0I2CIE |= UCB0RXIE;							// enable RX interrupt	
}

// send 1 byte, return 2 bytes - needs the return expanded for X bytes
int sendByte_getBytes(unsigned char reg_2_read, int bytes_to_rx)
{
// transmit slave address and register to read
iic_tx_init();

__delay_cycles(1000);  

   PTxData = (unsigned char *)&reg_2_read;     // TX array start address

   TXByteCtr = sizeof reg_2_read;              // Load TX byte counter

   start_TX();
   //
   // receive requested bytes
   iic_rx_init();								// set RX interrupt

   __delay_cycles(1000);

   PRxData = (unsigned char *)RxBuffer;    	// rx buffer

   RXByteCtr = bytes_to_rx;     				// number of bytes to receive

   start_RX();
   //
   return ((int)RxBuffer[0] << 8) | (int)RxBuffer[1];  // currently only returning 2 bytes

}

// iic start transmitting
void start_TX(void)
{
UCB0CTL1 |= UCTR + UCTXSTT;             	// I2C TX, start condition

   __bis_SR_register(LPM0_bits + GIE);     	// Enter LPM0, enable interrupts
   __no_operation();                       	// Remain in LPM0 until all data
                                           	// is TX'd
   while (UCB0CTL1 & UCTXSTP);             	// Ensure stop condition got sent
}

// iic restart and receive
void start_RX(void)
{
while (UCB0CTL1 & UCTXSTP);             	// wait for stop

   UCB0CTL1 &= ~UCTR;                      	// restart, set as receiver
   UCB0CTL1 |= UCTXSTT;                    	// start condition

   __bis_SR_register(LPM0_bits + GIE);

   while (UCB0CTL1 & UCTXSTP);
}
// interrupt pragma is defined in grace
void iic_TX_isr(void)
{
if (TXByteCtr)                          // Check TX byte counter
   {
     UCB0TXBUF = *PTxData++;               // Load TX buffer
     TXByteCtr--;                          // Decrement TX byte counter
   }
   else
   {
     UCB0CTL1 |= UCTXSTP;                  // I2C stop condition
     IFG2 &= ~UCB0TXIFG;                   // Clear USCI_B0 TX int flag
   }  
}
// interrupt pragma is defined in grace
void iic_RX_isr(void)
{	
RXByteCtr--;                            // Decrement RX byte counter
   if (RXByteCtr)
   {
   	P1OUT ^= 0x10;
     *PRxData++ = UCB0RXBUF;               // Move RX data to address PRxData
     if (RXByteCtr == 1)                   // Only one byte left?
       UCB0CTL1 |= UCTXSTP;                // Generate I2C stop condition
   }
   else
   {
     *PRxData = UCB0RXBUF;                 // Move final RX data to PRxData
   }
}

// tx function borrowed from TI's virtual_com_cmds.c
void TXString( char* string, int length )
{
 int pointer;
 for( pointer = 0; pointer < length; pointer++)
 {
   volatile int i;
   UCA0TXBUF = string[pointer];
   while (!(IFG2&UCA0TXIFG));              // USCI_A0 TX buffer ready?
 }
}

// timer A isr is simply toggling activity light for now.
// future pwm functions to go here
void timer_A_ISR(void)
{
P1OUT ^= BIT0;	
}

Link to post
Share on other sites
  • Replies 31
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

Ok, so the MSP-EXP430F5529 dev board may not provide me with optimal hardware I/O for my greenhouse controller. Basically, I'd want the power/speed of the F5529 without the accelerometer. If I were re

GWD,   Thanks for the post and files.   I am a noob and tried to do something similar with the BMP085 and MSP430G2231 when the launchpad was released and never could get I2C to work correctly. Gi

Not sure what's going on. I created that project in v4 a while back. It's already imported and working in v5.1 for me but it was imported quite a while ago. Not sure if I changed anything to get it go

  • 2 weeks later...

GWD,

 

Thanks for the post and files.

 

I am a noob and tried to do something similar with the BMP085 and MSP430G2231 when the launchpad was released and never could get I2C to work correctly. Given the flash limitations of that chip, not sure it would have been possible...

 

Your work inspired me to update ccs, install grace, and get it working! BTW, for any other noobs reading this, you will need to attach pullup resistors to SCL & SDA, jumper the TXD and RXD pins since they seem reversed on the 2553, and remove the jumper for pin 1.6 that connects it to the Launchpads LED2.

 

Grace seems nice. It is very easy for a noob to get stuck configuring pins, clocks, etc. It was nice to refer back to see what speed you had the UART running at, the pinout for SCL/SDA, etc.

 

Great stuff!

 

Thanks again...

Link to post
Share on other sites

Sure thing. I'm glad you could put it to use. I never could get any of the USI devices to work properly with the BMP085. Any of the USCI devices are much easier to work with.

 

Good idea mentioning the pullup resistors and removing the 1.6 jumper. That could cause some disappointments when it doesn't work.

 

Grace has been a big help and speeds bringup a lot. No reason to have a pdf open at the same time as configuring the hardware. I only wish it would support the new FR devices so I could sort out this Clock and Oscillator system.

Link to post
Share on other sites
  • 4 months later...
GWD,

 

Thanks for the post and files.

 

I am a noob and tried to do something similar with the BMP085 and MSP430G2231 when the launchpad was released and never could get I2C to work correctly. Given the flash limitations of that chip, not sure it would have been possible...

 

Your work inspired me to update ccs, install grace, and get it working! BTW, for any other noobs reading this, you will need to attach pullup resistors to SCL & SDA, jumper the TXD and RXD pins since they seem reversed on the 2553, and remove the jumper for pin 1.6 that connects it to the Launchpads LED2.

 

Grace seems nice. It is very easy for a noob to get stuck configuring pins, clocks, etc. It was nice to refer back to see what speed you had the UART running at, the pinout for SCL/SDA, etc.

 

Great stuff!

 

Thanks again...

 

 

"jumper the TXD and RXD pins since they seem reversed on the 2553"

What does that mean?

and when I try to run the code, it's missing "itoa.h"

help, anyone?

Link to post
Share on other sites

hi

 

"jumper the TXD and RXD pins since they seem reversed on the 2553"

 

here is the link for the RX / TX jumper:

viewtopic.php?f=8&t=1703

if you are using the g2553 and want serial out you need to swap the RX / TX pins.

I think it is fine for all the other chips, but Im not 100% on this. check the data sheet for the chip you are using.

you can get the data sheet on this forum in the upper right corner of your browser.

 

As for the itoa.h.

that is a function you need to have in the code

check here:

http://www.jb.man.ac.uk/~slowe/cpp/itoa.html

 

hope this helps

regards

tim

 

I think I posted this 1 second behind you blue

Link to post
Share on other sites

If you download the attached zip file, itoa.c and itoa.h are both included. The zip file contains a CCS project you can import -it will not operate with just the posted code alone.

 

You can use the Grace plugin to use a gui to see how the hardware is configured or you can look at each of the init source files in bmp085_2553.zip\src\csl

Link to post
Share on other sites
If you download the attached zip file, itoa.c and itoa.h are both included. The zip file contains a CCS project you can import -it will not operate with just the posted code alone.

 

You can use the Grace plugin to use a gui to see how the hardware is configured or you can look at each of the init source files in bmp085_2553.zip\src\csl

 

 

Oh thanks. that got me stuck for a bit.

 

So how do people write these types of code? is there a tutorial for configuring I2C?

and why is configuring hardware using Grace a kicker?

 

sorry I am a newb.

Link to post
Share on other sites
GWD,

 

Thanks for the post and files.

 

I am a noob and tried to do something similar with the BMP085 and MSP430G2231 when the launchpad was released and never could get I2C to work correctly. Given the flash limitations of that chip, not sure it would have been possible...

 

Your work inspired me to update ccs, install grace, and get it working! BTW, for any other noobs reading this, you will need to attach pullup resistors to SCL & SDA, jumper the TXD and RXD pins since they seem reversed on the 2553, and remove the jumper for pin 1.6 that connects it to the Launchpads LED2.

 

Grace seems nice. It is very easy for a noob to get stuck configuring pins, clocks, etc. It was nice to refer back to see what speed you had the UART running at, the pinout for SCL/SDA, etc.

 

Great stuff!

 

Thanks again...

 

 

How did you adapt the code for the 2231?

Link to post
Share on other sites
GWD,

 

Thanks for the post and files.

 

I am a noob and tried to do something similar with the BMP085 and MSP430G2231 when the launchpad was released and never could get I2C to work correctly. Given the flash limitations of that chip, not sure it would have been possible...

 

Your work inspired me to update ccs, install grace, and get it working! BTW, for any other noobs reading this, you will need to attach pullup resistors to SCL & SDA, jumper the TXD and RXD pins since they seem reversed on the 2553, and remove the jumper for pin 1.6 that connects it to the Launchpads LED2.

 

Grace seems nice. It is very easy for a noob to get stuck configuring pins, clocks, etc. It was nice to refer back to see what speed you had the UART running at, the pinout for SCL/SDA, etc.

 

Great stuff!

 

Thanks again...

 

could you please post your code?

Link to post
Share on other sites

Hello pfactorial, the code in the 1st post is all there is. It will not work on a G2231. The code is built for devices with USCI. The 2231 only has USI. That code, with minor timing and interrupt flag changes, definitely works on F2274, G2553, F5529, FR5739.

 

If you're a noob, you should consider looking at the grace project. If you're using CCS v5.1, import the project and double-click on the main.cfg file inside the project explorer. That will let you see how all of the hardware is configured.

Link to post
Share on other sites
Hello pfactorial, the code in the 1st post is all there is. It will not work on a G2231. The code is built for devices with USCI. The 2231 only has USI. That code, with minor timing and interrupt flag changes, definitely works on F2274, G2553, F5529, FR5739.

 

If you're a noob, you should consider looking at the grace project. If you're using CCS v5.1, import the project and double-click on the main.cfg file inside the project explorer. That will let you see how all of the hardware is configured.

Oh. I see.

 

But the msp430g2211 has USCI, right?

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...