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

📄 aic27.c

📁 Real-Time Digital Signal Processing Implementations, Applications, and Experiments with the TMS320C
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************/
/******************************************************************************/
/*  aic27.c - TLV320AIC27 Audio Codec Driver Routines                         */
/*                                                                            */
/*   This module is the device driver library for the TLV320AIC27 Audio Codec */
/*   on the 5510 EVM board.                                                   */
/*                                                                            */
/*  FUNCTIONS:                                                                */
/*                                                                            */
/*    aic27_open() - Open codec connection to McBSP with default reg values   */
/*    aic27_close() - Close codec connection to McBSP                         */
/*    aic27_init() - Initializes AIC27 control registers.                     */
/*    aic27_reset() - Reset the codec to the default configuration.           */
/*    aic27_read_reg() - Read an AIC27 control register                       */
/*    aic27_write_reg() - Write an AIC27 control register                     */
/*    aic27_sample_rate() - Configures the specified channel's sampling rate  */
/*    aic27_cont_play() - Sets continuous play (D/A) mode                     */
/*    aic27_cont_capture() - Sets continuous capture (A/D) mode               */
/*    aic27_stop_play() - Stops sending data to AIC27                         */
/*    aic27_stop_capture() - Stops receiving data from AIC27                  */
/*                                                                            */
/******************************************************************************/

/******************************************************************************/
/* FILE Global PROTOTYPES                                                     */
/******************************************************************************/

#pragma CODE_SECTION(aic27_open, "EVM5510");
#pragma CODE_SECTION(aic27_close, "EVM5510");
#pragma CODE_SECTION(aic27_init, "EVM5510");
#pragma CODE_SECTION(aic27_reset, "EVM5510");
#pragma CODE_SECTION(aic27_read_reg, "EVM5510");
#pragma CODE_SECTION(aic27_write_reg, "EVM5510");
#pragma CODE_SECTION(aic27_sample_rate, "EVM5510");
#pragma CODE_SECTION(aic27_cont_play, "EVM5510");
#pragma CODE_SECTION(aic27_cont_capture, "EVM5510");
#pragma CODE_SECTION(aic27_stop_play, "EVM5510");
#pragma CODE_SECTION(aic27_stop_capture, "EVM5510");

/******************************************************************************/
/* INCLUDES                                                                   */
/******************************************************************************/
//EVM Driver Include Files
#include  <stddef.h>
#include  <type.h>          //typedefs
#include  <aic27.h>         //AIC27 Codec public header file
#include  <board.h>         //board definitions
#include <regs55x.h>
#include <mcbsp55x.h>
#include <dma55x.h>
#include <intr.h>

/******************************************************************************/
/* DEFINITIONS                                                                */
/******************************************************************************/
//AIC27 timeslot valid bits
#define AIC27_CODEC_READY   	0x8000ul
#define AIC27_VALID_FRAME   	0x8000ul
#define AIC27_VALID_REGADDR_CH	0x4000ul //SLOT 1
#define AIC27_VALID_REGDATA_CH	0x2000ul //SLOT 2
#define AIC27_LEFT_CH			0x1000ul //Play data to left channel only
#define AIC27_RIGHT_CH   		0x0800ul //Play data to Right channel only
#define AIC27_BOTH_CH	 		0x1800ul //Play data to both channels
#define AIC27_DATA_REQ          0x0C00ul //On-demand data requests bit for channels 3 & 4
#define AIC27_SLOT3_REQ         0x0800ul //On-demand data request bit for channel 3
#define AIC27_SLOT4_REQ         0x0400ul //On-demand data request bit for channel 4

#define REG_READ_REQUEST        0x80000ul // b19 in composite 20-bit word

//DMA settings
#define AIC27TXCH				4		//DMA Ch 4
#define AIC27_TXDMA_FLAG		DMAC4
#define AIC27_TXDMA_TRAP		DMAC4_TRAP

#define AIC27RXCH				5		//DMA Ch 5
#define AIC27_RXDMA_FLAG		DMAC5
#define AIC27_RXDMA_TRAP		DMAC5_TRAP

#define DMA_BUFSIZE				5

//McBsp setting for AC'97 compliant codec in dual mode
#define WD_PER_FRAME_1			0x0
#define WD_PER_FRAME_4			0x3

#define RCR1_VAL				((WD_PER_FRAME_1 << 8) | (WORD_LENGTH_16 << 5))

#define RCR2_VAL 				((DUAL_PHASE        << 15) |\
								(WD_PER_FRAME_4     << 8)  |\
								(WORD_LENGTH_20     << 5)  |\
								(NO_COMPAND_MSB_1ST << 3)  |\
								(NO_FRAME_IGNORE    << 2)  |\
								(DATA_DELAY1        << 0))

#define XCR1_VAL				((WD_PER_FRAME_1 << 8) | (WORD_LENGTH_16 << 5))

#define XCR2_VAL				((DUAL_PHASE        << 15) |\
								(WD_PER_FRAME_4     << 8)  |\
								(WORD_LENGTH_20     << 5)  |\
								(NO_COMPAND_MSB_1ST << 3)  |\
								(NO_FRAME_IGNORE    << 2)  |\
								(DATA_DELAY1        << 0))

#define PCR_VAL					((FSYNC_POL_HIGH<<3)|(FSYNC_POL_HIGH<<2)|(CLKX_POL_RISING<<1)|(CLKR_POL_FALLING))

#define SPCR1_VAL               0
#define SPCR2_VAL               0

#define SRGR1_VAL               0
#define SRGR2_VAL               0

/******************************************************************************/
/* ENUMs                                                                      */
/******************************************************************************/
/*****************************************************************************/
/* AIC27 state                                                               */
/*****************************************************************************/
typedef enum
{
   AIC27_CODEC_CLOSED    = 0,
   AIC27_CODEC_OPENED    = 1
} AIC27State, *PAIC27State;

/******************************************************************************/
/* AIC27 codec structure  													  */
/******************************************************************************/
typedef struct _AIC27packet
{ 
    s16        status;        //complete (1) or not complete (0)
    u16        size;          //buffer size (64K max)
    u16        indx;          //sample count
    bool       bufi;          //selects ping-pong buffer
    s16        *pBuf[2];      //pointers to ping-pong buffers
    Fp         callback;      //callback function
} AIC27Packet, *PAIC27Packet;

typedef struct _AIC27Codec
{ 
    AIC27State state;		  //codec state
    AIC27Packet rxPkt;        //receive packet
    AIC27Packet txPkt;        //transmit packet
} AIC27Codec, *PAIC27Codec;

typedef struct _AIC27Reg
{
	u32  tag;
    u32  addr;       //20-bit reg address (slot 0)
    u32  data;       //20-bit reg value   (slot 1)
} AIC27Prog, *PAIC27Prog;

typedef struct _AIC27DmaStruct
{
	u32  tag;
    u32  addr;
    u32  data;
	u32  leftCh;
	u32  rightCh;
} AIC27DmaStruct, *PAIC27DmaStruct;

/******************************************************************************/
/* GLOBAL VARIABLES                                                           */
/******************************************************************************/
#pragma DATA_ALIGN(dmaTxBuf, 2 /*4*/)
#pragma DATA_ALIGN(dmaRxBuf, 2 /*4*/)

#pragma DATA_SECTION(dmaTxBuf, "EVMDATA");
#pragma DATA_SECTION(dmaRxBuf, "EVMDATA");
#pragma DATA_SECTION(aic27Status, "EVMDATA");
#pragma DATA_SECTION(aic27Cmd, "EVMDATA");

//pointer to DMA buffers allocated in ASM
volatile AIC27DmaStruct dmaTxBuf;
volatile AIC27DmaStruct dmaRxBuf;

volatile AIC27Prog aic27Status = {0,0,0};
volatile AIC27Prog aic27Cmd = {(u32)AIC27_VALID_FRAME,0,0};
/******************************************************************************/
/* FILE LOCAL (STATIC) VARIABLES                                              */
/******************************************************************************/

#pragma DATA_SECTION(cdx, "EVMDATA");
#pragma DATA_SECTION(writeDone, "EVMDATA");
#pragma DATA_SECTION(readDone, "EVMDATA");
#pragma DATA_SECTION(rx_stop, "EVMDATA");
#pragma DATA_SECTION(tx_stop, "EVMDATA");

static volatile AIC27Codec cdx = {AIC27_CODEC_CLOSED, 0, 0};

static volatile bool writeDone = True;
static volatile bool readDone = True;

static volatile bool rx_stop = False;
static volatile bool tx_stop = False;

/******************************************************************************/
/* FILE LOCAL (STATIC) PROTOTYPES                                             */
/******************************************************************************/
#pragma CODE_SECTION(_serial_reset, "EVM5510");
#pragma CODE_SECTION(_setup_aic27_serial_port, "EVM5510");
#pragma CODE_SECTION(_reset_aic27_pkts, "EVM5510");
#pragma CODE_SECTION(_setup_aic27_registers, "EVM5510");
#pragma CODE_SECTION(_setup_aic27_dma, "EVM5510");
#pragma CODE_SECTION(_enable_aic27_interrupt, "EVM5510");
#pragma CODE_SECTION(_disable_aic27_interrupt, "EVM5510");
#pragma CODE_SECTION(enable_codec_comm, "EVM5510");
#pragma CODE_SECTION(disable_codec_comm, "EVM5510");
#pragma CODE_SECTION(reset_dma, "EVM5510");
#pragma CODE_SECTION(setMemSpace, "EVM5510");
#pragma CODE_SECTION(_aic27_rxdma_isr, "EVM5510");

