📄 dac_wm8711.c
字号:
/*= dac_wm8711.c ===============================================================
*
* Copyright (C) 2005 Nordic Semiconductor
*
* This file is distributed in the hope that it will be useful, but WITHOUT
* WARRANTY OF ANY KIND.
*
* Author(s): Borge Strand
*
* Description:
*
* DAC specific code for Wolfson WM8711
* This file must be ported to any other DAC to be used.
* It must implement all functions in dac.h
* All defines specific to WM8711 reside in this file!
*
* Compiler: Tested with WinAVR, avr-gcc (GCC) 3.4.3
*
* Revision: 2.0
*
*==============================================================================
*/
#include "dac.h"
// Some forward declarations of functions that are not available externally
char dac_setvolume(void);
// Write a single byte to the DAC across the 2w interface on ARX.
char dac_singlewrite(char adr, char data) {
char temp = z1_flagready(RXEXEC); // Check if TX is ready
if (temp==OKAY) { // Is TX ready to convey data?
// Set up a transfer from MCU through ATX and ARX to DAC
z1_singlewrite(RXDCMD, 0x02); // Data for RXDCMD, 2-wire at RX, 2-wire start/stop, 100kb/s
z1_singlewrite(RXWCNT, 0x03); // Data for RXWCNT, sending 3 bytes to DAC
z1_singlewrite(RXRCNT, 0x00); // Data for RXRCNT, reading 0 bytes from DAC
z1_singlewrite(RXBUF_0, 0b00110100); // Data for RXBUF_0, 2-w hardware adr. of WM8711, r/_w = "0"
z1_singlewrite(RXBUF_1, adr); // Data for RXBUF_1, address and bit 8 of data
z1_singlewrite(RXBUF_2, data); // Data for RXBUF_2, bits 7 through 0 of data
z1_setflag(RXEXEC); // Execute transfer to RX
}
#ifdef DEBUGDAC
db_putenter(); // Sending data to DAC
mcu_putchar('D'); // No readback, say "D"
db_puthex(adr);
mcu_putchar(' ');
db_puthex(data);
mcu_putchar(' ');
db_puthex(temp);
#endif
return temp; // Say whether or not nRF24Z1 was ready for transfer
}
// Set up the DAC
char dac_init(void) {
#ifdef ARXDEVBOARD // ARX is development board, don't do any DAC stuff
return OKAY;
#else // ARX is Headphone reference design, initialize DAC
extern unsigned char volume;
extern char bass;
char error;
if (volume == 0xFF) volume = 0x60; // If volume wasn't properly initiated in main_optionX.c, set it conveniently
if (bass == 0xFF) bass = 0x00; // If bass wasn't properly initiated in main_optionX.c, set it conveniently
error = dac_singlewrite(0b00011110, 0b00000000); // Resetting DAC before continuing with init, page 20
if (error != OKAY) {
#ifdef DEBUGDAC
mcu_putchar('t');
#endif
return error;
}
error = dac_singlewrite(0b00001110, 0b00010010); // Slave mode, I2S, 16 bits, page 26
if (error != OKAY) {
#ifdef DEBUGDAC
mcu_putchar('u');
#endif
return error;
}
error = dac_singlewrite(0b00010000, 0b00100000); // 256x at 44.1ksps, page 26?
// error = dac_singlewrite(0b00010000, 0b00000000); // 256x at 32ksps, page 26?
if (error != OKAY) {
#ifdef DEBUGDAC
mcu_putchar('v');
#endif
return error;
}
error = dac_singlewrite(0b00010010, 0b00000001); // Activate digital interface, page 31
if (error != OKAY) {
#ifdef DEBUGDAC
mcu_putchar('x');
#endif
return error;
}
error = dac_wake();
if (error != OKAY) {
#ifdef DEBUGDAC
mcu_putchar('y');
#endif
}
return error;
#endif
}
// Increase volume
char dac_volume_up(void) {
#ifdef ARXDEVBOARD // ARX is development board, don't do any DAC stuff
return OKAY;
#else // ARX is Headphone reference design, change DAC volume
extern unsigned char volume; // Global variable
if (volume < 0x7F) // On WM8711, 0x7F is highest volume, 0x30 is lowest
volume++;
return dac_setvolume(); // Write the new volume setting to DAC
#endif
}
// Decrease volume
char dac_volume_down(void) {
#ifdef ARXDEVBOARD // ARX is development board, don't do any DAC stuff
return OKAY;
#else // ARX is Headphone reference design, change DAC volume
extern unsigned char volume; // Global variable
if (volume > 0x30) // On WM8711, 0x7F is highest volume, 0x30 is lowest
volume--;
return dac_setvolume(); // Write the new volume setting to DAC
#endif
}
// Transmit volume information
char dac_setvolume(void) {
extern unsigned char volume;
return dac_singlewrite(0b00000101, volume | 0x80); // Address and content for WM8711 volume control
}
//Bass boost not implemented on WM8711. But DAC-indipendant main() may call it!
char dac_bass_boost(void) {
extern char bass; // Global variable like the one used for volume
return OKAY; // bass_boost() does nothing for this DAC!
}
// Put the DAC into sleep mode to save current in ARX
char dac_sleep(void) {
#ifdef ARXDEVBOARD // ARX is development board, don't do any DAC stuff
return OKAY;
#else // ARX is Headphone reference design, put DAC to sleep
dac_singlewrite(0b00001010, 0b00001000); // Enable mute, disable de-emphasis, page 15
return dac_singlewrite(0b00001100, 0b01111111); // Power down CLKOUT, oscillator, output, and DAC
#endif
}
// Wake the DAC up after sleep mode
char dac_wake(void) {
#ifdef ARXDEVBOARD // ARX is development board, don't do any DAC stuff
return OKAY;
#else // ARX is Headphone reference design, wake up DAC
char error;
error = dac_singlewrite(0b00001000, 0b00010000); // 1 Select DAC, page 17. It has to be put in here and not in dac_init()
if (error != OKAY) {
#ifdef DEBUGDAC
mcu_putchar('l');
#endif
return error;
}
error = dac_singlewrite(0b00001100, 0b01100111); // 2 Power down CLKOUT and oscillator, enable output, DAC, and VMID page 33
if (error != OKAY) {
#ifdef DEBUGDAC
mcu_putchar('m');
#endif
return error;
}
error = dac_singlewrite(0b00001010, 0b00000000); // 3 Disable mute, disable de-emphasis, page 15
if (error != OKAY) {
#ifdef DEBUGDAC
mcu_putchar('n');
#endif
return error;
}
error = dac_singlewrite(0b00001100, 0b01100111); // 2 Must be executed again because of unknown Wolfson error
if (error != OKAY) {
#ifdef DEBUGDAC
mcu_putchar('o');
#endif
return error;
}
error = dac_setvolume(); // Reset volume
if (error != OKAY) {
#ifdef DEBUGDAC
mcu_putchar('p');
#endif
}
return error;
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -