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