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

📄 yampp7_usb.c

📁 yampp mp3 source code
💻 C
📖 第 1 页 / 共 5 页
字号:
	u08 i = 0;
	lcd_gotoxy(0,5);
	
	if (bRandom)
	{
		i=127;
		lcd_invert();
	}
	lcd_wrdata(i);
	puts("\x1\x2");				// Random signs
	lcd_normal();
	lcd_wrdata(i);
	lcd_wrdata(0);

	lcd_putchar(Repeat + 0x10);		// Repeat sign L
	lcd_putchar(Repeat + 0x14);		// Repeat sign R	
	lcd_wrdata(0);

	if (vs1001_fw)
	{
		lcd_wrdata(0);
		lcd_putchar('L');
		lcd_putchar((bLoudness > 9) ? bLoudness + ('A'-10) : bLoudness + '0');
	}
	else
	{
		i=0;
		if (bLoudness)
		{
			i=127;
			lcd_invert();
		}
		puts("\x3\x4");			// MegaBass signs
		lcd_normal();
		lcd_wrdata(i);
	}

	lcd_wrdata(0);

	if ((keylock & 1) == 1)
	{
		puts("\x5\x6");			// locked sign

#if (BACKLIGHT_TIME != 0)
		backlight_off();		// Backlight off in locked state
#endif
	}
	else
	{
		if (autolock)
			puts("\xE\xF");		// autolock signs
		else
			puts("  ");
	}

	lcd_wrdata(0);

	if (lobatt > 1)
		puts("\x8\x9");			// low battery signs
	else
		puts("\xB\xC");			// good battery signs

	if(info_flag == 1)
	{
		i = balance;
		if(balance <= 0)
		{
			lcd_putchar(0x1A);
			i = 0-balance;
		}
		else
			lcd_putchar(' ');

		printf("%u",i/6);
		lcd_putchar( (balance >= 0) ? 0x19 : ' ');
	}
	else 
	{
		if (volume < MIN_VOLUME)
		{
			for (i=0; i<16; i++)
			{
				if(MIN_VOLUME - volume >= i * VOL_STEP * NUM_VOL_STEPS / 16)
					lcd_wrdata(0xff << (8 - (i+1)/2));
				else
					lcd_wrdata(0);
			}
		}
		else
		{
			vs1001_setvolume(254,0);
			lcd_wrdata(0);
			lcd_putchar(0x07);		// speaker
			lcd_wrdata(0);
			lcd_wrdata(0);
			lcd_putchar('x');		// off :)
		}
	}
}
//--------------------------------------------------------------------------

u08 lcd_card_logo(void)
{
	u16 i;
	if (CARD_SW_Reset2())
	{
		CARD_Read(YADL_SEC_SCRATCH);				// read scrath sector
		if (SectorBuffer[0] == 'y' && SectorBuffer[1] == 'W')	// check for Logo Tag
		{							// if present:
			lcd_gotoxy(0,0);				// begin at x=0, y=0
			for (i = 2; i < 4*84+2; i++)			// 4x84 bytes of logo bytes
				lcd_wrdata(SectorBuffer[i]);		// write to LCD
			return 0;					// return status: logo found
		}
	}
	return (lcd_logo(0));						// check for EEPROM logo
}

//--------------------------------------------------------------------------

void eeprom_update(void)
{
	union u16convert Data;
	// save current settings to EEPROM
	Data.value = curPlaylist;
	eeprom_wb(EEPROM_PLAYLIST, Data.bytes.low);
	eeprom_wb(EEPROM_PLAYLIST + 1, Data.bytes.high);
	Data.value = curIndex;					// save song number within current playlist
	eeprom_wb(EEPROM_SONGPOS, Data.bytes.low);
	eeprom_wb(EEPROM_SONGPOS + 1, Data.bytes.high);
	eeprom_wb(EEPROM_VOLUME,volume);
	eeprom_wb(EEPROM_BALANCE,balance);
	eeprom_wb(EEPROM_REPEAT,Repeat);
	eeprom_wb(EEPROM_RANDOM,bRandom);
	eeprom_wb(EEPROM_TIME,timemode);
	eeprom_wb(EEPROM_LOUDNESS, bLoudness);
	eeprom_wb(EEPROM_AUTOLOCK,autolock);
#if (BACKLIGHT_TIME != 0)
	eeprom_wb(EEPROM_BACKLIGHT,light_mode);		// save backlight mode
#endif
}

