⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aic23b.c

📁 方便飞利浦arm7tdmi 处理器lpc2100开发的C函数库 Procyon ARMlib-LPC2100 C-Language Function Library for Philips LPC21
💻 C
字号:
/*! \file aic23b.c \brief TI TLV320AIC23B Audio Codec Driver. */
//*****************************************************************************
//
// File Name	: 'aic23b.c'
// Title		: TI TLV320AIC23B Audio Codec Driver
// Author		: Pascal Stang - Copyright (C) 2004
// Created		: 2004.05.05
// Revised		: 2004.07.12
// Version		: 0.1
// Target MCU	: ARM processors
// Editor Tabs	: 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested.  Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
//		which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************

#include "global.h"
#include "config.h"
#include "i2c.h"
#include "spi.h"
#include "lpc210x.h"
#include "armVIC.h"
#include "aic23b.h"

volatile u32 AicSpiCount = 0;
volatile u32 *SpiDataPtr;
volatile u32 SpiData = 0;
volatile u08 SpiDatab[6];
volatile u32 SpiCount = 0;

// Sin wave table (256 steps, 16-bit output)
signed short SinTable256_16[] = {
     0,	   804,	  1608,	  2410,	  3212,	  4011,	  4808,	  5602,	
  6393,	  7179,	  7962,	  8739,	  9512,	 10278,	 11039,	 11793,	
 12539,	 13279,	 14010,	 14732,	 15446,	 16151,	 16846,	 17530,	
 18204,	 18868,	 19519,	 20159,	 20787,	 21403,	 22005,	 22594,	
 23170,	 23731,	 24279,	 24811,	 25329,	 25832,	 26319,	 26790,	
 27245,	 27683,	 28105,	 28510,	 28898,	 29268,	 29621,	 29956,	
 30273,	 30571,	 30852,	 31113,	 31356,	 31580,	 31785,	 31971,	
 32137,	 32285,	 32412,	 32521,	 32609,	 32678,	 32728,	 32757,	
 32767,	 32757,	 32728,	 32678,	 32609,	 32521,	 32412,	 32285,	
 32137,	 31971,	 31785,	 31580,	 31356,	 31113,	 30852,	 30571,	
 30273,	 29956,	 29621,	 29268,	 28898,	 28510,	 28105,	 27683,	
 27245,	 26790,	 26319,	 25832,	 25329,	 24811,	 24279,	 23731,	
 23170,	 22594,	 22005,	 21403,	 20787,	 20159,	 19519,	 18868,	
 18204,	 17530,	 16846,	 16151,	 15446,	 14732,	 14010,	 13279,	
 12539,	 11793,	 11039,	 10278,	  9512,	  8739,	  7962,	  7179,	
  6393,	  5602,	  4808,	  4011,	  3212,	  2410,	  1608,	   804,	
     0,	  -804,	 -1608,	 -2410,	 -3212,	 -4011,	 -4808,	 -5602,	
 -6393,	 -7179,	 -7962,	 -8739,	 -9512,	-10278,	-11039,	-11793,	
-12539,	-13279,	-14010,	-14732,	-15446,	-16151,	-16846,	-17530,	
-18204,	-18868,	-19519,	-20159,	-20787,	-21403,	-22005,	-22594,	
-23170,	-23731,	-24279,	-24811,	-25329,	-25832,	-26319,	-26790,	
-27245,	-27683,	-28105,	-28510,	-28898,	-29268,	-29621,	-29956,	
-30273,	-30571,	-30852,	-31113,	-31356,	-31580,	-31785,	-31971,	
-32137,	-32285,	-32412,	-32521,	-32609,	-32678,	-32728,	-32757,	
-32767,	-32757,	-32728,	-32678,	-32609,	-32521,	-32412,	-32285,	
-32137,	-31971,	-31785,	-31580,	-31356,	-31113,	-30852,	-30571,	
-30273,	-29956,	-29621,	-29268,	-28898,	-28510,	-28105,	-27683,	
-27245,	-26790,	-26319,	-25832,	-25329,	-24811,	-24279,	-23731,	
-23170,	-22594,	-22005,	-21403,	-20787,	-20159,	-19519,	-18868,	
-18204,	-17530,	-16846,	-16151,	-15446,	-14732,	-14010,	-13279,	
-12539,	-11793,	-11039,	-10278,	 -9512,	 -8739,	 -7962,	 -7179,	
 -6393,	 -5602,	 -4808,	 -4011,	 -3212,	 -2410,	 -1608,	  -804,	
};


void aicInit(void)
{
	i2cInit();

	aicWriteReg(AIC_REG_RESET);
	aicWriteReg(AIC_REG_POWERDOWN | BIT(AIC_PD_MIC));
	aicWriteReg(AIC_REG_ANALOG_PATH | BIT(AIC_AP_DAC));
	aicWriteReg(AIC_REG_DIGITAL_PATH | BIT(AIC_DP_DEEMP1));

	// preset volume
	aicSetVolumeHp(5);
}

int aicWriteReg(u16 regdata)
{
	u08 packet[2];
	packet[0] = regdata>>8;
	packet[1] = regdata;
	if(i2cMasterSendNI(AIC_I2C_ADDR, 2, packet) == I2C_OK)
		return TRUE;
	else
		return FALSE;
}

void aicSetVolumeLineIn(u08 volume)
{
	// limit and bitmask
	volume = MIN(volume,31);
	volume &= 0x001F;
	// write to left and right channel
	aicWriteReg(AIC_REG_VOL_LINEIN_LEFT |
		volume | BIT(AIC_VLIL_LIM) | BIT(AIC_VLIL_LRS));
}

void aicSetVolumeHp(u08 volume)
{
	// add mute offset
	volume += 0x30;
	// limit and bitmask
	volume = MIN(volume,127);
	volume &= 0x007F;
	// write to left and right channel
	aicWriteReg(AIC_REG_VOL_HP_LEFT |
		volume | BIT(AIC_VHPL_LZC) | BIT(AIC_VHPL_LRS));
}

void aicDigitalEnable(void)
{
	// setup digital data format
	aicWriteReg(AIC_REG_INTERFACE_FORMAT | BIT(AIC_IF_MS)
		| AIC_IF_24BIT | AIC_IF_DSP);

	// set sample rate
	aicWriteReg(AIC_REG_SAMPLE_RATE |
		BIT(AIC_SR_CLKIN) | BIT(AIC_SR_CLKOUT) | AIC_SR_18432_48KHZ);

	// activate digital interface
	aicWriteReg(AIC_REG_DIGITAL_IF_ACT | 0x01);
}

void aicSpiInit(void)
{
	spiInit();

	// switch to slave mode
	SPCR &= BIT(SPCR_MSTR);
	// enable the SPI interrupt
	SPCR |= BIT(SPCR_SPIE);

	// initialize the interrupt vector
	VICIntSelect &= ~VIC_BIT(VIC_SPI);		// SPI selected as IRQ
	VICVectCntl1 = VIC_ENABLE | VIC_SPI;	// SPI on VIC vector 1
	VICVectAddr1 = (uint32_t)aicSpiService;	// address of the ISR
	VICIntEnable = VIC_BIT(VIC_SPI);		// SPI interrupt enabled
/*
	// initialize the FIQ vector
	VICIntSelect |= VIC_BIT(VIC_SPI);		// SPI selected as FIQ
	VICIntEnable = VIC_BIT(VIC_SPI);		// SPI interrupt enabled
*/
	// initialize the interrupt vector
	VICIntSelect &= ~VIC_BIT(VIC_TIMER1);	// TIMER1 selected as IRQ
	VICVectCntl0 = VIC_ENABLE | VIC_TIMER1;	// TIMER1 on VIC vector 0
	VICVectAddr0 = (uint32_t)aicLRCService;	// address of the ISR
	VICIntEnable = VIC_BIT(VIC_TIMER1);		// TIMER1 interrupt enabled

	// setup timer1
	// set pinselect
	PINSEL0 &= ~(1<<20);
	PINSEL0 |= (1<<21);
	// start timer
	T1TCR = TCR_ENABLE;
	// enable timer1 interrupt on CR0 rising edge
	T1CCR = TCCR_CR0_I | TCCR_CR0_R;

	// initialize SPI SS driver
	IODIR |= BIT(12);
	// assert address
	IOCLR = BIT(12);
	IOSET = BIT(12);

	AicSpiCount = 0;
	SpiData = 0;
	SpiCount = 3;
	SpiDataPtr = &SpiData;
}

u32 aicGetSampleCount(void)
{
	return AicSpiCount;
}

void aicClearSampleCount(void)
{
	AicSpiCount = 0;
}

void fast_interrupt_exception(void)
{
	// perform proper ISR entry so thumb-interwork works properly
	ISR_ENTRY();
	// recover registers and return
	ISR_EXIT();
}

void aicLRCService(void)
{
	ISR_ENTRY();
	// clear CR0 Interrupt
	T1IR |= TIR_CR0I;
	VICSoftIntClear = (1<<VIC_TIMER1);

	//VICIntEnable = VIC_BIT(VIC_SPI);		// SPI interrupt enabled
	IOCLR = BIT(12);
	SpiCount=3;
	SpiData = (AicSpiCount>>8) | ((AicSpiCount<<8) & 0xFF00);
	//SpiDataPtr = &SpiData;
	AicSpiCount++;

	VICVectAddr = 0x00000000;             // clear this interrupt from the VIC
	ISR_EXIT();                           // recover registers and return
}

void aicSpiService(void)
{
	u32 data;

	// perform proper ISR entry so thumb-interwork works properly
	ISR_ENTRY();
	// clear SPI interrupt
	SPINT = 0x01;
	//VICSoftIntClear = VIC_BIT(VIC_SPI);

	data = SPSR;

//	if(SPSR & BIT(SPSR_SPIF))
//	{
//	}

	// read the data
	//data = SPDR;
	// write the data
	SPDR = SpiDatab[0];
	//SPDR = SpiData;
	SpiData = SpiData>>8;
	SpiCount--;
	if(!SpiCount)
	{
		//VICIntEnClear = VIC_BIT(VIC_SPI);		// SPI interrupt disabled
		IOSET = BIT(12);
	}

//	AicSpiCount++;

	// clear this interrupt from the VIC
	VICVectAddr = 0x00000000;
	// recover registers and return
	ISR_EXIT();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -