├── .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 |
--------------------------------------------------------------------------------