歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

S3C6410裸機AC97驅動

目前能夠初始化AC97,能夠進入就緒中斷,說明能夠檢測到WM9714,但是無法讀取WM9714,不知道哪裡出錯了,目前正在解決中...

AC97.c

/*************************************************************************************************************
 * 文件名: AC97.c
 * 功能:  S3C6410 AC97底層驅動函數
 * 作者:  [email protected]
 * 創建時間: 2012年10月6日20:41
 * 最後修改時間:2012年10月6日
 * 詳細:  AC97控制器底層驅動
*************************************************************************************************************/
#include "system.h"
#include "ac97.h"
#include "delay.h"


//使能AC97-LINK傳輸數據
#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 //系統熱復位延時
#define AC97_COLDRESET_DELAY  2 //系統冷復位延時
#define AC97_CMDREAD_DELAY   2000//讀取延時
#define AC97_CMDWRITE_DELAY   22 //寫命令延時

 


/*************************************************************************************************************************
*函數    : void AC97_WarmReset(void)
*功能    : AC97控制器熱復位
*參數    : 無
*返回    : 無
*依賴 :  底層宏定義
*作者    : [email protected]
*時間    : 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);
}


/*************************************************************************************************************************
*函數    : void AC97_ColdReset(void)
*功能    : AC97控制器冷復位
*參數    : 無
*返回    : 無
*依賴 :  底層宏定義
*作者    : [email protected]
*時間    : 20121006
*最後修改時間: 20121006
*說明    : 用於復位編解碼器和控制器的邏輯,復位時間最小1us
*************************************************************************************************************************/
void AC97_ColdReset(void)
{
 AC97->GLBCTRL |= BIT0;    //開始復位
 Delay_US(AC97_COLDRESET_DELAY);
 AC97->GLBCTRL &= ~BIT0;    //結束復位
 AC97_WarmReset();
 Delay_US(1);
}


/*************************************************************************************************************************
*函數    : u8 AC97_Init(void)
*功能    : AC97控制器初始化
*參數    : 無
*返回    : 1:初始化失敗;0:初始化成功
*依賴 :  底層宏定義
*作者    : [email protected]
*時間    : 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;
}


/*************************************************************************************************************************
*函數    : u16 AC97_CodeCMD(AC97_CMD AC97_RW,u8 RegAddr,u16 CmdData)
*功能    : AC97讀寫命令控制
*參數    : AC97_RW:讀寫控制,見AC97_CMD;RegAddr:寄存器地址;CmdData:命令數據
*返回    : 無
*依賴 :  底層宏定義
*作者    : [email protected]
*時間    : 20121006
*最後修改時間: 20121006
*說明    : 連續寫命令需要延時,一個命令到下一個命令之間有延時多於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;
 }
}

 


/*************************************************************************************************************************
*函數    :  void AC97_IntEnable(u32 Int,u8 Enable)
*功能    :  AC97控制器中斷控制
*參數    :  Int:中斷編號,見宏定義;Enable:ENABLE:使能中斷,DISABLE:取消中斷
*返回    :  無
*依賴 :  底層宏定義
*作者    :  [email protected]
*時間    : 20121008
*最後修改時間: 20121008
*說明    : 無
*************************************************************************************************************************/
void AC97_IntEnable(u32 Int,u8 Enable)
{
 if(Enable == ENABLE) //使能中斷
 {
  AC97->GLBCTRL |= Int;
 }
 else     //取消中斷
 {
  AC97->GLBCTRL &= ~Int;
 }
}


/*************************************************************************************************************************
*函數    :  void AC97_IntClear(u32 Int)
*功能    :  AC97控制器中斷清除
*參數    :  Int:中斷編號,見宏定義
*返回    :  無
*依賴 :  底層宏定義
*作者    :  [email protected]
*時間    : 20121008
*最後修改時間: 20121008
*說明    : 無
*************************************************************************************************************************/
void AC97_IntClear(u32 Int)
{
 AC97->GLBCTRL |= (Int << 8); //寫1清除對應中斷
}

 

/*************************************************************************************************************************
*函數    :  u32 AC97_GetIntStatus(void)
*功能    :  獲取AC97中斷狀態
*參數    :  無
*返回    :  中斷狀態
*依賴 :  底層宏定義
*作者    :  [email protected]
*時間    : 20121008
*最後修改時間: 20121008
*說明    : 返回的中斷狀態與中斷編號相與
*************************************************************************************************************************/
u32 AC97_GetIntStatus(void)
{
 return (AC97->GLBSTAT & (0x7f << 16));
}

 

/*************************************************************************************************************************
*函數    :  AC97_State AC97_GetContStatus(void)
*功能    :  獲取AC97控制器狀態
*參數    :  無
*返回    :  控制器狀態,見AC97_State
*依賴 :  底層宏定義
*作者    :  [email protected]
*時間    : 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半滿中斷
 {
 
 }
}

Copyright © Linux教程網 All Rights Reserved