⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lib_twi.c

📁 this document is source code for arm9 of atmel
💻 C
📖 第 1 页 / 共 2 页
字号:

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 + -