24.5.1 Controller Mode

Controller Mode: Dynamically Address the Target and Perform Private Write and Read

typedef union I3C_CMD_TransferCommandDataStruct_Tag
{
    struct
{
    uint32_t CMD_ATTR:3;
    uint32_t TID:4;
    uint32_t CMD:8;
    uint32_t CP:1;
    uint32_t DEV_INDEX:5;
    uint32_t SPEED:3;
    uint32_t RESERVED:1;
    uint32_t DBP:1;
    uint32_t ROC:1;
    uint32_t SDAP:1;
    uint32_t RnW:1;
    uint32_t TGT_RST:1;
    uint32_t TOC:1;
    uint32_t PEC:1;
}F;
uint32_t TransferCommand;    
} I3C_CMD_TransferCommandDataStruct_T;

typedef union I3C_CMD_TransferArgumentDataStruct_Tag
{
struct
{
    uint32_t CMD_ATTR:3;
    uint32_t RESERVED:5;
    uint32_t DB:8;
    uint32_t DL:16;
}F;
uint32_t TransferArgument;    
} I3C_CMD_TransferArgumentDataStruct_T;

typedef union I3C_CMD_ShortDataArgumentStruct_Tag
{
    struct
    {
        uint32_t CMD_ATTR:3;
        uint32_t BYTE_STRB0:1;
        uint32_t BYTE_STRB1:1;
        uint32_t BYTE_STRB2:1;
        uint32_t RESERVED:2;
        uint32_t DATA_BYTE_0:8;
        uint32_t DATA_BYTE_1:8;
        uint32_t DATA_BYTE_2:8;
    }F;
    uint32_t ShortDataArgument;    
} I3C_CMD_ShortDataArgumentDataStruct_T;

typedef union I3C_CMD_AddrAssignCommandDataStruct_Tag
{
    struct
    {
        uint32_t CMD_ATTR:3;
        uint32_t TID:4;
        uint32_t CMD:8;
        uint32_t RESERVED:1;
        uint32_t DEV_INDEX:5;
        uint32_t DEV_COUNT:5;
        uint32_t ROC:1;
        uint32_t RESERVED1:3;
        uint32_t TOC:1;
        uint32_t RESERVED2:1;
    }F;
    uint32_t AddrAssignCommand;    
} I3C_CMD_AddrAssignCommandDataStruct_T;
typedef union I3C_ResponseDataStruct_Tag
{
    struct
    {
        uint32_t DL:16;
        uint32_t CCCT:8;
        uint32_t TID:4;
        uint32_t ERR_STS:4;
    }F;
    uint32_t RespondData;    
} I3C_ResponseDataStruct_T;

typedef struct I3C_DCT_Tag
{
    uint32_t DCT_LOC1;
    uint32_t DCT_LOC2;
    uint32_t DCT_LOC3;
    uint32_t DCT_LOC4;
  
} I3C_DCT_T;

I3C_CMD_AddrAssignCommandDataStruct_T cmd;
I3C_CMD_TransferCommandDataStruct_T transCmd;
I3C_CMD_TransferArgumentDataStruct_T transArg;
I3C_ResponseDataStruct_T respQ;
I3C_DCT_T target1;
uint32_t receivedData[100];

