Add bluetooth module and fix delay function in debug.c in ch32v208rbt6
1. Add command "test_ble" in shell to startup the ble module. The ble module could be found as "wch_ble_uart". But there is a bug: the command could be used only once before reset the board. 2. Fix a bug in Delay_Us function and Delay_Ms function in debug.c.
This commit is contained in:
parent
75c13d656b
commit
d75e3ad7f9
|
@ -52,6 +52,11 @@ void Delay_Init(void)
|
|||
*/
|
||||
void Delay_Us(uint32_t n)
|
||||
{
|
||||
// 保存SysTick所有相关状态
|
||||
u32 systick_ctlr = SysTick->CTLR;
|
||||
u64 systick_cmp = SysTick->CMP;
|
||||
u32 systick_sr = SysTick->SR;
|
||||
|
||||
uint32_t i;
|
||||
|
||||
SysTick->SR &= ~(1 << 0);
|
||||
|
@ -63,6 +68,11 @@ void Delay_Us(uint32_t n)
|
|||
|
||||
while((SysTick->SR & (1 << 0)) != (1 << 0));
|
||||
SysTick->CTLR &= ~(1 << 0);
|
||||
|
||||
// 恢复SysTick所有状态
|
||||
SysTick->CTLR = systick_ctlr; // 恢复控制寄存器状态,包括中断使能、计数器使能等
|
||||
SysTick->CMP = systick_cmp; // 恢复比较值
|
||||
SysTick->SR = systick_sr; // 恢复状态寄存器状态,注意清中断位的操作应根据实际情况调整
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
@ -78,12 +88,10 @@ void Delay_Ms(uint32_t n)
|
|||
{
|
||||
uint32_t i;
|
||||
|
||||
// 保存原始状态
|
||||
if (originalSysTickState.SR == 0) {
|
||||
originalSysTickState.SR = SysTick->SR;
|
||||
originalSysTickState.CMP = SysTick->CMP;
|
||||
originalSysTickState.CTLR = SysTick->CTLR;
|
||||
}
|
||||
// 保存SysTick所有相关状态
|
||||
u32 systick_ctlr = SysTick->CTLR;
|
||||
u64 systick_cmp = SysTick->CMP;
|
||||
u32 systick_sr = SysTick->SR;
|
||||
|
||||
SysTick->SR &= ~(1 << 0);
|
||||
i = (uint32_t)n * p_ms;
|
||||
|
@ -94,10 +102,11 @@ void Delay_Ms(uint32_t n)
|
|||
|
||||
while((SysTick->SR & (1 << 0)) != (1 << 0));
|
||||
SysTick->CTLR &= ~(1 << 0);
|
||||
// 恢复原始状态
|
||||
SysTick->SR = originalSysTickState.SR;
|
||||
SysTick->CMP = originalSysTickState.CMP;
|
||||
SysTick->CTLR = originalSysTickState.CTLR;
|
||||
|
||||
// 恢复SysTick所有状态
|
||||
SysTick->CTLR = systick_ctlr; // 恢复控制寄存器状态,包括中断使能、计数器使能等
|
||||
SysTick->CMP = systick_cmp; // 恢复比较值
|
||||
SysTick->SR = systick_sr; // 恢复状态寄存器状态,注意清中断位的操作应根据实际情况调整
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
SRC_FILES := boot.S interrupt.c tick.c switch.S prepare_rhwstack.c interrupt_switch.S
|
||||
SRC_FILES := boot.S interrupt.c tick.c switch.S prepare_rhwstack.c interrupt_switch.S ble_task_scheduler.S
|
||||
SRC_DIR := Core User Debug
|
||||
# interrupt_switch.S
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
|
@ -15,12 +15,13 @@
|
|||
#include "ch32v20x_tim.h"
|
||||
#include "eth_driver.h"
|
||||
#include <xs_isr.h>
|
||||
#include "wchble.h"
|
||||
|
||||
void NMI_Handler(void) __attribute__((interrupt()));
|
||||
void HardFault_Handler(void) __attribute__((interrupt()));
|
||||
void ETH_IRQHandler(void) __attribute__((interrupt()));
|
||||
void TIM2_IRQHandler(void) __attribute__((interrupt()));
|
||||
|
||||
void BB_IRQHandler(void) __attribute__((interrupt()));
|
||||
/*********************************************************************
|
||||
* @fn NMI_Handler
|
||||
*
|
||||
|
@ -67,6 +68,7 @@ void HardFault_Handler(void)
|
|||
*
|
||||
* @return none
|
||||
*/
|
||||
#ifdef BSP_USING_ETH
|
||||
void ETH_IRQHandler(void)
|
||||
{
|
||||
WCHNET_ETHIsr();
|
||||
|
@ -86,5 +88,18 @@ void TIM2_IRQHandler(void)
|
|||
WCHNET_TimeIsr(WCHNETTIMERPERIOD);
|
||||
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* @fn BB_IRQHandler
|
||||
*
|
||||
* @brief BB Interrupt for BLE.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
#ifdef BSP_USING_BLE
|
||||
void BB_IRQHandler(void)
|
||||
{
|
||||
BB_IRQLibHandler();
|
||||
}
|
||||
#endif
|
|
@ -23,14 +23,14 @@
|
|||
//#define SYSCLK_FREQ_56MHz_HSE 56000000
|
||||
//#define SYSCLK_FREQ_72MHz_HSE 72000000
|
||||
//#define SYSCLK_FREQ_96MHz_HSE 96000000
|
||||
//#define SYSCLK_FREQ_120MHz_HSE 120000000
|
||||
#define SYSCLK_FREQ_120MHz_HSE 120000000
|
||||
//#define SYSCLK_FREQ_144MHz_HSE 144000000
|
||||
//#define SYSCLK_FREQ_HSI HSI_VALUE
|
||||
//#define SYSCLK_FREQ_48MHz_HSI 48000000
|
||||
//#define SYSCLK_FREQ_56MHz_HSI 56000000
|
||||
//#define SYSCLK_FREQ_72MHz_HSI 72000000
|
||||
// #define SYSCLK_FREQ_96MHz_HSI 96000000
|
||||
#define SYSCLK_FREQ_120MHz_HSI 120000000
|
||||
// #define SYSCLK_FREQ_120MHz_HSI 120000000
|
||||
//#define SYSCLK_FREQ_144MHz_HSI 144000000
|
||||
|
||||
/* Clock Definitions */
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
.global Ecall_M_Mode_Handler
|
||||
.global Ecall_U_Mode_Handler
|
||||
.global LLE_IRQHandler
|
||||
|
||||
.extern g_LLE_IRQLibHandlerLocation
|
||||
|
||||
.section .highcode,"ax",@progbits
|
||||
.align 2
|
||||
.func
|
||||
Ecall_M_Mode_Handler:
|
||||
Ecall_U_Mode_Handler:
|
||||
|
||||
addi a1, x0, 0x20
|
||||
csrs 0x804, a1
|
||||
|
||||
lw a1, 0 * 4( sp )
|
||||
csrw mepc, a1
|
||||
|
||||
lw x1, 1 * 4( sp )
|
||||
lw x4, 2 * 4( sp )
|
||||
lw x5, 3 * 4( sp )
|
||||
lw x6, 4 * 4( sp )
|
||||
lw x7, 5 * 4( sp )
|
||||
lw x8, 6 * 4( sp )
|
||||
lw x9, 7 * 4( sp )
|
||||
lw x10, 8 * 4( sp )
|
||||
lw x11, 9 * 4( sp )
|
||||
lw x12, 10 * 4( sp )
|
||||
lw x13, 11 * 4( sp )
|
||||
lw x14, 12 * 4( sp )
|
||||
lw x15, 13 * 4( sp )
|
||||
lw x16, 14 * 4( sp )
|
||||
lw x17, 15 * 4( sp )
|
||||
lw x18, 16 * 4( sp )
|
||||
lw x19, 17 * 4( sp )
|
||||
lw x20, 18 * 4( sp )
|
||||
lw x21, 19 * 4( sp )
|
||||
lw x22, 20 * 4( sp )
|
||||
lw x23, 21 * 4( sp )
|
||||
lw x24, 22 * 4( sp )
|
||||
lw x25, 23 * 4( sp )
|
||||
lw x26, 24 * 4( sp )
|
||||
lw x27, 25 * 4( sp )
|
||||
lw x28, 26 * 4( sp )
|
||||
lw x29, 27 * 4( sp )
|
||||
lw x30, 28 * 4( sp )
|
||||
lw x31, 29 * 4( sp )
|
||||
|
||||
addi sp, sp, 32*4
|
||||
|
||||
mret
|
||||
.endfunc
|
||||
|
||||
.section .highcode.LLE_IRQHandler,"ax",@progbits
|
||||
.align 2
|
||||
.func
|
||||
LLE_IRQHandler:
|
||||
addi sp, sp, -32*4
|
||||
|
||||
sw x1, 1 * 4( sp )
|
||||
sw x4, 2 * 4( sp )
|
||||
sw x5, 3 * 4( sp )
|
||||
sw x6, 4 * 4( sp )
|
||||
sw x7, 5 * 4( sp )
|
||||
sw x8, 6 * 4( sp )
|
||||
sw x9, 7 * 4( sp )
|
||||
sw x10, 8 * 4( sp )
|
||||
sw x11, 9 * 4( sp )
|
||||
sw x12, 10 * 4( sp )
|
||||
sw x13, 11 * 4( sp )
|
||||
sw x14, 12 * 4( sp )
|
||||
sw x15, 13 * 4( sp )
|
||||
sw x16, 14 * 4( sp )
|
||||
sw x17, 15 * 4( sp )
|
||||
sw x18, 16 * 4( sp )
|
||||
sw x19, 17 * 4( sp )
|
||||
sw x20, 18 * 4( sp )
|
||||
sw x21, 19 * 4( sp )
|
||||
sw x22, 20 * 4( sp )
|
||||
sw x23, 21 * 4( sp )
|
||||
sw x24, 22 * 4( sp )
|
||||
sw x25, 23 * 4( sp )
|
||||
sw x26, 24 * 4( sp )
|
||||
sw x27, 25 * 4( sp )
|
||||
sw x28, 26 * 4( sp )
|
||||
sw x29, 27 * 4( sp )
|
||||
sw x30, 28 * 4( sp )
|
||||
sw x31, 29 * 4( sp )
|
||||
|
||||
la a1, g_LLE_IRQLibHandlerLocation
|
||||
lw a0, 0(a1)
|
||||
jalr x1, 0(a0)
|
||||
|
||||
lw x1, 1 * 4( sp )
|
||||
lw x4, 2 * 4( sp )
|
||||
lw x5, 3 * 4( sp )
|
||||
lw x6, 4 * 4( sp )
|
||||
lw x7, 5 * 4( sp )
|
||||
lw x8, 6 * 4( sp )
|
||||
lw x9, 7 * 4( sp )
|
||||
lw x10, 8 * 4( sp )
|
||||
lw x11, 9 * 4( sp )
|
||||
lw x12, 10 * 4( sp )
|
||||
lw x13, 11 * 4( sp )
|
||||
lw x14, 12 * 4( sp )
|
||||
lw x15, 13 * 4( sp )
|
||||
lw x16, 14 * 4( sp )
|
||||
lw x17, 15 * 4( sp )
|
||||
lw x18, 16 * 4( sp )
|
||||
lw x19, 17 * 4( sp )
|
||||
lw x20, 18 * 4( sp )
|
||||
lw x21, 19 * 4( sp )
|
||||
lw x22, 20 * 4( sp )
|
||||
lw x23, 21 * 4( sp )
|
||||
lw x24, 22 * 4( sp )
|
||||
lw x25, 23 * 4( sp )
|
||||
lw x26, 24 * 4( sp )
|
||||
lw x27, 25 * 4( sp )
|
||||
lw x28, 26 * 4( sp )
|
||||
lw x29, 27 * 4( sp )
|
||||
lw x30, 28 * 4( sp )
|
||||
lw x31, 29 * 4( sp )
|
||||
|
||||
addi sp, sp, 32*4
|
||||
|
||||
mret
|
||||
.endfunc
|
|
@ -38,6 +38,8 @@
|
|||
#include <xs_base.h>
|
||||
#include "connect_ether.h"
|
||||
#include "adc.h"
|
||||
#include "third_party_driver/ble/inc/wchble.h"
|
||||
#include "third_party_driver/ble/inc/HAL.h"
|
||||
|
||||
// core clock.
|
||||
extern uint32_t SystemCoreClock;
|
||||
|
@ -67,14 +69,24 @@ void InitBoardHardware()
|
|||
_SysTick_Config(SystemCoreClock / TICK_PER_SECOND);
|
||||
/* initialize memory system */
|
||||
InitBoardMemory(MEMORY_START_ADDRESS, (void*)MEMORY_END_ADDRESS);
|
||||
|
||||
#ifdef BSP_USING_UART
|
||||
InitHwUart();
|
||||
InstallConsole("uart1", SERIAL_DRV_NAME_1, SERIAL_1_DEVICE_NAME_0);
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_ETH
|
||||
InitHwEth();
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_ADC
|
||||
ADC_Function_Init();
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_BLE
|
||||
WCHBLE_Init();
|
||||
HAL_Init();
|
||||
#endif
|
||||
KPrintf("consle init completed.\n");
|
||||
KPrintf("board initialization......\n");
|
||||
// KPrintf("memory address range: [0x%08x - 0x%08x], size: %d\n", (x_ubase) MEMORY_START_ADDRESS, (x_ubase) MEMORY_END_ADDRESS, gd32vf103_SRAM_SIZE);
|
||||
|
|
|
@ -36,12 +36,12 @@ Modification:
|
|||
|
||||
#define ch32v20x_PIN_NUMBERS 48
|
||||
/* board configuration */
|
||||
#define SRAM_SIZE 48
|
||||
#define SRAM_SIZE 64
|
||||
#define EUSR_STACK_SIZE 2048
|
||||
|
||||
// #define SRAM_END (0x20000000 + SRAM_SIZE * 0x400)
|
||||
// #define SRAM_END (0x20008000)
|
||||
#define SRAM_END (0x2000C000)
|
||||
#define SRAM_END (0x20010000)
|
||||
extern int _ebss;
|
||||
extern int __stack_size;
|
||||
#define MEMORY_START_ADDRESS ((void *)&_ebss)
|
||||
|
|
|
@ -16,6 +16,7 @@ export CROSS_COMPILE ?=/opt/riscv64-toolchain/bin/riscv64-unknown-elf-
|
|||
export DEFINES := -DHAVE_CCONFIG_H -DHAVE_SIGINFO
|
||||
|
||||
export LINK_WCH_NET := $(KERNEL_ROOT)/board/ch32v208rbt6/third_party_driver/ethernet/libwchnet.a
|
||||
export LINK_WCH_BLE := $(KERNEL_ROOT)/board/ch32v208rbt6/third_party_driver/ble/lib/libwchble.a
|
||||
|
||||
export ARCH = risc-v
|
||||
export MCU = CH32V208
|
||||
|
|
|
@ -17,7 +17,7 @@ MEMORY
|
|||
/*
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 64K
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
|
||||
*/
|
||||
*/
|
||||
|
||||
/* CH32V20x_D8 - CH32V203RB
|
||||
CH32V20x_D8W - CH32V208x
|
||||
|
@ -26,8 +26,8 @@ MEMORY
|
|||
FLASH-144K + RAM-48K
|
||||
FLASH-160K + RAM-32K
|
||||
*/
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 144K
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 48K
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 448K
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
|
||||
}
|
||||
|
||||
|
||||
|
@ -48,14 +48,26 @@ SECTIONS
|
|||
*(.vector);
|
||||
. = ALIGN(64);
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
|
||||
.highcode :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.highcode);
|
||||
*(.highcode.*);
|
||||
. = ALIGN(4);
|
||||
} >FLASH AT>FLASH
|
||||
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
EXCLUDE_FILE (*wchble.a) *(.text .text*)
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.rodata)
|
||||
*(.rodata*)
|
||||
*(.sdata2.*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.gnu.linkonce.t.*)
|
||||
. = ALIGN(4);
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
menuconfig BSP_USING_UART
|
||||
bool "Using UART device"
|
||||
default y
|
||||
|
@ -14,4 +13,8 @@ menuconfig BSP_USING_ETH
|
|||
menuconfig BSP_USING_ADC
|
||||
bool "Using ADC"
|
||||
default y
|
||||
|
||||
menuconfig BSP_USING_BLE
|
||||
bool "Using BLE"
|
||||
default y
|
||||
|
|
@ -10,4 +10,7 @@ endif
|
|||
ifeq ($(CONFIG_BSP_USING_ADC),y)
|
||||
SRC_DIR += adc
|
||||
endif
|
||||
ifeq ($(CONFIG_BSP_USING_BLE),y)
|
||||
SRC_DIR += ble
|
||||
endif
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES :=
|
||||
SRC_DIR := test Profile src
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := devinfoservice.c gattprofile.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,588 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : devinfoservice.c
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2018/12/10
|
||||
* Description : Device information service
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
#include "../inc/config.h"
|
||||
#include "devinfoservice.h"
|
||||
|
||||
/*********************************************************************
|
||||
* MACROS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* CONSTANTS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* TYPEDEFS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*/
|
||||
// Device information service
|
||||
const uint8_t devInfoServUUID[ATT_BT_UUID_SIZE] = {
|
||||
LO_UINT16(DEVINFO_SERV_UUID), HI_UINT16(DEVINFO_SERV_UUID)};
|
||||
|
||||
// System ID
|
||||
const uint8_t devInfoSystemIdUUID[ATT_BT_UUID_SIZE] = {
|
||||
LO_UINT16(SYSTEM_ID_UUID), HI_UINT16(SYSTEM_ID_UUID)};
|
||||
|
||||
// Model Number String
|
||||
const uint8_t devInfoModelNumberUUID[ATT_BT_UUID_SIZE] = {
|
||||
LO_UINT16(MODEL_NUMBER_UUID), HI_UINT16(MODEL_NUMBER_UUID)};
|
||||
|
||||
// Serial Number String
|
||||
const uint8_t devInfoSerialNumberUUID[ATT_BT_UUID_SIZE] = {
|
||||
LO_UINT16(SERIAL_NUMBER_UUID), HI_UINT16(SERIAL_NUMBER_UUID)};
|
||||
|
||||
// Firmware Revision String
|
||||
const uint8_t devInfoFirmwareRevUUID[ATT_BT_UUID_SIZE] = {
|
||||
LO_UINT16(FIRMWARE_REV_UUID), HI_UINT16(FIRMWARE_REV_UUID)};
|
||||
|
||||
// Hardware Revision String
|
||||
const uint8_t devInfoHardwareRevUUID[ATT_BT_UUID_SIZE] = {
|
||||
LO_UINT16(HARDWARE_REV_UUID), HI_UINT16(HARDWARE_REV_UUID)};
|
||||
|
||||
// Software Revision String
|
||||
const uint8_t devInfoSoftwareRevUUID[ATT_BT_UUID_SIZE] = {
|
||||
LO_UINT16(SOFTWARE_REV_UUID), HI_UINT16(SOFTWARE_REV_UUID)};
|
||||
|
||||
// Manufacturer Name String
|
||||
const uint8_t devInfoMfrNameUUID[ATT_BT_UUID_SIZE] = {
|
||||
LO_UINT16(MANUFACTURER_NAME_UUID), HI_UINT16(MANUFACTURER_NAME_UUID)};
|
||||
|
||||
// IEEE 11073-20601 Regulatory Certification Data List
|
||||
const uint8_t devInfo11073CertUUID[ATT_BT_UUID_SIZE] = {
|
||||
LO_UINT16(IEEE_11073_CERT_DATA_UUID), HI_UINT16(IEEE_11073_CERT_DATA_UUID)};
|
||||
|
||||
// PnP ID
|
||||
const uint8_t devInfoPnpIdUUID[ATT_BT_UUID_SIZE] = {
|
||||
LO_UINT16(PNP_ID_UUID), HI_UINT16(PNP_ID_UUID)};
|
||||
|
||||
/*********************************************************************
|
||||
* EXTERNAL VARIABLES
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* EXTERNAL FUNCTIONS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* LOCAL VARIABLES
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* Profile Attributes - variables
|
||||
*/
|
||||
|
||||
// Device Information Service attribute
|
||||
static const gattAttrType_t devInfoService = {ATT_BT_UUID_SIZE, devInfoServUUID};
|
||||
|
||||
// System ID characteristic
|
||||
static uint8_t devInfoSystemIdProps = GATT_PROP_READ;
|
||||
static uint8_t devInfoSystemId[DEVINFO_SYSTEM_ID_LEN] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
// Model Number String characteristic
|
||||
static uint8_t devInfoModelNumberProps = GATT_PROP_READ;
|
||||
static const uint8_t devInfoModelNumber[] = "Model Number";
|
||||
|
||||
// Serial Number String characteristic
|
||||
static uint8_t devInfoSerialNumberProps = GATT_PROP_READ;
|
||||
static const uint8_t devInfoSerialNumber[] = "Serial Number";
|
||||
|
||||
// Firmware Revision String characteristic
|
||||
static uint8_t devInfoFirmwareRevProps = GATT_PROP_READ;
|
||||
static const uint8_t devInfoFirmwareRev[] = "Firmware Revision";
|
||||
|
||||
// Hardware Revision String characteristic
|
||||
static uint8_t devInfoHardwareRevProps = GATT_PROP_READ;
|
||||
static const uint8_t devInfoHardwareRev[] = "Hardware Revision";
|
||||
|
||||
// Software Revision String characteristic
|
||||
static uint8_t devInfoSoftwareRevProps = GATT_PROP_READ;
|
||||
static const uint8_t devInfoSoftwareRev[] = "Software Revision";
|
||||
|
||||
// Manufacturer Name String characteristic
|
||||
static uint8_t devInfoMfrNameProps = GATT_PROP_READ;
|
||||
static const uint8_t devInfoMfrName[] = "Manufacturer Name";
|
||||
|
||||
// IEEE 11073-20601 Regulatory Certification Data List characteristic
|
||||
static uint8_t devInfo11073CertProps = GATT_PROP_READ;
|
||||
static const uint8_t devInfo11073Cert[] = {
|
||||
DEVINFO_11073_BODY_EXP, // authoritative body type
|
||||
0x00, // authoritative body structure type
|
||||
// authoritative body data follows below:
|
||||
'e', 'x', 'p', 'e', 'r', 'i', 'm', 'e', 'n', 't', 'a', 'l'};
|
||||
|
||||
// System ID characteristic
|
||||
static uint8_t devInfoPnpIdProps = GATT_PROP_READ;
|
||||
static uint8_t devInfoPnpId[DEVINFO_PNP_ID_LEN] = {
|
||||
1, // Vendor ID source (1=Bluetooth SIG)
|
||||
LO_UINT16(0x07D7), HI_UINT16(0x07D7), // Vendor ID (WCH)
|
||||
LO_UINT16(0x0000), HI_UINT16(0x0000), // Product ID (vendor-specific)
|
||||
LO_UINT16(0x0110), HI_UINT16(0x0110) // Product version (JJ.M.N)
|
||||
};
|
||||
|
||||
/*********************************************************************
|
||||
* Profile Attributes - Table
|
||||
*/
|
||||
|
||||
static gattAttribute_t devInfoAttrTbl[] = {
|
||||
// Device Information Service
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, primaryServiceUUID}, /* type */
|
||||
GATT_PERMIT_READ, /* permissions */
|
||||
0, /* handle */
|
||||
(uint8_t *)&devInfoService /* pValue */
|
||||
},
|
||||
|
||||
// System ID Declaration
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, characterUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
&devInfoSystemIdProps},
|
||||
|
||||
// System ID Value
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, devInfoSystemIdUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
(uint8_t *)devInfoSystemId},
|
||||
|
||||
// Model Number String Declaration
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, characterUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
&devInfoModelNumberProps},
|
||||
|
||||
// Model Number Value
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, devInfoModelNumberUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
(uint8_t *)devInfoModelNumber},
|
||||
|
||||
// Serial Number String Declaration
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, characterUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
&devInfoSerialNumberProps},
|
||||
|
||||
// Serial Number Value
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, devInfoSerialNumberUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
(uint8_t *)devInfoSerialNumber},
|
||||
|
||||
// Firmware Revision String Declaration
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, characterUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
&devInfoFirmwareRevProps},
|
||||
|
||||
// Firmware Revision Value
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, devInfoFirmwareRevUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
(uint8_t *)devInfoFirmwareRev},
|
||||
|
||||
// Hardware Revision String Declaration
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, characterUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
&devInfoHardwareRevProps},
|
||||
|
||||
// Hardware Revision Value
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, devInfoHardwareRevUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
(uint8_t *)devInfoHardwareRev},
|
||||
|
||||
// Software Revision String Declaration
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, characterUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
&devInfoSoftwareRevProps},
|
||||
|
||||
// Software Revision Value
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, devInfoSoftwareRevUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
(uint8_t *)devInfoSoftwareRev},
|
||||
|
||||
// Manufacturer Name String Declaration
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, characterUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
&devInfoMfrNameProps},
|
||||
|
||||
// Manufacturer Name Value
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, devInfoMfrNameUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
(uint8_t *)devInfoMfrName},
|
||||
|
||||
// IEEE 11073-20601 Regulatory Certification Data List Declaration
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, characterUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
&devInfo11073CertProps},
|
||||
|
||||
// IEEE 11073-20601 Regulatory Certification Data List Value
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, devInfo11073CertUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
(uint8_t *)devInfo11073Cert},
|
||||
|
||||
// PnP ID Declaration
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, characterUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
&devInfoPnpIdProps},
|
||||
|
||||
// PnP ID Value
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, devInfoPnpIdUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
(uint8_t *)devInfoPnpId}};
|
||||
|
||||
/*********************************************************************
|
||||
* LOCAL FUNCTIONS
|
||||
*/
|
||||
static bStatus_t devInfo_ReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
|
||||
uint8_t *pValue, uint16_t *pLen, uint16_t offset, uint16_t maxLen, uint8_t method);
|
||||
|
||||
/*********************************************************************
|
||||
* PROFILE CALLBACKS
|
||||
*/
|
||||
// Device Info Service Callbacks
|
||||
gattServiceCBs_t devInfoCBs = {
|
||||
devInfo_ReadAttrCB, // Read callback function pointer
|
||||
NULL, // Write callback function pointer
|
||||
NULL // Authorization callback function pointer
|
||||
};
|
||||
|
||||
/*********************************************************************
|
||||
* NETWORK LAYER CALLBACKS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* PUBLIC FUNCTIONS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* @fn DevInfo_AddService
|
||||
*
|
||||
* @brief Initializes the Device Information service by registering
|
||||
* GATT attributes with the GATT server.
|
||||
*
|
||||
* @return Success or Failure
|
||||
*/
|
||||
bStatus_t DevInfo_AddService(void)
|
||||
{
|
||||
// Register GATT attribute list and CBs with GATT Server App
|
||||
return GATTServApp_RegisterService(devInfoAttrTbl,
|
||||
GATT_NUM_ATTRS(devInfoAttrTbl),
|
||||
GATT_MAX_ENCRYPT_KEY_SIZE,
|
||||
&devInfoCBs);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn DevInfo_SetParameter
|
||||
*
|
||||
* @brief Set a Device Information parameter.
|
||||
*
|
||||
* @param param - Profile parameter ID
|
||||
* @param len - length of data to write
|
||||
* @param value - pointer to data to write. This is dependent on
|
||||
* the parameter ID and WILL be cast to the appropriate
|
||||
* data type (example: data type of uint16_t will be cast to
|
||||
* uint16_t pointer).
|
||||
*
|
||||
* @return bStatus_t
|
||||
*/
|
||||
bStatus_t DevInfo_SetParameter(uint8_t param, uint8_t len, void *value)
|
||||
{
|
||||
bStatus_t ret = SUCCESS;
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case DEVINFO_SYSTEM_ID:
|
||||
tmos_memcpy(devInfoSystemId, value, len);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = INVALIDPARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn DevInfo_GetParameter
|
||||
*
|
||||
* @brief Get a Device Information parameter.
|
||||
*
|
||||
* @param param - Profile parameter ID
|
||||
* @param value - pointer to data to get. This is dependent on
|
||||
* the parameter ID and WILL be cast to the appropriate
|
||||
* data type (example: data type of uint16_t will be cast to
|
||||
* uint16_t pointer).
|
||||
*
|
||||
* @return bStatus_t
|
||||
*/
|
||||
bStatus_t DevInfo_GetParameter(uint8_t param, void *value)
|
||||
{
|
||||
bStatus_t ret = SUCCESS;
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case DEVINFO_SYSTEM_ID:
|
||||
tmos_memcpy(value, devInfoSystemId, sizeof(devInfoSystemId));
|
||||
break;
|
||||
|
||||
case DEVINFO_MODEL_NUMBER:
|
||||
tmos_memcpy(value, devInfoModelNumber, sizeof(devInfoModelNumber));
|
||||
break;
|
||||
case DEVINFO_SERIAL_NUMBER:
|
||||
tmos_memcpy(value, devInfoSerialNumber, sizeof(devInfoSerialNumber));
|
||||
break;
|
||||
|
||||
case DEVINFO_FIRMWARE_REV:
|
||||
tmos_memcpy(value, devInfoFirmwareRev, sizeof(devInfoFirmwareRev));
|
||||
break;
|
||||
|
||||
case DEVINFO_HARDWARE_REV:
|
||||
tmos_memcpy(value, devInfoHardwareRev, sizeof(devInfoHardwareRev));
|
||||
break;
|
||||
|
||||
case DEVINFO_SOFTWARE_REV:
|
||||
tmos_memcpy(value, devInfoSoftwareRev, sizeof(devInfoSoftwareRev));
|
||||
break;
|
||||
|
||||
case DEVINFO_MANUFACTURER_NAME:
|
||||
tmos_memcpy(value, devInfoMfrName, sizeof(devInfoMfrName));
|
||||
break;
|
||||
|
||||
case DEVINFO_11073_CERT_DATA:
|
||||
tmos_memcpy(value, devInfo11073Cert, sizeof(devInfo11073Cert));
|
||||
break;
|
||||
|
||||
case DEVINFO_PNP_ID:
|
||||
tmos_memcpy(value, devInfoPnpId, sizeof(devInfoPnpId));
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = INVALIDPARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn devInfo_ReadAttrCB
|
||||
*
|
||||
* @brief Read an attribute.
|
||||
*
|
||||
* @param connHandle - connection message was received on
|
||||
* @param pAttr - pointer to attribute
|
||||
* @param pValue - pointer to data to be read
|
||||
* @param pLen - length of data to be read
|
||||
* @param offset - offset of the first octet to be read
|
||||
* @param maxLen - maximum length of data to be read
|
||||
*
|
||||
* @return Success or Failure
|
||||
*/
|
||||
static bStatus_t devInfo_ReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
|
||||
uint8_t *pValue, uint16_t *pLen, uint16_t offset, uint16_t maxLen, uint8_t method)
|
||||
{
|
||||
bStatus_t status = SUCCESS;
|
||||
uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
|
||||
|
||||
switch(uuid)
|
||||
{
|
||||
case SYSTEM_ID_UUID:
|
||||
// verify offset
|
||||
if(offset >= sizeof(devInfoSystemId))
|
||||
{
|
||||
status = ATT_ERR_INVALID_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
// determine read length
|
||||
*pLen = MIN(maxLen, (sizeof(devInfoSystemId) - offset));
|
||||
|
||||
// copy data
|
||||
tmos_memcpy(pValue, &devInfoSystemId[offset], *pLen);
|
||||
}
|
||||
break;
|
||||
|
||||
case MODEL_NUMBER_UUID:
|
||||
// verify offset
|
||||
if(offset >= (sizeof(devInfoModelNumber) - 1))
|
||||
{
|
||||
status = ATT_ERR_INVALID_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
// determine read length (exclude null terminating character)
|
||||
*pLen = MIN(maxLen, ((sizeof(devInfoModelNumber) - 1) - offset));
|
||||
|
||||
// copy data
|
||||
tmos_memcpy(pValue, &devInfoModelNumber[offset], *pLen);
|
||||
}
|
||||
break;
|
||||
|
||||
case SERIAL_NUMBER_UUID:
|
||||
// verify offset
|
||||
if(offset >= (sizeof(devInfoSerialNumber) - 1))
|
||||
{
|
||||
status = ATT_ERR_INVALID_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
// determine read length (exclude null terminating character)
|
||||
*pLen = MIN(maxLen, ((sizeof(devInfoSerialNumber) - 1) - offset));
|
||||
|
||||
// copy data
|
||||
tmos_memcpy(pValue, &devInfoSerialNumber[offset], *pLen);
|
||||
}
|
||||
break;
|
||||
|
||||
case FIRMWARE_REV_UUID:
|
||||
// verify offset
|
||||
if(offset >= (sizeof(devInfoFirmwareRev) - 1))
|
||||
{
|
||||
status = ATT_ERR_INVALID_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
// determine read length (exclude null terminating character)
|
||||
*pLen = MIN(maxLen, ((sizeof(devInfoFirmwareRev) - 1) - offset));
|
||||
|
||||
// copy data
|
||||
tmos_memcpy(pValue, &devInfoFirmwareRev[offset], *pLen);
|
||||
}
|
||||
break;
|
||||
|
||||
case HARDWARE_REV_UUID:
|
||||
// verify offset
|
||||
if(offset >= (sizeof(devInfoHardwareRev) - 1))
|
||||
{
|
||||
status = ATT_ERR_INVALID_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
// determine read length (exclude null terminating character)
|
||||
*pLen = MIN(maxLen, ((sizeof(devInfoHardwareRev) - 1) - offset));
|
||||
|
||||
// copy data
|
||||
tmos_memcpy(pValue, &devInfoHardwareRev[offset], *pLen);
|
||||
}
|
||||
break;
|
||||
|
||||
case SOFTWARE_REV_UUID:
|
||||
// verify offset
|
||||
if(offset >= (sizeof(devInfoSoftwareRev) - 1))
|
||||
{
|
||||
status = ATT_ERR_INVALID_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
// determine read length (exclude null terminating character)
|
||||
*pLen = MIN(maxLen, ((sizeof(devInfoSoftwareRev) - 1) - offset));
|
||||
|
||||
// copy data
|
||||
tmos_memcpy(pValue, &devInfoSoftwareRev[offset], *pLen);
|
||||
}
|
||||
break;
|
||||
|
||||
case MANUFACTURER_NAME_UUID:
|
||||
// verify offset
|
||||
if(offset >= (sizeof(devInfoMfrName) - 1))
|
||||
{
|
||||
status = ATT_ERR_INVALID_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
// determine read length (exclude null terminating character)
|
||||
*pLen = MIN(maxLen, ((sizeof(devInfoMfrName) - 1) - offset));
|
||||
|
||||
// copy data
|
||||
tmos_memcpy(pValue, &devInfoMfrName[offset], *pLen);
|
||||
}
|
||||
break;
|
||||
|
||||
case IEEE_11073_CERT_DATA_UUID:
|
||||
// verify offset
|
||||
if(offset >= sizeof(devInfo11073Cert))
|
||||
{
|
||||
status = ATT_ERR_INVALID_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
// determine read length
|
||||
*pLen = MIN(maxLen, (sizeof(devInfo11073Cert) - offset));
|
||||
|
||||
// copy data
|
||||
tmos_memcpy(pValue, &devInfo11073Cert[offset], *pLen);
|
||||
}
|
||||
break;
|
||||
|
||||
case PNP_ID_UUID:
|
||||
// verify offset
|
||||
if(offset >= sizeof(devInfoPnpId))
|
||||
{
|
||||
status = ATT_ERR_INVALID_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
// determine read length
|
||||
*pLen = MIN(maxLen, (sizeof(devInfoPnpId) - offset));
|
||||
|
||||
// copy data
|
||||
tmos_memcpy(pValue, &devInfoPnpId[offset], *pLen);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
*pLen = 0;
|
||||
status = ATT_ERR_ATTR_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
|
@ -0,0 +1,109 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : devinfoservice.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2018/12/11
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef DEVINFOSERVICE_H
|
||||
#define DEVINFOSERVICE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* CONSTANTS
|
||||
*/
|
||||
|
||||
// Device Information Service Parameters
|
||||
#define DEVINFO_SYSTEM_ID 0
|
||||
#define DEVINFO_MODEL_NUMBER 1
|
||||
#define DEVINFO_SERIAL_NUMBER 2
|
||||
#define DEVINFO_FIRMWARE_REV 3
|
||||
#define DEVINFO_HARDWARE_REV 4
|
||||
#define DEVINFO_SOFTWARE_REV 5
|
||||
#define DEVINFO_MANUFACTURER_NAME 6
|
||||
#define DEVINFO_11073_CERT_DATA 7
|
||||
#define DEVINFO_PNP_ID 8
|
||||
|
||||
// IEEE 11073 authoritative body values
|
||||
#define DEVINFO_11073_BODY_EMPTY 0
|
||||
#define DEVINFO_11073_BODY_IEEE 1
|
||||
#define DEVINFO_11073_BODY_CONTINUA 2
|
||||
#define DEVINFO_11073_BODY_EXP 254
|
||||
|
||||
// System ID length
|
||||
#define DEVINFO_SYSTEM_ID_LEN 8
|
||||
|
||||
// PnP ID length
|
||||
#define DEVINFO_PNP_ID_LEN 7
|
||||
|
||||
/*********************************************************************
|
||||
* TYPEDEFS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* MACROS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* Profile Callbacks
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* API FUNCTIONS
|
||||
*/
|
||||
|
||||
/*
|
||||
* DevInfo_AddService- Initializes the Device Information service by registering
|
||||
* GATT attributes with the GATT server.
|
||||
*
|
||||
*/
|
||||
|
||||
extern bStatus_t DevInfo_AddService(void);
|
||||
|
||||
/*********************************************************************
|
||||
* @fn DevInfo_SetParameter
|
||||
*
|
||||
* @brief Set a Device Information parameter.
|
||||
*
|
||||
* @param param - Profile parameter ID
|
||||
* @param len - length of data to right
|
||||
* @param value - pointer to data to write. This is dependent on
|
||||
* the parameter ID and WILL be cast to the appropriate
|
||||
* data type (example: data type of uint16_t will be cast to
|
||||
* uint16_t pointer).
|
||||
*
|
||||
* @return bStatus_t
|
||||
*/
|
||||
bStatus_t DevInfo_SetParameter(uint8_t param, uint8_t len, void *value);
|
||||
|
||||
/*
|
||||
* DevInfo_GetParameter - Get a Device Information parameter.
|
||||
*
|
||||
* param - Profile parameter ID
|
||||
* value - pointer to data to write. This is dependent on
|
||||
* the parameter ID and WILL be cast to the appropriate
|
||||
* data type (example: data type of uint16_t will be cast to
|
||||
* uint16_t pointer).
|
||||
*/
|
||||
extern bStatus_t DevInfo_GetParameter(uint8_t param, void *value);
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DEVINFOSERVICE_H */
|
|
@ -0,0 +1,703 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : gattprofile.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2018/12/10
|
||||
* Description : Customized services containing five different attributes,
|
||||
* including readable, written, notified, readable, readable,
|
||||
* safe readable available
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
#include "../inc/config.h"
|
||||
#include "gattprofile.h"
|
||||
|
||||
/*********************************************************************
|
||||
* MACROS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* CONSTANTS
|
||||
*/
|
||||
|
||||
// Position of simpleProfilechar4 value in attribute array
|
||||
#define SIMPLEPROFILE_CHAR4_VALUE_POS 11
|
||||
|
||||
/*********************************************************************
|
||||
* TYPEDEFS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*/
|
||||
// Simple GATT Profile Service UUID: 0xFFF0
|
||||
const uint8_t simpleProfileServUUID[ATT_BT_UUID_SIZE] = {
|
||||
LO_UINT16(SIMPLEPROFILE_SERV_UUID), HI_UINT16(SIMPLEPROFILE_SERV_UUID)};
|
||||
|
||||
// Characteristic 1 UUID: 0xFFF1
|
||||
const uint8_t simpleProfilechar1UUID[ATT_BT_UUID_SIZE] = {
|
||||
LO_UINT16(SIMPLEPROFILE_CHAR1_UUID), HI_UINT16(SIMPLEPROFILE_CHAR1_UUID)};
|
||||
|
||||
// Characteristic 2 UUID: 0xFFF2
|
||||
const uint8_t simpleProfilechar2UUID[ATT_BT_UUID_SIZE] = {
|
||||
LO_UINT16(SIMPLEPROFILE_CHAR2_UUID), HI_UINT16(SIMPLEPROFILE_CHAR2_UUID)};
|
||||
|
||||
// Characteristic 3 UUID: 0xFFF3
|
||||
const uint8_t simpleProfilechar3UUID[ATT_BT_UUID_SIZE] = {
|
||||
LO_UINT16(SIMPLEPROFILE_CHAR3_UUID), HI_UINT16(SIMPLEPROFILE_CHAR3_UUID)};
|
||||
|
||||
// Characteristic 4 UUID: 0xFFF4
|
||||
const uint8_t simpleProfilechar4UUID[ATT_BT_UUID_SIZE] = {
|
||||
LO_UINT16(SIMPLEPROFILE_CHAR4_UUID), HI_UINT16(SIMPLEPROFILE_CHAR4_UUID)};
|
||||
|
||||
// Characteristic 5 UUID: 0xFFF5
|
||||
const uint8_t simpleProfilechar5UUID[ATT_BT_UUID_SIZE] = {
|
||||
LO_UINT16(SIMPLEPROFILE_CHAR5_UUID), HI_UINT16(SIMPLEPROFILE_CHAR5_UUID)};
|
||||
|
||||
/*********************************************************************
|
||||
* EXTERNAL VARIABLES
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* EXTERNAL FUNCTIONS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* LOCAL VARIABLES
|
||||
*/
|
||||
|
||||
static simpleProfileCBs_t *simpleProfile_AppCBs = NULL;
|
||||
|
||||
/*********************************************************************
|
||||
* Profile Attributes - variables
|
||||
*/
|
||||
|
||||
// Simple Profile Service attribute
|
||||
static const gattAttrType_t simpleProfileService = {ATT_BT_UUID_SIZE, simpleProfileServUUID};
|
||||
|
||||
// Simple Profile Characteristic 1 Properties
|
||||
static uint8_t simpleProfileChar1Props = GATT_PROP_READ | GATT_PROP_WRITE;
|
||||
|
||||
// Characteristic 1 Value
|
||||
static uint8_t simpleProfileChar1[SIMPLEPROFILE_CHAR1_LEN] = {0};
|
||||
|
||||
// Simple Profile Characteristic 1 User Description
|
||||
static uint8_t simpleProfileChar1UserDesp[] = "Characteristic 1\0";
|
||||
|
||||
// Simple Profile Characteristic 2 Properties
|
||||
static uint8_t simpleProfileChar2Props = GATT_PROP_READ;
|
||||
|
||||
// Characteristic 2 Value
|
||||
static uint8_t simpleProfileChar2[SIMPLEPROFILE_CHAR2_LEN] = {0};
|
||||
|
||||
// Simple Profile Characteristic 2 User Description
|
||||
static uint8_t simpleProfileChar2UserDesp[] = "Characteristic 2\0";
|
||||
|
||||
// Simple Profile Characteristic 3 Properties
|
||||
static uint8_t simpleProfileChar3Props = GATT_PROP_WRITE;
|
||||
|
||||
// Characteristic 3 Value
|
||||
static uint8_t simpleProfileChar3[SIMPLEPROFILE_CHAR3_LEN] = {0};
|
||||
|
||||
// Simple Profile Characteristic 3 User Description
|
||||
static uint8_t simpleProfileChar3UserDesp[] = "Characteristic 3\0";
|
||||
|
||||
// Simple Profile Characteristic 4 Properties
|
||||
static uint8_t simpleProfileChar4Props = GATT_PROP_NOTIFY;
|
||||
|
||||
// Characteristic 4 Value
|
||||
static uint8_t simpleProfileChar4[SIMPLEPROFILE_CHAR4_LEN] = {0};
|
||||
|
||||
// Simple Profile Characteristic 4 Configuration Each client has its own
|
||||
// instantiation of the Client Characteristic Configuration. Reads of the
|
||||
// Client Characteristic Configuration only shows the configuration for
|
||||
// that client and writes only affect the configuration of that client.
|
||||
static gattCharCfg_t simpleProfileChar4Config[4];
|
||||
|
||||
// Simple Profile Characteristic 4 User Description
|
||||
static uint8_t simpleProfileChar4UserDesp[] = "Characteristic 4\0";
|
||||
|
||||
// Simple Profile Characteristic 5 Properties
|
||||
static uint8_t simpleProfileChar5Props = GATT_PROP_READ;
|
||||
|
||||
// Characteristic 5 Value
|
||||
static uint8_t simpleProfileChar5[SIMPLEPROFILE_CHAR5_LEN] = {0};
|
||||
|
||||
// Simple Profile Characteristic 5 User Description
|
||||
static uint8_t simpleProfileChar5UserDesp[] = "Characteristic 5\0";
|
||||
|
||||
/*********************************************************************
|
||||
* Profile Attributes - Table
|
||||
*/
|
||||
|
||||
static gattAttribute_t simpleProfileAttrTbl[] = {
|
||||
// Simple Profile Service
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, primaryServiceUUID}, /* type */
|
||||
GATT_PERMIT_READ, /* permissions */
|
||||
0, /* handle */
|
||||
(uint8_t *)&simpleProfileService /* pValue */
|
||||
},
|
||||
|
||||
// Characteristic 1 Declaration
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, characterUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
&simpleProfileChar1Props},
|
||||
|
||||
// Characteristic Value 1
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, simpleProfilechar1UUID},
|
||||
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
|
||||
0,
|
||||
simpleProfileChar1},
|
||||
|
||||
// Characteristic 1 User Description
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, charUserDescUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
simpleProfileChar1UserDesp},
|
||||
|
||||
// Characteristic 2 Declaration
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, characterUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
&simpleProfileChar2Props},
|
||||
|
||||
// Characteristic Value 2
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, simpleProfilechar2UUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
simpleProfileChar2},
|
||||
|
||||
// Characteristic 2 User Description
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, charUserDescUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
simpleProfileChar2UserDesp},
|
||||
|
||||
// Characteristic 3 Declaration
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, characterUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
&simpleProfileChar3Props},
|
||||
|
||||
// Characteristic Value 3
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, simpleProfilechar3UUID},
|
||||
GATT_PERMIT_WRITE,
|
||||
0,
|
||||
simpleProfileChar3},
|
||||
|
||||
// Characteristic 3 User Description
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, charUserDescUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
simpleProfileChar3UserDesp},
|
||||
|
||||
// Characteristic 4 Declaration
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, characterUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
&simpleProfileChar4Props},
|
||||
|
||||
// Characteristic Value 4
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, simpleProfilechar4UUID},
|
||||
0,
|
||||
0,
|
||||
simpleProfileChar4},
|
||||
|
||||
// Characteristic 4 configuration
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, clientCharCfgUUID},
|
||||
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
|
||||
0,
|
||||
(uint8_t *)simpleProfileChar4Config},
|
||||
|
||||
// Characteristic 4 User Description
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, charUserDescUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
simpleProfileChar4UserDesp},
|
||||
|
||||
// Characteristic 5 Declaration
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, characterUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
&simpleProfileChar5Props},
|
||||
|
||||
// Characteristic Value 5
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, simpleProfilechar5UUID},
|
||||
GATT_PERMIT_AUTHEN_READ,
|
||||
0,
|
||||
simpleProfileChar5},
|
||||
|
||||
// Characteristic 5 User Description
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, charUserDescUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
simpleProfileChar5UserDesp},
|
||||
};
|
||||
|
||||
/*********************************************************************
|
||||
* LOCAL FUNCTIONS
|
||||
*/
|
||||
static bStatus_t simpleProfile_ReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
|
||||
uint8_t *pValue, uint16_t *pLen, uint16_t offset, uint16_t maxLen, uint8_t method);
|
||||
static bStatus_t simpleProfile_WriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
|
||||
uint8_t *pValue, uint16_t len, uint16_t offset, uint8_t method);
|
||||
|
||||
static void simpleProfile_HandleConnStatusCB(uint16_t connHandle, uint8_t changeType);
|
||||
|
||||
/*********************************************************************
|
||||
* PROFILE CALLBACKS
|
||||
*/
|
||||
// Simple Profile Service Callbacks
|
||||
gattServiceCBs_t simpleProfileCBs = {
|
||||
simpleProfile_ReadAttrCB, // Read callback function pointer
|
||||
simpleProfile_WriteAttrCB, // Write callback function pointer
|
||||
NULL // Authorization callback function pointer
|
||||
};
|
||||
|
||||
/*********************************************************************
|
||||
* PUBLIC FUNCTIONS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SimpleProfile_AddService
|
||||
*
|
||||
* @brief Initializes the Simple Profile service by registering
|
||||
* GATT attributes with the GATT server.
|
||||
*
|
||||
* @param services - services to add. This is a bit map and can
|
||||
* contain more than one service.
|
||||
*
|
||||
* @return Success or Failure
|
||||
*/
|
||||
bStatus_t SimpleProfile_AddService(uint32_t services)
|
||||
{
|
||||
uint8_t status = SUCCESS;
|
||||
|
||||
// Initialize Client Characteristic Configuration attributes
|
||||
GATTServApp_InitCharCfg(INVALID_CONNHANDLE, simpleProfileChar4Config);
|
||||
|
||||
// Register with Link DB to receive link status change callback
|
||||
linkDB_Register(simpleProfile_HandleConnStatusCB);
|
||||
|
||||
if(services & SIMPLEPROFILE_SERVICE)
|
||||
{
|
||||
// Register GATT attribute list and CBs with GATT Server App
|
||||
status = GATTServApp_RegisterService(simpleProfileAttrTbl,
|
||||
GATT_NUM_ATTRS(simpleProfileAttrTbl),
|
||||
GATT_MAX_ENCRYPT_KEY_SIZE,
|
||||
&simpleProfileCBs);
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SimpleProfile_RegisterAppCBs
|
||||
*
|
||||
* @brief Registers the application callback function. Only call
|
||||
* this function once.
|
||||
*
|
||||
* @param callbacks - pointer to application callbacks.
|
||||
*
|
||||
* @return SUCCESS or bleAlreadyInRequestedMode
|
||||
*/
|
||||
bStatus_t SimpleProfile_RegisterAppCBs(simpleProfileCBs_t *appCallbacks)
|
||||
{
|
||||
if(appCallbacks)
|
||||
{
|
||||
simpleProfile_AppCBs = appCallbacks;
|
||||
|
||||
return (SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (bleAlreadyInRequestedMode);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SimpleProfile_SetParameter
|
||||
*
|
||||
* @brief Set a Simple Profile parameter.
|
||||
*
|
||||
* @param param - Profile parameter ID
|
||||
* @param len - length of data to right
|
||||
* @param value - pointer to data to write. This is dependent on
|
||||
* the parameter ID and WILL be cast to the appropriate
|
||||
* data type (example: data type of uint16_t will be cast to
|
||||
* uint16_t pointer).
|
||||
*
|
||||
* @return bStatus_t
|
||||
*/
|
||||
bStatus_t SimpleProfile_SetParameter(uint8_t param, uint8_t len, void *value)
|
||||
{
|
||||
bStatus_t ret = SUCCESS;
|
||||
switch(param)
|
||||
{
|
||||
case SIMPLEPROFILE_CHAR1:
|
||||
if(len == SIMPLEPROFILE_CHAR1_LEN)
|
||||
{
|
||||
tmos_memcpy(simpleProfileChar1, value, SIMPLEPROFILE_CHAR1_LEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = bleInvalidRange;
|
||||
}
|
||||
break;
|
||||
|
||||
case SIMPLEPROFILE_CHAR2:
|
||||
if(len == SIMPLEPROFILE_CHAR2_LEN)
|
||||
{
|
||||
tmos_memcpy(simpleProfileChar2, value, SIMPLEPROFILE_CHAR2_LEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = bleInvalidRange;
|
||||
}
|
||||
break;
|
||||
|
||||
case SIMPLEPROFILE_CHAR3:
|
||||
if(len == SIMPLEPROFILE_CHAR3_LEN)
|
||||
{
|
||||
tmos_memcpy(simpleProfileChar3, value, SIMPLEPROFILE_CHAR3_LEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = bleInvalidRange;
|
||||
}
|
||||
break;
|
||||
|
||||
case SIMPLEPROFILE_CHAR4:
|
||||
if(len == SIMPLEPROFILE_CHAR4_LEN)
|
||||
{
|
||||
tmos_memcpy(simpleProfileChar4, value, SIMPLEPROFILE_CHAR4_LEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = bleInvalidRange;
|
||||
}
|
||||
break;
|
||||
|
||||
case SIMPLEPROFILE_CHAR5:
|
||||
if(len == SIMPLEPROFILE_CHAR5_LEN)
|
||||
{
|
||||
tmos_memcpy(simpleProfileChar5, value, SIMPLEPROFILE_CHAR5_LEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = bleInvalidRange;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = INVALIDPARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SimpleProfile_GetParameter
|
||||
*
|
||||
* @brief Get a Simple Profile parameter.
|
||||
*
|
||||
* @param param - Profile parameter ID
|
||||
* @param value - pointer to data to put. This is dependent on
|
||||
* the parameter ID and WILL be cast to the appropriate
|
||||
* data type (example: data type of uint16_t will be cast to
|
||||
* uint16_t pointer).
|
||||
*
|
||||
* @return bStatus_t
|
||||
*/
|
||||
bStatus_t SimpleProfile_GetParameter(uint8_t param, void *value)
|
||||
{
|
||||
bStatus_t ret = SUCCESS;
|
||||
switch(param)
|
||||
{
|
||||
case SIMPLEPROFILE_CHAR1:
|
||||
tmos_memcpy(value, simpleProfileChar1, SIMPLEPROFILE_CHAR1_LEN);
|
||||
break;
|
||||
|
||||
case SIMPLEPROFILE_CHAR2:
|
||||
tmos_memcpy(value, simpleProfileChar2, SIMPLEPROFILE_CHAR2_LEN);
|
||||
break;
|
||||
|
||||
case SIMPLEPROFILE_CHAR3:
|
||||
tmos_memcpy(value, simpleProfileChar3, SIMPLEPROFILE_CHAR3_LEN);
|
||||
break;
|
||||
|
||||
case SIMPLEPROFILE_CHAR4:
|
||||
tmos_memcpy(value, simpleProfileChar4, SIMPLEPROFILE_CHAR4_LEN);
|
||||
break;
|
||||
|
||||
case SIMPLEPROFILE_CHAR5:
|
||||
tmos_memcpy(value, simpleProfileChar5, SIMPLEPROFILE_CHAR5_LEN);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = INVALIDPARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn simpleProfile_Notify
|
||||
*
|
||||
* @brief Send a notification containing a heart rate
|
||||
* measurement.
|
||||
*
|
||||
* @param connHandle - connection handle
|
||||
* @param pNoti - pointer to notification structure
|
||||
*
|
||||
* @return Success or Failure
|
||||
*/
|
||||
bStatus_t simpleProfile_Notify(uint16_t connHandle, attHandleValueNoti_t *pNoti)
|
||||
{
|
||||
uint16_t value = GATTServApp_ReadCharCfg(connHandle, simpleProfileChar4Config);
|
||||
|
||||
// If notifications enabled
|
||||
if(value & GATT_CLIENT_CFG_NOTIFY)
|
||||
{
|
||||
// Set the handle
|
||||
pNoti->handle = simpleProfileAttrTbl[SIMPLEPROFILE_CHAR4_VALUE_POS].handle;
|
||||
|
||||
// Send the notification
|
||||
return GATT_Notification(connHandle, pNoti, FALSE);
|
||||
}
|
||||
return bleIncorrectMode;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn simpleProfile_ReadAttrCB
|
||||
*
|
||||
* @brief Read an attribute.
|
||||
*
|
||||
* @param connHandle - connection message was received on
|
||||
* @param pAttr - pointer to attribute
|
||||
* @param pValue - pointer to data to be read
|
||||
* @param pLen - length of data to be read
|
||||
* @param offset - offset of the first octet to be read
|
||||
* @param maxLen - maximum length of data to be read
|
||||
*
|
||||
* @return Success or Failure
|
||||
*/
|
||||
static bStatus_t simpleProfile_ReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
|
||||
uint8_t *pValue, uint16_t *pLen, uint16_t offset, uint16_t maxLen, uint8_t method)
|
||||
{
|
||||
bStatus_t status = SUCCESS;
|
||||
|
||||
// Make sure it's not a blob operation (no attributes in the profile are long)
|
||||
if(offset > 0)
|
||||
{
|
||||
return (ATT_ERR_ATTR_NOT_LONG);
|
||||
}
|
||||
|
||||
if(pAttr->type.len == ATT_BT_UUID_SIZE)
|
||||
{
|
||||
// 16-bit UUID
|
||||
uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
|
||||
switch(uuid)
|
||||
{
|
||||
// No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases;
|
||||
// gattserverapp handles those reads
|
||||
|
||||
// characteristics 1 and 2 have read permissions
|
||||
// characteritisc 3 does not have read permissions; therefore it is not
|
||||
// included here
|
||||
// characteristic 4 does not have read permissions, but because it
|
||||
// can be sent as a notification, it is included here
|
||||
case SIMPLEPROFILE_CHAR1_UUID:
|
||||
*pLen = SIMPLEPROFILE_CHAR1_LEN;
|
||||
tmos_memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR1_LEN);
|
||||
break;
|
||||
|
||||
case SIMPLEPROFILE_CHAR2_UUID:
|
||||
*pLen = SIMPLEPROFILE_CHAR2_LEN;
|
||||
tmos_memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR2_LEN);
|
||||
break;
|
||||
|
||||
case SIMPLEPROFILE_CHAR4_UUID:
|
||||
*pLen = SIMPLEPROFILE_CHAR4_LEN;
|
||||
tmos_memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR4_LEN);
|
||||
break;
|
||||
|
||||
case SIMPLEPROFILE_CHAR5_UUID:
|
||||
*pLen = SIMPLEPROFILE_CHAR5_LEN;
|
||||
tmos_memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR5_LEN);
|
||||
break;
|
||||
|
||||
default:
|
||||
// Should never get here! (characteristics 3 and 4 do not have read permissions)
|
||||
*pLen = 0;
|
||||
status = ATT_ERR_ATTR_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 128-bit UUID
|
||||
*pLen = 0;
|
||||
status = ATT_ERR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn simpleProfile_WriteAttrCB
|
||||
*
|
||||
* @brief Validate attribute data prior to a write operation
|
||||
*
|
||||
* @param connHandle - connection message was received on
|
||||
* @param pAttr - pointer to attribute
|
||||
* @param pValue - pointer to data to be written
|
||||
* @param len - length of data
|
||||
* @param offset - offset of the first octet to be written
|
||||
*
|
||||
* @return Success or Failure
|
||||
*/
|
||||
static bStatus_t simpleProfile_WriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
|
||||
uint8_t *pValue, uint16_t len, uint16_t offset, uint8_t method)
|
||||
{
|
||||
bStatus_t status = SUCCESS;
|
||||
uint8_t notifyApp = 0xFF;
|
||||
|
||||
// If attribute permissions require authorization to write, return error
|
||||
if(gattPermitAuthorWrite(pAttr->permissions))
|
||||
{
|
||||
// Insufficient authorization
|
||||
return (ATT_ERR_INSUFFICIENT_AUTHOR);
|
||||
}
|
||||
|
||||
if(pAttr->type.len == ATT_BT_UUID_SIZE)
|
||||
{
|
||||
// 16-bit UUID
|
||||
uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
|
||||
switch(uuid)
|
||||
{
|
||||
case SIMPLEPROFILE_CHAR1_UUID:
|
||||
//Validate the value
|
||||
// Make sure it's not a blob oper
|
||||
if(offset == 0)
|
||||
{
|
||||
if(len > SIMPLEPROFILE_CHAR1_LEN)
|
||||
{
|
||||
status = ATT_ERR_INVALID_VALUE_SIZE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = ATT_ERR_ATTR_NOT_LONG;
|
||||
}
|
||||
|
||||
//Write the value
|
||||
if(status == SUCCESS)
|
||||
{
|
||||
tmos_memcpy(pAttr->pValue, pValue, SIMPLEPROFILE_CHAR1_LEN);
|
||||
notifyApp = SIMPLEPROFILE_CHAR1;
|
||||
}
|
||||
break;
|
||||
|
||||
case SIMPLEPROFILE_CHAR3_UUID:
|
||||
//Validate the value
|
||||
// Make sure it's not a blob oper
|
||||
if(offset == 0)
|
||||
{
|
||||
if(len > SIMPLEPROFILE_CHAR3_LEN)
|
||||
{
|
||||
status = ATT_ERR_INVALID_VALUE_SIZE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = ATT_ERR_ATTR_NOT_LONG;
|
||||
}
|
||||
|
||||
//Write the value
|
||||
if(status == SUCCESS)
|
||||
{
|
||||
tmos_memcpy(pAttr->pValue, pValue, SIMPLEPROFILE_CHAR3_LEN);
|
||||
notifyApp = SIMPLEPROFILE_CHAR3;
|
||||
}
|
||||
break;
|
||||
|
||||
case GATT_CLIENT_CHAR_CFG_UUID:
|
||||
status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue, len,
|
||||
offset, GATT_CLIENT_CFG_NOTIFY);
|
||||
break;
|
||||
|
||||
default:
|
||||
// Should never get here! (characteristics 2 and 4 do not have write permissions)
|
||||
status = ATT_ERR_ATTR_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 128-bit UUID
|
||||
status = ATT_ERR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
// If a charactersitic value changed then callback function to notify application of change
|
||||
if((notifyApp != 0xFF) && simpleProfile_AppCBs && simpleProfile_AppCBs->pfnSimpleProfileChange)
|
||||
{
|
||||
simpleProfile_AppCBs->pfnSimpleProfileChange(notifyApp);
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn simpleProfile_HandleConnStatusCB
|
||||
*
|
||||
* @brief Simple Profile link status change handler function.
|
||||
*
|
||||
* @param connHandle - connection handle
|
||||
* @param changeType - type of change
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void simpleProfile_HandleConnStatusCB(uint16_t connHandle, uint8_t changeType)
|
||||
{
|
||||
// Make sure this is not loopback connection
|
||||
if(connHandle != LOOPBACK_CONNHANDLE)
|
||||
{
|
||||
// Reset Client Char Config if connection has dropped
|
||||
if((changeType == LINKDB_STATUS_UPDATE_REMOVED) ||
|
||||
((changeType == LINKDB_STATUS_UPDATE_STATEFLAGS) &&
|
||||
(!linkDB_Up(connHandle))))
|
||||
{
|
||||
GATTServApp_InitCharCfg(connHandle, simpleProfileChar4Config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
|
@ -0,0 +1,135 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : gattprofile.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2018/12/11
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef GATTPROFILE_H
|
||||
#define GATTPROFILE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* CONSTANTS
|
||||
*/
|
||||
|
||||
// Profile Parameters
|
||||
#define SIMPLEPROFILE_CHAR1 0 // RW uint8_t - Profile Characteristic 1 value
|
||||
#define SIMPLEPROFILE_CHAR2 1 // RW uint8_t - Profile Characteristic 2 value
|
||||
#define SIMPLEPROFILE_CHAR3 2 // RW uint8_t - Profile Characteristic 3 value
|
||||
#define SIMPLEPROFILE_CHAR4 3 // RW uint8_t - Profile Characteristic 4 value
|
||||
#define SIMPLEPROFILE_CHAR5 4 // RW uint8_t - Profile Characteristic 4 value
|
||||
|
||||
// Simple Profile Service UUID
|
||||
#define SIMPLEPROFILE_SERV_UUID 0xFFE0
|
||||
|
||||
// Key Pressed UUID
|
||||
#define SIMPLEPROFILE_CHAR1_UUID 0xFFE1
|
||||
#define SIMPLEPROFILE_CHAR2_UUID 0xFFE2
|
||||
#define SIMPLEPROFILE_CHAR3_UUID 0xFFE3
|
||||
#define SIMPLEPROFILE_CHAR4_UUID 0xFFE4
|
||||
#define SIMPLEPROFILE_CHAR5_UUID 0xFFE5
|
||||
|
||||
// Simple Keys Profile Services bit fields
|
||||
#define SIMPLEPROFILE_SERVICE 0x00000001
|
||||
|
||||
// Length of characteristic in bytes ( Default MTU is 23 )
|
||||
#define SIMPLEPROFILE_CHAR1_LEN 1
|
||||
#define SIMPLEPROFILE_CHAR2_LEN 1
|
||||
#define SIMPLEPROFILE_CHAR3_LEN 1
|
||||
#define SIMPLEPROFILE_CHAR4_LEN 1
|
||||
#define SIMPLEPROFILE_CHAR5_LEN 5
|
||||
|
||||
/*********************************************************************
|
||||
* TYPEDEFS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* MACROS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* Profile Callbacks
|
||||
*/
|
||||
|
||||
// Callback when a characteristic value has changed
|
||||
typedef void (*simpleProfileChange_t)(uint8_t paramID);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
simpleProfileChange_t pfnSimpleProfileChange; // Called when characteristic value changes
|
||||
} simpleProfileCBs_t;
|
||||
|
||||
/*********************************************************************
|
||||
* API FUNCTIONS
|
||||
*/
|
||||
|
||||
/*
|
||||
* SimpleProfile_AddService- Initializes the Simple GATT Profile service by registering
|
||||
* GATT attributes with the GATT server.
|
||||
*
|
||||
* @param services - services to add. This is a bit map and can
|
||||
* contain more than one service.
|
||||
*/
|
||||
|
||||
extern bStatus_t SimpleProfile_AddService(uint32_t services);
|
||||
|
||||
/*
|
||||
* SimpleProfile_RegisterAppCBs - Registers the application callback function.
|
||||
* Only call this function once.
|
||||
*
|
||||
* appCallbacks - pointer to application callbacks.
|
||||
*/
|
||||
extern bStatus_t SimpleProfile_RegisterAppCBs(simpleProfileCBs_t *appCallbacks);
|
||||
|
||||
/*
|
||||
* SimpleProfile_SetParameter - Set a Simple GATT Profile parameter.
|
||||
*
|
||||
* param - Profile parameter ID
|
||||
* len - length of data to right
|
||||
* value - pointer to data to write. This is dependent on
|
||||
* the parameter ID and WILL be cast to the appropriate
|
||||
* data type (example: data type of uint16_t will be cast to
|
||||
* uint16_t pointer).
|
||||
*/
|
||||
extern bStatus_t SimpleProfile_SetParameter(uint8_t param, uint8_t len, void *value);
|
||||
|
||||
/*
|
||||
* SimpleProfile_GetParameter - Get a Simple GATT Profile parameter.
|
||||
*
|
||||
* param - Profile parameter ID
|
||||
* value - pointer to data to write. This is dependent on
|
||||
* the parameter ID and WILL be cast to the appropriate
|
||||
* data type (example: data type of uint16_t will be cast to
|
||||
* uint16_t pointer).
|
||||
*/
|
||||
extern bStatus_t SimpleProfile_GetParameter(uint8_t param, void *value);
|
||||
|
||||
/*
|
||||
* simpleProfile_Notify - Send notification.
|
||||
*
|
||||
* connHandle - connect handle
|
||||
* pNoti - pointer to structure to notify.
|
||||
*/
|
||||
extern bStatus_t simpleProfile_Notify(uint16_t connHandle, attHandleValueNoti_t *pNoti);
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,82 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : HAL.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2016/05/05
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
#ifndef __HAL_H
|
||||
#define __HAL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include "RTC.h"
|
||||
#include "SLEEP.h"
|
||||
#include "KEY.h"
|
||||
#include "LED.h"
|
||||
|
||||
/* hal task Event */
|
||||
#define LED_BLINK_EVENT 0x0001
|
||||
#define HAL_KEY_EVENT 0x0002
|
||||
#define HAL_REG_INIT_EVENT 0x2000
|
||||
#define HAL_TEST_EVENT 0x4000
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*/
|
||||
extern tmosTaskID halTaskID;
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL FUNCTIONS
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Hardware initialization
|
||||
*/
|
||||
extern void HAL_Init(void);
|
||||
|
||||
/**
|
||||
* @brief HAL processing
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*/
|
||||
extern tmosEvents HAL_ProcessEvent(tmosTaskID task_id, tmosEvents events);
|
||||
|
||||
/**
|
||||
* @brief Initialization of the BLE library
|
||||
*/
|
||||
extern void WCHBLE_Init(void);
|
||||
|
||||
/**
|
||||
* @brief Get the internal temperature sampling value.
|
||||
* If the ADC interrupt sampling is used,
|
||||
* the interrupt is temporarily shielded in this function.
|
||||
*
|
||||
* @return Internal temperature sampling value.
|
||||
*/
|
||||
extern uint16_t HAL_GetInterTempValue(void);
|
||||
|
||||
/**
|
||||
* @brief Internal 32K calibration
|
||||
*/
|
||||
extern void Lib_Calibration_LSI(void);
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,112 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : KEY.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2016/04/12
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
#ifndef __KEY_H
|
||||
#define __KEY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**************************************************************************************************
|
||||
* MACROS
|
||||
**************************************************************************************************/
|
||||
#define HAL_KEY_POLLING_VALUE 100
|
||||
|
||||
/* Switches (keys) */
|
||||
#define HAL_KEY_SW_1 0x01 // key1
|
||||
#define HAL_KEY_SW_2 0x02 // key2
|
||||
#define HAL_KEY_SW_3 0x04 // key3
|
||||
#define HAL_KEY_SW_4 0x08 // key4
|
||||
|
||||
/* Key definition */
|
||||
|
||||
/* 1 - KEY */
|
||||
#define KEY1_PCENR (RCC_APB2Periph_GPIOB)
|
||||
#define KEY2_PCENR ()
|
||||
#define KEY3_PCENR ()
|
||||
#define KEY4_PCENR ()
|
||||
|
||||
#define KEY1_GPIO (GPIOB)
|
||||
#define KEY2_GPIO ()
|
||||
#define KEY3_GPIO ()
|
||||
#define KEY4_GPIO ()
|
||||
|
||||
#define KEY1_BV BV(13)
|
||||
#define KEY2_BV ()
|
||||
#define KEY3_BV ()
|
||||
#define KEY4_BV ()
|
||||
|
||||
#define KEY1_IN (GPIO_ReadInputDataBit(KEY1_GPIO, KEY1_BV)==0)
|
||||
#define KEY2_IN ()
|
||||
#define KEY3_IN ()
|
||||
#define KEY4_IN ()
|
||||
|
||||
#define HAL_PUSH_BUTTON1() (KEY1_IN) //Add custom button
|
||||
#define HAL_PUSH_BUTTON2() (0)
|
||||
#define HAL_PUSH_BUTTON3() (0)
|
||||
#define HAL_PUSH_BUTTON4() (0)
|
||||
|
||||
/**************************************************************************************************
|
||||
* TYPEDEFS
|
||||
**************************************************************************************************/
|
||||
typedef void (*halKeyCBack_t)(uint8_t keys);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t keys; // keys
|
||||
} keyChange_t;
|
||||
|
||||
/**************************************************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
**************************************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* FUNCTIONS
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize the Key Service
|
||||
*/
|
||||
void HAL_KeyInit(void);
|
||||
|
||||
/**
|
||||
* @brief This is for internal used by hal_driver
|
||||
*/
|
||||
void HAL_KeyPoll(void);
|
||||
|
||||
/**
|
||||
* @brief Configure the Key serivce
|
||||
*
|
||||
* @param cback - pointer to the CallBack function
|
||||
*/
|
||||
void HalKeyConfig(const halKeyCBack_t cback);
|
||||
|
||||
/**
|
||||
* @brief Read the Key callback
|
||||
*/
|
||||
void HalKeyCallback(uint8_t keys);
|
||||
|
||||
/**
|
||||
* @brief Read the Key status
|
||||
*/
|
||||
uint8_t HalKeyRead(void);
|
||||
|
||||
/**************************************************************************************************
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,133 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : LED.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2016/04/12
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
#ifndef __LED_H
|
||||
#define __LED_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* CONSTANTS
|
||||
*/
|
||||
|
||||
/* LEDS - The LED number is the same as the bit position */
|
||||
#define HAL_LED_1 0x01
|
||||
#define HAL_LED_2 0x02
|
||||
#define HAL_LED_3 0x04
|
||||
#define HAL_LED_4 0x08
|
||||
#define HAL_LED_ALL (HAL_LED_1 | HAL_LED_2 | HAL_LED_3 | HAL_LED_4)
|
||||
|
||||
/* Modes */
|
||||
#define HAL_LED_MODE_OFF 0x00
|
||||
#define HAL_LED_MODE_ON 0x01
|
||||
#define HAL_LED_MODE_BLINK 0x02
|
||||
#define HAL_LED_MODE_FLASH 0x04
|
||||
#define HAL_LED_MODE_TOGGLE 0x08
|
||||
|
||||
/* Defaults */
|
||||
#define HAL_LED_DEFAULT_MAX_LEDS 4
|
||||
#define HAL_LED_DEFAULT_DUTY_CYCLE 5
|
||||
#define HAL_LED_DEFAULT_FLASH_COUNT 50
|
||||
#define HAL_LED_DEFAULT_FLASH_TIME 1000
|
||||
|
||||
/*********************************************************************
|
||||
* TYPEDEFS
|
||||
*/
|
||||
|
||||
/* Connect an LED to monitor the progress of the demo program, the low-level LED is on */
|
||||
|
||||
/* 1 - LED */
|
||||
#define LED1_PCENR (RCC_APB2Periph_GPIOB)
|
||||
#define LED2_PCENR
|
||||
#define LED3_PCENR
|
||||
|
||||
#define LED1_GPIO (GPIOB)
|
||||
#define LED2_GPIO
|
||||
#define LED3_GPIO
|
||||
|
||||
#define LED1_BV BV(15)
|
||||
#define LED2_BV
|
||||
#define LED3_BV
|
||||
|
||||
#define HAL_TURN_OFF_LED1() (GPIO_WriteBit(LED1_GPIO, LED1_BV, Bit_SET))
|
||||
#define HAL_TURN_OFF_LED2()
|
||||
#define HAL_TURN_OFF_LED3()
|
||||
#define HAL_TURN_OFF_LED4()
|
||||
|
||||
#define HAL_TURN_ON_LED1() (GPIO_WriteBit(LED1_GPIO, LED1_BV, Bit_RESET))
|
||||
#define HAL_TURN_ON_LED2()
|
||||
#define HAL_TURN_ON_LED3()
|
||||
#define HAL_TURN_ON_LED4()
|
||||
|
||||
#define HAL_STATE_LED1() 0
|
||||
#define HAL_STATE_LED2() 0
|
||||
#define HAL_STATE_LED3() 0
|
||||
#define HAL_STATE_LED4() 0
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize LED Service.
|
||||
*/
|
||||
void HAL_LedInit(void);
|
||||
|
||||
/**
|
||||
* @brief update time LED Service.
|
||||
*/
|
||||
void HalLedUpdate(void);
|
||||
|
||||
/**
|
||||
* @brief Turn ON/OFF/TOGGLE given LEDs
|
||||
*
|
||||
* @param led - bit mask value of leds to be turned ON/OFF/TOGGLE
|
||||
* @param mode - BLINK, FLASH, TOGGLE, ON, OFF
|
||||
*/
|
||||
extern uint8_t HalLedSet(uint8_t led, uint8_t mode);
|
||||
|
||||
/**
|
||||
* @brief Blink the leds
|
||||
*
|
||||
* @param led - bit mask value of leds to be turned ON/OFF/TOGGLE
|
||||
* @param numBlinks - number of blinks
|
||||
* @param percent - the percentage in each period where the led will be on
|
||||
* @param period - length of each cycle in milliseconds
|
||||
*/
|
||||
extern void HalLedBlink(uint8_t leds, uint8_t cnt, uint8_t duty, uint16_t time);
|
||||
|
||||
/**
|
||||
* @brief Put LEDs in sleep state - store current values
|
||||
*/
|
||||
extern void HalLedEnterSleep(void);
|
||||
|
||||
/**
|
||||
* @brief Retore LEDs from sleep state
|
||||
*/
|
||||
extern void HalLedExitSleep(void);
|
||||
|
||||
/**
|
||||
* @brief Return LED state
|
||||
*/
|
||||
extern uint8_t HalLedGetState(void);
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,40 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : RTC.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2016/04/12
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
#ifndef __RTC_H
|
||||
#define __RTC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
extern volatile uint32_t RTCTigFlag;
|
||||
|
||||
/**
|
||||
* @brief Initialize time Service.
|
||||
*/
|
||||
void HAL_TimeInit(void);
|
||||
|
||||
/**
|
||||
* @brief Configure RTC trigger time
|
||||
*
|
||||
* @param time - Trigger time.
|
||||
*/
|
||||
extern void RTC_SetTignTime(uint32_t time);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,50 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : SLEEP.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2018/11/12
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
#ifndef __SLEEP_H
|
||||
#define __SLEEP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* FUNCTIONS
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Configure sleep Wake-up source - RTC wake up, trigger mode
|
||||
*/
|
||||
extern void HAL_SleepInit(void);
|
||||
|
||||
/**
|
||||
* @brief Start sleep
|
||||
*
|
||||
* @param time - Wake-up time (RTC absolute value)
|
||||
*
|
||||
* @return state.
|
||||
*/
|
||||
extern uint32_t BLE_LowPower(uint32_t time);
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,133 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : app_drv_fifo.h
|
||||
* Author : WCH
|
||||
* Version : V1.1
|
||||
* Date : 2022/01/19
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef __APP_DRV_FIFO_H__
|
||||
#define __APP_DRV_FIFO_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef BV
|
||||
#define BV(n) (1 << (n))
|
||||
#endif
|
||||
|
||||
#ifndef BF
|
||||
#define BF(x, b, s) (((x) & (b)) >> (s))
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(n, m) (((n) < (m)) ? (n) : (m))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(n, m) (((n) < (m)) ? (m) : (n))
|
||||
#endif
|
||||
|
||||
#ifndef ABS
|
||||
#define ABS(n) (((n) < 0) ? -(n) : (n))
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
APP_DRV_FIFO_RESULT_SUCCESS = 0,
|
||||
APP_DRV_FIFO_RESULT_LENGTH_ERROR,
|
||||
APP_DRV_FIFO_RESULT_NOT_FOUND,
|
||||
APP_DRV_FIFO_RESULT_NOT_MEM,
|
||||
APP_DRV_FIFO_RESULT_NULL,
|
||||
|
||||
} app_drv_fifo_result_t;
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* FIFO structure
|
||||
*/
|
||||
typedef struct Fifo_s
|
||||
{
|
||||
uint16_t begin;
|
||||
uint16_t end;
|
||||
uint8_t *data;
|
||||
uint16_t size;
|
||||
uint16_t size_mask;
|
||||
} app_drv_fifo_t;
|
||||
|
||||
//__inline uint16_t app_drv_fifo_length(app_drv_fifo_t *fifo);
|
||||
|
||||
uint16_t app_drv_fifo_length(app_drv_fifo_t *fifo);
|
||||
|
||||
/*!
|
||||
* Initializes the FIFO structure
|
||||
*
|
||||
* \param [IN] fifo Pointer to the FIFO object
|
||||
* \param [IN] buffer Buffer to be used as FIFO
|
||||
* \param [IN] size size of the buffer
|
||||
*/
|
||||
app_drv_fifo_result_t
|
||||
app_drv_fifo_init(app_drv_fifo_t *fifo, uint8_t *buffer, uint16_t buffer_size);
|
||||
|
||||
/*!
|
||||
* Pushes data to the FIFO
|
||||
*
|
||||
* \param [IN] fifo Pointer to the FIFO object
|
||||
* \param [IN] data data to be pushed into the FIFO
|
||||
*/
|
||||
void app_drv_fifo_push(app_drv_fifo_t *fifo, uint8_t data);
|
||||
|
||||
/*!
|
||||
* Pops data from the FIFO
|
||||
*
|
||||
* \param [IN] fifo Pointer to the FIFO object
|
||||
* \retval data data popped from the FIFO
|
||||
*/
|
||||
uint8_t app_drv_fifo_pop(app_drv_fifo_t *fifo);
|
||||
|
||||
/*!
|
||||
* Flushes the FIFO
|
||||
*
|
||||
* \param [IN] fifo Pointer to the FIFO object
|
||||
*/
|
||||
void app_drv_fifo_flush(app_drv_fifo_t *fifo);
|
||||
|
||||
/*!
|
||||
* Checks if the FIFO is empty
|
||||
*
|
||||
* \param [IN] fifo Pointer to the FIFO object
|
||||
* \retval isEmpty true: FIFO is empty, false FIFO is not empty
|
||||
*/
|
||||
bool app_drv_fifo_is_empty(app_drv_fifo_t *fifo);
|
||||
|
||||
/*!
|
||||
* Checks if the FIFO is full
|
||||
*
|
||||
* \param [IN] fifo Pointer to the FIFO object
|
||||
* \retval isFull true: FIFO is full, false FIFO is not full
|
||||
*/
|
||||
bool app_drv_fifo_is_full(app_drv_fifo_t *fifo);
|
||||
|
||||
app_drv_fifo_result_t
|
||||
app_drv_fifo_write(app_drv_fifo_t *fifo, uint8_t *data,
|
||||
uint16_t *p_write_length);
|
||||
|
||||
app_drv_fifo_result_t
|
||||
app_drv_fifo_write_from_same_addr(app_drv_fifo_t *fifo, uint8_t *data,
|
||||
uint16_t write_length);
|
||||
|
||||
app_drv_fifo_result_t
|
||||
app_drv_fifo_read(app_drv_fifo_t *fifo, uint8_t *data, uint16_t *p_read_length);
|
||||
|
||||
app_drv_fifo_result_t
|
||||
app_drv_fifo_read_to_same_addr(app_drv_fifo_t *fifo, uint8_t *data,
|
||||
uint16_t read_length);
|
||||
|
||||
#endif // __APP_DRV_FIFO_H__
|
|
@ -0,0 +1,66 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : app_uart.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2018/12/11
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef app_uart_H
|
||||
#define app_uart_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
|
||||
#include "app_drv_fifo.h"
|
||||
#include "ble_uart_service.h"
|
||||
|
||||
/*********************************************************************
|
||||
* CONSTANTS
|
||||
*/
|
||||
|
||||
extern uint8_t to_test_buffer[BLE_BUFF_MAX_LEN - 4 - 3];
|
||||
|
||||
extern app_drv_fifo_t app_uart_tx_fifo;
|
||||
extern app_drv_fifo_t app_uart_rx_fifo;
|
||||
|
||||
//interupt uart rx flag ,clear at main loop
|
||||
extern bool uart_rx_flag;
|
||||
|
||||
//for interrupt rx blcak hole ,when uart rx fifo full
|
||||
extern uint8_t for_uart_rx_black_hole;
|
||||
|
||||
//fifo length less that MTU-3, retry times
|
||||
extern uint32_t uart_to_ble_send_evt_cnt;
|
||||
|
||||
/*********************************************************************
|
||||
* MACROS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* FUNCTIONS
|
||||
*/
|
||||
|
||||
extern void app_uart_process(void);
|
||||
|
||||
extern void app_uart_init(void);
|
||||
|
||||
extern void on_bleuartServiceEvt(uint16_t connection_handle, ble_uart_evt_t *p_evt);
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,70 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : simpleGATTprofile.h
|
||||
* Author : WCH
|
||||
* Version : V1.1
|
||||
* Date : 2022/01/19
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef _BLE_UART_SERVICE_H
|
||||
#define _BLE_UART_SERVICE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//#include "att.h"
|
||||
#include "stdint.h"
|
||||
|
||||
#define BLE_UART_RX_BUFF_SIZE 1
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BLE_UART_EVT_TX_NOTI_DISABLED = 1,
|
||||
BLE_UART_EVT_TX_NOTI_ENABLED,
|
||||
BLE_UART_EVT_BLE_DATA_RECIEVED,
|
||||
} ble_uart_evt_type_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t const *p_data; /**< A pointer to the buffer with received data. */
|
||||
uint16_t length; /**< Length of received data. */
|
||||
} ble_uart_evt_rx_data_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ble_uart_evt_type_t type;
|
||||
ble_uart_evt_rx_data_t data;
|
||||
} ble_uart_evt_t;
|
||||
|
||||
typedef void (*ble_uart_ProfileChangeCB_t)(uint16_t connection_handle, ble_uart_evt_t *p_evt);
|
||||
|
||||
/*********************************************************************
|
||||
* API FUNCTIONS
|
||||
*/
|
||||
|
||||
/*
|
||||
* ble_uart_AddService- Initializes the raw pass GATT Profile service by registering
|
||||
* GATT attributes with the GATT server.
|
||||
*
|
||||
* @param services - services to add. This is a bit map and can
|
||||
* contain more than one service.
|
||||
*/
|
||||
|
||||
extern bStatus_t ble_uart_add_service(ble_uart_ProfileChangeCB_t cb);
|
||||
|
||||
extern uint8_t ble_uart_notify_is_ready(uint16_t connHandle);
|
||||
|
||||
extern bStatus_t ble_uart_notify(uint16_t connHandle, attHandleValueNoti_t *pNoti, uint8_t taskId);
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BLE_UART_SERVICE_H */
|
|
@ -0,0 +1,137 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : CONFIG.h
|
||||
* Author : WCH
|
||||
* Version : V1.2
|
||||
* Date : 2022/01/18
|
||||
* Description : Configuration description and default value,
|
||||
* it is recommended to modify the current value in the
|
||||
* pre-processing of the engineering configuration
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
#define ID_CH32V208 0x0208
|
||||
|
||||
#define CHIP_ID ID_CH32V208
|
||||
|
||||
#ifdef WCHBLE_ROM
|
||||
#include "WCHBLE_ROM.H"
|
||||
#else
|
||||
#include "wchble.h"
|
||||
#endif
|
||||
|
||||
#include "ch32v20x.h"
|
||||
|
||||
/*********************************************************************
|
||||
【MAC】
|
||||
BLE_MAC - 是否自定义蓝牙Mac地址 ( 默认:FALSE - 使用芯片Mac地址 ),需要在main.c修改Mac地址定义
|
||||
|
||||
【SLEEP】
|
||||
HAL_SLEEP - 是否开启睡眠功能 ( 默认:FALSE )
|
||||
WAKE_UP_MAX_TIME_US - 提前唤醒时间,即系统时钟稳定所需要时间
|
||||
暂停模式 - 45
|
||||
空闲模式 - 5
|
||||
|
||||
【TEMPERATION】
|
||||
TEM_SAMPLE - 是否打开根据温度变化校准的功能,单次校准耗时小于10ms( 默认:TRUE )
|
||||
|
||||
【CALIBRATION】
|
||||
BLE_CALIBRATION_ENABLE - 是否打开定时校准的功能,单次校准耗时小于10ms( 默认:TRUE )
|
||||
BLE_CALIBRATION_PERIOD - 定时校准的周期,单位ms( 默认:120000 )
|
||||
|
||||
【SNV】
|
||||
BLE_SNV - 是否开启SNV功能,用于储存绑定信息( 默认:TRUE )
|
||||
BLE_SNV_ADDR - SNV信息保存地址,使用data flash最后( 默认:0x77E00 )
|
||||
BLE_SNV_NUM - SNV信息存储扇区数量等于可存储的绑定数量( 默认:3 )
|
||||
- 如果配置了SNVNum参数,则需要对应修改Lib_Write_Flash函数内擦除的flash大小,大小为SNVBlock*SNVNum
|
||||
|
||||
【RTC】
|
||||
CLK_OSC32K - RTC时钟选择,如包含主机角色必须使用外部32K( 0 外部(32768Hz),默认:1:内部(32000Hz),2:内部(32768Hz) )
|
||||
|
||||
【MEMORY】
|
||||
BLE_MEMHEAP_SIZE - 蓝牙协议栈使用的RAM大小,不小于6K ( 默认:(1024*6) )
|
||||
|
||||
【DATA】
|
||||
BLE_BUFF_MAX_LEN - 单个连接最大包长度( 默认:27 (ATT_MTU=23),取值范围[27~251] )
|
||||
BLE_BUFF_NUM - 控制器缓存的包数量( 默认:5 )
|
||||
BLE_TX_NUM_EVENT - 单个连接事件最多可以发多少个数据包( 默认:1 )
|
||||
BLE_TX_POWER - 发射功率( 默认:LL_TX_POWEER_0_DBM (0dBm) )
|
||||
|
||||
【MULTICONN】
|
||||
PERIPHERAL_MAX_CONNECTION - 最多可同时做多少从机角色( 默认:1 )
|
||||
CENTRAL_MAX_CONNECTION - 最多可同时做多少主机角色( 默认:3 )
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* 默认配置值
|
||||
*/
|
||||
#ifndef BLE_MAC
|
||||
#define BLE_MAC FALSE
|
||||
#endif
|
||||
#ifndef HAL_SLEEP
|
||||
#define HAL_SLEEP FALSE
|
||||
#endif
|
||||
#ifndef WAKE_UP_MAX_TIME_US
|
||||
#define WAKE_UP_MAX_TIME_US 2400
|
||||
#endif
|
||||
#ifndef HAL_KEY
|
||||
#define HAL_KEY FALSE
|
||||
#endif
|
||||
#ifndef HAL_LED
|
||||
#define HAL_LED FALSE
|
||||
#endif
|
||||
#ifndef TEM_SAMPLE
|
||||
#define TEM_SAMPLE TRUE
|
||||
#endif
|
||||
#ifndef BLE_CALIBRATION_ENABLE
|
||||
#define BLE_CALIBRATION_ENABLE TRUE
|
||||
#endif
|
||||
#ifndef BLE_CALIBRATION_PERIOD
|
||||
#define BLE_CALIBRATION_PERIOD 120000
|
||||
#endif
|
||||
#ifndef BLE_SNV
|
||||
#define BLE_SNV TRUE
|
||||
#endif
|
||||
#ifndef BLE_SNV_ADDR
|
||||
#define BLE_SNV_ADDR 0x08077C00
|
||||
#endif
|
||||
#ifndef BLE_SNV_NUM
|
||||
#define BLE_SNV_NUM 3
|
||||
#endif
|
||||
#ifndef CLK_OSC32K
|
||||
#define CLK_OSC32K 1 // 该项请勿在此修改,必须在工程配置里的预处理中修改,如包含主机角色必须使用外部32K
|
||||
#endif
|
||||
#ifndef BLE_MEMHEAP_SIZE
|
||||
#define BLE_MEMHEAP_SIZE (1024*7)
|
||||
#endif
|
||||
#ifndef BLE_BUFF_MAX_LEN
|
||||
#define BLE_BUFF_MAX_LEN 27
|
||||
#endif
|
||||
#ifndef BLE_BUFF_NUM
|
||||
#define BLE_BUFF_NUM 5
|
||||
#endif
|
||||
#ifndef BLE_TX_NUM_EVENT
|
||||
#define BLE_TX_NUM_EVENT 1
|
||||
#endif
|
||||
#ifndef BLE_TX_POWER
|
||||
#define BLE_TX_POWER LL_TX_POWEER_0_DBM
|
||||
#endif
|
||||
#ifndef PERIPHERAL_MAX_CONNECTION
|
||||
#define PERIPHERAL_MAX_CONNECTION 1
|
||||
#endif
|
||||
#ifndef CENTRAL_MAX_CONNECTION
|
||||
#define CENTRAL_MAX_CONNECTION 3
|
||||
#endif
|
||||
|
||||
extern uint32_t MEM_BUF[BLE_MEMHEAP_SIZE / 4];
|
||||
extern const uint8_t MacAddr[6];
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : peripheral.h
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2018/12/11
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef PERIPHERAL_H
|
||||
#define PERIPHERAL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* CONSTANTS
|
||||
*/
|
||||
|
||||
// Peripheral Task Events
|
||||
#define SBP_START_DEVICE_EVT 0x0001
|
||||
|
||||
#define SBP_READ_RSSI_EVT 0x0004
|
||||
#define SBP_PARAM_UPDATE_EVT 0x0008
|
||||
#define UART_TO_BLE_SEND_EVT 0x0010
|
||||
|
||||
/*********************************************************************
|
||||
* MACROS
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t connHandle; // Connection handle of current connection
|
||||
uint16_t connInterval;
|
||||
uint16_t connSlaveLatency;
|
||||
uint16_t connTimeout;
|
||||
} peripheralConnItem_t;
|
||||
|
||||
extern uint8_t Peripheral_TaskID;
|
||||
/*********************************************************************
|
||||
* FUNCTIONS
|
||||
*/
|
||||
|
||||
/*
|
||||
* Task Initialization for the BLE Application
|
||||
*/
|
||||
extern void Peripheral_Init(void);
|
||||
|
||||
/*
|
||||
* Task Event Processor for the BLE Application
|
||||
*/
|
||||
extern uint16_t Peripheral_ProcessEvent(uint8_t task_id, uint16_t events);
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
12005
Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ble/lib/wchble_rom.hex
Executable file
12005
Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ble/lib/wchble_rom.hex
Executable file
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,140 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : KEY.c
|
||||
* Author : WCH
|
||||
* Version : V1.2
|
||||
* Date : 2022/01/18
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/* Header file contains */
|
||||
#include "../../inc/HAL.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
**************************************************************************************************/
|
||||
|
||||
static uint8_t halKeySavedKeys; /* Keep the last state of the button to query whether there is a key value change */
|
||||
|
||||
/**************************************************************************************************
|
||||
* FUNCTIONS - Local
|
||||
**************************************************************************************************/
|
||||
static halKeyCBack_t pHalKeyProcessFunction; /* callback function */
|
||||
|
||||
/**************************************************************************************************
|
||||
* @fn HAL_KeyInit
|
||||
*
|
||||
* @brief Initilize Key Service
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return None
|
||||
**************************************************************************************************/
|
||||
void HAL_KeyInit(void)
|
||||
{
|
||||
/* Initialize previous key to 0 */
|
||||
halKeySavedKeys = 0;
|
||||
/* Initialize callback function */
|
||||
pHalKeyProcessFunction = NULL;
|
||||
|
||||
RCC_APB2PeriphClockCmd(KEY1_PCENR, ENABLE);
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = KEY1_BV;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
|
||||
GPIO_Init(KEY1_GPIO, &GPIO_InitStructure);
|
||||
}
|
||||
|
||||
/**************************************************************************************************
|
||||
* @fn HalKeyConfig
|
||||
*
|
||||
* @brief Configure the Key serivce
|
||||
*
|
||||
* @param cback - pointer to the CallBack function
|
||||
*
|
||||
* @return None
|
||||
**************************************************************************************************/
|
||||
void HalKeyConfig(halKeyCBack_t cback)
|
||||
{
|
||||
/* Register the callback fucntion */
|
||||
pHalKeyProcessFunction = cback;
|
||||
tmos_start_task(halTaskID, HAL_KEY_EVENT, HAL_KEY_POLLING_VALUE); /* Kick off polling */
|
||||
}
|
||||
|
||||
/**************************************************************************************************
|
||||
* @fn HalKeyRead
|
||||
*
|
||||
* @brief Read the current value of a key
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return keys - current keys status
|
||||
**************************************************************************************************/
|
||||
uint8_t HalKeyRead(void)
|
||||
{
|
||||
uint8_t keys = 0;
|
||||
|
||||
if(HAL_PUSH_BUTTON1())
|
||||
{ //Read button 1
|
||||
keys |= HAL_KEY_SW_1;
|
||||
}
|
||||
if(HAL_PUSH_BUTTON2())
|
||||
{ //Read button 1
|
||||
keys |= HAL_KEY_SW_2;
|
||||
}
|
||||
if(HAL_PUSH_BUTTON3())
|
||||
{ //Read button 1
|
||||
keys |= HAL_KEY_SW_3;
|
||||
}
|
||||
if(HAL_PUSH_BUTTON4())
|
||||
{ //Read button 1
|
||||
keys |= HAL_KEY_SW_4;
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
/**************************************************************************************************
|
||||
* @fn HAL_KeyPoll
|
||||
*
|
||||
* @brief Called by hal_driver to poll the keys
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
**************************************************************************************************/
|
||||
void HAL_KeyPoll(void)
|
||||
{
|
||||
uint8_t keys = 0;
|
||||
if(HAL_PUSH_BUTTON1())
|
||||
{
|
||||
keys |= HAL_KEY_SW_1;
|
||||
}
|
||||
if(HAL_PUSH_BUTTON2())
|
||||
{
|
||||
keys |= HAL_KEY_SW_2;
|
||||
}
|
||||
if(HAL_PUSH_BUTTON3())
|
||||
{
|
||||
keys |= HAL_KEY_SW_3;
|
||||
}
|
||||
if(HAL_PUSH_BUTTON4())
|
||||
{
|
||||
keys |= HAL_KEY_SW_4;
|
||||
}
|
||||
if(keys == halKeySavedKeys)
|
||||
{ /* Exit - since no keys have changed */
|
||||
return;
|
||||
}
|
||||
halKeySavedKeys = keys; /* Store the current keys for comparation next time */
|
||||
/* Invoke Callback if new keys were depressed */
|
||||
if(keys && (pHalKeyProcessFunction))
|
||||
{
|
||||
(pHalKeyProcessFunction)(keys);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************** endfile @ key ******************************/
|
|
@ -0,0 +1,366 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : LED.c
|
||||
* Author : WCH
|
||||
* Version : V1.2
|
||||
* Date : 2022/01/18
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/* Header file contains */
|
||||
#include "../../inc/HAL.h"
|
||||
|
||||
/* LED control structure */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t mode; /* Operation mode */
|
||||
uint8_t todo; /* Blink cycles left */
|
||||
uint8_t onPct; /* On cycle percentage */
|
||||
uint16_t time; /* On/off cycle time (msec) */
|
||||
uint32_t next; /* Time for next change */
|
||||
} HalLedControl_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HalLedControl_t HalLedControlTable[HAL_LED_DEFAULT_MAX_LEDS];
|
||||
uint8_t sleepActive;
|
||||
} HalLedStatus_t;
|
||||
|
||||
/***************************************************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
***************************************************************************************************/
|
||||
static uint8_t HalLedState; // LED state at last set/clr/blink update
|
||||
|
||||
static uint8_t preBlinkState; // Original State before going to blink mode
|
||||
// bit 0, 1, 2, 3 represent led 0, 1, 2, 3
|
||||
static HalLedStatus_t HalLedStatusControl;
|
||||
|
||||
/***************************************************************************************************
|
||||
* LOCAL FUNCTION
|
||||
***************************************************************************************************/
|
||||
void HalLedOnOff(uint8_t leds, uint8_t mode);
|
||||
|
||||
/***************************************************************************************************
|
||||
* FUNCTIONS - API
|
||||
***************************************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* @fn HAL_LedInit
|
||||
*
|
||||
* @brief Initialize LED Service
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void HAL_LedInit(void)
|
||||
{
|
||||
/* Initialize all LEDs to OFF */
|
||||
RCC_APB2PeriphClockCmd(LED1_PCENR, ENABLE);
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = LED1_BV;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
GPIO_Init(LED1_GPIO, &GPIO_InitStructure);
|
||||
HalLedSet(HAL_LED_ALL, HAL_LED_MODE_OFF);
|
||||
// just test
|
||||
HalLedBlink(HAL_LED_1, 10, 30, 4000);
|
||||
/* Initialize sleepActive to FALSE */
|
||||
HalLedStatusControl.sleepActive = FALSE;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn HalLedSet
|
||||
*
|
||||
* @brief Turn ON/OFF/TOGGLE given LEDs
|
||||
*
|
||||
* @param led - bit mask value of leds to be turned ON/OFF/TOGGLE
|
||||
* @param mode - BLINK, FLASH, TOGGLE, ON, OFF
|
||||
*
|
||||
* @return 0
|
||||
*/
|
||||
uint8_t HalLedSet(uint8_t leds, uint8_t mode)
|
||||
{
|
||||
uint8_t led;
|
||||
HalLedControl_t *sts;
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case HAL_LED_MODE_BLINK:
|
||||
{
|
||||
/* Default blink, 1 time, D% duty cycle */
|
||||
HalLedBlink(leds, 1, HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME);
|
||||
break;
|
||||
}
|
||||
|
||||
case HAL_LED_MODE_FLASH:
|
||||
{
|
||||
/* Default flash, N times, D% duty cycle */
|
||||
HalLedBlink(leds, HAL_LED_DEFAULT_FLASH_COUNT, HAL_LED_DEFAULT_DUTY_CYCLE, HAL_LED_DEFAULT_FLASH_TIME);
|
||||
break;
|
||||
}
|
||||
|
||||
case HAL_LED_MODE_ON:
|
||||
case HAL_LED_MODE_OFF:
|
||||
case HAL_LED_MODE_TOGGLE:
|
||||
{
|
||||
led = HAL_LED_1;
|
||||
leds &= HAL_LED_ALL;
|
||||
sts = HalLedStatusControl.HalLedControlTable;
|
||||
while(leds)
|
||||
{
|
||||
if(leds & led)
|
||||
{
|
||||
if(mode != HAL_LED_MODE_TOGGLE)
|
||||
{
|
||||
sts->mode = mode; /* ON or OFF */
|
||||
}
|
||||
else
|
||||
{
|
||||
sts->mode ^= HAL_LED_MODE_ON; /* Toggle */
|
||||
}
|
||||
HalLedOnOff(led, sts->mode);
|
||||
leds ^= led;
|
||||
}
|
||||
led <<= 1;
|
||||
sts++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn HalLedBlink
|
||||
*
|
||||
* @brief Blink the leds
|
||||
*
|
||||
* @param led - bit mask value of leds to be turned ON/OFF/TOGGLE
|
||||
* @param numBlinks - number of blinks
|
||||
* @param percent - the percentage in each period where the led will be on
|
||||
* @param period - length of each cycle in milliseconds
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void HalLedBlink(uint8_t leds, uint8_t numBlinks, uint8_t percent, uint16_t period)
|
||||
{
|
||||
uint8_t led;
|
||||
HalLedControl_t *sts;
|
||||
|
||||
if(leds && percent && period)
|
||||
{
|
||||
if(percent < 100)
|
||||
{
|
||||
led = HAL_LED_1;
|
||||
leds &= HAL_LED_ALL;
|
||||
sts = HalLedStatusControl.HalLedControlTable;
|
||||
while(leds)
|
||||
{
|
||||
if(leds & led)
|
||||
{
|
||||
/* Store the current state of the led before going to blinking */
|
||||
preBlinkState |= (led & HalLedState);
|
||||
sts->mode = HAL_LED_MODE_OFF; /* Stop previous blink */
|
||||
sts->time = period; /* Time for one on/off cycle */
|
||||
sts->onPct = percent; /* % of cycle LED is on */
|
||||
sts->todo = numBlinks; /* Number of blink cycles */
|
||||
if(!numBlinks)
|
||||
{
|
||||
sts->mode |= HAL_LED_MODE_FLASH; /* Continuous */
|
||||
}
|
||||
sts->next = TMOS_GetSystemClock(); /* Start now */
|
||||
sts->mode |= HAL_LED_MODE_BLINK; /* Enable blinking */
|
||||
leds ^= led;
|
||||
}
|
||||
led <<= 1;
|
||||
sts++;
|
||||
}
|
||||
tmos_start_task(halTaskID, LED_BLINK_EVENT, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
HalLedSet(leds, HAL_LED_MODE_ON); /* >= 100%, turn on */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HalLedSet(leds, HAL_LED_MODE_OFF); /* No on time, turn off */
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn HalLedUpdate
|
||||
*
|
||||
* @brief Update leds to work with blink
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void HalLedUpdate(void)
|
||||
{
|
||||
uint8_t led, pct, leds;
|
||||
uint16_t next, wait;
|
||||
uint32_t time;
|
||||
HalLedControl_t *sts;
|
||||
|
||||
next = 0;
|
||||
led = HAL_LED_1;
|
||||
leds = HAL_LED_ALL;
|
||||
sts = HalLedStatusControl.HalLedControlTable;
|
||||
|
||||
/* Check if sleep is active or not */
|
||||
if(!HalLedStatusControl.sleepActive)
|
||||
{
|
||||
while(leds)
|
||||
{
|
||||
if(leds & led)
|
||||
{
|
||||
if(sts->mode & HAL_LED_MODE_BLINK)
|
||||
{
|
||||
time = TMOS_GetSystemClock();
|
||||
if(time >= sts->next)
|
||||
{
|
||||
if(sts->mode & HAL_LED_MODE_ON)
|
||||
{
|
||||
pct = 100 - sts->onPct; /* Percentage of cycle for off */
|
||||
sts->mode &= ~HAL_LED_MODE_ON; /* Say it's not on */
|
||||
HalLedOnOff(led, HAL_LED_MODE_OFF); /* Turn it off */
|
||||
if(!(sts->mode & HAL_LED_MODE_FLASH))
|
||||
{
|
||||
if(sts->todo != 0xff)
|
||||
{
|
||||
sts->todo--; /* Not continuous, reduce count */
|
||||
}
|
||||
if(!sts->todo)
|
||||
{
|
||||
sts->mode ^= HAL_LED_MODE_BLINK; /* No more blinks */
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pct = sts->onPct; /* Percentage of cycle for on */
|
||||
sts->mode |= HAL_LED_MODE_ON; /* Say it's on */
|
||||
HalLedOnOff(led, HAL_LED_MODE_ON); /* Turn it on */
|
||||
}
|
||||
if(sts->mode & HAL_LED_MODE_BLINK)
|
||||
{
|
||||
wait = (((uint32_t)pct * (uint32_t)sts->time) / 100);
|
||||
sts->next = time + wait;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no more blink, no more wait */
|
||||
wait = 0;
|
||||
/* After blinking, set the LED back to the state before it blinks */
|
||||
HalLedSet(led, ((preBlinkState & led) != 0) ? HAL_LED_MODE_ON : HAL_LED_MODE_OFF);
|
||||
/* Clear the saved bit */
|
||||
preBlinkState &= (led ^ 0xFF);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wait = sts->next - time; /* Time left */
|
||||
}
|
||||
if(!next || (wait && (wait < next)))
|
||||
{
|
||||
next = wait;
|
||||
}
|
||||
}
|
||||
leds ^= led;
|
||||
}
|
||||
led <<= 1;
|
||||
sts++;
|
||||
}
|
||||
if(next)
|
||||
{
|
||||
tmos_start_task(halTaskID, LED_BLINK_EVENT, next); /* Schedule event */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn HalLedOnOff
|
||||
*
|
||||
* @brief Turns specified LED ON or OFF
|
||||
*
|
||||
* @param led - LED bit mask
|
||||
* @param mode - LED_ON,LED_OFF,
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void HalLedOnOff(uint8_t leds, uint8_t mode)
|
||||
{
|
||||
if(leds & HAL_LED_1)
|
||||
{
|
||||
if(mode == HAL_LED_MODE_ON)
|
||||
{
|
||||
HAL_TURN_ON_LED1();
|
||||
}
|
||||
else
|
||||
{
|
||||
HAL_TURN_OFF_LED1();
|
||||
}
|
||||
}
|
||||
if(leds & HAL_LED_2)
|
||||
{
|
||||
if(mode == HAL_LED_MODE_ON)
|
||||
{
|
||||
HAL_TURN_ON_LED2();
|
||||
}
|
||||
else
|
||||
{
|
||||
HAL_TURN_OFF_LED2();
|
||||
}
|
||||
}
|
||||
if(leds & HAL_LED_3)
|
||||
{
|
||||
if(mode == HAL_LED_MODE_ON)
|
||||
{
|
||||
HAL_TURN_ON_LED3();
|
||||
}
|
||||
else
|
||||
{
|
||||
HAL_TURN_OFF_LED3();
|
||||
}
|
||||
}
|
||||
if(leds & HAL_LED_4)
|
||||
{
|
||||
if(mode == HAL_LED_MODE_ON)
|
||||
{
|
||||
HAL_TURN_ON_LED4();
|
||||
}
|
||||
else
|
||||
{
|
||||
HAL_TURN_OFF_LED4();
|
||||
}
|
||||
}
|
||||
/* Remember current state */
|
||||
if(mode)
|
||||
{
|
||||
HalLedState |= leds;
|
||||
}
|
||||
else
|
||||
{
|
||||
HalLedState &= (leds ^ 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************************************
|
||||
* @fn HalGetLedState
|
||||
*
|
||||
* @brief Dim LED2 - Dim (set level) of LED2
|
||||
*
|
||||
* @return led state
|
||||
*/
|
||||
uint8_t HalLedGetState()
|
||||
{
|
||||
return HalLedState;
|
||||
}
|
||||
|
||||
/******************************** endfile @ led ******************************/
|
|
@ -0,0 +1,328 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : MCU.c
|
||||
* Author : WCH
|
||||
* Version : V1.2
|
||||
* Date : 2022/01/18
|
||||
* Description : HAL task processing function and BLE and hardware initialization
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/* Header file contains */
|
||||
#include "../../inc/HAL.h"
|
||||
#include "string.h"
|
||||
#include "xs_base.h"
|
||||
|
||||
tmosTaskID halTaskID;
|
||||
uint32_t g_LLE_IRQLibHandlerLocation;
|
||||
|
||||
/*******************************************************************************
|
||||
* @fn Lib_Calibration_LSI
|
||||
*
|
||||
* @brief Internal 32K calibration
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void Lib_Calibration_LSI(void)
|
||||
{
|
||||
Calibration_LSI(Level_64);
|
||||
}
|
||||
|
||||
#if(defined(BLE_SNV)) && (BLE_SNV == TRUE)
|
||||
/*******************************************************************************
|
||||
* @fn Lib_Read_Flash
|
||||
*
|
||||
* @brief Callback function used for BLE lib.
|
||||
*
|
||||
* @param addr.
|
||||
* @param num.
|
||||
* @param pBuf.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
uint32_t Lib_Read_Flash(uint32_t addr, uint32_t num, uint32_t *pBuf)
|
||||
{
|
||||
tmos_memcpy(pBuf, (uint32_t*)addr, num*4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @fn Lib_Write_Flash
|
||||
*
|
||||
* @brief Callback function used for BLE lib.
|
||||
*
|
||||
* @param addr.
|
||||
* @param num.
|
||||
* @param pBuf.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
uint32_t Lib_Write_Flash(uint32_t addr, uint32_t num, uint32_t *pBuf)
|
||||
{
|
||||
FLASH_Unlock_Fast();
|
||||
FLASH_ErasePage_Fast( addr );
|
||||
FLASH_ProgramPage_Fast( addr, pBuf);
|
||||
FLASH_Lock_Fast();
|
||||
Delay_Us(1);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* @fn WCHBLE_Init
|
||||
*
|
||||
* @brief BLE library initialization
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void WCHBLE_Init(void)
|
||||
{
|
||||
uint8_t i;
|
||||
bleConfig_t cfg;
|
||||
|
||||
g_LLE_IRQLibHandlerLocation = (uint32_t)LLE_IRQLibHandler;
|
||||
|
||||
if(!tmos_memcmp(VER_LIB, VER_FILE, strlen(VER_FILE)))
|
||||
{
|
||||
PRINT("head file error...\n");
|
||||
while(1);
|
||||
}
|
||||
|
||||
// 32M crystal capacitance and current
|
||||
OSC->HSE_CAL_CTRL &= ~(0x07<<28);
|
||||
OSC->HSE_CAL_CTRL |= 0x03<<28;
|
||||
OSC->HSE_CAL_CTRL |= 3<<24;
|
||||
|
||||
tmos_memset(&cfg, 0, sizeof(bleConfig_t));
|
||||
cfg.MEMAddr = (uint32_t)MEM_BUF;
|
||||
cfg.MEMLen = (uint32_t)BLE_MEMHEAP_SIZE;
|
||||
cfg.BufMaxLen = (uint32_t)BLE_BUFF_MAX_LEN;
|
||||
cfg.BufNumber = (uint32_t)BLE_BUFF_NUM;
|
||||
cfg.TxNumEvent = (uint32_t)BLE_TX_NUM_EVENT;
|
||||
cfg.TxPower = (uint32_t)BLE_TX_POWER;
|
||||
#if(defined(BLE_SNV)) && (BLE_SNV == TRUE)
|
||||
cfg.SNVAddr = (uint32_t)BLE_SNV_ADDR;
|
||||
cfg.SNVNum = (uint32_t)BLE_SNV_NUM;
|
||||
cfg.readFlashCB = Lib_Read_Flash;
|
||||
cfg.writeFlashCB = Lib_Write_Flash;
|
||||
#endif
|
||||
cfg.ClockFrequency = CAB_LSIFQ/2;
|
||||
#if(CLK_OSC32K==0)
|
||||
cfg.ClockAccuracy = 50;
|
||||
#else
|
||||
cfg.ClockAccuracy = 1000;
|
||||
#endif
|
||||
cfg.ConnectNumber = (PERIPHERAL_MAX_CONNECTION & 3) | (CENTRAL_MAX_CONNECTION << 2);
|
||||
#if(defined TEM_SAMPLE) && (TEM_SAMPLE == TRUE)
|
||||
// Calibrate RF and internal RC according to temperature changes (greater than 7 degrees Celsius)
|
||||
cfg.tsCB = HAL_GetInterTempValue;
|
||||
#if(CLK_OSC32K)
|
||||
cfg.rcCB = Lib_Calibration_LSI; // Internal 32K clock calibration
|
||||
#endif
|
||||
#endif
|
||||
#if(defined(HAL_SLEEP)) && (HAL_SLEEP == TRUE)
|
||||
cfg.idleCB = BLE_LowPower; // Enable sleep
|
||||
#endif
|
||||
#if(defined(BLE_MAC)) && (BLE_MAC == TRUE)
|
||||
for(i = 0; i < 6; i++)
|
||||
{
|
||||
cfg.MacAddr[i] = MacAddr[5 - i];
|
||||
}
|
||||
#else
|
||||
{
|
||||
uint8_t MacAddr[6];
|
||||
FLASH_GetMACAddress(MacAddr);
|
||||
for(i = 0; i < 6; i++)
|
||||
{
|
||||
cfg.MacAddr[i] = MacAddr[i]; // Use chip mac address
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(!cfg.MEMAddr || cfg.MEMLen < 4 * 1024)
|
||||
{
|
||||
while(1);
|
||||
}
|
||||
i = BLE_LibInit(&cfg);
|
||||
if(i)
|
||||
{
|
||||
KPrintf("LIB init error code: %x ...\n", i);
|
||||
while(1);
|
||||
}
|
||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE );
|
||||
NVIC_EnableIRQ( BB_IRQn );
|
||||
NVIC_EnableIRQ( LLE_IRQn );
|
||||
KPrintf("WCHBLE_LibInit Success\n");
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @fn HAL_ProcessEvent
|
||||
*
|
||||
* @brief HAL processing
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events.
|
||||
*/
|
||||
tmosEvents HAL_ProcessEvent(tmosTaskID task_id, tmosEvents events)
|
||||
{
|
||||
uint8_t *msgPtr;
|
||||
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{
|
||||
/**
|
||||
* Process the HAL layer message, call tmos_msg_receive to read the message,
|
||||
* and delete the message after processing.
|
||||
*/
|
||||
msgPtr = tmos_msg_receive(task_id);
|
||||
if(msgPtr)
|
||||
{
|
||||
/* De-allocate */
|
||||
tmos_msg_deallocate(msgPtr);
|
||||
}
|
||||
return events ^ SYS_EVENT_MSG;
|
||||
}
|
||||
if(events & LED_BLINK_EVENT)
|
||||
{
|
||||
#if(defined HAL_LED) && (HAL_LED == TRUE)
|
||||
HalLedUpdate();
|
||||
#endif // HAL_LED
|
||||
return events ^ LED_BLINK_EVENT;
|
||||
}
|
||||
if(events & HAL_KEY_EVENT)
|
||||
{
|
||||
#if(defined HAL_KEY) && (HAL_KEY == TRUE)
|
||||
HAL_KeyPoll(); /* Check for keys */
|
||||
tmos_start_task(halTaskID, HAL_KEY_EVENT, MS1_TO_SYSTEM_TIME(100));
|
||||
return events ^ HAL_KEY_EVENT;
|
||||
#endif
|
||||
}
|
||||
if(events & HAL_REG_INIT_EVENT)
|
||||
{
|
||||
#if(defined BLE_CALIBRATION_ENABLE) && (BLE_CALIBRATION_ENABLE == TRUE) // Calibration tasks, a single time is less than 10ms
|
||||
BLE_RegInit(); // Calibrate RF
|
||||
#if(CLK_OSC32K)
|
||||
Lib_Calibration_LSI(); // Calibrate internal RC
|
||||
#endif
|
||||
tmos_start_task(halTaskID, HAL_REG_INIT_EVENT, MS1_TO_SYSTEM_TIME(BLE_CALIBRATION_PERIOD));
|
||||
return events ^ HAL_REG_INIT_EVENT;
|
||||
#endif
|
||||
}
|
||||
if(events & HAL_TEST_EVENT)
|
||||
{
|
||||
PRINT("* \n");
|
||||
tmos_start_task(halTaskID, HAL_TEST_EVENT, MS1_TO_SYSTEM_TIME(1000));
|
||||
return events ^ HAL_TEST_EVENT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @fn HAL_Init
|
||||
*
|
||||
* @brief 硬件初始化
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void HAL_Init()
|
||||
{
|
||||
halTaskID = TMOS_ProcessEventRegister(HAL_ProcessEvent);
|
||||
HAL_TimeInit();
|
||||
#if(defined HAL_SLEEP) && (HAL_SLEEP == TRUE)
|
||||
HAL_SleepInit();
|
||||
#endif
|
||||
#if(defined HAL_LED) && (HAL_LED == TRUE)
|
||||
HAL_LedInit();
|
||||
#endif
|
||||
#if(defined HAL_KEY) && (HAL_KEY == TRUE)
|
||||
HAL_KeyInit();
|
||||
#endif
|
||||
#if(defined BLE_CALIBRATION_ENABLE) && (BLE_CALIBRATION_ENABLE == TRUE)
|
||||
// Add a calibration task, and a single calibration takes less than 10ms
|
||||
tmos_start_task(halTaskID, HAL_REG_INIT_EVENT, MS1_TO_SYSTEM_TIME(BLE_CALIBRATION_PERIOD));
|
||||
#endif
|
||||
// tmos_start_task(halTaskID, HAL_TEST_EVENT, MS1_TO_SYSTEM_TIME(1000)); // Add a test task
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @fn HAL_GetInterTempValue
|
||||
*
|
||||
* @brief Get the internal temperature sampling value, if the ADC interrupt sampling is used,
|
||||
* it is necessary to temporarily shield the interrupt in this function.
|
||||
*
|
||||
* @return Internal temperature sampling value.
|
||||
*/
|
||||
uint16_t HAL_GetInterTempValue(void)
|
||||
{
|
||||
uint32_t rcc_apb2pcenr, rcc_cfgr0, adc1_ctrl1, adc1_ctrl2, adc1_rsqr1, adc1_rsqr2, adc1_rsqr3, adc1_samptr1, adc1_samptr2;
|
||||
uint32_t adc1_iofr1, adc1_iofr2, adc1_iofr3, adc1_iofr4, adc1_wdhtr, adc1_wdltr, adc1_isqr;
|
||||
ADC_InitTypeDef ADC_InitStructure = {0};
|
||||
uint16_t adc_data;
|
||||
|
||||
rcc_apb2pcenr = RCC->APB2PCENR;
|
||||
rcc_cfgr0 = RCC->CFGR0;
|
||||
adc1_ctrl1 = ADC1->CTLR1;
|
||||
adc1_ctrl2 = ADC1->CTLR2;
|
||||
adc1_rsqr1 = ADC1->RSQR1;
|
||||
adc1_rsqr2 = ADC1->RSQR2;
|
||||
adc1_rsqr3 = ADC1->RSQR3;
|
||||
adc1_samptr1 = ADC1->SAMPTR1;
|
||||
adc1_samptr2 = ADC1->SAMPTR2;
|
||||
adc1_iofr1 = ADC1->IOFR1;
|
||||
adc1_iofr2 = ADC1->IOFR2;
|
||||
adc1_iofr3 = ADC1->IOFR3;
|
||||
adc1_iofr4 = ADC1->IOFR4;
|
||||
adc1_wdhtr = ADC1->WDHTR;
|
||||
adc1_wdltr = ADC1->WDLTR;
|
||||
adc1_isqr = ADC1->ISQR;
|
||||
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
|
||||
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
|
||||
ADC_DeInit(ADC1);
|
||||
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
|
||||
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
|
||||
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
|
||||
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
|
||||
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
|
||||
ADC_InitStructure.ADC_NbrOfChannel = 1;
|
||||
ADC_Init(ADC1, &ADC_InitStructure);
|
||||
|
||||
ADC_Cmd(ADC1, ENABLE);
|
||||
ADC_BufferCmd(ADC1, ENABLE); //enable buffer
|
||||
ADC_TempSensorVrefintCmd(ENABLE);
|
||||
ADC_RegularChannelConfig(ADC1, ADC_Channel_TempSensor, 1, ADC_SampleTime_239Cycles5);
|
||||
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
|
||||
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
|
||||
adc_data = ADC_GetConversionValue(ADC1);
|
||||
|
||||
ADC_DeInit(ADC1);
|
||||
RCC->APB2PCENR = rcc_apb2pcenr;
|
||||
RCC->CFGR0 = rcc_cfgr0;
|
||||
ADC1->CTLR1 = adc1_ctrl1;
|
||||
ADC1->CTLR2 = adc1_ctrl2;
|
||||
ADC1->RSQR1 = adc1_rsqr1;
|
||||
ADC1->RSQR2 = adc1_rsqr2;
|
||||
ADC1->RSQR3 = adc1_rsqr3;
|
||||
ADC1->SAMPTR1 = adc1_samptr1;
|
||||
ADC1->SAMPTR2 = adc1_samptr2;
|
||||
ADC1->IOFR1 = adc1_iofr1;
|
||||
ADC1->IOFR2 = adc1_iofr2;
|
||||
ADC1->IOFR3 = adc1_iofr3;
|
||||
ADC1->IOFR4 = adc1_iofr4;
|
||||
ADC1->WDHTR = adc1_wdhtr;
|
||||
ADC1->WDLTR = adc1_wdltr;
|
||||
ADC1->ISQR = adc1_isqr;
|
||||
return (adc_data);
|
||||
}
|
||||
|
||||
/******************************** endfile @ mcu ******************************/
|
|
@ -0,0 +1,2 @@
|
|||
SRC_FILES := KEY.c LED.c MCU.c RTC.c SLEEP.c
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,113 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : RTC.c
|
||||
* Author : WCH
|
||||
* Version : V1.2
|
||||
* Date : 2022/01/18
|
||||
* Description : RTC configuration and its initialization
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/* Header file contains */
|
||||
#include "../../inc/HAL.h"
|
||||
|
||||
/*********************************************************************
|
||||
* CONSTANTS
|
||||
*/
|
||||
#define RTC_INIT_TIME_HOUR 0
|
||||
#define RTC_INIT_TIME_MINUTE 0
|
||||
#define RTC_INIT_TIME_SECEND 0
|
||||
|
||||
/***************************************************
|
||||
* Global variables
|
||||
*/
|
||||
volatile uint32_t RTCTigFlag;
|
||||
|
||||
/*******************************************************************************
|
||||
* @fn RTC_SetTignTime
|
||||
*
|
||||
* @brief Configure RTC trigger time
|
||||
*
|
||||
* @param time - Trigger time.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void RTC_SetTignTime(uint32_t time)
|
||||
{
|
||||
RTC_WaitForLastTask();
|
||||
RTC_SetAlarm(time);
|
||||
RTC_WaitForLastTask();
|
||||
RTCTigFlag = 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @fn HAL_Time0Init
|
||||
*
|
||||
* @brief System timer initialization
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void HAL_TimeInit(void)
|
||||
{
|
||||
uint16_t temp=0;
|
||||
uint8_t state=0;
|
||||
bleClockConfig_t conf={0};
|
||||
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP, ENABLE);
|
||||
PWR_BackupAccessCmd(ENABLE);
|
||||
#if( CLK_OSC32K )
|
||||
RCC_LSICmd(ENABLE);
|
||||
RCC_LSEConfig(RCC_LSE_OFF);
|
||||
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
|
||||
#else
|
||||
RCC_LSEConfig(RCC_LSE_ON);
|
||||
/* Check the specified RCC logo position settings or not,
|
||||
* wait for the low-speed crystal oscillator to be ready */
|
||||
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
|
||||
{
|
||||
temp++;
|
||||
Delay_Ms(10);
|
||||
}
|
||||
if(temp>=250)
|
||||
{
|
||||
printf("time error..\n");
|
||||
}
|
||||
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
|
||||
#endif
|
||||
RCC_RTCCLKCmd(ENABLE);
|
||||
RTC_WaitForLastTask();
|
||||
RTC_WaitForLastTask();
|
||||
RTC_SetPrescaler(1);
|
||||
RTC_WaitForLastTask();
|
||||
RTC_SetCounter(0);
|
||||
RTC_WaitForLastTask();
|
||||
#if( CLK_OSC32K )
|
||||
Lib_Calibration_LSI();
|
||||
#endif
|
||||
conf.ClockAccuracy = CLK_OSC32K?1000:100;
|
||||
conf.ClockFrequency = CAB_LSIFQ/2;
|
||||
conf.ClockMaxCount = 0xFFFFFFFF;
|
||||
conf.getClockValue = RTC_GetCounter;
|
||||
state = TMOS_TimerInit( &conf );
|
||||
if(state)
|
||||
{
|
||||
PRINT("TMOS_TimerInit err %x\n",state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
__attribute__((interrupt()))
|
||||
void RTCAlarm_IRQHandler(void)
|
||||
{
|
||||
RTCTigFlag = 1;
|
||||
EXTI_ClearITPendingBit(EXTI_Line17);
|
||||
RTC_ClearITPendingBit(RTC_IT_ALR);
|
||||
RTC_WaitForLastTask();
|
||||
}
|
||||
|
||||
/******************************** endfile @ time ******************************/
|
|
@ -0,0 +1,109 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : SLEEP.c
|
||||
* Author : WCH
|
||||
* Version : V1.2
|
||||
* Date : 2022/01/18
|
||||
* Description : Sleep configuration and its initialization
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/* Header file contains */
|
||||
#include "../../inc/HAL.h"
|
||||
#include "xs_base.h"
|
||||
|
||||
#define US_TO_TICK(us) (uint32_t)((us) / (1000000 / ((CAB_LSIFQ / 2))))
|
||||
|
||||
#define SLEEP_PERIOD_MIN_US 200
|
||||
#define SLEEP_PERIOD_MAX_TICK 0xFFD2393F
|
||||
#define SLEEP_PERIOD_MIN_TICK US_TO_TICK(SLEEP_PERIOD_MIN_US)
|
||||
#define HESREADY_TICK US_TO_TICK(WAKE_UP_MAX_TIME_US)
|
||||
|
||||
/*******************************************************************************
|
||||
* @fn BLE_LowPower
|
||||
*
|
||||
* @brief 启动睡眠
|
||||
*
|
||||
* @param time - 唤醒的时间点(RTC绝对值)
|
||||
*
|
||||
* @return state.
|
||||
*/
|
||||
uint32_t BLE_LowPower(uint32_t time)
|
||||
{
|
||||
KPrintf("%s %d\n", __FUNCTION__, __LINE__);
|
||||
#if(defined(HAL_SLEEP)) && (HAL_SLEEP == TRUE)
|
||||
uint32_t current_time;
|
||||
uint32_t sleep_period;
|
||||
uint32_t wake_time;
|
||||
|
||||
wake_time = time - HESREADY_TICK;
|
||||
|
||||
__disable_irq();
|
||||
current_time = RTC_GetCounter();
|
||||
sleep_period = wake_time - current_time;
|
||||
|
||||
if((sleep_period < SLEEP_PERIOD_MIN_TICK) || (sleep_period > SLEEP_PERIOD_MAX_TICK))
|
||||
{
|
||||
__enable_irq();
|
||||
return 2;
|
||||
}
|
||||
|
||||
RTC_SetTignTime(wake_time);
|
||||
__enable_irq();
|
||||
|
||||
#if(DEBUG == DEBUG_UART1) // To use other serial ports to output printing information, you need to modify this line of code
|
||||
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
|
||||
{
|
||||
__NOP();
|
||||
}
|
||||
#endif
|
||||
// LOW POWER-sleep
|
||||
if(!RTCTigFlag)
|
||||
{
|
||||
PWR_EnterSTOPMode_RAM_LV(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
|
||||
SystemInit();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @fn HAL_SleepInit
|
||||
*
|
||||
* @brief Configure sleep Wake-up source - RTC wake up, trigger mode
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void HAL_SleepInit(void)
|
||||
{
|
||||
#if(defined(HAL_SLEEP)) && (HAL_SLEEP == TRUE)
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
|
||||
RTC_WaitForLastTask();
|
||||
|
||||
RTC_ITConfig(RTC_IT_ALR, ENABLE);
|
||||
EXTI_InitTypeDef EXTI_InitStructure = {0};
|
||||
NVIC_InitTypeDef NVIC_InitStructure = {0};
|
||||
|
||||
EXTI_InitStructure.EXTI_Line = EXTI_Line17;
|
||||
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
|
||||
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
|
||||
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
|
||||
EXTI_Init(&EXTI_InitStructure);
|
||||
|
||||
NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := app_drv_fifo.c app_uart.c ble_uart_service.c
|
||||
SRC_DIR := HAL
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,191 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : app_drv_fifo.c
|
||||
* Author : WCH
|
||||
* Version : V1.1
|
||||
* Date : 2022/01/19
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#include "../inc/app_drv_fifo.h"
|
||||
|
||||
static __inline uint16_t fifo_length(app_drv_fifo_t *fifo)
|
||||
{
|
||||
uint16_t tmp = fifo->begin;
|
||||
return fifo->end - tmp;
|
||||
}
|
||||
|
||||
uint16_t app_drv_fifo_length(app_drv_fifo_t *fifo)
|
||||
{
|
||||
return fifo_length(fifo);
|
||||
}
|
||||
|
||||
app_drv_fifo_result_t
|
||||
app_drv_fifo_init(app_drv_fifo_t *fifo, uint8_t *buffer, uint16_t buffer_size)
|
||||
{
|
||||
if(buffer_size == 0)
|
||||
{
|
||||
return APP_DRV_FIFO_RESULT_LENGTH_ERROR;
|
||||
}
|
||||
if(0 != ((buffer_size) & (buffer_size - 1)))
|
||||
{
|
||||
return APP_DRV_FIFO_RESULT_LENGTH_ERROR;
|
||||
}
|
||||
fifo->begin = 0;
|
||||
fifo->end = 0;
|
||||
fifo->data = buffer;
|
||||
fifo->size = buffer_size;
|
||||
fifo->size_mask = buffer_size - 1;
|
||||
return APP_DRV_FIFO_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
void app_drv_fifo_push(app_drv_fifo_t *fifo, uint8_t data)
|
||||
{
|
||||
fifo->data[fifo->end & fifo->size_mask] = data;
|
||||
fifo->end++;
|
||||
}
|
||||
|
||||
uint8_t app_drv_fifo_pop(app_drv_fifo_t *fifo)
|
||||
{
|
||||
uint8_t data = fifo->data[fifo->begin & fifo->size_mask];
|
||||
fifo->begin++;
|
||||
return data;
|
||||
}
|
||||
|
||||
void app_drv_fifo_flush(app_drv_fifo_t *fifo)
|
||||
{
|
||||
fifo->begin = 0;
|
||||
fifo->end = 0;
|
||||
}
|
||||
|
||||
bool app_drv_fifo_is_empty(app_drv_fifo_t *fifo)
|
||||
{
|
||||
return (fifo->begin == fifo->end);
|
||||
}
|
||||
|
||||
bool app_drv_fifo_is_full(app_drv_fifo_t *fifo)
|
||||
{
|
||||
return (fifo_length(fifo) == fifo->size);
|
||||
}
|
||||
|
||||
app_drv_fifo_result_t
|
||||
app_drv_fifo_write(app_drv_fifo_t *fifo, uint8_t *data, uint16_t *p_write_length)
|
||||
{
|
||||
if(fifo == NULL)
|
||||
{
|
||||
return APP_DRV_FIFO_RESULT_NULL;
|
||||
}
|
||||
if(p_write_length == NULL)
|
||||
{
|
||||
return APP_DRV_FIFO_RESULT_NULL;
|
||||
}
|
||||
//PRINT("fifo_length = %d\r\n",fifo_length(fifo));
|
||||
const uint16_t available_count = fifo->size - fifo_length(fifo);
|
||||
const uint16_t requested_len = (*p_write_length);
|
||||
uint16_t index = 0;
|
||||
uint16_t write_size = MIN(requested_len, available_count);
|
||||
//PRINT("available_count %d\r\n",available_count);
|
||||
// Check if the FIFO is FULL.
|
||||
if(available_count == 0)
|
||||
{
|
||||
return APP_DRV_FIFO_RESULT_NOT_MEM;
|
||||
}
|
||||
|
||||
// Check if application has requested only the size.
|
||||
if(data == NULL)
|
||||
{
|
||||
return APP_DRV_FIFO_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
for(index = 0; index < write_size; index++)
|
||||
{
|
||||
//push
|
||||
fifo->data[fifo->end & fifo->size_mask] = data[index];
|
||||
fifo->end++;
|
||||
}
|
||||
(*p_write_length) = write_size;
|
||||
return APP_DRV_FIFO_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
app_drv_fifo_result_t
|
||||
app_drv_fifo_write_from_same_addr(app_drv_fifo_t *fifo, uint8_t *data, uint16_t write_length)
|
||||
{
|
||||
if(fifo == NULL)
|
||||
{
|
||||
return APP_DRV_FIFO_RESULT_NULL;
|
||||
}
|
||||
const uint16_t available_count = fifo->size_mask - fifo_length(fifo) + 1;
|
||||
const uint16_t requested_len = (write_length);
|
||||
uint16_t index = 0;
|
||||
uint16_t write_size = MIN(requested_len, available_count);
|
||||
|
||||
// Check if the FIFO is FULL.
|
||||
if(available_count == 0)
|
||||
{
|
||||
return APP_DRV_FIFO_RESULT_NOT_MEM;
|
||||
}
|
||||
|
||||
for(index = 0; index < write_size; index++)
|
||||
{
|
||||
//push
|
||||
fifo->data[fifo->end & fifo->size_mask] = data[0];
|
||||
fifo->end++;
|
||||
}
|
||||
return APP_DRV_FIFO_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
app_drv_fifo_result_t
|
||||
app_drv_fifo_read(app_drv_fifo_t *fifo, uint8_t *data, uint16_t *p_read_length)
|
||||
{
|
||||
if(fifo == NULL)
|
||||
{
|
||||
return APP_DRV_FIFO_RESULT_NULL;
|
||||
}
|
||||
if(p_read_length == NULL)
|
||||
{
|
||||
return APP_DRV_FIFO_RESULT_NULL;
|
||||
}
|
||||
const uint16_t byte_count = fifo_length(fifo);
|
||||
const uint16_t requested_len = (*p_read_length);
|
||||
uint32_t index = 0;
|
||||
uint32_t read_size = MIN(requested_len, byte_count);
|
||||
|
||||
if(byte_count == 0)
|
||||
{
|
||||
return APP_DRV_FIFO_RESULT_NOT_FOUND;
|
||||
}
|
||||
//PRINT("read size = %d,byte_count = %d\r\n",read_size,byte_count);
|
||||
for(index = 0; index < read_size; index++)
|
||||
{
|
||||
//pop
|
||||
data[index] = fifo->data[fifo->begin & fifo->size_mask];
|
||||
fifo->begin++;
|
||||
}
|
||||
|
||||
(*p_read_length) = read_size;
|
||||
return APP_DRV_FIFO_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
app_drv_fifo_result_t
|
||||
app_drv_fifo_read_to_same_addr(app_drv_fifo_t *fifo, uint8_t *data, uint16_t read_length)
|
||||
{
|
||||
if(fifo == NULL)
|
||||
{
|
||||
return APP_DRV_FIFO_RESULT_NULL;
|
||||
}
|
||||
const uint16_t byte_count = fifo_length(fifo);
|
||||
const uint16_t requested_len = (read_length);
|
||||
uint32_t index = 0;
|
||||
uint32_t read_size = MIN(requested_len, byte_count);
|
||||
|
||||
for(index = 0; index < read_size; index++)
|
||||
{
|
||||
//pop
|
||||
data[0] = fifo->data[fifo->begin & fifo->size_mask];
|
||||
fifo->begin++;
|
||||
}
|
||||
return APP_DRV_FIFO_RESULT_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,240 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : peripheral.C
|
||||
* Author : WCH
|
||||
* Version : v1.0
|
||||
* Date : 2020/11/26
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
#include "../inc/config.h"
|
||||
#include "../Profile/devinfoservice.h"
|
||||
#include "../Profile/gattprofile.h"
|
||||
#include "../inc/peripheral.h"
|
||||
#include "../inc/app_uart.h"
|
||||
#include "xs_base.h"
|
||||
|
||||
/*********************************************************************
|
||||
* MACROS
|
||||
*/
|
||||
//The buffer length should be a power of 2
|
||||
#define APP_UART_TX_BUFFER_LENGTH 512U
|
||||
#define APP_UART_RX_BUFFER_LENGTH 2048U
|
||||
|
||||
/*********************************************************************
|
||||
* CONSTANTS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* TYPEDEFS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*/
|
||||
uint8_t to_test_buffer[BLE_BUFF_MAX_LEN - 4 - 3];
|
||||
|
||||
app_drv_fifo_t app_uart_tx_fifo;
|
||||
app_drv_fifo_t app_uart_rx_fifo;
|
||||
|
||||
//interupt uart rx flag ,clear at main loop
|
||||
bool uart_rx_flag = false;
|
||||
|
||||
//for interrupt rx blcak hole ,when uart rx fifo full
|
||||
uint8_t for_uart_rx_black_hole = 0;
|
||||
|
||||
//fifo length less that MTU-3, retry times
|
||||
uint32_t uart_to_ble_send_evt_cnt = 0;
|
||||
|
||||
/*********************************************************************
|
||||
* EXTERNAL VARIABLES
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* EXTERNAL FUNCTIONS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* LOCAL VARIABLES
|
||||
*/
|
||||
//
|
||||
|
||||
//The tx buffer and rx buffer for app_drv_fifo
|
||||
//length should be a power of 2
|
||||
static uint8_t app_uart_tx_buffer[APP_UART_TX_BUFFER_LENGTH] = {0};
|
||||
static uint8_t app_uart_rx_buffer[APP_UART_RX_BUFFER_LENGTH] = {0};
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* LOCAL FUNCTIONS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* PROFILE CALLBACKS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* PUBLIC FUNCTIONS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* @fn app_uart_process
|
||||
*
|
||||
* @brief process uart data
|
||||
*
|
||||
* @return NULL
|
||||
*/
|
||||
void app_uart_process(void)
|
||||
{
|
||||
uint8_t data;
|
||||
__disable_irq();
|
||||
if(uart_rx_flag)
|
||||
{
|
||||
tmos_start_task(Peripheral_TaskID, UART_TO_BLE_SEND_EVT, 2);
|
||||
uart_rx_flag = false;
|
||||
}
|
||||
__enable_irq();
|
||||
|
||||
while(app_drv_fifo_length(&app_uart_tx_fifo))
|
||||
{
|
||||
app_drv_fifo_read_to_same_addr(&app_uart_tx_fifo, (uint8_t *)&data, 1);
|
||||
// USART_SendData(USART, data);
|
||||
KPrintf("%c", data);
|
||||
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) /* waiting for sending finish */
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
/*********************************************************************
|
||||
* @fn app_uart_init
|
||||
*
|
||||
* @brief init uart
|
||||
*
|
||||
* @return NULL
|
||||
*/
|
||||
void app_uart_init()
|
||||
{
|
||||
//tx fifo and tx fifo
|
||||
//The buffer length should be a power of 2
|
||||
app_drv_fifo_init(&app_uart_tx_fifo, app_uart_tx_buffer, APP_UART_TX_BUFFER_LENGTH);
|
||||
app_drv_fifo_init(&app_uart_rx_fifo, app_uart_rx_buffer, APP_UART_RX_BUFFER_LENGTH);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
||||
USART_InitTypeDef USART_InitStructure = {0};
|
||||
NVIC_InitTypeDef NVIC_InitStructure = {0};
|
||||
|
||||
//uart3 init
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
||||
|
||||
/* USART3 TX-->B.10 RX-->B.11 */
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
USART_InitStructure.USART_BaudRate = 115200;
|
||||
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
||||
USART_InitStructure.USART_StopBits = USART_StopBits_1;
|
||||
USART_InitStructure.USART_Parity = USART_Parity_No;
|
||||
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||||
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
|
||||
|
||||
USART_Init(USART3, &USART_InitStructure);
|
||||
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
|
||||
|
||||
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
|
||||
USART_Cmd(USART3, ENABLE);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn app_uart_tx_data
|
||||
*
|
||||
* @brief app_uart_tx_data
|
||||
*
|
||||
* @return NULL
|
||||
*/
|
||||
void app_uart_tx_data(uint8_t *data, uint16_t length)
|
||||
{
|
||||
uint16_t write_length = length;
|
||||
app_drv_fifo_write(&app_uart_tx_fifo, data, &write_length);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn UART3_IRQHandler
|
||||
*
|
||||
* @brief Not every uart reception will end with a UART_II_RECV_TOUT
|
||||
* UART_II_RECV_TOUT can only be triggered when R8_UARTx_RFC is not 0
|
||||
* Here we cannot rely UART_II_RECV_TOUT as the end of a uart reception
|
||||
*
|
||||
* @return NULL
|
||||
*/
|
||||
__attribute__((interrupt()))
|
||||
void USART3_IRQHandler(void)
|
||||
{
|
||||
uint16_t error;
|
||||
uint8_t data;
|
||||
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
|
||||
{
|
||||
data = USART_ReceiveData(USART3);
|
||||
error = app_drv_fifo_write_from_same_addr(&app_uart_rx_fifo, (uint8_t *)&data, 1);
|
||||
if(error != APP_DRV_FIFO_RESULT_SUCCESS)
|
||||
{
|
||||
KPrintf("APP_DRV_FIFO_RESULT_NOT_MEM\r\n");
|
||||
}
|
||||
uart_rx_flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn on_bleuartServiceEvTMOS_SystemProcesst
|
||||
*
|
||||
* @brief ble uart service callback handler
|
||||
*
|
||||
* @return NULL
|
||||
*/
|
||||
void on_bleuartServiceEvt(uint16_t connection_handle, ble_uart_evt_t *p_evt)
|
||||
{
|
||||
switch(p_evt->type)
|
||||
{
|
||||
case BLE_UART_EVT_TX_NOTI_DISABLED:
|
||||
KPrintf("%02x:bleuart_EVT_TX_NOTI_DISABLED\r\n", connection_handle);
|
||||
break;
|
||||
case BLE_UART_EVT_TX_NOTI_ENABLED:
|
||||
KPrintf("%02x:bleuart_EVT_TX_NOTI_ENABLED\r\n", connection_handle);
|
||||
break;
|
||||
case BLE_UART_EVT_BLE_DATA_RECIEVED:
|
||||
KPrintf("BLE RX DATA len:%d\r\n", p_evt->data.length);
|
||||
|
||||
//for notify back test
|
||||
//to ble
|
||||
uint16_t to_write_length = p_evt->data.length;
|
||||
app_drv_fifo_write(&app_uart_rx_fifo, (uint8_t *)p_evt->data.p_data, &to_write_length);
|
||||
tmos_start_task(Peripheral_TaskID, UART_TO_BLE_SEND_EVT, 2);
|
||||
//end of nofify back test
|
||||
|
||||
//ble to uart
|
||||
app_uart_tx_data((uint8_t *)p_evt->data.p_data, p_evt->data.length);
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
|
@ -0,0 +1,379 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ble_uart_service.c
|
||||
* Author : WCH
|
||||
* Version : V1.1
|
||||
* Date : 2022/01/19
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
|
||||
#include "../inc/config.h"
|
||||
#include "../Profile/gattprofile.h"
|
||||
#include "stdint.h"
|
||||
#include "../inc/ble_uart_service.h"
|
||||
|
||||
/*********************************************************************
|
||||
* MACROS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* CONSTANTS
|
||||
*/
|
||||
|
||||
#define SERVAPP_NUM_ATTR_SUPPORTED 7
|
||||
|
||||
#define RAWPASS_TX_VALUE_HANDLE 4
|
||||
#define RAWPASS_RX_VALUE_HANDLE 2
|
||||
/*********************************************************************
|
||||
* TYPEDEFS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*/
|
||||
////ble_uart GATT Profile Service UUID
|
||||
//const uint8_t ble_uart_ServiceUUID[ATT_UUID_SIZE] =
|
||||
//{0x55, 0xe4,0x05,0xd2,0xaf,0x9f,0xa9,0x8f,0xe5,0x4a,0x7d,0xfe,0x43,0x53,0x53,0x49};
|
||||
|
||||
//// Characteristic rx uuid
|
||||
//const uint8_t ble_uart_RxCharUUID[ATT_UUID_SIZE] =
|
||||
//{0xb3,0x9b,0x72,0x34,0xbe,0xec, 0xd4,0xa8,0xf4,0x43,0x41,0x88,0x43,0x53,0x53,0x49};
|
||||
|
||||
//// Characteristic tx uuid
|
||||
//const uint8_t ble_uart_TxCharUUID[ATT_UUID_SIZE] =
|
||||
//{0x16,0x96,0x24,0x47,0xc6,0x23, 0x61,0xba,0xd9,0x4b,0x4d,0x1e,0x43,0x53,0x53,0x49};
|
||||
|
||||
// ble_uart GATT Profile Service UUID
|
||||
const uint8_t ble_uart_ServiceUUID[ATT_UUID_SIZE] =
|
||||
{0x9F, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x01, 0x00, 0x40, 0x6E};
|
||||
|
||||
// Characteristic rx uuid
|
||||
const uint8_t ble_uart_RxCharUUID[ATT_UUID_SIZE] =
|
||||
{0x9F, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x02, 0x00, 0x40, 0x6E};
|
||||
|
||||
// Characteristic tx uuid
|
||||
const uint8_t ble_uart_TxCharUUID[ATT_UUID_SIZE] =
|
||||
{0x9F, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x03, 0x00, 0x40, 0x6E};
|
||||
|
||||
/*********************************************************************
|
||||
* EXTERNAL VARIABLES
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* EXTERNAL FUNCTIONS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* LOCAL VARIABLES
|
||||
*/
|
||||
|
||||
static ble_uart_ProfileChangeCB_t ble_uart_AppCBs = NULL;
|
||||
|
||||
/*********************************************************************
|
||||
* Profile Attributes - variables
|
||||
*/
|
||||
|
||||
// Profile Service attribute
|
||||
static const gattAttrType_t ble_uart_Service = {ATT_UUID_SIZE, ble_uart_ServiceUUID};
|
||||
|
||||
// Profile Characteristic 1 Properties
|
||||
//static uint8_t ble_uart_RxCharProps = GATT_PROP_WRITE_NO_RSP| GATT_PROP_WRITE;
|
||||
static uint8_t ble_uart_RxCharProps = GATT_PROP_WRITE_NO_RSP;
|
||||
|
||||
// Characteristic 1 Value
|
||||
static uint8_t ble_uart_RxCharValue[BLE_UART_RX_BUFF_SIZE];
|
||||
//static uint8_t ble_uart_RxCharValue[1];
|
||||
|
||||
// Profile Characteristic 2 Properties
|
||||
//static uint8_t ble_uart_TxCharProps = GATT_PROP_NOTIFY| GATT_PROP_INDICATE;
|
||||
static uint8_t ble_uart_TxCharProps = GATT_PROP_NOTIFY;
|
||||
|
||||
// Characteristic 2 Value
|
||||
static uint8_t ble_uart_TxCharValue = 0;
|
||||
|
||||
// Simple Profile Characteristic 2 User Description
|
||||
static gattCharCfg_t ble_uart_TxCCCD[4];
|
||||
|
||||
/*********************************************************************
|
||||
* Profile Attributes - Table
|
||||
*/
|
||||
|
||||
static gattAttribute_t ble_uart_ProfileAttrTbl[] = {
|
||||
// Simple Profile Service
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, primaryServiceUUID}, /* type */
|
||||
GATT_PERMIT_READ, /* permissions */
|
||||
0, /* handle */
|
||||
(uint8_t *)&ble_uart_Service /* pValue */
|
||||
},
|
||||
|
||||
// Characteristic 1 Declaration
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, characterUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
&ble_uart_RxCharProps},
|
||||
|
||||
// Characteristic Value 1
|
||||
{
|
||||
{ATT_UUID_SIZE, ble_uart_RxCharUUID},
|
||||
GATT_PERMIT_WRITE,
|
||||
0,
|
||||
&ble_uart_RxCharValue[0]},
|
||||
|
||||
// Characteristic 2 Declaration
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, characterUUID},
|
||||
GATT_PERMIT_READ,
|
||||
0,
|
||||
&ble_uart_TxCharProps},
|
||||
|
||||
// Characteristic Value 2
|
||||
{
|
||||
{ATT_UUID_SIZE, ble_uart_TxCharUUID},
|
||||
0,
|
||||
0,
|
||||
(uint8_t *)&ble_uart_TxCharValue},
|
||||
|
||||
// Characteristic 2 User Description
|
||||
{
|
||||
{ATT_BT_UUID_SIZE, clientCharCfgUUID},
|
||||
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
|
||||
0,
|
||||
(uint8_t *)ble_uart_TxCCCD},
|
||||
|
||||
};
|
||||
|
||||
/*********************************************************************
|
||||
* LOCAL FUNCTIONS
|
||||
*/
|
||||
static bStatus_t ble_uart_ReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
|
||||
uint8_t *pValue, uint16_t *pLen, uint16_t offset, uint16_t maxLen, uint8_t method);
|
||||
static bStatus_t ble_uart_WriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
|
||||
uint8_t *pValue, uint16_t len, uint16_t offset, uint8_t method);
|
||||
|
||||
static void ble_uart_HandleConnStatusCB(uint16_t connHandle, uint8_t changeType);
|
||||
|
||||
/*********************************************************************
|
||||
* PROFILE CALLBACKS
|
||||
*/
|
||||
// Simple Profile Service Callbacks
|
||||
gattServiceCBs_t ble_uart_ProfileCBs = {
|
||||
ble_uart_ReadAttrCB, // Read callback function pointer
|
||||
ble_uart_WriteAttrCB, // Write callback function pointer
|
||||
NULL // Authorization callback function pointer
|
||||
};
|
||||
|
||||
/*********************************************************************
|
||||
* PUBLIC FUNCTIONS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* @fn ble_uart_AddService
|
||||
*
|
||||
* @brief Initializes the Simple Profile service by registering
|
||||
* GATT attributes with the GATT server.
|
||||
*
|
||||
* @param services - services to add. This is a bit map and can
|
||||
* contain more than one service.
|
||||
*
|
||||
* @return Success or Failure
|
||||
*/
|
||||
bStatus_t ble_uart_add_service(ble_uart_ProfileChangeCB_t cb)
|
||||
{
|
||||
uint8_t status = SUCCESS;
|
||||
|
||||
GATTServApp_InitCharCfg(INVALID_CONNHANDLE, ble_uart_TxCCCD);
|
||||
// Register with Link DB to receive link status change callback
|
||||
linkDB_Register(ble_uart_HandleConnStatusCB);
|
||||
|
||||
// ble_uart_TxCCCD.connHandle = INVALID_CONNHANDLE;
|
||||
// ble_uart_TxCCCD.value = 0;
|
||||
// Register GATT attribute list and CBs with GATT Server App
|
||||
status = GATTServApp_RegisterService(ble_uart_ProfileAttrTbl,
|
||||
GATT_NUM_ATTRS(ble_uart_ProfileAttrTbl),
|
||||
GATT_MAX_ENCRYPT_KEY_SIZE,
|
||||
&ble_uart_ProfileCBs);
|
||||
if(status != SUCCESS)
|
||||
PRINT("Add ble uart service failed!\n");
|
||||
ble_uart_AppCBs = cb;
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn ble_uart_ReadAttrCB
|
||||
*
|
||||
* @brief Read an attribute.
|
||||
*
|
||||
* @param connHandle - connection message was received on
|
||||
* @param pAttr - pointer to attribute
|
||||
* @param pValue - pointer to data to be read
|
||||
* @param pLen - length of data to be read
|
||||
* @param offset - offset of the first octet to be read
|
||||
* @param maxLen - maximum length of data to be read
|
||||
*
|
||||
* @return Success or Failure
|
||||
*/
|
||||
static bStatus_t ble_uart_ReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
|
||||
uint8_t *pValue, uint16_t *pLen, uint16_t offset, uint16_t maxLen, uint8_t method)
|
||||
{
|
||||
bStatus_t status = SUCCESS;
|
||||
PRINT("ReadAttrCB\n");
|
||||
// Make sure it's not a blob operation (no attributes in the profile are long)
|
||||
if(pAttr->type.len == ATT_BT_UUID_SIZE)
|
||||
{
|
||||
// 16-bit UUID
|
||||
uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
|
||||
if(uuid == GATT_CLIENT_CHAR_CFG_UUID)
|
||||
{
|
||||
*pLen = 2;
|
||||
tmos_memcpy(pValue, pAttr->pValue, 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tmos_memcmp(pAttr->type.uuid, ble_uart_TxCharUUID, 16))
|
||||
{
|
||||
*pLen = 1;
|
||||
pValue[0] = '1';
|
||||
}
|
||||
else if(tmos_memcmp(pAttr->type.uuid, ble_uart_RxCharUUID, 16))
|
||||
{
|
||||
PRINT("read tx char\n");
|
||||
}
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn simpleProfile_WriteAttrCB
|
||||
*
|
||||
* @brief Validate attribute data prior to a write operation
|
||||
*
|
||||
* @param connHandle - connection message was received on
|
||||
* @param pAttr - pointer to attribute
|
||||
* @param pValue - pointer to data to be written
|
||||
* @param len - length of data
|
||||
* @param offset - offset of the first octet to be written
|
||||
*
|
||||
* @return Success or Failure
|
||||
*/
|
||||
|
||||
static bStatus_t ble_uart_WriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
|
||||
uint8_t *pValue, uint16_t len, uint16_t offset, uint8_t method)
|
||||
{
|
||||
bStatus_t status = SUCCESS;
|
||||
//uint8_t notifyApp = 0xFF;
|
||||
// If attribute permissions require authorization to write, return error
|
||||
if(gattPermitAuthorWrite(pAttr->permissions))
|
||||
{
|
||||
// Insufficient authorization
|
||||
return (ATT_ERR_INSUFFICIENT_AUTHOR);
|
||||
}
|
||||
|
||||
if(pAttr->type.len == ATT_BT_UUID_SIZE)
|
||||
{
|
||||
// 16-bit UUID
|
||||
uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
|
||||
if(uuid == GATT_CLIENT_CHAR_CFG_UUID)
|
||||
{
|
||||
status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue, len,
|
||||
offset, GATT_CLIENT_CFG_NOTIFY);
|
||||
if(status == SUCCESS && ble_uart_AppCBs)
|
||||
{
|
||||
uint16_t charCfg = BUILD_UINT16(pValue[0], pValue[1]);
|
||||
ble_uart_evt_t evt;
|
||||
|
||||
//PRINT("CCCD set: [%d]\n", charCfg);
|
||||
evt.type = (charCfg == GATT_CFG_NO_OPERATION) ? BLE_UART_EVT_TX_NOTI_DISABLED : BLE_UART_EVT_TX_NOTI_ENABLED;
|
||||
ble_uart_AppCBs(connHandle, &evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 128-bit UUID
|
||||
if(pAttr->handle == ble_uart_ProfileAttrTbl[RAWPASS_RX_VALUE_HANDLE].handle)
|
||||
{
|
||||
if(ble_uart_AppCBs)
|
||||
{
|
||||
ble_uart_evt_t evt;
|
||||
evt.type = BLE_UART_EVT_BLE_DATA_RECIEVED;
|
||||
evt.data.length = (uint16_t)len;
|
||||
evt.data.p_data = pValue;
|
||||
ble_uart_AppCBs(connHandle, &evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (status);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn simpleProfile_HandleConnStatusCB
|
||||
*
|
||||
* @brief Simple Profile link status change handler function.
|
||||
*
|
||||
* @param connHandle - connection handle
|
||||
* @param changeType - type of change
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void ble_uart_HandleConnStatusCB(uint16_t connHandle, uint8_t changeType)
|
||||
{
|
||||
// Make sure this is not loopback connection
|
||||
if(connHandle != LOOPBACK_CONNHANDLE)
|
||||
{
|
||||
// Reset Client Char Config if connection has dropped
|
||||
if((changeType == LINKDB_STATUS_UPDATE_REMOVED) ||
|
||||
((changeType == LINKDB_STATUS_UPDATE_STATEFLAGS) &&
|
||||
(!linkDB_Up(connHandle))))
|
||||
{
|
||||
//ble_uart_TxCCCD[0].value = 0;
|
||||
GATTServApp_InitCharCfg(connHandle, ble_uart_TxCCCD);
|
||||
//PRINT("clear client configuration\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ble_uart_notify_is_ready(uint16_t connHandle)
|
||||
{
|
||||
return (GATT_CLIENT_CFG_NOTIFY == GATTServApp_ReadCharCfg(connHandle, ble_uart_TxCCCD));
|
||||
}
|
||||
/*********************************************************************
|
||||
* @fn BloodPressure_IMeasNotify
|
||||
*
|
||||
* @brief Send a notification containing a bloodPressure
|
||||
* measurement.
|
||||
*
|
||||
* @param connHandle - connection handle
|
||||
* @param pNoti - pointer to notification structure
|
||||
*
|
||||
* @return Success or Failure
|
||||
*/
|
||||
bStatus_t ble_uart_notify(uint16_t connHandle, attHandleValueNoti_t *pNoti, uint8_t taskId)
|
||||
{
|
||||
//uint16_t value = ble_uart_TxCCCD[0].value;
|
||||
uint16_t value = GATTServApp_ReadCharCfg(connHandle, ble_uart_TxCCCD);
|
||||
// If notifications enabled
|
||||
if(value & GATT_CLIENT_CFG_NOTIFY)
|
||||
{
|
||||
// Set the handle
|
||||
pNoti->handle = ble_uart_ProfileAttrTbl[RAWPASS_TX_VALUE_HANDLE].handle;
|
||||
|
||||
// Send the Indication
|
||||
return GATT_Notification(connHandle, pNoti, FALSE);
|
||||
}
|
||||
return bleIncorrectMode;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := peripheral_main.c peripheral.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
651
Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ble/test/peripheral.c
Executable file
651
Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ble/test/peripheral.c
Executable file
|
@ -0,0 +1,651 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : peripheral.C
|
||||
* Author : WCH
|
||||
* Version : v1.0
|
||||
* Date : 2020/11/26
|
||||
* Description :
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
#include "../inc/config.h"
|
||||
#include "../Profile/devinfoservice.h"
|
||||
#include "../Profile/gattprofile.h"
|
||||
#include "../inc/peripheral.h"
|
||||
#include "../inc/ble_uart_service.h"
|
||||
#include "../inc/app_drv_fifo.h"
|
||||
#include "../inc/app_uart.h"
|
||||
#include "xs_base.h"
|
||||
|
||||
/*********************************************************************
|
||||
* MACROS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* CONSTANTS
|
||||
*/
|
||||
|
||||
// How often to perform periodic event
|
||||
#define SBP_PERIODIC_EVT_PERIOD 1600
|
||||
|
||||
// How often to perform read rssi event
|
||||
#define SBP_READ_RSSI_EVT_PERIOD 3200
|
||||
|
||||
// Parameter update delay
|
||||
#define SBP_PARAM_UPDATE_DELAY 6400
|
||||
|
||||
// What is the advertising interval when device is discoverable (units of 625us, 80=50ms)
|
||||
#define DEFAULT_ADVERTISING_INTERVAL 160
|
||||
|
||||
// Limited discoverable mode advertises for 30.72s, and then stops
|
||||
// General discoverable mode advertises indefinitely
|
||||
#define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_GENERAL
|
||||
|
||||
// Minimum connection interval (units of 1.25ms, 10=12.5ms)
|
||||
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL 8
|
||||
|
||||
// Maximum connection interval (units of 1.25ms, 100=125ms)
|
||||
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 20
|
||||
|
||||
// Slave latency to use parameter update
|
||||
#define DEFAULT_DESIRED_SLAVE_LATENCY 0
|
||||
|
||||
// Supervision timeout value (units of 10ms, 100=1s)
|
||||
#define DEFAULT_DESIRED_CONN_TIMEOUT 100
|
||||
|
||||
// Company Identifier: WCH
|
||||
#define WCH_COMPANY_ID 0x07D7
|
||||
|
||||
/*********************************************************************
|
||||
* TYPEDEFS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*/
|
||||
|
||||
uint8_t Peripheral_TaskID = INVALID_TASK_ID; // Task ID for internal task/event processing
|
||||
|
||||
/*********************************************************************
|
||||
* EXTERNAL VARIABLES
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* EXTERNAL FUNCTIONS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* LOCAL VARIABLES
|
||||
*/
|
||||
|
||||
//for send to ble
|
||||
typedef enum
|
||||
{
|
||||
SEND_TO_BLE_TO_SEND = 1,
|
||||
SEND_TO_BLE_ALLOC_FAILED,
|
||||
SEND_TO_BLE_SEND_FAILED,
|
||||
} send_to_ble_state_t;
|
||||
send_to_ble_state_t send_to_ble_state = SEND_TO_BLE_TO_SEND;
|
||||
|
||||
blePaControlConfig_t pa_lna_ctl;
|
||||
|
||||
//static uint8_t Peripheral_TaskID = INVALID_TASK_ID; // Task ID for internal task/event processing
|
||||
|
||||
// GAP - SCAN RSP data (max size = 31 bytes)
|
||||
static uint8_t scanRspData[] = {
|
||||
// complete name
|
||||
13, // length of this data
|
||||
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
|
||||
'w', 'c', 'h', '_', 'b', 'l', 'e', '_', 'u', 'a', 'r', 't',
|
||||
// connection interval range
|
||||
0x05, // length of this data
|
||||
GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
|
||||
LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL), // 100ms
|
||||
HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
|
||||
LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL), // 1s
|
||||
HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
|
||||
|
||||
// Tx power level
|
||||
0x02, // length of this data
|
||||
GAP_ADTYPE_POWER_LEVEL,
|
||||
0 // 0dBm
|
||||
};
|
||||
|
||||
// GAP - Advertisement data (max size = 31 bytes, though this is
|
||||
// best kept short to conserve power while advertisting)
|
||||
static uint8_t advertData[] = {
|
||||
// Flags; this sets the device to use limited discoverable
|
||||
// mode (advertises for 30 seconds at a time) instead of general
|
||||
// discoverable mode (advertises indefinitely)
|
||||
0x02, // length of this data
|
||||
GAP_ADTYPE_FLAGS,
|
||||
DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
|
||||
|
||||
// service UUID, to notify central devices what services are included
|
||||
// in this peripheral
|
||||
0x03, // length of this data
|
||||
GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all
|
||||
LO_UINT16(SIMPLEPROFILE_SERV_UUID),
|
||||
HI_UINT16(SIMPLEPROFILE_SERV_UUID)};
|
||||
|
||||
// GAP GATT Attributes
|
||||
static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "ch32v208_ble_uart";
|
||||
|
||||
// Connection item list
|
||||
static peripheralConnItem_t peripheralConnList;
|
||||
|
||||
/*********************************************************************
|
||||
* LOCAL FUNCTIONS
|
||||
*/
|
||||
static void Peripheral_ProcessTMOSMsg(tmos_event_hdr_t *pMsg);
|
||||
static void peripheralStateNotificationCB(gapRole_States_t newState, gapRoleEvent_t *pEvent);
|
||||
|
||||
static void peripheralParamUpdateCB(uint16_t connHandle, uint16_t connInterval,
|
||||
uint16_t connSlaveLatency, uint16_t connTimeout);
|
||||
static void peripheralInitConnItem(peripheralConnItem_t *peripheralConnList);
|
||||
static void peripheralRssiCB(uint16_t connHandle, int8_t rssi);
|
||||
|
||||
/*********************************************************************
|
||||
* PROFILE CALLBACKS
|
||||
*/
|
||||
|
||||
// GAP Role Callbacks
|
||||
static gapRolesCBs_t Peripheral_PeripheralCBs = {
|
||||
peripheralStateNotificationCB, // Profile State Change Callbacks
|
||||
peripheralRssiCB, // When a valid RSSI is read from controller (not used by application)
|
||||
peripheralParamUpdateCB};
|
||||
|
||||
// Broadcast Callbacks
|
||||
static gapRolesBroadcasterCBs_t Broadcaster_BroadcasterCBs = {
|
||||
NULL, // Not used in peripheral role
|
||||
NULL // Receive scan request callback
|
||||
};
|
||||
|
||||
// GAP Bond Manager Callbacks
|
||||
static gapBondCBs_t Peripheral_BondMgrCBs = {
|
||||
NULL, // Passcode callback (not used by application)
|
||||
NULL // Pairing / Bonding state Callback (not used by application)
|
||||
};
|
||||
|
||||
extern uint8_t disconnectFlag;
|
||||
/*********************************************************************
|
||||
* PUBLIC FUNCTIONS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Peripheral_Init
|
||||
*
|
||||
* @brief Initialization function for the Peripheral App Task.
|
||||
* This is called during initialization and should contain
|
||||
* any application specific initialization (ie. hardware
|
||||
* initialization/setup, table initialization, power up
|
||||
* notificaiton ... ).
|
||||
*
|
||||
* @param task_id - the ID assigned by TMOS. This ID should be
|
||||
* used to send messages and set timers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void Peripheral_Init()
|
||||
{
|
||||
Peripheral_TaskID = TMOS_ProcessEventRegister(Peripheral_ProcessEvent);
|
||||
|
||||
// Setup the GAP Peripheral Role Profile
|
||||
{
|
||||
uint8_t initial_advertising_enable = TRUE;
|
||||
uint16_t desired_min_interval = 6;
|
||||
uint16_t desired_max_interval = 1000;
|
||||
|
||||
// Set the GAP Role Parameters
|
||||
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initial_advertising_enable);
|
||||
GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData), scanRspData);
|
||||
GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
|
||||
GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16_t), &desired_min_interval);
|
||||
GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16_t), &desired_max_interval);
|
||||
}
|
||||
|
||||
// Set advertising interval
|
||||
{
|
||||
uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;
|
||||
|
||||
GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, advInt);
|
||||
GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, advInt);
|
||||
}
|
||||
|
||||
// Setup the GAP Bond Manager
|
||||
{
|
||||
uint32_t passkey = 0; // passkey "000000"
|
||||
uint8_t pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
|
||||
uint8_t mitm = TRUE;
|
||||
uint8_t bonding = TRUE;
|
||||
uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
|
||||
GAPBondMgr_SetParameter(GAPBOND_PERI_DEFAULT_PASSCODE, sizeof(uint32_t), &passkey);
|
||||
GAPBondMgr_SetParameter(GAPBOND_PERI_PAIRING_MODE, sizeof(uint8_t), &pairMode);
|
||||
GAPBondMgr_SetParameter(GAPBOND_PERI_MITM_PROTECTION, sizeof(uint8_t), &mitm);
|
||||
GAPBondMgr_SetParameter(GAPBOND_PERI_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);
|
||||
GAPBondMgr_SetParameter(GAPBOND_PERI_BONDING_ENABLED, sizeof(uint8_t), &bonding);
|
||||
}
|
||||
|
||||
// Initialize GATT attributes
|
||||
GGS_AddService(GATT_ALL_SERVICES); // GAP
|
||||
GATTServApp_AddService(GATT_ALL_SERVICES); // GATT attributes
|
||||
DevInfo_AddService(); // Device Information Service
|
||||
ble_uart_add_service(on_bleuartServiceEvt);
|
||||
|
||||
// Set the GAP Characteristics
|
||||
GGS_SetParameter(GGS_DEVICE_NAME_ATT, sizeof(attDeviceName), attDeviceName);
|
||||
|
||||
// Init Connection Item
|
||||
peripheralInitConnItem(&peripheralConnList);
|
||||
|
||||
// Register receive scan request callback
|
||||
GAPRole_BroadcasterSetCB(&Broadcaster_BroadcasterCBs);
|
||||
|
||||
// Setup a delayed profile startup
|
||||
tmos_set_event(Peripheral_TaskID, SBP_START_DEVICE_EVT);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn peripheralInitConnItem
|
||||
*
|
||||
* @brief Init Connection Item
|
||||
*
|
||||
* @param peripheralConnList -
|
||||
*
|
||||
* @return NULL
|
||||
*/
|
||||
static void peripheralInitConnItem(peripheralConnItem_t *peripheralConnList)
|
||||
{
|
||||
peripheralConnList->connHandle = GAP_CONNHANDLE_INIT;
|
||||
peripheralConnList->connInterval = 0;
|
||||
peripheralConnList->connSlaveLatency = 0;
|
||||
peripheralConnList->connTimeout = 0;
|
||||
}
|
||||
|
||||
uint32_t get_fattime(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Peripheral_ProcessEvent
|
||||
*
|
||||
* @brief Peripheral Application Task event processor. This function
|
||||
* is called to process all events for the task. Events
|
||||
* include timers, messages and any other user defined events.
|
||||
*
|
||||
* @param task_id - The TMOS assigned task ID.
|
||||
* @param events - events to process. This is a bit map and can
|
||||
* contain more than one event.
|
||||
*
|
||||
* @return events not processed
|
||||
*/
|
||||
uint16_t Peripheral_ProcessEvent(uint8_t task_id, uint16_t events)
|
||||
{
|
||||
static attHandleValueNoti_t noti;
|
||||
// VOID task_id; // TMOS required parameter that isn't used in this function
|
||||
|
||||
if(events & SYS_EVENT_MSG)
|
||||
{
|
||||
uint8_t *pMsg;
|
||||
|
||||
if((pMsg = tmos_msg_receive(Peripheral_TaskID)) != NULL)
|
||||
{
|
||||
Peripheral_ProcessTMOSMsg((tmos_event_hdr_t *)pMsg);
|
||||
// Release the TMOS message
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
// return unprocessed events
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
|
||||
if(events & SBP_START_DEVICE_EVT)
|
||||
{
|
||||
// Start the Device
|
||||
GAPRole_PeripheralStartDevice(Peripheral_TaskID, &Peripheral_BondMgrCBs, &Peripheral_PeripheralCBs);
|
||||
return (events ^ SBP_START_DEVICE_EVT);
|
||||
}
|
||||
if(events & SBP_PARAM_UPDATE_EVT)
|
||||
{
|
||||
// Send connect param update request
|
||||
GAPRole_PeripheralConnParamUpdateReq(peripheralConnList.connHandle,
|
||||
DEFAULT_DESIRED_MIN_CONN_INTERVAL,
|
||||
DEFAULT_DESIRED_MAX_CONN_INTERVAL,
|
||||
DEFAULT_DESIRED_SLAVE_LATENCY,
|
||||
DEFAULT_DESIRED_CONN_TIMEOUT,
|
||||
Peripheral_TaskID);
|
||||
|
||||
// GAPRole_PeripheralConnParamUpdateReq( peripheralConnList.connHandle,
|
||||
// 10,
|
||||
// 20,
|
||||
// 0,
|
||||
// 400,
|
||||
// Peripheral_TaskID);
|
||||
|
||||
return (events ^ SBP_PARAM_UPDATE_EVT);
|
||||
}
|
||||
|
||||
if(events & UART_TO_BLE_SEND_EVT)
|
||||
{
|
||||
static uint16_t read_length = 0;
|
||||
;
|
||||
uint8_t result = 0xff;
|
||||
switch(send_to_ble_state)
|
||||
{
|
||||
case SEND_TO_BLE_TO_SEND:
|
||||
|
||||
//notify is not enabled
|
||||
if(!ble_uart_notify_is_ready(peripheralConnList.connHandle))
|
||||
{
|
||||
if(peripheralConnList.connHandle == GAP_CONNHANDLE_INIT)
|
||||
{
|
||||
//connection lost, flush rx fifo here
|
||||
app_drv_fifo_flush(&app_uart_rx_fifo);
|
||||
}
|
||||
break;
|
||||
}
|
||||
read_length = ATT_GetMTU(peripheralConnList.connHandle) - 3;
|
||||
|
||||
if(app_drv_fifo_length(&app_uart_rx_fifo) >= read_length)
|
||||
{
|
||||
KPrintf("FIFO_LEN:%d\r\n", app_drv_fifo_length(&app_uart_rx_fifo));
|
||||
result = app_drv_fifo_read(&app_uart_rx_fifo, to_test_buffer, &read_length);
|
||||
uart_to_ble_send_evt_cnt = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(uart_to_ble_send_evt_cnt > 10)
|
||||
{
|
||||
result = app_drv_fifo_read(&app_uart_rx_fifo, to_test_buffer, &read_length);
|
||||
uart_to_ble_send_evt_cnt = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmos_start_task(Peripheral_TaskID, UART_TO_BLE_SEND_EVT, 4);
|
||||
uart_to_ble_send_evt_cnt++;
|
||||
// KPrintf("NO TIME OUT\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
if(APP_DRV_FIFO_RESULT_SUCCESS == result)
|
||||
{
|
||||
noti.len = read_length;
|
||||
noti.pValue = GATT_bm_alloc(peripheralConnList.connHandle, ATT_HANDLE_VALUE_NOTI, noti.len, NULL, 0);
|
||||
if(noti.pValue != NULL)
|
||||
{
|
||||
tmos_memcpy(noti.pValue, to_test_buffer, noti.len);
|
||||
result = ble_uart_notify(peripheralConnList.connHandle, ¬i, 0);
|
||||
if(result != SUCCESS)
|
||||
{
|
||||
KPrintf("R1:%02x\r\n", result);
|
||||
send_to_ble_state = SEND_TO_BLE_SEND_FAILED;
|
||||
GATT_bm_free((gattMsg_t *)¬i, ATT_HANDLE_VALUE_NOTI);
|
||||
tmos_start_task(Peripheral_TaskID, UART_TO_BLE_SEND_EVT, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
send_to_ble_state = SEND_TO_BLE_TO_SEND;
|
||||
//app_fifo_write(&app_uart_tx_fifo,to_test_buffer,&read_length);
|
||||
//app_drv_fifo_write(&app_uart_tx_fifo,to_test_buffer,&read_length);
|
||||
read_length = 0;
|
||||
tmos_start_task(Peripheral_TaskID, UART_TO_BLE_SEND_EVT, 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
send_to_ble_state = SEND_TO_BLE_ALLOC_FAILED;
|
||||
tmos_start_task(Peripheral_TaskID, UART_TO_BLE_SEND_EVT, 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//send_to_ble_state = SEND_TO_BLE_FIFO_EMPTY;
|
||||
}
|
||||
break;
|
||||
case SEND_TO_BLE_ALLOC_FAILED:
|
||||
case SEND_TO_BLE_SEND_FAILED:
|
||||
|
||||
noti.len = read_length;
|
||||
noti.pValue = GATT_bm_alloc(peripheralConnList.connHandle, ATT_HANDLE_VALUE_NOTI, noti.len, NULL, 0);
|
||||
if(noti.pValue != NULL)
|
||||
{
|
||||
tmos_memcpy(noti.pValue, to_test_buffer, noti.len);
|
||||
result = ble_uart_notify(peripheralConnList.connHandle, ¬i, 0);
|
||||
if(result != SUCCESS)
|
||||
{
|
||||
KPrintf("R2:%02x\r\n", result);
|
||||
send_to_ble_state = SEND_TO_BLE_SEND_FAILED;
|
||||
GATT_bm_free((gattMsg_t *)¬i, ATT_HANDLE_VALUE_NOTI);
|
||||
tmos_start_task(Peripheral_TaskID, UART_TO_BLE_SEND_EVT, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
send_to_ble_state = SEND_TO_BLE_TO_SEND;
|
||||
//app_drv_fifo_write(&app_uart_tx_fifo,to_test_buffer,&read_length);
|
||||
read_length = 0;
|
||||
tmos_start_task(Peripheral_TaskID, UART_TO_BLE_SEND_EVT, 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
send_to_ble_state = SEND_TO_BLE_ALLOC_FAILED;
|
||||
tmos_start_task(Peripheral_TaskID, UART_TO_BLE_SEND_EVT, 2);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return (events ^ UART_TO_BLE_SEND_EVT);
|
||||
}
|
||||
// Discard unknown events
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Peripheral_ProcessTMOSMsg
|
||||
*
|
||||
* @brief Process an incoming task message.
|
||||
*
|
||||
* @param pMsg - message to process
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void Peripheral_ProcessTMOSMsg(tmos_event_hdr_t *pMsg)
|
||||
{
|
||||
switch(pMsg->event)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Peripheral_LinkEstablished
|
||||
*
|
||||
* @brief Process link established.
|
||||
*
|
||||
* @param pEvent - event to process
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void Peripheral_LinkEstablished(gapRoleEvent_t *pEvent)
|
||||
{
|
||||
gapEstLinkReqEvent_t *event = (gapEstLinkReqEvent_t *)pEvent;
|
||||
|
||||
// See if already connected
|
||||
if(peripheralConnList.connHandle != GAP_CONNHANDLE_INIT)
|
||||
{
|
||||
GAPRole_TerminateLink(pEvent->linkCmpl.connectionHandle);
|
||||
KPrintf("Connection max...\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
peripheralConnList.connHandle = event->connectionHandle;
|
||||
peripheralConnList.connInterval = event->connInterval;
|
||||
peripheralConnList.connSlaveLatency = event->connLatency;
|
||||
peripheralConnList.connTimeout = event->connTimeout;
|
||||
|
||||
// Set timer for param update event
|
||||
tmos_start_task(Peripheral_TaskID, SBP_PARAM_UPDATE_EVT, SBP_PARAM_UPDATE_DELAY);
|
||||
|
||||
KPrintf("Conn %x - Int %x \n", event->connectionHandle, event->connInterval);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Peripheral_LinkTerminated
|
||||
*
|
||||
* @brief Process link terminated.
|
||||
*
|
||||
* @param pEvent - event to process
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void Peripheral_LinkTerminated(gapRoleEvent_t *pEvent)
|
||||
{
|
||||
gapTerminateLinkEvent_t *event = (gapTerminateLinkEvent_t *)pEvent;
|
||||
|
||||
if(event->connectionHandle == peripheralConnList.connHandle)
|
||||
{
|
||||
peripheralConnList.connHandle = GAP_CONNHANDLE_INIT;
|
||||
peripheralConnList.connInterval = 0;
|
||||
peripheralConnList.connSlaveLatency = 0;
|
||||
peripheralConnList.connTimeout = 0;
|
||||
|
||||
// Restart advertising
|
||||
{
|
||||
uint8_t advertising_enable = TRUE;
|
||||
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advertising_enable);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
KPrintf("ERR..\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn peripheralRssiCB
|
||||
*
|
||||
* @brief RSSI callback.
|
||||
*
|
||||
* @param connHandle - connection handle
|
||||
* @param rssi - RSSI
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void peripheralRssiCB(uint16_t connHandle, int8_t rssi)
|
||||
{
|
||||
KPrintf("RSSI -%d dB Conn %x \n", -rssi, connHandle);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn peripheralParamUpdateCB
|
||||
*
|
||||
* @brief Parameter update complete callback
|
||||
*
|
||||
* @param connHandle - connect handle
|
||||
* connInterval - connect interval
|
||||
* connSlaveLatency - connect slave latency
|
||||
* connTimeout - connect timeout
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void peripheralParamUpdateCB(uint16_t connHandle, uint16_t connInterval,
|
||||
uint16_t connSlaveLatency, uint16_t connTimeout)
|
||||
{
|
||||
if(connHandle == peripheralConnList.connHandle)
|
||||
{
|
||||
peripheralConnList.connInterval = connInterval;
|
||||
peripheralConnList.connSlaveLatency = connSlaveLatency;
|
||||
peripheralConnList.connTimeout = connTimeout;
|
||||
|
||||
KPrintf("Update %x - Int %x \n", connHandle, connInterval);
|
||||
}
|
||||
else
|
||||
{
|
||||
KPrintf("peripheralParamUpdateCB err..\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn peripheralStateNotificationCB
|
||||
*
|
||||
* @brief Notification from the profile of a state change.
|
||||
*
|
||||
* @param newState - new state
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void peripheralStateNotificationCB(gapRole_States_t newState, gapRoleEvent_t *pEvent)
|
||||
{
|
||||
switch(newState & GAPROLE_STATE_ADV_MASK)
|
||||
{
|
||||
case GAPROLE_STARTED:
|
||||
KPrintf("Initialized..\n");
|
||||
break;
|
||||
|
||||
case GAPROLE_ADVERTISING:
|
||||
if(pEvent->gap.opcode == GAP_LINK_TERMINATED_EVENT)
|
||||
{
|
||||
Peripheral_LinkTerminated(pEvent);
|
||||
}
|
||||
KPrintf("Advertising..\n");
|
||||
break;
|
||||
|
||||
case GAPROLE_CONNECTED:
|
||||
if(pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT)
|
||||
{
|
||||
Peripheral_LinkEstablished(pEvent);
|
||||
KPrintf("Connected..\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case GAPROLE_CONNECTED_ADV:
|
||||
KPrintf("Connected Advertising..\n");
|
||||
break;
|
||||
|
||||
case GAPROLE_WAITING:
|
||||
if(pEvent->gap.opcode == GAP_END_DISCOVERABLE_DONE_EVENT)
|
||||
{
|
||||
KPrintf("Waiting for advertising..\n");
|
||||
}
|
||||
else if(pEvent->gap.opcode == GAP_LINK_TERMINATED_EVENT)
|
||||
{
|
||||
Peripheral_LinkTerminated(pEvent);
|
||||
disconnectFlag = 1;
|
||||
KPrintf("Disconnected.. Reason:%x\n", pEvent->linkTerminate.reason);
|
||||
}
|
||||
else if(pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT)
|
||||
{
|
||||
if(pEvent->gap.hdr.status != SUCCESS)
|
||||
{
|
||||
KPrintf("Waiting for advertising..\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
KPrintf("Error..\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
KPrintf("Error..%x\n", pEvent->gap.opcode);
|
||||
}
|
||||
break;
|
||||
|
||||
case GAPROLE_ERROR:
|
||||
KPrintf("Error..\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
|
@ -0,0 +1,73 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : main.c
|
||||
* Author : WCH
|
||||
* Version : V1.1
|
||||
* Date : 2020/08/06
|
||||
* Description : Peripheral slave application main function and task system initialization
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/* Header file contains */
|
||||
#include "../inc/config.h"
|
||||
#include "../inc/HAL.h"
|
||||
#include "../Profile/gattprofile.h"
|
||||
#include "../inc/peripheral.h"
|
||||
#include "../inc/app_uart.h"
|
||||
#include "shell.h"
|
||||
#include "xs_base.h"
|
||||
#include "debug.h"
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL TYPEDEFS
|
||||
*/
|
||||
__attribute__((aligned(4))) uint32_t MEM_BUF[BLE_MEMHEAP_SIZE / 4];
|
||||
|
||||
#if(defined(BLE_MAC)) && (BLE_MAC == TRUE)
|
||||
uint8_t const MacAddr[6] = {0x84, 0xC2, 0xE4, 0x03, 0x02, 0x02};
|
||||
#endif
|
||||
|
||||
uint8_t disconnectFlag = 1; // ble disconnect flag
|
||||
/*********************************************************************
|
||||
* @fn Main_Circulation
|
||||
*
|
||||
* @brief Main loop
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
__attribute__((section(".highcode")))
|
||||
__attribute__((noinline))
|
||||
void Main_Circulation(void)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
if (disconnectFlag) {
|
||||
break;
|
||||
}
|
||||
TMOS_SystemProcess();
|
||||
app_uart_process();
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : main
|
||||
* Description : Main function
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
int test_ble(int argc, char *argv[])
|
||||
{
|
||||
KPrintf("%s\n", VER_LIB);
|
||||
GAPRole_PeripheralInit();
|
||||
Peripheral_Init();
|
||||
KPrintf("BLE Peripheral Slave Init Success.\n");
|
||||
app_uart_init();
|
||||
disconnectFlag = 0; // reset disconnect flag
|
||||
Main_Circulation();
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
|
||||
test_ble, test_ble, test test_ble command);
|
|
@ -400,6 +400,7 @@ int ping(int argc, char *argv[]) {
|
|||
}
|
||||
WCHNET_SocketClose(SocketId, TCP_CLOSE_NORMAL);
|
||||
ICMPCnt = 0; // restore the original ICMPCnt
|
||||
return 0;
|
||||
}
|
||||
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,7 +3,7 @@ OBJS := $(shell cat make.obj)
|
|||
$(TARGET): $(OBJS)
|
||||
@echo ------------------------------------------------
|
||||
@echo link $(TARGET)
|
||||
@$(CROSS_COMPILE)g++ -o $@ $($(LINK_FLAGS)) $(OBJS) $(LINK_LWIP) $(LINK_MUSLLIB) $(LINK_MONGOOSE) $(LINK_WCH_NET) $(LIBCC)
|
||||
@$(CROSS_COMPILE)g++ -o $@ $($(LINK_FLAGS)) $(OBJS) $(LINK_LWIP) $(LINK_MUSLLIB) $(LINK_MONGOOSE) $(LINK_WCH_NET) $(LIBCC) $(LINK_WCH_BLE)
|
||||
@echo ------------------------------------------------
|
||||
@$(CROSS_COMPILE)objcopy -O binary $@ XiZi-$(BOARD)$(COMPILE_TYPE).bin
|
||||
@$(CROSS_COMPILE)objdump -S $@ > XiZi-$(BOARD)$(COMPILE_TYPE).asm
|
||||
|
|
Loading…
Reference in New Issue