From 044ad7c3987460ede48ff27afd6bdb0ca05a0432 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 4 Jul 2011 20:52:54 +0200 Subject: import at91lib from at91lib_20100901_softpack_1_9_v_1_0_svn_v15011 it's sad to see that atmel doesn't publish their svn repo or has a centralized location or even puts proper version/release info into the library itself --- components/dac-at73c213/at73c213.c | 337 +++++++++++++++++++++++++++++++++++++ components/dac-at73c213/at73c213.h | 80 +++++++++ 2 files changed, 417 insertions(+) create mode 100644 components/dac-at73c213/at73c213.c create mode 100644 components/dac-at73c213/at73c213.h (limited to 'components/dac-at73c213') diff --git a/components/dac-at73c213/at73c213.c b/components/dac-at73c213/at73c213.c new file mode 100644 index 0000000..0ace517 --- /dev/null +++ b/components/dac-at73c213/at73c213.c @@ -0,0 +1,337 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include "at73c213.h" +#include +#include +#include +#include + +//------------------------------------------------------------------------------ +// Definitions +//------------------------------------------------------------------------------ +/// \internal Calculates the SSC Transmit Clock Mode Register value given the +/// desired sample size (in bytes) and number of channels. +#define AT73C213_TCMR(sampleSize, numChannels) \ + (AT91C_SSC_CKS_DIV \ + | AT91C_SSC_CKO_DATA_TX \ + | AT91C_SSC_START_FALL_RF \ + | SSC_STTDLY(1) \ + | SSC_PERIOD(sampleSize * 8 * numChannels)) + +/// \internal Calculates the SSC Transmit Frame Mode Register value given the +/// desired sample size (in bytes) and number of channels. +#define AT73C213_TFMR(sampleSize, numChannels) \ + (SSC_DATLEN(sampleSize * 8) \ + | AT91C_SSC_MSBF \ + | SSC_DATNB(numChannels) \ + | SSC_FSLEN(sampleSize * 8) \ + | AT91C_SSC_FSOS_NEGATIVE) + +/// \internal Maximum bitrate of AT73C213 SPI interface +#define AT73C213_SPCK_MAX 250000 + +/// \internal Calculates the SPI chip select configuration, given the system +/// master clock. +#define AT73C213_SPI_NPCSCONFIG(masterClock) \ + (AT91C_SPI_BITS_16 \ + | SPI_SCBR(AT73C213_SPCK_MAX, masterClock) \ + | SPI_DLYBS(50, masterClock) \ + | SPI_DLYBCT(0, masterClock)) + +// DAC user interface register addresses +/// \internal AT73C213 DAC control register address +#define AT73C213_DAC_CTRL 0x00 +/// \internal AT73C213 DAC left line in gain register address +#define AT73C213_DAC_LLIG 0x01 +/// \internal AT73C213 DAC right line in gain register address +#define AT73C213_DAC_RLIG 0x02 +/// \internal AT73C213 DAC left master playback gain register address +#define AT73C213_DAC_LMPG 0x03 +/// \internal AT73C213 DAC right master playback gain register address +#define AT73C213_DAC_RMPG 0x04 +/// \internal AT73C213 DAC left line out gain register address +#define AT73C213_DAC_LLOG 0x05 +/// \internal AT73C213 DAC right line out gain register address +#define AT73C213_DAC_RLOG 0x06 +/// \internal AT73C213 DAC output level control register address +#define AT73C213_DAC_OLC 0x07 +/// \internal AT73C213 DAC mixer control register address +#define AT73C213_DAC_MC 0x08 +/// \internal AT73C213 DAC clock and sampling frequency control register address +#define AT73C213_DAC_CSFC 0x09 +/// \internal AT73C213 DAC miscellaneous register address +#define AT73C213_DAC_MISC 0x0A +/// \internal AT73C213 DAC precharge control register address +#define AT73C213_DAC_PRECH 0x0C +/// \internal AT73C213 DAC auxiliary input gain control register address +#define AT73C213_DAC_AUXG 0x0D +/// \internal AT73C213 DAC reset register address +#define AT73C213_DAC_RST 0x10 +/// \internal AT73C213 power amplifier control register address +#define AT73C213_PA_CTRL 0x11 + +// Register field values +// DAC_CTRL +/// \internal Left channel line in amplifier enable +#define AT73C213_DAC_CTRL_ONLNIL (1 << 0) +/// \internal Right channel line in amplifier enable +#define AT73C213_DAC_CTRL_ONLNIR (1 << 1) +/// \internal Left channel line out driver enable +#define AT73C213_DAC_CTRL_ONLNOL (1 << 2) +/// \internal Right channel line out driver enable +#define AT73C213_DAC_CTRL_ONLNOR (1 << 3) +/// \internal Left channel DAC enable +#define AT73C213_DAC_CTRL_ONDACL (1 << 4) +/// \internal Right channel DAC enable +#define AT73C213_DAC_CTRL_ONDACR (1 << 5) +/// \internal Differential mono auxiliary input amplifier enable +#define AT73C213_DAC_CTRL_ONAUXIN (1 << 6) +/// \internal Differential mono power amplifier driver enable +#define AT73C213_DAC_CTRL_ONPADRV (1 << 7) + +// DAC_LLOG +/// \internal Digital gain of 0dB +#define AT73C213_DAC_LLOG_GAIN_0 0x00 +/// \internal Digital gain of -10.5dB +#define AT73C213_DAC_LLOG_GAIN_10_5N 0x07 +/// \internal Channel muted +#define AT73C213_DAC_LLOG_GAIN_MUTE 0x3F + +// DAC_RLOG +/// \internal Digital gain of 0dB +#define AT73C213_DAC_RLOG_GAIN_0 0x00 +/// \internal Digital gain of -10.5dB +#define AT73C213_DAC_RLOG_GAIN_10_5N 0x07 +/// \internal Channel muted +#define AT73C213_DAC_RLOG_GAIN_MUTE 0x3F + +// DAC_CSFC +/// \internal Master clock selector +#define AT73C213_DAC_CSFC_OVRSEL (1 << 4) + +// DAC_PRECH +/// \internal Master power on control +#define AT73C213_DAC_PRECH_ONMSTR (1 << 0) +/// \internal Precharge all mask +#define AT73C213_DAC_PRECH_ALL 0xFE + +// DAC_RST +/// \internal Active low reset of the audio codec +#define AT73C213_DAC_RST_RSTZ (1 << 0) +/// \internal Active low reset of the audio codec filter +#define AT73C213_DAC_RST_RESFILZ (1 << 1) +/// \internal Active high reset mask of the audio codec +#define AT73C213_DAC_RST_RESMASK (1 << 2) + +// PA_CTRL +/// \internal Audio power amplifier gain: -22dB +#define AT73C213_PA_CTRL_APAGAIN_22N 0xF +/// \internal Audio power amplifier gain: 8dB +#define AT73C213_PA_CTRL_APAGAIN_8 0x5 +/// \internal Audio power amplifier gain: -1dB +#define AT73C213_PA_CTRL_APAGAIN_1N 0x8 +/// \internal Audio power amplifier precharge bit +#define AT73C213_PA_CTRL_APAPRECH (1 << 5) +/// \internal Audio power amplifier on bit +#define AT73C213_PA_CTRL_APAON (1 << 6) + +//------------------------------------------------------------------------------ +// Internal functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Writes a byte of data at the given address of the DAC SPI user interface. +/// \param address Register address to write. +/// \param data New register value. +//------------------------------------------------------------------------------ +void AT73C213_Write(unsigned char address, unsigned char data) +{ + SPI_Write(BOARD_AT73C213_SPI, + BOARD_AT73C213_SPI_NPCS, + ((address & 0x7F) << 8) | (data & 0xFF)); +} + +//------------------------------------------------------------------------------ +/// Reads and returns a byte of data read at the given address of the DAC SPI +/// user interface. +/// \param address Register address to read. +//------------------------------------------------------------------------------ +unsigned char AT73C213_Read(unsigned char address) +{ + SPI_Write(BOARD_AT73C213_SPI, + BOARD_AT73C213_SPI_NPCS, + (1 << 15) | ((address & 0x7F) << 8)); + return SPI_Read(BOARD_AT73C213_SPI) & 0xFF; +} + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Enables the AT73C213 DAC to operate using the specified sample frequency (in +/// Hz), sample size (in bytes) and number of channels. If the master clock +/// sent to the DAC is equal to 384*Fs, then isClock384 must be 1; otherwise it +/// must be 0. +/// \param Fs Desired sampling frequency in Hz. +/// \param sampleSize Size of one sample in bytes. +/// \param numChannels Number of audio channels used. +/// \param isClock384 Must be 1 if DACmck = 384*Fs, 0 if DACmck = 256*Fs. +/// \param masterClock Frequency of the system master clock. +//------------------------------------------------------------------------------ +void AT73C213_Enable(unsigned int Fs, + unsigned int sampleSize, + unsigned int numChannels, + unsigned char isClock384, + unsigned int masterClock) +{ + // Configure the SPI peripheral chip select + SPI_ConfigureNPCS(BOARD_AT73C213_SPI, + BOARD_AT73C213_SPI_NPCS, + AT73C213_SPI_NPCSCONFIG(masterClock)); + + // DAC startup sequence + // De-assert reset + AT73C213_Write(AT73C213_DAC_RST, + AT73C213_DAC_RST_RSTZ + | AT73C213_DAC_RST_RESFILZ); + + // Precharge and turn on master power + AT73C213_Write(AT73C213_DAC_PRECH, + AT73C213_DAC_PRECH_ONMSTR + | AT73C213_DAC_PRECH_ALL); + + // Enable line out drivers + AT73C213_Write(AT73C213_DAC_CTRL, + AT73C213_DAC_CTRL_ONLNOL + | AT73C213_DAC_CTRL_ONLNOR); + + // TODO 500 ms delay + + // Stop precharging + AT73C213_Write(AT73C213_DAC_PRECH, AT73C213_DAC_PRECH_ONMSTR); + + // TODO 1ms delay + + // Enable DACs + AT73C213_Write(AT73C213_DAC_CTRL, + AT73C213_DAC_CTRL_ONLNOL + | AT73C213_DAC_CTRL_ONLNOR + | AT73C213_DAC_CTRL_ONDACL + | AT73C213_DAC_CTRL_ONDACR); + + // Select master clock speed + if (isClock384) { + + AT73C213_Write(AT73C213_DAC_CSFC, AT73C213_DAC_CSFC_OVRSEL); + } + + // Output DAC register values + unsigned int i; + TRACE_DEBUG_WP("DAC register values:\n\r"); + for (i=0; i <= AT73C213_PA_CTRL; i++) { + + TRACE_DEBUG_WP(" - @0x%02X = 0x%02X\n\r", i, AT73C213_Read(i)); + } + + // Unmute channels + AT73C213_SetMuteStatus(0, 0); + + // Configure the SSC + SSC_Configure(BOARD_AT73C213_SSC, + BOARD_AT73C213_SSC_ID, + Fs * sampleSize * 8 * numChannels, + masterClock); + SSC_ConfigureTransmitter(BOARD_AT73C213_SSC, + AT73C213_TCMR(sampleSize, numChannels), + AT73C213_TFMR(sampleSize, numChannels)); + SSC_EnableTransmitter(BOARD_AT73C213_SSC); +} + +//------------------------------------------------------------------------------ +/// Disables the AT73C213 DAC. +//------------------------------------------------------------------------------ +void AT73C213_Disable() +{ + // Set gain to -22dB + AT73C213_Write(AT73C213_PA_CTRL, + AT73C213_PA_CTRL_APAGAIN_22N | + AT73C213_PA_CTRL_APAON); + + // Turn off power amplifier + AT73C213_Write(AT73C213_PA_CTRL, AT73C213_PA_CTRL_APAGAIN_22N); + + // Disable DACs + AT73C213_Write(AT73C213_DAC_CTRL, + AT73C213_DAC_CTRL_ONLNOL + | AT73C213_DAC_CTRL_ONLNOR); + + // Disable master power + AT73C213_Write(AT73C213_DAC_PRECH, 0); + + // TODO 1ms delay + + // Power off everything + AT73C213_Write(AT73C213_DAC_CTRL, 0); +} + +//------------------------------------------------------------------------------ +/// Mutes or unmutes the left and/or right channel. +/// \param leftChannelMuted Indicates the new status of the left audio channel. +/// \param rightChannelMuted New status of the right audio channel. +//------------------------------------------------------------------------------ +void AT73C213_SetMuteStatus(unsigned char leftChannelMuted, + unsigned char rightChannelMuted) +{ + // Update left channel status + if (leftChannelMuted) { + + AT73C213_Write(AT73C213_DAC_LLOG, AT73C213_DAC_LLOG_GAIN_MUTE); + } + else { + + AT73C213_Write(AT73C213_DAC_LLOG, AT73C213_DAC_LLOG_GAIN_10_5N); + } + + // Update right channel status + if (rightChannelMuted) { + + AT73C213_Write(AT73C213_DAC_RLOG, AT73C213_DAC_RLOG_GAIN_MUTE); + } + else { + + AT73C213_Write(AT73C213_DAC_RLOG, AT73C213_DAC_RLOG_GAIN_10_5N); + } +} + diff --git a/components/dac-at73c213/at73c213.h b/components/dac-at73c213/at73c213.h new file mode 100644 index 0000000..897a40f --- /dev/null +++ b/components/dac-at73c213/at73c213.h @@ -0,0 +1,80 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +/// \dir +/// !Purpose +/// +/// Definitions and methods for using a single external AT73C213 DAC. Several +/// constants must be declared at the board.h level for that: +/// - BOARD_AT73C213_SPI +/// - BOARD_AT73C213_SPI_ID +/// - BOARD_AT73C213_NPCS +/// - BOARD_AT73C213_SSC +/// - BOARD_AT73C213_SSC_ID +/// +/// !Usage +/// +/// -# Configure the mode register of the SPI associated with the DAC and +/// enable the SPI peripheral (see spi.h). +/// -# Enable the master clock of the DAC (usually, it will be connected to +/// a programmable clock output). +/// -# Call the AT73C213_Enable function with the desired parameters. This +/// function configures the associated NPCS register of the SPI for correct +/// interfacing with the DAC, starts the DAC and configures the SSC. +/// -# Send audio data to the DAC using the SSC, with SSC_WriteBuffer or +/// SSC_Write. +//------------------------------------------------------------------------------ + +#ifndef AT73C213_H +#define AT73C213_H + +//------------------------------------------------------------------------------ +// Definitions +//------------------------------------------------------------------------------ + +// Master Clock Selector +#define AT73C213_MCK_SEL_256_FS 0 +#define AT73C213_MCK_SEL_384_FS 1 + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ + +extern void AT73C213_Enable(unsigned int Fs, + unsigned int sampleSize, + unsigned int numChannels, + unsigned char isClock384, + unsigned int masterClock); +extern void AT73C213_Disable(); +extern void AT73C213_SetMuteStatus(unsigned char leftChannelMuted, + unsigned char rightChannelMuted); + +#endif //#ifndef AT73C213_H + -- cgit v1.2.3