📄 i2c.c
字号:
/* Send SLA with R bit set, */
LPC_I2C2->DAT = I2CMasterBuffer[2][WrIndex2++];
LPC_I2C2->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
break;
case 0x18: /* Regardless, it's a ACK */
if ( I2CWriteLength[2] == 1 )
{
LPC_I2C2->CONSET = I2CONSET_STO; /* Set Stop flag */
I2CMasterState[2] = I2C_NO_DATA;
}
else
{
LPC_I2C2->DAT = I2CMasterBuffer[2][WrIndex2++];
}
LPC_I2C2->CONCLR = I2CONCLR_SIC;
break;
case 0x28: /* Data byte has been transmitted, regardless ACK or NACK */
if ( WrIndex2 < I2CWriteLength[2] )
{
LPC_I2C2->DAT = I2CMasterBuffer[2][WrIndex2++]; /* this should be the last one */
}
else
{
if ( I2CReadLength[2] != 0 )
{
LPC_I2C2->CONSET = I2CONSET_STA; /* Set Repeated-start flag */
}
else
{
LPC_I2C2->CONSET = I2CONSET_STO; /* Set Stop flag */
I2CMasterState[2] = I2C_OK;
}
}
LPC_I2C2->CONCLR = I2CONCLR_SIC;
break;
case 0x30:
LPC_I2C2->CONSET = I2CONSET_STO; /* Set Stop flag */
I2CMasterState[2] = I2C_NACK_ON_DATA;
LPC_I2C2->CONCLR = I2CONCLR_SIC;
break;
case 0x40: /* Master Receive, SLA_R has been sent */
if ( (RdIndex2 + 1) < I2CReadLength[2] )
{
/* Will go to State 0x50 */
LPC_I2C2->CONSET = I2CONSET_AA; /* assert ACK after data is received */
}
else
{
/* Will go to State 0x58 */
LPC_I2C2->CONCLR = I2CONCLR_AAC; /* assert NACK after data is received */
}
LPC_I2C2->CONCLR = I2CONCLR_SIC;
break;
case 0x50: /* Data byte has been received, regardless following ACK or NACK */
I2CSlaveBuffer[2][RdIndex2++] = LPC_I2C2->DAT;
if ( (RdIndex2 + 1) < I2CReadLength[2] )
{
LPC_I2C2->CONSET = I2CONSET_AA; /* assert ACK after data is received */
}
else
{
LPC_I2C2->CONCLR = I2CONCLR_AAC; /* assert NACK on last byte */
}
LPC_I2C2->CONCLR = I2CONCLR_SIC;
break;
case 0x58:
I2CSlaveBuffer[2][RdIndex2++] = LPC_I2C2->DAT;
I2CMasterState[2] = I2C_OK;
LPC_I2C2->CONSET = I2CONSET_STO; /* Set Stop flag */
LPC_I2C2->CONCLR = I2CONCLR_SIC; /* Clear SI flag */
break;
case 0x20: /* regardless, it's a NACK */
case 0x48:
LPC_I2C2->CONSET = I2CONSET_STO; /* Set Stop flag */
I2CMasterState[2] = I2C_NACK_ON_ADDRESS;
LPC_I2C2->CONCLR = I2CONCLR_SIC;
break;
case 0x38: /* Arbitration lost, in this example, we don't
deal with multiple master situation */
default:
I2CMasterState[2] = I2C_ARBITRATION_LOST;
LPC_I2C2->CONCLR = I2CONCLR_SIC;
break;
}
return;
}
/*****************************************************************************
** Function name: I2CStart
**
** Descriptions: Create I2C start condition, a timeout
** value is set if the I2C never gets started,
** and timed out. It's a fatal error.
**
** parameters: None
** Returned value: true or false, return false if timed out
**
*****************************************************************************/
uint32_t I2CStart( uint32_t portNum )
{
uint32_t retVal = FALSE;
timeout[portNum] = 0;
/*--- Issue a start condition ---*/
LPC_I2C[portNum]->CONSET = I2CONSET_STA; /* Set Start flag */
/*--- Wait until START transmitted ---*/
while( 1 )
{
if ( I2CMasterState[portNum] == I2C_STARTED )
{
retVal = TRUE;
break;
}
if ( timeout[portNum] >= MAX_TIMEOUT )
{
retVal = FALSE;
break;
}
timeout[portNum]++;
}
return( retVal );
}
/*****************************************************************************
** Function name: I2CStop
**
** Descriptions: Set the I2C stop condition, if the routine
** never exit, it's a fatal bus error.
**
** parameters: None
** Returned value: true or never return
**
*****************************************************************************/
uint32_t I2CStop( uint32_t portNum )
{
LPC_I2C[portNum]->CONSET = I2CONSET_STO; /* Set Stop flag */
LPC_I2C[portNum]->CONCLR = I2CONCLR_SIC; /* Clear SI flag */
/*--- Wait for STOP detected ---*/
while( LPC_I2C[portNum]->CONSET & I2CONSET_STO );
return TRUE;
}
/*****************************************************************************
** Function name: I2CInit
**
** Descriptions: Initialize I2C controller as a master
**
** parameters: None
** Returned value: None
**
*****************************************************************************/
void I2C0Init( void )
{
LPC_SC->PCONP |= (1 << 7);
/* set PIO0.27 and PIO0.28 to I2C0 SDA and SCL */
/* function to 01 on both SDA and SCL. */
LPC_PINCON->PINSEL1 &= ~((0x03<<22)|(0x03<<24));
LPC_PINCON->PINSEL1 |= ((0x01<<22)|(0x01<<24));
/*--- Clear flags ---*/
LPC_I2C0->CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;
/*--- Reset registers ---*/
#if FAST_MODE_PLUS
LPC_PINCON->I2CPADCFG |= ((0x1<<0)|(0x1<<2));
LPC_I2C0->SCLL = I2SCLL_HS_SCLL;
LPC_I2C0->SCLH = I2SCLH_HS_SCLH;
#else
LPC_PINCON->I2CPADCFG &= ~((0x1<<0)|(0x1<<2));
LPC_I2C0->SCLL = I2SCLL_SCLL;
LPC_I2C0->SCLH = I2SCLH_SCLH;
#endif
/* Install interrupt handler */
NVIC_EnableIRQ(I2C0_IRQn);
LPC_I2C0->CONSET = I2CONSET_I2EN;
return;
}
/*****************************************************************************
** Function name: I2C1Init
**
** Descriptions: Initialize I2C controller as a master
**
** parameters: None
** Returned value: None
**
*****************************************************************************/
void I2C1Init( void )
{
LPC_SC->PCONP |= (1 << 19);
#if 0
/* set PIO0.0 and PIO0.1 to I2C1 SDA and SCL */
/* function to 11 on both SDA and SCL. */
LPC_PINCON->PINSEL0 &= ~((0x3<<0)|(0x3<<2));
LPC_PINCON->PINSEL0 |= ((0x3<<0)|(0x3<<2));
LPC_PINCON->PINMODE0 &= ~((0x3<<0)|(0x3<<2));
LPC_PINCON->PINMODE0 |= ((0x2<<0)|(0x2<<2)); /* No pull-up no pull-down */
LPC_PINCON->PINMODE_OD0 |= ((0x01<<0)|(0x1<<1)); /* Open drain */
#endif
#if 1
/* set PIO0.19 and PIO0.20 to I2C1 SDA and SCL */
/* function to 11 on both SDA and SCL. */
LPC_PINCON->PINSEL1 &= ~((0x3<<6)|(0x3<<8));
LPC_PINCON->PINSEL1 |= ((0x3<<6)|(0x3<<8));
LPC_PINCON->PINMODE1 &= ~((0x3<<6)|(0x3<<8));
LPC_PINCON->PINMODE1 |= ((0x2<<6)|(0x2<<8)); /* No pull-up no pull-down */
LPC_PINCON->PINMODE_OD0 |= ((0x1<<19)|(0x1<<20));
#endif
/*--- Clear flags ---*/
LPC_I2C1->CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;
/*--- Reset registers ---*/
LPC_I2C1->SCLL = I2SCLL_SCLL;
LPC_I2C1->SCLH = I2SCLH_SCLH;
/* Install interrupt handler */
NVIC_EnableIRQ(I2C1_IRQn);
LPC_I2C1->CONSET = I2CONSET_I2EN;
return;
}
/*****************************************************************************
** Function name: I2C2Init
**
** Descriptions: Initialize I2C controller as a master
**
** parameters: None
** Returned value: None
**
*****************************************************************************/
void I2C2Init( void )
{
LPC_SC->PCONP |= (1 << 26);
/* set PIO0.10 and PIO0.11 to I2C2 SDA and SCL */
/* function to 10 on both SDA and SCL. */
LPC_PINCON->PINSEL0 &= ~((0x03<<20)|(0x03<<22));
LPC_PINCON->PINSEL0 |= ((0x02<<20)|(0x02<<22));
LPC_PINCON->PINMODE0 &= ~((0x03<<20)|(0x03<<22));
LPC_PINCON->PINMODE0 |= ((0x02<<20)|(0x2<<22)); /* No pull-up no pull-down */
LPC_PINCON->PINMODE_OD0 |= ((0x01<<10)|(0x1<<11));
/*--- Clear flags ---*/
LPC_I2C2->CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;
/*--- Reset registers ---*/
LPC_I2C2->SCLL = I2SCLL_SCLL;
LPC_I2C2->SCLH = I2SCLH_SCLH;
/* Install interrupt handler */
NVIC_EnableIRQ(I2C2_IRQn);
LPC_I2C2->CONSET = I2CONSET_I2EN;
return;
}
/*****************************************************************************
** Function name: I2CEngine
**
** Descriptions: The routine to complete a I2C transaction
** from start to stop. All the intermitten
** steps are handled in the interrupt handler.
** Before this routine is called, the read
** length, write length, I2C master buffer,
** and I2C command fields need to be filled.
** see i2cmst.c for more details.
**
** parameters: I2C port number
** Returned value: master state of current I2C port.
**
*****************************************************************************/
uint32_t I2CEngine( uint32_t portNum )
{
/*--- Issue a start condition ---*/
LPC_I2C[portNum]->CONSET = I2CONSET_STA; /* Set Start flag */
I2CMasterState[portNum] = I2C_BUSY;
while ( I2CMasterState[portNum] == I2C_BUSY )
{
if ( timeout[portNum] >= MAX_TIMEOUT )
{
I2CMasterState[portNum] = I2C_TIME_OUT;
break;
}
timeout[portNum]++;
}
LPC_I2C[portNum]->CONCLR = I2CONCLR_STAC;
return ( I2CMasterState[portNum] );
}
/******************************************************************************
** End Of File
******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -