Library for Texas Instruments TLV320AIC23B hi-def audio chip note: requires I2SSlave abstraction library
Dependents: playback FTSESpeech i2s_audio_echo i2s_audio_sampler ... more
Revision 0:bb2411673898, committed 2011-08-04
- Comitter:
- d_worrall
- Date:
- Thu Aug 04 15:04:59 2011 +0000
- Child:
- 1:7e76c6f56169
- Commit message:
- version 2.29
Changed in this revision
TLV320.cpp | Show annotated file Show diff for this revision Revisions of this file |
TLV320.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TLV320.cpp Thu Aug 04 15:04:59 2011 +0000 @@ -0,0 +1,361 @@ +/** +* @author Ioannis Kedros, Daniel Worrall +* +* @section LICENSE +* +* Copyright (c) 2011 mbed +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +* +* @section DESCRIPTION +* Library for Texas instruments TLV320AIC23B library NXP LPC1768 +* +*/ + +#include "mbed.h" +#include "TLV320.h" + +TLV320::TLV320(PinName sda, PinName scl, int addr, PinName tx_sda, PinName tx_ws, PinName clk, PinName rx_sda, PinName rx_ws) + : mAddr(addr), mI2c_(sda, scl), mI2s_(tx_sda, tx_ws, clk, rx_sda, rx_ws){ + mI2c_.frequency(150000); + reset(); //TLV resets + power(0x07); //Power Up the TLV320, but not the MIC, ADC and LINE + format(16, STEREO); //16Bit I2S protocol format, STEREO + frequency(44100); //Default sample frequency is 44.1kHz + bypass(false); //Do not bypass device + mute(false); //Not muted + activateDigitalInterface_(); //The digital part of the chip is active + outputVolume(0.7, 0.7); //Headphone volume to the default state + rxBuffer = &mI2s_.rxBuffer[0]; +} +//Public Functions +/****************************************************** + * Function name: inputVolume() + * + * Description: set line in volume for left and right channels + * + * Parameters: float leftVolumeIn, float rightVolumeIn + * Returns: int 0 (success), -1 (value out of range) +******************************************************/ +int TLV320::inputVolume(float leftVolumeIn, float rightVolumeIn){ + //check values are in range + if((leftVolumeIn < 0.0)||leftVolumeIn > 1.0) return -1; + if((rightVolumeIn < 0.0)||rightVolumeIn > 1.0) return -1; + //convert float to encoded char + char left = (char)31*leftVolumeIn; + char right = (char)31*rightVolumeIn; + //Left Channel + cmd[1] = left | (0 << 7); //set volume + cmd[0] = LEFT_LINE_INPUT_CHANNEL_VOLUME_CONTROL; //set address + mI2c_.write(mAddr, cmd, 2); //send + //Right Channel + cmd[1] = right | (0 << 7); //set volume + cmd[0] = RIGHT_LINE_INPUT_CHANNEL_VOLUME_CONTROL; //set address + mI2c_.write(mAddr, cmd, 2); //send + return 0; +} +/****************************************************** + * Function name: outputVolume() + * + * Description: Set headphone (line out) volume for left an right channels + * + * Parameters: float leftVolumeOut, float rightVolumeOut + * Returns: int 0 (success), -1 (value out of range) +******************************************************/ +int TLV320::outputVolume(float leftVolumeOut, float rightVolumeOut){ + //check values are in range + if((leftVolumeOut < 0.0)||leftVolumeOut > 1.0) return -1; + if((rightVolumeOut < 0.0)||rightVolumeOut > 1.0) return -1; + //convert float to encoded char + char left = (char)(79*leftVolumeOut)+0x30; + char right = (char)(79*rightVolumeOut)+0x30; + //Left Channel + cmd[1] = left | (1 << 7); //set volume + cmd[0] = LEFT_CHANNEL_HEADPHONE_VOLUME_CONTROL; //set address + mI2c_.write(mAddr, cmd, 2); //send + //Right Channel + cmd[1] = right | (1 << 7); //set volume + cmd[0] = RIGHT_CHANNEL_HEADPHONE_VOLUME_CONTROL; //set address + mI2c_.write(mAddr, cmd, 2); //send + return 0; +} +/****************************************************** + * Function name: bypass() + * + * Description: Send TLV320 into bypass mode, i.e. connect input to output + * + * Parameters: bool bypassVar + * Returns: none +******************************************************/ +void TLV320::bypass(bool bypassVar){ + if(bypassVar == true) + cmd[1] = (1 << 3) | (0 << 4) | (0 << 5);//bypass enabled, DAC disabled, sidetone insertion disabled + else + cmd[1] = (0 << 3) | (1 << 4); //bypass disabled, DAC enabled + cmd[1] |= (0 << 2); + cmd[0] = ANALOG_AUDIO_PATH_CONTROL; //set address + mI2c_.write(mAddr, cmd, 2); //send +} +/****************************************************** + * Function name: mute() + * + * Description: Send TLV320 into mute mode + * + * Parameters: bool softMute + * Returns: none +******************************************************/ +void TLV320::mute(bool softMute){ + if(softMute == true) cmd[1] = 0x08; //set instruction to mute + else cmd[1] = 0x00; //set instruction to NOT mute + + cmd[0] = DIGITAL_AUDIO_PATH_CONTROL; //set address + mI2c_.write(mAddr, cmd, 2); //send +} +/****************************************************** + * Function name: power() + * + * Description: Switch TLV320 on/off + * + * Parameters: bool powerUp + * Returns: none +******************************************************/ +void TLV320::power(bool powerUp){ + if(powerUp == true) cmd[1] = 0x00; //everything on + else cmd[1] = 0xFF; //everything off + + cmd[0] = POWER_DOWN_CONTROL; //set address + mI2c_.write(mAddr, cmd, 2); //send +} +/****************************************************** + * Function name: power() + * + * Description: Switch on individual devices on TLV320 + * + * Parameters: int device + * Returns: none +******************************************************/ +void TLV320::power(int device){ + cmd[1] = (char)device; //set user defined commands + cmd[0] = POWER_DOWN_CONTROL; //set address + mI2c_.write(mAddr, cmd, 2); //send +} +/****************************************************** + * Function name: format() + * + * Description: Set interface format + * + * Parameters: char length, bool mode + * Returns: none +******************************************************/ +void TLV320::format(char length, bool mode){ + char modeSet = (1 << 6); + modeSet |= (1 << 5); //swap left and right channels + + switch (length) //input data into instruction byte + { + case 16: + cmd[1] = modeSet | 0x02; + break; + case 20: + cmd[1] = modeSet | 0x06; + break; + case 24: + cmd[1] = modeSet | 0x0A; + break; + case 32: + cmd[1] = modeSet | 0x0E; + break; + default: + break; + } + mI2s_.format(length, mode); + cmd[0] = DIGITAL_AUDIO_INTERFACE_FORMAT; //set address + mI2c_.write(mAddr, cmd, 2); //send +} +/****************************************************** + * Function name: frequency() + * + * Description: Set sample frequency + * + * Parameters: int hz + * Returns: int 0 (success), -1 (value not recognised) +******************************************************/ +int TLV320::frequency(int hz){ + char rate; + switch(hz){ + case 8000: + rate = 0x03; + break; + case 8021: + rate = 0x0B; + break; + case 32000: + rate = 0x06; + break; + case 44100: + rate = 0x08; + break; + case 48000: + rate = 0x00; + break; + case 88200: + rate = 0x0F; + break; + case 96000: + rate = 0x07; + break; + default: + return -1; + } + char clockInChar = (0 << 6); + char clockModeChar = (1 << 0); + + cmd[1] = (rate << 2) | clockInChar | clockModeChar; //input data into instruciton byte + cmd[0] = SAMPLE_RATE_CONTROL; //set address + mI2c_.write(mAddr, cmd, 2); //send + return 0; +} +/****************************************************** + * Function name: reset() + * + * Description: Reset TLV320 + * + * Parameters: none + * Returns: none +******************************************************/ +void TLV320::reset(void){ + cmd[0] = RESET_REGISTER; //set address + cmd[1] = 0x00; //this resets the entire device + mI2c_.write(mAddr, cmd, 2); +} +/****************************************************** + * Function name: start() + * + * Description: Enable interrupts on the I2S port + * + * Parameters: int mode + * Returns: none +******************************************************/ +void TLV320::start(int mode){ + mI2s_.start(mode); +} +/****************************************************** + * Function name: stop() + * + * Description: Disable interrupts on the I2S port + * + * Parameters: none + * Returns: none +******************************************************/ +void TLV320::stop(void){ + mI2s_.stop(); +} +/****************************************************** + * Function name: write() + * + * Description: Write (part of) a buffer to the I2S port + * + * Parameters: int *buffer, int from, int length + * Returns: none +******************************************************/ +void TLV320::write(int *buffer, int from, int length){ + mI2s_.write(buffer, from, length); +} +/****************************************************** + * Function name: read() + * + * Description: Place I2SRXFIFO in rxBuffer + * + * Parameters: none + * Returns: none +******************************************************/ +void TLV320::read(void){ + mI2s_.read(); +} +/****************************************************** + * Function name: attach() + * + * Description: Attach a void/void function or void/void static member function to IRQHandler + * + * Parameters: none + * Returns: none +******************************************************/ +void TLV320::attach(void(*fptr)(void)){ + mI2s_.attach(fptr); +} +//Private Functions +/****************************************************** + * Function name: setSampleRate_() + * + * Description: Clocking control + * + * Parameters: char rate, bool clockIn, bool clockMode, bool bOSR + * Returns: none +******************************************************/ +void TLV320::setSampleRate_(char rate, bool clockIn, bool clockMode, bool bOSR){ + char clockInChar; + char clockModeChar; + char baseOverSamplingRate; + if(bOSR){ + baseOverSamplingRate = (1 << 0); + } else { + baseOverSamplingRate = (0 << 0); + } + if(clockIn){ + clockInChar = (1 << 6); + } else { + clockInChar = (0 << 6); + } + if(clockMode){ + clockModeChar = 0x01; + } else { + clockModeChar = 0x00; + } + cmd[1] = (rate << 2) | clockInChar | clockModeChar | baseOverSamplingRate; //input data into instruciton byte + cmd[0] = SAMPLE_RATE_CONTROL; //set address + mI2c_.write(mAddr, cmd, 2); //send +} +/****************************************************** + * Function name: activateDigitalInterface_() + * + * Description: Activate digital part of chip + * + * Parameters: none + * Returns: none +******************************************************/ +void TLV320::activateDigitalInterface_(void){ + cmd[1] = 0x01; //Activate + cmd[0] = DIGITAL_INTERFACE_ACTIVATION; //set address + mI2c_.write(mAddr, cmd, 2); //send +} +/****************************************************** + * Function name: deactivateDigitalInterface_ + * + * Description: Deactivate digital part of chip + * + * Parameters: none + * Returns: none +******************************************************/ +//Digital interface deactivation +void TLV320::deactivateDigitalInterface_(void){ + cmd[1] = 0x00; //Deactivate + cmd[0] = DIGITAL_INTERFACE_ACTIVATION; //set address + mI2c_.write(mAddr, cmd, 2); //send +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TLV320.h Thu Aug 04 15:04:59 2011 +0000 @@ -0,0 +1,203 @@ +/** +* @author Ioannis Kedros, Daniel Worrall +* +* @section LICENSE +* +* Copyright (c) 2011 mbed +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +* +* @section DESCRIPTION +* Library for Texas instruments TLV320AIC23B library NXP LPC1768 +* +*/ + +#ifndef MBED_TLV320_H +#define MBED_TLV320_H + +#include "mbed.h" +#include "I2SSlave.h" + +/** TLV320 class, defined on the I2C master bus +* +*/ + +class TLV320 +{ + public: + //constructor + /** Create a TLV320 object defined on the I2C port + * + * @param sda Serial data pin (p9 or p28) + * @param scl Serial clock pin (p10 or p27) + * @param addr Object address + */ + TLV320(PinName sda, PinName scl, int addr, PinName tx_sda, PinName tx_ws, PinName clk, PinName rx_sda, PinName rx_ws); + /** Power up/down + * + * @param powerUp 0 = power down, 1 = power up + */ + void power(bool powerUp); + /** Overloaded power() function default = 0x07, record requires 0x02 + * + * @param device Call individual devices to power up/down + * Device power 0x00 = On 0x80 = Off + * Clock 0x00 = On 0x40 = Off + * Oscillator 0x00 = On 0x20 = Off + * Outputs 0x00 = On 0x10 = Off + * DAC 0x00 = On 0x08 = Off + * ADC 0x00 = On 0x04 = Off + * Microphone input 0x00 = On 0x02 = Off + * Line input 0x00 = On 0x01 = Off + */ + void power(int device); + /** Set I2S interface bit length and mode + * + * @param length Set bit length to 16, 20, 24 or 32 bits + * @param mode Set STEREO (0), MONO (1) + */ + void format(char length, bool mode); + /** Set sample frequency + * + * @param frequency Sample frequency of data in Hz + * @return Returns an integer 0 = success, -1 = unrecognnised frequency + * + * The TLV320 supports the following frequencies: 8kHz, 8.021kHz, 32kHz, 44.1kHz, 48kHz, 88.2kHz, 96kHz + * Default is 44.1kHz + */ + int frequency(int hz); + /** Reset TLV320 + * + */ + void reset(void); + /** Start streaming i.e. enable interrupts + * + * @param mode Enable interrupts for NONE, TRANSMIT only, RECEIVE only, BOTH + */ + void start(int mode); + /** Stop streaming i.e. disable all interrupts + * + */ + void stop(void); + /** Write [length] 32 bit words in buffer to I2S port + * + * @param *buffer Address of buffer to be written + * @param from Start position in buffer to read from + * @param length Number of words to be written (MUST not exceed 4) + */ + void write(int *buffer, int from, int length); + /** Read 4 x (32bit) words into rxBuffer + * + */ + void read(void); + /** Attach a void/void function or void/void static member funciton to an interrupt generated by the I2SxxFIFOs + * + * @param function Function to attach + * + * e.g. myTlv320Object.attach(&myfunction); + * OR myTlv320Object.attach(&myClass::myStaticMemberFunction); + */ + void attach(void(*fptr)(void)); + /** Attach a nonstatic void/void member function to an interrupt generated by the I2SxxFIFOs + * + * @param tptr Object pointer + * @param mptr Member function pointer + * + * e.g. myTlv320Object.attach(&myObject, &myClass::myNonstaticMemberFunction); where myObject is an object of myClass + */ + template<typename T> + void attach(T *tptr, void(T::*mptr)(void)){ + mI2s_.attach(tptr, mptr); + } + /** Line in volume control i.e. record volume + * + * @param leftVolumeIn Left line-in volume + * @param rightVolumeIn Right line-in volume + * @return Returns 0 for success, -1 if parameters are out of range + * Parameters accept a value, where 0.0 < parameter < 1.0 and where 0.0 maps to -34.5dB + * and 1.0 maps to +12dB (0.74 = 0 dB default). + */ + int inputVolume(float leftVolumeIn, float rightVolumeIn); + /** Headphone out volume control + * + * @param leftVolumeOut Left line-out volume + * @param rightVolumeOut Right line-out volume + * @return Returns 0 for success, -1 if parameters are out of range + * Parameters accept a value, where 0.0 < parameter < 1.0 and where 0.0 maps to -73dB (mute) + * and 1.0 maps to +6dB (0.5 = default) + */ + int outputVolume(float leftVolumeOut, float rightVolumeOut); + /** Analog audio path control + * + * @param bypassVar Route analogue audio direct from line in to headphone out + */ + void bypass(bool bypassVar); + /**Digital audio path control + * + * @param softMute Mute output + */ + void mute(bool softMute); + //Receive buffer + + int *rxBuffer; + + protected: + char cmd[2]; //the address and command for TLV320 internal registers + int mAddr; //register write address + private: + I2C mI2c_; //MUST use the I2C port + I2SSlave mI2s_; + Ticker I2sTick; + void io(void); + /** Sample rate control + * + * @param rate Set the sampling rate as per datasheet section 3.3.2 + * @param clockIn Set the clock in divider MCLK, MCLK_DIV2 + * @param clockMode Set clock mode CLOCK_NORMAL, CLOCK_USB + */ + void setSampleRate_(char rate, bool clockIn, bool mode, bool bOSR); + /** Digital interface activation + * + */ + void activateDigitalInterface_(void); + /** Digital interface deactivation + * + */ + void deactivateDigitalInterface_(void); + + //TLV320AIC23B register addresses as defined in the TLV320AIC23B datasheet + #define LEFT_LINE_INPUT_CHANNEL_VOLUME_CONTROL (0x00 << 1) + #define RIGHT_LINE_INPUT_CHANNEL_VOLUME_CONTROL (0x01 << 1) + #define LEFT_CHANNEL_HEADPHONE_VOLUME_CONTROL (0x02 << 1) + #define RIGHT_CHANNEL_HEADPHONE_VOLUME_CONTROL (0x03 << 1) + #define ANALOG_AUDIO_PATH_CONTROL (0x04 << 1) + #define DIGITAL_AUDIO_PATH_CONTROL (0x05 << 1) + #define POWER_DOWN_CONTROL (0x06 << 1) + #define DIGITAL_AUDIO_INTERFACE_FORMAT (0x07 << 1) + #define SAMPLE_RATE_CONTROL (0x08 << 1) + #define DIGITAL_INTERFACE_ACTIVATION (0x09 << 1) + #define RESET_REGISTER (0x0F << 1) + + #define CLOCK_NORMAL 0 + #define CLOCK_USB 1 + #define MCLK 0 + #define MCLK_DIV2 1 +}; + +#endif \ No newline at end of file