中级
20 分钟

使用Proteus-e (2612011024000)和PIC18F96J94实现设备之间的无线数据传输

基于Bluetooth® LE 5.1技术的无线通信

Proteus-e Click with Fusion for PIC v8

已发布 12月 24, 2024

点击板

Proteus-e Click

开发板

Fusion for PIC v8

编译器

NECTO Studio

微控制器单元

PIC18F96J94

低功耗且安全的 Bluetooth® LE 5.1 通信,专为 工业自动化、智能家居 和 无线控制系统 而设计

A

A

硬件概览

它是如何工作的?

Proteus-e Click 基于 Würth Elektronik 的 2612011024000 无线通信射频模块,专为控制系统、遥控器、传感器等设备之间的连接设计。该模块采用 Bluetooth® LE 5.1 技术,确保在点对点拓扑中实现快速、可靠和安全的数据传输,其中 Proteus-e 充当 Bluetooth® LE“外围设备”。通信的对端(如 Proteus-III 模块或智能手机)需实现 Bluetooth® LE“中央设备”角色,并支持 Proteus-e 提供的相关 Bluetooth® LE 配置文件和特性。Proteus-e Click 非常适合工业自动化系统、传感器远程监控、智能家居设备以及需要低功耗、安全数据传输和可靠连接的无线控制系统等应用。2612011024000 模块的核心是 nRF52 系列的高性能 Bluetooth® LE 芯片,结合了卓越的功耗效率和性能。该芯片配备 64MHz ARM Cortex-M4 CPU,拥有 192kB 闪存和 24kB RAM,输出功率可达 4dBm。Proteus-e 在保持超低功耗的同时,提供强大的无线通信能力,非常适合电池供电的应用。模块固件支持类似 SPP 的 Bluetooth® LE 配置文件,实现 Proteus-e 与其他实现相同配置文件的 

Bluetooth® LE 设备之间的双向数据传输。这种数据传输通过加密和认证连接来保证,确保数据完整性并防止未经授权的访问。该 Click 板™ 采用支持 MIKROE 全新推出的“Click Snap”功能的独特设计格式。与标准化版本的 Click 板不同,这一功能通过折断 PCB,使主模块区域可以移动,从而提供了多种新的实现可能性。借助 Snap 功能,2612011024000 可通过直接访问标记为 1-8 的引脚自主运行。此外,Snap 部分还包括一个指定的固定螺孔位置,使用户能够将 Snap 板固定在所需位置。2612011024000 模块与主控 MCU 之间通过 UART 接口通信,使用标准的 UART RX 和 TX 引脚,以及作为测试点在板背面的硬件流控制引脚(CTS/RTS - 清除发送/准备发送)确保高效且可靠的数据传输。默认通信速率设置为 115200bps。除了接口引脚外,板上还提供一个复位(RST)引脚和一个 RESET 按钮,用于在必要时对模块进行硬复位。一个蓝色状态 LED(ST)清晰指示模块的工作状态,方便使用期间的监控。此外,mikroBUS™ 插槽的 EN 引脚具有多种功能。在通过

板载 MODE 开关选择透明模式(Transparent Mode)时,EN 引脚作为输出引脚,指示模块是否正在忙于数据传输。而在命令模式(Command Mode)下,EN 引脚作为具有内部上拉电阻的输入引脚,用于在 UART 通过 CMD_UARTDISABLE_REQ 命令禁用后唤醒 UART。该板还提供两个来自 Proteus-e 模块的专用 GPIO 引脚 IO1 和 IO2,这些引脚作为测试点位于板背面,可灵活用于远程控制和监控外部设备。Proteus-e 模块配有板载天线用于标准操作。然而,该板还包括一个外部天线连接器(CN1),在需要时可以连接额外的天线以扩展无线电范围。除了天线连接器外,板上还包含 SWD 焊盘,可与 MIKROE 的 6 针针式电缆配合使用,提供可选的 SWD(串行线调试)接口功能。该 Click 板™ 只能在 3.3V 逻辑电压电平下运行。在使用不同逻辑电平的 MCU 之前,板必须进行适当的逻辑电压电平转换。此外,板附带的库包含可用作进一步开发参考的函数和示例代码。

Proteus-e Click hardware overview image

功能概述

开发板

Fusion for PIC v8 是一款专为快速开发嵌入式应用而设计的开发板。它支持广泛的微控制器,如不同的 PIC、dsPIC、PIC24 和 PIC32 MCU,不论其引脚数量,并具有一系列独特功能,例如首次通过 WiFi 的嵌入式调试器/程序员。开发板布局合理,设计周到,确保最终用户在一个地方可以找到所有必需的元素,如开关、按钮、指示器、连接器等。得益于创新的制造 技术,Fusion for PIC v8 提供了流畅而沉浸式的工作体验,允许在任何情况下、任何地方都能访问。

Fusion for PIC v8 开发板的每个部分都包含了使同一板块运行最高效的必要组件。除了先进的集成 CODEGRIP 程序/调试模块,该模块提供许多有价值的编程/调试选项并与 Mikroe 软件环境无缝集成外,该板还包括一个为开发板提供的干净且调节过的电源供应模块。它可以使用广泛的外部电源,包括电池、外部 12V 电源供应,以及通过 USB Type-C(USB-C)连接器的电源。通信选项包括 USB-UART、USB HOST/DEVICE、CAN(如果 MCU 卡 支持的话)

和以太网,还包括广受好评的 mikroBUS™ 标准、为 MCU 卡提供的标准化插座(SiBRAIN 标准),以及两种显示选项,用于图形和基于字符的 LCD。Fusion for PIC v8 是 Mikroe 快速开发生态系统的一个重要组成部分,由 Mikroe 软件工具原生支持,得益于大量不同的 Click 板™(超过一千块板),其数量每天都在增长,它涵盖了原型制作和开发的许多方面。

Fusion for PIC v8 horizontal image

微控制器概述 

MCU卡片 / MCU

default

类型

8th Generation

建筑

PIC

MCU 内存 (KB)

64

硅供应商

Microchip

引脚数

100

RAM (字节)

3862

使用的MCU引脚

mikroBUS™映射器

NC
NC
AN
Reset
PJ4
RST
ID COMM
PL1
CS
NC
NC
SCK
NC
NC
MISO
NC
NC
MOSI
Power Supply
3.3V
3.3V
Ground
GND
GND
Data Transmission Busy / Module Wake-Up
PG4
PWM
NC
NC
INT
UART TX
PE1
TX
UART RX
PE0
RX
NC
NC
SCL
NC
NC
SDA
NC
NC
5V
Ground
GND
GND
1

“仔细看看!”

Click board™ 原理图

Proteus-e Click Schematic schematic

一步一步来

项目组装

Fusion for PIC v8 front image hardware assembly

从选择您的开发板和Click板™开始。以Fusion for PIC v8作为您的开发板开始

Fusion for PIC v8 front image hardware assembly
GNSS2 Click front image hardware assembly
SiBRAIN for PIC32MZ1024EFK144 front image hardware assembly
GNSS2 Click complete accessories setup image hardware assembly
Board mapper by product7 hardware assembly
Necto image step 2 hardware assembly
Necto image step 3 hardware assembly
Necto image step 4 hardware assembly
NECTO Compiler Selection Step Image hardware assembly
NECTO Output Selection Step Image hardware assembly
Necto image step 6 hardware assembly
Necto image step 7 hardware assembly
Necto image step 8 hardware assembly
Necto image step 9 hardware assembly
Necto image step 10 hardware assembly
Necto PreFlash Image hardware assembly

实时跟踪您的结果

应用程序输出

1. 应用程序输出 - 在调试模式下,“应用程序输出”窗口支持实时数据监控,直接提供执行结果的可视化。请按照提供的教程正确配置环境,以确保数据正确显示。

2. UART 终端 - 使用UART Terminal通过USB to UART converter监视数据传输,实现Click board™与开发系统之间的直接通信。请根据项目需求配置波特率和其他串行设置,以确保正常运行。有关分步设置说明,请参考提供的教程

3. Plot 输出 - Plot功能提供了一种强大的方式来可视化实时传感器数据,使趋势分析、调试和多个数据点的对比变得更加直观。要正确设置,请按照提供的教程,其中包含使用Plot功能显示Click board™读数的分步示例。在代码中使用Plot功能时,请使用以下函数:plot(insert_graph_name, variable_name);。这是一个通用格式,用户需要将“insert_graph_name”替换为实际图表名称,并将“variable_name”替换为要显示的参数。

软件支持

库描述

该库包含 Proteus-e Click 驱动程序的 API。

关键功能:

  • proteuse_send_cmd - 此功能从点击上下文对象发送所需的命令数据包。

  • proteuse_read_event - 此功能从环形缓冲区读取事件数据包并将其存储在点击上下文对象中。

  • proteuse_get_user_setting - 此功能从所需的用户设置索引读取数据并将其存储在点击上下文事件数据包对象中。

开源

代码示例

完整的应用程序代码和一个现成的项目可以通过NECTO Studio包管理器直接安装到NECTO Studio 应用程序代码也可以在MIKROE的GitHub账户中找到。

/*!
 * @file main.c
 * @brief Proteus-e Click Example.
 *
 * # Description
 * This example demonstrates the use of Proteus-e Click board by processing data
 * from a connected BT device.
 *
 * The demo application is composed of two sections :
 *
 * ## Application Init
 * Initializes the driver, resets and configures the Click board, and reads the device info.
 *
 * ## Application Task
 * Reads and parses all the received event packets and displays them the USB UART.
 * All incoming data messages received from the connected device will be echoed back.
 *
 * ## Additional Function
 * - static err_t proteuse_parse_cnf ( proteuse_t *ctx )
 * - static err_t proteuse_parse_rsp ( proteuse_t *ctx )
 * - static err_t proteuse_parse_ind ( proteuse_t *ctx )
 * - static err_t proteuse_parse_event ( proteuse_t *ctx )
 *
 * @note
 * We recommend using the WE Bluetooth LE Terminal smartphone application for the test.
 *
 * @author Stefan Filipovic
 *
 */

#include "board.h"
#include "log.h"
#include "proteuse.h"

// BT device name.
#define DEVICE_NAME         "Proteus-e Click"

static proteuse_t proteuse;
static log_t logger;

/**
 * @brief Proteus-e parse cnf function.
 * @details This function parses all received confirmation packets and displays them on the USB UART.
 * @param[in] ctx : Click context object.
 * See #proteuse_t object definition for detailed explanation.
 * @return @li @c 0 - Packet parsed successfully,
 *         @li @c 1 - Error.
 * See #err_t definition for detailed explanation.
 * @note None.
 */
static err_t proteuse_parse_cnf ( proteuse_t *ctx );

/**
 * @brief Proteus-e parse ind function.
 * @details This function parses all received response packets and displays them on the USB UART.
 * @param[in] ctx : Click context object.
 * See #proteuse_t object definition for detailed explanation.
 * @return @li @c 0 - Packet parsed successfully,
 *         @li @c 1 - Error.
 * See #err_t definition for detailed explanation.
 * @note None.
 */
static err_t proteuse_parse_rsp ( proteuse_t *ctx );

/**
 * @brief Proteus-e parse ind function.
 * @details This function parses all received indication packets and displays them on the USB UART.
 * @param[in] ctx : Click context object.
 * See #proteuse_t object definition for detailed explanation.
 * @return @li @c 0 - Packet parsed successfully,
 *         @li @c 1 - Error.
 * See #err_t definition for detailed explanation.
 * @note None.
 */
static err_t proteuse_parse_ind ( proteuse_t *ctx );

/**
 * @brief Proteus-e parse event function.
 * @details This function parses all received packets and displays them on the USB UART.
 * @param[in] ctx : Click context object.
 * See #proteuse_t object definition for detailed explanation.
 * @return @li @c 0 - Packet parsed successfully,
 *         @li @c 1 - Error.
 * See #err_t definition for detailed explanation.
 * @note None.
 */
static err_t proteuse_parse_event ( proteuse_t *ctx );

