Accueil
Réalisations électroniques
Programme PC

 

Lecteur MP3 IDE USB2.0

Ces lecteurs MP3 sont articulés autour d'un micro-controleur XC164CS (16bits/128Ko de Flash/6Ko RAM), d'une RAM externe de 64Ko, d'un controleur USB2.0 Mass Storage, d'un LCD graphique 128x64, d'un connecteur IDE 40pts, d'un connecteur compact Flash, d'un connecteur d'extension permettant d'ajouter des fonctionnalités diverses (carte Ethernet...).
J'ai développé entièrement le hard et le logiciel de ce projet; le logiel a été developpé avec le compilateur 'Keil'.



Principales caractéristiques:
- Supporte totalement un disque dur et/ou une compact Flash formaté en FAT32, supporte le partitionement des disques.
- Sauvegarde/Suppression/Modification de playlist (sauvegardée sur le disque dur au format M3U).
- USB2.0 Disque dur vu par l'ordinateur comme un périphérique 'USB Mass Storage'.
- Ecran 128x64 (BackLight continu / Seulement en lecture MP3 /
Arrêt Automatique si non utilisation du clavier)
- Gestion du lecteur par télécommande/clavier en face avant/port série
- Gestion en lecture et écriture des noms de répertoires et de fichiers courts et longs.
- Mode réveil avec une playlist définie. Arrêt automatique après x minutes.
- Mise en veille automatique du disque dur.

