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

📄 at24c.c

📁 this document is source code for arm9 of atmel
💻 C
📖 第 1 页 / 共 2 页
字号:
  {
    if ( Address > 0xFFFF) {
        p0 = 1;
        /* Mask the 17th bit to get the 16th LSB */
        WordAddress = Address & 0xFFFF ;
        SlaveAddress = ptAt24c->SlaveAddress + (p0<<16) ;
    }

   else {
    SlaveAddress = ptAt24c->SlaveAddress ;
    WordAddress = Address ;
    }
  }

  AT91F_TWI_ReadSingleIadr(SlaveAddress,
                           WordAddress,
                           AT91C_TWI_IADRSZ_2_BYTE,
                           &Data2Read);
  return (Data2Read);

}

/*-----------------------------------------------------------------------------
Function: AT91F_AT24C_ReadPage(..;..;..)

Arguments:
- <struct at24c *ptAt24c> : Structure of an AT24C Two-wire Eeprom
- <char *Buffer>: The data (*buffer) to store the values read
- <NumOfBytes>: Size of the buffer
- <unsigned int AddressOffSet>: Address offset form the page address

Comments:
This function uses a two bytes internal address (IADR) in relation of the
Eeprom's Internal "Word Address". NACK error not handled

Return Value: None. No read error checking is done.
-----------------------------------------------------------------------------*/
void AT91F_AT24C_ReadPage (struct at24c *ptAt24c,
                            char *Buffer,
                            unsigned int NumOfBytes,
                            unsigned int PageNumber,
                            unsigned int AddressOffSet)
{

  unsigned int WordAddress;   /* Word Address to access within the EEPROM */
  unsigned int SlaveAddress;  /* Address of the Slave device on the bus */
  unsigned int Count ;
  unsigned int status;

  /* 17th bit of the word address. Applicable to the AT24C1024 only */
  unsigned char p0=0;

  if (ptAt24c->EepromName == AT24C1024)
  {
    if ( ( (PageNumber*ptAt24c->PageSize) + AddressOffSet ) > 0xFFFF) {
        p0 = 1;
        /* Mask the 17th bit to get the 16th LSB */
        WordAddress = ( (PageNumber*ptAt24c->PageSize) + AddressOffSet ) & 0xFFFF ;
        SlaveAddress = ptAt24c->SlaveAddress + (p0<<16) ;
    }

   else {
    SlaveAddress = ptAt24c->SlaveAddress ;
    WordAddress = (PageNumber*ptAt24c->PageSize) + AddressOffSet ;
    }
  }

  /****************************************************************************/
  /* Speed improvement w/ large buffer, TWI is accessed witout calling TWI    */
  /* functions                                                                */
  /****************************************************************************/

   /* 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 =  SlaveAddress | AT91C_TWI_MREAD | AT91C_TWI_IADRSZ_2_BYTE;

   /* Set the internal address to access the wanted page */
   AT91C_BASE_TWI->TWI_IADR = WordAddress ;

   /* Send the Start + slave address + Internal Address */
   /* Read operation starts automatically */
   AT91C_BASE_TWI->TWI_CR = AT91C_TWI_START;

   /* Read the page and store it into the buffer */
   for ( Count=0; Count <NumOfBytes; Count++ )
   {
     /* Send the STOP cmd after the next-to-last data */
     if (Count == (NumOfBytes -1) )
      /* We are finished, send the stop command */
      AT91C_BASE_TWI->TWI_CR = AT91C_TWI_STOP;

     /* Wait until RXRDY is high to read the next data */
    status = AT91C_BASE_TWI->TWI_SR;
    while (!(status & AT91C_TWI_RXRDY))
      status = AT91C_BASE_TWI->TWI_SR;

    /*  Read the char received */
    *Buffer++ = AT91C_BASE_TWI->TWI_RHR;

   }

   /* Wait for the Transmit complete flag is set */
   status = AT91C_BASE_TWI->TWI_SR;
   while (!(status & AT91C_TWI_TXCOMP_MASTER))
     status = AT91C_BASE_TWI->TWI_SR;

}

