Programming I2C module on mCF5485

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

Programming I2C module on mCF5485

2,048 Views
rgirme
Contributor I

Hello, I am trying to connect an I2C device to the MCF5485. I want to read data from the device. Basically i want to write a device driver for that device. I have read the reference manual of the processor. I have inferred the following:The processor should be in master mode.

 

First I need to initialize the I2C module.

 

set correct value in I2FDR for SCL.

 

question: How do I address I2FDR? How so I set the I2FDR to a particular value?Will I2FDR = 0x36 work? I want the clock frequency to be 400KHz. Should I set I2FDR with 0x36 or 0x37?

 

set I2CR.

 

question : How do I address single bit in this register? I want the processor to be in Master mode, it will receive data from I2C device. But while transmitting device address, does the processor need to be in transmitter mode and then switch to receiver mode? What about acknowledge signal? Do i have to generate it every time or it is generated automatically?

 

Do dummy read of I2DR.

 

set I2SR.

 

start reading data from I2DR.

 

question: Do i need to set and clear any flag/bit from I2SR while reading data from I2DR?

 

Am I right about the above procedure? if not please let me know the correct procedure.

Thank you,

Rohit

Labels (1)
0 Kudos
5 Replies

501 Views
admin
Specialist II

> How do I address I2FDR? How so I set the I2FDR to a particular value?

 

Your development environment sure have either

(case 1) define or

(case 2) C structure, which allows access to any register of a peripheral controller.

 

In the first case, you where the ready-made define of I2FDR symbol is available, you can use similar to

   volatile BYTE * pI2FDR = I2FDR;

   *pI2FDR = 0x36;

In second case, where I2FDR is available as part of the C structure, you can use similar to

   sim.i2c.fdr = 0x36;

 

> Will I2FDR = 0x36 work?

 

Yes, if your development environment has define similar to

   #define I2FDR (sim.i2c.fdr)

 

> I want the clock frequency to be 400KHz. Should I set I2FDR with 0x36 or 0x37?

 

Which internal bus clock do you have?

For example, mcf5270 with core (system) clock Fsys=147.456 MHz, the calculated divider is

  IC = (Fsys/2)/Fsck = (147.456 MHz) / 2 / (0.4 MHz) = 184.32

Thus, the nearest integer value of the divider, which results in Fsck<=400 kHz, is 185.

 

> set I2CR.

> question : How do I address single bit in this register? I want the processor to be in Master mode,

> it will receive data from I2C device.

 

In the first case, where the ready-made define of I2FDR symbol is available. You can use similar to

   volatile BYTE * pI2CR = I2CR;

   *pI2CR |= 0x20;

 

In second case, where I2CR is available as part of the C structure, you can use similar to

   sim.i2c.cr |= 0x20;

 

> But while transmitting device address, does the processor need to be in transmitter mode and then switch to receiver mode?

 

In i2c protocol, transmit and receive are physically simultaneous. But, most of i2c libraries send START condition together with SLAVE_ADDRESS word by calling transmit_slave_address() function, and receive the data from the slave by receive_slave_data() function.

 

What about acknowledge signal? Do i have to generate it every time or it is generated automatically?

To transmit  the acknowledge bit, you need bit I2CR[TXAK] be zero before or simuntaneously with setting bit I2CR[MSTA].

 

> question: Do i need to set and clear any flag/bit from I2SR while reading data from I2DR?

 

No. But, you need verify I2SR[IBB]=0.

 

> Am I right about the above procedure? if not please let me know the correct procedure.

 

See examples in the Reference Manual.

 

 

 

0 Kudos

501 Views
rgirme
Contributor I

@yevgenit 

 

Thank you...your reply helped me figure out many things...

 

Rohit

0 Kudos

501 Views
rgirme
Contributor I

Hi, I have installed Linux on my board, hence I cannot access the processor registers directly from user space. So I am using the /dev interface. Here is my new code. I can open the I2C device and set the slave address. But when I try to read/write to the device, I get an error. Also how do I change the frequency of the I2C clock? Please help me out..

 

Thanks 

Rohit

 

 

 

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>

#include <linux/i2c.h>
#include<linux/i2c-dev.h>


int main()
{
    int filep;
    int addrs = 0x52;
    unsigned char buff[1];
    struct i2c_msg msg;
    struct i2c_rdwr_ioctl_data ptr;

    if((filep = open("/dev/i2c-0", O_RDWR)) < 0)
    {
        printf("\nCould not open device ..");
        exit(1);
    }
    else
    {
        printf("\nI2C Device opened ..");
    }
    if((ioctl(filep, I2C_SLAVE, addrs)) < 0)
    {
        printf("\nCould not set slave address ..");
        exit(1);
    }
    else
    {
        printf("\nSlave Address set ..");
    }
   
    int i=0;
    unsigned char res = 0x40;
    char buffer[3];
    buffer[0] = res;
    buffer[1] = 0x00;
    buffer[2] = 0x01;
    for(i=0;i<10;i++)
    {
        if(write(filep, buffer, 3) != 3)
        {
            printf("Write Failed ..");
        }
    }
   
    for(i=0;i<10;i++)
    {
        buff[0] = 0x40;
        msg.addr = addrs;
        msg.flags = 0;
        msg.len = 1;
        msg.buf = buff;
        ptr.msgs = &msg;

        if((ioctl(filep, I2C_RDWR, addrs)) < 0)
        {
            printf("\nCould not write to slave ..");
            //    exit(1);
        }
        else
        {
            printf("\nWrite Successful ..");
        }
    }

    buff[0] = 0x00;
    msg.addr = addrs;
    msg.flags = 0;
    msg.len = 1;
    msg.buf = buff;
    ptr.msgs = &msg;

    if((ioctl(filep, I2C_RDWR, addrs)) < 0)
    {
        printf("\nCould not write to slave ..");
        exit(1);
    }
    else
    {
        printf("\nWrite Successful ..");
    }


     


    return 0;
}

0 Kudos

501 Views
admin
Specialist II

rgirme  , I am not familiar with your Linux driver, but any I2C driver must have API to configure clock speed and other properties. Try to find such a functionality at files linux/i2c.h and linux/i2c-dev.h

 

0 Kudos

501 Views
admin
Specialist II

Correction:

 

What about acknowledge signal? Do i have to generate it every time or it is generated automatically?

 

To transmit  the acknowledge bit during read from the slave, you need bit I2CR[TXAK] be zero before reading I2DR.

0 Kudos