You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
3.7 KiB
C
91 lines
3.7 KiB
C
/***************************************************************************//**
|
|
* @file tlv320aic3104_ctrl.c
|
|
* @brief Control functions for TLV320AIC3104 audio codec using I2C
|
|
*//****************************************************************************/
|
|
|
|
//------------------------------C library---------------------------------------
|
|
#include <stdint.h>
|
|
//----------------------------user includes-------------------------------------
|
|
#include "tlv320aic3104_ctrl.h"
|
|
#include "i2c_master.h"
|
|
#include "main.h"
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
/* Private macros ------------------------------------------------------------*/
|
|
|
|
// Codecs on different I2C buses
|
|
#define I2C_CODEC_A I2C1
|
|
#define I2C_CODEC_B I2C3
|
|
|
|
#define CODEC_I2C_ADDR 0x30 // left-aligned 7-bit slave address
|
|
|
|
/* Private variables ---------------------------------------------------------*/
|
|
static uint8_t PageSelect[2] = {0xFF, 0xFF}; // current page selected for each codec, to optimize page switching
|
|
|
|
/* Functions -----------------------------------------------------------------*/
|
|
|
|
|
|
/***************************************************************************//**
|
|
* @brief Read register value from codec
|
|
* @param codec: codec select (0 for CODEC_A, 1 for CODEC_B)
|
|
* @param page: page select (0 or 1)
|
|
* @param reg: register address (0-127)
|
|
* @return register value (0-255) on success, negative error code on failure
|
|
*//****************************************************************************/
|
|
int16_t TlvReadReg(CODEC_SELECT codec, TLV_PAGE_SELECT page, uint8_t reg) {
|
|
if (page != PageSelect[codec]) {
|
|
int err = TlvPageSelect(codec, page);
|
|
if (err < 0) return err;
|
|
}
|
|
if (reg) reg--; // workaround: reading gives regaddr+1 positions back at (datasheet is wrong...)
|
|
uint8_t val = 0;
|
|
int err = I2C_ReadReg((codec == CODEC_A) ? I2C_CODEC_A : I2C_CODEC_B,
|
|
CODEC_I2C_ADDR,
|
|
®, 1,
|
|
&val, 1);
|
|
if (err < 0) return err;
|
|
return val;
|
|
}
|
|
|
|
/***************************************************************************//**
|
|
* @brief Write register value to codec
|
|
* @param codec: codec select (0 for CODEC_A, 1 for CODEC_B)
|
|
* @param reg: register address (0-127)
|
|
* @param val: register value to write (0-255)
|
|
* @return 0 on success, negative error code on failure
|
|
*//****************************************************************************/
|
|
int16_t TlvWriteReg(CODEC_SELECT codec, TLV_PAGE_SELECT page, uint8_t reg, uint8_t val) {
|
|
if (page != PageSelect[codec]) {
|
|
int err = TlvPageSelect(codec, page);
|
|
if (err < 0) return err;
|
|
}
|
|
uint8_t data[2] = {reg, val};
|
|
int err = I2C_Write((codec == CODEC_A) ? I2C_CODEC_A : I2C_CODEC_B,
|
|
CODEC_I2C_ADDR,
|
|
data, 2);
|
|
return err;
|
|
}
|
|
|
|
/***************************************************************************//**
|
|
* @brief Write register value to codec
|
|
* @param codec: codec select (0 for CODEC_A, 1 for CODEC_B)
|
|
* @param reg: register address (0-127)
|
|
* @param val: register value to write (0-255)
|
|
* @return 0 on success, negative error code on failure
|
|
*//****************************************************************************/
|
|
int16_t TlvPageSelect(CODEC_SELECT codec, TLV_PAGE_SELECT page) {
|
|
if (codec > CODEC_B) codec = CODEC_B; // clamp codec select
|
|
PageSelect[codec] = page; // update current page for the codec
|
|
uint8_t reg = 0; // page select register address is 0
|
|
uint8_t data[2] = {reg, page};
|
|
int err = I2C_Write((codec == CODEC_A) ? I2C_CODEC_A : I2C_CODEC_B,
|
|
CODEC_I2C_ADDR,
|
|
data, 2);
|
|
return err;
|
|
}
|
|
|
|
|
|
|
|
|