1/1

|
I2c-ocore linux driver debug
by Unknown on Jan 13, 2009 |
Not available! | ||
|
Hy,
I integrated the IP i2c ocore for my platform ARMadeus apf9328
(http://www.armadeus.com/wiki). ARMadeus platform is an embedded system with a
processor i.MXL and a FPGA Spartan3.
The interface between the processor and FPGA is a 16bits data bus, and it's
wired to do only 16bits read/write. Thus, I had to write a wrapper to convert
8bits ocore interface in 16bits interface. This wrapper mutiplex data bus to
keep data in low part of the 16bits bus (see attachement) and add an ID
register to unsure driver that the component is configured correctly.
I had two problems with the driver:
* Registers addresses.
* To send stop command, driver have to set stop bit *before* sending the last
byte. In the driver, this stop bit is set at the end of command, and that
doesn't work.
I was really surprised of this bugs, because this IP is old and I feel I am the
only one that have these problems. Maybe the problem come from wrapper but I
don't know why.
I modified the driver to fix these bugs (see diff in attachment), and that
work well with two components (LIS3LV02DL accelerometer and DS28CZ04 EEPROM)
and testbench provided in attachment.
Addresses registers problem
===========================
The original driver give these addresses:
/* registers */
#define OCI2C_PRELOW 0
#define OCI2C_PREHIGH 1
#define OCI2C_CONTROL 2
#define OCI2C_DATA 3
#define OCI2C_CMD 4 /* write only */
#define OCI2C_STATUS 4 /* read only, same address as OCI2C_CMD */
After lot of tests, I found that this addresses work better:
/* registers */
#define OCI2C_PRELOW 0
#define OCI2C_PREHIGH 1
#define OCI2C_CONTROL 2
#define OCI2C_CMD 4
#define OCI2C_DATA_TXR 5
#define OCI2C_STATUS 6
#define OCI2C_DATA_RXR 7
Stop command
============
The most important problem I had was the stop command. To send a command like
write quick SMBus (see Documentation/i2c/smbus-protocol) :
S Addr [Rd/Wr] P
The stop bit must be set at the same time that start bit. To do that I modified
the xfer function:
oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START);
by:
if(i2c->msg->len == 0)
oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START|OCI2C_CMD_STOP);
else
oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START);
The same problem occur with write and read commands, the stop bit must be set at
the same time that sending/receiving the last byte.
Sincerely
FabM
-------------- next part --------------
A non-text attachment was scrubbed...
Name: i2cocore_wb16.vhd
Type: application/octet-stream
Size: 4559 bytes
Desc: not available
Url : http://www.opencores.org/forums.cgi/cores/attachments/20090113/4fbeffe1/i2cocore_wb16-0001.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: i2c-ocore.diff
Type: text/x-diff
Size: 4348 bytes
Desc: not available
Url : http://www.opencores.org/forums.cgi/cores/attachments/20090113/4fbeffe1/i2c-ocore-0001.diff
-------------- next part --------------
A non-text attachment was scrubbed...
Name: i2c_testbench.c
Type: text/x-csrc
Size: 11813 bytes
Desc: not available
Url : http://www.opencores.org/forums.cgi/cores/attachments/20090113/4fbeffe1/i2c_testbench-0001.c
|
|||
|
I2c-ocore linux driver debug
by Unknown on Jan 14, 2009 |
Not available! | ||
|
Thanks'.
Best regards.
-----Original Message-----
From: cores-bounces at opencores.org [mailto:cores-bounces at opencores.org]
On Behalf Of Fabien Marteau
Sent: Tuesday, January 13, 2009 12:00 PM
To: Discussion list about free open source IP cores
Subject: [oc] I2c-ocore linux driver debug
Hy,
I integrated the IP i2c ocore for my platform ARMadeus apf9328
(http://www.armadeus.com/wiki). ARMadeus platform is an embedded system
with a
processor i.MXL and a FPGA Spartan3.
The interface between the processor and FPGA is a 16bits data bus, and
it's
wired to do only 16bits read/write. Thus, I had to write a wrapper to
convert
8bits ocore interface in 16bits interface. This wrapper mutiplex data
bus to
keep data in low part of the 16bits bus (see attachement) and add an ID
register to unsure driver that the component is configured correctly.
I had two problems with the driver:
* Registers addresses.
* To send stop command, driver have to set stop bit *before* sending the
last
byte. In the driver, this stop bit is set at the end of command, and
that
doesn't work.
I was really surprised of this bugs, because this IP is old and I feel I
am the
only one that have these problems. Maybe the problem come from wrapper
but I
don't know why.
I modified the driver to fix these bugs (see diff in attachment), and
that
work well with two components (LIS3LV02DL accelerometer and DS28CZ04
EEPROM)
and testbench provided in attachment.
Addresses registers problem
===========================
The original driver give these addresses:
/* registers */
#define OCI2C_PRELOW 0
#define OCI2C_PREHIGH 1
#define OCI2C_CONTROL 2
#define OCI2C_DATA 3
#define OCI2C_CMD 4 /* write only */
#define OCI2C_STATUS 4 /* read only, same address as
OCI2C_CMD */
After lot of tests, I found that this addresses work better:
/* registers */
#define OCI2C_PRELOW 0
#define OCI2C_PREHIGH 1
#define OCI2C_CONTROL 2
#define OCI2C_CMD 4
#define OCI2C_DATA_TXR 5
#define OCI2C_STATUS 6
#define OCI2C_DATA_RXR 7
Stop command
============
The most important problem I had was the stop command. To send a command
like
write quick SMBus (see Documentation/i2c/smbus-protocol) :
S Addr [Rd/Wr] P
The stop bit must be set at the same time that start bit. To do that I
modified
the xfer function:
oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START);
by:
if(i2c->msg->len == 0)
oc_setreg(i2c, OCI2C_CMD,
OCI2C_CMD_START|OCI2C_CMD_STOP);
else
oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START);
The same problem occur with write and read commands, the stop bit must
be set at
the same time that sending/receiving the last byte.
Sincerely
FabM
************************************************************************
************
This footnote confirms that this email message has been scanned by
PineApp Mail-SeCure for the presence of malicious code, vandals &
computer viruses.
************************************************************************
************
************************************************************************************
This footnote confirms that this email message has been scanned by
PineApp Mail-SeCure for the presence of malicious code, vandals & computer viruses.
************************************************************************************
|
|||
|
I2c-ocore linux driver debug
by Unknown on Jan 14, 2009 |
Not available! | ||
|
>>>>> "FM" == Fabien Marteau lepingouin.tux at gmail.com> writes:
Hi,
Discussions about the Linux i2c drivers belongs on the
linux-i2c at vger.kernel.org list, let's move discussion there.
FM> I integrated the IP i2c ocore for my platform ARMadeus apf9328
FM> (http://www.armadeus.com/wiki). ARMadeus platform is an embedded
FM> system with a processor i.MXL and a FPGA Spartan3.
FM> The interface between the processor and FPGA is a 16bits data bus,
FM> and it's wired to do only 16bits read/write. Thus, I had to write
FM> a wrapper to convert 8bits ocore interface in 16bits
FM> interface. This wrapper mutiplex data bus to keep data in low part
FM> of the 16bits bus (see attachement) and add an ID register to
FM> unsure driver that the component is configured correctly.
FM> I had two problems with the driver:
FM> * Registers addresses.
FM> * To send stop command, driver have to set stop bit *before*
FM> sending the last byte. In the driver, this stop bit is set at the
FM> end of command, and that doesn't work.
FM> I was really surprised of this bugs, because this IP is old and I
FM> feel I am the only one that have these problems. Maybe the problem
FM> come from wrapper but I don't know why.
FM> I modified the driver to fix these bugs (see diff in attachment), and that
FM> work well with two components (LIS3LV02DL accelerometer and DS28CZ04 EEPROM)
FM> and testbench provided in attachment.
FM> Addresses registers problem
FM> ===========================
FM> The original driver give these addresses:
FM> /* registers */
FM> #define OCI2C_PRELOW 0
FM> #define OCI2C_PREHIGH 1
FM> #define OCI2C_CONTROL 2
FM> #define OCI2C_DATA 3
FM> #define OCI2C_CMD 4 /* write only */
FM> #define OCI2C_STATUS 4 /* read only, same address as OCI2C_CMD */
That fits the specs (i2c_specs.pdf, by Richard Herveille)
FM> After lot of tests, I found that this addresses work better:
FM> /* registers */
FM> #define OCI2C_PRELOW 0
FM> #define OCI2C_PREHIGH 1
FM> #define OCI2C_CONTROL 2
FM> #define OCI2C_CMD 4
FM> #define OCI2C_DATA_TXR 5
FM> #define OCI2C_STATUS 6
FM> #define OCI2C_DATA_RXR 7
Strange, seems like something went wrong in your wrapper.
FM> Stop command
FM> ============
FM> The most important problem I had was the stop command. To send a command like
FM> write quick SMBus (see Documentation/i2c/smbus-protocol) :
FM> S Addr [Rd/Wr] P
FM> The stop bit must be set at the same time that start bit. To do
FM> that I modified
FM> the xfer function:
FM> oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START);
FM> by:
FM> if(i2c->msg->len == 0)
FM> oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START|OCI2C_CMD_STOP);
FM> else
FM> oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START);
It could be that we have a problem with zero length transfers (don't
have access to any smbus devices) - Could you please send a proper
patch in diff -urpN format?
--
Bye, Peter Korsgaard
|
|||
1/1

