- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm having trouble using an I2C connection between my CYBLE-014008-00 and an AD5933 bio impedance chip. This is what I have for my master read and master write functions but I am not sure if they are correct. Any help with these functions would be greatly appreciated.
bool writeByte(uint8 Reg, uint8 value) {
// Send byte to address
I2C_1_I2CMasterSendStart(AD5933_ADDR, I2C_1_I2C_WRITE_XFER_MODE, 1000);
I2C_1_I2CMasterWriteByte(Reg, 1000);
// Ensure transmission worked
if (I2C_1_I2CMasterStatus() != I2C_1_I2C_MSTAT_WR_CMPLT)
{
I2C_1_I2CMasterSendStop(1000);
return false;
}
I2C_1_I2CMasterWriteByte(value, 1000);
// Ensure transmission worked
if (I2C_1_I2CMasterStatus() != I2C_1_I2C_MSTAT_WR_CMPLT)
{
I2C_1_I2CMasterSendStop(1000);
return false;
}
I2C_1_I2CMasterSendStop(1000);
return true;
}
uint8 readByte(uint8 Reg, uint8 *value) {
// Request to read a byte using the address pointer register
I2C_1_I2CMasterSendStart(AD5933_ADDR, I2C_1_I2C_WRITE_XFER_MODE, 1000);
I2C_1_I2CMasterWriteByte(Reg, 1000);
// Ensure transmission worked
if (I2C_1_I2CMasterStatus() != I2C_1_I2C_MSTAT_WR_CMPLT)
{
I2C_1_I2CMasterSendStop(1000);
return false;
}
I2C_1_I2CMasterSendRestart(AD5933_ADDR,I2C_1_I2C_READ_XFER_MODE, 1000);
*value = I2C_1_I2CMasterReadByte(I2C_1_I2C_NAK_DATA, value, 1000);
I2C_1_I2CMasterSendStop(1000);
return true;
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I would also put a status check after SendStart() , as we often get an error here,
such as the slave device is busy , absent, or slave address is wrong, etc...
==========================
uint32 retStatus ;
retStatus = I2C_1_I2CMasterSendStart(AD5933_ADDR, I2C_1_I2C_WRITE_XFER_MODE, 1000);
if (retStatus != I2C_1_I2C_MSTR_NO_ERROR) {
I2C_1_I2CMasterSendStop(1000);
return false;
}
I2C_1_I2CMasterWriteByte(Reg, 1000);
==========================
Also I may want to add some delay after sending the register address before start reading the value
depending on the slave device.
moto
(Edited: Some English Spells)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for your suggestion. The status check after SendStart() returns I2C_1_I2C_MSTR_NOT_READY. The documentation on this error suggests that either a master or slave operation is in progress but no other I2C functions are running before I try to communicate with the AD5933. Any thoughts on what may be causing this error?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
When SendStart() fails, I would imagine the followings...
(1) I2C signals are not pulled up
Please make sure that both SCL and SDA are pulled up to VDD via 2K ~ 10K resistors.
(2) I2C component has not been initialized.
Please call function to initialize and start I2C_1 component.
In PSoC Creator, we do
I2C_1_Start()
(3) The sensor has not been powered up
(Probably this is not the case, though)
(4) The slave address is wrong
Please make sure that AD5933_ADDR is correct 7bit I2C address of you device's current configuration.
Note: Some device has selectable I2C address depending on the pin state at power up.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
1) I currently am using 2.2K pull ups resistors but have tried as high as 5K resistors
2) I call I2C_1_Start(); in my initialization function where I start the other components being used
3) The senor is on the same power supply as the CYBLE chip
4) the AD5933 datasheet specifies and address of 0x0D which is the address I am using
AD 5933 Datasheet I have included a link for the sensor's datasheet as I am still getting the same error on SendStart(). I will also include my initialization function at the end of this reply.
void Initialize(void)
{
Opamp_1_Start();
Opamp_2_Start();
Opamp_1_Sleep();
Opamp_2_Sleep();
ADC_Start();
ADC_Sleep();
RTC_Start();
RTC_SetPeriod(1, 256);
Ctl.state = OPSTATE_SLEEP; // load variables before initializing the NEMO
Ctl.samplesPerEntry = EEpromPointer[EE_IDX_samplesPerEntry];
Ctl.wakeupThreshold = EEpromPointer[EE_IDX_wakeupThreshold]; // inactivity wakeup threshold (0 to 63.)
Ctl.buzzer = EEpromPointer[EE_IDX_buzzer];
SPI_Start();
SPI_Sleep();
I2C_1_Start();
EventWriteIndex = FindFirstEmptyEvent();// now initialize event write index
Ctl.events = GetEventCount(EventWriteIndex);
CyDelay(200);
CyGlobalIntEnable;
CyBle_Start(GeneralEventHandler); // BLE on
CySysWdtSetInterruptCallback(CY_SYS_WDT_COUNTER2, WatchdogTimerISR);
CySysWdtEnableCounterIsr(CY_SYS_WDT_COUNTER2);
#ifdef UART_DEBUG
UART_Start();
#endif
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I think that you have been doing everything OK.
There were a couple of minor points, I'd like to mention.
(they may not fix the problem though)
(1) In the datasheet you provided the URL,
pull-up resistor for SDA and SCL are specified as 10 kOhm in the Table 4.
(2) As I2C requires interrupt to operate,
I would call
I2C_1_Start() ;
after
CyGlobalIntEnable;
moto
Edited: On 14-Jan-2021 Table 4 picture was added.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for your reply. I implemented the changes you suggested and now MasterSendStart() is returning an error of I2C_1_I2C_MSTR_ERR_LB_NAK.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
The error seems to be "Last Byte Naked".
In my experience, this can happen if the slave device at the specified address is absent.
I would check
- If the connections of SDA, SCL, VDD, GND are correct.
I have made this mistake not once. - If the sensor is not broken.
I wonder how we can test this, may be try another device? - Monitor the signals of SDA and SCL using an oscilloscope.
moto