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.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; }