Communication entre microcontrolleur et carte CompactFlash lecture erronee?

Résolu
develdelphi Messages postés 97 Date d'inscription mercredi 7 avril 2004 Statut Membre Dernière intervention 20 avril 2009 - 10 mars 2007 à 19:43
develdelphi Messages postés 97 Date d'inscription mercredi 7 avril 2004 Statut Membre Dernière intervention 20 avril 2009 - 13 mars 2007 à 22:27
Bonjour,

Voila j'ai un programme qui gere une communication avec un microcontrolleur de la famille
Atmel AT89C51SNDC1 ( a base de lecteur mp3) et une carte CompactFlash, ces deux elements sont presents dans mon PCB qui est un systeme qui gere des signaux audio en provenances de micro et switch ses signaux audio en sortie en fonction des priorites.
Le systeme communique avec la CF en bus de 16 bits physique mais j'ai du configurer mon microcontrolleur de maniere a ce qu'il travaille en 8 bits de donnees car la librairie que j'utilise et fait pour le 8 bits et la CF est en mode True Ide Mode.

Mon probleme est le suivant, je lis bien du debut du secteur d'une adresse de la carteCompactFlash mais je ne lis que 1 byte sur 2,  c'est comme ci les données étaient tronquées.

Car l'affichage du contenu de l'adresse (ici 6300) secteur physique de ma CF par Winhex
me donne se resultat:

C7344AE113FF329C367295
C3E0401D80465C37A7D3FF83D7E2EC4DACE4

FDF331C111299BC17BF3A2727276014<wbr>422F5DCE8499F368E93019CA41943B4<wbr>B3BC7</wbr></wbr>

968652FC1BBF403E69E6BF2CC458D40<wbr>D9D04C04164E1187D8705836056951B<wbr>D61D3</wbr></wbr>

8B4878A4DC09F878117BA6C0090745A<wbr>95AF3FFB492D44567BDE42484C0E989<wbr>ABAC</wbr></wbr>

9CF36526C188ED764D9936ED56F90A9<wbr>DB1BE41AF684968B87CB853E598147B<wbr>E6A0</wbr></wbr>

D821DE51BA90D257BDFF4E81FBE9460<wbr>CBCE26723AA2D530A5AB889996724FB<wbr>FCD</wbr></wbr>

20F77D575C57E40AC06285193922908<wbr>66971FDBF248B94C28295A2F2EDB508<wbr>D9079C</wbr></wbr>

85B64C5FA6188CB5B014DA1BCDA2D75<wbr>9F596D1A3BB7C3AFE80E5728F063C5B<wbr>E0A</wbr></wbr>

E8F89FE8C7F562AA42F90A1CEE85A51<wbr>35A2EDB4F7353E9A96214E788C42851<wbr>DC71</wbr></wbr>

643310361A74BB38AD1308E2E9650B8<wbr>E0A978D598009F5C8DC48692774B940<wbr>E29E36</wbr></wbr>

5B21A33B1B7BC056E488D5047C9B9A2<wbr>DB1FC79D30C526AD08A3A68919C1A63<wbr>33D8</wbr></wbr>

B3C0873816CFC1B8E7CAE8BE1B3C509<wbr>D9DF0A30C87BB5884DDC787BAEC3286<wbr>BB</wbr></wbr>

C926BD658BBB98303B4C8A8C9A11875<wbr>4341A66FC60120B9524585FC9204F61<wbr>5AF50</wbr></wbr>

CD5DACDA86F9AF0E6760899FF2E016E<wbr>B29DC54DF7699E58E5F05B70C0C92F7<wbr>C2E</wbr></wbr>

59B344FE32ECAA234DB68DAF75EFA9F<wbr>65F352E324826F63E23658B5297DA58<wbr>CC6B</wbr></wbr>

EDCC6A1FBC4095C57CE08F8FFA55</gras>

Alors que mon programme pour l'affichage du contenu de la CF a cette meme addresse:

me renvoi le résultat de la capture Hyperterminal suivant:

 004AE10000329C007200C300400080005C00A700FF00D700EC00AC00FD00
 310011009B007B00A20072001002200DC004900360093009C001900B400BC0068002F00
BB003009E00F20045004000D0004004E008700700036006900BD00D3004800A4009007800
7B00C000700A900F300B400D4006700E4008400E900AB009C006500C100ED004D003600
5600A00B1004100680068007C00530098007B00A0002100510090005700FF008100E900
C00E20023002D00A00B80099002400FC00F00D500C5004000600510092008009700DB00
48004C0029002F00DB008D0079005B00C5006100CB00100A100DA00750059001A00B700
AF00E0028006300BE00E8009F00C70062004200A00EE00A5005A00DB007300E9006200
E700C4005100710033003600740038001300E20065008E0097005900900C80048002700B900
E200360021003B007B00560088004009B002D00FC00D3005200D0003A0091001A003300
B30087001600C100E700E8001B0050009D00A30087005800DD008700EC008600C900BD00
8B0098003B008A009A008700340066006000B0024005F0020006100F500D500CD006F00
F000760099002E006E009D004D0069005800F0007000C9007C00590044003200AA004D00
8D007500A9005F002E004800F60023008B00970058006B00CC001F004000C500E0005E00
FA005500C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700
C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700
C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700
C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700
C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700
C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700
C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700
C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700
C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700
C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700
C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700
C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700
C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700
C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700
C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700C700
C700C700C700

Voici mon code de test de communication avec la CF:

void CF_operations2 (void)  //testali050307

{

//   cf_read_open (0,1);

printf ("ide_status avant cf_read_open() CF_operations: %X\n\r",ide_status);
      if (cf_read_open (6300,1))
  {
  printf ("\ncf_read_open is done\n");
  printf ("ide_status avant cf_read_byte() CF_operations: %X\n\r",ide_status);

  printf ("\n now call to cf_read_byte() and diplay of data\n");
  getchar();
  //for(rrd = 0; rrd < 200; rrd++);    //delay

   printf ("\n valeur de gl_ptr_mem avanr read byte (0): \n",gl_ptr_mem); ///testali0303<wbr>07

      for(rd=0;rd<512;rd++)
  {

       testrd[rd]=cf_read_byte();  <wbr>         //APPELAPPEL
        // for(rrd = 0; rrd < 10; rrd++);
  }</wbr></wbr>

  for(rrd = 0; rrd < 512; rrd++)
  {
  // tstok=testrd[rrd];   ///test
  // tstok[rrd]=testrd[rrd];   ///test
     printf("%X",testrd[rrd]);   <wbr>         //test AFFICHAGE OK
  // printf("%X",tstok);  ///test
  //getch();  //testali230207
  // for(rd = 0; rd < 100; rd++);
 // printf("%X",tstok[rrd]);  ///test
  }
       
        data_lu = cf_read_byte();            //APPEL APRES BOUCLE
        printf("\nDATA LU = %X\n",data_lu);  //re
        getchar();
  }
    else {printf ("\ncf_read_open is not done\n");}

    printf("ide_status fin CF_operations: %X\n\r",ide_status); //test</wbr>

}

 
Pour la communication avec la CF j'ai utulise la librairie d'Atmel que j'ai implemente dans le programme, je sais pas si je l'ai bien implementer mais, comme vous l'avez vu ci-dessus, je communique réellement avec la CF car j'ai pu lire à une adresse secteur de la CF.
 
Je pense que l'erreur provient du fait de l'insertion de 2 carateres aleatoires a la suite de la valeur affichee par exemple lorsque je faits un printf en hexadecimal (%X)  pour voir l'etat du registre de la carte CF on voit la presence de deux valeurs hexadecimals aleatoires derriere les valeurs reellement lues, comme vous avez pu constater dans la capture de mon programme ci-dessus (ici c'est "00"):

A quoi est-ce du la presence de ces deux caracteres hexadecimal est-ce un probleme de formatage de donnees lie a ma programmation en C ou est-ce que c'est un probleme lie a la communication entre le micro et la carte CF qui ferait apparaitre des signaux aleatoires, bits de parite, bits stop ou autres?

Ou bien le probleme vient de la CompactFlash de sa configuration est-elle reelement en True Ide Mode ?

 Merci de m'aider.

4 réponses

develdelphi Messages postés 97 Date d'inscription mercredi 7 avril 2004 Statut Membre Dernière intervention 20 avril 2009
13 mars 2007 à 22:27
Oui, mais en fait j'y suis arrive en passant le unsigned char a un int puis j'affichais avec le printf le
int et la il n'y a plus les deux caracteres parasites qui apparaissaient pour les chars.

Il s'agissait sans doute d'un probleme lie au printf ou au compilateur mais bref le probleme d'origine n'est toujours pas resoud. Malgres cette modif, la lecture des 512 bytes d'une adresse d'un secteur de la CF ne faite apparaitre que un byte sur deux. C'est comme ci la lecture se fesait en 16 bits?

La librairie que j'utilise est en 8 bits mais au niveau hardware je suis en 16 bits mais bien sur mon microcontrolleur Atmel (AT89C51SNDC1) me permet de passer en mode 8 bits par configuration du registre AUXR.
Du cote de la carte CF, j'envoi une commande pour etre aussi en 8 bits :

Ide_set_feature(IDE_ENABLE_8_BIT_TRANSFERT);
Ide_send_command(ATA_CMD_SET_FEATURES);          /* Set Features */ 

Je pense plutot qu'il s'agit d'un probleme de software mais sinon ce serait du cote de la CompactFlash, le True Ide Mode qui ne s'active pas?

Sauriez vous m'aider ?

Merci
3
goast_tu Messages postés 212 Date d'inscription dimanche 3 avril 2005 Statut Membre Dernière intervention 28 mai 2011 2
11 mars 2007 à 21:57
eh ben desolé je vois rien qui cloche. Mais je vois aucune declaration
de variables. et ca serai bien d'avoir les entets de certaines fonctions

<hr size="2" width="100%" />Trafic web gratuit!!!
0
develdelphi Messages postés 97 Date d'inscription mercredi 7 avril 2004 Statut Membre Dernière intervention 20 avril 2009
12 mars 2007 à 03:19
Bonjour Kill Bill,


Merci. En fait ce qui cloche, c'est uniquement le fait que un seul byte sur deux est que lu/affichée.

voici plus de détails, lors de l'init de la CF et les declarations :

/*______________ INIT DE LA CF POUR LE 8 BITS__________________________________*/


   Ide_set_feature(IDE_ENABLE_8_BIT_TRANSFERT);

   Ide_send_command(ATA_CMD_SET_FEATURES);          /* Set Features */

/*______________ D E C L A R A T I O N S __________________________________*/


extern  data    Byte   
gl_mem_tick;             
/* memory tick counter    */

extern  bdata   bit    
gl_mem_failure;          
/* memory hardware failure*/

extern  data    Uint32 
gl_ptr_mem;              
/* memory data pointer    */


xdata          
Uint32 
cf_mem_size;             
/* Card size in sector    */


/* IDE registers */

/*                         
name                       
|  RD# 0       |   WR#
0   | */

extern  xdata Byte volatile
ide_data;          
/*  | RD data        | WR
data     | */

extern  xdata Byte volatile
ide_error;         
/*  | Error         
| Features    | */

extern  xdata Byte volatile ide_sector_count;   /*  | Sect. count    | Sect. count | */

extern  xdata Byte volatile ide_sector_number;  /*  |
Sect. No       | Sect.
No    | */

extern  xdata Byte volatile ide_cylinder_low;   /* 
| Cyl. Low       | Cyl.
Low    | */

extern  xdata Byte volatile ide_cylinder_high;  /*  |
Cyl. High      | Cyl. High   | */

extern  xdata Byte volatile
ide_drive_head;     /*  |
Drive/Head     | Drive/Head  | */

extern  xdata Byte volatile
ide_status;         /*  |
Status         |
Command     | */

extern  xdata Byte volatile
ide_alt_status;     /*  | Alt
status     | Device Ctrl | */


code Uint32 cf_block_size = Cf_block_size();


unsigned int lecture_cond = 0x00;

unsigned int ide_status1 = 0x00;

unsigned int IDE_BSY1  = 0x00;

unsigned int IDE_DRDY1 = 0x00;

unsigned int ide_data1;

unsigned int nb_sector1;

unsigned int sect1;

unsigned int cf_rd_byte;

unsigned int BSY;

unsigned int DATA;

voici la fonction cf_read_byte():

Byte cf_read_byte(void)

{

  printf("ide_status debut cf_read_byte de C_Flash: %X\n\r",ide_status);

   getchar();


 if ((Card_detect() == KO) )

  {

    gl_mem_failure = TRUE;

    return 0xFF;

  } 


  while (Ide_notbsy() ==
KO)                 
/* Wait for bsy = 0 */

  {

    printf ("le registre est busy \n");

    getchar();

    if ((Card_detect() == KO) )

    {

      gl_mem_failure = TRUE;

      return 0xFF;

    } 

  }


  ide_status = 0x08;   //testali240207  //testali250207 re

  if (!(ide_status & IDE_DRQ))

  { 

   printf ("ide_status dans idestatus & IDE_RQ cf_read_byte de C_Flash: %X\n\r",ide_status); 

   getchar();

   //gl_ptr_mem++;  //ici  je mets en comm
car  je ne veux pas  lire a l'adresse du secteur suivant une

   // fois  la lecture des 512 bytes du secteur est faite

   // cf_read_open(gl_ptr_mem,
1);             
/* open the next sector */

  }


  printf ("Lecture OK_OK\n");

 // DATA = ide_read_8_databyte(); //testali250207 u

 // printf ("CF_DATA LU = %X\n",DATA);  //testali220207 unitile car retourne ça

 printf ("ide_status avant return ide_read_8_data cf_read_byte de C_Flash: %X\n\r",ide_status);  //test

  getchar();

  return ide_read_8_databyte();

//  return ide_read_databyte();


//  }

   printf("ide_status fin cf_read_byte de C_Flash: %X\n\r",ide_status); //test

   getchar();

}

Et enfin la fonction cf_read_open():


bit cf_read_open (Uint32 sect, Byte nb_sector)

{

/////Byte tees[6];  //test


//\ printf("Dans fonction cf_read_open \n\r") ; //testali270207  //test

 //\printf("valeur de AUXR %X\n\r",AUXR) ;  //testali270207  //test


 printf ("ide_status dans cf_read_open() debut C_Flash.c: %X\n\r",ide_status);  //test

getchar();

 ide_status1 = ide_status;


printf ("ide_status dans cf_read_open() apres status1 C_Flash.c: %X\n\r",ide_status); 

getchar();

//          Card_power_off();

//  ata_init ();  //test

 // ide_status = 0x21; //test

  while (ide_status & IDE_BSY)

  {

    printf ("ide_status dans cf_read_open() dans while bsy C_Flash.c: %X\n\r",ide_status);  //test

    printf ("ide_status est occupé\n"); 
//testali260207    //test a ameliorer si boucle continue

    getchar();

    if ( (Card_detect() == KO) )

    {

      gl_mem_failure = TRUE;

      lecture_cond = KO;

      return KO;

    }

  }

  /* Write device/head register */

  ide_alt_status;

  printf ("ide_status dans cf_read_open() après idealtstatus C_Flash.c: %X\n\r",ide_status); 

 getchar();

 

  Ide_set_drive_head(ATA_LBA_MODE + (((Byte*)&sect)[0] & 0x0F));  /* LBA 27-24 */

 printf ("ide_status dans cf_read_open() APRES IDE SET DRIVE C_Flash.c: %X\n\r",ide_status);  //test

 getchar();


  BSY = 0;


  while ( Ide_notbsy_drdy() ==
KO)          /* Wait for
BSY 0  and DRDY 1 */

  {

     printf ("ide_status dans cf_read_open() ds
while Ide_notbsy_drdy  C_Flash.c: %X\n\r",ide_status); 
//testali0308   

    getchar();

      if ((Card_detect() == KO) )

    {

      gl_mem_failure = TRUE;

      lecture_cond = KO;

      return KO;

    }

     printf ("ide_status value = %X\n", ide_status);

     printf ("ide_notsy_bsy \n");  //test     probleme dans cette boucle infinie

     printf ("IDE_STATUS_ADDRESS = %X \n",IDE_STATUS_ADDRESS); //test

    if (BSY >=60)                //

    {
//;                             
//

   ide_status = IDE_DRDY;
//testali260207        
//         

    //   
printf("**\n");                
//

   
}                              
//

   
BSY++;                         
//

  }


  while (Ide_notbsy_notdrq() KO);         /* Wait for BSY
0  and DRQ = 0 */ //Le boucle

    fonctionne en envers

   printf ("Ide_set_cylinder_high lba23-16() valeur avant set: %X\n\r",ide_cylinder_high); ///test

   getchar();

  Ide_set_sector_count ( nb_sector );        /* sending parameters  */

  Ide_set_sector_number(((Byte*)&sect)[3]);  /* LBA 7-0    */

  Ide_set_cylinder_low (((Byte*)&sect)[2]);  /* LBA 15-8   */

  Ide_set_cylinder_high(((Byte*)&sect)[1]);  /* LBA 23-16  */

   printf ("Ide_set_cylinder_high lba23-16() valeur apres set: %X\n\r",ide_cylinder_high); ///test

  Ide_send_command(ATA_CMD_READ_SECTOR);     /* send command */

  gl_ptr_mem =
sect;                        
/* Initialize the global byte counter */

  printf ("ide_status dasn cf_read_open() apres set C_Flash.c: %X\n\r",ide_status);   ///test

  getchar();

//      printf("***\n");

  while (ide_alt_status & IDE_BSY); //Fonctionnement à l'envers c à d sortie du boucle lorsque la condition = 0

//      printf("****\n");

    if (ide_status & IDE_ERR)

  { 

   printf ("ide_status dans cf_read_open() dans if IDE
ERROR  C_Flash.c: %X\n\r",ide_status); 
//testali0308   

    getchar();

//      printf("*****f\n");

    lecture_cond = KO;

    return KO;

  }

 

  printf ("ide_status dans cf_read_open() av idealtstatus et avant
forcage drq  C_Flash.c: %X\n\r",ide_status);  //test

    getchar();

  ide_alt_status;

 // ide_status = IDE_DRQ;  //testali260207  //test

 printf ("ide_status dans cf_read_open() ap idealtstatus et ap
forcage drq  C_Flash.c: %X\n\r",ide_status);  //test

    getchar();

  // printf ("ide_status dasn cf_read_open() CF_operations apres
DRQ: %X\n\r",ide_status);  ///test 7 si pqs cette ligne OK

  if (!(ide_status & IDE_DRQ))

    {


     printf ("ide_status dans cf_read_open() dans
if pas drq  C_Flash.c: %X\n\r",ide_status);  //test

    getchar();

    lecture_cond = KO;

    return KO;

    }

    lecture_cond = OK;


  printf("ide_status fin cf_read_open de C_Flash: %X\n\r",ide_status); //test


getchar();


  return OK; 


}

Voila en detail les 2 fonctions concernées. 


En revenant au probleme de l'affichage erronée pour moi c'est due au
fait que le printf en "%X" affiche en plus  des deux caractères
hexadecimaux du byte deux caratctères supplementaires '00' alors peut
être l'accu se charge et saute la lecture du byte suivant?

Exemple:


Au niveau de mon code, l'affichage des registres en %X, oon voit la presence

de 2 caracteres aleatoires ici '03':

Resultats:

ide_status avent read_8_data: 5803

ide_status pendant read_8_data: 5803

ide_status apres read_8_data et memsze: 5803

INSTL_CF2_OK

ide_status dans ata.c (CF2) : D803

 ide_status dans CF_oper;c (fonction cf_init) : 5003


J'ai fait un test avec de variables declarees interne,

on a generalement apparition de '00':


declaration:


unsigned char testrd[512];


extern unsigned int  A_O; 

extern unsigned int  A_1;

extern unsigned int  A_2;

extern unsigned int  PIO_WR;

unsigned char CHR1;

Byte CHR2 ;


fonction:


       printf("testrd 0 a: %X\n",testrd[0]); 

       printf("testrd 1 a: %X\n",testrd[1]);

       testrd[1] =0x3F;

       printf("testrd 1 aprs affect a: %X\n",testrd[1]);   


       A_O = P0_0;

       A_1 = P0_1;

       A_2 = P0_2;

       PIO_WR = P5_0;


       printf("AO %X\n", A_O);

       printf("A1 %X\n", A_1);

       printf("A2 %X\n", A_2);

       printf("PIO_PWR %X\n", PIO_WR);


       printf("CHR1 %X\n",CHR1);

       printf("CHR2 %X\n",CHR2);

      

Resultats:


testrd 0 a: 5000

testrd 1 a: 0

testrd 1 aprs affect a: 3F00

AO 1

A1 1

A2 1

PIO_PWR 0

CHR1 4000

CHR2 400


Donc Je pense qu'il faudra un algorithme qui puisse lire le contenu de
la variable qu'on souhaite affichée et enlever les deux derniers 00,
mais somment ?


Merci
0
goast_tu Messages postés 212 Date d'inscription dimanche 3 avril 2005 Statut Membre Dernière intervention 28 mai 2011 2
12 mars 2007 à 19:50
bon pour enlever les 2 zeros à un int c'est simple (enfait c'est 8 zeros en binaire) il suffit de faire un decalage

var=var>>8;

ou bien une division entiere par 2^8=256

<hr size="2" width="100%" />Trafic web gratuit!!!
0
Rejoignez-nous