45-CS43L22-Library (STM32F4)

Mit dieser Library kann der Audio-DAC (CS43L22) vom Discovery-Board benutzt werden um WAV-Files aus dem Flash abzuspielen.
(zum abspielen von MP3-Files gibt es eine extra LIB)

Die WAV-Files müssen im 16bit PCM-Format entweder Mono oder Stereo vorliegen. Und es funktionieren Abtastraten von 8kHz bis 48kHz.

Mit meinem PC-Programm “FileConverter” können beliebige WAV-Files in ein C-Format umgewandelt werden um dieses dann im Projekt hinzufügen zu können.

Der Header vom WAV-File wird vor dem abspielen geprüft und ausgewertet. Falls da was nicht stimmen sollte (z.B. nur 8bit Format) wird eine Fehlernummer zurückgeliefert.

Die WAV kann entweder nur einmal “single” oder endlos “loop” abgespielt werden. Es gibt noch Funktionen für Pause, Resume, Stop und Volume.

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

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

Enumerationen :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
typedef enum {
  WAV_OK = 0,        // WAVE-Header ist ok
  WAV_INIT_ERR,      // Fehler beim init
  WAV_SIZE_ERR,      // File zu klein
  WAV_ID_ERR,        // RIFF-ID fehlt
  WAV_ID2_ERR,       // WAVE-ID fehlt
  WAV_ID3_ERR,       // fmt-ID fehlt
  WAV_FMT_LEN_ERR,   // falsche Länge von ftm
  WAV_TYP_ERR,       // Typ ist nicht PCM
  WAV_CH_ERR,        // kein Mono oder Stereo
  WAV_FRQ_ERR,       // Fehler bei Samplefrq
  WAVE_FRAME_ERR,    // Fehler im Frame
  WAVE_BPS_ERR,      // Fehler bei Bit per Sample
  WAVE_ID4_ERR       // DATA-ID fehlt
}WAV_ERR_t;

Funktionen :

1
2
3
4
5
6
7
ErrorStatus UB_CS43L22_Init(void);                                // init vom CS43L22
WAV_ERR_t UB_CS43L22_PlayWAVSingle(UB_WAV *wav, uint8_t Volume);  // PLAY (einmal)
WAV_ERR_t UB_CS43L22_PlayWAVLoop(UB_WAV *wav, uint8_t Volume);    // PLAY (Endlos)
void UB_CS43L22_PauseWAV(void);                                   // PAUSE
void UB_CS43L22_ResumeWAV(void);                                  // WEITER (nach Pause)
void UB_CS43L22_StopWAV(void);                                    // STOP
void UB_CS43L22_SetVolume(uint8_t Volume);                        // zum einstellen der Lautstärke

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
//--------------------------------------------------------------
// File     : main.c
// Datum    : 09.06.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 CS43L22 Library
// Hinweis  : Diese zwei Files muessen auf 8MHz stehen
//              "cmsis_boot/stm32f4xx.h"
//              "cmsis_boot/system_stm32f4xx.c"
//--------------------------------------------------------------
 
#include "main.h"
#include "stm32_ub_led.h"
#include "stm32_ub_cs43l22.h"
 
int main(void)
{
  ErrorStatus check;
 
  SystemInit(); // Quarz Einstellungen aktivieren
 
  // init der LEDs
  UB_Led_Init();
 
  // init vom CS43L22
  check=UB_CS43L22_Init();
  if(check==SUCCESS) {
    UB_Led_On(LED_GREEN);
    // abspielen der WAV in einer Endlosloop
    UB_CS43L22_PlayWAVLoop(&m32k16b_wav, 70);
  }
  else {
    UB_Led_On(LED_RED);
  }
 
  while(1)
  {
 
  }
}

Hier die Library zum Download :

ub_stm32f4_cs43l22_v100

Hier der komplette CooCox-Projektordner zum Download :

Demo_45_CS43L22

Hier das PC-Programm zum umwandeln von WAV-Files in C-Files zum Download :

FileConverter_UB_v103

17 Antworten auf 45-CS43L22-Library (STM32F4)

  1. Tobias sagt:

    Hey,
    danke für das tolle Projekt. Deine Demo funktioniert wunderbar.
    Wenn ich aber selbst ein File einbinde, bleiben die Kopfhörer still. Ich habe eine MP3 mit Audacity eingelesen, gekürzt und dann als Wave 16-Bit PCM exportiert(44,1kHz Samplerate). Mit deinem Programm problemlos in *.c gewandelt, im Projekt eingebunden und programmiert. Die hex-Daten sehen gut aus, zumindest immer veränderliche Werte und im Betrieb geht auch die grüne Led an.
    Hast du eine Idee, wo ich den fehler mache?

    • admin_ub sagt:

      schwer zu sagen, sende mir einfach mal das original WAV-File zu, vlt finde ich den Fehler.

    • admin_ub sagt:

      du hast das Problem ja mittlerweile gelöst aber hier zur Info. Der WAV-Header von deinem File entspricht nicht dem standard und die Funktion “UB_CS43L22_PlayWAVLoop” wirft eine Fehlermeldung….die aber blöderweise in meinem Beispiel-Programm nicht angezeigt wird :-) da sollte man vlt. noch den Rückgabewert auswerten !

  2. Tobias sagt:

    Achso, das hatte ich dann auch vermutet. Da ist wohl etwas bei der Umwandlung mp3->wav schief gelaufen. Danke fürs schauen. Die leuchtende grüne Led hat mich verwirrt, da sie zu unrecht geleuchtet hat, auch wenn die mit meinem Fehler gar nix zu tun hatte.

  3. Aud sagt:

    Thank you very much for this (sorry I only know English).

    What is the “required format” for the wave files. I have the same issue as Tobias.

    This library is just what I have been looking for

  4. admin_ub sagt:

    The Sound-File-Format must be “PCM” with no compression, and 16bit per Sample
    Channels : mono or stereo, SamplFrq : 8kHz to 48kHz
    Please check the return value of the function “UB_CS43L22_PlayWAVLoop”
    to locate an error in the WAV-Header

  5. Sidney sagt:

    Hey,
    First of all thank you for this website, it has greatly improved my understanding of the STM32F4 discovery board.
    I’m working on a project where i want to record audio (using the MP45DT02 mic) and save it as a WAV file on a USB stick. After this i want to use the Audio-DAC (CS43L22) to play the recorded file. I have used a combination of Demo_32_USB_MSC_HOST, Demo_47_MP45DT02, Demo_54_USB_MP3 and this one to achieve this. I’m having some trouble with the last step, i don’t know how i can acces the recorded file. Maybe you can help me?
    Again, thanks for everything.

    Greetings, Sidney

    • admin_ub sagt:

      Hi, the MP45DT02-Lib saves the audio as WAV-File (not MP3) please test on a first step that this file is ok. You can play it on a pc to verify that. In a second step you have to change the CS43L22-Lib to play the WAV from USB instead of FLash.

      • Sidney sagt:

        Hey, thanks for the response. Sorry i didn’t reply sooner, but my computer crashed. Right now i have recorded a WAV file on the USB using the UB_MP45DT02_RecordLoop function from the Demo_47_MP45DT02 library. Now i want to use the UB_CS43L22_PlayWAVLoop function to play the recording. The PlayWAVLoop function requires a “UB_WAV” input. I don’t know how i can acces the recording and change it to meet this requirement. Hopefully you can help me with this problem.

      • Sidney sagt:

        Hi, please ignore my previous question. Where do i have to change the CS43L22-Lib to play the WAV from USB instead of FLash? Thank you.

        • admin_ub sagt:

          please have a look at the function “UB_CS43L22_PlayWAVSingle”

          you need to call two functions :
          1. UB_AUDIO_InitNew()
          2. EVAL_AUDIO_Play()

          The “init” defines the output, volume and samplerate.
          The “play” plays the wav-file.

          But you have to call the play function in a loop
          becouse you must load the wav-file from usb
          in little packets so you need a buffer

          char sampl_buf[256];
          
          do {
            load_from_usb(sampl_buf,256)
            play_wav(sampl_buf,256)
          }while(not eof)
          

          like this

          • Sidney sagt:

            Hi, thank you for your answer. I have changed the “UB_CS43L22_PlayWAVSingle” function like you told me, but there is still no sound from the device.

            My code:

            WAV_ERR_t UB_CS43L22_PlayWAVSingle(uint8_t Volume)
            {
            WAV_ERR_t ret_wert=WAV_INIT_ERR;
            UB_WAV wav_file;
            UB_WAV * wav_file_pt;
            FATFS_t controle;
            FATFS_t buffer_check;
            FIL recording;
            uint8_t wav_buff[256]="0";

            if((cs43l22_status==CS43L22_INIT_OK) || (cs43l22_status==CS43L22_STOP)) {
            // check vom WAV-Header

            wav_start = wav_buff;
            wav_file_pt = &wav_file;
            controle=UB_Fatfs_OpenFile(&recording,“test16k.wav“,F_RD);
            buffer_check=UB_Fatfs_ReadBlock(&recording,wav_start,256,wav_file.size);
            wav_file.size = UB_Fatfs_FileSize(&recording);
            wav_file.table = wav_start;

            ret_wert=P_CS43L22_CheckWAV(wav_file_pt);

            if(ret_wert==WAV_OK) {
            cs43l22_status=CS43L22_PLAY;
            wav_loop=0; // single play
            wav_start=wav_file.table[my_wav.data_start];

            if(my_wav.channels==2) {
            // stereo
            UB_AUDIO_InitNew(OUTPUT_DEVICE_HEADPHONE, Volume, my_wav.samplerate);
            }
            else {
            // mono
            UB_AUDIO_InitNew(OUTPUT_DEVICE_HEADPHONE, Volume, my_wav.samplerate/2);
            }
            UB_Led_On(LED_BLUE);
            EVAL_AUDIO_Play((uint16_t*)wav_start, 256);

            wav_start = wav_buff;

            while(buffer_check!=FATFS_EOF)
            {
            buffer_check=UB_Fatfs_ReadBlock(&recording,wav_start,256,wav_file.size);
            EVAL_AUDIO_Play((uint16_t*)wav_start, 256);
            wav_start = wav_buff;
            }
            }
            }
            return(ret_wert);
            }

          • Sidney sagt:

            Sorry, more readable:
            http://pastebin.com/ZrRA2wHz

  6. Daniel sagt:

    Hallo,
    ich gebe ein sehr kurzes File wieder: 16 Bit mono 44,1kHz ca. 4000 Werte.

    Habe dein Projekt direkt in CoIDE genommen und dann den Inhalt
    deines Audio-Files gegen mein kurzes getauscht.

    Nun spielt er erst mein kurzes, dann aber das lange von dir (ist wohl noch im Flash!).

    Hab dann trotzdem es in mein Projekt kopiert. Nun stürzt nach Aufruf
    UB_CS43L22_PlayWAVSingle(&File1, 255);
    irgend es ab (es werden Variablen und Ports überschrieben…).

    Das Audio-File wird fehlerlos erkannt.

    Woran könnte das liegen?

    • admin_ub sagt:

      hast du nur die Daten mit einem Editor ersetzt ?
      Du musst dein WAV-File mit meinem File-Converter in ein C-File
      wandeln, damit wird auch die Längenangabe mit gespeichert.
      in deinem Fall die 4000 Bytes.

  7. Daniel sagt:

    ah, – noch ne Frage

    wie kommt die Audio-Datei ins Flash?

    Wie geht es, dass direkt aus dem Flash wiedergegeben wird?
    Gibt es eine Einstellung in CoIDE?

    Habe “const” benutzt, aber dann wird nach Reset nur die const Daten ins RAM
    kopiert und dann von dort wiedergegeben.

    • admin_ub sagt:

      mit der Angabe “const” landen die Daten im Flash. 880 kByte würden auch schlecht ins RAM vom F4 passen :-)


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.