KL17 I2C question

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

KL17 I2C question

632 Views
dougbaker
Contributor III

I am working with a KL17 CPU and I have a I2C question.  The KL17 in my application is a slave I2C device that talks to another embedded CPU that is the I2C master. I am using the “Transcational” I2C API since I want to use non blocking transfers.  I have the I2C working for a fixed message size of 2 bytes but my question is what is the recommended method of handling variable messages lengths?   For example, if the master CPU sends or requests  a 2 byte message for the KL17, the I2C bus would have the following (ignoring the start/stop and repeat start bits):

[slave address]  [register] [slave address] [byte1] [byte 2]   

My callback is shown below:

static void i2c_slave_callback(I2C_Type *base, i2c_slave_transfer_t *xfer, void *userData)

{

    switch (xfer->event)

    {

        /*  Transmit request */

        case kI2C_SlaveTransmitEvent:

            /*  Update information for transmit process */

            xfer->data = g_I2C_buff;                     

            xfer->dataSize = 3;                                                                                                                                  

            break;

 

        /*  Receive request */

        case kI2C_SlaveReceiveEvent:

            /*  Update information for received process */

            xfer->data = g_I2C_buff;                         

          xfer->dataSize = 3;             

            break;

 

        /*  Transfer done */

        case kI2C_SlaveCompletionEvent:

            g_SlaveCompletionFlag = true;

            break;

 

        default:

            g_SlaveCompletionFlag = true;

            break;

    }

}

 

Since a write or read of two bytes would also needs to handle the [register] I found that      xfer->dataSize = 3; gave the desired results.  My question is what is the recommended method of sending or receiving different length messages based on the [register] value?

For example say register = 0x02 should be a two byte read and register = 0x03 is a one byte read.  The Kl17 is at slave address 0x28.

[0x28] [0x02] [0x28] [byte1] [byte2]       0x02 is read 2 bytes

[0x28] [0x03] [0x28] [byte1]                         0x01 is read 1 byte

I won’t know how to set the transfer up till I get the get the [register] value.    What is the recommended method for doing this?

Thanks,

Doug

0 Kudos
1 Reply

358 Views
jorge_a_vazquez
NXP Employee
NXP Employee

Hi Doug Baker

If I understand correctly, your master will first send a number of bytes to read (you named it as Register) and then this number of bytes your master will read it back, right?

If your MCU KL17 going to be the slave, then the correct method to do what you want is to pass the value that you received in the kI2C_SlaveReceiveEvent event to your kI2C_SlaveTransmitEvent event, this mean, something like:

        /*  Transmit request */
        case kI2C_SlaveTransmitEvent:
            /*  Update information for transmit process */
            xfer->data = g_slave_buff;
            xfer->dataSize = (*g_size_to_send);
            break;


        /*  Receive request */
        case kI2C_SlaveReceiveEvent:
            /*  Update information for received process */
            xfer->data = g_size_to_send;
            xfer->dataSize = 1;
            break;

As you can see here, I create the g_size_to_send, which will contain the number of bytes the our Kl17 will send, this variable the master has send it before any attend to read. So when this transfer has finished, your slave will have in g_size_to_send the number of bytes to send to the master.

Best Regards

Jorge Alcala

0 Kudos