示例#1
0
文件: tpa6130.c 项目: InSoonPark/asf
/*! \brief Writes data to a register.
 *  \param reg Register index. Use the defines in this file.
 *  \param data Register data. Macros from this file can be used
 *  to ease writing to the bitfields.
 */
static void tpa6130_write_data(uint8_t reg, uint8_t data)
{
  uint16_t message = (reg << 8) | data;
  int twi_status;

  twi_package_t twi_package =
  {
    .chip = TPA6130_TWI_ADDRESS,
    .addr_length = 0,//AVR32_TWI_MMR_IADRSZ_NO_ADDR,
    .buffer = &message,
    .length = sizeof(message)
  };

  do
  {
     twi_status=twi_master_write(TPA6130_TWI, &twi_package);
  }
  while( twi_status != TWI_SUCCESS );

  /* Save write value to shadow registers */
  *(((uint8_t *) &tpa6130_shadow_regs) + reg - 1) = data;
}

/*! \brief Reads data from a register.
 *  The shadow parameter is used to specify if the data should be read
 *  from a driver internal register shadowing or directly from the device.
 *  \param reg Register index.
 *  \param shadow Read from device (shadow=false) or from shadowed register
 *  (shadow=true).
 */
static uint8_t tpa6130_read_data(uint8_t reg, bool shadow)
{
  uint8_t data;
  /*If we want to read from the shadowed registers */
  if(shadow)
  {
    data = *((uint8_t *) &tpa6130_shadow_regs + reg - 1);
  }
  else
  {
    twi_package_t twi_package =
    {
      .chip = TPA6130_TWI_ADDRESS,
      .addr_length = 1,//AVR32_TWI_MMR_IADRSZ_ONE_BYTE,
      .addr[0] = reg,
      .buffer = &data,
      .length = sizeof(data)
    };
    twi_master_read(TPA6130_TWI, &twi_package);
  }
  //print_dbg("Read reg ");
  //print_dbg_ulong(reg);
  //print_dbg(" = 0x");
  //print_dbg_hex(data);
  //print_dbg("\n");

  return data;
}

/*! \brief Probes and initializes the amplifier.
 *  Probes the TWI bus for the amplifier by using the slave address
 *  specified in the configuration (TPA6130_TWI_ADDRESS).
 *  If the device responds with an ACK the version register is read out
 *  and compared to the valid versions (TPA6130_VERSION).
 *  Last step is to set volume to 0, unmute and set the configuration
 *  specified in the conf_tpa6130.h file (stereo, mono ..).
 *
 *  \returns A positive value upon success and a negative value upon failure.
 */
int8_t tpa6130_init(void)
{
  /* Check if the device responds on the TWI bus*/
  if(twi_probe(TPA6130_TWI, TPA6130_TWI_ADDRESS) != TWI_SUCCESS)
  return TWI_NO_CHIP_FOUND;
  /* If the device has no valid version we can not use it */
  if(tpa6130_read_data(TPA6130_I2C_ADDRESS_VERSION, TWI_READ_HW)!= VERSION)
  {
    return -8;
  }
  /* un-mute the output channels, the volume is still 0 and
   * should be increased by an application (fade-in/fade-out) */
  tpa6130_write_data(TPA6130_VOLUME_AND_MUTE, tpa6130_shadow_regs.volume_and_mute);
  /* set stereo/mono mode and enable both amplifiers (left/right) */
  tpa6130_write_data(TPA6130_CONTROL,(TPA6130_MODE << 4) | HP_EN_L | HP_EN_R);

  return TWI_SUCCESS;
}

/*! \brief Shuts down the amplifier and sets it into low power mode.
 *  This is the software low power mode described in the datasheet.
 */
void tpa6130_shutdown(void)
{
  uint8_t data;
  data = tpa6130_read_data(TPA6130_CONTROL, TWI_READ_HW);
  tpa6130_write_data(TPA6130_CONTROL, data | SW_SHUTDOWN);
}
bool RTC_Init(unsigned long pba_hz)
{
	// setup hardware for TWI
	static const gpio_map_t TWI_GPIO_MAP =
	{
		{AVR32_TWI_SDA_0_0_PIN, AVR32_TWI_SDA_0_0_FUNCTION},
		{AVR32_TWI_SCL_0_0_PIN, AVR32_TWI_SCL_0_0_FUNCTION}
	};
	gpio_enable_module(TWI_GPIO_MAP, sizeof(TWI_GPIO_MAP) / sizeof(TWI_GPIO_MAP[0]));
	
	// set TWI options
	twi_options_t twi_options=
	{
		.pba_hz=pba_hz,
		.speed=100000,
		.chip=0				// not used for master mode
	};
	twi_master_init(&AVR32_TWI, &twi_options);
	
	
	if(twi_probe(&AVR32_TWI, RTC_SLAVE_ADDRESS)==TWI_SUCCESS)
	{
		return true;
	}
	else
	{
		return false;
	}
}


/* Return the current time and put it in *TIMER if TIMER is not NULL.  */
// declared in <time.h>
// reads the time from the RTC-chip via I2C (=TWI)
time_t time(time_t *__timer)
{
	time_t t;
	struct tm ts;
	uint8_t b[7]={0};
	
	twi_package_t twi_package=
	{
		.chip=RTC_SLAVE_ADDRESS,
		.addr={0, 0, 0},
		.addr_length=1,
		.buffer=b,
		.length=7
	};
	
	if(twi_master_read(&AVR32_TWI, &twi_package)!=TWI_SUCCESS)
	{
		printf("ERROR: could not read from real-time clock\n");
		return 0;
	}

	ts.tm_sec =  (((b[REG_Seconds]>>4) & 0x7)*10) +  (b[REG_Seconds]&0xF);
	ts.tm_min =  (((b[REG_Minutes]>>4) & 0x7)*10) +  (b[REG_Minutes]&0xF);
	ts.tm_hour = (((b[REG_Hours]  >>4) & 0x3)*10) +  (b[REG_Hours]  &0xF); // 24h format
	// ts_wday must not be initialized!
	ts.tm_mday = (((b[REG_Date] >>4) & 0x3)*10)  +  (b[REG_Date] &0xF);
	ts.tm_mon =  (((b[REG_Month]>>4) & 0x1)*10)  +  (b[REG_Month]&0xF) -1; // tm_mon=0..11
	ts.tm_year = (int)((((b[REG_Year] >>4) & 0xF)*10)  +  (b[REG_Year] &0xF)) + 2000 -1900;

	t = mktime(&ts);

	if(__timer)
	{
		*__timer = t;
	}
	return t;
}