/******************************************************************************
 * (c) Copyright 2011 Actel Corporation.  All rights reserved.
 *
 * This file contains the implementation of the Unified I2C Driver Abstraction
 * Layer (UI2C DAL) functions.
 *
 * Note - Interrupt support functions are not implemented in the UI2C DAL.
 * An application that requires interrupt controlled I2C communications must
 * use the interrupt support functions provided by the bare metal I2C drivers.
 *
 * SVN $Revision: 3994 $
 * SVN $Date: 2011-11-18 18:08:46 +0530 (Fri, 18 Nov 2011) $
 */

#include "ui2c_dal.h"

#if ( !UI2C_MSS_I2C_ENABLED )
#include "../../hal/hal_assert.h"
#endif

#if(UI2C_MSS_I2C_ENABLED)
#include "../mss_i2c/mss_i2c.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

/* Definition to use HAL_ASSERT if MSS_UART is not used in the design */
#if ( !UI2C_MSS_I2C_ENABLED )
#define ASSERT  HAL_ASSERT
#endif

#if ( UI2C_CORE_I2C_ENABLED )
/* Local function prototype */
static i2c_slave_handler_ret_t dummy_core_i2c_write_handler
(
    i2c_instance_t * instance,
    uint8_t * data,
    uint16_t size
);
#endif

#if(UI2C_MSS_I2C_ENABLED)
static mss_i2c_slave_handler_ret_t dummy_mss_i2c_write_handler
(
    mss_i2c_instance_t * instance,
    uint8_t * data,
    uint16_t size
);
#endif

#if ( UI2C_CORE_I2C_ENABLED )
/*------------------------------------------------------------------------------
 * UI2C_core_i2c_open()
 * See "ui2c_dal.h" for details of how to use this function.
 */
void UI2C_core_i2c_open
(
    ui2c_channel_t * channel,
    i2c_instance_t * instance
)
{
    ASSERT( ( (ui2c_channel_t *)0 ) != channel );
    ASSERT( ( (i2c_instance_t *)0 ) != instance );

    if( ( ( (ui2c_channel_t *)0 ) != channel ) &&
        ( ( (i2c_instance_t *)0 ) != instance ) )
    {
        /* Open CoreI2C channel */
        channel->i2c_type = UI2C_CORE_I2C;
        channel->instance.core_i2c = instance;
        instance->p_user_data = (void *)channel;
    }
}
#endif

#if ( UI2C_MSS_I2C_ENABLED )
/*------------------------------------------------------------------------------
 * UI2C_mss_i2c_open()
 * See "ui2c_dal.h" for details of how to use this function.
 */
void UI2C_mss_i2c_open
(
    ui2c_channel_t * channel,
    mss_i2c_instance_t * instance
)
{
    ASSERT( ( (ui2c_channel_t *)0 ) != channel );
    ASSERT( ( (mss_i2c_instance_t *)0 ) != instance );

    if( ( ( (ui2c_channel_t *)0 ) != channel ) &&
        ( ( (mss_i2c_instance_t *)0 ) != instance ) )
    {
        /* Open MSS I2C channel */
        channel->i2c_type = UI2C_MSS_I2C;
        channel->instance.mss_i2c = instance;
        instance->p_user_data = (void *)channel;
    }
}
#endif

/*------------------------------------------------------------------------------
 * UI2C_write()
 * See "ui2c_dal.h" for details of how to use this function.
 */
void UI2C_write
(
    ui2c_channel_t * channel,
    uint8_t serial_addr,
    const uint8_t * write_buffer,
    uint16_t write_size,
    uint8_t options
)
{
    ASSERT( ((ui2c_channel_t *)0) != channel );

    if( ((ui2c_channel_t *)0) != channel )
    {
        ASSERT((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type));
        if((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type))
        {
            switch(channel->i2c_type)
            {
#if ( UI2C_CORE_I2C_ENABLED )
                case UI2C_CORE_I2C :
                {
                    I2C_write (channel->instance.core_i2c, serial_addr, write_buffer, write_size, options);
                    break;
                }
#endif

#if ( UI2C_MSS_I2C_ENABLED )
                case UI2C_MSS_I2C :
                {
                    MSS_I2C_write(channel->instance.mss_i2c, serial_addr, write_buffer, write_size, options);
                    break ;
                }
#endif
                default:
                   break;
           }
        }
    }
}

/*------------------------------------------------------------------------------
 * UI2C_read()
 * See "ui2c_dal.h" for details of how to use this function.
 */
void UI2C_read
(
    ui2c_channel_t * channel,
    uint8_t serial_addr,
    uint8_t * read_buffer,
    uint16_t read_size,
    uint8_t options
)
{
    ASSERT( ((ui2c_channel_t *)0) != channel );

    if( ((ui2c_channel_t *)0) != channel )
    {
        ASSERT((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type));
        if((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type))
        {
            switch(channel->i2c_type)
            {
#if ( UI2C_CORE_I2C_ENABLED )
                case UI2C_CORE_I2C :
                {
                    I2C_read( channel->instance.core_i2c, serial_addr, read_buffer, read_size, options);
                    break;
                }
#endif

#if ( UI2C_MSS_I2C_ENABLED )
                case UI2C_MSS_I2C :
                {
                    MSS_I2C_read(channel->instance.mss_i2c, serial_addr, read_buffer, read_size, options);
                    break ;
                }
#endif
                default:
                    break;
            }
       }
    }
}

/*------------------------------------------------------------------------------
 * UI2C_write_read()
 * See "ui2c_dal.h" for details of how to use this function.
 */
void UI2C_write_read
(
    ui2c_channel_t * channel,
    uint8_t serial_addr,
    const uint8_t * addr_offset,
    uint16_t offset_size,
    uint8_t * read_buffer,
    uint16_t read_size,
    uint8_t options
)
{
    ASSERT( ((ui2c_channel_t *)0) != channel );

    if( ((ui2c_channel_t *)0) != channel )
    {
        ASSERT((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type));
        if((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type))
        {
            switch(channel->i2c_type)
            {
#if ( UI2C_CORE_I2C_ENABLED )
                case UI2C_CORE_I2C :
                {
                    I2C_write_read( channel->instance.core_i2c, serial_addr, addr_offset,offset_size, read_buffer, read_size, options);
                    break;
                }
#endif

#if ( UI2C_MSS_I2C_ENABLED )
                case UI2C_MSS_I2C :
                {
                    MSS_I2C_write_read(channel->instance.mss_i2c, serial_addr,addr_offset, offset_size, read_buffer, read_size, options);
                    break ;
                }
#endif
                default:
                    break;
            }
        }
    }
}

/*------------------------------------------------------------------------------
 * UI2C_get_status()
 * See "ui2c_dal.h" for details of how to use this function.
 */
ui2c_status_t UI2C_get_status
(
    ui2c_channel_t * channel
)
{
    ui2c_status_t i2c_dev_status = UI2C_FAILED;

    ASSERT( ((ui2c_channel_t *)0) != channel );

    if( ((ui2c_channel_t *)0) != channel )
    {
        ASSERT((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type));
        if((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type))
        {
            switch(channel->i2c_type)
            {
#if ( UI2C_CORE_I2C_ENABLED )
                case UI2C_CORE_I2C :
                {
                    i2c_dev_status= (ui2c_status_t)I2C_get_status( channel->instance.core_i2c);
                    break;
                }
#endif

#if ( UI2C_MSS_I2C_ENABLED )
                case UI2C_MSS_I2C :
                {
                    i2c_dev_status= (ui2c_status_t)MSS_I2C_get_status(channel->instance.mss_i2c);
                    break ;
                }
#endif
                default:
                    break;
             }
        }
    }
    return(i2c_dev_status);
}

/*------------------------------------------------------------------------------
 * UI2C_wait_complete()
 * See "ui2c_dal.h" for details of how to use this function.
 */
ui2c_status_t UI2C_wait_complete
(
    ui2c_channel_t * channel
)
{
    ui2c_status_t i2c_dev_status = UI2C_IN_PROGRESS ;

    ASSERT( ((ui2c_channel_t *)0) != channel );

    if( ((ui2c_channel_t *)0) != channel )
    {
        ASSERT((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type));
        if((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type))
        {
            switch(channel->i2c_type)
            {
#if ( UI2C_CORE_I2C_ENABLED )
                case UI2C_CORE_I2C :
                {
                    i2c_dev_status= (ui2c_status_t)I2C_wait_complete( channel->instance.core_i2c);
                    break;
                }
#endif

#if ( UI2C_MSS_I2C_ENABLED )
                case UI2C_MSS_I2C :
                {
                    i2c_dev_status= (ui2c_status_t)MSS_I2C_get_status(channel->instance.mss_i2c);
                    break ;
                }
#endif
                default:
                    break;
            }
        }
    }
    return(i2c_dev_status);
}

/*------------------------------------------------------------------------------
 * UI2C_set_slave_tx_buffer()
 * See "ui2c_dal.h" for details of how to use this function.
 */
void UI2C_set_slave_tx_buffer
(
    ui2c_channel_t * channel,
    uint8_t * tx_buffer,
    uint16_t tx_size
)
{
    ASSERT( ((ui2c_channel_t *)0) != channel );

    if( ((ui2c_channel_t *)0) != channel )
    {
        ASSERT((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type));
        if((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type))
        {
            switch(channel->i2c_type)
            {
#if ( UI2C_CORE_I2C_ENABLED )
                case UI2C_CORE_I2C :
                {
                    I2C_set_slave_tx_buffer( channel->instance.core_i2c, tx_buffer, tx_size);
                    break;
                }
#endif

#if ( UI2C_MSS_I2C_ENABLED )
                case UI2C_MSS_I2C :
                {
                    MSS_I2C_set_slave_tx_buffer(channel->instance.mss_i2c, tx_buffer, tx_size);
                    break ;
                }
#endif
                default:
                    break;
            }
        }
    }
}

/*------------------------------------------------------------------------------
 * UI2C_set_slave_rx_buffer()
 * See "ui2c_dal.h" for details of how to use this function.
 */
void UI2C_set_slave_rx_buffer
(
    ui2c_channel_t * channel,
    uint8_t * rx_buffer,
    uint16_t rx_size
)
{
    ASSERT( ((ui2c_channel_t *)0) != channel );

    if( ((ui2c_channel_t *)0) != channel )
    {
        ASSERT((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type));
        if((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type))
        {
            switch(channel->i2c_type)
            {
#if ( UI2C_CORE_I2C_ENABLED )
                case UI2C_CORE_I2C :
                {
                    I2C_set_slave_rx_buffer( channel->instance.core_i2c, rx_buffer, rx_size);
                    break;
                }
#endif

#if ( UI2C_MSS_I2C_ENABLED )
                case UI2C_MSS_I2C :
                {
                    MSS_I2C_set_slave_rx_buffer( channel->instance.mss_i2c, rx_buffer, rx_size);
                    break ;
                }
#endif
                default:
                    break;
            }
        }
    }
}

/*------------------------------------------------------------------------------
 * UI2C_set_slave_mem_offset_length()
 * See "ui2c_dal.h" for details of how to use this function.
 */
void UI2C_set_slave_mem_offset_length
(
    ui2c_channel_t * channel,
    uint8_t offset_length
)
{
    ASSERT( ((ui2c_channel_t *)0) != channel );

    if( ((ui2c_channel_t *)0) != channel )
    {
        ASSERT((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type));
        if((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type))
        {
            switch(channel->i2c_type)
            {
#if ( UI2C_CORE_I2C_ENABLED )
                case UI2C_CORE_I2C :
                {
                    I2C_set_slave_mem_offset_length( channel->instance.core_i2c, offset_length);
                    break;
                }
#endif

#if ( UI2C_MSS_I2C_ENABLED )
                case UI2C_MSS_I2C :
                {
                    MSS_I2C_set_slave_mem_offset_length( channel->instance.mss_i2c, offset_length);
                    break ;
                }
#endif
                default:
                    break;
            }
        }
    }
}

/*------------------------------------------------------------------------------
 * UI2C_register_write_handler()
 * See "ui2c_dal.h" for details of how to use this function.
 */
void UI2C_register_write_handler
(
    ui2c_channel_t * channel,
    ui2c_slave_wr_handler_t handler
)
{
    ASSERT( ((ui2c_channel_t *)0) != channel );

    if( ((ui2c_channel_t *)0) != channel )
    {
        ASSERT((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type));
        if((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type))
        {
            switch(channel->i2c_type)
            {
#if ( UI2C_CORE_I2C_ENABLED )
                case UI2C_CORE_I2C :
                {
                    /* register the abstract "slave write handler" with the I2C_DAL channel */
                    channel->slave_write_handler = handler;

                    /* register the intermediate dummy "slave write handler" physical CoreI2C's instance struct */
                    I2C_register_write_handler( channel->instance.core_i2c, dummy_core_i2c_write_handler);
                    break;
                }
#endif

#if ( UI2C_MSS_I2C_ENABLED )
                case UI2C_MSS_I2C :
                {
                    /* register the abstract "slave write handler" with the I2C_DAL channel */
                    channel->slave_write_handler = handler;

                    /* register the intermediate dummy "slave write handler" physical MSS_I2C's instance struct */
                    MSS_I2C_register_write_handler( channel->instance.mss_i2c, dummy_mss_i2c_write_handler);
                    break ;
                }
#endif
                default:
                    break;
            }
        }
    }
}

