I am not sure how I do a library, so I will just post here what works for me.
 
#include "mbed.h"
#ifndef MyI2C_H
#define MyI2C_H
#define I2C_ACK  true
#define I2C_NACK false
#define I2C_WRITE 0
#define I2C_READ 1
extern bool I2C0AddressResponds(uint8_t);
class MyI2C 
{
private:
    bool waitclock(void);
public:
    //void frequency(uint32_t f);
    void start(void);
    void stop(void);
    uint8_t blockread(uint8_t r, char* b, uint8_t);
    uint8_t read(uint8_t r);
    bool blockwrite(uint8_t a, const char* b, uint8_t l);
    uint8_t write(uint8_t d);
};
#endif
 
#include "MyI2C.h"
const uint8_t mbed1768Pins[32] = { // Maping of mbed pins to LPC 1768 "port" pins
    255,255,255,255,255,9,8,7,6,0,
    1,18,17,15,16,23,24,25,26,62,
    63,69,68,67,66,65,64,11,10,5,
    4,255
};
#define I2C0SDASet (1<<mbed1768Pins[9&0x1f]) // 9
#define I2C0SDAPort (mbed1768Pins[9&0x0f]>>5)
PortInOut I2C0SDA(Port0, I2C0SDASet );
#define I2C0SCLSet (1<<mbed1768Pins[10&0x1f]) // 10
#define I2C0SCLPort (mbed1768Pins[10&0x0f]>>5)
PortInOut I2C0SCL(Port0, I2C0SCLSet );
MyI2C I2C0;
bool I2C0AddressResponds(uint8_t);
uint16_t I2CError[256];
void SDelay(uint16_t d) 
{ // 1.25 + 0.0475 * n uS ~0.05uS per click
    volatile int16_t v;
    for (v = 0; v < d ; v++ ) {};
}  // SDelay
#define SCLLowStartT SDelay(10)
#define DataLowPadT SDelay(16) // 10
#define SCLLowPadT SDelay(6)
#define SCLHighT SDelay(10)
#define I2CSDALow {I2C0SDA.write(0);I2C0SDA.output();SCLLowPadT;}
#define I2CSDAFloat {I2C0SDA.input();SCLLowPadT;}
#define I2CSCLLow {I2C0SCL.write(0);I2C0SCL.output();}
#define I2CSCLFloat {I2C0SCL.input();SCLHighT;}
void MyI2C::start(void)
{
    I2CSDAFloat;
    bool r = waitclock();
    I2CSDALow;
    SCLLowStartT;
    I2CSCLLow;
} // start
void MyI2C::stop(void)
{
    I2CSDALow;
    bool r = waitclock();
    I2CSDAFloat;
    SCLLowStartT;
} // stop
bool MyI2C::waitclock(void)
{
    static uint32_t s;
    I2CSCLFloat;        // set SCL to input, output a high
    s = 0;
    while ( I2C0SCL.read() == 0 )
    {
        if ( ++s > 16000 ) 
        { // ~1mS
            I2CError[0]++;
            // possible add SCL cycles here to attempt to force device reset
            //Stats[I2CFailS]++;
            return (false);
        }
    }
    return( true );
} // waitclock
uint8_t MyI2C::read(uint8_t ack) 
{
    static uint8_t s, d;
    I2CSDAFloat;
    d = 0;
    s = 8;
    do 
    {
        if ( waitclock() ) 
        {
            d <<= 1;
            if ( I2C0SDA.read() ) 
            {
                d |= 1;
                I2CSCLLow;
                DataLowPadT;
            }
            else 
            {
                I2CSCLLow;
                SDelay(10);//DataLowPadT;
            }
        } 
        else
        {
            return( 0 );
        }
    } while ( --s );
    if ( ack == I2C_NACK )
    {
        I2C0SDA.write(0xffff); // Port write with mask selecting SDA - messy
    }
    else
    {
        I2C0SDA.write(0);
    }
    I2C0SDA.output();
    SCLLowPadT;
    if ( waitclock() ) 
    {
        I2CSCLLow;
        return( d );
    } 
    else
    {
        return( 0 );
    }
} // read
uint8_t MyI2C::write(uint8_t d) 
{
    static uint8_t s, r;
    for ( s = 0; s < 8; s++) 
    {
        if ( d & 0x80 ) 
        {
            I2CSDAFloat;
        } 
        else 
        {
            I2CSDALow;
        }
        if ( waitclock() ) 
        {
            I2CSCLLow;
            d <<= 1;
        } 
        else
        {
            return(I2C_NACK);
        }
    }
    I2CSDAFloat;
    if ( waitclock() ) {
        if ( I2C0SDA.read() )
            r = I2C_NACK;
        else
            r = I2C_ACK;
        I2CSDALow;// kill runt pulses
        I2CSCLLow;
        return ( r );
    } 
    else
    {
//   I2CSCLLow;
        return(I2C_NACK);
    }
} // write
uint8_t MyI2C::blockread(uint8_t a, char* S, uint8_t l)
{
    static uint8_t b;
    static bool err;
    I2C0.start();
    err = I2C0.write(a|1) != I2C_ACK;
    for (b = 0; b < (l - 1); b++)
        S[b] = I2C0.read(I2C_ACK);
    S[l-1] = I2C0.read(I2C_NACK);
    I2C0.stop();
    return( err );
} // blockread
bool MyI2C::blockwrite(uint8_t a, const char* S, uint8_t l)
{
    static uint8_t b;
    I2C0.start();
    if ( I2C0.write(a) != I2C_ACK ) goto BlockWriteError; // use this?
    for ( b = 0; b < l; b++ )
        if ( I2C0.write(S[b]) != I2C_ACK ) goto BlockWriteError;
    I2C0.stop();
    return(false);
BlockWriteError:
    I2C0.stop();
    return(true);
} // blockwrite
bool I2C0AddressResponds(uint8_t s) {
    static bool r;
    I2C0.start();
    r = I2C0.write(s) == I2C_ACK;
    I2C0.stop();
    return (r);
} // I2C0AddressResponds
 
#include "MyI2C.h"
extern MyI2C I2C0;
...
#define ACCADDR (0x53<<1)
char buf[20];
bool initAcc()
{
    //Start sampling
    buf[0]=0x2D;
    buf[1]=0x08;
    
    //Set range 2G
    buf[2]=0x31;
    buf[3]=0x0B;
    return I2C0.blockwrite(ACCADDR, buf, 2) || I2C0.blockwrite(ACCADDR, &buf[2], 2);
}
...
It would be nice to have it written up in a published library of some sort. But im not sure how its done.
I'm not sure yet, but i think that in some situations my mbed is getting stuck inside the i2c read or write. Does anybody had the same problem?
Does anybody knows a "timeout solution" for this problem?
Thanks.