├── .gitignore ├── Firmware ├── Arduino │ ├── AdafruitDotStar_EPXDriver.cpp │ ├── AdafruitDotStar_EPXDriver.h │ ├── AdafruitNeoPixel_EPXDriver.cpp │ ├── AdafruitNeoPixel_EPXDriver.h │ ├── AdafruitRGBMatrix_EPXDriver.cpp │ ├── AdafruitRGBMatrix_EPXDriver.h │ ├── Examples │ │ ├── ExpressivePixelsFull │ │ │ ├── ExpressivePixels-Arduino-MatrixPortalM4-64x32.uf2 │ │ │ ├── ExpressivePixelsFull.ino │ │ │ └── config.h │ │ └── ExpressivePixelsMinimal │ │ │ ├── ExpressivePixelsMinimal.ino │ │ │ └── config.h │ ├── ExpressivePixelsArduinoCoreLibrary.zip │ ├── ExpressivePixelsArduinoPlatformLibrary.zip │ └── ExpressivePixelsMinimal.zip ├── Device_Nordic52840DK_SeggerEmbeddedStudio Minimal │ ├── EPXVariant.cpp │ ├── EPXVariant.h │ ├── data.c │ ├── main.c │ ├── mainCPP.cpp │ └── pca10056 │ │ └── s140 │ │ ├── config │ │ └── sdk_config.h │ │ └── ses │ │ ├── ExpressivePixels MINIMAL_pca10056_s140.emProject │ │ └── flash_placement.xml ├── Device_Nordic52840DK_SeggerEmbeddedStudio │ ├── EPXVariant.cpp │ ├── EPXVariant.h │ ├── MakeUF2.cmd │ ├── main.c │ ├── mainCPPStub.cpp │ └── pca10056 │ │ └── s140 │ │ ├── armgcc │ │ ├── Makefile │ │ └── ble_app_hrs_gcc_nrf52.ld │ │ ├── config │ │ └── sdk_config.h │ │ └── ses │ │ ├── ExpressivePixels_pca10056_s140.emProject │ │ └── flash_placement.xml ├── ExpressivePixelsCore │ ├── CAnimationManager.cpp │ ├── CAnimationManager.h │ ├── CBLEBeaconActivation.cpp │ ├── CBLEBeaconActivation.h │ ├── CBLEChannel.cpp │ ├── CBLEChannel.h │ ├── CCOBSProtocol.cpp │ ├── CCOBSProtocol.h │ ├── CDisplayArray.cpp │ ├── CDisplayArray.h │ ├── CDisplayTopology.cpp │ ├── CDisplayTopology.h │ ├── CLEDDriverBase.h │ ├── COBSCodec.cpp │ ├── COBSCodec.h │ ├── CSerialChannel.h │ ├── CSerialChannelBase.h │ ├── CStringProtocol.cpp │ ├── CStringProtocol.h │ ├── CUSBChannel.cpp │ ├── CUSBChannel.h │ ├── EPXAPP_CStorage.h │ ├── EPXApp.cpp │ ├── EPXApp.h │ ├── EPXApp_CStorage.cpp │ ├── EPXApp_ChannelConstants.h │ ├── EPXApp_ITriggerSource.h │ ├── EPXApp_JSON.cpp │ ├── EPXApp_MIDI.cpp │ ├── EPXApp_MIDI.h │ ├── EPXApp_Payload.cpp │ ├── EPXApp_Payload_Binary.cpp │ ├── EPXApp_Trigger_Switch.cpp │ ├── EPXApp_Trigger_Switch.h │ ├── EPXGlobal.h │ ├── EPXString.h │ ├── JsonListener.h │ ├── JsonStreamingParser.cpp │ ├── JsonStreamingParser.h │ ├── LICENSE.txt │ ├── README.md │ └── library.properties ├── ExpressivePixelsMIDI │ ├── MIDI.cpp │ ├── MIDI.h │ ├── MIDI.hpp │ ├── midi_Defs.h │ ├── midi_Message.h │ ├── midi_Namespace.h │ ├── midi_RingBuffer.h │ ├── midi_RingBuffer.hpp │ └── midi_Settings.h ├── LittleFS │ └── README.md ├── Platform_Arduino │ ├── AdafruitDotStar_EPXDriver.cpp │ ├── AdafruitDotStar_EPXDriver.h │ ├── AdafruitNeoPixel_EPXDriver.cpp │ ├── AdafruitNeoPixel_EPXDriver.h │ ├── AdafruitRGBMatrix_EPXDriver.cpp │ ├── AdafruitRGBMatrix_EPXDriver.h │ ├── EPXPlatform_BLE.cpp │ ├── EPXPlatform_BLE.h │ ├── EPXPlatform_CBatteryMonitor.cpp │ ├── EPXPlatform_CBatteryMonitor.h │ ├── EPXPlatform_CByteQueue.cpp │ ├── EPXPlatform_CByteQueue.h │ ├── EPXPlatform_CStorage.cpp │ ├── EPXPlatform_CStorage.h │ ├── EPXPlatform_CStorageBase.h │ ├── EPXPlatform_Crypto.cpp │ ├── EPXPlatform_Crypto.h │ ├── EPXPlatform_GPIO.cpp │ ├── EPXPlatform_GPIO.h │ ├── EPXPlatform_Runtime.cpp │ ├── EPXPlatform_Runtime.h │ ├── EPXPlatform_Settings.cpp │ ├── EPXPlatform_Settings.h │ ├── EPXPlatform_USB.cpp │ ├── EPXPlatform_USB.h │ ├── EPXVariant.cpp │ ├── EPXVariant.h │ ├── LICENSE.txt │ ├── README.md │ └── library.properties ├── Platform_NordicSDK │ ├── Adafruit_NeopixelDriver.cpp │ ├── Adafruit_NeopixelDriver.h │ ├── CAPA102-Driver.cpp │ ├── CAPA102-Driver.h │ ├── CAPA102-SPIDriver.h │ ├── CWS2812-I2SDriver.cpp │ ├── CWS2812-I2SDriver.h │ ├── CWS2812-SPIDriver.cpp │ ├── CWS2812-SPIDriver.h │ ├── EPXPlatform_BLE.c │ ├── EPXPlatform_BLE.h │ ├── EPXPlatform_BLE_DualNUS.c │ ├── EPXPlatform_BLE_DualNUS.h │ ├── EPXPlatform_CBatteryMonitor.cpp │ ├── EPXPlatform_CBatteryMonitor.h │ ├── EPXPlatform_CByteQueue.cpp │ ├── EPXPlatform_CByteQueue.h │ ├── EPXPlatform_CFlashStorageDevice.cpp │ ├── EPXPlatform_CFlashStorageDevice.h │ ├── EPXPlatform_CStorage.cpp │ ├── EPXPlatform_CStorage.h │ ├── EPXPlatform_CStorageBase.h │ ├── EPXPlatform_Crypto.cpp │ ├── EPXPlatform_Crypto.h │ ├── EPXPlatform_GPIO.cpp │ ├── EPXPlatform_GPIO.h │ ├── EPXPlatform_I2S.cpp │ ├── EPXPlatform_I2S.h │ ├── EPXPlatform_Runtime.cpp │ ├── EPXPlatform_Runtime.h │ ├── EPXPlatform_SPIClass.cpp │ ├── EPXPlatform_SPIClass.h │ ├── EPXPlatform_Settings.cpp │ ├── EPXPlatform_Settings.h │ ├── EPXPlatform_USB.c │ ├── EPXPlatform_USB.h │ ├── EPXPlatform_Uart.cpp │ └── EPXPlatform_Uart.h ├── README.md ├── RaspberryPi │ ├── animate.py │ ├── animation.py │ ├── ble_device.py │ ├── play.sh │ ├── protocol.py │ ├── readme.md │ ├── requirements.txt │ ├── serial_device.py │ ├── settings.yaml │ ├── sparklet.py │ ├── txt2anim.py │ └── win_animate.py ├── Segger │ ├── SEGGER_RTT.c │ ├── SEGGER_RTT.h │ ├── SEGGER_RTT_ASM_ARMv7M.S │ ├── SEGGER_RTT_Conf.h │ └── SEGGER_RTT_printf.c └── uf2conv.py ├── LICENSE ├── README.md ├── SECURITY.md ├── Windows └── ExpressivePixelsActivator │ ├── ConnectivityCore │ ├── BLE_Device.cs │ ├── BLE_DeviceManager.cs │ └── BLE_UARTService.cs │ ├── UWP │ ├── App.xaml │ ├── App.xaml.cs │ ├── Assets │ │ ├── LockScreenLogo.scale-200.png │ │ ├── SplashScreen.scale-200.png │ │ ├── Square150x150Logo.scale-200.png │ │ ├── Square44x44Logo.scale-200.png │ │ ├── Square44x44Logo.targetsize-24_altform-unplated.png │ │ ├── StoreLogo.png │ │ └── Wide310x150Logo.scale-200.png │ ├── Converters │ │ ├── BoolInverterConverter.cs │ │ ├── BoolToOpacityConverter.cs │ │ ├── BooleanToVisibilityConverter.cs │ │ └── EnumStateToStringConverter.cs │ ├── ExpressivePixelsActivatorUWP.csproj │ ├── ExpressivePixelsActivatorUWP.sln │ ├── MainPage.xaml │ ├── MainPage.xaml.cs │ ├── Package.appxmanifest │ └── Properties │ │ ├── AssemblyInfo.cs │ │ └── Default.rd.xml │ └── WPF │ ├── App.config │ ├── App.xaml │ ├── App.xaml.cs │ ├── Controls │ ├── ButtonAttachedBehavior.cs │ └── DelegateCommand.cs │ ├── Converters │ ├── BoolInverter.cs │ ├── BoolToOpacityConverter.cs │ ├── BooleanToVisibilityConverter.cs │ ├── BrightnessToSliderValueConverter.cs │ ├── DoubleToIntConverter.cs │ ├── EmptyStringToVisibilityConverter.cs │ ├── EnumStateToStringConverter.cs │ ├── EnumStringToTemplateConverter.cs │ ├── OrientationToVisibilityConverter.cs │ └── TrueFalseBrushConverter.cs │ ├── ExpressivePixelsActivatorWPF.csproj │ ├── ExpressivePixelsActivatorWPF.sln │ ├── MainWindow.xaml │ ├── MainWindow.xaml.cs │ ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings │ ├── Styles │ └── ExpressivePixelSliderStyle.xaml │ └── packages.config └── images ├── ArduinoAdaCPX16x16.jpg ├── ArduinoAdaCPX8x8.jpg ├── ArduinoLayers.png ├── ArduinoTinyUSB.png ├── Docs-AnimationFormat.png ├── Docs-AnimationFormatFrames.png ├── Docs-AnimationFormatHeader.png ├── Docs-AnimationFormatHigh.png ├── Docs-AnimationFormatPalette.png ├── Docs-CommsFormat.png ├── Docs-MakeCode-Button.png ├── Docs-MakeCode-Download.png ├── Docs-MakeCode-EPXDisplay.png ├── Docs-MakeCode-Extension.png ├── Docs-MakeCode-ExtensionURL.png ├── Docs-MakeCode-JScript.png ├── Docs-MakeCode-Javascript.png ├── Docs-MakeCode-SetDisplay.png ├── Docs-MakeCode-Startup.png ├── Docs-MatrixPortalActivation.png ├── Docs-MatrixPortalConnect.png ├── EPXArchitecture.png ├── EPXGitHubLockup.png ├── SWDConfiguration.jpg ├── VSCodeAdditionalUrls.png ├── VSCodeAdditionalUrlsSettings.png ├── VSCodeBoardManager.png ├── VSCodeInstallExtn.png ├── VSCodeSettingsJSON.png └── VSCodeVerify.png /Firmware/Arduino/AdafruitDotStar_EPXDriver.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include "EPXPlatform_Runtime.h" 4 | #include "AdafruitDotStar_EPXDriver.h" 5 | 6 | EPX_OPTIMIZEFORDEBUGGING_ON 7 | 8 | 9 | CAdafruitDotStar_EPXDriver::CAdafruitDotStar_EPXDriver(int dataPin, int clockPin, uint16_t numPixels) : CLEDDriverBase(numPixels) 10 | { 11 | m_nRainbowIteration = 0; 12 | m_AdaFruitDotStar = new Adafruit_DotStar(numPixels, dataPin, clockPin); 13 | } 14 | 15 | 16 | 17 | void CAdafruitDotStar_EPXDriver::Initialize() 18 | { 19 | m_AdaFruitDotStar->begin(); 20 | } 21 | 22 | 23 | 24 | void CAdafruitDotStar_EPXDriver::SetBrightness(uint8_t brightness) 25 | { 26 | m_AdaFruitDotStar->setBrightness(brightness); 27 | } 28 | 29 | 30 | 31 | uint16_t CAdafruitDotStar_EPXDriver::NumPixels() 32 | { 33 | return m_AdaFruitDotStar->numPixels(); 34 | } 35 | 36 | 37 | 38 | void CAdafruitDotStar_EPXDriver::SetPixel(uint16_t idx, uint8_t r, uint8_t g, uint8_t b) 39 | { 40 | m_AdaFruitDotStar->setPixelColor(idx, g, r, b); 41 | } 42 | 43 | 44 | 45 | void CAdafruitDotStar_EPXDriver::SetPixelColor(uint16_t idx, uint32_t color) 46 | { 47 | m_AdaFruitDotStar->setPixelColor(idx, color); 48 | } 49 | 50 | 51 | void CAdafruitDotStar_EPXDriver::Clear() 52 | { 53 | m_AdaFruitDotStar->clear(); 54 | } 55 | 56 | 57 | 58 | void CAdafruitDotStar_EPXDriver::Show() 59 | { 60 | m_AdaFruitDotStar->show(); 61 | } 62 | 63 | 64 | 65 | uint32_t CAdafruitDotStar_EPXDriver::Wheel(uint8_t WheelPos) 66 | { 67 | WheelPos = 255 - WheelPos; 68 | if (WheelPos < 85) 69 | return IntColor(255 - WheelPos * 3, 0, WheelPos * 3); 70 | if (WheelPos < 170) 71 | { 72 | WheelPos -= 85; 73 | return IntColor(0, WheelPos * 3, 255 - WheelPos * 3); 74 | } 75 | WheelPos -= 170; 76 | return IntColor(WheelPos * 3, 255 - WheelPos * 3, 0); 77 | } 78 | 79 | 80 | 81 | void CAdafruitDotStar_EPXDriver::Rainbow(uint8_t wait) 82 | { 83 | uint16_t i, j; 84 | 85 | for (j = 0; j < 256; j++) 86 | { 87 | for (i = 0; i < m_numPixels; i++) 88 | // SetPixelColor(i, Wheel((i + j) & 255)); 89 | m_AdaFruitDotStar->setPixelColor(i, Wheel((i + j) & 255)); 90 | m_AdaFruitDotStar->show(); 91 | delay(wait); 92 | } 93 | } 94 | 95 | 96 | 97 | // Slightly different, this makes the rainbow equally distributed throughout 98 | void CAdafruitDotStar_EPXDriver::RainbowCycle(uint8_t wait) 99 | { 100 | uint16_t i; 101 | 102 | if(m_nRainbowIteration >= 256 * 5) 103 | m_nRainbowIteration = 0; 104 | 105 | // 5 cycles of all colors on wheel 106 | for(i = 0 ; i < m_numPixels; i++) 107 | //SetPixelColor(i, Wheel(((i * 256 / m_numPixels) + j) & 255)); 108 | m_AdaFruitDotStar->setPixelColor(i, Wheel((i + m_nRainbowIteration) & 255)); 109 | m_AdaFruitDotStar->show(); 110 | delay(wait); 111 | 112 | m_nRainbowIteration++; 113 | } 114 | 115 | -------------------------------------------------------------------------------- /Firmware/Arduino/AdafruitDotStar_EPXDriver.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include "stdlib.h" 5 | #include "memory.h" 6 | #include "CLEDDriverBase.h" 7 | #include 8 | #include "Adafruit_DotStar.h" 9 | 10 | 11 | class CAdafruitDotStar_EPXDriver : public CLEDDriverBase 12 | { 13 | 14 | public: 15 | CAdafruitDotStar_EPXDriver(int dataPin, int clockPin, uint16_t numPixels); 16 | 17 | ~CAdafruitDotStar_EPXDriver() 18 | { 19 | if (m_pTXBuffer != NULL) 20 | free(m_pTXBuffer); 21 | } 22 | 23 | void Initialize(); 24 | void Rainbow(uint8_t wait); 25 | void RainbowCycle(uint8_t wait); 26 | void Show(); 27 | void Clear(); 28 | 29 | void SetBrightness(uint8_t brightness); 30 | void SetPixel(uint16_t idx, uint8_t r, uint8_t g, uint8_t b); 31 | void SetPixelColor(uint16_t idx, uint32_t color); 32 | uint16_t NumPixels(); 33 | 34 | private: 35 | uint32_t Wheel(uint8_t WheelPos); 36 | 37 | Adafruit_DotStar *m_AdaFruitDotStar; 38 | uint32_t *m_pTXBuffer; 39 | uint32_t m_nRainbowIteration; 40 | }; 41 | 42 | -------------------------------------------------------------------------------- /Firmware/Arduino/AdafruitNeoPixel_EPXDriver.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include "EPXPlatform_Runtime.h" 4 | #include "AdafruitNeoPixel_EPXDriver.h" 5 | 6 | EPX_OPTIMIZEFORDEBUGGING_ON 7 | 8 | 9 | CAdafruitNeoPixel_EPXDriver::CAdafruitNeoPixel_EPXDriver(int dataPin, uint16_t numPixels) : CLEDDriverBase(numPixels) 10 | { 11 | m_nRainbowIteration = 0; 12 | m_AdaFruitNeoPixel = new Adafruit_NeoPixel(numPixels, dataPin, NEO_GRB + NEO_KHZ800); 13 | } 14 | 15 | 16 | 17 | void CAdafruitNeoPixel_EPXDriver::Initialize() 18 | { 19 | m_AdaFruitNeoPixel->begin(); 20 | } 21 | 22 | 23 | 24 | void CAdafruitNeoPixel_EPXDriver::SetBrightness(uint8_t brightness) 25 | { 26 | m_AdaFruitNeoPixel->setBrightness(brightness); 27 | } 28 | 29 | 30 | 31 | uint16_t CAdafruitNeoPixel_EPXDriver::NumPixels() 32 | { 33 | return m_AdaFruitNeoPixel->numPixels(); 34 | } 35 | 36 | 37 | 38 | void CAdafruitNeoPixel_EPXDriver::SetPixel(uint16_t idx, uint8_t r, uint8_t g, uint8_t b) 39 | { 40 | m_AdaFruitNeoPixel->setPixelColor(idx, r, g, b); 41 | } 42 | 43 | 44 | 45 | void CAdafruitNeoPixel_EPXDriver::SetPixelColor(uint16_t idx, uint32_t color) 46 | { 47 | m_AdaFruitNeoPixel->setPixelColor(idx, color); 48 | } 49 | 50 | 51 | void CAdafruitNeoPixel_EPXDriver::Clear() 52 | { 53 | m_AdaFruitNeoPixel->clear(); 54 | } 55 | 56 | 57 | 58 | void CAdafruitNeoPixel_EPXDriver::Show() 59 | { 60 | m_AdaFruitNeoPixel->show(); 61 | } 62 | 63 | 64 | 65 | uint32_t CAdafruitNeoPixel_EPXDriver::Wheel(uint8_t WheelPos) 66 | { 67 | WheelPos = 255 - WheelPos; 68 | if (WheelPos < 85) 69 | return IntColor(255 - WheelPos * 3, 0, WheelPos * 3); 70 | if (WheelPos < 170) 71 | { 72 | WheelPos -= 85; 73 | return IntColor(0, WheelPos * 3, 255 - WheelPos * 3); 74 | } 75 | WheelPos -= 170; 76 | return IntColor(WheelPos * 3, 255 - WheelPos * 3, 0); 77 | } 78 | 79 | 80 | 81 | void CAdafruitNeoPixel_EPXDriver::Rainbow(uint8_t wait) 82 | { 83 | uint16_t i, j; 84 | 85 | for (j = 0; j < 256; j++) 86 | { 87 | for (i = 0; i < m_numPixels; i++) 88 | // SetPixelColor(i, Wheel((i + j) & 255)); 89 | m_AdaFruitNeoPixel->setPixelColor(i, Wheel((i + j) & 255)); 90 | m_AdaFruitNeoPixel->show(); 91 | delay(wait); 92 | } 93 | } 94 | 95 | 96 | 97 | // Slightly different, this makes the rainbow equally distributed throughout 98 | void CAdafruitNeoPixel_EPXDriver::RainbowCycle(uint8_t wait) 99 | { 100 | uint16_t i; 101 | 102 | if(m_nRainbowIteration >= 256 * 5) 103 | m_nRainbowIteration = 0; 104 | 105 | // 5 cycles of all colors on wheel 106 | for(i = 0 ; i < m_numPixels; i++) 107 | //SetPixelColor(i, Wheel(((i * 256 / m_numPixels) + j) & 255)); 108 | m_AdaFruitNeoPixel->setPixelColor(i, Wheel((i + m_nRainbowIteration) & 255)); 109 | m_AdaFruitNeoPixel->show(); 110 | delay(wait); 111 | 112 | m_nRainbowIteration++; 113 | } 114 | 115 | -------------------------------------------------------------------------------- /Firmware/Arduino/AdafruitNeoPixel_EPXDriver.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include "stdlib.h" 5 | #include "memory.h" 6 | #include "CLEDDriverBase.h" 7 | #include 8 | #include "Adafruit_NeoPixel.h" 9 | 10 | 11 | class CAdafruitNeoPixel_EPXDriver : public CLEDDriverBase 12 | { 13 | 14 | public: 15 | CAdafruitNeoPixel_EPXDriver(int dataPin, uint16_t numPixels); 16 | 17 | ~CAdafruitNeoPixel_EPXDriver() 18 | { 19 | if (m_pTXBuffer != NULL) 20 | free(m_pTXBuffer); 21 | } 22 | 23 | void Initialize(); 24 | void Rainbow(uint8_t wait); 25 | void RainbowCycle(uint8_t wait); 26 | void Show(); 27 | void Clear(); 28 | 29 | void SetBrightness(uint8_t brightness); 30 | void SetPixel(uint16_t idx, uint8_t r, uint8_t g, uint8_t b); 31 | void SetPixelColor(uint16_t idx, uint32_t color); 32 | uint16_t NumPixels(); 33 | 34 | private: 35 | uint32_t Wheel(uint8_t WheelPos); 36 | 37 | Adafruit_NeoPixel *m_AdaFruitNeoPixel; 38 | uint32_t *m_pTXBuffer; 39 | uint32_t m_nRainbowIteration; 40 | }; 41 | 42 | -------------------------------------------------------------------------------- /Firmware/Arduino/AdafruitRGBMatrix_EPXDriver.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | 5 | #include "stdlib.h" 6 | #include "memory.h" 7 | #include "CLEDDriverBase.h" 8 | #include 9 | #include 10 | 11 | class CAdafruitRGBMatrix_EPXDriver : public CLEDDriverBase 12 | { 13 | 14 | public: 15 | CAdafruitRGBMatrix_EPXDriver(int width, int height); 16 | ~CAdafruitRGBMatrix_EPXDriver(); 17 | 18 | void Initialize(); 19 | void Rainbow(uint8_t wait); 20 | void RainbowCycle(uint8_t wait); 21 | void Show(); 22 | void Clear(); 23 | 24 | void SetBrightness(uint8_t brightness); 25 | void SetPixel(uint16_t idx, uint8_t r, uint8_t g, uint8_t b); 26 | void SetPixelColor(uint16_t idx, uint32_t color); 27 | uint16_t NumPixels(); 28 | 29 | private: 30 | uint32_t Wheel(uint8_t WheelPos); 31 | 32 | Adafruit_Protomatter *m_pRGBmatrixPanel; 33 | uint32_t *m_pTXBuffer; 34 | uint32_t m_nRainbowIteration; 35 | int m_width; 36 | int m_height; 37 | int m_brightness; 38 | }; 39 | 40 | -------------------------------------------------------------------------------- /Firmware/Arduino/Examples/ExpressivePixelsFull/ExpressivePixels-Arduino-MatrixPortalM4-64x32.uf2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/Firmware/Arduino/Examples/ExpressivePixelsFull/ExpressivePixels-Arduino-MatrixPortalM4-64x32.uf2 -------------------------------------------------------------------------------- /Firmware/Arduino/Examples/ExpressivePixelsFull/ExpressivePixelsFull.ino: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include "EPXApp.h" 4 | #include "EPXApp_Trigger_Switch.h" 5 | EPX_OPTIMIZEFORDEBUGGING_ON 6 | 7 | /************************** Configuration ***********************************/ 8 | 9 | // edit the config.h tab and configure your display 10 | #include "config.h" 11 | 12 | char g_szDEFAULT_BLE_NAME[BLEMAX_DEVICENAME + 1] = "EPXArduino"; 13 | EPX_GUID g_displayDesignGUID = { 0x39, 0xF2, 0xB0, 0x5D, 0xAA, 0x8D, 0x49, 0x42, 0x99, 0x44, 0x31, 0xE0, 0x85, 0xF0, 0x13, 0x15 }; 14 | 15 | 16 | 17 | void setup() 18 | { 19 | void *g_pLEDDriver = NULL; 20 | 21 | // Create the underlying driver class 22 | #ifdef DISPLAYDRIVER_ADAFRUIT_DOTSTAR 23 | // For a APA102 type of LED 24 | CAdafruitDotStar_EPXDriver *pDotStarDriver = new CAdafruitDotStar_EPXDriver(PIN_STRIP_DATA, PIN_STRIP_CLOCK, DISPLAYARRAY_WIDTH * DISPLAYARRAY_HEIGHT); 25 | g_pLEDDriver = pDotStarDriver; 26 | #elif defined(DISPLAYDRIVER_ADAFRUIT_NEOPIXEL) 27 | // For WS2812 LEDs 28 | CAdafruitNeoPixel_EPXDriver *pNeoPixelDriver = new CAdafruitNeoPixel_EPXDriver(PIN_STRIP_DATA, DISPLAYARRAY_WIDTH * DISPLAYARRAY_HEIGHT); 29 | g_pLEDDriver = pNeoPixelDriver; 30 | #elif defined(DISPLAYDRIVER_ADAFRUIT_PROTOMATTER) 31 | // For Protomatter RGB Matrixes 32 | CAdafruitRGBMatrix_EPXDriver *pRGBMatrixDriver = new CAdafruitRGBMatrix_EPXDriver(DISPLAYARRAY_WIDTH, DISPLAYARRAY_HEIGHT); 33 | g_pLEDDriver = pRGBMatrixDriver; 34 | #endif 35 | 36 | #if defined(DISPLAY_SPARKLETSQUARE16X16) || defined(DISPLAY_MATRIX64x32) 37 | for(int i = 0;i < DISPLAYARRAY_WIDTH * DISPLAYARRAY_HEIGHT;i++) 38 | g_displayArrayPixelTopology[i] = i; 39 | #endif 40 | 41 | EPXPlatform_Runtime_Initialize(); 42 | CSwitchActivation::SubsystemInitialize(NUM_SWITCHTRIGGER_PINS, g_switchActivationMapping); 43 | EPXApp_Initialize(g_pLEDDriver, g_displayArrayPixelTopology, DISPLAYARRAY_WIDTH, DISPLAYARRAY_HEIGHT); 44 | } 45 | 46 | 47 | 48 | void loop() 49 | { 50 | // Process main app 51 | EPXPlatform_Runtime_Process(); 52 | EPXApp_Process(); 53 | } 54 | -------------------------------------------------------------------------------- /Firmware/Arduino/ExpressivePixelsArduinoCoreLibrary.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/Firmware/Arduino/ExpressivePixelsArduinoCoreLibrary.zip -------------------------------------------------------------------------------- /Firmware/Arduino/ExpressivePixelsArduinoPlatformLibrary.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/Firmware/Arduino/ExpressivePixelsArduinoPlatformLibrary.zip -------------------------------------------------------------------------------- /Firmware/Arduino/ExpressivePixelsMinimal.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/Firmware/Arduino/ExpressivePixelsMinimal.zip -------------------------------------------------------------------------------- /Firmware/Device_Nordic52840DK_SeggerEmbeddedStudio Minimal/EPXVariant.cpp: -------------------------------------------------------------------------------- 1 | #include "EPXVariant.h" 2 | #include "CDisplayTopology.h" 3 | 4 | -------------------------------------------------------------------------------- /Firmware/Device_Nordic52840DK_SeggerEmbeddedStudio Minimal/EPXVariant.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | enum VariantCapabilities 5 | { 6 | VARIANTCAPABILITY_STORAGE = 0x1, 7 | VARIANTCAPABILITY_PREVIEW = 0x2, 8 | }; 9 | 10 | 11 | #if defined(ADACPXBLUEFRUIT) 12 | #define GPIO_PIN_BOOSTER_ENABLE 0 13 | #define DISPLAYARRAY_DATAPIN 3 14 | #define DISPLAYARRAY_POWERPIN 0 15 | 16 | #endif 17 | 18 | extern char g_szDEFAULT_BLE_NAME[]; -------------------------------------------------------------------------------- /Firmware/Device_Nordic52840DK_SeggerEmbeddedStudio Minimal/main.c: -------------------------------------------------------------------------------- 1 | #include "nordic_common.h" 2 | #include "nrf.h" 3 | #include "app_timer.h" 4 | #include "app_util_platform.h" 5 | #include "nrf_log.h" 6 | #include "nrf_log_ctrl.h" 7 | #include "nrf_log_default_backends.h" 8 | #include "EPXPlatform_Runtime.h" 9 | 10 | 11 | #define DEAD_BEEF 0xDEADBEEF /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */ 12 | 13 | void NRF52_EPXApp_Initialize(); 14 | void NRF52_EPXApp_Process(); 15 | 16 | 17 | 18 | /**@brief Function for assert macro callback. 19 | * 20 | * @details This function will be called in case of an assert in the SoftDevice. 21 | * 22 | * @warning This handler is an example only and does not fit a final product. You need to analyse 23 | * how your product is supposed to react in case of Assert. 24 | * @warning On assert from the SoftDevice, the system can only recover on reset. 25 | * 26 | * @param[in] line_num Line number of the failing ASSERT call. 27 | * @param[in] p_file_name File name of the failing ASSERT call. 28 | */ 29 | void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name) 30 | { 31 | app_error_handler(DEAD_BEEF, line_num, p_file_name); 32 | } 33 | 34 | 35 | 36 | void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name) 37 | { 38 | __disable_irq(); 39 | 40 | 41 | NRF_LOG_ERROR("app_error_handler %d %d", error_code, line_num); 42 | NRF_LOG_FINAL_FLUSH(); 43 | #ifndef DEBUG 44 | NRF_LOG_WARNING("System reset"); 45 | NVIC_SystemReset(); 46 | #else 47 | // The following variable helps Keil keep the call stack visible, in addition, it can be set to 48 | // 0 in the debugger to continue executing code after the error check. 49 | volatile bool loop = true; 50 | while (loop) ; 51 | #endif // DEBUG 52 | } 53 | 54 | 55 | 56 | /**@brief Function for initializing the nrf log module. 57 | */ 58 | static void log_init(void) 59 | { 60 | ret_code_t err_code = NRF_LOG_INIT(NULL); 61 | APP_ERROR_CHECK(err_code); 62 | 63 | NRF_LOG_DEFAULT_BACKENDS_INIT(); 64 | } 65 | 66 | 67 | 68 | 69 | /**@brief Application main function. */ 70 | int main(void) 71 | { 72 | // Initialize. 73 | uint32_t err_code = app_timer_init(); 74 | APP_ERROR_CHECK(err_code); 75 | log_init(); 76 | 77 | EPXPlatform_Runtime_Initialize(); 78 | NRF52_EPXApp_Initialize(); 79 | 80 | // Enter main loop. 81 | for (;;) 82 | { 83 | UNUSED_RETURN_VALUE(NRF_LOG_PROCESS()); 84 | 85 | // Process main app 86 | EPXPlatform_Runtime_Process(); 87 | NRF52_EPXApp_Process(); 88 | } 89 | } 90 | 91 | -------------------------------------------------------------------------------- /Firmware/Device_Nordic52840DK_SeggerEmbeddedStudio Minimal/mainCPP.cpp: -------------------------------------------------------------------------------- 1 | #include "EPXPlatform_Runtime.h" 2 | #include "EPXPlatform_GPIO.h" 3 | #include "CAnimationManager.h" 4 | #include "CDisplayTopology.h" 5 | #include "CLEDDriverBase.h" 6 | #include "CWS2812-I2SDriver.h" 7 | #include "EPXVariant.h" 8 | 9 | 10 | 11 | #ifdef DISPLAYTYPE_EMOTICONWS2812 12 | 13 | #define DISPLAYARRAY_WIDTH 16 14 | #define DISPLAYARRAY_HEIGHT 16 15 | 16 | 17 | uint16_t g_displayArrayPixelTopology[DISPLAYARRAY_WIDTH * DISPLAYARRAY_HEIGHT] = 18 | { 19 | 0, 31, 32, 63, 64, 95, 96, 127,128,159,160,191,192,223,224,255, 20 | 1, 30, 33, 62, 65, 94, 97, 126,129,158,161,190,193,222,225,254, 21 | 2, 29, 34, 61, 66, 93, 98, 125,130,157,162,189,194,221,226,253, 22 | 3, 28, 35, 60, 67, 92, 99, 124,131,156,163,188,195,220,227,252, 23 | 4, 27, 36, 59, 68, 91,100, 123,132,155,164,187,196,219,228,251, 24 | 5, 26, 37, 58, 69, 90,101, 122,133,154,165,186,197,218,229,250, 25 | 6, 25, 38, 57, 70, 89,102, 121,134,153,166,185,198,217,230,249, 26 | 7, 24, 39, 56, 71, 88,103, 120,135,152,167,184,199,216,231,248, 27 | 8, 23, 40, 55, 72, 87,104, 119,136,151,168,183,200,215,232,247, 28 | 9, 22, 41, 54, 73, 86,105, 118,137,150,169,182,201,214,233,246, 29 | 10, 21, 42, 53, 74, 85,106, 117,138,149,170,181,202,213,234,245, 30 | 11, 20, 43, 52, 75, 84,107, 116,139,148,171,180,203,212,235,244, 31 | 12, 19, 44, 51, 76, 83,108, 115,140,147,172,179,204,211,236,243, 32 | 13, 18, 45, 50, 77, 82,109, 114,141,146,173,178,205,210,237,242, 33 | 14, 17, 46, 51, 78, 81,110, 113,142,145,174,177,206,209,238,241, 34 | 15, 16, 47, 48, 79, 80,111, 112,143,144,175,176,207,208,239,240 35 | }; 36 | 37 | 38 | #endif 39 | 40 | 41 | CDisplayArray g_CDisplayArray; 42 | CDisplayTopology g_CDisplayTopology; 43 | CAnimationManager g_CAnimator(&g_CDisplayArray); 44 | extern uint8_t bootAnimation[]; 45 | 46 | 47 | extern "C" 48 | { 49 | void NRF52_EPXApp_Initialize() 50 | { 51 | if(GPIO_PIN_BOOSTER_ENABLE > 0) 52 | pinMode(GPIO_PIN_BOOSTER_ENABLE, OUTPUT); 53 | 54 | 55 | CWS2812_I2SDriver *pCWS2812_I2S_Driver = new CWS2812_I2SDriver(DISPLAYARRAY_DATAPIN, DISPLAYARRAY_WIDTH * DISPLAYARRAY_HEIGHT); 56 | 57 | // Configure display and array 58 | g_CDisplayTopology.SetMatrix(g_displayArrayPixelTopology, DISPLAYARRAY_WIDTH, DISPLAYARRAY_HEIGHT); 59 | g_CAnimator.SetTopology(&g_CDisplayTopology); 60 | g_CDisplayArray.Initialize(pCWS2812_I2S_Driver, DISPLAYARRAY_WIDTH, DISPLAYARRAY_HEIGHT, DISPLAYARRAY_POWERPIN); 61 | g_CDisplayArray.SetBrightness(10); 62 | 63 | if(GPIO_PIN_BOOSTER_ENABLE > 0) 64 | digitalWrite(GPIO_PIN_BOOSTER_ENABLE, HIGH); 65 | g_CAnimator.Activate(bootAnimation); 66 | } 67 | 68 | 69 | 70 | void NRF52_EPXApp_Process() 71 | { 72 | if(g_CAnimator.Process()) 73 | g_CAnimator.Clear(); 74 | } 75 | } 76 | 77 | -------------------------------------------------------------------------------- /Firmware/Device_Nordic52840DK_SeggerEmbeddedStudio/MakeUF2.cmd: -------------------------------------------------------------------------------- 1 | ..\uf2conv.py pca10056\s140\ses\Output\Debug\Exe\ExpressivePixels_pca10056_s140.hex -c -f 0xADA52840 -o ExpressivePixels.uf2 2 | 3 | -------------------------------------------------------------------------------- /Firmware/Device_Nordic52840DK_SeggerEmbeddedStudio/mainCPPStub.cpp: -------------------------------------------------------------------------------- 1 | #include "EPXApp.h" 2 | #ifdef VARIANTDISPLAYDRIVER_I2SWS2812 3 | #include "CWS2812-I2SDriver.h" 4 | #elif defined(VARIANTDISPLAYDRIVER_ADANEOPIXEL) 5 | #include "Adafruit_NeopixelDriver.h" 6 | #endif 7 | 8 | extern SWITCHACTIVATION_GPIOBUTTON_MAPPING g_switchTriggerGPIOButtonMappings[]; 9 | extern uint16_t g_displayArrayPixelTopology[]; 10 | 11 | extern "C" 12 | { 13 | void NRF52_EPXApp_Initialize() 14 | { 15 | void *pDisplayDriver = NULL; 16 | 17 | #if defined(DISPLAYTYPE_16x16) || defined(DISPLAYTYPE_22x22) 18 | for(int i = 0;i < DISPLAYARRAY_WIDTH * DISPLAYARRAY_HEIGHT;i++) 19 | g_displayArrayPixelTopology[i] = i; 20 | 21 | #endif 22 | 23 | 24 | #ifdef VARIANTDISPLAYDRIVER_I2SWS2812 25 | CWS2812_I2SDriver *pCWS2812_I2S_Driver = new CWS2812_I2SDriver(DISPLAYARRAY_DATAPIN, DISPLAYARRAY_WIDTH * DISPLAYARRAY_HEIGHT); 26 | pDisplayDriver = pCWS2812_I2S_Driver; 27 | #elif defined(VARIANTDISPLAYDRIVER_ADANEOPIXEL) 28 | Adafruit_NeopixelDriver *pAdafruitNeopixelDriver = new Adafruit_NeopixelDriver(DISPLAYARRAY_DATAPIN, DISPLAYARRAY_WIDTH * DISPLAYARRAY_HEIGHT); 29 | pDisplayDriver = pAdafruitNeopixelDriver; 30 | #endif 31 | 32 | CSwitchActivation::SubsystemInitialize(VARIANT_NUMTRIGGERGPIOS, g_switchTriggerGPIOButtonMappings); 33 | EPXApp_Initialize(pDisplayDriver, g_displayArrayPixelTopology, DISPLAYARRAY_WIDTH, DISPLAYARRAY_HEIGHT); 34 | } 35 | 36 | 37 | 38 | void NRF52_EPXApp_Process() 39 | { 40 | EPXApp_Process(); 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /Firmware/Device_Nordic52840DK_SeggerEmbeddedStudio/pca10056/s140/armgcc/ble_app_hrs_gcc_nrf52.ld: -------------------------------------------------------------------------------- 1 | /* Linker script to configure memory regions. */ 2 | 3 | SEARCH_DIR(.) 4 | GROUP(-lgcc -lc -lnosys) 5 | 6 | MEMORY 7 | { 8 | FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0xda000 9 | RAM (rwx) : ORIGIN = 0x20002b88, LENGTH = 0x3d478 10 | } 11 | 12 | SECTIONS 13 | { 14 | } 15 | 16 | SECTIONS 17 | { 18 | . = ALIGN(4); 19 | .mem_section_dummy_ram : 20 | { 21 | } 22 | .cli_sorted_cmd_ptrs : 23 | { 24 | PROVIDE(__start_cli_sorted_cmd_ptrs = .); 25 | KEEP(*(.cli_sorted_cmd_ptrs)) 26 | PROVIDE(__stop_cli_sorted_cmd_ptrs = .); 27 | } > RAM 28 | .fs_data : 29 | { 30 | PROVIDE(__start_fs_data = .); 31 | KEEP(*(.fs_data)) 32 | PROVIDE(__stop_fs_data = .); 33 | } > RAM 34 | .log_dynamic_data : 35 | { 36 | PROVIDE(__start_log_dynamic_data = .); 37 | KEEP(*(SORT(.log_dynamic_data*))) 38 | PROVIDE(__stop_log_dynamic_data = .); 39 | } > RAM 40 | .log_filter_data : 41 | { 42 | PROVIDE(__start_log_filter_data = .); 43 | KEEP(*(SORT(.log_filter_data*))) 44 | PROVIDE(__stop_log_filter_data = .); 45 | } > RAM 46 | 47 | } INSERT AFTER .data; 48 | 49 | SECTIONS 50 | { 51 | .mem_section_dummy_rom : 52 | { 53 | } 54 | .sdh_soc_observers : 55 | { 56 | PROVIDE(__start_sdh_soc_observers = .); 57 | KEEP(*(SORT(.sdh_soc_observers*))) 58 | PROVIDE(__stop_sdh_soc_observers = .); 59 | } > FLASH 60 | .sdh_ble_observers : 61 | { 62 | PROVIDE(__start_sdh_ble_observers = .); 63 | KEEP(*(SORT(.sdh_ble_observers*))) 64 | PROVIDE(__stop_sdh_ble_observers = .); 65 | } > FLASH 66 | .pwr_mgmt_data : 67 | { 68 | PROVIDE(__start_pwr_mgmt_data = .); 69 | KEEP(*(SORT(.pwr_mgmt_data*))) 70 | PROVIDE(__stop_pwr_mgmt_data = .); 71 | } > FLASH 72 | .nrf_queue : 73 | { 74 | PROVIDE(__start_nrf_queue = .); 75 | KEEP(*(.nrf_queue)) 76 | PROVIDE(__stop_nrf_queue = .); 77 | } > FLASH 78 | .sdh_stack_observers : 79 | { 80 | PROVIDE(__start_sdh_stack_observers = .); 81 | KEEP(*(SORT(.sdh_stack_observers*))) 82 | PROVIDE(__stop_sdh_stack_observers = .); 83 | } > FLASH 84 | .sdh_req_observers : 85 | { 86 | PROVIDE(__start_sdh_req_observers = .); 87 | KEEP(*(SORT(.sdh_req_observers*))) 88 | PROVIDE(__stop_sdh_req_observers = .); 89 | } > FLASH 90 | .sdh_state_observers : 91 | { 92 | PROVIDE(__start_sdh_state_observers = .); 93 | KEEP(*(SORT(.sdh_state_observers*))) 94 | PROVIDE(__stop_sdh_state_observers = .); 95 | } > FLASH 96 | .nrf_balloc : 97 | { 98 | PROVIDE(__start_nrf_balloc = .); 99 | KEEP(*(.nrf_balloc)) 100 | PROVIDE(__stop_nrf_balloc = .); 101 | } > FLASH 102 | .cli_command : 103 | { 104 | PROVIDE(__start_cli_command = .); 105 | KEEP(*(.cli_command)) 106 | PROVIDE(__stop_cli_command = .); 107 | } > FLASH 108 | .crypto_data : 109 | { 110 | PROVIDE(__start_crypto_data = .); 111 | KEEP(*(SORT(.crypto_data*))) 112 | PROVIDE(__stop_crypto_data = .); 113 | } > FLASH 114 | .log_const_data : 115 | { 116 | PROVIDE(__start_log_const_data = .); 117 | KEEP(*(SORT(.log_const_data*))) 118 | PROVIDE(__stop_log_const_data = .); 119 | } > FLASH 120 | .log_backends : 121 | { 122 | PROVIDE(__start_log_backends = .); 123 | KEEP(*(SORT(.log_backends*))) 124 | PROVIDE(__stop_log_backends = .); 125 | } > FLASH 126 | 127 | } INSERT AFTER .text 128 | 129 | INCLUDE "nrf_common.ld" 130 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/CBLEBeaconActivation.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | /* 5 | * Class implementing Bluetooth beacon triggering 6 | **/ 7 | 8 | #pragma once 9 | #include 10 | #include "EPXPlatform_BLE.h" 11 | 12 | #define BEACONACTIVATION_ENTRY_FILENAME "BeaconActivations.dat" // Storage file for persisted activations 13 | 14 | 15 | #ifdef __cplusplus 16 | 17 | // Beacon activation classe 18 | class CBeaconActivation 19 | { 20 | public: 21 | CBeaconActivation(); 22 | ~CBeaconActivation(); 23 | 24 | bool AddEntry(char *pszHost, char *pszActivationBit, char *pszAnimationName); 25 | bool Load(); 26 | bool RemoveAll(); 27 | bool RemoveEntry(char *pszHost, char *pszActivationBit); 28 | BEACONACTIVATIONITEM **EntriesReference() { return &m_itemsHead; } 29 | BEACONACTIVATIONITEM *FindEntry(char *pszHost, char *pszActivationBit); 30 | BEACONACTIVATIONITEM *FindEntry(char *pszHost, uint8_t activationBit); 31 | BEACONACTIVATIONITEM *FirstEntry() { return m_itemsHead; } 32 | void Clear(); 33 | 34 | private: 35 | bool Save(); 36 | 37 | 38 | BEACONACTIVATIONITEM *m_itemsHead; // Linked list of beacon activations 39 | }; 40 | #endif 41 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/CBLEChannel.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | /* 5 | * Class implementing Bluetooth connectivity capability 6 | **/ 7 | #pragma once 8 | #include "EPXPlatform_CByteQueue.h" 9 | #include "CSerialChannelBase.h" 10 | #include "CBLEBeaconActivation.h" 11 | #include "EPXPlatform_BLE.h" 12 | #include "EPXGlobal.h" 13 | 14 | #define DEVICE_NAME_MAX_SIZE 18 // Max device name length 15 | 16 | 17 | 18 | // Bluetooth capability class 19 | class CBLEChannel : public CSerialChannelBase 20 | { 21 | public: 22 | CBLEChannel(); 23 | bool Initialize(char *pszDefaultBLEName); 24 | CByteQueue *SerialCache() { return &m_BLESerialCache; } 25 | char *GetDeviceName() { return m_BLEDeviceName; } 26 | char *GetRealizedDeviceName(); 27 | uint32_t GetLastBeaconReceived(); 28 | void Disconnect(); 29 | void SetAppInstance(void *pInst) { m_pAppInstance = pInst; } 30 | void SetBeaconActivation(bool on); 31 | void SetBeaconActivationEntries(BEACONACTIVATIONITEM ** ppBeaconActivationEntries); 32 | void SetDeviceName(char *pszName); 33 | void SetManufacturerPayload(uint8_t * pPayload, uint8_t cbPayload); 34 | void Start(); 35 | void UpdateAdvertisingDeviceData(); 36 | 37 | /**** CSerialChannelBase ****/ 38 | char *channelName() { return (char *) "BLE"; } 39 | int available() { return m_BLESerialCache.available(); } 40 | int read() { return m_BLESerialCache.pop(); } 41 | size_t write(void *pvPayload, uint16_t cb, bool altChannel); 42 | 43 | void SetPowerStateChangedHandler(PFN_EPX_POWERSTATE_CHANGED pfnEPXPowerStateChanged) { m_pfnEPXPowerStateChanged = pfnEPXPowerStateChanged; } 44 | void SetCommunicationsReadyHandler(PFN_EPX_COMMUNICATION_READY pfnEPXCommunicationReady) { m_pfnEPXCommunicationReady = pfnEPXCommunicationReady; } 45 | void SetConnectionStateChangedHandler(PFN_EPX_CONNECTIONSTATE_CHANGED pfnEPXConnectionStateChanged) { m_pfnEPXConnectionStateChanged = pfnEPXConnectionStateChanged; } 46 | void SetBeaconReceivedHandler(PFN_EPX_BEACONRECEIVED pfnEPXBeaconReceived) { m_pfnEPXBeaconReceived = pfnEPXBeaconReceived; } 47 | 48 | 49 | 50 | private: 51 | static void BLE_CommunicationReady(void *pinstance, bool altChannel); 52 | static void BLE_ConnectionStageChanged(void *pinstance, bool connected); 53 | static void BLE_ByteReceived(void *pinstance, bool altChannel, uint8_t data); 54 | static void BLE_BeaconReceived(void *pinstance, char *pszHost, uint8_t beaconData); 55 | 56 | CByteQueue m_BLESerialCache; // Queue of incoming received bytes 57 | char m_BLEDeviceName[BLEMAX_DEVICENAME]; // Device name 58 | void *m_pAppInstance; // Reference to host application class instance 59 | PFN_EPX_POWERSTATE_CHANGED m_pfnEPXPowerStateChanged; // Callback function for Power State Change 60 | PFN_EPX_COMMUNICATION_READY m_pfnEPXCommunicationReady; // Callback function for Communication Ready event 61 | PFN_EPX_CONNECTIONSTATE_CHANGED m_pfnEPXConnectionStateChanged; // Callback function for BLE Connection State Change 62 | PFN_EPX_BEACONRECEIVED m_pfnEPXBeaconReceived; // Callback function for BLE Beacon activation 63 | }; 64 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/CDisplayArray.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | /* 5 | * Class implementation for Display array 6 | **/ 7 | #pragma once 8 | #include 9 | #include 10 | #include "CLEDDriverBase.h" 11 | 12 | #define DISPLAYARRAY_BYTESPERPIXEL 3 13 | #define DISPLAYARRAY_DEFAULTBRIGHTNESS 25 14 | #define DISPLAYARRAY_MINBRIGHTNESS 5 15 | #define DISPLAYARRAY_CLEARTIMEOUT_MS 4000 16 | 17 | // Dimension structure 18 | typedef struct 19 | { 20 | uint8_t width; 21 | uint8_t height; 22 | } DISPLAYINFO; 23 | 24 | 25 | 26 | // Class definition for DisplayArray 27 | class CDisplayArray 28 | { 29 | public: 30 | CDisplayArray(); 31 | 32 | bool IsPowered() { return m_Powered; } 33 | inline int Width() { return m_width; } 34 | inline int Height() { return m_height; } 35 | uint8_t GetBrightness(); 36 | uint16_t TotalPixels() { return m_pLEDController->NumPixels(); } 37 | static inline uint32_t ColorFromBytes(uint8_t r, uint8_t g, uint8_t b) 38 | { 39 | return (uint32_t)(((uint32_t) r << 16) | ((uint32_t) g << 8) | ((uint32_t) b << 0)); 40 | } 41 | void Chase(bool reset); 42 | void Clear(); 43 | inline void GetPixelBytes(uint32_t color, uint8_t *pr, uint8_t *pg, uint8_t *pb) 44 | { 45 | *pr = (uint8_t)(color >> 16); 46 | *pg = (uint8_t)(color >> 8); 47 | *pb = (uint8_t)color; 48 | } 49 | void Initialize(CLEDDriverBase *pCLEDControllerBase, int width, int height, int powerPin = -1); 50 | void PreviewColor(uint32_t color); 51 | bool Process(); 52 | void RainbowCycle(uint8_t wait); 53 | void SetBrightness(uint8_t brightness, bool overrideClamp = false); 54 | void SetPixelColor(uint16_t i, uint32_t color); 55 | void SetPixelRGB(uint16_t i, uint8_t r, uint8_t g, uint8_t b); 56 | void ShowSingleFrame(char *pFrame, uint16_t pixelCount); 57 | void ShowSinglePixel(uint16_t idx, uint32_t color); 58 | void Show(bool fromClear = false); 59 | void PowerOff(); 60 | void PowerOn(); 61 | void PowerManagementReset(); 62 | 63 | private: 64 | CLEDDriverBase *m_pLEDController; // Reference to underlying display driver 65 | 66 | bool m_Powered; // True if display is powered on 67 | int m_nPowerPin; // GPIO pin for display hardware power module 68 | int m_nDataPin; // GPIO pin for display hardware data line 69 | int m_nClockPin; // GPIO pin for display hardware clock line 70 | int m_width, m_height; // Physical dimensions of display 71 | 72 | uint8_t m_brightness; // Current brightness of display 73 | 74 | uint32_t m_lastClearRequest; // Last time display was cleared 75 | 76 | // Chaser control 77 | int m_chaserPosition; // Chaser position 78 | }; 79 | 80 | 81 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/CDisplayTopology.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include "CDisplayTopology.h" 4 | 5 | 6 | 7 | uint16_t CDisplayTopology::MapRotated(uint16_t pos, int rotation) 8 | { 9 | if (pos < m_topologyPixels) 10 | { 11 | int srcX, srcY; 12 | 13 | srcY = pos / m_displayWidth; 14 | srcX = pos - (srcY * m_displayWidth); 15 | switch (rotation) 16 | { 17 | case 90: 18 | return m_pTopologyMatrix[((m_displayWidth - srcX - 1) * m_displayWidth) + srcY]; 19 | 20 | case 180: 21 | return m_pTopologyMatrix[((m_displayHeight - 1 - srcY) * m_displayWidth) + (m_displayWidth - 1 - srcX)]; 22 | 23 | case 270: 24 | return m_pTopologyMatrix[(srcX * m_displayWidth) + (m_displayHeight - srcY - 1)]; 25 | } 26 | return m_pTopologyMatrix[pos]; 27 | } 28 | return TOPOLOGYPIXEL_UNASSIGNED; 29 | } 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/CDisplayTopology.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include 5 | #include 6 | #include "CDisplayArray.h" 7 | 8 | #define TOPOLOGYPIXEL_UNASSIGNED 0xFFFF 9 | 10 | class CDisplayTopology 11 | { 12 | public: 13 | CDisplayTopology() 14 | { 15 | m_pTopologyMatrix = 0; 16 | } 17 | 18 | void SetMatrix(uint16_t *pTopologyMatrix, uint16_t displayWidth, uint16_t displayHeight) 19 | { 20 | m_pTopologyMatrix = pTopologyMatrix; 21 | m_displayWidth = displayWidth; 22 | m_displayHeight = displayHeight; 23 | m_topologyPixels = m_displayWidth * m_displayHeight; 24 | } 25 | 26 | 27 | 28 | inline uint16_t Map(uint16_t pos) 29 | { 30 | if (pos < m_topologyPixels) 31 | return m_pTopologyMatrix[pos]; 32 | return TOPOLOGYPIXEL_UNASSIGNED; 33 | } 34 | 35 | uint16_t MapRotated(uint16_t pos, int rotation); 36 | 37 | inline uint16_t TotalPixels() { return m_topologyPixels; } 38 | 39 | private: 40 | uint16_t m_displayWidth, m_displayHeight; 41 | uint16_t m_topologyPixels; 42 | uint16_t *m_pTopologyMatrix; 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/CLEDDriverBase.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include 5 | #include "stdlib.h" 6 | #include "string.h" 7 | #include "EPXPlatform_Runtime.h" 8 | 9 | 10 | #define DEFAULT_BRIGHTNESS 20 11 | 12 | typedef struct 13 | { 14 | uint8_t r; 15 | uint8_t g; 16 | uint8_t b; 17 | } LEDDRIVERPIXEL; 18 | 19 | 20 | 21 | class CLEDDriverBase 22 | { 23 | public: 24 | CLEDDriverBase(uint16_t numPixels) 25 | { 26 | m_brightness = DEFAULT_BRIGHTNESS; 27 | m_numPixels = numPixels; 28 | m_pPixels = NULL; 29 | } 30 | 31 | 32 | ~CLEDDriverBase() 33 | { 34 | if (m_pPixels != NULL) 35 | TFREE(m_pPixels); 36 | } 37 | 38 | virtual uint16_t NumPixels() { return m_numPixels; } 39 | virtual void SetPixel(uint16_t idx, uint8_t r, uint8_t g, uint8_t b) 40 | { 41 | if (idx < m_numPixels) 42 | { 43 | m_pPixels[idx].r = r; 44 | m_pPixels[idx].g = g; 45 | m_pPixels[idx].b = b; 46 | } 47 | } 48 | virtual void SetPixelColor(uint16_t idx, uint32_t color) 49 | { 50 | if (idx < m_numPixels) 51 | { 52 | m_pPixels[idx].r = (uint8_t)(color >> 16); 53 | m_pPixels[idx].g = (uint8_t)(color >> 8); 54 | m_pPixels[idx].b = (uint8_t) color; 55 | } 56 | } 57 | virtual void Initialize() 58 | { 59 | m_pPixels = (LEDDRIVERPIXEL *) TMALLOC(sizeof(LEDDRIVERPIXEL) * m_numPixels); 60 | if (m_pPixels != NULL) 61 | memset(m_pPixels, 0x00, sizeof(LEDDRIVERPIXEL) * m_numPixels); 62 | } 63 | 64 | virtual uint8_t GetBrightness() { return m_brightness; } 65 | 66 | virtual void SetBrightness(uint8_t brightness) { m_brightness = brightness; } 67 | 68 | virtual void Show() = 0; 69 | 70 | virtual void RainbowCycle(uint8_t wait) = 0; 71 | 72 | 73 | virtual void Clear() 74 | { 75 | memset(m_pPixels, 0x00, sizeof(LEDDRIVERPIXEL) * m_numPixels); 76 | } 77 | uint32_t IntColor(uint8_t r, uint8_t g, uint8_t b) { return ((uint32_t)r << 16) | ((uint32_t)g << 8) | b; } 78 | 79 | protected: 80 | LEDDRIVERPIXEL *m_pPixels; 81 | uint8_t m_brightness; 82 | uint16_t m_numPixels; 83 | }; 84 | 85 | 86 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/COBSCodec.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * StuffData byte stuffs "length" bytes of data 3 | * at the location pointed to by "ptr", writing 4 | * the output to the location pointed to by "dst". 5 | * 6 | * Returns the length of the encoded data. 7 | */ 8 | #include "COBSCodec.h" 9 | 10 | /* Copyright 2011, Jacques Fortier. All rights reserved. 11 | * https://github.com/jacquesf/COBS-Consistent-Overhead-Byte-Stuffing 12 | * Redistribution and use in source and binary forms are permitted, with or without modification. 13 | */ 14 | #include 15 | #include 16 | 17 | /* Stuffs "length" bytes of data at the location pointed to by 18 | * "input", writing the output to the location pointed to by 19 | * "output". Returns the number of bytes written to "output". 20 | * 21 | * Remove the "restrict" qualifiers if compiling with a 22 | * pre-C99 C dialect. 23 | * 24 | */ 25 | size_t COBS_Encode(const uint8_t * input, size_t length, uint8_t * output) 26 | { 27 | size_t read_index = 0; 28 | size_t write_index = 1; 29 | size_t code_index = 0; 30 | uint8_t code = 1; 31 | 32 | while (read_index < length) 33 | { 34 | if (input[read_index] == 0) 35 | { 36 | output[code_index] = code; 37 | code = 1; 38 | code_index = write_index++; 39 | read_index++; 40 | } 41 | else 42 | { 43 | output[write_index++] = input[read_index++]; 44 | code++; 45 | if (code == 0xFF) 46 | { 47 | output[code_index] = code; 48 | code = 1; 49 | code_index = write_index++; 50 | } 51 | } 52 | } 53 | 54 | output[code_index] = code; 55 | 56 | return write_index; 57 | } 58 | 59 | /* Unstuffs "length" bytes of data at the location pointed to by 60 | * "input", writing the output * to the location pointed to by 61 | * "output". Returns the number of bytes written to "output" if 62 | * "input" was successfully unstuffed, and 0 if there was an 63 | * error unstuffing "input". 64 | * 65 | * Remove the "restrict" qualifiers if compiling with a 66 | * pre-C99 C dialect. 67 | */ 68 | size_t COBS_Decode(const uint8_t * input, size_t length, uint8_t * output) 69 | { 70 | size_t read_index = 0; 71 | size_t write_index = 0; 72 | uint8_t code; 73 | uint8_t i; 74 | 75 | while (read_index < length) 76 | { 77 | code = input[read_index]; 78 | 79 | if (read_index + code > length && code != 1) 80 | return 0; 81 | 82 | read_index++; 83 | 84 | for (i = 1; i < code; i++) 85 | output[write_index++] = input[read_index++]; 86 | if (code != 0xFF && read_index != length) 87 | output[write_index++] = '\0'; 88 | } 89 | 90 | return write_index; 91 | } -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/COBSCodec.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | extern "C" 9 | { 10 | size_t COBS_Encode(const uint8_t * input, size_t length, uint8_t * output); 11 | size_t COBS_Decode(const uint8_t * input, size_t length, uint8_t * output); 12 | 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/CSerialChannel.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include "EPXPlatform_CByteQueue.h" 5 | #include "CSerialChannelBase.h" 6 | 7 | #define SERIALCHANNEL_PURGE_THRESHOLD (BYTEQUEUEBUFFERSIZE / 2) 8 | 9 | class CSerialChannel : public CSerialChannelBase 10 | { 11 | public: 12 | CSerialChannel() {} 13 | 14 | CByteQueue *SerialCache() { return &m_SerialCache; } 15 | 16 | /**** CSerialChannelBase ****/ 17 | char *channelName() { return (char *) "Serial"; } 18 | int available() { return m_SerialCache.available(); } 19 | int read() { return m_SerialCache.pop(); } 20 | size_t write(void *pvPayload, uint16_t cb); 21 | 22 | private: 23 | CByteQueue m_SerialCache; 24 | }; 25 | 26 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/CSerialChannelBase.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include 5 | #include 6 | 7 | class CSerialChannelBase 8 | { 9 | public: 10 | virtual char *channelName() = 0; 11 | virtual int available() = 0; 12 | virtual int read() = 0; 13 | virtual size_t write(void *pvPayload, uint16_t cb, bool altChannel) = 0; 14 | }; 15 | 16 | 17 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/CStringProtocol.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include 4 | #include "EPXApp.h" 5 | #include "EPXPlatform_Runtime.h" 6 | #include "CStringProtocol.h" 7 | 8 | EPX_OPTIMIZEFORDEBUGGING_ON 9 | 10 | CStringProtocol::CStringProtocol() 11 | { 12 | m_stringBuilderLength = 0; 13 | } 14 | 15 | 16 | 17 | void CStringProtocol::Reset() 18 | { 19 | m_stringBuilderLength = 0; 20 | StringPayloadReset(); 21 | } 22 | 23 | 24 | int g_cntr = 0; 25 | 26 | void CStringProtocol::StringProtocolProcess() 27 | { 28 | if (m_pCActiveStringProtocolSerialChannel != NULL) 29 | { 30 | while (m_pCActiveStringProtocolSerialChannel->available()) 31 | { 32 | char cVal = m_pCActiveStringProtocolSerialChannel->read(); 33 | if (cVal == 0x00) 34 | { 35 | if (++g_cntr == 3) 36 | g_cntr++; 37 | StringPayloadFinalized(); 38 | Reset(); 39 | } 40 | else 41 | { 42 | StringPayloadParse(cVal); 43 | 44 | // If the max length of the stringbuilder has been reached just reset the process 45 | if (m_stringBuilderLength == MAX_STRING_PROTOCOL_LENGTH - 1) 46 | Reset(); 47 | else 48 | m_stringBuilderLength++; 49 | } 50 | } 51 | } 52 | } 53 | 54 | 55 | 56 | void CStringProtocol::StringProtocolSend(uint8_t *payload, uint16_t payloadLength) 57 | { 58 | m_pCActiveStringProtocolSerialChannel->write(payload, payloadLength, true); 59 | } 60 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/CStringProtocol.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "CSerialChannelBase.h" 3 | 4 | #define MAX_STRING_PROTOCOL_LENGTH 237 5 | 6 | class CStringProtocol 7 | { 8 | public: 9 | CStringProtocol(); 10 | 11 | void Reset(); 12 | void SetActiveStringProtocolSerialChannel(CSerialChannelBase *pCSerialChannelBase) { m_pCActiveStringProtocolSerialChannel = pCSerialChannelBase; } 13 | void StringProtocolProcess(); 14 | void StringProtocolSend(uint8_t *payload, uint16_t payloadLength); 15 | 16 | virtual void StringPayloadFinalized() {} 17 | virtual void StringPayloadParse(uint8_t data) {} 18 | virtual void StringPayloadReset() {} 19 | 20 | private: 21 | CSerialChannelBase *m_pCActiveStringProtocolSerialChannel; // Reference to active serial channel class 22 | uint16_t m_stringBuilderLength; 23 | }; 24 | 25 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/CUSBChannel.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include "EPXPlatform_Runtime.h" 4 | #include "EPXPlatform_USB.h" 5 | #include "CUSBChannel.h" 6 | 7 | EPX_OPTIMIZEFORDEBUGGING_ON 8 | 9 | CUSBChannel::CUSBChannel() 10 | { 11 | m_pfnEPXPowerStateChanged = NULL; 12 | m_pfnEPXConnectionStateChanged = NULL; 13 | m_pfnPurgeRequestHandler = NULL; 14 | } 15 | 16 | 17 | 18 | bool CUSBChannel::Initialize() 19 | { 20 | return EPXPlatform_USB_Initialize(this, USB_PowerStageChanged, USB_ConnectionStageChanged, USB_CommunicationReady, USB_ByteReceived); 21 | } 22 | 23 | 24 | 25 | void CUSBChannel::SetDeviceName(char *pszName) 26 | { 27 | EPXPlatform_USB_SetDeviceName(pszName); 28 | } 29 | 30 | 31 | 32 | void CUSBChannel::Activate() 33 | { 34 | EPXPlatform_USB_Activate(); 35 | } 36 | 37 | 38 | 39 | 40 | void CUSBChannel::Process() 41 | { 42 | EPXPlatform_USB_Process(); 43 | } 44 | 45 | 46 | 47 | void CUSBChannel::USB_ByteReceived(void *pinstance, uint8_t data) 48 | { 49 | CUSBChannel *pthis = (CUSBChannel *) pinstance; 50 | pthis->m_ByteCache.push(data); 51 | 52 | // Force processing if cache growing beyond threshold 53 | if(pthis->m_ByteCache.available() > USBCHANNEL_PURGE_THRESHOLD) 54 | { 55 | DEBUGLOGLN("ExpressivePixelsSerialChannelCache FORCE FLUSH %d", pthis->m_ByteCache.available()); 56 | (*pthis->m_pfnPurgeRequestHandler)(pthis); 57 | } 58 | } 59 | 60 | 61 | 62 | size_t CUSBChannel::write(void *pvPayload, uint16_t cb, bool altChannel) 63 | { 64 | return EPXPlatform_USB_Write((uint8_t *)pvPayload, cb); 65 | } 66 | 67 | 68 | 69 | void CUSBChannel::USB_PowerStageChanged(void *pinstance, bool connected) 70 | { 71 | CUSBChannel *pthis = (CUSBChannel *) pinstance; 72 | 73 | if (connected) 74 | (*pthis->m_pfnEPXPowerStateChanged)(pthis->m_pAppInstance, EPXAPP_POWERSTATE_ON_USB, true); 75 | else 76 | (*pthis->m_pfnEPXPowerStateChanged)(pthis->m_pAppInstance, EPXAPP_POWERSTATE_ON_USB, false); 77 | } 78 | 79 | 80 | 81 | void CUSBChannel::USB_ConnectionStageChanged(void *pinstance, bool connected) 82 | { 83 | CUSBChannel *pthis = (CUSBChannel *) pinstance; 84 | 85 | if (connected) 86 | (*pthis->m_pfnEPXConnectionStateChanged)(pthis->m_pAppInstance, EPXAPP_CONNECTIONCHANNEL_USB, true); 87 | else 88 | (*pthis->m_pfnEPXConnectionStateChanged)(pthis->m_pAppInstance, EPXAPP_CONNECTIONCHANNEL_USB, false); 89 | } 90 | 91 | 92 | 93 | void CUSBChannel::USB_CommunicationReady(void *pinstance) 94 | { 95 | CUSBChannel *pthis = (CUSBChannel *) pinstance; 96 | (*pthis->m_pfnEPXCommunicationReady)(pthis->m_pAppInstance, false); 97 | } 98 | 99 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/CUSBChannel.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include "EPXPlatform_CByteQueue.h" 5 | #include "CSerialChannelBase.h" 6 | #include "EPXGlobal.h" 7 | 8 | #define USBCHANNEL_PURGE_THRESHOLD (BYTEQUEUEBUFFERSIZE / 2) 9 | 10 | typedef void(*PFN_EPXUSBCHANNNEL_PURGEREQUEST)(void *pinstance); 11 | 12 | 13 | class CUSBChannel : public CSerialChannelBase 14 | { 15 | public: 16 | CUSBChannel(); 17 | 18 | bool Initialize(); 19 | CByteQueue *SerialCache() { return &m_ByteCache; } 20 | void Activate(); 21 | void Process(); 22 | void SetDeviceName(char *pszName); 23 | void SetAppInstance(void *pInst) { m_pAppInstance = pInst; } 24 | 25 | /**** CSerialChannelBase ****/ 26 | char *channelName() { return (char *) "USB"; } 27 | int available() { return m_ByteCache.available(); } 28 | int read() { return m_ByteCache.pop(); } 29 | size_t write(void *pvPayload, uint16_t cb, bool altChannel); 30 | 31 | 32 | void SetPowerStateChangedHandler(PFN_EPX_POWERSTATE_CHANGED pfnEPXPowerStateChanged) { m_pfnEPXPowerStateChanged = pfnEPXPowerStateChanged; } 33 | void SetConnectionStateChangedHandler(PFN_EPX_CONNECTIONSTATE_CHANGED pfnEPXConnectionStateChanged) { m_pfnEPXConnectionStateChanged = pfnEPXConnectionStateChanged; } 34 | void SetCommunicationReadyHandler(PFN_EPX_COMMUNICATION_READY pfnEPXCommunicationReady) { m_pfnEPXCommunicationReady = pfnEPXCommunicationReady; } 35 | void SetPurgeRequestHandler(PFN_EPXUSBCHANNNEL_PURGEREQUEST pfnPurgeRequestHandler) { m_pfnPurgeRequestHandler = pfnPurgeRequestHandler; } 36 | 37 | 38 | 39 | private: 40 | static void USB_ConnectionStageChanged(void *pinstance, bool connected); 41 | static void USB_PowerStageChanged(void *pinstance, bool connected); 42 | static void USB_ByteReceived(void *pinstance, uint8_t data); 43 | static void USB_CommunicationReady(void *pinstance); 44 | 45 | void *m_pAppInstance; 46 | PFN_EPX_POWERSTATE_CHANGED m_pfnEPXPowerStateChanged; 47 | PFN_EPX_CONNECTIONSTATE_CHANGED m_pfnEPXConnectionStateChanged; 48 | PFN_EPX_COMMUNICATION_READY m_pfnEPXCommunicationReady; 49 | PFN_EPXUSBCHANNNEL_PURGEREQUEST m_pfnPurgeRequestHandler; 50 | CByteQueue m_ByteCache; 51 | }; 52 | 53 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/EPXAPP_CStorage.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include "EPXString.h" 5 | #include "EPXPlatform_CStorage.h" 6 | #include "CAnimationManager.h" 7 | 8 | #define SETTINGS_FILENAME "SETTINGS.JSON" 9 | 10 | #define STORAGEMANAGER_WRITECACHESIZE 512 11 | 12 | 13 | enum UpdateSequenceListOperations : uint8_t 14 | { 15 | UPDATESEQUENCELIST_ADDORUPDATE, 16 | UPDATESEQUENCELIST_DELETE 17 | }; 18 | 19 | typedef struct 20 | { 21 | PPERSISTED_SEQUENCE_LIST pSequenceListHead; 22 | PPERSISTED_SEQUENCE_LIST pSequenceListCurrent; 23 | } AUTOPLAYPLAYLIST, *PAUTOPLAYPLAYLIST; 24 | 25 | 26 | 27 | class CExpressivePixelsStorage 28 | { 29 | public: 30 | CExpressivePixelsStorage(); 31 | ~CExpressivePixelsStorage(); 32 | 33 | void AutoPlaylistClear(); 34 | void Initialize(bool format = false); 35 | void EnumerateSequencesJSON(EPXString &response, uint32_t activeTransactionID, char *pszInnerContainerObject = NULL); 36 | bool AutoPlaylistIterate(bool playOnce = false, bool *pbRestarted = NULL); 37 | bool IsAutoPlayActive() { return m_pAutoPlayList != NULL; } 38 | bool DeleteFile(const char *pszFilename); 39 | bool EnumerateAutoPlaylist(); 40 | bool Format(); 41 | bool SequenceDelete(char *pszGUID); 42 | bool SequenceRead(const char *pszGUID, EXPRESSIVEPIXEL_SEQUENCE *pSequence, bool playFromFile = false); 43 | bool SequenceWriteData(EXPRESSIVEPIXEL_SEQUENCE *pSequence, void *pBuf, uint16_t cb); 44 | bool SequenceWriteCacheFlush(EXPRESSIVEPIXEL_SEQUENCE *pSequence); 45 | 46 | bool SequenceWriteSection(EXPRESSIVEPIXEL_SEQUENCE *pSequence, uint8_t section = 0, uint8_t *pData = NULL, uint16_t cb = 0); 47 | bool SequenceWriteToken(EXPRESSIVEPIXEL_SEQUENCE *pSequence, uint8_t token); 48 | 49 | char *SequenceIDFromName(char *pszName); 50 | char *SequenceReadTokenString(void *pFile, uint8_t tokenType); 51 | PPERSISTED_SEQUENCE_LIST AutoPlaylistCurrent(); 52 | PPERSISTED_SEQUENCE_LIST FirstStoredSequence() { return m_pSequenceFileListHead; } 53 | 54 | uint16_t SequenceReadTokenData(void *pFile, uint8_t tokenType, void *pData, uint16_t cb); 55 | 56 | static void Power(bool on); 57 | void SequenceClose(void *pFile); 58 | void *SequenceOpen(const char *pszFilename, int *fileSize = NULL); 59 | void SequenceWriteClose(EXPRESSIVEPIXEL_SEQUENCE *pSequence); 60 | void SetReadDirectFromFile(bool bDirect) { m_bForceDirectFromFile = bDirect; } 61 | 62 | private: 63 | CStorage m_CStorage; 64 | PPERSISTED_SEQUENCE_LIST m_pSequenceFileListHead = NULL; 65 | 66 | bool ReadBytes(void *pFile, uint32_t *pFileSize, uint8_t *pBuf, uint32_t cbToRead); 67 | bool SequenceReadTokenTraverse(void *pFile, uint8_t tokenType, uint32_t originalFileSize, uint32_t *pFileSize, uint32_t *pSkipBytes); 68 | bool SequenceWriteTokenAndData(void *pFile, uint8_t token, void *pBuf, uint16_t cb); 69 | PPERSISTED_SEQUENCE_LIST EnumerateSequences(); 70 | EPXString SequenceFilenameFromID(const char *pszGUID, int cb = 0); 71 | void UpdateSequenceList(UpdateSequenceListOperations operation, char *pszGUID, char *pszName = NULL, uint16_t size = 0, uint32_t utc = 0); 72 | void UpdateSequenceListItem(PPERSISTED_SEQUENCE_LIST pItem, char *pszGUID, char *pszName, uint16_t size, uint32_t utc); 73 | 74 | bool m_bForceDirectFromFile; 75 | uint8_t m_writeCache[STORAGEMANAGER_WRITECACHESIZE]; 76 | uint16_t m_writeCachePosition; 77 | uint32_t m_cbTotalBytesWritten; 78 | PAUTOPLAYPLAYLIST m_pAutoPlayList; 79 | }; 80 | 81 | 82 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/EPXApp_ITriggerSource.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include 5 | #include 6 | #include "EPXString.h" 7 | 8 | typedef void(*PFN_ACIVATE_ANIMATION)(void *pContext, char *pszAnimationName, uint8_t triggerPowerMode); 9 | 10 | class ITriggerSource 11 | { 12 | public: 13 | virtual void Initialize() = 0; 14 | virtual void Process() = 0; 15 | virtual bool ConsoleCommandProcess(const char *pszCommand, bool *pbResponseSuccess, EPXString &innerResponse) = 0; 16 | virtual EPXString AppendConsoleHelpSyntax() = 0; 17 | virtual void SetAnimationActivationHandler(void *pEPXHost, PFN_ACIVATE_ANIMATION pfnActivateAnimation) = 0; 18 | virtual void SetTraceEventHandler(void *pEPXHost, PFN_EPX_TRACE_EVENT pfnTraceEvent) = 0; 19 | }; 20 | 21 | 22 | typedef struct _tagTriggerSourceItem 23 | { 24 | ITriggerSource *pITriggerSource; 25 | struct _tagTriggerSourceItem *pNext; 26 | } TRIGGERSOURCEITEM; 27 | 28 | 29 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/EPXApp_MIDI.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include "EPXPlatform_Runtime.h" 5 | #include "EPXGlobal.h" 6 | #include "EPXApp_ITriggerSource.h" 7 | 8 | #ifdef EPXMIDI 9 | 10 | #define MIDIACTIVATION_ENTRY_FILENAME "MIDIActivations.dat" 11 | 12 | typedef struct _tagMIDIActivationItem 13 | { 14 | uint8_t channel; 15 | uint8_t note; 16 | char szAnimationName[32]; 17 | struct _tagMIDIActivationItem *pNext; 18 | } MIDIACTIVATIONITEM; 19 | 20 | 21 | 22 | 23 | class CMIDIActivation 24 | { 25 | public: 26 | CMIDIActivation(); 27 | ~CMIDIActivation(); 28 | 29 | bool AddEntry(char *pszHost, char *pszActivationBit, char *pszAnimationName); 30 | bool Load(); 31 | bool RemoveAll(); 32 | bool RemoveEntry(char *pszHost, char *pszActivationBit); 33 | MIDIACTIVATIONITEM **EntriesReference() { return &m_itemsHead; } 34 | MIDIACTIVATIONITEM *FindEntry(char *pszHost, char *pszNote); 35 | MIDIACTIVATIONITEM *FindEntry(uint8_t channel, uint8_t note); 36 | MIDIACTIVATIONITEM *FirstEntry() { return m_itemsHead; } 37 | void Initialize(); 38 | void Clear(); 39 | void Process(); 40 | void SetAnimationActivationHandler(void *pEPXHost, PFN_ACIVATE_ANIMATION pfnActivateAnimation); 41 | void SetTraceEventHandler(void *pEPXHost, PFN_EPX_TRACE_EVENT pfnTraceEvent); 42 | void SetTrace(bool on); 43 | 44 | private: 45 | bool Save(); 46 | 47 | static void NoteOff(uint8_t inChannel, uint8_t inNumber, uint8_t inVelocity); 48 | static void NoteOn(uint8_t inChannel, uint8_t inNumber, uint8_t inVelocity); 49 | 50 | bool m_bTracing; 51 | MIDIACTIVATIONITEM *m_itemsHead; 52 | PFN_ACIVATE_ANIMATION m_pfnActivateAnimation; 53 | PFN_EPX_TRACE_EVENT m_pfnTraceEvent; 54 | }; 55 | #endif 56 | 57 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/EPXApp_Trigger_Switch.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include "EPXPlatform_Runtime.h" 5 | #include "EPXGlobal.h" 6 | #include "EPXApp_ITriggerSource.h" 7 | 8 | #define TTYTOKEN_SWITCHACTIVATION F("SWITCHACTIVATION") 9 | #define SWITCHACTIVATION_ENTRY_FILENAME "SwitchActivations.dat" 10 | #define TRIGGERSWITCH_DEBOUNCE_MILLIS 1000 11 | 12 | typedef void(*PFN_ACIVATE_ANIMATION)(void *pContext, char *pszAnimationName, uint8_t triggerPowerMode); 13 | 14 | 15 | typedef struct _tagSwitchTriggerActivationItem 16 | { 17 | uint16_t gpioPin; 18 | const char *pszPin; 19 | char szAnimationName[32]; 20 | uint32_t triggerTime; 21 | struct _tagSwitchTriggerActivationItem *pNext; 22 | } SWITCHACTIVATIONITEM; 23 | 24 | 25 | 26 | 27 | class CSwitchActivation : public ITriggerSource 28 | { 29 | public: 30 | CSwitchActivation(); 31 | ~CSwitchActivation(); 32 | 33 | 34 | void Initialize(); 35 | void Process(); 36 | virtual bool ConsoleCommandProcess(const char *pszCommand, bool *pbResponseSuccess, EPXString &innerResponse); 37 | EPXString AppendConsoleHelpSyntax(); 38 | 39 | bool AddEntry(char *pszPin, char *pszAnimationName); 40 | bool Load(); 41 | bool RemoveAll(); 42 | bool RemoveEntry(char *pszPin); 43 | SWITCHACTIVATIONITEM **EntriesReference() { return &m_itemsHead; } 44 | SWITCHACTIVATIONITEM *FindEntry(uint16_t gpioPin); 45 | SWITCHACTIVATIONITEM *FirstEntry() { return m_itemsHead; } 46 | 47 | static void SubsystemInitialize(int numMappings, SWITCHACTIVATION_GPIOBUTTON_MAPPING *pMappings); 48 | void Clear(); 49 | void SetAnimationActivationHandler(void *pEPXHost, PFN_ACIVATE_ANIMATION pfnActivateAnimation); 50 | void SetTraceEventHandler(void *pEPXHost, PFN_EPX_TRACE_EVENT pfnTraceEvent); 51 | void SetTrace(bool on); 52 | 53 | private: 54 | bool Save(); 55 | static void SystemGPIOEventHandler(void *pinstance, uint8_t event, uint16_t pin, uint16_t value); 56 | SWITCHACTIVATION_GPIOBUTTON_MAPPING *MapLogicalPin(char *pszPin); 57 | SWITCHACTIVATION_GPIOBUTTON_MAPPING *MapPhysicalPin(uint16_t pin); 58 | 59 | bool m_bTracing; 60 | SWITCHACTIVATIONITEM *m_itemsHead; 61 | PFN_ACIVATE_ANIMATION m_pfnActivateAnimation; 62 | PFN_EPX_TRACE_EVENT m_pfnTraceEvent; 63 | uint8_t m_queuedButtonPin; 64 | }; 65 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/EPXGlobal.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include "EPXPlatform_Runtime.h" 5 | 6 | typedef struct 7 | { 8 | uint8_t guid[16]; 9 | } EPX_GUID; 10 | 11 | 12 | typedef struct 13 | { 14 | const char *pszPinName; 15 | uint16_t gpioPin; 16 | } SWITCHACTIVATION_GPIOBUTTON_MAPPING; 17 | 18 | 19 | enum ConnectionChannel 20 | { 21 | EPXAPP_CONNECTIONCHANNEL_NONE = 0x0, 22 | EPXAPP_CONNECTIONCHANNEL_USB = 0x1, 23 | EPXAPP_CONNECTIONCHANNEL_BLE = 0x2 24 | }; 25 | 26 | 27 | 28 | enum PowerStates 29 | { 30 | EPXAPP_POWERSTATE_NONE = 0x0, 31 | EPXAPP_POWERSTATE_ON_USB = 0x1, 32 | EPXAPP_POWERSTATE_ON_BLE = 0x2 33 | }; 34 | 35 | 36 | 37 | typedef void(*PFN_EPX_TRACE_EVENT)(void *pinstance, char *pszTrace); 38 | typedef void(*PFN_EPX_POWERSTATE_CHANGED)(void *pinstance, uint8_t state, bool set); 39 | typedef void(*PFN_EPX_COMMUNICATION_READY)(void *pinstance, bool altChannel); 40 | typedef void(*PFN_EPX_CONNECTIONSTATE_CHANGED)(void *pinstance, uint8_t state, bool set); 41 | typedef void(*PFN_EPX_BEACONRECEIVED)(void *pinstance, char *pszHost, uint8_t beaconData); 42 | 43 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/EPXString.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | 10 | class EPXString 11 | { 12 | public: 13 | EPXString() 14 | { 15 | Reset(); 16 | } 17 | 18 | 19 | 20 | EPXString(const EPXString &__str) 21 | { 22 | Reset(); 23 | assign(__str); 24 | } 25 | 26 | 27 | 28 | 29 | EPXString(const char* __s) 30 | { 31 | Reset(); 32 | assign(__s); 33 | } 34 | 35 | 36 | 37 | EPXString(char* psz) 38 | { 39 | Reset(); 40 | assign(psz); 41 | } 42 | 43 | 44 | 45 | EPXString(int val) 46 | { 47 | Reset(); 48 | 49 | char szFmt[16]; 50 | itoa(val, szFmt, 10); 51 | assign(szFmt); 52 | } 53 | 54 | 55 | 56 | 57 | ~EPXString() 58 | { 59 | free(); 60 | } 61 | 62 | 63 | 64 | 65 | const char* c_str() { return m_psz; } 66 | 67 | 68 | const int length() { return m_len; } 69 | 70 | 71 | EPXString& append(const EPXString& __str) 72 | { 73 | return append(__str.m_psz); 74 | } 75 | 76 | 77 | 78 | EPXString& operator+=(const EPXString& __str) 79 | { 80 | return this->append(__str); 81 | } 82 | 83 | 84 | 85 | EPXString& operator+(const EPXString& __str) 86 | { 87 | return this->append(__str); 88 | } 89 | 90 | 91 | 92 | EPXString& operator+=(const char *__str) 93 | { 94 | return this->append(__str); 95 | } 96 | 97 | 98 | 99 | EPXString& operator+=(char *psz) 100 | { 101 | return this->append(psz); 102 | } 103 | 104 | 105 | 106 | EPXString& operator=(const EPXString& __s) 107 | { 108 | return assign(__s); 109 | } 110 | 111 | 112 | 113 | EPXString& operator=(char *psz) 114 | { 115 | return assign(psz); 116 | } 117 | 118 | 119 | 120 | void Reset() 121 | { 122 | m_len = 0; 123 | m_psz = NULL; 124 | } 125 | 126 | 127 | void free() 128 | { 129 | if (m_psz != NULL) 130 | { 131 | TFREE(m_psz); 132 | m_psz = NULL; 133 | } 134 | } 135 | 136 | 137 | EPXString& append(const char *psz) 138 | { 139 | char *pszNew; 140 | int __len = strlen(psz) + this->m_len; 141 | 142 | pszNew = (char *) TMALLOC(__len + 1); 143 | *pszNew = 0x00; 144 | 145 | if (m_psz != NULL) 146 | strcpy(pszNew, m_psz); 147 | strcat(pszNew, psz); 148 | 149 | if (m_psz != NULL) 150 | TFREE(m_psz); 151 | m_psz = pszNew; 152 | m_len = __len; 153 | return *this; 154 | } 155 | 156 | 157 | 158 | private: 159 | 160 | EPXString& assign(const EPXString& __str) 161 | { 162 | free(); 163 | 164 | m_len = __str.m_len; 165 | m_psz = (char *) TMALLOC(m_len + 1); 166 | if (m_psz != NULL) 167 | strcpy(m_psz, __str.m_psz); 168 | return *this; 169 | } 170 | 171 | 172 | 173 | EPXString& assign(const char *psz) 174 | { 175 | free(); 176 | 177 | m_len = strlen(psz); 178 | m_psz = (char *) TMALLOC(m_len + 1); 179 | if (m_psz != NULL) 180 | strcpy(m_psz, psz); 181 | return *this; 182 | } 183 | 184 | 185 | 186 | char *m_psz; 187 | int m_len; 188 | }; 189 | 190 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/JsonListener.h: -------------------------------------------------------------------------------- 1 | /**The MIT License (MIT) 2 | 3 | Copyright (c) 2015 by Daniel Eichhorn 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | See more at http://blog.squix.ch and https://github.com/squix78/json-streaming-parser 24 | */ 25 | 26 | #pragma once 27 | 28 | class JsonListener { 29 | private: 30 | 31 | public: 32 | 33 | virtual void whitespace(char c) = 0; 34 | 35 | virtual void startDocument() = 0; 36 | 37 | virtual void key(char *key) = 0; 38 | 39 | virtual void value(char *value) = 0; 40 | 41 | virtual void endArray() = 0; 42 | 43 | virtual void endObject() = 0; 44 | 45 | virtual void endDocument() = 0; 46 | 47 | virtual void startArray() = 0; 48 | 49 | virtual void startObject() = 0; 50 | 51 | virtual void byteAsHexValue(char *value) = 0; 52 | 53 | }; 54 | 55 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/README.md: -------------------------------------------------------------------------------- 1 | Welcome to the Microsoft Expressive Pixels project!! 2 | 3 | Please be sure to visit the Wiki at https://github.com/microsoft/ExpressivePixels/wiki 4 | to learn more about how to integrate Expressive Pixels capabilities in your own creations. -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsCore/library.properties: -------------------------------------------------------------------------------- 1 | name=ExpressivePixels Core 2 | version=1.0.1 3 | author=Microsoft 4 | maintainer=ExpressivePixels 5 | sentence=ExpressivePixels Core Library 6 | paragraph=ExpressivePixels Core Library 7 | category=Display 8 | url=https://github.com/microsoft/ExpressivePixels 9 | architectures=* 10 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsMIDI/midi_Message.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * @file midi_Message.h 3 | * Project Arduino MIDI Library 4 | * @brief MIDI Library for the Arduino - Message struct definition 5 | * @author Francois Best 6 | * @date 11/06/14 7 | * @license MIT - Copyright (c) 2015 Francois Best 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | 28 | #pragma once 29 | 30 | #include "midi_Namespace.h" 31 | #include "midi_Defs.h" 32 | 33 | BEGIN_MIDI_NAMESPACE 34 | 35 | /*! The Message structure contains decoded data of a MIDI message 36 | read from the serial port with read() 37 | */ 38 | template 39 | struct Message 40 | { 41 | /*! Default constructor 42 | \n Initializes the attributes with their default values. 43 | */ 44 | inline Message() 45 | : channel(0) 46 | , type(midi::InvalidType) 47 | , data1(0) 48 | , data2(0) 49 | , valid(false) 50 | { 51 | memset(sysexArray, 0, sSysExMaxSize * sizeof(DataByte)); 52 | } 53 | 54 | /*! The maximum size for the System Exclusive array. 55 | */ 56 | static const unsigned sSysExMaxSize = SysExMaxSize; 57 | 58 | /*! The MIDI channel on which the message was recieved. 59 | \n Value goes from 1 to 16. 60 | */ 61 | Channel channel; 62 | 63 | /*! The type of the message 64 | (see the MidiType enum for types reference) 65 | */ 66 | MidiType type; 67 | 68 | /*! The first data byte. 69 | \n Value goes from 0 to 127. 70 | */ 71 | DataByte data1; 72 | 73 | /*! The second data byte. 74 | If the message is only 2 bytes long, this one is null. 75 | \n Value goes from 0 to 127. 76 | */ 77 | DataByte data2; 78 | 79 | /*! System Exclusive dedicated byte array. 80 | \n Array length is stocked on 16 bits, 81 | in data1 (LSB) and data2 (MSB) 82 | */ 83 | DataByte sysexArray[sSysExMaxSize]; 84 | 85 | /*! This boolean indicates if the message is valid or not. 86 | There is no channel consideration here, 87 | validity means the message respects the MIDI norm. 88 | */ 89 | bool valid; 90 | 91 | inline unsigned getSysExSize() const 92 | { 93 | const unsigned size = unsigned(data2) << 8 | data1; 94 | return size > sSysExMaxSize ? sSysExMaxSize : size; 95 | } 96 | }; 97 | 98 | END_MIDI_NAMESPACE 99 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsMIDI/midi_Namespace.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * @file midi_Namespace.h 3 | * Project Arduino MIDI Library 4 | * @brief MIDI Library for the Arduino - Namespace declaration 5 | * @author Francois Best 6 | * @date 24/02/11 7 | * @license MIT - Copyright (c) 2015 Francois Best 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | 28 | #pragma once 29 | 30 | #define MIDI_NAMESPACE midi 31 | #define BEGIN_MIDI_NAMESPACE namespace MIDI_NAMESPACE { 32 | #define END_MIDI_NAMESPACE } 33 | 34 | #define USING_NAMESPACE_MIDI using namespace MIDI_NAMESPACE; 35 | 36 | BEGIN_MIDI_NAMESPACE 37 | 38 | END_MIDI_NAMESPACE 39 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsMIDI/midi_RingBuffer.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * @file midi_RingBuffer.h 3 | * Project Arduino MIDI Library 4 | * @brief MIDI Library for Arduino - Ring Buffer 5 | * @author Francois Best 6 | * @date 10/10/2016 7 | * @license MIT - Copyright (c) 2016 Francois Best 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | 28 | #pragma once 29 | 30 | #include "midi_Namespace.h" 31 | 32 | BEGIN_MIDI_NAMESPACE 33 | 34 | template 35 | class RingBuffer 36 | { 37 | public: 38 | RingBuffer(); 39 | ~RingBuffer(); 40 | 41 | public: 42 | int getLength() const; 43 | bool isEmpty() const; 44 | 45 | public: 46 | void write(DataType inData); 47 | void write(const DataType* inData, int inSize); 48 | void clear(); 49 | 50 | public: 51 | DataType read(); 52 | void read(DataType* outData, int inSize); 53 | 54 | private: 55 | DataType mData[Size]; 56 | DataType* mWriteHead; 57 | DataType* mReadHead; 58 | }; 59 | 60 | END_MIDI_NAMESPACE 61 | 62 | #include "midi_RingBuffer.hpp" 63 | -------------------------------------------------------------------------------- /Firmware/ExpressivePixelsMIDI/midi_Settings.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * @file midi_Settings.h 3 | * Project Arduino MIDI Library 4 | * @brief MIDI Library for the Arduino - Settings 5 | * @author Francois Best 6 | * @date 24/02/11 7 | * @license MIT - Copyright (c) 2015 Francois Best 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | 28 | #pragma once 29 | 30 | #include "midi_Defs.h" 31 | 32 | BEGIN_MIDI_NAMESPACE 33 | 34 | /*! \brief Default Settings for the MIDI Library. 35 | 36 | To change the default settings, don't edit them there, create a subclass and 37 | override the values in that subclass, then use the MIDI_CREATE_CUSTOM_INSTANCE 38 | macro to create your instance. The settings you don't override will keep their 39 | default value. Eg: 40 | \code{.cpp} 41 | struct MySettings : public midi::DefaultSettings 42 | { 43 | static const unsigned SysExMaxSize = 1024; // Accept SysEx messages up to 1024 bytes long. 44 | }; 45 | 46 | MIDI_CREATE_CUSTOM_INSTANCE(HardwareSerial, Serial2, midi, MySettings); 47 | \endcode 48 | */ 49 | struct DefaultSettings 50 | { 51 | /*! Running status enables short messages when sending multiple values 52 | of the same type and channel.\n 53 | Warning: does not work with some hardware, enable with caution. 54 | */ 55 | static const bool UseRunningStatus = false; 56 | 57 | /*! NoteOn with 0 velocity should be handled as NoteOf.\n 58 | Set to true to get NoteOff events when receiving null-velocity NoteOn messages.\n 59 | Set to false to get NoteOn events when receiving null-velocity NoteOn messages. 60 | */ 61 | static const bool HandleNullVelocityNoteOnAsNoteOff = true; 62 | 63 | /*! Setting this to true will make MIDI.read parse only one byte of data for each 64 | call when data is available. This can speed up your application if receiving 65 | a lot of traffic, but might induce MIDI Thru and treatment latency. 66 | */ 67 | static const bool Use1ByteParsing = true; 68 | 69 | /*! Override the default MIDI baudrate to transmit over USB serial, to 70 | a decoding program such as Hairless MIDI (set baudrate to 115200)\n 71 | http://projectgus.github.io/hairless-midiserial/ 72 | */ 73 | static const long BaudRate = 31250; 74 | 75 | /*! Maximum size of SysEx receivable. Decrease to save RAM if you don't expect 76 | to receive SysEx, or adjust accordingly. 77 | */ 78 | static const unsigned SysExMaxSize = 128; 79 | }; 80 | 81 | END_MIDI_NAMESPACE 82 | -------------------------------------------------------------------------------- /Firmware/LittleFS/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | Expressive Pixels Nordic SDK firmware implementation leverages the [LittleFS](https://github.com/ARMmbed/littlefs) filesystem because of its fail-safe design for embedded microcontrollers. Clone the LittleFS Repo into this folder before compiling. 4 | 5 | 6 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/AdafruitDotStar_EPXDriver.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include "EPXPlatform_Runtime.h" 4 | #include "AdafruitDotStar_EPXDriver.h" 5 | 6 | EPX_OPTIMIZEFORDEBUGGING_ON 7 | 8 | 9 | CAdafruitDotStar_EPXDriver::CAdafruitDotStar_EPXDriver(int dataPin, int clockPin, uint16_t numPixels) : CLEDDriverBase(numPixels) 10 | { 11 | m_nRainbowIteration = 0; 12 | m_AdaFruitDotStar = new Adafruit_DotStar(numPixels, dataPin, clockPin); 13 | } 14 | 15 | 16 | 17 | void CAdafruitDotStar_EPXDriver::Initialize() 18 | { 19 | m_AdaFruitDotStar->begin(); 20 | } 21 | 22 | 23 | 24 | void CAdafruitDotStar_EPXDriver::SetBrightness(uint8_t brightness) 25 | { 26 | m_AdaFruitDotStar->setBrightness(brightness); 27 | } 28 | 29 | 30 | 31 | uint16_t CAdafruitDotStar_EPXDriver::NumPixels() 32 | { 33 | return m_AdaFruitDotStar->numPixels(); 34 | } 35 | 36 | 37 | 38 | void CAdafruitDotStar_EPXDriver::SetPixel(uint16_t idx, uint8_t r, uint8_t g, uint8_t b) 39 | { 40 | m_AdaFruitDotStar->setPixelColor(idx, g, r, b); 41 | } 42 | 43 | 44 | 45 | void CAdafruitDotStar_EPXDriver::SetPixelColor(uint16_t idx, uint32_t color) 46 | { 47 | m_AdaFruitDotStar->setPixelColor(idx, color); 48 | } 49 | 50 | 51 | void CAdafruitDotStar_EPXDriver::Clear() 52 | { 53 | m_AdaFruitDotStar->clear(); 54 | } 55 | 56 | 57 | 58 | void CAdafruitDotStar_EPXDriver::Show() 59 | { 60 | m_AdaFruitDotStar->show(); 61 | } 62 | 63 | 64 | 65 | uint32_t CAdafruitDotStar_EPXDriver::Wheel(uint8_t WheelPos) 66 | { 67 | WheelPos = 255 - WheelPos; 68 | if (WheelPos < 85) 69 | return IntColor(255 - WheelPos * 3, 0, WheelPos * 3); 70 | if (WheelPos < 170) 71 | { 72 | WheelPos -= 85; 73 | return IntColor(0, WheelPos * 3, 255 - WheelPos * 3); 74 | } 75 | WheelPos -= 170; 76 | return IntColor(WheelPos * 3, 255 - WheelPos * 3, 0); 77 | } 78 | 79 | 80 | 81 | void CAdafruitDotStar_EPXDriver::Rainbow(uint8_t wait) 82 | { 83 | uint16_t i, j; 84 | 85 | for (j = 0; j < 256; j++) 86 | { 87 | for (i = 0; i < m_numPixels; i++) 88 | // SetPixelColor(i, Wheel((i + j) & 255)); 89 | m_AdaFruitDotStar->setPixelColor(i, Wheel((i + j) & 255)); 90 | m_AdaFruitDotStar->show(); 91 | delay(wait); 92 | } 93 | } 94 | 95 | 96 | 97 | // Slightly different, this makes the rainbow equally distributed throughout 98 | void CAdafruitDotStar_EPXDriver::RainbowCycle(uint8_t wait) 99 | { 100 | uint16_t i; 101 | 102 | if(m_nRainbowIteration >= 256 * 5) 103 | m_nRainbowIteration = 0; 104 | 105 | // 5 cycles of all colors on wheel 106 | for(i = 0 ; i < m_numPixels; i++) 107 | //SetPixelColor(i, Wheel(((i * 256 / m_numPixels) + j) & 255)); 108 | m_AdaFruitDotStar->setPixelColor(i, Wheel((i + m_nRainbowIteration) & 255)); 109 | m_AdaFruitDotStar->show(); 110 | delay(wait); 111 | 112 | m_nRainbowIteration++; 113 | } 114 | 115 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/AdafruitDotStar_EPXDriver.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include "stdlib.h" 5 | #include "memory.h" 6 | #include "CLEDDriverBase.h" 7 | #include 8 | #include "Adafruit_DotStar.h" 9 | 10 | 11 | class CAdafruitDotStar_EPXDriver : public CLEDDriverBase 12 | { 13 | 14 | public: 15 | CAdafruitDotStar_EPXDriver(int dataPin, int clockPin, uint16_t numPixels); 16 | 17 | ~CAdafruitDotStar_EPXDriver() 18 | { 19 | if (m_pTXBuffer != NULL) 20 | free(m_pTXBuffer); 21 | } 22 | 23 | void Initialize(); 24 | void Rainbow(uint8_t wait); 25 | void RainbowCycle(uint8_t wait); 26 | void Show(); 27 | void Clear(); 28 | 29 | void SetBrightness(uint8_t brightness); 30 | void SetPixel(uint16_t idx, uint8_t r, uint8_t g, uint8_t b); 31 | void SetPixelColor(uint16_t idx, uint32_t color); 32 | uint16_t NumPixels(); 33 | 34 | private: 35 | uint32_t Wheel(uint8_t WheelPos); 36 | 37 | Adafruit_DotStar *m_AdaFruitDotStar; 38 | uint32_t *m_pTXBuffer; 39 | uint32_t m_nRainbowIteration; 40 | }; 41 | 42 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/AdafruitNeoPixel_EPXDriver.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include "EPXPlatform_Runtime.h" 4 | #include "AdafruitNeoPixel_EPXDriver.h" 5 | 6 | EPX_OPTIMIZEFORDEBUGGING_ON 7 | 8 | 9 | CAdafruitNeoPixel_EPXDriver::CAdafruitNeoPixel_EPXDriver(int dataPin, uint16_t numPixels) : CLEDDriverBase(numPixels) 10 | { 11 | m_nRainbowIteration = 0; 12 | m_AdaFruitNeoPixel = new Adafruit_NeoPixel(numPixels, dataPin, NEO_GRB + NEO_KHZ800); 13 | } 14 | 15 | 16 | 17 | void CAdafruitNeoPixel_EPXDriver::Initialize() 18 | { 19 | m_AdaFruitNeoPixel->begin(); 20 | } 21 | 22 | 23 | 24 | void CAdafruitNeoPixel_EPXDriver::SetBrightness(uint8_t brightness) 25 | { 26 | m_AdaFruitNeoPixel->setBrightness(brightness); 27 | } 28 | 29 | 30 | 31 | uint16_t CAdafruitNeoPixel_EPXDriver::NumPixels() 32 | { 33 | return m_AdaFruitNeoPixel->numPixels(); 34 | } 35 | 36 | 37 | 38 | void CAdafruitNeoPixel_EPXDriver::SetPixel(uint16_t idx, uint8_t r, uint8_t g, uint8_t b) 39 | { 40 | m_AdaFruitNeoPixel->setPixelColor(idx, r, g, b); 41 | } 42 | 43 | 44 | 45 | void CAdafruitNeoPixel_EPXDriver::SetPixelColor(uint16_t idx, uint32_t color) 46 | { 47 | m_AdaFruitNeoPixel->setPixelColor(idx, color); 48 | } 49 | 50 | 51 | void CAdafruitNeoPixel_EPXDriver::Clear() 52 | { 53 | m_AdaFruitNeoPixel->clear(); 54 | } 55 | 56 | 57 | 58 | void CAdafruitNeoPixel_EPXDriver::Show() 59 | { 60 | m_AdaFruitNeoPixel->show(); 61 | } 62 | 63 | 64 | 65 | uint32_t CAdafruitNeoPixel_EPXDriver::Wheel(uint8_t WheelPos) 66 | { 67 | WheelPos = 255 - WheelPos; 68 | if (WheelPos < 85) 69 | return IntColor(255 - WheelPos * 3, 0, WheelPos * 3); 70 | if (WheelPos < 170) 71 | { 72 | WheelPos -= 85; 73 | return IntColor(0, WheelPos * 3, 255 - WheelPos * 3); 74 | } 75 | WheelPos -= 170; 76 | return IntColor(WheelPos * 3, 255 - WheelPos * 3, 0); 77 | } 78 | 79 | 80 | 81 | void CAdafruitNeoPixel_EPXDriver::Rainbow(uint8_t wait) 82 | { 83 | uint16_t i, j; 84 | 85 | for (j = 0; j < 256; j++) 86 | { 87 | for (i = 0; i < m_numPixels; i++) 88 | // SetPixelColor(i, Wheel((i + j) & 255)); 89 | m_AdaFruitNeoPixel->setPixelColor(i, Wheel((i + j) & 255)); 90 | m_AdaFruitNeoPixel->show(); 91 | delay(wait); 92 | } 93 | } 94 | 95 | 96 | 97 | // Slightly different, this makes the rainbow equally distributed throughout 98 | void CAdafruitNeoPixel_EPXDriver::RainbowCycle(uint8_t wait) 99 | { 100 | uint16_t i; 101 | 102 | if(m_nRainbowIteration >= 256 * 5) 103 | m_nRainbowIteration = 0; 104 | 105 | // 5 cycles of all colors on wheel 106 | for(i = 0 ; i < m_numPixels; i++) 107 | //SetPixelColor(i, Wheel(((i * 256 / m_numPixels) + j) & 255)); 108 | m_AdaFruitNeoPixel->setPixelColor(i, Wheel((i + m_nRainbowIteration) & 255)); 109 | m_AdaFruitNeoPixel->show(); 110 | delay(wait); 111 | 112 | m_nRainbowIteration++; 113 | } 114 | 115 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/AdafruitNeoPixel_EPXDriver.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include "stdlib.h" 5 | #include "memory.h" 6 | #include "CLEDDriverBase.h" 7 | #include 8 | #include "Adafruit_NeoPixel.h" 9 | 10 | 11 | class CAdafruitNeoPixel_EPXDriver : public CLEDDriverBase 12 | { 13 | 14 | public: 15 | CAdafruitNeoPixel_EPXDriver(int dataPin, uint16_t numPixels); 16 | 17 | ~CAdafruitNeoPixel_EPXDriver() 18 | { 19 | if (m_pTXBuffer != NULL) 20 | free(m_pTXBuffer); 21 | } 22 | 23 | void Initialize(); 24 | void Rainbow(uint8_t wait); 25 | void RainbowCycle(uint8_t wait); 26 | void Show(); 27 | void Clear(); 28 | 29 | void SetBrightness(uint8_t brightness); 30 | void SetPixel(uint16_t idx, uint8_t r, uint8_t g, uint8_t b); 31 | void SetPixelColor(uint16_t idx, uint32_t color); 32 | uint16_t NumPixels(); 33 | 34 | private: 35 | uint32_t Wheel(uint8_t WheelPos); 36 | 37 | Adafruit_NeoPixel *m_AdaFruitNeoPixel; 38 | uint32_t *m_pTXBuffer; 39 | uint32_t m_nRainbowIteration; 40 | }; 41 | 42 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/AdafruitRGBMatrix_EPXDriver.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | 5 | #include "stdlib.h" 6 | #include "memory.h" 7 | #include "CLEDDriverBase.h" 8 | #include 9 | #include 10 | 11 | class CAdafruitRGBMatrix_EPXDriver : public CLEDDriverBase 12 | { 13 | 14 | public: 15 | CAdafruitRGBMatrix_EPXDriver(int width, int height); 16 | ~CAdafruitRGBMatrix_EPXDriver(); 17 | 18 | void Initialize(); 19 | void Rainbow(uint8_t wait); 20 | void RainbowCycle(uint8_t wait); 21 | void Show(); 22 | void Clear(); 23 | 24 | void SetBrightness(uint8_t brightness); 25 | void SetPixel(uint16_t idx, uint8_t r, uint8_t g, uint8_t b); 26 | void SetPixelColor(uint16_t idx, uint32_t color); 27 | uint16_t NumPixels(); 28 | 29 | private: 30 | uint32_t Wheel(uint8_t WheelPos); 31 | 32 | Adafruit_Protomatter *m_pRGBmatrixPanel; 33 | uint32_t *m_pTXBuffer; 34 | uint32_t m_nRainbowIteration; 35 | int m_width; 36 | int m_height; 37 | int m_brightness; 38 | }; 39 | 40 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/EPXPlatform_BLE.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include "EPXPlatform_Runtime.h" 5 | #include "CBLEBeaconActivation.h" 6 | 7 | #if defined (NRF52832_XXAA) || defined (NRF52840_XXAA) 8 | #define EPX_BLUETOOTH 9 | #include 10 | #endif 11 | 12 | 13 | // #define DISABLE_BLE_ADVERTISING 14 | #define BLEMAX_DEVICENAME 18 15 | 16 | 17 | typedef struct _tagBeaconActivationItem 18 | { 19 | char szBeaconHostName[32]; 20 | uint8_t beaconHostAddr[6]; 21 | uint8_t m_beaconActivationBit; 22 | char szAnimationName[32]; 23 | struct _tagBeaconActivationItem *pNext; 24 | } BEACONACTIVATIONITEM; 25 | 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | typedef void(*PFN_EPXPLATFORM_BLE_BYTERECEIVED)(void *pinstance, bool altChannel, uint8_t data); 32 | typedef void(*PFN_EPXPLATFORM_BLE_COMMUNICATIONREADY)(void *pinstance, bool altChannel); 33 | typedef void(*PFN_EPXPLATFORM_BLE_CONNECTIONSTATECHANGED)(void *pinstance, bool connected); 34 | typedef void(*PFN_EPXPLATFORM_BLE_BEACONRECEIVED)(void *pinstance, char *pszHost, uint8_t beaconData); 35 | 36 | 37 | void EPXPlatform_BLE_AdvertizingUpdate(); 38 | void EPXPlatform_BLE_Disconnect(); 39 | void EPXPlatform_BLE_Initialize(void *pinstance, char *pszDEFAULT_BLE_NAME, PFN_EPXPLATFORM_BLE_CONNECTIONSTATECHANGED pfnConnectionStateChanged, PFN_EPXPLATFORM_BLE_COMMUNICATIONREADY pfnCommunicationReady, PFN_EPXPLATFORM_BLE_BYTERECEIVED pfnByteReceived); 40 | void EPXPlatform_BLE_SetManufacturerPayload(uint8_t *p, uint8_t cb); 41 | size_t EPXPlatform_BLE_SendBytes(void *pvPayload, uint16_t cb, bool altChannel); 42 | uint32_t EPXPlatform_BLE_GetLastBeaconReceived(); 43 | char *EPXPlatform_BLE_GetRealizedDeviceName(); 44 | void EPXPlatform_BLE_SetBeaconActivation(bool on); 45 | void EPXPlatform_BLE_SetBeaconActivationEntries(BEACONACTIVATIONITEM ** ppBeaconActivationEntries); 46 | void EPXPlatform_BLE_SetBeaconReceivedHandler(PFN_EPXPLATFORM_BLE_BEACONRECEIVED pfnBLEBeaconReceived); 47 | void EPXPlatform_BLE_SetDeviceName(char *pszDeviceName); 48 | void EPXPlatform_BLE_Start(); 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/EPXPlatform_CBatteryMonitor.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "EPXPlatform_CBatteryMonitor.h" 8 | 9 | #define VBAT_MV_PER_LSB (0.87890625F) // 3.6V ADC range and 12-bit ADC resolution = 3600mV/4096 10 | #define VBAT_MV_PER_LSB (0.87890625F) // 3.6V ADC range and 12-bit ADC resolution = 3600mV/4096 11 | #define VBAT_DIVIDER (0.59820538F) // 1.2M + 0.806M voltage divider on VBAT = (1.2M / (0.806M + 2M)) 12 | #define VBAT_DIVIDER_COMP (1.70583495F) 13 | 14 | #define SAMPLES_IN_BUFFER 1 15 | 16 | 17 | uint16_t BatteryMonitor::m_milliVolts = 5000; 18 | uint8_t BatteryMonitor::m_percentage = 100; 19 | 20 | 21 | 22 | BatteryMonitor::BatteryMonitor() 23 | { 24 | m_bInitialized = false; 25 | } 26 | 27 | 28 | void BatteryMonitor::Initialize(uint16_t samplingPeriod) 29 | { 30 | m_samplingPeriod = samplingPeriod; 31 | m_bInitialized = true; 32 | } 33 | 34 | 35 | 36 | void BatteryMonitor::PowerOn() 37 | { 38 | } 39 | 40 | 41 | 42 | void BatteryMonitor::PowerOff() 43 | { 44 | 45 | 46 | } 47 | 48 | 49 | 50 | void BatteryMonitor::StopSampling() 51 | { 52 | if (m_bInitialized) 53 | { 54 | 55 | } 56 | } 57 | 58 | 59 | 60 | void BatteryMonitor::StartSampling() 61 | { 62 | if (m_bInitialized) 63 | { 64 | 65 | } 66 | } 67 | 68 | 69 | 70 | void BatteryMonitor::GetInfo(uint16_t *pMV, uint8_t *pPct) 71 | { 72 | if (pMV != NULL) 73 | *pMV = m_milliVolts; 74 | if (pPct != NULL) 75 | *pPct = m_percentage; 76 | } 77 | 78 | 79 | 80 | void BatteryMonitor::SingleSampleRequest() 81 | { 82 | // m_milliVolts = (uint16_t)((float) adcValue * VBAT_MV_PER_LSB * VBAT_DIVIDER_COMP); 83 | // m_percentage = VoltToPercent(m_milliVolts); 84 | 85 | } 86 | 87 | 88 | 89 | 90 | /* 91 | 100.00 4.2 92 | 90 4.13 93 | 80 4.06 94 | 70 3.99 95 | 60 3.92 96 | 50 3.85 97 | 40 3.78 98 | 30 3.71 99 | 20 3.64 100 | 10 3.57 101 | 0 3.5 */ 102 | uint8_t BatteryMonitor::VoltToPercent(uint16_t mvolts) 103 | { 104 | if (mvolts >= 4200) 105 | return 100; 106 | else if (mvolts > 4130) 107 | return 90; 108 | else if (mvolts > 4060) 109 | return 80; 110 | else if (mvolts > 3990) 111 | return 70; 112 | else if (mvolts > 3920) 113 | return 60; 114 | else if (mvolts > 3850) 115 | return 50; 116 | else if (mvolts > 3780) 117 | return 40; 118 | else if (mvolts > 3710) 119 | return 30; 120 | else if (mvolts > 3640) 121 | return 20; 122 | else if (mvolts > 3570) 123 | return 10; 124 | return 0; 125 | } 126 | 127 | 128 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/EPXPlatform_CBatteryMonitor.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | 5 | class BatteryMonitor 6 | { 7 | public: 8 | BatteryMonitor(); 9 | 10 | void Initialize(uint16_t samplingPeriod = 0); 11 | void GetInfo(uint16_t *pMV, uint8_t *pPct); 12 | void Power(bool on) 13 | { 14 | if (on) 15 | PowerOn(); 16 | else 17 | PowerOff(); 18 | } 19 | void PowerOn(); 20 | void PowerOff(); 21 | void SingleSampleRequest(); 22 | void StartSampling(); 23 | void StopSampling(); 24 | 25 | private: 26 | 27 | static uint8_t VoltToPercent(uint16_t mvolts); 28 | 29 | bool m_bInitialized; 30 | uint16_t m_samplingPeriod; 31 | static uint16_t m_milliVolts; 32 | static uint8_t m_percentage; 33 | }; 34 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/EPXPlatform_CByteQueue.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include "EPXPlatform_CByteQueue.h" 4 | 5 | EPX_OPTIMIZEFORDEBUGGING_ON 6 | 7 | 8 | CByteQueue::CByteQueue() 9 | { 10 | _buffer_overflow = false; 11 | _receive_buffer_tail = 0; 12 | _receive_buffer_head = 0; 13 | } 14 | 15 | 16 | 17 | bool CByteQueue::push(uint8_t val) 18 | { 19 | uint16_t next = (_receive_buffer_tail + 1) % BYTEQUEUEBUFFERSIZE; 20 | if (next != _receive_buffer_head) 21 | { 22 | // save new data in buffer: tail points to where byte goes 23 | _receive_buffer[_receive_buffer_tail] = val; // save new byte 24 | _receive_buffer_tail = next; 25 | return true; 26 | } 27 | _buffer_overflow = true; 28 | return false; 29 | } 30 | 31 | 32 | 33 | // Read data from buffer 34 | int CByteQueue::pop() 35 | { 36 | // Empty buffer? 37 | if(_receive_buffer_head == _receive_buffer_tail) 38 | return - 1; 39 | 40 | // Read from "head" 41 | uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte 42 | _receive_buffer_head = (_receive_buffer_head + 1) % BYTEQUEUEBUFFERSIZE; 43 | return d; 44 | } 45 | 46 | 47 | 48 | int CByteQueue::available() 49 | { 50 | return (_receive_buffer_tail + BYTEQUEUEBUFFERSIZE - _receive_buffer_head) % BYTEQUEUEBUFFERSIZE; 51 | } 52 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/EPXPlatform_CByteQueue.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | 5 | #include "EPXPlatform_Runtime.h" 6 | 7 | #define BYTEQUEUEBUFFERSIZE 1024 8 | 9 | class CByteQueue 10 | { 11 | public: 12 | CByteQueue(); 13 | 14 | bool push(uint8_t val); 15 | int available(); 16 | int pop(); 17 | 18 | private: 19 | bool _buffer_overflow; 20 | 21 | uint8_t _receive_buffer[BYTEQUEUEBUFFERSIZE]; 22 | uint16_t _receive_buffer_tail; 23 | uint16_t _receive_buffer_head; 24 | }; -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/EPXPlatform_CStorage.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include "EPXPlatform_Runtime.h" 5 | #include "EPXPlatform_CStorageBase.h" 6 | 7 | #define ADAFSFORK_FILENAMEMAX 13 8 | 9 | class CStorage 10 | { 11 | public: 12 | static bool Initialize(uint16_t pinMISO, uint16_t pinMOSI, uint16_t pinSCLK, uint16_t pinCS, bool format = false); 13 | static bool CreateFolder(const char *pszFolder); 14 | static bool DeleteFile(const char *pszFilename); 15 | static bool FileExists(const char *pszFilename); 16 | static bool Format(); 17 | static bool Seek(void *pFile, uint32_t pos); 18 | static uint32_t FileSize(void *pFile); 19 | static void EnumFolder(const char *pszFolder, PPERSISTED_SEQUENCE_LIST *ppFileList); 20 | static void FreeEnumFolderList(PPERSISTED_SEQUENCE_LIST *ppList); 21 | static void FreeEnumFolderListItem(PPERSISTED_SEQUENCE_LIST pItem); 22 | static void FreeEnumFolderListItemFilename(PPERSISTED_SEQUENCE_LIST pItem); 23 | 24 | static uint16_t ReadFile(void *pFile, void *pData, uint16_t cbToRead); 25 | static uint16_t WriteFile(void *pFile, void *pData, uint16_t cbToRead); 26 | static uint32_t Capacity(); 27 | static uint32_t UsedSpace(); 28 | static uint32_t Position(void *pFile); 29 | 30 | static char *TrimFilename(const char *pszInFilename); 31 | static void Close(void *pFile); 32 | static void *CreateFile(const char *pszFilename); 33 | static void *OpenFile(const char *pszFilename, int *pFileSize = NULL); 34 | static void Power(bool on); 35 | 36 | static const int FilenameMax() { return ADAFSFORK_FILENAMEMAX; } 37 | 38 | static bool m_lfsInitialized; 39 | static int m_nvmPageSize; 40 | static int m_nvmPageCount; 41 | static int m_nvmCapacity; 42 | static int m_nvmRowSize; 43 | static int m_deviceBlocks; 44 | 45 | static void NVMErase(const volatile void* flash_ptr, uint32_t size); 46 | static void NVMRead(const volatile void* flash_ptr, void* data, uint32_t size); 47 | static void NVMEraseRow(const volatile void* flash_ptr); 48 | static inline uint32_t NVMReadWord(const void* data); 49 | static void NVMWrite(const volatile void* flash_ptr, const void* data, uint32_t size); 50 | 51 | }; 52 | 53 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/EPXPlatform_CStorageBase.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | 5 | #include 6 | 7 | 8 | typedef struct _PERSISTED_SEQUENCE_LIST 9 | { 10 | char *pszFilename; 11 | char *pszGUID; 12 | char *pszName; 13 | uint16_t size; 14 | uint32_t utcTimestamp; 15 | struct _PERSISTED_SEQUENCE_LIST *pNext; 16 | } PERSISTED_SEQUENCE_LIST, *PPERSISTED_SEQUENCE_LIST; 17 | 18 | 19 | 20 | class BaseStorageClass 21 | { 22 | public: 23 | virtual bool Initialize() = 0; 24 | 25 | virtual bool CreateFolder(char *pszFolder) = 0; 26 | virtual bool DeleteFile(const char *pszFilename) = 0; 27 | virtual bool FileExists(const char *pszFilename) = 0; 28 | virtual bool Format() = 0; 29 | virtual size_t ReadFile(File *file, uint8_t *pBuffer, int bufferLen) = 0; 30 | virtual size_t WriteFile(File *file, uint8_t *pBuffer, int bufferLen) = 0; 31 | virtual File OpenFile(char *pszFilename, uint8_t mode) = 0; 32 | virtual File *OpenFileDyn(char *pszFilename, uint8_t mode) = 0; 33 | virtual uint32_t Position(File *file) = 0; 34 | virtual void Close(File *file) = 0; 35 | virtual void EnumFolder(const char *pszFolder, PPERSISTED_SEQUENCE_LIST *ppFileList) = 0; 36 | 37 | 38 | void ReleaseSequenceFileList(PPERSISTED_SEQUENCE_LIST pFileList); 39 | }; 40 | 41 | 42 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/EPXPlatform_Crypto.cpp: -------------------------------------------------------------------------------- 1 | #include "EPXPlatform_Runtime.h" 2 | #include "EPXPlatform_Crypto.h" 3 | 4 | 5 | 6 | void EPXPlatform_Crypto_Initialize() 7 | { 8 | } 9 | 10 | 11 | 12 | uint8_t *EPXPlatform_Crypto_Encrypt(uint8_t * pAESKey, void *p_data, size_t len) 13 | { 14 | return NULL; 15 | } 16 | 17 | 18 | 19 | uint8_t *EPXPlatform_Crypto_Decrypt(uint8_t * pAESKey, void *p_data, size_t len) 20 | { 21 | return NULL; 22 | } 23 | 24 | 25 | 26 | 27 | void EPXPlatform_Crypto_GenerateNONCE(uint8_t * p_buf) 28 | { 29 | 30 | } 31 | 32 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/EPXPlatform_Crypto.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define EPX_AES_KEY_BYTE_SIZE 16 4 | #define EPX_NONCE_SIZE 16 5 | 6 | 7 | void EPXPlatform_Crypto_Initialize(); 8 | uint8_t *EPXPlatform_Crypto_Decrypt(uint8_t * pAESKey, void *p_data, size_t len); 9 | uint8_t *EPXPlatform_Crypto_Encrypt(uint8_t * pAESKey, void * p_data, size_t len); 10 | void EPXPlatform_Crypto_GenerateNONCE(uint8_t * p_buf); -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/EPXPlatform_GPIO.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | enum EPXGPIOStateChange 11 | { 12 | EPXGPIO_PIN_STATECHANGE = 0, 13 | EPXGPIO_BUTTON_PUSHED, 14 | EPXGPIO_BUTTON_RELEASED 15 | }; 16 | 17 | #define EPXGPIO_LOW (0x0) 18 | #define EPXGPIO_HIGH (0x1) 19 | #define EPXGPIO_INPUT (0x0) 20 | #define EPXGPIO_OUTPUT (0x1) 21 | 22 | 23 | typedef void(*PFN_EPXGPIO_EVENTHANDLER)(void *pinstance, uint8_t event, uint16_t pin, uint16_t value); 24 | 25 | typedef void(*PFN_EPX_BUTTON_PUSHED)(void *pinstance); 26 | 27 | void EPXPlatform_GPIO_ButtonClickConfigure(uint32_t ulPin); 28 | void EPXPlatform_GPIO_ButtonClickFinalize(); 29 | bool EPXPlatform_GPIO_Initialize(void *pinstance, PFN_EPXGPIO_EVENTHANDLER eventHandler); 30 | uint32_t EPXPlatform_GPIO_PinRead(uint32_t ulPin); 31 | void EPXPlatform_GPIO_PinConfigure(uint32_t ulPin, uint32_t type); 32 | void EPXPlatform_GPIO_PinWrite(uint32_t ulPin, uint32_t ulVal); 33 | 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | 39 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/EPXPlatform_Runtime.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include 5 | // #define USESEGGERRTT_LOG 6 | #define EPX_OPTIMIZEFORDEBUGGING 7 | 8 | enum enumLogLevel { LOGLEVEL_INFO = 1, LOGLEVEL_PAYLOAD, LOGLEVEL_NONE }; 9 | 10 | enum enumRebootTypes 11 | { 12 | REBOOTTYPE_NONE, REBOOTTYPE_UF2, REBOOTTYPE_OTA, REBOOTTYPE_SERIAL 13 | }; 14 | 15 | uint8_t HexToByte(char *hex, int len); 16 | void BytesToHex(uint8_t *p, int cb, char *psz, int stringCB); 17 | int freeRam(); 18 | 19 | 20 | #ifndef epxmin 21 | #define epxmin(a,b) ((a)<(b)?(a):(b)) 22 | #endif 23 | 24 | #ifndef epxmax 25 | #define epxmax(a,b) ((a)>(b)?(a):(b)) 26 | #endif 27 | 28 | 29 | #define BytesToUInt16(a) ((uint16_t)(((uint32_t) *a << 8) | ((uint32_t) *(a + 1) << 0))) 30 | 31 | #define T(a) ((const char *) a) 32 | 33 | #ifdef EPX_OPTIMIZEFORDEBUGGING 34 | 35 | #define EPX_OPTIMIZEFORDEBUGGING_ON \ 36 | _Pragma("GCC push_options") \ 37 | _Pragma("GCC optimize (\"O0\")") 38 | 39 | #define EPX_OPTIMIZEFORDEBUGGING_OFF \ 40 | _Pragma("#pragma GCC pop_options") \ 41 | 42 | #else 43 | #define EPX_OPTIMIZEFORDEBUGGING_ON 44 | #define EPX_OPTIMIZEFORDEBUGGING_OFF 45 | #endif 46 | 47 | #ifdef __cplusplus 48 | extern "C" { 49 | #endif 50 | void EPXPlatform_Runtime_ControlAppTimer(bool on); 51 | void EPXPlatform_Runtime_Initialize(); 52 | void EPXPlatform_Runtime_Process(); 53 | void EPXPlatform_Runtime_Reboot(uint8_t rebootType); 54 | void EPXPlatform_Runtime_MCUSleep(); 55 | void EPXPlatform_Runtime_MCUDeepSleep(); 56 | 57 | uint32_t millisPassed(uint32_t localMillis); 58 | 59 | void *tmalloc(const char *pszFile, int line, size_t siz); 60 | void tfree(void *buf); 61 | void tmallocdump(); 62 | void tmallocstats(); 63 | 64 | #define TMALLOC(size) tmalloc(__FILE__, __LINE__, size) 65 | #define TFREE(ptr) tfree((uint8_t *) ptr) 66 | 67 | char *stristr(const char *subject, const char *object); 68 | int stricmp(const char *s1, const char *s2); 69 | char *epx_strupr(char s[]); 70 | 71 | #ifdef USESEGGERRTT_LOG 72 | void SEGGER_RTT_LogLn(const char* fmt, ...); 73 | 74 | #define DEBUGLOGLN(...) SEGGER_RTT_LogLn( __VA_ARGS__) 75 | #else 76 | #define DEBUGLOGLN(...) 77 | #endif 78 | 79 | #ifdef __cplusplus 80 | } 81 | #endif 82 | 83 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/EPXPlatform_Settings.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include 4 | #include "EPXString.h" 5 | #include "EPXPlatform_Settings.h" 6 | #include "EPXPlatform_CStorage.h" 7 | 8 | EPX_OPTIMIZEFORDEBUGGING_ON 9 | 10 | void CSettings::Initialize() 11 | { 12 | CStorage::CreateFolder((const char *) SETTINGS_FOLDER); 13 | } 14 | 15 | 16 | 17 | void CSettings::ClearAll() 18 | { 19 | 20 | } 21 | 22 | 23 | 24 | uint16_t CSettings::Write(const char *pszSettingsKey, void *pBuffer, uint16_t cb) 25 | { 26 | uint16_t bytesWritten = 0; 27 | 28 | EPXString filename = EPXString((const char *) SETTINGS_FOLDER) + "/" + pszSettingsKey; 29 | void *pFile = CStorage::CreateFile(filename.c_str()); 30 | if (pFile != NULL) 31 | { 32 | bytesWritten = CStorage::WriteFile(pFile, pBuffer, cb); 33 | CStorage::Close(pFile); 34 | } 35 | return bytesWritten; 36 | } 37 | 38 | 39 | 40 | uint16_t CSettings::Read(const char *pszSettingsKey, void *pBuffer, uint16_t cb) 41 | { 42 | uint16_t bytesRead = 0; 43 | 44 | EPXString filename = EPXString((const char *) SETTINGS_FOLDER) + "/" + pszSettingsKey; 45 | if (CStorage::FileExists(filename.c_str())) 46 | { 47 | void *pFile = CStorage::OpenFile(filename.c_str()); 48 | if (pFile != NULL) 49 | { 50 | bytesRead = CStorage::ReadFile(pFile, pBuffer, cb); 51 | CStorage::Close(pFile); 52 | } 53 | } 54 | return bytesRead; 55 | } 56 | 57 | 58 | 59 | bool CSettings::WriteString(const char *pszSettingsKey, char *pszValue, uint16_t valueLength) 60 | { 61 | bool success = false; 62 | uint16_t bytesWritten = 0; 63 | 64 | EPXString filename = EPXString((const char *) SETTINGS_FOLDER) + "/" + pszSettingsKey; 65 | void *pFile = CStorage::CreateFile(filename.c_str()); 66 | if (pFile != NULL) 67 | { 68 | uint16_t length = valueLength == 0 ? strlen(pszValue) : valueLength; 69 | bytesWritten = CStorage::WriteFile(pFile, &length, sizeof(length)); 70 | if (bytesWritten == sizeof(length)) 71 | { 72 | bytesWritten = CStorage::WriteFile(pFile, pszValue, length); 73 | if (bytesWritten == length) 74 | success = true; 75 | } 76 | CStorage::Close(pFile); 77 | } 78 | return success; 79 | } 80 | 81 | 82 | 83 | bool CSettings::ReadString(const char *pszSettingsKey, char *pszValue, uint16_t bufferLength) 84 | { 85 | bool success = false; 86 | uint16_t bytesRead = 0; 87 | 88 | EPXString filename = EPXString((const char *) SETTINGS_FOLDER) + "/" + pszSettingsKey; 89 | memset(pszValue, 0x00, bufferLength); 90 | 91 | if (CStorage::FileExists(filename.c_str())) 92 | { 93 | void *pFile = CStorage::OpenFile(filename.c_str()); 94 | if (pFile != NULL) 95 | { 96 | uint16_t length = strlen(pszValue); 97 | 98 | bytesRead = CStorage::ReadFile(pFile, &length, sizeof(length)); 99 | if (bytesRead == sizeof(length)) 100 | { 101 | uint16_t bytesToRead = epxmin(length, bufferLength - 1); 102 | 103 | bytesRead = CStorage::ReadFile(pFile, pszValue, bytesToRead); 104 | if (bytesRead == bytesToRead) 105 | { 106 | pszValue[bytesRead] = 0x00; 107 | success = true; 108 | } 109 | } 110 | CStorage::Close(pFile); 111 | } 112 | } 113 | return success; 114 | } 115 | 116 | 117 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/EPXPlatform_Settings.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include "EPXPlatform_Runtime.h" 5 | 6 | #define SETTINGS_FOLDER F("/SETTINGS") 7 | 8 | class CSettings 9 | { 10 | public: 11 | static void Initialize(); 12 | 13 | static bool WriteString(const char *pszSettingsKey, char *pszValue, uint16_t valueLength = 0); 14 | static bool ReadString(const char *pszSettingsKey, char *pszValue, uint16_t bufferLength); 15 | static uint16_t Read(const char *pszSettingsKey, void *pBuffer, uint16_t cb); 16 | static uint16_t Write(const char *pszSettingsKey, void *pBuffer, uint16_t cb); 17 | static void ClearAll(); 18 | }; 19 | 20 | 21 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/EPXPlatform_USB.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include "Arduino.h" 4 | #include "EPXPlatform_Runtime.h" 5 | #include "EPXPlatform_USB.h" 6 | 7 | EPX_OPTIMIZEFORDEBUGGING_ON 8 | 9 | static bool g_USBConnected = false; 10 | 11 | void *g_USBHostInstance = NULL; 12 | static PFN_EPXPLATFORM_USB_CONNECTIONSTATECHANGED g_pfnUSBConnectionStateChanged = NULL; 13 | static PFN_EPXPLATFORM_USB_COMMUNICATIONREADY g_pfnUSBCommunicationReady = NULL; 14 | static PFN_EPXPLATFORM_USB_POWERSTATECHANGED g_pfnUSBPowerStateChanged = NULL; 15 | static PFN_EPXPLATFORM_USB_BYTERECEIVED g_pfnUSBByteReceived = NULL; 16 | 17 | 18 | 19 | size_t EPXPlatform_USB_Write(uint8_t *p, uint16_t cb) 20 | { 21 | return Serial.write(p, cb); 22 | } 23 | 24 | 25 | 26 | void EPXPlatform_USB_SetDeviceName(char *pszDeviceName) 27 | { 28 | } 29 | 30 | 31 | 32 | bool EPXPlatform_USB_Initialize(void *pinstance, PFN_EPXPLATFORM_USB_POWERSTATECHANGED pfnUSBPowerStateChanged, PFN_EPXPLATFORM_USB_CONNECTIONSTATECHANGED pfnConnectionStateChanged, PFN_EPXPLATFORM_USB_COMMUNICATIONREADY pfnCommunicationReady, PFN_EPXPLATFORM_USB_BYTERECEIVED pfnByteReceived) 33 | { 34 | g_USBHostInstance = pinstance; 35 | g_pfnUSBPowerStateChanged = pfnUSBPowerStateChanged; 36 | g_pfnUSBCommunicationReady = pfnCommunicationReady; 37 | g_pfnUSBConnectionStateChanged = pfnConnectionStateChanged; 38 | g_pfnUSBByteReceived = pfnByteReceived; 39 | return true; 40 | } 41 | 42 | 43 | 44 | bool EPXPlatform_USB_Activate() 45 | { 46 | (*g_pfnUSBPowerStateChanged)(g_USBHostInstance, true); 47 | return true; 48 | } 49 | 50 | 51 | 52 | void EPXPlatform_USB_Process() 53 | { 54 | if(Serial && !g_USBConnected) 55 | { 56 | g_USBConnected = true; 57 | (*g_pfnUSBConnectionStateChanged)(g_USBHostInstance, true); 58 | (*g_pfnUSBCommunicationReady)(g_USBHostInstance); 59 | return; 60 | } 61 | else if(!Serial && g_USBConnected) 62 | { 63 | g_USBConnected = false; 64 | (*g_pfnUSBConnectionStateChanged)(g_USBHostInstance, false); 65 | return; 66 | } 67 | 68 | int processSize = min(1024, Serial.available()); 69 | while(processSize--) 70 | (*g_pfnUSBByteReceived)(g_USBHostInstance, Serial.read()); 71 | } 72 | 73 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/EPXPlatform_USB.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | typedef void(*PFN_EPXPLATFORM_USB_BYTERECEIVED)(void *pinstance, uint8_t data); 10 | typedef void(*PFN_EPXPLATFORM_USB_CONNECTIONSTATECHANGED)(void *pinstance, bool connected); 11 | typedef void(*PFN_EPXPLATFORM_USB_COMMUNICATIONREADY)(void *pinstance); 12 | typedef void(*PFN_EPXPLATFORM_USB_POWERSTATECHANGED)(void *pinstance, bool powered); 13 | 14 | 15 | 16 | bool EPXPlatform_USB_Initialize(void *pinstance, PFN_EPXPLATFORM_USB_POWERSTATECHANGED g_pfnUSBPowerStateChanged, PFN_EPXPLATFORM_USB_CONNECTIONSTATECHANGED pfnConnectionStateChanged, PFN_EPXPLATFORM_USB_COMMUNICATIONREADY pfnCommunicationReady, PFN_EPXPLATFORM_USB_BYTERECEIVED pfnByteReceived); 17 | size_t EPXPlatform_USB_Write(uint8_t *p, uint16_t cb); 18 | bool EPXPlatform_USB_Activate(); 19 | void EPXPlatform_USB_SetDeviceName(char *pszDeviceName); 20 | void EPXPlatform_USB_Process(); 21 | 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | 27 | 28 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/EPXVariant.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include "EPXVariant.h" 4 | #include "EPXGlobal.h" 5 | #include "CDisplayTopology.h" 6 | 7 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/EPXVariant.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | 5 | #define EPX_DEVICEMODEL "EPXArduino" 6 | #define BLE_DEFAULT_DEVICE_NAME "EPXArduino" /**< Name of device. Will be included in the advertising data. */ 7 | #define EPX_FWVERSIONSRC "" 8 | 9 | #define GPIO_PIN_STATUSLED 13 10 | #define GPIO_PIN_FLASHRAM_CS 0 11 | #define GPIO_PIN_FLASHRAM_MISO 0 12 | #define GPIO_PIN_FLASHRAM_SCLK 0 13 | #define GPIO_PIN_FLASHRAM_MOSI 0 14 | #define GPIO_PIN_FEATURE 0 15 | #define GPIO_PIN_3V3_ACCEN 0 16 | #define GPIO_PIN_BOOSTER_ENABLE 0 17 | #define DISPLAYARRAY_POWERPIN 0 18 | #define FLASH_SPI_CS SS // Flash chip SS pin. 19 | #define FLASH_SPI_PORT SPI // What SPI port is Flash on? 20 | 21 | #define VARIANTCAPABILITY_STORAGE 22 | #define VARIANTCAPABILITY_PREVIEW 23 | #define VARIANTCAPABILITY_BATTERY_MONITORING 24 | // #define VARIANTCAPABILITY_SECURITY 25 | // #define VARIANTCAPABILITY_DFU 26 | // #define VARIANT_DISPLAY_PWRMGNT 27 | 28 | extern char g_szDEFAULT_BLE_NAME[]; 29 | -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/README.md: -------------------------------------------------------------------------------- 1 | Welcome to the Microsoft Expressive Pixels project!! 2 | 3 | Please be sure to visit the Wiki at https://github.com/microsoft/ExpressivePixels/wiki 4 | to learn more about how to integrate Expressive Pixels capabilities in your own creations. -------------------------------------------------------------------------------- /Firmware/Platform_Arduino/library.properties: -------------------------------------------------------------------------------- 1 | name=ExpressivePixels Arduino Platform 2 | version=1.0.1 3 | author=Microsoft 4 | maintainer=ExpressivePixels 5 | sentence=ExpressivePixels Arduino Platform Library 6 | paragraph=ExpressivePixels Arduino Platform Library 7 | category=Display 8 | url=https://github.com/microsoft/ExpressivePixels 9 | architectures=* 10 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/Adafruit_NeopixelDriver.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include "app_util_platform.h" 4 | #include "nrf_delay.h" 5 | #include "EPXPlatform_Runtime.h" 6 | #include "EPXVariant.h" 7 | 8 | #ifdef VARIANTDISPLAYDRIVER_ADANEOPIXEL 9 | #include "Adafruit_NeopixelDriver.h" 10 | #include "..\Adafruit_NeoPixel\Adafruit_NeoPixel.h" 11 | 12 | 13 | 14 | Adafruit_NeopixelDriver::Adafruit_NeopixelDriver(int dataPin, uint16_t numPixels) : CLEDDriverBase(numPixels) 15 | { 16 | Adafruit_NeoPixel *pNeopixel = new Adafruit_NeoPixel(numPixels, dataPin); 17 | m_pvAdafruitNeopixel = pNeopixel; 18 | } 19 | 20 | 21 | 22 | void Adafruit_NeopixelDriver::Initialize() 23 | { 24 | Adafruit_NeoPixel *pNeopixel = (Adafruit_NeoPixel *) m_pvAdafruitNeopixel; 25 | pNeopixel->begin(); 26 | 27 | CLEDDriverBase::Initialize(); 28 | } 29 | 30 | 31 | 32 | void Adafruit_NeopixelDriver::SetPixel(uint16_t idx, uint8_t r, uint8_t g, uint8_t b) 33 | { 34 | Adafruit_NeoPixel *pNeopixel = (Adafruit_NeoPixel *) m_pvAdafruitNeopixel; 35 | pNeopixel->setPixelColor(idx, r, g, b); 36 | } 37 | 38 | 39 | 40 | void Adafruit_NeopixelDriver::SetPixelColor(uint16_t idx, uint32_t color) 41 | { 42 | Adafruit_NeoPixel *pNeopixel = (Adafruit_NeoPixel *) m_pvAdafruitNeopixel; 43 | pNeopixel->setPixelColor(idx, color); 44 | } 45 | 46 | 47 | 48 | void Adafruit_NeopixelDriver::SetBrightness(uint8_t brightness) 49 | { 50 | Adafruit_NeoPixel *pNeopixel = (Adafruit_NeoPixel *) m_pvAdafruitNeopixel; 51 | pNeopixel->setBrightness(brightness); 52 | } 53 | 54 | 55 | 56 | void Adafruit_NeopixelDriver::Clear() 57 | { 58 | Adafruit_NeoPixel *pNeopixel = (Adafruit_NeoPixel *) m_pvAdafruitNeopixel; 59 | pNeopixel->clear(); 60 | } 61 | 62 | 63 | 64 | void Adafruit_NeopixelDriver::Show() 65 | { 66 | Adafruit_NeoPixel *pNeopixel = (Adafruit_NeoPixel *) m_pvAdafruitNeopixel; 67 | pNeopixel->show(); 68 | } 69 | 70 | 71 | 72 | uint32_t Adafruit_NeopixelDriver::Wheel(uint8_t WheelPos) 73 | { 74 | WheelPos = 255 - WheelPos; 75 | if (WheelPos < 85) 76 | return IntColor(255 - WheelPos * 3, 0, WheelPos * 3); 77 | if (WheelPos < 170) 78 | { 79 | WheelPos -= 85; 80 | return IntColor(0, WheelPos * 3, 255 - WheelPos * 3); 81 | } 82 | WheelPos -= 170; 83 | return IntColor(WheelPos * 3, 255 - WheelPos * 3, 0); 84 | } 85 | 86 | 87 | 88 | void Adafruit_NeopixelDriver::Rainbow(uint8_t wait) 89 | { 90 | uint16_t i, j; 91 | 92 | for (j = 0; j < 256; j++) 93 | { 94 | for (i = 0; i < m_numPixels; i++) 95 | SetPixelColor(i, Wheel((i + j) & 255)); 96 | Show(); 97 | delay(wait); 98 | } 99 | } 100 | 101 | 102 | 103 | // Slightly different, this makes the rainbow equally distributed throughout 104 | void Adafruit_NeopixelDriver::RainbowCycle(uint8_t wait) 105 | { 106 | uint16_t i; 107 | 108 | if (m_nRainbowIteration >= 256 * 5) 109 | m_nRainbowIteration = 0; 110 | 111 | // 5 cycles of all colors on wheel 112 | for(i = 0 ; i < m_numPixels ; i++) 113 | SetPixelColor(i, Wheel(((i * 256 / m_numPixels) + m_nRainbowIteration) & 255)); 114 | Show(); 115 | delay(wait); 116 | 117 | m_nRainbowIteration++; 118 | 119 | } 120 | #endif 121 | 122 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/Adafruit_NeopixelDriver.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include "stdlib.h" 5 | #include "string.h" 6 | #include "CLEDDriverBase.h" 7 | 8 | 9 | 10 | class Adafruit_NeopixelDriver : public CLEDDriverBase 11 | { 12 | 13 | public: 14 | Adafruit_NeopixelDriver(int dataPin, uint16_t numPixels); 15 | 16 | ~Adafruit_NeopixelDriver() 17 | { 18 | } 19 | 20 | void Initialize(); 21 | void Rainbow(uint8_t wait); 22 | void RainbowCycle(uint8_t wait); 23 | void Show(); 24 | 25 | void SetPixel(uint16_t idx, uint8_t r, uint8_t g, uint8_t b); 26 | void SetPixelColor(uint16_t idx, uint32_t color); 27 | void SetBrightness(uint8_t brightness); 28 | void Clear(); 29 | 30 | private: 31 | uint32_t Wheel(uint8_t WheelPos); 32 | 33 | uint32_t m_nRainbowIteration; 34 | void *m_pvAdafruitNeopixel; 35 | }; 36 | 37 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/CAPA102-Driver.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include "app_util_platform.h" 4 | #include "nrf_delay.h" 5 | #include "EPXPlatform_Runtime.h" 6 | #include <..\Adafruit_DotStar\Adafruit_DotStar.h> 7 | #include "CAPA102-Driver.h" 8 | 9 | Adafruit_DotStar *g_pStripDotStar; 10 | 11 | 12 | void CAPA102::Initialize() 13 | { 14 | g_pStripDotStar = new Adafruit_DotStar(m_numPixels, m_dataPin, m_clockPin, DOTSTAR_BGR); 15 | g_pStripDotStar->begin(); 16 | g_pStripDotStar->setBrightness(DEFAULT_BRIGHTNESS); 17 | g_pStripDotStar->show(); 18 | } 19 | 20 | 21 | 22 | void CAPA102::SetBrightness(uint8_t brightness) 23 | { 24 | g_pStripDotStar->setBrightness(brightness); 25 | } 26 | 27 | 28 | 29 | void CAPA102::Clear() 30 | { 31 | g_pStripDotStar->clear(); 32 | } 33 | 34 | 35 | 36 | void CAPA102::SetPixel(uint16_t idx, uint8_t r, uint8_t g, uint8_t b) 37 | { 38 | g_pStripDotStar->setPixelColor(idx, r, g, b); 39 | } 40 | 41 | 42 | 43 | void CAPA102::SetPixelColor(uint16_t idx, uint32_t color) 44 | { 45 | g_pStripDotStar->setPixelColor(idx, color); 46 | } 47 | 48 | 49 | 50 | void CAPA102::Show() 51 | { 52 | g_pStripDotStar->show(); 53 | } 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/CAPA102-Driver.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | /* 5 | * Class implementation for APA102 Display driver 6 | * 7 | **/ 8 | #pragma once 9 | #include "stdlib.h" 10 | #include "memory.h" 11 | #include "CLEDDriverBase.h" 12 | 13 | 14 | 15 | class CAPA102 : public CLEDDriverBase 16 | { 17 | 18 | public: 19 | // Constructor 20 | CAPA102(uint16_t numPixels, uint16_t dataPin, uint16_t clockPin) : CLEDDriverBase(numPixels) 21 | { 22 | m_numPixels = numPixels; 23 | m_dataPin = dataPin; 24 | m_brightness = clockPin; 25 | } 26 | 27 | 28 | void Clear(); 29 | void Initialize(); 30 | void Rainbow(uint8_t wait) { } 31 | void RainbowCycle(uint8_t wait) { } 32 | 33 | void SetBrightness(uint8_t brightness); 34 | void SetPixel(uint16_t idx, uint8_t r, uint8_t g, uint8_t b); 35 | void SetPixelColor(uint16_t idx, uint32_t color); 36 | void Show(); 37 | 38 | private: 39 | uint16_t m_numPixels; // Number of pixels in display array 40 | uint16_t m_dataPin; // GPIO data pin 41 | uint16_t m_clockPin; // GPIO clock pin 42 | }; 43 | 44 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/CAPA102-SPIDriver.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | /* 5 | * Class implementation for SPI based APA102 Display driver 6 | * 7 | **/ 8 | 9 | #pragma once 10 | #include "stdlib.h" 11 | #include "memory.h" 12 | #include "EPXPlatform_SPIClass.h" 13 | #include "CLEDDriverBase.h" 14 | 15 | 16 | 17 | class CAPA102 : public CLEDDriverBase 18 | { 19 | 20 | public: 21 | // Constructor 22 | CAPA102(SPIClass *pSPIClass, uint16_t numPixels) : CLEDDriverBase(numPixels) 23 | { 24 | m_pSPIClass = pSPIClass; 25 | } 26 | 27 | 28 | 29 | void Initialize() 30 | { 31 | CLEDDriverBase::Initialize(); 32 | } 33 | 34 | 35 | 36 | void Rainbow(uint8_t wait) { } 37 | void RainbowCycle(uint8_t wait) { } 38 | 39 | 40 | void Show() 41 | { 42 | int i; 43 | uint8_t header[4] = { 0x00, 0x00, 0x00, 0x00 }; 44 | uint16_t brightness = m_brightness; 45 | 46 | m_pSPIClass->transfer(header, sizeof(header)); 47 | for (i = 0; i < m_numPixels; i++) 48 | { 49 | m_pSPIClass->transfer(0xFF); 50 | m_pSPIClass->transfer((m_pPixels[i].b * brightness) >> 8); 51 | m_pSPIClass->transfer((m_pPixels[i].g * brightness) >> 8); 52 | m_pSPIClass->transfer((m_pPixels[i].r * brightness) >> 8); 53 | } 54 | for (i = 0; i < ((m_numPixels + 15) / 16); i++) 55 | m_pSPIClass->transfer(0xFF); 56 | } 57 | 58 | 59 | private: 60 | SPIClass *m_pSPIClass; // System SPI class reference 61 | }; 62 | 63 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/CWS2812-I2SDriver.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include "app_util_platform.h" 4 | #include "nrf_delay.h" 5 | #include "EPXPlatform_I2S.h" 6 | #include "EPXPlatform_Runtime.h" 7 | #include "CWS2812-I2SDriver.h" 8 | 9 | 10 | 11 | void CWS2812_I2SDriver::FillI2SDriverBuffer() 12 | { 13 | LEDDRIVERPIXEL*pPixel = m_pPixels; 14 | int8_t offset = 1; 15 | uint8_t *pTX = (uint8_t *) m_pTXBuffer; 16 | 17 | for (uint16_t iPixel = 0; iPixel < m_numPixels; iPixel++) 18 | { 19 | uint32_t rgb = (((pPixel->g * m_brightness) >> 8) << 16) | (((pPixel->r * m_brightness) >> 8) << 8) | ((pPixel->b * m_brightness) >> 8); 20 | for (uint8_t i_rgb = 0; i_rgb < I2S_WS2812B_DRIVE_BUF_SIZE_PER_LED; i_rgb++) 21 | { 22 | switch (rgb & 0x00c00000) 23 | { 24 | case (0x00400000): 25 | *(pTX + offset) = (uint8_t)((I2S_WS2812B_DRIVE_PATTERN_0 << 4) | I2S_WS2812B_DRIVE_PATTERN_1); 26 | break; 27 | case (0x00800000): 28 | *(pTX + offset) = (uint8_t)((I2S_WS2812B_DRIVE_PATTERN_1 << 4) | I2S_WS2812B_DRIVE_PATTERN_0); 29 | break; 30 | case (0x00c00000): 31 | *(pTX + offset) = (uint8_t)((I2S_WS2812B_DRIVE_PATTERN_1 << 4) | I2S_WS2812B_DRIVE_PATTERN_1); 32 | break; 33 | default: 34 | *(pTX + offset) = (uint8_t)((I2S_WS2812B_DRIVE_PATTERN_0 << 4) | I2S_WS2812B_DRIVE_PATTERN_0); 35 | break; 36 | } 37 | pTX++; 38 | offset = -offset; 39 | rgb <<= (24 / I2S_WS2812B_DRIVE_BUF_SIZE_PER_LED); 40 | } 41 | pPixel++; 42 | } 43 | } 44 | 45 | 46 | 47 | CWS2812_I2SDriver::CWS2812_I2SDriver(int dataPin, uint16_t numPixels) : CLEDDriverBase(numPixels) 48 | { 49 | m_pTXBuffer = NULL; 50 | m_i2sBufferSize = 3 * m_numPixels + RESET_BITS; 51 | 52 | EPXPlatform_I2S_Configure(dataPin); 53 | } 54 | 55 | 56 | 57 | void CWS2812_I2SDriver::Initialize() 58 | { 59 | CLEDDriverBase::Initialize(); 60 | m_pTXBuffer = (uint32_t *) TMALLOC(sizeof(uint32_t) * m_i2sBufferSize); 61 | } 62 | 63 | 64 | 65 | void CWS2812_I2SDriver::Show() 66 | { 67 | EPXPlatform_I2S_Initialize(); 68 | 69 | FillI2SDriverBuffer(); 70 | EPXPlatform_I2S_Start(m_pTXBuffer, m_i2sBufferSize); 71 | 72 | delayMicroseconds((m_numPixels + 20) * (24 * 5 / 4)); 73 | 74 | EPXPlatform_I2S_Stop(); 75 | EPXPlatform_I2S_UnInitialize(); 76 | } 77 | 78 | 79 | 80 | uint32_t CWS2812_I2SDriver::Wheel(uint8_t WheelPos) 81 | { 82 | WheelPos = 255 - WheelPos; 83 | if (WheelPos < 85) 84 | return IntColor(255 - WheelPos * 3, 0, WheelPos * 3); 85 | if (WheelPos < 170) 86 | { 87 | WheelPos -= 85; 88 | return IntColor(0, WheelPos * 3, 255 - WheelPos * 3); 89 | } 90 | WheelPos -= 170; 91 | return IntColor(WheelPos * 3, 255 - WheelPos * 3, 0); 92 | } 93 | 94 | 95 | 96 | void CWS2812_I2SDriver::Rainbow(uint8_t wait) 97 | { 98 | uint16_t i, j; 99 | 100 | for (j = 0; j < 256; j++) 101 | { 102 | for (i = 0; i < m_numPixels; i++) 103 | SetPixelColor(i, Wheel((i + j) & 255)); 104 | Show(); 105 | delay(wait); 106 | } 107 | } 108 | 109 | 110 | 111 | // Slightly different, this makes the rainbow equally distributed throughout 112 | void CWS2812_I2SDriver::RainbowCycle(uint8_t wait) 113 | { 114 | uint16_t i; 115 | 116 | if (m_nRainbowIteration >= 256 * 5) 117 | m_nRainbowIteration = 0; 118 | 119 | // 5 cycles of all colors on wheel 120 | for(i = 0 ; i < m_numPixels ; i++) 121 | SetPixelColor(i, Wheel(((i * 256 / m_numPixels) + m_nRainbowIteration) & 255)); 122 | Show(); 123 | delay(wait); 124 | 125 | m_nRainbowIteration++; 126 | 127 | } 128 | 129 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/CWS2812-I2SDriver.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | /* 5 | * Class implementation for I2S based WS2812 Display driver 6 | * 7 | **/ 8 | 9 | #pragma once 10 | #include "stdlib.h" 11 | #include "string.h" 12 | #include "CLEDDriverBase.h" 13 | 14 | #define RESET_BITS 6 15 | #define I2S_WS2812B_DRIVE_PATTERN_0 ((uint8_t)0x08) // Bit pattern for data "0" is "HLLL". 16 | #define I2S_WS2812B_DRIVE_PATTERN_1 ((uint8_t)0x0e) // Bit pattern for data "1" is "HHHL". 17 | #define I2S_WS2812B_DRIVE_BUF_SIZE_PER_LED (12) // buffer size for each LED (8bit * 4 * 3 ) 18 | 19 | 20 | 21 | class CWS2812_I2SDriver : public CLEDDriverBase 22 | { 23 | 24 | public: 25 | // Constructor 26 | CWS2812_I2SDriver(int dataPin, uint16_t numPixels); 27 | 28 | // Destructor 29 | ~CWS2812_I2SDriver() 30 | { 31 | // Clean up I2S transmission buffer 32 | if (m_pTXBuffer != NULL) 33 | TFREE(m_pTXBuffer); 34 | } 35 | 36 | void Initialize(); 37 | void Rainbow(uint8_t wait); 38 | void RainbowCycle(uint8_t wait); 39 | void Show(); 40 | 41 | private: 42 | void FillI2SDriverBuffer(); 43 | uint32_t Wheel(uint8_t WheelPos); 44 | 45 | uint16_t m_i2sBufferSize; // I2S transmission buffer size 46 | uint32_t *m_pTXBuffer; // I2S transmission buffer 47 | uint32_t m_nRainbowIteration;// Rainbow iteration tracking 48 | }; 49 | 50 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/CWS2812-SPIDriver.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | /* 5 | * Class implementation for SPI based WS2812 Display driver 6 | * 7 | **/ 8 | #pragma once 9 | #include "stdlib.h" 10 | #include "memory.h" 11 | #include "EPXPlatform_SPIClass.h" 12 | #include "CLEDDriverBase.h" 13 | 14 | 15 | class CWS2812_SPIDriver : public CLEDDriverBase 16 | { 17 | 18 | public: 19 | // Consructor 20 | CWS2812_SPIDriver(SPIClass *pSPIClass, uint16_t numPixels); 21 | 22 | // Destructor 23 | ~CWS2812_SPIDriver() 24 | { 25 | } 26 | 27 | void Initialize(); 28 | 29 | void Rainbow(uint8_t wait); 30 | void RainbowCycle(uint8_t wait); 31 | void Show(); 32 | 33 | 34 | private: 35 | void SendPayloadBits(uint32_t bits); 36 | uint32_t Wheel(uint8_t WheelPos); 37 | 38 | SPIClass *m_pSPIClass; // Pointer to system SPI class interface 39 | uint8_t *m_pTXBuffer; // Transmission buffer 40 | }; 41 | 42 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/EPXPlatform_BLE.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | /* 5 | * Implementation declarations for BluetoothLE on Nordic SDK 6 | * 7 | **/ 8 | #pragma once 9 | #include "EPXPlatform_Runtime.h" 10 | 11 | 12 | 13 | //#define DISABLE_BLE_ADVERTISING // Uncomment to disable advertising so app can be debugged without tripping the SoftDevice watchdog 14 | #define BLEMAX_DEVICENAME 18 // Max length of BLE device display name (balanced with other advertising payload info) 15 | 16 | 17 | // Structure to manage beacon triggering activation 18 | typedef struct _tagBeaconActivationItem 19 | { 20 | char szBeaconHostName[32]; 21 | uint8_t beaconHostAddr[6]; 22 | uint8_t m_beaconActivationBit; 23 | char szAnimationName[32]; 24 | struct _tagBeaconActivationItem *pNext; 25 | } BEACONACTIVATIONITEM; 26 | 27 | 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /* 34 | * C function callback definitions 35 | **/ 36 | typedef void(*PFN_EPXPLATFORM_BLE_BYTERECEIVED)(void *pinstance, bool altChannel, uint8_t data); 37 | typedef void(*PFN_EPXPLATFORM_BLE_COMMUNICATIONREADY)(void *pinstance, bool altChannel); 38 | typedef void(*PFN_EPXPLATFORM_BLE_CONNECTIONSTATECHANGED)(void *pinstance, bool connected); 39 | typedef void(*PFN_EPXPLATFORM_BLE_BEACONRECEIVED)(void *pinstance, char *pszHost, uint8_t beaconData); 40 | 41 | void EPXPlatform_BLE_AdvertizingUpdate(); 42 | void EPXPlatform_BLE_Disconnect(); 43 | void EPXPlatform_BLE_Initialize(void *pinstance, char *pszDEFAULT_BLE_NAME, PFN_EPXPLATFORM_BLE_CONNECTIONSTATECHANGED pfnConnectionStateChanged, PFN_EPXPLATFORM_BLE_COMMUNICATIONREADY pfnCommunicationReady, PFN_EPXPLATFORM_BLE_BYTERECEIVED pfnByteReceived); 44 | void EPXPlatform_BLE_SetManufacturerPayload(uint8_t *p, uint8_t cb); 45 | size_t EPXPlatform_BLE_SendBytes(void *pvPayload, uint16_t cb, bool altChannel); 46 | uint32_t EPXPlatform_BLE_GetLastBeaconReceived(); 47 | void EPXPlatform_BLE_SetBeaconActivation(bool on); 48 | void EPXPlatform_BLE_SetBeaconActivationEntries(BEACONACTIVATIONITEM ** ppBeaconActivationEntries); 49 | void EPXPlatform_BLE_SetBeaconReceivedHandler(PFN_EPXPLATFORM_BLE_BEACONRECEIVED pfnBLEBeaconReceived); 50 | void EPXPlatform_BLE_SetDeviceName(char *pszDeviceName); 51 | void EPXPlatform_BLE_Start(); 52 | char *EPXPlatform_BLE_GetRealizedDeviceName(); 53 | 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif 58 | 59 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/EPXPlatform_CBatteryMonitor.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #pragma once 4 | #include "nrf_drv_saadc.h" 5 | #include "nrf_drv_timer.h" 6 | 7 | /* 8 | * Class implementation declarations for Battery Monitor functionality on Nordic SDK 9 | * 10 | **/ 11 | 12 | class BatteryMonitor 13 | { 14 | public: 15 | BatteryMonitor(); 16 | 17 | void Initialize(uint16_t samplingPeriod = 0); 18 | void GetInfo(uint16_t *pMV, uint8_t *pPct); 19 | void Power(bool on) 20 | { 21 | if (on) 22 | PowerOn(); 23 | else 24 | PowerOff(); 25 | } 26 | void PowerOn(); 27 | void PowerOff(); 28 | void SingleSampleRequest(); 29 | void StartSampling(); 30 | void StopSampling(); 31 | 32 | private: 33 | void SAADC_Init(); 34 | void SAADC_UnInit(); 35 | void SAADC_SamplingInit(); 36 | 37 | static void SAADC_Callback(nrf_drv_saadc_evt_t const * p_event); 38 | static void PPI_Timerhandler(nrf_timer_event_t event_type, void * p_context); 39 | 40 | static uint8_t VoltToPercent(uint16_t mvolts); 41 | 42 | bool m_bInitialized; // True if battery monitor has been initialized 43 | bool m_bSAADCInitialized; // True if SAADC has been initialized 44 | uint16_t m_samplingPeriod; // SAADC sampling period 45 | static uint16_t m_milliVolts; // Last MV sampling value 46 | static uint8_t m_percentage; // Last battery percent remaining value 47 | }; 48 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/EPXPlatform_CByteQueue.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include "EPXPlatform_CByteQueue.h" 4 | 5 | //NRF_QUEUE_DEF(uint8_t, BLESerialCacheQueue, 1024, NRF_QUEUE_MODE_NO_OVERFLOW); 6 | 7 | /****************************************************************************/ 8 | /* BLESerialCache */ 9 | /****************************************************************************/ 10 | CByteQueue::CByteQueue() 11 | { 12 | #ifdef NORDICSDK 13 | memset(&m_queuecb, 0x00, sizeof(m_queuecb)); 14 | memset(&m_queue, 0x00, sizeof(m_queue)); 15 | m_queue.p_cb = &m_queuecb; 16 | m_queue.element_size = sizeof(uint8_t); 17 | m_queue.p_buffer = m_queueBuffer; 18 | m_queue.size = BYTEQUEUEBUFFERSIZE; 19 | m_queue.mode = NRF_QUEUE_MODE_NO_OVERFLOW; 20 | #else 21 | _buffer_overflow = false; 22 | _receive_buffer_tail = 0; 23 | _receive_buffer_head = 0; 24 | #endif 25 | } 26 | 27 | 28 | 29 | bool CByteQueue::push(uint8_t val) 30 | { 31 | #ifdef NORDICSDK 32 | uint32_t errno = nrf_queue_push(&m_queue, &val); 33 | return errno == NRF_SUCCESS; 34 | #else 35 | uint8_t next = (_receive_buffer_tail + 1) % BYTEQUEUEBUFFERSIZE; 36 | if (next != _receive_buffer_head) 37 | { 38 | // save new data in buffer: tail points to where byte goes 39 | _receive_buffer[_receive_buffer_tail] = val; // save new byte 40 | _receive_buffer_tail = next; 41 | return true; 42 | } 43 | _buffer_overflow = true; 44 | return false; 45 | #endif 46 | } 47 | 48 | 49 | 50 | // Read data from buffer 51 | int CByteQueue::pop() 52 | { 53 | #ifdef NORDICSDK 54 | uint8_t d = 0; 55 | uint32_t errno = nrf_queue_pop(&m_queue, &d); 56 | return d; 57 | #else 58 | // Empty buffer? 59 | if(_receive_buffer_head == _receive_buffer_tail) 60 | return - 1; 61 | 62 | // Read from "head" 63 | uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte 64 | _receive_buffer_head = (_receive_buffer_head + 1) % BYTEQUEUEBUFFERSIZE; 65 | return d; 66 | #endif 67 | } 68 | 69 | 70 | 71 | int CByteQueue::available() 72 | { 73 | #ifdef NORDICSDK 74 | return nrf_queue_utilization_get(&m_queue); 75 | #else 76 | return (_receive_buffer_tail + BYTEQUEUEBUFFERSIZE - _receive_buffer_head) % BYTEQUEUEBUFFERSIZE; 77 | #endif 78 | } 79 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/EPXPlatform_CByteQueue.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | /* 5 | * Class implementation declarations for ByteQueue capability on Nordic SDK 6 | * 7 | **/ 8 | #pragma once 9 | #include "app_util_platform.h" 10 | #include "nrf_queue.h" 11 | 12 | #define BYTEQUEUEBUFFERSIZE 1024 13 | 14 | class CByteQueue 15 | { 16 | public: 17 | CByteQueue(); 18 | 19 | bool push(uint8_t val); 20 | int available(); 21 | int pop(); 22 | 23 | private: 24 | #ifdef NORDICSDK 25 | uint8_t m_queueBuffer[BYTEQUEUEBUFFERSIZE + 1]; 26 | nrf_queue_cb_t m_queuecb; 27 | nrf_queue_t m_queue; 28 | #else 29 | bool _buffer_overflow; 30 | 31 | uint8_t _receive_buffer[BYTEQUEUEBUFFERSIZE]; 32 | uint8_t _receive_buffer_tail; 33 | uint8_t _receive_buffer_head; 34 | #endif 35 | }; 36 | 37 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/EPXPlatform_CFlashStorageDevice.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | #pragma once 5 | /* 6 | * Class implementation for flash chip storage access on Nordic SDK 7 | * 8 | **/ 9 | #include "EPXPlatform_SPIClass.h" 10 | 11 | // Flash status bits 12 | #define WINBOND_STAT_BUSY 0x01 // Erase/Write in Progress 13 | #define WINBOND_STAT_WRTEN 0x02 // Write Enable Latch 14 | 15 | #define WINBOND_CMD_STATREAD 0x02 16 | #define WINBOND_CMD_DATAWRITE 0x01 17 | #define WINBOND_CMD_DATAREAD 0x03 18 | #define WINBOND_CMD_READY 0x01 19 | 20 | 21 | #define WINBOND_CMD_WRITEENABLE 0x06 // Write Enabled 22 | #define WINBOND_CMD_WRITEDISABLE 0x04 // Write Disabled 23 | #define WINBOND_CMD_READSTAT1 0x05 // Read Status Register 1 24 | #define WINBOND_CMD_READSTAT2 0x35 // Read Status Register 2 25 | #define WINBOND_CMD_CHIPERASE 0xC7 // Chip Erase 26 | #define WINBOND_CMD_JEDECID 0x9F // JEDEC ID 27 | #define WINBOND_CMD_POWERDOWN 0xB9 // Power Down 28 | #define WINBOND_CMD_RELEASPOWERDOWN 0xAB // Release Power Down/Device ID 29 | #define WINBOND_CMD_SECTORERASE4K 0x20 // Sector Erase (4KB) 30 | #define WINBOND_CMD_PAGEPROG 0x02 // Page Program 31 | 32 | // Supported flash chip type JEDEC identifiers 33 | typedef enum 34 | { 35 | CHIPTYPE_W25X20CL = 0xEF120000, 36 | CHIPTYPE_W25Q80DV = 0xEF140000, 37 | CHIPTYPE_GD25Q16 = 0xC81540C8 38 | } enumChipTypes; 39 | 40 | 41 | 42 | class CFlashStorageDevice 43 | { 44 | public: 45 | CFlashStorageDevice(int8_t ss, SPIClass *spiinterface); 46 | 47 | bool ChipErase(); 48 | bool EraseUnit(uint32_t address); 49 | bool Initialize(); 50 | uint32_t ChipGetJEDECID(); 51 | uint32_t ReadBuffer(uint32_t address, uint8_t *buffer, uint32_t len); 52 | uint32_t WriteBuffer(uint32_t address, uint8_t *buffer, uint32_t len); 53 | void PowerDown(); 54 | void PowerUp(bool overrideCache = false); 55 | uint32_t BlockCount() { return m_Blocks; } 56 | uint32_t DeviceID() { return m_deviceID; } 57 | 58 | private: 59 | inline void ActivateChip(); 60 | inline void DeActivateChip(); 61 | 62 | bool ChipWaitForReady(uint32_t timeout = 1000); 63 | uint8_t ChipReadStatus(); 64 | uint8_t ChipRead(); 65 | void ChipRead(uint8_t *data, uint16_t length); 66 | void ChipWriteEnable(bool enable); 67 | void ChipWrite(uint8_t data); 68 | void ChipWrite(uint8_t *data, uint16_t length); 69 | 70 | uint32_t WritePage(uint32_t address, uint8_t *buffer, uint32_t len); 71 | 72 | bool m_bPoweredDown; // True if chip in powereddown state 73 | SPIClass *m_spi; // Reference to system SPI capability 74 | int8_t m_cs; // Flash chip select line 75 | 76 | uint32_t m_deviceID; // JEDEC flash chip ID 77 | uint32_t m_Blocks; // Number of blocks available on flash chip 78 | uint32_t m_PageSize; // Page size on flash chip 79 | uint32_t m_Pages; // Number of pages available on flash chip 80 | uint32_t m_Capacity; // Byte capacity available on flash chip 81 | }; 82 | 83 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/EPXPlatform_CStorage.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | /* 5 | * Class implementation declarations for Storage capability on Nordic SDK 6 | * 7 | **/ 8 | #pragma once 9 | #include "EPXPlatform_Runtime.h" 10 | #include "EPXPlatform_CStorageBase.h" 11 | 12 | 13 | class CStorage 14 | { 15 | public: 16 | static bool Initialize(uint16_t pinMISO, uint16_t pinMOSI, uint16_t pinSCLK, uint16_t pinCS, bool format = false); 17 | static bool CreateFolder(char *pszFolder); 18 | static bool DeleteFile(const char *pszFilename); 19 | static bool FileExists(const char *pszFilename); 20 | static bool Format(); 21 | static bool Seek(void *pFile, uint32_t pos); 22 | static uint32_t FileSize(void *pFile); 23 | static void EnumFolder(const char *pszFolder, PPERSISTED_SEQUENCE_LIST *ppFileList); 24 | static void FreeEnumFolderList(PPERSISTED_SEQUENCE_LIST *ppList); 25 | static void FreeEnumFolderListItem(PPERSISTED_SEQUENCE_LIST pItem); 26 | static void FreeEnumFolderListItemFilename(PPERSISTED_SEQUENCE_LIST pItem); 27 | static void FlashChip(); 28 | 29 | static uint16_t ReadFile(void *pFile, void *pData, uint16_t cbToRead); 30 | static uint16_t WriteFile(void *pFile, void *pData, uint16_t cbToRead); 31 | static uint32_t Capacity(); 32 | static uint32_t UsedSpace(); 33 | static uint32_t Position(void *pFile); 34 | 35 | static void Close(void *pFile); 36 | static void *CreateFile(const char *pszFilename); 37 | static void *OpenFile(const char *pszFilename, int *pFileSize = NULL); 38 | static void Power(bool on); 39 | }; 40 | 41 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/EPXPlatform_CStorageBase.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | 5 | #pragma once 6 | 7 | typedef struct _PERSISTED_SEQUENCE_LIST 8 | { 9 | char *pszFilename; 10 | char *pszGUID; 11 | char *pszName; 12 | uint16_t size; 13 | uint32_t utcTimestamp; 14 | struct _PERSISTED_SEQUENCE_LIST *pNext; 15 | } PERSISTED_SEQUENCE_LIST, *PPERSISTED_SEQUENCE_LIST; 16 | 17 | 18 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/EPXPlatform_Crypto.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | /* 5 | * Platform implementation for crypto functions on Nordic SDK 6 | * 7 | **/ 8 | #pragma once 9 | #include "app_util_platform.h" 10 | 11 | #define EPX_AES_KEY_BYTE_SIZE 16 12 | #define EPX_NONCE_SIZE 16 13 | 14 | 15 | void EPXPlatform_Crypto_Initialize(); 16 | uint8_t *EPXPlatform_Crypto_Decrypt(uint8_t * pAESKey, void *p_data, size_t len); 17 | uint8_t *EPXPlatform_Crypto_Encrypt(uint8_t * pAESKey, void * p_data, size_t len); 18 | void EPXPlatform_Crypto_GenerateNONCE(uint8_t * p_buf); -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/EPXPlatform_GPIO.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include "nrf_gpio.h" 4 | #include "app_util_platform.h" 5 | #include "app_button.h" 6 | #include "EPXPlatform_GPIO.h" 7 | #include "EPXPlatform_Runtime.h" 8 | 9 | #define MAX_GPIO_EVENTHANDLERS 4 10 | #define MAX_APP_BUTTONS 4 11 | 12 | static uint8_t g_numConfiguredAppButtons = 0; 13 | static app_button_cfg_t g_appButtons[MAX_APP_BUTTONS]; 14 | static void *g_gpioHostInstances[MAX_GPIO_EVENTHANDLERS] = { NULL, NULL, NULL, NULL }; 15 | static PFN_EPXGPIO_EVENTHANDLER g_gpioEventHandlers[MAX_GPIO_EVENTHANDLERS] = { NULL, NULL, NULL, NULL }; 16 | 17 | 18 | 19 | static void appbutton_event_handler(uint8_t pin_no, uint8_t button_action) 20 | { 21 | if (button_action == APP_BUTTON_PUSH || button_action == APP_BUTTON_RELEASE) 22 | { 23 | DEBUGLOGLN("GPIO_PIN %s", button_action == APP_BUTTON_PUSH ? "Pushed" : "Released"); 24 | for (int idx = 0; idx < MAX_GPIO_EVENTHANDLERS; idx++) 25 | { 26 | if (g_gpioEventHandlers[idx] != NULL) 27 | (*g_gpioEventHandlers[idx])(g_gpioHostInstances[idx], button_action == APP_BUTTON_PUSH ? EPXGPIO_BUTTON_PUSHED : EPXGPIO_BUTTON_RELEASED, pin_no, 1); 28 | } 29 | } 30 | } 31 | 32 | 33 | 34 | void EPXPlatform_GPIO_PinConfigure(uint32_t ulPin, uint32_t type) 35 | { 36 | if (type == EPXGPIO_OUTPUT) 37 | nrf_gpio_cfg_output(ulPin); 38 | else 39 | nrf_gpio_cfg_input(ulPin, NRF_GPIO_PIN_PULLUP); 40 | } 41 | 42 | 43 | 44 | uint32_t EPXPlatform_GPIO_PinRead(uint32_t ulPin) 45 | { 46 | return nrf_gpio_pin_read(ulPin); 47 | } 48 | 49 | 50 | 51 | void EPXPlatform_GPIO_PinWrite(uint32_t ulPin, uint32_t ulVal) 52 | { 53 | if (ulVal == EPXGPIO_HIGH) 54 | nrf_gpio_pin_set(ulPin); 55 | else if (ulVal == EPXGPIO_LOW) 56 | nrf_gpio_pin_clear(ulPin); 57 | } 58 | 59 | 60 | 61 | bool EPXPlatform_GPIO_Initialize(void *pinstance, PFN_EPXGPIO_EVENTHANDLER eventHandler) 62 | { 63 | 64 | for (int idx = 0; idx < MAX_GPIO_EVENTHANDLERS; idx++) 65 | { 66 | if (g_gpioEventHandlers[idx] == NULL) 67 | { 68 | g_gpioHostInstances[idx] = pinstance; 69 | g_gpioEventHandlers[idx] = eventHandler; 70 | return true; 71 | } 72 | } 73 | return false; 74 | } 75 | 76 | 77 | 78 | void EPXPlatform_GPIO_ButtonClickConfigure(uint32_t ulPin) 79 | { 80 | if (g_numConfiguredAppButtons < MAX_APP_BUTTONS) 81 | { 82 | g_appButtons[g_numConfiguredAppButtons].pin_no = (uint8_t) ulPin; 83 | g_appButtons[g_numConfiguredAppButtons].active_state = APP_BUTTON_ACTIVE_LOW; 84 | g_appButtons[g_numConfiguredAppButtons].pull_cfg = NRF_GPIO_PIN_PULLUP; 85 | g_appButtons[g_numConfiguredAppButtons].button_handler = appbutton_event_handler; 86 | g_numConfiguredAppButtons++; 87 | } 88 | } 89 | 90 | 91 | 92 | void EPXPlatform_GPIO_ButtonClickFinalize() 93 | { 94 | app_button_init(g_appButtons, g_numConfiguredAppButtons, 10); 95 | app_button_enable(); 96 | } 97 | 98 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/EPXPlatform_GPIO.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | /* 4 | * Platform implementation for GPIO capability on Nordic SDK 5 | * 6 | **/ 7 | 8 | #pragma once 9 | #include "app_util_platform.h" 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | enum EPXGPIOStateChange 16 | { 17 | EPXGPIO_PIN_STATECHANGE = 0, 18 | EPXGPIO_BUTTON_PUSHED, 19 | EPXGPIO_BUTTON_RELEASED 20 | }; 21 | 22 | #define EPXGPIO_LOW (0x0) 23 | #define EPXGPIO_HIGH (0x1) 24 | #define EPXGPIO_INPUT (0x0) 25 | #define EPXGPIO_OUTPUT (0x1) 26 | 27 | 28 | typedef void(*PFN_EPXGPIO_EVENTHANDLER)(void *pinstance, uint8_t event, uint16_t pin, uint16_t value); 29 | 30 | typedef void(*PFN_EPX_BUTTON_PUSHED)(void *pinstance); 31 | 32 | void EPXPlatform_GPIO_ButtonClickConfigure(uint32_t ulPin); 33 | void EPXPlatform_GPIO_ButtonClickFinalize(); 34 | bool EPXPlatform_GPIO_Initialize(void *pinstance, PFN_EPXGPIO_EVENTHANDLER eventHandler); 35 | uint32_t EPXPlatform_GPIO_PinRead(uint32_t ulPin); 36 | void EPXPlatform_GPIO_PinConfigure(uint32_t ulPin, uint32_t type); 37 | void EPXPlatform_GPIO_PinWrite(uint32_t ulPin, uint32_t ulVal); 38 | 39 | 40 | // Compatability with Arduino libraries 41 | #define LOW EPXGPIO_LOW 42 | #define HIGH EPXGPIO_HIGH 43 | #define INPUT EPXGPIO_INPUT 44 | #define OUTPUT EPXGPIO_OUTPUT 45 | 46 | #define digitalWrite(ulPin, ulVal) EPXPlatform_GPIO_PinWrite(ulPin, ulVal) 47 | #define pinMode(ulPin, ulVal) EPXPlatform_GPIO_PinConfigure(ulPin, ulVal) 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | 53 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/EPXPlatform_I2S.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include 4 | #include "nrf_drv_i2s.h" 5 | #include "EPXPlatform_I2S.h" 6 | 7 | static nrf_drv_i2s_config_t g_i2sConfig; 8 | 9 | 10 | void i2s_handler(nrfx_i2s_buffers_t const *p_released, uint32_t status) 11 | { 12 | } 13 | 14 | 15 | 16 | 17 | void EPXPlatform_I2S_Configure(uint16_t pin) 18 | { 19 | nrf_drv_i2s_config_t config = NRF_DRV_I2S_DEFAULT_CONFIG; 20 | memcpy(&g_i2sConfig, &config, sizeof(nrf_drv_i2s_config_t)); 21 | g_i2sConfig.sdin_pin = NRFX_I2S_PIN_NOT_USED; 22 | g_i2sConfig.sdout_pin = pin; 23 | g_i2sConfig.mck_setup = NRF_I2S_MCK_32MDIV10; ///< 32 MHz / 10 = 3.2 MHz. 24 | g_i2sConfig.ratio = NRF_I2S_RATIO_32X; ///< LRCK = MCK / 32. 25 | g_i2sConfig.channels = NRF_I2S_CHANNELS_STEREO; 26 | } 27 | 28 | 29 | 30 | bool EPXPlatform_I2S_Initialize() 31 | { 32 | return nrf_drv_i2s_init(&g_i2sConfig, i2s_handler) == 0; 33 | } 34 | 35 | 36 | 37 | void EPXPlatform_I2S_UnInitialize() 38 | { 39 | nrfx_i2s_uninit(); 40 | } 41 | 42 | 43 | 44 | bool EPXPlatform_I2S_Start(void *p, size_t cb) 45 | { 46 | nrfx_i2s_buffers_t buffers; 47 | buffers.p_rx_buffer = NULL; 48 | buffers.p_tx_buffer = (uint32_t *) p; 49 | return nrf_drv_i2s_start(&buffers, cb, 0) == 0; 50 | } 51 | 52 | 53 | 54 | void EPXPlatform_I2S_Stop() 55 | { 56 | nrf_drv_i2s_stop(); 57 | } -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/EPXPlatform_I2S.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | /* 5 | * Platform implementation for I2C capability on Nordic SDK 6 | * 7 | **/ 8 | #pragma once 9 | #include "app_util_platform.h" 10 | 11 | 12 | 13 | bool EPXPlatform_I2S_Initialize(); 14 | bool EPXPlatform_I2S_Start(void *p, size_t cb); 15 | void EPXPlatform_I2S_Configure(uint16_t pin); 16 | void EPXPlatform_I2S_UnInitialize(); 17 | void EPXPlatform_I2S_Stop(); 18 | 19 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/EPXPlatform_Runtime.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | /* 5 | * General runtime implementation on Nordic SDK 6 | * 7 | **/ 8 | #pragma once 9 | 10 | #include 11 | 12 | enum enumLogLevel { LOGLEVEL_INFO = 1, LOGLEVEL_PAYLOAD, LOGLEVEL_NONE }; 13 | 14 | 15 | enum enumRebootTypes 16 | { 17 | REBOOTTYPE_NONE, REBOOTTYPE_UF2, REBOOTTYPE_OTA, REBOOTTYPE_SERIAL 18 | }; 19 | 20 | uint8_t HexToByte(char *hex, int len); 21 | void BytesToHex(uint8_t *p, int cb, char *psz, int stringCB); 22 | int freeRam(); 23 | 24 | #ifndef epxmin 25 | #define epxmin(a,b) ((a)<(b)?(a):(b)) 26 | #endif 27 | 28 | #ifndef epxmax 29 | #define epxmax(a,b) ((a)>(b)?(a):(b)) 30 | #endif 31 | 32 | #define EPX_OPTIMIZEFORDEBUGGING_ON 33 | 34 | #define BytesToUInt16(a) ((uint16_t)(((uint32_t) *a << 8) | ((uint32_t) *(a + 1) << 0))) 35 | 36 | #define T(a) ((const char *) a) 37 | 38 | #ifdef __cplusplus 39 | class __FlashStringHelper; 40 | #define F(string_literal) (reinterpret_cast(string_literal)) 41 | #endif 42 | 43 | 44 | #ifdef __cplusplus 45 | extern "C" { 46 | #endif 47 | #define DEBUGLOGLN(...) NRF_LOG_DEBUG( __VA_ARGS__) 48 | 49 | void EPXPlatform_Runtime_ControlAppTimer(bool on); 50 | void EPXPlatform_Runtime_Initialize(); 51 | void EPXPlatform_Runtime_Process(); 52 | void EPXPlatform_Runtime_Reboot(uint8_t rebootType); 53 | void EPXPlatform_Runtime_MCUSleep(); 54 | void EPXPlatform_Runtime_MCUDeepSleep(); 55 | 56 | unsigned long micros(); 57 | uint32_t millis(); 58 | uint32_t millisPassed(uint32_t localMillis); 59 | 60 | void *tmalloc(const char *pszFile, int line, size_t siz); 61 | void tfree(void *buf); 62 | void tmallocdump(); 63 | void tmallocstats(); 64 | 65 | #define TMALLOC(size) tmalloc(__FILE__, __LINE__, size) 66 | #define TFREE(ptr) tfree((uint8_t *) ptr) 67 | 68 | char *stristr(const char *subject, const char *object); 69 | int stricmp(const char *s1, const char *s2); 70 | char *epx_strupr(char s[]); 71 | 72 | void delay(uint32_t ms); 73 | void delayMicroseconds(uint32_t us); 74 | 75 | #ifdef __cplusplus 76 | } 77 | #endif 78 | 79 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/EPXPlatform_SPIClass.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | /* 5 | * SPI implementation on Nordic SDK 6 | * 7 | **/ 8 | #pragma once 9 | #include "nrf_drv_spi.h" 10 | #include "app_util_platform.h" 11 | #include "EPXPlatform_GPIO.h" 12 | 13 | #define F_CPU 48000000L 14 | // SPI_HAS_TRANSACTION means SPI has 15 | // - beginTransaction() 16 | // - endTransaction() 17 | // - usingInterrupt() 18 | // - SPISetting(clock, bitOrder, dataMode) 19 | #define SPI_HAS_TRANSACTION 1 20 | 21 | #define SPI_MODE0 0x00 22 | #define SPI_MODE1 0x01 23 | #define SPI_MODE2 0x02 24 | #define SPI_MODE3 0x03 25 | 26 | #define SPI_MIN_CLOCK_DIVIDER 2 27 | 28 | 29 | enum BitOrder { 30 | LSBFIRST = 0, 31 | MSBFIRST = 1 32 | }; 33 | 34 | typedef enum 35 | { 36 | MSB_FIRST = 0, 37 | LSB_FIRST 38 | } SercomDataOrder; 39 | 40 | 41 | typedef enum 42 | { 43 | SERCOM_SPI_MODE_0 = 0, 44 | // CPOL : 0 | CPHA : 0 45 | SERCOM_SPI_MODE_1, 46 | // CPOL : 0 | CPHA : 1 47 | SERCOM_SPI_MODE_2, 48 | // CPOL : 1 | CPHA : 0 49 | SERCOM_SPI_MODE_3 // CPOL : 1 | CPHA : 1 50 | } SercomSpiClockMode; 51 | 52 | 53 | 54 | class SPISettings 55 | { 56 | public: 57 | SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) { 58 | if (__builtin_constant_p(clock)) { 59 | init_AlwaysInline(clock, bitOrder, dataMode); 60 | } 61 | else { 62 | init_MightInline(clock, bitOrder, dataMode); 63 | } 64 | } 65 | 66 | // Default speed set to 4MHz, SPI mode set to MODE 0 and Bit order set to MSB first. 67 | SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); } 68 | 69 | private: 70 | void init_MightInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) { 71 | init_AlwaysInline(clock, bitOrder, dataMode); 72 | } 73 | 74 | void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) __attribute__((__always_inline__)) { 75 | this->clockFreq = (clock >= (F_CPU / SPI_MIN_CLOCK_DIVIDER) ? F_CPU / SPI_MIN_CLOCK_DIVIDER : clock); 76 | 77 | this->bitOrder = (bitOrder == MSBFIRST ? MSB_FIRST : LSB_FIRST); 78 | 79 | switch (dataMode) 80 | { 81 | case SPI_MODE0: 82 | this->dataMode = SERCOM_SPI_MODE_0; break; 83 | case SPI_MODE1: 84 | this->dataMode = SERCOM_SPI_MODE_1; break; 85 | case SPI_MODE2: 86 | this->dataMode = SERCOM_SPI_MODE_2; break; 87 | case SPI_MODE3: 88 | this->dataMode = SERCOM_SPI_MODE_3; break; 89 | default: 90 | this->dataMode = SERCOM_SPI_MODE_0; break; 91 | } 92 | } 93 | 94 | uint32_t clockFreq; 95 | SercomSpiClockMode dataMode; 96 | SercomDataOrder bitOrder; 97 | 98 | friend class SPIClass; 99 | }; 100 | 101 | 102 | 103 | 104 | 105 | class SPIClass { 106 | public: 107 | SPIClass(NRF_SPI_Type *p_spi, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI); 108 | 109 | uint8_t transfer(uint8_t data); 110 | uint8_t transfer(uint8_t *pTXData, uint16_t cbTX, uint8_t *pRXData = NULL, uint16_t cbRX = 0); 111 | 112 | // Transaction Functions 113 | void beginTransaction(SPISettings settings); 114 | void endTransaction(void); 115 | 116 | void begin(); 117 | void end(); 118 | 119 | void setBitOrder(BitOrder order); 120 | void setDataMode(uint8_t uc_mode); 121 | void setFrequency(unsigned long freq); 122 | 123 | private: 124 | void config(SPISettings settings); 125 | 126 | NRF_SPI_Type *_p_spi; 127 | uint8_t _uc_pinSS; 128 | uint8_t _uc_pinMiso; 129 | uint8_t _uc_pinMosi; 130 | uint8_t _uc_pinSCK; 131 | 132 | uint8_t _dataMode; 133 | uint32_t _bitOrder; 134 | }; 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/EPXPlatform_Settings.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include 4 | #include "EPXString.h" 5 | #include "EPXPlatform_Settings.h" 6 | #include "EPXPlatform_CStorage.h" 7 | 8 | 9 | 10 | void CSettings::Initialize() 11 | { 12 | CStorage::CreateFolder((char *) SETTINGS_FOLDER); 13 | } 14 | 15 | 16 | 17 | void CSettings::ClearAll() 18 | { 19 | 20 | } 21 | 22 | 23 | 24 | uint16_t CSettings::Write(const char *pszSettingsKey, void *pBuffer, uint16_t cb) 25 | { 26 | uint16_t bytesWritten = 0; 27 | 28 | EPXString filename = EPXString((const char *) SETTINGS_FOLDER) + "/" + pszSettingsKey; 29 | void *pFile = CStorage::CreateFile(filename.c_str()); 30 | if (pFile != NULL) 31 | { 32 | bytesWritten = CStorage::WriteFile(pFile, pBuffer, cb); 33 | CStorage::Close(pFile); 34 | } 35 | return bytesWritten; 36 | } 37 | 38 | 39 | 40 | uint16_t CSettings::Read(const char *pszSettingsKey, void *pBuffer, uint16_t cb) 41 | { 42 | uint16_t bytesRead = 0; 43 | 44 | EPXString filename = EPXString((const char *) SETTINGS_FOLDER) + "/" + pszSettingsKey; 45 | memset(pBuffer, 0x00, cb); 46 | if (CStorage::FileExists(filename.c_str())) 47 | { 48 | void *pFile = CStorage::OpenFile(filename.c_str()); 49 | if (pFile != NULL) 50 | { 51 | bytesRead = CStorage::ReadFile(pFile, pBuffer, cb); 52 | CStorage::Close(pFile); 53 | } 54 | } 55 | return bytesRead; 56 | } 57 | 58 | 59 | 60 | bool CSettings::WriteString(const char *pszSettingsKey, char *pszValue, uint16_t valueLength) 61 | { 62 | bool success = false; 63 | uint16_t bytesWritten = 0; 64 | 65 | EPXString filename = EPXString((const char *) SETTINGS_FOLDER) + "/" + pszSettingsKey; 66 | void *pFile = CStorage::CreateFile(filename.c_str()); 67 | if (pFile != NULL) 68 | { 69 | uint16_t length = valueLength == 0 ? strlen(pszValue) : valueLength; 70 | bytesWritten = CStorage::WriteFile(pFile, &length, sizeof(length)); 71 | if (bytesWritten == sizeof(length)) 72 | { 73 | bytesWritten = CStorage::WriteFile(pFile, pszValue, length); 74 | if (bytesWritten == length) 75 | success = true; 76 | } 77 | CStorage::Close(pFile); 78 | } 79 | return success; 80 | } 81 | 82 | 83 | 84 | bool CSettings::ReadString(const char *pszSettingsKey, char *pszValue, uint16_t bufferLength) 85 | { 86 | bool success = false; 87 | uint16_t bytesRead = 0; 88 | 89 | EPXString filename = EPXString((const char *) SETTINGS_FOLDER) + "/" + pszSettingsKey; 90 | memset(pszValue, 0x00, bufferLength); 91 | 92 | if (CStorage::FileExists(filename.c_str())) 93 | { 94 | void *pFile = CStorage::OpenFile(filename.c_str()); 95 | if (pFile != NULL) 96 | { 97 | uint16_t length = strlen(pszValue); 98 | 99 | bytesRead = CStorage::ReadFile(pFile, &length, sizeof(length)); 100 | if (bytesRead == sizeof(length)) 101 | { 102 | uint16_t bytesToRead = epxmin(length, bufferLength - 1); 103 | 104 | bytesRead = CStorage::ReadFile(pFile, pszValue, bytesToRead); 105 | if (bytesRead == bytesToRead) 106 | { 107 | pszValue[bytesRead] = 0x00; 108 | success = true; 109 | } 110 | } 111 | CStorage::Close(pFile); 112 | } 113 | } 114 | return success; 115 | } 116 | 117 | 118 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/EPXPlatform_Settings.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | /* 5 | * Setting persistance implementation on Nordic SDK 6 | * 7 | **/ 8 | #pragma once 9 | #include "EPXPlatform_Runtime.h" 10 | 11 | #define SETTINGS_FOLDER F("/SETTINGS") 12 | 13 | class CSettings 14 | { 15 | public: 16 | static void Initialize(); 17 | 18 | static bool WriteString(const char *pszSettingsKey, char *pszValue, uint16_t valueLength = 0); 19 | static bool ReadString(const char *pszSettingsKey, char *pszValue, uint16_t bufferLength); 20 | static uint16_t Read(const char *pszSettingsKey, void *pBuffer, uint16_t cb); 21 | static uint16_t Write(const char *pszSettingsKey, void *pBuffer, uint16_t cb); 22 | static void ClearAll(); 23 | }; 24 | 25 | 26 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/EPXPlatform_USB.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | /* 5 | * USB implementation on Nordic SDK 6 | * 7 | **/ 8 | #pragma once 9 | #include "app_util_platform.h" 10 | 11 | #define EPXUSB_NAME_ROOT "Sparklet " 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | typedef void(*PFN_EPXPLATFORM_USB_BYTERECEIVED)(void *pinstance, uint8_t data); 18 | typedef void(*PFN_EPXPLATFORM_USB_CONNECTIONSTATECHANGED)(void *pinstance, bool connected); 19 | typedef void(*PFN_EPXPLATFORM_USB_COMMUNICATIONREADY)(void *pinstance); 20 | typedef void(*PFN_EPXPLATFORM_USB_POWERSTATECHANGED)(void *pinstance, bool powered); 21 | 22 | 23 | 24 | bool EPXPlatform_USB_Initialize(void *pinstance, PFN_EPXPLATFORM_USB_POWERSTATECHANGED g_pfnUSBPowerStateChanged, PFN_EPXPLATFORM_USB_CONNECTIONSTATECHANGED pfnConnectionStateChanged, PFN_EPXPLATFORM_USB_COMMUNICATIONREADY pfnCommunicationReady, PFN_EPXPLATFORM_USB_BYTERECEIVED pfnByteReceived); 25 | size_t EPXPlatform_USB_Write(uint8_t *p, uint16_t cb); 26 | bool EPXPlatform_USB_Activate(); 27 | void EPXPlatform_USB_Process(); 28 | void EPXPlatform_USB_SetDeviceName(char *pszDeviceName); 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | 34 | 35 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/EPXPlatform_Uart.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | #include "app_uart.h" 4 | #include "nrf_log.h" 5 | #include "nrf_log_ctrl.h" 6 | #include "nrf_log_default_backends.h" 7 | #include "EPXPlatform_Uart.h" 8 | 9 | 10 | #define UART_TX_BUF_SIZE 256 /**< UART TX buffer size. */ 11 | #define UART_RX_BUF_SIZE 256 /**< UART RX buffer size. */ 12 | 13 | 14 | const uint16_t EPXUart::SysExMaxSize = 64; 15 | CByteQueue EPXUart::UartFIFO; 16 | 17 | 18 | void uart_event_handle(app_uart_evt_t * p_event) 19 | { 20 | if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR) 21 | { 22 | NRF_LOG_INFO("uart_event_handle ERROR %d", p_event->data.error_communication); 23 | } 24 | else if (p_event->evt_type == APP_UART_FIFO_ERROR) 25 | { 26 | NRF_LOG_INFO("uart_event_handle FIFO %d", p_event->data.error_code); 27 | } 28 | else if (p_event->evt_type == APP_UART_DATA_READY) 29 | { 30 | uint8_t data; 31 | app_uart_get(&data); 32 | //NRF_LOG_INFO("UART DATA %c", data); 33 | EPXUart::UartFIFO.push(data); 34 | } 35 | } 36 | 37 | 38 | 39 | EPXUart::EPXUart(uint32_t rxPin, uint32_t txPin, uint32_t baud) 40 | { 41 | uint32_t err_code; 42 | 43 | const app_uart_comm_params_t comm_params = 44 | { 45 | rxPin == 0 ? UART_PIN_DISCONNECTED : rxPin, 46 | txPin == 0 ? UART_PIN_DISCONNECTED : txPin, 47 | UART_PIN_DISCONNECTED, 48 | UART_PIN_DISCONNECTED, 49 | APP_UART_FLOW_CONTROL_DISABLED, 50 | false, 51 | baud 52 | }; 53 | 54 | APP_UART_FIFO_INIT(&comm_params, 55 | UART_RX_BUF_SIZE, 56 | UART_TX_BUF_SIZE, 57 | uart_event_handle, 58 | APP_IRQ_PRIORITY_LOWEST, 59 | err_code); 60 | APP_ERROR_CHECK(err_code); 61 | } 62 | 63 | -------------------------------------------------------------------------------- /Firmware/Platform_NordicSDK/EPXPlatform_Uart.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT license. 3 | 4 | /* 5 | * UART implementation on Nordic SDK 6 | * 7 | **/ 8 | #pragma once 9 | #include "stdint.h" 10 | #include "nrf_uart.h" 11 | #include "EPXPlatform_CByteQueue.h" 12 | 13 | 14 | 15 | class EPXUart 16 | { 17 | public: 18 | static const uint16_t SysExMaxSize; 19 | static CByteQueue UartFIFO; 20 | 21 | EPXUart(uint32_t rxPin, uint32_t txPin, uint32_t baud); 22 | 23 | void begin(unsigned long baud) 24 | { 25 | 26 | } 27 | 28 | 29 | 30 | int available(void) 31 | { 32 | return UartFIFO.available(); 33 | } 34 | 35 | 36 | 37 | int read(void) 38 | { 39 | // return -1 when data is unvailable (arduino api) 40 | if(UartFIFO.available()) 41 | return UartFIFO.pop(); 42 | return -1; 43 | } 44 | 45 | 46 | uint16_t write(uint8_t c) 47 | { 48 | // return uart_write_char(_uart, c); 49 | return 0; 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /Firmware/RaspberryPi/play.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | sudo python animate.py play "$*" 3 | -------------------------------------------------------------------------------- /Firmware/RaspberryPi/readme.md: -------------------------------------------------------------------------------- 1 | # Expressive Pixels on Raspberry Pi 2 | 3 | ## Python support 4 | 5 | Running Expressive Pixels with Raspberry Pi allows you to extend the platform using Python. Please follow the steps below for working with Raspberry Pi. 6 | 7 | ## Hardware 8 | You need the following things for an initial prototype. 9 | * Raspberry Pi (I haven't yet tested Raspberry Pi Zero. But that should work as well) 10 | * A WS2811 or other compatible displays with individually addressable LEDs (e.g. [Sparklet display](https://www.amazon.com/Sparklet-256X-Round-Color-Display/dp/B08FHGGC7N/) 11 | * [TTL Serial Cable](https://www.amazon.com/JBtek-WINDOWS-Supported-Raspberry-Programming/dp/B00QT7LQ88/) (If you find BLE to be buggy and wish to use the serial port) 12 | 13 | ### Raspberry Pi Setup 14 | * [Install the Raspberry Pi OS](https://www.raspberrypi.org/software/) 15 | * You can connect to your Pi using USB or over the network. Initially USB is convenient, but it is a good idea to make your Raspberry Pi accessible over the network for later use. 16 | * [Steps for USB](https://howchoo.com/pi/raspberry-pi-gadget-mode) 17 | * The main thing here is to make sure that the Pi is connected to your WiFi network and its name can be resolved over the network. Follow these steps for [name resolution from Windows](https://serverfault.com/questions/145994/resolve-linux-hostname-in-windows). 18 | * Setup password less login(http://rebol.com/docs/ssh-auto-login.html) 19 | 20 | At this point you should be able to connect to your Raspberri Pi and login. Make sure you have common tools installed like git and Python 3.x. 21 | 22 | 23 | ### Wiring 24 | *NOTE* The Python firmware supports connecting from the Expressive Pixels app using both BLE and Serial ports. The steps below indicate 25 | 26 | Please refer to the [GPIO pin layout](https://www.raspberrypi.org/documentation/usage/gpio/) of Raspberry Pi and make the following connections: 27 | 28 | ------- 29 | |Raspberry Pi Pin | Connected to | 30 | ------------------------|----------------| 31 | | Pin 2 (5V Power) |Sparklet Pin 5V | 32 | | Pin 4 (5V Power) |Sparklet Pin EN | 33 | | Pin 6 (GND) |Sparklet Pin GND| 34 | | Pin 8 (GPIO 14-TXD) |TTL cable WHITE | 35 | | Pin 10 (GPIO 15-RXD) |TTL cable GREEN | 36 | | Pin 12 (GPIO 18-PCM_CLK)|Sparklet Pin DATA(D) | 37 | | Pin 14 (GND) |TTL cable BLACK (GND)| 38 | ------ 39 | 40 | 41 | NOTE: The TTL cable connections are needed only if you are using the TTL cable. As noted above, BLE is supported, but the serial cable can be helpful in isolating connection issues. 42 | 43 | ## Software 44 | * On the Raspberry Pi 45 | * `git clone https://github.com/microsoft/ExpressivePixels/` 46 | * `cd ExpressivePixels/Firmware/RaspberryPi` 47 | * For BLE connections: 48 | * `sudo python3 sparklet.py ble` 49 | * For serial connections: 50 | * `sudo python3 sparklet.py serial` 51 | 52 | * Install the [Expressive Pixels](https://www.microsoft.com/en-us/p/expressive-pixels/9mtc56w1rxqh?activetab=pivot:overviewtab) app from the Windows Store 53 | * Run and use the Expressive Pixels app 54 | 55 | -------------------------------------------------------------------------------- /Firmware/RaspberryPi/requirements.txt: -------------------------------------------------------------------------------- 1 | pybleno==0.11 2 | fire==0.3.1 3 | numpy==1.16.2 4 | rpi_ws281x==4.2.5 5 | cobs==1.1.4 6 | arcade==2.5.1 7 | backports.statistics==0.1.0 8 | Cython==0.29.21 9 | dataclasses==0.8 10 | ipaddr==2.2.0 11 | ordereddict==1.1 12 | Pillow==8.0.1 13 | psutil==5.7.3 14 | pyserial==3.5 15 | PyYAML==5.3.1 16 | wincertstore==0.2 17 | -------------------------------------------------------------------------------- /Firmware/RaspberryPi/serial_device.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import serial 3 | import time 4 | 5 | class SerialDevice: 6 | def __init__(self, sparklet): 7 | self.sparklet = sparklet 8 | self.name = 'PiSpark' 9 | self.short_name = 'PSPK' 10 | self.port = '/dev/ttyS0' 11 | self.baud = 115200 12 | self.stop = False 13 | self.timeout = 10 14 | 15 | def start(self): 16 | self.serial = serial.Serial(self.port, self.baud) 17 | self.serial.timeout = 10 18 | while not self.stop: 19 | data = self.serial.read(4096) 20 | if len(data) > 0: 21 | logging.debug(f'SerialDevice received {len(data)} bytes') 22 | self.sparklet.on_write_request(data, 0) 23 | else: 24 | time.sleep(0.1) 25 | self.serial.close() 26 | 27 | def write(self, data): 28 | logging.debug(f'SerialDevice writing {len(data)} bytes') 29 | self.serial.write(data) 30 | 31 | def stop(self): 32 | self.stop = True 33 | 34 | 35 | -------------------------------------------------------------------------------- /Firmware/RaspberryPi/settings.yaml: -------------------------------------------------------------------------------- 1 | brightness: 50 2 | -------------------------------------------------------------------------------- /Firmware/RaspberryPi/txt2anim.py: -------------------------------------------------------------------------------- 1 | import fire 2 | from PIL import Image, ImageDraw, ImageFont 3 | from animation import Animation, IFrame, DFrame, Color 4 | 5 | def get_palette(images): 6 | palette = [] 7 | for image in images: 8 | w, h = image.size 9 | colors = [image.getpixel((i % w, i // w)) for i in range(w*h)] 10 | palette.extend(colors) 11 | palette = list(set(palette)) 12 | return palette 13 | 14 | def images_to_animation(images, delay): 15 | animation = Animation(None) 16 | palette = get_palette(images) 17 | palette_lookup = {clr: index for index, clr in enumerate(palette)} 18 | animation.palette = [Color(r, g, b) for (r, g, b) in palette] 19 | 20 | frames = [] 21 | for image in images: 22 | w, h = image.size 23 | colors = [image.getpixel((i % w, i // w)) for i in range(w*h)] 24 | indices = [palette_lookup[clr] for clr in colors] 25 | frame = IFrame(ord('I'), w * h, indices) 26 | frames.append(frame) 27 | 28 | frame = DFrame(ord('D'), delay) 29 | frames.append(frame) 30 | 31 | animation.frames_count = len(frames) 32 | animation.data = frames 33 | return animation 34 | 35 | def text_to_animation(text, font_size, color, delay): 36 | animation_size = (18, 18) 37 | font_path = '/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf' 38 | font = ImageFont.truetype(font_path, font_size) 39 | width, height = animation_size 40 | images = [] 41 | for char in text: 42 | img = Image.new('RGB', animation_size) 43 | draw = ImageDraw.Draw(img) 44 | size = draw.textsize(char, font) 45 | x = (width - size[0]) // 2 46 | y = (height - size[1]) // 2 47 | draw.text((x, y), char, color, font) 48 | images.append(img) 49 | animation = images_to_animation(images, delay) 50 | animation.name = text 51 | Animation.save(text, animation) 52 | 53 | 54 | # e.g. 55 | # python txt2anim.py "HAPPY NEW YEAR" 15, #00ff00 500 56 | if __name__ == '__main__': 57 | fire.Fire(text_to_animation) 58 | 59 | 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | Welcome to the Microsoft Expressive Pixels project!! Please be sure to visit the [Wiki](https://github.com/microsoft/ExpressivePixels/wiki) to learn more about how to integrate Expressive Pixels capabilities in your own creations. 4 | 5 | 6 | # Contributing 7 | 8 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 9 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 10 | the rights to use your contribution. For details, visit https://cla.microsoft.com. 11 | 12 | When you submit a pull request, a CLA-bot will automatically determine whether you need to provide 13 | a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions 14 | provided by the bot. You will only need to do this once across all repos using our CLA. 15 | 16 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 17 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 18 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 19 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/UWP/App.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/UWP/Assets/LockScreenLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/Windows/ExpressivePixelsActivator/UWP/Assets/LockScreenLogo.scale-200.png -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/UWP/Assets/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/Windows/ExpressivePixelsActivator/UWP/Assets/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/UWP/Assets/Square150x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/Windows/ExpressivePixelsActivator/UWP/Assets/Square150x150Logo.scale-200.png -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/UWP/Assets/Square44x44Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/Windows/ExpressivePixelsActivator/UWP/Assets/Square44x44Logo.scale-200.png -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/Windows/ExpressivePixelsActivator/UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/UWP/Assets/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/Windows/ExpressivePixelsActivator/UWP/Assets/StoreLogo.png -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/UWP/Assets/Wide310x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/Windows/ExpressivePixelsActivator/UWP/Assets/Wide310x150Logo.scale-200.png -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/UWP/Converters/BoolInverterConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Runtime.CompilerServices; 6 | using Windows.Foundation; 7 | using Windows.Foundation.Collections; 8 | using Windows.Graphics.Display; 9 | using Windows.UI.ViewManagement; 10 | using Windows.UI.Xaml; 11 | using Windows.UI.Xaml.Controls; 12 | using Windows.UI.Xaml.Data; 13 | 14 | namespace Microsoft.ExpressivePixels.Converters 15 | { 16 | /// 17 | /// Value converter that translates true to and false to 18 | /// . 19 | /// 20 | public sealed class BooleanInverterConverter : IValueConverter 21 | { 22 | public object Convert(object value, Type targetType, object parameter, string language) 23 | { 24 | return (!(bool)value); 25 | } 26 | 27 | public object ConvertBack(object value, Type targetType, object parameter, string language) 28 | { 29 | return value is Visibility && (Visibility)value == Visibility.Visible; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/UWP/Converters/BoolToOpacityConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Windows.UI.Xaml; 3 | using Windows.UI.Xaml.Data; 4 | 5 | namespace Microsoft.ExpressivePixels.Converters 6 | { 7 | /// 8 | /// Value converter that translates true to and false to 9 | /// . 10 | /// 11 | public sealed class BooleanToOpacityConverter : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, string language) 14 | { 15 | string[] opacityPair = ((string)parameter).Split(','); 16 | return (bool)value ? System.Convert.ToDouble(opacityPair[0]) : System.Convert.ToDouble(opacityPair[1]); 17 | } 18 | 19 | public object ConvertBack(object value, Type targetType, object parameter, string language) 20 | { 21 | throw new NotImplementedException(); 22 | } 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/UWP/Converters/BooleanToVisibilityConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Runtime.CompilerServices; 6 | using Windows.Foundation; 7 | using Windows.Foundation.Collections; 8 | using Windows.Graphics.Display; 9 | using Windows.UI.ViewManagement; 10 | using Windows.UI.Xaml; 11 | using Windows.UI.Xaml.Controls; 12 | using Windows.UI.Xaml.Data; 13 | 14 | namespace Microsoft.ExpressivePixels.Converters 15 | { 16 | /// 17 | /// Value converter that translates true to and false to 18 | /// . 19 | /// 20 | public sealed class BooleanToVisibilityConverter : IValueConverter 21 | { 22 | public object Convert(object value, Type targetType, object parameter, string language) 23 | { 24 | return (value is bool && (bool)value) ? Visibility.Visible : Visibility.Collapsed; 25 | 26 | } 27 | 28 | public object ConvertBack(object value, Type targetType, object parameter, string language) 29 | { 30 | return Convert(value, targetType, parameter, language); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/UWP/Converters/EnumStateToStringConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Windows.UI.Xaml; 4 | using Windows.UI.Xaml.Data; 5 | 6 | namespace Microsoft.ExpressivePixels.Converters 7 | { 8 | /// 9 | /// Value converter that translates true to and false to 10 | /// . 11 | /// 12 | public sealed class EnumStateToStringConverter : IValueConverter 13 | { 14 | public object Convert(object value, Type targetType, object parameter, string language) 15 | { 16 | Dictionary setDictionary = new Dictionary(); 17 | var sets = ((string)parameter).Split(';'); 18 | foreach (string set in sets) 19 | { 20 | var pair = set.Split(','); 21 | setDictionary[pair[0]] = pair[1]; 22 | } 23 | return setDictionary[value.ToString()]; 24 | } 25 | 26 | public object ConvertBack(object value, Type targetType, object parameter, string language) 27 | { 28 | throw new NotImplementedException(); 29 | } 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/UWP/ExpressivePixelsActivatorUWP.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30503.244 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExpressivePixelsActivatorUWP", "ExpressivePixelsActivatorUWP.csproj", "{320D1674-26DB-410F-A276-7F0DFB836756}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|ARM = Debug|ARM 11 | Debug|ARM64 = Debug|ARM64 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|ARM = Release|ARM 15 | Release|ARM64 = Release|ARM64 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {320D1674-26DB-410F-A276-7F0DFB836756}.Debug|ARM.ActiveCfg = Debug|ARM 21 | {320D1674-26DB-410F-A276-7F0DFB836756}.Debug|ARM.Build.0 = Debug|ARM 22 | {320D1674-26DB-410F-A276-7F0DFB836756}.Debug|ARM.Deploy.0 = Debug|ARM 23 | {320D1674-26DB-410F-A276-7F0DFB836756}.Debug|ARM64.ActiveCfg = Debug|ARM64 24 | {320D1674-26DB-410F-A276-7F0DFB836756}.Debug|ARM64.Build.0 = Debug|ARM64 25 | {320D1674-26DB-410F-A276-7F0DFB836756}.Debug|ARM64.Deploy.0 = Debug|ARM64 26 | {320D1674-26DB-410F-A276-7F0DFB836756}.Debug|x64.ActiveCfg = Debug|x64 27 | {320D1674-26DB-410F-A276-7F0DFB836756}.Debug|x64.Build.0 = Debug|x64 28 | {320D1674-26DB-410F-A276-7F0DFB836756}.Debug|x64.Deploy.0 = Debug|x64 29 | {320D1674-26DB-410F-A276-7F0DFB836756}.Debug|x86.ActiveCfg = Debug|x86 30 | {320D1674-26DB-410F-A276-7F0DFB836756}.Debug|x86.Build.0 = Debug|x86 31 | {320D1674-26DB-410F-A276-7F0DFB836756}.Debug|x86.Deploy.0 = Debug|x86 32 | {320D1674-26DB-410F-A276-7F0DFB836756}.Release|ARM.ActiveCfg = Release|ARM 33 | {320D1674-26DB-410F-A276-7F0DFB836756}.Release|ARM.Build.0 = Release|ARM 34 | {320D1674-26DB-410F-A276-7F0DFB836756}.Release|ARM.Deploy.0 = Release|ARM 35 | {320D1674-26DB-410F-A276-7F0DFB836756}.Release|ARM64.ActiveCfg = Release|ARM64 36 | {320D1674-26DB-410F-A276-7F0DFB836756}.Release|ARM64.Build.0 = Release|ARM64 37 | {320D1674-26DB-410F-A276-7F0DFB836756}.Release|ARM64.Deploy.0 = Release|ARM64 38 | {320D1674-26DB-410F-A276-7F0DFB836756}.Release|x64.ActiveCfg = Release|x64 39 | {320D1674-26DB-410F-A276-7F0DFB836756}.Release|x64.Build.0 = Release|x64 40 | {320D1674-26DB-410F-A276-7F0DFB836756}.Release|x64.Deploy.0 = Release|x64 41 | {320D1674-26DB-410F-A276-7F0DFB836756}.Release|x86.ActiveCfg = Release|x86 42 | {320D1674-26DB-410F-A276-7F0DFB836756}.Release|x86.Build.0 = Release|x86 43 | {320D1674-26DB-410F-A276-7F0DFB836756}.Release|x86.Deploy.0 = Release|x86 44 | EndGlobalSection 45 | GlobalSection(SolutionProperties) = preSolution 46 | HideSolutionNode = FALSE 47 | EndGlobalSection 48 | GlobalSection(ExtensibilityGlobals) = postSolution 49 | SolutionGuid = {B4ED7ACE-0FBF-4E1F-BD1A-B9D86F1CD683} 50 | EndGlobalSection 51 | EndGlobal 52 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/UWP/Package.appxmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | ExpressivePixelsActivatorUWP 18 | gavinj 19 | Assets\StoreLogo.png 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/UWP/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ExpressivePixelsActivatorUWP")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ExpressivePixelsActivatorUWP")] 13 | [assembly: AssemblyCopyright("Copyright © 2020")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Version information for an assembly consists of the following four values: 18 | // 19 | // Major Version 20 | // Minor Version 21 | // Build Number 22 | // Revision 23 | // 24 | // You can specify all the values or you can default the Build and Revision Numbers 25 | // by using the '*' as shown below: 26 | // [assembly: AssemblyVersion("1.0.*")] 27 | [assembly: AssemblyVersion("1.0.0.0")] 28 | [assembly: AssemblyFileVersion("1.0.0.0")] 29 | [assembly: ComVisible(false)] -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/UWP/Properties/Default.rd.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/WPF/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/WPF/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace Microsoft.Research.ExpressivePixelsActivatorWPF 4 | { 5 | /// 6 | /// Interaction logic for App.xaml 7 | /// 8 | public partial class App : Application 9 | { 10 | public App() 11 | { 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/WPF/Controls/DelegateCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Input; 3 | 4 | namespace Microsoft.Research 5 | { 6 | public class DelegateCommand : ICommand 7 | { 8 | private readonly Predicate _canExecute; 9 | private readonly Action _execute; 10 | 11 | 12 | public event EventHandler CanExecuteChanged; 13 | 14 | public DelegateCommand(Action execute) 15 | : this(execute, null) 16 | { 17 | } 18 | 19 | 20 | 21 | public DelegateCommand(Action execute, 22 | Predicate canExecute) 23 | { 24 | _execute = execute; 25 | _canExecute = canExecute; 26 | } 27 | 28 | 29 | 30 | public bool CanExecute(object parameter) 31 | { 32 | if (_canExecute == null) 33 | { 34 | return true; 35 | } 36 | return _canExecute(parameter); 37 | } 38 | 39 | 40 | 41 | public void Execute(object parameter) 42 | { 43 | _execute(parameter); 44 | } 45 | 46 | 47 | 48 | public void RaiseCanExecuteChanged() 49 | { 50 | CanExecuteChanged?.Invoke(this, null); 51 | } 52 | } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/WPF/Converters/BoolInverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows.Data; 8 | using System.Windows.Markup; 9 | 10 | namespace Microsoft.ExpressivePixels.Converters 11 | { 12 | public class BoolInverter : MarkupExtension, IValueConverter 13 | { 14 | public override object ProvideValue(IServiceProvider serviceProvider) 15 | { 16 | return this; 17 | } 18 | 19 | public object Convert(object value, Type targetType, object parameter, CultureInfo language) 20 | { 21 | return (!(bool)value); 22 | } 23 | 24 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo language) 25 | { 26 | return Convert(value, targetType, parameter, language); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/WPF/Converters/BoolToOpacityConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | 5 | namespace Microsoft.ExpressivePixels.Converters 6 | { 7 | class BoolToOpacityConverter : IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, CultureInfo language) 10 | { 11 | string[] opacityPair = ((string)parameter).Split(','); 12 | return (bool)value ? System.Convert.ToDouble(opacityPair[0]) : System.Convert.ToDouble(opacityPair[1]); 13 | } 14 | 15 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo language) 16 | { 17 | throw new NotImplementedException(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/WPF/Converters/BooleanToVisibilityConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace Microsoft.ExpressivePixels.Converters 7 | { 8 | /// 9 | /// Value converter that translates true to and false to 10 | /// . 11 | /// 12 | public sealed class BooleanToVisibilityConverter : IValueConverter 13 | { 14 | public object Convert(object value, Type targetType, object parameter, CultureInfo language) 15 | { 16 | bool inverse = (parameter != null && String.Compare((string) parameter, "True", StringComparison.OrdinalIgnoreCase) == 0); 17 | return (value is bool && (bool)value) ? (inverse ? Visibility.Collapsed : Visibility.Visible) : (inverse ? Visibility.Visible : Visibility.Collapsed); 18 | } 19 | 20 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo language) 21 | { 22 | return value is Visibility && (Visibility)value == Visibility.Visible; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/WPF/Converters/BrightnessToSliderValueConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Controls; 5 | using System.Windows.Data; 6 | 7 | namespace Microsoft.ExpressivePixels.Converters 8 | { 9 | public sealed class BrightnessToSliderValueConverter : IValueConverter 10 | { 11 | public object Convert(object value, Type targetType, object parameter, CultureInfo language) 12 | { 13 | if (parameter == null) 14 | throw new Exception("BrightnessToSliderValueConverter exception Range parameter missing"); 15 | double dparameter = System.Convert.ToDouble((string) parameter); 16 | return (double)value * dparameter; 17 | } 18 | 19 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo language) 20 | { 21 | if (parameter == null) 22 | throw new Exception("BrightnessToSliderValueConverter exception Range parameter missing"); 23 | double dparameter = System.Convert.ToDouble((string)parameter); 24 | return ((double)value / dparameter); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/WPF/Converters/DoubleToIntConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace Microsoft.ExpressivePixels.Converters 7 | { 8 | public sealed class DoubleToIntConverter : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo language) 11 | { 12 | double dval = (double)value; 13 | return (int)dval; 14 | } 15 | 16 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo language) 17 | { 18 | return new NotImplementedException(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/WPF/Converters/EmptyStringToVisibilityConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | using System.Windows.Data; 9 | 10 | namespace Microsoft.ExpressivePixels.Converters 11 | { 12 | public class EmptyStringToVisibilityConverter : IValueConverter 13 | { 14 | public object Convert(object value, Type targetType, object parameter, CultureInfo language) 15 | { 16 | string emptyString = value as string; 17 | 18 | bool inverse = (parameter != null && String.Compare((string)parameter, "True", StringComparison.OrdinalIgnoreCase) == 0); 19 | return (emptyString != null && emptyString.Length > 0) ? (inverse ? Visibility.Collapsed : Visibility.Visible) : (inverse ? Visibility.Visible : Visibility.Collapsed); 20 | } 21 | 22 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo language) 23 | { 24 | throw new NotImplementedException(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/WPF/Converters/EnumStateToStringConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows.Data; 8 | 9 | namespace Microsoft.ExpressivePixels.Converters 10 | { 11 | public class EnumStateToStringConverter : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo language) 14 | { 15 | Dictionary setDictionary = new Dictionary(); 16 | var sets = ((string)parameter).Split(';'); 17 | foreach(string set in sets) 18 | { 19 | var pair = set.Split(','); 20 | setDictionary[pair[0]] = pair[1]; 21 | } 22 | return setDictionary[value.ToString()]; 23 | } 24 | 25 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo language) 26 | { 27 | throw new NotImplementedException(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/WPF/Converters/EnumStringToTemplateConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | using System.Windows.Data; 9 | 10 | namespace Microsoft.ExpressivePixels.Converters 11 | { 12 | public class EnumStringToTemplateConverter : IValueConverter 13 | { 14 | public object Convert(object value, Type targetType, object parameter, CultureInfo language) 15 | { 16 | Dictionary setDictionary = new Dictionary(); 17 | var sets = ((string)parameter).Split(';'); 18 | foreach (string set in sets) 19 | { 20 | var pair = set.Split(','); 21 | setDictionary[pair[0]] = pair[1]; 22 | } 23 | if (setDictionary.ContainsKey(value.ToString())) 24 | return Application.Current.FindResource(setDictionary[value.ToString()]); 25 | else 26 | return null; 27 | } 28 | 29 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo language) 30 | { 31 | throw new NotImplementedException(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/WPF/Converters/OrientationToVisibilityConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Controls; 5 | using System.Windows.Data; 6 | 7 | namespace Microsoft.ExpressivePixels.Converters 8 | { 9 | public class OrientationToVisibilityConverter : IValueConverter 10 | { 11 | public object Convert(object value, Type targetType, object parameter, CultureInfo language) 12 | { 13 | Orientation orientation = (Orientation)value; 14 | return String.Compare((string)orientation.ToString(), "Vertical") == 0 ? Visibility.Visible : Visibility.Collapsed; 15 | } 16 | 17 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo language) 18 | { 19 | throw new NotImplementedException(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/WPF/Converters/TrueFalseBrushConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows.Data; 8 | using System.Windows.Media; 9 | 10 | namespace Microsoft.ExpressivePixels.Converters 11 | { 12 | public sealed class TrueFalseBrushConverter : IValueConverter 13 | { 14 | public Brush TrueBrush { get; set; } 15 | public Brush FalseBrush { get; set; } 16 | 17 | 18 | public object Convert(object value, Type targetType, object parameter, CultureInfo language) 19 | { 20 | return (value is bool && (bool)value) ? TrueBrush : FalseBrush; 21 | } 22 | 23 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo language) 24 | { 25 | throw new Exception(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/WPF/ExpressivePixelsActivatorWPF.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30503.244 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExpressivePixelsActivatorWPF", "ExpressivePixelsActivatorWPF.csproj", "{82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|ARM = Debug|ARM 12 | Debug|ARM64 = Debug|ARM64 13 | Debug|x64 = Debug|x64 14 | Debug|x86 = Debug|x86 15 | Release|Any CPU = Release|Any CPU 16 | Release|ARM = Release|ARM 17 | Release|ARM64 = Release|ARM64 18 | Release|x64 = Release|x64 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}.Debug|ARM.ActiveCfg = Debug|Any CPU 25 | {82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}.Debug|ARM.Build.0 = Debug|Any CPU 26 | {82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}.Debug|ARM64.ActiveCfg = Debug|Any CPU 27 | {82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}.Debug|ARM64.Build.0 = Debug|Any CPU 28 | {82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}.Debug|x64.ActiveCfg = Debug|Any CPU 29 | {82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}.Debug|x64.Build.0 = Debug|Any CPU 30 | {82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}.Debug|x86.ActiveCfg = Debug|x86 31 | {82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}.Debug|x86.Build.0 = Debug|x86 32 | {82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}.Release|ARM.ActiveCfg = Release|Any CPU 35 | {82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}.Release|ARM.Build.0 = Release|Any CPU 36 | {82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}.Release|ARM64.ActiveCfg = Release|Any CPU 37 | {82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}.Release|ARM64.Build.0 = Release|Any CPU 38 | {82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}.Release|x64.ActiveCfg = Release|Any CPU 39 | {82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}.Release|x64.Build.0 = Release|Any CPU 40 | {82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}.Release|x86.ActiveCfg = Release|x86 41 | {82E66ACA-F91D-49C9-BB0D-843F47DCDD7C}.Release|x86.Build.0 = Release|x86 42 | EndGlobalSection 43 | GlobalSection(SolutionProperties) = preSolution 44 | HideSolutionNode = FALSE 45 | EndGlobalSection 46 | GlobalSection(ExtensibilityGlobals) = postSolution 47 | SolutionGuid = {7061D24D-6554-49A9-AF5D-0A52A3C4D6AA} 48 | EndGlobalSection 49 | GlobalSection(Performance) = preSolution 50 | HasPerformanceSessions = true 51 | EndGlobalSection 52 | EndGlobal 53 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/WPF/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("Microsoft.Research.EmbeddedDeviceConnectivity.SampleWPF")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("")] 14 | [assembly: AssemblyProduct("Microsoft.Research.EmbeddedDeviceConnectivity.SampleWPF")] 15 | [assembly: AssemblyCopyright("Copyright © 2019")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(false)] 23 | 24 | //In order to begin building localizable applications, set 25 | //CultureYouAreCodingWith in your .csproj file 26 | //inside a . For example, if you are using US english 27 | //in your source files, set the to en-US. Then uncomment 28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 29 | //the line below to match the UICulture setting in the project file. 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 36 | //(used if a resource is not found in the page, 37 | // or application resource dictionaries) 38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 39 | //(used if a resource is not found in the page, 40 | // app, or any theme specific resource dictionaries) 41 | )] 42 | 43 | 44 | // Version information for an assembly consists of the following four values: 45 | // 46 | // Major Version 47 | // Minor Version 48 | // Build Number 49 | // Revision 50 | // 51 | // You can specify all the values or you can default the Build and Revision Numbers 52 | // by using the '*' as shown below: 53 | // [assembly: AssemblyVersion("1.0.*")] 54 | [assembly: AssemblyVersion("1.0.0.0")] 55 | [assembly: AssemblyFileVersion("1.0.0.0")] 56 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/WPF/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Microsoft.Research.ExpressivePixelsActivatorWPF.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.Research.ExpressivePixelsActivatorWPF.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/WPF/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Microsoft.Research.ExpressivePixelsActivatorWPF.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.7.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/WPF/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Windows/ExpressivePixelsActivator/WPF/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /images/ArduinoAdaCPX16x16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/ArduinoAdaCPX16x16.jpg -------------------------------------------------------------------------------- /images/ArduinoAdaCPX8x8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/ArduinoAdaCPX8x8.jpg -------------------------------------------------------------------------------- /images/ArduinoLayers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/ArduinoLayers.png -------------------------------------------------------------------------------- /images/ArduinoTinyUSB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/ArduinoTinyUSB.png -------------------------------------------------------------------------------- /images/Docs-AnimationFormat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/Docs-AnimationFormat.png -------------------------------------------------------------------------------- /images/Docs-AnimationFormatFrames.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/Docs-AnimationFormatFrames.png -------------------------------------------------------------------------------- /images/Docs-AnimationFormatHeader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/Docs-AnimationFormatHeader.png -------------------------------------------------------------------------------- /images/Docs-AnimationFormatHigh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/Docs-AnimationFormatHigh.png -------------------------------------------------------------------------------- /images/Docs-AnimationFormatPalette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/Docs-AnimationFormatPalette.png -------------------------------------------------------------------------------- /images/Docs-CommsFormat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/Docs-CommsFormat.png -------------------------------------------------------------------------------- /images/Docs-MakeCode-Button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/Docs-MakeCode-Button.png -------------------------------------------------------------------------------- /images/Docs-MakeCode-Download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/Docs-MakeCode-Download.png -------------------------------------------------------------------------------- /images/Docs-MakeCode-EPXDisplay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/Docs-MakeCode-EPXDisplay.png -------------------------------------------------------------------------------- /images/Docs-MakeCode-Extension.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/Docs-MakeCode-Extension.png -------------------------------------------------------------------------------- /images/Docs-MakeCode-ExtensionURL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/Docs-MakeCode-ExtensionURL.png -------------------------------------------------------------------------------- /images/Docs-MakeCode-JScript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/Docs-MakeCode-JScript.png -------------------------------------------------------------------------------- /images/Docs-MakeCode-Javascript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/Docs-MakeCode-Javascript.png -------------------------------------------------------------------------------- /images/Docs-MakeCode-SetDisplay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/Docs-MakeCode-SetDisplay.png -------------------------------------------------------------------------------- /images/Docs-MakeCode-Startup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/Docs-MakeCode-Startup.png -------------------------------------------------------------------------------- /images/Docs-MatrixPortalActivation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/Docs-MatrixPortalActivation.png -------------------------------------------------------------------------------- /images/Docs-MatrixPortalConnect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/Docs-MatrixPortalConnect.png -------------------------------------------------------------------------------- /images/EPXArchitecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/EPXArchitecture.png -------------------------------------------------------------------------------- /images/EPXGitHubLockup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/EPXGitHubLockup.png -------------------------------------------------------------------------------- /images/SWDConfiguration.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/SWDConfiguration.jpg -------------------------------------------------------------------------------- /images/VSCodeAdditionalUrls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/VSCodeAdditionalUrls.png -------------------------------------------------------------------------------- /images/VSCodeAdditionalUrlsSettings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/VSCodeAdditionalUrlsSettings.png -------------------------------------------------------------------------------- /images/VSCodeBoardManager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/VSCodeBoardManager.png -------------------------------------------------------------------------------- /images/VSCodeInstallExtn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/VSCodeInstallExtn.png -------------------------------------------------------------------------------- /images/VSCodeSettingsJSON.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/VSCodeSettingsJSON.png -------------------------------------------------------------------------------- /images/VSCodeVerify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ExpressivePixels/e4e1cb79c493202a68bbb2bd0530f4b9ecd5ab28/images/VSCodeVerify.png --------------------------------------------------------------------------------