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

📄 main.c

📁 一款MP3 Player Firmware 的原代码,非常有参考价值
💻 C
📖 第 1 页 / 共 2 页
字号:
			state = S_CACHING;			caching_step = 0;			r = SP;			printfd("S_READ_DIR, mp3_fd=%d %x\r\n", mp3_fd, r);			songStartFrameCount = GetFrameCount();			playback.mode_known = 0;			play_blocks(-1);			set_timer(TIMER_LCD_UPDATE, LCD_UPDATE_INTERVAL);			update_playlist_state_needed = 1;			param_restart_write_timer(25);            trackCounter++;			//parse_event_setup();			break;		  case S_CACHING:			r = SP;			printfd("S_CACHING, mp3_fd=%d %x\r\n", mp3_fd, r);			r = file_cache_work(mp3_fd);			/* TODO: check return value from file_cache_work */			if (++caching_step > 6) {				file_seek(mp3_fd, 0);                if (param_value[PARAM_STARTUP_MODE] == STARTUP_MODE_PLAYING || trackCounter != 1)                {                    state = S_PLAYING_AND_CACHING;                }                else                {                    // generate PAUSE event					put_back_event(E_PLAY_PAUSE);                }			}						break;		  case S_PLAYING_AND_CACHING:			printfd("S_PLAYING_CACHING, mp3_fd=%d\r\n", mp3_fd);			r = file_cache_work(mp3_fd);			if (r) {				state = S_PLAYING;				disk_spin_down_timer();				clear_timer(TIMER_POST_PLAYING);				set_timer(TIMER_POST_PLAYING, 20);				//out of memory				if(r == 2)				{					//print a message					printf("\\[\\B $Buffer Memory Full\\]\r\n");				}				do_id3 = 1;				// process_id3(mp3_fd, current_file_size);				free_fat_memory();			}			/* fall through into S_PLAYING's code */		  case S_PLAYING:			printfd("S_PLAYING\r\n");			if (play_blocks(mp3_fd) != 0) {				current_file = next_file(current_file, 0);				begin_simple_timeout();				state = S_FINISH_PLAYING;			}			break;		  case S_FINISH_PLAYING:			// Resettings the songStartFrameCount here should			// get us a new count at the start of each song			printfd("S_FINISH_PLAYING, q=\r\n", play_queue_avail());			if (is_play_queue_empty() && is_ide_idle()) {                                lcd_display_id3_init();				file_close(mp3_fd);				current_file_size = 0xFFFFFFFF;				free_fat_memory();				print_memory_available();				if (is_ide_sleeping()) {					ide_hard_reset();					begin_simple_timeout();					while (!ide_init()) {						if (simple_timeout(150)) {							reboot();						}					}					tweak_rand_seed();				}				state = S_READ_DIR;			} else {				if (simple_timeout(900)) {					reboot();				}			}			do_id3 = 0;			// songStartFrameCount = GetFrameCount();			break;		  case S_PAUSED:			if (prior_state == S_PLAYING_AND_CACHING || prior_state == S_CACHING) {				r = file_cache_work(mp3_fd);				if (r) {					prior_state = S_PLAYING;					disk_spin_down_timer();					do_id3 = 1;					clear_timer(TIMER_POST_PLAYING);					set_timer(TIMER_POST_PLAYING, 20);					// process_id3(mp3_fd, current_file_size);					free_fat_memory();				}			 }			break;		  default:					    print("ILLEGAL STATE:");			print_hex16(state);			print_crlf();		}#else //NEW_STATE_MACHINE		// This state machine will control playing data from memory		switch (play_state) {		  case S_START_NEW_FILE:		  case S_PLAYING_FILE:		  case S_FINISH_PLAYING_FILE:		  case S_FINISHED_FILE:		  case S_PAUSED:			break;		  default:			print("Illegal play_state\r\n");			play_state = S_START_NEW_FILE;			break;		}		// And this separate state machine will be responsible for		// disk access.  The idea is to be able to do various things		// with the disk drive independent of what the current state		// of the playback might happen to be.		switch (disk_state) {		  case S_DRIVE_INACTIVE:			if (disk_activity_needed) { // TODO && sleep not pending				ide_hard_reset();				disk_time_mark = clock_tick();				disk_state = S_WAIT_DRIVE_READY;			}			break;		  case S_WAIT_DRIVE_READY:			if (ide_init()) {				disk_latency = (clock_tick() - disk_time_mark);				disk_state = S_CACHING_PRIORITY_1;				caching_priority = 1;			} else {				// TODO, timeout, go back to and try again			}			break;		  case S_CACHING:			if (highest_priority == NULL) {				ide_sleep();				free_fat_memory();				disk_state = S_WAIT_SHUTDOWN;				break;			}			r = file_cache_work(highest_priority->file_desc);			if (r == 1) {  // finished caching this file				highest_priority->priority = 0;				highest_priority = highest_priority->next;				break;			}			if (r == 2) {  // ran out of memory				highest_priority = NULL;			}			break;		  case S_WAIT_SHUTDOWN:			// TODO, check if drive is actually in sleep mode			// and remain in this state until it really is			disk_state = S_DRIVE_INACTIVE;			break;		  default:			print("Illegal disk_state\r\n");			play_state = S_DRIVE_INACTIVE;			break;		}#endif //NEW_STATE_MACHINE	}	pm2_exit();}/* choose "current_file" for initial startup */void init_current_list_and_file(void){	playlist_state_t state;		if (first_playlist == 0) {		print("\\[\\B \"   - No files found -   \\]\r\n");		print("No files found...\r\n");		pm2_exit();	}	state.byte.list_offset_lsb = param_value[PARAM_PLST_INDEX_LO];	state.byte.list_offset_msb = param_value[PARAM_PLST_INDEX_HI];	state.byte.song_offset_lsb = param_value[PARAM_TRACK_INDEX_LO];	state.byte.song_offset_msb = param_value[PARAM_TRACK_INDEX_HI];	print("resuming playlist state = ");	print_hex32(state.whole);	print_crlf();	update_playlist_state_needed = 0;	current_file = state_to_playlist(state.whole);	//current_file = ((playlist_list_t *)Addr6(first_playlist))->playlist_start_sequential;}void save_playlist_state(void){	playlist_state_t state;	state.whole = playlist_to_state(Addr7(current_file));	ibuf[0]=state.byte.list_offset_lsb;	write_flash_param(PARAM_PLST_INDEX_LO, ibuf);	ibuf[0]=state.byte.list_offset_msb;	write_flash_param(PARAM_PLST_INDEX_HI, ibuf);	ibuf[0]=state.byte.song_offset_lsb;	write_flash_param(PARAM_TRACK_INDEX_LO, ibuf);	ibuf[0]=state.byte.song_offset_msb;	write_flash_param(PARAM_TRACK_INDEX_HI, ibuf);	update_playlist_state_needed = 0;}code unsigned int disk_times[EPARAM_DISK_SPIN_COUNT] = {   0,   0xffff,   10,   20,   50,   100,   150,   200,   300,   600,   1200,   3000,   6000,};void disk_spin_down_timer(){   static xdata unsigned int duration;   duration = disk_times[param_value[PARAM_DISK_SPIN_DOWN_DELAY]];   printf("Duration is %d\r\n", duration);   timer_spin_down_mode = 1;      switch(duration)   {      case 0:	 // Never - nothing to do	 break;      case 0xffff:	 // ASAP	 put_back_event(E_DISK_SPIN_TIMER);	 break;      default:	 set_timer(TIMER_DISK_SPIN, duration);	 break;   }}// start the spin up timer// // there are two ways we can end up here.  At the end of the spin down// timer and at the end of the play started timer.  We will only start// the spin up timer if the spin down and play started timers hav// startedvoid disk_spin_up_timer(){#if 0   xdata unsigned int file_remaining_seconds;   xdata unsigned int file_length_seconds;      // check timer is not running and bitrate is valid   if (read_timer(TIMER_DISK_SPIN) != 0 && playback.mode_known != 0)   {      // wait for spin down or playback timer to elapse      return;   }      // divide by 1024 (bytes to kbytes) & multiply by 8 (bytes to bits)   // => shift by 7 bits   file_length_seconds = (current_file_size / playback.bitrate) >> 7;   file_remaining_seconds = file_length_seconds - (GetFrameCount() * playback.ms_per_frame / 1000);   printf("file_remaining_seconds = %d\r\n", file_remaining_seconds);   timer_spin_down_mode = 0;   switch(disk_times[param_value[PARAM_DISK_SPIN_UP_AHEAD]])   {      case 0:	 // Never - nothing to do	 break;      case 0xffff:	 // ASAP	 put_back_event(E_DISK_SPIN_TIMER);	 break;      default:	 file_remaining_seconds *= 10;	 file_remaining_seconds -= disk_times[param_value[PARAM_DISK_SPIN_UP_AHEAD]];	 printf("spinning up in %d seconds\r\n", file_remaining_seconds/10);	 set_timer(TIMER_DISK_SPIN, file_remaining_seconds);	 break;   }#endif}char is_state_normal(unsigned char state){	if (state == S_PLAYING	 || state == S_PLAYING_AND_CACHING	 || state == S_FINISH_PLAYING) {		return 1;	}	return 0;}#define BLOCK_SIZE 4096/* return 0 if there is more to play, or non-zero if we have played *//* everything or nothing more can play for some reason */char play_blocks(char mp3_fd){	unsigned int block;	static unsigned long played_bytes;	static unsigned char eof_count;	if (mp3_fd == -1) {		played_bytes = 0;		eof_count = 0;		return 1;	}	if (current_file_size == 0xFFFFFFFF) {		print("WARNING: play_blocks called without known file size\r\n");		return 1;	}	while (play_queue_avail()) {		block = file_read_block(mp3_fd);		printfd("FRB, r=%x, played=%lx, size=%lx\r\n",			block, played_bytes, current_file_size);		if (block == 0) {			return 0;	// not in cache yet		}		if (block == 0xFFFF) {			if (++eof_count > 240) {				played_bytes = 0;	// end of file (physical on disk)				return 1;			} else {				return 0;		// maybe more will be read soon?			}		}		if (current_file_size - played_bytes > BLOCK_SIZE) {			play_block(block, BLOCK_SIZE);			played_bytes += BLOCK_SIZE;		} else {			play_block(block, current_file_size - played_bytes);			played_bytes = current_file_size;			return 1;		}	}	eof_count = 0;	return 0;}static unsigned long simple_timout_start_time;void begin_simple_timeout(void){	simple_timout_start_time = clock_tick();}unsigned char simple_timeout(unsigned int ticks){	if ((clock_tick() - simple_timout_start_time) > (unsigned long)ticks) {		return 1;	}	return 0;}void reboot(void){	_asm	mov	r0, #000001$:	mov	r1, #000002$:	nop				;delay, hopefully to allow any	nop				;buffered serial output	djnz	r1, 00002$	djnz	r0, 00001$	clr	ea	ljmp	0	_endasm;}

⌨️ 快捷键说明

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