STM32H750VB_DAC_AzureRTOS/lib/tpa6130a2/src/tpa6130a2.c

102 lines
3.5 KiB
C

#include "tpa6130a2.h"
#define TPA_SLAVE_ADDR 0x60
#define TPA_REG_CTRL 0x01
#define TPA_REG_VOL 0x02
#define TPA_REG_OUT_HIZ 0x03
#define TPA_REG_REV 0x04
#define TPA_REG_CTRL_HPEN_L_Pos 7
#define TPA_REG_CTRL_HPEN_L_Msk (1U << TPA_REG_CTRL_HPEN_L_Pos)
#define TPA_REG_CTRL_HPEN_R_Pos 6
#define TPA_REG_CTRL_HPEN_R_Msk (1U << TPA_REG_CTRL_HPEN_R_Pos)
#define TPA_REG_CTRL_HPEN_Msk (TPA_REG_CTRL_HPEN_L_Msk | TPA_REG_CTRL_HPEN_R_Msk)
#define TPA_REG_VOL_MUTE_L_Pos 7
#define TPA_REG_VOL_MUTE_L_Msk (1U << TPA_REG_VOL_MUTE_L_Pos)
#define TPA_REG_VOL_MUTE_R_Pos 6
#define TPA_REG_VOL_MUTE_R_Msk (1U << TPA_REG_VOL_MUTE_R_Pos)
#define TPA_REG_VOL_MUTE_Msk (TPA_REG_VOL_MUTE_L_Msk | TPA_REG_VOL_MUTE_R_Msk)
#define TPA_REG_VOL_VOL_Pos 0
#define TPA_REG_VOL_VOL_Msk (63U << TPA_REG_VOL_VOL_Pos)
#define TPA_REG_REV_VERSION_Pos 0
#define TPA_REG_REV_VERSION_Msk (0x0FU << TPA_REG_REV_VERSION_Pos)
#define TPA_ERROR_CHECK(x) \
if (x != TPA6130_OK) return TPA6130_FAIL
/**
* @brief Get TPA6130 silicon revision. Through datasheet, the only valid
* revision for a production TPA6130A2 is 0010b(2).
*
* @param tpa pointer to tps6130_t structure
* @param rev pointer to the revision number
* @return tpa6130_ret_t TPA6130_OK for success, TPA6130_FAIL for errors.
*/
tpa6130_ret_t tpa6130a2_revision(tpa6130_t *tpa, uint8_t *rev) {
uint8_t rev_reg;
TPA_ERROR_CHECK(tpa->cb.read_reg_cb(tpa->user_data, TPA_SLAVE_ADDR, TPA_REG_REV, &rev_reg));
*rev = rev_reg & TPA_REG_REV_VERSION_Msk;
return TPA6130_OK;
}
/**
* @brief Enable amplifier channel outputs
*
* @param tpa pointer to tps6130_t structure
* @param ch tpa6130_ch_t bitmask, e.g. TPA6130_CH_L for left channel
* @return tpa6130_ret_t TPA6130_OK for success, TPA6130_FAIL for errors.
*/
tpa6130_ret_t tpa6130a2_enable_channel(tpa6130_t *tpa, tpa6130_ch_t ch) {
uint8_t ctrl_reg;
TPA_ERROR_CHECK(tpa->cb.read_reg_cb(tpa->user_data, TPA_SLAVE_ADDR, TPA_REG_CTRL, &ctrl_reg));
ctrl_reg &= ~TPA_REG_CTRL_HPEN_Msk;
ctrl_reg |= ch & TPA_REG_CTRL_HPEN_Msk;
TPA_ERROR_CHECK(tpa->cb.write_reg_cb(tpa->user_data, TPA_SLAVE_ADDR, TPA_REG_CTRL, ctrl_reg));
return TPA6130_OK;
}
/**
* @brief Set amplifier volume.
*
* @param tpa pointer to tps6130_t structure
* @param volume volume to be set, valid range from 0 to 63, invalid bits will be clipped.
* @return tpa6130_ret_t TPA6130_OK for success, TPA6130_FAIL for errors.
*/
tpa6130_ret_t tpa6130a2_set_volume(tpa6130_t *tpa, uint8_t volume) {
uint8_t vol_reg;
TPA_ERROR_CHECK(tpa->cb.read_reg_cb(tpa->user_data, TPA_SLAVE_ADDR, TPA_REG_VOL, &vol_reg));
vol_reg &= ~TPA_REG_VOL_VOL_Msk;
vol_reg |= volume & TPA_REG_VOL_VOL_Msk;
TPA_ERROR_CHECK(tpa->cb.write_reg_cb(tpa->user_data, TPA_SLAVE_ADDR, TPA_REG_VOL, vol_reg));
return TPA6130_OK;
}
/**
* @brief Mute or unmute amplifier
*
* @param tpa pointer to tps6130_t structure
* @param ch tpa6130_ch_t bitmask, e.g. TPA6130_CH_L for left channel, TPA6130_NONE for unmute all channels.
* @return tpa6130_ret_t TPA6130_OK for success, TPA6130_FAIL for errors.
*/
tpa6130_ret_t tpa6130a2_set_mute(tpa6130_t *tpa, tpa6130_ch_t ch) {
uint8_t vol_reg;
TPA_ERROR_CHECK(tpa->cb.read_reg_cb(tpa->user_data, TPA_SLAVE_ADDR, TPA_REG_VOL, &vol_reg));
vol_reg &= ~TPA_REG_VOL_MUTE_Msk;
vol_reg |= ch & TPA_REG_VOL_MUTE_Msk;
TPA_ERROR_CHECK(tpa->cb.write_reg_cb(tpa->user_data, TPA_SLAVE_ADDR, TPA_REG_VOL, vol_reg));
return TPA6130_OK;
}