Module Setup in I3C Mode

The I3C Target module can be set up to operate in I3C mode by following the recommended order of settings shown in Table 1. An example setup code is shown in Module Setup in I3C Mode below.

Important: The I3C Target module always starts by operating in I2C mode (OPMD = 0b00) until it is assigned a Dynamic Address by the Controller either through the Hot-Join Mechanism process or regular Dynamic Address Assignment.
Table 1. Recommended Module Setup Order for I3C® Mode Operation
Setting Description Section Reference
Pad Buffer Selection(2) Select the appropriate pad buffer (I3C Low-Voltage Buffer or ST Buffer) using the RxyI2C and IOLVCON registers. Ensure that any I2C related settings are disabled in I3CxI2CCON registers. Enable bandgap reference using FVRCON register for future buffer changes if ST buffer is selected SDA and SCL Pins
Module Clock Select the appropriate clock for the I3C module using I3CxCLK register I3C Module Clock
Bus Conditions Select the appropriate values for I3CxBIDL and I3CxBAVL registers based on the I3C clock speed to match the Bus Idle and Bus Available conditions I3C Bus Conditions
Bus Time-out (optional) If the bus time-out feature is desired, the feature can be enabled using BTOEN bit in I3CxCON register. The bus time-out threshold and duration can be set using I3CxBTO and I3CxBRST registers Bus Time-out Reset
In-Band Interrupt and Hot-Join The arbitration request retry limit for IBI and Hot-Join can be set using the I3CxRETRY register. The IBI Mandatory Data Byte can be set using I3CxIBIMB register

Hot-Join Mechanism

In-Band Interrupt (IBI)

Static Address Set the desired static address for the I3C module using I3CxSADR register I2C Static Address
Provisional ID and Device ID Set the Provisional ID for the I3C module using the I3CxPID0 through I3CxPID5 registers. In addition, set an appropriate Device ID using the I3CxDCR register.

I3C Characteristics Registers

Provisional ID

Speed Limitations If the device/application is speed limited, set the BCR0 bit in I3CxBCR register. If speed-limited, set the maximum read/write speed and read turnaround times using the I3CxMWS, I3CxMRS and I3CxMRT registers Speed Limitations
Buffers and FIFO The CLRRXB and CLRTXB bits in the I3CxCON register can be used to clear the receive and transmit buffers and FIFO immediately after the I3C module is enabled Transmit and Receive Buffers
Interrupts Clear all the module-level and system-level interrupt flags. Enable the desired interrupts by setting the appropriate interrupt enable bits. Remember to enable the system-level interrupt controller to generate the enabled interrupts Interrupts and DMA Triggers
Module Enable Enable the I3C module in the end by setting the EN bit in the I3CxCON register
Notes:
  1. 1.Alternatively, the module can also be configured to use I2C/SMBus buffers during start-up. However, it is highly recommended to switch to using I3C® buffers once the module has started to operate in I3C mode (OPMD = 0b01). Enable bandgap reference using FVRCON register for future buffer changes if ST buffer is selected.
  2. 2.It is recommended to select the appropriate pad buffers as the first thing when initializing the module to ensure that there is enough delay after selecting the buffer to request for bandgap reference before enabling the module. Refer to section I3C Low-Voltage Buffer for more information
Tip: It is recommended for the user to set up and use DMA to read and write from the I3C Transmit and Receive Buffers to ensure that the CPU is able to keep up with the higher I3C speeds. Refer to section Interrupts and DMA Triggers and "DMA - Direct Memory Access" chapter for more information.

Module Setup in I3C® Mode

void I3C1_Target_Setup()
{
    // Select I3C Buffer
    I3C1I2CCON = 0x00;      // Disable spike filter and SDA hold time
    RC0I2C = 0x00;          // Disable I2C/SMBus buffers on I3C1_SCL pin
    RC1I2C = 0x00;          // Disable I2C/SMBus buffers on I3C1_SDA pin
    IOLVCONbits.VDDIO2LVEN = 1; // Enable Low-Voltage I3C buffers on VDDIO2 domain (for VDDIO2<1.62V)

    // If non-I3C LV buffers are selected, enable the FVR module and request for bandgap for quickly switching to I3C LV buffers later
    // FVRCONbits.EN = 1;
    
    // Select Clock
    I3C1CLK = 0x01;         // Fosc=64MHz

    // Set Bus Idle and Bus Available Conditions
    I3C1BIDL = 12800;       // 200us
    I3C1BAVL = 64;          // 1us

    // Bus Time-out settings (optional)
    I3C1CONbits.BTOEN = 1;  // Enable Bus Time-out
    I3C1BTO = 164;          // 32*F_scl @ F_scl=12.5MHz
    I3C1BRST = 15;          // Bus Time-out Reset duration

    // IBI/HJ Settings
    I3C1RETRY = 3;          // Number of retries for IBI and HJ
    I3C1IBIMB = 0x00;       // IBI Mandatory Byte (0x00 = User Defined)

    // Static Address
    I3C1SADR = 0x30;        // Static Address

    // Set Provisional ID
    I3C1PID5 = 0x06;        // PID[37:33] is MIPI Manufacturer ID (Microchip = 0x034D<<1 = 0x069A)
    I3C1PID4 = 0x9A;        // PID32=0 (PID[31:0] is vendor defined)
    I3C1PID3 = 0x00;        // PID[31:16] is Part ID
    I3C1PID2 = 0x00;
    I3C1PID1 = 0x00;        // PID[15:12] is Instance ID
    I3C1PID0 = 0x00;        // PID[11:0] is vendor defined

    // Set Device ID
    I3C1DCR = 0xC6;         // 0xC6 = Microcontroller

    // Is device speed limited? (application dependent)
    I3C1BCRbits.BCR0 = 1;   // Speed limited (If not, BCR0=0)

    // Add support for Get Max Data Speed (GETMXDS CCC) since device is speed limited (BCR0=1 above)
    I3C1MWS = 0x00;         // Max Write Speed
    I3C1MRS = 0x00;         // Max Read Speed (specified Clock-to-Data Turnaround Time)
    I3C1MRT = 45;           // Max Read Turnaround Time (in us)

    // Clear buffers and FIFOs
    I3C1CONbits.CLRRXB = 1; // Clears I3C1RXB Rx Buffer and Rx FIFO
    I3C1CONbits.CLRTXB = 1; // Clears I3C1TXB Tx Buffer and Tx FIFO

    // Clear all interrupt flags (x = Appropriate PIR register)
    I3C1PIR0 = 0x00;        // Module-level general interrupts
    I3C1PIR1 = 0x00;
    I3C1ERRIR0 = 0x00;      // Module-level error interrupts
    I3C1ERRIR1 = 0x00;
    PIRxbits.I3C1IF = 0;    // System-level general interrupt
    PIRxbits.I3C1EIF = 0;   // System-level error interrupt
    PIRxbits.I3C1TXIF = 0;  // System-level transmit interrupt
    PIRxbits.I3C1RXIF = 0;  // System-level receive interrupt
    PIRxbits.I3C1RIF = 0;   // System-level Reset interrupt

    // Enable interrupts as needed (x = Appropriate PIR register)
    I3C1PIE0 = 0x00;
    I3C1PIE1 = 0x00;
    I3C1ERRIE0 = 0x00;
    I3C1ERRIE1 = 0x00;
    PIExbits.I3C1IE = 0;  
    PIExbits.I3C1EIE = 0;   
    PIExbits.I3C1TXIE = 0;  
    PIExbits.I3C1RXIE = 0;  
    PIExbits.I3C1RIE = 0;  
   
    // Enable Target Module
    I3C1CONbits.EN = 1;     // Also disables TTL buffers on SDA/SCL pads
}