static void _serial_reset();
static void _setup_aic27_serial_port();
static void _reset_aic27_pkts();
static void _setup_aic27_registers();
static void _setup_aic27_dma();
static void _enable_aic27_interrupt();
static void _disable_aic27_interrupt();
static void enable_codec_comm();
static void disable_codec_comm();
static void reset_dma();
static u16 setMemSpace(u32 addr);

// McBSP Interrupt Handler
interrupt void _aic27_rxdma_isr(void);

/******************************************************************************/
/* aic27_open() - Open AIC27 codec and connect codec to McBSP.                */
/*																			  */
/*                                                                            */
/*    Parameters - None                                                       */
/*                                                                            */
/*    Returns - BRD_OK on success, BRD_ERROR on failure.                      */
/*                                                                            */
/******************************************************************************/
int aic27_open()
{
    // If codec is already open return BRD_OK
    if (cdx.state == AIC27_CODEC_OPENED)
		return BRD_OK;

    // Set flag to opened
    cdx.state = AIC27_CODEC_OPENED;
		
    // Initialize AIC27
    aic27_init();
	
    // Return true
    return BRD_OK;
}

/******************************************************************************/
/* aic27_close() - Closes codec connection									  */
/*                                                                            */
/*    Parameters - None                                                       */
/*                                                                            */
/*    Returns - BRD_OK on success, BRD_ERROR on failure.                      */
/*                                                                            */
/******************************************************************************/
int aic27_close()
{
    // If codec not opened, then just return
    if (cdx.state == AIC27_CODEC_CLOSED)
		return BRD_OK;
	
    // Disable codec interrupt
	disable_codec_comm();

    cdx.state = AIC27_CODEC_CLOSED;
	
    return BRD_OK;
}

/******************************************************************************/
/* aic27_init() - Initialize AIC27 codec by setting up the registers          */
/*                                                                            */
/*    Parameters - None                                                       */
/*                                                                            */
/*    Returns - None                                                          */
/*                                                                            */
/******************************************************************************/
void aic27_init()
{
	rx_stop = tx_stop = False;

    //Enable codec communications
    enable_codec_comm();

	//Setup AIC27 codec registers
	_setup_aic27_registers();
}

/******************************************************************************/
/* aic27_reset() - Reset the codec to the default configuration.              */
/*                                                                            */
/*   This function resets the AIC27 codec by sending it a software reset.     */
/*   All registers are configured to their default values.                    */
/*                                                                            */
/*    Parameters - None                                                       */
/*                                                                            */
/*    Returns - BRD_OK on success, BRD_ERROR on failure.                      */
/*                                                                            */
/******************************************************************************/
int aic27_reset()
{
	//reset aic27 codec by writing any value to register the reset reg (addr 0x00)
	if (aic27_write_reg(RESET, 0xffff, 0xffff) == (u16)BRD_ERROR)
		return BRD_ERROR;

	disable_codec_comm();

    cdx.state = AIC27_CODEC_OPENED;

    return BRD_OK;
}

/******************************************************************************/
/*    aic27_read_reg() - Read an AIC27 control register                       */
/*                                                                            */
/*    Parameters -                                                            */
/*     reg - an element of an enumeration indicating the register to read.    */
/*                                                                            */
/*    Returns - Content of the indicated register                             */
/*                                                                            */
/******************************************************************************/
u16 aic27_read_reg(AIC27Reg reg)
{
    if (cdx.state == AIC27_CODEC_CLOSED)
		return (u16)BRD_ERROR;

    //disable receive DMA interrupt
    IER0 &= (u16)(~(1<<AIC27_RXDMA_FLAG));

    //assemble cmd addr
	//b19 in composite 20-bit word is 1
	//aic27Cmd.addrL = ((reg & 0xe) << 12);
	//aic27Cmd.addrH = REG_READ_REQUEST | ((reg & 0x70) >> 4);
    aic27Cmd.addr = REG_READ_REQUEST | ((u32)((u32)reg & 0x7e) << 12);
	
    //data must be 0 for read
    aic27Cmd.data = 0;

    //set tag for next output frame (indicate addr/data slots are valid)
    aic27Cmd.tag |= (AIC27_VALID_REGADDR_CH | AIC27_VALID_REGDATA_CH);
	aic27Status.tag &= ~(AIC27_VALID_REGADDR_CH | AIC27_VALID_REGDATA_CH);

⌨️ 快捷键说明

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