Exemplo n.º 1
0
void I2CDevice::initSMBusMode()
{
    // enable clock
    clockEnable(true);

    // disable I2C module
    enable(false);

    //NOTE: followed configuration is SMBus specific configuration

    // timing configuration for: I2CCLK = SYSCLK = 48 MHz
    // and transmission type: 100 kHz
    I2C1->TIMINGR |= ( (I2C_TIMINGR_PRESC & 0xBBBBBBBB)
                    | (I2C_TIMINGR_SCLL & 0x13131313)
                    | (I2C_TIMINGR_SCLH & 0x0F0F0F0F)
                    | (I2C_TIMINGR_SDADEL & 0x22222222)
                    | (I2C_TIMINGR_SCLDEL & 0x44444444));


    // rest configuration
    I2C1->CR1 |= ( I2C_CR1_PECEN    // enable PEC ( CRC8 byte )
//                | I2C_CR1_ERRIE   // enable interrupt on PEC error
//                | I2C_CR1_TCIE    // enable interrupt on Transfer Complete
//                | I2C_CR1_TXIE    // enable interrupt on Transmit buffer empty
//                | I2C_CR1_RXIE    // enable interrupt on Receive buffer Not Empty

                );

    // set the slave address to right register
    setSlaveAddr();

}
Exemplo n.º 2
0
// 1) doesn't work if size is > 255
// todo it is not finished. Address is sent properly, but need to examine if it works
// with real device
void I2CDevice::send(const uint8_t addr, const uint8_t * const pBuff, const size_t size)
{
    if(nullptr == pBuff)
        return ;


    //set the Slave address
    setSlaveAddr();
    //set number of bytes to be transmitted
    setTransferBytes(size+2); //+1 for PEC byte and +1 for the addr/command

    // enable PEC functionality
    I2C1->CR1 |= I2C_CR1_PECEN ;

    enable(true);

    // this is write transmission
    I2C1->CR2 &= ~I2C_CR2_RD_WRN;

    I2C1->CR2 |= I2C_CR2_AUTOEND    // set autoend
              |  I2C_CR2_PECBYTE    // PEC byte will be transmitted
              |  I2C_CR2_START      // generate start
              ;

    // Transmit the command / address where to store:
    // - wait for TX buffer to be empty
    while( !(I2C1->ISR & I2C_ISR_TXIS) ) { asm(""); }
    // - write the command / address
    I2C1->TXDR = addr;

    // Write Data Bytes
    for(size_t i = 0; i < size ; ++i)
    {
        // wait for NACK flag or TXIS flag
        while(!(I2C1->ISR & I2C_ISR_NACKF) && !(I2C1->ISR & I2C_ISR_TXIS)) { asm(""); }

        // check for NACK flag
        if(I2C1->ISR & I2C_ISR_NACKF)
        {
            // todo report an error
            // This is an error
            // 1) not found address
            // 2) Receiver cannot read byte
            // 3) Receiver has detected error in bytes (CRC)
            return ;
        }
        // TXIS flag - write next byte
        else
        {
            I2C1->TXDR = pBuff[i];
        }
    }


    // wait until STOP symbol will be detected
    while(I2C1->ISR & I2C_ISR_BUSY) { asm(""); }

    // disable peripheral -> clear flags
    enable(false);
}
Exemplo n.º 3
0
Arquivo: i2c.cpp Projeto: hateif/pixy
I2c::I2c(LPC_I2Cn_Type *i2c, uint8_t addr, SerialCallback callback) : m_rq(I2C_RECEIVE_BUF_SIZE), m_tq(I2C_TRANSMIT_BUF_SIZE, callback)
{
	m_i2c = i2c;

	m_16bit = true;
	m_clearOnEnd = false;
	 
	I2C_Init(m_i2c, 100000);
   	setSlaveAddr(addr);

	NVIC_SetPriority(SSP1_IRQn, 0);	// high priority interrupt
}
Exemplo n.º 4
0
void I2CDevice::read(const uint8_t addr, uint8_t * const pBuff, const size_t len)
{
    // because this is an SMBus -> need to write command
    // in this case the command defines the EEPROM or RAM memory and cell address

    if(nullptr == pBuff)
        return;
    if(0 == len)
        return;

    // todo is this necessary on each call?
    //set the Slave address
    setSlaveAddr();

    // 1) Transmit command
    // - need to disable the PEC for writing command byte
    I2C1->CR1 &= ~I2C_CR1_PECEN;

    // - set number of bytes to be transmitted: 1 - only command
    setTransferBytes(1);

    enable(true);

    // disable the autoend because need to generate the RESTART signal
    I2C1->CR2 &= ~I2C_CR2_AUTOEND;

    I2C1->CR2 &= ~I2C_CR2_RD_WRN;   // this is a write transmission - to transmit the command
    I2C1->CR2 |= I2C_CR2_START;     // generate start

    // Wait for TX buffer to be empty
    while( !(I2C1->ISR & I2C_ISR_TXIS) );

    // write the command / address
    I2C1->TXDR = addr;

    // Wait for Transfer Completion
    while( !(I2C1->ISR & I2C_ISR_TC) );

    // 2) Read bytes from device

    // - set number of bytes to be received: 'len' data bytes and PEC
    setTransferBytes(len + 1);      // +1 for PEC byte

    // - enable PEC
    I2C1->CR1 |= I2C_CR1_PECEN;

    I2C1->CR2 |= I2C_CR2_AUTOEND    // enable autoend
                | I2C_CR2_RD_WRN    // this will be a read transfer
                | I2C_CR2_START ;   // generate 'restart' signal


    // read data
    for(size_t i = 0 ; i < len ; ++i)
    {
        while(!(I2C1->ISR & I2C_ISR_RXNE));

        pBuff[i] = I2C1->RXDR;
    }


    // wait for the PEC byte and he end transmission
    while( I2C1->ISR & I2C_ISR_BUSY );


    // todo check if transmission was not broken
    if( I2C1->ISR & I2C_ISR_PECERR )
    {
        // return PEC error
        int n = 0 ;
        n ++ ;
    }
    else
    {
        // return OK
        int i = 0 ;
        i++;
    }

    // disable peripheral -> clear flags
    enable(false);

}