National Semiconductor CP3BT26 User Manual page 190

Reprogrammable connectivity processor with bluetooth, usb, and can interfaces
Table of Contents

Advertisement

24.4.1
Avoiding 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
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; NAME: ACBRead
Reads "Count" byte(s) from selected I2C Slave.
;
Read or Write operation (as recorded in NextAddress), a "dummy" write transaction is
;
initiated to reset the address to the desired location.
;
Start sequence and the Read transaction.
;
which sends the Start condition and Slave address.
;
; PARAMETERS:
UBYTE
;
UWORD
;
UWORD
;
UBYTE
;
; 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;
if (Addrs != NextAddress) {
NextAddress =
KeyInit();
KBD_OUT &= ~BIT0;
if ((err = ACBStartX (Slave | (Addrs >> 7 & 0x0E), ACB_WRITE, 0)))
return (err);
//
KBD_OUT &= ~BIT0;
acb->ACBsda =
KBD_OUT &= ~BIT0;
Timeout =
1000;
while (!(acb->ACBst & ACBSDAST) && !(acb->ACBst & ACBBER) && Timeout--);
if (acb->ACBst & ACBBER) {
acb->ACBst
return (ACBERR_COLLISION);
}
KBD_OUT &= ~BIT0;
if (!Timeout)
return (ACBERR_TIMEOUT);
}
if ((err = ACBStartX (Slave | (Addrs >> 7 & 0x0E), ACB_READ, Count)))
return (err);
rcv =
buf;
while (Count) {
if (Count-- == 1)
acb->ACBctl1
Timeout =
1000;
while (!(acb->ACBst & ACBSDAST) && Timeout--);
if (!Timeout)
return (ACBERR_TIMEOUT);
*rcv++
=
acb->ACBsda;
NextAddress++;
}
www.national.com
Slave
-
Slave Device Address. Must be of format 0xXXXX0000
Addrs
-
Byte/Array address (extended addressing mode uses two byte address)
Count
-
Number of bytes to read
*buf
-
Pointer to receive buffer
Addrs;
(UBYTE)Addrs;
|=
ACBBER;
|=
ACBACK;
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.
If read address differs from previous
All transactions begin with a call to ACBStartX
Checks for errors throughout process.
/* Set pointer to ACB module
/* 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..
/* Update last address placeholder
/* Send start bit and Slave address...
/* If unsuccessful, return error code
/* Send new address byte
/* Set timeout
/* Wait for xmitter to be ready...zzzzzzzzz
/* If a bus error occurs while sending address, clear
/* the error flag and return error status
/* If we timeout, return error
/* (Re)Send start bit and Slave address...
/* If error, return
/* Get address of read buffer
/* Read Count bytes into user's buffer
/* If this the final byte, or only one requested, send
/* the NACK bit after reception
/* Set timeout
/* Timed out??
/* YES - return error
/* NO - Read byte from Recv register
/* Adjust current address placeholder
190
This is followed by a repeated
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

Advertisement

Table of Contents
loading

Table of Contents