/*-----------------------------------------------------------------------------
Function: AT91F_AT24C_SequentialRead(..;..;..)

Arguments:
- <struct at24c *ptAt24c> : Structure of an AT24C Two-wire Eeprom
- <char *Buffer>: The data (*buffer) to store the values read
- <NumOfBytes>: Size of the buffer
- <unsigned int Address>: Address to strat reading from

Comments:
This function uses a two bytes internal address (IADR) in relation of the
Eeprom's Internal "Word Address"

Return Value: None. No read error checking is done.
-----------------------------------------------------------------------------*/
void AT91F_AT24C_SequentialRead (struct at24c *ptAt24c,
                                 char *Buffer,
                                 unsigned int NumOfBytes,
                                 unsigned int Address)
{
  unsigned int WordAddress;   /* Word Address to access within the EEPROM */
  unsigned int SlaveAddress;  /* Address of the Slave device on the bus */
  unsigned int Count ;
  unsigned int status;

  /* 17th bit of the word address. Applicable to the AT24C1024 only */
  unsigned char p0=0;

   if (ptAt24c->EepromName == AT24C1024)
  {
    if ( Address > 0xFFFF) {
        p0 = 1;
        /* Mask the 17th bit to get the 16th LSB */
        WordAddress = Address & 0xFFFF ;
        SlaveAddress = ptAt24c->SlaveAddress + (p0<<16) ;
    }

   else {
    SlaveAddress = ptAt24c->SlaveAddress ;
    WordAddress = Address ;
    }
  }

  /****************************************************************************/
  /* Speed improvement w/ large buffer, TWI is accessed witout calling TWI    */
  /* functions                                                                */
  /****************************************************************************/

   /* 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 =  SlaveAddress | AT91C_TWI_MREAD | AT91C_TWI_IADRSZ_2_BYTE;

   /* Set the internal address to access the wanted page */
   AT91C_BASE_TWI->TWI_IADR = WordAddress ;

   /* Send the Start + slave address + Internal Address */
   AT91C_BASE_TWI->TWI_CR = AT91C_TWI_START;

   /* Read the page and store it into the buffer */
   for ( Count=0; Count <NumOfBytes; Count++ )
   {
    if (Count == (NumOfBytes -1) )
      /* We are finished, send the stop command */
      AT91C_BASE_TWI->TWI_CR = AT91C_TWI_STOP;

    /* Wait until RXRDY is high to read the next data */
    status = AT91C_BASE_TWI->TWI_SR;
    while (!(status & AT91C_TWI_RXRDY))
      status = AT91C_BASE_TWI->TWI_SR;

    /*  Read the char received */
    *Buffer++ = AT91C_BASE_TWI->TWI_RHR;
   }

   /* Wait for the Transmit complete flag is set */
   status = AT91C_BASE_TWI->TWI_SR;
   while (!(status & AT91C_TWI_TXCOMP_MASTER))
     status = AT91C_BASE_TWI->TWI_SR;

}

/*-----------------------------------------------------------------------------
Function: AT91F_AT24C_MemoryReset(void)

Arguments:
- <const AT91PS_PIO pPio> : Pointer to a PIO structure,
- <int PioID> :  PIO peripheral ID
- <int Twck> : PIO/TWI clock pin
- <int Twd> : PIO/TWI data pin

Comments:
This function sends a "bus recovery" sequence" compatible with I2C(tm)
MEMORY RESET: After an interruption in protocol, power loss or system reset,
any two-wire part can be reset by following these steps:
1. Clock up to 9 cycles.
2. Look for SDA high in each cycle while SCL is high.
3. Create a start condition.
Since the TWI Port does not have the embedded "bus recovery" sequence, it
is managed in PIO mode. The clock peiod is set to 400KHz.

Return Value: None
-----------------------------------------------------------------------------*/
void AT91F_AT24C_MemoryReset (const AT91PS_PIO pPio, int PioID, int Twck, int Twd)
{
  unsigned int ClockPulse;

  /* First, enable the clock of the PIO */
  AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << PioID ) ;

  /* Set the TWI pins controlled by the PIO */
  AT91F_PIO_Enable(pPio,Twck|Twd ) ;

  /* then, we configure the PIO Lines corresponding to TWD & TWCK
     to be outputs. */
  AT91F_PIO_CfgOutput (pPio, Twck|Twd ) ;

  /* Enable open drain on TWCK / TWD PIO lines */
  pPio->PIO_MDER = (Twck|Twd) ;

  /* Disable the pull up on the TWI line */
  pPio->PIO_PPUDR = (Twck|Twd) ;

  /* Set TWCK and TWD to high level */
  AT91F_PIO_SetOutput(pPio, Twck|Twd ) ;
  AT91F_AT24C_WaitMicroSecond(2);

  /* Perform the bus recovery sequence */

  /* 1. Clock up to 9 cycles */
  for (ClockPulse=0 ; ClockPulse < 9 ; ClockPulse++)
  {
     /* Toggle the clock */
     AT91F_PIO_SetOutput(pPio, Twck );
     AT91F_AT24C_WaitMicroSecond(2);
     AT91F_PIO_ClearOutput(pPio, Twck );
     AT91F_AT24C_WaitMicroSecond(2);
     AT91F_PIO_SetOutput(pPio, Twck );
     AT91F_AT24C_WaitMicroSecond(2);

     /* 2. Look for SDA high in each cycle while SCL is high */
     AT91F_PIO_CfgInput(pPio,Twd );

     if ( (AT91F_PIO_GetInput(pPio)&Twd) == Twd)
      ClockPulse = 10;
  }

  AT91F_PIO_SetOutput(pPio, Twck|Twd ) ;
  AT91F_PIO_CfgOutput (pPio, Twd ) ;
  /* Set the TWCK and TWD to send the next start */
  AT91F_PIO_SetOutput(pPio, Twck|Twd );
  AT91F_AT24C_WaitMicroSecond(2);

  /* 3. Create a start condition */
  AT91F_PIO_ClearOutput(pPio, Twd );
  AT91F_AT24C_WaitMicroSecond(2);
  AT91F_PIO_ClearOutput(pPio, Twck );
  AT91F_AT24C_WaitMicroSecond(2);



}





⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -