⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sta013.c

📁 一款MP3 Player Firmware 的原代码,非常有参考价值
💻 C
字号:
#include "printf.h"#include "as31glue.h"#include "main.h"#include "display.h"#include "params.h"#include "sta013.h"#define MAX_ATTN 64#define STA013_TREBLE 0x7B#define STA013_BASS 0x7C#define STA013_TONE_ATTEN 0x7D#define STA013_TREBLE_FREQUENCY_LOW     0x77#define STA013_TREBLE_FREQUENCY_HIGH    0x78#define STA013_BASS_FREQUENCY_LOW       0x79#define STA013_BASS_FREQUENCY_HIGH      0x7A#define STA013_MUTE 0x14static xdata unsigned int silent_mp3_clip;xdata unsigned char tone_attn;/* nb. the strings describing these frequencies are contained in params.c */code unsigned int bass_freq_table[NUM_BASS_FREQ]={40, 50, 63, 80, 100, 125, 160, 200,250, 320, 400, 500, 640};code unsigned int treble_freq_table[NUM_TREBLE_FREQ]={1000, 1250, 1600, 2000, 2500, 3150, 4000, 5000,6300, 8000, 10000, 12500, 16000};static void set_sta013_tone_levels(void){	xdata char tone_temp;   	/* sanity checks */	if ((param_value[PARAM_TREBLE] > STA013_PARAM_CENTRE + STA013_MAX_TONE) ||	    (param_value[PARAM_TREBLE] < STA013_PARAM_CENTRE - STA013_MAX_TONE)) {		print("Bad TREBLE Level Setting\r\n");		param_value[PARAM_TREBLE] = STA013_PARAM_CENTRE;		param_write(PARAM_TREBLE);	}	if ((param_value[PARAM_BASS] > STA013_PARAM_CENTRE + STA013_MAX_TONE) ||	    (param_value[PARAM_BASS] < STA013_PARAM_CENTRE - STA013_MAX_TONE)) {		print("Bad BASS Level Setting\r\n");		param_value[PARAM_BASS] = STA013_PARAM_CENTRE;		param_write(PARAM_BASS);	}	/* does this simple calculation produce enough "headroom" */	/* for the TONE_ATTEN register with all combinations of */	/* treble and bass roll-off frequencies ??? */	tone_attn = STA013_PARAM_CENTRE;	if (param_value[PARAM_TREBLE] > (char)tone_attn)                tone_attn = param_value[PARAM_TREBLE];	if (param_value[PARAM_BASS] > (char)tone_attn)                tone_attn = param_value[PARAM_BASS];	tone_temp = tone_attn - STA013_PARAM_CENTRE;        sta013_write(STA013_TONE_ATTEN, &tone_temp);	tone_temp = param_value[PARAM_TREBLE] - STA013_PARAM_CENTRE;        sta013_write(STA013_TREBLE, &tone_temp);	tone_temp = param_value[PARAM_BASS] - STA013_PARAM_CENTRE;	sta013_write(STA013_BASS, &tone_temp);}void set_sta013_treble_frequency(void){	xdata unsigned char tmp_value;	xdata unsigned char current_index;	current_index = param_value[PARAM_TREBLE_FREQ_INDEX];	/* sanity check */	if (current_index >= NUM_TREBLE_FREQ) {		print("Bad TREBLE Freq Setting\r\n");		current_index = param_default_value(PARAM_TREBLE_FREQ_INDEX);		param_value[PARAM_TREBLE_FREQ_INDEX] = current_index;		param_write(PARAM_TREBLE_FREQ_INDEX);	}	tmp_value = treble_freq_table[current_index] >> 8;        sta013_write(STA013_TREBLE_FREQUENCY_HIGH, &tmp_value);	tmp_value = treble_freq_table[current_index] & 255;        sta013_write(STA013_TREBLE_FREQUENCY_LOW, &tmp_value);}void set_sta013_bass_frequency(void){	xdata unsigned char tmp_value;	xdata unsigned char current_index;	current_index = param_value[PARAM_BASS_FREQ_INDEX];	/* sanity check */	if (current_index >= NUM_BASS_FREQ) {		print("Bad BASS Freq Setting\r\n");		current_index = param_default_value(PARAM_BASS_FREQ_INDEX);		param_value[PARAM_BASS_FREQ_INDEX] = current_index;		param_write(PARAM_BASS_FREQ_INDEX);	}	tmp_value = bass_freq_table[current_index] >> 8;        sta013_write(STA013_BASS_FREQUENCY_HIGH, &tmp_value);	tmp_value = bass_freq_table[current_index] & 255;        sta013_write(STA013_BASS_FREQUENCY_LOW, &tmp_value);}// volume or balance changed - update sta013static void action_attn_change(){    xdata unsigned char left_attn = param_value[PARAM_ATTN];    xdata unsigned char right_attn = param_value[PARAM_ATTN];    xdata unsigned char balance = param_value[PARAM_BALANCE];    if (balance > STA013_PARAM_CENTRE)    {	right_attn += ((STA013_PARAM_CENTRE - balance) << 1);	left_attn -= ((STA013_PARAM_CENTRE - balance) << 1);    }    else    {	right_attn -= ((balance - STA013_PARAM_CENTRE) << 1);	left_attn += ((balance - STA013_PARAM_CENTRE) << 1);    }    // Check for wraparound (balance is best effort)    if (left_attn > 0x40) left_attn = 0;    if (right_attn > 0x40) right_attn = 0;    sta013_set_attenuation(left_attn, right_attn);}// Volume up by 2 dB means attenuation down 2dBvoid action_vol_up(void){   if (param_value[PARAM_ATTN] > 2)   {      param_value[PARAM_ATTN] -= 2;   }   else   {      param_value[PARAM_ATTN] = 0;   }   action_attn_change();   lcd_change(PARAM_ATTN);      update_sta013_needed = 1;   param_restart_write_timer(12);}// Volume down by 2 dB means attenuation up 2dBvoid action_vol_down(void){   if (param_value[PARAM_ATTN] < MAX_ATTN - 2)   {      param_value[PARAM_ATTN] += 2;   }   else   {      param_value[PARAM_ATTN] = MAX_ATTN;   }      action_attn_change();   lcd_change(PARAM_ATTN);       update_sta013_needed = 1;   param_restart_write_timer(12);}// tone parameter changed - update sta013 and start timer for// flash writestatic void sta013_tone_change(){	set_sta013_tone_levels();        update_sta013_needed = 1;	param_restart_write_timer(100);}// tone (PARAM_TREBLE or PARAM_BASS) up by 1dBvoid sta013_tone_up(param_t tone_type){   if (param_value[tone_type] < STA013_PARAM_CENTRE + STA013_MAX_TONE)   {      param_value[tone_type]++;   }   else   {      param_value[tone_type] = STA013_PARAM_CENTRE + STA013_MAX_TONE;   }   if (tone_type == PARAM_BALANCE)   {       action_attn_change();   }   else   {       sta013_tone_change();   }   lcd_change(tone_type);}// tone (PARAM_TREBLE or PARAM_BASS) down by 1dBvoid sta013_tone_down(param_t tone_type){   if (param_value[tone_type] > STA013_PARAM_CENTRE - STA013_MAX_TONE)   {      param_value[tone_type]--;   }   else   {      param_value[tone_type] = STA013_PARAM_CENTRE - STA013_MAX_TONE;   }   if (tone_type == PARAM_BALANCE)   {       action_attn_change();   }   else   {       sta013_tone_change();   }   lcd_change(tone_type);}code int mpeg1_bitrates[16]={-1, 32, 40, 48, 56, 64, 80, 96, 112,	128, 160, 192, 224, 256, 320, -1};code int mpeg2_bitrates[16]={-1, 8, 16, 24, 32, 40, 48, 56, 64,	80, 96, 112, 128, 144, 160, -1};code unsigned char mpeg1_freq[4]={44, 48, 32, 0};code unsigned char mpeg2_freq[4]={22, 24, 16, 0};code unsigned char mpeg25_freq[4]={11, 12, 8, 0};// These are used to get the number of milliseconds per MP3 frame played.// We'll use this for time display on screen// BEWARE:  The copies of these numbers in the STA013's docs are inaccurate// for the 44.1 value.  Check http://www.mpeg.org/ for info on how to calculate// the proper values (which are included below)/// -ZSB 12-Aug-2001 2:50 PMcode unsigned char mpeg1_ms_per_frame[4]={26,24,36,0};code unsigned char mpeg2_ms_per_frame[4]={26,24,36,0};code unsigned char mpeg25_ms_per_frame[4]={48,48,72,0};struct playback_struct playback;static xdata union {        struct {                unsigned char l;                unsigned char m;                unsigned char h;                unsigned char sync;        } byte;        unsigned long ul;} header;unsigned charupdate_playback_parms(void) {	if (playback.mode_known == 0) {		header.ul = sta013_read_header();		// TODO: there's a bug in sta013_read_header (or perhaps the		//  I2C communication code) where every other attempt to read		//  the header fails.  Uncomment this line to be able to see it.		// printf("hdr = %lx\r\n", header.ul);		// I *think* I fixed this -- bug in I2C Code.  -ZSB 		if (header.byte.sync != 2) return 0;		if (header.byte.h & 0x08) {     /* mpeg1 stream */			playback.bitrate = mpeg1_bitrates[header.byte.m >> 4];			playback.freq = mpeg1_freq[(header.byte.m >> 2) & 3];			playback.ms_per_frame = mpeg1_ms_per_frame[(header.byte.m >> 2) & 3];		} else {                /* mpeg2 stream */			playback.bitrate = mpeg2_bitrates[header.byte.m >> 4];			if (header.byte.h & 0x10) {     /* mpeg2.0 */				playback.freq = mpeg2_freq[(header.byte.m >> 2) & 3];				playback.ms_per_frame = mpeg2_ms_per_frame[(header.byte.m >> 2) & 3];			} else {                /* mpeg2.5 */				playback.freq = mpeg25_freq[(header.byte.m >> 2) & 3];				playback.ms_per_frame = mpeg25_ms_per_frame[(header.byte.m >> 2) & 3];			}		}				if ((header.byte.l & 0xC0) == 0xC0) {			playback.mode = "  Mono";		} else {			playback.mode = "Stereo";		}				playback.mode_known = 1;		return 1;	}		return 0;}unsigned long GetFrameCount() {// Returns the current frame count from the STA013 as an unsigned long	xdata unsigned char tmp;	xdata unsigned long retval = 0;		//print("GetFrameCount: ");		if(!sta013_read(STA013_FRAME_CNT_H, &tmp)) {		retval += (tmp * 65536);	} else {		//print("err_h ");	}	if(!sta013_read(STA013_FRAME_CNT_M, &tmp)) {		retval += (tmp * 256);	} else {		//print("err_m ");	}	if(!sta013_read(STA013_FRAME_CNT_L, &tmp)) {		retval += tmp;	} else {		//print("err_l ");	}	//printf("%ld\r\n", retval);	return retval;}/* this should be called right before calling play_abort() *//* or doing anything else that could disrupt the data flow *//* to the sta013, so that the user won't hear a blip by *//* the discontinuity in mpeg data framing.  Once the output *//* is muted, the silent clip should be played, so that when *//* new data is sent into the chip, it will have received *//* several good frames of data and be waiting for the start *//* of a new frame (instead of the rest of an incomplete one) */void mute_sta013_output(void){	xdata unsigned char value=1;	sta013_write(STA013_MUTE, &value);	mute_is_on = 1;}void restore_sta013_settings(void){        action_attn_change();	set_sta013_tone_levels();	set_sta013_treble_frequency();	set_sta013_bass_frequency();}void backup_sta013_settings(void){   // write sta013 parameters to flash    // nb. frequency indices are eparams and are handled by the   // parameter editor   param_write(PARAM_ATTN);   param_write(PARAM_TREBLE);   param_write(PARAM_BASS);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -