37.3.2 Module Setup in I2C/SMBus Mode

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

Tip: To always operate this I3C module in I2C mode, the user can enable Hot-Join capability (HJCAP = 1) and never request for a Hot-Join. This ensures that all the ENTDAA CCCs from the Controller will be NACK'd and the Target will never participate in the Dynamic Address Assignment process.
Table 37-21. Recommended Module Setup Order for I2C/SMBus Mode Operation
Setting Description Section Reference
Pad Buffer Selection Set SDA/SCL pins as open-drain inputs and select an appropriate pad buffer (I2C/SMBus Buffer) using the RxyFEAT register. 37.2.3.2 SDA and SCL Pins
Spike Filter and SDA Delay Enable the 50 ns spike filters on the SDA/SCL pads using FLTEN bit. An additional SDA delay can be configured using SDAHT bits. 37.2.3.2.1 I3C Pad Compatibility with I2C/SMBus Levels
Module Clock Select the appropriate clock for the I3C module using I3CxCLK register. 37.2.1 I3C Module Clock
Bus Time-out If the bus time-out feature is desired, the feature can be enabled using BTOEN bit. The bus time-out threshold can be set using I3CxBTO register. 37.2.3.4.4 Bus Time-out
Static Address Set the desired static address for the I3C module using I3CxSADR register. 37.2.4.2.1 I2C Static Address
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. 37.2.4.4 Transmit and Receive Buffers and FIFO
I2C Transaction Configure ACK control for I2C Transactions using ACKP and ACKPOS bits. 37.2.5 Legacy I2C Transaction on I3C Bus
Permanent I2C Mode Enable Hot-Join capability using HJCAP bit to prevent the device from participating in Dynamic Address Assignment process. The user must ensure to not send a Hot-Join request to permanently stay in I2C mode. 37.2.8 Hot-Join Mechanism
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. 37.2.14 Interrupts and DMA Triggers
Module Enable Enable the I3C module in the end by setting the EN bit.

Module Setup in I2C/SMBus Mode

// RxyFEAT Buffer Selection
#define GPIO_BUFFER         0b000   // ST/CMOS or LVBUF/TTL selected through INLVLx
#define I2C_BUFFER          0b001
#define SMB2_BUFFER         0b010
#define SMB3_BUFFER         0b011
#define I3CFST_BUFFER       0b100   // Only for >1.62V (set VDDIOxMD config properly)
#define I3CLV_BUFFER        0b101   // Only for <1.62V (set VDDIOxMD config properly)

void I3C1_Target_Setup()
{
    // Assumption: RC0/RC1 pins are SCL/SDA
    
    // Ensure module is turned off for setup
    I3C1CON0bits.EN = 0;            
    
    // Note: VDDIOxMD config bit must be set properly

    // Set SDA/SCL pins to be open-drain inputs
    ODCONCbits.ODCC0 = 1;
    ODCONCbits.ODCC1 = 1;
    TRISCbits.TRISC0 = 1;
    TRISCbits.TRISC1 = 1;
    
    // Select I2C/SMB2/SMB3 buffer
    RC0FEATbits.I3CBUF = I2C_BUFFER;
    RC1FEATbits.I3CBUF = I2C_BUFFER;
    
    // Enable I2C features on I3C pads as needed
    I3C1I2CCONbits.FLTEN = 1;       // 50 ns glitch filter
    I3C1I2CCONbits.SDAHT = 0b00;    // SDA Hold Time
    
    // Select Clock
    I3C1CLK = 0x01;         // 0x01=Fosc   

    // Bus Timeout settings (optional)
    I3C1CON0bits.BTOEN = 0; // Enable/Disable Bus Timeout
    I3C1BTO = 164;          // 32*F_scl @ F_scl=12.5MHz (or any appropriate value)

    // Static Address
    I3C1SADR = 0x30;        // Static Address  
    
    // Clear buffers and FIFOs
    I3C1CON0bits.CLRRXB = 1; // Clears RXB Rx Buffer and Rx FIFO
    I3C1CON0bits.CLRTXB = 1; // Clears TXB Tx Buffer and Tx FIFO

    // Default I2C Write/Read ACK setting
    I3C1CON0bits.ACKP = 0;   // 0=ACK; 1=NACK
    I3C1CON1bits.ACKPOS = 0; // 0=One-shot disabled

    // Enabling Hot-Join capability ensures that the module does
    // not respond to ENTDAA unless HJ is requested first.
    // To always stay in I2C mode, user must not request HJ after this
    I3C1FEATbits.HJCAP = 1;
    
    // 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 PIE 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
    I3C1CON0bits.EN = 1;        
}