LPC23/24/21 I2C hW = problema.

Software e Hardware para linha ARM

Moderadores: 51, guest2003, Renie, gpenga

LPC23/24/21 I2C hW = problema.

Mensagempor fabim » 24 Mai 2011 15:57

Psoal, infelizmente fui forçado a usar a fuck I2C do ARM7 NXP via hW.

Só que exemplo não worka, dicas não workan, nada worka, via hW.

Gostaria de saber se algum fio de Deus daqui ja mexeu na I2C do ARM7 da nxp e poderia me ajudar.

Seguinte.
O elma chips que eu estou tentando comunicar é simples bagarai.

CMD1-Start Condition + ADDR + COMMAND + Stop Condition.

CMD2-Start Condition + ADDR + Leio 1 + Leio 2 + Stop Condition.

Acontece, que não é necessario e não pode ter o re-*start...

Módique, existe um delay entre o CMD1 e CMD2 de 50mS, isso é pra eu não ficar parado lendo 3 em 3 bytes, e testando o bit 7 do ultimo byte pra saber se os dados foram validos.....

Simplesmente não works, eu estou aqui com o DS1102D e essa carta de tempo do fiadaputa ta me deixando louco.

Seria para hablar com lo MCP3426, que esta implementado em um sistema full gauge, mais ta brabo..

Froid, alguém alguma dicosa ?
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor tcpipchip » 24 Mai 2011 17:27

Talvez este link te ajude...
http://www.inf.furb.br/~maw/arm/lpc-ARM-book_srn_p.pdf
A partir da pagina 95
Eu lembro que funcionou com DS1621...que usa o mesmo esquema de CMD para habilitar o AD
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Re: LPC23/24/21 I2C hW = problema.

Mensagempor Rodrigo_P_A » 25 Mai 2011 08:42

fabim escreveu:Psoal, infelizmente fui forçado a usar a fuck I2C do ARM7 NXP via hW.

Só que exemplo não worka, dicas não workan, nada worka, via hW.

Gostaria de saber se algum fio de Deus daqui ja mexeu na I2C do ARM7 da nxp e poderia me ajudar.

Seguinte.
O elma chips que eu estou tentando comunicar é simples bagarai.

CMD1-Start Condition + ADDR + COMMAND + Stop Condition.

CMD2-Start Condition + ADDR + Leio 1 + Leio 2 + Stop Condition.

Acontece, que não é necessario e não pode ter o re-*start...

Módique, existe um delay entre o CMD1 e CMD2 de 50mS, isso é pra eu não ficar parado lendo 3 em 3 bytes, e testando o bit 7 do ultimo byte pra saber se os dados foram validos.....

Simplesmente não works, eu estou aqui com o DS1102D e essa carta de tempo do fiadaputa ta me deixando louco.

Seria para hablar com lo MCP3426, que esta implementado em um sistema full gauge, mais ta brabo..

Froid, alguém alguma dicosa ?


aqui tem exemplo funcional criado pelo Alessandro do forum:

http://www.kitmcu.com.br/loja/produtove ... rodutoid=1
---
Avatar do usuário
Rodrigo_P_A
Dword
 
Mensagens: 2237
Registrado em: 12 Out 2006 18:27
Localização: Osasco - S.P - Brasil

Mensagempor Red Neck Guy » 25 Mai 2011 10:21

Eu tenha uma biblioteca que alterei pra usar o controlador interno.
Também vou postar aqui uma biblioteca pra eeprom i2c com uma camada de abstração de escrita de blocos de N tamanho a partir de qualquer endereço da eeprom.




I2C0.C
Código: Selecionar todos



/******************************************************************************
 * Includes
 *****************************************************************************/
#include <NXP\IOLPC2220.H>

#include "I2C0.H"

/******************************************************************************
 * Defines and typedefs
 *****************************************************************************/
#define CRYSTAL_FREQUENCY FOSC
#define PLL_FACTOR        PLL_MUL
#define VPBDIV_FACTOR     PBSD

//different modes
#define I2C_MODE_ACK0 0
#define I2C_MODE_ACK1 1
#define I2C_MODE_READ 2


/******************************************************************************
 *
 * Description:
 *    Checks the I2C status.
 *
 *  Returns:
 *      00h Bus error
 *      08h START condition transmitted
 *      10h Repeated START condition transmitted
 *      18h SLA + W transmitted, ACK received
 *      20h SLA + W transmitted, ACK not received
 *      28h Data byte transmitted, ACK received
 *      30h Data byte transmitted, ACK not received
 *      38h Arbitration lost
 *      40h SLA + R transmitted, ACK received
 *      48h SLA + R transmitted, ACK not received
 *      50h Data byte received in master mode, ACK transmitted
 *      58h Data byte received in master mode, ACK not transmitted
 *      60h SLA + W received, ACK transmitted
 *      68h Arbitration lost, SLA + W received, ACK transmitted
 *      70h General call address received, ACK transmitted
 *      78h Arbitration lost, general call addr received, ACK transmitted
 *      80h Data byte received with own SLA, ACK transmitted
 *      88h Data byte received with own SLA, ACK not transmitted
 *      90h Data byte received after general call, ACK transmitted
 *      98h Data byte received after general call, ACK not transmitted
 *      A0h STOP or repeated START condition received in slave mode
 *      A8h SLA + R received, ACK transmitted
 *      B0h Arbitration lost, SLA + R received, ACK transmitted
 *      B8h Data byte transmitted in slave mode, ACK received
 *      C0h Data byte transmitted in slave mode, ACK not received
 *      C8h Last byte transmitted in slave mode, ACK received
 *      F8h No relevant status information, SI=0
 *      FFh Channel error
 *
 *****************************************************************************/
tU8
i2cCheckStatus(void)
{
  tU8 status;

  //wait for I2C Status changed
  while( (I2C_I2CONSET & 0x08) == 0)   //while SI == 0
    ;

  //read I2C State
  status = I2C_I2STAT;

  //NOTE! SI flag is not cleared here

  return status;
}

/******************************************************************************
 *
 * Description:
 *    Reset and initialize the I2C peripheral.
 *
 * Params:
 *    [in]  i2cFrequency  - frequency on clock signal in Hz (max 400 kHz)
 *
 *****************************************************************************/
void
i2cInit(tU32 i2cFrequency)
{
   //connect I2C signals (SDA & SCL) to P0.2 and P0.3
  PINSEL0 &= ~0x000000F0;
  PINSEL0 |=  0x00000050;

  //clear flags
  I2C_I2CONCLR = 0x6c;

  //set bit timing ans start with checking for maximum speed (400kHz)
  if (i2cFrequency > 400000)
    i2cFrequency = 400000;
  I2C_I2SCLH   = (60000000 / i2cFrequency + 1) / 2;
  I2C_I2SCLL   = (60000000 / i2cFrequency) / 2;

  //reset registers
  I2C_I2ADR    = 0x00;
  I2C_I2CONSET = 0x40;
}

/******************************************************************************
 *
 * Description:
 *    Generates a start condition on I2C when bus is free.
 *    Master mode will also automatically be entered.
 *
 * Returns:
 *    I2C_CODE_OK or I2C status code
 *
 *****************************************************************************/
tS8
i2cStart(void)
{
  tU8   status  = 0;
  tS8   retCode = 0;

  //issue a start condition
  I2C_I2CONSET |= 0x20;   //STA = 1, set start flag

  //wait until START transmitted
  while(1)
  {
    status = i2cCheckStatus();

    //start transmitted
    if((status == 0x08) || (status == 0x10))
    {
      retCode = I2C_CODE_OK;
      break;
    }

    //error
    else if(status != 0xf8)
    {
      retCode = (tS8) status;
      break;
    }

    else
    {
      //clear SI flag
      I2C_I2CONCLR = 0x08;
    }   
  }

  //clear start flag
  I2C_I2CONCLR = 0x20;

  return retCode;
}

/******************************************************************************
 *
 * Description:
 *    Generates a start condition on I2C when bus is free.
 *    Master mode will also automatically be entered.
 *
 * Returns:
 *    I2C_CODE_OK or I2C status code
 *
 *****************************************************************************/
tS8
i2cRepeatStart(void)
{
  tU8   status  = 0;
  tS8   retCode = 0;

  //issue a start condition
  I2C_I2CONSET |= 0x20;   //STA = 1, set start flag
  I2C_I2CONCLR = 0x08;    //clear SI flag

  //wait until START transmitted
  while(1)
  {
    status = i2cCheckStatus();

    //start transmitted
    if((status == 0x08) || (status == 0x10))
    {
      retCode = I2C_CODE_OK;
      break;
    }

    //error
    else if(status != 0xf8)
    {
      retCode = (tS8) status;
      break;
    }

    else
    {
      //clear SI flag
      I2C_I2CONCLR = 0x08;
    }   
  }

  //clear start flag
  I2C_I2CONCLR = 0x20;

  return retCode;
}

/******************************************************************************
 *
 * Description:
 *    Generates a stop condition in master mode or recovers from an error
 *    condition in slave mode.
 *
 * Returns:
 *    I2C_CODE_OK
 *
 *****************************************************************************/
tS8
i2cStop(void)
{
  I2C_I2CONSET |= 0x10;  //STO = 1, set stop flag
  I2C_I2CONCLR = 0x08;   //clear SI flag

  //wait for STOP detected (while STO = 1)
  while((I2C_I2CONSET & 0x10) == 0x10)
    ;

  return I2C_CODE_OK;
}

/******************************************************************************
 *
 * Description:
 *    Sends a character on the I2C network
 *
 * Params:
 *    [in] data - the character to send
 *
 * Returns:
 *    I2C_CODE_OK   - successful
 *    I2C_CODE_BUSY - data register is not ready -> byte was not sent
 *
 *****************************************************************************/
tS8
i2cPutChar(tU8 data)
{
  tS8 retCode = 0;

  //check if I2C Data register can be accessed
  if((I2C_I2CONSET & 0x08) != 0)    //if SI = 1
  {
    /* send data */
    I2C_I2DAT    = data;
    I2C_I2CONCLR = 0x08;       //clear SI flag
    retCode    = I2C_CODE_OK;
  }
  else
  {
    //data register not ready
    retCode = (tS8)I2C_CODE_BUSY;
  }

  return retCode;
}

/******************************************************************************
 *
 * Description:
 *    Read a character. I2C master mode is used.
 *    This function is also used to prepare if the master shall generate
 *    acknowledge or not acknowledge.
 *
 * Params:
 *    [in]  mode  - I2C_MODE_ACK0 Set ACK=0. Slave sends next byte
 *                  I2C_MODE_ACK1 Set ACK=1. Slave sends last byte
 *                  I2C_MODE_READ Read data from data register
 *    [out] pData - a pointer to where the data shall be saved.
 *
 * Returns:
 *    I2C_CODE_OK    - successful
 *    I2C_CODE_EMPTY - no data is available
 *
 *****************************************************************************/
tS8
i2cGetChar(tU8  mode,
           tU8* pData)
{
  tS8 retCode = I2C_CODE_OK;

  if(mode == I2C_MODE_ACK0)
  {
    //the operation mode is changed from master transmit to master receive
    //set ACK=0 (informs slave to send next byte)
    I2C_I2CONSET |= 0x04;   //AA=1
    I2C_I2CONCLR = 0x08;    //clear SI flag
  }
  else if(mode == I2C_MODE_ACK1)
  {
    //set ACK=1 (informs slave to send last byte)
    I2C_I2CONCLR = 0x04;     
    I2C_I2CONCLR = 0x08;   //clear SI flag
  }
  else if(mode == I2C_MODE_READ)
  {
    //check if I2C Data register can be accessed
    if((I2C_I2CONSET & 0x08) != 0)    //SI = 1
    {
      //read data
      *pData = (tU8)I2C_I2DAT;
    }
    else
    {
      //No data available
      retCode = (tS8)I2C_CODE_EMPTY;
    }
  }

  return retCode;
}


/******************************************************************************
 *
 * Description:
 *    Wait after transmission of a byte until done
 *
 * Returns:
 *    I2C_CODE_OK    - successful / done
 *    I2C_CODE_ERROR - an error occured
 *
 *****************************************************************************/
tS8
i2cWaitAfterTransmit(void)
{
  tU8 status = 0;

  //wait until data transmitted
  while(1)
  {
    //get new status
    status = i2cCheckStatus();

    /*
     * SLA+W transmitted, ACK received or
     * data byte transmitted, ACK received
     */
    if( (status == 0x18) || (status == 0x28) )
    {
      //data transmitted and ACK received
      return I2C_CODE_OK;
    }

    //no relevant status information
    else if(status != 0xf8 )
    {
      //error
      return I2C_CODE_ERROR;
    }
  }
}


/******************************************************************************
 *
 * Description:
 *    Sends a character on the I2C network and wait until done
 *
 * Params:
 *    [in] data - the character to send
 *
 * Returns:
 *    I2C_CODE_OK    - successful
 *    I2C_CODE_BUSY  - data register is not ready -> byte was not sent
 *    I2C_CODE_ERROR - an error occured
 *
 *****************************************************************************/
tS8
i2cPutCharAndWait(tU8 data)
{
  tS8 retCode;
 
  retCode = i2cPutChar(data);
  while(retCode == (tS8)I2C_CODE_BUSY)
    retCode = i2cPutChar(data);

  if(retCode == I2C_CODE_OK)
    retCode = i2cWaitAfterTransmit();

  return retCode;
}


/******************************************************************************
 *
 * Description:
 *    Sends data on the I2C network
 *
 *    Note: No stop condition is generated after the transmission - this must
 *          be done after calling this function.
 *
 * Params:
 *    [in] addr     - address
 *    [in] extraCmd - controls if 0, 1 or 2 extra bytes shall be transmitted
 *                    before data buffer
 *    [in] extra    - byte of word to be transmitted before data buffer
 *    [in] pData    - data to transmit
 *    [in] len      - number of bytes to transmit
 *
 * Returns:
 *    I2C_CODE_OK    - successful
 *    I2C_CODE_ERROR - an error occured
 *
 *****************************************************************************/
tS8
i2cWrite(tU8  addr,
         tU8  extraCmd,
         tU16 extra,
         tU8* pData,
         tU16 len)
{
  tS8 retCode = 0;
  tU8 i       = 0;

  do
  {
    //generate Start condition
    retCode = i2cStart();
    if(retCode != I2C_CODE_OK)
      break;
   
    //Transmit slave address
    retCode = i2cPutCharAndWait(addr);
    if(retCode != I2C_CODE_OK)
      break;

    //Transmit MSB of extra word (if wanted)
      if (extraCmd == I2C_EXTRA_WORD)
     {
      retCode = i2cPutCharAndWait((tU8)(extra >> 8));
      if(retCode != I2C_CODE_OK)
        break;
    }

    //Transmit LSB of extra work (if wanted)
      if ((extraCmd == I2C_EXTRA_BYTE) || (extraCmd == I2C_EXTRA_WORD))
      {
      retCode = i2cPutCharAndWait((tU8)(extra & 0xff));
      if(retCode != I2C_CODE_OK)
        break;
     }

    //wait until address transmitted and transmit data
    for(i = 0; i < len; i++)
    {
      retCode = i2cPutCharAndWait(*pData);
      if(retCode != I2C_CODE_OK)
        break;
      pData++;
    }
  } while(0);

  return retCode;
}


/******************************************************************************
 *
 * Description:
 *    Waits till slave device returns ACK (after busy period)
 *
 * Params:
 *    [in] addr  - address
 *
 * Returns:
 *    I2C_CODE_OK or I2C_CODE_ERROR
 *
 *****************************************************************************/
tS8
i2cPoll(tU8 addr)
{
  tS8 retCode  = I2C_CODE_OK;
  tU8 status   = 0;
  volatile tU8 deviceReady = FALSE;

  while(deviceReady == FALSE)
  {
    //Generate Start condition
    retCode = i2cStart();

    //Transmit SLA+W
    if(retCode == I2C_CODE_OK)
    {
      //write SLA+W
      retCode = i2cPutChar(addr);
      while(retCode == (tS8)I2C_CODE_BUSY)
        retCode = i2cPutChar(addr);
    }

    if(retCode == I2C_CODE_OK)
    {
      //Wait until SLA+W transmitted
      //Get new status
      status = i2cCheckStatus();

      if(status == 0x18)
      {
        //data transmitted and ACK received
        deviceReady = TRUE;
      }
      else if(status == 0x20)
      {
        //data transmitted and ACK not received
        //send start bit, start again
        deviceReady = FALSE;
      }
      else if( status != 0xf8 )
      {
        //error
        retCode = I2C_CODE_ERROR;
        deviceReady = TRUE;
      }
    }

    //Generate Stop condition
    i2cStop();
  }

  return retCode;
}


/******************************************************************************
 *
 * Description:
 *    Read a specified number of bytes from the I2C network.
 *
 *    Note: No start condition is generated in the beginningis must be
 *          done before calling this function.
 *
 * Params:
 *    [in] addr - address
 *    [in] pBuf - receive buffer
 *    [in] len  - number of bytes to receive
 *
 * Returns:
 *    I2C_CODE_OK or I2C status code
 *
 *****************************************************************************/
tS8
i2cRead(tU8  addr,
        tU8* pBuf,
        tU16 len)
{
  tS8 retCode = 0;
  tU8 status  = 0;
  tU8 i       = 0;

  //write SLA+R
  retCode = i2cPutChar(addr);
  while(retCode == (tS8)I2C_CODE_BUSY)
    retCode = i2cPutChar(addr);

  if(retCode == I2C_CODE_OK )
  {
    //wait until address transmitted and receive data
    for(i = 1; i <= len; i++ )
    {
      //wait until data transmitted
      while(1)
      {
        //get new status
        status = i2cCheckStatus();

        /*
         * SLA+R transmitted, ACK received or
         * SLA+R transmitted, ACK not received
         * data byte received in master mode, ACK transmitted
         */
        if((status == 0x40 ) || (status == 0x48 ) || (status == 0x50 ))
        {
          //data received
          if(i == len)
          {
            //Set generate NACK
            retCode = i2cGetChar(I2C_MODE_ACK1, pBuf);
          }
          else
          {
            retCode = i2cGetChar(I2C_MODE_ACK0, pBuf);
          }

          //Read data
          retCode = i2cGetChar(I2C_MODE_READ, pBuf);
          while(retCode == (tS8)I2C_CODE_EMPTY)
            retCode = i2cGetChar(I2C_MODE_READ, pBuf);
          pBuf++;
          break;
        }

        //no relevant status information
        else if(status != 0xf8 )
        {
          //error
          i = len;
          retCode = I2C_CODE_ERROR;
          break;
        }
      }
    }
  }

  //Generate Stop condition
  i2cStop();

  return retCode;
}


Código: Selecionar todos


#ifndef _I2C_H
#define _I2C_H

/******************************************************************************
 * Includes
 *****************************************************************************/
//#include <GERAL.H>

typedef unsigned char tU8;
typedef unsigned short int tU16;
typedef unsigned int tU32;
typedef char tS8;
typedef short int tS16;
typedef int tS32;
#define TRUE                                    1
#define FALSE                                   0
/******************************************************************************
 * Defines, macros, and typedefs
 *****************************************************************************/

/* I2C Interface 0 */
#define I2C_I2CONSET   (*((volatile unsigned long *) 0xE001C000))
#define I2C_I2STAT     (*((volatile unsigned long *) 0xE001C004))
#define I2C_I2DAT      (*((volatile unsigned long *) 0xE001C008))
#define I2C_I2ADR      (*((volatile unsigned long *) 0xE001C00C))
#define I2C_I2SCLH     (*((volatile unsigned long *) 0xE001C010))
#define I2C_I2SCLL     (*((volatile unsigned long *) 0xE001C014))
#define I2C_I2CONCLR   (*((volatile unsigned long *) 0xE001C018))

#define I2CONSET       (*((volatile unsigned long *) 0xE001C000))
#define I2STAT         (*((volatile unsigned long *) 0xE001C004))
#define I2DAT          (*((volatile unsigned long *) 0xE001C008))
#define I2ADR          (*((volatile unsigned long *) 0xE001C00C))
#define I2SCLH         (*((volatile unsigned long *) 0xE001C010))
#define I2SCLL         (*((volatile unsigned long *) 0xE001C014))
#define I2CONCLR       (*((volatile unsigned long *) 0xE001C018))

//Return codes
#define I2C_CODE_OK     1
#define I2C_CODE_ERROR  0
#define I2C_CODE_EMPTY -1
#define I2C_CODE_BUSY  -2

//Command codes for transmitting extra bytes
#define I2C_EXTRA_NONE 0
#define I2C_EXTRA_BYTE 1
#define I2C_EXTRA_WORD 2


/******************************************************************************
 * Public functions
 *****************************************************************************/

/******************************************************************************
 *
 * Description:
 *    Checks the I2C status.
 *
 *  Returns:
 *      00h Bus error
 *      08h START condition transmitted
 *      10h Repeated START condition transmitted
 *      18h SLA + W transmitted, ACK received
 *      20h SLA + W transmitted, ACK not received
 *      28h Data byte transmitted, ACK received
 *      30h Data byte transmitted, ACK not received
 *      38h Arbitration lost
 *      40h SLA + R transmitted, ACK received
 *      48h SLA + R transmitted, ACK not received
 *      50h Data byte received in master mode, ACK transmitted
 *      58h Data byte received in master mode, ACK not transmitted
 *      60h SLA + W received, ACK transmitted
 *      68h Arbitration lost, SLA + W received, ACK transmitted
 *      70h General call address received, ACK transmitted
 *      78h Arbitration lost, general call addr received, ACK transmitted
 *      80h Data byte received with own SLA, ACK transmitted
 *      88h Data byte received with own SLA, ACK not transmitted
 *      90h Data byte received after general call, ACK transmitted
 *      98h Data byte received after general call, ACK not transmitted
 *      A0h STOP or repeated START condition received in slave mode
 *      A8h SLA + R received, ACK transmitted
 *      B0h Arbitration lost, SLA + R received, ACK transmitted
 *      B8h Data byte transmitted in slave mode, ACK received
 *      C0h Data byte transmitted in slave mode, ACK not received
 *      C8h Last byte transmitted in slave mode, ACK received
 *      F8h No relevant status information, SI=0
 *      FFh Channel error
 *
 *****************************************************************************/
tU8 i2cCheckStatus(void);


/******************************************************************************
 *
 * Description:
 *    Reset and initialize the I2C peripheral.
 *
 * Params:
 *    [in]  i2cFrequency  - frequency on clock signal in Hz (max 400 kHz)
 *
 *****************************************************************************/
void i2cInit(tU32 i2cFrequency);


/******************************************************************************
 *
 * Description:
 *    Generates a start condition on I2C when bus is free.
 *    Master mode will also automatically be entered.
 *
 * Returns:
 *    I2C_CODE_OK or I2C status code
 *
 *****************************************************************************/
tS8 i2cStart(void);


/******************************************************************************
 *
 * Description:
 *    Generates a start condition on I2C when bus is free.
 *    Master mode will also automatically be entered.
 *
 * Returns:
 *    I2C_CODE_OK or I2C status code
 *
 *****************************************************************************/
tS8 i2cRepeatStart(void);


/******************************************************************************
 *
 * Description:
 *    Generates a stop condition in master mode or recovers from an error
 *    condition in slave mode.
 *
 * Returns:
 *    I2C_CODE_OK
 *
 *****************************************************************************/
tS8 i2cStop(void);


/******************************************************************************
 *
 * Description:
 *    Sends a character on the I2C network
 *
 * Params:
 *    [in] data - the character to send
 *
 * Returns:
 *    I2C_CODE_OK   - successful
 *    I2C_CODE_BUSY - data register is not ready -> byte was not sent
 *
 *****************************************************************************/
tS8 i2cPutChar(tU8 data);


/******************************************************************************
 *
 * Description:
 *    Read a character. I2C master mode is used.
 *    This function is also used to prepare if the master shall generate
 *    acknowledge or not acknowledge.
 *
 * Params:
 *    [in]  mode  - I2C_MODE_ACK0 Set ACK=0. Slave sends next byte
 *                  I2C_MODE_ACK1 Set ACK=1. Slave sends last byte
 *                  I2C_MODE_READ Read data from data register
 *    [out] pData - a pointer to where the data shall be saved.
 *
 * Returns:
 *    I2C_CODE_OK    - successful
 *    I2C_CODE_EMPTY - no data is available
 *
 *****************************************************************************/
tS8 i2cGetChar(tU8 mode, tU8* pData);


/******************************************************************************
 *
 * Description:
 *    Wait after transmission of a byte until done
 *
 * Returns:
 *    I2C_CODE_OK    - successful / done
 *    I2C_CODE_ERROR - an error occured
 *
 *****************************************************************************/
tS8 i2cWaitAfterTransmit(void);


/******************************************************************************
 *
 * Description:
 *    Sends a character on the I2C network and wait until done
 *
 * Params:
 *    [in] data - the character to send
 *
 * Returns:
 *    I2C_CODE_OK    - successful
 *    I2C_CODE_BUSY  - data register is not ready -> byte was not sent
 *    I2C_CODE_ERROR - an error occured
 *
 *****************************************************************************/
tS8 i2cPutCharAndWait(tU8 data);


/******************************************************************************
 *
 * Description:
 *    Sends data on the I2C network
 *
 *    Note: No stop condition is generated after the transmission - this must
 *          be done after calling this function.
 *
 * Params:
 *    [in] addr     - address
 *    [in] extraCmd - controls if 0, 1 or 2 extra bytes shall be transmitted
 *                    before data buffer
 *    [in] extra    - byte of word to be transmitted before data buffer
 *    [in] pData    - data to transmit
 *    [in] len      - number of bytes to transmit
 *
 * Returns:
 *    I2C_CODE_OK    - successful
 *    I2C_CODE_ERROR - an error occured
 *
 *****************************************************************************/
tS8 i2cWrite(tU8 addr, tU8 extraCmd, tU16 extra, tU8* pData, tU16 len);


/******************************************************************************
 *
 * Description:
 *    Waits till slave device returns ACK (after busy period)
 *
 * Params:
 *    [in] addr  - address
 *
 * Returns:
 *    I2C_CODE_OK or I2C_CODE_ERROR
 *
 *****************************************************************************/
tS8 i2cPoll(tU8 addr);


/******************************************************************************
 *
 * Description:
 *    Read a specified number of bytes from the I2C network.
 *
 *    Note: No start condition is generated in the beginningis must be
 *          done before calling this function.
 *
 * Params:
 *    [in] addr - address
 *    [in] pBuf - receive buffer
 *    [in] len  - number of bytes to receive
 *
 * Returns:
 *    I2C_CODE_OK or I2C status code
 *
 *****************************************************************************/
tS8 i2cRead(tU8 addr, tU8* pBuf, tU16 len);


#endif


EEPROM.C
Código: Selecionar todos

/*__________________________________________________________________________________
|   EngenhoSUL
|       Blumenau - SC
| __________________________________________________________________________________
|
|       This source code was developed by EngenhoSUL and cannot be copied, in part or
|       in whole, or used, except when legally licensed by Engesul or its distributors.
|
|       Este código é propriedade da EngenhoSUL e não pode ser copiado, em parte ou
|       em todo, ou utilizado, exceto quando for legalmente licenciado pela EngenhoSUL
|       ou por um de seus distribuidores.
| __________________________________________________________________________________
|
|       Product       :   Driver para controle da 24C1025 no utilizando
|                       o controlador I2c do LPC2000
|       Module       :   
|       File       :   EEPROM.C
|       Description :   
|   Author      :   Marcos Aquino
|
|       Created on  :   21/09/2009
|
|       History     :
|
|
| __________________________________________________________________________________
*/
/***********************************************************************************
*   Includes
***********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <intrinsics.h>

//Includes do X
#include "include\DDLX\LPC\DDLX_LPC_devices.h"
#include "include\DDLX\LPC\DDLX_LPC_rtc.h"
#include "include\X\xl.h"

//Meus includes
#include "I2C0.H"
#include "EEPROM.H"
/***********************************************************************************
*   Defines - Local
***********************************************************************************/
#define PAGE_0_INIT                               0x00000000
#define PAGE_1_INIT                               0x00020000
#define PAGE_2_INIT                               0x00040000
#define PAGE_3_INIT                               0x00060000

#define EEPROM_ID                                 0xA0
#define EEPROM_READ                               0x01
#define EEPROM_WRITE                              0x00

#define WRITE_PAGE_SIZE                           128
#define MEMORY_PAGE_SIZE                          0xFFFF
/***********************************************************************************
*   Enumerations - Local
***********************************************************************************/


/***********************************************************************************
*   Structs - Local
***********************************************************************************/


/***********************************************************************************
*   Types - Local
***********************************************************************************/


/***********************************************************************************
*   Variables - Local
***********************************************************************************/
unsigned char busBuffer[150];

Semaphore EEPROM_sem(1);

/***********************************************************************************
*   Functions - Local
***********************************************************************************/
unsigned char directWriteBlock(unsigned int enderecoInicial,unsigned char *pData,
                               unsigned int tamanho);

unsigned char diretecReadBlock(unsigned int enderecoInicial,unsigned char *pData,
                               unsigned int tamanho);

void resolveEndereco(unsigned int endereco,unsigned int *address,unsigned char *ctrl);
/***********************************************************************************
*   Implementations
***********************************************************************************/

/***********************************************************************************
*       Descrição     : Inicialização do módulo
*       Parametros    : (nenhum)
*       Retorno       : (nenhum)
***********************************************************************************/
void EEPROM_init(void){
 
  i2cInit(100000);
}
/***********************************************************************************
*       Descrição     : Escreve um bloco de dados na EEPROM
*       Parametros    : (unsigned long int) número de 32 bits
*                       (unsigned char*) Ponteiro para o buffer que será salvo
*                       na eeprom
*                       (unsigned int) tamanho do bloco que será salvo na eeprom
*       Retorno       : (unsigned char) Resultado da operação de escrita na eeprom
***********************************************************************************/
unsigned char EEPROM_writeBlock(unsigned int address,unsigned char *pData,unsigned int size){
  unsigned int pagina,offSet,toWriteBytes,espacoInicial;
   
  //Fecha a porta pro resto do pessoal
  EEPROM_sem.Wait();
   
    pagina  = address/WRITE_PAGE_SIZE;
    offSet = address - (pagina*WRITE_PAGE_SIZE);   
     
    espacoInicial = WRITE_PAGE_SIZE - offSet;
 
    while(size){
   
      offSet = address - (pagina*WRITE_PAGE_SIZE);   
     
      if(espacoInicial<size){
        toWriteBytes = espacoInicial;         
        espacoInicial = 0xFFFFFFFF;               
      }
      else{
        if(size>WRITE_PAGE_SIZE)
          toWriteBytes = WRITE_PAGE_SIZE;
        else
          toWriteBytes = size;                   
      }
     
      directWriteBlock(address,pData,toWriteBytes);
     
      pData+=toWriteBytes;//Ajusta o ponteiro com a quantidade de bytes que foi enviada ao controlador da memória
     
      pagina++;   
      size-=toWriteBytes;
      address+=toWriteBytes;   
     
      os.SleepFor(5*MSEC);
    }
   
   //Abre a porta para os demais passarem
   EEPROM_sem.Signal();
   
   return 0;
}
/***********************************************************************************
*       Descrição     :  Lê um bloco de dados da EEPROM
*       Parametros    : (unsigned long int) Número de 32 bit referente ao endereço
*                       (unsigned char*) POnteiro para o buffer que receberá os
*                       os dados
*       Retorno       : (unsigned char) Resultado da operação de leitura da eeprom
***********************************************************************************/
unsigned char EEPROM_readBlock(unsigned int address,unsigned char *pData,unsigned int size){
  unsigned int pagina,offSet,toWriteBytes,espacoInicial;
     
  EEPROM_sem.Wait(); 
   
  pagina  = address/WRITE_PAGE_SIZE;
  offSet = address - (pagina*WRITE_PAGE_SIZE); 
 
  espacoInicial = WRITE_PAGE_SIZE - offSet; 
 
  while(size){
   
    offSet = address - (pagina*WRITE_PAGE_SIZE);   
   
    if(espacoInicial<size){
      toWriteBytes = espacoInicial;         
     espacoInicial = 0xFFFFFFFF;
    }
    else{     
      if(size>WRITE_PAGE_SIZE)
        toWriteBytes = WRITE_PAGE_SIZE;
      else
        toWriteBytes = size;     
    }
 
    diretecReadBlock(address,pData,toWriteBytes);
    pData+=toWriteBytes;//Ajusta o ponteiro com a quantidade de bytes que foi enviada ao controlador da memória
   
    pagina++;   
    size-=toWriteBytes;   
    address+=toWriteBytes;   
  }         
   
  //Deixa os outros passaram por aqui
  EEPROM_sem.Signal();     

  return 0;
}
/***********************************************************************************
*       Descrição     : Escreve um bloco de bytes fazendo acesso direto à memória
*       Parametrso    : (unsigned int) enderecoInicial
*                       (unsigned char*) Ponteiro para o buffer que receberá os dados
*                       (unsigned int) tamanho do bloco de dados
*       Retorno       : (unsigned char) Resultado da operação de leitura da eeprom
***********************************************************************************/
unsigned char directWriteBlock(unsigned int enderecoInicial,unsigned char *pData,
                               unsigned int tamanho){
 
  unsigned int address;
  unsigned char mem;
 
  resolveEndereco(enderecoInicial,&address,&mem);   
                                                                   
  i2cWrite(EEPROM_ID | EEPROM_WRITE | mem,I2C_EXTRA_WORD,address,pData,tamanho);
  i2cStop();                                 
 
  return 0;
}
/***********************************************************************************
*       Descrição     : Lê um bloco de bytes fazendo acesso direto à memória
*       Parametros    : (unsigned int) endereço inicial
*                       (unsigned char*) Ponteiro para o buffer que receberá
*                       os dados
*                       (unsigned int) tamanho do bloco de dados
*       Retorno       : (unsigned char) Resultado da operação da leitura da eprom
***********************************************************************************/
unsigned char diretecReadBlock(unsigned int enderecoInicial,unsigned char *pData,
                               unsigned int tamanho){
  unsigned int address;
  unsigned char mem;
 
  resolveEndereco(enderecoInicial,&address,&mem);
                                 
                                 
  i2cWrite(EEPROM_ID | EEPROM_WRITE | mem,I2C_EXTRA_WORD,address,NULL,0);
 
  i2cRepeatStart();
  i2cRead(EEPROM_ID | EEPROM_READ | mem,pData,tamanho);                                 
                                   
  return 0;                                 
}
/***********************************************************************************
*       Descrição     : Resolve um endereço lógico em um endereço físico
*       Parametros    : (unsigned int) endereço
*                       (unsigned int*) endereco
*                       (unsigned char*) byte de controle
*       Retorno       : (nenhum)
***********************************************************************************/
void resolveEndereco(unsigned int endereco,unsigned int *address,unsigned char *ctrl){
 
  *address = endereco &0xFFFF; //Endereço dentro do bloco de 16 bits
  *ctrl  = 0x00;
  *ctrl  = ((endereco>>16)&0x01)<<3;// | ((endereco>>16)&0x03); 
  *ctrl |= (((endereco>>17)&0x03)<<1);
}
/***********************************************************************************
*   End of file
***********************************************************************************/


Código: Selecionar todos
/*__________________________________________________________________________________
|   EngenhoSUL
|       Blumenau - SC
|       www.EngenhoSUL.com  - ped@EngenhoSUL.com
| __________________________________________________________________________________
|
|       This source code was developed by EngenhoSUL and cannot be copied, in part or
|       in whole, or used, except when legally licensed by EngenhoSUL or its distributors.
|
|       Este código é propriedade da EngenhoSUL e não pode ser copiado, em parte ou
|       em todo, ou utilizado, exceto quando for legalmente licenciado pela EngenhoSUL
|       ou por um de seus distribuidores.
| __________________________________________________________________________________
|
|       Product       :   Driver para controle da 24C1025 no utilizando
|                       o controlador I2c do LPC2000
|       Module       :   
|       File       :   EEPROM.C
|       Description :   
|   Author      :   Marcos Aquino
|
|       Created on  :   21/09/2009
|
|       History     :
|
|
| __________________________________________________________________________________
*/
#ifndef EEPROM_H
#define   EEPROM_H
/***********************************************************************************
*   Defines - Global
***********************************************************************************/
#define NUMBER_OF_PAGES                                                 0x04

/***********************************************************************************
*   Enumerations - Global
***********************************************************************************/


/***********************************************************************************
*   Structs - Global
***********************************************************************************/


/***********************************************************************************
*   Types - Global
***********************************************************************************/


/***********************************************************************************
*   Variables - Global
***********************************************************************************/


/***********************************************************************************
*   Functions - Global
***********************************************************************************/
void EEPROM_init(void);
unsigned char EEPROM_writeBlock(unsigned int address,unsigned char *pData,unsigned int size);
unsigned char EEPROM_readBlock(unsigned int address,unsigned char *pData,unsigned int size);
/***********************************************************************************
*   End of file
***********************************************************************************/
#endif //EEPROM_H


Seguinte, isso tudo ai em cima tem:
-Um driver pro controlador I2C do LPC2xxx
-Uma biblioteca para EEPROM que abstraí a escrita em toda a faixa de endereço, permitindo que seja escrito um bloco de tamanho N a partir de qualquer endereço. (lembrando que sem isso, o cara tem que ficar tomando cuidado com a tamanho máximo do buffer e a virada das páginas).

Eu compartilho códigos com os meus amigos.
E aqueles que não falam, ou falaram, mal de mim pra pessoas com quem eu me relacionava sexualmente.(Essas, do sexo F).
ASM51 descanse em paz!
Avatar do usuário
Red Neck Guy
Dword
 
Mensagens: 1968
Registrado em: 12 Out 2006 22:24

Mensagempor proex » 25 Mai 2011 10:34

Aquino, como perder peso agora?









Não contém glutem.
proex
Dword
 
Mensagens: 2101
Registrado em: 11 Out 2006 14:05
Localização: São Paulo

Mensagempor Red Neck Guy » 25 Mai 2011 11:47

proex escreveu:Aquino, como perder peso agora?



1º) Arrume emprego em uma empresa com um ramo de atuação que ao seu ver, seja economicamente atraente.

2º) Comece a elaborar projetos de produtos equivalentes a linha comercializada por essa empresa.

3º) Arrume um sócio investidor para montar uma nova empresa concorrente dessa onde você estará trabalhando.

4º) Levante o máximo de contatos de clientes, obras em andamento e afins antes de pedir demissão e dedicar-se a nova empreitada

5º) (Esse é o ponto chave) Relacione-se com alguma das meninas da empresa e conte sobre seus planos pra ela, com todos os detalhes.

6º) Saia da empresa pra tocar o seu novo negócio.

Pronto, a partir do 6º passo, a incomodação será tão grande que te fará perder peso rapidamente.
ASM51 descanse em paz!
Avatar do usuário
Red Neck Guy
Dword
 
Mensagens: 1968
Registrado em: 12 Out 2006 22:24

Mensagempor fabim » 25 Mai 2011 11:58

Aquino!!
Olhando o seu exemplo do I2C, dei uma estudada nos passos e comparei com aquela parte do UM do 23 que trata da I2C.

O fiadaputa do exemplo que eu tenho tem gambiarra pra funcar especificamente com aquele meledito do chippu..
Foi só mudar e deixar parecido com o seu, e pumba, funcionou na hora!!
O problema não estava no hw propriamente dito. eu estava lendo as posições do buffer erradas !! hehehe
E outra coisa que eu não tinha nem batatinha observado.

Esse fuck MCP3426 devolve o resultado signed!!! hehehe Por isso eu achei que o valor tava sempre errado!!

Valew pela ajuda mano !!! Muito obrigado, tu quebraste um galhão!!


Nestas horas bate a fraqueza, e sinto 1/(101.00*10^33) de saudade do pic.. Era tão mais simples...

Froid
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor Red Neck Guy » 25 Mai 2011 12:10

fabim escreveu:Aquino!!
Olhando o seu exemplo do I2C, dei uma estudada nos passos e comparei com aquela parte do UM do 23 que trata da I2C.

O fiadaputa do exemplo que eu tenho tem gambiarra pra funcar especificamente com aquele meledito do chippu..
Foi só mudar e deixar parecido com o seu, e pumba, funcionou na hora!!
O problema não estava no hw propriamente dito. eu estava lendo as posições do buffer erradas !! hehehe
E outra coisa que eu não tinha nem batatinha observado.

Esse fuck MCP3426 devolve o resultado signed!!! hehehe Por isso eu achei que o valor tava sempre errado!!

Valew pela ajuda mano !!! Muito obrigado, tu quebraste um galhão!!


Nestas horas bate a fraqueza, e sinto 1/(101.00*10^33) de saudade do pic.. Era tão mais simples...

Froid


Cara, eu vim sem óculos hoje....
Levei um susto com essa frase:
" Nestas horas bate a fraqueza, e sinto 1/(101.00*10^33) de saudade do pic.. "

Flw
ASM51 descanse em paz!
Avatar do usuário
Red Neck Guy
Dword
 
Mensagens: 1968
Registrado em: 12 Out 2006 22:24


Voltar para ARM

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x