Monday, September 12, 2011

Integration of BOSCH BMP085 using JENNIC 2-wire serial interface (I2Ccompatible) on JN-5148

The article describes use of Jennic hardware API library (AppHardwareApi_JN514x.h) for reading and writing data from the BOSCH BMP085 temperature and pressure sensor.

Hardware Description:
- The Jennic JN-5148 provides 2-wire synchronous serial interface, following I2C protocol, containing two lines of SCL (Serial Clock Line) connected to DIO14 and bi-directional SDA (Serial Data Line) connected to DIO15. The detailed description of Jennic Serial Interface and associated functions can be found at http://www.jennic.com/files/support_files/JN-UG-3066-Integrated-Peripherals-API.pdf.

- The BOSCH BMP085 consists of SCL (Serial Clock Line) connected to pin 6 and bi-directional SDA (Serial Data Line) connected to pin 7. The comprehensive description of BMP085 can be found at http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP085-DS000-05.pdf.

Protocol Implementation Algorithm:
Major focus of this article is on how to communicate with BMP085 in order to read/write operations, and mathematical calculations for temperature and pressure can be found in the datasheet of BMP085.
Implementation is based on configuring Jennic as Master without interrupts enable and BMP085 as Slave device. The operational frequency 100 kHz is derived from Jennic system clock of 16 MHz by using pre-defined formula,

Operational Frequency = 16/[(Prescaler + 1) * 5]

Steps:
  • Jennic as Master Device and BMP085 as Slave Device configuration
  • Read calibration data from E2PROM of BMP085 for temperature and pressure
  • Reading and calculation of temperature
  • Reading and calculation of pressure
  • Resolution of output data is; Pressure – 0.01 hPa, and Temperature – 0.1 ˚C
Associated Jennic Functions:
  • void vAHI_SiMasterConfigure (bool_t bPulseSuppressionEnable, bool_t bInterruptEnable, uint8 u8PreScaler);
  • void vAHI_SiMasterWriteSlaveAddr (uint8 u8SlaveAddress, bool_t bReadStatus);
  • bool_t bAHI_SiMasterSetCmdReg (bool_t bSetSTA, bool_t bSetSTO, bool_t bSetRD, bool_t bSetWR, bool_t bSetAckCtrl, bool_t bSetIACK);
  • bool_t bAHI_SiMasterPollTransferInProgress (void);
  • void vAHI_SiMasterWriteData8 (uint8 u8Out);
  • uint8 u8AHI_SiMasterReadData8 (void);
Reading/Writing data from BMP085:
From the datasheet the BMP module address LSB distinguishes between read (1) and write (0) operations, corresponding to address 0xEF (read) and 0xEE (write). Where 0x77 is the BMP085 device address which will be Slave address.

// Sensor Address - Write Operation
uint8 BMP085_W = 0xEE;
// Sensor Address - Read Operation
uint8 BMP085_R  = 0xEF;

PRIVATE void vI2CRead (uint8 u8ReadAddress, uint8* u8DataOut, uint8 u8Length)
{
          uint8 i = 0;
          uint8 u8ReadLength;
          bool_t bFlag = FALSE;
          u8ReadLength = u8Length;
          vAHI_SiMasterWriteSlaveAddr (BMP085_W>>1, FALSE); // FALSE - Write Operation
          bFlag = bAHI_SiMasterSetCmdReg (E_AHI_SI_START_BIT,
                                                                      E_AHI_SI_NO_STOP_BIT,
                                                                      E_AHI_SI_NO_SLAVE_READ,
                                                                      E_AHI_SI_SLAVE_WRITE,
                                                                      E_AHI_SI_SEND_ACK,
                                                                      E_AHI_SI_NO_IRQ_ACK);
          while(bAHI_SiMasterPollTransferInProgress());    // Wait While Busy
          vAHI_SiMasterWriteData8(u8ReadAddress);          // Address to Start Read From
          bFlag = bAHI_SiMasterSetCmdReg(E_AHI_SI_NO_START_BIT,
                                                                      E_AHI_SI_NO_STOP_BIT,
                                                                      E_AHI_SI_NO_SLAVE_READ,
                                                                      E_AHI_SI_SLAVE_WRITE,
                                                                      E_AHI_SI_SEND_ACK,
                                                                      E_AHI_SI_NO_IRQ_ACK);
          while(bAHI_SiMasterPollTransferInProgress());    // Wait While Busy
          vAHI_SiMasterWriteSlaveAddr(BMP085_R>>1,TRUE); // TRUE - Read Operation
          vAHI_SiMasterSetCmdReg(E_AHI_SI_START_BIT,
                                                  E_AHI_SI_NO_STOP_BIT,
                                                  E_AHI_SI_NO_SLAVE_READ,
                                                  E_AHI_SI_SLAVE_WRITE,
                                                  E_AHI_SI_SEND_ACK,
                                                  E_AHI_SI_NO_IRQ_ACK);
          while(bAHI_SiMasterPollTransferInProgress()); // wait while busy
          // now we can start reading data back from the eeprom
          while(u8ReadLength > 0)
          {
                    if(u8ReadLength < 2)    // is it the last byte
                    {
                              vAHI_SiMasterSetCmdReg(E_AHI_SI_NO_START_BIT,
                                                                      E_AHI_SI_STOP_BIT,
                                                                      E_AHI_SI_SLAVE_READ,
                                                                      E_AHI_SI_NO_SLAVE_WRITE,
                                                                      E_AHI_SI_SEND_NACK,
                                                                      E_AHI_SI_NO_IRQ_ACK);
                    }
                    else
                    {
                              vAHI_SiMasterSetCmdReg(E_AHI_SI_NO_START_BIT,
                                                                      E_AHI_SI_NO_STOP_BIT,
                                                                      E_AHI_SI_SLAVE_READ,
                                                                      E_AHI_SI_NO_SLAVE_WRITE,
                                                                      E_AHI_SI_SEND_ACK,
                                                                      E_AHI_SI_NO_IRQ_ACK);
                    }
                    while(bAHI_SiMasterPollTransferInProgress()); // wait while busy
                    u8DataOut[i] = u8AHI_SiMasterReadData8();
                    i=i+1;
                    u8ReadLength--;
          }
}