int main()
{  
/* Configure System Clock and I3C Clock Generator*/



   /*Enable Internal pull up which acts as Bus High Keeper*/ 
    _CNPUC4 = 1;
    _CNPUC5 = 1;    
/********************************************************************************/   
    I3C1CONbits.ON = 1 ;                           // I3C module enable
    I3C1CTRLEXTbits.DEVOPMOD = 0 ;                 // Controller mode
    I3C1ADDbits.DYNADDR = 0x4C;                    // Controller Self Dynamic Address Assignment 
    I3C1ADDbits.DYNADDRVALID = 1;                  // Dynamic Address valid     

    I3C1SCLODTIM = 0x0007001A;                     // Configure SCL Open Drain timing
    I3C1PPTIM = 0x00070007;                        // Configure SCL Push pull timing

    I3C1QUETHLDCON =  (I3C1QUETHLDCON & 0xFFFF00FF) | 0x00000000;   // Configure response threshold to 1 level
    I3C1BUFTHLDbits.RXTHLD = 1 ;                    // Configure RX threshold to 4 levels
    
    I3C1INTSTACONbits.RXTHLDSTAEN = 1;              //Enable RX status  
    I3C1INTCONbits.RXTHLDINTEN = 1;                 // Enable Rx interrupt
    I3C1INTSTACONbits.RESPQSTAEN = 1;               // Enable Response status
    I3C1INTCONbits.RESPQINTEN = 1;                  // Enable response interrupt
    
    I3C1CNTRLbits.IBA  = 1 ;                        // Include I3C broadcast address
    /*Write address table (DAT)*/
    /* Target device is I3C
     * Dynamic address 0x33, after calculate odd parity 0xB3
     * IBI with data supported
     * Static address 0x45 */
    I3C1DEVADDRTAB1LOC1= 0x00B31045;                  
    
    I3C1CNTRLbits.ENABLE  = 1 ;                     // Enable I3C operation
    
    /* Enable interrupt signal*/
    IFS11bits.I3C1GIF = 0;
    IEC11bits.I3C1GIE = 1;
    
/******************Dynamic Addressing - ENTDAA Command***********************/     
    cmd.F.CMD_ATTR = 0x03;                  // Address Assignment Command
    cmd.F.TID = 0x1;                        // Transaction ID
    cmd.F.CMD = 0x07;                       // ENTDAA command
    cmd.F.DEV_COUNT = 1;                    // One device
    cmd.F.DEV_INDEX = 0;                    // 0th index
    cmd.F.TOC = 1;                          // Termination On Completion
    cmd.F.ROC = 1;                          // Response On Completion
    I3C1CMDQUE = cmd.AddrAssignCommand;     // Write to CMD queue 
    
   /**************Controller Private Write******************************/ 
    /*Write data to Transmit FIFO*/
    I3C1TXRXDATA = 0x5555AAA1;
    I3C1TXRXDATA = 0x5555AAA2;
    I3C1TXRXDATA = 0x5555AAA3;
    I3C1TXRXDATA = 0x5555AAA4;

    transArg.F.CMD_ATTR = 0x1;              // Transfer Argument
    transArg.F.DL = 0x10;                   // Data length
    
    transCmd.F.CMD_ATTR = 0;                // Transfer Command         
    transCmd.F.TID = 0x2;                   // Transaction ID
    transCmd.F.TOC = 1;                     // Termination On Completion
    transCmd.F.ROC = 1;                     // Response On Completion
    I3C1CMDQUE = transArg.TransferArgument;  // Write to CMD queue 
    I3C1CMDQUE = transCmd.TransferCommand;  // Write to CMD queue 
    
/**********************Controller Private Read****************************/    
    
    
    transArg.F.CMD_ATTR = 0x1;               // Transfer Argument    
    transArg.F.DL = 0x10;                   // Data length
    
    transCmd.F.CMD_ATTR = 0;                 // Transfer Command 
    transCmd.F.TID = 0x3;                    // Transaction ID
    transCmd.F.RnW = 1;                      // Read
    transCmd.F.TOC = 1;                     // Termination On Completion
    transCmd.F.ROC = 1;                     // Response On Completion
    I3C1CMDQUE = transArg.TransferArgument; // Write to CMD queue 
    I3C1CMDQUE = transCmd.TransferCommand;  // Write to CMD queue 

/******************************************************************************/
   
    while(1);
    return 0;
}

void __attribute__((interrupt, no_auto_psv)) _I3C1Interrupt()
{
/*Response interrupt is enabled so check if interrupt is due to response received*/
    if(I3C1INTSTAbits.RESPQSTA)
    {
        respQ.RespondData = I3C1RESPQUE;
        if(respQ.F.ERR_STS == 0) // No error
        {
            if (respQ.F.TID = 0x1) // Transaction ID for ENTDAA
            {
                /*Read Device characteristic Table(DCT)*/
                target1.DCT_LOC1 = I3C1DEVCHARTAB1LOC1;
                target1.DCT_LOC2 = I3C1DEVCHARTAB1LOC2;
                target1.DCT_LOC3 = I3C1DEVCHARTAB1LOC3;
                target1.DCT_LOC4 = I3C1DEVCHARTAB1LOC4;
            }
            if(respQ.F.TID = 0x2) // Transaction ID for transmit
            {
                
            }
            if(respQ.F.TID = 0x3) // Transaction ID for Receive
            {
                if(I3C1INTSTAbits.RXTHLDSTA) // Check threshold value, read RXFIFO
                {
                    receivedData[0]= I3C1TXRXDATA;
                    receivedData[1]= I3C1TXRXDATA;
                    receivedData[2]= I3C1TXRXDATA;
                    receivedData[3]= I3C1TXRXDATA;
                }
            }
        }
        else
        {
            /*Error handling*/
        }
    }    
    IFS11bits.I3C1GIF = 0;
}