1
). This is communicated to the Controller
during the Dynamic Address Assignment procedure or when the Controller requests for it using the
GETBCR
(Get Bus Characteristics Register) Direct Common Command Code (CCC).The Controller sets the maximum payload size using the SETMRL (Set Maximum Read Length) CCC. This value is stored in the read-only I3CxIBIPSZ IBI Payload Size register. A payload size value of zero indicates that the IBI payload is only the Mandatory Data Byte. Any other payload size value indicates the size of payload (excluding Mandatory Data Byte) in bytes. Hence, the minimum payload size supported by the Target is one byte (the Mandatory Data Byte) and the maximum payload size is 256 bytes. The Controller can use the GETMRL (Get Maximum Read Length) CCC to read the value of the maximum payload size stored in the I3CxIBIPSZ register.
Once the Controller ACKs the IBI request, it cannot decline the reception of the Mandatory Data Byte since it is transmitted in Push-Pull mode and must wait for the next T-bit. After receiving the Mandatory Data Byte, the Controller can continue to receive further payload data from the Target in Push-Pull mode or terminate any subsequent transmission by asserting the End-of-Data T-bit (Restart) or transmitting a Stop. The frame format of a successful IBI transaction is shown in Figure 1.
The I3CxIBIMB Mandatory Data Byte provides the Controller additional information about the event that has happened and is divided into two fields as defined by MIPI:
0
’.uint8_t payloadData[SIZE]; // payload data to be sent
uint8_t I3C1_Target_IBI()
{
// Check Target's operating mode first
if(I3C1STATbits.OPMD != 0b01) {
// Target is operating in I2C mode, cannot perform IBI
return 1;
}
// Check if Controller has disabled IBI requests
if(!I3C1ECbits.IBIEN) {
// Controller has disabled IBI requests
return 1;
}
// Begin IBI request
I3C1CONbits.IBIREQ = 1;
// Mandatory Data Byte in I3C1IBIMB is sent automatically
// Send IBI Payload
I3C1_Target_IBI_SendPayload();
// Check whether IBI process is complete
while(I3C1CONbits.IBIREQ); // IBIREQ clears when process is complete
// Check if IBI completed successfully
if(I3C1PIR1bits.IBIDONEIF) { /* Successful IBI */ }
else if(I3C1ERRIR0bits.IBIEIF || I3C1ERRIR1bits.IBIAEIF) { /* Error */ }
}
uint8_t I3C1_Target_IBI_SendPayload()
{
uint16_t payloadSize = I3C1IBIPSZ; // Max Payload Size set by Controller
uint8_t i = 0;
while(i < SIZE) {
// Wait for Tx Buffer to become empty
while(!I3C1STATbits.TXBE);
// Write payload data to Transmit buffer and increment pointer
I3C1TXB = payloadData[i++];
// Check if payload size overflow
if(i >= payloadSize) {
// Software has exceeded max Payload Size set by the Controller
// Take appropriate action
break;
}
// Perform error checking if desired
// Check for Tx Underrun Error or Tx Write Error
// if(I3C1ERRIR0bits.TXUIF || I3C1ERRIR1bits.TXWEIF) { ... }
// Check for Controller aborting transaction prematurely
if(I3C1PIR0bits.PCIF || I3C1PIR0bits.RSCIF || I3C1PIR1bits.TCOMPIF) {
return 1; // end of transaction with Controller abort
}
}
// Wait for Stop or Restart for End of Transaction
while(!I3C1PIR0bits.PCIF && !I3C1PIR0bits.RSCIF && !I3C1PIR1bits.TCOMPIF)
{
// While waiting, check for additional errors (if desired)
// if(I3C1ERRIR0bits.TXUIF || I3C1ERRIR1bits.TXWEIF) { ... }
}
return 0;
}