PRIVATE void vI2CWrite (uint8* u8DataIn, uint8 u8Length)
{
          uint8 i = 0;
          uint8 u8WriteLength;
          u8WriteLength = u8Length;
          // set slave address
          vAHI_SiMasterWriteSlaveAddr(BMP085_W >> 1,FALSE);
          bAHI_SiMasterSetCmdReg(E_AHI_SI_START_BIT,
                                                  E_AHI_SI_NO_STOP_BIT,
                                                  E_AHI_SI_NO_SLAVE_READ,
                                                  E_AHI_SI_SLAVE_WRITE,
                                                  E_AHI_SI_SEND_ACK,
                                                  E_AHI_SI_NO_IRQ_ACK);
          while(bAHI_SiMasterPollTransferInProgress()); // wait while busy
          // now we can start writing data to the device
          while(u8WriteLength > 0)
          {
                    // data to write
                    vAHI_SiMasterWriteData8(u8DataIn[i++]);
                    if(u8WriteLength < 2)    // is it the last byte
                    {
                              bAHI_SiMasterSetCmdReg(E_AHI_SI_NO_START_BIT,
                                                                      E_AHI_SI_STOP_BIT,
                                                                      E_AHI_SI_NO_SLAVE_READ,
                                                                      E_AHI_SI_SLAVE_WRITE,
                                                                      E_AHI_SI_SEND_NACK,
                                                                      E_AHI_SI_NO_IRQ_ACK);
                    }
                    else
                    {
                              bAHI_SiMasterSetCmdReg(E_AHI_SI_NO_START_BIT,
                                                                      E_AHI_SI_NO_STOP_BIT,
                                                                      E_AHI_SI_NO_SLAVE_READ,
                                                                      E_AHI_SI_SLAVE_WRITE,
                                                                      E_AHI_SI_SEND_ACK,
                                                                      E_AHI_SI_NO_IRQ_ACK);
                    }
                    u8WriteLength--;
                    while(bAHI_SiMasterPollTransferInProgress()); // wait while busy
          }
}

I spent few days in understanding I2C protocol in general to start integration of pressure sensor with Jennic board, so I thought it would be beneficial to write in blog for others who found difficulty as well.

If anyone still interested in complete code, you can ask. I can send it you :)

17 comments:

  1. [...] is the original post: Integration of BOSCH BMP085 using JENNIC 2-wire serial interface … Category: Bez kategorii Tags: api, article-describes, bosch, hashim, jennic, [...]

    ReplyDelete
  2. Clarita Calvo GonzalezSeptember 13, 2011 at 6:58 PM

    Hi! hola, yo estoy intentando comunicarme con un RTC DS1307 desde el jn5148,tb por i2C.
    Si pudieras echarme una mano.....
    He puesto tu codigo, pero nose como introducir las incializaciones en los registros del Real time clock....

    ReplyDelete
  3. Clarita Calvo GonzalezSeptember 13, 2011 at 7:09 PM

    Sorry...jajaj, i read your post and thought in spanish.... :-S....
    I try to add one RTC DS1307 with my jn5148. Your post is the most explanatory and easy that i have read.
    And at least, you offer some help!!
    I connect my RTC with JN5148, use your code, because i dont understand very well the protocol I2C after read jennic 2-wire. I find information about sensor, but i use one real time clock.
    How can i initilize the reister of DS1307??
    How is the comunication between jennic and RTC??
    I have programmed time&data code, but when turn off my device, the time configuration is erased, so i want to add a external RTC.
    Thanksss

    ReplyDelete
  4. Hi Clara!!
    I will take a look on datasheet of DS1307, and will let you know how it will work with Jennic. Be patient, I hope you are not in hurry :)
    Thanks

    ReplyDelete
  5. Clarita Calvo GonzalezSeptember 13, 2011 at 7:24 PM

    uuuf....im crazy with jennic.....I design a inteligent system control for streetlight. I do it with arduino, and now with jennic and zigbee Pro, so in this moment i stay studied i2c and communicate with other device!!! its marvelous....grrrrr. a lot of work.....ajjajajaja.
    Thanks Hashim!!

    ReplyDelete
  6. DS1307
    Slave Device Addr = 0xD0>>1
    Write Operation = 0xD0
    Read Operation = 0xD1

    Then, according to datasheet of DS1307, in order to write any specific Timekeeper Register, first need to write slave address followed by 0xD0 (for writing) and then register address (e.g. 0x00 for seconds) and then send the data which you want to write.

    Similarly, for reading data first write slave address, then for reading data write 0xD1 and then register address you want to read (e.g. 0x00 for reading seconds).

    I will suggest you to read carefully Table 2, Figure 4, and Figure 5, so you will get every information from there.

    Apart from this, the code I upload in the blog is for reading and writing 2 bytes but in your case you need to read/write only one byte, so you have to change little bit there and of course Slave Address, Reading/Writing Address, and rest would be the same.

    I am not sure you are actually interested in backup battery for the first run of the project so there is no need to configure Control Register for the moment (this is what I understood from datasheet).

    Moreover, you can also utilize RAM to store time and date in case of battery failure or something else so you can retrieve data from RAM, rather to write again from scratch.
    I hope you can integrate this, but if need help we can look again :)

    ReplyDelete
  7. Clarita Calvo GonzalezSeptember 14, 2011 at 3:23 PM

    Thank you very much....I try this, and i tell you. If i need more help, i upload my code and we look it.
    muuuak. GRACIASSS

    ReplyDelete
  8. Hi! No problem at all. Plz share in any case with me, I would like to see the integration process. Maybe you can share your blog if you have.
    Have good work :)
    Thanks

    ReplyDelete
  9. Clarita Calvo GonzalezSeptember 14, 2011 at 6:11 PM

    Ok!! I havent Blog, but my code is you code ;-).
    I need look sec, min, hour trough the UART0....i will tell you..... muak

    ReplyDelete
  10. Clarita Calvo GonzalezSeptember 14, 2011 at 7:27 PM

    I dont understand that instruction i have to use to indicate the direction of registration and data sent. I read the datasheet, and JN-UG-3066 to send data to 2-wire..grrrr

    ReplyDelete
  11. Clarita Calvo GonzalezSeptember 14, 2011 at 7:30 PM

    PRIVATE void vI2CWrite (0x00, 0)

    register of seconds: 0x00
    initilize : 0

    is it the call??

    ReplyDelete
  12. Hey, I sent you email as well. I am little busy right now. Can you send me your code, what you have already written so far.
    Don't get worry, it will work :)

    ReplyDelete
  13. Clarita Calvo GonzalezSeptember 14, 2011 at 9:12 PM

    nonono !!!!! I do not want you to work for me! I just wondered if the call from main function was correct. Quiet, I get it! thank you very much and do not bother you any more ... ha ha ha, for now!

    thankkkkkss

    ReplyDelete
  14. Hey Hashim
    Well I have no clue what to do with this device. I have Jennic 5148 with the controller and the sensor, as we know that it is loaded with the default program to display the temperature,humidity and light via sensor. I want to flash this to a program which senses the on and off state of a machine and then display the span it was on. I have never ever worked with micro controllers and the eclipse IDE. I have no idea where to start from. So far am I able to load the configurations and libraries. How do move ahead in the direction to achieve my goal. Please help (reply @abhinv@gmail.com )

    ReplyDelete
    Replies
    1. Hello!
      Sorry for late answer but I am sure you will not like it:(
      The help you are asking me is really tough at this moment. In fact, you need to learn by yourself first hardware architecture which you can find in the help documents. Eclipse C, is the same as normal C, you can imagine just the new interface, for the time being until you get used to of it.
      Firstly, you need to initialize sensors and check if they are working properly (You can use vPrintf() command to print out values), then you can integrate your desired code to get desired result.
      I hope you'll do it.

      Delete
  15. thanks for the tips and information..i really appreciate it.. LG Dishwasher Repair Near Me

    ReplyDelete
  16. Very informative post! There is a lot of information here that can help any business get started with a successful social networking campaign. Cooktop Repair Dacor, Wolf, Dcsc, Viking, Nxr, Bosch, Ge, Miele in Los Angeles

    ReplyDelete

Integration of SQLite3 and Netbeans C/C++ IDE

Few days back, I wanted to use SQLite database for one of my project. I spend couple of hours to find a way to integrate with Netbeans. Mayb...