I2c_BUS_BUSY

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

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?

0 Likes
18 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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

0 Likes
Anonymous
Not applicable

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

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

of course, thanks for your support so far.
i've got this working using an arduino and a raspberry pi so im quite sure the physical circuitry is solid.

   

Kind regards,
Ronald

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

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
 

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Please check the returned status of every I2C access to find out the place and reason of faillure.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

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

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Or are you trying to access the on-board FRAM chip???

   

 

   

Bob

0 Likes
Anonymous
Not applicable

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

   

   

   

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Hi bob,

   

it hasn't changed much from the earlier versions in this thread.
 

0 Likes
lock attach
Attachments are accessible only for community members.
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Check the attached. There was an error with "status" and "Status", Heap size increased and some smaller modifications.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

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?

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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

0 Likes
Anonymous
Not applicable

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
 

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Ale you seeing the clock at SCL pin? what level are SCL and SDA?

   

What is connected to your UART pins?

   

 

   

Bob

0 Likes