📄 sta013.c
字号:
i2cReceive(STA_I2C_DEV, reg, 1, &data);
return data;
}
void sta013WriteReg(u08 reg, u08 data)
{
i2cSend(STA_I2C_DEV, reg, 1, &data);
}
void sta013DownloadUpdate(void)
{
u16 i;
u08 reg, data;
i=0;
// get first reg/data pair
reg = PRG_RDB(STA013_UpdateData + i++);
data = PRG_RDB(STA013_UpdateData + i++);
// loop until end of update
while( (reg != 0xff) )
{
sta013WriteReg(reg, data);
reg = PRG_RDB(STA013_UpdateData + i++);
data = PRG_RDB(STA013_UpdateData + i++);
}
}
u08 sta013Init(void)
{
// reset STA013 device
sta013HWReset();
// identify STA013 device
if(sta013ReadReg(STA_REG_IDENT) != STA_IDENT)
{
return FALSE;
}
// do firmware configuration and update
sta013DownloadUpdate();
// start decoder
sta013StartDecoder();
return TRUE;
}
void sta013StartDecoder(void)
{
// Soft reset
sta013WriteReg(STA_REG_SOFT_RESET, 0x01);
sta013WriteReg(STA_REG_SOFT_RESET, 0x00);
// Mute and configure DAC output
sta013WriteReg(STA_REG_MUTE, 0x01);
sta013WriteReg(STA_REG_PCMDIVIDER, 0x01); // 32-bit mode, O_FAC = 256
sta013WriteReg(STA_REG_PCMCONF, 0x31); // 18-bit mode & more
// Configure PLL for MP3 rates
sta013WriteReg(STA_REG_PLLFRAC_441_H, 0x67);
sta013WriteReg(STA_REG_PLLFRAC_441_L, 0x77);
sta013WriteReg(STA_REG_PLLFRAC_H, 0xbb);
sta013WriteReg(STA_REG_PLLFRAC_L, 0x3a);
sta013WriteReg(STA_REG_MFSDF_441, 0x10);
sta013WriteReg(STA_REG_MFSDF, 0x0F);
// Configure interface polarities, etc
sta013WriteReg(STA_REG_PLLCTL_2, 0x0C);
sta013WriteReg(STA_REG_PLLCTL_3, 0x00);
sta013WriteReg(STA_REG_PLLCTL_1, 0xA1);
sta013WriteReg(STA_REG_SCLK_POL, 0x00); // data sampled on rising edge
sta013WriteReg(STA_REG_REQ_POL, 0x01); // REQ line active high
sta013WriteReg(STA_REG_DATA_REQ_ENABLE, 0x04);
sta013WriteReg(STA_REG_PLLCTL_1, 0xA1);
// Set audio tone controls
sta013SetTone(0, 0, 0, 0);
// Unmute and start running
sta013WriteReg(STA_REG_RUN, 0x01);
sta013WriteReg(STA_REG_PLAY, 0x01);
sta013WriteReg(STA_REG_MUTE, 0x00);
}
void sta013StopDecoder(void)
{
// mute output
sta013WriteReg(STA_REG_MUTE, 0x01);
// soft reset
sta013WriteReg(STA_REG_SOFT_RESET, 0x01);
sta013WriteReg(STA_REG_SOFT_RESET, 0x00);
}
void sta013PauseDecoder(void)
{
// enable mute
sta013WriteReg(STA_REG_MUTE, 0x01);
// stop the decoder
sta013WriteReg(STA_REG_PLAY, 0x00);
}
void sta013ResumeDecoder(void)
{
// run the decoder
sta013WriteReg(STA_REG_PLAY, 0x01);
// disable mute
sta013WriteReg(STA_REG_MUTE, 0x00);
}
void sta013GetMP3Info(u16 *bitrate, u08 *sampFreq, u08 *mode)
{
u08 headL, headM, headH;
u08 mpegID, bitrateIndex, sampFreqIndex;
// get the MP3 header info
headH = sta013ReadReg(STA_REG_HEAD_H);
headM = sta013ReadReg(STA_REG_HEAD_M);
headL = sta013ReadReg(STA_REG_HEAD_L);
// IDex:ID is in head[20:19]
// 00 - MPEG2.5
// 01 - reserved
// 10 - MPEG2
// 11 - MPEG1
mpegID = (headH & 0x18)>>3;
// sampling frequency is in head[11:10]
sampFreqIndex = ((headM & 0x0C)>>2) | (mpegID<<2);
// bitrate index is in head[15:12]
bitrateIndex = ((headM & 0xF0)>>4) | ((mpegID & 0x01)<<4);
//bitrateIndex = ((headM & 0xF0)>>4) | (1<<4);
// mode is in head[7:6]
// 00 - stereo
// 01 - joint stereo
// 10 - dual channel
// 11 - single channel (mono)
*mode = (headL & 0xC0)>>6;
*bitrate = 2 * PRG_RDB( MP3_Bitrates + bitrateIndex );
*sampFreq = PRG_RDB( MP3_SamplingFrequencies + sampFreqIndex );
/*
header = (unsigned long)sta013ReadReg(STA_REG_HEAD_H) << 16 |
(unsigned long)sta013ReadReg(STA_REG_HEAD_M) << 8 |
(unsigned long)sta013ReadReg(STA_REG_HEAD_L);
// hdr->word = l;
// hdr->emphasis = l & 0x03;
// hdr->isOriginal = (l >> 2) & 0x01;
// hdr->isCopyrighted = (l >> 3) & 0x01;
// hdr->modeExtension = (l >> 4) & 0x03;
// hdr->mode = (l >> 6) & 0x03;
// hdr->private = (l >> 8) & 0x01;
// hdr->padding = (l >> 9) & 0x01;
// hdr->frequencyIndex = (l >> 10) & 0x03;
// hdr->bitrateIndex = (l >> 12) & 0x0f;
// hdr->protection = (l >> 16) & 0x01;
// hdr->layer = (l >> 17) & 0x03;
// hdr->ID = (l >> 19) & 0x01;
// hdr->ID_ex = (l >> 20) & 0x01;
*/
}
u16 sta013GetAverageBitrate(void)
{
return (2 * sta013ReadReg(STA_REG_AVERAGE_BITRATE));
}
void sta013SetVolume(u08 volume, s08 balance)
{
char attenL, attenR;
// volume is expected as 0-100 value
// Note:
// #define MIN_VOLUME_ATTENUATION 0
// #define MAX_VOLUME_ATTENUATION 96
if( balance > 0)
{ // balance to the left, attenuate right
attenL = (100 - volume);
attenR = (100 - volume) - (balance);
}
else
{ // balance to the right, attenuate left
attenL = (100 - volume) + (balance);
attenR = (100 - volume);
}
// respect limits
attenL = MIN(attenL,MAX_VOLUME_ATTENUATION);
attenL = MAX(attenL,MIN_VOLUME_ATTENUATION);
attenR = MIN(attenR,MAX_VOLUME_ATTENUATION);
attenR = MAX(attenR,MIN_VOLUME_ATTENUATION);
// set volume
sta013WriteReg(STA_REG_DLA, attenL);
sta013WriteReg(STA_REG_DLB, MAX_VOLUME_ATTENUATION);
sta013WriteReg(STA_REG_DRA, attenR);
sta013WriteReg(STA_REG_DRB, MAX_VOLUME_ATTENUATION);
}
void sta013SetTone(s08 bassEnh, u16 bassFreq, s08 trebleEnh, u16 trebleFreq)
{
// set bass enhancement
sta013WriteReg(STA_REG_BASS_FREQUENCY_LOW, (bassFreq ) & 0xFF );
sta013WriteReg(STA_REG_BASS_FREQUENCY_HIGH, (bassFreq>>8) & 0xFF );
// respect limits
bassEnh = MIN(bassEnh,MAX_BASS_ENHANCE);
bassEnh = MAX(bassEnh,MIN_BASS_ENHANCE);
sta013WriteReg(STA_REG_BASS_ENHANCE, bassEnh);
// set treble enhancement
sta013WriteReg(STA_REG_TREBLE_FREQUENCY_LOW, (trebleFreq ) & 0xFF );
sta013WriteReg(STA_REG_TREBLE_FREQUENCY_HIGH, (trebleFreq>>8) & 0xFF );
// respect limits
trebleEnh = MIN(trebleEnh,MAX_TREBLE_ENHANCE);
trebleEnh = MAX(trebleEnh,MIN_TREBLE_ENHANCE);
sta013WriteReg(STA_REG_TREBLE_ENHANCE, trebleEnh);
// set attentuation to avoid clipping
sta013WriteReg( STA_REG_TONE_ATTEN, MAX(bassEnh,trebleEnh) );
}
u08 sta013Demand(void)
{
return bit_is_set(STA013_DEMAND_PORTIN,STA013_DEMAND_PIN);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -