Problema com gravação sequêncial em uma eeprom externa.

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Mensagempor Sergio38br » 20 Jan 2010 16:00

regis qual a freq. do clock?? ta com hspll?

[ ]'s
Sergio
Avatar do usuário
Sergio38br
Word
 
Mensagens: 759
Registrado em: 22 Nov 2007 13:39
Localização: São Paulo - SP

Mensagempor barboza » 20 Jan 2010 16:09

Djalma Toledo Rodrigues escreveu:Resumindo:

É numa hora dessa que se vê a falta que faz o ASM

DJ


Quando não se sabe o que esta acontecendo ou se tem o controle do que esta fazendo, não importa se é ASM, C, Java, lua, .........

Bugs existem...... ainda bem.
Colchas de retalho tb.......
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor RobL » 20 Jan 2010 16:11

Verifique se seu problema é rollover, pois você fala do tamanho da página em 127 e ela é de 128 bytes.
A primeira página vai do endereço 0 a 127d = 128 bytes.
A próxima página a gravar tem o endereço inicial em 128d (+ 128bytes), incluindo o endereço 128d, como sendo o primeiro byte.
Se seu programa iniciar a segunda página no endereço 127 ele vai gravar tudo outra vez de zero a 127 e não sai disso.
Verifique se é isso.

Nota: Seu programa precisa ser capaz de pegar a quantidade de bytes a gravar dividir por 128 e a sobra gravar como página também, iniciando em um endereço múltiplo de 128. Para página parcial, a sobra que não completa 128bytes, o buffer dessa memo só gravará os dados entrados na página. Não altera os demais, ou seja, vai gravar uma página também.
Para ficar mais claro, não existe gravação de um ou poucos bytes nessas eeproms externas, somente páginas. Quando se grava um byte, grava-se uma página.

Não esquecer também que a cada página os bits do byte de mais alta ordem, do endereço (word) tem que ser enviados. Os mais baixos até 127d incrementa automaticamente dentro da eeprom. A cada página um novo endereço da página (byte MSB primeiro byte LSB depois).

Quanto aos seus bytes, se estão em ASCII e de fato for necessário mudar para bin, pode até fazer um pgm interno em run time no micro antes de mandar para a eeprom externa.

Caro DJ.
Qualquer IDE em C gera também um assembly do que foi feito. É só debugar em asm.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor vtrx » 20 Jan 2010 21:31

sei lá, sou contra esse negocio de avatar estilo baratinha, que deixa a gente com uma coisa ruim, com vontade de dar ticão na tela do pc.

Tambem não gosto dessa baratinha besta...
após isto esta tentando mandar um start + comando de gravação??

Tem que enviar controle de GRAVAÇÃO para tentar resposta se o buffer está ocupado,ta fazendo isto?
Regis,me manda o arquivo texto explicando que bytes voce usa,serve colar os byte neste formato:
//SDCard icon

const char logo6[]={

0x0,0x0,

0x7,0x3C,

0x8,0x4,

0x15,0x14,

0x15,0x14,

0x15,0x14,

0x10,0x4,

0x10,0x4,

0x10,0x4,

0x10,0x4,

0x10,0x4,

0x1F,0x3C,

};

e gerar um arquivo .Hex com esse bytes?
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Mensagempor barboza » 20 Jan 2010 22:02

Cara, estive olhando seu codigo e acho que pode testar algo assim:
Como já foi dito a pagina tem 128 bytes, de 0 a 127.
Outro detalhe importante, você não inicializa seu contador e com isso pode ter problemas.

Código: Selecionar todos
 void GravarImagemEEprom(unsigned int end, char pagina)
{   int x=0, TamanhoImagem;
   char BufferEEprom = 0, CrtByte;
   
   
   if (pagina){            //icone=1
         TamanhoImagem = 24;    //icone 24 bytes
      //   Inicio = 0;         //Inicio da primeira imagem
         CrtByte = 0XA8;        //Pagina 1
                 
      }
    else{                  //Logo=0
         TamanhoImagem = 2560;   //Logo 2560 bytes   
      //   Inicio = 100;      //Inicio da primeira imagem
         CrtByte = 0XA0;        //Pagina 0
      }
   
   

   rw_start_eeprom(end, CrtByte);   //Envia Endereço e Byte de controle
   
   for (x=0; x < TamanhoImagem; x++)
      {
      if (++BufferEEprom>127)      //Se o buffer interno da EEprom ficou cheio
         {   
         i2c_stop();         //Avisa EEprom para iniciar a gravação
         BufferEEprom = 0;    //reinicia contador
         while(1)         //Aguarda ACK da Memória
            {
            i2c_start();      //Envia Start
            //i2c_repStart();     
            i2c_waitForIdle();   //Aguarda condição de Idle
            i2c_write(CrtByte);   //Envia Byte de controle
            i2c_waitForIdle();   //Aguarda condição de Idle
            if (!ACKSTAT) break;   //Se receber acknowledge sai do loop
            i2c_stop();         //Envia stop
            i2c_waitForIdle();   //Aguarda condição de Idle
           
            }
      i2c_repStart();   
      rw_start_eeprom(end, CrtByte);   //Envia Endereço e Byte de controle
      //i2c_write(CrtByte);
         }
      else
         {
         i2c_write(logo1[x]);   //Aqui define qual array vai ser enviado
         end++;   
         }
      }
     
   i2c_stop();
}
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor ze » 21 Jan 2010 10:32

se for só questão de converter arquivos...

Se o amigo é adepto da simplicidade e não muito fã dos alternativos e já tem os binários das telas, uma outra opção que sugiro é o bin2hex.exe que deve ter + que 20 anos e já não tem mais proprietário (se é que teve). Tem até fonte. Tem também o hex2bin.exe. Roda no prompt do dos (se souber o que é). google "bin2.hex.exe" e"hex2bin.exe"

½ of topic:
Tive um probl de compatibilidade com o .hex gerado pelo keil prum arm LPC no proteus. Resolvi “forjando” o .hex com o bat do DOS: hex2bin %1.hex e bin2hex %1.bin
abç
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Mensagempor regiscruz » 21 Jan 2010 16:20

Oi Sergio, sim esta em HSPLL meu Fosc é de 24Mhz mas calculei minha I2C para 400Khz, SSPADD = 0x0E.

RobL escreveu:Verifique se seu problema é rollover, pois você fala do tamanho da página em 127 e ela é de 128 bytes. ...
...Seu programa precisa ser capaz de pegar a quantidade de bytes a gravar dividir por 128 e a sobra gravar como página também....
...não existe gravação de um ou poucos bytes nessas eeproms externas, somente páginas. Quando se grava um byte, grava-se uma página.

Rob, obrigado pelas dicas, estas estavam passando batido mesmo. Isto não estava previsto no meu código, assim que eu conseguir gravar uma tela inteira (segundo meus cálculos serão 20 paginas) eu vou começar a trabalhar nisto.

vtrx escreveu:...Regis,me manda o arquivo texto explicando que bytes voce usa,serve colar os byte neste formato:

Suponho que você esteja se referindo ao arquivo com os arrays das telas de 240x64, eles são um pouco longos, acho que não vale a pena coloca-los em forma de código aqui pois vai dificultar a navegação afinal são 2560 bytes cada tela...rs... mas de qualquer forma eu coloquei ele aqui é só baixar.


barboza escreveu: Cara, estive olhando seu código e acho que pode testar algo assim: ...

Barboza, obrigado por analisar meu código.
Eu testei ele e funcionou parcialmente, vou explicar (me corrija se eu estiver errado)...
Minha primeira tela de 240x64 vai ser gravada na posição 0x0A00, as posições anteriores serão reservadas para uso geral. Bom se cada tela vai ter um total de 2560 bytes decimal ou 0xA00, isto significa que minha primeira tela vai acabar na posição 0x13FF, se cada pagina tem 128 bytes então cada tela terá 20 paginas (2560/128=20) ou seja, não teremos sobra na ultima pagina e consequentemente a próxima tela poderá começar na posição 0x1400 e asim vai até terminar o Bloco 0 de memória.

Quanto coloquei o seu código para gravar a tela logo1 ele começou a gravação na posição correta (0x0A00) mas terminou algumas posições antes mais especificamente na posição 0x137F ou seja 128 posições antes do esperado, coincidentemente uma pagina de memória.
Não cheguei a analisar toda a integridade dos dados mas percebi que a cada 127 posições apareceram os valores 0xFF, este é outro problema pois estes valores não existem nas minhas telas, o valor máximo é 0x3F, na verdade isto indica que estas posições não foram alteradas (tomei o cuidado de formatar a eeprom antes de fazer o teste). No screenshot abaixo aparece o ultimo 0xFF na posição 0x136C.

