📄 lib_twi.c
字号:
return error;
}
/*-----------------------------------------------------------------------------
Function: AT91F_TWI_ReadSingle
Arguments:
<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.
Return Value: <data>: Data read via a pointer.
-----------------------------------------------------------------------------*/
int AT91F_TWI_ReadSingle(int SlaveAddr,
char *data)
{
unsigned int status,error=0, end=0;
/* Enable Master Mode */
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_MSEN|AT91C_TWI_SVDIS ;
/* Set the TWI Master Mode Register */
AT91C_BASE_TWI->TWI_MMR = SlaveAddr | AT91C_TWI_MREAD;
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_START | AT91C_TWI_STOP;
while (!end)
{
status = AT91C_BASE_TWI->TWI_SR;
if ((status & AT91C_TWI_NACK_MASTER) == AT91C_TWI_NACK_MASTER)
{
error = AT91C_TWI_NACK_MASTER;
end=1;
}
/* Wait for the receive ready is set */
if ((status & AT91C_TWI_RXRDY) == AT91C_TWI_RXRDY)
end=1;
}
*data = AT91C_BASE_TWI->TWI_RHR;
/* Wait for the Transmit complete is set */
status = AT91C_BASE_TWI->TWI_SR;
while (!(status & AT91C_TWI_TXCOMP_MASTER))
status = AT91C_BASE_TWI->TWI_SR;
return (error);
}
/*-----------------------------------------------------------------------------
Function: AT91F_TWI_ReadSingleIadr
Arguments:
<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.
Return Value: <data>: Data read via a pointer.
-----------------------------------------------------------------------------*/
int AT91F_TWI_ReadSingleIadr(int SlaveAddr,
int IntAddr,
int IntAddrSize,
char *data)
{
unsigned int status,error=0, end=0;
/* Enable Master Mode */
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_MSEN|AT91C_TWI_SVDIS ;
/* Set the TWI Master Mode Register */
AT91C_BASE_TWI->TWI_MMR = SlaveAddr | IntAddrSize | AT91C_TWI_MREAD;
/* Set TWI Internal Address Register if needed */
AT91C_BASE_TWI->TWI_IADR = IntAddr;
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_START | AT91C_TWI_STOP;
while (!end)
{
status = AT91C_BASE_TWI->TWI_SR;
if ((status & AT91C_TWI_NACK_MASTER) == AT91C_TWI_NACK_MASTER)
{
error = AT91C_TWI_NACK_MASTER;
end=1;
}
/* Wait for the receive ready is set */
if ((status & AT91C_TWI_RXRDY) == AT91C_TWI_RXRDY)
end=1;
}
*data = AT91C_BASE_TWI->TWI_RHR;
/* Wait for the Transmit complete is set */
status = AT91C_BASE_TWI->TWI_SR;
while (!(status & AT91C_TWI_TXCOMP_MASTER))
status = AT91C_BASE_TWI->TWI_SR;
return (error);
}
/*-----------------------------------------------------------------------------
Function: AT91F_TWI_ReadMultiple
Arguments:
<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.
Return Value: <data>: Data read via a pointer.
-----------------------------------------------------------------------------*/
int AT91F_TWI_ReadMultiple(int SlaveAddr,
char *data,
unsigned int NumOfBytes)
{
unsigned int status,error=0, ReadCount, end=0;
/* Enable Master Mode of the TWI */
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_MSEN|AT91C_TWI_SVDIS ;
/* 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;
end=0;
/* Wait until RXRDY is high to read the next data or NACK received */
while (!end)
{
status = AT91C_BASE_TWI->TWI_SR ;
if ((status & AT91C_TWI_NACK_MASTER) == AT91C_TWI_NACK_MASTER)
{
error = AT91C_TWI_NACK_MASTER;
end=1;
}
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_MASTER))
status = AT91C_BASE_TWI->TWI_SR;
return (error);
}
/*-----------------------------------------------------------------------------
Function: AT91F_TWI_ReadMultipleIadr
Arguments:
<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
<NumOfBytes>: Number of data to read
Comments : Read multiple data from a slave device with internal address.
Return Value: <data>: Data read via a pointer.
-----------------------------------------------------------------------------*/
int AT91F_TWI_ReadMultipleIadr(int SlaveAddr,
int IntAddr,
int IntAddrSize,
char *data,
unsigned int NumOfBytes)
{
unsigned int status,error=0,ReadCount,end=0 ;
/* Enable Master Mode of the TWI */
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_MSEN|AT91C_TWI_SVDIS ;
/* Set the TWI Master Mode Register */
AT91C_BASE_TWI->TWI_MMR = SlaveAddr | IntAddrSize | AT91C_TWI_MREAD;
/* Set TWI Internal Address Register if needed */
AT91C_BASE_TWI->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;
end=0;
/* Wait until RXRDY is high to read the next data or NACK received */
while (!end)
{
status = AT91C_BASE_TWI->TWI_SR ;
if ((status & AT91C_TWI_NACK_MASTER) == AT91C_TWI_NACK_MASTER)
{
error = AT91C_TWI_NACK_MASTER;
end=1;
}
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_MASTER))
status = AT91C_BASE_TWI->TWI_SR;
return (error);
}
/*----------------------------------------------------------------------------
Function : AT91F_TWI_ProbeDevices
Arguments:
<SlaveAddr>: Address of the slave device to probe.
Comments : Write a single data into a slave device to see if it is connected on
the bus.
Return Value: AT91C_TWI_NACK_MASTER if so, SlaveAddress otherwise.
-----------------------------------------------------------------------------*/
int AT91F_TWI_ProbeDevices(int SlaveAddr)
{
unsigned int end = 0, status, Return;
/* Enable Master Mode */
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_MSEN|AT91C_TWI_SVDIS ;
/* Set the TWI Master Mode Register */
AT91C_BASE_TWI->TWI_MMR = SlaveAddr & ~AT91C_TWI_MREAD;
/* Write the data to send into THR. Start conditionn DADDR and R/W bit
are sent automatically */
AT91C_BASE_TWI->TWI_THR = 0x55;
while (!end)
{
status = AT91C_BASE_TWI->TWI_SR;
if ((status & AT91C_TWI_NACK_MASTER) == AT91C_TWI_NACK_MASTER)
{
Return = AT91C_TWI_NACK_MASTER ;
end=1;
}
/* Wait for the Transmit ready is set */
else if ((status & AT91C_TWI_TXRDY_MASTER) == AT91C_TWI_TXRDY_MASTER)
{
end=1;
Return = SlaveAddr>>16;
}
}
/* Wait for the Transmit complete is set */
status = AT91C_BASE_TWI->TWI_SR;
while (!(status & AT91C_TWI_TXCOMP_MASTER))
status = AT91C_BASE_TWI->TWI_SR;
return (Return);
}
/*-----------------------------------------------------------------------------
* \fn AT91F_TWI_Open
* \brief Initializes TWI device
-----------------------------------------------------------------------------*/
void AT91F_TWI_Open(int TwiClock)
{
/* Configure the PIO pins corresponding to the TWI pins */
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 + -