void application_init ( void ) 
{
    log_cfg_t log_cfg;  /**< Logger config object. */
    proteuse_cfg_t proteuse_cfg;  /**< Click config object. */

    /** 
     * Logger initialization.
     * Default baud rate: 115200
     * Default log level: LOG_LEVEL_DEBUG
     * @note If USB_UART_RX and USB_UART_TX 
     * are defined as HAL_PIN_NC, you will 
     * need to define them manually for log to work. 
     * See @b LOG_MAP_USB_UART macro definition for detailed explanation.
     */
    LOG_MAP_USB_UART( log_cfg );
    log_init( &logger, &log_cfg );
    log_info( &logger, " Application Init " );

    // Click initialization.
    proteuse_cfg_setup( &proteuse_cfg );
    PROTEUSE_MAP_MIKROBUS( proteuse_cfg, MIKROBUS_1 );
    if ( UART_ERROR == proteuse_init( &proteuse, &proteuse_cfg ) ) 
    {
        log_error( &logger, " Communication init." );
        for ( ; ; );
    }
    
    if ( PROTEUSE_ERROR == proteuse_default_cfg ( &proteuse ) )
    {
        log_error( &logger, " Default configuration." );
        for ( ; ; );
    }
    
    log_printf( &logger, ">> Get device info.\r\n" );
    if ( PROTEUSE_OK == proteuse_get_user_setting ( &proteuse, PROTEUSE_SET_IDX_FS_DEVICE_INFO ) ) 
    {
        log_printf( &logger, " < OS version: 0x%.2X%.2X\r\n", 
                    ( uint16_t ) proteuse.evt_pkt.payload[ 2 ], 
                    ( uint16_t ) proteuse.evt_pkt.payload[ 1 ] );
        log_printf( &logger, "   Build code: 0x%.2X%.2X%.2X%.2X\r\n", 
                    ( uint16_t ) proteuse.evt_pkt.payload[ 6 ], 
                    ( uint16_t ) proteuse.evt_pkt.payload[ 5 ], 
                    ( uint16_t ) proteuse.evt_pkt.payload[ 4 ], 
                    ( uint16_t ) proteuse.evt_pkt.payload[ 3 ] );
        log_printf( &logger, "   Package variant: 0x%.2X%.2X\r\n", 
                    ( uint16_t ) proteuse.evt_pkt.payload[ 8 ], 
                    ( uint16_t ) proteuse.evt_pkt.payload[ 7 ] );
        log_printf( &logger, "   Chip ID: 0x%.2X%.2X%.2X%.2X\r\n\n", 
                    ( uint16_t ) proteuse.evt_pkt.payload[ 12 ], 
                    ( uint16_t ) proteuse.evt_pkt.payload[ 11 ], 
                    ( uint16_t ) proteuse.evt_pkt.payload[ 10 ], 
                    ( uint16_t ) proteuse.evt_pkt.payload[ 9 ] );
    }

    log_printf( &logger, ">> Get FW version.\r\n" );
    if ( PROTEUSE_OK == proteuse_get_user_setting ( &proteuse, PROTEUSE_SET_IDX_FS_FW_VERSION ) ) 
    {
        log_printf( &logger, " < FW version: %u.%u.%u\r\n\n", 
                    ( uint16_t ) proteuse.evt_pkt.payload[ 3 ], 
                    ( uint16_t ) proteuse.evt_pkt.payload[ 2 ], 
                    ( uint16_t ) proteuse.evt_pkt.payload[ 1 ] );
    }

    log_printf( &logger, ">> Get BT MAC.\r\n" );
    if ( PROTEUSE_OK == proteuse_get_user_setting ( &proteuse, PROTEUSE_SET_IDX_FS_BTMAC ) ) 
    {
        log_printf( &logger, " < BT MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\r\n\n", 
                    ( uint16_t ) proteuse.evt_pkt.payload[ 6 ], 
                    ( uint16_t ) proteuse.evt_pkt.payload[ 5 ],
                    ( uint16_t ) proteuse.evt_pkt.payload[ 4 ], 
                    ( uint16_t ) proteuse.evt_pkt.payload[ 3 ],
                    ( uint16_t ) proteuse.evt_pkt.payload[ 2 ], 
                    ( uint16_t ) proteuse.evt_pkt.payload[ 1 ] );
    }

    log_printf( &logger, ">> Set device name to \"%s\".\r\n", ( char * ) DEVICE_NAME );
    if ( PROTEUSE_OK == proteuse_set_user_setting ( &proteuse, PROTEUSE_SET_IDX_RF_DEVICE_NAME, 
                                                    DEVICE_NAME, strlen ( DEVICE_NAME ) ) )
    {
        log_printf( &logger, " < Request received, settings set successfully\r\n\n" );
    }

    log_printf( &logger, ">> Get device name.\r\n" );
    if ( PROTEUSE_OK == proteuse_get_user_setting ( &proteuse, PROTEUSE_SET_IDX_RF_DEVICE_NAME ) ) 
    {
        log_printf( &logger, " < Device name: \"%s\"\r\n\n", &proteuse.evt_pkt.payload[ 1 ] );
    }

    log_info( &logger, " Application Task " );
}

void application_task ( void ) 
{
    if ( PROTEUSE_OK == proteuse_read_event ( &proteuse ) ) 
    {
        proteuse_parse_event ( &proteuse );
    }
}

int main ( void ) 
{
    /* Do not remove this line or clock might not be set correctly. */
    #ifdef PREINIT_SUPPORTED
    preinit();
    #endif
    
    application_init( );
    
    for ( ; ; ) 
    {
        application_task( );
    }

    return 0;
}

static err_t proteuse_parse_cnf ( proteuse_t *ctx )
{
    err_t error_flag = PROTEUSE_OK;
    uint16_t byte_cnt = 0;

    if ( PROTEUSE_CMD_TYPE_CNF == ( ctx->evt_pkt.cmd & PROTEUSE_CMD_TYPE_MASK ) )
    {
        // Parse confirmation packet
        switch ( ctx->evt_pkt.cmd )
        {
            case PROTEUSE_CMD_CNF_GET_STATE:
            {
                log_printf( &logger, " < GET_STATE_CNF -> Role: 0x%.2X, Actions: 0x%.2X", 
                            ( uint16_t ) ctx->evt_pkt.payload[ 0 ], ( uint16_t ) ctx->evt_pkt.payload[ 1 ] );
                if ( ctx->evt_pkt.payload_len > 2 )
                {
                    log_printf( &logger, "\r\n   More info: " );
                    for ( byte_cnt = 2; byte_cnt < ctx->evt_pkt.payload_len; byte_cnt++ )
                    {
                        log_printf( &logger, "0x%.2X ", ( uint16_t ) ctx->evt_pkt.payload[ byte_cnt ] );
                    }
                }
                break;
            }
            case PROTEUSE_CMD_CNF_GET:
            {
                log_printf( &logger, " < GET_CNF -> " );
                switch ( ctx->evt_pkt.payload[ 0 ] )
                {
                    case PROTEUSE_CNF_GET_STATUS_OK:
                    {
                        log_printf( &logger, "Request received, read out of setting successful" );
                        break;
                    }
                    case PROTEUSE_CNF_GET_STATUS_FAILED:
                    {
                        log_printf( &logger, "Operation failed" );
                        break;
                    }
                    case PROTEUSE_CNF_GET_STATUS_NOT_PERMITTED:
                    {
                        log_printf( &logger, "Operation not permitted" );
                        break;
                    }
                    default:
                    {
                        log_printf( &logger, "Unknown status: 0x%.2X", ( uint16_t ) ctx->evt_pkt.payload[ 0 ] );
                        break;
                    }
                }
                if ( ctx->evt_pkt.payload_len > 1 )
                {
                    log_printf( &logger, "\r\n   Setting: " );
                    for ( byte_cnt = 1; byte_cnt < ctx->evt_pkt.payload_len; byte_cnt++ )
                    {
                        log_printf( &logger, "0x%.2X ", ( uint16_t ) ctx->evt_pkt.payload[ byte_cnt ] );
                    }
                }
                break;
            }
            case PROTEUSE_CMD_CNF_DATA:
            {
                log_printf( &logger, " < DATA_CNF -> " );
                switch ( ctx->evt_pkt.payload[ 0 ] )
                {
                    case PROTEUSE_CNF_DATA_STATUS_OK:
                    {
                        log_printf( &logger, "Request received, will send data now" );
                        break;
                    }
                    case PROTEUSE_CNF_DATA_STATUS_FAILED:
                    {
                        log_printf( &logger, "Operation failed" );
                        break;
                    }
                    case PROTEUSE_CNF_DATA_STATUS_NOT_PERMITTED:
                    {
                        log_printf( &logger, "Operation not permitted" );
                        break;
                    }
                    default:
                    {
                        log_printf( &logger, "Unknown status: 0x%.2X", ( uint16_t ) ctx->evt_pkt.payload[ 0 ] );
                        break;
                    }
                }
                break;
            }
            default:
            {
                log_printf( &logger, " < CMD_CNF 0x%.2X -> ", ( uint16_t ) ctx->evt_pkt.cmd );
                for ( byte_cnt = 0; byte_cnt < ctx->evt_pkt.payload_len; byte_cnt++ )
                {
                    log_printf( &logger, "0x%.2X ", ( uint16_t ) ctx->evt_pkt.payload[ byte_cnt ] );
                }
                break;
            }
        }
        log_printf( &logger, "\r\n\n" );
    }
    else
    {
        // Wrong packet type
        error_flag |= PROTEUSE_ERROR;
    }
    return error_flag;
}