Imagem


Acho que o problema esta no loop que conta a pagina, vou fazer alguns testes.



lellis escreveu:Se o amigo é adepto da simplicidade e não muito fã dos alternativos e já tem os binários das telas, uma outra opção que sugiro é o bin2hex.exe que deve ter + que 20 anos e já não tem mais proprietário (se é que teve). Tem até fonte. Tem também o hex2bin.exe. Roda no prompt do dos (se souber o que é). google "bin2.hex.exe" e"hex2bin.exe"

Valeu pela dica Lellis, ta na mira!!!
Existem três leis que governam o mundo...
A Lei da gravidade, a Lei do mais forte e a lei de Murphy.
Avatar do usuário
regiscruz
Byte
 
Mensagens: 154
Registrado em: 21 Out 2006 10:22
Localização: Uberaba - MG

Mensagempor barboza » 21 Jan 2010 16:46

regiscruz escreveu:Acho que o problema esta no loop que conta a pagina, vou fazer alguns testes.



Troca para essa linha.
Problemas de precedências....

Código: Selecionar todos
if (BufferEEprom++>127)      //Se o buffer interno da EEprom ficou cheio
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor regiscruz » 21 Jan 2010 17:25

barboza escreveu:Troca para essa linha.
Problemas de precedências....


Hehehe!!! Agora foi...
Fiz a alteração que vc falou e adicionei mais alguma coisa, a perda de dados foi resolvida com a subtração por 1 da variável x, me veio essa luz mas ainda não entendi porque funcionou...rs...
Vou confirmar para ter certeza que todos os dados estão na eeprom.

Código: Selecionar todos
 void GravarImagemEEprom(unsigned int end, char pagina)
{   int x=0, TamanhoImagem;
   char BufferEEprom = 0, CrtByte;
   
   
   if (pagina){            //icone=1
         TamanhoImagem = 24;      //icone 24 bytes
      //   Inicio = 0;         //Inicio da primeira imagem
         CrtByte = 0XA8;      //Bloco 1
                 
      }
    else{               //Logo=0
         TamanhoImagem = 2560;   //Logo 2560 bytes   
      //   Inicio = 100;      //Inicio da primeira imagem
         CrtByte = 0XA0;           //Bloco 0
      }
   
   

   rw_start_eeprom(end, CrtByte);   //Envia Endereço e Byte de controle
   
   for (x=0; x < TamanhoImagem; x++)
      {
      if (BufferEEprom++>=128)      //Se o buffer interno da EEprom ficou cheio
         {   
         i2c_stop();               //Avisa EEprom para iniciar a gravação
         
         while(1)               //Aguarda ACK da Memória
            {
            i2c_start();         //Envia Start
            //i2c_repStart();     
            i2c_waitForIdle();     //Aguarda condição de Idle
            i2c_write(CrtByte);      //Envia Byte de controle
            i2c_waitForIdle();      //Aguarda condição de Idle
            if (!ACKSTAT) break;      //Se receber acknowledge sai do loop
            i2c_stop();            //Envia stop
            i2c_waitForIdle();      //Aguarda condição de Idle
           
            }
      BufferEEprom = 0;         //reinicia contador
      i2c_repStart();   
      x=x-1;
      rw_start_eeprom(end, CrtByte);//Envia Endereço e Byte de controle
      //i2c_write(CrtByte);
         }
      else
         {
         i2c_write(logo1[x]);      //Aqui define qual array vai ser enviado
         end++;   
         }
      }
     
   i2c_stop();
}
Existem três leis que governam o mundo...
A Lei da gravidade, a Lei do mais forte e a lei de Murphy.
Avatar do usuário
regiscruz
Byte
 
Mensagens: 154
Registrado em: 21 Out 2006 10:22
Localização: Uberaba - MG

Mensagempor barboza » 21 Jan 2010 18:47

Seus dados não devem estar certos. O primeiro byte de cada pagina deve estar errada.

Retira a subtração do x e mantenha a comparação com 127 que você trocou por 128.
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor barboza » 21 Jan 2010 19:32

barboza escreveu:Seus dados não devem estar certos. O primeiro byte de cada pagina deve estar errada.

Retira a subtração do x e mantenha a comparação com 127 que você trocou por 128.


Pode deixar essa linha assim. Não vi que colocou o sinal de = tb.
>127 é o mesmo que >= 128.


Agora vai:

Código: Selecionar todos
 void GravarImagemEEprom(unsigned int end, char pagina)
{   int x=0, TamanhoImagem;
   char CrtByte;
   
   
   if (pagina){            //icone=1
         TamanhoImagem = 24;      //icone 24 bytes
      //   Inicio = 0;         //Inicio da primeira imagem
         CrtByte = 0XA8;      //Bloco 1
                 
      }
    else{               //Logo=0
         TamanhoImagem = 2560;   //Logo 2560 bytes   
      //   Inicio = 100;      //Inicio da primeira imagem
         CrtByte = 0XA0;           //Bloco 0
      }
   
   

   rw_start_eeprom(end, CrtByte);   //Envia Endereço e Byte de controle
   
   for (x=0; x < TamanhoImagem; x++)
      {

         i2c_write(logo1[x]);      //Aqui define qual array vai ser enviado

      if (!(++end & 0x007F))      //Se o buffer interno da EEprom ficou cheio
         {   
         i2c_stop();               //Avisa EEprom para iniciar a gravação
         
         while(1)               //Aguarda ACK da Memória
            {
            i2c_start();         //Envia Start
            //i2c_repStart();     
            i2c_waitForIdle();     //Aguarda condição de Idle
            i2c_write(CrtByte);      //Envia Byte de controle
            i2c_waitForIdle();      //Aguarda condição de Idle
            if (!ACKSTAT) break;      //Se receber acknowledge sai do loop
            i2c_stop();            //Envia stop
            i2c_waitForIdle();      //Aguarda condição de Idle
           
            }
      i2c_repStart();   
      rw_start_eeprom(end, CrtByte);//Envia Endereço e Byte de controle
         }
      }
     
   i2c_stop();
}



Esta é outra opção, pois a sua original, se o endereço inicial for diferente de xx00, terá problemas:

Código: Selecionar todos
void GravarEEprom(unsigned int end_eeprom, char *end_ram, unsigned int size, char controle)
{

   while (size--)
   {
      rw_start_eeprom(end_eeprom, controle);      //Envia Endereço e Byte de controle
      
      i2c_write(*end_ram++);            //Aqui define qual array vai ser enviado

      if (!(++end_eeprom & 0x007F))         //Se o buffer interno da EEprom ficou cheio
      {
         i2c_stop();            //Avisa EEprom para iniciar a gravação

         while(1)            //Aguarda ACK da Memória
         {
            i2c_start();         //Envia Start
            i2c_waitForIdle();      //Aguarda condição de Idle
            i2c_write(controle);      //Envia Byte de controle
            i2c_waitForIdle();      //Aguarda condição de Idle
            if (!ACKSTAT)
            {
               break;         //Se receber acknowledge sai do loop
            }
            i2c_stop();         //Envia stop
            i2c_waitForIdle();      //Aguarda condição de Idle
         }
      }
   }
   i2c_stop();         //Envia stop
}


Para gravar os ícones:

Código: Selecionar todos
   GravarEEprom(0x0A00, &logo, 24, 0xA8);


Para gravar a tela:

Código: Selecionar todos
   GravarEEprom(0x0A00, &logo, 2560, 0xA0);



Só não entendi o que é este byte de controle que você tem ai.

CrtByte
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor regiscruz » 21 Jan 2010 20:29

barboza escreveu:Seus dados não devem estar certos. O primeiro byte de cada pagina deve estar errada.

Retira a subtração do x e mantenha a comparação com 127 que você trocou por 128.


Poxa barboza, agora você me deixou com a pulga atrás da orelha, dei uma visualizada no que foi gravado na eeprom e aparentemente esta tudo certo. Quero testar estas outras duas versões, parecem mais eficientes especialmente esta última, mas antes vou jogar estas informações da eeprom para o display para vermos o que esta acontecendo com mais clareza.
Me da algumas horas que ja te falo.

barboza escreveu:Só não entendi o que é este byte de controle que você tem ai.

CrtByte


CrtByte é o byte que uso para definir o endereço, Bloco e operação de escrita ou leitura na eeprom, esta aqui na pagina 7 figura 5-1.

Neste caso estou usando CrtByte=0XA0, minha eeprom esta configurada para responder ao endereço 0 e as informaçòes estão sendo guardadas no Bloco 0.
Existem três leis que governam o mundo...
A Lei da gravidade, a Lei do mais forte e a lei de Murphy.
Avatar do usuário
regiscruz
Byte
 
Mensagens: 154
Registrado em: 21 Out 2006 10:22
Localização: Uberaba - MG

Mensagempor barboza » 21 Jan 2010 22:08

regiscruz escreveu:
Poxa barboza, agora você me deixou com a pulga atrás da orelha, dei uma visualizada no que foi gravado na eeprom e aparentemente esta tudo certo. Quero testar estas outras duas versões, parecem mais eficientes especialmente esta última, mas antes vou jogar estas informações da eeprom para o display para vermos o que esta acontecendo com mais clareza.
Me da algumas horas que ja te falo.




Deve estar certo mesmo. O problema era o sinal que igual que não vi.

regiscruz escreveu:
Neste caso estou usando CrtByte=0XA0, minha eeprom esta configurada para responder ao endereço 0 e as informaçòes estão sendo guardadas no Bloco 0.




Neste caso você pode retirar isso dos parametros da função e deixar como uma constante.

Versão editada e corrigida:

Código: Selecionar todos
void GravarEEprom(unsigned int end_eeprom, char *end_ram, unsigned int size)
{

   rw_start_eeprom(end_eeprom, CONST_A0);      //Envia Endereço e Byte de controle
     
   while (size--)
   {
      i2c_write(*end_ram++);            //Aqui define qual array vai ser enviado

      if (!(++end_eeprom & 0x007F))         //Se o buffer interno da EEprom ficou cheio
      {
         i2c_stop();            //Avisa EEprom para iniciar a gravação

         while(1)            //Aguarda ACK da Memória
         {
            i2c_start();         //Envia Start
            i2c_waitForIdle();      //Aguarda condição de Idle
            i2c_write(controle);      //Envia Byte de controle
            i2c_waitForIdle();      //Aguarda condição de Idle
            if (!ACKSTAT)
            {
               break;         //Se receber acknowledge sai do loop
            }
            i2c_stop();         //Envia stop
            i2c_waitForIdle();      //Aguarda condição de Idle
         }
         rw_start_eeprom(end_eeprom, CONST_A0);      //Envia Endereço e Byte de controle
      }
   }
   i2c_stop();         //Envia stop
}
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor regiscruz » 22 Jan 2010 01:50

100%!!! Programei o microcontrolador para ler o conteúdo da eeprom e mostrar a figura no display, todos os bits estão no lugar certo tanto na memória quanto no display.
Primeiro fiz aquela confirmação da mensagem anterior e tirei a pulda da orelha...rs...
Depois peguei esta ultima versão que você disponibilizou e funcionou de primeira. :shock:

Infelizmente não posso deixar o CrtByte como sendo uma constante pois preciso escrever tanto no Bloco 0 (0x00000 ~ 0x0FFFF) quanto no Bloco 1 (0x10000 ~ 0x1FFFF) da memória. E para mudar o Bloco eu preciso trocar o bit 3 do byte de controle.
Mas isso é o de menos, é muito simples de resolver além do mais não foi problema usar como constante durante o testes.
Agora eu preciso confirmar com você se estou chamando a função da forma correta pois recebi esse alerta do compilador na linha da chamada da função:
Código: Selecionar todos
Warning [359] D:\Técnico\Projetos\Wifi_Radio\Gravação EEProm\main.c; 516.30 illegal conversion between pointer types

Esta foi a forma como chamei a sua função:
Código: Selecionar todos
GravarEEprom(0xA00, &logo1[0], 2560);

Na sua função a única coisa que fiz foi adicionar a constante do byte de controle.

Obrigado
Existem três leis que governam o mundo...
A Lei da gravidade, a Lei do mais forte e a lei de Murphy.
Avatar do usuário
regiscruz
Byte
 
Mensagens: 154
Registrado em: 21 Out 2006 10:22
Localização: Uberaba - MG

Mensagempor barboza » 22 Jan 2010 07:05

Isso:

Código: Selecionar todos
GravarEEprom(0xA00, &logo1[0], 2560);


É o mesmo que isso.

Código: Selecionar todos
GravarEEprom(0xA00, &logo1, 2560);


Como esta declarada a variável "logo1"?

Talvez ela não seja do tipo char como esta aguardando a função.
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

AnteriorPróximo

Voltar para PIC

Quem está online

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

cron

x