I2C Comms with Orientation Sensor

I2C Comms with Orientation Sensor

Postby GettinBetter » Sat Jan 18, 2020 10:07 pm

I2C Comms with Orientation Sensor
This thread is partially a continuation of this topic http://picforum.ric323.com/viewtopic.php?f=5&t=745
But since the hardware has changed & the subject matter is not the MCC, I think it is better to start afresh here.

HW: Explorer 16/32 ver3, 8MHz, PIC33CH128MP508 PIM
SW: MPLABX v5.3, MCC, XC16, terminal via UART1/mini USB
Slave: BNO055 Absolute Orientation Sensor
Aims: Output BNO data to terminal via UART.

PIN Config:
Debug (PGEC2 dp 45, PGED2 dp 43).
I2C (SCL dp 60, SDA dp 61).
UART (Tx dp 50 - pp 49, Rx dp 49, pp 51).
In order to get the UART to USB (hence out to terminal) requires that the Explorer16/32 board j48 block pin49 be linked to pin 52 & J48 block pin 50 to pin 51.
[dp = device(chip)pin]
[pp = PIM pin]


Hi Peeps,
Using Microchips generated example code in the I2C1.h file, I'm struggling to create my version Transaction Request Blocks, specifically the *pData & writebuffer.

Because this code is written with EEPROM in mind, the code is constructed to use (I believe) a two byte address whereas my device only requires a single byte address. (Am I correct?)

Also *pData , I know it's a pointer but what should I do with it in this case?


Code: Select all
#include "mcc_generated_files/system.h"
#include "mcc_generated_files/mcc.h"
#include <libpic30.h> //Defines __delay32();
#include <stdio.h> // Defines printf("");
 
 
uint16_t slaveDeviceAddress = 0x29;         //BNO device address
uint16_t dataAddress = 0x34;                //BNO device temperature read only register address

int main(void)
{
    // initialise the device
    SYSTEM_Initialize();
 
    //Program and enable slave
    SLAVE1_Program();
    SLAVE1_Start();     //Slave NOT used in this test

    printf("Explorer 16/32 DM240001-3, ICD3, dsPIC33CH128PM508 PIM\n\r");
    printf("MPLABX v5.3, MCC v3.85.1, XC16 v1.41\n\r");
    printf("Add I2C to test prog\n\r");
   
   
#define SLAVE_I2C_GENERIC_SLAVE_TIMEOUT     50
#define SLAVE_I2C_GENERIC_RETRY_MAX         100
   
    uint8_t ncount = 1;
    uint8_t result;
    result = BNO_Read(slaveDeviceAddress,dataAddress,*pData, ncount);
    printf("BNO Temperature is:  %d ", result);

           while (1);
}

//        @Example code obtained from I2C1.h
//        <code>
uint8_t BNO_Read(uint16_t slaveDeviceAddress,uint16_t dataAddress,uint8_t *pData,uint16_t nCount)
            {
                I2C1_MESSAGE_STATUS status;
                I2C1_TRANSACTION_REQUEST_BLOCK readTRB[2];
                uint8_t     writeBuffer[3];
                uint16_t    timeOut, slaveTimeOut;

                // this initial value is important
                status = I2C1_MESSAGE_PENDING;

                // build the write buffer first
                // starting address of the EEPROM memory
                writeBuffer[0] = (dataAddress >> 8);        // high address
                writeBuffer[1] = (uint8_t)(dataAddress);    // low low address

                // we need to create the TRBs for a random read sequence to the EEPROM
                // Build TRB for sending address
                I2C1_MasterWriteTRBBuild(&readTRB[0],writeBuffer,2,slaveDeviceAddress);
                // Build TRB for receiving data
                I2C1_MasterReadTRBBuild(&readTRB[1],pData,nCount,slaveDeviceAddress);

                timeOut = 0;
                slaveTimeOut = 0;

                while(status != I2C1_MESSAGE_FAIL)
                {
                    // now send the transactions
                    I2C1_MasterTRBInsert(2, readTRB, &status);

                    // wait for the message to be sent or status has changed.
                    while(status == I2C1_MESSAGE_PENDING)
                    {
                        // add some delay here

                        // timeout checking
                        // check for max retry and skip this byte
                        if (slaveTimeOut == SLAVE_I2C_GENERIC_SLAVE_TIMEOUT)
                            return (0);
                        else
                            slaveTimeOut++;
                    }

                    if (status == I2C1_MESSAGE_COMPLETE)
                        break;

                    // if status is  I2C1_MESSAGE_ADDRESS_NO_ACK,
                    //               or I2C1_DATA_NO_ACK,
                    // The device may be busy and needs more time for the last
                    // write so we can retry writing the data, this is why we
                    // use a while loop here

                    // check for max retry and skip this byte
                    if (timeOut == SLAVE_I2C_GENERIC_RETRY_MAX)
                        return (0);
                    else
                        timeOut++;

                }
                return (1);
            }
//        </code>



Any suggestions/advice greatly appreciated.

Regards
Les
History teaches us that history doesn't teach us.
User avatar
GettinBetter
 
Posts: 43
Joined: Wed Jun 06, 2018 8:48 pm

Return to dsPIC33CH

Who is online

Users browsing this forum: No registered users and 2 guests

cron