📄 cs44800.c
字号:
//=============================================================================
// File Name: cs44800.c
//
// (c) Copyright [2003] Cirrus Logic Inc. All rights reserved
//
// This source code is Cirrus Logic, Inc. proprietary and confidential
// information
//
// Description:
// Routines to support setup and control of the CS44800
//
// Modification History:
// 10/15/03 - TMS Created
//=============================================================================
#include "apiconfig.h"
#if USE_PWM
#include "apii2c.h"
#include "cs44800.h"
#include "eromdbg.h"
#include "delay.h"
//-----------------------------------------------------------------------------
// External objects
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Local definitions
//-----------------------------------------------------------------------------
#define MAX_VOL 63 // Maximum volume value
#define OFF_VOL 0x81 // CS44800 volume value for
// -127dB
#define RAMP_UP 0x19 // Ramp up value for the Ramp
// config register
#define RAMP_DN 0x09 // Ramp down value for the Ramp
// config register
#define RAMP_OFF 0x01 // Ramp off value for the Ramp
// config register
#define USE_CRYSTAL false // Set to true to use crystal
// Set to false to use oscillator
#define CS44800_CRYSTAL 0x00 // Mask for using crystal as
// CS44800 clock source
#define CS44800_OSC 0x04 // Mask for using oscillator as
// CS44800 clock source
#define CS44800_FB_PDN_MODE 0x00 // Mask for full-bridge outputs
// in PDN mode
#define CS44800_HB_PDN_MODE 0x02 // Mask for half-bridge outputs
// in PDN mode
#define CS44800_PDN 0x01 // Mask to put the CS44800 in PDN
// mode
#define PSR_OFFSET_LIMIT_HI 0x400fff // Upper limit for PSR offset
// value after calibration
#define PSR_OFFSET_LIMIT_LO 0x3fef90 // Lower limit for PSR offset
// value after calibration
#define PSR_INIT_DEC_SCALE 0x220000 // Initial value of the decimator
// scale factor
#define PSR_DEC_DELTA 0x000200 // Amount by which the decimator
// scale factor is adjusted
// each pass through the PSR
// calibration loop
typedef union // Union of a long (32 bits) and
{ // 4 bytes for byte access of a long
unsigned long word;
struct
{
Byte hi;
Byte mh;
Byte ml;
Byte lo;
}byte8;
} lhlong;
#define DEBUG_MSG
#define DEBUG_PWM_WINDOW 6
#ifdef DEBUG_MSG
#define DEBUG_OUT(fmt, args...) { ERomPrintFunc (DEBUG_PWM_WINDOW, fmt, ## args); }
#else
#define DEBUG_OUT(fmt, args...)
#endif
#define CHECK_RETURN(ret) \
if (SUCCESS != ret) \
{ \
ErrPrint("Error communicating to CS44800\n"); \
DEBUG_OUT("Error communicating to CS44800\n"); \
return FAIL; \
}
//-----------------------------------------------------------------------------
// Local objects
//-----------------------------------------------------------------------------
unsigned char Write3Bytes( unsigned char reg,
unsigned char byte1,
unsigned char byte2,
unsigned char byte3);
unsigned char Read3Bytes( unsigned char reg,
unsigned char* byte1,
unsigned char* byte2,
unsigned char* byte3);
//-----------------------------------------------------------------------------
// Function:
int PWM_Init(
// Description:
// Initializes the CS44800 for stand-alone operation. The "pwm" parameter
// determines whether to initialize for a half-bridge or a full-bridge
// PWM back end.
// Notes:
//
// Parameters:
void)
// Returns: unsigned char
// SUCCESS = 0, FAIL otherwise
//-----------------------------------------------------------------------------
{
Uint8 retval;
unsigned char data;
lhlong offset_word, cpsr_word;
DEBUG_OUT("PWM_Init start\n");
// We use a half bridge design
data = CS44800_FB_PDN_MODE | CS44800_PDN;
data |= CS44800_OSC;
retval = API_SendI2C(CS44800_ADDRESS, // Set up Clock config register
CS44800_CLK_CONFIG,
data);
CHECK_RETURN(retval);
retval |= API_SendI2C(CS44800_ADDRESS, // Set Interrupt pin for active
CS44800_INT_CNTL, // low open drain
0x80);
CHECK_RETURN(retval);
retval |= API_SendI2C(CS44800_ADDRESS, // Set GPIO data to 0x00
CS44800_GPIO_STAT,
0x00);
CHECK_RETURN(retval);
retval |= API_SendI2C(CS44800_ADDRESS, // Set GPIO type to CMOS
CS44800_GPIO_PT,
0x00);
CHECK_RETURN(retval);
// Set up the GPIO direction
// appropriately for the half bridge
// type of PWM back end
data = 0x7f;
retval |= API_SendI2C(CS44800_ADDRESS, // Set GPIO direction
CS44800_GPIO_IO,
data);
CHECK_RETURN(retval);
retval |= API_SendI2C(CS44800_ADDRESS, // Set GPIO0 Level/Edge
CS44800_GPIO_LE, // sensitivity to edge.
0x01);
CHECK_RETURN(retval);
retval |= API_SendI2C(CS44800_ADDRESS, // Set GPIO0 to trigger
CS44800_GPIO_INT_MASK, // the CS44800 ~INT pin
0x01);
CHECK_RETURN(retval);
retval |= API_SendI2C(CS44800_ADDRESS, // Power down all channels
CS44800_PWM_PDN,
0xff);
CHECK_RETURN(retval);
// Set up the GPIO direction
// appropriately for the half bridge
// type of PWM back end
data = 0x1f;
retval |= API_SendI2C(CS44800_ADDRESS, // Set PWM output configuration
CS44800_PWM_CONFIG,
data);
CHECK_RETURN(retval);
// Full bridge, no ramp
data = RAMP_OFF;
retval |= API_SendI2C(CS44800_ADDRESS, // Set up the Ramp config register
CS44800_RAMP_CONFIG,
data);
CHECK_RETURN(retval);
retval |= API_SendI2C(CS44800_ADDRESS, // Set the minimum PWM pulse width
CS44800_PWM_MIN_PULSE, // to 0
0x00);
CHECK_RETURN(retval);
retval |= API_SendI2C(CS44800_ADDRESS, // Set up the Volume config register
CS44800_VOL_CONFIG,
0x47);
CHECK_RETURN(retval);
retval |= API_SendI2C(CS44800_ADDRESS, // Set Master volume to +10 dB (DSP attenuates)
CS44800_MINT_VOL,
0x0A);
CHECK_RETURN(retval);
retval |= API_SendI2C(CS44800_ADDRESS, // Disable peak limiter
CS44800_PEAK_LIM,
0x00);
CHECK_RETURN(retval);
retval |= API_SendI2C(CS44800_ADDRESS, // Set PWMOUT delay register
CS44800_PWM_DELAY,
0x10);
CHECK_RETURN(retval);
retval |= CS44800_SetPDNState(PWM_RUN); // Bring the CS44800 out of
// power down
CHECK_RETURN(retval);
// Delay to give the SRC time to lock
Delay_ms(500);
// **** Start of PSR calibration routine ***
cpsr_word.word = PSR_INIT_DEC_SCALE; // Set the PSR scale factor to 2.0
retval |= Write3Bytes( CS44800_DEC_SCALE_2,
cpsr_word.byte8.mh,
cpsr_word.byte8.ml,
cpsr_word.byte8.lo);
CHECK_RETURN(retval);
retval |= API_SendI2C(CS44800_ADDRESS, // Release the PSR Reset
CS44800_PSR_CONFIG,
0x40);
CHECK_RETURN(retval);
retval |= API_SendI2C(CS44800_ADDRESS, // Toggle the PSR_EN line
CS44800_PSR_CONFIG,
0xc0);
CHECK_RETURN(retval);
retval |= API_SendI2C(CS44800_ADDRESS,
CS44800_PSR_CONFIG,
0x40);
CHECK_RETURN(retval);
for(;;) // Repeatedly read the PSR offset
{ // and adjust the scale factor
offset_word.byte8.hi = 0; // until the output is within
// acceptable limits
retval |= Read3Bytes( CS44800_DEC_OUT_2,
&offset_word.byte8.mh,
&offset_word.byte8.ml,
&offset_word.byte8.lo);
CHECK_RETURN(retval);
if(offset_word.word > PSR_OFFSET_LIMIT_LO
&& offset_word.word < PSR_OFFSET_LIMIT_HI )
{
break;
}
if(offset_word.word > PSR_OFFSET_LIMIT_HI)
{
cpsr_word.word -= PSR_DEC_DELTA;
}
else
{
cpsr_word.word += PSR_DEC_DELTA;
}
retval |= Write3Bytes( CS44800_DEC_SCALE_2,
cpsr_word.byte8.mh,
cpsr_word.byte8.ml,
cpsr_word.byte8.lo);
CHECK_RETURN(retval);
}
// **** End of PSR calibration routine ***
//bsp_SetMuteLEDState(OFF); // Turn off Mute LED once PSR
// Calibration is successful
retval |= API_SendI2C(CS44800_ADDRESS, // Set up the Power down register
CS44800_PWM_PDN, // to turn on all channels
0x00);
retval |= API_SendI2C( CS44800_ADDRESS, // Turn on PSR
CS44800_PSR_CONFIG,
0x60);
retval |= API_SendI2C( CS44800_ADDRESS, // Be sure all channels are unmuted
CS44800_CHAN_MUTE,
0x00);
DEBUG_OUT("PWM_Init success\n");
return SUCCESS;
} // CS44800_Init
//-----------------------------------------------------------------------------
// Function:
int CS44800_SetPDNState(
// Description:
// Sets the power down state of the CS44800
// Notes:
//
// Parameters:
enum pwm_runstate state) // 0 - power down, 1 - run
// Returns: unsigned char
// SUCCESS = 0, FAIL otherwise
//-----------------------------------------------------------------------------
{
unsigned char retval;
unsigned char data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -