Ejemplo n.º 1
0
        static void Init()
        {
            LED = new OutputPort(Pin.LED, false);

            #region Settings

            var sd = GetRootDirectory();

            var settings = Settings.Init(sd != null ? sd + @"\imBMW.ini" : null);
            var log      = settings.Log || settings.LogToSD;

            Localization.SetCurrent(settings.Language);
            Features.Comfort.AutoLockDoors    = settings.AutoLockDoors;
            Features.Comfort.AutoUnlockDoors  = settings.AutoUnlockDoors;
            Features.Comfort.AutoCloseWindows = settings.AutoCloseWindows;
            Features.Comfort.AutoCloseSunroof = settings.AutoCloseSunroof;
            Logger.Info("Preferences inited");

            #if DEBUG
            log = true;
            #else
            // already inited in debug mode
            if (settings.Log)
            {
                Logger.Logged += Logger_Logged;
                Logger.Info("Logger inited");
            }
            #endif

            if (settings.LogToSD && sd != null)
            {
                FileLogger.Init(sd + @"\Logs", () =>
                {
                    VolumeInfo.GetVolumes()[0].FlushAll();
                });
            }

            Logger.Info(version);
            SettingsScreen.Instance.Status = version.Length > 11 ? version.Replace(" ", "") : version;

            #endregion

            #region iBus Manager

            // Create serial port to work with Melexis TH3122
            //ISerialPort iBusPort = new SerialPortEcho();
            ISerialPort iBusPort = new SerialPortTH3122(Serial.COM3, Pin.TH3122SENSTA);
            Logger.Info("TH3122 serial port inited");

            /*InputPort jumper = new InputPort((Cpu.Pin)FEZ_Pin.Digital.An7, false, Port.ResistorMode.PullUp);
             * if (!jumper.Read())
             * {
             *  Logger.Info("Jumper installed. Starting virtual COM port");
             *
             *  // Init hub between iBus port and virtual USB COM port
             *  ISerialPort cdc = new SerialPortCDC(USBClientController.StandardDevices.StartCDC_WithDebugging(), 0, iBus.Message.PacketLengthMax);
             *  iBusPort = new SerialPortHub(iBusPort, cdc);
             *  Logger.Info("Serial port hub started");
             * }*/

            iBus.Manager.Init(iBusPort);
            Logger.Info("iBus manager inited");

            #endregion

            #region iBus IO logging

            Message sent1 = null, sent2 = null; // light "buffer" for last 2 messages
            bool    isSent1 = false;
            iBus.Manager.BeforeMessageReceived += (e) =>
            {
                LED.Write(Busy(true, 1));
            };
            iBus.Manager.AfterMessageReceived += (e) =>
            {
                LED.Write(Busy(false, 1));

                if (!log)
                {
                    return;
                }

                // Show only messages which are described
                if (e.Message.Describe() == null)
                {
                    return;
                }
                // Filter CDC emulator messages echoed by iBus
                //if (e.Message.SourceDevice == iBus.DeviceAddress.CDChanger) { return; }
                if (e.Message.SourceDevice != DeviceAddress.Radio &&
                    e.Message.DestinationDevice != DeviceAddress.Radio &&
                    e.Message.SourceDevice != DeviceAddress.GraphicsNavigationDriver &&
                    e.Message.SourceDevice != DeviceAddress.Diagnostic && e.Message.DestinationDevice != DeviceAddress.Diagnostic)
                {
                    //return;
                }
                var logIco = "< ";
                if (e.Message.ReceiverDescription == null)
                {
                    if (sent1 != null && sent1.Data.Compare(e.Message.Data))
                    {
                        e.Message.ReceiverDescription = sent1.ReceiverDescription;
                        logIco = "<E";
                    }
                    else if (sent2 != null && sent2.Data.Compare(e.Message.Data))
                    {
                        e.Message.ReceiverDescription = sent2.ReceiverDescription;
                        logIco = "<E";
                    }
                }
                if (settings.LogMessageToASCII)
                {
                    Logger.Info(e.Message.ToPrettyString(true, true), logIco);
                }
                else
                {
                    Logger.Info(e.Message, logIco);
                }

                /*if (e.Message.ReceiverDescription == null)
                 * {
                 *  Logger.Info(ASCIIEncoding.GetString(e.Message.Data));
                 * }*/
                //Logger.Info(e.Message.PacketDump);
            };
            iBus.Manager.BeforeMessageSent += (e) =>
            {
                LED.Write(Busy(true, 2));
            };
            iBus.Manager.AfterMessageSent += (e) =>
            {
                LED.Write(Busy(false, 2));

                if (!log)
                {
                    return;
                }

                Logger.Info(e.Message, " >");
                if (isSent1)
                {
                    sent1 = e.Message;
                }
                else
                {
                    sent2 = e.Message;
                }
                isSent1 = !isSent1;
            };
            Logger.Info("iBus manager events subscribed");

            #endregion

            #region CAN BUS

            #if CANBUS
            var speed = CanAdapterSettings.CanSpeed.Kbps100;
            CanAdapter.Current = new CanNativeAdapter(Pin.CAN, speed);
            //var canInterrupt = Cpu.Pin.GPIO_NONE;
            //var canInterrupt = Pin.Di2;
            //CanAdapter.Current = new CanMCP2515Adapter(Pin.SPI, Pin.SPI_ChipSelect, canInterrupt, speed, CanMCP2515AdapterSettings.AdapterFrequency.Mhz8);
            CanAdapter.Current.MessageReceived += Can_MessageReceived;
            CanAdapter.Current.MessageSent     += Can_MessageSent;
            CanAdapter.Current.Error           += Can_ErrorReceived;
            CanAdapter.Current.IsEnabled        = true;

            #if E65SEATS
            Button.Toggle(Pin.Di2, pressed => { if (pressed)
                                                {
                                                    E65Seats.EmulatorPaused = true;
                                                }
                                                else
                                                {
                                                    E65Seats.EmulatorPaused = false;
                                                } });
            E65Seats.Init();
            HomeScreen.Instance.SeatsScreen = E65SeatsScreen.Instance;
            #endif

            Logger.Info("CAN BUS inited");
            #endif

            #endregion

            #region Set iPod or Bluetooth as AUX or CDC-emulator for Bordmonitor or Radio

            //
            //Bordmonitor.ReplyToScreenUpdates = true;
            //settings.MenuMode = MenuMode.RadioCDC;
            //settings.MediaShield = "WT32";
            //settings.BluetoothPin = "1111";
            //

            BluetoothWT32 wt32;
            if (settings.MediaShield == "WT32")
            {
                wt32   = new BluetoothWT32(Serial.COM2, Settings.Instance.BluetoothPin);
                player = wt32;
                InternalCommunications.Register(wt32);

                byte gain = 0;
                Button.OnPress(Pin.Di14, () => wt32.SetMicGain((byte)(++gain % 16)));
            }
            else
            {
                player = new BluetoothOVC3860(Serial.COM2, sd != null ? sd + @"\contacts.vcf" : null);
                //player = new iPodViaHeadset(Pin.PC2);
            }

            //
            //player.IsCurrentPlayer = true;
            //player.PlayerHostState = PlayerHostState.On;
            //

            MediaEmulator emulator;
            if (settings.MenuMode != Tools.MenuMode.RadioCDC || Manager.FindDevice(DeviceAddress.OnBoardMonitor))
            {
                if (player is BluetoothWT32)
                {
                    ((BluetoothWT32)player).NowPlayingTagsSeparatedRows = true;
                }
                if (settings.MenuMode == Tools.MenuMode.BordmonitorCDC)
                {
                    emulator = new CDChanger(player);
                    if (settings.NaviVersion == NaviVersion.MK2)
                    {
                        Localization.Current = new RadioLocalization();
                        SettingsScreen.Instance.CanChangeLanguage = false;
                    }
                }
                else
                {
                    emulator = new BordmonitorAUX(player);
                }
                Bordmonitor.NaviVersion         = settings.NaviVersion;
                BordmonitorMenu.FastMenuDrawing = settings.NaviVersion == NaviVersion.MK4;
                //MenuScreen.MaxItemsCount = 6;
                BordmonitorMenu.Init(emulator);

                Logger.Info("Bordmonitor menu inited");
            }
            else
            {
                Localization.Current = new RadioLocalization();
                SettingsScreen.Instance.CanChangeLanguage = false;
                MultiFunctionSteeringWheel.EmulatePhone   = true;
                Radio.HasMID = Manager.FindDevice(DeviceAddress.MultiInfoDisplay);
                var menu = RadioMenu.Init(new CDChanger(player));
                menu.TelephoneModeForNavigation = settings.MenuMFLControl;
                Logger.Info("Radio menu inited" + (Radio.HasMID ? " with MID" : ""));
            }

            ShieldLED = new OutputPort(Pin.Di10, false);
            player.IsPlayingChanged += (p, s) =>
            {
                ShieldLED.Write(s);
                RefreshLEDs();
            };
            player.StatusChanged += (p, s, e) =>
            {
                if (e == PlayerEvent.IncomingCall && !p.IsEnabled)
                {
                    InstrumentClusterElectronics.Gong1();
                }
            };
            Logger.Info("Player events subscribed");

            #endregion

            /*blinkerTimer = new Timer((s) =>
             * {
             *  if (InstrumentClusterElectronics.CurrentIgnitionState == IgnitionState.Off && !blinkerOn)
             *  {
             *      return;
             *  }
             *  blinkerOn = !blinkerOn;
             *  RefreshLEDs();
             * }, null, 0, 3000);*/

            RefreshLEDs();

            //
            //var ign = new Message(DeviceAddress.InstrumentClusterElectronics, DeviceAddress.GlobalBroadcastAddress, "Ignition ACC", 0x11, 0x01);
            //Manager.EnqueueMessage(ign);
            //Manager.AddMessageReceiverForDestinationDevice(DeviceAddress.InstrumentClusterElectronics, m =>
            //{
            //    if (m.Data.Compare(0x10))
            //    {
            //        Manager.EnqueueMessage(ign);
            //    }
            //});
            //var b = Manager.FindDevice(DeviceAddress.Radio);
            //

            LED.Write(true);
            Thread.Sleep(50);
            LED.Write(false);
            Logger.Info("LED blinked - inited");
        }
Ejemplo n.º 2
0
        void Init()
        {
            LED = new OutputPort(launcherSettings.LEDPin, false);

            #region Settings

            var sd = GetRootDirectory();

            var settings = Settings.Init(sd != null ? sd + @"\imBMW.ini" : null);

            if (settingsOverride != null)
            {
                settingsOverride(settings);
            }

            var log = settings.Log || settings.LogToSD;
#if DEBUG
            log = true;
            settings.LogMessageToASCII = true;
#else
            // already inited in debug mode
            if (settings.Log)
            {
                Logger.Logged += Logger_Logged;
                Logger.Info("Logger inited");
            }
#endif
            if (settings.LogToSD && sd != null)
            {
                FileLogger.Init(sd + @"\Logs", () =>
                {
                    VolumeInfo.GetVolumes()[0].FlushAll();
                });
            }

            Logger.Info(version);

            Localization.SetCurrent(settings.Language);
            Comfort.AutoLockDoors    = settings.AutoLockDoors;
            Comfort.AutoUnlockDoors  = settings.AutoUnlockDoors;
            Comfort.AutoCloseWindows = settings.AutoCloseWindows;
            Comfort.AutoCloseSunroof = settings.AutoCloseSunroof;
            Logger.Info("Preferences inited");

            SettingsScreen.Instance.Status = version.Length > 11 ? version.Replace(" ", "") : version;

            #endregion

            #region iBus Manager

            // Create serial port to work with Melexis TH3122
            //ISerialPort iBusPort = new SerialPortEcho();
            ISerialPort iBusPort = new SerialPortTH3122(launcherSettings.iBusPort, launcherSettings.iBusBusyPin);
            Logger.Info("TH3122 serial port inited");

            /*InputPort jumper = new InputPort((Cpu.Pin)FEZ_Pin.Digital.An7, false, Port.ResistorMode.PullUp);
             * if (!jumper.Read())
             * {
             *  Logger.Info("Jumper installed. Starting virtual COM port");
             *
             *  // Init hub between iBus port and virtual USB COM port
             *  ISerialPort cdc = new SerialPortCDC(USBClientController.StandardDevices.StartCDC_WithDebugging(), 0, iBus.Message.PacketLengthMax);
             *  iBusPort = new SerialPortHub(iBusPort, cdc);
             *  Logger.Info("Serial port hub started");
             * }*/

            Manager.Init(iBusPort);
            Logger.Info("iBus manager inited");

            #endregion

            #region iBus IO logging

            Message sent1 = null, sent2 = null; // light "buffer" for last 2 messages
            bool    isSent1 = false;
            Manager.BeforeMessageReceived += (e) =>
            {
                LED.Write(Busy(true, 1));
            };
            Manager.AfterMessageReceived += (e) =>
            {
                LED.Write(Busy(false, 1));

                if (!log)
                {
                    return;
                }

                var logIco = "< ";
                if (e.Message.ReceiverDescription == null)
                {
                    if (sent1 != null && sent1.Data.Compare(e.Message.Data))
                    {
                        e.Message.ReceiverDescription = sent1.ReceiverDescription;
                        logIco = "<E";
                    }
                    else if (sent2 != null && sent2.Data.Compare(e.Message.Data))
                    {
                        e.Message.ReceiverDescription = sent2.ReceiverDescription;
                        logIco = "<E";
                    }
                }
                if (settings.LogMessageToASCII && e.Message.ReceiverDescription == null)
                {
                    Logger.Info(e.Message.ToPrettyString(true, true), logIco);
                }
                else
                {
                    Logger.Info(e.Message, logIco);
                }
            };
            Manager.BeforeMessageSent += (e) =>
            {
                LED.Write(Busy(true, 2));
            };
            Manager.AfterMessageSent += (e) =>
            {
                LED.Write(Busy(false, 2));

                if (!log)
                {
                    return;
                }

                Logger.Info(e.Message, " >");
                if (isSent1)
                {
                    sent1 = e.Message;
                }
                else
                {
                    sent2 = e.Message;
                }
                isSent1 = !isSent1;
            };
            Logger.Info("iBus manager events subscribed");

            #endregion

            #region Features

#if DEBUG
            InstrumentClusterElectronics.RequestDateTimeAndSetLocal(false);
#endif

            #endregion

            #region CAN BUS

            if (launcherSettings.CanBus != 0)
            {
                var speed = CanAdapterSettings.CanSpeed.Kbps100;
                CanAdapter.Current = new CanNativeAdapter(launcherSettings.CanBus, speed);
                //var canInterrupt = Cpu.Pin.GPIO_NONE;
                //var canInterrupt = Pin.Di2;
                //CanAdapter.Current = new CanMCP2515Adapter(Pin.SPI, Pin.SPI_ChipSelect, canInterrupt, speed, CanMCP2515AdapterSettings.AdapterFrequency.Mhz8);
                if (log)
                {
                    CanAdapter.Current.MessageReceived += Can_MessageReceived;
                    CanAdapter.Current.MessageSent     += Can_MessageSent;
                    CanAdapter.Current.Error           += Can_ErrorReceived;
                }
                CanAdapter.Current.IsEnabled = true;

                if (launcherSettings.E65Seats)
                {
                    //HardwareButton.Toggle(Pin.Di2, pressed => { if (pressed) E65Seats.EmulatorPaused = true; else E65Seats.EmulatorPaused = false; });
                    E65Seats.Init();
                    E65Seats.AutoHeater             = true;
                    E65Seats.AutoVentilation        = true;
                    HomeScreen.Instance.SeatsScreen = E65SeatsScreen.Instance;
                }

                Logger.Info("CAN BUS inited");
            }

            #endregion

            #region Set iPod or Bluetooth as AUX or CDC-emulator for Bordmonitor or Radio

            BluetoothWT32 wt32;
            if (settings.MediaShield == "WT32")
            {
                wt32   = new BluetoothWT32(launcherSettings.MediaShieldPort, Settings.Instance.BluetoothPin);
                player = wt32;
                InternalCommunications.Register(wt32);

                //byte gain = 0;
                //HardwareButton.OnPress(Pin.Di14, () => wt32.SetMicGain((byte)(++gain % 16)));
            }
            else
            {
                player = new BluetoothOVC3860(launcherSettings.MediaShieldPort, sd != null ? sd + @"\contacts.vcf" : null);
            }

            MediaEmulator emulator;
            if (settings.MenuMode == MenuMode.BordmonitorAUX ||
                settings.MenuMode == MenuMode.BordmonitorCDC ||
                Manager.FindDevice(DeviceAddress.OnBoardMonitor))
            {
                if (player is BluetoothWT32)
                {
                    ((BluetoothWT32)player).NowPlayingTagsSeparatedRows = true;
                }
                if (settings.MenuMode == MenuMode.BordmonitorCDC)
                {
                    emulator = new CDChanger(player, true);
                    if (settings.NaviVersion == NaviVersion.MK2)
                    {
                        Localization.Current = new RadioLocalization();
                        SettingsScreen.Instance.CanChangeLanguage = false;
                    }
                }
                else
                {
                    emulator = new BordmonitorAUX(player);
                }
                Bordmonitor.NaviVersion         = settings.NaviVersion;
                BordmonitorMenu.FastMenuDrawing = settings.NaviVersion == NaviVersion.MK4;
                //MenuScreen.MaxItemsCount = 6;
                BordmonitorMenu.Init(emulator);

                Logger.Info("Bordmonitor menu inited");
            }
            else
            {
                Localization.Current = new RadioLocalization();
                SettingsScreen.Instance.CanChangeLanguage = false;
                MultiFunctionSteeringWheel.EmulatePhone   = true;
                if (settings.MenuMode == MenuMode.MIDAUX)
                {
                    Radio.HasMID = true;
                    emulator     = new MIDAUX(player);
                }
                else
                {
                    Radio.HasMID = Manager.FindDevice(DeviceAddress.MultiInfoDisplay);
                    emulator     = new CDChanger(player);
                }
                var menu = RadioMenu.Init(emulator);
                menu.IsDuplicateOnIKEEnabled    = true;
                menu.TelephoneModeForNavigation = settings.MenuMFLControl;
                Logger.Info("Radio menu inited" + (Radio.HasMID ? " with MID" : ""));
            }

            player.IsShowStatusOnIKEEnabled = true;

            ShieldLED = new OutputPort(launcherSettings.MediaShieldLED, false);
            player.IsPlayingChanged += (p, e) =>
            {
                ShieldLED.Write(e.IsPlaying);
                RefreshLEDs();
            };
            player.StatusChanged += (p, e) =>
            {
                if (e.Event == PlayerEvent.IncomingCall && !p.IsEnabled)
                {
                    InstrumentClusterElectronics.Gong1();
                }
            };
            Logger.Info("Player events subscribed");

            #endregion

            RefreshLEDs();

            LED.Write(true);
            Thread.Sleep(50);
            LED.Write(false);
            Logger.Info("LED blinked - inited");
        }
