gwdeveloper 275 Posted July 28, 2011 Share Posted July 28, 2011 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 *)®_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; } displacedtexan, pfactorial, davidbowie and 5 others 8 Quote Link to post Share on other sites
bluehash 1,581 Posted July 29, 2011 Share Posted July 29, 2011 Thanks GWD. Quote Link to post Share on other sites
displacedtexan 1 Posted August 6, 2011 Share Posted August 6, 2011 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... pfactorial 1 Quote Link to post Share on other sites
gwdeveloper 275 Posted August 6, 2011 Author Share Posted August 6, 2011 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. Quote Link to post Share on other sites
pfactorial 7 Posted December 24, 2011 Share Posted December 24, 2011 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? Quote Link to post Share on other sites
bluehash 1,581 Posted December 24, 2011 Share Posted December 24, 2011 "jumper the TXD and RXD pins since they seem reversed on the 2553" If you are using a 2553 on the launchpad, you need to swap the RX/TX pins. Quote Link to post Share on other sites
timotet 44 Posted December 24, 2011 Share Posted December 24, 2011 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 Quote Link to post Share on other sites
gwdeveloper 275 Posted December 24, 2011 Author Share Posted December 24, 2011 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 Quote Link to post Share on other sites
pfactorial 7 Posted December 25, 2011 Share Posted December 25, 2011 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. Quote Link to post Share on other sites
pfactorial 7 Posted December 25, 2011 Share Posted December 25, 2011 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? Quote Link to post Share on other sites
pfactorial 7 Posted December 25, 2011 Share Posted December 25, 2011 Also it works weird-ly with CCSv5 Quote Link to post Share on other sites
pfactorial 7 Posted December 25, 2011 Share Posted December 25, 2011 430F22x4.Instance#0: no property named 'P1SEL2' main.cfg /bmp085_2553 20 C/C++ Problem That's what happens after changing to MSP430G2231 Quote Link to post Share on other sites
pfactorial 7 Posted December 25, 2011 Share Posted December 25, 2011 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? Quote Link to post Share on other sites
gwdeveloper 275 Posted December 25, 2011 Author Share Posted December 25, 2011 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. Quote Link to post Share on other sites
pfactorial 7 Posted December 25, 2011 Share Posted December 25, 2011 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? Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.