STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
wm8994.c
Go to the documentation of this file.
1 
38 /* Includes ------------------------------------------------------------------*/
39 #include "wm8994.h"
40 
66 /* Uncomment this line to enable verifying data sent to codec after each write
67  operation (for debug purpose) */
68 #if !defined (VERIFY_WRITTENDATA)
69 /*#define VERIFY_WRITTENDATA*/
70 #endif /* VERIFY_WRITTENDATA */
71 
87 /* Audio codec driver structure initialization */
89 {
93 
97  wm8994_Stop,
98 
103 
105 };
106 
107 static uint32_t outputEnabled = 0;
108 static uint32_t inputEnabled = 0;
116 static uint8_t CODEC_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value);
136 uint32_t wm8994_Init(uint16_t DeviceAddr, uint16_t OutputInputDevice, uint8_t Volume, uint32_t AudioFreq)
137 {
138  uint32_t counter = 0;
139  uint16_t output_device = OutputInputDevice & 0xFF;
140  uint16_t input_device = OutputInputDevice & 0xFF00;
141  uint16_t power_mgnt_reg_1 = 0;
142 
143  /* Initialize the Control interface of the Audio Codec */
144  AUDIO_IO_Init();
145  /* wm8994 Errata Work-Arounds */
146  counter += CODEC_IO_Write(DeviceAddr, 0x102, 0x0003);
147  counter += CODEC_IO_Write(DeviceAddr, 0x817, 0x0000);
148  counter += CODEC_IO_Write(DeviceAddr, 0x102, 0x0000);
149 
150  /* Enable VMID soft start (fast), Start-up Bias Current Enabled */
151  counter += CODEC_IO_Write(DeviceAddr, 0x39, 0x006C);
152 
153  /* Enable bias generator, Enable VMID */
154  if (input_device > 0)
155  {
156  counter += CODEC_IO_Write(DeviceAddr, 0x01, 0x0013);
157  }
158  else
159  {
160  counter += CODEC_IO_Write(DeviceAddr, 0x01, 0x0003);
161  }
162 
163  /* Add Delay */
164  AUDIO_IO_Delay(50);
165 
166  /* Path Configurations for output */
167  if (output_device > 0)
168  {
169  outputEnabled = 1;
170  switch (output_device)
171  {
173  /* Enable DAC1 (Left), Enable DAC1 (Right),
174  Disable DAC2 (Left), Disable DAC2 (Right)*/
175  counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0C0C);
176 
177  /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
178  counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0000);
179 
180  /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
181  counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0000);
182 
183  /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
184  counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
185 
186  /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
187  counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
188  break;
189 
191  /* Disable DAC1 (Left), Disable DAC1 (Right),
192  Enable DAC2 (Left), Enable DAC2 (Right)*/
193  counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
194 
195  /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
196  counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
197 
198  /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
199  counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
200 
201  /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
202  counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
203 
204  /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
205  counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
206  break;
207 
208  case OUTPUT_DEVICE_BOTH:
209  if (input_device == INPUT_DEVICE_DIGITAL_MIC1_MIC2)
210  {
211  /* Enable DAC1 (Left), Enable DAC1 (Right),
212  also Enable DAC2 (Left), Enable DAC2 (Right)*/
213  counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303 | 0x0C0C);
214 
215  /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path
216  Enable the AIF1 Timeslot 1 (Left) to DAC 1 (Left) mixer path */
217  counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0003);
218 
219  /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path
220  Enable the AIF1 Timeslot 1 (Right) to DAC 1 (Right) mixer path */
221  counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0003);
222 
223  /* Enable the AIF1 Timeslot 0 (Left) to DAC 2 (Left) mixer path
224  Enable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
225  counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0003);
226 
227  /* Enable the AIF1 Timeslot 0 (Right) to DAC 2 (Right) mixer path
228  Enable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
229  counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0003);
230  }
231  else
232  {
233  /* Enable DAC1 (Left), Enable DAC1 (Right),
234  also Enable DAC2 (Left), Enable DAC2 (Right)*/
235  counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303 | 0x0C0C);
236 
237  /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
238  counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
239 
240  /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
241  counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
242 
243  /* Enable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
244  counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
245 
246  /* Enable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
247  counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
248  }
249  break;
250 
251  case OUTPUT_DEVICE_AUTO :
252  default:
253  /* Disable DAC1 (Left), Disable DAC1 (Right),
254  Enable DAC2 (Left), Enable DAC2 (Right)*/
255  counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
256 
257  /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
258  counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
259 
260  /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
261  counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
262 
263  /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
264  counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
265 
266  /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
267  counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
268  break;
269  }
270  }
271  else
272  {
273  outputEnabled = 0;
274  }
275 
276  /* Path Configurations for input */
277  if (input_device > 0)
278  {
279  inputEnabled = 1;
280  switch (input_device)
281  {
283  /* Enable AIF1ADC2 (Left), Enable AIF1ADC2 (Right)
284  * Enable DMICDAT2 (Left), Enable DMICDAT2 (Right)
285  * Enable Left ADC, Enable Right ADC */
286  counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x0C30);
287 
288  /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC2 Left/Right Timeslot 1 */
289  counter += CODEC_IO_Write(DeviceAddr, 0x450, 0x00DB);
290 
291  /* Disable IN1L, IN1R, IN2L, IN2R, Enable Thermal sensor & shutdown */
292  counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x6000);
293 
294  /* Enable the DMIC2(Left) to AIF1 Timeslot 1 (Left) mixer path */
295  counter += CODEC_IO_Write(DeviceAddr, 0x608, 0x0002);
296 
297  /* Enable the DMIC2(Right) to AIF1 Timeslot 1 (Right) mixer path */
298  counter += CODEC_IO_Write(DeviceAddr, 0x609, 0x0002);
299 
300  /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC2 signal detect */
301  counter += CODEC_IO_Write(DeviceAddr, 0x700, 0x000E);
302  break;
303 
305  /* IN1LN_TO_IN1L, IN1LP_TO_VMID, IN1RN_TO_IN1R, IN1RP_TO_VMID */
306  counter += CODEC_IO_Write(DeviceAddr, 0x28, 0x0011);
307 
308  /* Disable mute on IN1L_TO_MIXINL and +30dB on IN1L PGA output */
309  counter += CODEC_IO_Write(DeviceAddr, 0x29, 0x0035);
310 
311  /* Disable mute on IN1R_TO_MIXINL, Gain = +30dB */
312  counter += CODEC_IO_Write(DeviceAddr, 0x2A, 0x0035);
313 
314  /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
315  * Enable Left ADC, Enable Right ADC */
316  counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x0303);
317 
318  /* Enable AIF1 DRC1 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
319  counter += CODEC_IO_Write(DeviceAddr, 0x440, 0x00DB);
320 
321  /* Enable IN1L and IN1R, Disable IN2L and IN2R, Enable Thermal sensor & shutdown */
322  counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x6350);
323 
324  /* Enable the ADCL(Left) to AIF1 Timeslot 0 (Left) mixer path */
325  counter += CODEC_IO_Write(DeviceAddr, 0x606, 0x0002);
326 
327  /* Enable the ADCR(Right) to AIF1 Timeslot 0 (Right) mixer path */
328  counter += CODEC_IO_Write(DeviceAddr, 0x607, 0x0002);
329 
330  /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
331  counter += CODEC_IO_Write(DeviceAddr, 0x700, 0x000D);
332  break;
333 
335  /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
336  * Enable DMICDAT1 (Left), Enable DMICDAT1 (Right)
337  * Enable Left ADC, Enable Right ADC */
338  counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x030C);
339 
340  /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
341  counter += CODEC_IO_Write(DeviceAddr, 0x440, 0x00DB);
342 
343  /* Disable IN1L, IN1R, IN2L, IN2R, Enable Thermal sensor & shutdown */
344  counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x6350);
345 
346  /* Enable the DMIC2(Left) to AIF1 Timeslot 0 (Left) mixer path */
347  counter += CODEC_IO_Write(DeviceAddr, 0x606, 0x0002);
348 
349  /* Enable the DMIC2(Right) to AIF1 Timeslot 0 (Right) mixer path */
350  counter += CODEC_IO_Write(DeviceAddr, 0x607, 0x0002);
351 
352  /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
353  counter += CODEC_IO_Write(DeviceAddr, 0x700, 0x000D);
354  break;
356  /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
357  * Enable DMICDAT1 (Left), Enable DMICDAT1 (Right)
358  * Enable Left ADC, Enable Right ADC */
359  counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x0F3C);
360 
361  /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC2 Left/Right Timeslot 1 */
362  counter += CODEC_IO_Write(DeviceAddr, 0x450, 0x00DB);
363 
364  /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
365  counter += CODEC_IO_Write(DeviceAddr, 0x440, 0x00DB);
366 
367  /* Disable IN1L, IN1R, Enable IN2L, IN2R, Thermal sensor & shutdown */
368  counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x63A0);
369 
370  /* Enable the DMIC2(Left) to AIF1 Timeslot 0 (Left) mixer path */
371  counter += CODEC_IO_Write(DeviceAddr, 0x606, 0x0002);
372 
373  /* Enable the DMIC2(Right) to AIF1 Timeslot 0 (Right) mixer path */
374  counter += CODEC_IO_Write(DeviceAddr, 0x607, 0x0002);
375 
376  /* Enable the DMIC2(Left) to AIF1 Timeslot 1 (Left) mixer path */
377  counter += CODEC_IO_Write(DeviceAddr, 0x608, 0x0002);
378 
379  /* Enable the DMIC2(Right) to AIF1 Timeslot 1 (Right) mixer path */
380  counter += CODEC_IO_Write(DeviceAddr, 0x609, 0x0002);
381 
382  /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
383  counter += CODEC_IO_Write(DeviceAddr, 0x700, 0x000D);
384  break;
386  default:
387  /* Actually, no other input devices supported */
388  counter++;
389  break;
390  }
391  }
392  else
393  {
394  inputEnabled = 0;
395  }
396 
397  /* Clock Configurations */
398  switch (AudioFreq)
399  {
400  case AUDIO_FREQUENCY_8K:
401  /* AIF1 Sample Rate = 8 (KHz), ratio=256 */
402  counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0003);
403  break;
404 
405  case AUDIO_FREQUENCY_16K:
406  /* AIF1 Sample Rate = 16 (KHz), ratio=256 */
407  counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0033);
408  break;
409 
410  case AUDIO_FREQUENCY_32K:
411  /* AIF1 Sample Rate = 32 (KHz), ratio=256 */
412  counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0063);
413  break;
414 
415  case AUDIO_FREQUENCY_48K:
416  /* AIF1 Sample Rate = 48 (KHz), ratio=256 */
417  counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
418  break;
419 
420  case AUDIO_FREQUENCY_96K:
421  /* AIF1 Sample Rate = 96 (KHz), ratio=256 */
422  counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x00A3);
423  break;
424 
425  case AUDIO_FREQUENCY_11K:
426  /* AIF1 Sample Rate = 11.025 (KHz), ratio=256 */
427  counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0013);
428  break;
429 
430  case AUDIO_FREQUENCY_22K:
431  /* AIF1 Sample Rate = 22.050 (KHz), ratio=256 */
432  counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0043);
433  break;
434 
435  case AUDIO_FREQUENCY_44K:
436  /* AIF1 Sample Rate = 44.1 (KHz), ratio=256 */
437  counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0073);
438  break;
439 
440  default:
441  /* AIF1 Sample Rate = 48 (KHz), ratio=256 */
442  counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
443  break;
444  }
445 
446  if(input_device == INPUT_DEVICE_DIGITAL_MIC1_MIC2)
447  {
448  /* AIF1 Word Length = 16-bits, AIF1 Format = DSP mode */
449  counter += CODEC_IO_Write(DeviceAddr, 0x300, 0x4018);
450  //counter += CODEC_IO_Write(DeviceAddr, 0x300, 0x4078); //ADC channel, 32bit, I2S
451  }
452  else
453  {
454  /* AIF1 Word Length = 16-bits, AIF1 Format = I2S (Default Register Value) */
455  counter += CODEC_IO_Write(DeviceAddr, 0x300, 0x4010);
456  //counter += CODEC_IO_Write(DeviceAddr, 0x300, 0x4070); //ADC channel, 32bit, I2S
457  }
458 
459  /* slave mode */
460  counter += CODEC_IO_Write(DeviceAddr, 0x302, 0x0000);
461 
462  /* Enable the DSP processing clock for AIF1, Enable the core clock */
463  counter += CODEC_IO_Write(DeviceAddr, 0x208, 0x000A);
464 
465  /* Enable AIF1 Clock, AIF1 Clock Source = MCLK1 pin */
466  counter += CODEC_IO_Write(DeviceAddr, 0x200, 0x0001);
467 
468  if (output_device > 0) /* Audio output selected */
469  {
470  /* Analog Output Configuration */
471 
472  /* Enable SPKRVOL PGA, Enable SPKMIXR, Enable SPKLVOL PGA, Enable SPKMIXL */
473  counter += CODEC_IO_Write(DeviceAddr, 0x03, 0x0300);
474 
475  /* Left Speaker Mixer Volume = 0dB */
476  counter += CODEC_IO_Write(DeviceAddr, 0x22, 0x0000);
477 
478  /* Speaker output mode = Class D, Right Speaker Mixer Volume = 0dB ((0x23, 0x0100) = class AB)*/
479 #ifdef AMP_CLASS_AB
480  counter += CODEC_IO_Write(DeviceAddr, 0x23, 0x0100); //Class-AB
481  counter += CODEC_IO_Write(DeviceAddr, 0x22, 0x0000); //Class-AB Referencer: 0 = SLKVDD/2, 0x0100 = VMID
482 #else
483  counter += CODEC_IO_Write(DeviceAddr, 0x23, 0x0000); //Class-D
484 #endif
485 
486  /* Unmute DAC2 (Left) to Left Speaker Mixer (SPKMIXL) path,
487  Unmute DAC2 (Right) to Right Speaker Mixer (SPKMIXR) path */
488  counter += CODEC_IO_Write(DeviceAddr, 0x36, 0x0300);
489 
490  /* Enable bias generator, Enable VMID, Enable SPKOUTL, Enable SPKOUTR */
491  counter += CODEC_IO_Write(DeviceAddr, 0x01, 0x3003);
492 
493  /* Headphone/Speaker Enable */
494 
495  if (input_device == INPUT_DEVICE_DIGITAL_MIC1_MIC2)
496  {
497  /* Enable Class W, Class W Envelope Tracking = AIF1 Timeslots 0 and 1 */
498  counter += CODEC_IO_Write(DeviceAddr, 0x51, 0x0205);
499  }
500  else
501  {
502  /* Enable Class W, Class W Envelope Tracking = AIF1 Timeslot 0 */
503  counter += CODEC_IO_Write(DeviceAddr, 0x51, 0x0005);
504  }
505 
506  /* Enable bias generator, Enable VMID, Enable HPOUT1 (Left) and Enable HPOUT1 (Right) input stages */
507  /* idem for Speaker */
508  power_mgnt_reg_1 |= 0x0303 | 0x3003;
509  counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1);
510 
511  /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate stages */
512  counter += CODEC_IO_Write(DeviceAddr, 0x60, 0x0022);
513 
514  /* Enable Charge Pump */
515  counter += CODEC_IO_Write(DeviceAddr, 0x4C, 0x9F25);
516 
517  /* Add Delay */
518  AUDIO_IO_Delay(15);
519 
520  /* Select DAC1 (Left) to Left Headphone Output PGA (HPOUT1LVOL) path */
521  counter += CODEC_IO_Write(DeviceAddr, 0x2D, 0x0001);
522 
523  /* Select DAC1 (Right) to Right Headphone Output PGA (HPOUT1RVOL) path */
524  counter += CODEC_IO_Write(DeviceAddr, 0x2E, 0x0001);
525 
526  /* Enable Left Output Mixer (MIXOUTL), Enable Right Output Mixer (MIXOUTR) */
527  /* idem for SPKOUTL and SPKOUTR */
528  counter += CODEC_IO_Write(DeviceAddr, 0x03, 0x0030 | 0x0300);
529 
530  /* Enable DC Servo and trigger start-up mode on left and right channels */
531  counter += CODEC_IO_Write(DeviceAddr, 0x54, 0x0033);
532 
533  /* Add Delay */
534  AUDIO_IO_Delay(250);
535 
536  /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate and output stages. Remove clamps */
537  counter += CODEC_IO_Write(DeviceAddr, 0x60, 0x00EE);
538 
539  /* Unmutes */
540 
541  /* Unmute DAC 1 (Left) */
542  counter += CODEC_IO_Write(DeviceAddr, 0x610, 0x00C0);
543 
544  /* Unmute DAC 1 (Right) */
545  counter += CODEC_IO_Write(DeviceAddr, 0x611, 0x00C0);
546 
547  /* Unmute the AIF1 Timeslot 0 DAC path */
548  counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0000);
549 
550  /* Unmute DAC 2 (Left) */
551  counter += CODEC_IO_Write(DeviceAddr, 0x612, 0x00C0);
552 
553  /* Unmute DAC 2 (Right) */
554  counter += CODEC_IO_Write(DeviceAddr, 0x613, 0x00C0);
555 
556  /* Unmute the AIF1 Timeslot 1 DAC2 path */
557  counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0000);
558 
559  /* Volume Control */
560  wm8994_SetVolume(DeviceAddr, Volume);
561  }
562 
563  if (input_device > 0) /* Audio input selected */
564  {
565  if ((input_device == INPUT_DEVICE_DIGITAL_MICROPHONE_1) || (input_device == INPUT_DEVICE_DIGITAL_MICROPHONE_2))
566  {
567  /* Enable Microphone bias 1 generator, Enable VMID */
568  power_mgnt_reg_1 |= 0x0013;
569  counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1);
570 
571  /* ADC oversample enable */
572  counter += CODEC_IO_Write(DeviceAddr, 0x620, 0x0002);
573 
574  /* AIF ADC2 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
575  counter += CODEC_IO_Write(DeviceAddr, 0x411, 0x3800);
576  }
577  else if(input_device == INPUT_DEVICE_DIGITAL_MIC1_MIC2)
578  {
579  /* Enable Microphone bias 1 generator, Enable VMID */
580  power_mgnt_reg_1 |= 0x0013;
581  counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1);
582 
583  /* ADC oversample enable */
584  counter += CODEC_IO_Write(DeviceAddr, 0x620, 0x0002);
585 
586  /* AIF ADC1 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
587  counter += CODEC_IO_Write(DeviceAddr, 0x410, 0x1800);
588 
589  /* AIF ADC2 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
590  counter += CODEC_IO_Write(DeviceAddr, 0x411, 0x1800);
591  }
592  else if ((input_device == INPUT_DEVICE_INPUT_LINE_1) || (input_device == INPUT_DEVICE_INPUT_LINE_2))
593  {
594  /* Disable mute on IN1L, IN1L Volume = +0dB */
595  //counter += CODEC_IO_Write(DeviceAddr, 0x18, 0x000B);
596  counter += CODEC_IO_Write(DeviceAddr, 0x18, 0x0009); //XXXX
597 
598  /* Disable mute on IN1R, IN1R Volume = +0dB */
599  counter += CODEC_IO_Write(DeviceAddr, 0x1A, 0x000B);
600 
601  /* Disable mute on IN1L_TO_MIXINL, Gain = +0dB */
602  //counter += CODEC_IO_Write(DeviceAddr, 0x29, 0x0025);
603  //ATT: disable (mute) IN1 feedback to Mixer !
604  counter += CODEC_IO_Write(DeviceAddr, 0x29, 0x0020); //XXXX
605 
606  /* Disable mute on IN1R_TO_MIXINL, Gain = +0dB */
607  //counter += CODEC_IO_Write(DeviceAddr, 0x2A, 0x0025);
608  //ATT: disable (mute) IN1 feedback to Mixer !
609  counter += CODEC_IO_Write(DeviceAddr, 0x2A, 0x0020); //XXXX
610 
611  /* IN1LN_TO_IN1L, IN1LP_TO_VMID, IN1RN_TO_IN1R, IN1RP_TO_VMID */
612  counter += CODEC_IO_Write(DeviceAddr, 0x28, 0x0011); //XXXX
613 
614  /* AIF ADC1 HPF enable, HPF cut = hifi mode fc=4Hz at fs=48kHz */
615  counter += CODEC_IO_Write(DeviceAddr, 0x410, 0x1800);
616  }
617  /* Volume Control */
618  wm8994_SetVolume(DeviceAddr, Volume);
619  }
620  /* Return communication control value */
621  return counter;
622 }
623 
629 void wm8994_DeInit(void)
630 {
631  /* Deinitialize Audio Codec interface */
632  AUDIO_IO_DeInit();
633 }
634 
640 uint32_t wm8994_ReadID(uint16_t DeviceAddr)
641 {
642  /* Initialize the Control interface of the Audio Codec */
643  AUDIO_IO_Init();
644 
645  return ((uint32_t)AUDIO_IO_Read(DeviceAddr, WM8994_CHIPID_ADDR));
646 }
647 
654 uint32_t wm8994_Play(uint16_t DeviceAddr, uint16_t* pBuffer, uint16_t Size)
655 {
656  uint32_t counter = 0;
657 
658  /* Resumes the audio file playing */
659  /* Unmute the output first */
660  counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
661 
662  return counter;
663 }
664 
670 uint32_t wm8994_Pause(uint16_t DeviceAddr)
671 {
672  uint32_t counter = 0;
673 
674  /* Pause the audio file playing */
675  /* Mute the output first */
676  counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_ON);
677 
678  /* Put the Codec in Power save mode */
679  counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x01);
680 
681  return counter;
682 }
683 
689 uint32_t wm8994_Resume(uint16_t DeviceAddr)
690 {
691  uint32_t counter = 0;
692 
693  /* Resumes the audio file playing */
694  /* Unmute the output first */
695  counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
696 
697  return counter;
698 }
699 
713 uint32_t wm8994_Stop(uint16_t DeviceAddr, uint32_t CodecPdwnMode)
714 {
715  uint32_t counter = 0;
716 
717  if (outputEnabled != 0)
718  {
719  /* Mute the output first */
720  counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_ON);
721 
722  if (CodecPdwnMode == CODEC_PDWN_SW)
723  {
724  /* Only output mute required*/
725  }
726  else /* CODEC_PDWN_HW */
727  {
728  /* Mute the AIF1 Timeslot 0 DAC1 path */
729  counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0200);
730 
731  /* Mute the AIF1 Timeslot 1 DAC2 path */
732  counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0200);
733 
734  /* Disable DAC1L_TO_HPOUT1L */
735  counter += CODEC_IO_Write(DeviceAddr, 0x2D, 0x0000);
736 
737  /* Disable DAC1R_TO_HPOUT1R */
738  counter += CODEC_IO_Write(DeviceAddr, 0x2E, 0x0000);
739 
740  /* Disable DAC1 and DAC2 */
741  counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0000);
742 
743  /* Reset Codec by writing in 0x0000 address register */
744  counter += CODEC_IO_Write(DeviceAddr, 0x0000, 0x0000);
745 
746  outputEnabled = 0;
747  }
748  }
749  return counter;
750 }
751 
759 uint32_t wm8994_SetVolume(uint16_t DeviceAddr, uint8_t Volume)
760 {
761  uint32_t counter = 0;
762  uint8_t convertedvol = VOLUME_CONVERT(Volume);
763 
764  /* Output volume */
765  if (outputEnabled != 0)
766  {
767  if(convertedvol > 0x3E)
768  {
769  /* Unmute audio codec */
770  counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
771 
772  /* Left Headphone Volume */
773  counter += CODEC_IO_Write(DeviceAddr, 0x1C, 0x3F | 0x140);
774 
775  /* Right Headphone Volume */
776  counter += CODEC_IO_Write(DeviceAddr, 0x1D, 0x3F | 0x140);
777 
778  /* Left Speaker Volume */
779  counter += CODEC_IO_Write(DeviceAddr, 0x26, 0x3F | 0x140);
780 
781  /* Right Speaker Volume */
782  counter += CODEC_IO_Write(DeviceAddr, 0x27, 0x3F | 0x140);
783  }
784  else if (Volume == 0)
785  {
786  /* Mute audio codec */
787  counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_ON);
788  }
789  else
790  {
791  /* Unmute audio codec */
792  counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
793 
794  /* Left Headphone Volume */
795  counter += CODEC_IO_Write(DeviceAddr, 0x1C, convertedvol | 0x140);
796 
797  /* Right Headphone Volume */
798  counter += CODEC_IO_Write(DeviceAddr, 0x1D, convertedvol | 0x140);
799 
800  /* Left Speaker Volume */
801  counter += CODEC_IO_Write(DeviceAddr, 0x26, convertedvol | 0x140);
802 
803  /* Right Speaker Volume */
804  counter += CODEC_IO_Write(DeviceAddr, 0x27, convertedvol | 0x140);
805  }
806  }
807 
808  /* Input volume */
809  if (inputEnabled != 0)
810  {
811  convertedvol = VOLUME_IN_CONVERT(Volume);
812 
813  /* Left AIF1 ADC1 volume */
814  counter += CODEC_IO_Write(DeviceAddr, 0x400, convertedvol | 0x100);
815 
816  /* Right AIF1 ADC1 volume */
817  counter += CODEC_IO_Write(DeviceAddr, 0x401, convertedvol | 0x100);
818 
819  /* Left AIF1 ADC2 volume */
820  counter += CODEC_IO_Write(DeviceAddr, 0x404, convertedvol | 0x100);
821 
822  /* Right AIF1 ADC2 volume */
823  counter += CODEC_IO_Write(DeviceAddr, 0x405, convertedvol | 0x100);
824  }
825  return counter;
826 }
827 
835 uint32_t wm8994_SetMute(uint16_t DeviceAddr, uint32_t Cmd)
836 {
837  uint32_t counter = 0;
838 
839  if (outputEnabled != 0)
840  {
841  /* Set the Mute mode */
842  if(Cmd == AUDIO_MUTE_ON)
843  {
844  /* Soft Mute the AIF1 Timeslot 0 DAC1 path L&R */
845  counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0200);
846 
847  /* Soft Mute the AIF1 Timeslot 1 DAC2 path L&R */
848  counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0200);
849  }
850  else /* AUDIO_MUTE_OFF Disable the Mute */
851  {
852  /* Unmute the AIF1 Timeslot 0 DAC1 path L&R */
853  counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0000);
854 
855  /* Unmute the AIF1 Timeslot 1 DAC2 path L&R */
856  counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0000);
857  }
858  }
859  return counter;
860 }
861 
870 uint32_t wm8994_SetOutputMode(uint16_t DeviceAddr, uint8_t Output)
871 {
872  uint32_t counter = 0;
873 
874  switch (Output)
875  {
877  /* Enable DAC1 (Left), Enable DAC1 (Right),
878  Disable DAC2 (Left), Disable DAC2 (Right)*/
879  counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0C0C);
880 
881  /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
882  counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0000);
883 
884  /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
885  counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0000);
886 
887  /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
888  counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
889 
890  /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
891  counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
892  break;
893 
895  /* Disable DAC1 (Left), Disable DAC1 (Right),
896  Enable DAC2 (Left), Enable DAC2 (Right)*/
897  counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
898 
899  /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
900  counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
901 
902  /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
903  counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
904 
905  /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
906  counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
907 
908  /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
909  counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
910  break;
911 
912  case OUTPUT_DEVICE_BOTH:
913  /* Enable DAC1 (Left), Enable DAC1 (Right),
914  also Enable DAC2 (Left), Enable DAC2 (Right)*/
915  counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303 | 0x0C0C);
916 
917  /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
918  counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
919 
920  /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
921  counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
922 
923  /* Enable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
924  counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
925 
926  /* Enable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
927  counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
928  break;
929 
930  default:
931  /* Disable DAC1 (Left), Disable DAC1 (Right),
932  Enable DAC2 (Left), Enable DAC2 (Right)*/
933  counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
934 
935  /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
936  counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
937 
938  /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
939  counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
940 
941  /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
942  counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
943 
944  /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
945  counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
946  break;
947  }
948  return counter;
949 }
950 
957 uint32_t wm8994_SetFrequency(uint16_t DeviceAddr, uint32_t AudioFreq)
958 {
959  uint32_t counter = 0;
960 
961  /* Clock Configurations */
962  switch (AudioFreq)
963  {
964  case AUDIO_FREQUENCY_8K:
965  /* AIF1 Sample Rate = 8 (KHz), ratio=256 */
966  counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0003);
967  break;
968 
969  case AUDIO_FREQUENCY_16K:
970  /* AIF1 Sample Rate = 16 (KHz), ratio=256 */
971  counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0033);
972  break;
973 
974  case AUDIO_FREQUENCY_48K:
975  /* AIF1 Sample Rate = 48 (KHz), ratio=256 */
976  counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
977  break;
978 
979  case AUDIO_FREQUENCY_96K:
980  /* AIF1 Sample Rate = 96 (KHz), ratio=256 */
981  counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x00A3);
982  break;
983 
984  case AUDIO_FREQUENCY_11K:
985  /* AIF1 Sample Rate = 11.025 (KHz), ratio=256 */
986  counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0013);
987  break;
988 
989  case AUDIO_FREQUENCY_22K:
990  /* AIF1 Sample Rate = 22.050 (KHz), ratio=256 */
991  counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0043);
992  break;
993 
994  case AUDIO_FREQUENCY_44K:
995  /* AIF1 Sample Rate = 44.1 (KHz), ratio=256 */
996  counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0073);
997  break;
998 
999  default:
1000  /* AIF1 Sample Rate = 48 (KHz), ratio=256 */
1001  counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
1002  break;
1003  }
1004  return counter;
1005 }
1006 
1012 uint32_t wm8994_Reset(uint16_t DeviceAddr)
1013 {
1014  uint32_t counter = 0;
1015 
1016  /* Reset Codec by writing in 0x0000 address register */
1017  counter = CODEC_IO_Write(DeviceAddr, 0x0000, 0x0000);
1018  outputEnabled = 0;
1019  inputEnabled=0;
1020 
1021  return counter;
1022 }
1023 
1031 static uint8_t CODEC_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value)
1032 {
1033  uint32_t result = 0;
1034 
1035  AUDIO_IO_Write(Addr, Reg, Value);
1036 
1037 #ifdef VERIFY_WRITTENDATA
1038  /* Verify that the data has been correctly written */
1039  result = (AUDIO_IO_Read(Addr, Reg) == Value)? 0:1;
1040 #endif /* VERIFY_WRITTENDATA */
1041 
1042  return result;
1043 }
1044 
1061 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
#define AUDIO_MUTE_ON
Definition: wm8994.h:97
#define VOLUME_CONVERT(Volume)
Definition: wm8994.h:111
#define CODEC_PDWN_SW
Definition: wm8994.h:94
uint32_t wm8994_Play(uint16_t DeviceAddr, uint16_t *pBuffer, uint16_t Size)
Start the audio Codec play feature.
Definition: wm8994.c:654
void wm8994_DeInit(void)
Deinitializes the audio codec.
Definition: wm8994.c:629
#define OUTPUT_DEVICE_BOTH
Definition: wm8994.h:76
void AUDIO_IO_Init(void)
Initializes Audio low level.
#define OUTPUT_DEVICE_AUTO
Definition: wm8994.h:77
#define AUDIO_FREQUENCY_16K
Definition: wm8994.h:107
#define AUDIO_MUTE_OFF
Definition: wm8994.h:98
#define OUTPUT_DEVICE_HEADPHONE
Definition: wm8994.h:75
uint32_t wm8994_SetFrequency(uint16_t DeviceAddr, uint32_t AudioFreq)
Sets new frequency.
Definition: wm8994.c:957
#define INPUT_DEVICE_INPUT_LINE_2
Definition: wm8994.h:81
void AUDIO_IO_DeInit(void)
DeInitializes Audio low level.
#define AUDIO_FREQUENCY_22K
Definition: wm8994.h:106
#define AUDIO_FREQUENCY_48K
Definition: wm8994.h:103
void AUDIO_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value)
Writes a single data.
#define AUDIO_FREQUENCY_11K
Definition: wm8994.h:108
uint32_t wm8994_SetMute(uint16_t DeviceAddr, uint32_t Cmd)
Enables or disables the mute feature on the audio codec.
Definition: wm8994.c:835
This file contains all the functions prototypes for the wm8994.c driver.
#define OUTPUT_DEVICE_SPEAKER
Definition: wm8994.h:74
#define INPUT_DEVICE_DIGITAL_MICROPHONE_2
Definition: wm8994.h:79
#define WM8994_CHIPID_ADDR
Device ID Register: Reading from this register will indicate device family ID 8994h.
Definition: wm8994.h:126
AUDIO_DrvTypeDef wm8994_drv
Definition: wm8994.c:88
uint32_t wm8994_Init(uint16_t DeviceAddr, uint16_t OutputInputDevice, uint8_t Volume, uint32_t AudioFreq)
Initializes the audio codec and the control interface.
Definition: wm8994.c:136
#define AUDIO_FREQUENCY_44K
Definition: wm8994.h:104
#define AUDIO_FREQUENCY_32K
Definition: wm8994.h:105
uint32_t wm8994_SetVolume(uint16_t DeviceAddr, uint8_t Volume)
Sets higher or lower the codec volume level.
Definition: wm8994.c:759
#define INPUT_DEVICE_DIGITAL_MIC1_MIC2
Definition: wm8994.h:82
uint32_t wm8994_Stop(uint16_t DeviceAddr, uint32_t CodecPdwnMode)
Stops audio Codec playing. It powers down the codec.
Definition: wm8994.c:713
uint8_t AUDIO_IO_Read(uint8_t Addr, uint16_t Reg)
Reads a single data.
uint32_t wm8994_Reset(uint16_t DeviceAddr)
Resets wm8994 registers.
Definition: wm8994.c:1012
#define INPUT_DEVICE_DIGITAL_MICROPHONE_1
Definition: wm8994.h:78
uint32_t wm8994_SetOutputMode(uint16_t DeviceAddr, uint8_t Output)
Switch dynamically (while audio file is played) the output target (speaker or headphone).
Definition: wm8994.c:870
void AUDIO_IO_Delay(uint32_t Delay)
AUDIO Codec delay.
uint32_t wm8994_Resume(uint16_t DeviceAddr)
Resumes playing on the audio codec.
Definition: wm8994.c:689
#define INPUT_DEVICE_INPUT_LINE_1
Definition: wm8994.h:80
#define AUDIO_FREQUENCY_8K
Definition: wm8994.h:109
uint32_t wm8994_ReadID(uint16_t DeviceAddr)
Get the WM8994 ID.
Definition: wm8994.c:640
#define VOLUME_IN_CONVERT(Volume)
Definition: wm8994.h:112
#define AUDIO_FREQUENCY_96K
Definition: wm8994.h:102
uint32_t wm8994_Pause(uint16_t DeviceAddr)
Pauses playing on the audio codec.
Definition: wm8994.c:670