<code>
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Инициализация i2c
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
void I2C_Open(u32_t baud)
{
// set port pins
PINSEL0 &= ~(3<<PINSEL0_P0_2);
PINSEL0 |= (PINSEL_FUNC_01<<PINSEL0_P0_2);
PINSEL0 &= ~(3<<PINSEL0_P0_3);
PINSEL0 |= (PINSEL_FUNC_01<<PINSEL0_P0_3);
// initialize the interrupt vector
VICIntSelect &= ~(1<<VIC_I2C);
VICVectAddr2 = (u32_t)I2C_Handler;
VICVectCntl2 = (1<<VIC_CHNL_ENABLE_BIT) | VIC_I2C;
VICIntEnable |= (1<<VIC_I2C);
//rate set
I2SCLH = baud;
I2SCLL = baud;
}
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// Прием данных
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
void I2C_Receive(u8_t selector, u8_t bsize)
{
// Set I2C bus as active
i2c.err_cnt = 0;
i2c.bcnt = 0;
i2c.flags &= ~(1<<I2C_FLAG_READY);
i2c.flags &= ~(1<<I2C_FLAG_OP_COMPLETE);
i2c.err_code = I2C_NO_ERR;
// Place address and data in Globals to be used by the interrupt
i2c.dsel = selector + I2C_RDFLAG;
i2c.ptr_to_data = (u8_t*)&i2c.buf[I2C_BUF_DATA];
i2c.bsize = bsize; // Counter
I2CONCLR = ((1<<I2CONSET_AA_BIT) | (1<<I2CONSET_SI_BIT) | (1<<I2CONSET_STA_BIT) | (1<<I2CONSET_I2EN_BIT)); // Clear all I2C settings/flags
I2CONSET = ((1<<I2CONSET_STA_BIT) | (1<<I2CONSET_I2EN_BIT)); // Enable the I2C interface + Start condition
}
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
// I2C interrupt routine
//::::::::::::::::::::::::::::::::::::::::::::::::::::::
void I2C_Handler(void)__irq
{
switch(I2STAT) // Read result code and switch to next action
{
//---- Start and TRANSMIT conditions -------
case 0x08:
// A START condition has been transmitted
case 0x10:
// A repated START condition has been transmitted
if(i2c.err_cnt < I2C_MAX_ERR)
{
I2CONCLR = (1<<I2CONSET_STA_BIT); // Clear start bit
I2DAT = i2c.dsel; // Send (Resend) Selector and RW bit
i2c.err_cnt++;
}
else
{
i2c.err_code = I2C_ERR;
i2c.flags |= (1<<I2C_FLAG_READY);// Signal end of I2C activity
}
break;
case 0x20:
// Salve Selector+WR, Not ACK
case 0x48:
// Slave Selector+RD, Not Ack
// Предполагается при неготовности при продолжении цикла записи
// посылается старт заново
if(i2c.err_cnt < I2C_MAX_ERR)
{
I2CONSET = (1<<I2CONSET_STA_BIT); // Set start bit
i2c.err_cnt++;
}
else
{
i2c.err_code = I2C_ERR;
i2c.flags |= (1<<I2C_FLAG_READY); // Signal end of I2C activity
}
break;
case 0x18:
// Slave Selector+WR has been transmitted, ACK
I2DAT = *(i2c.ptr_to_data + i2c.bcnt); // Write to TX register first DATA byte
i2c.bcnt++;
i2c.err_cnt = 0;
break;
case 0x28:
// Data byte has been transmitted; ACK has been received
if(i2c.bcnt < i2c.bsize) // Data sent, Ack
{
I2DAT = *(i2c.ptr_to_data + i2c.bcnt); // Write data to TX register
i2c.bcnt++;
}
else
{
I2CONSET = (1<<I2CONSET_STO_BIT); // Stop condition
i2c.flags |= (1<<I2C_FLAG_READY); // Signal end of I2C activity
}
i2c.err_cnt = 0;
break;
case 0x30:
// Data sent, NOT Ack
if(i2c.err_cnt < I2C_MAX_ERR)
{
I2DAT = *(i2c.ptr_to_data + i2c.bcnt); // Resent Data
i2c.err_cnt++;
}
else
{
i2c.err_code = I2C_ERR;
i2c.flags |= (1<<I2C_FLAG_READY); // Signal end of I2C activity
}
break;
//------------------------------------------
case 0x38:
// Arbitration Lost
if(i2c.err_cnt < I2C_MAX_ERR)
{
I2CONSET = (1<<I2CONSET_STA_BIT); // Set start bit
i2c.err_cnt++;
}
else
{
i2c.err_code = I2C_ERR;
i2c.flags |= (1<<I2C_FLAG_READY); // Signal end of I2C activity
}
break;
//---- RECEIVE conditions ------------------
case 0x40:
// Slave Selector+RD, ACK
I2CONSET = (1<<I2CONSET_AA_BIT); // Enable ACK for data byte
i2c.err_cnt = 0;
break;
case 0x50:
// Data Received, ACK has been returned
if(i2c.bcnt < i2c.bsize)
{
*(i2c.ptr_to_data + i2c.bcnt) = I2DAT;
i2c.bcnt++;
I2CONSET = (1<<I2CONSET_AA_BIT); // Enable ACK for data byte
}
else
{
I2CONCLR = (1<<I2CONSET_AA_BIT);
I2CONSET = (1<<I2CONSET_STO_BIT); // Stop condition
i2c.flags |= (1<<I2C_FLAG_READY); // Signal end of I2C activity
}
i2c.err_cnt = 0;
break;
case 0x58:
// Data Received, Not Ack
if(i2c.bcnt < i2c.bsize)i2c.err_code = I2C_ERR;
i2c.flags |= (1<<I2C_FLAG_READY); // Signal end of I2C activity
break;
default:
// Unknown code
if(i2c.err_cnt < I2C_MAX_ERR)
{
I2CONSET = (1<<I2CONSET_STA_BIT); // Resend
i2c.err_cnt++;
}
else
{
i2c.err_code = I2C_ERR;
i2c.flags |= (1<<I2C_FLAG_READY); // Signal end of I2C activity
}
}
I2CONCLR = (1<<I2CONSET_SI_BIT); // Clear I2C interrupt flag
VICVectAddr = 0; // Clear interrupt
}
</code>