/*------------------------------------------------------------------------------
 * UI2C_enable_slave_rx()
 * See "ui2c_dal.h" for details of how to use this function.
 */
void UI2C_enable_slave_rx
(
    ui2c_channel_t * channel
)
{
    ASSERT( ((ui2c_channel_t *)0) != channel );

    if( ((ui2c_channel_t *)0) != channel )
    {
        ASSERT((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type));
        if((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type))
        {
            switch(channel->i2c_type)
            {
#if ( UI2C_CORE_I2C_ENABLED )
                case UI2C_CORE_I2C :
                {
                    I2C_enable_slave( channel->instance.core_i2c);
                    break;
                }
#endif

#if ( UI2C_MSS_I2C_ENABLED )
                case UI2C_MSS_I2C :
                {
                    MSS_I2C_enable_slave( channel->instance.mss_i2c);
                    break ;
                }
#endif
                default:
                    break;
            }
        }
    }
}

/*------------------------------------------------------------------------------
 * UI2C_set_slave_second_addr()
 * See "ui2c_dal.h" for details of how to use this function.
 */
void UI2C_set_slave_second_addr
(
    ui2c_channel_t *channel,
    uint8_t second_slave_addr
)
{
    ASSERT( ((ui2c_channel_t *)0) != channel );

    if( ((ui2c_channel_t *)0) != channel )
    {
        ASSERT((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type));
        ASSERT(UI2C_MSS_I2C != channel->i2c_type);
        if(
            (UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type)
                                      &&
                       (UI2C_MSS_I2C != channel->i2c_type)
          )
        {
            switch(channel->i2c_type)
            {
#if ( UI2C_CORE_I2C_ENABLED )
                case UI2C_CORE_I2C :
                {
                    I2C_set_slave_second_addr( channel->instance.core_i2c, second_slave_addr);
                    break;
                }
#endif
                default:
                    break;
            }
        }
    }
}

/*------------------------------------------------------------------------------
 * UI2C_disable_slave_second_addr()
 * See "ui2c_dal.h" for details of how to use this function.
 */
void UI2C_disable_slave_second_addr
(
    ui2c_channel_t *channel
)
{
    ASSERT( ((ui2c_channel_t *)0) != channel );

    if( ((ui2c_channel_t *)0) != channel )
    {
        ASSERT((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type));
        ASSERT(UI2C_MSS_I2C != channel->i2c_type);
        if(
            (UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type)
                                      &&
                       (UI2C_MSS_I2C != channel->i2c_type)
          )
        {
            switch(channel->i2c_type)
            {
#if ( UI2C_CORE_I2C_ENABLED )
                case UI2C_CORE_I2C :
                {
                    I2C_disable_slave_second_addr( channel->instance.core_i2c);
                    break;
                }
#endif
                default:
                    break;
            }
        }
    }
}

/*------------------------------------------------------------------------------
 * UI2C_set_gca()
 * See "ui2c_dal.h" for details of how to use this function.
 */
void UI2C_set_gca
(
    ui2c_channel_t *channel
)
{
    ASSERT( ((ui2c_channel_t *)0) != channel );

    if( ((ui2c_channel_t *)0) != channel )
    {
        ASSERT((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type));
        if((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type))
        {
            switch(channel->i2c_type)
            {
#if ( UI2C_CORE_I2C_ENABLED )
                case UI2C_CORE_I2C :
                {
                    I2C_set_gca( channel->instance.core_i2c);
                    break;
                }
#endif

#if ( UI2C_MSS_I2C_ENABLED )
                case UI2C_MSS_I2C :
                {
                    MSS_I2C_set_gca( channel->instance.mss_i2c);
                    break ;
                }
#endif
                default:
                    break;
            }
        }
    }
}
/*------------------------------------------------------------------------------
 * UI2C_clear_gca()
 * See "ui2c_dal.h" for details of how to use this function.
 */
