diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/.pio/build/project.checksum b/.pio/build/project.checksum new file mode 100644 index 0000000..fa7d2a1 --- /dev/null +++ b/.pio/build/project.checksum @@ -0,0 +1 @@ +c6791a4fbf98852daca2023ec98649d785fdba3c \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index a43f083..61966d4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,11 +4,9 @@ language: generic env: global: - - IDE_VERSION=1.8.10 + - IDE_VERSION=1.6.11 matrix: - - BOARD="esp8266:esp8266:huzzah:FlashSize=4M3M,CpuFrequency=80" - - BOARD="esp8266:esp8266:thing" - - BOARD="esp32:esp32:huzzah" + - BOARD="arduino:samd:nano_33_iot" before_install: - /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16 - sleep 3 @@ -17,28 +15,38 @@ before_install: - tar xf arduino-$IDE_VERSION-linux64.tar.xz - mv arduino-$IDE_VERSION $HOME/arduino-ide - export PATH=$PATH:$HOME/arduino-ide + - if [[ "$BOARD" =~ "arduino:samd:" ]]; then + arduino --install-boards arduino:samd; + arduino --install-library WiFiNINA; + arduino --install-library WiFi101; + arduino --install-library RTCZero; + arduino --install-library NTPClient; + fi - if [[ "$BOARD" =~ "esp8266:esp8266:" ]]; then arduino --pref "boardsmanager.additional.urls=http://arduino.esp8266.com/stable/package_esp8266com_index.json" --install-boards esp8266:esp8266; arduino --pref "boardsmanager.additional.urls=" --save-prefs; arduino --install-library NTPClient; - fi - - if [[ "$BOARD" =~ "esp32:esp32:" ]]; then - arduino --pref "boardsmanager.additional.urls=https://dl.espressif.com/dl/package_esp32_index.json" --install-boards esp32:esp32; - arduino --pref "boardsmanager.additional.urls=" --save-prefs; arduino --install-library NTPClient; fi - - findAndReplace() { sed -i'' -e"s|$1|$2|g" "$3"; } - buildExampleSketch() { - EXAMPLE_SKETCH=$PWD/examples/iothub_ll_telemetry_sample/iothub_ll_telemetry_sample.ino; + EXAMPLE_SKETCH=$PWD/examples/ArduinoNano33iot/iothub_ll_telemetry_sample/iothub_ll_telemetry_sample.ino; + + if [[ "$BOARD" =~ "esp8266:esp8266:" ]]; then + findAndReplace WiFi101 ESP8266WiFi $EXAMPLE_SKETCH; + findAndReplace WiFiSSLClient WiFiClientSecure $EXAMPLE_SKETCH; + findAndReplace WiFiUdp WiFiUdp $EXAMPLE_SKETCH; + fi + + cat $EXAMPLE_SKETCH; arduino --verbose-build --verify --board $BOARD $EXAMPLE_SKETCH; } install: + - arduino --install-library "AzureIoTHub" - arduino --install-library "AzureIoTUtility" - - arduino --install-library "AzureIoTSocket_WiFi" - - arduino --install-library "AzureIoTProtocol_MQTT" - arduino --install-library "AzureIoTProtocol_HTTP" + - arduino --install-library "AzureIoTProtocol_MQTT" - ln -s $PWD $HOME/Arduino/libraries/. script: - - buildExampleSketch telemetry_sample.c + - buildExampleSketch iothub_ll_telemetry_sample \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..e80666b --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..6c3cbaa --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,12 @@ +{ + "cSpell.words": [ + "ddont", + "iothub", + "ll", + "samd", + "sample", + "telemetry", + "uploadtoblob", + "use" + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..f97e9e6 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,26 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "type": "shell", + "command": "msbuild", + "args": [ + // Ask msbuild to generate full paths for file names. + "/property:GenerateFullPaths=true", + "/t:build", + // Do not generate summary otherwise it leads to duplicate errors in Problems panel + "/consoleloggerparameters:NoSummary" + ], + "group": "build", + "presentation": { + // Reveal the output only if unrecognized errors occur. + "reveal": "silent" + }, + // Use the standard MS compiler pattern to detect errors, warnings and infos + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md index 1db40ac..9b19be5 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,40 @@ You should have the following ready before beginning with any board: 9. Access the [Huzzah Get Started](https://azure.microsoft.com/en-us/documentation/samples/iot-hub-c-huzzah-getstartedkit/) tutorial to learn more about Microsoft Huzzah Dev Kit. + +## ARDUINO NANO 33 IOT + +##### ARDUINO NANO 33 IOT board + +1. Install Arduino Nano33 IoT board support into your Arduino IDE. + + - Open Boards Manager from Tools > Board menu and install arduino nano 33 iot platform 1.8.11 or later + + - Select your Arduino Nano 33 IoT board from Tools > Board menu after installation + +2. Open the `iothub_ll_telemetry_sample` example from the Arduino IDE File->Examples->AzureIoTHub menu. + +3. Update Wifi SSID/Password in `iot_configs.h` + +- Ensure you are using a wifi network that does not require additional manual steps after connection, such as opening a web browser. + +4. Update IoT Hub Connection string in `iot_configs.h` + +5. Configure board library using the automation script and `python3`. If you choose this method you can skip step 6. + - Clone or download this repo: `git clone https://github.com/Azure/azure-iot-pal-arduino.git` , navigate to the downloaded sub-folder: `cd azure-iot-pal-arduino/build_all/base-libraries/AzureIoTHub/src/scripts` , and check that the script `automate_board_config.py` exists in this location. If this folder or script cannot be located, download the script [directly](https://raw.githubusercontent.com/Azure/azure-iot-pal-arduino/master/build_all/base-libraries/AzureIoTHub/src/scripts/automate_board_config.py). + - Run the script E.x.: `python3 automate_board_config.py` and select appropriate options. + - Note: if you update or reinstall your board library in Arduino you will need to run this script again. + +6. Navigate to where your arduino nano 33 iot board package is located, typically in `C:\Users\\AppData\Local\Arduino15\packages` on Windows and `~/.arduino15/packages/` on Linux + + - Navigate deeper in to `hardware/samd//` where the `platform.txt` file lives. + + - Copy the [`platform.local.txt`](https://github.com/Azure/azure-iot-arduino/blob/master/examples/iothub_ll_telemetry_sample/ArduinoNano33iot/platform.local.txt) file from the `ArduinoNano33iot` folder in the sample into the same folder as the `platform.txt`. + + - Alternatively, or for later versions of the Board Package, add the define `-DDONT_USE_UPLOADTOBLOB` to `build.extra_flags=` in `platform.txt` or a `platform.local.txt` that you create. + +7. Run the sample. + ## License See [LICENSE](LICENSE) file. diff --git a/examples/ArduinoNano33iot/iothub_ll_telemetry_sample/iot_configs.h b/examples/ArduinoNano33iot/iothub_ll_telemetry_sample/iot_configs.h new file mode 100644 index 0000000..cea4b62 --- /dev/null +++ b/examples/ArduinoNano33iot/iothub_ll_telemetry_sample/iot_configs.h @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#ifndef IOT_CONFIGS_H +#define IOT_CONFIGS_H + +/** + * WiFi setup + */ +#define IOT_CONFIG_WIFI_SSID "InfoNet-BB" +#define IOT_CONFIG_WIFI_PASSWORD "pakistan313" + +/** + * IoT Hub Device Connection String setup + * Find your Device Connection String by going to your Azure portal, creating (or navigating to) an IoT Hub, + * navigating to IoT Devices tab on the left, and creating (or selecting an existing) IoT Device. + * Then click on the named Device ID, and you will have able to copy the Primary or Secondary Device Connection String to this sample. + */ +#define DEVICE_CONNECTION_STRING "HostName=ArduinoNano33IoT.azure-devices.net;DeviceId=ArduinoNano33IoTDevice;SharedAccessKey=0XrwEGjbnYkbIglMadXZ/+SOIXHrn5eVxn7EoCIBqPM=" + +// The protocol you wish to use should be uncommented +// +#define SAMPLE_MQTT +//#define SAMPLE_HTTP + +#endif /* IOT_CONFIGS_H */ diff --git a/examples/ArduinoNano33iot/iothub_ll_telemetry_sample/iothub_ll_telemetry_sample.ino b/examples/ArduinoNano33iot/iothub_ll_telemetry_sample/iothub_ll_telemetry_sample.ino new file mode 100644 index 0000000..949cc69 --- /dev/null +++ b/examples/ArduinoNano33iot/iothub_ll_telemetry_sample/iothub_ll_telemetry_sample.ino @@ -0,0 +1,313 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +// CAVEAT: This sample is to demonstrate azure IoT client concepts only and is not a guide design principles or style +// Checking of return codes and error values shall be omitted for brevity. Please practice sound engineering practices +// when writing production code. + +// Note: PLEASE see https://github.com/Azure/azure-iot-arduino#simple-sample-instructions for detailed sample setup instructions. +// Note2: To use this sample with the esp32, you MUST build the AzureIoTSocket_WiFi library by using the make_sdk.py, +// found in https://github.com/Azure/azure-iot-pal-arduino/tree/master/build_all. +// Command line example: python3 make_sdk.py -o +#include +#include +#include +#include + +#include "iot_configs.h" // You must set your wifi SSID, wifi PWD, and your IoTHub Device Connection String in iot_configs.h +#include "sample_init.h" + +#ifdef is_esp_board + #include "Esp.h" +#endif + +#ifdef is_arduino_board + #include "Arduino.h" +#endif + +#ifdef SAMPLE_MQTT + #include "AzureIoTProtocol_MQTT.h" + #include "iothubtransportmqtt.h" +#endif // SAMPLE_MQTT +#ifdef SAMPLE_HTTP + #include "AzureIoTProtocol_HTTP.h" + #include "iothubtransporthttp.h" +#endif // SAMPLE_HTTP + +static const char ssid[] = IOT_CONFIG_WIFI_SSID; +static const char pass[] = IOT_CONFIG_WIFI_PASSWORD; + +/* Define several constants/global variables */ +const int RESET_PIN = 40; +static const char* connectionString = DEVICE_CONNECTION_STRING; +static bool g_continueRunning = true; // defines whether or not the device maintains its IoT Hub connection after sending (think receiving messages from the cloud) +static size_t g_message_count_send_confirmations = 0; +static bool g_run_demo = true; + +IOTHUB_MESSAGE_HANDLE message_handle; +size_t messages_sent = 0; +#define MESSAGE_COUNT 5 // determines the number of times the device tries to send a message to the IoT Hub in the cloud. +const char* telemetry_msg = "test_message"; +const char* quit_msg = "quit"; +const char* exit_msg = "exit"; + +IOTHUB_DEVICE_CLIENT_LL_HANDLE device_ll_handle; + +static int callbackCounter; +int receiveContext = 0; + +/* -- receive_message_callback -- + * Callback method which executes upon receipt of a message originating from the IoT Hub in the cloud. + * Note: Modifying the contents of this method allows one to command the device from the cloud. + */ +static IOTHUBMESSAGE_DISPOSITION_RESULT receive_message_callback(IOTHUB_MESSAGE_HANDLE message, void* userContextCallback) +{ + int* counter = (int*)userContextCallback; + const unsigned char* buffer; + size_t size; + const char* messageId; + + // Message properties + if ((messageId = IoTHubMessage_GetMessageId(message)) == NULL) + { + messageId = ""; + } + + // Message content + if (IoTHubMessage_GetByteArray(message, (const unsigned char**)&buffer, &size) != IOTHUB_MESSAGE_OK) + { + LogInfo("unable to retrieve the message data\r\n"); + } + else + { + LogInfo("Received Message [%d]\r\n Message ID: %s\r\n Data: <<<%.*s>>> & Size=%d\r\n", *counter, messageId, (int)size, buffer, (int)size); + // If we receive the word 'quit' then we stop running + if (size == (strlen(quit_msg) * sizeof(char)) && memcmp(buffer, quit_msg, size) == 0) + { + g_continueRunning = false; + } + } + + /* Some device specific action code goes here... */ + (*counter)++; + return IOTHUBMESSAGE_ACCEPTED; +} + + +/* -- send_confirm_callback -- + * Callback method which executes upon confirmation that a message originating from this device has been received by the IoT Hub in the cloud. + */ +static void send_confirm_callback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback) +{ + (void)userContextCallback; + // When a message is sent this callback will get envoked + g_message_count_send_confirmations++; + Serial.println("confirmation callback recieved"); + LogInfo("Confirmation callback received for message %lu with result %s\r\n", (unsigned long)g_message_count_send_confirmations, MU_ENUM_TO_STRING(IOTHUB_CLIENT_CONFIRMATION_RESULT, result)); + Serial.println((unsigned long)g_message_count_send_confirmations); + Serial.println(MU_ENUM_TO_STRING(IOTHUB_CLIENT_CONFIRMATION_RESULT, result)); +} + +/* -- connection_status_callback -- + * Callback method which executes on receipt of a connection status message from the IoT Hub in the cloud. + */ +static void connection_status_callback(IOTHUB_CLIENT_CONNECTION_STATUS result, IOTHUB_CLIENT_CONNECTION_STATUS_REASON reason, void* user_context) +{ + (void)reason; + (void)user_context; + // This sample DOES NOT take into consideration network outages. + if (result == IOTHUB_CLIENT_CONNECTION_AUTHENTICATED) + { + Serial.println("Device is connected to iothub"); + LogInfo("The device client is connected to iothub\r\n"); + } + else + { + Serial.println("Device is unable to connected to iothub"); + LogInfo("The device client has been disconnected\r\n"); + } +} + +/* -- reset_esp_helper -- + * waits for call of exit_msg over Serial line to reset device + */ +static void reset_esp_helper() +{ +#ifdef is_esp_board + // Read from local serial + if (Serial.available()){ + String s1 = Serial.readStringUntil('\n');// s1 is String type variable. + Serial.print("Received Data: "); + Serial.println(s1);//display same received Data back in serial monitor. + + // Restart device upon receipt of 'exit' call. + int e_start = s1.indexOf('e'); + String ebit = (String) s1.substring(e_start, e_start+4); + if(ebit == exit_msg) + { + ESP.restart(); + } + } +#endif // is_esp_board +} +// void(* resetFunc) (void) = 0; +// static void reset_arduino_helper() +// { +// #ifdef is_arduino_board +// delay(5000); +// digitalWrite(RESET_PIN, LOW); +// // Read from local serial +// if (Serial.available()){ +// String s1 = Serial.readStringUntil('\n');// s1 is String type variable. +// Serial.print("Received Data: "); +// Serial.println(s1);//display same received Data back in serial monitor. + +// // Restart device upon receipt of 'exit' call. +// int e_start = s1.indexOf('e'); +// String ebit = (String) s1.substring(e_start, e_start+4); +// if(ebit == exit_msg) +// { +// resetFunc(); +// } +// } +// #endif // is_arduino_board +// } +/* -- run_demo -- + * Runs active task of sending telemetry to IoTHub + * WARNING: only call this function once, as it includes steps to destroy handles and clean up at the end. + */ +static void run_demo() +{ + int result = 0; + + // action phase of the program, sending messages to the IoT Hub in the cloud. + do + { + if (messages_sent < MESSAGE_COUNT) + { + // Construct the iothub message from a string or a byte array + message_handle = IoTHubMessage_CreateFromString(telemetry_msg); + //message_handle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, strlen(msgText))); + + // Set Message property + /*(void)IoTHubMessage_SetMessageId(message_handle, "MSG_ID"); + (void)IoTHubMessage_SetCorrelationId(message_handle, "CORE_ID"); + (void)IoTHubMessage_SetContentTypeSystemProperty(message_handle, "application%2fjson"); + (void)IoTHubMessage_SetContentEncodingSystemProperty(message_handle, "utf-8");*/ + + // Add custom properties to message + // (void)IoTHubMessage_SetProperty(message_handle, "property_key", "property_value"); + + LogInfo("Sending message %d to IoTHub\r\n", (int)(messages_sent + 1)); + Serial.println("Sending message to iothub"); + result = IoTHubDeviceClient_LL_SendEventAsync(device_ll_handle, message_handle, send_confirm_callback, NULL); + // The message is copied to the sdk so the we can destroy it + IoTHubMessage_Destroy(message_handle); + + messages_sent++; + } + else if (g_message_count_send_confirmations >= MESSAGE_COUNT) + { + // After all messages are all received stop running + Serial.println("else called in do"); + g_continueRunning = false; + } + + IoTHubDeviceClient_LL_DoWork(device_ll_handle); + ThreadAPI_Sleep(3); + // reset_esp_helper(); + // reset_arduino_helper(); + + } while (g_continueRunning); + + // Clean up the iothub sdk handle + IoTHubDeviceClient_LL_Destroy(device_ll_handle); + // Free all the sdk subsystem + IoTHub_Deinit(); + + LogInfo("done with sending"); + return; +} +void setup() { + + + // digitalWrite(RESET_PIN, HIGH); + // pinMode(RESET_PIN, OUTPUT); + + // Select the Protocol to use with the connection +#ifdef SAMPLE_MQTT + IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol = MQTT_Protocol; +#endif // SAMPLE_MQTT +#ifdef SAMPLE_HTTP + IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol = HTTP_Protocol; +#endif // SAMPLE_HTTP + Serial.println("before sample innit"); + + sample_init(ssid, pass); + Serial.println("after sample inti"); + + // Used to initialize IoTHub SDK subsystem + (void)IoTHub_Init(); + // Create the iothub handle here + device_ll_handle = IoTHubDeviceClient_LL_CreateFromConnectionString(connectionString, protocol); + LogInfo("Creating IoTHub Device handle\r\n"); + + if (device_ll_handle == NULL) + { + LogInfo("Error AZ002: Failure creating Iothub device. Hint: Check you connection string.\r\n"); + Serial.println("error creating device handle"); + } + else + { + // Set any option that are neccessary. + // For available options please see the iothub_sdk_options.md documentation in the main C SDK + // turn off diagnostic sampling + int diag_off = 0; + Serial.println("device handle created sucessfully"); + IoTHubDeviceClient_LL_SetOption(device_ll_handle, OPTION_DIAGNOSTIC_SAMPLING_PERCENTAGE, &diag_off); + +#ifndef SAMPLE_HTTP + // Example sdk status tracing for troubleshooting + bool traceOn = true; + IoTHubDeviceClient_LL_SetOption(device_ll_handle, OPTION_LOG_TRACE, &traceOn); +#endif // SAMPLE_HTTP + + // Setting the Trusted Certificate. + IoTHubDeviceClient_LL_SetOption(device_ll_handle, OPTION_TRUSTED_CERT, certificates); + +#if defined SAMPLE_MQTT + //Setting the auto URL Encoder (recommended for MQTT). Please use this option unless + //you are URL Encoding inputs yourself. + //ONLY valid for use with MQTT + bool urlEncodeOn = true; + IoTHubDeviceClient_LL_SetOption(device_ll_handle, OPTION_AUTO_URL_ENCODE_DECODE, &urlEncodeOn); + /* Setting Message call back, so we can receive Commands. */ + if (IoTHubClient_LL_SetMessageCallback(device_ll_handle, receive_message_callback, &receiveContext) != IOTHUB_CLIENT_OK) + { + LogInfo("ERROR: IoTHubClient_LL_SetMessageCallback..........FAILED!\r\n"); + Serial.println("Error IoTHubClient_LL_SetMessageCallback "); + } + else + { + Serial.println("PASS IoTHubClient_LL_SetMessageCallback "); + } +#endif // SAMPLE_MQTT + + // Setting connection status callback to get indication of connection to iothub + (void)IoTHubDeviceClient_LL_SetConnectionStatusCallback(device_ll_handle, connection_status_callback, NULL); + + } +} + +void loop(void) +{ + + if (g_run_demo) + { + Serial.println("running demo"); + run_demo(); + g_run_demo = false; + } +// reset_esp_helper(); +// reset_arduino_helper(); +} diff --git a/examples/ArduinoNano33iot/iothub_ll_telemetry_sample/platform.local.txt b/examples/ArduinoNano33iot/iothub_ll_telemetry_sample/platform.local.txt new file mode 100644 index 0000000..ab5bf54 --- /dev/null +++ b/examples/ArduinoNano33iot/iothub_ll_telemetry_sample/platform.local.txt @@ -0,0 +1,243 @@ +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +# Arduino SAMD Core and platform. +# +# For more info: +# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification + +name=Arduino SAMD (32-bits ARM Cortex-M0+) Boards +version=1.8.11 + +# Compile variables +# ----------------- + +compiler.warning_flags=-w +compiler.warning_flags.none=-w +compiler.warning_flags.default= +compiler.warning_flags.more=-Wall +compiler.warning_flags.all=-Wall -Wextra + +# EXPERIMENTAL feature: optimization flags +# - this is alpha and may be subject to change without notice +compiler.optimization_flags=-Os +compiler.optimization_flags.release=-Os +compiler.optimization_flags.debug=-Og -g3 + +compiler.path={runtime.tools.arm-none-eabi-gcc-7-2017q4.path}/bin/ +compiler.c.cmd=arm-none-eabi-gcc +compiler.c.flags=-mcpu={build.mcu} -mthumb -c -g {compiler.optimization_flags} {compiler.warning_flags} -std=gnu11 -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -MMD +compiler.c.elf.cmd=arm-none-eabi-g++ +compiler.c.elf.flags={compiler.optimization_flags} -Wl,--gc-sections -save-temps +compiler.S.cmd=arm-none-eabi-gcc +compiler.S.flags=-c -g -x assembler-with-cpp -MMD +compiler.cpp.cmd=arm-none-eabi-g++ +compiler.cpp.flags=-mcpu={build.mcu} -mthumb -c -g {compiler.optimization_flags} {compiler.warning_flags} -std=gnu++11 -ffunction-sections -fdata-sections -fno-threadsafe-statics -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -MMD +compiler.ar.cmd=arm-none-eabi-ar +compiler.ar.flags=rcs +compiler.objcopy.cmd=arm-none-eabi-objcopy +compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 +compiler.elf2hex.bin.flags=-O binary +compiler.elf2hex.hex.flags=-O ihex -R .eeprom +compiler.elf2hex.cmd=arm-none-eabi-objcopy +compiler.ldflags=-mcpu={build.mcu} -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align +compiler.size.cmd=arm-none-eabi-size +compiler.define=-DARDUINO= +compiler.readelf.cmd=arm-none-eabi-readelf + +# this can be overriden in boards.txt +build.extra_flags= -DDONT_USE_UPLOADTOBLOB + +# These can be overridden in platform.local.txt +compiler.c.extra_flags= +compiler.c.elf.extra_flags= +#compiler.c.elf.extra_flags=-v +compiler.cpp.extra_flags= +compiler.S.extra_flags= +compiler.ar.extra_flags= +compiler.elf2hex.extra_flags= + +compiler.arm.cmsis.c.flags="-I{runtime.tools.CMSIS-4.5.0.path}/CMSIS/Include/" "-I{runtime.tools.CMSIS-Atmel-1.2.0.path}/CMSIS/Device/ATMEL/" +compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-4.5.0.path}/CMSIS/Lib/GCC/" -larm_cortexM0l_math + +compiler.libraries.ldflags= + +# USB Flags +# --------- +build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} -DUSBCON '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' + +# Default usb manufacturer will be replaced at compile time using +# numeric vendor ID if available or by board's specific value. +build.usb_manufacturer="Unknown" + +# Compile patterns +# ---------------- + +## Compile c files +recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {compiler.arm.cmsis.c.flags} "-I{build.core.path}/api/deprecated" "-I{build.core.path}/api/deprecated-avr-comp" {includes} "{source_file}" -o "{object_file}" + +## Compile c++ files +recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {compiler.arm.cmsis.c.flags} "-I{build.core.path}/api/deprecated" "-I{build.core.path}/api/deprecated-avr-comp" {includes} "{source_file}" -o "{object_file}" + +## Compile S files +recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {compiler.arm.cmsis.c.flags} "-I{build.core.path}/api/deprecated" "-I{build.core.path}/api/deprecated-avr-comp" {includes} "{source_file}" -o "{object_file}" + +## Create archives +# archive_file_path is needed for backwards compatibility with IDE 1.6.5 or older, IDE 1.6.6 or newer overrides this value +archive_file_path={build.path}/{archive_file} +recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}" + +## Combine gc-sections, archives, and objects +recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" --specs=nano.specs --specs=nosys.specs {compiler.ldflags} -o "{build.path}/{build.project_name}.elf" {object_files} {compiler.libraries.ldflags} -Wl,--start-group {compiler.arm.cmsis.ldflags} -lm "{build.path}/{archive_file}" -Wl,--end-group + +## Create output (bin file) +recipe.objcopy.bin.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.bin.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin" + +## Create output (hex file) +recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex" + +build.preferred_out_format=bin + +## Save hex +recipe.output.tmp_file={build.project_name}.{build.preferred_out_format} +recipe.output.save_file={build.project_name}.{build.variant}.{build.preferred_out_format} + +## Compute size +recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" +recipe.size.regex=^(?:\.text|\.data|)\s+([0-9]+).* +recipe.size.regex.data=^(?:\.data|\.bss)\s+([0-9]+).* + + +# Debugger configuration (general options) +# ---------------------------------------- +# EXPERIMENTAL feature: +# - this is alpha and may be subject to change without notice +debug.executable={build.path}/{build.project_name}.elf +debug.toolchain=gcc +debug.toolchain.path={runtime.tools.arm-none-eabi-gcc-7-2017q4.path}/bin/ +debug.toolchain.prefix=arm-none-eabi- +debug.server=openocd +debug.server.openocd.path={runtime.tools.openocd-0.10.0-arduino7.path}/bin/openocd +debug.server.openocd.scripts_dir={runtime.tools.openocd-0.10.0-arduino7.path}/share/openocd/scripts/ +debug.server.openocd.script={runtime.platform.path}/variants/{build.variant}/{build.openocdscript} + +# Upload/Debug tools +# ------------------ + +# +# AVRDUDE +# +tools.avrdude.path={runtime.tools.avrdude.path} +tools.avrdude.cmd={path}/bin/avrdude +tools.avrdude.config.path={path}/etc/avrdude.conf + +tools.avrdude.upload.params.verbose=-v -v +tools.avrdude.upload.params.quiet=-q -q +tools.avrdude.upload.params.noverify=-V +tools.avrdude.upload.pattern="{cmd}" "-C{config.path}" {upload.verbose} -p{build.emu.mcu} -c{upload.protocol} -P{serial.port} -b{upload.speed} "-Uflash:w:{build.path}/{build.project_name}.hex:i" + +tools.avrdude_remote.upload.pattern="openocd --version 2>&1 | grep 2016 && if opkg update; then opkg upgrade openocd; exit 1; else echo 'Please connect your board to the Internet in order to upgrade tools' >&2; exit 1; fi || /usr/bin/run-avrdude /tmp/sketch.hex" + +tools.avrdude.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA +tools.avrdude.upload.network_pattern="{network_cmd}" -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b + +# +# BOSSA +# +tools.bossac.path={runtime.tools.bossac-1.7.0-arduino3.path} +tools.bossac.cmd=bossac +tools.bossac.cmd.windows=bossac.exe + +tools.bossac.upload.params.verbose=-i -d +tools.bossac.upload.params.quiet= +tools.bossac.upload.pattern="{path}/{cmd}" {upload.verbose} --port={serial.port.file} -U {upload.native_usb} -i -e -w -v "{build.path}/{build.project_name}.bin" -R + +tools.bossac_remote.upload.pattern=/usr/bin/run-bossac {upload.verbose} --port=ttyATH0 -U {upload.native_usb} -e -w -v /tmp/sketch.bin -R + +arduinoota.extraflags= +tools.bossac.network_cmd={runtime.tools.arduinoOTA-1.3.0.path}/bin/arduinoOTA +tools.bossac.upload.network_pattern="{network_cmd}" -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b {arduinoota.extraflags} + +# +# BOSSA (ignore binary size) +# +tools.bossacI.path={runtime.tools.bossac-1.7.0-arduino3.path} +tools.bossacI.cmd=bossac +tools.bossacI.cmd.windows=bossac.exe + +tools.bossacI.upload.params.verbose=-i -d +tools.bossacI.upload.params.quiet= +tools.bossacI.upload.pattern="{path}/{cmd}" {upload.verbose} --port={serial.port.file} -I -U {upload.native_usb} -i -e -w "{build.path}/{build.project_name}.bin" -R + +tools.bossacI_remote.upload.pattern=/usr/bin/run-bossac {upload.verbose} --port=ttyATH0 -U {upload.native_usb} -e -w -v /tmp/sketch.bin -R + +tools.bossacI.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA +tools.bossacI.upload.network_pattern="{network_cmd}" -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b + + +# +# OpenOCD sketch upload +# + +tools.openocd.path={runtime.tools.openocd-0.10.0-arduino7.path} +tools.openocd.cmd=bin/openocd +tools.openocd.cmd.windows=bin/openocd.exe + +tools.openocd.upload.params.verbose=-d2 +tools.openocd.upload.params.quiet=-d0 +tools.openocd.upload.pattern="{path}/{cmd}" {upload.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.bin} verify reset 0x2000; shutdown" + +tools.openocd.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA +tools.openocd.upload.network_pattern={network_cmd} -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b + +tools.openocd.program.params.verbose=-d2 +tools.openocd.program.params.quiet=-d0 +tools.openocd.program.pattern="{path}/{cmd}" {program.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.hex} verify reset; shutdown" + +tools.openocd.erase.params.verbose=-d3 +tools.openocd.erase.params.quiet=-d0 +tools.openocd.erase.pattern= + +tools.openocd.bootloader.params.verbose=-d2 +tools.openocd.bootloader.params.quiet=-d0 +tools.openocd.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; init; halt; at91samd bootloader 0; program {{runtime.platform.path}/bootloaders/{bootloader.file}} verify reset; shutdown" + +# +# OpenOCD sketch upload - version with configurable bootloader size +# FIXME: this programmer is a workaround for default options being overwritten by uploadUsingPreferences +# + +tools.openocd-withbootsize.path={runtime.tools.openocd-0.10.0-arduino7.path} +tools.openocd-withbootsize.cmd=bin/openocd +tools.openocd-withbootsize.cmd.windows=bin/openocd.exe + +tools.openocd-withbootsize.upload.params.verbose=-d2 +tools.openocd-withbootsize.upload.params.quiet=-d0 +tools.openocd-withbootsize.upload.pattern="{path}/{cmd}" {upload.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.bin} verify reset {bootloader.size}; shutdown" + +# Program flashes the binary at 0x0000, so use the linker script without_bootloader +tools.openocd-withbootsize.program.params.verbose=-d2 +tools.openocd-withbootsize.program.params.quiet=-d0 +tools.openocd-withbootsize.program.pattern="{path}/{cmd}" {program.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.elf} verify reset; shutdown" + +tools.openocd-withbootsize.erase.params.verbose=-d3 +tools.openocd-withbootsize.erase.params.quiet=-d0 +tools.openocd-withbootsize.erase.pattern= + +tools.openocd-withbootsize.bootloader.params.verbose=-d2 +tools.openocd-withbootsize.bootloader.params.quiet=-d0 +tools.openocd-withbootsize.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; init; halt; at91samd bootloader 0; program {{runtime.platform.path}/bootloaders/{bootloader.file}} verify reset; shutdown" + diff --git a/examples/ArduinoNano33iot/iothub_ll_telemetry_sample/sample_init.h b/examples/ArduinoNano33iot/iothub_ll_telemetry_sample/sample_init.h new file mode 100644 index 0000000..5400379 --- /dev/null +++ b/examples/ArduinoNano33iot/iothub_ll_telemetry_sample/sample_init.h @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#ifndef SAMPLE_INIT_H +#define SAMPLE_INIT_H +#if defined(ARDUINO_ARCH_ESP8266) + #define sample_init esp8266_sample_init + #define is_esp_board + void esp8266_sample_init(const char* ssid, const char* password); +#endif // ARDUINO_ARCH_ESP8266 +#if defined(ARDUINO_ARCH_ESP32) + #define sample_init esp32_sample_init + #define is_esp_board + void esp32_sample_init(const char* ssid, const char* password); +#endif // ARDUINO_ARCH_ESP32 +#if defined(ARDUINO_ARCH_SAMD) + #define sample_init m0_sample_init + #define is_arduino_board + void m0_sample_init(const char* ssid, const char* password); +#endif +#endif // SAMPLE_INIT_H diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..1160f87 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,5 @@ +[env:nano_33_iot] +platform = atmelsam +board = nano_33_iot +framework = arduino +build_flags = -DDONT_USE_UPLOADTOBLOB -DUSE_BALTIMORE_CERT -DUSE_MBEDTLS