37.3.1 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 37-20. 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.Setting | Description | Section Reference |
---|---|---|
Pad Buffer Selection | Set SDA/SCL pins as open-drain inputs and select an appropriate pad buffer (I3C LV/FST Buffer) using the RxyFEAT register. | 37.2.3.2 SDA and SCL Pins |
Module Clock | Select the appropriate clock for the I3C module using I3CxCLK register. | 37.2.1 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. | 37.2.3.4 I3C Bus Conditions |
Bus Time-out (optional) | If the bus time-out feature is desired, the feature can be enabled using BTOEN bit in RxyFEAT register. The bus time-out threshold can be set using I3CxBTO register. | 37.2.3.4.4 Bus Time-out |
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 and Payload Size can be set using the I3CxIBIMDB and I3CxIBIPSZ registers. The module can be made Hot-Join capable by setting the HJCAP bit. | |
Static Address | Set the desired static address for the I3C module using I3CxSADR register. | 37.2.4.2.1 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. | |
Speed Limitations | If the device/application is speed limited, set the BCR0 bit in I3CxBCR register. Set the maximum read/write speed and read turnaround times using the I3CxMWS, I3CxMRS and I3CxMRT registers. | 37.2.3.3 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. | 37.2.4.4 Transmit and Receive Buffers and FIFO |
Static Address SDR Mode | If desired, the Static Address SDR Mode can be enabled using the SASDRMD bit. | 37.2.6.4 Static Address SDR Mode |
Private Transaction | Configure ACK control for Private Transactions using ACKP and ACKPOS bits. Change Maximum Read/Write Lengths as necessary using I3CxMRL and I3CxMWL registers. | 37.2.10 Private Transaction |
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. | — |
Tip: It is recommended that the user
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 the Interrupts and DMA Triggers section
and the "DMA - Direct Memory Access" chapter for more information.
Module Setup in I3C® 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 I3C FST/LV buffer RC0FEATbits.I3CBUF = I3CFST_BUFFER; RC1FEATbits.I3CBUF = I3CFST_BUFFER; // Enable/Disable I2C features on I3C pads as needed I3C1I2CCONbits.FLTEN = 0; // 50 ns glitch filter I3C1I2CCONbits.SDAHT = 0b00; // SDA Hold Time // Select Clock I3C1CLK = 0x01; // 0x01=Fosc // Set Bus Idle and Bus Available Conditions I3C1BIDL = 12800; // 200us I3C1BAVL = 64; // 1us // Bus Timeout settings (optional) I3C1CON0bits.BTOEN = 0; // Enable/Disable Bus Timeout I3C1BTO = 164; // 32*F_scl @ F_scl=12.5MHz (or any appropriate value) // IBI/HJ Settings // HJCAP=0: module responds to ENTDAA all the time and cannot request HJ // HJCAP=1: module cannot respond to ENTDAA unless HJ is requested first I3C1FEATbits.HJCAP = 0; // HJ capable or not? I3C1RETRY = 3; // Number of retries for IBI and HJ I3C1IBIMDB = 0xA5; // IBI Mandatory Byte (0x00 = User Defined) I3C1IBIPSZ = 0; // Payload size (0 = unlimited, 8-bit value) // 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 = 0x11; // PID[31:16] is Part ID I3C1PID2 = 0x22; I3C1PID1 = 0x33; // PID[15:12] is Instance ID I3C1PID0 = 0x44; // PID[11:0] is vendor defined // Set Initial Device Status for GETSTATUS CCC I3C1DSTAT0 = 0x00; // Activity mode, Protocol Error, Pending Interrupt I3C1DSTAT1 = 0x00; // Vendor Reserved // Is device speed limited? (application dependent) I3C1BCRbits.BCR0 = 1; // Speed limited (If no, BCR0=0) // Device Characteristics I3C1DCR = 0xC6; // 0xC6 = Microcontroller // 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 = 0; // Max Read Turnaround Time (in us) // 24-bit // Clear buffers and FIFOs I3C1CON0bits.CLRRXB = 1; // Clears RXB Rx Buffer and Rx FIFO I3C1CON0bits.CLRTXB = 1; // Clears TXB Tx Buffer and Tx FIFO // Static Address SDR Mode Enable? I3C1CON1bits.SASDRMD = 0; // Private Transaction Settings // Default Private Write/Read ACK setting I3C1CON0bits.ACKP = 0; // 0=ACK; 1=NACK I3C1CON1bits.ACKPOS = 0; // 0=One-shot disabled // Max Rd and Max Wr Lengths I3C1MRL = 0; // 0=unlimited (16-bit value) I3C1MWL = 0; // 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; }