void UI2C_clear_gca
(
    ui2c_channel_t *channel
)
{
    ASSERT( ((ui2c_channel_t *)0) != channel );

    if( ((ui2c_channel_t *)0) != channel )
    {
        ASSERT((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type));
        if((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type))
        {
            switch(channel->i2c_type)
            {
#if ( UI2C_CORE_I2C_ENABLED )
                case UI2C_CORE_I2C :
                {
                    I2C_clear_gca( channel->instance.core_i2c);
                    break;
                }
#endif

#if ( UI2C_MSS_I2C_ENABLED )
                case UI2C_MSS_I2C :
                {
                    MSS_I2C_clear_gca( channel->instance.mss_i2c);
                    break ;
                }
#endif
                default:
                    break;
            }
        }
    }
}
/*------------------------------------------------------------------------------
 * UI2C_smbus_init()
 * See "ui2c_dal.h" for details of how to use this function.
 */
void UI2C_smbus_init
(
    ui2c_channel_t *channel,
    uint8_t frequency
)
{
    ASSERT( ((ui2c_channel_t *)0) != channel );

    if( ((ui2c_channel_t *)0) != channel )
    {
        ASSERT((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type));
        if((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type))
        {
            switch(channel->i2c_type)
            {
#if ( UI2C_CORE_I2C_ENABLED )
                case UI2C_CORE_I2C :
                {
                    I2C_smbus_init( channel->instance.core_i2c);
                    break;
                }
#endif

#if ( UI2C_MSS_I2C_ENABLED )
                case UI2C_MSS_I2C :
                {
                    MSS_I2C_smbus_init( channel->instance.mss_i2c, frequency);
                    break ;
                }
#endif
                default:
                    break;
            }
        }
    }
}
/*------------------------------------------------------------------------------
 * UI2C_enable_smbus_irq()
 * See "ui2c_dal.h" for details of how to use this function.
 */
void UI2C_enable_smbus_irq
(
    ui2c_channel_t *channel,
    uint8_t  irq_type
)
{
    ASSERT( ((ui2c_channel_t *)0) != channel );

    if( ((ui2c_channel_t *)0) != channel )
    {
        ASSERT((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type));
        if((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type))
        {
            switch(channel->i2c_type)
            {
#if ( UI2C_CORE_I2C_ENABLED )
                case UI2C_CORE_I2C :
                {
                    I2C_enable_smbus_irq( channel->instance.core_i2c, irq_type);
                    break;
                }
#endif

#if ( UI2C_MSS_I2C_ENABLED )
                case UI2C_MSS_I2C :
                {
                    MSS_I2C_enable_smbus_irq( channel->instance.mss_i2c, irq_type);
                    break ;
                }
#endif
                default:
                    break;
            }
        }
    }
}
/*------------------------------------------------------------------------------
 * UI2C_disable_smbus_irq()
 * See "ui2c_dal.h" for details of how to use this function.
 */
void UI2C_disable_smbus_irq
(
    ui2c_channel_t *channel,
    uint8_t  irq_type
)
{
    ASSERT( ((ui2c_channel_t *)0) != channel );

    if( ((ui2c_channel_t *)0) != channel )
    {
        ASSERT((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type));
        if((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type))
        {
            switch(channel->i2c_type)
            {
#if ( UI2C_CORE_I2C_ENABLED )
                case UI2C_CORE_I2C :
                {
                    I2C_disable_smbus_irq( channel->instance.core_i2c, irq_type);
                    break;
                }
#endif

#if ( UI2C_MSS_I2C_ENABLED )
                case UI2C_MSS_I2C :
                {
                    MSS_I2C_disable_smbus_irq( channel->instance.mss_i2c, irq_type);
                    break ;
                }
#endif
                default:
                    break;
            }
        }
    }
}
/*------------------------------------------------------------------------------
 * UI2C_suspend_smbus_slave()
 * See "ui2c_dal.h" for details of how to use this function.
 */
void UI2C_suspend_smbus_slave
(
    ui2c_channel_t *channel
)
{
    ASSERT( ((ui2c_channel_t *)0) != channel );

    if( ((ui2c_channel_t *)0) != channel )
    {
        ASSERT((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type));
        if((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type))
        {
            switch(channel->i2c_type)
            {
#if ( UI2C_CORE_I2C_ENABLED )
                case UI2C_CORE_I2C :
                {
                    I2C_suspend_smbus_slave( channel->instance.core_i2c);
                    break;
                }
#endif

#if ( UI2C_MSS_I2C_ENABLED )
                case UI2C_MSS_I2C :
                {
                    MSS_I2C_suspend_smbus_slave( channel->instance.mss_i2c);
                    break ;
                }
#endif
                default:
                    break;
            }
        }
    }
}
/*------------------------------------------------------------------------------
 * UI2C_reset_smbus()
 * See "ui2c_dal.h" for details of how to use this function.
 */
