S3C6410裸機(jī)AC97驅(qū)動
目前能夠初始化AC97,能夠進(jìn)入就緒中斷,說明能夠檢測到WM9714,但是無法讀取WM9714,不知道哪里出錯了,目前正在解決中...
AC97.c
/************************************************************************************************************* ?*?文件名: AC97.c ?*?功能: S3C6410?AC97底層驅(qū)動函數(shù) ?*?作者: cp1300@139.com ?*?創(chuàng)建時(shí)間: 2012年10月6日20:41 ?*?最后修改時(shí)間:2012年10月6日 ?*?詳細(xì): AC97控制器底層驅(qū)動 *************************************************************************************************************/ #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) //編解碼器準(zhǔn)備就緒中斷 #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半滿中斷 //延時(shí)控制,單位US #define?AC97_WARMRESET_DELAY 2 //系統(tǒng)熱復(fù)位延時(shí) #define?AC97_COLDRESET_DELAY 2 //系統(tǒng)冷復(fù)位延時(shí) #define?AC97_CMDREAD_DELAY 2000//讀取延時(shí) #define?AC97_CMDWRITE_DELAY 22 //寫命令延時(shí) /************************************************************************************************************************* *函數(shù)????: void?AC97_WarmReset(void) *功能????: AC97控制器熱復(fù)位 *參數(shù)????: 無 *返回????: 無 *依賴 :? 底層宏定義 *作者?????: cp1300@139.com *時(shí)間?????: 20121006 *最后修改時(shí)間: 20121006 *說明?????: 用于從關(guān)閉電源喚醒編解碼器 *************************************************************************************************************************/ void?AC97_WarmReset(void) { AC97->GLBCTRL?&=?~(0xf); //清除設(shè)置 AC97->GLBCTRL?|=?BIT1; //開始復(fù)位 Delay_US(AC97_WARMRESET_DELAY); //延時(shí),大于1US AC97->GLBCTRL?&=?~BIT1; //結(jié)束復(fù)位 AC97_ACLinkOn(); AC97_EnTraansferACLink(); Delay_US(1); } /************************************************************************************************************************* *函數(shù)????: void?AC97_ColdReset(void) *功能????: AC97控制器冷復(fù)位 *參數(shù)????: 無 *返回????: 無 *依賴 :? 底層宏定義 *作者?????: cp1300@139.com *時(shí)間?????: 20121006 *最后修改時(shí)間: 20121006 *說明?????: 用于復(fù)位編解碼器和控制器的邏輯,復(fù)位時(shí)間最小1us *************************************************************************************************************************/ void?AC97_ColdReset(void) { AC97->GLBCTRL?|=?BIT0; //開始復(fù)位 Delay_US(AC97_COLDRESET_DELAY); AC97->GLBCTRL?&=?~BIT0; //結(jié)束復(fù)位 AC97_WarmReset(); Delay_US(1); } /************************************************************************************************************************* *函數(shù)????: u8?AC97_Init(void) *功能????: AC97控制器初始化 *參數(shù)????: 無 *返回????: 1:初始化失敗;0:初始化成功 *依賴 :? 底層宏定義 *作者?????: cp1300@139.com *時(shí)間?????: 20121006 *最后修改時(shí)間: 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控制器門控時(shí)鐘 AC97_ColdReset(); //AC97控制器冷復(fù)位 AC97_IntClear(CODE_READY_INT); //清除準(zhǔn)備就緒中斷 AC97_IntEnable(CODE_READY_INT,ENABLE); //使能準(zhǔn)備就緒中斷 while(!(AC97_GetIntStatus()?&?CODE_READY_INT)) //等待準(zhǔn)備就緒中斷 { i?++; if(i?>?1000) { DEBUG("AC97?Waint?Time?Out!n"); return?1; } Delay_MS(1); } AC97_IntEnable(CODE_READY_INT,DISABLE); //關(guān)閉準(zhǔn)備就緒中斷 AC97_IntClear(CODE_READY_INT); //清除準(zhǔn)備就緒中斷 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 *時(shí)間?????: 20121006 *最后修改時(shí)間: 20121006 *說明?????: 連續(xù)寫命令需要延時(shí),一個命令到下一個命令之間有延時(shí)多于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 *時(shí)間?????: 20121008 *最后修改時(shí)間: 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 *時(shí)間?????: 20121008 *最后修改時(shí)間: 20121008 *說明?????: 無 *************************************************************************************************************************/ void?AC97_IntClear(u32?Int) { AC97->GLBCTRL?|=?(Int?<<?8); //寫1清除對應(yīng)中斷 } /************************************************************************************************************************* *函數(shù)????: u32?AC97_GetIntStatus(void) *功能????: 獲取AC97中斷狀態(tài) *參數(shù)????: 無 *返回????: 中斷狀態(tài) *依賴 :? 底層宏定義 *作者?????: cp1300@139.com *時(shí)間?????: 20121008 *最后修改時(shí)間: 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 *時(shí)間?????: 20121009 *最后修改時(shí)間: 20121009 *說明?????: 無 *************************************************************************************************************************/ AC97_State?AC97_GetContStatus(void) { return?(AC97_State)(AC97->GLBSTAT?&?0x07); } //AC97控制器中斷服務(wù)程序 void?__irq?Isr_AC97(void) { if(AC97->GLBSTAT?&?CODE_READY_INT) //編解碼器準(zhǔn)備就緒中斷 { } 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底層驅(qū)動函數(shù) ?*?作者: cp1300@139.com ?*?創(chuàng)建時(shí)間: 2012年10月6日20:41 ?*?最后修改時(shí)間:2012年10月6日 ?*?詳細(xì): AC97控制器底層驅(qū)動 *************************************************************************************************************/ #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閃爍程序,在定時(shí)器0中斷服務(wù)程序中閃爍,周期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); //初始化定時(shí)器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)