• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

dsPIC33CH128MP508 PIM I2C Coms Issue

GettinBetter

New Member
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 BNO055 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 Guys,
I'm a bit of a noob with 'C' programming, but (as my name suggests) I'm getting better...
I'm using the MCC in the above named software to generate the code but, there are sections that require customisation/additional code etc.

The code in the i2c.h file shows a MasterRead & MasterWrite examples, but the read from EEPROM example requires a TRB to be setup. now I'm thinking that as the read & write functions are only single byte action, that they could be passed directly to the function.
Below I have removed all the timeout & retry counts for clarity (I can add maybe them later)

C:
/**
    @Summary
        Handles one i2c master read transaction with the
        supplied parameters.

    @Description
        This function prepares a TRB, then inserts it on the i2c queue.
        Finally, it waits for the transaction to complete and returns
        the result.

    @Preconditions
        None

    @Param
        address - The address of the i2c peripheral to be accessed
    
    @Param
        length - The length of the data block to be sent
    
    @Param
        *pdata - A pointer to the memory location where received data will
                 be stored

    @Param
        *pstatus - A pointer to the status variable that the i2c driver
            updates during the execution of the message.

    @Returns
        I2C1_MESSAGE_STATUS

    @Example
        <code>

/* address -The address of the i2c peripheral to be accessed.
*  length - The length of the data block to be sent.
*  *pdata - A pointer to the memory location where received data will be stored.
*  *pstatus - A pointer to the status variable that the i2c driver updates during the execution of the message.
*/
            uint8_t BNO055_Read(uint16_t address, uint8_t *pData, uint16_t nCount)
            {
            I2C1_MESSAGE_STATUS status;
            uint8_t     *pD;
            uint16_t address = 0x29;         // slave device address
            uint8_t length = 1;
            uint8_t *pData;

                pD = pData;

                    while(status != I2C1_MESSAGE_FAIL)
                    {
                    void I2C1_MasterWrite(uint8_t *pdata, uint8_t length, uint16_t address, I2C1_MESSAGE_STATUS *pstatus);
                        while(status == I2C1_MESSAGE_PENDING)
                        {
                             __delay32(5000);
                            
                        }

                        if (status == I2C1_MESSAGE_COMPLETE)
                            break;
                    }

                    if (status == I2C1_MESSAGE_COMPLETE)
                    {

                        // this portion will read the byte from the BNO Temperature register location.

                        while(status != I2C1_MESSAGE_FAIL)
                        {
                            I2C1_MasterRead( pD, 1, BNO055_ADDRESS, &status);

                            while(status == I2C1_MESSAGE_PENDING)
                            {
                                __delay32(5000);       
                            }

                            if (status == I2C1_MESSAGE_COMPLETE)
                                break;
                        }
                    }

                    // exit if the last transaction failed
                    if (status == I2C1_MESSAGE_FAIL)
                    {
                        return(0);
                        break;
                    }
                }
                return(1);
            }
 
//        </code>
I've attached the original MCC generated file for your perusal.
Am I on the right path, or am I approaching this from the wrong angle? Any feedback would be appreciated.
Regards
GB
 

Attachments

Pommie

Well-Known Member
Most Helpful Member
The MCC module produces incomprehensible code. Start with a simple pic16 chip, work out how to program that and then move on to more advanced chips. Why do you want to jump in at the deep end?

Mike.
 

GettinBetter

New Member
The MCC module produces incomprehensible code...

Mike.
That's becoming clearer, as I dig deeper the irregularities are becoming obvious.
I started with 8bit, then 16, each time realising they wouldn't be able to fulfill my projects requirements. A learning curve is a learning curve ..
 

rjenkinsgb

Well-Known Member
Most Helpful Member
The MCC code is a nightmare..

If you plan to do any serious work in C with PIC MCUs, I'd strongly recommend you get the CCS compiler.
That still works with MPLab for editing, compiling and debugging - but all functions are far easier to use.

eg. Reading a block of data from an I2C device, in the simplest form, can be done with a single function i2c_transfer(), though It does have many more discrete configuration and transfer functions as well.

C:
unsigned int8 rData[16];

int1 ack;
// rData is a pointer to the location the data read in will be stored

ack=i2c_transfer_in(0xA0,rData,16);

if(ack==0)
     printf("Data read successfully");
else
     printf("data not read");
You can download the compiler manual here, to have a look through it.

In general the functions and C code for any feature are the same for any type/size PIC, as long as the relevant peripheral is present in the device being used.
 

Latest threads

EE World Online Articles

Loading

 
Top