//--------------------------------------------------------------------------

void PowerOff(void)
{
	beep(SINE_500,150);
#if (BACKLIGHT_TIME != 0)
	backlight_on();
#endif
	lcd_clrscr();
	if(lcd_card_logo())
		lcd_gotoxy(2,2);
	else
		lcd_gotoxy(2,4);
	puts("Goodbye !!");
	u08 i =80;
	while(i--)
	{
		lcd_gotoxy(0,5);
		lcd_bar(i,82);
		delayms(15);
	}
	eeprom_update();
	sbi(ACSR,ACD);				// Disable Analog Comparator
	sbi(GIMSK,INT2);			// enable external interrupt 2 on falling edge
	wdt_disable();				// disable the watchdog
	sei();					// global interrupt enable
	cbi(PORTB, RESET_PIN);			// keep VS1001 reset
	lcd_clrscr();
	lcd_off();
	cbi(CHARGE_PORT,CHARGE_PIN);		// disable pullup on charge input
	cbi(CHARGE_PORT-1,CHARGE_PIN);		// and switch to input for no current draw in sleep mode
	outp(0, TCCR0);
	cbi(PORTB, LED_PIN);			// Backlight off

#ifdef MMC_CARD
	MMC_Off();
//	sbi(MMC_PORT,MMC_CS);			// MMC CS HIGH
//	sbi(MMC_PORT-1,MMC_CS);
#endif
	outp(0x00,PORTA);
	outp(0xff,DDRA);			// PORTA Output and LOW
	outp(0x80,PORTC);			// Deselect CF Card
	cbi(PORTB, PB2);			// FTDI reset
#ifndef FIXED_RESET
	outp(0x32,PORTD);			// WR and RD low to avoid powering FTDI chip via WR and RD signals
#else
	outp(0xB2,PORTD);			// RD high and and WR low to avoid powering FTDI chip via WR and RD signals,
#endif						// but need to modyfi the board. High RD is for solving problems
						// with accidentaly CF card "True IDE Mode" entering after card insert.

	outp(0xC0,DDRD);			// WR and RD as output
sldo:	outp(0x30,MCUCR);			// enable deep sleep mode and disable EXT RAM
	outp(0, TCCR1B);			// stop timer1
	asm volatile("sleep");			// Enter to Sleep mode
	asm volatile("nop");

// *********************************** 

	// wakeup going here
	outp(0x20,MCUCR);			// enable idle mode
	outp(4, TCCR1B);			// start timer1
	sleepcount = 0;
	while(sleepcount < 10)
	{
		asm volatile("sleep");		// Enter to idle mode
		asm volatile("nop");
		if bit_is_set(PINE,BUTTON_1)	// Play key pressed ?
			goto sldo;		// No, go to deep sleep again
	}
	outp(0xFF,PORTD);			// WR and RD high to avoid CF garbage
	wdt_enable(1);
	while (1);				// reset player by watchdog
}

/******************************************************************************
*				KEYBOARD CONTROL FUNCTION					*
******************************************************************************/

//
// button handling
//

//------------------------------------------------------------------------------------------
// Keyboard layout (while playing)
//
//		 			BUTTON_1	BUTTON_2	BUTTON_3	BUTTON_4	
u08 TableKbdShort[] = { EV_IDLE,	EV_PLAY,	EV_STOP, 	EV_NEXT,  	EV_PREV };
u08 TableKbdLong[]  = { EV_IDLE, 	EV_FFWD,	EV_MENU, 	EV_UP, 		EV_DOWN };

// Keyboard layout (On Stop)
//	 				BUTTON_1	BUTTON_2	BUTTON_3	BUTTON_4	
//			ShortPress:	PLAY		STOP	 	MBASS	  	RANDOM
//			LongPress: 	PWR.OFF 	MENU		AU.LOCK,	LCD Contrast


void check_keylock(void)
{
	if (autolock)
	{
		// if automatic lock timer enabled and timeout -> Led blink
		if (keylock_time > AUTOLOCK_TIME && keylock_time < AUTOLOCK_TIME+20)
			goto KBLINK;
	}

	if (bit_is_clear(PIND,BUTTON_3) && bit_is_clear(PIND,BUTTON_4))
	{						// if both top buttons down
		wdt_disable();				// disable watchdog for prevent from bootloader entering
		keylock |= 2;				// mark as pressed
#if (BACKLIGHT_TIME != 0)
		backlight_on();
#endif
		if (nKeyTime == 10)			// if pressed by 1 second
		{
			nKeyTime++;
			keylock ^= 1;			// flip keylock status (bit 0)
		}
		if (nKeyTime > 10)			// signalise by Led blink
		{
			nKeyTime = 11;

 KBLINK:

#if (BACKLIGHT_TIME == 0)
			if ((time_flag & 3) == 2)
			{
				time_flag++;
				if (bit_is_set(PORTB,LED_PIN))		// LED Flashing
					cbi(PORTB,LED_PIN);
				else
					sbi(PORTB,LED_PIN);
			}
#endif
			return;
		}
	}
	else
	{
		// both top buttons released and change occur
		if (keylock > 1 && bit_is_set(PIND,BUTTON_3) && bit_is_set(PIND,BUTTON_4))
		{
#if (BACKLIGHT_TIME == 0)
			sbi(PORTB,LED_PIN);		// Led ON
#endif
			nKeyTime = 0;			// clear key timer
			keylock_time = 0;		// clear automatic lock timer
			keylock &= 1;			// clear marker
			wdt_enable(6);			// enable watchdog
		}

		if (keylock)
			nKeyTime = 0;
	}
}

void get_key(void)
{
	static u08 keydown = 0;
	u08 keyflag;
	event_e event = EV_IDLE;

	if (keydown)					// if a key was pressed earlier
	{
		// see if it has been released
		
		if (bit_is_set(PINE,BUTTON_1) &&			// if key up
		    bit_is_set(PIND,BUTTON_2) &&			// if key up
		    bit_is_set(PIND,BUTTON_3) &&			// if key up
		    bit_is_set(PIND,BUTTON_4) )			// if key up
		{
			// no key is down, return last key seen
			if (nKeyTime < 8 && nKeyTime > 0)		// max 0.8 sec for shortpress
				event = TableKbdShort[keydown];	// short keypress event
			keydown = 0;
		}
		else
			if ((nKeyTime & 0x7F) >= 8)			// long keypress ? 
			{
#if (BACKLIGHT_TIME != 0)
				light_time = 0;
#endif
				event = TableKbdLong[keydown];		// long keypress event
				if (event == EV_UP || event == EV_DOWN || event == EV_FFWD)
					nKeyTime = 0x86;		// 0.2 sec repeat time for volume
				else
					nKeyTime = 0x80;		// as long repeat as possible
			}	
	}
	else
	{	
		keyflag = 0;
		if (bit_is_clear(PINE,BUTTON_1))			// if key 1 down
			keyflag = 1;					// store it
		if (bit_is_clear(PIND,BUTTON_2))			// if key 2 down
			keyflag = 2;					// store it
		if (bit_is_clear(PIND,BUTTON_3))			// if key 3 down
			keyflag = 3;					// store it
		if (bit_is_clear(PIND,BUTTON_4))			// if key 4 down
			keyflag = 4;					// store it

		if (keyflag && nKeyTime > 0)
		{
			keydown = keyflag;				// store it
			keylock_time = 0;

#if (BACKLIGHT_TIME != 0)
			backlight_on();
#endif
		}

		if (keyflag == 0)
			nKeyTime = 0;					// clear keypress timer
	}	

	if (event != EV_IDLE)
		set_event(event);
}

/******************************************************************
*			RANDOM STUFF				  *
******************************************************************/

// Random stuff, maximum 512 songs

static u32 seed = 1;
u08 RANDOM_TAB[64];				// "True Random" table, maximum 512 songs

// Init randomize table
void InitRnd(void)
{
u08 Temp;
	if (bRandom)
	{
		for (Temp = 0; Temp < 64; Temp++)
			RANDOM_TAB[Temp] = 0;		// one bit in table represent one song
	}
}


u16 randcalc(u16 max)				// returned random value from 0 to max - 1
{
//  return ((seed = seed * 1103515245L + 12345) % max);	// get new song number

	asm volatile ("push r24");
	asm volatile ("push r25");
	asm volatile ("lds r22,seed");
	asm volatile ("lds r23,(seed)+1");
	asm volatile ("lds r24,(seed)+2");
	asm volatile ("lds r25,(seed)+3");
	asm volatile ("ldi r18,lo8(1103515245)");
	asm volatile ("ldi r19,hi8(1103515245)");
	asm volatile ("ldi r20,hlo8(1103515245)");
	asm volatile ("ldi r21,hhi8(1103515245)");
	asm volatile ("call __mulsi3");
	asm volatile ("subi r22,lo8(-(12345))");
	asm volatile ("sbci r23,hi8(-(12345))");
	asm volatile ("sbci r24,hlo8(-(12345))");
	asm volatile ("sbci r25,hhi8(-(12345))");
	asm volatile ("sts seed,r22");
	asm volatile ("sts (seed)+1,r23");
	asm volatile ("sts (seed)+2,r24");
	asm volatile ("sts (seed)+3,r25");
	asm volatile ("pop r19");
	asm volatile ("pop r18");
	asm volatile ("clr r20");
	asm volatile ("clr r21");
	asm volatile ("call __udivmodsi4");
	asm volatile ("mov r25,r23");
	asm volatile ("mov r24,r22");
	return max;
}


u08 tabval(u16 num, u08 fn)				// check random tabele for song status
{								// and mark as played if necessary
	u08 index = (u08)(num >> 3);
	u08 offset = 1 << (num % 8);
	if(fn)
		RANDOM_TAB[index] |= offset;		// if fn=1 mark as played
	return (RANDOM_TAB[index] & offset);	// return status
}

// new random procedure
u16 do_rand(u16 max)					// returned random value from 0 to max - 1
{
u16 num;
	max &= 0x01ff;					// limit to 512 songs for lower RAM usage
	for(num = 0; num < max; num++)		// check for all songs in playlist
		if(tabval(num,0) == 0)			// not be played yet
			break;
	if (num == max)
		num = -1;					// no more songs in current playlist
	else
	{
		do
		{
			wdt_reset();
			num = randcalc(max);
		} while (tabval(num,0) != 0);		// check this song not be played piervously
		tabval(num,1);				// mark as just played
	}
	return num;
}


/************************************************************************
*				FORMAT NEW DISK				*
*************************************************************************/

u08 format_new_disk(void)
{
	YADL_ROOT_SECTOR *pBoot;					// Boot Sector struct
	u32 sectors;

#ifndef MMC_CARD

	IDENTIFY_DATA *pID;	
	u08 i,c;
	u08 tmpSectorBuffer[sizeof(pID->ModelNumber)];

	// first get some drive data
	CARD_Identify();
	
	// flip and save the ModelNumber data
	pID = (IDENTIFY_DATA *) SectorBuffer;
	strncpy(tmpSectorBuffer,(u08*)pID->ModelNumber,sizeof(pID->ModelNumber));
	for (i=0;i<sizeof(pID->ModelNumber);i+=2)
	{
		c = tmpSectorBuffer[i];
		tmpSectorBuffer[i] = tmpSectorBuffer[i+1];
		tmpSectorBuffer[i+1] = c;
	}
	tmpSectorBuffer[sizeof(pID->ModelNumber)] = 0;			// terminate entry
	
	// get max sectors (disk size)
	sectors = pID->UserAddressableSectors;

#else

	u08 tmpSectorBuffer[8];
	MMC_Name();
	strncpy(tmpSectorBuffer, SectorBuffer, 7);
	tmpSectorBuffer[7] = 0;					// terminate entry
	sectors = MMC_Capacity();

#endif

	// clear buffer
	pBoot = (YADL_ROOT_SECTOR *) SectorBuffer;		// use temp buffer for room
	strcpy_P(pBoot->model,firmware_scan_tag);		// for compiler warning supression...
								// I don't know why, but it decrease code size too
	memset(pBoot,0,512);				

// section 1
	strncpy(pBoot->id,"YADL",4);
	pBoot->disk_size = sectors;
	pBoot->unmount_state = YADL_STATE_NEW;
	pBoot->media_type = YADL_MEDIA_FLASH;

	pBoot->disk_version_major = DISK_LAYOUT_VERSION_MAJOR;
	pBoot->disk_version_minor = DISK_LAYOUT_VERSION_MINOR;

	strcpy_P(pBoot->model,model_txt);	// yampp model name

	// copy the ModelNumber result from Identify Drive
	strcpy(pBoot->disk_info,tmpSectorBuffer);	

// section 2
	
	strcpy_P(pBoot->build_timestamp,date_txt);
	pBoot->build_timestamp[YADL_LEN_BUILD_TIMESTAMP-1] = 0;	// make sure it's terminated

	pBoot->firmware_version_major = YAMPP_FIRMWARE_VERSION_MAJOR;

⌨️ 快捷键说明

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