static err_t proteuse_parse_rsp ( proteuse_t *ctx )
{
    err_t error_flag = PROTEUSE_OK;

    if ( PROTEUSE_CMD_TYPE_RSP == ( ctx->evt_pkt.cmd & PROTEUSE_CMD_TYPE_MASK ) )
    {
        // Parse response packet
        if ( PROTEUSE_CMD_RSP_TX_COMPLETE == ctx->evt_pkt.cmd )
        {
            log_printf( &logger, " < TX_COMPLETE_IND -> " );
            if ( ctx->evt_pkt.payload[ 0 ] )
            {
                log_printf( &logger, "Data transmission failed" );
            }
            else
            {
                log_printf( &logger, "Data transmitted successfully" );
            }
        }
        else if ( PROTEUSE_CMD_RSP_CHANNEL_OPEN == ctx->evt_pkt.cmd )
        {
            log_printf( &logger, " < CHANNEL_OPEN_RSP -> " );
            if ( ctx->evt_pkt.payload[ 0 ] )
            {
                log_printf( &logger, "Failed" );
            }
            else
            {
                log_printf( &logger, "MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X, MPS: %u", 
                            ( uint16_t ) ctx->evt_pkt.payload[ 6 ], ( uint16_t ) ctx->evt_pkt.payload[ 5 ],
                            ( uint16_t ) ctx->evt_pkt.payload[ 4 ], ( uint16_t ) ctx->evt_pkt.payload[ 3 ],
                            ( uint16_t ) ctx->evt_pkt.payload[ 2 ], ( uint16_t ) ctx->evt_pkt.payload[ 1 ],
                            ( uint16_t ) ctx->evt_pkt.payload[ 7 ] );
            }
        }
        else
        {
            log_printf( &logger, " < UNKNOWN_RSP 0x%.2X", ( uint16_t ) ctx->evt_pkt.cmd );
        }
        log_printf( &logger, "\r\n\n" );
    }
    else
    {
        // Wrong packet type
        error_flag |= PROTEUSE_ERROR;
    }
    return error_flag;
}

static err_t proteuse_parse_ind ( proteuse_t *ctx )
{
    err_t error_flag = PROTEUSE_OK;
    uint16_t byte_cnt = 0;

    if ( PROTEUSE_CMD_TYPE_IND == ( ctx->evt_pkt.cmd & PROTEUSE_CMD_TYPE_MASK ) )
    {
        // Parse indication packet
        switch ( ctx->evt_pkt.cmd )
        {
            case PROTEUSE_CMD_IND_SLEEP:
            {
                log_printf( &logger, " < SLEEP_IND -> Advertising timeout detected, will go to sleep now" );
                break;
            }
            case PROTEUSE_CMD_IND_DATA:
            {
                log_printf( &logger, " < DATA_IND -> " );
                log_printf( &logger, "MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X, RSSI: %d\r\n", 
                            ( uint16_t ) ctx->evt_pkt.payload[ 5 ], ( uint16_t ) ctx->evt_pkt.payload[ 4 ],
                            ( uint16_t ) ctx->evt_pkt.payload[ 3 ], ( uint16_t ) ctx->evt_pkt.payload[ 2 ],
                            ( uint16_t ) ctx->evt_pkt.payload[ 1 ], ( uint16_t ) ctx->evt_pkt.payload[ 0 ],
                            ( int16_t ) ( ( int8_t ) ctx->evt_pkt.payload[ 6 ] ) );
                log_printf( &logger, "   Data (HEX): " );
                for ( byte_cnt = 7; byte_cnt < ctx->evt_pkt.payload_len; byte_cnt++ )
                {
                    log_printf( &logger, "0x%.2X ", ( uint16_t ) ctx->evt_pkt.payload[ byte_cnt ] );
                }
                ctx->evt_pkt.payload[ ctx->evt_pkt.payload_len ] = 0;
                log_printf( &logger, "\r\n   Data (STR): %s", &ctx->evt_pkt.payload[ 7 ] );
                
                log_printf( &logger, "\r\n\n>> Echo back the received message." );
                ctx->cmd_pkt.cmd = PROTEUSE_CMD_REQ_DATA;
                ctx->cmd_pkt.payload_len = ctx->evt_pkt.payload_len - 7;
                memcpy ( &ctx->cmd_pkt.payload[ 0 ], &ctx->evt_pkt.payload[ 7 ], ctx->evt_pkt.payload_len - 7 );
                proteuse_send_cmd ( ctx );
                break;
            }
            case PROTEUSE_CMD_IND_CONNECT:
            {
                log_printf( &logger, " < CONNECT_IND -> " );
                if ( ctx->evt_pkt.payload[ 0 ] )
                {
                    log_printf( &logger, "Connection failed, e.g. due to a timeout" );
                }
                else
                {
                    log_printf( &logger, "MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X", 
                                ( uint16_t ) ctx->evt_pkt.payload[ 6 ], ( uint16_t ) ctx->evt_pkt.payload[ 5 ],
                                ( uint16_t ) ctx->evt_pkt.payload[ 4 ], ( uint16_t ) ctx->evt_pkt.payload[ 3 ],
                                ( uint16_t ) ctx->evt_pkt.payload[ 2 ], ( uint16_t ) ctx->evt_pkt.payload[ 1 ] );
                }
                break;
            }
            case PROTEUSE_CMD_IND_DISCONNECT:
            {
                log_printf( &logger, " < DISCONNECT_IND -> " );
                switch ( ctx->evt_pkt.payload[ 0 ] )
                {
                    case PROTEUSE_IND_DISC_REASON_TIMEOUT:
                    {
                        log_printf( &logger, "Connection timeout" );
                        break;
                    }
                    case PROTEUSE_IND_DISC_REASON_USER_TERM:
                    {
                        log_printf( &logger, "User terminated connection" );
                        break;
                    }
                    case PROTEUSE_IND_DISC_REASON_HOST_TERM:
                    {
                        log_printf( &logger, "Host terminated connection" );
                        break;
                    }
                    case PROTEUSE_IND_DISC_REASON_CONN_INTERVAL:
                    {
                        log_printf( &logger, "Connection interval unacceptable" );
                        break;
                    }
                    case PROTEUSE_IND_DISC_REASON_MIC_FAILURE:
                    {
                        log_printf( &logger, "Connection terminated due to MIC failure" );
                        break;
                    }
                    case PROTEUSE_IND_DISC_REASON_SETUP_FAILED:
                    {
                        log_printf( &logger, "Connection setup failed" );
                        break;
                    }
                    default:
                    {
                        log_printf( &logger, "Unknown reason: 0x%.2X", ( uint16_t ) ctx->evt_pkt.payload[ 0 ] );
                        break;
                    }
                }
                break;
            }
            case PROTEUSE_CMD_IND_SECURITY:
            {
                log_printf( &logger, " < SECURITY_IND -> " );
                switch ( ctx->evt_pkt.payload[ 0 ] )
                {
                    case PROTEUSE_IND_SEC_STATUS_RE_BONDED:
                    {
                        log_printf( &logger, "Encrypted link to previously bonded device established\r\n" );
                        break;
                    }
                    case PROTEUSE_IND_SEC_STATUS_BONDED:
                    {
                        log_printf( &logger, "Bonding successful, encrypted link established\r\n" );
                        break;
                    }
                    case PROTEUSE_IND_SEC_STATUS_PAIRED:
                    {
                        log_printf( &logger, "No bonding, pairing successful, encrypted link established\r\n" );
                        break;
                    }
                    default:
                    {
                        log_printf( &logger, "Unknown status: 0x%.2X", ( uint16_t ) ctx->evt_pkt.payload[ 0 ] );
                        break;
                    }
                }
                log_printf( &logger, "   MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X", 
                            ( uint16_t ) ctx->evt_pkt.payload[ 6 ], ( uint16_t ) ctx->evt_pkt.payload[ 5 ],
                            ( uint16_t ) ctx->evt_pkt.payload[ 4 ], ( uint16_t ) ctx->evt_pkt.payload[ 3 ],
                            ( uint16_t ) ctx->evt_pkt.payload[ 2 ], ( uint16_t ) ctx->evt_pkt.payload[ 1 ] );
                break;
            }
            case PROTEUSE_CMD_IND_PHY_UPDATE:
            {
                log_printf( &logger, " < PHY_UPDATE_IND -> " );
                if ( ctx->evt_pkt.payload[ 0 ] )
                {
                    log_printf( &logger, "Unsupported feature of remote device" );
                }
                else
                {
                    log_printf( &logger, "RX: %uMBit, TX: %uMBit, ", 
                                ( uint16_t ) ctx->evt_pkt.payload[ 1 ], ( uint16_t ) ctx->evt_pkt.payload[ 2 ] );
                    log_printf( &logger, "MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X", 
                                ( uint16_t ) ctx->evt_pkt.payload[ 8 ], ( uint16_t ) ctx->evt_pkt.payload[ 7 ],
                                ( uint16_t ) ctx->evt_pkt.payload[ 6 ], ( uint16_t ) ctx->evt_pkt.payload[ 5 ],
                                ( uint16_t ) ctx->evt_pkt.payload[ 4 ], ( uint16_t ) ctx->evt_pkt.payload[ 3 ] );
                }
                break;
            }
            case PROTEUSE_CMD_IND_UART_ENABLE:
            {
                log_printf( &logger, " < UART_ENABLE_IND -> UART has been re-enabled successfully" );
                break;
            }
            case PROTEUSE_CMD_IND_ERROR:
            {
                log_printf( &logger, " < ERROR_IND -> UART buffer overflow" );
                break;
            }
            default:
            {
                log_printf( &logger, " < CMD_IND 0x%.2X -> ", ( uint16_t ) ctx->evt_pkt.cmd );
                for ( byte_cnt = 0; byte_cnt < ctx->evt_pkt.payload_len; byte_cnt++ )
                {
                    log_printf( &logger, "0x%.2X ", ( uint16_t ) ctx->evt_pkt.payload[ byte_cnt ] );
                }
                break;
            }
        }
        log_printf( &logger, "\r\n\n" );
    }
    else
    {
        // Wrong packet type
        error_flag |= PROTEUSE_ERROR;
    }
    return error_flag;
}

static err_t proteuse_parse_event ( proteuse_t *ctx )
{
    err_t error_flag = PROTEUSE_OK;

    if ( PROTEUSE_CMD_TYPE_CNF == ( ctx->evt_pkt.cmd & PROTEUSE_CMD_TYPE_MASK ) )
    {
        error_flag |= proteuse_parse_cnf ( ctx );
    }
    else if ( PROTEUSE_CMD_TYPE_RSP == ( ctx->evt_pkt.cmd & PROTEUSE_CMD_TYPE_MASK ) )
    {
        error_flag |= proteuse_parse_rsp ( ctx );
    }
    else if ( PROTEUSE_CMD_TYPE_IND == ( ctx->evt_pkt.cmd & PROTEUSE_CMD_TYPE_MASK ) )
    {
        error_flag |= proteuse_parse_ind ( ctx );
    }
    else
    {
        // Error packet should not be a command request
        error_flag |= PROTEUSE_ERROR;
    }
    return error_flag;
}

// ------------------------------------------------------------------------ END

额外支持

资源

喜欢这个项目吗?

'购买此套件' 按钮会直接带您进入购物车,您可以在购物车中轻松添加或移除产品。