📄 lib_twi.c
字号:
Arguments: <AT91PS_TWI pTwi> : Pointer to the TWI structure.
<SlaveAddr>: Address of the slave device to read from.
<data>: Pointer to the data to read
Comments : Read single data from a slave device without internal address.
Takes into account the NACK errata.
Return Value: <data>: Data read via a pointer.
-----------------------------------------------------------------------------*/
int AT91F_TWI_ReadSingle(const AT91PS_TWI pTwi,
int SlaveAddr,
char *data)
{
unsigned int status,error=0, end=0;
/* Enable Master Mode */
pTwi->TWI_CR = AT91C_TWI_MSEN ;
/* Set the TWI Master Mode Register */
pTwi->TWI_MMR = SlaveAddr | AT91C_TWI_MREAD;
pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_STOP;
/* NACK errata handling */
/* Do not poll the TWI_SR */
/* Wait 3 x 9 TWCK pulse (max) 2 if IADRR not used, before reading TWI_SR */
/* From 400Khz down to 1Khz, the time to wait will be in 祍 range.*/
/* In this example the TWI period is 1/400KHz */
AT91F_TWI_WaitMicroSecond (40) ;
while (!end)
{
status = AT91C_BASE_TWI->TWI_SR;
if ((status & AT91C_TWI_NACK) == AT91C_TWI_NACK)
{
error++;
end=1;
}
/* Wait for the receive ready is set */
if ((status & AT91C_TWI_RXRDY) == AT91C_TWI_RXRDY)
end=1;
}
*(data) = pTwi->TWI_RHR;
/* Wait for the Transmit complete is set */
status = AT91C_BASE_TWI->TWI_SR;
while (!(status & AT91C_TWI_TXCOMP))
status = AT91C_BASE_TWI->TWI_SR;
return 0;
}
/*-----------------------------------------------------------------------------
Function: AT91F_TWI_ReadSingleIadr
Arguments: <AT91PS_TWI pTwi> : Pointer to the TWI structure.
<SlaveAddr>: Address of the slave device to read from.
<IntAddr>: Internal slave device address. Set to 0 if no.
<IntAddrSize>: Size of the internal address.Set to 0 if no.
<data>: Pointer to the data to read
Comments : Read single data from a slave device with internal address.
Takes into account the NACK errata.
Return Value: <data>: Data read via a pointer.
-----------------------------------------------------------------------------*/
int AT91F_TWI_ReadSingleIadr(const AT91PS_TWI pTwi,
int SlaveAddr,
int IntAddr,
int IntAddrSize,
char *data)
{
unsigned int status,error=0, end=0;
/* Enable Master Mode */
pTwi->TWI_CR = AT91C_TWI_MSEN ;
/* Set the TWI Master Mode Register */
pTwi->TWI_MMR = SlaveAddr | IntAddrSize | AT91C_TWI_MREAD;
/* Set TWI Internal Address Register if needed */
pTwi->TWI_IADR = IntAddr;
pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_STOP;
/* NACK errata handling */
/* Do not poll the TWI_SR */
/* Wait 3 x 9 TWCK pulse (max) 2 if IADRR not used, before reading TWI_SR */
/* From 400Khz down to 1Khz, the time to wait will be in 祍 range.*/
/* In this example the TWI period is 1/400KHz */
AT91F_TWI_WaitMicroSecond (40) ;
while (!end)
{
status = AT91C_BASE_TWI->TWI_SR;
if ((status & AT91C_TWI_NACK) == AT91C_TWI_NACK)
{
error++;
end=1;
}
/* Wait for the receive ready is set */
if ((status & AT91C_TWI_RXRDY) == AT91C_TWI_RXRDY)
end=1;
}
*(data) = pTwi->TWI_RHR;
/* Wait for the Transmit complete is set */
status = AT91C_BASE_TWI->TWI_SR;
while (!(status & AT91C_TWI_TXCOMP))
status = AT91C_BASE_TWI->TWI_SR;
return 0;
}
/*-----------------------------------------------------------------------------
Function: AT91F_TWI_ReadMultiple
Arguments: <AT91PS_TWI pTwi> : Pointer to the TWI structure.
<SlaveAddr>: Address of the slave device to read from.
<NumOfBytes>: Number of data to read
<data>: Pointer to the data to read
Comments : Read multiple data from a slave device without internal address.
Takes into account the NACK errata.
Return Value: <data>: Data read via a pointer.
-----------------------------------------------------------------------------*/
int AT91F_TWI_ReadMultiple(const AT91PS_TWI pTwi,
int SlaveAddr,
unsigned int NumOfBytes,
char *data)
{
unsigned int status,error=0, ReadCount, end=0;
/* Enable Master Mode of the TWI */
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_MSEN ;
/* Set the TWI Master Mode Register */
AT91C_BASE_TWI->TWI_MMR = SlaveAddr | AT91C_TWI_MREAD ;
/* Send the Start + slave address */
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_START;
/* Read and store it into the buffer */
for ( ReadCount=0; ReadCount <NumOfBytes; ReadCount++ )
{
/* if next-lo-last data send the stop */
if (ReadCount == (NumOfBytes -1) )
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_STOP;
/* NACK errata handling */
/* Do not poll the TWI_SR */
/* Wait 3 x 9 TWCK pulse (max) 2 if IADRR not used, before reading TWI_SR */
/* From 400Khz down to 1Khz, the time to wait will be in 祍 range.*/
/* In this example the TWI period is 1/400KHz */
AT91F_TWI_WaitMicroSecond (40) ;
while (!end)
{
status = AT91C_BASE_TWI->TWI_SR;
if ((status & AT91C_TWI_NACK) == AT91C_TWI_NACK)
{
error++;
end=1;
}
/* Wait until RXRDY is high to read the next data */
if ((status & AT91C_TWI_RXRDY) == AT91C_TWI_RXRDY)
end=1;
}
/* Read the char received */
*data++ = AT91C_BASE_TWI->TWI_RHR;
}
/* Wait for the Transmit complete is set */
status = AT91C_BASE_TWI->TWI_SR;
while (!(status & AT91C_TWI_TXCOMP))
status = AT91C_BASE_TWI->TWI_SR;
return 0;
}
/*-----------------------------------------------------------------------------
Function: AT91F_TWI_ReadMultipleIadr
Arguments: <AT91PS_TWI pTwi> : Pointer to the TWI structure.
<SlaveAddr>: Address of the slave device to read from.
<IntAddr>: Internal slave device address. Set to 0 if no.
<IntAddrSize>: Size of the internal address.Set to 0 if no.
<NumOfBytes>: Number of data to read
<data>: Pointer to the data to read
Comments : Read multiple data from a slave device with internal address.
Takes into account the NACK errata.
Return Value: <data>: Data read via a pointer.
-----------------------------------------------------------------------------*/
int AT91F_TWI_ReadMultipleIadr(const AT91PS_TWI pTwi,
int SlaveAddr,
unsigned int NumOfBytes,
int IntAddr,
int IntAddrSize,
char *data)
{
unsigned int status,error=0, ReadCount, end=0;
/* Enable Master Mode of the TWI */
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_MSEN ;
/* Set the TWI Master Mode Register */
pTwi->TWI_MMR = SlaveAddr | IntAddrSize | AT91C_TWI_MREAD;
/* Set TWI Internal Address Register if needed */
pTwi->TWI_IADR = IntAddr;
/* Send the Start + slave address */
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_START;
/* Read and store it into the buffer */
for ( ReadCount=0; ReadCount <NumOfBytes; ReadCount++ )
{
/* if next-lo-last data send the stop */
if (ReadCount == (NumOfBytes -1) )
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_STOP;
/* NACK errata handling */
/* Do not poll the TWI_SR */
/* Wait 3 x 9 TWCK pulse (max) 2 if IADRR not used, before reading TWI_SR */
/* From 400Khz down to 1Khz, the time to wait will be in 祍 range.*/
/* In this example the TWI period is 1/400KHz */
AT91F_TWI_WaitMicroSecond (40) ;
while (!end)
{
status = AT91C_BASE_TWI->TWI_SR;
if ((status & AT91C_TWI_NACK) == AT91C_TWI_NACK)
{
error++;
end=1;
}
/* Wait until RXRDY is high to read the next data */
if ((status & AT91C_TWI_RXRDY) == AT91C_TWI_RXRDY)
end=1;
}
/* Read the char received */
*data = AT91C_BASE_TWI->TWI_RHR;
data++;
}
/* Wait for the Transmit complete is set */
status = AT91C_BASE_TWI->TWI_SR;
while (!(status & AT91C_TWI_TXCOMP))
status = AT91C_BASE_TWI->TWI_SR;
return 0;
}
/*----------------------------------------------------------------------------
Function : AT91F_TWI_ProbeDevices
Arguments: <AT91PS_TWI pTwi> : Pointer to the TWI structure.
<SlaveAddr>: Address of the slave device to probe.
Comments : Write a single data into a slave device to see if it is connected
Takes into account the NACK errata.
Return Value: AT91C_TWI_NACK if so, SlaveAddress otherwise.
-----------------------------------------------------------------------------*/
int AT91F_TWI_ProbeDevices(const AT91PS_TWI pTwi, int SlaveAddr)
{
unsigned int end = 0, status, Return;
/* Enable Master Mode */
pTwi->TWI_CR = AT91C_TWI_MSEN ;
/* Set the TWI Master Mode Register */
pTwi->TWI_MMR = SlaveAddr & ~AT91C_TWI_MREAD;
/* Write the data to send into THR. Start conditionn DADDR and R/W bit
are sent automatically */
pTwi->TWI_THR = 0x55;
/* NACK errata handling */
/* Do not poll the TWI_SR */
/* Wait 3 x 9 TWCK pulse (max) 2 if IADRR not used, before reading TWI_SR */
/* From 400Khz down to 1Khz, the time to wait will be in 祍 range.*/
/* In this example the TWI period is 1/400KHz */
AT91F_TWI_WaitMicroSecond (50) ;
while (!end)
{
status = AT91C_BASE_TWI->TWI_SR;
if ((status & AT91C_TWI_NACK) == AT91C_TWI_NACK)
{
Return = AT91C_TWI_NACK ;
end=1;
}
/* Wait for the Transmit ready is set */
else if ((status & AT91C_TWI_TXRDY) == AT91C_TWI_TXRDY)
{
end=1;
Return = SlaveAddr>>16;
}
}
/* Wait for the Transmit complete is set */
status = AT91C_BASE_TWI->TWI_SR;
while (!(status & AT91C_TWI_TXCOMP))
status = AT91C_BASE_TWI->TWI_SR;
return (Return);
}
/*-----------------------------------------------------------------------------
* \fn AT91F_TWI_Open
* \brief Initializes TWI device
-----------------------------------------------------------------------------*/
void AT91F_TWI_Open(int TwiClock)
{
/* Configure TWI PIOs */
AT91F_TWI_CfgPIO ();
/* Configure PMC by enabling TWI clock */
AT91F_TWI_CfgPMC ();
/* Reset the TWI */
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_SWRST;
/* Configure TWI in master mode */
AT91F_TWI_Configure (AT91C_BASE_TWI);
/* Set TWI Clock Waveform Generator Register */
AT91F_SetTwiClock(TwiClock);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -