/*-----------------------------------------------------------------------------*
 *  NAME
 *      I2CReadRegisters
 *
 *  DESCRIPTION
 *      This function reads a contiguous sequence of registers from the 
 *      specified device
 *
 *  RETURNS
 *      TRUE if successful
 *
 *----------------------------------------------------------------------------*/
extern bool I2CReadRegisters(uint8 base_address, uint8 start_reg, 
                              uint8 num_bytes, uint8 *p_buffer)
{
    bool success = FALSE;
    uint8 *p_write_pos;

    /* We assume that the supplied buffer is big enough. */
    if( (I2cRawStart(TRUE)                     == sys_status_success) &&
        (I2cRawWriteByte(base_address)         == sys_status_success) &&
        (I2cRawWaitAck(TRUE)                   == sys_status_success) &&
        (I2cRawWriteByte(start_reg)            == sys_status_success) &&
        (I2cRawWaitAck(TRUE)                   == sys_status_success) &&
        (I2cRawRestart(TRUE)                   == sys_status_success) &&
        (I2cRawWriteByte((base_address | 0x1)) == sys_status_success) &&
        (I2cRawWaitAck(TRUE)                   == sys_status_success))
    {
        for(p_write_pos = p_buffer;
            num_bytes > 1;
            num_bytes--)
        {
            I2cRawReadByte(p_write_pos++); /* Assume this works - */
            I2cRawSendAck(TRUE);        /* everything up to this point has. */
        }
        /* This is the last byte */
        I2cRawReadByte(p_write_pos++);
        I2cRawSendNack(TRUE);
        
        success = (I2cRawStop(TRUE) == sys_status_success);
    }
    I2cRawComplete(1 * MILLISECOND);
    I2cRawTerminate();
    
    return success;
}
extern bool I2CWritesRegister(uint8 base_address, uint8* register_value, 
                              uint8 reg)
{
    bool success;
    bool check = FALSE;
    
    if ( I2cRawStart(TRUE) == 0 )
    {
           check = TRUE;
    }
     
    success = ( (I2cRawStart(TRUE)               == sys_status_success) &&
                (I2cRawWriteByte(base_address)   == sys_status_success) &&
                (I2cRawWaitAck(TRUE)             == sys_status_success) &&
                (I2cRawWrite(register_value, reg) == sys_status_success) &&
                (I2cRawWaitAck(TRUE)             == sys_status_success) &&
 //               (I2cRawWriteByte(register_value) == sys_status_success) &&
 //               (I2cRawWaitAck(TRUE)             == sys_status_success) &&
                (I2cRawStop(TRUE)                == sys_status_success));

    I2cRawComplete(1 * MILLISECOND);
    I2cRawTerminate();
    
    return success;
}
void LcdDisplayI2cWriteString(uint8 i2c_address, const uint8 *data)
{
    LcdDisplayInitI2c();

    bool wait = TRUE;
    uint8 strlen;
    for(strlen = 0; (strlen <= STRLEN_MAX) && (data[strlen] != 0); strlen++){;} 
    I2cRawStart(wait);
    I2cRawWriteByte(i2c_address << 1); /* Bit 0 is R/!W. */
    I2cRawWaitAck(wait);
    I2cRawWriteByte('@'); /* Data follows. */
    I2cRawWaitAck(wait);
    I2cRawWrite(data, strlen);
    I2cRawStop(wait);
    
    I2cRawTerminate();
} /* LcdDisplayI2cWriteString */
extern bool I2CWriteRegisters(uint8 base_address, uint8 reg ,
                            uint8* register_value, uint8 length)          
{
    bool success;
    
    success = ( (I2cRawStart(TRUE)                   == sys_status_success) &&
                (I2cRawWriteByte(base_address)       == sys_status_success) &&
                (I2cRawWaitAck(TRUE)                 == sys_status_success) && 
                (I2cRawWriteByte(reg)                == sys_status_success) &&
                (I2cRawWaitAck(TRUE)                 == sys_status_success) &&
                (I2cRawWrite(register_value, length) == sys_status_success) &&
                (I2cRawStop(TRUE)                == sys_status_success));

    I2cRawComplete(1 * MILLISECOND);
    I2cRawTerminate();
    
    return success;
}
void LcdDisplayI2cWrite(uint8 i2c_address, const uint8 *data, uint8 num_bytes)
{
    LcdDisplayInitI2c();

    bool wait = TRUE;
    I2cRawStart(wait);
    I2cRawWriteByte(i2c_address << 1); /* Bit 0 is R/!W. */
    I2cRawWaitAck(wait);
    if((data[0] & 0x3F) != 0)
    {
        /* Caller did not put in leading command byte.  Assume data. */
        I2cRawWriteByte('@'); /* Data follows. */
        I2cRawWaitAck(wait);
    }
    I2cRawWrite(data, num_bytes);
    I2cRawStop(wait);
    
    I2cRawTerminate();
} /* LcdDisplayI2cWrite */
/*-----------------------------------------------------------------------------*
 *  NAME
 *      I2CReadRegister
 *
 *  DESCRIPTION
 *      This function reads the specified register from the specified device
 *
 *  RETURNS
 *      TRUE if successful
 *
 *----------------------------------------------------------------------------*/
