diff --git a/Hardware/Schematic_v1.pdf b/Hardware/Schematic_v1.pdf
new file mode 100644
index 0000000..cbbed4f
Binary files /dev/null and b/Hardware/Schematic_v1.pdf differ
diff --git a/Hardware/Schematic_v2.c.pdf b/Hardware/Schematic_v2.c.pdf
new file mode 100644
index 0000000..acfc7a7
Binary files /dev/null and b/Hardware/Schematic_v2.c.pdf differ
diff --git a/Hardware/Schematic_v3.b.pdf b/Hardware/Schematic_v3.b.pdf
new file mode 100644
index 0000000..56e24ca
Binary files /dev/null and b/Hardware/Schematic_v3.b.pdf differ
diff --git a/Source/Juego.sln b/Source/Juego.sln
index eb02482..26c3c43 100644
--- a/Source/Juego.sln
+++ b/Source/Juego.sln
@@ -39,6 +39,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meadow.Modbus", "..\..\Mead
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet", "..\..\MQTTnet\Source\MQTTnet\MQTTnet.csproj", "{20EC73F2-5F86-40DB-8FEA-4B60BFE3D7EA}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sensors.Motion.Bmi270", "..\..\Meadow.Foundation\Source\Meadow.Foundation.Peripherals\Sensors.Motion.Bmi270\Driver\Sensors.Motion.Bmi270.csproj", "{638A262A-E4F3-4D86-9E34-21717F928D79}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Audio.MicroAudio", "..\..\Meadow.Foundation\Source\Meadow.Foundation.Libraries_and_Frameworks\Audio.MicroAudio\Driver\Audio.MicroAudio.csproj", "{8E8CE3FA-D9D8-4912-A76D-F8017A7AEBC7}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -135,6 +139,18 @@ Global
{20EC73F2-5F86-40DB-8FEA-4B60BFE3D7EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{20EC73F2-5F86-40DB-8FEA-4B60BFE3D7EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{20EC73F2-5F86-40DB-8FEA-4B60BFE3D7EA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {638A262A-E4F3-4D86-9E34-21717F928D79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {638A262A-E4F3-4D86-9E34-21717F928D79}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {638A262A-E4F3-4D86-9E34-21717F928D79}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {638A262A-E4F3-4D86-9E34-21717F928D79}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {638A262A-E4F3-4D86-9E34-21717F928D79}.Release|Any CPU.Build.0 = Release|Any CPU
+ {638A262A-E4F3-4D86-9E34-21717F928D79}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {8E8CE3FA-D9D8-4912-A76D-F8017A7AEBC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8E8CE3FA-D9D8-4912-A76D-F8017A7AEBC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8E8CE3FA-D9D8-4912-A76D-F8017A7AEBC7}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {8E8CE3FA-D9D8-4912-A76D-F8017A7AEBC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8E8CE3FA-D9D8-4912-A76D-F8017A7AEBC7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8E8CE3FA-D9D8-4912-A76D-F8017A7AEBC7}.Release|Any CPU.Deploy.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -154,6 +170,8 @@ Global
{7D611BC9-B5BF-424C-A03C-3FC7FA8E703A} = {FF570CB7-3F54-4049-A167-304A90098DB6}
{D1FD4798-703D-4199-940C-4EDC516E88FC} = {FF570CB7-3F54-4049-A167-304A90098DB6}
{20EC73F2-5F86-40DB-8FEA-4B60BFE3D7EA} = {FF570CB7-3F54-4049-A167-304A90098DB6}
+ {638A262A-E4F3-4D86-9E34-21717F928D79} = {FF570CB7-3F54-4049-A167-304A90098DB6}
+ {8E8CE3FA-D9D8-4912-A76D-F8017A7AEBC7} = {FF570CB7-3F54-4049-A167-304A90098DB6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {CB582CC6-C626-484E-9742-43FD65FE8158}
diff --git a/Source/Juego/IJuegoHardware.cs b/Source/Juego/IJuegoHardware.cs
index 5edf1fd..b3c0d39 100644
--- a/Source/Juego/IJuegoHardware.cs
+++ b/Source/Juego/IJuegoHardware.cs
@@ -1,18 +1,19 @@
using Meadow.Foundation.Audio;
using Meadow.Foundation.Graphics;
using Meadow.Foundation.Leds;
+using Meadow.Foundation.Sensors.Accelerometers;
using Meadow.Foundation.Sensors.Buttons;
using Meadow.Hardware;
namespace WildernessLabs.Hardware.Juego
{
///
- /// Represents the hardware interface for the Juego device.
+ /// Represents the hardware interface for the Juego device
///
public interface IJuegoHardware
{
///
- /// Gets the graphics display interface.
+ /// Gets the graphics display interface
///
public IGraphicsDisplay? Display { get; }
@@ -74,9 +75,19 @@ public interface IJuegoHardware
///
public PwmLed? BlinkyLed { get; }
+ ///
+ /// Gets the motion sensor
+ ///
+ public Bmi270? MotionSensor { get; }
+
///
/// Gets the display header connector
///
public DisplayConnector DisplayHeader { get; }
+
+ ///
+ /// Gets the Stemma QT I2C Qwiic connector
+ ///
+ public I2cConnector? Qwiic { get; }
}
}
\ No newline at end of file
diff --git a/Source/Juego/Juego.cs b/Source/Juego/Juego.cs
index 82157c8..f8687e9 100644
--- a/Source/Juego/Juego.cs
+++ b/Source/Juego/Juego.cs
@@ -1,19 +1,24 @@
using Meadow;
+using Meadow.Foundation.Audio;
+using Meadow.Foundation.ICs.IOExpanders;
using Meadow.Logging;
using System;
namespace WildernessLabs.Hardware.Juego
{
+ ///
+ /// Juego hardware factory class for Juego v1, v2, and v3 hardware
+ ///
public class Juego
{
private Juego() { }
///
- /// Create an instance of the Juego class
+ /// Create an instance of the Juego class for the current hardware
///
- public static IJuegoHardware Create()
+ public static IJuegoHardware? Create()
{
- IJuegoHardware hardware;
+ IJuegoHardware? hardware;
Logger? logger = Resolver.Log;
logger?.Debug("Initializing Juego...");
@@ -35,8 +40,48 @@ public static IJuegoHardware Create()
}
else if (device is IF7CoreComputeMeadowDevice { } ccm)
{
- logger?.Info("Instantiating Juego v2 hardware");
- hardware = new JuegoHardwareV2(ccm);
+ try
+ {
+ // hack for PWM init bug .... move back into the hardware classes once it's fixed
+ var leftSpeaker = new PiezoSpeaker(ccm.Pins.PB8);
+ var rightSpeaker = new PiezoSpeaker(ccm.Pins.PB9);
+
+ var i2cBus = ccm.CreateI2cBus(busSpeed: Meadow.Hardware.I2cBusSpeed.FastPlus);
+ logger?.Info("I2C Bus instantiated");
+
+ var mcpVersion = new Mcp23008(i2cBus, address: 0x23);
+
+ logger?.Trace("McpVersion up");
+ var version = mcpVersion.ReadFromPorts();
+
+ logger?.Info($"Hardware version is {version}");
+
+ if (version >= JuegoHardwareV3.MinimumHardareVersion)
+ {
+ logger?.Info("Instantiating Juego v3 hardware");
+ hardware = new JuegoHardwareV3(ccm, i2cBus)
+ {
+ Mcp_VersionInfo = mcpVersion,
+ LeftSpeaker = leftSpeaker,
+ RightSpeaker = rightSpeaker,
+ };
+ }
+ else
+ {
+ logger?.Info("Instantiating Juego v2 hardware");
+ hardware = new JuegoHardwareV2(ccm, i2cBus)
+ {
+ Mcp_VersionInfo = mcpVersion,
+ LeftSpeaker = leftSpeaker,
+ RightSpeaker = rightSpeaker,
+ };
+ }
+ }
+ catch (Exception e)
+ {
+ logger?.Debug($"Failed to create McpVersion: {e.Message}");
+ hardware = null;
+ }
}
else
{
diff --git a/Source/Juego/Juego.csproj b/Source/Juego/Juego.csproj
index 50bf2ef..7118bff 100644
--- a/Source/Juego/Juego.csproj
+++ b/Source/Juego/Juego.csproj
@@ -25,7 +25,9 @@
+
+
diff --git a/Source/Juego/JuegoHardwareV1.cs b/Source/Juego/JuegoHardwareV1.cs
index 4d2be9d..6f32413 100644
--- a/Source/Juego/JuegoHardwareV1.cs
+++ b/Source/Juego/JuegoHardwareV1.cs
@@ -3,6 +3,7 @@
using Meadow.Foundation.Displays;
using Meadow.Foundation.Graphics;
using Meadow.Foundation.Leds;
+using Meadow.Foundation.Sensors.Accelerometers;
using Meadow.Foundation.Sensors.Buttons;
using Meadow.Foundation.Sensors.Hid;
using Meadow.Hardware;
@@ -11,39 +12,60 @@
namespace WildernessLabs.Hardware.Juego
{
+ ///
+ /// Represents the hardware interface for the Juego v1 device
+ ///
public class JuegoHardwareV1 : IJuegoHardware
{
+ ///
protected IF7FeatherMeadowDevice Device { get; }
+ ///
public IGraphicsDisplay Display { get; }
+ ///
protected ISpiBus SpiBus { get; }
+ ///
public AnalogJoystick? AnalogJoystick { get; protected set; }
+ ///
public PushButton? Right_UpButton { get; protected set; }
+ ///
public PushButton? Right_DownButton { get; protected set; }
+ ///
public PushButton? Right_LeftButton { get; protected set; }
+ ///
public PushButton? Right_RightButton { get; protected set; }
-
+ ///
public PushButton? Left_UpButton => null;
+ ///
public PushButton? Left_DownButton => null;
+ ///
public PushButton? Left_LeftButton => null;
+ ///
public PushButton? Left_RightButton => null;
-
+ ///
public PushButton? StartButton { get; protected set; }
+ ///
public PushButton? SelectButton { get; protected set; }
-
+ ///
public PiezoSpeaker? LeftSpeaker { get; protected set; }
+ ///
public PiezoSpeaker? RightSpeaker { get; protected set; }
-
+ ///
public PwmLed? BlinkyLed => null;
- ///
- /// Gets the display header connector on the Juego board
- ///
+ ///
+ public Bmi270? MotionSensor => null;
+
+ ///
public DisplayConnector DisplayHeader => (DisplayConnector)Connectors[0];
+ ///
+ public I2cConnector Qwiic => null;
+
+
///
/// Collection of connectors on the Juego board
///
@@ -54,7 +76,7 @@ public IConnector?[] Connectors
if (_connectors == null)
{
_connectors = new IConnector[1];
- _connectors[1] = CreateDisplayConnector();
+ _connectors[0] = CreateDisplayConnector();
}
return _connectors;
@@ -63,6 +85,9 @@ public IConnector?[] Connectors
private IConnector?[]? _connectors;
+ ///
+ /// Create a new Juego hardware v1 object
+ ///
public JuegoHardwareV1(IF7FeatherMeadowDevice device)
{
Device = device;
diff --git a/Source/Juego/JuegoHardwareV2.cs b/Source/Juego/JuegoHardwareV2.cs
index 887d5d7..ca2dd8d 100644
--- a/Source/Juego/JuegoHardwareV2.cs
+++ b/Source/Juego/JuegoHardwareV2.cs
@@ -4,61 +4,78 @@
using Meadow.Foundation.Graphics;
using Meadow.Foundation.ICs.IOExpanders;
using Meadow.Foundation.Leds;
+using Meadow.Foundation.Sensors.Accelerometers;
using Meadow.Foundation.Sensors.Buttons;
using Meadow.Hardware;
-using Meadow.Logging;
using Meadow.Units;
using System;
using System.Threading;
namespace WildernessLabs.Hardware.Juego
{
+ ///
+ /// Represents the hardware interface for the Juego v2 device
+ ///
public class JuegoHardwareV2 : IJuegoHardware
{
+ ///
protected IF7CoreComputeMeadowDevice Device { get; }
+ ///
protected IDigitalInterruptPort McpInterrupt_1 { get; }
-
+ ///
protected IDigitalInterruptPort McpInterrupt_2 { get; }
-
+ ///
protected IDigitalOutputPort Mcp_Reset { get; }
-
+ ///
public IGraphicsDisplay Display { get; }
-
+ ///
public IDigitalOutputPort DisplayBacklightPort { get; }
-
+ ///
protected II2cBus I2cBus { get; }
+ ///
protected ISpiBus SpiBus { get; }
-
+ ///
public Mcp23008 Mcp_1 { get; protected set; }
+ ///
public Mcp23008 Mcp_2 { get; protected set; }
- public Mcp23008 Mcp_VersionInfo { get; protected set; }
-
+ ///
+ public Mcp23008 Mcp_VersionInfo { get; set; }
+ ///
public PushButton? Right_UpButton { get; protected set; }
+ ///
public PushButton? Right_DownButton { get; protected set; }
+ ///
public PushButton? Right_LeftButton { get; protected set; }
+ ///
public PushButton? Right_RightButton { get; protected set; }
-
+ ///
public PushButton? Left_UpButton { get; protected set; }
+ ///
public PushButton? Left_DownButton { get; protected set; }
+ ///
public PushButton? Left_LeftButton { get; protected set; }
+ ///
public PushButton? Left_RightButton { get; protected set; }
-
+ ///
public PushButton? StartButton { get; protected set; }
+ ///
public PushButton? SelectButton { get; protected set; }
-
- public PiezoSpeaker? LeftSpeaker { get; protected set; }
- public PiezoSpeaker? RightSpeaker { get; protected set; }
-
+ ///
+ public PiezoSpeaker? LeftSpeaker { get; set; }
+ ///
+ public PiezoSpeaker? RightSpeaker { get; set; }
+ ///
public PwmLed? BlinkyLed { get; protected set; }
+ ///
+ public Bmi270? MotionSensor => null;
- ///
- /// Gets the display header connector on the Juego board
- ///
+ ///
public DisplayConnector DisplayHeader => (DisplayConnector)Connectors[0];
- ///
- /// Collection of connectors on the Juego board
- ///
+ ///
+ public I2cConnector? Qwiic => null;
+
+ ///
public IConnector?[] Connectors
{
get
@@ -66,7 +83,7 @@ public IConnector?[] Connectors
if (_connectors == null)
{
_connectors = new IConnector[1];
- _connectors[1] = CreateDisplayConnector();
+ _connectors[0] = CreateDisplayConnector();
}
return _connectors;
@@ -75,40 +92,34 @@ public IConnector?[] Connectors
private IConnector?[]? _connectors;
- public JuegoHardwareV2(IF7CoreComputeMeadowDevice device)
+ ///
+ /// Create a new Juego hardware v2 object
+ ///
+ public JuegoHardwareV2(IF7CoreComputeMeadowDevice device, II2cBus i2cBus)
{
Device = device;
+ I2cBus = i2cBus;
Resolver.Log.Info("Initialize hardware...");
// DEV NOTE: **ALWAYS** Set up PWMs first - Nuttx PWM driver will step on pin configs otherwise
- try
- {
- LeftSpeaker = new PiezoSpeaker(device.Pins.PB8); //D03
- }
- catch (Exception e)
- {
- Resolver.Log.Error($"Err Left Speaker: {e.Message}");
- }
-
- try
- {
- RightSpeaker = new PiezoSpeaker(device.Pins.PB9); //D04
- }
- catch (Exception e)
- {
- Resolver.Log.Error($"Err Right Speaker: {e.Message}");
- }
-
- try
- {
- I2cBus = Device.CreateI2cBus(busSpeed: I2cBusSpeed.FastPlus);
- Resolver.Log.Info("I2C initialized");
- }
- catch (Exception e)
- {
- Resolver.Log.Error($"Err initializing I2C Bus: {e.Message}");
- }
+ /* try - code left intentionally, restore once the PWM bug is fixed
+ {
+ LeftSpeaker = new PiezoSpeaker(device.Pins.PB8); //D03
+ }
+ catch (Exception e)
+ {
+ Resolver.Log.Error($"Err Left Speaker: {e.Message}");
+ }
+
+ try
+ {
+ RightSpeaker = new PiezoSpeaker(device.Pins.PB9); //D04
+ }
+ catch (Exception e)
+ {
+ Resolver.Log.Error($"Err Right Speaker: {e.Message}");
+ } */
try
{
@@ -133,16 +144,6 @@ public JuegoHardwareV2(IF7CoreComputeMeadowDevice device)
Resolver.Log.Error($"Err MCP 2: {e.Message}");
}
- try
- {
- Mcp_VersionInfo = new Mcp23008(I2cBus, 0x23);
- Resolver.Log.Info("Mcp23008 version initialized");
- }
- catch (Exception e)
- {
- Resolver.Log.Error($"Err MCP 3: {e.Message}");
- }
-
try
{
BlinkyLed = new PwmLed(device.Pins.D20, TypicalForwardVoltage.Green);
diff --git a/Source/Juego/JuegoHardwareV3.cs b/Source/Juego/JuegoHardwareV3.cs
new file mode 100644
index 0000000..cbae9f7
--- /dev/null
+++ b/Source/Juego/JuegoHardwareV3.cs
@@ -0,0 +1,284 @@
+using Meadow;
+using Meadow.Foundation.Audio;
+using Meadow.Foundation.Displays;
+using Meadow.Foundation.Graphics;
+using Meadow.Foundation.ICs.IOExpanders;
+using Meadow.Foundation.Leds;
+using Meadow.Foundation.Sensors.Accelerometers;
+using Meadow.Foundation.Sensors.Buttons;
+using Meadow.Hardware;
+using Meadow.Units;
+using System;
+using System.Threading;
+
+namespace WildernessLabs.Hardware.Juego
+{
+ ///
+ /// Represents the hardware interface for the Juego v1 device
+ ///
+ public class JuegoHardwareV3 : IJuegoHardware
+ {
+ ///
+ /// The minimum hardware version for Juego v3 hardware
+ ///
+ public static int MinimumHardareVersion => 3;
+
+ ///
+ protected IF7CoreComputeMeadowDevice Device { get; }
+ ///
+ protected IDigitalInterruptPort McpInterrupt_1 { get; }
+ ///
+ protected IDigitalInterruptPort McpInterrupt_2 { get; }
+ ///
+ protected IDigitalOutputPort Mcp_Reset { get; }
+ ///
+ public IGraphicsDisplay Display { get; }
+ ///
+ public IDigitalOutputPort DisplayBacklightPort { get; }
+ ///
+ protected II2cBus I2cBus { get; }
+ ///
+ protected ISpiBus SpiBus { get; }
+ ///
+ public Mcp23008 Mcp_1 { get; protected set; }
+ ///
+ public Mcp23008 Mcp_2 { get; protected set; }
+ ///
+ public Mcp23008 Mcp_VersionInfo { get; set; }
+ ///
+ public PushButton? Right_UpButton { get; protected set; }
+ ///
+ public PushButton? Right_DownButton { get; protected set; }
+ ///
+ public PushButton? Right_LeftButton { get; protected set; }
+ ///
+ public PushButton? Right_RightButton { get; protected set; }
+ ///
+ public PushButton? Left_UpButton { get; protected set; }
+ ///
+ public PushButton? Left_DownButton { get; protected set; }
+ ///
+ public PushButton? Left_LeftButton { get; protected set; }
+ ///
+ public PushButton? Left_RightButton { get; protected set; }
+ ///
+ public PushButton? StartButton { get; protected set; }
+ ///
+ public PushButton? SelectButton { get; protected set; }
+ ///
+ public PiezoSpeaker? LeftSpeaker { get; set; }
+ ///
+ public PiezoSpeaker? RightSpeaker { get; set; }
+ ///
+ public PwmLed? BlinkyLed { get; protected set; }
+ ///
+ public Bmi270? MotionSensor { get; protected set; }
+
+ ///
+ public DisplayConnector DisplayHeader => (DisplayConnector)Connectors[0];
+
+ ///
+ public I2cConnector? Qwiic => (I2cConnector)Connectors[1];
+
+ ///
+ /// Collection of connectors on the Juego board
+ ///
+ public IConnector?[] Connectors
+ {
+ get
+ {
+ if (_connectors == null)
+ {
+ _connectors = new IConnector[2];
+ _connectors[0] = CreateDisplayConnector();
+ _connectors[1] = CreateQwiicConnector();
+ }
+
+ return _connectors;
+ }
+ }
+
+ private IConnector?[]? _connectors;
+
+ ///
+ /// Create a new Juego hardware v3 object
+ ///
+ public JuegoHardwareV3(IF7CoreComputeMeadowDevice device, II2cBus i2cBus)
+ {
+ Device = device;
+ I2cBus = i2cBus;
+
+ Resolver.Log.Info("Initialize hardware...");
+
+ // DEV NOTE: **ALWAYS** Set up PWMs first - Nuttx PWM driver will step on pin configs otherwise
+ /* try // code left intentionally, restore once the PWM bug is fixed
+ {
+ LeftSpeaker = new PiezoSpeaker(device.Pins.PB8); //D03
+ }
+ catch (Exception e)
+ {
+ Resolver.Log.Error($"Err Left Speaker: {e.Message}");
+ }
+
+ try
+ {
+ RightSpeaker = new PiezoSpeaker(device.Pins.PB9); //D04
+ }
+ catch (Exception e)
+ {
+ Resolver.Log.Error($"Err Right Speaker: {e.Message}");
+ } */
+
+ /*
+ try
+ {
+ I2cBus = Device.CreateI2cBus(busSpeed: I2cBusSpeed.FastPlus);
+ Resolver.Log.Info("I2C initialized");
+ }
+ catch (Exception e)
+ {
+ Resolver.Log.Error($"Err initializing I2C Bus: {e.Message}");
+ }
+ */
+
+ try
+ {
+ Mcp_Reset = Device.CreateDigitalOutputPort(Device.Pins.PA10, true);
+ McpInterrupt_1 = Device.CreateDigitalInterruptPort(Device.Pins.PD5, InterruptMode.EdgeRising);
+ Mcp_1 = new Mcp23008(I2cBus, 0x20, McpInterrupt_1, Mcp_Reset);
+ Resolver.Log.Info("Mcp23008 #1 initialized");
+ }
+ catch (Exception e)
+ {
+ Resolver.Log.Error($"Err MCP 1: {e.Message}");
+ }
+
+ try
+ {
+ McpInterrupt_2 = Device.CreateDigitalInterruptPort(Device.Pins.PI11, InterruptMode.EdgeRising);
+ Mcp_2 = new Mcp23008(I2cBus, 0x21, McpInterrupt_2);
+ Resolver.Log.Info("Mcp23008 #2 initialized");
+ }
+ catch (Exception e)
+ {
+ Resolver.Log.Error($"Err MCP 2: {e.Message}");
+ }
+
+ try
+ {
+ BlinkyLed = new PwmLed(device.Pins.D20, TypicalForwardVoltage.Green);
+ }
+ catch (Exception e)
+ {
+ Resolver.Log.Error($"Err BlinkyLed: {e.Message}");
+ }
+
+ try
+ {
+ var config = new SpiClockConfiguration(new Frequency(48000, Frequency.UnitType.Kilohertz), SpiClockConfiguration.Mode.Mode0);
+ SpiBus = Device.CreateSpiBus(Device.Pins.SPI5_SCK, Device.Pins.SPI5_COPI, Device.Pins.SPI5_CIPO, config);
+ }
+ catch (Exception e)
+ {
+ Resolver.Log.Error($"Err initializing SPI: {e.Message}");
+ }
+ Resolver.Log.Info("SPI initialized");
+
+ if (Mcp_1 != null)
+ {
+ DisplayBacklightPort = Device.CreateDigitalOutputPort(Device.Pins.D05, true);
+
+ var chipSelectPort = Mcp_1.CreateDigitalOutputPort(Mcp_1.Pins.GP5);
+ var dcPort = Mcp_1.CreateDigitalOutputPort(Mcp_1.Pins.GP6);
+ var resetPort = Mcp_1.CreateDigitalOutputPort(Mcp_1.Pins.GP7);
+
+ Thread.Sleep(50);
+
+ Display = new Ili9341(
+ spiBus: SpiBus,
+ chipSelectPort: chipSelectPort,
+ dataCommandPort: dcPort,
+ resetPort: resetPort,
+ width: 240, height: 320)
+ {
+ SpiBusSpeed = new Frequency(48000, Frequency.UnitType.Kilohertz),
+ };
+
+ ((Ili9341)Display).SetRotation(RotationType._270Degrees);
+
+ Resolver.Log.Info("Display initialized");
+ }
+
+ try
+ {
+ Resolver.Log.Info("Instantiating motion sensor");
+ MotionSensor = new Bmi270(I2cBus);
+ Resolver.Log.Info("Motion sensor up");
+ }
+ catch (Exception ex)
+ {
+ Resolver.Log.Error($"Unable to create the BMI270 IMU: {ex.Message}");
+ }
+
+ if (Mcp_1 != null)
+ {
+ var upPort = Mcp_1.Pins.GP1.CreateDigitalInterruptPort(InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
+ var rightPort = Mcp_1.CreateDigitalInterruptPort(Mcp_1.Pins.GP2, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
+ var downPort = Mcp_1.CreateDigitalInterruptPort(Mcp_1.Pins.GP3, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
+ var leftPort = Mcp_1.CreateDigitalInterruptPort(Mcp_1.Pins.GP4, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
+
+ Left_UpButton = new PushButton(upPort);
+ Left_RightButton = new PushButton(rightPort);
+ Left_DownButton = new PushButton(downPort);
+ Left_LeftButton = new PushButton(leftPort);
+ }
+
+ if (Mcp_2 != null)
+ {
+ var upPort = Mcp_2.CreateDigitalInterruptPort(Mcp_2.Pins.GP5, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
+ var rightPort = Mcp_2.CreateDigitalInterruptPort(Mcp_2.Pins.GP4, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
+ var downPort = Mcp_2.CreateDigitalInterruptPort(Mcp_2.Pins.GP3, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
+ var leftPort = Mcp_2.CreateDigitalInterruptPort(Mcp_2.Pins.GP2, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
+ var startPort = Mcp_2.CreateDigitalInterruptPort(Mcp_2.Pins.GP1, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
+ var selectPort = Mcp_2.CreateDigitalInterruptPort(Mcp_2.Pins.GP0, InterruptMode.EdgeBoth, ResistorMode.InternalPullUp);
+
+ Right_UpButton = new PushButton(upPort);
+ Right_RightButton = new PushButton(rightPort);
+ Right_DownButton = new PushButton(downPort);
+ Right_LeftButton = new PushButton(leftPort);
+ StartButton = new PushButton(startPort);
+ SelectButton = new PushButton(selectPort);
+ }
+ }
+
+ internal DisplayConnector CreateDisplayConnector()
+ {
+ Resolver.Log.Trace("Creating display connector");
+
+ return new DisplayConnector(
+ "Display",
+ new PinMapping
+ {
+ new PinMapping.PinAlias(DisplayConnector.PinNames.CS, Mcp_1.Pins.GP5),
+ new PinMapping.PinAlias(DisplayConnector.PinNames.RST, Mcp_1.Pins.GP7),
+ new PinMapping.PinAlias(DisplayConnector.PinNames.DC, Mcp_1.Pins.GP6),
+ new PinMapping.PinAlias(DisplayConnector.PinNames.CLK, Device.Pins.SCK),
+ new PinMapping.PinAlias(DisplayConnector.PinNames.COPI, Device.Pins.COPI),
+ });
+ }
+
+ internal I2cConnector CreateQwiicConnector()
+ {
+ Resolver.Log.Trace("Creating Qwiic I2C connector");
+
+ return new I2cConnector(
+ "Qwiic",
+ new PinMapping
+ {
+ new PinMapping.PinAlias(I2cConnector.PinNames.SCL, Device.Pins.D08),
+ new PinMapping.PinAlias(I2cConnector.PinNames.SDA, Device.Pins.D07),
+ },
+ new I2cBusMapping(Device, 1));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Juego_Demo/DisplayController.cs b/Source/Juego_Demo/DisplayController.cs
index b7eccd1..2a32630 100644
--- a/Source/Juego_Demo/DisplayController.cs
+++ b/Source/Juego_Demo/DisplayController.cs
@@ -1,6 +1,6 @@
-using Meadow;
-using Meadow.Foundation;
+using Meadow.Foundation;
using Meadow.Foundation.Graphics;
+using Meadow.Units;
namespace Juego_Demo
{
@@ -8,6 +8,17 @@ public class DisplayController
{
readonly MicroGraphics graphics;
+ public Acceleration3D? Acceleration3D
+ {
+ get => acceleration3D;
+ set
+ {
+ acceleration3D = value;
+ Update();
+ }
+ }
+ Acceleration3D? acceleration3D = null;
+
public bool Right_UpButtonState
{
get => right_upButtonState;
@@ -123,13 +134,11 @@ public bool SelectButtonState
public DisplayController(IGraphicsDisplay display)
{
- Resolver.Log.Info("Display controller ctor");
-
graphics = new MicroGraphics(display)
{
Rotation = RotationType._270Degrees,
IgnoreOutOfBoundsPixels = true,
- CurrentFont = new Font12x16()
+ CurrentFont = new Font12x20()
};
graphics.Clear(Color.YellowGreen);
@@ -161,35 +170,36 @@ public void Update()
}
}
- void DrawStatus(string label, string value, Color color, int yPosition)
- {
- graphics.DrawText(x: 2, y: yPosition, label, color: color);
- graphics.DrawText(x: 318, y: yPosition, value, alignmentH: HorizontalAlignment.Right, color: color);
- }
- void DrawDivider(Color color, int yPosition)
- {
- graphics.DrawLine(0, yPosition, graphics.Width, yPosition, color);
- }
void Draw()
{
- graphics.DrawText(x: 2, y: 0, "Hello Juego!", WildernessLabsColors.AzureBlue);
-
- DrawStatus("Up D-pad:", $"{(Left_UpButtonState ? "pressed" : "released")}", WildernessLabsColors.ChileanFire, 20);
- DrawStatus("Down D-pad:", $"{(Left_DownButtonState ? "pressed" : "released")}", WildernessLabsColors.ChileanFire, 40);
- DrawStatus("Left D-pad:", $"{(Left_LeftButtonState ? "pressed" : "released")}", WildernessLabsColors.ChileanFire, 60);
- DrawStatus("Right D-pad:", $"{(Left_RightButtonState ? "pressed" : "released")}", WildernessLabsColors.ChileanFire, 80);
- DrawDivider(WildernessLabsColors.AzureBlue, 98);
-
- DrawStatus("Up button:", $"{(Right_UpButtonState ? "pressed" : "released")}", WildernessLabsColors.ChileanFire, 100);
- DrawStatus("Down button:", $"{(Right_DownButtonState ? "pressed" : "released")}", WildernessLabsColors.ChileanFire, 120);
- DrawStatus("Left button:", $"{(Right_LeftButtonState ? "pressed" : "released")}", WildernessLabsColors.ChileanFire, 140);
- DrawStatus("Right button:", $"{(Right_RightButtonState ? "pressed" : "released")}", WildernessLabsColors.ChileanFire, 160);
- DrawDivider(WildernessLabsColors.AzureBlue, 178);
-
- DrawStatus("Select button:", $"{(SelectButtonState ? "pressed" : "released")}", WildernessLabsColors.ChileanFire, 180);
- DrawStatus("Start button:", $"{(StartButtonState ? "pressed" : "released")}", WildernessLabsColors.ChileanFire, 200);
+ graphics.DrawText(x: graphics.Width / 2, y: 0, "Hello Juego!", WildernessLabsColors.AzureBlue, alignmentH: HorizontalAlignment.Center);
+
+ //D-Pad
+ graphics.DrawRectangle(5, 100, 30, 30, WildernessLabsColors.DustyGray, Left_LeftButtonState);
+ graphics.DrawRectangle(65, 100, 30, 30, WildernessLabsColors.DustyGray, Left_RightButtonState);
+ graphics.DrawRectangle(35, 70, 30, 30, WildernessLabsColors.DustyGray, Left_UpButtonState);
+ graphics.DrawRectangle(35, 130, 30, 30, WildernessLabsColors.DustyGray, Left_DownButtonState);
+ graphics.DrawCircle(50, 115, 7, WildernessLabsColors.DustyGray, true);
+
+ //Start and Select
+ graphics.DrawRoundedRectangle(graphics.Width / 2 - 35, 140, 30, 15, 4, WildernessLabsColors.ChileanFire, SelectButtonState);
+ graphics.DrawRoundedRectangle(graphics.Width / 2 + 5, 140, 30, 15, 4, WildernessLabsColors.ChileanFire, StartButtonState);
+
+ //Buttons
+ graphics.DrawCircle(graphics.Width - 90, 115, 15, WildernessLabsColors.PearGreen, Right_LeftButtonState);
+ graphics.DrawCircle(graphics.Width - 20, 115, 15, WildernessLabsColors.PearGreen, Right_RightButtonState);
+ graphics.DrawCircle(graphics.Width - 55, 80, 15, WildernessLabsColors.PearGreen, Right_UpButtonState);
+ graphics.DrawCircle(graphics.Width - 55, 150, 15, WildernessLabsColors.PearGreen, Right_DownButtonState);
+
+ //Motion
+ if (acceleration3D is { } accel)
+ {
+ graphics.DrawCircle(graphics.Width / 2, 200, 30, WildernessLabsColors.AzureBlue, false);
+ //radius is 30 .... new circle is 10 ... scale position via x & y
+ graphics.DrawCircle(graphics.Width / 2 + (int)(accel.X.Gravity * 20), 200 + (int)(accel.Y.Gravity * -20), 10, WildernessLabsColors.AzureBlue, true);
+ }
}
}
}
\ No newline at end of file
diff --git a/Source/Juego_Demo/MeadowApp.cs b/Source/Juego_Demo/MeadowApp.cs
index 782cdd5..65b5bd6 100644
--- a/Source/Juego_Demo/MeadowApp.cs
+++ b/Source/Juego_Demo/MeadowApp.cs
@@ -1,5 +1,6 @@
using Meadow;
using Meadow.Devices;
+using Meadow.Foundation.Audio;
using Meadow.Units;
using System;
using System.Threading.Tasks;
@@ -7,96 +8,110 @@
namespace Juego_Demo
{
- // Change F7FeatherV2 to F7FeatherV1 for V1.x boards
public class MeadowApp : App
{
- private IJuegoHardware hardware;
+ private IJuegoHardware juego;
private DisplayController displayController;
+ private MicroAudio audioLeft, audioRight;
public override Task Initialize()
{
Resolver.Log.Info("Initialize");
- hardware = Juego.Create();
+ juego = Juego.Create();
- if (hardware.Display is { } display)
+ if (juego.Display is { } display)
{
displayController = new DisplayController(display);
}
- if (hardware.Left_LeftButton is { } leftDpad)
+ //---- BMI270 Accel/IMU
+ if (juego.MotionSensor is { } bmi270)
+ {
+ Resolver.Log.Info("Found BMI270");
+ bmi270.Updated += Bmi270Updated;
+ }
+
+ if (juego.Left_LeftButton is { } leftDpad)
{
leftDpad.PressStarted += (s, e) => displayController.Left_LeftButtonState = true;
leftDpad.PressEnded += (s, e) => displayController.Left_LeftButtonState = false;
}
- if (hardware.Left_RightButton is { } rightDpad)
+ if (juego.Left_RightButton is { } rightDpad)
{
rightDpad.PressStarted += (s, e) => displayController.Left_RightButtonState = true;
rightDpad.PressEnded += (s, e) => displayController.Left_RightButtonState = false;
}
- if (hardware.Left_UpButton is { } upDpad)
+ if (juego.Left_UpButton is { } upDpad)
{
upDpad.PressStarted += (s, e) => displayController.Left_UpButtonState = true;
upDpad.PressEnded += (s, e) => displayController.Left_UpButtonState = false;
}
- if (hardware.Left_DownButton is { } downDpad)
+ if (juego.Left_DownButton is { } downDpad)
{
downDpad.PressStarted += (s, e) => displayController.Left_DownButtonState = true;
downDpad.PressEnded += (s, e) => displayController.Left_DownButtonState = false;
}
- if (hardware.Right_LeftButton is { } leftButton)
+ if (juego.Right_LeftButton is { } leftButton)
{
leftButton.PressStarted += (s, e) => displayController.Right_LeftButtonState = true;
leftButton.PressEnded += (s, e) => displayController.Right_LeftButtonState = false;
}
- if (hardware.Right_RightButton is { } rightButton)
+ if (juego.Right_RightButton is { } rightButton)
{
rightButton.PressStarted += (s, e) => displayController.Right_RightButtonState = true;
rightButton.PressEnded += (s, e) => displayController.Right_RightButtonState = false;
}
- if (hardware.Right_UpButton is { } upButton)
+ if (juego.Right_UpButton is { } upButton)
{
upButton.PressStarted += (s, e) => displayController.Right_UpButtonState = true;
upButton.PressEnded += (s, e) => displayController.Right_UpButtonState = false;
}
- if (hardware.Right_DownButton is { } downButton)
+ if (juego.Right_DownButton is { } downButton)
{
downButton.PressStarted += (s, e) => displayController.Right_DownButtonState = true;
downButton.PressEnded += (s, e) => displayController.Right_DownButtonState = false;
}
- if (hardware.SelectButton is { } selectButton)
+ if (juego.SelectButton is { } selectButton)
{
selectButton.PressStarted += (s, e) => displayController.SelectButtonState = true;
selectButton.PressEnded += (s, e) => displayController.SelectButtonState = false;
}
- if (hardware.StartButton is { } startButton)
+ if (juego.StartButton is { } startButton)
{
startButton.PressStarted += (s, e) => displayController.StartButtonState = true;
startButton.PressEnded += (s, e) => displayController.StartButtonState = false;
}
- return base.Initialize();
+ audioLeft = new MicroAudio(juego.LeftSpeaker);
+ audioRight = new MicroAudio(juego.RightSpeaker);
+
+ return Task.CompletedTask;
}
public async override Task Run()
{
Resolver.Log.Info("Run...");
- if (displayController != null)
- {
- displayController.Update();
- }
+ displayController?.Update();
+ juego.MotionSensor?.StartUpdating(TimeSpan.FromMilliseconds(250));
- for (int i = 0; i < 5; i++)
- {
- Resolver.Log.Info("Playing tone");
- await hardware.LeftSpeaker.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(500));
- await hardware.RightSpeaker.PlayTone(new Frequency(540), TimeSpan.FromMilliseconds(500));
- }
+ await audioLeft.PlaySystemSound(SystemSoundEffect.PowerUp);
+ await audioRight.PlayGameSound(GameSoundEffect.LevelComplete);
return;
}
+
+ private void Bmi270Updated(object sender, IChangeResult<(Acceleration3D? Acceleration3D, AngularVelocity3D? AngularVelocity3D, Temperature? Temperature)> e)
+ {
+ Resolver.Log.Info($"BMI270: X:{e.New.Acceleration3D.Value.X.Gravity:0.0}g, Y:{e.New.Acceleration3D.Value.Y.Gravity:0.0}g, Z:{e.New.Acceleration3D.Value.Z.Gravity:0.0}g");
+
+ if (displayController != null)
+ {
+ displayController.Acceleration3D = e.New.Acceleration3D;
+ }
+ }
}
}
\ No newline at end of file