191
www.national.com
CP3
BT26
acb->ACBctl1 |= ACBSTOP; /* Send STOP bit */
/* Return success status.... */
return (ACB_NOERR);
}
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; NAME: ACBStartX Initiates an ACB bus transaction by sending the Start bit, followed by the Slave address
; and R/W flag. Checks for any ACB errors throughout this sequence and returns status.
;
; PARAMETERS: UBYTE Slave - I2C address of Slave device
; UBYTE R_nW - Read/Write flag (0x01 or 0x00)
; UWORD Count - Desired number of bytes (read/write)
;
; CALLS:
;
; RETURNED: error/success
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
UWORD ACBStartX (UBYTE Slave, UBYTE R_nW, UWORD Count)
{
ACB_T *acb;
UWORD Timeout;
/* Get address of ACB module */
acb = (ACB_T*)ACB_ADDRESS;
/* If Bus is Busy and we’re NOT the Master, return err */
if (acb->ACBcst & ACBBB && !(acb->ACBst & ACBMASTER))
return (ACBERR_NOTMASTER);
/* If we’re good to go, send Start condition */
acb->ACBctl1 |= ACBSTART;
/* Check if we’re the Bus Master with timeout */
Timeout = 100;
while (!(acb->ACBst & ACBSDAST) && Timeout--) /* Related to bus error problem */
{
if (acb->ACBst & ACBBER) { /* If collision occurs, clear error and return status */
acb->ACBst |= ACBBER;
return (ACBERR_COLLISION);
}
}
if (!Timeout) /* If timeout, we must NOT be the Master...signal error */
return (ACBERR_NOTMASTER);
/* Now, send the address and R/W flag... */
acb->ACBsda = Slave | R_nW; /* Send address and R/W flag */
Timeout = 1000; /* Failsafe for lockup */
/* Wait for address to be sent and ACK’d */
while (!(acb->ACBst & ACBSDAST) &&
!(acb->ACBst & ACBNEGACK)&&
--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; // OScope marker
if (!Timeout) /* If timeout, signal error */
return (ACBERR_TIMEOUT);
/* Or if Slave does not reply, report busy/error */
else if (acb->ACBst & ACBNEGACK)
return (ACBERR_NEGACK);
/* Otherwise return success */
else {
return (ACB_NOERR);
}