extern bool I2CReadRegister(uint8 base_address, uint8 reg, 
                             uint8 *p_register_value)
{
    bool success;
    
    success = ( (I2cRawStart(TRUE)                     == sys_status_success) &&
                (I2cRawWriteByte(base_address)         == sys_status_success) &&
                (I2cRawWaitAck(TRUE)                   == sys_status_success) &&
                (I2cRawWriteByte(reg)                  == sys_status_success) &&
                (I2cRawWaitAck(TRUE)                   == sys_status_success) &&
                (I2cRawRestart(TRUE)                   == sys_status_success) &&
                (I2cRawWriteByte((base_address | 0x1)) == sys_status_success) &&
                (I2cRawWaitAck(TRUE)                   == sys_status_success) &&
                (I2cRawReadByte(p_register_value)      == sys_status_success) &&
                (I2cRawSendNack(TRUE)                  == sys_status_success) &&
                (I2cRawStop(TRUE)                      == sys_status_success));
    I2cRawComplete(1 * MILLISECOND);
    I2cRawTerminate();
    
    return success;
}
extern void readChannels(uint8 channel_map, uint8 *data) {

    I2cReset();
    I2cRawCommand(i2c_cmd_send_start, TRUE, I2C_WAIT_CMD_TIMEOUT);
    I2cRawWriteByte((0b0100011 << 1) | 0);
    I2cRawCommand(i2c_cmd_wait_ack, TRUE, I2C_WAIT_ACK_TIMEOUT);
    I2cRawWriteByte(0b01110010);
    I2cRawCommand(i2c_cmd_wait_ack, TRUE, I2C_WAIT_ACK_TIMEOUT);  
    /*Channel map*/
    I2cRawWriteByte((channel_map >> 4) & 0x0F);
    I2cRawCommand(i2c_cmd_wait_ack, TRUE, I2C_WAIT_ACK_TIMEOUT);  
    I2cRawWriteByte(((channel_map << 4) & 0xF0) | 0b1000);
    I2cRawCommand(i2c_cmd_wait_ack, TRUE, I2C_WAIT_ACK_TIMEOUT);  
    I2cRawCommand(i2c_cmd_send_stop, TRUE, I2C_WAIT_CMD_TIMEOUT);
    
    /*Setup conversion register for read access*/
    I2cRawCommand(i2c_cmd_send_start, TRUE, I2C_WAIT_CMD_TIMEOUT);
    I2cRawWriteByte(0b01000110);
    I2cRawCommand(i2c_cmd_wait_ack, TRUE, I2C_WAIT_ACK_TIMEOUT);    
    I2cRawWriteByte(0b01110000);
    I2cRawCommand(i2c_cmd_wait_ack, TRUE, I2C_WAIT_ACK_TIMEOUT);
    
    /*read*/
    I2cRawCommand( i2c_cmd_send_restart, TRUE, I2C_WAIT_CMD_TIMEOUT);
    I2cRawWriteByte(0b01000111);

    I2cRawCommand(i2c_cmd_wait_ack, TRUE, I2C_WAIT_ACK_TIMEOUT);
    I2cRawRead(&data[0], bitcount(channel_map)*2);
    I2cRawCommand(i2c_cmd_send_stop, TRUE, I2C_WAIT_CMD_TIMEOUT);
    
    I2cRawTerminate();

}