void UI2C_reset_smbus
(
    ui2c_channel_t *channel
)
{
    ASSERT( ((ui2c_channel_t *)0) != channel );

    if( ((ui2c_channel_t *)0) != channel )
    {
        ASSERT((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type));
        if((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type))
        {
            switch(channel->i2c_type)
            {
#if ( UI2C_CORE_I2C_ENABLED )
                case UI2C_CORE_I2C :
                {
                    I2C_reset_smbus( channel->instance.core_i2c);
                    break;
                }
#endif

#if ( UI2C_MSS_I2C_ENABLED )
                case UI2C_MSS_I2C :
                {
                    MSS_I2C_reset_smbus( channel->instance.mss_i2c);
                    break ;
                }
#endif
                default:
                    break;
            }
        }
    }
}
/*------------------------------------------------------------------------------
 * UI2C_set_smbus_alert()
 * See "ui2c_dal.h" for details of how to use this function.
 */
void UI2C_set_smbus_alert
(
    ui2c_channel_t *channel
)
{
    ASSERT( ((ui2c_channel_t *)0) != channel );

    if( ((ui2c_channel_t *)0) != channel )
    {
        ASSERT((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type));
        if((UI2C_LAST > channel->i2c_type) && (UI2C_INVALID < channel->i2c_type))
        {
            switch(channel->i2c_type)
            {
#if ( UI2C_CORE_I2C_ENABLED )
                case UI2C_CORE_I2C :
                {
                    I2C_set_smbus_alert( channel->instance.core_i2c);
                    break;
                }
#endif

#if ( UI2C_MSS_I2C_ENABLED )
                case UI2C_MSS_I2C :
                {
                    MSS_I2C_set_smbus_alert( channel->instance.mss_i2c);
                    break ;
                }
#endif
                default:
                    break;
            }
        }
    }
}

#if ( UI2C_CORE_I2C_ENABLED )
/*------------------------------------------------------------------------------
 * dummy_core_i2c_write_handler()
 * I2C_DAL intermediate "dummy" slave write handler, complaint with the prototype
 * declared in the CoreI2C driver. This function is private to the I2C_DAL.
 */
static i2c_slave_handler_ret_t dummy_core_i2c_write_handler
(
    i2c_instance_t * instance,
    uint8_t * data,
    uint16_t size
)
{
    i2c_slave_handler_ret_t core_i2c_slave_handler_ret = I2C_REENABLE_SLAVE_RX;
    ui2c_slave_handler_ret_t i2c_slave_handler_ret;
    ui2c_channel_t *channel ;

    channel = (ui2c_channel_t *)(instance->p_user_data) ;
    i2c_slave_handler_ret = channel->slave_write_handler (data, size);

    if ( UI2C_PAUSE_SLAVE_RX == i2c_slave_handler_ret )
    {
        core_i2c_slave_handler_ret = I2C_PAUSE_SLAVE_RX;
    }
    return core_i2c_slave_handler_ret;
}
#endif

#if ( UI2C_MSS_I2C_ENABLED )
/*------------------------------------------------------------------------------
 * dummy_mss_i2c_write_handler()
 * I2C_DAL intermediate "dummy" slave write handler, complaint with the prototype
 * declared in the MSS I2C driver. This function is private to the I2C_DAL.
 */
static mss_i2c_slave_handler_ret_t dummy_mss_i2c_write_handler
(
    mss_i2c_instance_t * instance,
    uint8_t * data,
    uint16_t size
)
{
    mss_i2c_slave_handler_ret_t mss_i2c_slave_handler_ret = MSS_I2C_REENABLE_SLAVE_RX;
    ui2c_slave_handler_ret_t i2c_slave_handler_ret;
    ui2c_channel_t *channel ;

    channel = (ui2c_channel_t *)(instance->p_user_data) ;
    i2c_slave_handler_ret = channel->slave_write_handler (data, size);

    if ( UI2C_PAUSE_SLAVE_RX == i2c_slave_handler_ret )
    {
        mss_i2c_slave_handler_ret = MSS_I2C_PAUSE_SLAVE_RX;
    }
    return mss_i2c_slave_handler_ret;
}
#endif

#ifdef __cplusplus
}
#endif
