Wave-Player with TLV320
Dependencies: FatFileSystemCpp I2SSlave TLV320 mbed
main.cpp@0:3087f1924901, 2015-12-09 (annotated)
- Committer:
- HB9GAA
- Date:
- Wed Dec 09 20:58:55 2015 +0000
- Revision:
- 0:3087f1924901
Wave-Player with TLV320
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
HB9GAA | 0:3087f1924901 | 1 | //------------------------------------------------------------------------------------------------------------ |
HB9GAA | 0:3087f1924901 | 2 | // Demoprogramm 6 für die Audio-Ausgabe über das AudioCODEC Board (RS Product Code 754-1965) |
HB9GAA | 0:3087f1924901 | 3 | //------------------------------------------------------------------------------------------------------------ |
HB9GAA | 0:3087f1924901 | 4 | //(c) Roland Elmiger, ELcon Consulting & Engineering, Switzerland |
HB9GAA | 0:3087f1924901 | 5 | // |
HB9GAA | 0:3087f1924901 | 6 | // Version 1.0A |
HB9GAA | 0:3087f1924901 | 7 | // |
HB9GAA | 0:3087f1924901 | 8 | // Enwickelt am : 22.11.2015 |
HB9GAA | 0:3087f1924901 | 9 | // Letzter Update : 06.12.2015 |
HB9GAA | 0:3087f1924901 | 10 | //------------------------------------------------------------------------------------------------------------ |
HB9GAA | 0:3087f1924901 | 11 | // Jedes WAV-Files mit den Bedingungen 44100Hz, 16-bit, Stereo sollte funktionieren. |
HB9GAA | 0:3087f1924901 | 12 | // |
HB9GAA | 0:3087f1924901 | 13 | // Beschaltung: |
HB9GAA | 0:3087f1924901 | 14 | // |
HB9GAA | 0:3087f1924901 | 15 | // AudioCODEC Board mbed NXP LPC1768 |
HB9GAA | 0:3087f1924901 | 16 | // --------------------- --------------------- |
HB9GAA | 0:3087f1924901 | 17 | // GND | 1 <-------> 1 | GND (0V) |
HB9GAA | 0:3087f1924901 | 18 | // LRCOUT | 2 | |
HB9GAA | 0:3087f1924901 | 19 | // DOUT | 3 | |
HB9GAA | 0:3087f1924901 | 20 | // BCLK | 4 <-------- 7 | P7 (SCLK) |
HB9GAA | 0:3087f1924901 | 21 | // DIN | 5 <-------- 5 | P5 (MOSI) |
HB9GAA | 0:3087f1924901 | 22 | // LCRIN | 6 <-------- 6 | P6 (MISO) |
HB9GAA | 0:3087f1924901 | 23 | // /CS | 7 <-------> 1 | GND (0V) |
HB9GAA | 0:3087f1924901 | 24 | // MODE | 8 <-------> 1 | GND (0V) |
HB9GAA | 0:3087f1924901 | 25 | // SDIN | 9 <-------- 9 | P9 (SDA) |
HB9GAA | 0:3087f1924901 | 26 | // SCLK |10 <--------10 | P10 (SCL) |
HB9GAA | 0:3087f1924901 | 27 | // +3.3V |11 <------->40 | Vout (3.3V) |
HB9GAA | 0:3087f1924901 | 28 | // --------------------- --------------------- |
HB9GAA | 0:3087f1924901 | 29 | |
HB9GAA | 0:3087f1924901 | 30 | |
HB9GAA | 0:3087f1924901 | 31 | //------------------------------------------------------------------------------------------------------------ |
HB9GAA | 0:3087f1924901 | 32 | |
HB9GAA | 0:3087f1924901 | 33 | #include "mbed.h" |
HB9GAA | 0:3087f1924901 | 34 | #include "TLV320.h" |
HB9GAA | 0:3087f1924901 | 35 | #include "SDHCFileSystem.h" |
HB9GAA | 0:3087f1924901 | 36 | #include "LCD.h" |
HB9GAA | 0:3087f1924901 | 37 | |
HB9GAA | 0:3087f1924901 | 38 | |
HB9GAA | 0:3087f1924901 | 39 | DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4); |
HB9GAA | 0:3087f1924901 | 40 | Serial pc(USBTX, USBRX); |
HB9GAA | 0:3087f1924901 | 41 | |
HB9GAA | 0:3087f1924901 | 42 | TextLCD lcd(p26, p25, p24, p23, p22, p20, p19, TextLCD::LCD20x4); // RS, RW, E, D0, D1, D2, D3, Typ |
HB9GAA | 0:3087f1924901 | 43 | TLV320 audio(p9, p10, 0x34, p5, p6, p7, p8, p29); //Objekt I2S Codec |
HB9GAA | 0:3087f1924901 | 44 | |
HB9GAA | 0:3087f1924901 | 45 | SDFileSystem sd(p11, p12, p13, p14, "sd"); //Objekt SD-Karte (MOSI, MISO, SCLK, CS, "SD-Kartenname") |
HB9GAA | 0:3087f1924901 | 46 | |
HB9GAA | 0:3087f1924901 | 47 | FILE *fp; //Zeiger auf die Audiodatei |
HB9GAA | 0:3087f1924901 | 48 | |
HB9GAA | 0:3087f1924901 | 49 | AnalogIn aIn(p15); //Lautstärke |
HB9GAA | 0:3087f1924901 | 50 | |
HB9GAA | 0:3087f1924901 | 51 | #define DEBOUNCING_INTERVAL 20 //Debouncing Interval (in Millisekunden) |
HB9GAA | 0:3087f1924901 | 52 | |
HB9GAA | 0:3087f1924901 | 53 | // Variablen |
HB9GAA | 0:3087f1924901 | 54 | //--------------------------------------------------------------------------------------------------------------------------------------- |
HB9GAA | 0:3087f1924901 | 55 | int RingBuffer[4096]; //Ringspeicher |
HB9GAA | 0:3087f1924901 | 56 | volatile int ReadPointer = 0; |
HB9GAA | 0:3087f1924901 | 57 | volatile int Theta = 0; |
HB9GAA | 0:3087f1924901 | 58 | |
HB9GAA | 0:3087f1924901 | 59 | /* Wav file header data, for setting up the transfer protocol */ |
HB9GAA | 0:3087f1924901 | 60 | short Channels; //Kanalzahl (2 = Stereo, 1 = Mono) |
HB9GAA | 0:3087f1924901 | 61 | long SampleRate; //Abtastrate |
HB9GAA | 0:3087f1924901 | 62 | short WordWidth; //Bit-Anzahl der Daten (z.B. 16 Bit) |
HB9GAA | 0:3087f1924901 | 63 | |
HB9GAA | 0:3087f1924901 | 64 | bool AnsagePlay = false; // |
HB9GAA | 0:3087f1924901 | 65 | char AnsageNr = 0; //Nr. der Ansage |
HB9GAA | 0:3087f1924901 | 66 | |
HB9GAA | 0:3087f1924901 | 67 | // Texte für die Anzeigen und die Audio-Dateiauswahl |
HB9GAA | 0:3087f1924901 | 68 | //--------------------------------------------------------------------------------------------------------------------------------------- |
HB9GAA | 0:3087f1924901 | 69 | const char AnsageAudio[5][40] = { |
HB9GAA | 0:3087f1924901 | 70 | {"/sd/Bahnhof1.wav"}, |
HB9GAA | 0:3087f1924901 | 71 | {"/sd/Bahnhof2.wav"}, |
HB9GAA | 0:3087f1924901 | 72 | {"/sd/Bahnhof3.wav"}, |
HB9GAA | 0:3087f1924901 | 73 | {"/sd/Bahnhof4.wav"}, |
HB9GAA | 0:3087f1924901 | 74 | {"/sd/Bahnhof5.wav"} }; |
HB9GAA | 0:3087f1924901 | 75 | |
HB9GAA | 0:3087f1924901 | 76 | const char AnzeigeText[5][40] = { |
HB9GAA | 0:3087f1924901 | 77 | {"Bahnhof 1\n\nEndstation\nRestaurant"}, |
HB9GAA | 0:3087f1924901 | 78 | {"Bahnhof 2\n\nLoewengehege"}, |
HB9GAA | 0:3087f1924901 | 79 | {"Bahnhof 3\n\nRegenwald"}, |
HB9GAA | 0:3087f1924901 | 80 | {"Bahnhof 4\n\nSchweizer-Tiere"}, |
HB9GAA | 0:3087f1924901 | 81 | {"Bahnhof 5\n\nEndstation\nStreichel-Zoo"} }; |
HB9GAA | 0:3087f1924901 | 82 | |
HB9GAA | 0:3087f1924901 | 83 | InterruptIn Reed1(p16); //Eingänge der Reed-Kontakte (LOW aktiv) |
HB9GAA | 0:3087f1924901 | 84 | InterruptIn Reed2(p17); |
HB9GAA | 0:3087f1924901 | 85 | InterruptIn Reed3(p18); |
HB9GAA | 0:3087f1924901 | 86 | InterruptIn Reed4(p28); |
HB9GAA | 0:3087f1924901 | 87 | InterruptIn Reed5(p30); |
HB9GAA | 0:3087f1924901 | 88 | |
HB9GAA | 0:3087f1924901 | 89 | |
HB9GAA | 0:3087f1924901 | 90 | // Funktion zum lesen des Potentiometerwerts und setzten der Ausgangslautstärke |
HB9GAA | 0:3087f1924901 | 91 | //------------------------------------------------------------------------------------------------------------ |
HB9GAA | 0:3087f1924901 | 92 | void SetVolume(void) |
HB9GAA | 0:3087f1924901 | 93 | { |
HB9GAA | 0:3087f1924901 | 94 | audio.outputVolume(1-aIn, 1-aIn); |
HB9GAA | 0:3087f1924901 | 95 | } |
HB9GAA | 0:3087f1924901 | 96 | |
HB9GAA | 0:3087f1924901 | 97 | |
HB9GAA | 0:3087f1924901 | 98 | // Funktion zum lesen des Zirkular-Speichers und zum senden der Daten zum TLV320 |
HB9GAA | 0:3087f1924901 | 99 | //------------------------------------------------------------------------------------------------------------ |
HB9GAA | 0:3087f1924901 | 100 | void isr_audio(void) |
HB9GAA | 0:3087f1924901 | 101 | { |
HB9GAA | 0:3087f1924901 | 102 | audio.write(RingBuffer, ReadPointer, 8); |
HB9GAA | 0:3087f1924901 | 103 | ReadPointer += 8; |
HB9GAA | 0:3087f1924901 | 104 | ReadPointer &= 0xfff; |
HB9GAA | 0:3087f1924901 | 105 | Theta -= 8; |
HB9GAA | 0:3087f1924901 | 106 | } |
HB9GAA | 0:3087f1924901 | 107 | |
HB9GAA | 0:3087f1924901 | 108 | |
HB9GAA | 0:3087f1924901 | 109 | // Funktion um den Zirkular-Speicher von der SD Karte zu laden |
HB9GAA | 0:3087f1924901 | 110 | //------------------------------------------------------------------------------------------------------------ |
HB9GAA | 0:3087f1924901 | 111 | void FillBuffer(void) |
HB9GAA | 0:3087f1924901 | 112 | { |
HB9GAA | 0:3087f1924901 | 113 | while(!feof(fp)) |
HB9GAA | 0:3087f1924901 | 114 | { //füllt den Zirkularspeicher bis zum Ende des Files |
HB9GAA | 0:3087f1924901 | 115 | static volatile int WritePointer = 0; |
HB9GAA | 0:3087f1924901 | 116 | if(Theta < 4096) |
HB9GAA | 0:3087f1924901 | 117 | { |
HB9GAA | 0:3087f1924901 | 118 | fread(&RingBuffer[WritePointer], 4, 4, fp); //liest 4 integer Werte auf einmal in den Zirzularspeicher |
HB9GAA | 0:3087f1924901 | 119 | Theta += 4; |
HB9GAA | 0:3087f1924901 | 120 | WritePointer += 4; |
HB9GAA | 0:3087f1924901 | 121 | WritePointer &= 0xfff; |
HB9GAA | 0:3087f1924901 | 122 | } |
HB9GAA | 0:3087f1924901 | 123 | } |
HB9GAA | 0:3087f1924901 | 124 | } |
HB9GAA | 0:3087f1924901 | 125 | |
HB9GAA | 0:3087f1924901 | 126 | |
HB9GAA | 0:3087f1924901 | 127 | // Interruptroutine für die Abfrage der Reed Kontakte (LOW aktiv) |
HB9GAA | 0:3087f1924901 | 128 | //------------------------------------------------------------------------------------------------------------ |
HB9GAA | 0:3087f1924901 | 129 | void ReedClosed() |
HB9GAA | 0:3087f1924901 | 130 | { |
HB9GAA | 0:3087f1924901 | 131 | wait_ms(DEBOUNCING_INTERVAL); |
HB9GAA | 0:3087f1924901 | 132 | { |
HB9GAA | 0:3087f1924901 | 133 | if((Reed1 == 0 || Reed2 == 0 || Reed3 == 0 || Reed4 == 0 || Reed5 == 0) && (AnsagePlay == false)) |
HB9GAA | 0:3087f1924901 | 134 | { |
HB9GAA | 0:3087f1924901 | 135 | AnsagePlay = true; //eine Ansage ist zum abspielen bereit |
HB9GAA | 0:3087f1924901 | 136 | |
HB9GAA | 0:3087f1924901 | 137 | if(Reed1 == 0) AnsageNr = 0; //Ansage Nr 1 Endstation Restaurant |
HB9GAA | 0:3087f1924901 | 138 | else if(Reed2 == 0) AnsageNr = 1; //Ansage Nr 2 Löwengehege |
HB9GAA | 0:3087f1924901 | 139 | else if(Reed3 == 0) AnsageNr = 2; //Ansage Nr 3 Regenwald |
HB9GAA | 0:3087f1924901 | 140 | else if(Reed4 == 0) AnsageNr = 3; //Ansage Nr 4 Schweizer Tiere |
HB9GAA | 0:3087f1924901 | 141 | else if(Reed5 == 0) AnsageNr = 4; //Ansage Nr 5 Endstation Streichelzoo |
HB9GAA | 0:3087f1924901 | 142 | |
HB9GAA | 0:3087f1924901 | 143 | pc.printf("%s\n",AnzeigeText[AnsageNr]);//zur Kontrolle den Text auch auf der serielle Schnittstelle ausgeben |
HB9GAA | 0:3087f1924901 | 144 | lcd.cls(); //LC-Display löschen |
HB9GAA | 0:3087f1924901 | 145 | lcd.printf("%s",AnzeigeText[AnsageNr]); //Bahnhoftext auf LCD ausgeben |
HB9GAA | 0:3087f1924901 | 146 | } |
HB9GAA | 0:3087f1924901 | 147 | } |
HB9GAA | 0:3087f1924901 | 148 | } |
HB9GAA | 0:3087f1924901 | 149 | |
HB9GAA | 0:3087f1924901 | 150 | |
HB9GAA | 0:3087f1924901 | 151 | // Hauptprogramm (hier beginnt der Programmablauf, "main" muss immer existieren) |
HB9GAA | 0:3087f1924901 | 152 | //--------------------------------------------------------------------------------------------------------------------------------------- |
HB9GAA | 0:3087f1924901 | 153 | int main(int argc, char *argv[]) |
HB9GAA | 0:3087f1924901 | 154 | { |
HB9GAA | 0:3087f1924901 | 155 | pc.baud(115200); |
HB9GAA | 0:3087f1924901 | 156 | |
HB9GAA | 0:3087f1924901 | 157 | audio.power(0x02); //Mikrofon aus |
HB9GAA | 0:3087f1924901 | 158 | audio.inputVolume(0.2, 0.2); //Eingangspegel 0.0 bis 1.0 (leftVolumeIn, rightVolumeIn) |
HB9GAA | 0:3087f1924901 | 159 | audio.outputVolume(0.5, 0.5); //Ausgangspegel 0.0 bis 1.0 (leftVolumeOut, rightVolumeOut) |
HB9GAA | 0:3087f1924901 | 160 | audio.frequency(44100); //8kHz, 8.021kHz, 32kHz, 44.1kHz, 48kHz, 88.2kHz, 96kHz -> Default ist 44.1kHz |
HB9GAA | 0:3087f1924901 | 161 | audio.attach(&isr_audio); //Interrupt für die I2SxxFIFOs |
HB9GAA | 0:3087f1924901 | 162 | |
HB9GAA | 0:3087f1924901 | 163 | Reed1.mode(PullUp); Reed1.fall(ReedClosed); |
HB9GAA | 0:3087f1924901 | 164 | Reed2.mode(PullUp); Reed2.fall(ReedClosed); |
HB9GAA | 0:3087f1924901 | 165 | Reed3.mode(PullUp); Reed3.fall(ReedClosed); |
HB9GAA | 0:3087f1924901 | 166 | Reed4.mode(PullUp); Reed4.fall(ReedClosed); |
HB9GAA | 0:3087f1924901 | 167 | Reed5.mode(PullUp); Reed5.fall(ReedClosed); |
HB9GAA | 0:3087f1924901 | 168 | |
HB9GAA | 0:3087f1924901 | 169 | pc.printf("--------------------\nSTART\n--------------------\n\n"); // "START" auf erste Zeile schreiben |
HB9GAA | 0:3087f1924901 | 170 | wait(2); // 2s warten |
HB9GAA | 0:3087f1924901 | 171 | |
HB9GAA | 0:3087f1924901 | 172 | // t.start(); //Timer start |
HB9GAA | 0:3087f1924901 | 173 | |
HB9GAA | 0:3087f1924901 | 174 | while(1) |
HB9GAA | 0:3087f1924901 | 175 | { |
HB9GAA | 0:3087f1924901 | 176 | if (AnsagePlay == true) |
HB9GAA | 0:3087f1924901 | 177 | { |
HB9GAA | 0:3087f1924901 | 178 | // audio.start(TRANSMIT); //Interrupt starten (NONE, nur TRANSMIT, nur RECEIVE, BOTH) |
HB9GAA | 0:3087f1924901 | 179 | pc.printf("%s\n\n",AnsageAudio[AnsageNr]); |
HB9GAA | 0:3087f1924901 | 180 | |
HB9GAA | 0:3087f1924901 | 181 | fp = fopen(AnsageAudio[AnsageNr],"rb"); |
HB9GAA | 0:3087f1924901 | 182 | |
HB9GAA | 0:3087f1924901 | 183 | if(!fp) return(printf("File Error\n")); |
HB9GAA | 0:3087f1924901 | 184 | |
HB9GAA | 0:3087f1924901 | 185 | fseek(fp, 22, SEEK_SET); fread(&Channels, 2, 1, fp); //Parse WAV File Header |
HB9GAA | 0:3087f1924901 | 186 | fseek(fp, 24, SEEK_SET); fread(&SampleRate, 4, 1, fp); |
HB9GAA | 0:3087f1924901 | 187 | fseek(fp, 34, SEEK_SET); fread(&WordWidth, 2, 1, fp); |
HB9GAA | 0:3087f1924901 | 188 | audio.format(WordWidth, (2-Channels)); //setzen des Transferprotokoll |
HB9GAA | 0:3087f1924901 | 189 | |
HB9GAA | 0:3087f1924901 | 190 | for(int j = 0; j < 4096; ++j) //RingSpeicher löschen |
HB9GAA | 0:3087f1924901 | 191 | { |
HB9GAA | 0:3087f1924901 | 192 | RingBuffer[j] = 0; //Zirkularspeicher löschen |
HB9GAA | 0:3087f1924901 | 193 | } |
HB9GAA | 0:3087f1924901 | 194 | |
HB9GAA | 0:3087f1924901 | 195 | SetVolume(); //Ausgangspegel vom Potentiometer lesen (leftVolumeOut, rightVolumeOut) |
HB9GAA | 0:3087f1924901 | 196 | audio.start(TRANSMIT); //Interrupt kommt nur vom I2STXFIFO |
HB9GAA | 0:3087f1924901 | 197 | FillBuffer(); //kontinuierlich den Zirkularspeicher füllen |
HB9GAA | 0:3087f1924901 | 198 | audio.stop(); |
HB9GAA | 0:3087f1924901 | 199 | fclose(fp); |
HB9GAA | 0:3087f1924901 | 200 | AnsagePlay = false; |
HB9GAA | 0:3087f1924901 | 201 | } |
HB9GAA | 0:3087f1924901 | 202 | } |
HB9GAA | 0:3087f1924901 | 203 | } |
HB9GAA | 0:3087f1924901 | 204 |