Hardware Introduction
nRF7002-DK is a development kit for the nRF7002 Wi-Fi 6 collaboration IC. The development kit uses the nRF5340 multi-protocol system-on-chip (SoC) as the main processor of the nRF7002 and contains everything needed for development work on a single circuit board., allowing developers to easily start IoT projects based on nRF7002. The DK includes an Arduino connector, two programmable buttons, a Wi-Fi dual-band antenna and a Bluetooth Low Energy antenna, and current measurement pins.
This DK supports low-power Wi-Fi application development and implements multiple Wi-Fi 6 functions, such as OFDMA, beamforming and TWT. The nRF7002 Wi-Fi 6 companion IC adds low-power Wi-Fi 6 capabilities to another host, providing seamless connectivity and Wi-Fi-based location (SSID sniffing of local Wi-Fi hubs) capabilities. The IC is designed to work with Nordic's existing nRF52® and nRF53® series of multi-protocol systems-on-chips (SoCs) and nRF91® series of cellular IoT system-in-packages (SiPs). The nRF7002 IC can also be used with non-Nordic host devices. Communicates with the host via SPI or QSPI with additional coexistence capabilities to seamlessly coexist with other protocols such as Bluetooth, Thread or Zigbee.
The nRF7002 provides integration and support in Nordic’s nRF Connect SDK.
Board features:
Development kit for nRF7002 dual-band Wi-Fi 6 companion IC
nRF5340 SoC host device
Wi-Fi 6 (IEEE 802.11 a/b/g/n/ac/ax), Bluetooth Low Energy (LE), Bluetooth Mesh, 802.15.4, Thread, Zigbee®, ANT, 2.4GHz proprietary and NFC Wireless protocol supports 2.4GHz, 5GHz chips and NFC antennas
SWF RF connector
SEGGER J-Link Onboard Programmer/Debugger
User programmable LEDs (2x) and buttons (2x)
Pin for measuring power consumption
2.9V to 5.0V power from USB, external or lithium polymer battery
Arduino connector
Development environment and project directoryDevelopment environment and project directory
- Manually install SDK and other dependencies according to the official website documentation nRF Connect SDK version.
- Since the author is working in a Linux environment and has a certain degree of mysophobia, I used Poetry alone during installation to create a Python virtual environment. And based on this, install additional Python dependencies. Each time you use it, activate the Python virtual environment first.
v2.4.2westwest
Poetry installation - PoetryYou can ncs/nrf/samplesmake a copy of the project directory based on the sample in and add your own code or configuration based on it. For example:
├ build
├ src
│ ├ main.c
├ CMakeLists.txt
├ prj.conf
├ sample.yaml
├ README.md
└ ...
prj.conf Configure the libraries that need to be enabled so that the corresponding header files can be compiled when compiling the program. sample.yaml It is only used to describe the sample program. In addition, Kconfigit is so that users can manually configure certain options (mainly optional functions) in menu config, which is omitted in this project.
Within CMakeLists.txt, additionally added set(BOARD nrf7002dk_nrf5340_cpuapp) so that the compile option west build can be omitted when -b nrf7002dk_nrf5340_cpuapp).
cmake_minimum_required(VERSION 3.20.0)
set(BOARD nrf7002dk_nrf5340_cpuapp)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(nfc_function_switching)
FILE(GLOB app_sources src/*.c)
Hardware initialization
Initialize the LEDs and buttons on the board here. And turn on LED2 to indicate that the board is working normally.
dk_buttons_init(NULL);
dk_leds_init();
dk_set_led_on(SYSTEM_ON_LED);
NFC function implementation
First, nfc_t2t_setup()register the callback function of the NFC event. The callback function mainly responds to the events when the NFC tag detects the external NFC field and when it is removed. LED1 lights up when an external NFC field is detected and turns off when removed.
nfc_t2t_setup(nfc_callback, NULL)
static void nfc_callback(void *context,
nfc_t2t_event_t event,
const uint8_t *data,
size_t data_length)
{
ARG_UNUSED(context);
ARG_UNUSED(data);
ARG_UNUSED(data_length);
switch (event)
{
case NFC_T2T_EVENT_FIELD_ON:
dk_set_led_on(NFC_FIELD_LED);
break;
case NFC_T2T_EVENT_FIELD_OFF:
dk_set_led_off(NFC_FIELD_LED);
break;
default:
break;
}
}
Text record
Mainly use the nfc library provided by nRF. First generate an NDEF text record descriptor, then add this record to the NDEF message, then nfc_ndef_msg_encodeencode it and store bufferit in, with a length of len.
static int nfc_text_encode(uint8_t *buffer, uint32_t *len)
{
NFC_NDEF_TEXT_RECORD_DESC_DEF(nfc_text_rec,
UTF_8,
en_code,
sizeof(en_code),
en_payload,
sizeof(en_payload));
NFC_NDEF_MSG_DEF(nfc_text_msg, MAX_REC_COUNT);
/* Add record */
if (nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_text_msg),
&NFC_NDEF_TEXT_RECORD_DESC(nfc_text_rec)) < 0)
{
printk("Cannot add record!\n");
return -1;
}
/* Encode text message */
if (nfc_ndef_msg_encode(&NFC_NDEF_MSG(nfc_text_msg), buffer, len) < 0)
{
printk("Cannot encode message!\n");
return -1;
}
return 0;
}
Android app opens
All that is needed is the name of the Android application android_pkg_name. Here, Arknights will be opened com.hypergryph.arknights. And nfc_launchapp_msg_encodecomplete the creation and encoding of this type of message through, and save it to buffer, the length is len.
/* Package: com.hypergryph.arknights */
static const uint8_t android_pkg_name[] = {
'c', 'o', 'm', '.',
'h', 'y', 'p', 'e', 'r', 'g', 'r', 'y', 'p', 'h', '.',
'a', 'r', 'k', 'n', 'i', 'g', 'h', 't', 's'};
static int nfc_launchapp_encode(uint8_t *buffer, uint32_t *len)
{
/* Encode launch app data */
if (nfc_launchapp_msg_encode(android_pkg_name,
sizeof(android_pkg_name), NULL, 0, buffer, len) < 0)
{
printk("Cannot encode message!\n");
return -1;
}
return 0;
}
Button to switch NFC function
To implement this function, a enumtype variable is required nfc_app_tto store the category of the current function. And after initializing the NFC function, while (true)scan the button in the loop to determine DK_BTN1whether it is pressed. If pressed, the function category will be switched. At the same time, nfc_appthe NFC payload will be regenerated and set according to.
typedef enum
{
NFC_APP_TEXT = 0U,
NFC_APP_LAUNCHAPP
} nfc_app_t;
// In main() function
while (true)
{
dk_read_buttons(&button_state, NULL);
if (button_state & DK_BTN1_MSK)
{
nfc_app = 1 - nfc_app;
/* Stop sensing NFC field */
if (nfc_t2t_emulation_stop() < 0)
{
printk("Cannot stop emulation!\n");
return -1;
}
if (nfc_payload_set(nfc_app) < 0)
{
printk("NFC payload set failed!\n");
goto fail;
}
}
k_sleep(K_MSEC(200));
}
It should be noted that the payloads of the two functions are different in length and content. If they share the same buffer to store NDEF messages, for example static uint8_t buffer[256], actual measurement will be wrong. Therefore, a separate buffer is set up for each of the two functions to store NDEF messages. Then, according to nfc_appthe value of, encode and set different categories of NDEF messages:
#define NDEF_MSG_BUF_SIZE 256
static uint8_t text_msg_buf[NDEF_MSG_BUF_SIZE];
static uint8_t launch_app_msg_buf[NDEF_MSG_BUF_SIZE];
len = sizeof(text_msg_buf);
nfc_text_encode(text_msg_buf, &len);
nfc_t2t_payload_set(text_msg_buf, len);
len = sizeof(launch_app_msg_buf);
nfc_launchapp_encode(launch_app_msg_buf, &len);
nfc_t2t_payload_set(launch_app_msg_buf, len);
Comments