2008-06-26 07:01:27 I2c on the BF548 EZ-KIT LITE board
Luxe Thomas (AUSTRIA)
Message: 57907
Hi, I've tried to use the TWI of the board but I don't get it working. I want to access the TWI over user space with the i2c-dev.h from the lm_sensors project. I can see the i2c-0 device in the /dev directory.
In my application it's possible to open the device but when I want to read or write something the functions return -1. I've also tried to catch signals with the oszilloscope but neither on the SDA nor on the SCL line I could get signals.
In the kernel I've enbaled the I2C support with this options enabled: I2C device interface, I2C Hardware Bus support--->Blackfin TWI I2C support
Can anybody please help me to get this thing working?
fg Thomas
TranslateQuoteReplyEditDelete
2008-06-26 07:27:41 Re: I2c on the BF548 EZ-KIT LITE board
Michael Hennerich (GERMANY)
Message: 57908
i2c-dev should just work.
Make sure you measure at the right TWI interface BF548 has two.
Check the schematics.
-Michael
QuoteReplyEditDelete
2008-06-26 08:37:44 Re: I2c on the BF548 EZ-KIT LITE board
Luxe Thomas (AUSTRIA)
Message: 57913
Okay the other one on the SOPRT3 connector has a voltage level of 3.3... but I still can't see any clock cycles on the SCL pin with the osziloscope!
Fg Thomas
TranslateQuoteReplyEditDelete
2008-06-26 08:53:01 Re: I2c on the BF548 EZ-KIT LITE board
Mike Frysinger (UNITED STATES)
Message: 57914
if things are erroring like that, then the userspace software is probably incorrect
please post the code you're attempting to run
QuoteReplyEditDelete
2008-06-26 09:14:29 Re: I2c on the BF548 EZ-KIT LITE board
Luxe Thomas (AUSTRIA)
Message: 57916
the code looks like this:
#include <i2c-dev.h>
#define I2C_PORT "/dev/i2c-0"
int fd,control;
char str[5];
str[0]=0x21;
str[1]=0x04;
fd=open(I2C_PORT,O_RDWR);
control = ioctl(fd,I2C_SLAVE,0x20);
control = write(fd,str,2);
control = ioctl(fd,I2C_SLAVE,0x21);
control = read(fd,str,4);
open returns a valid value
ioctl returns 0
read or write returns -1
It's my first time working with I2C, so I'm really not sure if this code is working as it should
fg Thomas
TranslateQuoteReplyEditDelete
2008-06-26 09:35:05 Re: I2c on the BF548 EZ-KIT LITE board
Michael Hennerich (GERMANY)
Message: 57919
This doesn't look right.
Here is a set of functions using i2c-dev I played with some time ago.
/*
*
* Rev: $Id: i2c.c 987 2005-07-18 10:13:16Z hennerich $
* Revision: $Revision: 987 $
* Source: $Source$
* Created: 06.07.2005 18:16
* Author: Michael Hennerich
* mail: hennerich@blackfin.uclinux.org
* Description: Simple I2C Routines
*
* Copyright (C) 2005 Michael Hennerich
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
****************************************************************************
* MODIFICATION HISTORY:
***************************************************************************/
#include "i2c-dev.h"
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/poll.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#define I2C_DEVICE "/dev/i2c-0"
#define I2C_SLAVE_ADDR 0x38 /* Randomly picked */
#define I2C_DEVID (0xB8>>1)
//#define main
#undef main
int i2c_write_register(char * , unsigned char , unsigned char , unsigned short );
int i2c_read_register(char * , unsigned char , unsigned char );
i2c_dump_register(char * , unsigned char , unsigned short , unsigned short );
i2c_scan_bus(char * );
#if main
int main()
{
i2c_scan_bus(I2C_DEVICE);
i2c_write_register(I2C_DEVICE,I2C_DEVID,9,0x0248);
i2c_dump_register(I2C_DEVICE,I2C_DEVID,0,255);
printf("Read Register 9 = 0x%X \n",
i2c_read_register(I2C_DEVICE, I2C_DEVID,9) );
exit( 0 );
}
#endif
int i2c_write_register(char * device, unsigned char client, unsigned char reg, unsigned short value)
{
int addr = I2C_SLAVE_ADDR;
char msg_data[32];
struct i2c_msg msg = { addr, 0, 0, msg_data };
struct i2c_rdwr_ioctl_data rdwr = { &msg, 1 };
int fd,i;
if ( (fd = open( device, O_RDWR ) ) < 0 ) {
fprintf(stderr, "Error: could not open %s\n", device);
exit( 1 );
}
if ( ioctl( fd, I2C_SLAVE, addr ) < 0 ) {
fprintf(stderr, "Error: could not bind address %x \n", addr );
}
msg.len = 3;
msg.flags = 0;
msg_data[0] = reg;
msg_data[2] = (0xFF & value);
msg_data[1] = (value >> 8);
msg.addr = client;
if ( ioctl( fd, I2C_RDWR, &rdwr ) < 0 ) {
fprintf(stderr, "Error: could not write \n");
}
close( fd );
return 0;
}
int i2c_read_register(char * device, unsigned char client, unsigned char reg)
{
int addr = I2C_SLAVE_ADDR;
char msg_data[32];
struct i2c_msg msg = { addr, 0, 0, msg_data };
struct i2c_rdwr_ioctl_data rdwr = { &msg, 1 };
int fd,i;
if ( (fd = open( device, O_RDWR ) ) < 0 ) {
fprintf(stderr, "Error: could not open %s\n", device);
exit( 1 );
}
if ( ioctl( fd, I2C_SLAVE, addr ) < 0 ) {
fprintf(stderr, "Error: could not bind address %x \n", addr );
}
msg_data[0]= reg;
msg.addr = client;
msg.len = 1;
msg.flags = 0;
if ( ioctl( fd, I2C_RDWR, &rdwr ) < 0 ) {
fprintf(stderr, "Error: could not write \n");
};
msg.len = 2;
msg_data[0]=0;
msg_data[1]=0;
msg.flags = I2C_M_RD ;
if ( ioctl( fd, I2C_RDWR, &rdwr ) < 0 ) {
fprintf(stderr, "Error: could not read back\n");
close( fd );
return -1;
}
close( fd );
return (((unsigned char)msg_data[0])<<8 | ((unsigned char)msg_data[1]) );
}
i2c_dump_register(char * device, unsigned char client, unsigned short start, unsigned short end)
{
int addr = I2C_SLAVE_ADDR;
char msg_data[32];
struct i2c_msg msg = { addr, 0, 0, msg_data };
struct i2c_rdwr_ioctl_data rdwr = { &msg, 1 };
int fd,i;
if ( (fd = open( device, O_RDWR ) ) < 0 ) {
fprintf(stderr, "Error: could not open %s\n", device);
exit( 1 );
}
if ( ioctl( fd, I2C_SLAVE, addr ) < 0 ) {
fprintf(stderr, "Error: could not bind address %x \n", addr );
}
for(i = start; i < end; i++) {
msg_data[0]= i;
msg.addr = client;
msg.len = 1;
msg.flags = 0;
if ( ioctl( fd, I2C_RDWR, &rdwr ) < 0 ) {
fprintf(stderr, "Error: could not write \n");
};
msg.len = 2;
msg_data[0]=0;
msg_data[1]=0;
msg.flags = I2C_M_RD ;
if ( ioctl( fd, I2C_RDWR, &rdwr ) < 0 ) {
fprintf(stderr, "Error: could not read back\n");
} else {
fprintf(stderr, "Register %02x : %02x%02x \n",i, (unsigned char)msg_data[0],(unsigned char)msg_data[1]);
}
}
close( fd );
return;
}
i2c_scan_bus(char * device)
{
int addr = I2C_SLAVE_ADDR;
char msg_data[32];
struct i2c_msg msg = { addr, 0, 0, msg_data };
struct i2c_rdwr_ioctl_data rdwr = { &msg, 1 };
int fd,i;
if ( (fd = open( device, O_RDWR ) ) < 0 ) {
fprintf(stderr, "Error: could not open %s\n", device);
exit( 1 );
}
if ( ioctl( fd, I2C_SLAVE, addr ) < 0 ) {
fprintf(stderr, "Error: could not bind address %x \n", addr );
}
msg.len = 1;
msg.flags = 0;
msg_data[0]=0;
msg_data[1]=0;
for ( i = 0; i < 128; i++){
msg.addr = i;
if ( ioctl( fd, I2C_RDWR, &rdwr ) < 0 ) {
//fprintf(stderr, "Error: could not write \n");
}else
fprintf(stderr, "FOUND I2C device at 0x%X (8-bit Adrress 0x%X) \n",msg.addr,msg.addr<<1);
}
close( fd );
return;
}
QuoteReplyEditDelete
2008-06-26 09:39:01 Re: I2c on the BF548 EZ-KIT LITE board
Michael Hennerich (GERMANY)
Message: 57920
Take a look at:
uclinux-dist-trunk/user/blkfin-test/ppifcd-test/i2c-dev.h
uclinux-dist-trunk/user/blkfin-test/ppifcd-test/i2c.c
-Michael
QuoteReplyEditDelete
2008-06-26 10:27:15 Re: I2c on the BF548 EZ-KIT LITE board
Luxe Thomas (AUSTRIA)
Message: 57921
Is threre any possibility to find out if the I2C is working without connecting a device?
Thanks for your help,
Fg Thomas
TranslateQuoteReplyEditDelete
2008-06-26 10:43:14 Re: I2c on the BF548 EZ-KIT LITE board
Mike Frysinger (UNITED STATES)
Message: 57922
you can only send out a request, but after that, no ... if you read the i2c document:
http://docs.blackfin.uclinux.org/doku.php?id=i2c
you'll see that you can issue a master can initiate a transfer, but it'll error as there is no slave to ack it
QuoteReplyEditDelete
2008-06-26 12:14:42 Re: I2c on the BF548 EZ-KIT LITE board
Luxe Thomas (AUSTRIA)
Message: 57928
Do I have to change something in the Linux Kernel Framework as shown on the link you sent me if I want to access the TWI only over user space?
fg Thomas
TranslateQuoteReplyEditDelete
2008-06-27 12:35:41 Re: I2c on the BF548 EZ-KIT LITE board
Mike Frysinger (UNITED STATES)
Message: 57966
no ... there's nothing specific other than enabling the i2c dev driver and a bus driver