/// <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; }
//--// /// <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; } } }