forked from len0rd/rockbox
Added proper clock-stretching to the pcf50606 I2C driver
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8018 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
5124844e32
commit
dcb8df5180
1 changed files with 4 additions and 34 deletions
|
@ -38,7 +38,7 @@
|
||||||
#define SCL_INPUT and_l(~0x00001000, &GPIO_ENABLE)
|
#define SCL_INPUT and_l(~0x00001000, &GPIO_ENABLE)
|
||||||
#define SCL_OUTPUT or_l( 0x00001000, &GPIO_ENABLE)
|
#define SCL_OUTPUT or_l( 0x00001000, &GPIO_ENABLE)
|
||||||
#define SCL_LO and_l(~0x00001000, &GPIO_OUT)
|
#define SCL_LO and_l(~0x00001000, &GPIO_OUT)
|
||||||
#define SCL_HI or_l( 0x00001000, &GPIO_OUT)
|
#define SCL_HI SCL_INPUT;while(!SCL){};or_l(0x1000, &GPIO_OUT);SCL_OUTPUT
|
||||||
#define SCL ( 0x00001000 & GPIO_READ)
|
#define SCL ( 0x00001000 & GPIO_READ)
|
||||||
|
|
||||||
/* delay loop to achieve 400kHz at 120MHz CPU frequency */
|
/* delay loop to achieve 400kHz at 120MHz CPU frequency */
|
||||||
|
@ -68,28 +68,13 @@ static void pcf50606_i2c_stop(void)
|
||||||
|
|
||||||
static void pcf50606_i2c_ack(bool ack)
|
static void pcf50606_i2c_ack(bool ack)
|
||||||
{
|
{
|
||||||
/* Here's the deal. The slave is slow, and sometimes needs to wait
|
|
||||||
before it can receive the acknowledge. Therefore it forces the clock
|
|
||||||
low until it is ready. We need to poll the clock line until it goes
|
|
||||||
high before we release the ack.
|
|
||||||
|
|
||||||
In their infinite wisdom, iriver didn't pull up the SCL line, so
|
|
||||||
we have to drive the SCL high repeatedly to simulate a pullup. */
|
|
||||||
|
|
||||||
SCL_LO; /* Set the clock low */
|
SCL_LO; /* Set the clock low */
|
||||||
if(ack)
|
if(ack)
|
||||||
SDA_LO;
|
SDA_LO;
|
||||||
else
|
else
|
||||||
SDA_HI;
|
SDA_HI;
|
||||||
|
|
||||||
SCL_INPUT; /* Set the clock to input */
|
SCL_HI;
|
||||||
while(!SCL) /* and wait for the slave to release it */
|
|
||||||
{
|
|
||||||
SCL_OUTPUT; /* Set the clock to output */
|
|
||||||
SCL_HI;
|
|
||||||
SCL_INPUT; /* Set the clock to input */
|
|
||||||
DELAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
DELAY;
|
DELAY;
|
||||||
SCL_OUTPUT;
|
SCL_OUTPUT;
|
||||||
|
@ -100,23 +85,8 @@ static int pcf50606_i2c_getack(void)
|
||||||
{
|
{
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
|
|
||||||
/* Here's the deal. The slave is slow, and sometimes needs to wait
|
|
||||||
before it can send the acknowledge. Therefore it forces the clock
|
|
||||||
low until it is ready. We need to poll the clock line until it goes
|
|
||||||
high before we read the ack.
|
|
||||||
|
|
||||||
In their infinite wisdom, iriver didn't pull up the SCL line, so
|
|
||||||
we have to drive the SCL high repeatedly to simulate a pullup. */
|
|
||||||
|
|
||||||
SDA_INPUT; /* And set to input */
|
SDA_INPUT; /* And set to input */
|
||||||
SCL_INPUT; /* Set the clock to input */
|
SCL_HI;
|
||||||
while(!SCL) /* and wait for the slave to release it */
|
|
||||||
{
|
|
||||||
SCL_OUTPUT; /* Set the clock to output */
|
|
||||||
SCL_HI;
|
|
||||||
SCL_INPUT; /* Set the clock to input */
|
|
||||||
DELAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SDA)
|
if (SDA)
|
||||||
/* ack failed */
|
/* ack failed */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue