硬件介绍
nRF7002-DK是用于nRF7002 Wi-Fi 6协同IC的开发套件,该开发套件采用nRF5340多协议片上系统 (SoC) 作为nRF7002的主处理器,在单一的电路板上包含了开发工作所需的一切,可让开发人员轻松开启基于nRF7002 的物联网项目。该 DK 包括 Arduino 连接器、两个可编程按钮、一个 Wi-Fi 双频段天线和一个低功耗蓝牙天线,以及电流测量引脚。
这款DK支持低功耗 Wi-Fi 应用开发,并实现了多项 Wi-Fi 6 功能,比如 OFDMA、波束成型和 TWT。nRF7002 Wi-Fi 6配套IC为另一个主机添加了低功耗Wi-Fi 6功能,提供无缝连接和基于Wi-Fi的定位(本地Wi-Fi集线器的SSID嗅探)功能。该IC设计用于搭配Nordic现有的nRF52®和nRF53®系列多协议片上系统 (SoC) 和nRF91®系列蜂窝物联网系统级封装 (SiP) 使用。nRF7002 IC 还可与非nordic主机器件搭配使用。通过SPI或QSPI与主机通信,并带有额外的共存功能,可与其他协议如蓝牙、Thread或Zigbee无缝共存。
nRF7002是Nordic的Wi-Fi产品系列中的首款器件,符合802.11ax标准,可提供双频段(2.4和5GHz)连接,支持Matter中使用的全部无线协议,可以为产品中添加最新的Wi-Fi 6技术,该芯片还具有帮助保护用户数据的先进安全功能。并与Nordic现有的超低功率技术无缝结合,可延长电池使用寿命。它提供快速、可靠的连接,具有先进的安全功能,并且方便集成到各个应用当中。
板上的nRF5340是支持低功耗蓝牙、蓝牙Mesh、NFC、Thread和Zigbee的双核蓝牙5.3 SoC,并且蓝牙测向可实现所有到达角(AoA)和出发角(AoD)的测量功能。此外,它支持低功耗蓝牙音频,2 Mbps高吞吐量、广播扩展和长距离。像蓝牙Mesh、Thread和Zigbee这样的Mesh协议可以与低功耗蓝牙同时运行,从而使智能手机能够配网、入网、配置和控制Mesh节点。还支持NFC、ANT、802.15.4和2.4 GHz专有协议。
板卡特性
- Arduino连接器
- 两个可编程的按钮
- 搭载nRF7002 Wi-Fi协同IC
- 作为主处理器的nRF5340 SoC
- 电流测量引脚
- 2.4GHz、2.4/5 GHz和NFC天线
- 高性能的128MHz Arm Cortex-M33应用内核
- 超低功率的64MHz Arm Cortex-M33网络核心
项目介绍
此次项目主要基于nRFConnect SDK 进行开发,它集成了Zephyr 操作系统使用Zephyr 实现 NDEF 数据格式存储、加载、覆盖。
设计思路
1.通过led 显示 当前nfc 读取 设置相关状态
2.通过jlink 进行 程序刷写 log 显示
3.通过按键进行 ndef 数据重置,重置成硬禾学堂的链接
4.可以通过手机nrf tools进行 ndef 数据格式设置,然后通过天线获取数据,保存到芯片flash中,芯片下次启动时,读取固定地址数据,判读是否有数据,没有的话 加载默认 硬禾学堂链接的设置。
5.手机可以进行连接图片 名片 wifi 等相关设置,设置相对比较方面
6.通过切换按键可以切换到下一个nfc 卡片,方便进行不同功能实现。
软件流程图
各功能对应的主要代码片段及说明
/* Configure LED-pins as outputs. */
if (board_init() < 0) {
printk("Cannot initialize board!\n");
goto fail;
}
/* Initialize NVS. */
if (ndef_file_setup() < 0) {
printk("Cannot setup NDEF file!\n");
goto fail;
}
/* Load NDEF message from the flash file. */
if (ndef_file_load(ndef_msg_buf, sizeof(ndef_msg_buf)) < 0) {
printk("Cannot load NDEF file!\n");
goto fail;
}
上电进行nvs 存储器 板子按键 led 等相关外设的初始化,并且通过nvs 驱动ndef数据到buffer中。
/* Restore default NDEF message if button is pressed. */
uint32_t button_state;
dk_read_buttons(&button_state, NULL);
if (button_state & NDEF_RESTORE_BTN_MSK) {
if (ndef_restore_default(ndef_msg_buf,
sizeof(ndef_msg_buf)) < 0) {
printk("Cannot flash NDEF message!\n");
goto fail;
}
printk("Default NDEF message restored!\n");
}
判断按键状态,如果重置按键有按下,则重置 nfc 功能,使用默认的设置设置所有nfc 存储区域
/* Set up NFC */
int err = nfc_t4t_setup(nfc_callback, NULL);
if (err < 0) {
printk("Cannot setup t4t library!\n");
goto fail;
}
/* Run Read-Write mode for Type 4 Tag platform */
if (nfc_t4t_ndef_rwpayload_set(ndef_msg_buf,
sizeof(ndef_msg_buf)) < 0) {
printk("Cannot set payload!\n");
goto fail;
}
/* Start sensing NFC field */
if (nfc_t4t_emulation_start() < 0) {
printk("Cannot start emulation!\n");
goto fail;
}
设置nfc 相关回调函数,配置可写属性,配置成功后,开始进行模拟
static void nfc_callback(void *context,
nfc_t4t_event_t event,
const uint8_t *data,
size_t data_length,
uint32_t flags)
{
ARG_UNUSED(context);
ARG_UNUSED(data);
ARG_UNUSED(flags);
switch (event) {
case NFC_T4T_EVENT_FIELD_ON:
dk_set_led_on(NFC_FIELD_LED);
break;
case NFC_T4T_EVENT_FIELD_OFF:
dk_set_leds(DK_NO_LEDS_MSK);
break;
case NFC_T4T_EVENT_NDEF_READ:
dk_set_led_on(NFC_READ_LED);
break;
case NFC_T4T_EVENT_NDEF_UPDATED:
if (data_length > 0) {
dk_set_led_on(NFC_WRITE_LED);
flash_buffer_prepare(data_length);
}
break;
default:
break;
}
}
根据nfc 相关状态设置不同的灯显示状态。主要有 nfc 扫描开始、结束 读取数据 写入数据控制。
/** .. include_startingpoint_ndef_file_rst */
static const uint8_t m_url[] = /*my url*/
{'r','f','i','d','f','a','n','s','.','c','o','m','/','p','t','a','g','/','i','n','d','e','x','.','p','h','p','?','u','n','a','m','e','=','x','i','n','j','i','a','q','i','1','&','u','n','i','c','o','d','e','=','b','4','b','2','4','e','0','9',\
'6','5','e','8','e','f','0','a','7','9','7','c','d','a','f','1','e','2','4','5','0','0','0','2'};
int ndef_file_default_message(uint8_t *buff, uint32_t *size)
{
int err;
uint32_t ndef_size = nfc_t4t_ndef_file_msg_size_get(*size);
/* Encode URI message into buffer. */
err = nfc_ndef_uri_msg_encode(NFC_URI_HTTP_WWW,
m_url,
sizeof(m_url),
nfc_t4t_ndef_file_msg_get(buff),
&ndef_size);
if (err) {
return err;
}
err = nfc_t4t_ndef_file_encode(buff, &ndef_size);
if (err) {
return err;
}
*size = ndef_size;
return 0;
}
这里使用了链接设置,主要通过
dk_read_buttons(&button_state, NULL);
//set nextread
if (button_state & NDEF_NEXT_BTN_MSK) {
if (atomic_cas(&op_flags, FLASH_WRITE_FINISHED,
FLASH_WRITE_FINISHED))
{
updatwrIdx();
/* Run Read-Write mode for Type 4 Tag platform */
if (nfc_t4t_ndef_rwpayload_set(ndef_msg_buf,
sizeof(ndef_msg_buf)) < 0) {
printk("Cannot set payload!\n");
goto fail;
}
/* Run Read-Write mode for Type 4 Tag platform */
if (nfc_t4t_ndef_rwpayload_set(ndef_msg_buf,
sizeof(ndef_msg_buf)) < 0) {
printk("Cannot set payload!\n");
goto fail;
}
/* Start sensing NFC field */
if (nfc_t4t_emulation_start() < 0) {
printk("Cannot start emulation!\n");
goto fail;
}
}
}
这里在主循环进行检测,当切换按钮按下时,切换下一nfc 卡片功能
void updatwrIdx(void)
{
readidx ++;
if(readidx==NVS_SECTOR_COUNT)
{
readidx=1;
}
}
读取和写入都通过readidx 进行设置,这个当切换按键按下时,readidx +1,当readidx 大于最大存储时,返回到第一个设置中。
功能展示及说明
天线 pin朝下接入,板卡正常上电,使用小米手机进行扫描设置
对本活动的心得体会(包括意见或建议)
建议后续多举办这样的活动,更多小伙伴参与进来
vscode 如果有不识别的头文件时可以添加c++setting 进行设置,目录根据自己的目录进行修改,这样调试 跳转查找相对方便些。
{
"nrf-connect.topdir": "g:\\win10\\Desktop\\Embedded\\Nordic\\sdk\\v2.4.2",
"nrf-connect.toolchain.path": "${nrf-connect.toolchain:2.4.0}",
"nrf-connect.applications": [
"g:\\win10\\Desktop\\Embedded\\Nordic\\code\\hello_world",
"${workspaceFolder}"
],
"files.associations": {
"array": "c",
"bitset": "c",
"deque": "c",
"format": "c",
"initializer_list": "c",
"list": "c",
"queue": "c",
"random": "c",
"ranges": "c",
"regex": "c",
"span": "c",
"type_traits": "c",
"vector": "c",
"xhash": "c",
"xstring": "c",
"xtree": "c",
"xutility": "c",
"stdbool.h": "c"
}
}
3.后续可以加一个屏幕,这样不同的nfc 可以通过屏幕进行显示基础信息,方便不同的nfc 进行切换及信息确认。