Organigramme du lecteur (version 3"5)

'Performance' IDE (entre XC164 et le disque dur)
Timing pour un disque dur supportant le PIO mode 3 (tps cycle min= 180ns)
utilisation du uC pendant la lecture d'un MP3 à 128kbps: 8% du CPU
Copie d'un fichier disque dur -> disque dur: 77Ko/s (fichier de 1.3Mo)
Vitesse de lecture/écriture: 500 Ko/s (512o RAM -> secteur du HD)
Recherche d'un MP3 dans une playliste de 1000 lignes: (230ms dans le pire des cas)


Pricipales modules et fonctions logiciel
------ Module FAT.c
------
- Retourne un pointeur sur la table des partitions: s_PartitionFind * FAT_GetTablePartition( void );
- Permet de trouver un fichier et d'initialiser la structure s_File:  BOOL FAT_FileOpen (BYTE *pName, s_File * hFile);
- Créer un fichier, si le fichier existe déjà il est vidé:  BOOL FAT_FileCreate (BYTE *pName, s_File * hFile);
- Vider un fichier de son contenu: BOOL FAT_FileEmpty (s_File * hFile) ;
- Supprimer un fichier: BOOL FAT_FileDelete (s_File * hFile) ;
- Copier un fichier. Si pName n'existe pas on le crée:  BOOL FAT_FileCopy (s_File * hFileSrc, BYTE * pName) ;
- Permet d'écrire NbOctet au fichier pFile:  BOOL FAT_FileAddText(s_File * pFile,void * pData,WORD NbOctet);
- Permet de lire NbOctet du fichier pFile:  WORD FAT_FileRead (s_File * pFile, void * pData, WORD NbOctet);
- Retourne le nombre d'entrées trouvées à partir de indiceFirstCluster: FAT_GetNumberEntry(DWORD indiceFirstCluster, WORD filtre);
- Retourne, dans un ordre alphabétique les entrées (correspondant au filtre) trouvées à partir de indiceFirstCluster (filtre: F_DIR, F_ALLFILE, F_FILEMP3, F_SUBENTRY, F_ONLYRETOURN_NBENTRY):
void FAT_GetAllEntry(DWORD indiceFirstCluster, WORD filtre, s_TableEntry ** PtptEntry, WORD * NbEntryFind);
- Récupérer la prochaine entrée dans la FAT. La recherche est initialisée avec FAT_initGetNextEntry:
BOOL FAT_GetNextEntry( s_TableEntry * TableEntry );

------ Module File.c (Traitement sur les fichiers: lecture, recherche de texte...) ------
- Initialiser pFile au début du fichier: void File_SetStart( s_File * pFile );
- Initialiser pFile àla fin du fichier: void File_SetEnd( s_File * pFile );
- positionner pFile sur le début de la ligne LineNumber:  BOOL File_SetFocusLine(s_File * pFile, WORD LineNumber);
- positionner pFile sur la ligne LineNumber,Ignore Les lignes commançant par pdata
      BOOL File_SetFocusIgnoreLineStartWith(s_File * pFile, WORD LineNumber, void * pData)
- Lit une ligne entière le début de la ligne est indiquée par pFile :
      WORD File_ReadLine(s_File * pFile, void * pData, WORD NbOctetMax)
- Retourner le nombre de fois ou la chaine est trouvée en début de ligne
      WORD File_CountLineStartWith(s_File * pFile, void * pData);
- Positionner pFile sur la prochaine ligne commançant par la chaine pData:
      BOOL File_FindNextLineStartWith(s_File * pFile, void * pData);
- Positionner pFile sur la prochaine chaine pData: BOOL File_FindText(s_File * pFile, void * pData);

------ IDE.c (acces bas niveau au disque dur) ------
- initialiser le module IDE : void IDE_init( void );
- Reset hardware BYTE IDE_hardwareReset( void );
- Sélectionner le device 0(Master) ou le device 1(slave): BYTE IDE_SelectDevice (BOOL bDevice);
- Récupérer les infos du disque dur actif (commande Identify device):  void IDE_GetDriveInfo(s_DriveInfo * ataDriveInfo);
- Permettre de mettre le disque dur StandBy (=true) ou en idle(=false): void IDE_StandBy( BOOL state );
- Ecrire NbSector adresse de début=AddSectorLBA, buffer= data source:  
BYTE IDE_writeSectorsLBA(DWORD AddSectorLBA,BYTE NbSectors,BYTE *buffer)
- Lit NbSectors à partir de AddSectorLBA place le résultat dans buffer:
BYTE IDE_readSectorsLBA(DWORD AddSectorLBA, BYTE NbSectors, WORD * buffer);
- Lit NbByte à partir de DataOffsetInByte à l'adresse AddSectorLBA: BYTE IDE_readNbByteSectorLBA(DWORD AddSectorLBA, BYTE DataOffsetInByte, WORD ReadNbBYTE, void * buffer);
- Menu de test du module IDE (MENUDEBUGIDE=1): void IDE_testmodule( void );

------ LCD.c (Routine d'affichage) ------
Routine chaine de caractère
- Affiche du texte (supporte \n): void LCD_AffText(BYTE * ptData, BYTE style);
- Efface une ligne du LCD: void LCD_clearLign(BYTE lign);
- Ecrit un caractère (pour changer la position LCD_SetCursor) :void LCD_Putchar (BYTE Char, BYTE style);
- void LCD_RestoreAff( s_CopyLCD * ptCopyLCD );
- void LCD_SaveAff( s_CopyLCD * ptCopyLCD );
- void LCD_setFont(s_FontDef * ptFontDef);
- void LCD_setMaxLign( SBYTE * NbMaxLign );
- void LCD_traitCycCursor( BOOL validCursor );
Routine de dialogue
- Affiche une boîte de dialogue avec des boutons Oui/Non, ptData pointe sur le texte à afficher, bmp est une image de 16x16max et StateDef indique si c'est le bouton yes ou no qui est selectionné:
 BOOL LCD_MessageBoxYesNo(BYTE * ptData, s_PICTURE_DEF * bmp, BOOL StateDef);
- Affiche dans une boite de dialogue le message ptData si TimeDisplay=0. Le message est affiché et la fonction bloquante en continu tant qu' aucune touche n'est appuyée sinon il est affiché TimeDisplay secondes:
void LCD_MessageFreeze(BYTE * ptData, BYTE TimeDisplay);
- Permet d'afficher dans une boite de dialogue le message ptData. On re-affiche ce qui etait mis avant dès que l'on appelle la fonction LCD_MessageStop ou dès que l'on utilise une fonction d'affichage void LCD_Message(BYTE * ptData);
- idem LCD_Message mais avec l'affichage d'un bmp 32x32: void LCD_MessageBmp(BYTE * ptData, s_PICTURE_DEF * bmp);
- Affiche un menu déroulant: BOOL LCD_MenuBox(BYTE * ptDescription, BYTE * TabItmem, BYTE * IndexItemSel );
Routine graphique
- void LCD_pixel(BYTE x, BYTE y, BOOL show);
- void LCD_rectangle(BYTE x1, BYTE y1, BYTE x2, BYTE y2, BOOL show);
- void LCD_degree_line(BYTE x, BYTE y, BYTE degree, BYTE distance, BOOL show);
- void LCD_circle(BYTE x, BYTE y, BYTE radius, BOOL show);
- void LCD_line(BYTE x1, BYTE y1, BYTE x2, BYTE y2, BOOL show);
- void LCD_DisplayPicture (x1,y1,s_PICTURE_DEF * bmp);

Liaison série
Pour pouvoir débugger indépendamment chaque module, des menus de test sont accessibles par la liaison série.
Voici quelques exemples de menu concernant l'accès au disque dur: