CP3BT26

24.4.1Avoiding Bus Error During Write Transaction

A Bus Error (BER) may occur during a write transaction if the data register is written at a very specific time. The mod- ule generates one system-clock cycle setup time of SDA to SCL vs. the minimum time of the clock divider ratio.

The problem can be masked within the driver by dynamical- ly dividing-by-half the SCL width immediately after the slave

address is successfully sent and before writing to the ACB- SDA register. This has the effect of forcing SCL into the stretch state.

The following code example is the relevant segment of the ACCESS.bus driver addressing this issue.

/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

; NAME: ACBRead

Reads "Count"

byte(s) from selected I2C Slave. If read address differs from previous

;

 

Read or Write

operation (as recorded in NextAddress), a "dummy" write transaction is

;

 

initiated to reset the address to the desired location. This is followed by a repeated

;

 

Start sequence and the Read transaction. All transactions begin with a call to ACBStartX

;

 

which sends

the Start condition and Slave address. Checks for errors throughout process.

;

 

 

 

 

 

; PARAMETERS:

UBYTE

Slave

-

Slave Device Address. Must be of format 0xXXXX0000

;

 

UWORD

Addrs

-

Byte/Array address (extended addressing mode uses two byte address)

;

 

UWORD

Count

-

Number of bytes to read

;

 

UBYTE

*buf

-

Pointer to receive buffer

;

 

 

 

 

 

; CALLS:

ACBStartX

 

 

 

;

 

 

 

 

 

;RETURNED: error status ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

UWORD

ACBRead (UBYTE Slave, UWORD Addrs, UWORD Count, UBYTE *buf)

 

{

 

 

 

 

ACB_T

*acb;

 

 

UBYTE

err, *rcv;

 

 

UWORD

Timeout;

 

 

acb =

(ACB_T*)ACB_ADDRESS;

/* Set pointer to ACB module

*/

if (Addrs != NextAddress) {

/* If the indicated address differs from the last

*/

/* recorded access (i.e. Random Read), we must first

*/

 

 

 

 

 

 

/* send a "dummy" write to the desired new address..

*/

 

NextAddress = Addrs;

/* Update last address placeholder

*/

KeyInit();

 

 

KBD_OUT &= ~BIT0;

 

 

 

 

 

/* Send start bit and Slave address...

*/

 

if ((err = ACBStartX (Slave (Addrs >> 7 & 0x0E), ACB_WRITE, 0)))

 

 

 

return (err);

/* If unsuccessful, return error code

*/

//KBD_OUT &= ~BIT0;

 

acb->ACBsda =

(UBYTE)Addrs;

/*

Send new address byte

*/

KBD_OUT

&= ~BIT0;

 

 

 

 

 

 

Timeout =

1000;

/*

Set timeout

*/

 

 

 

 

/*

Wait for xmitter to be ready...zzzzzzzzz

*/

 

while (!(acb->ACBst & ACBSDAST) && !(acb->ACBst & ACBBER) && Timeout--);

 

 

if (acb->ACBst & ACBBER) {

/*

If a bus error occurs while sending address, clear

*/

 

 

 

 

 

acb->ACBst = ACBBER;

/*

the error flag and return error status

*/

 

return (ACBERR_COLLISION);

 

 

 

 

}

 

 

 

 

 

KBD_OUT

&= ~BIT0;

 

 

 

 

 

 

if (!Timeout)

 

/*

If we timeout, return error

*/

}

return (ACBERR_TIMEOUT);

 

 

 

 

 

 

/*

(Re)Send start bit and Slave address...

*/

 

 

 

 

if ((err = ACBStartX (Slave (Addrs >> 7 & 0x0E),

ACB_READ, Count)))

 

 

return (err);

 

/*

If error, return

*/

 

 

 

 

 

rcv

= buf;

 

 

/*

Get address of read buffer

*/

while (Count) {

 

 

/*

Read Count bytes into user’s buffer

*/

 

 

 

 

 

 

if (Count-- == 1)

/*

If this the final byte, or only one requested, send

*/

 

acb->ACBctl1

= ACBACK;

/*

the NACK bit after reception

*/

 

Timeout =

1000;

/*

Set timeout

*/

 

while (!(acb->ACBst & ACBSDAST) && Timeout--);

 

 

 

if (!Timeout)

 

/*

Timed out??

*/

 

return (ACBERR_TIMEOUT);

/*

YES - return error

*/

 

 

 

 

 

*rcv++ =

acb->ACBsda;

/*

NO - Read byte from Recv register

*/

 

NextAddress++;

 

/*

Adjust current address placeholder

*/

}

 

 

 

 

 

 

 

 

 

 

www.national.com

190

Page 190
Image 190
National CP3BT26 manual Avoiding Bus Error During Write Transaction, 190