目前能夠初始化AC97,能夠進入就緒中斷,說明能夠檢測到WM9714,但是無法讀取WM9714,不知道哪里出錯了,目前正在解決中...
AC97.c
/*************************************************************************************************************
?*?文件名: AC97.c
?*?功能: S3C6410?AC97底層驅動函數(shù)
?*?作者: cp1300@139.com
?*?創(chuàng)建時間: 2012年10月6日20:41
?*?最后修改時間:2012年10月6日
?*?詳細: AC97控制器底層驅動
*************************************************************************************************************/
#include?"system.h"
#include?"ac97.h"
#include?"delay.h"
//使能AC97-LINK傳輸數(shù)據(jù)
#define?AC97_EnTraansferACLink() (AC97->GLBCTRL?|=?BIT3)
//使能AC97-LINK
#define?AC97_ACLinkOn() (AC97->GLBCTRL?|=?BIT2)
//AC97中斷定義
#define?AC97_ALL_INT (0x7f?<<?16)//全部中斷
#define?CODE_READY_INT (1?<<?22) //編解碼器準備就緒中斷
#define?PCM_OUT_UNDER_INT (1?<<?21) //PCM輸出通道FIFO空中斷
#define?PCM_IN_OVER_INT (1?<<?20) //PCM輸入通道FIFO滿中斷
#define?MIC_IN_OVER_INT (1?<<?19) //MIC輸入通道FIFO滿中斷
#define?PCM_OUT_THRES_INT (1?<<?18) //PCM輸出通道FIFO半滿中斷
#define?PCM_IN_THRES_INT (1?<<?17) //PCM輸入通道FIFO半滿中斷
#define?MIC_IN_THRES_INT (1?<<?16) //MIC輸入通道FIFO半滿中斷
//延時控制,單位US
#define?AC97_WARMRESET_DELAY 2 //系統(tǒng)熱復位延時
#define?AC97_COLDRESET_DELAY 2 //系統(tǒng)冷復位延時
#define?AC97_CMDREAD_DELAY 2000//讀取延時
#define?AC97_CMDWRITE_DELAY 22 //寫命令延時
/*************************************************************************************************************************
*函數(shù)????: void?AC97_WarmReset(void)
*功能????: AC97控制器熱復位
*參數(shù)????: 無
*返回????: 無
*依賴 :? 底層宏定義
*作者?????: cp1300@139.com
*時間?????: 20121006
*最后修改時間: 20121006
*說明?????: 用于從關閉電源喚醒編解碼器
*************************************************************************************************************************/
void?AC97_WarmReset(void)
{
AC97->GLBCTRL?&=?~(0xf); //清除設置
AC97->GLBCTRL?|=?BIT1; //開始復位
Delay_US(AC97_WARMRESET_DELAY); //延時,大于1US
AC97->GLBCTRL?&=?~BIT1; //結束復位
AC97_ACLinkOn();
AC97_EnTraansferACLink();
Delay_US(1);
}
/*************************************************************************************************************************
*函數(shù)????: void?AC97_ColdReset(void)
*功能????: AC97控制器冷復位
*參數(shù)????: 無
*返回????: 無
*依賴 :? 底層宏定義
*作者?????: cp1300@139.com
*時間?????: 20121006
*最后修改時間: 20121006
*說明?????: 用于復位編解碼器和控制器的邏輯,復位時間最小1us
*************************************************************************************************************************/
void?AC97_ColdReset(void)
{
AC97->GLBCTRL?|=?BIT0; //開始復位
Delay_US(AC97_COLDRESET_DELAY);
AC97->GLBCTRL?&=?~BIT0; //結束復位
AC97_WarmReset();
Delay_US(1);
}
/*************************************************************************************************************************
*函數(shù)????: u8?AC97_Init(void)
*功能????: AC97控制器初始化
*參數(shù)????: 無
*返回????: 1:初始化失敗;0:初始化成功
*依賴 :? 底層宏定義
*作者?????: cp1300@139.com
*時間?????: 20121006
*最后修改時間: 20121006
*說明?????: 無
*************************************************************************************************************************/
u8?AC97_Init(void)
{
u16?i?=?0;
//初始化AC97硬件接口
rGPDPUD?=?0x1?<<?2; //AC97BITCLK?CDCLK?Pull?Down?Enable
rGPDCON?=?0x44444;
Set_GateClk(PCLK_AC97,ENABLE); //使能AC97控制器門控時鐘
AC97_ColdReset(); //AC97控制器冷復位
AC97_IntClear(CODE_READY_INT); //清除準備就緒中斷
AC97_IntEnable(CODE_READY_INT,ENABLE); //使能準備就緒中斷
while(!(AC97_GetIntStatus()?&?CODE_READY_INT)) //等待準備就緒中斷
{
i?++;
if(i?>?1000)
{
DEBUG("AC97?Waint?Time?Out!n");
return?1;
}
Delay_MS(1);
}
AC97_IntEnable(CODE_READY_INT,DISABLE); //關閉準備就緒中斷
AC97_IntClear(CODE_READY_INT); //清除準備就緒中斷
Delay_MS(1);
return?0;
}
/*************************************************************************************************************************
*函數(shù)????: u16?AC97_CodeCMD(AC97_CMD?AC97_RW,u8?RegAddr,u16?CmdData)
*功能????: AC97讀寫命令控制
*參數(shù)????: AC97_RW:讀寫控制,見AC97_CMD;RegAddr:寄存器地址;CmdData:命令數(shù)據(jù)
*返回????: 無
*依賴 :? 底層宏定義
*作者?????: cp1300@139.com
*時間?????: 20121006
*最后修改時間: 20121006
*說明?????: 連續(xù)寫命令需要延時,一個命令到下一個命令之間有延時多于1?/?48KHz?大約23US
*************************************************************************************************************************/
u16?AC97_CodeCMD(AC97_CMD?AC97_RW,u8?RegAddr,u16?CmdData)
{
if(AC97_RW?==?AC97_READ) //讀取
{
AC97->CODEC_CMD?=?(u32)((RegAddr?<<?16)?|?(1?<<?23)?|?(0?<<?0));
Delay_US(AC97_CMDREAD_DELAY);
return?(u16)(AC97->CODEC_STAT?&?0xffff);
}
else?if(AC97_RW?==?AC97_WRITE) //寫入
{
AC97->CODEC_CMD?=?(u32)((RegAddr?<<?16)?|?(0?<<?23)?|?(CmdData?<<?0));
Delay_US(AC97_CMDWRITE_DELAY);
return?0;
}
else
{
DEBUG("AC97?CMD?Error!n");
return?0;
}
}
/*************************************************************************************************************************
*函數(shù)????: void?AC97_IntEnable(u32?Int,u8?Enable)
*功能????: AC97控制器中斷控制
*參數(shù)????: Int:中斷編號,見宏定義;Enable:ENABLE:使能中斷,DISABLE:取消中斷
*返回????: 無
*依賴 :? 底層宏定義
*作者?????: cp1300@139.com
*時間?????: 20121008
*最后修改時間: 20121008
*說明?????: 無
*************************************************************************************************************************/
void?AC97_IntEnable(u32?Int,u8?Enable)
{
if(Enable?==?ENABLE) //使能中斷
{
AC97->GLBCTRL?|=?Int;
}
else //取消中斷
{
AC97->GLBCTRL?&=?~Int;
}
}
/*************************************************************************************************************************
*函數(shù)????: void?AC97_IntClear(u32?Int)
*功能????: AC97控制器中斷清除
*參數(shù)????: Int:中斷編號,見宏定義
*返回????: 無
*依賴 :? 底層宏定義
*作者?????: cp1300@139.com
*時間?????: 20121008
*最后修改時間: 20121008
*說明?????: 無
*************************************************************************************************************************/
void?AC97_IntClear(u32?Int)
{
AC97->GLBCTRL?|=?(Int?<<?8); //寫1清除對應中斷
}
/*************************************************************************************************************************
*函數(shù)????: u32?AC97_GetIntStatus(void)
*功能????: 獲取AC97中斷狀態(tài)
*參數(shù)????: 無
*返回????: 中斷狀態(tài)
*依賴 :? 底層宏定義
*作者?????: cp1300@139.com
*時間?????: 20121008
*最后修改時間: 20121008
*說明?????: 返回的中斷狀態(tài)與中斷編號相與
*************************************************************************************************************************/
u32?AC97_GetIntStatus(void)
{
return?(AC97->GLBSTAT?&?(0x7f?<<?16));
}
/*************************************************************************************************************************
*函數(shù)????: AC97_State?AC97_GetContStatus(void)
*功能????: 獲取AC97控制器狀態(tài)
*參數(shù)????: 無
*返回????: 控制器狀態(tài),見AC97_State
*依賴 :? 底層宏定義
*作者?????: cp1300@139.com
*時間?????: 20121009
*最后修改時間: 20121009
*說明?????: 無
*************************************************************************************************************************/
AC97_State?AC97_GetContStatus(void)
{
return?(AC97_State)(AC97->GLBSTAT?&?0x07);
}
//AC97控制器中斷服務程序
void?__irq?Isr_AC97(void)
{
if(AC97->GLBSTAT?&?CODE_READY_INT) //編解碼器準備就緒中斷
{
}
if(AC97->GLBSTAT?&?PCM_OUT_UNDER_INT) //PCM輸出通道FIFO空中斷
{
}
if(AC97->GLBSTAT?&?PCM_IN_OVER_INT) //PCM輸入通道FIFO滿中斷
{
}
if(AC97->GLBSTAT?&?MIC_IN_OVER_INT) //MIC輸入通道FIFO滿中斷
{
}
if(AC97->GLBSTAT?&?PCM_OUT_THRES_INT) //PCM輸出通道FIFO半滿中斷
{
}
if(AC97->GLBSTAT?&?PCM_IN_THRES_INT) //PCM輸入通道FIFO半滿中斷
{
}
if(AC97->GLBSTAT?&?MIC_IN_THRES_INT) //MIC輸入通道FIFO半滿中斷
{
}
}AC97.h
/*************************************************************************************************************
?*?文件名: AC97.h
?*?功能: S3C6410?AC97底層驅動函數(shù)
?*?作者: cp1300@139.com
?*?創(chuàng)建時間: 2012年10月6日20:41
?*?最后修改時間:2012年10月6日
?*?詳細: AC97控制器底層驅動
*************************************************************************************************************/
#ifndef?AC97_H_
#define?AC97_H_
//AC97控制器狀態(tài)
typedef?enum
{
AC97_State_Idle? =?0,
AC97_State_Init? =?1,
AC97_State_Ready? =?2,
AC97_State_Active? =?3,
AC97_State_LP? =?4,
AC97_State_Warm? =?5
}AC97_State;
//AC97讀寫命令控制
typedef?enum?
{
AC97_WRITE? =?0,?
AC97_READ? =?1
}AC97_CMD;
u8?AC97_Init(void); //AC97初始化
u16?AC97_CodeCMD(AC97_CMD?AC97_RW,u8?RegAddr,u16?CmdData);
void?AC97_IntEnable(u32?Int,u8?Enable);
void?AC97_IntClear(u32?Int);
u32?AC97_GetIntStatus(void);
AC97_State?AC97_GetContStatus(void);
#endif?/*AC97_H_*/
//main.c
#include?"system.h"
#include?"uart.h"
#include?"tft_lcd.h"
#include?"other.h"
#include?"delay.h"
#include?"timer.h"
#include?"ac97.h"
//LED1閃爍程序,在定時器0中斷服務程序中閃爍,周期400MS
void?LED1_flash(void)
{
LED1_FLASH();
}
int?main(void)
{
LCD_Init(); //初始化LCD
UART0_Init(DISABLE,115200); //初始化串口,失能中斷接收,波特率115200
LED_Init(); //初始化LED
Timer1_Init(400000-1,ENABLE,LED1_flash); //初始化定時器0,周期400ms
lcd_printf("Get_FCLK?:?%d?Hzn",Get_FCLK());
lcd_printf("Get_PCLK?:?%d?Hzn",Get_PCLK());
if(AC97_Init()) //初始化AC97控制器
{
lcd_printf("AC97?Init?error!n");
}
else
{
lcd_printf("AC97?Init?OK!n");
}
lcd_printf("0x%Xn",AC97_CodeCMD(AC97_READ,0x7c,0));
lcd_printf("0x%Xn",AC97_CodeCMD(AC97_READ,0x7e,0));
while(1)
{
LED2_FLASH(); //LED2閃爍
Delay_US(600000);
}
}
我讀取這兩個寄存器的值,但是讀取到的一直是0,不知道問題在哪,明天繼續(xù)解決
//寄存器映射
//AC97控制器?寄存器
typedef?struct
{
vu32 GLBCTRL; ? ?//?0x7F001000?讀/寫? AC97?通用控制寄存器。? 0x00000000
vu32 GLBSTAT; ? ?//?0x7F001004?讀? AC97?全球狀態(tài)寄存器。? 0x00000001
vu32 CODEC_CMD; ? ?//?0x7F001008?讀/寫? AC97?編解碼器命令寄存器。? 0x00000000
vu32 CODEC_STAT; ? ?//?0x7F00100C?讀 AC97?編解碼器狀態(tài)寄存器。? 0x00000000
vu32 PCMADDR; ? ?//?0x7F001010?讀? AC97?的PCM?輸出/輸入?通道FIFO?地址 0x00000000
vu32 MICADDR; ? ?//?0x7F001014?讀? AC97?的MIC?輸入通道FIFO?地址寄存器。 0x00000000
vu32 PCMDATA; ? ?//?0x7F001018?讀/寫? AC97?的PCM?輸出/輸入?通道FIFO?數(shù)據(jù) 0x00000000
vu32 MICDATA; ? ?//?0x7F00101C?讀/寫? AC97?的MIC?輸入通道FIFO?數(shù)據(jù)寄存器。? 0x00000000
}AC97_TypeDef;//AC97?控制器 #define?AC97_BASE 0x7F001000
#define?AC97 ((AC97_TypeDef*)AC97_BASE)





