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