/* ================================================================== >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<< ------------------------------------------------------------------ Copyright (c) 2019-2023 by Lattice Semiconductor Corporation ALL RIGHTS RESERVED ------------------------------------------------------------------ IMPORTANT: THIS FILE IS USED BY OR GENERATED BY the LATTICE PROPELâ„¢ DEVELOPMENT SUITE, WHICH INCLUDES PROPEL BUILDER AND PROPEL SDK. Lattice grants permission to use handle code pursuant to the terms of the Lattice Propel License Agreement. DISCLAIMER: LATTICE MAKES NO WARRANTIES ON THIS FILE OR ITS CONTENTS, WHETHER EXPRESSED, IMPLIED, STATUTORY, OR IN ANY PROVISION OF THE LATTICE PROPEL LICENSE AGREEMENT OR COMMUNICATION WITH LICENSEE, AND LATTICE SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. LATTICE DOES NOT WARRANT THAT THE FUNCTIONS CONTAINED HEREIN WILL MEET LICENSEE 'S REQUIREMENTS, OR THAT LICENSEE' S OPERATION OF ANY DEVICE, SOFTWARE OR SYSTEM USING THIS FILE OR ITS CONTENTS WILL BE UNINTERRUPTED OR ERROR FREE, OR THAT DEFECTS HEREIN WILL BE CORRECTED. LICENSEE ASSUMES RESPONSIBILITY FOR SELECTION OF MATERIALS TO ACHIEVE ITS INTENDED RESULTS, AND FOR THE PROPER INSTALLATION, USE, AND RESULTS OBTAINED THEREFROM. LICENSEE ASSUMES THE ENTIRE RISK OF THE FILE AND ITS CONTENTS PROVING DEFECTIVE OR FAILING TO PERFORM PROPERLY AND IN SUCH EVENT, LICENSEE SHALL ASSUME THE ENTIRE COST AND RISK OF ANY REPAIR, SERVICE, CORRECTION, OR ANY OTHER LIABILITIES OR DAMAGES CAUSED BY OR ASSOCIATED WITH THE SOFTWARE.IN NO EVENT SHALL LATTICE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS FILE OR ITS CONTENTS, EVEN IF LATTICE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. LATTICE 'S SOLE LIABILITY, AND LICENSEE' S SOLE REMEDY, IS SET FORTH ABOVE. LATTICE DOES NOT WARRANT OR REPRESENT THAT THIS FILE, ITS CONTENTS OR USE THEREOF DOES NOT INFRINGE ON THIRD PARTIES' INTELLECTUAL PROPERTY RIGHTS, INCLUDING ANY PATENT. IT IS THE USER' S RESPONSIBILITY TO VERIFY THE USER SOFTWARE DESIGN FOR CONSISTENCY AND FUNCTIONALITY THROUGH THE USE OF FORMAL SOFTWARE VALIDATION METHODS. ------------------------------------------------------------------ ================================================================== */ #include "i3c_controller.h" /** * @brief Initialization function for i3c controller. * @param : handle : handle for the controller * @return : status for initialization */ unsigned int i3c_controller_init(i3c_controller_handle_t *handle) { unsigned char reg_value; unsigned int status; if(handle->base_addr != ZERO ) { i3c_cntler_reg_t *i3c_contrlr=(i3c_cntler_reg_t *)(handle->base_addr); if(handle->mode==I3C_MODE) { i3c_contrlr->i3c_controller_config0=I3C_MODE_ALLOWED|EN_DAA_UID_IN_RXFIFO; //SET i3c mode reg_value= i3c_contrlr->i3c_controller_clock_divider; //to check the clock and open drain values reg_value= i3c_contrlr->i3c_controller_open_drain; }else { i3c_contrlr->i3c_controller_config0=I2C_MODE_ALLOWED; //SET i2c mode reg_value= i3c_contrlr->i3c_controller_i2c_clock_divider; //to check the i2c clock } i3c_contrlr->i3c_controller_intrpt_enable0=ALL_BITS_EN; //interrupt enable0 i3c_contrlr->i3c_controller_intrpt_enable1=ALL_BITS_EN; //interrupt enable1 i3c_contrlr->i3c_controller_intrpt_enable2=ALL_BITS_EN; //interrupt enable2 status=SUCCESS; } else { status=FAILURE; } return status; } /* * @brief entdaa_config function for i3c controller. * @param : handle : handle for the controller * @return : status for entdaa_config */ unsigned int i3c_controller_entdaa_1tgt(i3c_controller_handle_t *handle){ unsigned int wr_length; unsigned int control; unsigned int status; if((handle->base_addr != ZERO) && (handle->target_dyn_addr != ZERO) && (handle->target_nums != ZERO) ) { i3c_cntler_reg_t *i3c_contrlr=(i3c_cntler_reg_t *)(handle->base_addr); wr_length=SET+handle->target_nums; control = CCC_CMD1_WR_RD0|STOP_IN_FRAME|CCC_COMMAND_WITH_START; i3c_contrlr->i3c_controller_tx_fifo= control; i3c_contrlr->i3c_controller_tx_fifo= RESERVED_ADDRESS<i3c_controller_tx_fifo= wr_length; //write length i3c_contrlr->i3c_controller_tx_fifo= ENTDAA; //ENTDAA CCC i3c_contrlr->i3c_controller_tx_fifo= handle->target_dyn_addr<< SET; status=SUCCESS; } else { status= FAILURE; } return status; } /* @brief DAA function for i3c controller. * @param : handle : handle for the controller * info : struct for device board * @return : status for DAA */ unsigned int i3c_controller_daa_1tgt(i3c_controller_handle_t *handle,i3c_dev_info_t *info) { unsigned int device_pid = CLEAR; unsigned int device_pid_shift = CLEAR; unsigned int device_bcr; unsigned int device_dcr; unsigned char read_value; unsigned int status=FAILURE; unsigned int int_status = CLEAR; int count; int cnt=CLEAR; if((handle->base_addr != ZERO) && (handle->target_dyn_addr < MAX_ADRR_SIZE) ) { i3c_cntler_reg_t *i3c_contrlr=(i3c_cntler_reg_t *)(handle->base_addr); i3c_contrlr->i3c_controller_intrpt_status0= ALL_BITS_EN ; i3c_controller_entdaa_1tgt(handle); i3c_contrlr->i3c_controller_start_reg = START; do { if(i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_CMND_DONE) { i3c_contrlr->i3c_controller_intrpt_status0= RCVD_CMND_DONE; if(i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_SLAVE_NACK) // wait until all targets ACK on DAA { i3c_contrlr->i3c_controller_intrpt_status0 = RCVD_SLAVE_NACK; if (i3c_contrlr->i3c_controller_da_ack_reg) { if(i3c_contrlr->i3c_controller_intrpt_status0 & RX_FIFO_n_EMPTY) { i3c_contrlr->i3c_controller_intrpt_status0= RX_FIFO_n_EMPTY; for(cnt=ZERO;cnttarget_nums;cnt++) //get info from readfifo { for(count=FIVE_SHIFT;count>=CLEAR;count--) { read_value=i3c_contrlr->i3c_controller_rx_fifo; device_pid_shift = (unsigned int) read_value; device_pid = device_pid | (device_pid_shift << (EIGHT_LEFT_SHIFT*count)); } read_value=i3c_contrlr->i3c_controller_rx_fifo; device_bcr=read_value; read_value=i3c_contrlr->i3c_controller_rx_fifo; device_dcr=read_value; info->pid=device_pid; info->bcr=device_bcr; info->dcr=device_dcr; info->init_dyn_addr=handle->target_dyn_addr; } break; } break; } else { status=FAILURE;; } } } }while(status==FAILURE); } else { status= FAILURE; } return status; } /* * @brief i3c_controller_entdaa_ntargets function for i3c controller. * @param : handle : handle for the controller * @return : status for entdaa_config */ unsigned int i3c_controller_entdaa_multitargets(i3c_controller_handle_t *handle){ unsigned int wr_length; unsigned int control; unsigned int status; unsigned int index; if((handle->base_addr != ZERO)&& (handle->target_dyn_addr != ZERO) && (handle->target_nums != ZERO)) { i3c_cntler_reg_t *i3c_contrlr=(i3c_cntler_reg_t *)(handle->base_addr); wr_length=SET+handle->target_nums; control = CCC_CMD1_WR_RD0|STOP_IN_FRAME|CCC_COMMAND_WITH_START; i3c_contrlr->i3c_controller_tx_fifo= control; //control i3c_contrlr->i3c_controller_tx_fifo= RESERVED_ADDRESS<i3c_controller_tx_fifo= wr_length; //write length i3c_contrlr->i3c_controller_tx_fifo= ENTDAA; //ENTDAA CCC for(index=ZERO;indexi3c_controller_tx_fifo=handle->target_dyn_addr_multi[index] <i3c_controller_start_reg = START; status=SUCCESS; } else { status=FAILURE; } return status; } /** * @brief i3c write function for i3c controller. * @param : handle : handle for the controller * @return : status for i3c write */ unsigned int i3c_controller_private_i3c_write(i3c_controller_handle_t *handle){ unsigned int control; unsigned int status; unsigned int index; if((handle->base_addr != ZERO) && (handle->target_dyn_addr != ZERO) && (handle->len != ZERO) && (handle->buf != ZERO) && (handle->lenbase_addr); control = STOP_IN_FRAME; i3c_contrlr->i3c_controller_intrpt_status0 = ALL_BITS_EN; //interrupt enable i3c_contrlr->i3c_controller_config0 = I3C_MODE_ALLOWED; // enter i3c mode i3c_contrlr->i3c_controller_tx_fifo = control; // control i3c_contrlr->i3c_controller_tx_fifo = handle->target_dyn_addr<i3c_controller_tx_fifo = handle->len; //SET the length of data to write for (index=ZERO;indexlen;index++) { i3c_contrlr->i3c_controller_tx_fifo = handle->buf[index]; //write the data } i3c_contrlr->i3c_controller_start_reg = START; do { if (i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_CMND_DONE) { if(i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_SLAVE_NACK) { i3c_contrlr->i3c_controller_intrpt_status0 = RCVD_SLAVE_NACK; status=FAILURE; } else { i3c_contrlr->i3c_controller_intrpt_status0 = RCVD_CMND_DONE; status=SUCCESS; } } }while(status!=SUCCESS); } else { status= FAILURE; } return status; } /** * @brief i3c read function for i3c controller. * @param : handle : handle for the controller * @return : status for i3c read */ unsigned int i3c_controller_private_i3c_read(i3c_controller_handle_t *handle ){ unsigned int control; unsigned int status; unsigned int index; if((handle->base_addr != ZERO) && (handle->target_dyn_addr != ZERO) && (handle->len != ZERO) && (handle->buf != ZERO) && (handle->lenbase_addr); control = STOP_IN_FRAME; i3c_contrlr->i3c_controller_intrpt_status0 = ALL_BITS_EN; //interrupt enable i3c_contrlr->i3c_controller_config0 = I3C_MODE_ALLOWED; // enter i3c mode i3c_contrlr->i3c_controller_tx_fifo = control; // control i3c_contrlr->i3c_controller_tx_fifo = (handle->target_dyn_addr<i3c_controller_tx_fifo = handle->len; //SET the length of data to read i3c_contrlr->i3c_controller_start_reg = START; do { if(i3c_contrlr->i3c_controller_intrpt_status0 & RX_FIFO_n_EMPTY) { if(i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_CMND_DONE) { if(i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_SLAVE_NACK) { i3c_contrlr->i3c_controller_intrpt_status0 = RCVD_SLAVE_NACK; status=FAILURE; } else if (i3c_contrlr->i3c_controller_intrpt_status0 & RD_CMD_DONE) { for(index=ZERO;indexlen;index++) { handle->buf[index]=i3c_contrlr->i3c_controller_rx_fifo; } i3c_contrlr->i3c_controller_intrpt_status0 = RX_FIFO_n_EMPTY|RCVD_CMND_DONE|RD_CMD_DONE; status= SUCCESS; } } } }while(status!=SUCCESS); } else { status= FAILURE; } return status; } /** * @brief i2c write function for i3c controller. * @param : handle : handle for the controller * @return : status for i2c write */ unsigned int i3c_controller_private_i2c_write(i3c_controller_handle_t *handle ){ unsigned int control; unsigned int status; unsigned int index; if((handle->base_addr != ZERO) && (handle->target_static_addr != ZERO) && (handle->len != ZERO) && (handle->buf != ZERO) && (handle->lenbase_addr); control = STOP_IN_FRAME|I2C_FRAME; i3c_contrlr->i3c_controller_intrpt_status0 = ALL_BITS_EN; //interrupt enable i3c_contrlr->i3c_controller_config0 = I2C_MODE_ALLOWED; //i2c mode allowed i3c_contrlr->i3c_controller_tx_fifo = control; //control i3c_contrlr->i3c_controller_tx_fifo = handle->target_static_addr<i3c_controller_tx_fifo = handle->len; //SET the length of data to write for (index=ZERO;indexlen;index++) { i3c_contrlr->i3c_controller_tx_fifo = handle->buf[index]; //write the data } i3c_contrlr->i3c_controller_start_reg = START; do { if (i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_CMND_DONE) { if(i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_SLAVE_NACK) { i3c_contrlr->i3c_controller_intrpt_status0 = RCVD_SLAVE_NACK; status=FAILURE; } else { i3c_contrlr->i3c_controller_intrpt_status0 = RCVD_CMND_DONE; status= SUCCESS; } } }while(status!=SUCCESS); } else { status=FAILURE; } return status; } /** * @brief i2c read function for i3c controller. * @param : handle : handle for the controller * @return : status for i2c read */ unsigned int i3c_controller_private_i2c_read(i3c_controller_handle_t *handle ){ unsigned int control; unsigned int status; unsigned int index; if((handle->base_addr != ZERO) && (handle->target_static_addr != ZERO) && (handle->len != ZERO) && (handle->buf != ZERO) && (handle->lenbase_addr); control = STOP_IN_FRAME|I2C_FRAME; i3c_contrlr->i3c_controller_intrpt_status0 = ALL_BITS_EN; //interrupt enable i3c_contrlr->i3c_controller_config0 = I2C_MODE_ALLOWED; //SET to allow i2c mode i3c_contrlr->i3c_controller_tx_fifo = control; // control i3c_contrlr->i3c_controller_tx_fifo = (handle->target_static_addr<i3c_controller_tx_fifo = handle->len; //SET the length of data to read i3c_contrlr->i3c_controller_start_reg = START; do { if(i3c_contrlr->i3c_controller_intrpt_status0 & RX_FIFO_n_EMPTY) { if(i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_CMND_DONE) { if(i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_SLAVE_NACK) { i3c_contrlr->i3c_controller_intrpt_status0 = RCVD_SLAVE_NACK; status=FAILURE; } else if (i3c_contrlr->i3c_controller_intrpt_status0 & RD_CMD_DONE) { for(index=ZERO;indexlen;index++) { handle->buf[index]=i3c_contrlr->i3c_controller_rx_fifo ; } i3c_contrlr->i3c_controller_intrpt_status0 = RX_FIFO_n_EMPTY|RCVD_CMND_DONE|RD_CMD_DONE; status= SUCCESS; } } } }while(status!=SUCCESS); } else { status=FAILURE; } return status; } /* * @brief broadcast_ccc function for i3c controller. * @param : handle : handle for the controller * @return : status for broadcast_ccc */ unsigned int i3c_controller_broadcast_ccc(i3c_controller_handle_t *handle){ unsigned int control; unsigned int status; unsigned int index; if((handle->base_addr != ZERO) && (handle->len != ZERO) && (handle->buf != ZERO) && (handle->lenbase_addr); control = CCC_CMD1_WR_RD0|CCC_COMMAND_WITH_START|STOP_IN_FRAME; i3c_contrlr->i3c_controller_intrpt_status0 = ALL_BITS_EN; //interrupt enable i3c_contrlr->i3c_controller_tx_fifo = control; //control i3c_contrlr->i3c_controller_tx_fifo = RESERVED_ADDRESS<i3c_controller_tx_fifo = handle->len; //Set command length for (index=ZERO;indexlen;index++) { i3c_contrlr->i3c_controller_tx_fifo=handle->buf[index]; // command+optional Bytes } i3c_contrlr->i3c_controller_start_reg=START; do{ if (i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_CMND_DONE) { i3c_contrlr->i3c_controller_intrpt_status0=RCVD_CMND_DONE; status=SUCCESS; } }while(status!=SUCCESS); } else { status=FAILURE; } return status; } /** * @brief direct_ccc write function for i3c controller. * @param : handle : handle for the controller * @return : status for direct_ccc write */ unsigned int i3c_controller_direct_ccc_write(i3c_controller_handle_t *handle){ unsigned int index; unsigned int status; i3c_cntler_reg_t *i3c_contrlr=(i3c_cntler_reg_t *)(handle->base_addr); i3c_contrlr->i3c_controller_tx_fifo=handle->target_dyn_addr<i3c_controller_tx_fifo=handle->direct_ccc_optnal_bytes; //Set command length for ( index=ZERO;indexdirect_ccc_optnal_bytes;index++) { i3c_contrlr->i3c_controller_tx_fifo=handle->direct_ccc_optnal_data_array[index]; //write the data } i3c_contrlr->i3c_controller_start_reg=START; do { if (i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_CMND_DONE) { if(i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_SLAVE_NACK) { i3c_contrlr->i3c_controller_intrpt_status0 =RCVD_SLAVE_NACK; status=FAILURE; } else { i3c_contrlr->i3c_controller_intrpt_status0 =RCVD_CMND_DONE; status= SUCCESS; } } }while(status!=SUCCESS); return status; } /** * @brief direct_ccc read function for i3c controller. * @param : handle : handle for the controller * @return : status for direct_ccc read */ unsigned int i3c_controller_direct_ccc_read(i3c_controller_handle_t *handle){ unsigned int index; unsigned int status; i3c_cntler_reg_t *i3c_contrlr=(i3c_cntler_reg_t *)(handle->base_addr); i3c_contrlr->i3c_controller_tx_fifo=(handle->target_dyn_addr<i3c_controller_tx_fifo=handle->direct_ccc_optnal_bytes; //Set command length i3c_contrlr->i3c_controller_start_reg=START; do { if(i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_CMND_DONE) { if(i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_SLAVE_NACK) { i3c_contrlr->i3c_controller_intrpt_status0 = RCVD_SLAVE_NACK; status=FAILURE; } else { for(index=ZERO;indexdirect_ccc_optnal_bytes;index++) { handle->buf[index]=i3c_contrlr->i3c_controller_rx_fifo; } i3c_contrlr->i3c_controller_intrpt_status0=RCVD_CMND_DONE; status= SUCCESS; } } }while(status!=SUCCESS); return status; } /** * @brief direct_ccc function for i3c controller. * @param : handle : handle for the controller * read1_write0 : to SET read or write * @return : status for direct_ccc */ unsigned int i3c_controller_direct_ccc(i3c_controller_handle_t *handle, bool read1_write0){ unsigned int control; unsigned int status; unsigned int index; if((handle->base_addr != ZERO) && (handle->target_dyn_addr != ZERO) && (handle->len != ZERO) && (handle->buf != ZERO) && (handle->lenbase_addr); control = CCC_CMD1_WR_RD0|CCC_COMMAND_WITH_START; i3c_contrlr->i3c_controller_intrpt_status0= ALL_BITS_EN; i3c_contrlr->i3c_controller_config0=I3C_MODE_ALLOWED; // enter i3c mode i3c_contrlr->i3c_controller_tx_fifo=control; // control i3c_contrlr->i3c_controller_tx_fifo=RESERVED_ADDRESS <i3c_controller_tx_fifo=handle->len; //Set command length for (index=ZERO;indexlen;index++) { i3c_contrlr->i3c_controller_tx_fifo=handle->buf[index]; // command+optional Bytes } i3c_contrlr->i3c_controller_tx_fifo=CCC_CMD1_WR_RD0|REPEATED_START_IN_FRAME|STOP_IN_FRAME; //Control if(read1_write0==WRITE) { i3c_controller_direct_ccc_write(handle); } else if(read1_write0==READ) { i3c_controller_direct_ccc_read(handle); } } else { status=FAILURE; } return status; } /** * @brief i3c_enter_hdr_ddr_mode function for i3c controller. * @param : handle : handle for the controller * @return : status for i3c_enter_hdr_ddr_mode */ unsigned int i3c_enter_hdr_ddr_mode(i3c_controller_handle_t *handle){ unsigned int status; if(handle->base_addr != ZERO) { i3c_cntler_reg_t *i3c_contrlr=(i3c_cntler_reg_t *)(handle->base_addr); i3c_contrlr->i3c_controller_tx_fifo=CCC_CMD1_WR_RD0|CCC_COMMAND_WITH_START; //Control - 0x09 i3c_contrlr->i3c_controller_tx_fifo = RESERVED_ADDRESS<i3c_controller_tx_fifo = SET; //Set number of bytes writing to the Tx FIFO i3c_contrlr->i3c_controller_tx_fifo = ENTHDR0; //Set HDR Code 0x20 status=SUCCESS; } else { status=FAILURE; } return status; } /** * @brief hdr write function for i3c controller. * @param : handle : handle for the controller * @return : status for hdr write */ unsigned int i3c_controller_hdr_ddr_write(i3c_controller_handle_t *handle){ unsigned int status; unsigned int index; if((handle->base_addr != ZERO) && (handle->target_dyn_addr != ZERO) && (handle->len != ZERO) && (handle->buf != ZERO) && (handle->lenbase_addr); i3c_contrlr->i3c_controller_intrpt_status2=ALL_BITS_EN; i3c_contrlr->hdr_ddr_config0 = DDR_IGNORE_CMD_DONE|NO_CRC_AFTER_TERM|EN_WRCMD_ACKNAK_CAP|EN_WR_EARLY_TERM; i3c_enter_hdr_ddr_mode(handle); i3c_contrlr->i3c_controller_tx_fifo = REPEATED_START_IN_FRAME|STOP_IN_FRAME|WAIT_NEXT_PACKET|HDR_MODE; //Control i3c_contrlr->i3c_controller_tx_fifo = handle->target_dyn_addr<i3c_controller_tx_fifo = handle->len+SET; //SET the length of data to write i3c_contrlr->i3c_controller_tx_fifo = handle->user_7bit_code>>SET; //user command code for (index=ZERO;index<(handle->len);index++) // length or data is always multiples of 2 { i3c_contrlr->i3c_controller_tx_fifo = handle->buf[index]; //write the data } i3c_contrlr->i3c_controller_start_reg = START; do { if (i3c_contrlr->i3c_controller_intrpt_status2 & HDR_CMND_DONE) { if(i3c_contrlr->i3c_controller_intrpt_status2 & HDR_SLAVE_NACK) { i3c_contrlr->i3c_controller_intrpt_status2=HDR_SLAVE_NACK; status=FAILURE; } else { i3c_contrlr->i3c_controller_intrpt_status2=HDR_CMND_DONE; status= SUCCESS; } } }while(status!=SUCCESS); } else { status=FAILURE; } return status; } /* * @brief hdr read function for i3c controller. * @param : handle : handle for the controller * @return : status for hdr read */ unsigned int i3c_controller_hdr_ddr_read(i3c_controller_handle_t *handle){ unsigned int status; unsigned int index; if((handle->base_addr != ZERO) && (handle->target_dyn_addr != ZERO) && (handle->len != ZERO) && (handle->buf != ZERO) && (handle->lenbase_addr); i3c_contrlr->i3c_controller_intrpt_status2=ALL_BITS_EN; i3c_contrlr->hdr_ddr_config0 = DDR_IGNORE_CMD_DONE|NO_CRC_AFTER_TERM|EN_WRCMD_ACKNAK_CAP|EN_WR_EARLY_TERM; i3c_enter_hdr_ddr_mode(handle); i3c_contrlr->i3c_controller_tx_fifo = REPEATED_START_IN_FRAME|WAIT_NEXT_PACKET|HDR_MODE; //Control i3c_contrlr->i3c_controller_tx_fifo = handle->target_dyn_addr<i3c_controller_tx_fifo = SET; //SET the length of data to read i3c_contrlr->i3c_controller_tx_fifo = handle->user_7bit_code>>SET|READ_RIGHT_SHIFT; //user command code to read i3c_contrlr->i3c_controller_tx_fifo = REPEATED_START_IN_FRAME|STOP_IN_FRAME|WAIT_NEXT_PACKET|HDR_MODE; //Control i3c_contrlr->i3c_controller_tx_fifo = handle->target_dyn_addr<i3c_controller_tx_fifo = handle->len; //SET the length of data to write i3c_contrlr->i3c_controller_start_reg = START; do { if(i3c_contrlr->i3c_controller_intrpt_status0 & RX_FIFO_n_EMPTY) { if(i3c_contrlr->i3c_controller_intrpt_status2 & HDR_CMND_DONE) { if(i3c_contrlr->i3c_controller_intrpt_status2 & HDR_SLAVE_NACK) { i3c_contrlr->i3c_controller_intrpt_status2 = HDR_SLAVE_NACK; status= FAILURE; } else if (i3c_contrlr->i3c_controller_intrpt_status2 & HDR_RD_CMD_DONE) { for(index=ZERO;indexlen;index++) { handle->buf[index]=i3c_contrlr->i3c_controller_rx_fifo; } i3c_contrlr->i3c_controller_intrpt_status0 = RX_FIFO_n_EMPTY; i3c_contrlr->i3c_controller_intrpt_status2 = HDR_CMND_DONE|HDR_RD_CMD_DONE; status= SUCCESS; } } } }while(status!=SUCCESS); } else { status=FAILURE; } return status; } /** * @brief i3c_controller_Consecutive_private_i3c_write function for i3c controller. * @param : handle : handle for the controller * @return : status for i3c_controller_Consecutive_private_i3c_write */ unsigned int i3c_controller_Consecutive_private_i3c_write(i3c_controller_handle_t *handle) { unsigned int status; unsigned int control; unsigned int index; if((handle->base_addr != ZERO) && (handle->target_dyn_addr != ZERO) && (handle->len != ZERO) && (handle->buf != ZERO) && (handle->lenbase_addr); control = CLEAR; i3c_contrlr->i3c_controller_intrpt_status0 = ALL_BITS_EN; //interrupt enable i3c_contrlr->i3c_controller_config0 = I3C_MODE_ALLOWED; // enter i3c mode i3c_contrlr->i3c_controller_tx_fifo = control; // SET to stop in frame i3c_contrlr->i3c_controller_tx_fifo = handle->target_dyn_addr<i3c_controller_tx_fifo = handle->len; //SET the length of data to write for (index=ZERO;indexlen;index++) { i3c_contrlr->i3c_controller_tx_fifo = handle->buf[index]; //write the data } control=REPEATED_START_IN_FRAME | STOP_IN_FRAME; i3c_contrlr->i3c_controller_tx_fifo = control; // SET to stop in frame i3c_contrlr->i3c_controller_tx_fifo = handle->target2_dyn_addr<i3c_controller_tx_fifo = handle->len2; //SET the length of data to write for (index=ZERO;indexlen2;index++) { i3c_contrlr->i3c_controller_tx_fifo = handle->buf2[index]; //write the data } i3c_contrlr->i3c_controller_start_reg = START; do { if (i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_CMND_DONE) { if(i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_SLAVE_NACK) { i3c_contrlr->i3c_controller_intrpt_status0 = RCVD_SLAVE_NACK; status= FAILURE; } else { i3c_contrlr->i3c_controller_intrpt_status0 = RCVD_CMND_DONE; status= SUCCESS; } } }while(status!=SUCCESS); } else { status=FAILURE; } return status; } /** * @brief i3c_controller_Consecutive_private_i3c_write_read function for i3c controller. * @param : handle : handle for the controller * @return : status for i3c_controller_Consecutive_private_i3c_write_read */ unsigned int i3c_controller_Consecutive_private_i3c_write_read(i3c_controller_handle_t *handle){ unsigned int control; unsigned int status; unsigned int index; if((handle->base_addr != ZERO) && (handle->target_dyn_addr != ZERO) && (handle->len != ZERO) && (handle->buf != ZERO) && (handle->lenbase_addr); control = CLEAR; i3c_contrlr->i3c_controller_intrpt_status0 = ALL_BITS_EN; //interrupt enable i3c_contrlr->i3c_controller_config0 = I3C_MODE_ALLOWED; // enter i3c mode i3c_contrlr->i3c_controller_tx_fifo = control; // control i3c_contrlr->i3c_controller_tx_fifo = handle->target_dyn_addr<i3c_controller_tx_fifo = handle->len; //SET the length of data to write for (index=ZERO;indexlen;index++) { i3c_contrlr->i3c_controller_tx_fifo = handle->buf[index]; //write the data } control = REPEATED_START_IN_FRAME|STOP_IN_FRAME; i3c_contrlr->i3c_controller_tx_fifo = control; // control i3c_contrlr->i3c_controller_tx_fifo = (handle->target_dyn_addr<i3c_controller_tx_fifo = handle->len2; //SET the length of data to read i3c_contrlr->i3c_controller_start_reg = START; do { if(i3c_contrlr->i3c_controller_intrpt_status0 & RX_FIFO_n_EMPTY) { if(i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_CMND_DONE) { if(i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_SLAVE_NACK) { i3c_contrlr->i3c_controller_intrpt_status0 = RCVD_SLAVE_NACK; status=FAILURE; } else if (i3c_contrlr->i3c_controller_intrpt_status0 & RD_CMD_DONE) { for(index=ZERO;indexlen;index++) { handle->buf2[index]=i3c_contrlr->i3c_controller_rx_fifo ; } i3c_contrlr->i3c_controller_intrpt_status0 = RX_FIFO_n_EMPTY|RCVD_CMND_DONE|RD_CMD_DONE; status= SUCCESS; } } } }while(status!=SUCCESS); } else { status=FAILURE; } return status; } /** * @brief i3c_controller_Consecutive_private_i2c_write_read function for i3c controller. * @param : handle : handle for the controller * @return : status for i3c_controller_Consecutive_private_i2c_write_read */ unsigned int i3c_controller_Consecutive_private_i2c_write_read(i3c_controller_handle_t *handle ){ unsigned int control; unsigned int status; unsigned int index; if((handle->base_addr != ZERO) && (handle->target_static_addr != ZERO) && (handle->len != ZERO) && (handle->buf != ZERO) && (handle->lenbase_addr); control = I2C_FRAME; i3c_contrlr->i3c_controller_intrpt_status0 = ALL_BITS_EN; //interrupt enable i3c_contrlr->i3c_controller_config0 = I2C_MODE_ALLOWED; i3c_contrlr->i3c_controller_tx_fifo = control; //control i3c_contrlr->i3c_controller_tx_fifo = handle->target_static_addr<i3c_controller_tx_fifo = handle->len; //SET the length of data to write for (index=ZERO;indexlen;index++) { i3c_contrlr->i3c_controller_tx_fifo = handle->buf[index]; //write the data } control = REPEATED_START_IN_FRAME|STOP_IN_FRAME|I2C_FRAME; i3c_contrlr->i3c_controller_tx_fifo = control; // SET to stop in frame i3c_contrlr->i3c_controller_tx_fifo = (handle->target_static_addr<i3c_controller_tx_fifo = handle->len2; //SET the length of data to read i3c_contrlr->i3c_controller_start_reg = START; do { if(i3c_contrlr->i3c_controller_intrpt_status0 & RX_FIFO_n_EMPTY) { if(i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_CMND_DONE) { if(i3c_contrlr->i3c_controller_intrpt_status0 & RCVD_SLAVE_NACK) { i3c_contrlr->i3c_controller_intrpt_status0 = RCVD_SLAVE_NACK; status=FAILURE; } else if (i3c_contrlr->i3c_controller_intrpt_status0 & RD_CMD_DONE) { for(index=ZERO;indexlen2;index++) { handle->buf2[index]=i3c_contrlr->i3c_controller_rx_fifo ; } i3c_contrlr->i3c_controller_intrpt_status0 = RX_FIFO_n_EMPTY|RCVD_CMND_DONE|RD_CMD_DONE; status= SUCCESS; } } } }while(status!=SUCCESS); } else { status=FAILURE; } return status; } /** * @brief i3c_controller_Consecutive_hdr_ddr_write_read function for i3c controller. * @param : handle : handle for the controller * @return : status for i3c_controller_Consecutive_hdr_ddr_write_read */ unsigned int i3c_controller_Consecutive_hdr_ddr_write_read(i3c_controller_handle_t *handle){ unsigned int control; unsigned int status; unsigned int index; if((handle->base_addr != ZERO) && (handle->target_dyn_addr != ZERO) && (handle->len != ZERO) && (handle->buf != ZERO) && (handle->lenbase_addr); i3c_contrlr->i3c_controller_intrpt_status2=ALL_BITS_EN; i3c_contrlr->hdr_ddr_config0 = DDR_IGNORE_CMD_DONE|NO_CRC_AFTER_TERM|EN_WRCMD_ACKNAK_CAP|EN_WR_EARLY_TERM; i3c_enter_hdr_ddr_mode(handle); i3c_contrlr->i3c_controller_tx_fifo = REPEATED_START_IN_FRAME|WAIT_NEXT_PACKET|HDR_MODE; //Control i3c_contrlr->i3c_controller_tx_fifo = handle->target_dyn_addr<i3c_controller_tx_fifo = handle->len+SET; //SET the length of data to write i3c_contrlr->i3c_controller_tx_fifo = handle->user_7bit_code>>SET; //user command code for (index=ZERO;indexlen;index++) { i3c_contrlr->i3c_controller_tx_fifo = handle->buf[index]; //write the data } control = REPEATED_START_IN_FRAME|WAIT_NEXT_PACKET|HDR_MODE; //Control i3c_contrlr->i3c_controller_tx_fifo = control; i3c_contrlr->i3c_controller_tx_fifo = (handle->target_dyn_addr<i3c_controller_tx_fifo = SET; //SET the length of data to read i3c_contrlr->i3c_controller_tx_fifo = handle->user_7bit_code>>SET|READ_RIGHT_SHIFT; //user command code i3c_contrlr->i3c_controller_tx_fifo = REPEATED_START_IN_FRAME|STOP_IN_FRAME|WAIT_NEXT_PACKET|HDR_MODE; //Control i3c_contrlr->i3c_controller_tx_fifo = (handle->target_dyn_addr<i3c_controller_tx_fifo = handle->len2; //SET the length of data to read i3c_contrlr->i3c_controller_start_reg = START; do { if(i3c_contrlr->i3c_controller_intrpt_status0 & RX_FIFO_n_EMPTY) { if(i3c_contrlr->i3c_controller_intrpt_status2 & HDR_CMND_DONE) { if(i3c_contrlr->i3c_controller_intrpt_status2 & HDR_SLAVE_NACK) { i3c_contrlr->i3c_controller_intrpt_status2 = HDR_SLAVE_NACK; status=FAILURE; } else if (i3c_contrlr->i3c_controller_intrpt_status2 & HDR_RD_CMD_DONE) { for(index=ZERO;indexlen2;index++) { handle->buf2[index]=i3c_contrlr->i3c_controller_rx_fifo; } i3c_contrlr->i3c_controller_intrpt_status2 = RX_FIFO_n_EMPTY|HDR_CMND_DONE|HDR_RD_CMD_DONE; status= SUCCESS; } } } }while(status!=SUCCESS); } else { status=FAILURE; } return status; } /** @brief ibi_handling function for i3c controller. * @param : handle : handle for the controller * ibi_config : to set ibi auto response low * @return : status for ibi_handling */ unsigned int i3c_controller_ibi_handling(i3c_controller_handle_t *handle,bool ibi_config ){ unsigned int target_addr; unsigned int status; unsigned int control; unsigned int status_read; unsigned int index; if((handle->base_addr != ZERO) && (handle->ibi_read_count != ZERO) && (handle->ibi_payload_data != ZERO)) { i3c_cntler_reg_t *i3c_contrlr=(i3c_cntler_reg_t *)(handle->base_addr); i3c_contrlr->i3c_controller_intrpt_enable0=ALL_BITS_EN; //rcvd ibi en 0x10 i3c_contrlr->i3c_controller_intrpt_enable1=ALL_BITS_EN; //ibi rd dn en 0x04 if(ibi_config==SET) { i3c_contrlr->i3c_controller_config0 = ALL_BITS_EN & IBI_AUTO_RESP_LOW; // SET the IBI_AUTO_RESP to low } else { i3c_contrlr->i3c_controller_config0 = ALL_BITS_EN; // SET the IBI_AUTO_RESP to high } do { status_read=(IBI_INTRPT_RCVD & i3c_contrlr->i3c_controller_intrpt_status0); }while(!status_read); do { if (WAITING_IBI_RESP & (i3c_contrlr->i3c_controller_intrpt_status1)) { target_addr = i3c_contrlr->ibi_address_register ; //Read the reserved target address i3c_contrlr->ibi_read_count_register= handle->ibi_read_count; i3c_contrlr->ibi_response_register = CLEAR; // SET ack do { if(i3c_contrlr->i3c_controller_intrpt_status0 & RX_FIFO_n_EMPTY) { if (i3c_contrlr->i3c_controller_intrpt_status1 & IBI_RD_DONE_EN) { for(index=ZERO;indexibi_read_count;index++) { handle->ibi_payload_data[index]=i3c_contrlr->i3c_controller_rx_fifo; status= SUCCESS; } } } }while(status!=SUCCESS); i3c_contrlr->i3c_controller_intrpt_status0 = IBI_INTRPT_RCVD|RX_FIFO_n_EMPTY; i3c_contrlr->i3c_controller_intrpt_status1=IBI_RD_DONE_EN|WAITING_IBI_RESP; status= SUCCESS; } else { i3c_contrlr->ibi_response_register = SET; // SET nack status=FAILURE; } }while(status!=SUCCESS); } else { status=FAILURE; } return status; } /* @brief hotjoin_handling function for i3c controller. * @param : handle : handle for the controller * ibi_config : to set ibi auto response low * @return : status for hotjoin_handling */ unsigned int i3c_controller_hj_handling(i3c_controller_handle_t *handle,bool ibi_config){ unsigned int target_addr; unsigned int status; unsigned int status_read; if(handle->base_addr != ZERO) { i3c_cntler_reg_t *i3c_contrlr=(i3c_cntler_reg_t *)(handle->base_addr); i3c_contrlr->i3c_controller_intrpt_enable0=ALL_BITS_EN; //rcvd ibi en 0x10 i3c_contrlr->i3c_controller_intrpt_enable1=ALL_BITS_EN; //ibi rd dn en 0x04 if(ibi_config==SET) { i3c_contrlr->i3c_controller_config0 = ALL_BITS_EN & IBI_AUTO_RESP_LOW; // SET the IBI_AUTO_RESP to low } else { i3c_contrlr->i3c_controller_config0 = ALL_BITS_EN; // SET the IBI_AUTO_RESP to high } do { status_read=(HOT_JOIN_INTRPT_RCVD & i3c_contrlr->i3c_controller_intrpt_status0); }while(!status_read); do { if (WAITING_IBI_RESP & (i3c_contrlr->i3c_controller_intrpt_status1)) { target_addr = i3c_contrlr->ibi_address_register ; //Read the reserved target address i3c_contrlr->ibi_response_register = CLEAR; // SET ack i3c_contrlr->ibi_read_count_register= CLEAR; //SET read count 0 status= SUCCESS; } else{ i3c_contrlr->ibi_response_register = SET; // SET nack status=FAILURE; } }while(status!=SUCCESS); i3c_contrlr->i3c_controller_intrpt_status0 = HOT_JOIN_INTRPT_RCVD; i3c_contrlr->i3c_controller_intrpt_status1 = WAITING_IBI_RESP; } else { status=FAILURE; } return status; } /* @brief Get active controller function for i3c controller. * @param : handle : handle for the controller * @return : status for Contrlr_handoff */ unsigned int i3c_controller_Contrlr_handoff(i3c_controller_handle_t *handle){ unsigned int int_status; unsigned int status; unsigned int crh_timeout_100us; unsigned int target_addr; if((handle->base_addr != ZERO) && (handle->target_dyn_addr != ZERO) && (handle->len != ZERO) && (handle->buf != ZERO) && (handle->lenbase_addr); i3c_contrlr->i3c_controller_intrpt_enable0=ALL_BITS_EN; i3c_contrlr->i3c_controller_intrpt_enable1=ALL_BITS_EN; i3c_contrlr->i3c_controller_config0 = ALL_BITS_EN & IBI_AUTO_RESP_LOW; // SET the IBI_AUTO_RESP to low do { int_status=(SEC_CTRRL_INTRPT_RCVD & i3c_contrlr->i3c_controller_intrpt_status0); }while(!int_status); target_addr = i3c_contrlr->ibi_address_register ; //Read the reserved target address i3c_contrlr->ibi_response_register = CLEAR; // SET ack crh_timeout_100us=CRH_TIMEOUT_VALUE; i3c_contrlr->secondary_contr_timeout_17=crh_timeout_100us & CRH_TIMEOUT_VALUE_REG17; i3c_contrlr->secondary_contr_timeout_18=crh_timeout_100us & CRH_TIMEOUT_VALUE_REG18; i3c_contrlr->secondary_contr_timeout_19=crh_timeout_100us & CRH_TIMEOUT_VALUE_REG19; i3c_contrlr->pull_up_resistor_disable=PULL_UP_RES_DISABLE; i3c_controller_direct_ccc(handle,READ); //Call getacccr function do { int_status=i3c_contrlr->i3c_controller_intrpt_status1; }while(!(int_status & GET_ACCR_DONE)); //check getacccr done if(i3c_contrlr->secondary_contr_status & GET_ACCR_RESULT) //check for successful controller handoff { status=FAILURE; } else { status=SUCCESS; } i3c_contrlr->i3c_controller_intrpt_status0 = SEC_CTRRL_INTRPT_RCVD; i3c_contrlr->i3c_controller_intrpt_status1=GET_ACCR_DONE ; } else { status=FAILURE; } return status; } /* * @brief hdr_broadcast_ccc function for i3c controller. * @param : handle : handle for the controller * @return : status for broadcast_ccc in hdr mode */ unsigned int i3c_controller_hdr_broadcast_ccc(i3c_controller_handle_t *handle){ unsigned int control; unsigned int status; unsigned int index; if((handle->base_addr != ZERO) && (handle->len != ZERO) && (handle->buf != ZERO) && (handle->lenbase_addr); i3c_contrlr->i3c_controller_intrpt_status2=ALL_BITS_EN; i3c_contrlr->hdr_ddr_config0 = DDR_IGNORE_CMD_DONE|NO_CRC_AFTER_TERM|EN_WRCMD_ACKNAK_CAP|EN_WR_EARLY_TERM; i3c_enter_hdr_ddr_mode(handle); control = CCC_CMD1_WR_RD0|REPEATED_START_IN_FRAME|STOP_IN_FRAME|CCC_COMMAND_WITH_START|WAIT_NEXT_PACKET|HDR_MODE; i3c_contrlr->i3c_controller_tx_fifo = control; //control i3c_contrlr->i3c_controller_tx_fifo = RESERVED_ADDRESS<i3c_controller_tx_fifo = handle->len+SET; //Set command length + optional bytes length i3c_contrlr->i3c_controller_tx_fifo = handle->user_7bit_code>>SET; //user command code for (index=ZERO;indexlen;index++) { i3c_contrlr->i3c_controller_tx_fifo=handle->buf[index]; // command+optional Bytes } i3c_contrlr->i3c_controller_start_reg=START; do { if (i3c_contrlr->i3c_controller_intrpt_status2 & HDR_CMND_DONE) { i3c_contrlr->i3c_controller_intrpt_status2=HDR_CMND_DONE; status=SUCCESS; } }while(status!=SUCCESS); } else { status=FAILURE; } return status; } /** * @brief direct_ccc write function in hdr mode for i3c controller. * @param : handle : handle for the controller * @return : status for direct_ccc write in hdr mode */ unsigned int i3c_controller_hdr_direct_ccc_write(i3c_controller_handle_t *handle) { unsigned int index; unsigned int status; i3c_cntler_reg_t *i3c_contrlr=(i3c_cntler_reg_t *)(handle->base_addr); i3c_contrlr->i3c_controller_tx_fifo=CCC_CMD1_WR_RD0|REPEATED_START_IN_FRAME|WAIT_NEXT_PACKET|STOP_IN_FRAME|HDR_MODE; //Control i3c_contrlr->i3c_controller_tx_fifo=handle->target_dyn_addr<i3c_controller_tx_fifo=handle->direct_ccc_optnal_bytes+SET; //Set command length i3c_contrlr->i3c_controller_tx_fifo = handle->user_7bit_code>>SET; //user command code for (index=ZERO;indexdirect_ccc_optnal_bytes;index++) { i3c_contrlr->i3c_controller_tx_fifo=handle->direct_ccc_optnal_data_array[index]; //write the data } i3c_contrlr->i3c_controller_start_reg=START; do { if (i3c_contrlr->i3c_controller_intrpt_status2 & HDR_CMND_DONE) { if(i3c_contrlr->i3c_controller_intrpt_status2 & HDR_SLAVE_NACK) { i3c_contrlr->i3c_controller_intrpt_status2 =HDR_SLAVE_NACK; status=FAILURE; } else { i3c_contrlr->i3c_controller_intrpt_status2 =HDR_CMND_DONE; status= SUCCESS; } } }while(status!=SUCCESS); return status; } /** * @brief direct_ccc read function in hdr mode for i3c controller. * @param : handle : handle for the controller * @return : status for direct_ccc read in hdr mode */ unsigned int i3c_controller_hdr_direct_ccc_read(i3c_controller_handle_t *handle) { unsigned int index; unsigned int status; i3c_cntler_reg_t *i3c_contrlr=(i3c_cntler_reg_t *)(handle->base_addr); i3c_contrlr->i3c_controller_tx_fifo=REPEATED_START_IN_FRAME|WAIT_NEXT_PACKET|HDR_MODE|CCC_CMD1_WR_RD0; //Control i3c_contrlr->i3c_controller_tx_fifo=handle->target_dyn_addr<i3c_controller_tx_fifo=SET; //Set command length i3c_contrlr->i3c_controller_tx_fifo=handle->user_7bit_code>>SET|READ_RIGHT_SHIFT; //Set read command i3c_contrlr->i3c_controller_tx_fifo=CCC_CMD1_WR_RD0|REPEATED_START_IN_FRAME|WAIT_NEXT_PACKET|STOP_IN_FRAME|HDR_MODE; //Control i3c_contrlr->i3c_controller_tx_fifo=(handle->target_dyn_addr<i3c_controller_tx_fifo=handle->direct_ccc_optnal_bytes; // //length number of bytes to read i3c_contrlr->i3c_controller_start_reg=START; do { if(i3c_contrlr->i3c_controller_intrpt_status2 & HDR_CMND_DONE) { if(i3c_contrlr->i3c_controller_intrpt_status2 & HDR_SLAVE_NACK) { i3c_contrlr->i3c_controller_intrpt_status2 = HDR_SLAVE_NACK; status=FAILURE; } else { for(index=ZERO;indexdirect_ccc_optnal_bytes;index++) { handle->buf[index]=i3c_contrlr->i3c_controller_rx_fifo; } i3c_contrlr->i3c_controller_intrpt_status2=HDR_CMND_DONE; status= SUCCESS; } } }while(status!=SUCCESS); return status; } /** * @brief direct_ccc function in hdr mode for i3c controller. * @param : handle : handle for the controller * read1_write0 : to SET read or write * @return : status for direct_ccc in hdr mode */ unsigned int i3c_controller_hdr_direct_ccc(i3c_controller_handle_t *handle, bool read1_write0) { unsigned int status; unsigned int control; unsigned int index; if((handle->base_addr != ZERO) && (handle->target_dyn_addr != ZERO) && (handle->len != ZERO) && (handle->buf != ZERO) && (handle->lenbase_addr); i3c_contrlr->i3c_controller_intrpt_status2=ALL_BITS_EN; i3c_contrlr->hdr_ddr_config0 = DDR_IGNORE_CMD_DONE|NO_CRC_AFTER_TERM|EN_WRCMD_ACKNAK_CAP|EN_WR_EARLY_TERM; i3c_enter_hdr_ddr_mode(handle); control = CCC_CMD1_WR_RD0|REPEATED_START_IN_FRAME|CCC_COMMAND_WITH_START|WAIT_NEXT_PACKET|HDR_MODE; i3c_contrlr->i3c_controller_tx_fifo = control; //control i3c_contrlr->i3c_controller_tx_fifo = RESERVED_ADDRESS<i3c_controller_tx_fifo = handle->len+SET; //SET the length of data to write (+ user command so added 1) i3c_contrlr->i3c_controller_tx_fifo = handle->user_7bit_code>>SET; //user command code for (index=ZERO;indexlen;index++) { i3c_contrlr->i3c_controller_tx_fifo=handle->buf[index]; // command+optional Bytes } if(read1_write0==WRITE) { i3c_controller_hdr_direct_ccc_write(handle); } else if(read1_write0==READ) { i3c_controller_hdr_direct_ccc_read(handle); } } else { status=FAILURE; } return status; }