Ejemplo n.º 3
0
        static void Init()
        {
            LED = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.LED, false);

            var settings = Settings.Init(null);
            var log      = settings.Log || settings.LogToSD;

            // TODO move to settings
            Localization.Current              = new EnglishLocalization();
            Features.Comfort.AutoLockDoors    = true;
            Features.Comfort.AutoUnlockDoors  = true;
            Features.Comfort.AutoCloseWindows = true;
            Logger.Info("Preferences inited");

            Logger.Info(version);
            SettingsScreen.Instance.Status = version;

            // Create serial port to work with Melexis TH3122
            ISerialPort iBusPort = new SerialPortTH3122(Serial.COM3, (Cpu.Pin)FEZ_Pin.Interrupt.Di4);

            //ISerialPort iBusPort = new SerialPortOptoPair(Serial.COM3);
            Logger.Info("TH3122 serial port inited");

            InputPort jumper = new InputPort((Cpu.Pin)FEZ_Pin.Digital.An7, false, Port.ResistorMode.PullUp);

            /*if (!jumper.Read())
             * {
             *  Logger.Info("Jumper installed. Starting virtual COM port");
             *
             *  // Init hub between iBus port and virtual USB COM port
             *  ISerialPort cdc = new SerialPortCDC(USBClientController.StandardDevices.StartCDC_WithDebugging(), 0, iBus.Message.PacketLengthMax);
             *  iBusPort = new SerialPortHub(iBusPort, cdc);
             *  Logger.Info("Serial port hub started");
             * }*/

            // Enable iBus Manager
            iBus.Manager.Init(iBusPort);
            Logger.Info("iBus manager inited");

            Message sent1 = null, sent2 = null; // light "buffer" for last 2 messages
            bool    isSent1 = false;

            iBus.Manager.BeforeMessageReceived += (e) =>
            {
                LED.Write(Busy(true, 1));
            };
            iBus.Manager.AfterMessageReceived += (e) =>
            {
                LED.Write(Busy(false, 1));

                if (!log)
                {
                    return;
                }

                // Show only messages which are described
                if (e.Message.Describe() == null)
                {
                    return;
                }
                // Filter CDC emulator messages echoed by iBus
                //if (e.Message.SourceDevice == iBus.DeviceAddress.CDChanger) { return; }
                if (e.Message.SourceDevice != DeviceAddress.Radio &&
                    e.Message.DestinationDevice != DeviceAddress.Radio &&
                    e.Message.SourceDevice != DeviceAddress.GraphicsNavigationDriver &&
                    e.Message.SourceDevice != DeviceAddress.Diagnostic && e.Message.DestinationDevice != DeviceAddress.Diagnostic)
                {
                    return;
                }
                if (e.Message.ReceiverDescription == null)
                {
                    if (sent1 != null && sent1.Data.Compare(e.Message.Data))
                    {
                        e.Message.ReceiverDescription = sent1.ReceiverDescription;
                    }
                    else if (sent2 != null && sent2.Data.Compare(e.Message.Data))
                    {
                        e.Message.ReceiverDescription = sent2.ReceiverDescription;
                    }
                }
                if (settings.LogMessageToASCII)
                {
                    Logger.Info(e.Message.ToPrettyString(true, true), "< ");
                }
                else
                {
                    Logger.Info(e.Message, "< ");
                }

                /*if (e.Message.ReceiverDescription == null)
                 * {
                 *  Logger.Info(ASCIIEncoding.GetString(e.Message.Data));
                 * }*/
                //Logger.Info(e.Message.PacketDump);
            };
            iBus.Manager.BeforeMessageSent += (e) =>
            {
                LED.Write(Busy(true, 2));
            };
            iBus.Manager.AfterMessageSent += (e) =>
            {
                LED.Write(Busy(false, 2));

                if (!log)
                {
                    return;
                }

                Logger.Info(e.Message, " >");
                if (isSent1)
                {
                    sent1 = e.Message;
                }
                else
                {
                    sent2 = e.Message;
                }
                isSent1 = !isSent1;
            };
            Logger.Info("iBus manager events subscribed");

            // Set iPod or Bluetooth as AUX or CDC-emulator for Bordmonitor or Radio
            //player = new BluetoothOVC3860(Serial.COM2, sd != null ? sd + @"\contacts.vcf" : null);
            player = new iPodViaHeadset((Cpu.Pin)FEZ_Pin.Digital.Di3);

            MediaEmulator emulator;

            if (settings.MenuMode != Tools.MenuMode.RadioCDC || Manager.FindDevice(DeviceAddress.OnBoardMonitor))
            {
                if (settings.MenuMode == Tools.MenuMode.BordmonitorCDC)
                {
                    emulator = new CDChanger(player);
                    if (settings.NaviVersion == NaviVersion.MK2)
                    {
                        Localization.Current = new RadioLocalization();
                        SettingsScreen.Instance.CanChangeLanguage = false;
                    }
                }
                else
                {
                    emulator = new BordmonitorAUX(player);
                }
                Bordmonitor.NaviVersion         = settings.NaviVersion;
                BordmonitorMenu.FastMenuDrawing = settings.NaviVersion == NaviVersion.MK4;
                //MenuScreen.MaxItemsCount = 6;
                BordmonitorMenu.Init(emulator);

                Logger.Info("Bordmonitor menu inited");
            }
            else
            {
                Localization.Current = new RadioLocalization();
                SettingsScreen.Instance.CanChangeLanguage = false;
                MultiFunctionSteeringWheel.EmulatePhone   = true;
                Radio.HasMID = Manager.FindDevice(DeviceAddress.MultiInfoDisplay);
                var menu = RadioMenu.Init(new CDChanger(player));
                menu.TelephoneModeForNavigation = settings.MenuMFLControl;
                Logger.Info("Radio menu inited" + (Radio.HasMID ? " with MID" : ""));
            }

            LED.Write(true);
            Thread.Sleep(50);
            LED.Write(false);
            Logger.Info("LED blinked - inited");
        }
Ejemplo n.º 4
0
        static void Init()
        {
            LED = new OutputPort(FEZPin.PA8, false);

            var sd = GetRootDirectory();

            var settings = Settings.Init(sd != null ? sd + @"\imBMW.ini" : null);
            var log      = settings.Log || settings.LogToSD;

            Localization.SetCurrent(settings.Language);
            Features.Comfort.AutoLockDoors    = settings.AutoLockDoors;
            Features.Comfort.AutoUnlockDoors  = settings.AutoUnlockDoors;
            Features.Comfort.AutoCloseWindows = settings.AutoCloseWindows;
            Features.Comfort.AutoCloseSunroof = settings.AutoCloseSunroof;
            Logger.Info("Preferences inited");

            #if DEBUG
            log = true;
            #else
            // already inited in debug mode
            if (settings.Log)
            {
                Logger.Logged += Logger_Logged;
                Logger.Info("Logger inited");
            }
            #endif

            if (settings.LogToSD && sd != null)
            {
                FileLogger.Init(sd + @"\Logs", () =>
                {
                    VolumeInfo.GetVolumes()[0].FlushAll();
                });
            }

            Logger.Info(version);
            SettingsScreen.Instance.Status = version;

            // Create serial port to work with Melexis TH3122
            ISerialPort iBusPort = new SerialPortTH3122(Serial.COM3, FEZPin.PC2, true);
            Logger.Info("TH3122 serial port inited");

            /*InputPort jumper = new InputPort((Cpu.Pin)FEZ_Pin.Digital.An7, false, Port.ResistorMode.PullUp);
             * if (!jumper.Read())
             * {
             *  Logger.Info("Jumper installed. Starting virtual COM port");
             *
             *  // Init hub between iBus port and virtual USB COM port
             *  ISerialPort cdc = new SerialPortCDC(USBClientController.StandardDevices.StartCDC_WithDebugging(), 0, iBus.Message.PacketLengthMax);
             *  iBusPort = new SerialPortHub(iBusPort, cdc);
             *  Logger.Info("Serial port hub started");
             * }*/

            // Enable iBus Manager
            iBus.Manager.Init(iBusPort);
            Logger.Info("iBus manager inited");

            Message sent1 = null, sent2 = null; // light "buffer" for last 2 messages
            bool    isSent1 = false;
            iBus.Manager.BeforeMessageReceived += (e) =>
            {
                LED.Write(Busy(true, 1));
            };
            iBus.Manager.AfterMessageReceived += (e) =>
            {
                LED.Write(Busy(false, 1));

                if (!log)
                {
                    return;
                }

                // Show only messages which are described
                if (e.Message.Describe() == null)
                {
                    return;
                }
                // Filter CDC emulator messages echoed by iBus
                //if (e.Message.SourceDevice == iBus.DeviceAddress.CDChanger) { return; }
                if (e.Message.SourceDevice != DeviceAddress.Radio &&
                    e.Message.DestinationDevice != DeviceAddress.Radio &&
                    e.Message.SourceDevice != DeviceAddress.GraphicsNavigationDriver &&
                    e.Message.SourceDevice != DeviceAddress.Diagnostic && e.Message.DestinationDevice != DeviceAddress.Diagnostic)
                {
                    //return;
                }
                var logIco = "< ";
                if (e.Message.ReceiverDescription == null)
                {
                    if (sent1 != null && sent1.Data.Compare(e.Message.Data))
                    {
                        e.Message.ReceiverDescription = sent1.ReceiverDescription;
                        logIco = "<E";
                    }
                    else if (sent2 != null && sent2.Data.Compare(e.Message.Data))
                    {
                        e.Message.ReceiverDescription = sent2.ReceiverDescription;
                        logIco = "<E";
                    }
                }
                if (settings.LogMessageToASCII)
                {
                    Logger.Info(e.Message.ToPrettyString(true, true), logIco);
                }
                else
                {
                    Logger.Info(e.Message, logIco);
                }

                /*if (e.Message.ReceiverDescription == null)
                 * {
                 *  Logger.Info(ASCIIEncoding.GetString(e.Message.Data));
                 * }*/
                //Logger.Info(e.Message.PacketDump);
            };
            iBus.Manager.BeforeMessageSent += (e) =>
            {
                LED.Write(Busy(true, 2));
            };
            iBus.Manager.AfterMessageSent += (e) =>
            {
                LED.Write(Busy(false, 2));

                if (!log)
                {
                    return;
                }

                Logger.Info(e.Message, " >");
                if (isSent1)
                {
                    sent1 = e.Message;
                }
                else
                {
                    sent2 = e.Message;
                }
                isSent1 = !isSent1;
            };
            Logger.Info("iBus manager events subscribed");

            // Set iPod or Bluetooth as AUX or CDC-emulator for Bordmonitor or Radio
            player = new BluetoothOVC3860(Serial.COM2, sd != null ? sd + @"\contacts.vcf" : null);
            //player = new iPodViaHeadset(Pin.PC2);

            if (settings.MenuMode != Tools.MenuMode.RadioCDC || Manager.FindDevice(DeviceAddress.OnBoardMonitor))
            {
                MediaEmulator emulator;
                if (settings.MenuMode == Tools.MenuMode.BordmonitorCDC)
                {
                    emulator = new CDChanger(player);
                    if (settings.MenuModeMK2)
                    {
                        Bordmonitor.MK2Mode  = true;
                        Localization.Current = new RadioLocalization();
                        SettingsScreen.Instance.CanChangeLanguage = false;
                    }
                }
                else
                {
                    emulator = new BordmonitorAUX(player);
                }
                //MenuScreen.MaxItemsCount = 6;
                BordmonitorMenu.Init(emulator);
                Logger.Info("Bordmonitor menu inited");
            }
            else
            {
                Localization.Current = new RadioLocalization();
                SettingsScreen.Instance.CanChangeLanguage = false;
                MultiFunctionSteeringWheel.EmulatePhone   = true;
                Radio.HasMID = Manager.FindDevice(DeviceAddress.MultiInfoDisplay);
                var menu = RadioMenu.Init(new CDChanger(player));
                menu.TelephoneModeForNavigation = settings.MenuMFLControl;
                Logger.Info("Radio menu inited" + (Radio.HasMID ? " with MID" : ""));
            }

            ShieldLED = new OutputPort(Pin.Di10, false);
            player.IsPlayingChanged += (p, s) =>
            {
                ShieldLED.Write(s);
                RefreshLEDs();
            };
            player.StatusChanged += (p, s, e) =>
            {
                if (e == PlayerEvent.IncomingCall && !p.IsEnabled)
                {
                    InstrumentClusterElectronics.Gong1();
                }
            };
            Logger.Info("Player events subscribed");

            //SampleFeatures.Init();
            //Logger.Info("Sample features inited");

            /*blinkerTimer = new Timer((s) =>
             * {
             *  if (InstrumentClusterElectronics.CurrentIgnitionState == IgnitionState.Off && !blinkerOn)
             *  {
             *      return;
             *  }
             *  blinkerOn = !blinkerOn;
             *  RefreshLEDs();
             * }, null, 0, 3000);*/

            LED.Write(true);
            Thread.Sleep(50);
            LED.Write(false);
            Logger.Info("LED blinked - inited");
        }