Skip to content

Commit add58e3

Browse files
Initial commit (#1007)
Co-authored-by: José Antonio Bagur Nájera <[email protected]>
1 parent 231789d commit add58e3

File tree

7 files changed

+385
-0
lines changed

7 files changed

+385
-0
lines changed
120 KB
Loading
245 KB
Loading
95.7 KB
Loading
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
/**
2+
Opta device information retrieval
3+
Name: opta_info.ino
4+
Purpose: Retrieve information of an Opta device such as its bootloader version, hardware functionalities, external memory size, and MAC address.
5+
6+
@author Arduino PRO Content team
7+
@version 1.0 27/03/22
8+
*/
9+
10+
// Include the necessary header files and define macros
11+
uint8_t* bootloader_data = (uint8_t*)(0x801F000);
12+
uint8_t* bootloader_identification = (uint8_t*)(0x80002F0);
13+
14+
#if __has_include("opta_info.h")
15+
#include "opta_info.h"
16+
#define GET_OPTA_OTP_BOARD_INFO
17+
OptaBoardInfo* info;
18+
OptaBoardInfo* boardInfo();
19+
#endif
20+
21+
void setup() {
22+
Serial.begin(115200);
23+
while (!Serial) {}
24+
delay(2500);
25+
26+
Serial.println("Opta Device Information");
27+
28+
uint8_t currentBootloaderVersion = bootloader_data[1];
29+
String currentBootloaderIdentifier = String(bootloader_identification, 15);
30+
31+
if (!currentBootloaderIdentifier.equals("MCUboot Arduino")) {
32+
currentBootloaderIdentifier = "Arduino loader";
33+
}
34+
35+
Serial.println("- Bootloader identifier: " + currentBootloaderIdentifier);
36+
Serial.println("- Magic number (validation): " + String(bootloader_data[0], HEX));
37+
Serial.println("- Bootloader version: " + String(bootloader_data[1]));
38+
39+
#if defined(GET_OPTA_OTP_BOARD_INFO)
40+
printOptaSecureInfo();
41+
#endif
42+
}
43+
44+
#if defined(GET_OPTA_OTP_BOARD_INFO)
45+
46+
/**
47+
Checks if the magic number is 0xB5. If it is, prints the secure information of the device in the Serial Monitor.
48+
49+
@params none
50+
@return none
51+
*/
52+
void printOptaSecureInfo() {
53+
info = boardInfo();
54+
if (info->magic == 0xB5) {
55+
Serial.println("- Secure information version: " + String(info->version));
56+
Serial.println("- Ethernet functionality: " + String(info->_board_functionalities.ethernet == 1 ? "Yes" : "No"));
57+
Serial.println("- Wi-Fi module functionality: " + String(info->_board_functionalities.wifi == 1 ? "Yes" : "No"));
58+
Serial.println("- RS-485 functionality: " + String(info->_board_functionalities.rs485 == 1 ? "Yes" : "No"));
59+
Serial.println("- QSPI memory size: " + String(info->external_flash_size) + " MB");
60+
Serial.println("- Secure board revision: " + String(info->revision >> 8) + "." + String(info->revision & 0xFF));
61+
Serial.println("- Secure VID: 0x" + String(info->vid, HEX));
62+
Serial.println("- Secure PID: 0x" + String(info->pid, HEX));
63+
Serial.println("- Ethernet MAC address: " + String(info->mac_address[0], HEX) + ":" + String(info->mac_address[1], HEX) + ":" + String(info->mac_address[2], HEX) + ":" + String(info->mac_address[3], HEX) + ":" + String(info->mac_address[4], HEX) + ":" + String(info->mac_address[5], HEX));
64+
if (info->_board_functionalities.wifi == 1) {
65+
Serial.println("- Wi-Fi MAC address: " + String(info->mac_address_2[0], HEX) + ":" + String(info->mac_address_2[1], HEX) + ":" + String(info->mac_address_2[2], HEX) + ":" + String(info->mac_address_2[3], HEX) + ":" + String(info->mac_address_2[4], HEX) + ":" + String(info->mac_address_2[5], HEX));
66+
}
67+
} else {
68+
Serial.println("- No secure information available!");
69+
printBootloaderInfo();
70+
}
71+
}
72+
#endif
73+
74+
/**
75+
Prints clock source, USB speed, Ethernet functionality, Wi-Fi functionality, RAM memory size, QSPI memory size, video output functionality, and secure element functionality.
76+
77+
@params none
78+
@return none
79+
*/
80+
void printBootloaderInfo() {
81+
Serial.println("- Clock source: " + getClockSource(bootloader_data[2]));
82+
Serial.println("- USB Speed: " + getUSBSpeed(bootloader_data[3]));
83+
Serial.println("- Ethernet functionality: " + String(bootloader_data[4] == 1 ? "Yes" : "No"));
84+
Serial.println("- Wi-Fi functionality: " + String(bootloader_data[5] == 1 ? "Yes" : "No"));
85+
Serial.println("- RAM size: " + getRAMSize(bootloader_data[6]));
86+
Serial.println("- QSPI memory size: " + String(bootloader_data[7]) + " MB");
87+
Serial.println("- Video output functionality: " + String(bootloader_data[8] == 1 ? "Yes" : "No"));
88+
Serial.println("- Secure element functionality: " + String(bootloader_data[9] == 1 ? "Yes" : "No"));
89+
}
90+
91+
/**
92+
Convert a flag in the bootloader data to USB speed information.
93+
94+
@param bootloader flag (uint8_t)
95+
@return USB speed information as a String
96+
*/
97+
String getUSBSpeed(uint8_t flag) {
98+
switch (flag) {
99+
case 1:
100+
return "USB 2.0/Hi-Speed (480 Mbps)";
101+
case 2:
102+
return "USB 1.1/Full-Speed (12 Mbps)";
103+
default:
104+
return "N/A";
105+
}
106+
}
107+
108+
/**
109+
Convert a flag in the bootloader data to clock source information.
110+
111+
@param bootloader flag (uint8_t)
112+
@return clock source information as a String
113+
*/
114+
String getClockSource(uint8_t flag) {
115+
switch (flag) {
116+
case 0x8:
117+
return "External oscillator";
118+
case 0x4:
119+
return "External crystal";
120+
case 0x2:
121+
return "Internal clock";
122+
default:
123+
return "N/A";
124+
}
125+
}
126+
127+
/**
128+
Convert a flag in the bootloader data to RAM size information.
129+
130+
@param bootloader flag (uint8_t)
131+
@return RAM size information as a String
132+
*/
133+
String getRAMSize(uint8_t flag) {
134+
if (flag == 0) {
135+
return "N/A";
136+
}
137+
return (String(flag) + "MB");
138+
}
139+
140+
void loop() {
141+
delay(1000);
142+
}
229 KB
Loading
Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
---
2+
title: 'Retrieve the Opta™ MAC Address'
3+
description: "Learn how to retrieve your Opta™ device's MAC address using the Arduino® ecosystem tools."
4+
5+
difficulty: beginner
6+
tags:
7+
- Opta™
8+
- MAC address
9+
author: 'José Bagur and Taddy Chung'
10+
software:
11+
- ide-v1
12+
- ide-v2
13+
hardware:
14+
- hardware/07.opta/opta-family/opta
15+
---
16+
17+
## Overview
18+
19+
The Media Access Control (MAC) address is essential for computer networking and devices with Internet of Things (IoT) capabilities, such as the [Opta™](https://store.arduino.cc/pages/opta). In this tutorial, we will learn how to retrieve the MAC address of an Opta™ device using the Arduino ecosystem tools.
20+
21+
![The Opta™ MAC address retrieval](assets/mac-address-retrieval.png)
22+
23+
## Goals
24+
25+
- Learn how to retrieve the MAC address of an Opta™ device.
26+
- Learn how to use the Arduino ecosystem tools to get information from Arduino hardware devices.
27+
28+
## Hardware and Software Requirements
29+
30+
### Hardware Requirements
31+
32+
- [Opta™](https://store.arduino.cc/collections/pro-family) (any variant) (x1)
33+
- USB-C® cable (x1)
34+
35+
### Software Requirements
36+
37+
- [Arduino IDE 1.8.10+](https://www.arduino.cc/en/software), [Arduino IDE 2.0+](https://www.arduino.cc/en/software), or [Arduino Web Editor](https://create.arduino.cc/editor)
38+
- [The MAC address retrieval example sketch](assets/opta_info.ino)
39+
40+
## MAC Address Basics
41+
42+
43+
A MAC address is a unique value associated with a network adapter. They are also known, or usually referred to, as the **hardware or physical address** of electronic devices with networking capabilities. The MAC address is used to identify and distinguish it from other devices connected to a network; which allows it to send and receive data to specific devices in the network.
44+
45+
***A MAC address uniquely identifies a network adapter in a Local Area Network (LAN).***
46+
47+
MAC addresses are 48-bit numbers written in one of the following 12 hexadecimal digits formats:
48+
49+
- `MMMMMMSSSSSS`
50+
- `MM MM MM SS SS SS`
51+
- `MMMM MMSS SSSS`
52+
- `MM:MM:MM:SS:SS:SS`
53+
- `MMMM:MMSS:SSSS`
54+
- `MM.MM.MM.SS.SS.SS`
55+
- `MMMM.MMSS.SSSS`
56+
57+
The first half of the 12-digit number (the first 24 bits) identifies the adapter manufacturer (identified with an M); the second half of the 12-digit number represents a serial number (identified with an S) assigned to the adapter by its manufacturer. For example:
58+
59+
- `00:A0:C9:14:C8:29`
60+
61+
In the MAC address shown above, `00A0C9` indicates that the adapter manufacturer is Intel®, and `14C829` is the serial number assigned by Intel to the adapter.
62+
63+
### Opta™ MAC Address
64+
65+
Opta™ is available in three variants; **all of them have an Ethernet connection and its corresponding MAC address and, in the case of the most advanced variant with Wi-Fi®/Bluetooth®, an additional MAC address to identify the additional Wi-Fi®/Bluetooth® module**. Let's learn how to retrieve the MAC addresses of an Opta™ device using the Arduino ecosystem tools.
66+
67+
## Instructions
68+
69+
### Setting Up the Arduino IDE
70+
71+
This tutorial will need the latest version of the Arduino IDE; you can download it [here](https://www.arduino.cc/en/software). If it is your first time setting up the Opta™ with the Arduino IDE, check our [Getting Started with Opta™ tutorial](https://docs.arduino.cc/tutorials/opta/getting-started) first. In the Arduino IDE, we need to install the core for Opta™ devices; this can be done by navigating to **Tools > Board > Boards Manager**. In the Board Manager tab, search for `opta` and install the latest `Arduino Mbed OS Opta Boards` version.
72+
73+
![Installing the Opta™ core in the Arduino IDE bootloader.](assets/arduino-ide-1.png)
74+
75+
Now we are ready to start compiling and uploading sketches to an Opta™ device using the Arduino IDE.
76+
77+
### Retrieving the MAC Address of an Opta™ Device
78+
79+
Opta™ device information is stored in a secured memory space. The example code shown below shows how that memory space can be accessed using predefined functions of the Opta™ core:
80+
81+
```arduino
82+
/**
83+
Opta device information retrieval
84+
Name: opta_info.ino
85+
Purpose: Retrieve information of an Opta device such as its bootloader version, hardware functionalities, external memory size, and MAC address.
86+
87+
@author Arduino PRO Content team
88+
@version 1.0 27/03/22
89+
*/
90+
91+
// Include the necessary header files and define macros
92+
uint8_t* bootloader_data = (uint8_t*)(0x801F000);
93+
uint8_t* bootloader_identification = (uint8_t*)(0x80002F0);
94+
95+
#if __has_include("opta_info.h")
96+
#include "opta_info.h"
97+
#define GET_OPTA_OTP_BOARD_INFO
98+
OptaBoardInfo* info;
99+
OptaBoardInfo* boardInfo();
100+
#endif
101+
102+
void setup() {
103+
Serial.begin(115200);
104+
while (!Serial) {}
105+
delay(2500);
106+
107+
Serial.println("Opta Device Information");
108+
109+
uint8_t currentBootloaderVersion = bootloader_data[1];
110+
String currentBootloaderIdentifier = String(bootloader_identification, 15);
111+
112+
if (!currentBootloaderIdentifier.equals("MCUboot Arduino")) {
113+
currentBootloaderIdentifier = "Arduino loader";
114+
}
115+
116+
Serial.println("- Bootloader identifier: " + currentBootloaderIdentifier);
117+
Serial.println("- Magic number (validation): " + String(bootloader_data[0], HEX));
118+
Serial.println("- Bootloader version: " + String(bootloader_data[1]));
119+
120+
#if defined(GET_OPTA_OTP_BOARD_INFO)
121+
printOptaSecureInfo();
122+
#endif
123+
}
124+
125+
#if defined(GET_OPTA_OTP_BOARD_INFO)
126+
127+
/**
128+
Checks if the magic number is 0xB5. If it is, prints the secure information of the device in the Serial Monitor.
129+
130+
@params none
131+
@return none
132+
*/
133+
void printOptaSecureInfo() {
134+
info = boardInfo();
135+
if (info->magic == 0xB5) {
136+
Serial.println("- Secure information version: " + String(info->version));
137+
Serial.println("- Ethernet functionality: " + String(info->_board_functionalities.ethernet == 1 ? "Yes" : "No"));
138+
Serial.println("- Wi-Fi module functionality: " + String(info->_board_functionalities.wifi == 1 ? "Yes" : "No"));
139+
Serial.println("- RS-485 functionality: " + String(info->_board_functionalities.rs485 == 1 ? "Yes" : "No"));
140+
Serial.println("- QSPI memory size: " + String(info->external_flash_size) + " MB");
141+
Serial.println("- Secure board revision: " + String(info->revision >> 8) + "." + String(info->revision & 0xFF));
142+
Serial.println("- Secure VID: 0x" + String(info->vid, HEX));
143+
Serial.println("- Secure PID: 0x" + String(info->pid, HEX));
144+
Serial.println("- Ethernet MAC address: " + String(info->mac_address[0], HEX) + ":" + String(info->mac_address[1], HEX) + ":" + String(info->mac_address[2], HEX) + ":" + String(info->mac_address[3], HEX) + ":" + String(info->mac_address[4], HEX) + ":" + String(info->mac_address[5], HEX));
145+
if (info->_board_functionalities.wifi == 1) {
146+
Serial.println("- Wi-Fi MAC address: " + String(info->mac_address_2[0], HEX) + ":" + String(info->mac_address_2[1], HEX) + ":" + String(info->mac_address_2[2], HEX) + ":" + String(info->mac_address_2[3], HEX) + ":" + String(info->mac_address_2[4], HEX) + ":" + String(info->mac_address_2[5], HEX));
147+
}
148+
} else {
149+
Serial.println("- No secure information available!");
150+
printBootloaderInfo();
151+
}
152+
}
153+
#endif
154+
155+
/**
156+
Prints clock source, USB speed, Ethernet functionality, Wi-Fi functionality, RAM memory size, QSPI memory size, video output functionality, and secure element functionality.
157+
158+
@params none
159+
@return none
160+
*/
161+
void printBootloaderInfo() {
162+
Serial.println("- Clock source: " + getClockSource(bootloader_data[2]));
163+
Serial.println("- USB Speed: " + getUSBSpeed(bootloader_data[3]));
164+
Serial.println("- Ethernet functionality: " + String(bootloader_data[4] == 1 ? "Yes" : "No"));
165+
Serial.println("- Wi-Fi functionality: " + String(bootloader_data[5] == 1 ? "Yes" : "No"));
166+
Serial.println("- RAM size: " + getRAMSize(bootloader_data[6]));
167+
Serial.println("- QSPI memory size: " + String(bootloader_data[7]) + " MB");
168+
Serial.println("- Video output functionality: " + String(bootloader_data[8] == 1 ? "Yes" : "No"));
169+
Serial.println("- Secure element functionality: " + String(bootloader_data[9] == 1 ? "Yes" : "No"));
170+
}
171+
172+
/**
173+
Convert a flag in the bootloader data to USB speed information.
174+
175+
@param bootloader flag (uint8_t)
176+
@return USB speed information as a String
177+
*/
178+
String getUSBSpeed(uint8_t flag) {
179+
switch (flag) {
180+
case 1:
181+
return "USB 2.0/Hi-Speed (480 Mbps)";
182+
case 2:
183+
return "USB 1.1/Full-Speed (12 Mbps)";
184+
default:
185+
return "N/A";
186+
}
187+
}
188+
189+
/**
190+
Convert a flag in the bootloader data to clock source information.
191+
192+
@param bootloader flag (uint8_t)
193+
@return clock source information as a String
194+
*/
195+
String getClockSource(uint8_t flag) {
196+
switch (flag) {
197+
case 0x8:
198+
return "External oscillator";
199+
case 0x4:
200+
return "External crystal";
201+
case 0x2:
202+
return "Internal clock";
203+
default:
204+
return "N/A";
205+
}
206+
}
207+
208+
/**
209+
Convert a flag in the bootloader data to RAM size information.
210+
211+
@param bootloader flag (uint8_t)
212+
@return RAM size information as a String
213+
*/
214+
String getRAMSize(uint8_t flag) {
215+
if (flag == 0) {
216+
return "N/A";
217+
}
218+
return (String(flag) + "MB");
219+
}
220+
221+
void loop() {
222+
delay(1000);
223+
}
224+
```
225+
226+
To upload the code, click the **Verify** button to compile the sketch and check for errors; then click the **Upload** button to program the device with the sketch.
227+
228+
![Uploading a sketch to the Opta™ the Arduino IDE.](assets/arduino-ide-2.png)
229+
230+
The code above retrieves information from an Opta™ device, including its MAC address, and prints it to the Arduino IDE's Serial Monitor. The information shown includes the bootloader version and identifier, secure board information, and general board information.
231+
232+
![Opta™ device information shown in the Arduino IDE Serial Monitor.](assets/serial-monitor-1.png)
233+
234+
- The `printOptaSecureInfo()` function checks if the magic number of the `OptaBoardInfo` structure is `0xB5`, indicating that secure information is available. If it is, it prints the secure information to the IDE's Serial Monitor, including the board's functionalities (Ethernet, Wi-Fi®/Bluetooth® capabilities, and RS-485 capabilities), QSPI memory size, board revision, VID, PID, and the MAC address of the Ethernet port. If the board has Wi-Fi®/Bluetooth® capabilities, the function will also print the MAC address of the Wi-Fi®/Bluetooth® module.
235+
- If the magic number doesn't match, it prints a message indicating that no secure information is available and proceeds to print the bootloader information using the `printBootloaderInfo()` function. The `printBootloaderInfo()` function prints the following information to the IDE's Serial Monitor: clock source, USB speed, Ethernet functionality, Wi-Fi®/Bluetooth® module functionality, RAM size, QSPI memory size, video output functionality, and secure element functionality.
236+
237+
## Conclusion
238+
239+
In this tutorial, we have learned how to retrieve the MAC address(es) of an Opta™ device using the Arduino ecosystem tools. Following the provided steps and sketch, you can access essential information about your Opta™ device, such as its bootloader version, hardware functionalities, and MAC address. Understanding this information can be beneficial when working on networking and device identification projects. This knowledge allows you to explore and build more advanced projects using the Opta™ and Arduino ecosystem tools.
240+
241+
### Next Steps
242+
243+
Now that you know how to retrieve the MAC address of an Opta™ device, have a look at the Opta™ [connectivity features tutorial](https://docs.arduino.cc/tutorials/opta/getting-started-connectivity) to learn how to use its connectivity features such as Wi-Fi®, Bluetooth® and Ethernet capabilities.
428 KB
Loading

0 commit comments

Comments
 (0)