void WM8960_WriteData(Uint8 channel, Uint8 Register, Uint16 Data) { Uint8 HightByte,LowByte; Uint8 I2C_Status; HightByte = Data >> 8; HightByte = HightByte & 0x01; HightByte |= (Register << 1); LowByte = Data; //bit 7 - 0 IIC_Start(channel); IIC_Delay(); if(!(IIC_WriteByte(channel,WM8960_Write_ADD))) { I2C_Status = IIC_WriteByte(channel,HightByte); I2C_Status = IIC_WriteByte(channel,LowByte); IIC_Delay(); IIC_Stop(channel); #if DebugVerbosity > 1 if(I2C_Status == 0) { UART_TxStr("Channel = "); UART_TxUint8(channel); UART_TxStr("Register = "); UART_TxUint8(Register); UART_TxStr(" Value = "); UART_TxUint8(Data>>8); UART_TxUint8(LowByte); UART_TxStr("\n\r"); }
/* SerialControl routine This routine allows changing the settings via the serial port. */ void SerialControl(void) { Uint8 Command; // See if new command available if (!RxAvail) return; // Grab it and kick of the next read Command = CmdRxBuf[0]; UART_Rx(CmdRxBuf, 1); // Process the command switch (Command) { case 't': // Test command ConfigDevices(); break; default: if (!SettingsControl(Command)) { UART_TxStr("?"); UART_TxNum(Command, 1); UART_TxStr("?\r\n"); } break; } }
/* ConfigDevices routine */ void ConfigDevices(void) { Uint16 TempInt; Uint8 TempByte; // Set up lamp brightness for (TempInt = 0; TempInt < KBSettings; TempInt++) { TempByte = Settings.LampBrightness[TempInt]; if (TempByte != 0xFF) { ExchangeBoardMsg(BCAKeypadController, BCTLampBrightness, TempByte, 0, BCTAck); BCMessageReceive(RxBuf); } } // Set up headphones if (HeadphoneBay < NoBay) { for (TempByte = 0; TempByte < HeadPhoneChMax; TempByte++) { UART_TxStr("Channel "); UART_TxNum(TempByte, 1); UART_TxStr(" setting gain "); UART_TxNum(Settings.HeadPhoneChGain[TempByte], 1); UART_TxStr(" dB\r\n"); ExchangeBoardMsg(BCAOutput + HeadphoneBay, BCTHeadphoneChGain, TempByte + 1, Settings.HeadPhoneChGain[TempByte], BCTAck); BCMessageReceive(RxBuf); UART_TxStr("Setting max volume "); UART_TxNum(Settings.HeadphoneChMax[TempByte], 1); UART_TxNewLine(); ExchangeBoardMsg(BCAOutput + HeadphoneBay, BCTHeadphoneChMax, TempByte + 1, Settings.HeadphoneChMax[TempByte], BCTAck); BCMessageReceive(RxBuf); } } }
/* SetVolume routine This routine sets the volume. If at minimum then turns off relay */ void SetVolume(Uint8 NewVolume) { //static enum TBay LastBay = NoBay; //static Uint8 LastVolume; if (BayProduct[Bay] == UnknownProduct) // Don't set the volume of unknown products return; //if ((Bay == LastBay) && (NewVolume == LastVolume)) // Suppress sending duplicate messages // return; //LastBay = Bay; //LastVolume = NewVolume; if (NewVolume) // If we are not muting the clear the premuted volume/flag PreMuteVolume = 0; if (Bay != NoBay) { UART_TxStr("SetVolume "); UART_TxNum(NewVolume, 3); UART_TxStr(" for bay "); UART_TxNum(Bay, 1); UART_TxNewLine(); ExchangeBoardMsg(BCAOutput + Bay, BCTVolume, NewVolume, 0, BCTAck); BCMessageReceive(RxBuf); // Finished with it so get ready for next msg } }
/* SetInput routine This routine sets the input for a bay. */ void SetInput(enum TInput Source, enum TBay SIBay) { enum TInput NewSource; enum TInput OldSource; OldSource = BaySource[SIBay]; UART_TxStr("SetInput "); UART_TxNum(Source, 1); UART_TxStr(" for bay "); UART_TxNum(SIBay, 1); // Override any input request to a missing source if (InputPresent[Source]) { NewSource = Source; } else { UART_TxStr(" overriding as "); if (InputPresent[MP3In]) NewSource = MP3In; else NewSource = LCDIn; UART_TxNum(NewSource, 1); } UART_TxNewLine(); // Ignore requests for same source or empty bay if ((OldSource == NewSource) || (BayProduct[SIBay] == UnknownProduct)) { return; } // Handle format changes if ((OldSource > RightTablet) || (InputFormat[OldSource] != InputFormat[NewSource])) { ExchangeBoardMsg(BCAOutput + SIBay, BCTAudioFormat, InputFormat[NewSource], 0, BCTAck); BCMessageReceive(RxBuf); // Finished with it so get ready for next msg } // Change the actual stream BaySource[SIBay] = NewSource; Input = NewSource; SetMux(NewSource, SIBay); DelayMS(100); // Give the audio board a chance to sync to new stream }
int main(void) { uint16_t adc_result; int i; char value[10]; sbi(DDRB, 4); sbi(DDRC, 5); cbi(PORTB,4); sbi(PORTC,5); UART_init(250000); InitADC(); sei(); while(1) { adc_result=ReadADC(2); // Read Analog value from channel-2 // Voltage = adc_result*5/1024 // Temperature = (V - 1035 mV)/(-5.5 (mV/oC)) itoa(adc_result,value,10); for(i=0;i<=2;i++){ UART_TxChar(value[i]);} UART_TxStr("\n\r\0"); PORTB ^= (1<<PB4); _delay_ms(100); } }
void AppTask1 (void *p_arg) { CPU_INT32U i; CPU_CHAR tx_num[16]; i = 0; tx_num[0] = 'T'; tx_num[1] = 'x'; tx_num[2] = ' '; tx_num[3] = '#'; while (1) { i++; tx_num[4] = i / 1000000000 + '0'; tx_num[5] = (i % 100000000) / 10000000 + '0'; tx_num[6] = (i % 10000000) / 1000000 + '0'; tx_num[7] = (i % 1000000) / 100000 + '0'; tx_num[8] = (i % 100000) / 10000 + '0'; tx_num[9] = (i % 10000) / 1000 + '0'; tx_num[10] = (i % 1000) / 100 + '0'; tx_num[11] = (i % 100) / 10 + '0'; tx_num[12] = i % 10 + '0'; tx_num[13] = '\r'; tx_num[14] = '\n'; tx_num[15] = '\0'; #if (uC_PROBE_OS_PLUGIN > 0) || (uC_PROBE_COM_MODULE > 0) ProbeCom_TxStr((CPU_CHAR *)&tx_num, 100); #else UART_TxStr((CPU_CHAR *)&tx_num); #endif OSTimeDlyHMSM(0, 0, 1, 0); } }
/* ShowProducts routine This routine shows the products found in each bay. */ void ShowProducts(void) { Uint8 Pos; UART_TxStr("Inputs are:"); for (Pos = 0; Pos <= RightTablet; Pos++) { UART_TxChar(' '); UART_TxNum(InputPresent[Pos], 1); } UART_TxStr("\r\nOutputs are:"); for (Pos = LeftBay; Pos <= RightBay; Pos++) { UART_TxChar(' '); UART_TxNum(BayProduct[Pos], 1); } UART_TxNewLine(); }
/* SerialControl routine This routine allows changing the settings via the serial port. */ void SerialControl(void) { Uint8 Command; // See if new command available if (!RxAvail) return; // Grab it and kick of the next read Command = CmdRxBuf[0]; UART_Rx(CmdRxBuf, 1); // Process the command switch (Command) { case 't': // Test command MP3_Volume(250); UART_TxStr("MP3Ready "); UART_TxNum(MP3Ready, 1); UART_TxStr(", MP3Paused "); UART_TxNum(MP3Paused, 1); UART_TxNewLine(); break; default: if (!SettingsControl(Command)) { UART_TxStr("?"); UART_TxNum(Command, 1); UART_TxStr("?\r\n"); } break; } }
/* MainLoop routine This routine should be called ever LoopPeriod. The PlayerStatus should be 0 if stopped or 1 is playing. */ void MainLoop(Uint8 PlayerStatus) { // Update state info FlashPhase++; if (PrevTime) PrevTime--; // See if we need to start playback of next track if (PlayerStatus == 0) { if (++Track > Tracks) Track = 1; //MP3_Track(Track); } // Process an incoming comms CheckForBoardMsg(); // Check for settings changes SerialControl(); // Poll keys Key = GetKey(); /* if (Key) ClearBit(LogoLEDPort, LogoLED); else SetBit(LogoLEDPort, LogoLED); */ // if (!Settings.PauseKeyEnabled && (Key == PlayPause)) // Handle disabled // Key = LastKey; if (LastKey != Key) { // Until we know the keyboard is good show it's output UART_TxStr("Key "); UART_TxNum(Key, 1); UART_TxNewLine(); } // Handle un-pausing /*if (Key && (Key != PlayPause)) { if (MP3Paused) // If paused then unpause MP3_Pause(false); if (PreMuteVolume) { // If muted then unmute SetVolume(PreMuteVolume); } }*/ // Process key touched switch (Key){ case LeftSelect: case RightSelect: case CenterSelect: //if (Key != LastKey) // ProcessSelectKey(Key); break; case NextTrack: case PrevTrack: //if (Key != LastKey) // ProcessTrackKey(Key); break; case VolUp: case VolDown: //ProcessVolumeKey(Key); break; case PlayPause: //if (Key != LastKey) // ProcessPlayKey(Key); break; default: break; } LastKey = Key; // Handle time out if (Key) { // See if currently not idle /* if (IdleTime == 0) { IdleTime++; Track = 1; SetDefaultBay(); } */ IdleTime = Settings.IdlePeriod; } else if (IdleTime && !--IdleTime) { Ramp = RampDown; } // Handle volume ramping switch (Ramp) { case RampDown: UART_TxStr("Ramping down\r\n"); if ((Volume >= MinVolume) && (Volume >= IdleVolume + Settings.VolumeRampStep)) Volume -= Settings.VolumeRampStep; else Volume = IdleVolume; SetVolume(Volume); if (Volume <= IdleVolume) { Ramp = NoRamp; // SetIdleState(); } break; case RampDefault: UART_TxStr("Ramping to default\r\n"); if (Volume < DefaultVolume) { if (Volume + Settings.VolumeRampStep <= DefaultVolume) Volume += Settings.VolumeRampStep; else Volume = DefaultVolume; SetVolume(Volume); } else if (Volume > DefaultVolume) { if (Volume >= DefaultVolume + Settings.VolumeRampStep) Volume -= Settings.VolumeRampStep; else Volume = DefaultVolume; SetVolume(Volume); } else { Ramp = NoRamp; } break; default: break; } RefreshLamps(); }
/* SettingsControl routine This routine allows changing the settings via the serial port. */ void SettingsControl(void) { Uint8 Command; Uint8 TempInt,channel; Uint16 TempData, WM8960Data; Uint8 WM8960Register; // See if new command available if (RxAvail < 9) return; // Grab it and kick of the next read UART_Rx(RxData, 9); Command = RxData[0]; // Process the command // s channel data switch (Command) { case 's': // case 'S': for(TempInt = 1; TempInt < 9; TempInt++) { switch(RxData[TempInt]) { case 'a': case 'A': RxData[TempInt] = 0xa; break; case 'b': case 'B': RxData[TempInt] = 0xb; break; case 'c': case 'C': RxData[TempInt] = 0xc; break; case 'd': case 'D': RxData[TempInt] = 0xd; break; case 'e': case 'E': RxData[TempInt] = 0xe; break; case 'f': case 'F': RxData[TempInt] = 0xf; break; default: if((RxData[TempInt] >= '0') && (RxData[TempInt] <= '9')) RxData[TempInt] = RxData[TempInt] - '0'; else RxData[TempInt] = 0; break; } } channel = RxData[1] << 4; channel |= RxData[2]; WM8960Register = RxData[3] << 4; WM8960Register |= RxData[4]; TempData = RxData[5]; TempData = TempData << 12; WM8960Data = TempData; TempData = RxData[6]; TempData = TempData << 8; WM8960Data |= TempData; TempData = RxData[7]; TempData = TempData << 4; WM8960Data |= TempData; WM8960Data |= RxData[8]; WM8960_WriteData(channel,WM8960Register,WM8960Data); UART_Rx(RxData, 9);//receive if(WM8960Register == 0) { Volume_Set(WM8960Data); } break; default: UART_Rx(RxData, 9); UART_TxStr("?"); UART_TxNum(Command); UART_TxStr("?\r\n"); break; } }
/* main routine Program entry point */ int main(void) { Uint8 TxBuf[BCMsgSize]; Uint8 RxBuf[BCMsgSize]; Uint8 Address; // Address of device in bay Uint8 Destination; // Address we will reply to Uint8 Param,Param2; MainInit(); UART_TxStr("\r\nPower up\r\n"); UART_Rx(RxData, 9); // Input register setting command Address = BCAOutput + ReadPosition(); BCMessageInit(Address); // Set up the UART BCMessageReceive(RxBuf); // Kick off receive // Enter the main loop for( ; ; ) { // Run forever DelayMS(LoopRate); SettingsControl(); if (BCRXAvail) { // We have a new message if ((RxBuf[BCPAddr] & 0b1111) == Address) { // Check it is for us Destination = RxBuf[BCPAddr] >> 4; // Pre-setup assuming we will reply Destination &= 0b1111; Destination |= Address << 4; TxBuf[BCPAddr] = Destination; DelayMS(2); // Allow line turn around delay switch (RxBuf[BCPType]) { case BCTInquire: // Master request of slave ID TxBuf[BCPType] = BCTInquireAnswer; TxBuf[BCPParam1] = ReadProductID(); TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf,true); // Send the reply BCMessageReceive(RxBuf); // Kick off receive of next frame break; case BCTVolume: // Volume set TxBuf[BCPType] = BCTAck; TxBuf[BCPParam1] = 0; TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf,true); // Send the reply Param = RxBuf[BCPParam1]; // Save parameter so we can receive next frame while processing this request BCMessageReceive(RxBuf); // Kick off receive of next frame // Timer_Clear(); Volume_Set(Param); // UART_TxStr("Volume_Set took "); // UART_TxNum(Timer_Read()); // UART_TxStr("mS\r\n"); break; case BCTHeadphoneChGain: // Volume set TxBuf[BCPType] = BCTAck; TxBuf[BCPParam1] = 0; TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf,true); // Send the reply Param = RxBuf[BCPParam1]; // Save parameter so we can receive next frame while processing this request Param2 = RxBuf[BCPParam2]; // Save parameter so we can receive next frame while processing this request BCMessageReceive(RxBuf); // Kick off receive of next frame // Timer_Clear(); SetChannelAdjust(Param,Param2); // UART_TxStr("Volume_Set took "); // UART_TxNum(Timer_Read()); // UART_TxStr("mS\r\n"); break; case BCTHeadphoneChMax: // Volume set TxBuf[BCPType] = BCTAck; TxBuf[BCPParam1] = 0; TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf,true); // Send the reply Param = RxBuf[BCPParam1]; // Save parameter so we can receive next frame while processing this request Param2 = RxBuf[BCPParam2]; // Save parameter so we can receive next frame while processing this request BCMessageReceive(RxBuf); // Kick off receive of next frame SetChMaxVolume(Param, Param2); break; case BCTAudioFormat: // Audio format set TxBuf[BCPType] = BCTAck; TxBuf[BCPParam1] = 0; TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf,true); // Send the reply Param = RxBuf[BCPParam1]; // Save parameter so we can receive next frame while processing this request BCMessageReceive(RxBuf); // Kick off receive of next frame // Timer_Clear(); WM8960_SetAudioFormat(Param); // UART_TxStr("WM8960_SetAudioFormat took "); // UART_TxNum(Timer_Read()); // UART_TxStr("mS\r\n"); break; default: // Unknown command TxBuf[BCPType] = BCTNAck; TxBuf[BCPParam1] = BCNUnkownType; TxBuf[BCPParam2] = RxBuf[BCPType]; BCMessageSend(TxBuf,true); // Send the reply BCMessageReceive(RxBuf); // Kick off receive of next frame break; } } } }
void SearchDevices(void) { UART_TxStr("Searching for devices\r\n"); // Look for input devices InputPresent[MP3In] = MP3Ready && Tracks; InputFormat[MP3In] = I2S32Bit; InputPresent[LCDIn] = ExchangeBoardMsg(BDCLCD, BCTInquire, 0, 0, BCTInquireAnswer); InputFormat[LCDIn] = RxBuf[BCPParam2]; BCMessageReceive(RxBuf); InputPresent[LeftTablet] = ExchangeBoardMsg(BCATabletLeft, BCTInquire, 0, 0, BCTInquireAnswer); InputFormat[LeftTablet] = RxBuf[BCPParam2]; BCMessageReceive(RxBuf); InputPresent[RightTablet]= ExchangeBoardMsg(BCATabletRight, BCTInquire, 0, 0, BCTInquireAnswer); InputFormat[RightTablet] = RxBuf[BCPParam2]; BCMessageReceive(RxBuf); // Look for output devices wdt_reset(); HeadphoneBay = NoBay; BayCount = 0; for(Bay = LeftBay; Bay <= RightBay; Bay++) { if (ExchangeBoardMsg(BCAOutput + Bay, BCTInquire, 0, 0, BCTInquireAnswer)) { BayCount++; UART_TxStr("Found bay "); UART_TxNum(Bay, 1); UART_TxStr(" = "); BayProduct[Bay] = RxBuf[BCPParam1]; if (BayProduct[Bay] == FiveHeadphones) HeadphoneBay = Bay; UART_TxNum(BayProduct[Bay], 1); UART_TxNewLine(); } BCMessageReceive(RxBuf); // Finished with it so get ready for next msg } Bay = LeftBay; BCMessageReceive(RxBuf); // Finished with it so get ready for next msg wdt_reset(); // Allow E2 overwrite of detected defaults if (Settings.LeftProduct != UnknownProduct) { UART_TxStr("E2 replaced left product "); UART_TxNum(BayProduct[LeftBay], 1); UART_TxStr(" with "); UART_TxNum(Settings.LeftProduct, 1); UART_TxNewLine(); BayProduct[LeftBay] = Settings.LeftProduct; } if (Settings.CenterProduct != UnknownProduct) { UART_TxStr("E2 replaced center product "); UART_TxNum(BayProduct[CenterBay], 1); UART_TxStr(" with "); UART_TxNum(Settings.CenterProduct, 1); UART_TxNewLine(); BayProduct[CenterBay] = Settings.CenterProduct; } if (Settings.RightProduct != UnknownProduct) { UART_TxStr("E2 replaced right product "); UART_TxNum(BayProduct[RightBay], 1); UART_TxStr(" with "); UART_TxNum(Settings.RightProduct, 1); UART_TxNewLine(); BayProduct[RightBay] = Settings.RightProduct; } ShowProducts(); // Determine operational mode // TODO: Check for override in E2 config wdt_reset(); Config = TwoBaysTwoSources; // Default mode if (!InputPresent[LCDIn]) { Config = TwoBaysOneSource; if (!InputPresent[MP3In]) // If no valid inputs, display error and reboot ShowError(ErrorNoSource, true); if(BayCount < 2) Config = OneBayOneSource; } else if (BayCount < 2) { if (!BayCount) // If no valid outputs, display error and reboot ShowError(ErrorNoBays, true); Config = OneBayTwoSources; } else { Config = TwoBaysTwoSources; } UART_TxStr("Mode: "); switch (Config) { case TwoBaysOneSource: UART_TxStr("Two bays, one source\r\n"); break; case OneBayTwoSources: UART_TxStr("One bay, two sources\r\n"); break; case TwoBaysTwoSources: UART_TxStr("Two bays, two sources\r\n"); break; case OneBayOneSource: UART_TxStr("Some error,one bay one source\r\n");break; } // TODO: Check for override in E2 config if (InputPresent[LeftTablet] && InputPresent[RightTablet]) // If two tablets BayNotSourceButtons = false; // Assume input selection buttons else if (BayCount < 2) // Only one bay BayNotSourceButtons = false; // Assume input selection buttons else // We have two, or more, products and one controller BayNotSourceButtons = true; }
/* SetBassTreble routine This routine writes the setting values to the MP3 bass/treble settings and displays them. */ void SetBassTreble(void) { Uint16 Treble; // Write current settings to MP3 chip vs_set_bass(Settings.TrebleLevel, Settings.BassLevel, Settings.TrebleFreq, Settings.BassFreq); // Show them to the user UART_TxStr("Bass "); if (Settings.BassLevel) { UART_TxChar('+'); UART_TxNum(Settings.BassLevel, 1); UART_TxStr("dB at "); UART_TxNum(Settings.BassFreq, 1); UART_TxStr("0Hz"); } else { UART_TxStr("off"); } UART_TxStr("\r\nTreble "); if (Settings.TrebleLevel == 0) { UART_TxStr("off\r\n"); } else { if (!(Settings.TrebleLevel & 0b10000000)) { Treble = Settings.TrebleLevel; UART_TxStr("+"); } else { Treble = 256 - Settings.TrebleLevel; UART_TxStr("-"); } Treble = Treble * 3 / 2; UART_TxNum(Treble, 1); if (Settings.TrebleLevel & 0b1) UART_TxStr(".5"); UART_TxStr("dB at "); UART_TxNum(Settings.TrebleFreq, 1); UART_TxStr("kHz\r\n"); } }
/* ProcessSelectKey routine This routine processes a select button depending on the current mode of operation. */ void ProcessSelectKey(Uint8 Key) { Uint8 MappedKey; bool BayNotSource; MappedKey = Key; // Default to no key remapping BayNotSource = BayNotSourceButtons; // Handle settings over rides switch (Key) { case LeftSelect: if (Settings.LeftSelectKeyOveride & 0b10000000) { BayNotSource = Settings.LeftSelectKeyOveride & 0b01000000; MappedKey = Settings.LeftSelectKeyOveride & 0b00001111; } break; case CenterSelect: if (Settings.CenterSelectKeyOveride & 0b10000000) { BayNotSource = Settings.CenterSelectKeyOveride & 0b01000000; MappedKey = Settings.CenterSelectKeyOveride & 0b00001111; } break; case RightSelect: if (Settings.RightSelectKeyOveride & 0b10000000) { BayNotSource = Settings.RightSelectKeyOveride & 0b01000000; MappedKey = Settings.RightSelectKeyOveride & 0b00001111; } break; } if (!BayNotSource) { // If selection source selection if (!InputPresent[MP3In]) // If MP3 player is dead then ignore these keys return; // Selecting the audio source if (((MappedKey == LeftSelect) && (Input == MP3In)) || ((MappedKey == RightSelect) && (Input == LCDIn))) { // Selecting same input returns to idle state // Ramp = RampDown; // UART_TxStr("Same input, going to idle state\r\n"); Ramp = RampDefault; UART_TxStr("Same input, going to default volume\r\n"); } else { if ((IdleTime == 0) || (Settings.InputChangeTrack1)) { MP3_Track(1); Track = 1; } if (MappedKey == LeftSelect) SetAllInputs(MP3In); // Left key selects MP3 else { SetAllInputs(LCDIn); // Right key selects LCD video } if (Volume < DefaultVolume) { Ramp = RampDefault; } } // Selecting the bay } else { UART_TxStr("Product selection "); if (IdleTime && // If not idle (((MappedKey == LeftSelect) && (Bay == LeftBay)) || // and selecting the current bay ((MappedKey == CenterSelect) && (Bay == CenterBay)) || ((MappedKey == RightSelect) && (Bay == RightBay)))) { Ramp = RampDown; // Causes us to return to idle mode UART_TxStr("off\r\n"); while (GetKey() == Key) { // Wait for key up before starting idle process MP3_Process(); RefreshLamps(); } DelayMS(10); } else { // Selecting a new bay UART_TxNum(MappedKey, 1); UART_TxNewLine(); if (IdleTime == 0) { // If was idle if (IdleVolume > MinVolume) Volume = IdleVolume; if (TwoBaysOneSource) { SetAllInputs(MP3In); MP3_Track(1); Track = 1; } IdleTime = Settings.IdlePeriod; Volume = MinVolume; Ramp = RampDefault; } else { if (HeadphoneBay == NoBay) { LastBayVolume[Bay] = Volume; // Save the volume for if we return to bay UART_TxStr("Saving bay "); UART_TxNum(Bay, 1); UART_TxStr(" volume "); UART_TxNum(Volume, 3); UART_TxNewLine(); } else { Volume = MinVolume; Ramp = RampDefault; } } if (MappedKey == LeftSelect) { SetBay(LeftBay); } else if (MappedKey == CenterSelect) { SetBay(CenterBay); } else { SetBay(RightBay); } if ((HeadphoneBay == NoBay) && (IdleTime != Settings.IdlePeriod)) { Volume = LastBayVolume[Bay]; // Restore the volume from last time bay was active UART_TxStr("Restoring bay "); UART_TxNum(Bay, 1); UART_TxStr(" volume "); UART_TxNum(Volume, 3); UART_TxNewLine(); SetVolume(Volume); } } } }
/* SetIdleState routine This routine sets the audio source, destination and volume to the idle state. */ void SetIdleState(void) { enum TBay TempBay; UART_TxStr("Setting to idle\r\n"); IdleTime = 0; // Work out default input for each bay if (Settings.LeftIdleInput <= RightTablet) { SetInput(Settings.LeftIdleInput, LeftBay); } else if (BayProduct[LeftBay] != UnknownProduct) { if (InputPresent[LeftTablet]) SetInput(LeftTablet, LeftBay); else if (InputPresent[RightTablet]) SetInput(RightTablet, LeftBay); else if (InputPresent[LCDIn]) SetInput(LCDIn, LeftBay); else SetInput(MP3In, LeftBay); } if (Settings.CenterIdleInput <= RightTablet) { SetInput(Settings.CenterIdleInput, CenterBay); } else if (BayProduct[CenterBay] != UnknownProduct) { if (InputPresent[LCDIn]) SetInput(LCDIn, CenterBay); else SetInput(MP3In, CenterBay); } if (Settings.RightIdleInput <= RightTablet) { SetInput(Settings.RightIdleInput, RightBay); } else if (BayProduct[RightBay] != UnknownProduct) { if (InputPresent[RightTablet]) SetInput(RightTablet, RightBay); else if (InputPresent[LeftTablet]) SetInput(LeftTablet, RightBay); else if (InputPresent[LCDIn]) SetInput(LCDIn, RightBay); else SetInput(MP3In, RightBay); } SetDefaultBay(); TempBay = Bay; // Work out the idle volume for each bay UART_TxStr("Setting idle volumes\r\n"); for (Bay = LeftBay; Bay <= RightBay; Bay++) { LastBayVolume[Bay] = Settings.ProdDef[BayProduct[Bay]].DefaultVolume; UART_TxStr("Setting bay "); UART_TxNum(Bay, 1); UART_TxStr(" default volume "); UART_TxNum(LastBayVolume[Bay], 3); UART_TxNewLine(); Volume = Settings.ProdDef[BayProduct[Bay]].IdleVolume; SetVolume(Volume); } Bay = TempBay; Volume = IdleVolume; UART_TxStr("Idle volume is "); UART_TxNum(Volume, 1); UART_TxNewLine(); if (MP3Paused) // If paused then unpause MP3_Pause(false); }
/* SetBay routine This routine sets the output device bay. */ void SetBay (enum TBay Device) { enum TBay PWMBay; enum TProducts PWMProduct; if (Device > NoBay) // Ignore bogus requests return; // If idle scan thru all bays setting them to idle state if (Device == NoBay) { PWMBay = Bay; for (Bay = LeftBay; Bay < NoBay; Bay++) { PWMProduct = BayProduct[Bay]; if (PWMProduct != UnknownProduct) SetVolume(0); } Bay = PWMBay; } else if ((Device != Bay) && (Bay != NoBay)) { // If changing bay and wasn't on no bay // Set the current bay to it's deselected state SetVolume(0); DelayMS(10); // Give time to get there before doing the actual change. } // Set global vars to match the product selected Bay = Device; Product = BayProduct[Bay]; IdleVolume = Settings.ProdDef[Product].IdleVolume; MinVolume = Settings.ProdDef[Product].MinimumVolume; DefaultVolume = Settings.ProdDef[Product].DefaultVolume; MaxVolume = Settings.ProdDef[Product].MaximumVolume; UART_TxStr("Bay "); UART_TxNum(Bay, 1); UART_TxStr(" Idle "); UART_TxNum(IdleVolume, 1); UART_TxStr(" Min "); UART_TxNum(MinVolume, 1); UART_TxStr(" Def "); UART_TxNum(DefaultVolume, 1); UART_TxStr(" Max "); UART_TxNum(MaxVolume, 1); UART_TxStr(" Cur "); UART_TxNum(Volume, 1); UART_TxNewLine(); // Select the bay if (Device == NoBay) return; // Deal with out of range values when changing output if (Volume > MaxVolume) { Volume = MaxVolume; SetVolume(Volume); } else if (IdleTime && (Volume < MinVolume)) { Volume = MinVolume; SetVolume(Volume); } else if (Device != Bay) { // If changing bay SetVolume(Volume); } }
//int main(void) __attribute__((noreturn)); // Main never returns so don't waste stack space on it. int main(void) { Uint16 TempInt; // Set up the I/O lines DDRA = PortDirA; DDRB = PortDirB; DDRC = PortDirC; DDRD = PortDirD; PINA = PortPullUpA; PINB = PortPullUpB; PINC = PortPullUpC; PIND = PortPullUpD; //set the channel is the keyboard. //mp3 init finish ,after reset the slave board have volume; SetBit(SelAPort, Sel0A); SetBit(SelAPort, Sel1A); SetBit(SelBPort, Sel0B); SetBit(SelBPort, Sel1B); SetBit(SelCPort, Sel0C); SetBit(SelCPort, Sel1C); // Init the peripherals Timer_Init(); // Set up timers UART_Init(); BCMessageInit(BCAMP3Contoller); // Set up key vars UART_Rx(CmdRxBuf, 1); Track = 1; IdleTime = 0; FlashPhase = 0; Volume = 0; PreMuteVolume = 0; Ramp = NoRamp; LastKey = 0; for(Bay = LeftBay; Bay <= NoBay; Bay++) { BayProduct[Bay] = UnknownProduct; BaySource[Bay] = 0xff; } Bay = LeftBay; SlaveMode = false; sei(); // Enable global interrupts // Print product build banner UART_TxStr("\r\n================================\r\n031-517-202 "); UART_TxStr(__TIME__); UART_TxChar(' '); UART_TxStr(__DATE__); UART_TxStr("\r\n================================\r\n"); // For reset the slave board maybe volume very high so have noise // so first set volume is 0 /*BCMessageReceive(RxBuf); // Finished with it so get ready for next msg ExchangeBoardMsg(BCALeftBay, BCTVolume, 0, 0, BCTAck); BCMessageReceive(RxBuf); // Finished with it so get ready for next msg ExchangeBoardMsg(BCACenterBay, BCTVolume, 0, 0, BCTAck); BCMessageReceive(RxBuf); // Finished with it so get ready for next msg ExchangeBoardMsg(BCARightBay, BCTVolume, 0, 0, BCTAck); BCMessageReceive(RxBuf); // Finished with it so get ready for next msg // Test the LEDs while bays boot up DelayMS(500); // Allow some time for keypad to boot up UART_TxStr("Testing LEDs\r\n"); for (TempInt = 1; TempInt <= 2; TempInt++) for (Key = 1; Key <= MaxKey; Key++) { SetLamp(Key); DelayMS(250); } // Keyboard test Count = 0xff; SetLamps(Count); for(;;){ if (BCRXAvail) { // See if we have a new frame ProcessBoardMsg(); BCMessageReceive(RxBuf); // Get the next message } if (GetKey() != TempInt) { TempInt = GetKey(); if (TempInt) { Count ^= 1 << (TempInt - 1); SetLamps(Count); } } } */ // Load EEPROM settings /* SetLamp(1); LoadEEPROMSetting(); UART_TxStr("Settings:\r\n"); PrintSettings(); // Prepare MP3 decoder for work SetLamp(4); Timer_Clear(); MP3_Init(); MP3_Volume(250); UART_TxStr("MP3 init time = "); UART_TxNum(Timer_Read(), 1); UART_TxStr("mS\r\n"); // Find the last track on the card SetLamp(3); for (Tracks = 1; Tracks <= 99; Tracks++) { if (!MP3_OpenFile(Tracks)) break; } Tracks--; SetBassTreble(); // Set the audio curve // Determine what is connected SetLamp(2); UART_TxStr("Searching for devices\r\n"); // Look for input devices InputPresent[MP3In] = true; InputFormat[MP3In] = I2S32Bit; InputPresent[LCDIn] = ExchangeBoardMsg(BDCLCD, BCTInquire, 0, 0, BCTInquireAnswer); InputFormat[LCDIn] = RxBuf[BCPParam2]; BCMessageReceive(RxBuf); InputPresent[LeftTablet] = ExchangeBoardMsg(BCATabletLeft, BCTInquire, 0, 0, BCTInquireAnswer); InputFormat[LeftTablet] = RxBuf[BCPParam2]; BCMessageReceive(RxBuf); InputPresent[RightTablet]= ExchangeBoardMsg(BCATabletRight, BCTInquire, 0, 0, BCTInquireAnswer); InputFormat[RightTablet] = RxBuf[BCPParam2]; BCMessageReceive(RxBuf); */ // Look for output devices /*HeadphoneBay = NoBay; BayCount = 0; for(Bay = LeftBay; Bay <= RightBay; Bay++) { if (ExchangeBoardMsg(BCAOutput + Bay, BCTInquire, 0, 0, BCTInquireAnswer)) { BayCount++; UART_TxStr("Found bay "); UART_TxNum(Bay, 1); UART_TxStr(" = "); BayProduct[Bay] = RxBuf[BCPParam1]; if (BayProduct[Bay] == FiveHeadphones) HeadphoneBay = Bay; UART_TxNum(BayProduct[Bay], 1); UART_TxNewLine(); } } Bay = LeftBay; BCMessageReceive(RxBuf); // Finished with it so get ready for next msg // Allow E2 overwrite of detected defaults if (Settings.LeftProduct != UnknownProduct) { UART_TxStr("E2 replaced left product "); UART_TxNum(BayProduct[LeftBay], 1); UART_TxStr(" with "); UART_TxNum(Settings.LeftProduct, 1); UART_TxNewLine(); BayProduct[LeftBay] = Settings.LeftProduct; } if (Settings.CenterProduct != UnknownProduct) { UART_TxStr("E2 replaced center product "); UART_TxNum(BayProduct[CenterBay], 1); UART_TxStr(" with "); UART_TxNum(Settings.CenterProduct, 1); UART_TxNewLine(); BayProduct[CenterBay] = Settings.CenterProduct; } if (Settings.RightProduct != UnknownProduct) { UART_TxStr("E2 replaced right product "); UART_TxNum(BayProduct[RightBay], 1); UART_TxStr(" with "); UART_TxNum(Settings.RightProduct, 1); UART_TxNewLine(); BayProduct[RightBay] = Settings.RightProduct; } ShowProducts(); // Determine operational mode // TODO: Check for override in E2 config Config = TwoBaysTwoSources; // Default mode if (!InputPresent[LCDIn]) { Config = TwoBaysOneSource; } else if (BayCount < 2) { Config = OneBayTwoSources; } else { Config = TwoBaysTwoSources; } UART_TxStr("Mode: "); switch (Config) { case TwoBaysOneSource: UART_TxStr("Two bays, one source\r\n"); break; case OneBayTwoSources: UART_TxStr("One bay, two sources\r\n"); break; case TwoBaysTwoSources: UART_TxStr("Two bays, two sources\r\n"); break; } // TODO: Check for override in E2 config if (InputPresent[LeftTablet] && InputPresent[RightTablet]) // If two tablets BayNotSourceButtons = false; // Assume input selection buttons else if (BayCount < 2) // Only one bay BayNotSourceButtons = false; // Assume input selection buttons else // We have two, or more, products and one controller BayNotSourceButtons = true; ConfigDevices(); // Configure connected devices SetIdleState(); MP3_Track(1); UART_TxStr("Start up complete\r\n"); // // Enter the main loop // */ Timer_Clear(); for( ; ; ) { // Run forever if (SlaveMode) { // In slave mode only handle slave mode messages CheckForBoardMsg(); } else { // Not in slave mode so feed the MP3 engine //if (!MP3_Process()) // MainLoop(0); // Tell the main loop we have stopped playback // Call the main loop if it is due //if (Timer_Read() >= LoopPeriod) { // Run the main loop at 10Hz // Timer_Clear(); MainLoop(0); // Tell the main loop we are still playing a track // } } } return 0; }
/* main routine Program entry point */ int main(void) { Uint8 TxBuf[BCMsgSize]; Uint8 RxBuf[BCMsgSize]; Uint8 Address; // Address of device in bay Uint8 Destination; // Address we will reply to Uint8 Param,Param2; Uint8 Volume = 0; Uint8 TempInt; #ifdef CTRL_LED Uint8 TempInt; Uint8 RceiveAddress; Uint8 i; i = 0; #endif MainInit(); UART_TxStr("\r\nPower up\r\n"); UART_Rx(RxData, 9); // Input register setting command Address = BCAOutput + ReadPosition(); BCMessageInit(Address); // Set up the UART BCMessageReceive(RxBuf); // Kick off receive if(ReadProductID()) // 1:pill 2:beats box 3:rave ChannelNumbers = 1; else ChannelNumbers = 5;//0:5 position headphone // Enter the main loop LED1_ON(); LED2_ON(); LED_GRAPHICAL_ON(); SetLamps(3); for( ; ; ) { // Run forever Timer_Clear(); DelayMS(LoopRate); TempInt++; SettingsControl(); if (BCRXAvail) { // We have a new message //send data #ifdef SecondUART #ifdef DumpComms UART_TxStr("Receive: "); for (TempInt = BCPSOH; TempInt <= BCPChecksum; TempInt++) { UART_TxUint8(RxBuf[TempInt]); UART_TxChar(' '); } UART_TxStr("\r\n"); #endif #endif if ((RxBuf[BCPAddr] & 0b1111) == Address) // Check it is for us { Destination = RxBuf[BCPAddr] >> 4; // Pre-setup assuming we will reply Destination &= 0b1111; Destination |= Address << 4; TxBuf[BCPAddr] = Destination; DelayMS(2); // Allow line turn around delay switch (RxBuf[BCPType]) { case BCTInquire: // Master request of slave ID TxBuf[BCPType] = BCTInquireAnswer; TxBuf[BCPParam1] = ReadProductID(); TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf,true); // Send the reply break; case BCTLamps: // Set lamps TxBuf[BCPType] = BCTAck; TxBuf[BCPParam1] = 0; TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf, true); // Send the reply Param = RxBuf[BCPParam1]; SetLamps(Param); break; case BCTVolume: // Volume set TxBuf[BCPType] = BCTAck; TxBuf[BCPParam1] = 0; TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf,true); // Send the reply Volume = RxBuf[BCPParam1]; // Save parameter so we can receive next frame while processing this request Param2 = RxBuf[BCPParam2]; // Save parameter so we can receive next frame while processing this request Volume_Set(Volume,Param2); break; case BCTHeadphoneChGain: // Volume set TxBuf[BCPType] = BCTAck; TxBuf[BCPParam1] = 0; TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf,true); // Send the reply Param = RxBuf[BCPParam1]; // Save parameter so we can receive next frame while processing this request Param2 = RxBuf[BCPParam2]; // Save parameter so we can receive next frame while processing this request SetChannelAdjust(Param,Param2); break; case BCTHeadphoneChMax: // Volume set TxBuf[BCPType] = BCTAck; TxBuf[BCPParam1] = 0; TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf,true); // Send the reply Param = RxBuf[BCPParam1]; // Save parameter so we can receive next frame while processing this request Param2 = RxBuf[BCPParam2]; // Save parameter so we can receive next frame while processing this request SetChMaxVolume(Param, Param2); break; case BCTAudioFormat: // Audio format set TxBuf[BCPType] = BCTAck; TxBuf[BCPParam1] = 0; TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf,true); // Send the reply Param = RxBuf[BCPParam1]; // Save parameter so we can receive next frame while processing this request WM8960_SetAudioFormat(Param); break; case BCTBrightness: // Set lamp brightness TxBuf[BCPType] = BCTAck; TxBuf[BCPParam1] = 0; TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf, true); // Send the reply Param = RxBuf[BCPParam1]; // Save parameter so we can receive next frame while processing this request Param2 = RxBuf[BCPParam2]; // Save parameter so we can receive next frame while processing this request if (Param == 1) LED1 = Param2; else if(Param == 2) LED2 = Param2; break; case BCTReset: // Volume set TxBuf[BCPType] = BCTAck; TxBuf[BCPParam1] = 0; TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf,true); // Send the reply Param = RxBuf[BCPParam1]; // Save parameter so we can receive next frame while processing this request BCMessageReceive(RxBuf); // Kick off receive of next frame asm("jmp 0x0000");//reset break; default: // Unknown command TxBuf[BCPType] = BCTNAck; TxBuf[BCPParam1] = BCNUnkownType; TxBuf[BCPParam2] = RxBuf[BCPType]; BCMessageSend(TxBuf,true); // Send the reply // BCMessageReceive(RxBuf); // Kick off receive of next frame break; } //this send command tv change to 031-517-209 board #if VideoTrackCtrl Uint8 VideoTrack; Uint8 SendVideoFlag; if(Volume > 47) { if(SendVideoFlag) { SendVideoFlag = false; if(Address == BCARightBay) { VideoTrack = 1; } else if(Address == BCALeftBay) { VideoTrack = 2; } TxBuf[BCPAddr] = Address << 4; TxBuf[BCPAddr] |= BDCLCD; TxBuf[BCPType] = BCTPlayTrack; TxBuf[BCPParam1] = VideoTrack; TxBuf[BCPParam2] = 0; BCMessageSend(TxBuf, true); // Send the reply } } else { SendVideoFlag = 1; } #endif } //this for ctrl LED it itself #ifdef CTRL_LED if(RxBuf[BCPType] == BCTVolume) { RceiveAddress = RxBuf[BCPAddr] & 0b1111; a_Volume[RceiveAddress-BCAOutput] = RxBuf[BCPParam1]; if((a_Volume[RceiveAddress-BCAOutput] > 47) && (LastVolume[RceiveAddress-BCAOutput] > 47))//have volume { if((RceiveAddress) == Address) { LED1_ON(); } else { LED1_OFF(); } } i = 0; for(TempInt = 0; TempInt < 4; ) //all volume off { if((a_Volume[TempInt] <= 47) && (LastVolume[TempInt] <= 47)) i++; TempInt++; } if(i >= TempInt) { LED1_ON(); } LastVolume[RceiveAddress-BCAOutput] = a_Volume[RceiveAddress-BCAOutput]; } #endif BCMessageReceive(RxBuf); // Kick off receive of next frame } }
//int main(void) __attribute__((noreturn)); // Main never returns so don't waste stack space on it. int main(void) { Uint16 TempInt; // Set up the I/O lines DDRA = PortDirA; DDRB = PortDirB; SD_PowerOn(); DDRC = PortDirC; DDRD = PortDirD; PINA = PortPullUpA; PINB = PortPullUpB; PINC = PortPullUpC; PIND = PortPullUpD; //set the channel is the keyboard. //mp3 init finish ,after reset the slave board have volume; SetBit(SelAPort, Sel0A); SetBit(SelAPort, Sel1A); SetBit(SelBPort, Sel0B); SetBit(SelBPort, Sel1B); SetBit(SelCPort, Sel0C); SetBit(SelCPort, Sel1C); LastError = 0; // Indicate no errors yet // Init the peripherals Timer_Init(); // Set up timers UART_Init(); InitKey(); BCMessageInit(BCAMP3Contoller); wdt_enable(WDTO_8S);//wdt 8s // Set up key vars UART_Rx(CmdRxBuf, 1); Track = 1; IdleTime = 0; FlashPhase = 0; Volume = 0; PreMuteVolume = 0; Ramp = NoRamp; LastKey = 0; for(Bay = LeftBay; Bay <= NoBay; Bay++) { BayProduct[Bay] = UnknownProduct; BaySource[Bay] = 0xff; } Bay = LeftBay; SlaveMode = false; SlaveModePara = 0; sei(); // Enable global interrupts // Print product build banner wdt_reset(); UART_TxStr("\r\n======================================\r\n031-517-202 "); UART_TxChar('0' + SWVerMajor); UART_TxChar('.'); UART_TxChar('0' + SWVerMinor); UART_TxChar('.'); UART_TxChar('0' + SWVerFix); UART_TxChar(' '); UART_TxStr(__TIME__); UART_TxChar(' '); UART_TxStr(__DATE__); UART_TxStr("\r\n======================================\r\n"); // For reset the slave board maybe volume very high so have noise // so first set volume is 0 wdt_reset(); BCMessageReceive(RxBuf); // Finished with it so get ready for next msg ExchangeBoardMsg(BCALeftBay, BCTVolume, 0, 0, BCTAck); BCMessageReceive(RxBuf); // Finished with it so get ready for next msg ExchangeBoardMsg(BCACenterBay, BCTVolume, 0, 0, BCTAck); BCMessageReceive(RxBuf); // Finished with it so get ready for next msg ExchangeBoardMsg(BCARightBay, BCTVolume, 0, 0, BCTAck); BCMessageReceive(RxBuf); // Finished with it so get ready for next msg // Test the LEDs while bays boot up DelayMS(100); // Allow some time for keypad to boot up UART_TxStr("Testing LEDs\r\n"); for (TempInt = 1; TempInt <= 2; TempInt++){ for (Key = 1; Key <= MaxKey; Key++) { if(!SetLamp(Key)){ SlaveMode = true; break; } DelayMS(250); wdt_reset();//feed the watchdog } if(SlaveMode) break; } // Show version number if(!SlaveMode){ SetLamps(0); DelayMS(1000); SetLamps(LeftLEDs | SWVerMajor); DelayMS(2000); wdt_reset(); SetLamps(RightLEDs | SWVerMinor); DelayMS(2000); wdt_reset(); SetLamps(LeftLEDs | RightLEDs | SWVerFix); DelayMS(2000); wdt_reset(); } // Load EEPROM settings SetLamp(1); LoadEEPROMSetting(); UART_TxStr("Settings:\r\n"); PrintSettings(); //wait for tablet ready wait 60 seconds if(SlaveMode) { UART_TxStr("Wait for tablet ready\r\n"); for(TempInt = 0; TempInt < 6000; TempInt++) { DelayMS(10); CheckForBoardMsg(); wdt_reset(); } } // Prepare MP3 decoder for work wdt_reset(); // Feed the watchdog DelayMS(500); SetLamp(4); Timer_Clear(); for (TempInt = 1; TempInt <= 5; TempInt++) { if (MP3_Init()) break; // If init ok exit loop wdt_reset(); // Feed the watchdog DelayMS(250); // Wait before trying again } MP3_Volume(250); UART_TxStr("MP3 init time = "); UART_TxNum(Timer_Read(), 1); UART_TxStr("mS\r\n"); // Find the last track on the card wdt_reset(); SetLamp(3); for (Tracks = 1; Tracks <= 99; Tracks++) { if (!MP3_OpenFile(Tracks)) break; } Tracks--; SetBassTreble(); // Set the audio curve // Determine what is connected wdt_reset(); SetLamp(2); SearchDevices(); if(!SlaveMode) { ConfigDevices(); // Configure connected devices SetIdleState(); MP3_Track(1); if (!InputPresent[MP3In]) // If no MP3 player display error ShowError(ErrorNoMP3, false); } UART_TxStr("Start up complete\r\n"); // // Enter the main loop // Timer_Clear(); SlaveModeTimerClear(); for( ; ; ) { // Run forever if (SlaveMode) { // In slave mode only handle slave mode messages CheckForBoardMsg(); if(SlaveModeTimerRead() > 5000) { UART_TxNum(SlaveModeTimerRead(),5); UART_TxStr("\r\nMore than 5 seconds change to normal mode\r\n"); SlaveMode = false;//return to Normal mode SearchDevices(); Volume = 99; //if Volume == IdleVolume the not need send the volume so need give the diffent IdleVolume value Bay = RightBay; SetIdleState(); SetMux(Input,LeftBay); SetMux(Input,CenterBay); SetMux(Input,RightBay); } wdt_reset(); // Update the watchdog } else { // Not in slave mode so feed the MP3 engine if (MP3Ready && !MP3_Process()) MainLoop(0); // Tell the main loop we have stopped playback // Call the main loop if it is due if (Timer_Read() >= LoopPeriod) { // Run the main loop at 10Hz Timer_Clear(); MainLoop(1); // Tell the main loop we are still playing a track } } } return 0; }
/* MainLoop routine This routine should be called ever LoopPeriod. The PlayerStatus should be 0 if stopped or 1 is playing. */ void MainLoop(Uint8 PlayerStatus) { // Update state info wdt_reset(); // Update the watchdog FlashPhase++; if (PrevTime) PrevTime--; // Check for failure of MP3 player if (InputPresent[MP3In] && !MP3Ready) // If MP3 player has died ShowError(ErrorNoMP3, true); // Display error then reboot // See if we need to start playback of next track if (InputPresent[MP3In] && (PlayerStatus == 0)) { if (++Track > Tracks) Track = 1; if(!MP3_Track(Track)){ UART_TxStr("\r\nCan't open track, waiting for watchdog reset\r\n"); DelayMS(10000); // Force the watchdog to activate } } // Process an incoming comms CheckForBoardMsg(); // Check for settings changes SerialControl(); // Poll keys Key = GetKey(); /* if (Key) ClearBit(LogoLEDPort, LogoLED); else SetBit(LogoLEDPort, LogoLED); */ //if no card or in 5headphone no TV input ,some key need disable if(Config==OneBayOneSource){//only one bay,so not need left and right bay if((Key==LeftSelect) || (Key==RightSelect)){ Key = 0; } }else if((Config==OneBayTwoSources) && (!MP3Ready)){ // if((Key==LeftSelect) || (Key==RightSelect) || (Key==PrevTrack) || (Key==NextTrack)){ Key = 0; } }else if(!MP3Ready){ if((Key==PrevTrack) || (Key==NextTrack)){ //if Mp3 not ready so next and prev key not need Key = 0; } } if (!Settings.PauseKeyEnabled && (Key == PlayPause)) // Handle disabled Key = LastKey; if (LastKey != Key) { // Until we know the keyboard is good show it's output UART_TxStr("Key "); UART_TxNum(Key, 1); UART_TxNewLine(); } // Handle error code display request if (Key && (LastKey != Key) && KonamiCheck(Key)) // Until we know the keyboard is good show it's output ShowError(LastError, false); // Handle un-pausing if (Key && (Key != PlayPause)) { // && InputPresent[MP3In] if (MP3Paused) // If paused then unpause MP3_Pause(false); if (PreMuteVolume) { // If muted then unmute Volume = PreMuteVolume; SetVolume(Volume); } } // Process key touched switch (Key){ case LeftSelect: case RightSelect: case CenterSelect: if (Key != LastKey){ if(Config!=OneBayOneSource)//no need to select ProcessSelectKey(Key); } break; case NextTrack: case PrevTrack: if (Key != LastKey) ProcessTrackKey(Key); break; case VolUp: case VolDown: ProcessVolumeKey(Key); break; case PlayPause: if (Key != LastKey) ProcessPlayKey(Key); break; default: break; } LastKey = Key; // Handle time out if (Key) { // See if currently not idle IdleTime = Settings.IdlePeriod; } else if (IdleTime && !--IdleTime) { UART_TxStr("Idle timeout\r\n"); Ramp = RampDown; } // Handle volume ramping switch (Ramp) { case RampDown: UART_TxStr("Ramping down\r\n"); if ((Volume >= MinVolume) && (Volume >= IdleVolume + Settings.VolumeRampStep)) Volume -= Settings.VolumeRampStep; else Volume = IdleVolume; SetVolume(Volume); if (Volume <= IdleVolume) { Ramp = NoRamp; SetIdleState(); } break; case RampDefault: UART_TxStr("Ramping to default\r\n"); if (Volume < DefaultVolume) { if (Volume + Settings.VolumeRampStep <= DefaultVolume) Volume += Settings.VolumeRampStep; else Volume = DefaultVolume; SetVolume(Volume); } else if (Volume > DefaultVolume) { if (Volume >= DefaultVolume + Settings.VolumeRampStep) Volume -= Settings.VolumeRampStep; else Volume = DefaultVolume; SetVolume(Volume); } else { Ramp = NoRamp; } break; default: break; } if(!SlaveMode){ PollTime(); RefreshLamps(); } }