54-CS43L22_MP3_USB-Library (STM32F4)

Mit dieser Library kann der Audio-DAC (CS43L22) vom Discovery-Board benutzt werden um normale MP3-Files von einem USB-Stick abzuspielen.
(es gibt auch noch eine andere Lib um MP3 aus dem Flash abzuspielen)

Die MP3-Files müssen mit einer Sampling-Frq von 44,1 kHz vorliegen.

Das MP3 kann entweder nur einmal “single” oder endlos “loop” abgespielt werden. Es gibt noch Funktionen für Pause, Resume, Stop und Volume.
Die Funktion “UB_CS43L22_PlayMP3Do” muss ständig zyklisch aufgerufen werden !

Hinweis : Der I2S-Clock und der notwendige PLL muss nicht im “system_stm32f4xx.c-File” eingestellt werden, das wird von der Library erledigt.

MP3-Decoder :
Als MP3-Decoder habe ich Helix-MP3 benutzt (der Link dazu steht im Quellfile)

Um die MP3-Files vom USB-Stick laden zu können, wird die USB-Version der FATFS-Library benötigt und die Library für den USB-MSC im Host-Mode.

Compiler-Settings :
Die “Optimization” muss bei CoIDE auf “-O3″ eingestellt sein, sonst kommt es zu Knackgeräuschen beim abspielen !!

Benutzte Pins :

1
2
3
4
5
6
7
PB9  = SDA
PB6  = SCL
PA4  = WS
PC7  = MCLK
PC10 = SCK
PC12 = SD
PD4  = Reset

Voraussetzungen :

1
2
Benutzte Module der CooCox-IDE : SPI, DMA, MISC
Benutzte Librarys : STM32_UB_I2C1, STM32_UB_USB_MSC_HOST

Enumerationen :

1
2
3
4
5
6
7
8
9
10
11
12
typedef enum {
  MP3_OK = 0,       // kein Fehler
  MP3_INIT_ERR,     // Fehler beim init
  MP3_MALLOC_ERR,   // nicht genug RAM frei
  MP3_FILE_ERR,     // File Fehler
  MP3_SYNC_ERR,     // kein Sync gefunden
  MP3_FRQ_ERR,      // Fehler bei Samplefrq
  MP3_FRAME_ERR,    // sonstiger Frame fehler
  MP3_IDATA_ERR,    // INDATA_UNDERFLOW
  MP3_MDATA_ERR,    // MAINDATA_UNDERFLOW
  MP3_DECODE_ERR    // sonstige Dekoder fehler
}MP3_ERR_t;

Funktionen :

1
2
3
4
5
6
7
8
9
ErrorStatus UB_CS43L22_InitMP3(void);                                  // init vom CS43L22
MP3_ERR_t UB_CS43L22_PlayMP3Single(const char* name, uint8_t Volume);  // PLAY (einmal)
MP3_ERR_t UB_CS43L22_PlayMP3Loop(const char* name, uint8_t Volume);    // PLAY (Endlos)
CS43L22_STATUS_t UB_CS43L22_PlayMP3Do(void);                           // muss zyklisch aufgerufen werden
void UB_CS43L22_PauseMP3(void);                                        // PAUSE
void UB_CS43L22_ResumeMP3(void);                                       // WEITER (nach Pause)
void UB_CS43L22_StopMP3(void);                                         // STOP
void UB_CS43L22_SetVolumeMP3(uint8_t Volume);                          // zum einstellen der Lautstärke
MP3_ERR_t UB_CS43L22_GetMP3Err(void);                                  // zum auslesen der Fehlernummer

Beispiel :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//--------------------------------------------------------------
// File     : main.c
// Datum    : 18.08.2013
// Version  : 1.0
// Autor    : UB
// EMail    : mc-4u(@)t-online.de
// Web      : www.mikrocontroller-4u.de
// CPU      : STM32F4
// IDE      : CooCox CoIDE 1.7.0
// Module   : CMSIS_BOOT, M4_CMSIS_CORE
// Funktion : Demo der MP3-Lib (per USB_MSC_Host und FATFS)
// Hinweis  : Diese zwei Files muessen auf 8MHz stehen
//              "cmsis_boot/stm32f4xx.h"
//              "cmsis_boot/system_stm32f4xx.c"
//
// Compiler Optimization auf -O3 einstellen !!
//--------------------------------------------------------------
 
#include "main.h"
#include "stm32_ub_usb_msc_host.h"
#include "stm32_ub_cs43l22_mp3_fatfs.h"
 
int main(void)
{
  uint8_t play_mode=0;
 
  SystemInit(); // Quarz Einstellungen aktivieren
 
  // Init vom USB-OTG-Port als MSC-HOST
  // (zum lesen/schreiben auf einen USB-Stick)
  UB_USB_MSC_HOST_Init();
 
  // Init vom CS43L22 (im MP3 Mode)
  if(UB_CS43L22_InitMP3()==SUCCESS) {
    play_mode=1; // init war ok
  }
 
  while(1)
  {
    // pollen vom USB-Status
    if(UB_USB_MSC_HOST_Do()==USB_MSC_DEV_CONNECTED) {
      // wenn USB-Stick erkannt wurde
 
      // MP3-Funktion zum abspielen zyklisch aufrufen
      UB_CS43L22_PlayMP3Do();
 
      if(play_mode==1) {
        // Media einmal mounten
        if(UB_Fatfs_Mount(USB_0)==FATFS_OK) {
          play_mode=2;
          // abspielen vom MP3-File von USB in einer Endlosloop
          UB_CS43L22_PlayMP3Loop("skinny.mp3",70);
        }
      }
    }
    else {
      // kein USB-Stick vorhanden
      if(play_mode>1) {
        play_mode=1;
        // Media unmounten
        UB_Fatfs_UnMount(USB_0);
      }
    }
  }
}

Hier die Library zum Download :

ub_stm32f4_cs43l22_usb_mp3_v101

Hier der komplette CooCox-Projektordner zum Download :

Demo_54_USB_MP3

Hier das MP3-File zum Download :

skinny_mp3

10 Antworten auf 54-CS43L22_MP3_USB-Library (STM32F4)

  1. Daniel sagt:

    Hallo!
    Mich würde interessieren, warum man für eine einwandfreie Funktion der Library die Code- Optimierung benötigt. Hat jemand eine Idee dazu?

    • admin_ub sagt:

      ich vermute ohne die Optimierung dauert das laden der Daten vom Stick zu lange. So wie ich das noch in Erinnerung habe, läuft die Version wo das MP3-File im Flash liegt auch ohne Optimierung.

  2. Jürgen sagt:

    Vielen Dank für die Veröffentlichung Deiner Arbeit…

    Diese Demo funktioniert ja auch mit nur einer winzigen Parameteranpassung auf dem STM32F401C-Disco, wobei bei der Compilierung von O0-O3 alles ohne Aussetzer funktioniert, soweit ich das hören kann (mp3 mit 320kbit/sec):

    in system_stm32f4xx.c(146) die Clocks auf 84Mhz verkleinern und bei der PLL darauf achten, dass USB-clock mit 48 Mhz ganzzahlig “erteilt” werden kann…

    /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
    #define PLL_M 4 // 8
    #define PLL_N 168 // 336

    /* SYSCLK = PLL_VCO / PLL_P */
    #define PLL_P 4 // 2

    /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
    #define PLL_Q 7

    Gruss

    • admin_ub sagt:

      Danke für den Hinweis.

  3. Marcel_u sagt:

    Ich hätte mal eine frage. Ist in dem Programm schon das auslesen des Namens oder der Aktuellen Position Implementieren? Ich Würde die Daten nämlich gerne auf einem LCD ausgeben. Wie bekomme ich Daten wie Titel und Position und gesamt länge?

    MfG
    Marcel

    • admin_ub sagt:

      das Programm ist ein “minimal” Beispiel. Für Name, Interpret usw müsste man die ID3 Tags auswerten. Im Netz gibts da sicher Beispiele dafür.

  4. Mathias Tantau sagt:

    Wenn zwischen den einzelnen Liedern die Funktion “UB_USB_MSC_HOST_Do()” aufgerufen wird, kommt es beim Öffnen des nächsten Liedes zu einem Fehler. Die Funktion darf offensichtlich nur zu Anfang aufgerufen werden und nach dem ersten mounten nie mehr wieder, aber dann kann das Programm nicht auf ein Abstecken des USB-Sticks durch den Nutzer reagieren. Die Funktion “UB_USB_MSC_HOST_Do()” muss doch auch später noch immer wieder aufgerufen werden können, ohne dass es danach beim Öffnen einer Datei einen Fehler gibt.

    Kennt jemand das Problem / eine Lösung?

  5. Mathias Tantau sagt:

    Danke!
    Mit dem Beispiel und viel Experimentieren ist mir folgendes klar geworden:
    Die Funktion USBH_Process() von STMicroelectronics muss periodisch aufgerufen werden. Aber nicht nach jedem Aufruf dürfen Dateifunktionen wie f_write(), f_open(), … ausgeführt werden. Nur wenn USBH_Process() die callback-Funktion USBH_USR_MSC_Application() aufruft, dürfen danach die Dateifunktionen bis zum nächsten Aufruf von USBH_Process() genutzt werden (oder direkt in der callback-Funktion). Wird das nicht berücksichtigt, kommt es zu Fehlfunktionen, aber nicht unbedingt zu Fehlermeldungen, ganz gefährlich. Also unbedingt in USBH_USR_MSC_Application() irgendein flag setzen…!

  6. Felix sagt:

    Danke für das Projekt!
    Ich hätte eine Frage bezüglich der Sampleraten der mp3 Files. Der Dekoder kann ja auch mp3s mit 48kHz Samplerate abspielen. Welche Änderungen wären in den Librarys notwendig um das zu implementieren?
    MfG
    Felix


Wie hat Dir dieser Artikel gefallen?

1 Stern2 Sterne3 Sterne4 Sterne5 Sterne (Noch keine Bewertungen)
Loading...

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.