📄 ml2011drv.c
字号:
/******************************************************************************
*
* Oki Sound Library for ML2011
* ML2011 Driver (ML2011drv.c)
*
* Oki Electric Industry Co.,Ltd.
* Software Development Department
*
* 2006, 7, 12 released
* -------------------------------------------------------------------------
* ML2011 Driver Function
******************************************************************************/
/******************************************************************************
* INCLUDE FILES
******************************************************************************/
#include "ML2011.h"
#include "ML2011io.h"
#include "ML2011usersfunc.h"
#include "ML2011drv.h"
/******************************************************************************
* CONSTANTS DEFINITION (local)
******************************************************************************/
#define BIT_MOEN (unsigned char)(0x02)
#define BIT_SPEN (unsigned char)(0x01)
#define SRST_BIT (unsigned char)(0x01)
#define DRV_SET (1)
#define DRV_RESET (0)
#define DRV_MP3_STOP 0x00
#define DRV_MP3_DEC_START 0x01
#define DRV_MP3_PLAY 0x03
#define DRV_MP3_PAUSE 0x01
/*** SAMPLE RATE FOR ML2841 ***/
const unsigned short sampleRateForML2841[9]={8000,11025,12000,16000,22050,24000,32000,44100,48000};
/*_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
/
/ POWER SEQUENCE
/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_*/
/******************************************************************************
* POWER SEQUENCE(GLOBAL)
* -----------------------------
* -L2011drv_Init
******************************************************************************/
/******************************************************************************
* L2011drv_Init()
*******************************************************************************/
void L2011drv_Init(DRV_CTRL *drvCtrl)
{
L2011drv_ReadWriteInit(drvCtrl);
/* Set up power down */
L2011drv_WriteReg(drvCtrl, IDX_PWRDWN, 0x00); /* CLPD=0, CLKE=0 */
/*** Input master clock to CLOCK pin ***/
/* Set the following register. Each value refers to the chapter of "Register of Master Clock " in application note. */
L2011drv_SetClockParameter(drvCtrl);
/* wait */
usrTimerDelay(3);
/* Set up power down */
L2011drv_WriteReg(drvCtrl, IDX_PWRDWN, 0x08); /* CLPD=0, CLKE=1 */
/* Software Reset */
L2011drv_SoftReset(drvCtrl);
/* Set ISS bit (0:original, 1:invert) */
L2011drv_WriteReg(drvCtrl, IDX_IRQENA, DEFAULT_ISS_BIT);
/* Set MP3 Dual channel */
L2011drv_SetMP3DualChSel(drvCtrl, L2011DRV_MP3DUAL_NORMAL);
/* Set up PWM mode */
L2011drv_InitPwmSetting(drvCtrl);
/* Set up power down */
L2011drv_WriteReg(drvCtrl, IDX_PWRDWN,0x10); /* CLPD=1, CLKE=0 */
/* Initialize Driver Control Structure Variable */
drvCtrl->MasterCloskOnNo = 0;
drvCtrl->DacStatus = L2011DRV_AUDIOPATH_OFF;
return;
}
/******************************************************************************
* POWER SEQUENCE(LOCAL)
* ---------------------------
* -L2011drv_SoftReset
* -L2011drv_DacOn
* -L2011drv_DacOff
* -L2011drv_SpAmpOn
* -L2011drv_SpAmpOff
* -L2011drv_HpAmpOn
* -L2011drv_HpAmpOff
* -L2011drv_MasterClockOn
* -L2011drv_MasterClockOff
* -L2011drv_SetClockParameter
* -L2011drv_InitPwmSetting
******************************************************************************/
/***************************************************************
* L2011drv_SoftReset()
****************************************************************/
void L2011drv_SoftReset(DRV_CTRL *drvCtrl)
{
L2011drv_WriteReg(drvCtrl, IDX_SOFTRST, DRV_SET);
usrTimerDelay(1); //--- need 100ns
L2011drv_WriteReg(drvCtrl, IDX_SOFTRST, DRV_RESET);
return;
}
/*******************************************************************************
* L2011drv_DacOn()
*******************************************************************************/
void L2011drv_DacOn(DRV_CTRL *drvCtrl, unsigned char ucApath)
{
unsigned char tmp;
if(drvCtrl->DacStatus == ucApath){
return;
}
/*--- [SP] AOUT --------------------------------------*/
if(ucApath == L2011DRV_AUDIOPATH_AOUT){
L2011drv_HpAmpOff(drvCtrl); /* Close HP Amp */
L2011drv_WriteReg(drvCtrl, IDX_HPPWRDWN, 0x77); /* HP Powerdown and Set monaural*/
tmp = L2011drv_ReadReg(drvCtrl, IDX_ANLGPWRDWN);
L2011drv_WriteReg(drvCtrl, IDX_ANLGPWRDWN, (tmp & (unsigned char)(~BIT_MOEN) )); /* Set MOEN=0 (Enable SP AMP) */
drvCtrl->DacStatus = L2011DRV_AUDIOPATH_AOUT; /* Set audio path parameter */
/*--- [HP] LOUT ROUT ---------------------------------*/
}else{
tmp = L2011drv_ReadReg(drvCtrl, IDX_ANLGPWRDWN);
L2011drv_WriteReg(drvCtrl, IDX_ANLGPWRDWN, (tmp | BIT_MOEN) ); /* Set MOEN=1 */
L2011drv_WriteReg(drvCtrl, IDX_HPPWRDWN, 0x99);
usrTimerDelay(WAIT_TIME_TO_THE_HPAMPOPEN);
L2011drv_HpAmpOn(drvCtrl); /* Open HP Amp */
drvCtrl->DacStatus = L2011DRV_AUDIOPATH_LROUT; /* Set headphone path parameter */
}
}
/*******************************************************************************
* L2011drv_DacOff()
*******************************************************************************/
void L2011drv_DacOff(DRV_CTRL *drvCtrl)
{
unsigned char tmp;
L2011drv_HpAmpOff(drvCtrl); /* Close HP Amp */
tmp = L2011drv_ReadReg(drvCtrl, IDX_ANLGPWRDWN);
L2011drv_WriteReg(drvCtrl, IDX_ANLGPWRDWN, (tmp | BIT_MOEN)); /* Set MOEN=1 */
L2011drv_WriteReg(drvCtrl, IDX_HPPWRDWN, 0x55); /* HP Powerdown */
drvCtrl->DacStatus = L2011DRV_AUDIOPATH_OFF;
}
/*******************************************************************************
* L2011drv_SpAmpOn()
*******************************************************************************/
void L2011drv_SpAmpOn(DRV_CTRL *drvCtrl)
{
unsigned char tmp;
if(drvCtrl->MasterCloskOnNo == 0){
L2011drv_MasterClockOn(drvCtrl);
tmp = L2011drv_ReadReg(drvCtrl, IDX_ANLGPWRDWN);
tmp = tmp & (unsigned char)(~BIT_SPEN);
L2011drv_WriteReg(drvCtrl, IDX_ANLGPWRDWN, tmp); /* Set SPEN=0 */
usrTimerDelay(100); /* wait */
L2011drv_MasterClockOff(drvCtrl);
}else{
tmp = L2011drv_ReadReg(drvCtrl, IDX_ANLGPWRDWN);
tmp = tmp & (unsigned char)(~BIT_SPEN);
L2011drv_WriteReg(drvCtrl, IDX_ANLGPWRDWN, tmp); /* Set SPEN=0 */
}
}
/*******************************************************************************
* L2011drv_SpAmpOff()
*******************************************************************************/
void L2011drv_SpAmpOff(DRV_CTRL *drvCtrl)
{
unsigned char tmp;
tmp = L2011drv_ReadReg(drvCtrl, IDX_ANLGPWRDWN);
tmp = tmp | BIT_SPEN;
L2011drv_WriteReg(drvCtrl, IDX_ANLGPWRDWN, tmp); /* Set SPEN=1 */
}
/*******************************************************************************
* L2011drv_HpAmpOn()
*******************************************************************************/
void L2011drv_HpAmpOn(DRV_CTRL *drvCtrl)
{
usrExtHpAmpOpen();
}
/*******************************************************************************
* L2011drv_HpAmpOff()
*******************************************************************************/
void L2011drv_HpAmpOff(DRV_CTRL *drvCtrl)
{
usrExtHpAmpClose();
}
/*******************************************************************************
* L2011drv_MasterClockOn()
*******************************************************************************/
void L2011drv_MasterClockOn(DRV_CTRL *drvCtrl)
{
if(drvCtrl->MasterCloskOnNo == 0){
/*--- Start PLL Opetation ---*/
L2011drv_WriteReg(drvCtrl, IDX_PWRDWN, 0xe7); /* CLPD=0, CLKE=0 */
/*--- Wait 3ms(tCLOCK1+tCLOCK2) ---*/
usrTimerDelay(WAIT_tCLOCK1+WAIT_tCLOCK2);
/*--- Start LSI Initialize ---*/
L2011drv_WriteReg(drvCtrl, IDX_PWRDWN, 0xef); /* CLPD=0, CLKE=1 */
}
drvCtrl->MasterCloskOnNo ++;
return;
}
/*******************************************************************************
* L2011drv_MasterClockOff()
*******************************************************************************/
void L2011drv_MasterClockOff(DRV_CTRL *drvCtrl)
{
if(drvCtrl->MasterCloskOnNo == 0){
return;
}else{
drvCtrl->MasterCloskOnNo --;
if(drvCtrl->MasterCloskOnNo == 0){
/*--- Set up power down of digital block ---*/
L2011drv_WriteReg(drvCtrl, IDX_PWRDWN, 0xf7); /* CLPD=1, CLKE=0 */
}
}
return;
}
/*******************************************************************************
* ML2011drv_SetClockParameter()
*******************************************************************************/
void L2011drv_SetClockParameter(DRV_CTRL *drvCtrl)
{
L2011drv_WriteReg(drvCtrl, IDX_CLK, DEFAULT_CLK_REGISTER);
L2011drv_WriteReg(drvCtrl, IDX_PLL2CLKDIV, DEFAULT_PLL2CLKDIV_REGISTER);
L2011drv_WriteReg(drvCtrl, IDX_PLL64ACLKDIV, DEFAULT_PLL64ACLKDIV_REGISTER);
L2011drv_WriteReg(drvCtrl, IDX_PLL64ACLKMLT, DEFAULT_PLL64ACLKMLT_REGISTER);
L2011drv_WriteReg(drvCtrl, IDX_PLL88ACLKDIV, DEFAULT_PLL88ACLKDIV_REGISTER);
L2011drv_WriteReg(drvCtrl, IDX_PLL88ACLKMLT, DEFAULT_PLL88ACLKMLT_REGISTER);
L2011drv_WriteReg(drvCtrl, IDX_PLL96ACLKDIV, DEFAULT_PLL96ACLKDIV_REGISTER);
L2011drv_WriteReg(drvCtrl, IDX_PLL96ACLKMLT, DEFAULT_PLL96ACLKMLT_REGISTER);
L2011drv_WriteReg(drvCtrl, IDX_EXTCLKCTRL, DEFAULT_EXTCLKCTRL_REGISTER);
return;
}
/*_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
/
/ PWM CONTROL
/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_*/
/*******************************************************************************
* L2011drv_InitPwmSetting()
*******************************************************************************/
void L2011drv_InitPwmSetting(DRV_CTRL *drvCtrl)
{
L2011drv_WriteReg(drvCtrl, IDX_PWMOUTSEL, DEFAULT_PWMOUTSEL_REGISTER);
L2011drv_WriteReg(drvCtrl, IDX_PORTIO, DEFAULT_PORTIO_REGISTER);
L2011drv_WriteReg(drvCtrl, IDX_PORT, DEFAULT_PORT_REGISTER);
L2011drv_WriteReg(drvCtrl, IDX_PULLUP, DEFAULT_PULLUP_REGISTER);
L2011drv_WriteReg(drvCtrl, IDX_PORTENA, DEFAULT_PORTENA_REGISTER);
return;
}
/*******************************************************************************
* L2011drv_SetPwmaValue()
*******************************************************************************/
signed short L2011drv_SetValue(DRV_CTRL *drvCtrl, unsigned char pwm, unsigned char value)
{
unsigned char tmp;
unsigned char pwmMode;
if(value >= 0x80){
return(L2011DRV_ERR_PARAM);
}
pwmMode = L2011drv_ReadReg(drvCtrl, IDX_PWMOUTSEL);
switch(pwm){
case L2011DRV_PWMTYPE_PWMA:
if(pwmMode & L2011DRV_PWMTYPE_PWMA){
tmp = (unsigned char)(L2011drv_ReadReg(drvCtrl, IDX_PWMA) & 0x80);
L2011drv_WriteReg(drvCtrl, IDX_PWMA, (tmp | (value & 0x7F)) );
}else{
return(L2011DRV_ERR_STATUS);
}
break;
case L2011DRV_PWMTYPE_VIB:
if(pwmMode & L2011DRV_PWMTYPE_VIB){
tmp = (unsigned char)(L2011drv_ReadReg(drvCtrl, IDX_VIB) & 0x80);
L2011drv_WriteReg(drvCtrl, IDX_VIB, (tmp | (value & 0x7F)) );
}else{
return(L2011DRV_ERR_STATUS);
}
break;
default:
return(L2011DRV_ERR_PARAM);
}
return(L2011DRV_OK);
}
/*******************************************************************************
* L2011drv_GetPwmaValue()
*******************************************************************************/
signed short L2011drv_GetValue(DRV_CTRL *drvCtrl, unsigned char pwm, unsigned char *value)
{
unsigned char pwmMode;
pwmMode = L2011drv_ReadReg(drvCtrl, IDX_PWMOUTSEL);
switch(pwm){
case L2011DRV_PWMTYPE_PWMA:
if(pwmMode & L2011DRV_PWMTYPE_PWMA){
*value = (unsigned char)(L2011drv_ReadReg(drvCtrl, IDX_PWMA) & 0x7F);
}else{
return(L2011DRV_ERR_STATUS);
}
break;
case L2011DRV_PWMTYPE_VIB:
if(pwmMode & L2011DRV_PWMTYPE_VIB){
*value = (unsigned char)(L2011drv_ReadReg(drvCtrl, IDX_VIB) & 0x7F);
}else{
return(L2011DRV_ERR_STATUS);
}
break;
default:
return(L2011DRV_ERR_PARAM);
}
return(L2011DRV_OK);
}
/*******************************************************************************
* L2011drv_SetPwmEnable()
*******************************************************************************/
signed short L2011drv_SetEnable(DRV_CTRL *drvCtrl, unsigned char pwm, unsigned char ena)
{
unsigned char value;
unsigned char pwmMode;
pwmMode = L2011drv_ReadReg(drvCtrl, IDX_PWMOUTSEL);
switch(pwm){
case L2011DRV_PWMTYPE_PWMA:
if(pwmMode & L2011DRV_PWMTYPE_PWMA){
value = L2011drv_ReadReg(drvCtrl, IDX_PWMA);
if(ena){
value = 0x80 | value;
}else{
value &= 0x7F;
}
L2011drv_WriteReg(drvCtrl, IDX_PWMA, value);
}else{
return(L2011DRV_ERR_STATUS);
}
break;
case L2011DRV_PWMTYPE_VIB:
if(pwmMode & L2011DRV_PWMTYPE_VIB){
value = L2011drv_ReadReg(drvCtrl, IDX_VIB);
if(ena){
value = 0x80 | value;
}else{
value &= 0x7F;
}
L2011drv_WriteReg(drvCtrl, IDX_VIB, value);
}else{
return(L2011DRV_ERR_STATUS);
}
break;
default:
return(L2011DRV_ERR_PARAM);
}
return(L2011DRV_OK);
}
/*_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
/
/ VOLUME CONTROL
/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_*/
/******************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -