/// <summary>
        /// Takes a PowerState as a suggestion and tries to put the Promi chip
        /// in that state (or in as close a state as possible to that state).
        /// </summary>
        /// <param name="ps">
        /// The suggested PowerState.  Before returning, this variable is assigned
        /// the PowerState that the Promi chip was actually set to.
        /// </param>
        /// <returns>
        /// True if the Promi chip was put in the requested PowerState or the closest
        /// state possible, false if changing the PowerState of the chip was not possible.
        /// </returns>
        /// <remarks>
        /// The Promi SD only supports the Park low-power mode, so Hold and Sniff
        /// are most closely matched by Park.
        /// </remarks>
        public override bool SetPowerState(ref PowerState ps)
        {
            if (m_powerState == ps) return true;

            if (PowerState.Park == m_powerState && (PowerState.Hold == ps || PowerState.Sniff == ps))
            {
                ps = PowerState.Park;
                return true;
            }

            if (CheckState(BTDeviceState.PENDING))
            {
                return false;
            }

            if (ChangeState(BTDeviceState.ONLINE, BTDeviceState.PENDING))
            {   // Then enter or leave Park mode
                try
                {
                    // Make application responsible for explicitly disconnecting before switching power off
                    if (PowerState.Off == ps) throw new InvalidOperationException();

                    // Otherwise temporarily goto standby (try 3 times to go to standby because SD is unreliable)
                    bool inStandby = false;
                    for (int i = 0; i < 3; i++)
                    {
                        Thread.Sleep(50);
                        if (m_ioCtrl.WriteCmd(true, c_OneSecondTimeout, c_ATC_GOTO_STANDBY, null))
                        {
                            inStandby = true;
                            break;
                        }
                    }

                    if (inStandby)
                    {
                        if (PowerState.On == ps)
                        {   // Then un-Park the chip
                            if (m_ioCtrl.WriteCmd(true,
                                                  c_OneSecondTimeout,
                                                  c_ATC_BTLPM,
                                                  new object[] { (byte)'0', c_CR }))
                            {
                                m_powerState = PowerState.On;
                            }
                        }
                        else
                        {   // Then Park the chip
                            if (m_ioCtrl.WriteCmd(true,
                                                  c_OneSecondTimeout,
                                                  c_ATC_BTLPM,
                                                  new object[] { (byte)'1', c_CR }))
                            {
                                m_powerState = PowerState.Park;
                            }
                        }

                        // Now go back online
                        m_ioCtrl.WriteCmd(false, c_OneSecondTimeout, c_ATC_GOTO_ONLINE, null);
                    }
                }
                finally
                {
                    ForceState(BTDeviceState.ONLINE);
                }
            }
            else if (ChangeState(BTDeviceState.OFF, BTDeviceState.PENDING))
            {   // Then switch chip On and possibly Park it
                BTDeviceState finalState = BTDeviceState.OFF;
                try
                {
                    if (SwitchPower(true))
                    {
                        finalState = BTDeviceState.STANDBY;
                        m_powerState = PowerState.On;

                        if (PowerState.On != ps)
                        {
                            if (m_ioCtrl.WriteCmd(true,
                                                  c_OneSecondTimeout,
                                                  c_ATC_BTLPM,
                                                  new object[] { (byte)'1', c_CR }))
                            {
                                m_powerState = PowerState.Park;
                            }
                        }
                    }
                }
                finally
                {
                    ForceState(finalState);
                }
            }
            else if (ChangeState(BTDeviceState.STANDBY, BTDeviceState.PENDING))
            {   // Then switch chip Off, or enter/leave Park mode
                BTDeviceState finalState = BTDeviceState.STANDBY;
                try
                {
                    if (PowerState.Off == ps)
                    {
                        if (SwitchPower(false))
                        {
                            finalState = BTDeviceState.OFF;
                            m_powerState = PowerState.Off;
                        }
                    }
                    else if (PowerState.On == ps)
                    {
                        if (m_ioCtrl.WriteCmd(true,
                                              c_OneSecondTimeout,
                                              c_ATC_BTLPM,
                                              new object[] { (byte)'0', c_CR }))
                        {
                            m_powerState = PowerState.On;
                        }
                    }
                    else
                    {
                        if (m_ioCtrl.WriteCmd(true,
                                              c_OneSecondTimeout,
                                              c_ATC_BTLPM,
                                              new object[] { (byte)'1', c_CR }))
                        {
                            m_powerState = PowerState.Park;
                        }
                    }
                }
                finally
                {
                    ForceState(finalState);
                }
            }
            else
            {   // Throw an exception if the driver has been disposed
                throw new InvalidOperationException();
            }

            ps = m_powerState;

            return true;
        }
Example #2
0
        //--//

        /// <summary>
        /// Takes a PowerState as a suggestion and tries to put the Bluetooth chip
        /// in that state (or in as close a state as possible to that state).
        /// </summary>
        /// <param name="ps">
        /// The suggested PowerState
        /// </param>
        /// <returns>
        /// The PowerState that the Bluetooth chip was actually set to
        /// </returns>
        public virtual bool SetPowerState(ref PowerState ps)
        {
            return true;
        }
        private bool m_disposed;                // Whether or not the driver is disposed

        //--//

        /// <summary>
        /// Creates a new instance of PromiSDBTDriver by initializing
        /// the Serial connection and checking if the SD is present.
        /// </summary>
        /// <param name="comNum">
        /// Number of the COM port to use
        /// </param>
        /// <param name="baudRate">
        /// Baud rate of the COM port to use
        /// </param>
        /// <param name="powerPin">
        /// GPIO to turn the bluetooth power off
        /// </param>
        /// <remarks>
        /// GPIO pin for the N6D should be GPIO22_VTU_TIO3A, if there is no GPIO for power control
        /// then use GPIO_NONE.
        /// </remarks>
        public PromiSDBTDriver(string com, BaudRate baud, Cpu.Pin powerPin)
        {
            bool success = false;

            m_com = com;
            m_baud = baud;

            try
            {
                if (!CreateSerialConnection(m_com, m_baud)) throw new SystemException("Error booting SD");

                m_power = (powerPin == Cpu.Pin.GPIO_NONE) ? null : new OutputPort(powerPin, false);
                m_powerState = PowerState.Off;
                m_state = BTDeviceState.OFF;

                PowerState state = PowerState.On;
                if (!SetPowerState(ref state) || !CheckDevicePresent()) throw new SystemException("Error booting SD");

                success = true;

                UpdateDeviceStatus();

                m_disposed = false;
            }
            finally
            {
                if (!success)
                {
                    if (null != m_power)
                    {
                        m_power.Dispose();
                        m_power = null;
                    }

                    m_disposed = true;
                }
            }
        }