From e23c0ef94dcdb5392f27d338d4ba20b1227b2c17 Mon Sep 17 00:00:00 2001 From: lottaviano Date: Fri, 3 Jul 2009 15:51:31 +0000 Subject: [PATCH] Import tas5706a driver. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@2737 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/cfg/cfg_tas5706a.h | 52 ++++++++++++++ bertos/drv/tas5706a.c | 146 ++++++++++++++++++++++++++++++++++++++ bertos/drv/tas5706a.h | 89 +++++++++++++++++++++++ bertos/hw/hw_tas5706a.h | 69 ++++++++++++++++++ 4 files changed, 356 insertions(+) create mode 100644 bertos/cfg/cfg_tas5706a.h create mode 100644 bertos/drv/tas5706a.c create mode 100644 bertos/drv/tas5706a.h create mode 100644 bertos/hw/hw_tas5706a.h diff --git a/bertos/cfg/cfg_tas5706a.h b/bertos/cfg/cfg_tas5706a.h new file mode 100644 index 00000000..b0f3fe73 --- /dev/null +++ b/bertos/cfg/cfg_tas5706a.h @@ -0,0 +1,52 @@ +/** + * \file + * + * + * \brief Configuration file for the TAS5706A module. + * + * \version $Id$ + * \author Luca Ottaviano + */ + +#ifndef CFG_TAS5706A_H +#define CFG_TAS5706A_H + +/** + * Maximum output volume for TAS chip [dB]. + * + * $WIZ$ type = "int" + * $WIZ$ min = -100 + * $WIZ$ max = 24 + * $WIZ$ supports = "at91" + */ +#define CONFIG_TAS_MAX_VOL -39 + +#endif /* CFG_TAS5706A_H */ diff --git a/bertos/drv/tas5706a.c b/bertos/drv/tas5706a.c new file mode 100644 index 00000000..b935c42f --- /dev/null +++ b/bertos/drv/tas5706a.c @@ -0,0 +1,146 @@ +/** + * \file + * + * + * \brief TAS5706A Power DAC i2c driver. + * + * + * \version $Id$ + * \author Francesco Sacchi + */ + +#include "tas5706a.h" +#include + +#include +#include + +#include "hw/hw_tas5706a.h" +#include "cfg/cfg_tas5706a.h" + +#define TAS_ADDR 0x36 + +typedef uint8_t tas_addr_t; + +static bool tas5706a_send(tas_addr_t addr, const void *buf, size_t len) +{ + bool ret = i2c_start_w(TAS_ADDR) && i2c_put(addr) && i2c_send(buf, len); + i2c_stop(); + return ret; +} + +INLINE bool tas5706a_putc(tas_addr_t addr, uint8_t ch) +{ + return tas5706a_send(addr, &ch, sizeof(ch)); +} + +static bool tas5706a_recv(tas_addr_t addr, void *buf, size_t len) +{ + bool ret = i2c_start_w(TAS_ADDR) && i2c_put(addr) && i2c_start_r(TAS_ADDR) && i2c_recv(buf, len); + i2c_stop(); + return ret; +} + +INLINE int tas5706a_getc(tas_addr_t addr) +{ + uint8_t ch; + if (tas5706a_recv(addr, &ch, sizeof(ch))) + return (int)(uint8_t)ch; + else + return EOF; +} + +#define TRIM_REG 0x1B +#define SYS_REG2 0x05 +#define VOLUME_REG 0x07 +#define MUTE_VOL 0xFF + +#define DB_TO_REG(db) ((24 - (db)) * 2) + +void tas5706a_init(void) +{ + MOD_CHECK(i2c); + MOD_CHECK(timer); + TAS5706A_PIN_INIT(); + timer_delay(200); + TAS5706A_SETPOWERDOWN(false); + TAS5706A_SETMUTE(false); + TAS5706A_MCLK_INIT(); + timer_delay(2); + TAS5706A_SETRESET(false); + timer_delay(20); + tas5706a_putc(TRIM_REG, 0x00); + + tas5706a_putc(VOLUME_REG, DB_TO_REG(CONFIG_TAS_MAX_VOL)); + + /* Unmute */ + tas5706a_putc(SYS_REG2, 0); +} + +#define CH1_VOL_REG 0x08 +#define CH2_VOL_REG 0x09 +#define CH3_VOL_REG 0x0A +#define CH4_VOL_REG 0x0B + +void tas5706a_setVolume(Tas5706aCh ch, tas5706a_vol_t vol) +{ + ASSERT(ch < TAS_CNT); + ASSERT(vol <= TAS_VOL_MAX); + + tas_addr_t addr1, addr2; + + switch(ch) + { + case TAS_CH1: + addr1 = CH1_VOL_REG; + addr2 = CH3_VOL_REG; + break; + case TAS_CH2: + addr1 = CH2_VOL_REG; + addr2 = CH4_VOL_REG; + break; + default: + ASSERT(0); + return; + } + + uint8_t vol_att = 0xff - ((vol * 0xff) / TAS_VOL_MAX); + + tas5706a_putc(addr1, vol_att); + tas5706a_putc(addr2, vol_att); +} + +void tas5706a_setLowPower(bool val) +{ + TAS5706A_SETPOWERDOWN(val); + TAS5706A_SETMUTE(val); +} + diff --git a/bertos/drv/tas5706a.h b/bertos/drv/tas5706a.h new file mode 100644 index 00000000..2f602356 --- /dev/null +++ b/bertos/drv/tas5706a.h @@ -0,0 +1,89 @@ +/** + * \file + * + * + * \brief TAS5706A Power DAC i2c driver. + * + * + * \version $Id$ + * \author Francesco Sacchi + */ + +#ifndef DRV_TAS5706A_H +#define DRV_TAS5706A_H + +#include + +typedef enum Tas5706aCh +{ + TAS_CH1, + TAS_CH2, + TAS_CNT, +} Tas5706aCh; + +/** + * TAS minimum volume (%). + */ +#define TAS_VOL_MIN 0 + +/** + * TAS maximum volume (%). + */ +#define TAS_VOL_MAX 100 + +typedef uint8_t tas5706a_vol_t; + +/** + * Set the volume for the specified channel. + * + * The volume must be expressed in % and will be at maximum CONFIG_TAS_MAX_VOL. + * + * \param ch The channel to be controlled. + * \param vol The volume you want to set. + */ +void tas5706a_setVolume(Tas5706aCh ch, tas5706a_vol_t vol); + +/** + * Initialize the TAS chip. + */ +void tas5706a_init(void); + +/** + * Set TAS chip to low power mode. + * + * When in low power mode, the TAS will not play any sound. You should put the TAS chip in low + * power whenever possible to prevent overheating and to save power. + * + * \param val True if you want to enable low power mode, false otherwise. + */ +void tas5706a_setLowPower(bool val); + +#endif /* DRV_TAS5706A_H */ diff --git a/bertos/hw/hw_tas5706a.h b/bertos/hw/hw_tas5706a.h new file mode 100644 index 00000000..e67a1405 --- /dev/null +++ b/bertos/hw/hw_tas5706a.h @@ -0,0 +1,69 @@ +/** + * \file + * + * + * \brief HW pin handling. + * + * \version $Id$ + * + * \author Francesco Sacchi + */ + +#ifndef HW_TAS5706A_H +#define HW_TAS5706A_H + +#include +#include + +#define TAS5706A_SETPOWERDOWN(val) do { if (val) PIOA_CODR = BV(6); else PIOA_SODR = BV(6); } while (0) +#define TAS5706A_SETRESET(val) do { if (val) PIOA_CODR = BV(7); else PIOA_SODR = BV(7); } while (0) +#define TAS5706A_SETMUTE(val) do { if (val) PIOA_CODR = BV(8); else PIOA_SODR = BV(8); } while (0) + +#define TAS5706A_PIN_INIT() \ + do { \ + TAS5706A_SETPOWERDOWN(true); \ + TAS5706A_SETRESET(true); \ + TAS5706A_SETMUTE(true); \ + PIOA_PER = BV(6) | BV(7) | BV(8); \ + PIOA_OER = BV(6) | BV(7) | BV(8); \ + } while (0) + +#define TAS5706A_MCLK_INIT() \ + do { \ + PIOA_PDR = BV(2); /* enable PWM pin */ \ + PWM_CMR2 = 0; /* set prescaler to MCK, left aligned, start with low level */ \ + PWM_CPRD2 = 4; /* 11.2896 MHz MCLK */ \ + PWM_CDTY2 = 2; /* 50% duty */ \ + PWM_ENA = BV(2); /* Enable PWM on MCLK pin */ \ + } while(0) + + +#endif /* HW_TAS5706A_H */ -- 2.25.1