cancel
Showing results for 
Search instead for 
Did you mean: 

PSoC 4 MCU

New Contributor II

I'm setting up the PSoC4 BLE chip to read in data from a light sensor. Should the I2C component be set as the master mode or slave mode? (I'm thinking that the light sensor is the slave and PSoC4 BLE is the master - how does this affect the I2C component?)

   

 

   

Is it necessary to manually set the slave address in main.c using the API I2C_I2CSlaveSetAddress? or is setting the slave address in the dialog box when clicking on the I2C component enough / the correct way? 

   

 

   

Also, where are the write commands? I've built the project so I have all the c and h files but can't seem to find APIs such as I2C_I2CMasterWriteBuf that are in the pressure sensor example project. 

   

 

   

Thanks,

   

Caroline

0 Likes
Reply
1 Solution
Esteemed Contributor II

You are reading a 16bit value split into two separate bytes. So you will need to combine these bytes to a 16 bit integer. I normally use

   

int16 Result;

   

uint8 msb,lsb;

   

Result = (int16)msb << 8 | lsb;

   

where msb and lsb are the two values red from your slave.

   

msb =  I2C_MasterReadByte(I2C_ACK_DATA);            // Read from register

   

lsb =  I2C_MasterReadByte(I2C_NAK_DATA);            // Read from register, last byte is NAKed

   

Of course you may shorten this.

   

 

   

 

   

Bob

View solution in original post

0 Likes
Reply
7 Replies
Esteemed Contributor II

I'm thinking that the light sensor is the slave and PSoC4 BLE is the master That's right

   

Is it necessary to manually set the slave address in main.c using the API I2C_I2CSlaveSetAddress? or is setting the slave address in the dialog box when clicking on the I2C component enough / the correct way?  No to both. The BLE is a master that can address multiple slaves. You need the 7-bit slave address from your sensor(s) to address it.

   

Byte I2C interface is quite simple: After setting up the component and starting it you use

   

    I2C_MasterSendStart(DeviceAddress,I2C_WRITE_XFER_MODE);    // Initialize a transaction for writing
    I2C_MasterWriteByte(Register);                // Indicate which register you want to write to
    I2C_MasterWriteByte(Value);                // Write to register
    I2C_MasterSendStop();                    // End of transaction

   

When you want to read from a device you use (example for reading two bytes

   

    I2C_MasterSendStart(DeviceAddress,I2C_WRITE_XFER_MODE);    // Initialize a transaction for writing
    I2C_MasterWrite(Register);                // Indicate which register you want to write to
    I2C_MasterSendRestart(DeviceAddress,I2C_READ_XFER_MODE);
    I2C_MasterReadByte(I2C_ACK_DATA);            // Read from register
    I2C_MasterReadByte(I2C_NAK_DATA);            // Read from register, last byte is NAKed
    I2C_MasterSendStop();                    // End of transaction

   

Also, where are the write commands All APIs are prefixed ba your component name which might be "I2C_1" when you didn't change it in the configuration dialog.

   

 

   

Bob

0 Likes
Reply
New Contributor II

Thanks!! So helpful. 

   

 

   

So the first byte that is read from the sensor is the "msb" and the second byte is the "lsb"

   

 

   

How do I set the byte value = msb ? Is that a simple variable declaration? (msb = I2C_I2C_ACK-DATA) after the reading is done 

0 Likes
Reply
Esteemed Contributor II

You are reading a 16bit value split into two separate bytes. So you will need to combine these bytes to a 16 bit integer. I normally use

   

int16 Result;

   

uint8 msb,lsb;

   

Result = (int16)msb << 8 | lsb;

   

where msb and lsb are the two values red from your slave.

   

msb =  I2C_MasterReadByte(I2C_ACK_DATA);            // Read from register

   

lsb =  I2C_MasterReadByte(I2C_NAK_DATA);            // Read from register, last byte is NAKed

   

Of course you may shorten this.

   

 

   

 

   

Bob

View solution in original post

0 Likes
Reply
New Contributor II

Got it, thanks! 

   

I'm having trouble with "multiple definition" errors - I've attached an OPT3001 test project. Are there any blatant errors where I'm calling variables twice?

0 Likes
Reply
Esteemed Contributor II

Caroline, you used in main.c

   

#include <BLEapp.c>

   


aamof you should only #include .h files, furthermore do not define any variables or functions in a .h. Onl use declarations.

   

A .h usually has got a scheme like

   

#ifndef filename__h

   

#define filename__h

   

... file body

   

#endif

   

This ensures that a .h file can be #included multiple times within a project (as should be with your main.h)

   

 

   

Bob

0 Likes
Reply
New Contributor II

Okay, that makes sense. I think that I have all files called properly now. 

   

 

   

I am now working on sending the two bytes read from the OPT3001 register and viewing those bytes using the CySmart BLE dongle / PC app. I've written a function that sends data of type uint8 but as you mentioned before I need to send a 16 bit integer since that's what the result is. How is this typically done? Do I simply change the function to send a 16 bit integer? 

0 Likes
Reply
New Contributor II

Okay, that makes sense. I think that I have all files called properly now. 

   

 

   

I am now working on sending the two bytes read from the OPT3001 register and viewing those bytes using the CySmart BLE dongle / PC app. I've written a function that sends data of type uint8 but as you mentioned before I need to send a 16 bit integer since that's what the result is. How is this typically done? Do I simply change the function to send a 16 bit integer? 

   

 

   

Also, is it possible to directly display a decimal instead of hex number in the CySmart "Value"  column?

   

Thanks for all of your help!

0 Likes
Reply