- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi everyone,
i've been trying to read an EEProm over the I2c bus using a psoc4 BLE prototyping board.
no matter what i do i keep getting the i2c_bus_busy status.
The SCL and SDA lines are connected to the 5v line with a pair of 3,3kOhm resistors.
using this setup with, for example a raspberry pi does net results.
void i2cRead(int device,int memory, int length){
SCB2_I2CMasterWriteBuf(device, (uint8*) memory, 1,SCB2_I2C_MODE_NO_STOP);
status = SCB2_I2CMasterSendStart(device, SCB2_I2C_MODE_REPEAT_START);
/* Check if transfer completed without errors */
if(status == SCB2_I2C_MSTR_NO_ERROR ){
/* Read array of length bytes */
uint8_t i = 0;
for(i=0; i<length; i++){
rdBuf = SCB2_I2CMasterReadByte(SCB2_I2C_MODE_REPEAT_START);
}
SCB2_I2CMasterSendStop(); /* Send Stop */
//memset(rdBuf,0,128);
}
}
i'm stumped as to why this doesn't work, anyone have an idea?
- Labels:
-
BLE
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try
status = SCB2_I2CMasterWriteBuf(device, (uint8*) memory, sizeof(int),SCB2_I2C_MODE_NO_STOP);
/* Check if transfer completed without errors */
if(status == SCB2_I2C_MSTR_NO_ERROR )
{
/* Read array of length bytes */
status = SCB2_I2CMasterReadBuf(device,rdBuf,length,SCB2_I2C_MODE_REPEAT_START);
}
else SCB_I2CMasterSendStop();
}
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
Not too difficult. Keep in mind that most of the APIs (except those for reading a byte) return a status byte which, when non-zero indicate an error condition.
The high-level APIs must be used in this way:
Writing to slave Count bytes
I2C_MasterWriteBuf(SlaveAddress,DataPtr,Count,I2C_MODE_COMPLETE_XFER);
Reading from Slave sending register/command byte first:
I2C_MasterWriteBuf(SlaveAddress,&RegAddress,1,I2C_MODE_NO_STOP);
I2C_MasterReadBuf(SlaveAddress,DataPtr,Count,I2C_MODE_REPEAT_START);
Do not mix the high- and low level APIs
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi bob,
Thanks for your explanation on the High and low level api's i found the datasheet for the SCB block quite cumbersome to read
i've tried implementing your code, it returns 0x04, which (correct me if im wrong) corresponds to: SCB_2_I2C_MSTR_NOT_READY.
stepping trough the automatically generated code i find this:
uint32 SCB2_I2CMasterWriteBuf(uint32 slaveAddress, uint8 * wrData, uint32 cnt, uint32 mode)
{
uint32 errStatus;
errStatus = SCB2_I2C_MSTR_NOT_READY;
if(NULL != wrData) /* Check buffer pointer */
{
/* Check FSM state and bus before generating Start/ReStart condition */
if(SCB2_CHECK_I2C_FSM_IDLE)
{
SCB2_DisableInt(); /* Lock from interruption */
/* Check bus state */
errStatus = SCB2_CHECK_I2C_STATUS(SCB2_I2C_STATUS_BUS_BUSY) ?
SCB2_I2C_MSTR_BUS_BUSY : SCB2_I2C_MSTR_NO_ERROR;
}
else if(SCB2_CHECK_I2C_FSM_HALT)
{
SCB2_mstrStatus &= (uint16) ~SCB2_I2C_MSTAT_XFER_HALT;
errStatus = SCB2_I2C_MSTR_NO_ERROR;
}
else
{
/* Unexpected FSM state: exit */
}
}
considering that sometimes my eeproms start at 0x00 this method will always give me this error correct?
also writing 0x01 still gives me the bus_busy error.
Kind regards,
Ronald
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can you please post your complete project, so that we all can have a look at all of your settings. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Two bugs I can see:
status = SCB2_I2CMasterWriteBuf(device, (uint8*)&memory, sizeof(int),SCB2_I2C_MODE_NO_STOP);
How a simple "&" can change everything! You will need to care for high and low bytes (endianess) because "memory" is an int.
I2C addresses are always < 127 (0x7f).
There is an abiguity in the documentation: Some datasheet provide a 7-bit address (ie. Cypress) wihich is expanded by a trailing r/w bit and some docs are talking about 8-bit addresses including the r/w bit.
So your statement (there are some more...)
i2cRead(0xa0, 0x01, 16);
is wrong and should read as
i2cRead(0x50, 0x01, 16);
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi bob,
I've fixed said bugs. however no matter what i do, i still get this error.
to clarify the hardware setup: we're using the CY8CKIT-042-BLE with the EZ-BLE Proc Module
we've got the SDA line connected to pin 3.4 and the SCL line connected to 3.5 and the bus is running at 3.3V
i see no reason why this setup shouldn't work.
Thanks again,
Ronald
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please check the returned status of every I2C access to find out the place and reason of faillure.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi bob,
I've tried running a loop that reads a buffer from every i2c adress and returns the adress if the status isnt 0x08u,
i get nothing,
Kind regards,
Ronald
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Configure the i2c component to "Byte mode"
To find active I2C slaves try a loop with
Status = SendStart(address,readmode);
SendStop();
When you do not find any slaves you have got a hardware problem.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Or are you trying to access the on-board FRAM chip???
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi bob, what i tried so far was:
int i2cScan(char start,char stop)
{
int i;
for(i = start; i <stop; i++)
{
uint8 rddata[64];
status = SCB2_I2CMasterReadBuf(start, (uint8*) rddata, sizeof(int), SCB2_I2C_MODE_COMPLETE_XFER);
if(status != 0x08u )
{
return i;
}
}
return -1; // error if nothing found
}
which i've changed to:
int i2cScan(char start,char stop)
{
int i;
for(i = start; i <stop; i++)
{
int Status = SCB2_I2CMasterSendStart(i,SCB2_I2C_MODE_COMPLETE_XFER);
SCB2_I2CMasterSendStop();
if(status != 0x08u )
{
char str [40];
sprintf(str, "I2C addr: %d status: %d \n" , i,status);
SCB_UartPutString(str);
}
}
return -1; // error if nothing found
}
i seem to be having issues with both SCB's because printing to UART isn't working either.
i've attached several photos to show the current setup.
I've tried swapping Rx/Tx with no avail aswell
please note that both the individual i2c component and the UART work on the raspberry pi, so i'm quite sure its not that hardware
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can you please post your actual project, so that we all can have a look at all of your settings. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hi bob,
a bit of a breaktrough here. i thought i'd try accessing the onboard FRAM chip over i2c.
to my suprise this worked instantly, it was found by the i2cscan function and i could read/write to it using my program.
so code-wise there seems to be no issue.
i'm currently fiddling with the port allocation on the PSOC, trying to read from and external I2C device and writing to UART.
Both external connections don't seem to work.
i've tried the i2c bus on several ports,
port p0[5] , p1[5], and p3[5]. for the SCL
port p0[4], p1[4] and p3[4]. for the SDA
5[1] and 5[0] were the only one giving a result as it is connected to the FRAM chip. but that bus has no external connections otherwise.
is this an incompatibility between the cyble222014-01 and the devkit?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The only ways that I2C doesn't work are:
- Swapping scl and sda
- Bad pullup resistors
- Bad pin configuration (not in your case, pins are configured by component)
I would suggest to triple check. Have you got a logic analyzer?
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hi bob,
going by your list:
i can condirm i've got the SDA and SCL Lines laid out correctly.
to double check i've also tried with them reversed, but that didn't work either
both the SDA and SCL lines have a pullup resistor of 3.350 kOhm.
i believe this is in accordance with the I2C spec.
i've tried reading the data with a IIC logic analyzer, this shows no data being transmitted over the bus at all.
not even the start/stop commands. it always fails on the bus_busy check with 0x00000008 as error status
Then there's the issue of not seeing any data being sent over UART either.
Kind regards,
Ronald
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ale you seeing the clock at SCL pin? what level are SCL and SDA?
What is connected to your UART pins?
Bob