├── .gitattributes ├── .gitignore ├── AvnetStarterKitReferenceDesign ├── AvnetStarterKitReferenceDesign.vcxproj ├── AvnetStarterKitReferenceDesign.vcxproj.filters ├── CMakeLists.txt ├── CMakeSettings.json ├── Hardware │ ├── avnet_aesms_mt3620 │ │ ├── avnet_aesms_mt3620.json │ │ └── inc │ │ │ └── hw │ │ │ └── avnet_aesms_mt3620.h │ ├── avnet_mt3620_sk │ │ ├── avnet_mt3620_sk.json │ │ └── inc │ │ │ └── hw │ │ │ └── avnet_mt3620_sk.h │ └── mt3620 │ │ ├── inc │ │ └── hw │ │ │ └── mt3620.h │ │ └── mt3620.json ├── app_manifest.json ├── applibs_versions.h ├── azure_iot_utilities.c ├── azure_iot_utilities.h ├── build_options.h ├── connection_strings.h ├── deviceTwin.h ├── device_twin.c ├── epoll_timerfd_utilities.c ├── epoll_timerfd_utilities.h ├── i2c.c ├── i2c.h ├── launch.vs.json ├── lps22hh_reg.c ├── lps22hh_reg.h ├── lsm6dso_reg.c ├── lsm6dso_reg.h ├── main.c ├── mt3620_avnet_dev.h ├── mt3620_rdb.h ├── parson.c └── parson.h └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio. 3 | ################################################################################ 4 | 5 | /AvnetStarterKitReferenceDesign/.vs 6 | /AvnetStarterKitReferenceDesign/out 7 | /.vs/AvnetStarterKitReferenceDesign/v15 8 | /AvnetStarterKitReferenceDesign/AvnetStarterKitReferenceDesign.vcxproj.user 9 | /.vs 10 | -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/AvnetStarterKitReferenceDesign.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | ARM 7 | 8 | 9 | Release 10 | ARM 11 | 12 | 13 | 14 | {1ec4aaf4-4a6f-46c8-b538-4f4b9da1238b} 15 | AzureSphere 16 | AvnetStarterKitReferenceDesign 17 | 15.0 18 | Linux 19 | 1.0 20 | Generic 21 | {D51BCBC9-82E9-4017-911E-C93873C4EA2B} 22 | Device 23 | GCC_AzureSphere_1_0 24 | 25 | 26 | 27 | true 28 | 3 29 | 30 | 31 | false 32 | 1 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -Werror=implicit-function-declaration %(AdditionalOptions) 71 | 72 | 73 | applibs;pthread;gcc_s;c;azureiot 74 | -Wl,--no-undefined -nodefaultlibs %(AdditionalOptions) 75 | 76 | 77 | -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/AvnetStarterKitReferenceDesign.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | 32 | Source Files 33 | 34 | 35 | Source Files 36 | 37 | 38 | Source Files 39 | 40 | 41 | Source Files 42 | 43 | 44 | Source Files 45 | 46 | 47 | Source Files 48 | 49 | 50 | 51 | 52 | Header Files 53 | 54 | 55 | Header Files 56 | 57 | 58 | Header Files 59 | 60 | 61 | Header Files 62 | 63 | 64 | Header Files 65 | 66 | 67 | Header Files 68 | 69 | 70 | Header Files 71 | 72 | 73 | Header Files 74 | 75 | 76 | Header Files 77 | 78 | 79 | Header Files 80 | 81 | 82 | -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Corporation. All rights reserved. 2 | # Licensed under the MIT License. 3 | 4 | CMAKE_MINIMUM_REQUIRED(VERSION 3.8) 5 | PROJECT(AvnetStarterKitReferenceDesign C) 6 | 7 | azsphere_configure_tools(TOOLS_REVISION "20.07") 8 | azsphere_configure_api(TARGET_API_SET "6") 9 | 10 | # Create executable 11 | ADD_EXECUTABLE(${PROJECT_NAME} main.c epoll_timerfd_utilities.c parson.c azure_iot_utilities.c device_twin.c i2c.c lps22hh_reg.c lsm6dso_reg.c) 12 | TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PUBLIC ${AZURE_SPHERE_API_SET_DIR}/usr/include/azureiot) 13 | TARGET_COMPILE_DEFINITIONS(${PROJECT_NAME} PUBLIC AZURE_IOT_HUB_CONFIGURED) 14 | 15 | azsphere_target_hardware_definition(${PROJECT_NAME} TARGET_DIRECTORY ${projectDir}"\\Hardware\\avnet_mt3620_sk" TARGET_DEFINITION "avnet_mt3620_sk.json") 16 | 17 | 18 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} m azureiot applibs pthread gcc_s c) 19 | 20 | # Add MakeImage post-build command 21 | INCLUDE("${AZURE_SPHERE_MAKE_IMAGE_FILE}") 22 | 23 | -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/CMakeSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "environments": [ 3 | { 4 | "environment": "AzureSphere" 5 | } 6 | ], 7 | "configurations": [ 8 | { 9 | "name": "ARM-Debug", 10 | "generator": "Ninja", 11 | "configurationType": "Debug", 12 | "inheritEnvironments": [ 13 | "AzureSphere" 14 | ], 15 | "buildRoot": "${projectDir}\\out\\${name}", 16 | "installRoot": "${projectDir}\\install\\${name}", 17 | "cmakeToolchain": "${env.AzureSphereDefaultSDKDir}CMakeFiles\\AzureSphereToolchain.cmake", 18 | "cmakeCommandArgs": "--no-warn-unused-cli", 19 | "buildCommandArgs": "-v", 20 | "ctestCommandArgs": "", 21 | "variables": [ 22 | { 23 | "name": "AZURE_SPHERE_TARGET_API_SET", 24 | "value": "latest-lts" 25 | } 26 | ] 27 | }, 28 | { 29 | "name": "ARM-Release", 30 | "generator": "Ninja", 31 | "configurationType": "Release", 32 | "inheritEnvironments": [ 33 | "AzureSphere" 34 | ], 35 | "buildRoot": "${projectDir}\\out\\${name}", 36 | "installRoot": "${projectDir}\\install\\${name}", 37 | "cmakeToolchain": "${env.AzureSphereDefaultSDKDir}CMakeFiles\\AzureSphereToolchain.cmake", 38 | "buildCommandArgs": "-v", 39 | "ctestCommandArgs": "", 40 | "variables": [ 41 | { 42 | "name": "AZURE_SPHERE_TARGET_API_SET", 43 | "value": "latest-lts" 44 | } 45 | ] 46 | } 47 | ] 48 | } -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/Hardware/avnet_aesms_mt3620/avnet_aesms_mt3620.json: -------------------------------------------------------------------------------- 1 | { 2 | "Metadata": 3 | { 4 | "Type": "Azure Sphere Hardware Definition", 5 | "Version": 1 6 | }, 7 | "Description": 8 | { 9 | "Name": "AES-MS-MT3620", 10 | "MainCoreHeaderFileTopContent": [ 11 | "/* Copyright (c) Microsoft Corporation. All rights reserved.", 12 | " Licensed under the MIT License. */", 13 | "", 14 | "// This header lists the available peripherals for the Avnet AES-MS-MT3620", 15 | "// and provides the header definition and application manifest values required to use them." 16 | ] 17 | }, 18 | "Imports" : [ {"Path": "../mt3620/mt3620.json"} ], 19 | "Peripherals": [ 20 | {"Name": "AVNET_AESMS_PIN5_GPIO0", "Type": "Gpio", "Mapping": "MT3620_GPIO0", "Comment": "AES-MS-MT3620 pin 5 exposes GPIO 0. Pin shared with ADC Controller 0."}, 21 | {"Name": "AVNET_AESMS_PIN6_GPIO1", "Type": "Gpio", "Mapping": "MT3620_GPIO1", "Comment": "AES-MS-MT3620 pin 6 exposes GPIO 1. Pin shared with ADC Controller 0."}, 22 | {"Name": "AVNET_AESMS_PIN7_GPIO2", "Type": "Gpio", "Mapping": "MT3620_GPIO2", "Comment": "AES-MS-MT3620 pin 7 exposes GPIO 2. Pin shared with ADC Controller 0."}, 23 | {"Name": "AVNET_AESMS_PIN8_GPIO4", "Type": "Gpio", "Mapping": "MT3620_GPIO4", "Comment": "AES-MS-MT3620 pin 8 exposes GPIO 4. Pin shared with ADC Controller 1."}, 24 | {"Name": "AVNET_AESMS_PIN9_GPIO5", "Type": "Gpio", "Mapping": "MT3620_GPIO5", "Comment": "AES-MS-MT3620 pin 9 exposes GPIO 5. Pin shared with ADC Controller 1."}, 25 | {"Name": "AVNET_AESMS_PIN10_GPIO6", "Type": "Gpio", "Mapping": "MT3620_GPIO6", "Comment": "AES-MS-MT3620 pin 10 exposes GPIO 6. Pin shared with ADC Controller 1."}, 26 | {"Name": "AVNET_AESMS_PIN11_GPIO8", "Type": "Gpio", "Mapping": "MT3620_GPIO8", "Comment": "AES-MS-MT3620 pin 11 exposes GPIO 8. Pin shared with ADC Controller 2."}, 27 | {"Name": "AVNET_AESMS_PIN12_GPIO9", "Type": "Gpio", "Mapping": "MT3620_GPIO9", "Comment": "AES-MS-MT3620 pin 12 exposes GPIO 9. Pin shared with ADC Controller 2."}, 28 | {"Name": "AVNET_AESMS_PIN13_GPIO10", "Type": "Gpio", "Mapping": "MT3620_GPIO10", "Comment": "AES-MS-MT3620 pin 13 exposes GPIO 10. Pin shared with ADC Controller 2."}, 29 | {"Name": "AVNET_AESMS_PIN14_GPIO12", "Type": "Gpio", "Mapping": "MT3620_GPIO12", "Comment": "AES-MS-MT3620 pin 14 exposes GPIO 12."}, 30 | {"Name": "AVNET_AESMS_PIN15_GPIO13", "Type": "Gpio", "Mapping": "MT3620_GPIO13", "Comment": "AES-MS-MT3620 pin 15 exposes GPIO 13."}, 31 | {"Name": "AVNET_AESMS_PIN16_GPIO16", "Type": "Gpio", "Mapping": "MT3620_GPIO16", "Comment": "AES-MS-MT3620 pin 16 exposes GPIO 16."}, 32 | {"Name": "AVNET_AESMS_PIN17_GPIO17", "Type": "Gpio", "Mapping": "MT3620_GPIO17", "Comment": "AES-MS-MT3620 pin 17 exposes GPIO 17."}, 33 | {"Name": "AVNET_AESMS_PIN18_GPIO26", "Type": "Gpio", "Mapping": "MT3620_GPIO26", "Comment": "AES-MS-MT3620 pin 18 exposes GPIO 26. Pin shared with SPI0 and UART0."}, 34 | {"Name": "AVNET_AESMS_PIN19_GPIO27", "Type": "Gpio", "Mapping": "MT3620_GPIO27", "Comment": "AES-MS-MT3620 pin 19 exposes GPIO 27. Pin shared with ISU0."}, 35 | {"Name": "AVNET_AESMS_PIN20_GPIO28", "Type": "Gpio", "Mapping": "MT3620_GPIO28", "Comment": "AES-MS-MT3620 pin 20 exposes GPIO 28. Pin shared with ISU0."}, 36 | {"Name": "AVNET_AESMS_PIN21_GPIO29", "Type": "Gpio", "Mapping": "MT3620_GPIO29", "Comment": "AES-MS-MT3620 pin 21 exposes GPIO 29. Pin shared with UART0 and SPI0."}, 37 | {"Name": "AVNET_AESMS_PIN22_GPIO31", "Type": "Gpio", "Mapping": "MT3620_GPIO31", "Comment": "AES-MS-MT3620 pin 22 exposes GPIO 31. Pin shared with SPI1 and UART1."}, 38 | {"Name": "AVNET_AESMS_PIN23_GPIO32", "Type": "Gpio", "Mapping": "MT3620_GPIO32", "Comment": "AES-MS-MT3620 pin 23 exposes GPIO 32. Pin shared with ISU1."}, 39 | {"Name": "AVNET_AESMS_PIN24_GPIO33", "Type": "Gpio", "Mapping": "MT3620_GPIO33", "Comment": "AES-MS-MT3620 pin 24 exposes GPIO 33. Pin shared with ISU1."}, 40 | {"Name": "AVNET_AESMS_PIN25_GPIO34", "Type": "Gpio", "Mapping": "MT3620_GPIO34", "Comment": "AES-MS-MT3620 pin 25 exposes GPIO 34. Pin shared with SPI1 and UART1."}, 41 | {"Name": "AVNET_AESMS_PIN26_GPIO35", "Type": "Gpio", "Mapping": "MT3620_GPIO35", "Comment": "AES-MS-MT3620 pin 26 exposes GPIO 35. Pin shared with SPI1."}, 42 | {"Name": "AVNET_AESMS_PIN27_GPIO37", "Type": "Gpio", "Mapping": "MT3620_GPIO37", "Comment": "AES-MS-MT3620 pin 27 exposes GPIO 37. Pin shared with I2C2."}, 43 | {"Name": "AVNET_AESMS_PIN28_GPIO38", "Type": "Gpio", "Mapping": "MT3620_GPIO38", "Comment": "AES-MS-MT3620 pin 28 exposes GPIO 38. Pin shared with I2C2."}, 44 | {"Name": "AVNET_AESMS_PIN29_GPIO41", "Type": "Gpio", "Mapping": "MT3620_GPIO41", "Comment": "AES-MS-MT3620 pin 29 exposes GPIO 41. Pin shared with ADC Controller 0."}, 45 | {"Name": "AVNET_AESMS_PIN30_GPIO42", "Type": "Gpio", "Mapping": "MT3620_GPIO42", "Comment": "AES-MS-MT3620 pin 30 exposes GPIO 42. Pin shared with ADC Controller 0."}, 46 | {"Name": "AVNET_AESMS_PIN31_GPIO43", "Type": "Gpio", "Mapping": "MT3620_GPIO43", "Comment": "AES-MS-MT3620 pin 31 exposes GPIO 43. Pin shared with ADC Controller 0."}, 47 | {"Name": "AVNET_AESMS_PWM_CONTROLLER0", "Type": "Pwm", "Mapping": "MT3620_PWM_CONTROLLER0", "Comment": "AES-MS-MT3620 PWM CONTROLLER 0: channel 0 on pin 5, channel 1 on pin 6, channel 2 on pin 7. Pins for this controller are shared with AVNET_AESMS_PIN5_GPIO0, AVNET_AESMS_PIN6_GPIO1, and AVNET_AESMS_PIN7_GPIO2. If this PWM controller is requested, none of these GPIOs can be used."}, 48 | {"Name": "AVNET_AESMS_PWM_CONTROLLER1", "Type": "Pwm", "Mapping": "MT3620_PWM_CONTROLLER1", "Comment": "AES-MS-MT3620 PWM CONTROLLER 1: channel 0 on pin 8, channel 1 on pin 9, channel 2 on pin 10. Pins for this controller are shared with AVNET_AESMS_PIN8_GPIO4, AVNET_AESMS_PIN9_GPIO5, AVNET_AESMS_PIN10_GPIO6. If this PWM controller is requested, none of these GPIOs can be used."}, 49 | {"Name": "AVNET_AESMS_PWM_CONTROLLER2", "Type": "Pwm", "Mapping": "MT3620_PWM_CONTROLLER2", "Comment": "AES-MS-MT3620 PWM CONTROLLER 2: channel 0 on pin 11, channel 1 on pin 12, channel 2 on pin 13. Pins for this controller are shared with AVNET_AESMS_PIN11_GPIO8, AVNET_AESMS_PIN12_GPIO9, and AVNET_AESMS_PIN13_GPIO10. If this PWM controller is requested, none of these GPIOs can be used."}, 50 | {"Name": "AVNET_AESMS_ADC_CONTROLLER0", "Type": "Adc", "Mapping": "MT3620_ADC_CONTROLLER0", "Comment": "AES-MS-MT3620 ADC CONTROLLER 0: channel 0 on pin 29, channel 1 on pin 30, channel 2 on pin 31. Pins for this controller are shared with AVNET_AESMS_PIN29_GPIO41, AVNET_AESMS_PIN30_GPIO42, and AVNET_AESMS_PIN31_GPIO43. If this ADC controller is requested, none of these GPIOs can be used."}, 51 | {"Name": "AVNET_AESMS_ISU0_UART", "Type": "Uart", "Mapping": "MT3620_ISU0_UART", "Comment": "AES-MS-MT3620 ISU 0 configured as UART, pin 20 (RX), pin 18 (TX), pin 21 (CTS), pin 19 (RTS)."}, 52 | {"Name": "AVNET_AESMS_ISU0_SPI", "Type": "SpiMaster", "Mapping": "MT3620_ISU0_SPI", "Comment": "AES-MS-MT3620 ISU 0 configured as SPI, pin 20 (MISO), pin 18 (SCLK), pin 21 (CSA), pin 19 (MOSI)."}, 53 | {"Name": "AVNET_AESMS_ISU0_I2C", "Type": "I2cMaster", "Mapping": "MT3620_ISU0_I2C", "Comment": "AES-MS-MT3620 ISU 0 configured as I2C, pin 20 (SDA) and pin 18 (SCL)."}, 54 | {"Name": "AVNET_AESMS_ISU1_UART", "Type": "Uart", "Mapping": "MT3620_ISU1_UART", "Comment": "AES-MS-MT3620 ISU 1 configured as UART, pin 24 (RX), pin 22 (TX), pin 25 (CTS), pin 23 (RTS)."}, 55 | {"Name": "AVNET_AESMS_ISU1_SPI", "Type": "SpiMaster", "Mapping": "MT3620_ISU1_SPI", "Comment": "AES-MS-MT3620 ISU 1 configured as SPI, pin 24 (MISO), pin 22 (SCLK), pin 25 (CSA), pin 23 (MOSI) and pin 26 (CSB)."}, 56 | {"Name": "AVNET_AESMS_ISU1_I2C", "Type": "I2cMaster", "Mapping": "MT3620_ISU1_I2C", "Comment": "AES-MS-MT3620 ISU 1 configured as I2C, pin 24 (SDA) and pin 23 (SCL)."}, 57 | {"Name": "AVNET_AESMS_ISU2_I2C", "Type": "I2cMaster", "Mapping": "MT3620_ISU2_I2C", "Comment": "AES-MS-MT3620 ISU 2 configured as I2C, pin 28 (SDA) and pin 27 (SCL)."} 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/Hardware/avnet_aesms_mt3620/inc/hw/avnet_aesms_mt3620.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) Microsoft Corporation. All rights reserved. 2 | Licensed under the MIT License. */ 3 | 4 | // This header lists the available peripherals for the Avnet AES-MS-MT3620 5 | // and provides the header definition and application manifest values required to use them. 6 | 7 | // This file is autogenerated from ../../avnet_aesms_mt3620.json. Do not edit it directly. 8 | 9 | #pragma once 10 | #include "../../../mt3620/inc/hw/mt3620.h" 11 | 12 | // AES-MS-MT3620 pin 5 exposes GPIO 0. Pin shared with ADC Controller 0. 13 | #define AVNET_AESMS_PIN5_GPIO0 MT3620_GPIO0 14 | 15 | // AES-MS-MT3620 pin 6 exposes GPIO 1. Pin shared with ADC Controller 0. 16 | #define AVNET_AESMS_PIN6_GPIO1 MT3620_GPIO1 17 | 18 | // AES-MS-MT3620 pin 7 exposes GPIO 2. Pin shared with ADC Controller 0. 19 | #define AVNET_AESMS_PIN7_GPIO2 MT3620_GPIO2 20 | 21 | // AES-MS-MT3620 pin 8 exposes GPIO 4. Pin shared with ADC Controller 1. 22 | #define AVNET_AESMS_PIN8_GPIO4 MT3620_GPIO4 23 | 24 | // AES-MS-MT3620 pin 9 exposes GPIO 5. Pin shared with ADC Controller 1. 25 | #define AVNET_AESMS_PIN9_GPIO5 MT3620_GPIO5 26 | 27 | // AES-MS-MT3620 pin 10 exposes GPIO 6. Pin shared with ADC Controller 1. 28 | #define AVNET_AESMS_PIN10_GPIO6 MT3620_GPIO6 29 | 30 | // AES-MS-MT3620 pin 11 exposes GPIO 8. Pin shared with ADC Controller 2. 31 | #define AVNET_AESMS_PIN11_GPIO8 MT3620_GPIO8 32 | 33 | // AES-MS-MT3620 pin 12 exposes GPIO 9. Pin shared with ADC Controller 2. 34 | #define AVNET_AESMS_PIN12_GPIO9 MT3620_GPIO9 35 | 36 | // AES-MS-MT3620 pin 13 exposes GPIO 10. Pin shared with ADC Controller 2. 37 | #define AVNET_AESMS_PIN13_GPIO10 MT3620_GPIO10 38 | 39 | // AES-MS-MT3620 pin 14 exposes GPIO 12. 40 | #define AVNET_AESMS_PIN14_GPIO12 MT3620_GPIO12 41 | 42 | // AES-MS-MT3620 pin 15 exposes GPIO 13. 43 | #define AVNET_AESMS_PIN15_GPIO13 MT3620_GPIO13 44 | 45 | // AES-MS-MT3620 pin 16 exposes GPIO 16. 46 | #define AVNET_AESMS_PIN16_GPIO16 MT3620_GPIO16 47 | 48 | // AES-MS-MT3620 pin 17 exposes GPIO 17. 49 | #define AVNET_AESMS_PIN17_GPIO17 MT3620_GPIO17 50 | 51 | // AES-MS-MT3620 pin 18 exposes GPIO 26. Pin shared with SPI0 and UART0. 52 | #define AVNET_AESMS_PIN18_GPIO26 MT3620_GPIO26 53 | 54 | // AES-MS-MT3620 pin 19 exposes GPIO 27. Pin shared with ISU0. 55 | #define AVNET_AESMS_PIN19_GPIO27 MT3620_GPIO27 56 | 57 | // AES-MS-MT3620 pin 20 exposes GPIO 28. Pin shared with ISU0. 58 | #define AVNET_AESMS_PIN20_GPIO28 MT3620_GPIO28 59 | 60 | // AES-MS-MT3620 pin 21 exposes GPIO 29. Pin shared with UART0 and SPI0. 61 | #define AVNET_AESMS_PIN21_GPIO29 MT3620_GPIO29 62 | 63 | // AES-MS-MT3620 pin 22 exposes GPIO 31. Pin shared with SPI1 and UART1. 64 | #define AVNET_AESMS_PIN22_GPIO31 MT3620_GPIO31 65 | 66 | // AES-MS-MT3620 pin 23 exposes GPIO 32. Pin shared with ISU1. 67 | #define AVNET_AESMS_PIN23_GPIO32 MT3620_GPIO32 68 | 69 | // AES-MS-MT3620 pin 24 exposes GPIO 33. Pin shared with ISU1. 70 | #define AVNET_AESMS_PIN24_GPIO33 MT3620_GPIO33 71 | 72 | // AES-MS-MT3620 pin 25 exposes GPIO 34. Pin shared with SPI1 and UART1. 73 | #define AVNET_AESMS_PIN25_GPIO34 MT3620_GPIO34 74 | 75 | // AES-MS-MT3620 pin 26 exposes GPIO 35. Pin shared with SPI1. 76 | #define AVNET_AESMS_PIN26_GPIO35 MT3620_GPIO35 77 | 78 | // AES-MS-MT3620 pin 27 exposes GPIO 37. Pin shared with I2C2. 79 | #define AVNET_AESMS_PIN27_GPIO37 MT3620_GPIO37 80 | 81 | // AES-MS-MT3620 pin 28 exposes GPIO 38. Pin shared with I2C2. 82 | #define AVNET_AESMS_PIN28_GPIO38 MT3620_GPIO38 83 | 84 | // AES-MS-MT3620 pin 29 exposes GPIO 41. Pin shared with ADC Controller 0. 85 | #define AVNET_AESMS_PIN29_GPIO41 MT3620_GPIO41 86 | 87 | // AES-MS-MT3620 pin 30 exposes GPIO 42. Pin shared with ADC Controller 0. 88 | #define AVNET_AESMS_PIN30_GPIO42 MT3620_GPIO42 89 | 90 | // AES-MS-MT3620 pin 31 exposes GPIO 43. Pin shared with ADC Controller 0. 91 | #define AVNET_AESMS_PIN31_GPIO43 MT3620_GPIO43 92 | 93 | // AES-MS-MT3620 PWM CONTROLLER 0: channel 0 on pin 5, channel 1 on pin 6, channel 2 on pin 7. Pins for this controller are shared with AVNET_AESMS_PIN5_GPIO0, AVNET_AESMS_PIN6_GPIO1, and AVNET_AESMS_PIN7_GPIO2. If this PWM controller is requested, none of these GPIOs can be used. 94 | #define AVNET_AESMS_PWM_CONTROLLER0 MT3620_PWM_CONTROLLER0 95 | 96 | // AES-MS-MT3620 PWM CONTROLLER 1: channel 0 on pin 8, channel 1 on pin 9, channel 2 on pin 10. Pins for this controller are shared with AVNET_AESMS_PIN8_GPIO4, AVNET_AESMS_PIN9_GPIO5, AVNET_AESMS_PIN10_GPIO6. If this PWM controller is requested, none of these GPIOs can be used. 97 | #define AVNET_AESMS_PWM_CONTROLLER1 MT3620_PWM_CONTROLLER1 98 | 99 | // AES-MS-MT3620 PWM CONTROLLER 2: channel 0 on pin 11, channel 1 on pin 12, channel 2 on pin 13. Pins for this controller are shared with AVNET_AESMS_PIN11_GPIO8, AVNET_AESMS_PIN12_GPIO9, and AVNET_AESMS_PIN13_GPIO10. If this PWM controller is requested, none of these GPIOs can be used. 100 | #define AVNET_AESMS_PWM_CONTROLLER2 MT3620_PWM_CONTROLLER2 101 | 102 | // AES-MS-MT3620 ADC CONTROLLER 0: channel 0 on pin 29, channel 1 on pin 30, channel 2 on pin 31. Pins for this controller are shared with AVNET_AESMS_PIN29_GPIO41, AVNET_AESMS_PIN30_GPIO42, and AVNET_AESMS_PIN31_GPIO43. If this ADC controller is requested, none of these GPIOs can be used. 103 | #define AVNET_AESMS_ADC_CONTROLLER0 MT3620_ADC_CONTROLLER0 104 | 105 | // AES-MS-MT3620 ISU 0 configured as UART, pin 20 (RX), pin 18 (TX), pin 21 (CTS), pin 19 (RTS). 106 | #define AVNET_AESMS_ISU0_UART MT3620_ISU0_UART 107 | 108 | // AES-MS-MT3620 ISU 0 configured as SPI, pin 20 (MISO), pin 18 (SCLK), pin 21 (CSA), pin 19 (MOSI). 109 | #define AVNET_AESMS_ISU0_SPI MT3620_ISU0_SPI 110 | 111 | // AES-MS-MT3620 ISU 0 configured as I2C, pin 20 (SDA) and pin 18 (SCL). 112 | #define AVNET_AESMS_ISU0_I2C MT3620_ISU0_I2C 113 | 114 | // AES-MS-MT3620 ISU 1 configured as UART, pin 24 (RX), pin 22 (TX), pin 25 (CTS), pin 23 (RTS). 115 | #define AVNET_AESMS_ISU1_UART MT3620_ISU1_UART 116 | 117 | // AES-MS-MT3620 ISU 1 configured as SPI, pin 24 (MISO), pin 22 (SCLK), pin 25 (CSA), pin 23 (MOSI) and pin 26 (CSB). 118 | #define AVNET_AESMS_ISU1_SPI MT3620_ISU1_SPI 119 | 120 | // AES-MS-MT3620 ISU 1 configured as I2C, pin 24 (SDA) and pin 23 (SCL). 121 | #define AVNET_AESMS_ISU1_I2C MT3620_ISU1_I2C 122 | 123 | // AES-MS-MT3620 ISU 2 configured as I2C, pin 28 (SDA) and pin 27 (SCL). 124 | #define AVNET_AESMS_ISU2_I2C MT3620_ISU2_I2C 125 | 126 | -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/Hardware/avnet_mt3620_sk/avnet_mt3620_sk.json: -------------------------------------------------------------------------------- 1 | { 2 | "Metadata": 3 | { 4 | "Type": "Azure Sphere Hardware Definition", 5 | "Version": 1 6 | }, 7 | "Description": 8 | { 9 | "Name": "Avnet MT3620 Starter Kit (SK)", 10 | "MainCoreHeaderFileTopContent": [ 11 | "/* Copyright (c) Microsoft Corporation. All rights reserved.", 12 | " Licensed under the MIT License. */", 13 | "", 14 | "// This header contains the peripheral pinout definitions for the", 15 | "// Avnet MT3620 Starter Kit (SK)" 16 | ] 17 | }, 18 | "Imports" : [ {"Path": "../avnet_aesms_mt3620/avnet_aesms_mt3620.json"} ], 19 | "Peripherals": [ 20 | {"Name": "AVNET_MT3620_SK_APP_STATUS_LED_YELLOW", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN8_GPIO4", "Comment": "Application status LED uses GPIO4."}, 21 | {"Name": "AVNET_MT3620_SK_WLAN_STATUS_LED_YELLOW", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN9_GPIO5", "Comment": "WLAN status LED uses GPIO5."}, 22 | {"Name": "AVNET_MT3620_SK_USER_LED_RED", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN11_GPIO8", "Comment": "User LED Red channel uses GPIO8."}, 23 | {"Name": "AVNET_MT3620_SK_USER_LED_GREEN", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN12_GPIO9", "Comment": "User LED Green channel uses GPIO9."}, 24 | {"Name": "AVNET_MT3620_SK_USER_LED_BLUE", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN13_GPIO10", "Comment": "User LED Blue channel uses GPIO10."}, 25 | {"Name": "AVNET_MT3620_SK_USER_BUTTON_A", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN14_GPIO12", "Comment": "User BUTTON A uses GPIO12."}, 26 | {"Name": "AVNET_MT3620_SK_USER_BUTTON_B", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN15_GPIO13", "Comment": "User BUTTON B uses GPIO13."}, 27 | {"Name": "AVNET_MT3620_SK_GPIO42", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN30_GPIO42", "Comment": "GPIO42 is exposed on SOCKET1."}, 28 | {"Name": "AVNET_MT3620_SK_GPIO43", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN31_GPIO43", "Comment": "GPIO43 is exposed on SOCKET2."}, 29 | {"Name": "AVNET_MT3620_SK_GPIO16", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN16_GPIO16", "Comment": "GPIO16 is exposed on SOCKET1."}, 30 | {"Name": "AVNET_MT3620_SK_GPIO17", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN17_GPIO17", "Comment": "GPIO17 is exposed on SOCKET2 and UART/BLE Connector."}, 31 | {"Name": "AVNET_MT3620_SK_GPIO34", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN25_GPIO34", "Comment": "GPIO34 is exposed on SOCKET1."}, 32 | {"Name": "AVNET_MT3620_SK_GPIO35", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN26_GPIO35", "Comment": "GPIO35 is exposed on SOCKET2."}, 33 | {"Name": "AVNET_MT3620_SK_GPIO31", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN22_GPIO31", "Comment": "GPIO31 is exposed on SOCKET1 and SOCKET2."}, 34 | {"Name": "AVNET_MT3620_SK_GPIO33", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN24_GPIO33", "Comment": "GPIO33 is exposed on SOCKET1 and SOCKET2."}, 35 | {"Name": "AVNET_MT3620_SK_GPIO32", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN23_GPIO32", "Comment": "GPIO32 is exposed on SOCKET1 and SOCKET2."}, 36 | {"Name": "AVNET_MT3620_SK_GPIO0", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN5_GPIO0", "Comment": "GPIO0 is exposed on SOCKET1."}, 37 | {"Name": "AVNET_MT3620_SK_GPIO1", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN6_GPIO1", "Comment": "GPIO1 is exposed on SOCKET2 and UART/BLE Connector."}, 38 | {"Name": "AVNET_MT3620_SK_GPIO2", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN7_GPIO2", "Comment": "GPIO2 is exposed on SOCKET1, SOCKET2, and UART/BLE Connector."}, 39 | {"Name": "AVNET_MT3620_SK_GPIO28", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN20_GPIO28", "Comment": "GPIO28 is exposed on SOCKET1, SOCKET2, and UART/BLE Connector."}, 40 | {"Name": "AVNET_MT3620_SK_GPIO26", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN18_GPIO26", "Comment": "GPIO26 is exposed on SOCKET1, SOCKET2, and UART/BLE Connector."}, 41 | {"Name": "AVNET_MT3620_SK_GPIO37", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN27_GPIO37", "Comment": "GPIO37 is exposed on SOCKET1, SOCKET2, GROVE Connector, and OLED Display Connector."}, 42 | {"Name": "AVNET_MT3620_SK_GPIO38", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN28_GPIO38", "Comment": "GPIO38 is exposed on SOCKET1, SOCKET2, GROVE Connector, and OLED Display Connector."}, 43 | {"Name": "AVNET_MT3620_SK_GPIO29", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN21_GPIO29", "Comment": "GPIO29 is exposed on UART/BLE Connector."}, 44 | {"Name": "AVNET_MT3620_SK_GPIO27", "Type": "Gpio", "Mapping": "AVNET_AESMS_PIN19_GPIO27", "Comment": "GPIO27 is exposed on UART/BLE Connector."}, 45 | {"Name": "AVNET_MT3620_SK_PWM_CONTROLLER0", "Type": "Pwm", "Mapping": "AVNET_AESMS_PWM_CONTROLLER0", "Comment": "PWM CONTROLLER 0: channel 0 is exposed on SOCKET1 pin PWM, channel 1 is exposed on: SOCKET2 pin PWM and UART/BLE Connector pin 9, channel 2 is exposed on: SOCKET1 pin INT, SOCKET2 pin INT and UART/BLE Connector pin 7. Pins for this controller are shared with AVNET_MT3620_SK_GPIO0, AVNET_MT3620_SK_GPIO1 and AVNET_MT3620_SK_GPIO2. If this PWM controller is requested, none of these GPIOs can be used."}, 46 | {"Name": "AVNET_MT3620_SK_PWM_CONTROLLER1", "Type": "Pwm", "Mapping": "AVNET_AESMS_PWM_CONTROLLER1", "Comment": "PWM CONTROLLER 1: channel 0 is used by Application Status LED, and channel 1 is used by WLAN status LED. Pins for this controller are shared with AVNET_MT3620_SK_APP_STATUS_LED_YELLOW and AVNET_MT3620_SK_WLAN_STATUS_LED_YELLOW. If this PWM controller is requested, none of these GPIOs can be used."}, 47 | {"Name": "AVNET_MT3620_SK_PWM_CONTROLLER2", "Type": "Pwm", "Mapping": "AVNET_AESMS_PWM_CONTROLLER2", "Comment": "PWM CONTROLLER 2: channel 0 is used by User LED Red, channel 1 is used by User LED Green, channel 2 is used by User LED Blue. Pins for this controller are shared with AVNET_MT3620_SK_USER_LED_RED, AVNET_MT3620_SK_USER_LED_GREEN, and AVNET_MT3620_SK_USER_LED_BLUE. If this PWM controller is requested, none of these GPIOs can be used."}, 48 | {"Name": "AVNET_MT3620_SK_ADC_CONTROLLER0", "Type": "Adc", "Mapping": "AVNET_AESMS_ADC_CONTROLLER0", "Comment": "ADC CONTROLLER 0: channel 0 is used by Ambient Light Sensor, channel 1 is exposed on SOCKET1 AN, channel 2 is exposed on SOCKET2 AN. Pins for this controller are shared with AVNET_MT3620_SK_GPIO42 and AVNET_MT3620_SK_GPIO43. If this ADC controller is requested, none of these GPIOs can be used."}, 49 | {"Name": "AVNET_MT3620_SK_ISU0_UART", "Type": "Uart", "Mapping": "AVNET_AESMS_ISU0_UART", "Comment": "ISU0 UART is exposed on SOCKET1, SOCKET2, and UART/BLE Connector. On SOCKET1/2: TX (TX), RX (RX) since RTS/CTS are not exposed, UART0 must be used with software flow control. On UART/BLE Connector: pin1 (CTS), pin2 (TX), pin3 (RX), pin4 (RTS)."}, 50 | {"Name": "AVNET_MT3620_SK_ISU0_SPI", "Type": "SpiMaster", "Mapping": "AVNET_AESMS_ISU0_SPI", "Comment": "ISU0 SPI is exposed on UART/BLE Connector: pin 3 (MISO), pin 2 (SCLK), pin 1 (CSA), pin 4 (MOSI)."}, 51 | {"Name": "AVNET_MT3620_SK_ISU0_I2C", "Type": "I2cMaster", "Mapping": "AVNET_AESMS_ISU0_I2C", "Comment": "ISU0 I2C is exposed on UART/BLE Connector: pin 15 (SDA) and pin 10 (SCL)."}, 52 | {"Name": "AVNET_MT3620_SK_ISU1_UART", "Type": "Uart", "Mapping": "AVNET_AESMS_ISU1_UART", "Comment": "ISU1 UART is exposed on SOCKET1: \"MISO\" (RX), \"SCK\" (TX), \"CS\" (CTS), and \"MOSI\" (RTS)."}, 53 | {"Name": "AVNET_MT3620_SK_ISU1_SPI", "Type": "SpiMaster", "Mapping": "AVNET_AESMS_ISU1_SPI", "Comment": "ISU1 SPI is shared between SOCKET1 and SOCKET2: MISO (MISO), SCK (SCLK), CS (CSA on SOCKET1 and CSB on SOCKET2), and MOSI (MOSI)."}, 54 | {"Name": "AVNET_MT3620_SK_ISU1_I2C", "Type": "I2cMaster", "Mapping": "AVNET_AESMS_ISU1_I2C", "Comment": "ISU2 I2C is shared between GROVE Connector, OLED DISPLAY Connector, SOCKET1 and SOCKET2. On GROVE Connector: pin 15 (SDA) and pin 10 (SCL). On OLED Display connector: pin 4 (SDA) and pin 3 (SCL).On SOCKET1/2: \"MISO\" (SDA) and \"MOSI\" (SCL)"}, 55 | {"Name": "AVNET_MT3620_SK_ISU2_I2C", "Type": "I2cMaster", "Mapping": "AVNET_AESMS_ISU2_I2C", "Comment": "ISU2 I2C is shared between GROVE Connector, OLED DISPLAY Connector, SOCKET1 and SOCKET2. On GROVE Connector: pin 15 (SDA) and pin 10 (SCL). On OLED Display connector: pin 4 (SDA) and pin 3 (SCL).On SOCKET1/2: SDA (SDA) and SCL (SCL)"} 56 | ] 57 | } 58 | -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/Hardware/avnet_mt3620_sk/inc/hw/avnet_mt3620_sk.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) Microsoft Corporation. All rights reserved. 2 | Licensed under the MIT License. */ 3 | 4 | // This header contains the peripheral pinout definitions for the 5 | // Avnet MT3620 Starter Kit (SK) 6 | 7 | // This file is autogenerated from ../../avnet_mt3620_sk.json. Do not edit it directly. 8 | 9 | #pragma once 10 | #include "../../../avnet_aesms_mt3620/inc/hw/avnet_aesms_mt3620.h" 11 | 12 | // Application status LED uses GPIO4. 13 | #define AVNET_MT3620_SK_APP_STATUS_LED_YELLOW AVNET_AESMS_PIN8_GPIO4 14 | 15 | // WLAN status LED uses GPIO5. 16 | #define AVNET_MT3620_SK_WLAN_STATUS_LED_YELLOW AVNET_AESMS_PIN9_GPIO5 17 | 18 | // User LED Red channel uses GPIO8. 19 | #define AVNET_MT3620_SK_USER_LED_RED AVNET_AESMS_PIN11_GPIO8 20 | 21 | // User LED Green channel uses GPIO9. 22 | #define AVNET_MT3620_SK_USER_LED_GREEN AVNET_AESMS_PIN12_GPIO9 23 | 24 | // User LED Blue channel uses GPIO10. 25 | #define AVNET_MT3620_SK_USER_LED_BLUE AVNET_AESMS_PIN13_GPIO10 26 | 27 | // User BUTTON A uses GPIO12. 28 | #define AVNET_MT3620_SK_USER_BUTTON_A AVNET_AESMS_PIN14_GPIO12 29 | 30 | // User BUTTON B uses GPIO13. 31 | #define AVNET_MT3620_SK_USER_BUTTON_B AVNET_AESMS_PIN15_GPIO13 32 | 33 | // GPIO42 is exposed on SOCKET1. 34 | #define AVNET_MT3620_SK_GPIO42 AVNET_AESMS_PIN30_GPIO42 35 | 36 | // GPIO43 is exposed on SOCKET2. 37 | #define AVNET_MT3620_SK_GPIO43 AVNET_AESMS_PIN31_GPIO43 38 | 39 | // GPIO16 is exposed on SOCKET1. 40 | #define AVNET_MT3620_SK_GPIO16 AVNET_AESMS_PIN16_GPIO16 41 | 42 | // GPIO17 is exposed on SOCKET2 and UART/BLE Connector. 43 | #define AVNET_MT3620_SK_GPIO17 AVNET_AESMS_PIN17_GPIO17 44 | 45 | // GPIO34 is exposed on SOCKET1. 46 | #define AVNET_MT3620_SK_GPIO34 AVNET_AESMS_PIN25_GPIO34 47 | 48 | // GPIO35 is exposed on SOCKET2. 49 | #define AVNET_MT3620_SK_GPIO35 AVNET_AESMS_PIN26_GPIO35 50 | 51 | // GPIO31 is exposed on SOCKET1 and SOCKET2. 52 | #define AVNET_MT3620_SK_GPIO31 AVNET_AESMS_PIN22_GPIO31 53 | 54 | // GPIO33 is exposed on SOCKET1 and SOCKET2. 55 | #define AVNET_MT3620_SK_GPIO33 AVNET_AESMS_PIN24_GPIO33 56 | 57 | // GPIO32 is exposed on SOCKET1 and SOCKET2. 58 | #define AVNET_MT3620_SK_GPIO32 AVNET_AESMS_PIN23_GPIO32 59 | 60 | // GPIO0 is exposed on SOCKET1. 61 | #define AVNET_MT3620_SK_GPIO0 AVNET_AESMS_PIN5_GPIO0 62 | 63 | // GPIO1 is exposed on SOCKET2 and UART/BLE Connector. 64 | #define AVNET_MT3620_SK_GPIO1 AVNET_AESMS_PIN6_GPIO1 65 | 66 | // GPIO2 is exposed on SOCKET1, SOCKET2, and UART/BLE Connector. 67 | #define AVNET_MT3620_SK_GPIO2 AVNET_AESMS_PIN7_GPIO2 68 | 69 | // GPIO28 is exposed on SOCKET1, SOCKET2, and UART/BLE Connector. 70 | #define AVNET_MT3620_SK_GPIO28 AVNET_AESMS_PIN20_GPIO28 71 | 72 | // GPIO26 is exposed on SOCKET1, SOCKET2, and UART/BLE Connector. 73 | #define AVNET_MT3620_SK_GPIO26 AVNET_AESMS_PIN18_GPIO26 74 | 75 | // GPIO37 is exposed on SOCKET1, SOCKET2, GROVE Connector, and OLED Display Connector. 76 | #define AVNET_MT3620_SK_GPIO37 AVNET_AESMS_PIN27_GPIO37 77 | 78 | // GPIO38 is exposed on SOCKET1, SOCKET2, GROVE Connector, and OLED Display Connector. 79 | #define AVNET_MT3620_SK_GPIO38 AVNET_AESMS_PIN28_GPIO38 80 | 81 | // GPIO29 is exposed on UART/BLE Connector. 82 | #define AVNET_MT3620_SK_GPIO29 AVNET_AESMS_PIN21_GPIO29 83 | 84 | // GPIO27 is exposed on UART/BLE Connector. 85 | #define AVNET_MT3620_SK_GPIO27 AVNET_AESMS_PIN19_GPIO27 86 | 87 | // PWM CONTROLLER 0: channel 0 is exposed on SOCKET1 pin PWM, channel 1 is exposed on: SOCKET2 pin PWM and UART/BLE Connector pin 9, channel 2 is exposed on: SOCKET1 pin INT, SOCKET2 pin INT and UART/BLE Connector pin 7. Pins for this controller are shared with AVNET_MT3620_SK_GPIO0, AVNET_MT3620_SK_GPIO1 and AVNET_MT3620_SK_GPIO2. If this PWM controller is requested, none of these GPIOs can be used. 88 | #define AVNET_MT3620_SK_PWM_CONTROLLER0 AVNET_AESMS_PWM_CONTROLLER0 89 | 90 | // PWM CONTROLLER 1: channel 0 is used by Application Status LED, and channel 1 is used by WLAN status LED. Pins for this controller are shared with AVNET_MT3620_SK_APP_STATUS_LED_YELLOW and AVNET_MT3620_SK_WLAN_STATUS_LED_YELLOW. If this PWM controller is requested, none of these GPIOs can be used. 91 | #define AVNET_MT3620_SK_PWM_CONTROLLER1 AVNET_AESMS_PWM_CONTROLLER1 92 | 93 | // PWM CONTROLLER 2: channel 0 is used by User LED Red, channel 1 is used by User LED Green, channel 2 is used by User LED Blue. Pins for this controller are shared with AVNET_MT3620_SK_USER_LED_RED, AVNET_MT3620_SK_USER_LED_GREEN, and AVNET_MT3620_SK_USER_LED_BLUE. If this PWM controller is requested, none of these GPIOs can be used. 94 | #define AVNET_MT3620_SK_PWM_CONTROLLER2 AVNET_AESMS_PWM_CONTROLLER2 95 | 96 | // ADC CONTROLLER 0: channel 0 is used by Ambient Light Sensor, channel 1 is exposed on SOCKET1 AN, channel 2 is exposed on SOCKET2 AN. Pins for this controller are shared with AVNET_MT3620_SK_GPIO42 and AVNET_MT3620_SK_GPIO43. If this ADC controller is requested, none of these GPIOs can be used. 97 | #define AVNET_MT3620_SK_ADC_CONTROLLER0 AVNET_AESMS_ADC_CONTROLLER0 98 | 99 | // ISU0 UART is exposed on SOCKET1, SOCKET2, and UART/BLE Connector. On SOCKET1/2: TX (TX), RX (RX) since RTS/CTS are not exposed, UART0 must be used with software flow control. On UART/BLE Connector: pin1 (CTS), pin2 (TX), pin3 (RX), pin4 (RTS). 100 | #define AVNET_MT3620_SK_ISU0_UART AVNET_AESMS_ISU0_UART 101 | 102 | // ISU0 SPI is exposed on UART/BLE Connector: pin 3 (MISO), pin 2 (SCLK), pin 1 (CSA), pin 4 (MOSI). 103 | #define AVNET_MT3620_SK_ISU0_SPI AVNET_AESMS_ISU0_SPI 104 | 105 | // ISU0 I2C is exposed on UART/BLE Connector: pin 15 (SDA) and pin 10 (SCL). 106 | #define AVNET_MT3620_SK_ISU0_I2C AVNET_AESMS_ISU0_I2C 107 | 108 | // ISU1 UART is exposed on SOCKET1: "MISO" (RX), "SCK" (TX), "CS" (CTS), and "MOSI" (RTS). 109 | #define AVNET_MT3620_SK_ISU1_UART AVNET_AESMS_ISU1_UART 110 | 111 | // ISU1 SPI is shared between SOCKET1 and SOCKET2: MISO (MISO), SCK (SCLK), CS (CSA on SOCKET1 and CSB on SOCKET2), and MOSI (MOSI). 112 | #define AVNET_MT3620_SK_ISU1_SPI AVNET_AESMS_ISU1_SPI 113 | 114 | // ISU2 I2C is shared between GROVE Connector, OLED DISPLAY Connector, SOCKET1 and SOCKET2. On GROVE Connector: pin 15 (SDA) and pin 10 (SCL). On OLED Display connector: pin 4 (SDA) and pin 3 (SCL).On SOCKET1/2: "MISO" (SDA) and "MOSI" (SCL) 115 | #define AVNET_MT3620_SK_ISU1_I2C AVNET_AESMS_ISU1_I2C 116 | 117 | // ISU2 I2C is shared between GROVE Connector, OLED DISPLAY Connector, SOCKET1 and SOCKET2. On GROVE Connector: pin 15 (SDA) and pin 10 (SCL). On OLED Display connector: pin 4 (SDA) and pin 3 (SCL).On SOCKET1/2: SDA (SDA) and SCL (SCL) 118 | #define AVNET_MT3620_SK_ISU2_I2C AVNET_AESMS_ISU2_I2C 119 | 120 | -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/Hardware/mt3620/inc/hw/mt3620.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) Microsoft Corporation. All rights reserved. 2 | Licensed under the MIT License. */ 3 | 4 | // This header lists the available peripherals for the Mediatek MT3620 5 | // and provides the header definition and application manifest values required to use them. 6 | 7 | // This file is autogenerated from ../../mt3620.json. Do not edit it directly. 8 | 9 | #pragma once 10 | // MT3620 GPIO 0. Pin shared with PWM Controller 0. 11 | #define MT3620_GPIO0 (0) 12 | 13 | // MT3620 GPIO 1. Pin shared with PWM Controller 0. 14 | #define MT3620_GPIO1 (1) 15 | 16 | // MT3620 GPIO 2. Pin shared with PWM Controller 0. 17 | #define MT3620_GPIO2 (2) 18 | 19 | // MT3620 GPIO 3. Pin shared with PWM Controller 0. 20 | #define MT3620_GPIO3 (3) 21 | 22 | // MT3620 GPIO 4. Pin shared with PWM Controller 1. 23 | #define MT3620_GPIO4 (4) 24 | 25 | // MT3620 GPIO 5. Pin shared with PWM Controller 1. 26 | #define MT3620_GPIO5 (5) 27 | 28 | // MT3620 GPIO 6. Pin shared with PWM Controller 1. 29 | #define MT3620_GPIO6 (6) 30 | 31 | // MT3620 GPIO 7. Pin shared with PWM Controller 1. 32 | #define MT3620_GPIO7 (7) 33 | 34 | // MT3620 GPIO 8. Pin shared with PWM Controller 2. 35 | #define MT3620_GPIO8 (8) 36 | 37 | // MT3620 GPIO 9. Pin shared with PWM Controller 2. 38 | #define MT3620_GPIO9 (9) 39 | 40 | // MT3620 GPIO 10. Pin shared with PWM Controller 2. 41 | #define MT3620_GPIO10 (10) 42 | 43 | // MT3620 GPIO 11. Pin shared with PWM Controller 2. 44 | #define MT3620_GPIO11 (11) 45 | 46 | // MT3620 GPIO 12 47 | #define MT3620_GPIO12 (12) 48 | 49 | // MT3620 GPIO 13 50 | #define MT3620_GPIO13 (13) 51 | 52 | // MT3620 GPIO 14 53 | #define MT3620_GPIO14 (14) 54 | 55 | // MT3620 GPIO 15 56 | #define MT3620_GPIO15 (15) 57 | 58 | // MT3620 GPIO 16 59 | #define MT3620_GPIO16 (16) 60 | 61 | // MT3620 GPIO 17 62 | #define MT3620_GPIO17 (17) 63 | 64 | // MT3620 GPIO 18 65 | #define MT3620_GPIO18 (18) 66 | 67 | // MT3620 GPIO 19 68 | #define MT3620_GPIO19 (19) 69 | 70 | // MT3620 GPIO 20 71 | #define MT3620_GPIO20 (20) 72 | 73 | // MT3620 GPIO 21 74 | #define MT3620_GPIO21 (21) 75 | 76 | // MT3620 GPIO 22 77 | #define MT3620_GPIO22 (22) 78 | 79 | // MT3620 GPIO 23 80 | #define MT3620_GPIO23 (23) 81 | 82 | // MT3620 GPIO 26. Pin shared with ISU0 83 | #define MT3620_GPIO26 (26) 84 | 85 | // MT3620 GPIO 27. Pin shared with ISU0 86 | #define MT3620_GPIO27 (27) 87 | 88 | // MT3620 GPIO 28. Pin shared with ISU0 89 | #define MT3620_GPIO28 (28) 90 | 91 | // MT3620 GPIO 29. Pin shared with ISU0 92 | #define MT3620_GPIO29 (29) 93 | 94 | // MT3620 GPIO 30. Pin shared with ISU0 95 | #define MT3620_GPIO30 (30) 96 | 97 | // MT3620 GPIO 31. Pin shared with ISU1 98 | #define MT3620_GPIO31 (31) 99 | 100 | // MT3620 GPIO 32. Pin shared with ISU1 101 | #define MT3620_GPIO32 (32) 102 | 103 | // MT3620 GPIO 33. Pin shared with ISU1 104 | #define MT3620_GPIO33 (33) 105 | 106 | // MT3620 GPIO 34. Pin shared with ISU1 107 | #define MT3620_GPIO34 (34) 108 | 109 | // MT3620 GPIO 35. Pin shared with ISU1 110 | #define MT3620_GPIO35 (35) 111 | 112 | // MT3620 GPIO 36. Pin shared with ISU2 113 | #define MT3620_GPIO36 (36) 114 | 115 | // MT3620 GPIO 37. Pin shared with ISU2 116 | #define MT3620_GPIO37 (37) 117 | 118 | // MT3620 GPIO 38. Pin shared with ISU2 119 | #define MT3620_GPIO38 (38) 120 | 121 | // MT3620 GPIO 39. Pin shared with ISU2 122 | #define MT3620_GPIO39 (39) 123 | 124 | // MT3620 GPIO 40. Pin shared with ISU2 125 | #define MT3620_GPIO40 (40) 126 | 127 | // MT3620 GPIO 41. Pin shared with ADC Controller 0. 128 | #define MT3620_GPIO41 (41) 129 | 130 | // MT3620 GPIO 42. Pin shared with ADC Controller 0. 131 | #define MT3620_GPIO42 (42) 132 | 133 | // MT3620 GPIO 43. Pin shared with ADC Controller 0. 134 | #define MT3620_GPIO43 (43) 135 | 136 | // MT3620 GPIO 44. Pin shared with ADC Controller 0. 137 | #define MT3620_GPIO44 (44) 138 | 139 | // MT3620 GPIO 45. Pin shared with ADC Controller 0. 140 | #define MT3620_GPIO45 (45) 141 | 142 | // MT3620 GPIO 46. Pin shared with ADC Controller 0. 143 | #define MT3620_GPIO46 (46) 144 | 145 | // MT3620 GPIO 47. Pin shared with ADC Controller 0. 146 | #define MT3620_GPIO47 (47) 147 | 148 | // MT3620 GPIO 48. Pin shared with ADC Controller 0. 149 | #define MT3620_GPIO48 (48) 150 | 151 | // MT3620 GPIO 56 152 | #define MT3620_GPIO56 (56) 153 | 154 | // MT3620 GPIO 57 155 | #define MT3620_GPIO57 (57) 156 | 157 | // MT3620 GPIO 58 158 | #define MT3620_GPIO58 (58) 159 | 160 | // MT3620 GPIO 59 161 | #define MT3620_GPIO59 (59) 162 | 163 | // MT3620 GPIO 60 164 | #define MT3620_GPIO60 (60) 165 | 166 | // MT3620 GPIO 61 167 | #define MT3620_GPIO61 (61) 168 | 169 | // MT3620 GPIO 62 170 | #define MT3620_GPIO62 (62) 171 | 172 | // MT3620 GPIO 63 173 | #define MT3620_GPIO63 (63) 174 | 175 | // MT3620 GPIO 64 176 | #define MT3620_GPIO64 (64) 177 | 178 | // MT3620 GPIO 65 179 | #define MT3620_GPIO65 (65) 180 | 181 | // MT3620 GPIO 66. Pin shared with ISU3 182 | #define MT3620_GPIO66 (66) 183 | 184 | // MT3620 GPIO 67. Pin shared with ISU3 185 | #define MT3620_GPIO67 (67) 186 | 187 | // MT3620 GPIO 68. Pin shared with ISU3 188 | #define MT3620_GPIO68 (68) 189 | 190 | // MT3620 GPIO 69. Pin shared with ISU3 191 | #define MT3620_GPIO69 (69) 192 | 193 | // MT3620 GPIO 70. Pin shared with ISU3 194 | #define MT3620_GPIO70 (70) 195 | 196 | // MT3620 GPIO 71. Pin shared with ISU4 197 | #define MT3620_GPIO71 (71) 198 | 199 | // MT3620 GPIO 72. Pin shared with ISU4 200 | #define MT3620_GPIO72 (72) 201 | 202 | // MT3620 GPIO 73. Pin shared with ISU4 203 | #define MT3620_GPIO73 (73) 204 | 205 | // MT3620 GPIO 74. Pin shared with ISU4 206 | #define MT3620_GPIO74 (74) 207 | 208 | // MT3620 GPIO 75. Pin shared with ISU4 209 | #define MT3620_GPIO75 (75) 210 | 211 | // MT3620 GPIO 80 212 | #define MT3620_GPIO80 (80) 213 | 214 | // MT3620 PWM CONTROLLER 0: channel 0 on pin 0, channel 1 on pin 1, channel 2 on pin 2, and channel 3 on pin 3. Pins for this controller are shared with GPIO0, GPIO1, GPIO2, GPIO3. If this PWM controller is requested, none of these GPIOs can be used. 215 | #define MT3620_PWM_CONTROLLER0 (0) 216 | 217 | // MT3620 PWM CONTROLLER 1: channel 0 on pin 4, channel 1 on pin 5, channel 2 on pin 6, and channel 3 on pin 7. Pins for this controller are shared with GPIO4, GPIO5, GPIO6, GPIO7. If this PWM controller is requested, none of these GPIOs can be used. 218 | #define MT3620_PWM_CONTROLLER1 (1) 219 | 220 | // MT3620 PWM CONTROLLER 2: channel 0 on pin 8, channel 1 on pin 9, channel 2 on pin 10, and channel 3 on pin 11. Pins for this controller are shared with GPIO8, GPIO9, GPIO10, GPIO11. If this PWM controller is requested, none of these GPIOs can be used. 221 | #define MT3620_PWM_CONTROLLER2 (2) 222 | 223 | // MT3620 ADC CONTROLLER 0: channel 0 on pin 41, channel 1 on pin 42, channel 2 on pin 43, channel 3 on pin 44, channel 4 on pin 45, channel 5 on pin 46, channel 6 on pin 47, and channel 7 on pin 48. Pins for this controller are shared with GPIO41, GPIO42, GPIO43, GPIO44, GPIO45, GPIO46, GPIO47 and GPIO48. If this ADC controller is requested, none of these GPIOs can be used. 224 | #define MT3620_ADC_CONTROLLER0 (0) 225 | 226 | // MT3620 ISU 0 configured as I2C 227 | #define MT3620_ISU0_I2C (0) 228 | 229 | // MT3620 ISU 1 configured as I2C 230 | #define MT3620_ISU1_I2C (1) 231 | 232 | // MT3620 ISU 2 configured as I2C 233 | #define MT3620_ISU2_I2C (2) 234 | 235 | // MT3620 ISU 3 configured as I2C 236 | #define MT3620_ISU3_I2C (3) 237 | 238 | // MT3620 ISU 4 configured as I2C 239 | #define MT3620_ISU4_I2C (4) 240 | 241 | // MT3620 ISU 0 configured as SPI 242 | #define MT3620_ISU0_SPI (0) 243 | 244 | // MT3620 ISU 1 configured as SPI 245 | #define MT3620_ISU1_SPI (1) 246 | 247 | // MT3620 ISU 2 configured as SPI 248 | #define MT3620_ISU2_SPI (2) 249 | 250 | // MT3620 ISU 3 configured as SPI 251 | #define MT3620_ISU3_SPI (3) 252 | 253 | // MT3620 ISU 4 configured as SPI 254 | #define MT3620_ISU4_SPI (4) 255 | 256 | // MT3620 ISU 0 configured as UART 257 | #define MT3620_ISU0_UART (4) 258 | 259 | // MT3620 ISU 1 configured as UART 260 | #define MT3620_ISU1_UART (5) 261 | 262 | // MT3620 ISU 2 configured as UART 263 | #define MT3620_ISU2_UART (6) 264 | 265 | // MT3620 ISU 3 configured as UART 266 | #define MT3620_ISU3_UART (7) 267 | 268 | // MT3620 ISU 4 configured as UART 269 | #define MT3620_ISU4_UART (8) 270 | 271 | // MT3620 PWM CHANNEL 0, it must not be used as a peripheral in app_manifest.json 272 | #define MT3620_PWM_CHANNEL0 (0) 273 | 274 | // MT3620 PWM CHANNEL 1, it must not be used as a peripheral in app_manifest.json 275 | #define MT3620_PWM_CHANNEL1 (1) 276 | 277 | // MT3620 PWM CHANNEL 2, it must not be used as a peripheral in app_manifest.json 278 | #define MT3620_PWM_CHANNEL2 (2) 279 | 280 | // MT3620 PWM CHANNEL 3, it must not be used as a peripheral in app_manifest.json 281 | #define MT3620_PWM_CHANNEL3 (3) 282 | 283 | // MT3620 SPI CS A, it must not be used as a peripheral in app_manifest 284 | #define MT3620_SPI_CS_A (-1) 285 | 286 | // MT3620 SPI CS B, it must not be used as a peripheral in app_manifest 287 | #define MT3620_SPI_CS_B (-2) 288 | 289 | // MT3620 ADC CHANNEL 0, it must not be used as a peripheral in app_manifest.json 290 | #define MT3620_ADC_CHANNEL0 (0) 291 | 292 | // MT3620 ADC CHANNEL 1, it must not be used as a peripheral in app_manifest.json 293 | #define MT3620_ADC_CHANNEL1 (1) 294 | 295 | // MT3620 ADC CHANNEL 2, it must not be used as a peripheral in app_manifest.json 296 | #define MT3620_ADC_CHANNEL2 (2) 297 | 298 | // MT3620 ADC CHANNEL 3, it must not be used as a peripheral in app_manifest.json 299 | #define MT3620_ADC_CHANNEL3 (3) 300 | 301 | // MT3620 ADC CHANNEL 4, it must not be used as a peripheral in app_manifest.json 302 | #define MT3620_ADC_CHANNEL4 (4) 303 | 304 | // MT3620 ADC CHANNEL 5, it must not be used as a peripheral in app_manifest.json 305 | #define MT3620_ADC_CHANNEL5 (5) 306 | 307 | // MT3620 ADC CHANNEL 6, it must not be used as a peripheral in app_manifest.json 308 | #define MT3620_ADC_CHANNEL6 (6) 309 | 310 | // MT3620 ADC CHANNEL 7, it must not be used as a peripheral in app_manifest.json 311 | #define MT3620_ADC_CHANNEL7 (7) 312 | 313 | -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/Hardware/mt3620/mt3620.json: -------------------------------------------------------------------------------- 1 | { 2 | "Metadata": 3 | { 4 | "Type": "Azure Sphere Hardware Definition", 5 | "Version": 1 6 | }, 7 | "Description": 8 | { 9 | "Name": "MT3620", 10 | "MainCoreHeaderFileTopContent": [ 11 | "/* Copyright (c) Microsoft Corporation. All rights reserved.", 12 | " Licensed under the MIT License. */", 13 | "", 14 | "// This header lists the available peripherals for the Mediatek MT3620", 15 | "// and provides the header definition and application manifest values required to use them." 16 | ] 17 | }, 18 | "Peripherals": [ 19 | {"Name": "MT3620_GPIO0", "Type": "Gpio", "MainCoreHeaderValue": "(0)", "AppManifestValue": 0, "Comment": "MT3620 GPIO 0. Pin shared with PWM Controller 0."}, 20 | {"Name": "MT3620_GPIO1", "Type": "Gpio", "MainCoreHeaderValue": "(1)", "AppManifestValue": 1, "Comment": "MT3620 GPIO 1. Pin shared with PWM Controller 0."}, 21 | {"Name": "MT3620_GPIO2", "Type": "Gpio", "MainCoreHeaderValue": "(2)", "AppManifestValue": 2, "Comment": "MT3620 GPIO 2. Pin shared with PWM Controller 0."}, 22 | {"Name": "MT3620_GPIO3", "Type": "Gpio", "MainCoreHeaderValue": "(3)", "AppManifestValue": 3, "Comment": "MT3620 GPIO 3. Pin shared with PWM Controller 0."}, 23 | {"Name": "MT3620_GPIO4", "Type": "Gpio", "MainCoreHeaderValue": "(4)", "AppManifestValue": 4, "Comment": "MT3620 GPIO 4. Pin shared with PWM Controller 1."}, 24 | {"Name": "MT3620_GPIO5", "Type": "Gpio", "MainCoreHeaderValue": "(5)", "AppManifestValue": 5, "Comment": "MT3620 GPIO 5. Pin shared with PWM Controller 1."}, 25 | {"Name": "MT3620_GPIO6", "Type": "Gpio", "MainCoreHeaderValue": "(6)", "AppManifestValue": 6, "Comment": "MT3620 GPIO 6. Pin shared with PWM Controller 1."}, 26 | {"Name": "MT3620_GPIO7", "Type": "Gpio", "MainCoreHeaderValue": "(7)", "AppManifestValue": 7, "Comment": "MT3620 GPIO 7. Pin shared with PWM Controller 1."}, 27 | {"Name": "MT3620_GPIO8", "Type": "Gpio", "MainCoreHeaderValue": "(8)", "AppManifestValue": 8, "Comment": "MT3620 GPIO 8. Pin shared with PWM Controller 2."}, 28 | {"Name": "MT3620_GPIO9", "Type": "Gpio", "MainCoreHeaderValue": "(9)", "AppManifestValue": 9, "Comment": "MT3620 GPIO 9. Pin shared with PWM Controller 2."}, 29 | {"Name": "MT3620_GPIO10", "Type": "Gpio", "MainCoreHeaderValue": "(10)", "AppManifestValue": 10, "Comment": "MT3620 GPIO 10. Pin shared with PWM Controller 2."}, 30 | {"Name": "MT3620_GPIO11", "Type": "Gpio", "MainCoreHeaderValue": "(11)", "AppManifestValue": 11, "Comment": "MT3620 GPIO 11. Pin shared with PWM Controller 2."}, 31 | {"Name": "MT3620_GPIO12", "Type": "Gpio", "MainCoreHeaderValue": "(12)", "AppManifestValue": 12, "Comment": "MT3620 GPIO 12"}, 32 | {"Name": "MT3620_GPIO13", "Type": "Gpio", "MainCoreHeaderValue": "(13)", "AppManifestValue": 13, "Comment": "MT3620 GPIO 13"}, 33 | {"Name": "MT3620_GPIO14", "Type": "Gpio", "MainCoreHeaderValue": "(14)", "AppManifestValue": 14, "Comment": "MT3620 GPIO 14"}, 34 | {"Name": "MT3620_GPIO15", "Type": "Gpio", "MainCoreHeaderValue": "(15)", "AppManifestValue": 15, "Comment": "MT3620 GPIO 15"}, 35 | {"Name": "MT3620_GPIO16", "Type": "Gpio", "MainCoreHeaderValue": "(16)", "AppManifestValue": 16, "Comment": "MT3620 GPIO 16"}, 36 | {"Name": "MT3620_GPIO17", "Type": "Gpio", "MainCoreHeaderValue": "(17)", "AppManifestValue": 17, "Comment": "MT3620 GPIO 17"}, 37 | {"Name": "MT3620_GPIO18", "Type": "Gpio", "MainCoreHeaderValue": "(18)", "AppManifestValue": 18, "Comment": "MT3620 GPIO 18"}, 38 | {"Name": "MT3620_GPIO19", "Type": "Gpio", "MainCoreHeaderValue": "(19)", "AppManifestValue": 19, "Comment": "MT3620 GPIO 19"}, 39 | {"Name": "MT3620_GPIO20", "Type": "Gpio", "MainCoreHeaderValue": "(20)", "AppManifestValue": 20, "Comment": "MT3620 GPIO 20"}, 40 | {"Name": "MT3620_GPIO21", "Type": "Gpio", "MainCoreHeaderValue": "(21)", "AppManifestValue": 21, "Comment": "MT3620 GPIO 21"}, 41 | {"Name": "MT3620_GPIO22", "Type": "Gpio", "MainCoreHeaderValue": "(22)", "AppManifestValue": 22, "Comment": "MT3620 GPIO 22"}, 42 | {"Name": "MT3620_GPIO23", "Type": "Gpio", "MainCoreHeaderValue": "(23)", "AppManifestValue": 23, "Comment": "MT3620 GPIO 23"}, 43 | {"Name": "MT3620_GPIO26", "Type": "Gpio", "MainCoreHeaderValue": "(26)", "AppManifestValue": 26, "Comment": "MT3620 GPIO 26. Pin shared with ISU0"}, 44 | {"Name": "MT3620_GPIO27", "Type": "Gpio", "MainCoreHeaderValue": "(27)", "AppManifestValue": 27, "Comment": "MT3620 GPIO 27. Pin shared with ISU0"}, 45 | {"Name": "MT3620_GPIO28", "Type": "Gpio", "MainCoreHeaderValue": "(28)", "AppManifestValue": 28, "Comment": "MT3620 GPIO 28. Pin shared with ISU0"}, 46 | {"Name": "MT3620_GPIO29", "Type": "Gpio", "MainCoreHeaderValue": "(29)", "AppManifestValue": 29, "Comment": "MT3620 GPIO 29. Pin shared with ISU0"}, 47 | {"Name": "MT3620_GPIO30", "Type": "Gpio", "MainCoreHeaderValue": "(30)", "AppManifestValue": 30, "Comment": "MT3620 GPIO 30. Pin shared with ISU0"}, 48 | {"Name": "MT3620_GPIO31", "Type": "Gpio", "MainCoreHeaderValue": "(31)", "AppManifestValue": 31, "Comment": "MT3620 GPIO 31. Pin shared with ISU1"}, 49 | {"Name": "MT3620_GPIO32", "Type": "Gpio", "MainCoreHeaderValue": "(32)", "AppManifestValue": 32, "Comment": "MT3620 GPIO 32. Pin shared with ISU1"}, 50 | {"Name": "MT3620_GPIO33", "Type": "Gpio", "MainCoreHeaderValue": "(33)", "AppManifestValue": 33, "Comment": "MT3620 GPIO 33. Pin shared with ISU1"}, 51 | {"Name": "MT3620_GPIO34", "Type": "Gpio", "MainCoreHeaderValue": "(34)", "AppManifestValue": 34, "Comment": "MT3620 GPIO 34. Pin shared with ISU1"}, 52 | {"Name": "MT3620_GPIO35", "Type": "Gpio", "MainCoreHeaderValue": "(35)", "AppManifestValue": 35, "Comment": "MT3620 GPIO 35. Pin shared with ISU1"}, 53 | {"Name": "MT3620_GPIO36", "Type": "Gpio", "MainCoreHeaderValue": "(36)", "AppManifestValue": 36, "Comment": "MT3620 GPIO 36. Pin shared with ISU2"}, 54 | {"Name": "MT3620_GPIO37", "Type": "Gpio", "MainCoreHeaderValue": "(37)", "AppManifestValue": 37, "Comment": "MT3620 GPIO 37. Pin shared with ISU2"}, 55 | {"Name": "MT3620_GPIO38", "Type": "Gpio", "MainCoreHeaderValue": "(38)", "AppManifestValue": 38, "Comment": "MT3620 GPIO 38. Pin shared with ISU2"}, 56 | {"Name": "MT3620_GPIO39", "Type": "Gpio", "MainCoreHeaderValue": "(39)", "AppManifestValue": 39, "Comment": "MT3620 GPIO 39. Pin shared with ISU2"}, 57 | {"Name": "MT3620_GPIO40", "Type": "Gpio", "MainCoreHeaderValue": "(40)", "AppManifestValue": 40, "Comment": "MT3620 GPIO 40. Pin shared with ISU2"}, 58 | {"Name": "MT3620_GPIO41", "Type": "Gpio", "MainCoreHeaderValue": "(41)", "AppManifestValue": 41, "Comment": "MT3620 GPIO 41. Pin shared with ADC Controller 0."}, 59 | {"Name": "MT3620_GPIO42", "Type": "Gpio", "MainCoreHeaderValue": "(42)", "AppManifestValue": 42, "Comment": "MT3620 GPIO 42. Pin shared with ADC Controller 0."}, 60 | {"Name": "MT3620_GPIO43", "Type": "Gpio", "MainCoreHeaderValue": "(43)", "AppManifestValue": 43, "Comment": "MT3620 GPIO 43. Pin shared with ADC Controller 0."}, 61 | {"Name": "MT3620_GPIO44", "Type": "Gpio", "MainCoreHeaderValue": "(44)", "AppManifestValue": 44, "Comment": "MT3620 GPIO 44. Pin shared with ADC Controller 0."}, 62 | {"Name": "MT3620_GPIO45", "Type": "Gpio", "MainCoreHeaderValue": "(45)", "AppManifestValue": 45, "Comment": "MT3620 GPIO 45. Pin shared with ADC Controller 0."}, 63 | {"Name": "MT3620_GPIO46", "Type": "Gpio", "MainCoreHeaderValue": "(46)", "AppManifestValue": 46, "Comment": "MT3620 GPIO 46. Pin shared with ADC Controller 0."}, 64 | {"Name": "MT3620_GPIO47", "Type": "Gpio", "MainCoreHeaderValue": "(47)", "AppManifestValue": 47, "Comment": "MT3620 GPIO 47. Pin shared with ADC Controller 0."}, 65 | {"Name": "MT3620_GPIO48", "Type": "Gpio", "MainCoreHeaderValue": "(48)", "AppManifestValue": 48, "Comment": "MT3620 GPIO 48. Pin shared with ADC Controller 0."}, 66 | {"Name": "MT3620_GPIO56", "Type": "Gpio", "MainCoreHeaderValue": "(56)", "AppManifestValue": 56, "Comment": "MT3620 GPIO 56"}, 67 | {"Name": "MT3620_GPIO57", "Type": "Gpio", "MainCoreHeaderValue": "(57)", "AppManifestValue": 57, "Comment": "MT3620 GPIO 57"}, 68 | {"Name": "MT3620_GPIO58", "Type": "Gpio", "MainCoreHeaderValue": "(58)", "AppManifestValue": 58, "Comment": "MT3620 GPIO 58"}, 69 | {"Name": "MT3620_GPIO59", "Type": "Gpio", "MainCoreHeaderValue": "(59)", "AppManifestValue": 59, "Comment": "MT3620 GPIO 59"}, 70 | {"Name": "MT3620_GPIO60", "Type": "Gpio", "MainCoreHeaderValue": "(60)", "AppManifestValue": 60, "Comment": "MT3620 GPIO 60"}, 71 | {"Name": "MT3620_GPIO61", "Type": "Gpio", "MainCoreHeaderValue": "(61)", "AppManifestValue": 61, "Comment": "MT3620 GPIO 61"}, 72 | {"Name": "MT3620_GPIO62", "Type": "Gpio", "MainCoreHeaderValue": "(62)", "AppManifestValue": 62, "Comment": "MT3620 GPIO 62"}, 73 | {"Name": "MT3620_GPIO63", "Type": "Gpio", "MainCoreHeaderValue": "(63)", "AppManifestValue": 63, "Comment": "MT3620 GPIO 63"}, 74 | {"Name": "MT3620_GPIO64", "Type": "Gpio", "MainCoreHeaderValue": "(64)", "AppManifestValue": 64, "Comment": "MT3620 GPIO 64"}, 75 | {"Name": "MT3620_GPIO65", "Type": "Gpio", "MainCoreHeaderValue": "(65)", "AppManifestValue": 65, "Comment": "MT3620 GPIO 65"}, 76 | {"Name": "MT3620_GPIO66", "Type": "Gpio", "MainCoreHeaderValue": "(66)", "AppManifestValue": 66, "Comment": "MT3620 GPIO 66. Pin shared with ISU3"}, 77 | {"Name": "MT3620_GPIO67", "Type": "Gpio", "MainCoreHeaderValue": "(67)", "AppManifestValue": 67, "Comment": "MT3620 GPIO 67. Pin shared with ISU3"}, 78 | {"Name": "MT3620_GPIO68", "Type": "Gpio", "MainCoreHeaderValue": "(68)", "AppManifestValue": 68, "Comment": "MT3620 GPIO 68. Pin shared with ISU3"}, 79 | {"Name": "MT3620_GPIO69", "Type": "Gpio", "MainCoreHeaderValue": "(69)", "AppManifestValue": 69, "Comment": "MT3620 GPIO 69. Pin shared with ISU3"}, 80 | {"Name": "MT3620_GPIO70", "Type": "Gpio", "MainCoreHeaderValue": "(70)", "AppManifestValue": 70, "Comment": "MT3620 GPIO 70. Pin shared with ISU3"}, 81 | {"Name": "MT3620_GPIO71", "Type": "Gpio", "MainCoreHeaderValue": "(71)", "AppManifestValue": 71, "Comment": "MT3620 GPIO 71. Pin shared with ISU4"}, 82 | {"Name": "MT3620_GPIO72", "Type": "Gpio", "MainCoreHeaderValue": "(72)", "AppManifestValue": 72, "Comment": "MT3620 GPIO 72. Pin shared with ISU4"}, 83 | {"Name": "MT3620_GPIO73", "Type": "Gpio", "MainCoreHeaderValue": "(73)", "AppManifestValue": 73, "Comment": "MT3620 GPIO 73. Pin shared with ISU4"}, 84 | {"Name": "MT3620_GPIO74", "Type": "Gpio", "MainCoreHeaderValue": "(74)", "AppManifestValue": 74, "Comment": "MT3620 GPIO 74. Pin shared with ISU4"}, 85 | {"Name": "MT3620_GPIO75", "Type": "Gpio", "MainCoreHeaderValue": "(75)", "AppManifestValue": 75, "Comment": "MT3620 GPIO 75. Pin shared with ISU4"}, 86 | {"Name": "MT3620_GPIO80", "Type": "Gpio", "MainCoreHeaderValue": "(80)", "AppManifestValue": 80, "Comment": "MT3620 GPIO 80"}, 87 | {"Name": "MT3620_PWM_CONTROLLER0", "Type": "Pwm", "MainCoreHeaderValue": "(0)", "AppManifestValue": "PWM-CONTROLLER-0", "Comment": "MT3620 PWM CONTROLLER 0: channel 0 on pin 0, channel 1 on pin 1, channel 2 on pin 2, and channel 3 on pin 3. Pins for this controller are shared with GPIO0, GPIO1, GPIO2, GPIO3. If this PWM controller is requested, none of these GPIOs can be used."}, 88 | {"Name": "MT3620_PWM_CONTROLLER1", "Type": "Pwm", "MainCoreHeaderValue": "(1)", "AppManifestValue": "PWM-CONTROLLER-1", "Comment": "MT3620 PWM CONTROLLER 1: channel 0 on pin 4, channel 1 on pin 5, channel 2 on pin 6, and channel 3 on pin 7. Pins for this controller are shared with GPIO4, GPIO5, GPIO6, GPIO7. If this PWM controller is requested, none of these GPIOs can be used."}, 89 | {"Name": "MT3620_PWM_CONTROLLER2", "Type": "Pwm", "MainCoreHeaderValue": "(2)", "AppManifestValue": "PWM-CONTROLLER-2", "Comment": "MT3620 PWM CONTROLLER 2: channel 0 on pin 8, channel 1 on pin 9, channel 2 on pin 10, and channel 3 on pin 11. Pins for this controller are shared with GPIO8, GPIO9, GPIO10, GPIO11. If this PWM controller is requested, none of these GPIOs can be used."}, 90 | {"Name": "MT3620_ADC_CONTROLLER0", "Type": "Adc", "MainCoreHeaderValue": "(0)", "AppManifestValue": "ADC-CONTROLLER-0", "Comment": "MT3620 ADC CONTROLLER 0: channel 0 on pin 41, channel 1 on pin 42, channel 2 on pin 43, channel 3 on pin 44, channel 4 on pin 45, channel 5 on pin 46, channel 6 on pin 47, and channel 7 on pin 48. Pins for this controller are shared with GPIO41, GPIO42, GPIO43, GPIO44, GPIO45, GPIO46, GPIO47 and GPIO48. If this ADC controller is requested, none of these GPIOs can be used."}, 91 | {"Name": "MT3620_ISU0_I2C", "Type": "I2cMaster", "MainCoreHeaderValue": "(0)", "AppManifestValue": "ISU0", "Comment": "MT3620 ISU 0 configured as I2C"}, 92 | {"Name": "MT3620_ISU1_I2C", "Type": "I2cMaster", "MainCoreHeaderValue": "(1)", "AppManifestValue": "ISU1", "Comment": "MT3620 ISU 1 configured as I2C"}, 93 | {"Name": "MT3620_ISU2_I2C", "Type": "I2cMaster", "MainCoreHeaderValue": "(2)", "AppManifestValue": "ISU2", "Comment": "MT3620 ISU 2 configured as I2C"}, 94 | {"Name": "MT3620_ISU3_I2C", "Type": "I2cMaster", "MainCoreHeaderValue": "(3)", "AppManifestValue": "ISU3", "Comment": "MT3620 ISU 3 configured as I2C"}, 95 | {"Name": "MT3620_ISU4_I2C", "Type": "I2cMaster", "MainCoreHeaderValue": "(4)", "AppManifestValue": "ISU4", "Comment": "MT3620 ISU 4 configured as I2C"}, 96 | {"Name": "MT3620_ISU0_SPI", "Type": "SpiMaster", "MainCoreHeaderValue": "(0)", "AppManifestValue": "ISU0", "Comment": "MT3620 ISU 0 configured as SPI"}, 97 | {"Name": "MT3620_ISU1_SPI", "Type": "SpiMaster", "MainCoreHeaderValue": "(1)", "AppManifestValue": "ISU1", "Comment": "MT3620 ISU 1 configured as SPI"}, 98 | {"Name": "MT3620_ISU2_SPI", "Type": "SpiMaster", "MainCoreHeaderValue": "(2)", "AppManifestValue": "ISU2", "Comment": "MT3620 ISU 2 configured as SPI"}, 99 | {"Name": "MT3620_ISU3_SPI", "Type": "SpiMaster", "MainCoreHeaderValue": "(3)", "AppManifestValue": "ISU3", "Comment": "MT3620 ISU 3 configured as SPI"}, 100 | {"Name": "MT3620_ISU4_SPI", "Type": "SpiMaster", "MainCoreHeaderValue": "(4)", "AppManifestValue": "ISU4", "Comment": "MT3620 ISU 4 configured as SPI"}, 101 | {"Name": "MT3620_ISU0_UART", "Type": "Uart", "MainCoreHeaderValue": "(4)", "AppManifestValue": "ISU0", "Comment": "MT3620 ISU 0 configured as UART"}, 102 | {"Name": "MT3620_ISU1_UART", "Type": "Uart", "MainCoreHeaderValue": "(5)", "AppManifestValue": "ISU1", "Comment": "MT3620 ISU 1 configured as UART"}, 103 | {"Name": "MT3620_ISU2_UART", "Type": "Uart", "MainCoreHeaderValue": "(6)", "AppManifestValue": "ISU2", "Comment": "MT3620 ISU 2 configured as UART"}, 104 | {"Name": "MT3620_ISU3_UART", "Type": "Uart", "MainCoreHeaderValue": "(7)", "AppManifestValue": "ISU3", "Comment": "MT3620 ISU 3 configured as UART"}, 105 | {"Name": "MT3620_ISU4_UART", "Type": "Uart", "MainCoreHeaderValue": "(8)", "AppManifestValue": "ISU4", "Comment": "MT3620 ISU 4 configured as UART"}, 106 | {"Name": "MT3620_PWM_CHANNEL0", "Type": "int", "MainCoreHeaderValue": "(0)", "Comment": "MT3620 PWM CHANNEL 0, it must not be used as a peripheral in app_manifest.json"}, 107 | {"Name": "MT3620_PWM_CHANNEL1", "Type": "int", "MainCoreHeaderValue": "(1)", "Comment": "MT3620 PWM CHANNEL 1, it must not be used as a peripheral in app_manifest.json"}, 108 | {"Name": "MT3620_PWM_CHANNEL2", "Type": "int", "MainCoreHeaderValue": "(2)", "Comment": "MT3620 PWM CHANNEL 2, it must not be used as a peripheral in app_manifest.json"}, 109 | {"Name": "MT3620_PWM_CHANNEL3", "Type": "int", "MainCoreHeaderValue": "(3)", "Comment": "MT3620 PWM CHANNEL 3, it must not be used as a peripheral in app_manifest.json"}, 110 | {"Name": "MT3620_SPI_CS_A", "Type": "int", "MainCoreHeaderValue": "(-1)", "Comment": "MT3620 SPI CS A, it must not be used as a peripheral in app_manifest"}, 111 | {"Name": "MT3620_SPI_CS_B", "Type": "int", "MainCoreHeaderValue": "(-2)", "Comment": "MT3620 SPI CS B, it must not be used as a peripheral in app_manifest"}, 112 | {"Name": "MT3620_ADC_CHANNEL0", "Type": "int", "MainCoreHeaderValue": "(0)", "Comment": "MT3620 ADC CHANNEL 0, it must not be used as a peripheral in app_manifest.json"}, 113 | {"Name": "MT3620_ADC_CHANNEL1", "Type": "int", "MainCoreHeaderValue": "(1)", "Comment": "MT3620 ADC CHANNEL 1, it must not be used as a peripheral in app_manifest.json"}, 114 | {"Name": "MT3620_ADC_CHANNEL2", "Type": "int", "MainCoreHeaderValue": "(2)", "Comment": "MT3620 ADC CHANNEL 2, it must not be used as a peripheral in app_manifest.json"}, 115 | {"Name": "MT3620_ADC_CHANNEL3", "Type": "int", "MainCoreHeaderValue": "(3)", "Comment": "MT3620 ADC CHANNEL 3, it must not be used as a peripheral in app_manifest.json"}, 116 | {"Name": "MT3620_ADC_CHANNEL4", "Type": "int", "MainCoreHeaderValue": "(4)", "Comment": "MT3620 ADC CHANNEL 4, it must not be used as a peripheral in app_manifest.json"}, 117 | {"Name": "MT3620_ADC_CHANNEL5", "Type": "int", "MainCoreHeaderValue": "(5)", "Comment": "MT3620 ADC CHANNEL 5, it must not be used as a peripheral in app_manifest.json"}, 118 | {"Name": "MT3620_ADC_CHANNEL6", "Type": "int", "MainCoreHeaderValue": "(6)", "Comment": "MT3620 ADC CHANNEL 6, it must not be used as a peripheral in app_manifest.json"}, 119 | {"Name": "MT3620_ADC_CHANNEL7", "Type": "int", "MainCoreHeaderValue": "(7)", "Comment": "MT3620 ADC CHANNEL 7, it must not be used as a peripheral in app_manifest.json"} 120 | ] 121 | } 122 | -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/app_manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "SchemaVersion": 1, 3 | "Name": "Avnet-Starter-Kit-reference-V1.0", 4 | "ComponentId": "685f13af-25a5-40b2-8dd8-8cbc253ecbd8", 5 | "EntryPoint": "/bin/app", 6 | "CmdArgs": [ "Avnet-Starter-Kit-reference-V1.0" ], 7 | "Capabilities": { 8 | "AllowedConnections": [], 9 | "AllowedTcpServerPorts": [], 10 | "AllowedUdpServerPorts": [], 11 | "Gpio": [ "$AVNET_MT3620_SK_GPIO0", "$AVNET_MT3620_SK_APP_STATUS_LED_YELLOW", "$AVNET_MT3620_SK_WLAN_STATUS_LED_YELLOW", "$AVNET_MT3620_SK_USER_LED_RED", "$AVNET_MT3620_SK_USER_LED_GREEN", "$AVNET_MT3620_SK_USER_LED_BLUE", "$AVNET_MT3620_SK_USER_BUTTON_A", "$AVNET_MT3620_SK_USER_BUTTON_B", "$AVNET_MT3620_SK_GPIO34" ], 12 | "Uart": [], 13 | "I2cMaster": [ "$AVNET_MT3620_SK_ISU2_I2C" ], 14 | "SpiMaster": [], 15 | "WifiConfig": true, 16 | "NetworkConfig": false, 17 | "SystemTime" : false 18 | } 19 | } -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/applibs_versions.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) Microsoft Corporation. All rights reserved. 2 | Licensed under the MIT License. */ 3 | 4 | #pragma once 5 | 6 | /// 7 | /// This identifier should be defined before including any of the networking-related header files. 8 | /// It indicates which version of the Wi-Fi data structures the application uses. 9 | /// 10 | #define NETWORKING_STRUCTS_VERSION 1 11 | 12 | /// 13 | /// This identifier must be defined before including any of the Wi-Fi related header files. 14 | /// It indicates which version of the Wi-Fi data structures the application uses. 15 | /// 16 | #define WIFICONFIG_STRUCTS_VERSION 1 17 | 18 | /// 19 | /// This identifier must be defined before including any of the UART-related header files. 20 | /// It indicates which version of the UART data structures the application uses. 21 | /// 22 | #define UART_STRUCTS_VERSION 1 23 | 24 | /// 25 | /// This identifier must be defined before including any of the SPI-related header files. 26 | /// It indicates which version of the SPI data structures the application uses. 27 | /// 28 | #define SPI_STRUCTS_VERSION 1 -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/azure_iot_utilities.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "azure_iot_utilities.h" 12 | #include "build_options.h" 13 | #include "connection_strings.h" 14 | 15 | 16 | // Refer to https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-device-sdk-c-intro for more 17 | // information on Azure IoT SDK for C 18 | 19 | // 20 | // String containing Hostname, Device Id & Device Key in the format: 21 | // "HostName=;DeviceId=;SharedAccessKey=" 22 | 23 | // see information on iothub-explorer at http://aka.ms/iothubgetstartedVSCS 24 | // 25 | 26 | #include "connection_strings.h" 27 | 28 | static const char connectionString[] = MY_CONNECTION_STRING; 29 | 30 | /// 31 | /// Maximum amount of time to attempt reconnection when the connection to the IoT Hub drops. 32 | /// 33 | /// Time expressed in seconds. A value of 0 means to retry forever. 34 | static const size_t retryTimeoutSeconds = 0; 35 | 36 | /// 37 | /// Function invoked to provide the result of the Device Twin reported properties 38 | /// delivery. 39 | /// 40 | static DeviceTwinDeliveryConfirmationFnType deviceTwinConfirmationCb = 0; 41 | 42 | /// 43 | /// Function invoked whenever a Direct Method call is received from the IoT Hub. 44 | /// 45 | static DirectMethodCallFnType directMethodCallCb = 0; 46 | 47 | /// 48 | /// Function invoked whenever a Device Twin update is received from the IoT Hub. 49 | /// 50 | static TwinUpdateFnType twinUpdateCb = 0; 51 | 52 | /// 53 | /// Function invoked whenever the connection status to the IoT Hub changes. 54 | /// 55 | static ConnectionStatusFnType hubConnectionStatusCb = 0; 56 | 57 | /// 58 | /// Function invoked whenever a message is received from the IoT Hub. 59 | /// 60 | static MessageReceivedFnType messageReceivedCb = 0; 61 | 62 | /// 63 | /// Function invoked to report the delivery confirmation of a message sent to the IoT 64 | /// Hub. 65 | /// 66 | static MessageDeliveryConfirmationFnType messageDeliveryConfirmationCb = 0; 67 | 68 | /// 69 | /// The handle to the IoT Hub client used for communication with the hub. 70 | /// 71 | IOTHUB_DEVICE_CLIENT_LL_HANDLE iothubClientHandle = NULL; 72 | 73 | /// 74 | /// Used to set the keepalive period over MQTT to 20 seconds. 75 | /// 76 | static int keepalivePeriodSeconds = 20; 77 | 78 | /// 79 | /// Set of bundle of root certificate authorities. 80 | /// 81 | static const char azureIoTCertificatesX[] = 82 | /* DigiCert Baltimore Root */ 83 | "-----BEGIN CERTIFICATE-----\r\n" 84 | "MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ\r\n" 85 | "RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD\r\n" 86 | "VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX\r\n" 87 | "DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y\r\n" 88 | "ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy\r\n" 89 | "VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr\r\n" 90 | "mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr\r\n" 91 | "IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK\r\n" 92 | "mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu\r\n" 93 | "XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy\r\n" 94 | "dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye\r\n" 95 | "jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1\r\n" 96 | "BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3\r\n" 97 | "DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92\r\n" 98 | "9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx\r\n" 99 | "jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0\r\n" 100 | "Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz\r\n" 101 | "ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS\r\n" 102 | "R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\r\n" 103 | "-----END CERTIFICATE-----\r\n" 104 | /* DigiCert Global Root CA */ 105 | "-----BEGIN CERTIFICATE-----\r\n" 106 | "MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh\r\n" 107 | "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\r\n" 108 | "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\r\n" 109 | "QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT\r\n" 110 | "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\r\n" 111 | "b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG\r\n" 112 | "9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB\r\n" 113 | "CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97\r\n" 114 | "nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt\r\n" 115 | "43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P\r\n" 116 | "T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4\r\n" 117 | "gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO\r\n" 118 | "BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR\r\n" 119 | "TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw\r\n" 120 | "DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr\r\n" 121 | "hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg\r\n" 122 | "06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF\r\n" 123 | "PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls\r\n" 124 | "YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk\r\n" 125 | "CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=\r\n" 126 | "-----END CERTIFICATE-----\r\n" 127 | /* D-TRUST Root Class 3 CA 2 2009 */ 128 | "-----BEGIN CERTIFICATE-----\r\n" 129 | "MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF\r\n" 130 | "MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD\r\n" 131 | "bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha\r\n" 132 | "ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM\r\n" 133 | "HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB\r\n" 134 | "BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03\r\n" 135 | "UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42\r\n" 136 | "tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R\r\n" 137 | "ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM\r\n" 138 | "lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp\r\n" 139 | "/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G\r\n" 140 | "A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G\r\n" 141 | "A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj\r\n" 142 | "dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy\r\n" 143 | "MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl\r\n" 144 | "cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js\r\n" 145 | "L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL\r\n" 146 | "BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni\r\n" 147 | "acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0\r\n" 148 | "o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K\r\n" 149 | "zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8\r\n" 150 | "PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y\r\n" 151 | "Johw1+qRzT65ysCQblrGXnRl11z+o+I=\r\n" 152 | "-----END CERTIFICATE-----\r\n"; 153 | 154 | // Forward declarations. 155 | static void sendMessageCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void *context); 156 | static IOTHUBMESSAGE_DISPOSITION_RESULT receiveMessageCallback(IOTHUB_MESSAGE_HANDLE message, 157 | void *context); 158 | static void twinCallback(DEVICE_TWIN_UPDATE_STATE updateState, const unsigned char *payLoad, 159 | size_t size, void *userContextCallback); 160 | static int directMethodCallback(const char *methodName, const unsigned char *payload, size_t size, 161 | unsigned char **response, size_t *response_size, 162 | void *userContextCallback); 163 | static void hubConnectionStatusCallback(IOTHUB_CLIENT_CONNECTION_STATUS result, 164 | IOTHUB_CLIENT_CONNECTION_STATUS_REASON reason, 165 | void *userContextCallback); 166 | 167 | #if (defined(IOT_CENTRAL_APPLICATION) || defined(IOT_HUB_APPLICATION)) 168 | #define MAXS_SIZE 512 169 | // Verify that the connection string is not too long 170 | _Static_assert(sizeof(connectionString) <= MAXS_SIZE, "Connection string too long"); 171 | // Verify tthat the connection string is defined 172 | _Static_assert(sizeof(connectionString) > 1, "Connection string not defined! Define MY_CONNECTION_STRING in connection_strings.h"); 173 | #endif 174 | 175 | /// 176 | /// Converts the IoT Hub connection status reason to a string. 177 | /// 178 | static const char *getReasonString(IOTHUB_CLIENT_CONNECTION_STATUS_REASON reason) 179 | { 180 | static char *reasonString = "unknown reason"; 181 | switch (reason) { 182 | case IOTHUB_CLIENT_CONNECTION_EXPIRED_SAS_TOKEN: 183 | reasonString = "IOTHUB_CLIENT_CONNECTION_EXPIRED_SAS_TOKEN"; 184 | break; 185 | case IOTHUB_CLIENT_CONNECTION_DEVICE_DISABLED: 186 | reasonString = "IOTHUB_CLIENT_CONNECTION_DEVICE_DISABLED"; 187 | break; 188 | case IOTHUB_CLIENT_CONNECTION_BAD_CREDENTIAL: 189 | reasonString = "IOTHUB_CLIENT_CONNECTION_BAD_CREDENTIAL"; 190 | break; 191 | case IOTHUB_CLIENT_CONNECTION_RETRY_EXPIRED: 192 | reasonString = "IOTHUB_CLIENT_CONNECTION_RETRY_EXPIRED"; 193 | break; 194 | case IOTHUB_CLIENT_CONNECTION_NO_NETWORK: 195 | reasonString = "IOTHUB_CLIENT_CONNECTION_NO_NETWORK"; 196 | break; 197 | case IOTHUB_CLIENT_CONNECTION_COMMUNICATION_ERROR: 198 | reasonString = "IOTHUB_CLIENT_CONNECTION_COMMUNICATION_ERROR"; 199 | break; 200 | case IOTHUB_CLIENT_CONNECTION_OK: 201 | reasonString = "IOTHUB_CLIENT_CONNECTION_OK"; 202 | break; 203 | } 204 | return reasonString; 205 | } 206 | 207 | /// 208 | /// Log a message related to the Azure IoT Hub client with 209 | /// prefix [Azure IoT Hub client]:" 210 | /// 211 | /// The format string containing the error to output along with 212 | /// placeholders 213 | /// The list of arguments to populate the format string placeholders 214 | void LogMessage(char *message, ...) 215 | { 216 | va_list args; 217 | va_start(args, message); 218 | Log_Debug("[Azure IoT Hub client] "); 219 | Log_DebugVarArgs(message, args); 220 | va_end(args); 221 | } 222 | 223 | /// 224 | /// Sets up the client in order to establish the communication channel to Azure IoT Hub. 225 | /// 226 | /// The client is created by using the IoT Hub connection string that is provisioned 227 | /// on the device or hardcoded into the source. The client is setup with the following 228 | /// options: 229 | /// - IOTHUB_CLIENT_RETRY_INTERVAL retry policy which, when the network connection 230 | /// to the IoT Hub drops, attempts a reconnection each 5 seconds for a period of time 231 | /// of 5000 seconds before giving up; 232 | /// - MQTT procotol 'keepalive' value of 20 seconds; when no PINGRESP is received after 233 | /// 20 seconds, the connection is believed to be down and the retry policy kicks in; 234 | /// 235 | /// 'true' if the client has been properly set up. 'false' when a fatal error occurred 236 | /// while setting up the client. 237 | /// This function is a no-op when the client has already been set up, i.e. this 238 | /// function has already completed successfully. 239 | bool AzureIoT_SetupClient(void) 240 | { 241 | if (iothubClientHandle != NULL) { 242 | return true; 243 | } 244 | 245 | iothubClientHandle = 246 | IoTHubDeviceClient_LL_CreateFromConnectionString(connectionString, MQTT_Protocol); 247 | 248 | if (iothubClientHandle == NULL) { 249 | return false; 250 | } 251 | 252 | if (IoTHubDeviceClient_LL_SetOption(iothubClientHandle, "TrustedCerts", 253 | azureIoTCertificatesX) != IOTHUB_CLIENT_OK) { 254 | LogMessage("ERROR: failure to set option \"TrustedCerts\"\n"); 255 | return false; 256 | } 257 | 258 | if (IoTHubDeviceClient_LL_SetOption(iothubClientHandle, OPTION_KEEP_ALIVE, 259 | &keepalivePeriodSeconds) != IOTHUB_CLIENT_OK) { 260 | LogMessage("ERROR: failure setting option \"%s\"\n", OPTION_KEEP_ALIVE); 261 | return false; 262 | } 263 | 264 | // Set callbacks for Message, MethodCall and Device Twin features. 265 | IoTHubDeviceClient_LL_SetMessageCallback(iothubClientHandle, receiveMessageCallback, NULL); 266 | IoTHubDeviceClient_LL_SetDeviceMethodCallback(iothubClientHandle, directMethodCallback, NULL); 267 | IoTHubDeviceClient_LL_SetDeviceTwinCallback(iothubClientHandle, twinCallback, NULL); 268 | 269 | // Set callbacks for connection status related events. 270 | if (IoTHubDeviceClient_LL_SetConnectionStatusCallback( 271 | iothubClientHandle, hubConnectionStatusCallback, NULL) != IOTHUB_CLIENT_OK) { 272 | LogMessage("ERROR: failure setting callback\n"); 273 | return false; 274 | } 275 | 276 | // Set retry policy for the connection to the IoT Hub. 277 | if (IoTHubDeviceClient_LL_SetRetryPolicy(iothubClientHandle, IOTHUB_CLIENT_RETRY_INTERVAL, 278 | retryTimeoutSeconds) != IOTHUB_CLIENT_OK) { 279 | LogMessage("ERROR: failure setting retry policy\n"); 280 | return false; 281 | } 282 | 283 | return true; 284 | } 285 | 286 | /// 287 | /// Destroys the Azure IoT Hub client. 288 | /// 289 | void AzureIoT_DestroyClient(void) 290 | { 291 | if (iothubClientHandle != NULL) { 292 | IoTHubDeviceClient_LL_Destroy(iothubClientHandle); 293 | iothubClientHandle = NULL; 294 | } 295 | } 296 | 297 | /// 298 | /// Periodically outputs a provided format string with a variable number of arguments. 299 | /// 300 | /// Pointer where to store the 'last time this function has been 301 | /// invoked' information 302 | /// The desired period of the output 303 | /// The format string 304 | static void PeriodicLogVarArgs(time_t *lastInvokedTime, time_t periodInSeconds, const char *format, 305 | ...) 306 | { 307 | struct timespec ts; 308 | int timeOk = timespec_get(&ts, TIME_UTC); 309 | if (!timeOk) { 310 | return; 311 | } 312 | 313 | if (ts.tv_sec > *lastInvokedTime + periodInSeconds) { 314 | va_list args; 315 | va_start(args, format); 316 | Log_Debug("[Azure IoT Hub client] "); 317 | Log_DebugVarArgs(format, args); 318 | va_end(args); 319 | *lastInvokedTime = ts.tv_sec; 320 | } 321 | } 322 | 323 | /// 324 | /// Keeps IoT Hub Client alive by exchanging data with the Azure IoT Hub. 325 | /// 326 | /// 327 | /// This function must to be invoked periodically so that the Azure IoT Hub 328 | /// SDK can accomplish its work (e.g. sending messages, invocation of callbacks, reconnection 329 | /// attempts, and so forth). 330 | /// 331 | void AzureIoT_DoPeriodicTasks(void) 332 | { 333 | static time_t lastTimeLogged = 0; 334 | PeriodicLogVarArgs(&lastTimeLogged, 5, "INFO: %s calls in progress...\n", __func__); 335 | 336 | // DoWork - send some of the buffered events to the IoT Hub, and receive some of the buffered 337 | // events from the IoT Hub. 338 | IoTHubDeviceClient_LL_DoWork(iothubClientHandle); 339 | } 340 | 341 | /// 342 | /// Creates and enqueues a message to be delivered the IoT Hub. The message is not actually sent 343 | /// immediately, but it is sent on the next invocation of AzureIoT_DoPeriodicTasks(). 344 | /// 345 | /// The payload of the message to send. 346 | void AzureIoT_SendMessage(const char *messagePayload) 347 | { 348 | if (iothubClientHandle == NULL) { 349 | LogMessage("WARNING: IoT Hub client not initialized\n"); 350 | return; 351 | } 352 | 353 | IOTHUB_MESSAGE_HANDLE messageHandle = IoTHubMessage_CreateFromString(messagePayload); 354 | 355 | if (messageHandle == 0) { 356 | LogMessage("WARNING: unable to create a new IoTHubMessage\n"); 357 | return; 358 | } 359 | 360 | if (IoTHubDeviceClient_LL_SendEventAsync(iothubClientHandle, messageHandle, sendMessageCallback, 361 | /*&callback_param*/ 0) != IOTHUB_CLIENT_OK) { 362 | LogMessage("WARNING: failed to hand over the message to IoTHubClient\n"); 363 | } else { 364 | LogMessage("INFO: IoTHubClient accepted the message for delivery\n"); 365 | } 366 | 367 | IoTHubMessage_Destroy(messageHandle); 368 | } 369 | 370 | /// 371 | /// Sets the function to be invoked whenever the Device Twin properties have been delivered to 372 | /// the IoT Hub. 373 | /// 374 | /// The function pointer to the callback function. 375 | void AzureIoT_SetDeviceTwinDeliveryConfirmationCallback( 376 | DeviceTwinDeliveryConfirmationFnType callback) 377 | { 378 | deviceTwinConfirmationCb = callback; 379 | } 380 | 381 | /// 382 | /// Callback invoked when the Device Twin reported properties are accepted by IoT Hub. 383 | /// 384 | static void reportStatusCallback(int result, void *context) 385 | { 386 | LogMessage("INFO: Device Twin reported properties update result: HTTP status code %d\n", 387 | result); 388 | if (deviceTwinConfirmationCb) 389 | deviceTwinConfirmationCb(result); 390 | } 391 | 392 | /// 393 | /// Creates and enqueues a report containing the name and value pair of a Device Twin reported 394 | /// property. 395 | /// The report is not actually sent immediately, but it is sent on the next invocation of 396 | /// AzureIoT_DoPeriodicTasks(). 397 | /// 398 | void AzureIoT_TwinReportState(const char *propertyName, size_t propertyValue) 399 | { 400 | if (iothubClientHandle == NULL) { 401 | LogMessage("ERROR: client not initialized\n"); 402 | return; 403 | } 404 | 405 | char *reportedPropertiesString = NULL; 406 | JSON_Value *reportedPropertiesRootJson = json_value_init_object(); 407 | if (reportedPropertiesRootJson == NULL) { 408 | LogMessage("ERROR: could not create the JSON_Value for Device Twin reporting.\n"); 409 | return; 410 | } 411 | 412 | JSON_Object *reportedPropertiesJson = json_value_get_object(reportedPropertiesRootJson); 413 | if (reportedPropertiesJson == NULL) { 414 | LogMessage("ERROR: could not get the JSON_Object for Device Twin reporting.\n"); 415 | goto cleanup; 416 | } 417 | 418 | if (JSONSuccess != 419 | json_object_set_number(reportedPropertiesJson, propertyName, propertyValue)) { 420 | LogMessage("ERROR: could not set the property value for Device Twin reporting.\n"); 421 | goto cleanup; 422 | } 423 | 424 | reportedPropertiesString = json_serialize_to_string(reportedPropertiesRootJson); 425 | if (reportedPropertiesString == NULL) { 426 | LogMessage( 427 | "ERROR: could not serialize the JSON payload to string for Device " 428 | "Twin reporting.\n"); 429 | goto cleanup; 430 | } 431 | 432 | if (IoTHubDeviceClient_LL_SendReportedState( 433 | iothubClientHandle, (unsigned char *)reportedPropertiesString, 434 | strlen(reportedPropertiesString), reportStatusCallback, 0) != IOTHUB_CLIENT_OK) { 435 | LogMessage("ERROR: failed to set reported property '%s'.\n", propertyName); 436 | } else { 437 | LogMessage("INFO: Set reported property '%s' to value %d.\n", propertyName, propertyValue); 438 | } 439 | 440 | cleanup: 441 | if (reportedPropertiesRootJson != NULL) { 442 | json_value_free(reportedPropertiesRootJson); 443 | } 444 | if (reportedPropertiesString != NULL) { 445 | json_free_serialized_string(reportedPropertiesString); 446 | } 447 | } 448 | 449 | /// 450 | /// Sets a callback function invoked whenever a message is received from IoT Hub. 451 | /// 452 | /// The callback function invoked when a message is received 453 | void AzureIoT_SetMessageReceivedCallback(MessageReceivedFnType callback) 454 | { 455 | messageReceivedCb = callback; 456 | } 457 | 458 | /// 459 | /// Sets the function to be invoked whenever the message to the Iot Hub has been delivered. 460 | /// 461 | /// The function pointer to the callback function. 462 | void AzureIoT_SetMessageConfirmationCallback(MessageDeliveryConfirmationFnType callback) 463 | { 464 | messageDeliveryConfirmationCb = callback; 465 | } 466 | 467 | /// 468 | /// Function invoked when the message delivery confirmation is being reported. 469 | /// 470 | /// Message delivery status 471 | /// User specified context 472 | static void sendMessageCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void *context) 473 | { 474 | LogMessage("INFO: Message received by IoT Hub. Result is: %d\n", result); 475 | if (messageDeliveryConfirmationCb) { 476 | messageDeliveryConfirmationCb(result == IOTHUB_CLIENT_CONFIRMATION_OK); 477 | } 478 | } 479 | 480 | /// 481 | /// Callback function invoked when a message is received from IoT Hub. 482 | /// 483 | /// The handle of the received message 484 | /// The user context specified at IoTHubDeviceClient_LL_SetMessageCallback() 485 | /// invocation time 486 | /// Return value to indicates the message procession status (i.e. accepted, rejected, 487 | /// abandoned) 488 | static IOTHUBMESSAGE_DISPOSITION_RESULT receiveMessageCallback(IOTHUB_MESSAGE_HANDLE message, 489 | void *context) 490 | { 491 | const unsigned char *buffer = NULL; 492 | size_t size = 0; 493 | if (IoTHubMessage_GetByteArray(message, &buffer, &size) != IOTHUB_MESSAGE_OK) { 494 | LogMessage("WARNING: failure performing IoTHubMessage_GetByteArray\n"); 495 | return IOTHUBMESSAGE_REJECTED; 496 | } 497 | 498 | // 'buffer' is not zero terminated. 499 | unsigned char *str_msg = (unsigned char *)malloc(size + 1); 500 | if (str_msg == NULL) { 501 | LogMessage("ERROR: could not allocate buffer for incoming message\n"); 502 | abort(); 503 | } 504 | memcpy(str_msg, buffer, size); 505 | str_msg[size] = '\0'; 506 | 507 | if (messageReceivedCb != 0) { 508 | messageReceivedCb(str_msg); 509 | } else { 510 | LogMessage("WARNING: no user callback set up for event 'message received from IoT Hub'\n"); 511 | } 512 | 513 | LogMessage("INFO: Received message '%s' from IoT Hub\n", str_msg); 514 | free(str_msg); 515 | 516 | return IOTHUBMESSAGE_ACCEPTED; 517 | } 518 | 519 | /// 520 | /// Sets the function to be invoked whenever a Direct Method call from the IoT Hub is received. 521 | /// 522 | /// The callback function invoked when a Direct Method call is 523 | /// received 524 | void AzureIoT_SetDirectMethodCallback(DirectMethodCallFnType callback) 525 | { 526 | directMethodCallCb = callback; 527 | } 528 | 529 | /// 530 | /// Sets the function callback invoked whenever a Device Twin update from the IoT Hub is 531 | /// received. 532 | /// 533 | /// The callback function invoked when a Device Twin update is 534 | /// received 535 | void AzureIoT_SetDeviceTwinUpdateCallback(TwinUpdateFnType callback) 536 | { 537 | twinUpdateCb = callback; 538 | } 539 | 540 | /// 541 | /// Callback when direct method is called. 542 | /// 543 | static int directMethodCallback(const char *methodName, const unsigned char *payload, size_t size, 544 | unsigned char **response, size_t *responseSize, 545 | void *userContextCallback) 546 | { 547 | LogMessage("INFO: Trying to invoke method %s\n", methodName); 548 | 549 | int result = 404; 550 | 551 | if (directMethodCallCb != NULL) { 552 | char *responseFromCallback = NULL; 553 | size_t responseFromCallbackSize = 0; 554 | 555 | result = directMethodCallCb(methodName, payload, size, &responseFromCallback, 556 | &responseFromCallbackSize); 557 | *responseSize = responseFromCallbackSize; 558 | *response = responseFromCallback; 559 | } else { 560 | LogMessage("INFO: No method '%s' found, HttpStatus=%d\n", methodName, result); 561 | static const char methodNotFound[] = "\"No method found\""; 562 | *responseSize = strlen(methodNotFound); 563 | *response = (unsigned char *)malloc(*responseSize); 564 | if (*response != NULL) { 565 | strncpy((char *)(*response), methodNotFound, *responseSize); 566 | } else { 567 | LogMessage("ERROR: Cannot create response message for method call.\n"); 568 | abort(); 569 | } 570 | } 571 | 572 | return result; 573 | } 574 | 575 | /// 576 | /// Callback invoked when a Device Twin update is received from IoT Hub. 577 | /// 578 | static void twinCallback(DEVICE_TWIN_UPDATE_STATE updateState, const unsigned char *payLoad, 579 | size_t payLoadSize, void *userContextCallback) 580 | { 581 | size_t nullTerminatedJsonSize = payLoadSize + 1; 582 | char *nullTerminatedJsonString = (char *)malloc(nullTerminatedJsonSize); 583 | if (nullTerminatedJsonString == NULL) { 584 | LogMessage("ERROR: Could not allocate buffer for twin update payload.\n"); 585 | abort(); 586 | } 587 | 588 | // Copy the provided buffer to a null terminated buffer. 589 | memcpy(nullTerminatedJsonString, payLoad, payLoadSize); 590 | // Add the null terminator at the end. 591 | nullTerminatedJsonString[nullTerminatedJsonSize - 1] = 0; 592 | 593 | JSON_Value *rootProperties = NULL; 594 | rootProperties = json_parse_string(nullTerminatedJsonString); 595 | if (rootProperties == NULL) { 596 | LogMessage("WARNING: Cannot parse the string as JSON content.\n"); 597 | goto cleanup; 598 | } 599 | 600 | JSON_Object *rootObject = json_value_get_object(rootProperties); 601 | JSON_Object *desiredProperties = json_object_dotget_object(rootObject, "desired"); 602 | if (desiredProperties == NULL) { 603 | desiredProperties = rootObject; 604 | } 605 | // Call the provided Twin Device callback if any. 606 | if (twinUpdateCb != NULL) { 607 | twinUpdateCb(desiredProperties); 608 | } 609 | 610 | cleanup: 611 | // Release the allocated memory. 612 | json_value_free(rootProperties); 613 | free(nullTerminatedJsonString); 614 | } 615 | 616 | /// 617 | /// Sets the function to be invoked whenever the connection status to the IoT Hub changes. 618 | /// 619 | /// The callback function invoked when Azure IoT Hub network connection 620 | /// status changes. 621 | void AzureIoT_SetConnectionStatusCallback(ConnectionStatusFnType callback) 622 | { 623 | hubConnectionStatusCb = callback; 624 | } 625 | 626 | /// 627 | /// Callback function invoked whenever the connection status to IoT Hub changes. 628 | /// 629 | /// Current authentication status 630 | /// result's specific reason 631 | /// User specified context 632 | static void hubConnectionStatusCallback(IOTHUB_CLIENT_CONNECTION_STATUS result, 633 | IOTHUB_CLIENT_CONNECTION_STATUS_REASON reason, 634 | void *userContextCallback) 635 | { 636 | bool authenticated = (result == IOTHUB_CLIENT_CONNECTION_AUTHENTICATED); 637 | if (hubConnectionStatusCb) { 638 | hubConnectionStatusCb(result == IOTHUB_CLIENT_CONNECTION_AUTHENTICATED); 639 | } 640 | const char *reasonString = getReasonString(reason); 641 | if (!authenticated) { 642 | LogMessage("INFO: IoT Hub connection is down (%s), retrying connection in 5 seconds...\n", 643 | reasonString); 644 | } else { 645 | LogMessage("INFO: connection to the IoT Hub has been established (%s).\n", reasonString); 646 | } 647 | } 648 | 649 | /// 650 | /// Initializes the Azure IoT Hub SDK. 651 | /// 652 | /// 'true' if initialization has been successful. 653 | bool AzureIoT_Initialize(void) 654 | { 655 | if (IoTHub_Init() != 0) { 656 | LogMessage("ERROR: failed initializing platform.\n"); 657 | return false; 658 | } 659 | return true; 660 | } 661 | 662 | /// 663 | /// Deinitializes the Azure IoT Hub SDK. 664 | /// 665 | void AzureIoT_Deinitialize(void) 666 | { 667 | IoTHub_Deinit(); 668 | } 669 | /// 670 | /// Creates and enqueues reported properties state using a prepared json string. 671 | /// The report is not actually sent immediately, but it is sent on the next 672 | /// invocation of AzureIoT_DoPeriodicTasks(). 673 | /// 674 | void AzureIoT_TwinReportStateJson( 675 | char *reportedPropertiesString, 676 | size_t reportedPropertiesSize) 677 | { 678 | 679 | if (iothubClientHandle == NULL) { 680 | LogMessage("ERROR: client not initialized\n"); 681 | } 682 | else { 683 | if (reportedPropertiesString != NULL) { 684 | if (IoTHubDeviceClient_LL_SendReportedState(iothubClientHandle, 685 | (unsigned char *)reportedPropertiesString, reportedPropertiesSize, 686 | reportStatusCallback, 0) != IOTHUB_CLIENT_OK) { 687 | LogMessage("ERROR: failed to set reported state as '%s'.\n", 688 | reportedPropertiesString); 689 | } 690 | else { 691 | LogMessage("INFO: Reported state as '%s'.\n", reportedPropertiesString); 692 | } 693 | } 694 | else { 695 | LogMessage("ERROR: no JSON string for Device Twin reporting.\n"); 696 | } 697 | } 698 | } -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/azure_iot_utilities.h: -------------------------------------------------------------------------------- 1 | /// \file azure_iot_utilities.h 2 | /// \brief This header defines a sample interface for performing basic operations with an 3 | /// Azure IoT Hub using the low-level API layer provided by the IoTHubClient library 4 | /// included in the Azure IoT Device SDK for C. 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include "parson.h" 10 | 11 | /// 12 | /// Sets up the client in order to establish the communication channel to Azure IoT Hub. 13 | /// 14 | /// The client is created by using the IoT Hub connection string that is provisioned 15 | /// on the device or hardcoded into the source. The client is setup with the following 16 | /// options: 17 | /// - IOTHUB_CLIENT_RETRY_INTERVAL retry policy which, when the network connection 18 | /// to the IoT Hub drops, attempts a reconnection each 5 seconds for a period of time 19 | /// of 5000 seconds before giving up; 20 | /// - MQTT procotol 'keepalive' value of 20 seconds; when no PINGRESP is received after 21 | /// 20 seconds, the connection is believed to be down and the retry policy kicks in; 22 | /// 23 | /// 'true' if the client has been properly set up. 'false' when a fatal error occurred 24 | /// while setting up the client. 25 | /// This function is a no-op when the client has already been set up, i.e. this 26 | /// function has already completed successfully. 27 | bool AzureIoT_SetupClient(void); 28 | 29 | /// 30 | /// Destroys the Azure IoT Hub client. 31 | /// 32 | void AzureIoT_DestroyClient(void); 33 | 34 | /// 35 | /// Creates and enqueues reported properties state using a prepared json string. 36 | /// The report is not actually sent immediately, but it is sent on the next 37 | /// invocation of AzureIoT_DoPeriodicTasks(). 38 | /// 39 | void AzureIoT_TwinReportStateJson( 40 | char *reportedPropertiesString, 41 | size_t reportedPropertiesSize); 42 | 43 | /// 44 | /// Creates and enqueues a report containing the name and value pair of a Device Twin reported 45 | /// property. 46 | /// The report is not actually sent immediately, but it is sent on the next invocation of 47 | /// AzureIoT_DoPeriodicTasks(). 48 | /// 49 | /// The name of the property to report. 50 | /// The value of the property. 51 | void AzureIoT_TwinReportState(const char *propertyName, size_t propertyValue); 52 | 53 | /// 54 | /// Creates and enqueues a message to be delivered the IoT Hub. The message is not actually sent 55 | /// immediately, but it is sent on the next invocation of AzureIoT_DoPeriodicTasks(). 56 | /// 57 | /// The payload of the message to send. 58 | void AzureIoT_SendMessage(const char *messagePayload); 59 | 60 | /// 61 | /// Keeps IoT Hub Client alive by exchanging data with the Azure IoT Hub. 62 | /// 63 | /// 64 | /// This function must to be invoked periodically so that the Azure IoT Hub 65 | /// SDK can accomplish its work (e.g. sending messages, invokation of callbacks, reconnection 66 | /// attempts, and so forth). 67 | /// 68 | void AzureIoT_DoPeriodicTasks(void); 69 | 70 | /// 71 | /// Type of the function callback invoked whenever a message is received from IoT Hub. 72 | /// 73 | typedef void (*MessageReceivedFnType)(const char *payload); 74 | 75 | /// 76 | /// Sets a callback function invoked whenever a message is received from IoT Hub. 77 | /// 78 | /// The callback function invoked when a message is received 79 | void AzureIoT_SetMessageReceivedCallback(MessageReceivedFnType callback); 80 | 81 | /// 82 | /// Type of the function callback invoked whenever a Device Twin update from the IoT Hub is 83 | /// received. 84 | /// 85 | /// The JSON object containing the Device Twin desired properties. 86 | typedef void (*TwinUpdateFnType)(JSON_Object *desiredProperties); 87 | 88 | /// 89 | /// Sets the function callback invoked whenever a Device Twin update from the IoT Hub is 90 | /// received. 91 | /// 92 | /// The callback function invoked when a Device Twin update is 93 | /// received 94 | void AzureIoT_SetDeviceTwinUpdateCallback(TwinUpdateFnType callback); 95 | 96 | /// 97 | /// Type of the function callback invoked when a Direct Method call from the IoT Hub is 98 | /// received. 99 | /// 100 | /// The name of the direct method to invoke 101 | /// The payload of the direct method call 102 | /// The payload size of the direct method call 103 | /// The payload of the response provided by the callee. It must be 104 | /// either NULL or an heap allocated string. 105 | /// The size of the response payload provided by the 106 | /// callee. 107 | /// The HTTP status code. e.g. 404 for method not found. 108 | typedef int (*DirectMethodCallFnType)(const char *directMethodName, const char *payload, 109 | size_t payloadSize, char **responsePayload, 110 | size_t *responsePayloadSize); 111 | 112 | /// 113 | /// Sets the function to be invoked whenever a Direct Method call from the IoT Hub is received. 114 | /// 115 | /// The callback function invoked when a Direct Method call is 116 | /// received 117 | void AzureIoT_SetDirectMethodCallback(DirectMethodCallFnType callback); 118 | 119 | /// 120 | /// Type of the function callback invoked when the IoT Hub connection status changes. 121 | /// 122 | typedef void (*ConnectionStatusFnType)(bool connected); 123 | 124 | /// 125 | /// Sets the function to be invoked whenever the connection status to thye IoT Hub changes. 126 | /// 127 | /// The callback function invoked when Azure IoT Hub network connection 128 | /// status changes. 129 | void AzureIoT_SetConnectionStatusCallback(ConnectionStatusFnType callback); 130 | 131 | /// 132 | /// Type of the function callback invoked to report whether a message sent to the IoT Hub has 133 | /// been successfully delivered or not. 134 | /// 135 | /// 'true' when the message has been successfully delivered. 136 | typedef void (*MessageDeliveryConfirmationFnType)(bool delivered); 137 | 138 | /// 139 | /// Sets the function to be invoked whenever the message to the Iot Hub has been delivered. 140 | /// 141 | /// The function pointer to the callback function. 142 | void AzureIoT_SetMessageConfirmationCallback(MessageDeliveryConfirmationFnType callback); 143 | 144 | /// 145 | /// Type of the function callback invoked to report whether the Device Twin properties 146 | /// to the IoT Hub have been successfully delivered. 147 | /// 148 | /// The HTTP status code returned by the IoT Hub. 149 | typedef void (*DeviceTwinDeliveryConfirmationFnType)(int httpStatusCode); 150 | 151 | /// 152 | /// Sets the function to be invoked whenever the Device Twin properties have been delivered to 153 | /// the IoT Hub. 154 | /// 155 | /// The function pointer to the callback function. 156 | void AzureIoT_SetDeviceTwinDeliveryConfirmationCallback( 157 | DeviceTwinDeliveryConfirmationFnType callback); 158 | 159 | /// 160 | /// Initializes the Azure IoT Hub SDK. 161 | /// 162 | /// 'true' if initialization has been successful. 163 | bool AzureIoT_Initialize(void); 164 | 165 | /// 166 | /// Deinitializes the Azure IoT Hub SDK. 167 | /// 168 | void AzureIoT_Deinitialize(void); 169 | -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/build_options.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // If your application is going to connect to an IoT Central Application, then enable this define. When 4 | // enabled Device Twin JSON updates will conform to what IoT Central expects to confirm Device Twin settings 5 | //#define IOT_CENTRAL_APPLICATION 6 | 7 | // If your application is going to connect straight to a IoT Hub, then enable this define. 8 | //#define IOT_HUB_APPLICATION 9 | 10 | #if (defined(IOT_CENTRAL_APPLICATION) && defined(IOT_HUB_APPLICATION)) 11 | #error "Can not define both IoT Central and IoT Hub Applications at the same time only define one." 12 | #endif 13 | 14 | #if (!defined(IOT_CENTRAL_APPLICATION) && !defined(IOT_HUB_APPLICATION)) 15 | #warning "Building application for no cloud connectivity" 16 | #endif 17 | 18 | #ifdef IOT_CENTRAL_APPLICATION 19 | #warning "Building for IoT Central Application" 20 | #endif 21 | 22 | #ifdef IOT_HUB_APPLICATION 23 | #warning "Building for IoT Hub Application" 24 | #endif 25 | 26 | 27 | // Defines how quickly the accelerator data is read and reported 28 | #define ACCEL_READ_PERIOD_SECONDS 1 29 | #define ACCEL_READ_PERIOD_NANO_SECONDS 0 30 | 31 | // Enables I2C read/write debug 32 | //#define ENABLE_READ_WRITE_DEBUG -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/connection_strings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Define your connection string here. The connection string is required to connect to Azure. 4 | #define MY_CONNECTION_STRING "" 5 | -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/deviceTwin.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "parson.h" 5 | 6 | #define JSON_BUFFER_SIZE 128 7 | 8 | typedef enum { 9 | TYPE_INT = 0, 10 | TYPE_FLOAT = 1, 11 | TYPE_BOOL = 2, 12 | TYPE_STRING = 3 13 | } data_type_t; 14 | 15 | typedef struct { 16 | char* twinKey; 17 | void* twinVar; 18 | int* twinFd; 19 | GPIO_Id twinGPIO; 20 | data_type_t twinType; 21 | bool active_high; 22 | } twin_t; 23 | 24 | /// 25 | /// Parses received desired property changes. 26 | /// 27 | ///Address of desired properties JSON_Object 28 | void deviceTwinChangedHandler(JSON_Object * desiredProperties); 29 | 30 | void checkAndUpdateDeviceTwin(char*, void*, data_type_t, bool); 31 | 32 | 33 | #define NO_GPIO_ASSOCIATED_WITH_TWIN -1 -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/device_twin.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | // applibs_versions.h defines the API struct versions to use for applibs APIs. 12 | #include "applibs_versions.h" 13 | #include "epoll_timerfd_utilities.h" 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include "hw/avnet_mt3620_sk.h" 20 | #include "deviceTwin.h" 21 | #include "azure_iot_utilities.h" 22 | #include "parson.h" 23 | #include "build_options.h" 24 | 25 | bool userLedRedIsOn = false; 26 | bool userLedGreenIsOn = false; 27 | bool userLedBlueIsOn = false; 28 | bool appLedIsOn = false; 29 | bool wifiLedIsOn = false; 30 | bool clkBoardRelay1IsOn = true; 31 | bool clkBoardRelay2IsOn = true; 32 | 33 | extern int userLedRedFd; 34 | extern int userLedGreenFd; 35 | extern int userLedBlueFd; 36 | 37 | extern int appLedFd; 38 | extern int wifiLedFd; 39 | extern int clickSocket1Relay1Fd; 40 | extern int clickSocket1Relay2Fd; 41 | 42 | extern volatile sig_atomic_t terminationRequired; 43 | 44 | static const char cstrDeviceTwinJsonInteger[] = "{\"%s\": %d}"; 45 | static const char cstrDeviceTwinJsonFloat[] = "{\"%s\": %.2f}"; 46 | static const char cstrDeviceTwinJsonBool[] = "{\"%s\": %s}"; 47 | static const char cstrDeviceTwinJsonString[] = "{\"%s\": \"%s\"}"; 48 | #ifdef IOT_CENTRAL_APPLICATION 49 | static const char cstrDeviceTwinJsonFloatIOTC[] = "{\"%s\": {\"value\": %.2f, \"status\" : \"completed\" , \"desiredVersion\" : %d }}"; 50 | static const char cstrDeviceTwinJsonBoolIOTC[] = "{\"%s\": {\"value\": %s, \"status\" : \"completed\" , \"desiredVersion\" : %d }}"; 51 | static const char cstrDeviceTwinJsonIntegerIOTC[] = "{\"%s\": {\"value\": %d, \"status\" : \"completed\" , \"desiredVersion\" : %d }}"; 52 | static const char cstrDeviceTwinJsonStringIOTC[] = "{\"%s\": {\"value\": %s, \"status\" : \"completed\" , \"desiredVersion\" : %d }}"; 53 | #endif 54 | 55 | static int desiredVersion = 0; 56 | 57 | // Define each device twin key that we plan to catch, process, and send reported property for. 58 | // .twinKey - The JSON Key piece of the key: value pair 59 | // .twinVar - The address of the application variable keep this key: value pair data 60 | // .twinFD - The associated File Descriptor for this item. This is usually a GPIO FD. NULL if NA. 61 | // .twinGPIO - The associted GPIO number for this item. NO_GPIO_ASSOCIATED_WITH_TWIN if NA 62 | // .twinType - The data type for this item, TYPE_BOOL, TYPE_STRING, TYPE_INT, or TYPE_FLOAT 63 | // .active_high - true if GPIO item is active high, false if active low. This is used to init the GPIO 64 | twin_t twinArray[] = { 65 | {.twinKey = "userLedRed",.twinVar = &userLedRedIsOn,.twinFd = &userLedRedFd,.twinGPIO = AVNET_MT3620_SK_USER_LED_RED,.twinType = TYPE_BOOL,.active_high = false}, 66 | {.twinKey = "userLedGreen",.twinVar = &userLedGreenIsOn,.twinFd = &userLedGreenFd,.twinGPIO = AVNET_MT3620_SK_USER_LED_GREEN,.twinType = TYPE_BOOL,.active_high = false}, 67 | {.twinKey = "userLedBlue",.twinVar = &userLedBlueIsOn,.twinFd = &userLedBlueFd,.twinGPIO = AVNET_MT3620_SK_USER_LED_BLUE,.twinType = TYPE_BOOL,.active_high = false}, 68 | {.twinKey = "appLed",.twinVar = &appLedIsOn,.twinFd = &appLedFd,.twinGPIO = AVNET_MT3620_SK_APP_STATUS_LED_YELLOW,.twinType = TYPE_BOOL,.active_high = false}, 69 | {.twinKey = "wifiLed",.twinVar = &wifiLedIsOn,.twinFd = &wifiLedFd,.twinGPIO = AVNET_MT3620_SK_WLAN_STATUS_LED_YELLOW,.twinType = TYPE_BOOL,.active_high = false}, 70 | {.twinKey = "clickBoardRelay1",.twinVar = &clkBoardRelay1IsOn,.twinFd = &clickSocket1Relay1Fd,.twinGPIO = AVNET_MT3620_SK_GPIO34,.twinType = TYPE_BOOL,.active_high = true}, 71 | {.twinKey = "clickBoardRelay2",.twinVar = &clkBoardRelay2IsOn,.twinFd = &clickSocket1Relay2Fd,.twinGPIO = AVNET_MT3620_SK_GPIO0,.twinType = TYPE_BOOL,.active_high = true}}; 72 | 73 | // Calculate how many twin_t items are in the array. We use this to iterate through the structure. 74 | int twinArraySize = sizeof(twinArray) / sizeof(twin_t); 75 | 76 | /// 77 | /// check to see if any of the device twin properties have been updated. If so, send up the current data. 78 | /// 79 | void checkAndUpdateDeviceTwin(char* property, void* value, data_type_t type, bool ioTCentralFormat) 80 | { 81 | int nJsonLength = -1; 82 | 83 | char *pjsonBuffer = (char *)malloc(JSON_BUFFER_SIZE); 84 | if (pjsonBuffer == NULL) { 85 | Log_Debug("ERROR: not enough memory to report device twin changes."); 86 | } 87 | 88 | if (property != NULL) { 89 | 90 | // report current device twin data as reported properties to IoTHub 91 | 92 | switch (type) { 93 | case TYPE_BOOL: 94 | #ifdef IOT_CENTRAL_APPLICATION 95 | if (ioTCentralFormat) { 96 | nJsonLength = snprintf(pjsonBuffer, JSON_BUFFER_SIZE, cstrDeviceTwinJsonBoolIOTC, property, *(bool*)value ? "true" : "false", desiredVersion); 97 | } 98 | else 99 | #endif 100 | nJsonLength = snprintf(pjsonBuffer, JSON_BUFFER_SIZE, cstrDeviceTwinJsonBool, property, *(bool*)value ? "true" : "false", desiredVersion); 101 | 102 | break; 103 | case TYPE_FLOAT: 104 | #ifdef IOT_CENTRAL_APPLICATION 105 | if (ioTCentralFormat) { 106 | nJsonLength = snprintf(pjsonBuffer, JSON_BUFFER_SIZE, cstrDeviceTwinJsonFloatIOTC, property, *(float*)value, desiredVersion); 107 | } 108 | else 109 | #endif 110 | nJsonLength = snprintf(pjsonBuffer, JSON_BUFFER_SIZE, cstrDeviceTwinJsonFloat, property, *(float*)value, desiredVersion); 111 | break; 112 | case TYPE_INT: 113 | #ifdef IOT_CENTRAL_APPLICATION 114 | if (ioTCentralFormat) { 115 | nJsonLength = snprintf(pjsonBuffer, JSON_BUFFER_SIZE, cstrDeviceTwinJsonIntegerIOTC, property, *(int*)value, desiredVersion); 116 | } 117 | else 118 | #endif 119 | nJsonLength = snprintf(pjsonBuffer, JSON_BUFFER_SIZE, cstrDeviceTwinJsonInteger, property, *(int*)value, desiredVersion); 120 | break; 121 | case TYPE_STRING: 122 | #ifdef IOT_CENTRAL_APPLICATION 123 | if (ioTCentralFormat) { 124 | nJsonLength = snprintf(pjsonBuffer, JSON_BUFFER_SIZE, cstrDeviceTwinJsonStringIOTC, property, (char*)value, desiredVersion); 125 | } 126 | else 127 | #endif 128 | nJsonLength = snprintf(pjsonBuffer, JSON_BUFFER_SIZE, cstrDeviceTwinJsonString, property, (char*)value, desiredVersion); 129 | break; 130 | } 131 | 132 | if (nJsonLength > 0) { 133 | Log_Debug("[MCU] Updating device twin: %s\n", pjsonBuffer); 134 | AzureIoT_TwinReportStateJson(pjsonBuffer, (size_t)nJsonLength); 135 | } 136 | free(pjsonBuffer); 137 | } 138 | } 139 | 140 | /// 141 | /// Parses received desired property changes. 142 | /// 143 | ///Address of desired properties JSON_Object 144 | void deviceTwinChangedHandler(JSON_Object * desiredProperties) 145 | { 146 | int result = 0; 147 | 148 | // Pull the twin version out of the message. We use this value when we echo the new setting back to IoT Connect. 149 | if (json_object_has_value(desiredProperties, "$version") != 0) 150 | { 151 | desiredVersion = (int)json_object_get_number(desiredProperties, "$version"); 152 | } 153 | 154 | #ifdef IOT_CENTRAL_APPLICATION 155 | 156 | for (int i = 0; i < (sizeof(twinArray) / sizeof(twin_t)); i++) { 157 | 158 | if (json_object_has_value(desiredProperties, twinArray[i].twinKey) != 0) 159 | { 160 | 161 | JSON_Object *currentJSONProperties = json_object_dotget_object(desiredProperties, twinArray[i].twinKey); 162 | 163 | switch (twinArray[i].twinType) { 164 | case TYPE_BOOL: 165 | *(bool*)twinArray[i].twinVar = (bool)json_object_get_boolean(currentJSONProperties, "value"); 166 | result = GPIO_SetValue(*twinArray[i].twinFd, twinArray[i].active_high ? (GPIO_Value)*(bool*)twinArray[i].twinVar : !(GPIO_Value)*(bool*)twinArray[i].twinVar); 167 | 168 | if (result != 0) { 169 | Log_Debug("Fd: %d\n", twinArray[i].twinFd); 170 | Log_Debug("FAILURE: Could not set GPIO_%d, %d output value %d: %s (%d).\n", twinArray[i].twinGPIO, twinArray[i].twinFd, (GPIO_Value)*(bool*)twinArray[i].twinVar, strerror(errno), errno); 171 | terminationRequired = true; 172 | } 173 | Log_Debug("Received device update. New %s is %s\n", twinArray[i].twinKey, *(bool*)twinArray[i].twinVar ? "true" : "false"); 174 | checkAndUpdateDeviceTwin(twinArray[i].twinKey, twinArray[i].twinVar, TYPE_BOOL, true); 175 | break; 176 | case TYPE_FLOAT: 177 | *(float*)twinArray[i].twinVar = (float)json_object_get_number(currentJSONProperties, "value"); 178 | Log_Debug("Received device update. New %s is %0.2f\n", twinArray[i].twinKey, *(float*)twinArray[i].twinVar); 179 | checkAndUpdateDeviceTwin(twinArray[i].twinKey, twinArray[i].twinVar, TYPE_FLOAT, true); 180 | break; 181 | case TYPE_INT: 182 | *(int*)twinArray[i].twinVar = (int)json_object_get_number(currentJSONProperties, "value"); 183 | Log_Debug("Received device update. New %s is %d\n", twinArray[i].twinKey, *(int*)twinArray[i].twinVar); 184 | checkAndUpdateDeviceTwin(twinArray[i].twinKey, twinArray[i].twinVar, TYPE_INT, true); 185 | break; 186 | case TYPE_STRING: 187 | Log_Debug("ERROR: TYPE_STRING case not implemented!"); 188 | break; 189 | } 190 | } 191 | } 192 | #else // !IOT_CENTRAL_APPLICATION 193 | 194 | for (int i = 0; i < (sizeof(twinArray) / sizeof(twin_t)); i++) { 195 | 196 | if (json_object_has_value(desiredProperties, twinArray[i].twinKey) != 0) 197 | { 198 | 199 | switch (twinArray[i].twinType) { 200 | case TYPE_BOOL: 201 | *(bool*)twinArray[i].twinVar = (bool)json_object_get_boolean(desiredProperties, twinArray[i].twinKey); 202 | result = GPIO_SetValue(*twinArray[i].twinFd, twinArray[i].active_high ? (GPIO_Value)*(bool*)twinArray[i].twinVar : !(GPIO_Value)*(bool*)twinArray[i].twinVar); 203 | 204 | if (result != 0) { 205 | Log_Debug("Fd: %d\n", twinArray[i].twinFd); 206 | Log_Debug("FAILURE: Could not set GPIO_%d, %d output value %d: %s (%d).\n", twinArray[i].twinGPIO, twinArray[i].twinFd, (GPIO_Value)*(bool*)twinArray[i].twinVar, strerror(errno), errno); 207 | terminationRequired = true; 208 | } 209 | Log_Debug("Received device update. New %s is %s\n", twinArray[i].twinKey, *(bool*)twinArray[i].twinVar ? "true" : "false"); 210 | checkAndUpdateDeviceTwin(twinArray[i].twinKey, twinArray[i].twinVar, TYPE_BOOL, true); 211 | break; 212 | case TYPE_FLOAT: 213 | *(float*)twinArray[i].twinVar = (float)json_object_get_number(desiredProperties, twinArray[i].twinKey); 214 | Log_Debug("Received device update. New %s is %0.2f\n", twinArray[i].twinKey, *(float*)twinArray[i].twinVar); 215 | checkAndUpdateDeviceTwin(twinArray[i].twinKey, twinArray[i].twinVar, TYPE_FLOAT, true); 216 | break; 217 | case TYPE_INT: 218 | *(int*)twinArray[i].twinVar = (int)json_object_get_number(desiredProperties, twinArray[i].twinKey); 219 | Log_Debug("Received device update. New %s is %d\n", twinArray[i].twinKey, *(int*)twinArray[i].twinVar); 220 | checkAndUpdateDeviceTwin(twinArray[i].twinKey, twinArray[i].twinVar, TYPE_INT, true); 221 | break; 222 | case TYPE_STRING: 223 | Log_Debug("ERROR: TYPE_STRING case not implemented!"); 224 | break; 225 | } 226 | } 227 | } 228 | #endif 229 | 230 | } 231 | -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/epoll_timerfd_utilities.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) Microsoft Corporation. All rights reserved. 2 | Licensed under the MIT License. */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "epoll_timerfd_utilities.h" 10 | 11 | int CreateEpollFd(void) 12 | { 13 | int epollFd = -1; 14 | 15 | epollFd = epoll_create1(0); 16 | if (epollFd == -1) { 17 | Log_Debug("ERROR: Could not create epoll instance: %s (%d).\n", strerror(errno), errno); 18 | return -1; 19 | } 20 | 21 | return epollFd; 22 | } 23 | 24 | int RegisterEventHandlerToEpoll(int epollFd, int eventFd, EventData *persistentEventData, 25 | const uint32_t epollEventMask) 26 | { 27 | persistentEventData->fd = eventFd; 28 | struct epoll_event eventToAddOrModify = {.data.ptr = persistentEventData, 29 | .events = epollEventMask}; 30 | 31 | // Register the eventFd on the epoll instance referred by epollFd 32 | // and register the eventHandler handler for events in epollEventMask. 33 | if (epoll_ctl(epollFd, EPOLL_CTL_ADD, eventFd, &eventToAddOrModify) == -1) { 34 | // If the Add fails, retry with the Modify as the file descriptor has already been 35 | // added to the epoll set after it was removed by the kernel upon its closure. 36 | if (epoll_ctl(epollFd, EPOLL_CTL_MOD, eventFd, &eventToAddOrModify) == -1) { 37 | Log_Debug("ERROR: Could not register event to epoll instance: %s (%d).\n", 38 | strerror(errno), errno); 39 | return -1; 40 | } 41 | } 42 | 43 | return 0; 44 | } 45 | 46 | int UnregisterEventHandlerFromEpoll(int epollFd, int eventFd) 47 | { 48 | int res = 0; 49 | // Unregister the eventFd on the epoll instance referred by epollFd. 50 | if ((res = epoll_ctl(epollFd, EPOLL_CTL_DEL, eventFd, NULL)) == -1) { 51 | if (res == -1 && errno != EBADF) { // Ignore EBADF errors 52 | Log_Debug("ERROR: Could not remove event from epoll instance: %s (%d).\n", 53 | strerror(errno), errno); 54 | return -1; 55 | } 56 | } 57 | 58 | return 0; 59 | } 60 | 61 | int SetTimerFdToPeriod(int timerFd, const struct timespec *period) 62 | { 63 | struct itimerspec newValue = {.it_value = *period, .it_interval = *period}; 64 | 65 | if (timerfd_settime(timerFd, 0, &newValue, NULL) < 0) { 66 | Log_Debug("ERROR: Could not set timerfd period: %s (%d).\n", strerror(errno), errno); 67 | return -1; 68 | } 69 | 70 | return 0; 71 | } 72 | 73 | int SetTimerFdToSingleExpiry(int timerFd, const struct timespec *expiry) 74 | { 75 | struct itimerspec newValue = {.it_value = *expiry, .it_interval = {}}; 76 | 77 | if (timerfd_settime(timerFd, 0, &newValue, NULL) < 0) { 78 | Log_Debug("ERROR: Could not set timerfd interval: %s (%d).\n", strerror(errno), errno); 79 | return -1; 80 | } 81 | 82 | return 0; 83 | } 84 | 85 | int ConsumeTimerFdEvent(int timerFd) 86 | { 87 | uint64_t timerData = 0; 88 | 89 | if (read(timerFd, &timerData, sizeof(timerData)) == -1) { 90 | Log_Debug("ERROR: Could not read timerfd %s (%d).\n", strerror(errno), errno); 91 | return -1; 92 | } 93 | 94 | return 0; 95 | } 96 | 97 | int CreateTimerFdAndAddToEpoll(int epollFd, const struct timespec *period, 98 | EventData *persistentEventData, const uint32_t epollEventMask) 99 | { 100 | // Create the timerfd and arm it by setting the interval to period 101 | int timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); 102 | if (timerFd < 0) { 103 | Log_Debug("ERROR: Could not create timerfd: %s (%d).\n", strerror(errno), errno); 104 | return -1; 105 | } 106 | if (SetTimerFdToPeriod(timerFd, period) != 0) { 107 | int result = close(timerFd); 108 | if (result != 0) { 109 | Log_Debug("ERROR: Could not close timerfd: %s (%d).\n", strerror(errno), errno); 110 | } 111 | return -1; 112 | } 113 | 114 | persistentEventData->fd = timerFd; 115 | if (RegisterEventHandlerToEpoll(epollFd, timerFd, persistentEventData, epollEventMask) != 0) { 116 | return -1; 117 | } 118 | 119 | return timerFd; 120 | } 121 | 122 | int WaitForEventAndCallHandler(int epollFd) 123 | { 124 | struct epoll_event event; 125 | int numEventsOccurred = epoll_wait(epollFd, &event, 1, -1); 126 | 127 | if (numEventsOccurred == -1) { 128 | if (errno == EINTR) { 129 | // interrupted by signal, e.g. due to breakpoint being set; ignore 130 | return 0; 131 | } 132 | Log_Debug("ERROR: Failed waiting on events: %s (%d).\n", strerror(errno), errno); 133 | return -1; 134 | } 135 | 136 | if (numEventsOccurred == 1 && event.data.ptr != NULL) { 137 | EventData *eventData = event.data.ptr; 138 | eventData->eventHandler(eventData); 139 | } 140 | 141 | return 0; 142 | } 143 | 144 | void CloseFdAndPrintError(int fd, const char *fdName) 145 | { 146 | if (fd >= 0) { 147 | int result = close(fd); 148 | if (result != 0) { 149 | Log_Debug("ERROR: Could not close fd %s: %s (%d).\n", fdName, strerror(errno), errno); 150 | } 151 | } 152 | } -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/epoll_timerfd_utilities.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) Microsoft Corporation. All rights reserved. 2 | Licensed under the MIT License. */ 3 | 4 | #pragma once 5 | #include 6 | #include 7 | #include 8 | 9 | /// Forward declaration of the data type passed to the handlers. 10 | struct EventData; 11 | 12 | /// 13 | /// Function signature for event handlers. 14 | /// 15 | /// The provided event data 16 | typedef void (*EventHandler)(struct EventData *eventData); 17 | 18 | /// 19 | /// Contains context data for epoll events. 20 | /// When an event is registered with RegisterEventHandlerToEpoll, supply 21 | /// a pointer to an instance of this struct. The pointer must remain valid 22 | /// for as long as the event is active. 23 | /// 24 | /// 25 | typedef struct EventData { 26 | /// 27 | /// Function which is called when the event occurs. 28 | /// 29 | EventHandler eventHandler; 30 | /// 31 | /// The file descriptor that generated the event. 32 | /// 33 | int fd; 34 | } EventData; 35 | 36 | /// 37 | /// Creates an epoll instance. 38 | /// 39 | /// A valid epoll file descriptor on success, or -1 on failure 40 | int CreateEpollFd(void); 41 | 42 | /// 43 | /// Registers an event with the epoll instance. If the event was previously added, that 44 | /// registration will be modified to match the new mask. 45 | /// 46 | /// Epoll file descriptor 47 | /// File descriptor generating events for the epoll 48 | /// Persistent event data structure. This must stay in memory 49 | /// until the handler is removed from the epoll. 50 | /// Bit mask for the epoll event type 51 | /// 0 on success, or -1 on failure 52 | int RegisterEventHandlerToEpoll(int epollFd, int eventFd, EventData *persistentEventData, 53 | const uint32_t epollEventMask); 54 | 55 | /// 56 | /// Unregisters an event with the epoll instance. 57 | /// 58 | /// Epoll file descriptor 59 | /// File descriptor generating events for the epoll 60 | /// 0 on success, or -1 on failure 61 | int UnregisterEventHandlerFromEpoll(int epollFd, int eventFd); 62 | 63 | /// 64 | /// Sets the period of a timer. 65 | /// 66 | /// Timer file descriptor 67 | /// The new period 68 | /// 0 on success, or -1 on failure 69 | int SetTimerFdToPeriod(int timerFd, const struct timespec *period); 70 | 71 | /// 72 | /// Sets a timer to fire once only, after a duration specified in milliseconds. 73 | /// 74 | /// Timer file descriptor 75 | /// The time elapsed before it expires once 76 | /// 0 on success, or -1 on failure 77 | int SetTimerFdToSingleExpiry(int timerFd, const struct timespec *expiry); 78 | 79 | /// 80 | /// Consumes an event by reading from the timer file descriptor. 81 | /// If the event is not consumed, then it will immediately recur. 82 | /// 83 | /// Timer file descriptor 84 | /// 0 on success, or -1 on failure 85 | int ConsumeTimerFdEvent(int timerFd); 86 | 87 | /// 88 | /// Creates a timerfd and adds it to an epoll instance. 89 | /// 90 | /// Epoll file descriptor 91 | /// The timer period 92 | /// Persistent event data structure. This must stay in memory 93 | /// until the handler is removed from the epoll. 94 | /// Bit mask for the epoll event type 95 | /// A valid timerfd file descriptor on success, or -1 on failure 96 | int CreateTimerFdAndAddToEpoll(int epollFd, const struct timespec *period, 97 | EventData *persistentEventData, const uint32_t epollEventMask); 98 | 99 | /// 100 | /// Waits for an event on an epoll instance and triggers the handler. 101 | /// 102 | /// 103 | /// Epoll file descriptor which was created with . 104 | /// 105 | /// 0 on success, or -1 on failure 106 | int WaitForEventAndCallHandler(int epollFd); 107 | 108 | /// 109 | /// Closes a file descriptor and prints an error on failure. 110 | /// 111 | /// File descriptor to close 112 | /// File descriptor name to use in error message 113 | void CloseFdAndPrintError(int fd, const char *name); -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/i2c.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Some of the code in this file was copied from ST Micro. Below is their required information. 3 | * 4 | * @attention 5 | * 6 | *

© COPYRIGHT(c) 2018 STMicroelectronics

7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of STMicroelectronics nor the names of its 17 | * contributors may be used to endorse or promote products derived from 18 | * this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | * POSSIBILITY OF SUCH DAMAGE. 30 | * 31 | */ 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | // applibs_versions.h defines the API struct versions to use for applibs APIs. 41 | #include "applibs_versions.h" 42 | 43 | #include 44 | #include 45 | 46 | #include "hw/avnet_mt3620_sk.h" 47 | 48 | #include "deviceTwin.h" 49 | #include "azure_iot_utilities.h" 50 | #include "build_options.h" 51 | #include "i2c.h" 52 | #include "lsm6dso_reg.h" 53 | #include "lps22hh_reg.h" 54 | 55 | /* Private variables ---------------------------------------------------------*/ 56 | static axis3bit16_t data_raw_acceleration; 57 | static axis3bit16_t data_raw_angular_rate; 58 | static axis3bit16_t raw_angular_rate_calibration; 59 | static axis1bit32_t data_raw_pressure; 60 | static axis1bit16_t data_raw_temperature; 61 | static float acceleration_mg[3]; 62 | static float angular_rate_dps[3]; 63 | static float lsm6dsoTemperature_degC; 64 | static float pressure_hPa; 65 | static float lps22hhTemperature_degC; 66 | 67 | static uint8_t whoamI, rst; 68 | int accelTimerFd; 69 | const uint8_t lsm6dsOAddress = LSM6DSO_ADDRESS; // Addr = 0x6A 70 | lsm6dso_ctx_t dev_ctx; 71 | lps22hh_ctx_t pressure_ctx; 72 | bool lps22hhDetected; 73 | 74 | 75 | //Extern variables 76 | int i2cFd = -1; 77 | extern int epollFd; 78 | extern volatile sig_atomic_t terminationRequired; 79 | 80 | //Private functions 81 | 82 | // Routines to read/write to the LSM6DSO device 83 | static int32_t platform_write(int *fD, uint8_t reg, uint8_t *bufp, uint16_t len); 84 | static int32_t platform_read(int *fD, uint8_t reg, uint8_t *bufp, uint16_t len); 85 | 86 | // Routines to read/write to the LPS22HH device connected to the LSM6DSO sensor hub 87 | static int32_t lsm6dso_write_lps22hh_cx(void* ctx, uint8_t reg, uint8_t* data, uint16_t len); 88 | static int32_t lsm6dso_read_lps22hh_cx(void* ctx, uint8_t reg, uint8_t* data, uint16_t len); 89 | 90 | /// 91 | /// Sleep for delayTime ms 92 | /// 93 | void HAL_Delay(int delayTime) { 94 | struct timespec ts; 95 | ts.tv_sec = 0; 96 | ts.tv_nsec = delayTime * 10000; 97 | nanosleep(&ts, NULL); 98 | } 99 | 100 | /// 101 | /// Print latest data from on-board sensors. 102 | /// 103 | void AccelTimerEventHandler(EventData *eventData) 104 | { 105 | uint8_t reg; 106 | lps22hh_reg_t lps22hhReg; 107 | 108 | #if (defined(IOT_CENTRAL_APPLICATION) || defined(IOT_HUB_APPLICATION)) 109 | static bool firstPass = true; 110 | #endif 111 | // Consume the event. If we don't do this we'll come right back 112 | // to process the same event again 113 | if (ConsumeTimerFdEvent(accelTimerFd) != 0) { 114 | terminationRequired = true; 115 | return; 116 | } 117 | 118 | // Read the sensors on the lsm6dso device 119 | 120 | //Read output only if new xl value is available 121 | lsm6dso_xl_flag_data_ready_get(&dev_ctx, ®); 122 | if (reg) 123 | { 124 | // Read acceleration field data 125 | memset(data_raw_acceleration.u8bit, 0x00, 3 * sizeof(int16_t)); 126 | lsm6dso_acceleration_raw_get(&dev_ctx, data_raw_acceleration.u8bit); 127 | 128 | acceleration_mg[0] = lsm6dso_from_fs4_to_mg(data_raw_acceleration.i16bit[0]); 129 | acceleration_mg[1] = lsm6dso_from_fs4_to_mg(data_raw_acceleration.i16bit[1]); 130 | acceleration_mg[2] = lsm6dso_from_fs4_to_mg(data_raw_acceleration.i16bit[2]); 131 | 132 | Log_Debug("\nLSM6DSO: Acceleration [mg] : %.4lf, %.4lf, %.4lf\n", 133 | acceleration_mg[0], acceleration_mg[1], acceleration_mg[2]); 134 | } 135 | 136 | lsm6dso_gy_flag_data_ready_get(&dev_ctx, ®); 137 | if (reg) 138 | { 139 | // Read angular rate field data 140 | memset(data_raw_angular_rate.u8bit, 0x00, 3 * sizeof(int16_t)); 141 | lsm6dso_angular_rate_raw_get(&dev_ctx, data_raw_angular_rate.u8bit); 142 | 143 | // Before we store the mdps values subtract the calibration data we captured at startup. 144 | angular_rate_dps[0] = (lsm6dso_from_fs2000_to_mdps(data_raw_angular_rate.i16bit[0] - raw_angular_rate_calibration.i16bit[0])) / 1000.0; 145 | angular_rate_dps[1] = (lsm6dso_from_fs2000_to_mdps(data_raw_angular_rate.i16bit[1] - raw_angular_rate_calibration.i16bit[1])) / 1000.0; 146 | angular_rate_dps[2] = (lsm6dso_from_fs2000_to_mdps(data_raw_angular_rate.i16bit[2] - raw_angular_rate_calibration.i16bit[2])) / 1000.0; 147 | 148 | Log_Debug("LSM6DSO: Angular rate [dps] : %4.2f, %4.2f, %4.2f\r\n", 149 | angular_rate_dps[0], angular_rate_dps[1], angular_rate_dps[2]); 150 | 151 | } 152 | 153 | lsm6dso_temp_flag_data_ready_get(&dev_ctx, ®); 154 | if (reg) 155 | { 156 | // Read temperature data 157 | memset(data_raw_temperature.u8bit, 0x00, sizeof(int16_t)); 158 | lsm6dso_temperature_raw_get(&dev_ctx, data_raw_temperature.u8bit); 159 | lsm6dsoTemperature_degC = lsm6dso_from_lsb_to_celsius(data_raw_temperature.i16bit); 160 | 161 | Log_Debug("LSM6DSO: Temperature [degC]: %.2f\r\n", lsm6dsoTemperature_degC); 162 | } 163 | 164 | // Read the lps22hh sensor on the lsm6dso device 165 | 166 | // Initialize the data structures to 0s. 167 | memset(data_raw_pressure.u8bit, 0x00, sizeof(int32_t)); 168 | memset(data_raw_temperature.u8bit, 0x00, sizeof(int16_t)); 169 | 170 | if (lps22hhDetected) { 171 | lps22hh_read_reg(&pressure_ctx, LPS22HH_STATUS, (uint8_t *)&lps22hhReg, 1); 172 | 173 | //Read output only if new value is available 174 | 175 | if ((lps22hhReg.status.p_da == 1) && (lps22hhReg.status.t_da == 1)) 176 | { 177 | lps22hh_pressure_raw_get(&pressure_ctx, data_raw_pressure.u8bit); 178 | 179 | pressure_hPa = lps22hh_from_lsb_to_hpa(data_raw_pressure.i32bit); 180 | 181 | lps22hh_temperature_raw_get(&pressure_ctx, data_raw_temperature.u8bit); 182 | lps22hhTemperature_degC = lps22hh_from_lsb_to_celsius(data_raw_temperature.i16bit); 183 | 184 | Log_Debug("LPS22HH: Pressure [hPa] : %.2f\r\n", pressure_hPa); 185 | Log_Debug("LPS22HH: Temperature [degC]: %.2f\r\n", lps22hhTemperature_degC); 186 | } 187 | } 188 | // LPS22HH was not detected 189 | else { 190 | 191 | Log_Debug("LPS22HH: Pressure [hPa] : Not read!\r\n"); 192 | Log_Debug("LPS22HH: Temperature [degC]: Not read!\r\n"); 193 | } 194 | 195 | 196 | #if (defined(IOT_CENTRAL_APPLICATION) || defined(IOT_HUB_APPLICATION)) 197 | 198 | // We've seen that the first read of the Accelerometer data is garbage. If this is the first pass 199 | // reading data, don't report it to Azure. Since we're graphing data in Azure, this data point 200 | // will skew the data. 201 | if (!firstPass) { 202 | 203 | // Allocate memory for a telemetry message to Azure 204 | char *pjsonBuffer = (char *)malloc(JSON_BUFFER_SIZE); 205 | if (pjsonBuffer == NULL) { 206 | Log_Debug("ERROR: not enough memory to send telemetry"); 207 | } 208 | 209 | // construct the telemetry message 210 | snprintf(pjsonBuffer, JSON_BUFFER_SIZE, "{\"gX\":\"%.4lf\", \"gY\":\"%.4lf\", \"gZ\":\"%.4lf\", \"pressure\": \"%.2f\", \"aX\": \"%4.2f\", \"aY\": \"%4.2f\", \"aZ\": \"%4.2f\"}", 211 | acceleration_mg[0], acceleration_mg[1], acceleration_mg[2], pressure_hPa, angular_rate_dps[0], angular_rate_dps[1], angular_rate_dps[2]); 212 | 213 | Log_Debug("\n[Info] Sending telemetry: %s\n", pjsonBuffer); 214 | AzureIoT_SendMessage(pjsonBuffer); 215 | free(pjsonBuffer); 216 | 217 | } 218 | 219 | firstPass = false; 220 | 221 | #endif 222 | 223 | } 224 | 225 | /// 226 | /// Initializes the I2C interface. 227 | /// 228 | /// 0 on success, or -1 on failure 229 | int initI2c(void) { 230 | 231 | // Begin MT3620 I2C init 232 | 233 | i2cFd = I2CMaster_Open(AVNET_MT3620_SK_ISU2_I2C); 234 | if (i2cFd < 0) { 235 | Log_Debug("ERROR: I2CMaster_Open: errno=%d (%s)\n", errno, strerror(errno)); 236 | return -1; 237 | } 238 | 239 | int result = I2CMaster_SetBusSpeed(i2cFd, I2C_BUS_SPEED_STANDARD); 240 | if (result != 0) { 241 | Log_Debug("ERROR: I2CMaster_SetBusSpeed: errno=%d (%s)\n", errno, strerror(errno)); 242 | return -1; 243 | } 244 | 245 | result = I2CMaster_SetTimeout(i2cFd, 100); 246 | if (result != 0) { 247 | Log_Debug("ERROR: I2CMaster_SetTimeout: errno=%d (%s)\n", errno, strerror(errno)); 248 | return -1; 249 | } 250 | 251 | // Start lsm6dso specific init 252 | 253 | // Initialize lsm6dso mems driver interface 254 | dev_ctx.write_reg = platform_write; 255 | dev_ctx.read_reg = platform_read; 256 | dev_ctx.handle = &i2cFd; 257 | 258 | // Check device ID 259 | lsm6dso_device_id_get(&dev_ctx, &whoamI); 260 | if (whoamI != LSM6DSO_ID) { 261 | Log_Debug("LSM6DSO not found!\n"); 262 | return -1; 263 | } 264 | else { 265 | Log_Debug("LSM6DSO Found!\n"); 266 | } 267 | 268 | // Restore default configuration 269 | lsm6dso_reset_set(&dev_ctx, PROPERTY_ENABLE); 270 | do { 271 | lsm6dso_reset_get(&dev_ctx, &rst); 272 | } while (rst); 273 | 274 | // Disable I3C interface 275 | lsm6dso_i3c_disable_set(&dev_ctx, LSM6DSO_I3C_DISABLE); 276 | 277 | // Enable Block Data Update 278 | lsm6dso_block_data_update_set(&dev_ctx, PROPERTY_ENABLE); 279 | 280 | // Set Output Data Rate 281 | lsm6dso_xl_data_rate_set(&dev_ctx, LSM6DSO_XL_ODR_12Hz5); 282 | lsm6dso_gy_data_rate_set(&dev_ctx, LSM6DSO_GY_ODR_12Hz5); 283 | 284 | // Set full scale 285 | lsm6dso_xl_full_scale_set(&dev_ctx, LSM6DSO_4g); 286 | lsm6dso_gy_full_scale_set(&dev_ctx, LSM6DSO_2000dps); 287 | 288 | // Configure filtering chain(No aux interface) 289 | // Accelerometer - LPF1 + LPF2 path 290 | lsm6dso_xl_hp_path_on_out_set(&dev_ctx, LSM6DSO_LP_ODR_DIV_100); 291 | lsm6dso_xl_filter_lp2_set(&dev_ctx, PROPERTY_ENABLE); 292 | 293 | // lps22hh specific init 294 | 295 | // Default the flag to false. If we fail to communicate with the LPS22HH device, this flag 296 | // will cause application execution to skip over LPS22HH specific code. 297 | lps22hhDetected = false; 298 | 299 | // Initialize lps22hh mems driver interface 300 | pressure_ctx.read_reg = lsm6dso_read_lps22hh_cx; 301 | pressure_ctx.write_reg = lsm6dso_write_lps22hh_cx; 302 | pressure_ctx.handle = &i2cFd; 303 | 304 | int failCount = 10; 305 | 306 | while (!lps22hhDetected) { 307 | 308 | // Enable pull up on master I2C interface. 309 | lsm6dso_sh_pin_mode_set(&dev_ctx, LSM6DSO_INTERNAL_PULL_UP); 310 | 311 | // Check if LPS22HH is connected to Sensor Hub 312 | lps22hh_device_id_get(&pressure_ctx, &whoamI); 313 | if (whoamI != LPS22HH_ID) { 314 | Log_Debug("LPS22HH not found!\n"); 315 | } 316 | else { 317 | lps22hhDetected = true; 318 | Log_Debug("LPS22HH Found!\n"); 319 | } 320 | 321 | // Restore the default configuration 322 | lps22hh_reset_set(&pressure_ctx, PROPERTY_ENABLE); 323 | do { 324 | lps22hh_reset_get(&pressure_ctx, &rst); 325 | } while (rst); 326 | 327 | // Enable Block Data Update 328 | lps22hh_block_data_update_set(&pressure_ctx, PROPERTY_ENABLE); 329 | 330 | //Set Output Data Rate 331 | lps22hh_data_rate_set(&pressure_ctx, LPS22HH_10_Hz_LOW_NOISE); 332 | 333 | // If we failed to detect the lps22hh device, then pause before trying again. 334 | if (!lps22hhDetected) { 335 | HAL_Delay(100); 336 | } 337 | 338 | if (failCount-- == 0) { 339 | bool lps22hhDetected = false; 340 | Log_Debug("Failed to read LPS22HH device ID, disabling all access to LPS22HH device!\n"); 341 | Log_Debug("Usually a power cycle will correct this issue\n"); 342 | break; 343 | } 344 | } 345 | 346 | // Read the raw angular rate data from the device to use as offsets. We're making the assumption that the device 347 | // is stationary. 348 | 349 | uint8_t reg; 350 | 351 | Log_Debug("LSM6DSO: Calibrating angular rate . . .\n"); 352 | Log_Debug("LSM6DSO: Please make sure the device is stationary.\n"); 353 | 354 | do { 355 | 356 | // Delay and read the device until we have data! 357 | do { 358 | // Read the calibration values 359 | HAL_Delay(5000); 360 | lsm6dso_gy_flag_data_ready_get(&dev_ctx, ®); 361 | } while (!reg); 362 | 363 | if (reg) 364 | { 365 | // Read angular rate field data to use for calibration offsets 366 | memset(data_raw_angular_rate.u8bit, 0x00, 3 * sizeof(int16_t)); 367 | lsm6dso_angular_rate_raw_get(&dev_ctx, raw_angular_rate_calibration.u8bit); 368 | } 369 | 370 | // Delay and read the device until we have data! 371 | do { 372 | // Read the calibration values 373 | HAL_Delay(5000); 374 | lsm6dso_gy_flag_data_ready_get(&dev_ctx, ®); 375 | } while (!reg); 376 | 377 | // Read the angular data rate again and verify that after applying the calibration, we have 0 angular rate in all directions 378 | if (reg) 379 | { 380 | 381 | // Read angular rate field data 382 | memset(data_raw_angular_rate.u8bit, 0x00, 3 * sizeof(int16_t)); 383 | lsm6dso_angular_rate_raw_get(&dev_ctx, data_raw_angular_rate.u8bit); 384 | 385 | // Before we store the mdps values subtract the calibration data we captured at startup. 386 | angular_rate_dps[0] = lsm6dso_from_fs2000_to_mdps(data_raw_angular_rate.i16bit[0] - raw_angular_rate_calibration.i16bit[0]); 387 | angular_rate_dps[1] = lsm6dso_from_fs2000_to_mdps(data_raw_angular_rate.i16bit[1] - raw_angular_rate_calibration.i16bit[1]); 388 | angular_rate_dps[2] = lsm6dso_from_fs2000_to_mdps(data_raw_angular_rate.i16bit[2] - raw_angular_rate_calibration.i16bit[2]); 389 | 390 | } 391 | 392 | // If the angular values after applying the offset are not all 0.0s, then do it again! 393 | } while ((angular_rate_dps[0] != 0.0) || (angular_rate_dps[1] != 0.0) || (angular_rate_dps[2] != 0.0)); 394 | 395 | Log_Debug("LSM6DSO: Calibrating angular rate complete!\n"); 396 | 397 | // Init the epoll interface to periodically run the AccelTimerEventHandler routine where we read the sensors 398 | 399 | // Define the period in the build_options.h file 400 | struct timespec accelReadPeriod = { .tv_sec = ACCEL_READ_PERIOD_SECONDS,.tv_nsec = ACCEL_READ_PERIOD_NANO_SECONDS }; 401 | // event handler data structures. Only the event handler field needs to be populated. 402 | static EventData accelEventData = { .eventHandler = &AccelTimerEventHandler }; 403 | accelTimerFd = -1; 404 | accelTimerFd = CreateTimerFdAndAddToEpoll(epollFd, &accelReadPeriod, &accelEventData, EPOLLIN); 405 | if (accelTimerFd < 0) { 406 | return -1; 407 | } 408 | 409 | return 0; 410 | } 411 | 412 | /// 413 | /// Closes the I2C interface File Descriptors. 414 | /// 415 | void closeI2c(void) { 416 | 417 | CloseFdAndPrintError(i2cFd, "i2c"); 418 | CloseFdAndPrintError(accelTimerFd, "accelTimer"); 419 | } 420 | 421 | /// 422 | /// Writes data to the lsm6dso i2c device 423 | /// 424 | /// 0 425 | 426 | static int32_t platform_write(int *fD, uint8_t reg, uint8_t *bufp, 427 | uint16_t len) 428 | { 429 | 430 | #ifdef ENABLE_READ_WRITE_DEBUG 431 | Log_Debug("platform_write()\n"); 432 | Log_Debug("reg: %0x\n", reg); 433 | Log_Debug("len: %0x\n", len); 434 | Log_Debug("bufp contents: "); 435 | for (int i = 0; i < len; i++) { 436 | 437 | Log_Debug("%0x: ", bufp[i]); 438 | } 439 | Log_Debug("\n"); 440 | #endif 441 | 442 | // Construct a new command buffer that contains the register to write to, then the data to write 443 | uint8_t cmdBuffer[len + 1]; 444 | cmdBuffer[0] = reg; 445 | for (int i = 0; i < len; i++) { 446 | cmdBuffer[i + 1] = bufp[i]; 447 | } 448 | 449 | #ifdef ENABLE_READ_WRITE_DEBUG 450 | Log_Debug("cmdBuffer contents: "); 451 | for (int i = 0; i < len + 1; i++) { 452 | 453 | Log_Debug("%0x: ", cmdBuffer[i]); 454 | } 455 | Log_Debug("\n"); 456 | #endif 457 | 458 | // Write the data to the device 459 | int32_t retVal = I2CMaster_Write(*fD, lsm6dsOAddress, cmdBuffer, (size_t)len + 1); 460 | if (retVal < 0) { 461 | Log_Debug("ERROR: platform_write: errno=%d (%s)\n", errno, strerror(errno)); 462 | return -1; 463 | } 464 | #ifdef ENABLE_READ_WRITE_DEBUG 465 | Log_Debug("Wrote %d bytes to device.\n\n", retVal); 466 | #endif 467 | return 0; 468 | } 469 | 470 | /// 471 | /// Reads generic device register from the i2c interface 472 | /// 473 | /// 0 474 | 475 | /* 476 | * @brief Read generic device register (platform dependent) 477 | * 478 | * @param handle customizable argument. In this examples is used in 479 | * order to select the correct sensor bus handler. 480 | * @param reg register to read 481 | * @param bufp pointer to buffer that store the data read 482 | * @param len number of consecutive register to read 483 | * 484 | */ 485 | static int32_t platform_read(int *fD, uint8_t reg, uint8_t *bufp, 486 | uint16_t len) 487 | { 488 | 489 | #ifdef ENABLE_READ_WRITE_DEBUG 490 | Log_Debug("platform_read()\n"); 491 | Log_Debug("reg: %0x\n", reg); 492 | Log_Debug("len: %d\n", len); 493 | ; 494 | #endif 495 | 496 | // Set the register address to read 497 | int32_t retVal = I2CMaster_Write(i2cFd, lsm6dsOAddress, ®, 1); 498 | if (retVal < 0) { 499 | Log_Debug("ERROR: platform_read(write step): errno=%d (%s)\n", errno, strerror(errno)); 500 | return -1; 501 | } 502 | 503 | // Read the data into the provided buffer 504 | retVal = I2CMaster_Read(i2cFd, lsm6dsOAddress, bufp, len); 505 | if (retVal < 0) { 506 | Log_Debug("ERROR: platform_read(read step): errno=%d (%s)\n", errno, strerror(errno)); 507 | return -1; 508 | } 509 | 510 | #ifdef ENABLE_READ_WRITE_DEBUG 511 | Log_Debug("Read returned: "); 512 | for (int i = 0; i < len; i++) { 513 | Log_Debug("%0x: ", bufp[i]); 514 | } 515 | Log_Debug("\n\n"); 516 | #endif 517 | 518 | return 0; 519 | } 520 | /* 521 | * @brief Write lsm2mdl device register (used by configuration functions) 522 | * 523 | * @param handle customizable argument. In this examples is used in 524 | * order to select the correct sensor bus handler. 525 | * @param reg register to write 526 | * @param bufp pointer to data to write in register reg 527 | * @param len number of consecutive register to write 528 | * 529 | */ 530 | static int32_t lsm6dso_write_lps22hh_cx(void* ctx, uint8_t reg, uint8_t* data, 531 | uint16_t len) 532 | { 533 | axis3bit16_t data_raw_acceleration; 534 | int32_t ret; 535 | uint8_t drdy; 536 | lsm6dso_status_master_t master_status; 537 | lsm6dso_sh_cfg_write_t sh_cfg_write; 538 | 539 | // Configure Sensor Hub to write to the LPS22HH, and send the write data 540 | sh_cfg_write.slv0_add = (LPS22HH_I2C_ADD_L & 0xFEU) >> 1; // 7bit I2C address 541 | sh_cfg_write.slv0_subadd = reg, 542 | sh_cfg_write.slv0_data = *data, 543 | ret = lsm6dso_sh_cfg_write(&dev_ctx, &sh_cfg_write); 544 | 545 | /* Disable accelerometer. */ 546 | lsm6dso_xl_data_rate_set(&dev_ctx, LSM6DSO_XL_ODR_OFF); 547 | 548 | /* Enable I2C Master. */ 549 | lsm6dso_sh_master_set(&dev_ctx, PROPERTY_ENABLE); 550 | 551 | /* Enable accelerometer to trigger Sensor Hub operation. */ 552 | lsm6dso_xl_data_rate_set(&dev_ctx, LSM6DSO_XL_ODR_104Hz); 553 | 554 | /* Wait Sensor Hub operation flag set. */ 555 | lsm6dso_acceleration_raw_get(&dev_ctx, data_raw_acceleration.u8bit); 556 | do 557 | { 558 | HAL_Delay(20); 559 | lsm6dso_xl_flag_data_ready_get(&dev_ctx, &drdy); 560 | } while (!drdy); 561 | 562 | do 563 | { 564 | HAL_Delay(20); 565 | lsm6dso_sh_status_get(&dev_ctx, &master_status); 566 | } while (!master_status.sens_hub_endop); 567 | 568 | /* Disable I2C master and XL (trigger). */ 569 | lsm6dso_sh_master_set(&dev_ctx, PROPERTY_DISABLE); 570 | lsm6dso_xl_data_rate_set(&dev_ctx, LSM6DSO_XL_ODR_OFF); 571 | 572 | return ret; 573 | } 574 | 575 | /* 576 | * @brief Read lsm2mdl device register (used by configuration functions) 577 | * 578 | * @param handle customizable argument. In this examples is used in 579 | * order to select the correct sensor bus handler. 580 | * @param reg register to read 581 | * @param bufp pointer to buffer that store the data read 582 | * @param len number of consecutive register to read 583 | * 584 | */ 585 | static int32_t lsm6dso_read_lps22hh_cx(void* ctx, uint8_t reg, uint8_t* data, uint16_t len) 586 | { 587 | lsm6dso_sh_cfg_read_t sh_cfg_read; 588 | uint8_t buf_raw[6]; 589 | int32_t ret; 590 | uint8_t drdy; 591 | lsm6dso_status_master_t master_status; 592 | 593 | /* Disable accelerometer. */ 594 | lsm6dso_xl_data_rate_set(&dev_ctx, LSM6DSO_XL_ODR_OFF); 595 | 596 | /* Configure Sensor Hub to read LPS22HH. */ 597 | sh_cfg_read.slv_add = (LPS22HH_I2C_ADD_L & 0xFEU) >> 1; /* 7bit I2C address */ 598 | sh_cfg_read.slv_subadd = reg; 599 | sh_cfg_read.slv_len = (uint8_t)len; 600 | 601 | // Call the command to read the data from the sensor hub. 602 | // This data will be read from the device connected to the 603 | // sensor hub, and saved into a register for us to read. 604 | ret = lsm6dso_sh_slv0_cfg_read(&dev_ctx, &sh_cfg_read); 605 | 606 | // Using slave 0 only 607 | lsm6dso_sh_slave_connected_set(&dev_ctx, LSM6DSO_SLV_0); 608 | 609 | /* Enable I2C Master */ 610 | lsm6dso_sh_master_set(&dev_ctx, PROPERTY_ENABLE); 611 | 612 | /* Enable accelerometer to trigger Sensor Hub operation. */ 613 | lsm6dso_xl_data_rate_set(&dev_ctx, LSM6DSO_XL_ODR_104Hz); 614 | 615 | /* Wait Sensor Hub operation flag set. */ 616 | lsm6dso_acceleration_raw_get(&dev_ctx, buf_raw); 617 | do { 618 | HAL_Delay(20); 619 | lsm6dso_xl_flag_data_ready_get(&dev_ctx, &drdy); 620 | } while (!drdy); 621 | 622 | do { 623 | HAL_Delay(20); 624 | lsm6dso_sh_status_get(&dev_ctx, &master_status); 625 | } while (!master_status.sens_hub_endop); 626 | 627 | /* Disable I2C master and XL(trigger). */ 628 | lsm6dso_sh_master_set(&dev_ctx, PROPERTY_DISABLE); 629 | lsm6dso_xl_data_rate_set(&dev_ctx, LSM6DSO_XL_ODR_OFF); 630 | 631 | // Read the data from the device 632 | lsm6dso_sh_read_data_raw_get(&dev_ctx, data, (uint8_t)len); 633 | 634 | #ifdef ENABLE_READ_WRITE_DEBUG 635 | Log_Debug("Read %d bytes: ", len); 636 | for (int i = 0; i < len; i++) { 637 | Log_Debug("[%0x] ", data[i]); 638 | } 639 | Log_Debug("\n", len); 640 | #endif 641 | 642 | /* Re-enable accelerometer */ 643 | lsm6dso_xl_data_rate_set(&dev_ctx, LSM6DSO_XL_ODR_104Hz); 644 | 645 | return ret; 646 | } 647 | 648 | 649 | -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/i2c.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "epoll_timerfd_utilities.h" 5 | 6 | #define LSM6DSO_ID 0x6C // register value 7 | #define LSM6DSO_ADDRESS 0x6A // I2C Address 8 | 9 | int initI2c(void); 10 | void closeI2c(void); -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/launch.vs.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.1", 3 | "defaults": {}, 4 | "configurations": [ 5 | { 6 | "type": "azurespheredbg", 7 | "name": "GDB Debugger (HLCore)", 8 | "project": "CMakeLists.txt", 9 | "inheritEnvironments": [ 10 | "AzureSphere" 11 | ], 12 | "customLauncher": "AzureSphereLaunchOptions", 13 | "workingDirectory": "${workspaceRoot}", 14 | "applicationPath": "${debugInfo.target}", 15 | "imagePath": "${debugInfo.targetImage}", 16 | "targetCore": "HLCore", 17 | "targetApiSet": "${env.AzureSphereTargetApiSet}", 18 | "partnerComponents": [] 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/lps22hh_reg.h: -------------------------------------------------------------------------------- 1 | /* 2 | ****************************************************************************** 3 | * @file lps22hh_reg.h 4 | * @author Sensors Software Solution Team 5 | * @brief This file contains all the functions prototypes for the 6 | * lps22hh_reg.c driver. 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | *

© COPYRIGHT(c) 2018 STMicroelectronics

11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions 14 | * are met: 15 | * 1. Redistributions of source code must retain the above copyright notice, 16 | * this list of conditions and the following disclaimer. 17 | * 2. Redistributions in binary form must reproduce the above copyright 18 | * notice, this list of conditions and the following disclaimer in the 19 | * documentation and/or other materials provided with the distribution. 20 | * 3. Neither the name of STMicroelectronics nor the names of its 21 | * contributors may be used to endorse or promote products derived from 22 | * this software without specific prior written permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 25 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 28 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 32 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 | * POSSIBILITY OF SUCH DAMAGE. 35 | * 36 | */ 37 | 38 | /* Define to prevent recursive inclusion -------------------------------------*/ 39 | #ifndef LPS22HH_DRIVER_H 40 | #define LPS22HH_DRIVER_H 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | /* Includes ------------------------------------------------------------------*/ 47 | #include 48 | #include 49 | 50 | /** @addtogroup LPS22HH 51 | * @{ 52 | * 53 | */ 54 | 55 | /** @defgroup LPS22HH_sensors_common_types 56 | * @{ 57 | * 58 | */ 59 | 60 | #ifndef MEMS_SHARED_TYPES 61 | #define MEMS_SHARED_TYPES 62 | 63 | /** 64 | * @defgroup axisXbitXX_t 65 | * @brief These unions are useful to represent different sensors data type. 66 | * These unions are not need by the driver. 67 | * 68 | * REMOVING the unions you are compliant with: 69 | * MISRA-C 2012 [Rule 19.2] -> " Union are not allowed " 70 | * 71 | * @{ 72 | * 73 | */ 74 | 75 | typedef union{ 76 | int16_t i16bit[3]; 77 | uint8_t u8bit[6]; 78 | } axis3bit16_t; 79 | 80 | typedef union{ 81 | int16_t i16bit; 82 | uint8_t u8bit[2]; 83 | } axis1bit16_t; 84 | 85 | typedef union{ 86 | int32_t i32bit[3]; 87 | uint8_t u8bit[12]; 88 | } axis3bit32_t; 89 | 90 | typedef union{ 91 | int32_t i32bit; 92 | uint8_t u8bit[4]; 93 | } axis1bit32_t; 94 | 95 | /** 96 | * @} 97 | * 98 | */ 99 | 100 | typedef struct{ 101 | uint8_t bit0 : 1; 102 | uint8_t bit1 : 1; 103 | uint8_t bit2 : 1; 104 | uint8_t bit3 : 1; 105 | uint8_t bit4 : 1; 106 | uint8_t bit5 : 1; 107 | uint8_t bit6 : 1; 108 | uint8_t bit7 : 1; 109 | } bitwise_t; 110 | 111 | #define PROPERTY_DISABLE (0U) 112 | #define PROPERTY_ENABLE (1U) 113 | 114 | #endif /* MEMS_SHARED_TYPES */ 115 | 116 | /** 117 | * @} 118 | * 119 | */ 120 | 121 | /** @addtogroup LPS22HH_Interfaces_Functions 122 | * @brief This section provide a set of functions used to read and 123 | * write a generic register of the device. 124 | * MANDATORY: return 0 -> no Error. 125 | * @{ 126 | * 127 | */ 128 | 129 | typedef int32_t (*lps22hh_write_ptr)(void *, uint8_t, uint8_t*, uint16_t); 130 | typedef int32_t (*lps22hh_read_ptr) (void *, uint8_t, uint8_t*, uint16_t); 131 | 132 | typedef struct { 133 | /** Component mandatory fields **/ 134 | lps22hh_write_ptr write_reg; 135 | lps22hh_read_ptr read_reg; 136 | /** Customizable optional pointer **/ 137 | void *handle; 138 | } lps22hh_ctx_t; 139 | 140 | /** 141 | * @} 142 | * 143 | */ 144 | 145 | /** @defgroup LPS22HH_Infos 146 | * @{ 147 | * 148 | */ 149 | 150 | /** I2C Device Address 8 bit format if SA0=0 -> B9 if SA0=1 -> BB **/ 151 | #define LPS22HH_I2C_ADD_H 0xBBU 152 | #define LPS22HH_I2C_ADD_L 0xB9U 153 | 154 | /** Device Identification (Who am I) **/ 155 | #define LPS22HH_ID 0xB3U 156 | 157 | /** 158 | * @} 159 | * 160 | */ 161 | 162 | #define LPS22HH_INTERRUPT_CFG 0x0BU 163 | typedef struct { 164 | uint8_t pe : 2; /* ple + phe */ 165 | uint8_t lir : 1; 166 | uint8_t diff_en : 1; 167 | uint8_t reset_az : 1; 168 | uint8_t autozero : 1; 169 | uint8_t reset_arp : 1; 170 | uint8_t autorefp : 1; 171 | } lps22hh_interrupt_cfg_t; 172 | 173 | #define LPS22HH_THS_P_L 0x0CU 174 | typedef struct { 175 | uint8_t ths : 8; 176 | } lps22hh_ths_p_l_t; 177 | 178 | #define LPS22HH_THS_P_H 0x0DU 179 | typedef struct { 180 | uint8_t ths : 7; 181 | uint8_t not_used_01 : 1; 182 | } lps22hh_ths_p_h_t; 183 | 184 | #define LPS22HH_IF_CTRL 0x0EU 185 | typedef struct { 186 | uint8_t i2c_disable : 1; 187 | uint8_t i3c_disable : 1; 188 | uint8_t pd_dis_int1 : 1; 189 | uint8_t sdo_pu_en : 1; 190 | uint8_t sda_pu_en : 1; 191 | uint8_t not_used_01 : 2; 192 | uint8_t int_en_i3c : 1; 193 | } lps22hh_if_ctrl_t; 194 | 195 | #define LPS22HH_WHO_AM_I 0x0FU 196 | #define LPS22HH_CTRL_REG1 0x10U 197 | typedef struct { 198 | uint8_t sim : 1; 199 | uint8_t bdu : 1; 200 | uint8_t lpfp_cfg : 2; /* en_lpfp + lpfp_cfg */ 201 | uint8_t odr : 3; 202 | uint8_t not_used_01 : 1; 203 | } lps22hh_ctrl_reg1_t; 204 | 205 | #define LPS22HH_CTRL_REG2 0x11U 206 | typedef struct { 207 | uint8_t one_shot : 1; 208 | uint8_t low_noise_en : 1; 209 | uint8_t swreset : 1; 210 | uint8_t not_used_01 : 1; 211 | uint8_t if_add_inc : 1; 212 | uint8_t pp_od : 1; 213 | uint8_t int_h_l : 1; 214 | uint8_t boot : 1; 215 | } lps22hh_ctrl_reg2_t; 216 | 217 | #define LPS22HH_CTRL_REG3 0x12U 218 | typedef struct { 219 | uint8_t int_s : 2; 220 | uint8_t drdy : 1; 221 | uint8_t int_f_ovr : 1; 222 | uint8_t int_f_wtm : 1; 223 | uint8_t int_f_full : 1; 224 | uint8_t not_used_01 : 2; 225 | } lps22hh_ctrl_reg3_t; 226 | 227 | #define LPS22HH_FIFO_CTRL 0x13U 228 | typedef struct { 229 | uint8_t f_mode : 3; /* f_mode + trig_modes */ 230 | uint8_t stop_on_wtm : 1; 231 | uint8_t not_used_01 : 4; 232 | } lps22hh_fifo_ctrl_t; 233 | 234 | #define LPS22HH_FIFO_WTM 0x14U 235 | typedef struct { 236 | uint8_t wtm : 7; 237 | uint8_t not_used_01 : 1; 238 | } lps22hh_fifo_wtm_t; 239 | 240 | #define LPS22HH_REF_P_L 0x15U 241 | #define LPS22HH_REF_P_H 0x16U 242 | #define LPS22HH_RPDS_L 0x18U 243 | #define LPS22HH_RPDS_H 0x19U 244 | #define LPS22HH_INT_SOURCE 0x24U 245 | typedef struct { 246 | uint8_t ph : 1; 247 | uint8_t pl : 1; 248 | uint8_t ia : 1; 249 | uint8_t not_used_01 : 4; 250 | uint8_t boot_on : 1; 251 | } lps22hh_int_source_t; 252 | 253 | #define LPS22HH_FIFO_STATUS1 0x25U 254 | #define LPS22HH_FIFO_STATUS2 0x26U 255 | typedef struct { 256 | uint8_t not_used_01 : 5; 257 | uint8_t fifo_full_ia : 1; 258 | uint8_t fifo_ovr_ia : 1; 259 | uint8_t fifo_wtm_ia : 1; 260 | } lps22hh_fifo_status2_t; 261 | 262 | #define LPS22HH_STATUS 0x27U 263 | typedef struct { 264 | uint8_t p_da : 1; 265 | uint8_t t_da : 1; 266 | uint8_t not_used_01 : 2; 267 | uint8_t p_or : 1; 268 | uint8_t t_or : 1; 269 | uint8_t not_used_02 : 2; 270 | } lps22hh_status_t; 271 | 272 | #define LPS22HH_PRESS_OUT_XL 0x28U 273 | #define LPS22HH_PRESS_OUT_L 0x29U 274 | #define LPS22HH_PRESS_OUT_H 0x2AU 275 | #define LPS22HH_TEMP_OUT_L 0x2BU 276 | #define LPS22HH_TEMP_OUT_H 0x2CU 277 | #define LPS22HH_FIFO_DATA_OUT_PRESS_XL 0x78U 278 | #define LPS22HH_FIFO_DATA_OUT_PRESS_L 0x79U 279 | #define LPS22HH_FIFO_DATA_OUT_PRESS_H 0x7AU 280 | #define LPS22HH_FIFO_DATA_OUT_TEMP_L 0x7BU 281 | #define LPS22HH_FIFO_DATA_OUT_TEMP_H 0x7CU 282 | 283 | /** 284 | * @defgroup LPS22HH_Register_Union 285 | * @brief This union group all the registers that has a bitfield 286 | * description. 287 | * This union is useful but not need by the driver. 288 | * 289 | * REMOVING this union you are compliant with: 290 | * MISRA-C 2012 [Rule 19.2] -> " Union are not allowed " 291 | * 292 | * @{ 293 | * 294 | */ 295 | typedef union{ 296 | lps22hh_interrupt_cfg_t interrupt_cfg; 297 | lps22hh_if_ctrl_t if_ctrl; 298 | lps22hh_ctrl_reg1_t ctrl_reg1; 299 | lps22hh_ctrl_reg2_t ctrl_reg2; 300 | lps22hh_ctrl_reg3_t ctrl_reg3; 301 | lps22hh_fifo_ctrl_t fifo_ctrl; 302 | lps22hh_fifo_wtm_t fifo_wtm; 303 | lps22hh_int_source_t int_source; 304 | lps22hh_fifo_status2_t fifo_status2; 305 | lps22hh_status_t status; 306 | bitwise_t bitwise; 307 | uint8_t byte; 308 | } lps22hh_reg_t; 309 | 310 | /** 311 | * @} 312 | * 313 | */ 314 | 315 | int32_t lps22hh_read_reg(lps22hh_ctx_t *ctx, uint8_t reg, uint8_t* data, 316 | uint16_t len); 317 | int32_t lps22hh_write_reg(lps22hh_ctx_t *ctx, uint8_t reg, uint8_t* data, 318 | uint16_t len); 319 | 320 | extern float lps22hh_from_lsb_to_hpa(uint32_t lsb); 321 | extern float lps22hh_from_lsb_to_celsius(int16_t lsb); 322 | 323 | int32_t lps22hh_autozero_rst_set(lps22hh_ctx_t *ctx, uint8_t val); 324 | int32_t lps22hh_autozero_rst_get(lps22hh_ctx_t *ctx, uint8_t *val); 325 | 326 | int32_t lps22hh_autozero_set(lps22hh_ctx_t *ctx, uint8_t val); 327 | int32_t lps22hh_autozero_get(lps22hh_ctx_t *ctx, uint8_t *val); 328 | 329 | int32_t lps22hh_pressure_snap_rst_set(lps22hh_ctx_t *ctx, uint8_t val); 330 | int32_t lps22hh_pressure_snap_rst_get(lps22hh_ctx_t *ctx, uint8_t *val); 331 | 332 | int32_t lps22hh_pressure_snap_set(lps22hh_ctx_t *ctx, uint8_t val); 333 | int32_t lps22hh_pressure_snap_get(lps22hh_ctx_t *ctx, uint8_t *val); 334 | 335 | int32_t lps22hh_block_data_update_set(lps22hh_ctx_t *ctx, uint8_t val); 336 | int32_t lps22hh_block_data_update_get(lps22hh_ctx_t *ctx, uint8_t *val); 337 | 338 | typedef enum { 339 | LPS22HH_POWER_DOWN = 0x00, 340 | LPS22HH_ONE_SHOOT = 0x08, 341 | LPS22HH_1_Hz = 0x01, 342 | LPS22HH_10_Hz = 0x02, 343 | LPS22HH_25_Hz = 0x03, 344 | LPS22HH_50_Hz = 0x04, 345 | LPS22HH_75_Hz = 0x05, 346 | LPS22HH_1_Hz_LOW_NOISE = 0x11, 347 | LPS22HH_10_Hz_LOW_NOISE = 0x12, 348 | LPS22HH_25_Hz_LOW_NOISE = 0x13, 349 | LPS22HH_50_Hz_LOW_NOISE = 0x14, 350 | LPS22HH_75_Hz_LOW_NOISE = 0x15, 351 | LPS22HH_100_Hz = 0x06, 352 | LPS22HH_200_Hz = 0x07, 353 | } lps22hh_odr_t; 354 | int32_t lps22hh_data_rate_set(lps22hh_ctx_t *ctx, lps22hh_odr_t val); 355 | int32_t lps22hh_data_rate_get(lps22hh_ctx_t *ctx, lps22hh_odr_t *val); 356 | 357 | int32_t lps22hh_pressure_ref_set(lps22hh_ctx_t *ctx, uint8_t *buff); 358 | int32_t lps22hh_pressure_ref_get(lps22hh_ctx_t *ctx, uint8_t *buff); 359 | 360 | int32_t lps22hh_pressure_offset_set(lps22hh_ctx_t *ctx, uint8_t *buff); 361 | int32_t lps22hh_pressure_offset_get(lps22hh_ctx_t *ctx, uint8_t *buff); 362 | 363 | typedef struct{ 364 | lps22hh_int_source_t int_source; 365 | lps22hh_fifo_status2_t fifo_status2; 366 | lps22hh_status_t status; 367 | } lps22hh_all_sources_t; 368 | int32_t lps22hh_all_sources_get(lps22hh_ctx_t *ctx, 369 | lps22hh_all_sources_t *val); 370 | 371 | int32_t lps22hh_status_reg_get(lps22hh_ctx_t *ctx, lps22hh_status_t *val); 372 | 373 | int32_t lps22hh_press_flag_data_ready_get(lps22hh_ctx_t *ctx, uint8_t *val); 374 | 375 | int32_t lps22hh_temp_flag_data_ready_get(lps22hh_ctx_t *ctx, uint8_t *val); 376 | 377 | int32_t lps22hh_pressure_raw_get(lps22hh_ctx_t *ctx, uint8_t *buff); 378 | 379 | int32_t lps22hh_temperature_raw_get(lps22hh_ctx_t *ctx, uint8_t *buff); 380 | 381 | int32_t lps22hh_fifo_pressure_raw_get(lps22hh_ctx_t *ctx, uint8_t *buff); 382 | 383 | int32_t lps22hh_fifo_temperature_raw_get(lps22hh_ctx_t *ctx, uint8_t *buff); 384 | 385 | int32_t lps22hh_device_id_get(lps22hh_ctx_t *ctx, uint8_t *buff); 386 | 387 | int32_t lps22hh_reset_set(lps22hh_ctx_t *ctx, uint8_t val); 388 | int32_t lps22hh_reset_get(lps22hh_ctx_t *ctx, uint8_t *val); 389 | 390 | int32_t lps22hh_auto_increment_set(lps22hh_ctx_t *ctx, uint8_t val); 391 | int32_t lps22hh_auto_increment_get(lps22hh_ctx_t *ctx, uint8_t *val); 392 | 393 | int32_t lps22hh_boot_set(lps22hh_ctx_t *ctx, uint8_t val); 394 | int32_t lps22hh_boot_get(lps22hh_ctx_t *ctx, uint8_t *val); 395 | 396 | typedef enum { 397 | LPS22HH_LPF_ODR_DIV_2 = 0, 398 | LPS22HH_LPF_ODR_DIV_9 = 2, 399 | LPS22HH_LPF_ODR_DIV_20 = 3, 400 | } lps22hh_lpfp_cfg_t; 401 | int32_t lps22hh_lp_bandwidth_set(lps22hh_ctx_t *ctx, lps22hh_lpfp_cfg_t val); 402 | int32_t lps22hh_lp_bandwidth_get(lps22hh_ctx_t *ctx, lps22hh_lpfp_cfg_t *val); 403 | 404 | typedef enum { 405 | LPS22HH_I2C_ENABLE = 0, 406 | LPS22HH_I2C_DISABLE = 1, 407 | } lps22hh_i2c_disable_t; 408 | int32_t lps22hh_i2c_interface_set(lps22hh_ctx_t *ctx, 409 | lps22hh_i2c_disable_t val); 410 | int32_t lps22hh_i2c_interface_get(lps22hh_ctx_t *ctx, 411 | lps22hh_i2c_disable_t *val); 412 | 413 | typedef enum { 414 | LPS22HH_I3C_ENABLE = 0x00, 415 | LPS22HH_I3C_ENABLE_INT_PIN_ENABLE = 0x10, 416 | LPS22HH_I3C_DISABLE = 0x11, 417 | } lps22hh_i3c_disable_t; 418 | int32_t lps22hh_i3c_interface_set(lps22hh_ctx_t *ctx, 419 | lps22hh_i3c_disable_t val); 420 | int32_t lps22hh_i3c_interface_get(lps22hh_ctx_t *ctx, 421 | lps22hh_i3c_disable_t *val); 422 | 423 | typedef enum { 424 | LPS22HH_PULL_UP_DISCONNECT = 0, 425 | LPS22HH_PULL_UP_CONNECT = 1, 426 | } lps22hh_pu_en_t; 427 | int32_t lps22hh_sdo_sa0_mode_set(lps22hh_ctx_t *ctx, lps22hh_pu_en_t val); 428 | int32_t lps22hh_sdo_sa0_mode_get(lps22hh_ctx_t *ctx, lps22hh_pu_en_t *val); 429 | int32_t lps22hh_sda_mode_set(lps22hh_ctx_t *ctx, lps22hh_pu_en_t val); 430 | int32_t lps22hh_sda_mode_get(lps22hh_ctx_t *ctx, lps22hh_pu_en_t *val); 431 | 432 | typedef enum { 433 | LPS22HH_SPI_4_WIRE = 0, 434 | LPS22HH_SPI_3_WIRE = 1, 435 | } lps22hh_sim_t; 436 | int32_t lps22hh_spi_mode_set(lps22hh_ctx_t *ctx, lps22hh_sim_t val); 437 | int32_t lps22hh_spi_mode_get(lps22hh_ctx_t *ctx, lps22hh_sim_t *val); 438 | 439 | typedef enum { 440 | LPS22HH_INT_PULSED = 0, 441 | LPS22HH_INT_LATCHED = 1, 442 | } lps22hh_lir_t; 443 | int32_t lps22hh_int_notification_set(lps22hh_ctx_t *ctx, lps22hh_lir_t val); 444 | int32_t lps22hh_int_notification_get(lps22hh_ctx_t *ctx, lps22hh_lir_t *val); 445 | 446 | typedef enum { 447 | LPS22HH_PUSH_PULL = 0, 448 | LPS22HH_OPEN_DRAIN = 1, 449 | } lps22hh_pp_od_t; 450 | int32_t lps22hh_pin_mode_set(lps22hh_ctx_t *ctx, lps22hh_pp_od_t val); 451 | int32_t lps22hh_pin_mode_get(lps22hh_ctx_t *ctx, lps22hh_pp_od_t *val); 452 | 453 | typedef enum { 454 | LPS22HH_ACTIVE_HIGH = 0, 455 | LPS22HH_ACTIVE_LOW = 1, 456 | } lps22hh_int_h_l_t; 457 | int32_t lps22hh_pin_polarity_set(lps22hh_ctx_t *ctx, lps22hh_int_h_l_t val); 458 | int32_t lps22hh_pin_polarity_get(lps22hh_ctx_t *ctx, lps22hh_int_h_l_t *val); 459 | 460 | int32_t lps22hh_pin_int_route_set(lps22hh_ctx_t *ctx, 461 | lps22hh_ctrl_reg3_t *val); 462 | int32_t lps22hh_pin_int_route_get(lps22hh_ctx_t *ctx, 463 | lps22hh_ctrl_reg3_t *val); 464 | 465 | typedef enum { 466 | LPS22HH_NO_THRESHOLD = 0, 467 | LPS22HH_POSITIVE = 1, 468 | LPS22HH_NEGATIVE = 2, 469 | LPS22HH_BOTH = 3, 470 | } lps22hh_pe_t; 471 | int32_t lps22hh_int_on_threshold_set(lps22hh_ctx_t *ctx, lps22hh_pe_t val); 472 | int32_t lps22hh_int_on_threshold_get(lps22hh_ctx_t *ctx, lps22hh_pe_t *val); 473 | 474 | int32_t lps22hh_int_treshold_set(lps22hh_ctx_t *ctx, uint16_t buff); 475 | int32_t lps22hh_int_treshold_get(lps22hh_ctx_t *ctx, uint16_t *buff); 476 | 477 | typedef enum { 478 | LPS22HH_BYPASS_MODE = 0, 479 | LPS22HH_FIFO_MODE = 1, 480 | LPS22HH_STREAM_MODE = 2, 481 | LPS22HH_DYNAMIC_STREAM_MODE = 3, 482 | LPS22HH_BYPASS_TO_FIFO_MODE = 5, 483 | LPS22HH_BYPASS_TO_STREAM_MODE = 6, 484 | LPS22HH_STREAM_TO_FIFO_MODE = 7, 485 | } lps22hh_f_mode_t; 486 | int32_t lps22hh_fifo_mode_set(lps22hh_ctx_t *ctx, lps22hh_f_mode_t val); 487 | int32_t lps22hh_fifo_mode_get(lps22hh_ctx_t *ctx, lps22hh_f_mode_t *val); 488 | 489 | int32_t lps22hh_fifo_stop_on_wtm_set(lps22hh_ctx_t *ctx, uint8_t val); 490 | int32_t lps22hh_fifo_stop_on_wtm_get(lps22hh_ctx_t *ctx, uint8_t *val); 491 | 492 | int32_t lps22hh_fifo_watermark_set(lps22hh_ctx_t *ctx, uint8_t val); 493 | int32_t lps22hh_fifo_watermark_get(lps22hh_ctx_t *ctx, uint8_t *val); 494 | 495 | int32_t lps22hh_fifo_data_level_get(lps22hh_ctx_t *ctx, uint8_t *buff); 496 | 497 | int32_t lps22hh_fifo_src_get(lps22hh_ctx_t *ctx, lps22hh_fifo_status2_t *val); 498 | 499 | int32_t lps22hh_fifo_full_flag_get(lps22hh_ctx_t *ctx, uint8_t *val); 500 | 501 | int32_t lps22hh_fifo_ovr_flag_get(lps22hh_ctx_t *ctx, uint8_t *val); 502 | 503 | int32_t lps22hh_fifo_wtm_flag_get(lps22hh_ctx_t *ctx, uint8_t *val); 504 | 505 | int32_t lps22hh_fifo_ovr_on_int_set(lps22hh_ctx_t *ctx, uint8_t val); 506 | int32_t lps22hh_fifo_ovr_on_int_get(lps22hh_ctx_t *ctx, uint8_t *val); 507 | 508 | int32_t lps22hh_fifo_threshold_on_int_set(lps22hh_ctx_t *ctx, uint8_t val); 509 | int32_t lps22hh_fifo_threshold_on_int_get(lps22hh_ctx_t *ctx, uint8_t *val); 510 | 511 | int32_t lps22hh_fifo_full_on_int_set(lps22hh_ctx_t *ctx, uint8_t val); 512 | int32_t lps22hh_fifo_full_on_int_get(lps22hh_ctx_t *ctx, uint8_t *val); 513 | 514 | /** 515 | * @} 516 | * 517 | */ 518 | 519 | #ifdef __cplusplus 520 | } 521 | #endif 522 | 523 | #endif /*LPS22HH_REGS_H */ 524 | 525 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 526 | -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/main.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) Microsoft Corporation. All rights reserved. 2 | Licensed under the MIT License. */ 3 | 4 | /************************************************************************************************ 5 | Name: AvnetStarterKitReferenceDesign 6 | Sphere OS: 19.02 7 | This file contains the 'main' function. Program execution begins and ends there 8 | 9 | Authors: 10 | Peter Fenn (Avnet Engineering & Technology) 11 | Brian Willess (Avnet Engineering & Technology) 12 | 13 | Purpose: 14 | Using the Avnet Azure Sphere Starter Kit demonstrate the following features 15 | 16 | 1. Read X,Y,Z accelerometer data from the onboard LSM6DSO device using the I2C Interface 17 | 2. Read X,YZ Angular rate data from the onboard LSM6DSO device using the I2C Interface 18 | 3. Read the barometric pressure from the onboard LPS22HH device using the I2C Interface 19 | 4. Read the temperature from the onboard LPS22HH device using the I2C Interface 20 | 5. Read the state of the A and B buttons 21 | 6. Read BSSID address, Wi-Fi AP SSID, Wi-Fi Frequency 22 | ************************************************************************************************* 23 | Connected application features: When connected to Azure IoT Hub or IoT Central 24 | ************************************************************************************************* 25 | 7. Send X,Y,Z accelerometer data to Azure 26 | 8. Send barometric pressure data to Azure 27 | 9. Send button state data to Azure 28 | 10. Send BSSID address, Wi-Fi AP SSID, Wi-Fi Frequency data to Azure 29 | 11. Send the application version string to Azure 30 | 12. Control user RGB LEDs from the cloud using device twin properties 31 | 13. Control optional Relay Click relays from the cloud using device twin properties 32 | 14. Send Application version up as a device twin property 33 | 15. Stop application using "haltApplication" Direct Method call from the cloud 34 | 16. Modify sensor polling time using "setSensorPollTinme" Direct Method from the cloud 35 | TODO 36 | 1. Add support for a OLED display 37 | 2. Add support for on-board light sensor 38 | 39 | *************************************************************************************************/ 40 | 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | 51 | // applibs_versions.h defines the API struct versions to use for applibs APIs. 52 | #include "applibs_versions.h" 53 | #include "epoll_timerfd_utilities.h" 54 | #include "i2c.h" 55 | #include "hw/avnet_mt3620_sk.h" 56 | 57 | #include "deviceTwin.h" 58 | #include "azure_iot_utilities.h" 59 | #include "connection_strings.h" 60 | #include "build_options.h" 61 | 62 | #include 63 | #include 64 | #include 65 | #include 66 | #include 67 | 68 | // Provide local access to variables in other files 69 | extern twin_t twinArray[]; 70 | extern int twinArraySize; 71 | extern IOTHUB_DEVICE_CLIENT_LL_HANDLE iothubClientHandle; 72 | extern int accelTimerFd; 73 | 74 | // Support functions. 75 | static void TerminationHandler(int signalNumber); 76 | static int InitPeripheralsAndHandlers(void); 77 | static void ClosePeripheralsAndHandlers(void); 78 | 79 | // File descriptors - initialized to invalid value 80 | int epollFd = -1; 81 | static int buttonPollTimerFd = -1; 82 | static int buttonAGpioFd = -1; 83 | static int buttonBGpioFd = -1; 84 | 85 | int userLedRedFd = -1; 86 | int userLedGreenFd = -1; 87 | int userLedBlueFd = -1; 88 | int appLedFd = -1; 89 | int wifiLedFd = -1; 90 | int clickSocket1Relay1Fd = -1; 91 | int clickSocket1Relay2Fd = -1; 92 | 93 | // Button state variables, initilize them to button not-pressed (High) 94 | static GPIO_Value_Type buttonAState = GPIO_Value_High; 95 | static GPIO_Value_Type buttonBState = GPIO_Value_High; 96 | 97 | #if (defined(IOT_CENTRAL_APPLICATION) || defined(IOT_HUB_APPLICATION)) 98 | bool versionStringSent = false; 99 | #endif 100 | 101 | // Define the Json string format for the accelerator button press data 102 | static const char cstrButtonTelemetryJson[] = "{\"%s\":\"%d\"}"; 103 | 104 | // Termination state 105 | volatile sig_atomic_t terminationRequired = false; 106 | 107 | /// 108 | /// Signal handler for termination requests. This handler must be async-signal-safe. 109 | /// 110 | static void TerminationHandler(int signalNumber) 111 | { 112 | // Don't use Log_Debug here, as it is not guaranteed to be async-signal-safe. 113 | terminationRequired = true; 114 | } 115 | 116 | /// 117 | /// Allocates and formats a string message on the heap. 118 | /// 119 | /// The format of the message 120 | /// The maximum length of the formatted message string 121 | /// The pointer to the heap allocated memory. 122 | static void *SetupHeapMessage(const char *messageFormat, size_t maxLength, ...) 123 | { 124 | va_list args; 125 | va_start(args, maxLength); 126 | char *message = 127 | malloc(maxLength + 1); // Ensure there is space for the null terminator put by vsnprintf. 128 | if (message != NULL) { 129 | vsnprintf(message, maxLength, messageFormat, args); 130 | } 131 | va_end(args); 132 | return message; 133 | } 134 | 135 | /// 136 | /// Direct Method callback function, called when a Direct Method call is received from the Azure 137 | /// IoT Hub. 138 | /// 139 | /// The name of the method being called. 140 | /// The payload of the method. 141 | /// The response payload content. This must be a heap-allocated 142 | /// string, 'free' will be called on this buffer by the Azure IoT Hub SDK. 143 | /// The size of the response payload content. 144 | /// 200 HTTP status code if the method name is reconginized and the payload is correctly parsed; 145 | /// 400 HTTP status code if the payload is invalid; 146 | /// 404 HTTP status code if the method name is unknown. 147 | static int DirectMethodCall (const char *methodName, const char *payload, size_t payloadSize, char **responsePayload, size_t *responsePayloadSize) 148 | { 149 | Log_Debug("\nDirect Method called %s\n", methodName); 150 | 151 | int result = 404; // HTTP status code. 152 | 153 | if (payloadSize < 32) { 154 | 155 | // Declare a char buffer on the stack where we'll operate on a copy of the payload. 156 | char directMethodCallContent[payloadSize + 1]; 157 | 158 | // Prepare the payload for the response. This is a heap allocated null terminated string. 159 | // The Azure IoT Hub SDK is responsible of freeing it. 160 | *responsePayload = NULL; // Reponse payload content. 161 | *responsePayloadSize = 0; // Response payload content size. 162 | 163 | 164 | // Look for the haltApplication method name. This direct method does not require any payload, other than 165 | // a valid Json argument such as {}. 166 | 167 | if (strcmp(methodName, "haltApplication") == 0) { 168 | 169 | // Log that the direct method was called and set the result to reflect success! 170 | Log_Debug("haltApplication() Direct Method called\n"); 171 | result = 200; 172 | 173 | // Construct the response message. This response will be displayed in the cloud when calling the direct method 174 | static const char resetOkResponse[] = 175 | "{ \"success\" : true, \"message\" : \"Halting Application\" }"; 176 | size_t responseMaxLength = sizeof(resetOkResponse); 177 | *responsePayload = SetupHeapMessage(resetOkResponse, responseMaxLength); 178 | if (*responsePayload == NULL) { 179 | Log_Debug("ERROR: Could not allocate buffer for direct method response payload.\n"); 180 | abort(); 181 | } 182 | *responsePayloadSize = strlen(*responsePayload); 183 | 184 | // Set the terminitation flag to true. When in Visual Studio this will simply halt the application. 185 | // If this application was running with the device in field-prep mode, the application would halt 186 | // and the OS services would resetart the application. 187 | terminationRequired = true; 188 | return result; 189 | } 190 | 191 | // Check to see if the setSensorPollTime direct method was called 192 | else if (strcmp(methodName, "setSensorPollTime") == 0) { 193 | 194 | // Log that the direct method was called and set the result to reflect success! 195 | Log_Debug("setSensorPollTime() Direct Method called\n"); 196 | result = 200; 197 | 198 | // The payload should contain a JSON object such as: {"pollTime": 20} 199 | if (directMethodCallContent == NULL) { 200 | Log_Debug("ERROR: Could not allocate buffer for direct method request payload.\n"); 201 | abort(); 202 | } 203 | 204 | // Copy the payload into our local buffer then null terminate it. 205 | memcpy(directMethodCallContent, payload, payloadSize); 206 | directMethodCallContent[payloadSize] = 0; // Null terminated string. 207 | 208 | JSON_Value *payloadJson = json_parse_string(directMethodCallContent); 209 | 210 | // Verify we have a valid JSON string from the payload 211 | if (payloadJson == NULL) { 212 | goto payloadError; 213 | } 214 | 215 | // Verify that the payloadJson contains a valid JSON object 216 | JSON_Object *pollTimeJson = json_value_get_object(payloadJson); 217 | if (pollTimeJson == NULL) { 218 | goto payloadError; 219 | } 220 | 221 | // Pull the Key: value pair from the JSON object, we're looking for {"pollTime": } 222 | // Verify that the new timer is < 0 223 | int newPollTime = (int)json_object_get_number(pollTimeJson, "pollTime"); 224 | if (newPollTime < 1) { 225 | goto payloadError; 226 | } 227 | else { 228 | 229 | Log_Debug("New PollTime %d\n", newPollTime); 230 | 231 | // Construct the response message. This will be displayed in the cloud when calling the direct method 232 | static const char newPollTimeResponse[] = 233 | "{ \"success\" : true, \"message\" : \"New Sensor Poll Time %d seconds\" }"; 234 | size_t responseMaxLength = sizeof(newPollTimeResponse) + strlen(payload); 235 | *responsePayload = SetupHeapMessage(newPollTimeResponse, responseMaxLength, newPollTime); 236 | if (*responsePayload == NULL) { 237 | Log_Debug("ERROR: Could not allocate buffer for direct method response payload.\n"); 238 | abort(); 239 | } 240 | *responsePayloadSize = strlen(*responsePayload); 241 | 242 | // Define a new timespec variable for the timer and change the timer period 243 | struct timespec newAccelReadPeriod = { .tv_sec = newPollTime,.tv_nsec = 0 }; 244 | SetTimerFdToPeriod(accelTimerFd, &newAccelReadPeriod); 245 | return result; 246 | } 247 | } 248 | else { 249 | result = 404; 250 | Log_Debug("INFO: Direct Method called \"%s\" not found.\n", methodName); 251 | 252 | static const char noMethodFound[] = "\"method not found '%s'\""; 253 | size_t responseMaxLength = sizeof(noMethodFound) + strlen(methodName); 254 | *responsePayload = SetupHeapMessage(noMethodFound, responseMaxLength, methodName); 255 | if (*responsePayload == NULL) { 256 | Log_Debug("ERROR: Could not allocate buffer for direct method response payload.\n"); 257 | abort(); 258 | } 259 | *responsePayloadSize = strlen(*responsePayload); 260 | return result; 261 | } 262 | 263 | } 264 | else { 265 | Log_Debug("Payload size > 32 bytes, aborting Direct Method execution\n"); 266 | goto payloadError; 267 | } 268 | 269 | // If there was a payload error, construct the 270 | // response message and send it back to the IoT Hub for the user to see 271 | payloadError: 272 | 273 | 274 | result = 400; // Bad request. 275 | Log_Debug("INFO: Unrecognised direct method payload format.\n"); 276 | 277 | static const char noPayloadResponse[] = 278 | "{ \"success\" : false, \"message\" : \"request does not contain an identifiable " 279 | "payload\" }"; 280 | 281 | size_t responseMaxLength = sizeof(noPayloadResponse) + strlen(payload); 282 | responseMaxLength = sizeof(noPayloadResponse); 283 | *responsePayload = SetupHeapMessage(noPayloadResponse, responseMaxLength); 284 | if (*responsePayload == NULL) { 285 | Log_Debug("ERROR: Could not allocate buffer for direct method response payload.\n"); 286 | abort(); 287 | } 288 | *responsePayloadSize = strlen(*responsePayload); 289 | 290 | return result; 291 | 292 | } 293 | 294 | /// 295 | /// Handle button timer event: if the button is pressed, report the event to the IoT Hub. 296 | /// 297 | static void ButtonTimerEventHandler(EventData *eventData) 298 | { 299 | 300 | bool sendTelemetryButtonA = false; 301 | bool sendTelemetryButtonB = false; 302 | 303 | if (ConsumeTimerFdEvent(buttonPollTimerFd) != 0) { 304 | terminationRequired = true; 305 | return; 306 | } 307 | 308 | // Check for button A press 309 | GPIO_Value_Type newButtonAState; 310 | int result = GPIO_GetValue(buttonAGpioFd, &newButtonAState); 311 | if (result != 0) { 312 | Log_Debug("ERROR: Could not read button GPIO: %s (%d).\n", strerror(errno), errno); 313 | terminationRequired = true; 314 | return; 315 | } 316 | 317 | // If the A button has just been pressed, send a telemetry message 318 | // The button has GPIO_Value_Low when pressed and GPIO_Value_High when released 319 | if (newButtonAState != buttonAState) { 320 | if (newButtonAState == GPIO_Value_Low) { 321 | Log_Debug("Button A pressed!\n"); 322 | sendTelemetryButtonA = true; 323 | } 324 | else { 325 | Log_Debug("Button A released!\n"); 326 | } 327 | 328 | // Update the static variable to use next time we enter this routine 329 | buttonAState = newButtonAState; 330 | } 331 | 332 | // Check for button B press 333 | GPIO_Value_Type newButtonBState; 334 | result = GPIO_GetValue(buttonBGpioFd, &newButtonBState); 335 | if (result != 0) { 336 | Log_Debug("ERROR: Could not read button GPIO: %s (%d).\n", strerror(errno), errno); 337 | terminationRequired = true; 338 | return; 339 | } 340 | 341 | // If the B button has just been pressed/released, send a telemetry message 342 | // The button has GPIO_Value_Low when pressed and GPIO_Value_High when released 343 | if (newButtonBState != buttonBState) { 344 | if (newButtonBState == GPIO_Value_Low) { 345 | // Send Telemetry here 346 | Log_Debug("Button B pressed!\n"); 347 | sendTelemetryButtonB = true; 348 | } 349 | else { 350 | Log_Debug("Button B released!\n"); 351 | 352 | } 353 | 354 | // Update the static variable to use next time we enter this routine 355 | buttonBState = newButtonBState; 356 | } 357 | 358 | 359 | #if (defined(IOT_CENTRAL_APPLICATION) || defined(IOT_HUB_APPLICATION)) 360 | // If either button was pressed, then enter the code to send the telemetry message 361 | if (sendTelemetryButtonA || sendTelemetryButtonB) { 362 | 363 | char *pjsonBuffer = (char *)malloc(JSON_BUFFER_SIZE); 364 | if (pjsonBuffer == NULL) { 365 | Log_Debug("ERROR: not enough memory to send telemetry"); 366 | } 367 | 368 | if (sendTelemetryButtonA) { 369 | // construct the telemetry message for Button A 370 | snprintf(pjsonBuffer, JSON_BUFFER_SIZE, cstrButtonTelemetryJson, "buttonA", newButtonAState); 371 | Log_Debug("\n[Info] Sending telemetry %s\n", pjsonBuffer); 372 | AzureIoT_SendMessage(pjsonBuffer); 373 | } 374 | 375 | if (sendTelemetryButtonB) { 376 | // construct the telemetry message for Button B 377 | snprintf(pjsonBuffer, JSON_BUFFER_SIZE, cstrButtonTelemetryJson, "buttonB", newButtonBState); 378 | Log_Debug("\n[Info] Sending telemetry %s\n", pjsonBuffer); 379 | AzureIoT_SendMessage(pjsonBuffer); 380 | } 381 | 382 | free(pjsonBuffer); 383 | } 384 | #endif 385 | 386 | } 387 | 388 | // event handler data structures. Only the event handler field needs to be populated. 389 | static EventData buttonEventData = { .eventHandler = &ButtonTimerEventHandler }; 390 | 391 | /// 392 | /// Set up SIGTERM termination handler, initialize peripherals, and set up event handlers. 393 | /// 394 | /// 0 on success, or -1 on failure 395 | static int InitPeripheralsAndHandlers(void) 396 | { 397 | struct sigaction action; 398 | memset(&action, 0, sizeof(struct sigaction)); 399 | action.sa_handler = TerminationHandler; 400 | sigaction(SIGTERM, &action, NULL); 401 | 402 | epollFd = CreateEpollFd(); 403 | if (epollFd < 0) { 404 | return -1; 405 | } 406 | 407 | if (initI2c() == -1) { 408 | return -1; 409 | } 410 | 411 | // Traverse the twin Array and for each GPIO item in the list open the file descriptor 412 | for (int i = 0; i < twinArraySize; i++) { 413 | 414 | // Verify that this entry is a GPIO entry 415 | if (twinArray[i].twinGPIO != NO_GPIO_ASSOCIATED_WITH_TWIN) { 416 | 417 | *twinArray[i].twinFd = -1; 418 | 419 | // For each item in the data structure, initialize the file descriptor and open the GPIO for output. Initilize each GPIO to its specific inactive state. 420 | *twinArray[i].twinFd = (int)GPIO_OpenAsOutput(twinArray[i].twinGPIO, GPIO_OutputMode_PushPull, twinArray[i].active_high ? GPIO_Value_Low : GPIO_Value_High); 421 | 422 | if (*twinArray[i].twinFd < 0) { 423 | Log_Debug("ERROR: Could not open LED %d: %s (%d).\n", twinArray[i].twinGPIO, strerror(errno), errno); 424 | return -1; 425 | } 426 | } 427 | } 428 | 429 | // Open button A GPIO as input 430 | Log_Debug("Opening Starter Kit Button A as input.\n"); 431 | buttonAGpioFd = GPIO_OpenAsInput(AVNET_MT3620_SK_USER_BUTTON_A); 432 | if (buttonAGpioFd < 0) { 433 | Log_Debug("ERROR: Could not open button A GPIO: %s (%d).\n", strerror(errno), errno); 434 | return -1; 435 | } 436 | // Open button B GPIO as input 437 | Log_Debug("Opening Starter Kit Button B as input.\n"); 438 | buttonBGpioFd = GPIO_OpenAsInput(AVNET_MT3620_SK_USER_BUTTON_B); 439 | if (buttonBGpioFd < 0) { 440 | Log_Debug("ERROR: Could not open button B GPIO: %s (%d).\n", strerror(errno), errno); 441 | return -1; 442 | } 443 | 444 | // Set up a timer to poll the buttons 445 | struct timespec buttonPressCheckPeriod = { 0, 1000000 }; 446 | buttonPollTimerFd = 447 | CreateTimerFdAndAddToEpoll(epollFd, &buttonPressCheckPeriod, &buttonEventData, EPOLLIN); 448 | if (buttonPollTimerFd < 0) { 449 | return -1; 450 | } 451 | 452 | // Tell the system about the callback function that gets called when we receive a device twin update message from Azure 453 | AzureIoT_SetDeviceTwinUpdateCallback(&deviceTwinChangedHandler); 454 | 455 | // Tell the system about the callback function to call when we receive a Direct Method message from Azure 456 | AzureIoT_SetDirectMethodCallback(&DirectMethodCall); 457 | 458 | return 0; 459 | } 460 | 461 | /// 462 | /// Close peripherals and handlers. 463 | /// 464 | static void ClosePeripheralsAndHandlers(void) 465 | { 466 | Log_Debug("Closing file descriptors.\n"); 467 | 468 | closeI2c(); 469 | CloseFdAndPrintError(epollFd, "Epoll"); 470 | CloseFdAndPrintError(buttonPollTimerFd, "buttonPoll"); 471 | CloseFdAndPrintError(buttonAGpioFd, "buttonA"); 472 | CloseFdAndPrintError(buttonBGpioFd, "buttonB"); 473 | 474 | // Traverse the twin Array and for each GPIO item in the list the close the file descriptor 475 | for (int i = 0; i < twinArraySize; i++) { 476 | 477 | // Verify that this entry has an open file descriptor 478 | if (twinArray[i].twinGPIO != NO_GPIO_ASSOCIATED_WITH_TWIN) { 479 | 480 | CloseFdAndPrintError(*twinArray[i].twinFd, twinArray[i].twinKey); 481 | } 482 | } 483 | } 484 | 485 | /// 486 | /// Main entry point for this application. 487 | /// 488 | int main(int argc, char *argv[]) 489 | { 490 | // Variable to help us send the version string up only once 491 | bool networkConfigSent = false; 492 | char ssid[128]; 493 | uint32_t frequency; 494 | char bssid[20]; 495 | 496 | // Clear the ssid array 497 | memset(ssid, 0, 128); 498 | 499 | Log_Debug("Version String: %s\n", argv[1]); 500 | Log_Debug("Avnet Starter Kit Simple Reference Application starting.\n"); 501 | if (InitPeripheralsAndHandlers() != 0) { 502 | terminationRequired = true; 503 | } 504 | 505 | // Use epoll to wait for events and trigger handlers, until an error or SIGTERM happens 506 | while (!terminationRequired) { 507 | if (WaitForEventAndCallHandler(epollFd) != 0) { 508 | terminationRequired = true; 509 | } 510 | 511 | #if (defined(IOT_CENTRAL_APPLICATION) || defined(IOT_HUB_APPLICATION)) 512 | // Setup the IoT Hub client. 513 | // Notes: 514 | // - it is safe to call this function even if the client has already been set up, as in 515 | // this case it would have no effect; 516 | // - a failure to setup the client is a fatal error. 517 | if (!AzureIoT_SetupClient()) { 518 | Log_Debug("ERROR: Failed to set up IoT Hub client\n"); 519 | break; 520 | } 521 | #endif 522 | 523 | WifiConfig_ConnectedNetwork network; 524 | int result = WifiConfig_GetCurrentNetwork(&network); 525 | if (result < 0) { 526 | // Log_Debug("INFO: Not currently connected to a WiFi network.\n"); 527 | } 528 | else { 529 | 530 | frequency = network.frequencyMHz; 531 | snprintf(bssid, JSON_BUFFER_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x", 532 | network.bssid[0], network.bssid[1], network.bssid[2], 533 | network.bssid[3], network.bssid[4], network.bssid[5]); 534 | 535 | if ((strncmp(ssid, (char*)&network.ssid, network.ssidLength)!=0) || !networkConfigSent) { 536 | 537 | memset(ssid, 0, 128); 538 | strncpy(ssid, network.ssid, network.ssidLength); 539 | Log_Debug("SSID: %s\n", ssid); 540 | Log_Debug("Frequency: %dMHz\n", frequency); 541 | Log_Debug("bssid: %s\n", bssid); 542 | networkConfigSent = true; 543 | 544 | #if (defined(IOT_CENTRAL_APPLICATION) || defined(IOT_HUB_APPLICATION)) 545 | // Note that we send up this data to Azure if it changes, but the IoT Central Properties elements only 546 | // show the data that was currenet when the device first connected to Azure. 547 | checkAndUpdateDeviceTwin("ssid", &ssid, TYPE_STRING, false); 548 | checkAndUpdateDeviceTwin("freq", &frequency, TYPE_INT, false); 549 | checkAndUpdateDeviceTwin("bssid", &bssid, TYPE_STRING, false); 550 | #endif 551 | } 552 | } 553 | #if (defined(IOT_CENTRAL_APPLICATION) || defined(IOT_HUB_APPLICATION)) 554 | if (iothubClientHandle != NULL && !versionStringSent) { 555 | 556 | checkAndUpdateDeviceTwin("versionString", argv[1], TYPE_STRING, false); 557 | versionStringSent = true; 558 | } 559 | 560 | // AzureIoT_DoPeriodicTasks() needs to be called frequently in order to keep active 561 | // the flow of data with the Azure IoT Hub 562 | AzureIoT_DoPeriodicTasks(); 563 | #endif 564 | } 565 | 566 | ClosePeripheralsAndHandlers(); 567 | Log_Debug("Application exiting.\n"); 568 | return 0; 569 | } 570 | -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/mt3620_avnet_dev.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /// This header contains the peripheral pinout definitions for the Avnet MT3620 Module(s) and Starter Kit Board 3 | #pragma once 4 | 5 | #include 6 | //#include 7 | #include 8 | #include 9 | 10 | /* This file includes all the signal definitions to utilize the Avnet Azure Sphere (MT3620) Module and the Avnet Azure Sphere Starter Kit 11 | 12 | The file is broken into sections to help the user identify which defines he/she needs 13 | 14 | * Module defines contains definitions for all the signals that can be found on the Avnet MT3620 Module. These defines are used 15 | when defining the Starter Kit signals. 16 | 17 | * Click Module Sections contain the defines for each of the two click sockets and are broken into two headers for each module. 18 | Furthermore, the signals are listed in the same order that they are wired on the Starter Kit from pin 1 - pin 8. 19 | 20 | * Grove Connector, Display Connector, LSM6DSOTR sections contain the signal definitions for the I2C signals on the Starter Kit. Note 21 | that the signals for each connector/device are shared, we've included separate definitions to help with self-documenting code efforts. 22 | */ 23 | // Compatible Seeed MT3620 Dev Board defines (for backward compatability to earlier RDB examples) 24 | #define MT3620_RDB_LED1_RED MT3620_GPIO8 // AVT_MODULE_GPIO8 25 | #define MT3620_RDB_LED1_GREEN MT3620_GPIO9 // AVT_MODULE_GPIO9 26 | #define MT3620_RDB_LED1_BLUE MT3620_GPIO10 // AVT_MODULE_GPIO10 27 | #define MT3620_RDB_BUTTON_A MT3620_GPIO12 // AVT_MODULE_GPIO12 28 | #define MT3620_RDB_BUTTON_B MT3620_GPIO13 // AVT_MODULE_GPIO13 29 | 30 | 31 | // Avnet Starter Kit LED defines 32 | #define AVT_LED_APP AVT_MODULE_GPIO4 33 | #define AVT_LED_WIFI AVT_MODULE_GPIO5 34 | 35 | // Avnet MT3620 Module defines 36 | 37 | #define AVT_MODULE_GPIO0_PWM0 MT3620_GPIO0 38 | #define AVT_MODULE_GPIO1_PWM1 MT3620_GPIO1 39 | #define AVT_MODULE_GPIO2_PWM2 MT3620_GPIO2 40 | #define AVT_MODULE_GPIO4 MT3620_GPIO4 41 | #define AVT_MODULE_GPIO5 MT3620_GPIO5 42 | #define AVT_MODULE_GPIO6_PWM6 MT3620_GPIO6 43 | #define AVT_MODULE_GPIO8 MT3620_GPIO8 44 | #define AVT_MODULE_GPIO9 MT3620_GPIO9 45 | #define AVT_MODULE_GPIO10 MT3620_GPIO10 46 | #define AVT_MODULE_GPIO12 MT3620_GPIO12 47 | #define AVT_MODULE_GPIO13 MT3620_GPIO13 48 | #define AVT_MODULE_GPIO16 MT3620_GPIO16 49 | #define AVT_MODULE_GPIO17 MT3620_GPIO17 50 | #define AVT_MODULE_GPIO26_SCLK0_TX0 (GPIO_Id)26 51 | #define AVT_MODULE_GPIO27_MOSI0_RTS0_CLK0 (GPIO_Id)27 52 | #define AVT_MODULE_GPIO28_MISO0_RX0_DATA0 (GPIO_Id)28 53 | #define AVT_MODULE_GPIO29_CSA0_CTS0 (GPIO_Id)29 54 | #define AVT_MODULE_GPIO31_SCLK1_TXD1 (GPIO_Id)31 55 | #define AVT_MODULE_GPIO32_MOSI1_RTS1_CLK1 (GPIO_Id)32 56 | #define AVT_MODULE_GPIO33_MISO1_RXD1_DATA1 (GPIO_Id)33 57 | #define AVT_MODULE_GPIO34_CSA1_CTS1 (GPIO_Id)34 58 | #define AVT_MODULE_GPIO35_CSB1 MT3620_GPIO35 59 | #define AVT_MODULE_GPIO37_MOSI2_RTS2_SCL2 (GPIO_Id)37 60 | #define AVT_MODULE_GPIO38_MISO2_RXD2_SDA2 (GPIO_Id)38 61 | #define AVT_MODULE_GPIO41_ADC0 MT3620_GPIO41 62 | #define AVT_MODULE_GPIO42_ADC1 MT3620_GPIO42 63 | #define AVT_MODULE_GPIO43_ADC2 MT3620_GPIO43 64 | 65 | // Avnet MT3620 Starter Kit defines 66 | 67 | // Click Module Site #1 Header J1 68 | 69 | /// Click Module 1 AN is GPIO 42. 70 | #define AVT_SK_CM1_AN AVT_MODULE_GPIO42_ADC1 71 | 72 | /// Click Module 1 RST is GPIO 16. 73 | #define AVT_SK_CM1_RST AVT_MODULE_GPIO16 74 | 75 | /// Click Module 1 CS is GPIO 34. 76 | #define AVT_SK_CM1_CS AVT_MODULE_GPIO34_CSA1_CTS1 77 | 78 | /// Click Module 1 SCK is GPIO 31. 79 | #define AVT_SK_CM1_SCK AVT_MODULE_GPIO31_SCLK1_TXD1 80 | 81 | /// Click Module 1 MISO is GPIO 33. 82 | #define AVT_SK_CM1_MISO AVT_MODULE_GPIO33_MISO1_RXD1_DATA1 83 | 84 | /// Click Module 1 MOSI is GPIO 32. 85 | #define AVT_SK_CM1_MOSI AVT_MODULE_GPIO32_MOSI1_RTS1_CLK1 86 | 87 | // Pin 7 is +3.3V 88 | // Pin 8 is GND 89 | 90 | // Click Module Site #1 Header J2 91 | 92 | /// Click Module 1 PWM is GPIO 0. 93 | #define AVT_SK_CM1_PWM AVT_MODULE_GPIO0_PWM0 94 | 95 | /// Click Module 1 INT is GPIO 2. 96 | #define AVT_SK_CM1_INT AVT_MODULE_GPIO2_PWM2 97 | 98 | /// Click Module 1 RX is GPIO 28. 99 | #define AVT_SK_CM1_RX AVT_MODULE_GPIO28_MISO0_RX0_DATA0 100 | 101 | /// Click Module 1 TX is GPIO 26. 102 | #define AVT_SK_CM1_TX AVT_MODULE_GPIO26_SCLK0_TX0 103 | 104 | /// Click Module 1 SCL is GPIO 37. 105 | #define AVT_SK_CM1_SCL AVT_MODULE_GPIO37_MOSI2_RTS2_SCL2 106 | 107 | /// Click Module 1 SDA is GPIO 38. 108 | #define AVT_SK_CM1_SDA AVT_MODULE_GPIO38_MISO2_RXD2_SDA2 109 | 110 | // Pin 7 is +5V 111 | // Pin 8 is GND 112 | 113 | 114 | // Click Module Site #2 Header J3 115 | 116 | /// Click Module 2 AN is GPIO43. 117 | #define AVT_SK_CM2_AN AVT_MODULE_GPIO43_ADC2 118 | 119 | /// Click Module 2 RST is GPIO 17. 120 | #define AVT_SK_CM2_RST AVT_MODULE_GPIO17 121 | 122 | /// Click Module 2 CS is GPIO 35. 123 | #define AVT_SK_CM2_CS AVT_MODULE_GPIO35_CSB1 124 | 125 | /// Click Module 2 SCK is GPIO 31. 126 | #define AVT_SK_CM2_SCK AVT_MODULE_GPIO31_SCLK1_TXD1 127 | 128 | /// Click Module 2 MOSO is GPIO 33. 129 | #define AVT_SK_CM2_MISO AVT_MODULE_GPIO33_MISO1_RXD1_DATA1 130 | 131 | /// Click Module 2 MOSI is GPIO 32. 132 | #define AVT_SK_CM2_MOSI AVT_MODULE_GPIO32_MOSI1_RTS1_CLK1 133 | 134 | // Pin 7 is +3.3V 135 | // Pin 8 is GND 136 | 137 | // Click Module Site #2 Header J4 138 | 139 | /// Click Module 2 PWM is GPIO 1. 140 | #define AVT_SK_CM2_PWM AVT_MODULE_GPIO1_PWM1 141 | /// Click Module 2 INT is GPIO 2. 142 | #define AVT_SK_CM2_INT AVT_MODULE_GPIO2_PWM2 143 | 144 | /// Click Module 2 RX is GPIO 28. 145 | #define AVT_SK_CM2_RX AVT_MODULE_GPIO28_MISO0_RX0_DATA0 146 | 147 | /// Click Module 2 TX is GPIO 26. 148 | #define AVT_SK_CM2_TX AVT_MODULE_GPIO26_SCLK0_TX0 149 | 150 | /// Click Module 2 SCL is GPIO 37. 151 | #define AVT_SK_CM2_SCL AVT_MODULE_GPIO37_MOSI2_RTS2_SCL2 152 | 153 | /// Click Module 2 SDA is GPIO 38. 154 | #define AVT_SK_CM2_SDA AVT_MODULE_GPIO38_MISO2_RXD2_SDA2 155 | 156 | // Pin 7 is +5V 157 | // Pin 8 is GND 158 | 159 | // Grove Connector Signals 160 | 161 | /// Grove Connector SCL is GPIO 37. 162 | #define AVT_SK_GROVE_SCL AVT_MODULE_GPIO37_MOSI2_RTS2_SCL2 163 | 164 | /// Grove Connector SDA is GPIO 38. 165 | #define AVT_SK_GROVE_SDA AVT_MODULE_GPIO38_MISO2_RXD2_SDA2 166 | 167 | // Display Connector Signals 168 | 169 | /// Display Connector SCL is GPIO 37. 170 | #define AVT_SK_DISPLAY_SCL AVT_MODULE_GPIO37_MOSI2_RTS2_SCL2 171 | 172 | /// Display Connector SDA is GPIO 38. 173 | #define AVT_SK_DISPLAY_SDA AVT_MODULE_GPIO38_MISO2_RXD2_SDA2 174 | 175 | // LSM6DSOTR Signals 176 | 177 | /// LSM6DSOTR SCL is GPIO 37. 178 | #define AVT_SK_I2C_LSM6DSOTR_SCL AVT_MODULE_GPIO37_MOSI2_RTS2_SCL2 179 | 180 | /// LSM6DSOTR SLA is GPIO 38. 181 | #define AVT_SK_I2C_LSM6DSOTR_SDA2 AVT_MODULE_GPIO38_MISO2_RXD2_SDA2 182 | 183 | 184 | // Uart defines 185 | 186 | /// Click Module 1 UART is GPIO 26(TX) and GPIO 28(RX). 187 | #define AVT_SK_CM1_ISU0_UART MT3620_UART_ISU0 188 | 189 | /// Click Module 2 UART is GPIO 26(TX) and GPIO 28(RX). 190 | #define AVT_SK_CM2_ISU0_UART MT3620_UART_ISU0 191 | 192 | 193 | /// ISU2 is for I2C use. It connects to the Click Sockets, Grove Connector, OLED Display and the LSM6DSO sensor 194 | #define MT3620_RDB_HEADER4_ISU2_I2C MT3620_I2C_ISU2 195 | -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/mt3620_rdb.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) Microsoft Corporation. All rights reserved. 2 | Licensed under the MIT License. */ 3 | 4 | /// This header contains the peripheral pinout definitions for the 5 | /// MT3620 Reference Development Board (RDB) 6 | #pragma once 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | /// LED 1 Red channel is GPIO8. 14 | #define MT3620_RDB_LED1_RED MT3620_GPIO8 15 | 16 | /// LED 1 Green channel is GPIO9. 17 | #define MT3620_RDB_LED1_GREEN MT3620_GPIO9 18 | 19 | /// LED 1 Blue channel is GPIO10. 20 | #define MT3620_RDB_LED1_BLUE MT3620_GPIO10 21 | 22 | /// LED 2 Red channel is GPIO15. 23 | #define MT3620_RDB_LED2_RED MT3620_GPIO15 24 | 25 | /// LED 2 Green channel is GPIO16. 26 | #define MT3620_RDB_LED2_GREEN MT3620_GPIO16 27 | 28 | /// LED 2 Blue channel is GPIO17. 29 | #define MT3620_RDB_LED2_BLUE MT3620_GPIO17 30 | 31 | /// LED 3 Red channel is GPIO18. 32 | #define MT3620_RDB_LED3_RED MT3620_GPIO18 33 | 34 | /// LED 3 Green channel is GPIO19. 35 | #define MT3620_RDB_LED3_GREEN MT3620_GPIO19 36 | 37 | /// LED 3 Blue channel is GPIO20. 38 | #define MT3620_RDB_LED3_BLUE MT3620_GPIO20 39 | 40 | /// LED 4 Red channel is GPIO21. 41 | #define MT3620_RDB_LED4_RED MT3620_GPIO21 42 | 43 | /// LED 4 Green channel is GPIO22. 44 | #define MT3620_RDB_LED4_GREEN MT3620_GPIO22 45 | 46 | /// LED 4 Blue channel is GPIO23. 47 | #define MT3620_RDB_LED4_BLUE MT3620_GPIO23 48 | 49 | /// Status LED Red channel is GPIO45. 50 | #define MT3620_RDB_STATUS_LED_RED MT3620_GPIO45 51 | 52 | /// Status LED Green channel is GPIO46. 53 | #define MT3620_RDB_STATUS_LED_GREEN MT3620_GPIO46 54 | 55 | /// Status LED Blue channel is GPIO47. 56 | #define MT3620_RDB_STATUS_LED_BLUE MT3620_GPIO47 57 | 58 | /// Networking LED Red channel is GPIO48. 59 | #define MT3620_RDB_NETWORKING_LED_RED MT3620_GPIO48 60 | 61 | /// Networking LED Green channel is GPIO14. 62 | #define MT3620_RDB_NETWORKING_LED_GREEN MT3620_GPIO14 63 | 64 | /// Networking LED Blue channel is GPIO11. 65 | #define MT3620_RDB_NETWORKING_LED_BLUE MT3620_GPIO11 66 | 67 | /// Button A is GPIO12. 68 | #define MT3620_RDB_BUTTON_A MT3620_GPIO12 69 | 70 | /// Button B is GPIO13. 71 | #define MT3620_RDB_BUTTON_B MT3620_GPIO13 72 | 73 | // Header 1, pin 1 is SYS_RST 74 | // Header 1, pin 2 is GND 75 | 76 | /// GPIO59 is exposed on header 1, pin 3 77 | #define MT3620_RDB_HEADER1_PIN3_GPIO MT3620_GPIO59 78 | 79 | /// GPIO0 is exposed on header 1, pin 4 80 | #define MT3620_RDB_HEADER1_PIN4_GPIO MT3620_GPIO0 81 | 82 | /// GPIO56 is exposed on header 1, pin 5 83 | #define MT3620_RDB_HEADER1_PIN5_GPIO MT3620_GPIO56 84 | 85 | /// GPIO1 is exposed on header 1, pin 6 86 | #define MT3620_RDB_HEADER1_PIN6_GPIO MT3620_GPIO1 87 | 88 | /// GPIO58 is exposed on header 1, pin 7 89 | #define MT3620_RDB_HEADER1_PIN7_GPIO MT3620_GPIO58 90 | 91 | /// GPIO2 is exposed on header 1, pin 8 92 | #define MT3620_RDB_HEADER1_PIN8_GPIO MT3620_GPIO2 93 | 94 | /// GPIO57 is exposed on header 1, pin 9 95 | #define MT3620_RDB_HEADER1_PIN9_GPIO MT3620_GPIO57 96 | 97 | /// GPIO3 is exposed on header 1, pin 10 98 | #define MT3620_RDB_HEADER1_PIN10_GPIO MT3620_GPIO3 99 | 100 | /// GPIO60 is exposed on header 1, pin 11 101 | #define MT3620_RDB_HEADER1_PIN11_GPIO MT3620_GPIO60 102 | 103 | /// GPIO4 is exposed on header 1, pin 12 104 | #define MT3620_RDB_HEADER1_PIN12_GPIO MT3620_GPIO4 105 | 106 | /// GPIO28 is exposed on header 2, pin 1 107 | #define MT3620_RDB_HEADER2_PIN1_GPIO MT3620_GPIO28 108 | 109 | // Header 2, pin 2 is GND 110 | 111 | /// GPIO26 is exposed on header 2, pin 3 112 | #define MT3620_RDB_HEADER2_PIN3_GPIO MT3620_GPIO26 113 | 114 | /// GPIO5 is exposed on header 2, pin 4 115 | #define MT3620_RDB_HEADER2_PIN4_GPIO MT3620_GPIO5 116 | 117 | /// GPIO29 is exposed on header 2, pin 5 118 | #define MT3620_RDB_HEADER2_PIN5_GPIO MT3620_GPIO29 119 | 120 | /// GPIO6 is exposed on header 2, pin 6 121 | #define MT3620_RDB_HEADER2_PIN6_GPIO MT3620_GPIO6 122 | 123 | /// GPIO27 is exposed on header 2, pin 7 124 | #define MT3620_RDB_HEADER2_PIN7_GPIO MT3620_GPIO27 125 | 126 | /// ISU0 I2C is exposed on header 2, pins 1, 3, 5, 7 127 | #define MT3620_RDB_HEADER2_ISU0_I2C MT3620_I2C_ISU0 128 | 129 | /// ISU0 SPI is exposed on header 2, pins 1, 3, 5, 7 130 | #define MT3620_RDB_HEADER2_ISU0_SPI MT3620_SPI_ISU0 131 | 132 | /// ISU0 UART is exposed on header 2, pins 1, 3, 5, 7 133 | #define MT3620_RDB_HEADER2_ISU0_UART MT3620_UART_ISU0 134 | 135 | /// GPIO7 is exposed on header 2, pin 8 136 | #define MT3620_RDB_HEADER2_PIN8_GPIO MT3620_GPIO7 137 | 138 | /// GPIO30 is exposed on header 2, pin 9 139 | #define MT3620_RDB_HEADER2_PIN9_GPIO MT3620_GPIO30 140 | 141 | // Header 2, pin 10 is ADC VREF 142 | 143 | /// GPIO41 is exposed on header 2, pin 11 144 | #define MT3620_RDB_HEADER2_PIN11_GPIO MT3620_GPIO41 145 | 146 | /// GPIO43 is exposed on header 2, pin 12 147 | #define MT3620_RDB_HEADER2_PIN12_GPIO MT3620_GPIO43 148 | 149 | /// GPIO42 is exposed on header 2, pin 13 150 | #define MT3620_RDB_HEADER2_PIN13_GPIO MT3620_GPIO42 151 | 152 | /// GPIO44 is exposed on header 2, pin 14 153 | #define MT3620_RDB_HEADER2_PIN14_GPIO MT3620_GPIO44 154 | 155 | // Header 3, pin 1 is 5V 156 | // Header 3, pin 2 is GND 157 | // Header 3, pin 3 is 3V3 158 | // Header 3, pin 4 is RTC_WAKEUP 159 | 160 | /// GPIO66 is exposed on header 3, pin 5 161 | #define MT3620_RDB_HEADER3_PIN5_GPIO MT3620_GPIO66 162 | 163 | // Header 3, pin 6 is IO0 UART TX 164 | 165 | /// GPIO67 is exposed on header 3, pin 7 166 | #define MT3620_RDB_HEADER3_PIN7_GPIO MT3620_GPIO67 167 | 168 | // Header 3, pin 8 is IO1 UART TX 169 | 170 | /// GPIO68 is exposed on header 3, pin 9 171 | #define MT3620_RDB_HEADER3_PIN9_GPIO MT3620_GPIO68 172 | 173 | // Header 3, pin 10 is PMU EN 174 | 175 | /// GPIO69 is exposed on header 3, pin 11 176 | #define MT3620_RDB_HEADER3_PIN11_GPIO MT3620_GPIO69 177 | 178 | /// ISU3 I2C is exposed on header 3, pins 5, 7, 9, 11 179 | #define MT3620_RDB_HEADER3_ISU3_I2C MT3620_I2C_ISU3 180 | 181 | /// ISU3 SPI is exposed on header 3, pins 5, 7, 9, 11 182 | #define MT3620_RDB_HEADER3_ISU3_SPI MT3620_SPI_ISU3 183 | 184 | /// ISU3 UART is exposed on header 3, pins 5, 7, 9, 11 185 | #define MT3620_RDB_HEADER3_ISU3_UART MT3620_UART_ISU3 186 | 187 | /// GPIO70 is exposed on header 3, pin 12 188 | #define MT3620_RDB_HEADER3_PIN12_GPIO MT3620_GPIO70 189 | 190 | // Header 4, pin 1 is SWDIO 191 | // Header 4, pin 2 is GND 192 | // Header 4, pin 3 is SWCLK 193 | // Header 4, pin 4 is SWO 194 | 195 | /// GPIO33 is exposed on header 4, pin 5 196 | #define MT3620_RDB_HEADER4_PIN5_GPIO MT3620_GPIO33 197 | 198 | /// GPIO38 is exposed on header 4, pin 6 199 | #define MT3620_RDB_HEADER4_PIN6_GPIO MT3620_GPIO38 200 | 201 | /// GPIO31 is exposed on header 4, pin 7 202 | #define MT3620_RDB_HEADER4_PIN7_GPIO MT3620_GPIO31 203 | 204 | /// GPIO36 is exposed on header 4, pin 8 205 | #define MT3620_RDB_HEADER4_PIN8_GPIO MT3620_GPIO36 206 | 207 | /// GPIO34 is exposed on header 4, pin 9 208 | #define MT3620_RDB_HEADER4_PIN9_GPIO MT3620_GPIO34 209 | 210 | /// GPIO39 is exposed on header 4, pin 10 211 | #define MT3620_RDB_HEADER4_PIN10_GPIO MT3620_GPIO39 212 | 213 | /// GPIO32 is exposed on header 4, pin 11 214 | #define MT3620_RDB_HEADER4_PIN11_GPIO MT3620_GPIO32 215 | 216 | /// ISU1 I2C is exposed on header 4, pins 5, 7, 9, 11 217 | #define MT3620_RDB_HEADER4_ISU12_I2C MT3620_I2C_ISU1 218 | 219 | /// ISU1 SPI is exposed on header 4, pins 5, 7, 9, 11 220 | #define MT3620_RDB_HEADER4_ISU1_SPI MT3620_SPI_ISU1 221 | 222 | /// ISU1 UART is exposed on header 4, pins 5, 7, 9, 11 223 | #define MT3620_RDB_HEADER4_ISU1_UART MT3620_UART_ISU1 224 | 225 | /// GPIO37 is exposed on header 4, pin 12 226 | #define MT3620_RDB_HEADER4_PIN12_GPIO MT3620_GPIO37 227 | 228 | /// ISU2 I2C is exposed on header 4, pins 6, 8, 10, 12 229 | #define MT3620_RDB_HEADER4_ISU2_I2C MT3620_I2C_ISU2 230 | 231 | /// ISU2 SPI is exposed on header 4, pins 6, 8, 10, 12 232 | #define MT3620_RDB_HEADER4_ISU2_SPI MT3620_SPI_ISU2 233 | 234 | /// ISU2 UART is exposed on header 4, pins 6, 8, 10, 12 235 | #define MT3620_RDB_HEADER4_ISU2_UART MT3620_UART_ISU2 236 | 237 | /// GPIO35 is exposed on header 4, pin 13 238 | #define MT3620_RDB_HEADER4_PIN13_GPIO MT3620_GPIO35 239 | 240 | /// GPIO40 is exposed on header 4, pin 14 241 | #define MT3620_RDB_HEADER4_PIN14_GPIO MT3620_GPIO40 242 | -------------------------------------------------------------------------------- /AvnetStarterKitReferenceDesign/parson.h: -------------------------------------------------------------------------------- 1 | /* 2 | This source code comes from Git repository 3 | https://github.com/kgabis/parson at commit id 4f3eaa6 4 | Patched to avoid any usage of fopen(), and removed implicit 5 | cast warnings by making them explicit. 6 | */ 7 | 8 | /* 9 | Parson ( http://kgabis.github.com/parson/ ) 10 | Copyright (c) 2012 - 2017 Krzysztof Gabis 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy 13 | of this software and associated documentation files (the "Software"), to deal 14 | in the Software without restriction, including without limitation the rights 15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | copies of the Software, and to permit persons to whom the Software is 17 | furnished to do so, subject to the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be included in 20 | all copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | THE SOFTWARE. 29 | */ 30 | 31 | #ifndef parson_parson_h 32 | #define parson_parson_h 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | #include /* size_t */ 39 | 40 | /* Types and enums */ 41 | typedef struct json_object_t JSON_Object; 42 | typedef struct json_array_t JSON_Array; 43 | typedef struct json_value_t JSON_Value; 44 | 45 | enum json_value_type { 46 | JSONError = -1, 47 | JSONNull = 1, 48 | JSONString = 2, 49 | JSONNumber = 3, 50 | JSONObject = 4, 51 | JSONArray = 5, 52 | JSONBoolean = 6 53 | }; 54 | typedef int JSON_Value_Type; 55 | 56 | enum json_result_t { JSONSuccess = 0, JSONFailure = -1 }; 57 | typedef int JSON_Status; 58 | 59 | typedef void *(*JSON_Malloc_Function)(size_t); 60 | typedef void (*JSON_Free_Function)(void *); 61 | 62 | /* Call only once, before calling any other function from parson API. If not called, malloc and free 63 | from stdlib will be used for all allocations */ 64 | void json_set_allocation_functions(JSON_Malloc_Function malloc_fun, JSON_Free_Function free_fun); 65 | 66 | /* Parses first JSON value in a string, returns NULL in case of error */ 67 | JSON_Value *json_parse_string(const char *string); 68 | 69 | /* Parses first JSON value in a string and ignores comments (/ * * / and //), 70 | returns NULL in case of error */ 71 | JSON_Value *json_parse_string_with_comments(const char *string); 72 | 73 | /* Serialization */ 74 | size_t json_serialization_size(const JSON_Value *value); /* returns 0 on fail */ 75 | JSON_Status json_serialize_to_buffer(const JSON_Value *value, char *buf, size_t buf_size_in_bytes); 76 | char *json_serialize_to_string(const JSON_Value *value); 77 | 78 | /* Pretty serialization */ 79 | size_t json_serialization_size_pretty(const JSON_Value *value); /* returns 0 on fail */ 80 | JSON_Status json_serialize_to_buffer_pretty(const JSON_Value *value, char *buf, 81 | size_t buf_size_in_bytes); 82 | char *json_serialize_to_string_pretty(const JSON_Value *value); 83 | 84 | void json_free_serialized_string(char *string); /* frees string from json_serialize_to_string and 85 | json_serialize_to_string_pretty */ 86 | 87 | /* Comparing */ 88 | int json_value_equals(const JSON_Value *a, const JSON_Value *b); 89 | 90 | /* Validation 91 | This is *NOT* JSON Schema. It validates json by checking if object have identically 92 | named fields with matching types. 93 | For example schema {"name":"", "age":0} will validate 94 | {"name":"Joe", "age":25} and {"name":"Joe", "age":25, "gender":"m"}, 95 | but not {"name":"Joe"} or {"name":"Joe", "age":"Cucumber"}. 96 | In case of arrays, only first value in schema is checked against all values in tested array. 97 | Empty objects ({}) validate all objects, empty arrays ([]) validate all arrays, 98 | null validates values of every type. 99 | */ 100 | JSON_Status json_validate(const JSON_Value *schema, const JSON_Value *value); 101 | 102 | /* 103 | * JSON Object 104 | */ 105 | JSON_Value *json_object_get_value(const JSON_Object *object, const char *name); 106 | const char *json_object_get_string(const JSON_Object *object, const char *name); 107 | JSON_Object *json_object_get_object(const JSON_Object *object, const char *name); 108 | JSON_Array *json_object_get_array(const JSON_Object *object, const char *name); 109 | double json_object_get_number(const JSON_Object *object, const char *name); /* returns 0 on fail */ 110 | int json_object_get_boolean(const JSON_Object *object, const char *name); /* returns -1 on fail */ 111 | 112 | /* dotget functions enable addressing values with dot notation in nested objects, 113 | just like in structs or c++/java/c# objects (e.g. objectA.objectB.value). 114 | Because valid names in JSON can contain dots, some values may be inaccessible 115 | this way. */ 116 | JSON_Value *json_object_dotget_value(const JSON_Object *object, const char *name); 117 | const char *json_object_dotget_string(const JSON_Object *object, const char *name); 118 | JSON_Object *json_object_dotget_object(const JSON_Object *object, const char *name); 119 | JSON_Array *json_object_dotget_array(const JSON_Object *object, const char *name); 120 | double json_object_dotget_number(const JSON_Object *object, 121 | const char *name); /* returns 0 on fail */ 122 | int json_object_dotget_boolean(const JSON_Object *object, 123 | const char *name); /* returns -1 on fail */ 124 | 125 | /* Functions to get available names */ 126 | size_t json_object_get_count(const JSON_Object *object); 127 | const char *json_object_get_name(const JSON_Object *object, size_t index); 128 | JSON_Value *json_object_get_value_at(const JSON_Object *object, size_t index); 129 | JSON_Value *json_object_get_wrapping_value(const JSON_Object *object); 130 | 131 | /* Functions to check if object has a value with a specific name. Returned value is 1 if object has 132 | * a value and 0 if it doesn't. dothas functions behave exactly like dotget functions. */ 133 | int json_object_has_value(const JSON_Object *object, const char *name); 134 | int json_object_has_value_of_type(const JSON_Object *object, const char *name, 135 | JSON_Value_Type type); 136 | 137 | int json_object_dothas_value(const JSON_Object *object, const char *name); 138 | int json_object_dothas_value_of_type(const JSON_Object *object, const char *name, 139 | JSON_Value_Type type); 140 | 141 | /* Creates new name-value pair or frees and replaces old value with a new one. 142 | * json_object_set_value does not copy passed value so it shouldn't be freed afterwards. */ 143 | JSON_Status json_object_set_value(JSON_Object *object, const char *name, JSON_Value *value); 144 | JSON_Status json_object_set_string(JSON_Object *object, const char *name, const char *string); 145 | JSON_Status json_object_set_number(JSON_Object *object, const char *name, double number); 146 | JSON_Status json_object_set_boolean(JSON_Object *object, const char *name, int boolean); 147 | JSON_Status json_object_set_null(JSON_Object *object, const char *name); 148 | 149 | /* Works like dotget functions, but creates whole hierarchy if necessary. 150 | * json_object_dotset_value does not copy passed value so it shouldn't be freed afterwards. */ 151 | JSON_Status json_object_dotset_value(JSON_Object *object, const char *name, JSON_Value *value); 152 | JSON_Status json_object_dotset_string(JSON_Object *object, const char *name, const char *string); 153 | JSON_Status json_object_dotset_number(JSON_Object *object, const char *name, double number); 154 | JSON_Status json_object_dotset_boolean(JSON_Object *object, const char *name, int boolean); 155 | JSON_Status json_object_dotset_null(JSON_Object *object, const char *name); 156 | 157 | /* Frees and removes name-value pair */ 158 | JSON_Status json_object_remove(JSON_Object *object, const char *name); 159 | 160 | /* Works like dotget function, but removes name-value pair only on exact match. */ 161 | JSON_Status json_object_dotremove(JSON_Object *object, const char *key); 162 | 163 | /* Removes all name-value pairs in object */ 164 | JSON_Status json_object_clear(JSON_Object *object); 165 | 166 | /* 167 | *JSON Array 168 | */ 169 | JSON_Value *json_array_get_value(const JSON_Array *array, size_t index); 170 | const char *json_array_get_string(const JSON_Array *array, size_t index); 171 | JSON_Object *json_array_get_object(const JSON_Array *array, size_t index); 172 | JSON_Array *json_array_get_array(const JSON_Array *array, size_t index); 173 | double json_array_get_number(const JSON_Array *array, size_t index); /* returns 0 on fail */ 174 | int json_array_get_boolean(const JSON_Array *array, size_t index); /* returns -1 on fail */ 175 | size_t json_array_get_count(const JSON_Array *array); 176 | JSON_Value *json_array_get_wrapping_value(const JSON_Array *array); 177 | 178 | /* Frees and removes value at given index, does nothing and returns JSONFailure if index doesn't 179 | * exist. Order of values in array may change during execution. */ 180 | JSON_Status json_array_remove(JSON_Array *array, size_t i); 181 | 182 | /* Frees and removes from array value at given index and replaces it with given one. 183 | * Does nothing and returns JSONFailure if index doesn't exist. 184 | * json_array_replace_value does not copy passed value so it shouldn't be freed afterwards. */ 185 | JSON_Status json_array_replace_value(JSON_Array *array, size_t i, JSON_Value *value); 186 | JSON_Status json_array_replace_string(JSON_Array *array, size_t i, const char *string); 187 | JSON_Status json_array_replace_number(JSON_Array *array, size_t i, double number); 188 | JSON_Status json_array_replace_boolean(JSON_Array *array, size_t i, int boolean); 189 | JSON_Status json_array_replace_null(JSON_Array *array, size_t i); 190 | 191 | /* Frees and removes all values from array */ 192 | JSON_Status json_array_clear(JSON_Array *array); 193 | 194 | /* Appends new value at the end of array. 195 | * json_array_append_value does not copy passed value so it shouldn't be freed afterwards. */ 196 | JSON_Status json_array_append_value(JSON_Array *array, JSON_Value *value); 197 | JSON_Status json_array_append_string(JSON_Array *array, const char *string); 198 | JSON_Status json_array_append_number(JSON_Array *array, double number); 199 | JSON_Status json_array_append_boolean(JSON_Array *array, int boolean); 200 | JSON_Status json_array_append_null(JSON_Array *array); 201 | 202 | /* 203 | *JSON Value 204 | */ 205 | JSON_Value *json_value_init_object(void); 206 | JSON_Value *json_value_init_array(void); 207 | JSON_Value *json_value_init_string(const char *string); /* copies passed string */ 208 | JSON_Value *json_value_init_number(double number); 209 | JSON_Value *json_value_init_boolean(int boolean); 210 | JSON_Value *json_value_init_null(void); 211 | JSON_Value *json_value_deep_copy(const JSON_Value *value); 212 | void json_value_free(JSON_Value *value); 213 | 214 | JSON_Value_Type json_value_get_type(const JSON_Value *value); 215 | JSON_Object *json_value_get_object(const JSON_Value *value); 216 | JSON_Array *json_value_get_array(const JSON_Value *value); 217 | const char *json_value_get_string(const JSON_Value *value); 218 | double json_value_get_number(const JSON_Value *value); 219 | int json_value_get_boolean(const JSON_Value *value); 220 | JSON_Value *json_value_get_parent(const JSON_Value *value); 221 | 222 | /* Same as above, but shorter */ 223 | JSON_Value_Type json_type(const JSON_Value *value); 224 | JSON_Object *json_object(const JSON_Value *value); 225 | JSON_Array *json_array(const JSON_Value *value); 226 | const char *json_string(const JSON_Value *value); 227 | double json_number(const JSON_Value *value); 228 | int json_boolean(const JSON_Value *value); 229 | 230 | #ifdef __cplusplus 231 | } 232 | #endif 233 | 234 | #endif 235 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AvnetAzureSphereStarterKitReferenceDesign (Deprecated!!!) 2 | Reference design demonstrating Avnet Azure Sphere Starter Kit features. 3 | 4 | Note this repo has been deprecated. Please use the repo @ https://github.com/Avnet/AzureSphereHacksterTTC.git 5 | 6 | 7 | --------------------------------------------------------------------------------