diff --git a/arch/arm/include/phy62xx/armv6-m/irq.h b/arch/arm/include/phy62xx/armv6-m/irq.h new file mode 100755 index 00000000000..3e76f6a23c5 --- /dev/null +++ b/arch/arm/include/phy62xx/armv6-m/irq.h @@ -0,0 +1,371 @@ +/**************************************************************************** + * arch/arm/include/armv6-m/irq.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* This file should never be included directly but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_ARMV6_M_IRQ_H +#define __ARCH_ARM_INCLUDE_ARMV6_M_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#ifndef __ASSEMBLY__ +# include +# include +#endif + +#include + +/**************************************************************************** + * Pre-processor Prototypes + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* If this is a kernel build, + * how many nested system calls should we support? + */ + +#ifndef CONFIG_SYS_NNEST +# define CONFIG_SYS_NNEST 2 +#endif + +/* IRQ Stack Frame Format *************************************************** + * + * The following additional registers are stored by the interrupt handling + * logic. + */ + +#define REG_R13 (0) /* R13 = SP at time of interrupt */ +#define REG_PRIMASK (1) /* PRIMASK */ +#define REG_R4 (2) /* R4 */ +#define REG_R5 (3) /* R5 */ +#define REG_R6 (4) /* R6 */ +#define REG_R7 (5) /* R7 */ +#define REG_R8 (6) /* R8 */ +#define REG_R9 (7) /* R9 */ +#define REG_R10 (8) /* R10 */ +#define REG_R11 (9) /* R11 */ + +/* In the kernel build, we may return to either privileged or unprivileged + * modes. + */ + +#ifdef CONFIG_BUILD_PROTECTED +# define REG_EXC_RETURN (10) /* EXC_RETURN */ +# define SW_XCPT_REGS (11) +#else +# define SW_XCPT_REGS (10) +#endif + +/* The total number of registers saved by software */ + +#define SW_XCPT_SIZE (4 * SW_XCPT_REGS) + +/* On entry into an IRQ, the hardware automatically saves the following + * registers on the stack in this (address) order: + */ +#define REG_DUMMY0 (SW_XCPT_REGS+0) /* DUMMY */ +#define REG_DUMMY1 (SW_XCPT_REGS+1) /* DUMMY */ +#define REG_R0 (SW_XCPT_REGS+0+2) /* R0 */ +#define REG_R1 (SW_XCPT_REGS+1+2) /* R1 */ +#define REG_R2 (SW_XCPT_REGS+2+2) /* R2 */ +#define REG_R3 (SW_XCPT_REGS+3+2) /* R3 */ +#define REG_R12 (SW_XCPT_REGS+4+2) /* R12 */ +#define REG_R14 (SW_XCPT_REGS+5+2) /* R14 = LR */ +#define REG_R15 (SW_XCPT_REGS+6+2) /* R15 = PC */ +#define REG_XPSR (SW_XCPT_REGS+7+2) /* xPSR */ + +#define HW_XCPT_REGS (10) +#define HW_XCPT_SIZE (4 * HW_XCPT_REGS) + +#define XCPTCONTEXT_REGS (HW_XCPT_REGS + SW_XCPT_REGS) +#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS) + +/* Alternate register names */ + +#define REG_A1 REG_R0 +#define REG_A2 REG_R1 +#define REG_A3 REG_R2 +#define REG_A4 REG_R3 +#define REG_V1 REG_R4 +#define REG_V2 REG_R5 +#define REG_V3 REG_R6 +#define REG_V4 REG_R7 +#define REG_V5 REG_R8 +#define REG_V6 REG_R9 +#define REG_V7 REG_R10 +#define REG_SB REG_R9 +#define REG_SL REG_R10 +#define REG_FP REG_R7 +#define REG_IP REG_R12 +#define REG_SP REG_R13 +#define REG_LR REG_R14 +#define REG_PC REG_R15 + +/* The PIC register is usually R10. It can be R9 is stack checking is enabled + * or if the user changes it with -mpic-register on the GCC command line. + */ + +#define REG_PIC REG_R10 + +/* CONTROL register */ + +#define CONTROL_FPCA (1 << 2) /* Bit 2: Floating-point context active */ +#define CONTROL_SPSEL (1 << 1) /* Bit 1: Stack-pointer select */ +#define CONTROL_NPRIV (1 << 0) /* Bit 0: Not privileged */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* This structure represents the return state from a system call */ + +#ifdef CONFIG_LIB_SYSCALL +struct xcpt_syscall_s +{ + uint32_t excreturn; /* The EXC_RETURN value */ + uint32_t sysreturn; /* The return PC */ +}; +#endif + +/* The following structure is included in the TCB and defines the complete + * state of the thread. + */ + +struct xcptcontext +{ + /* The following function pointer is non-zero if there + * are pending signals to be processed. + */ + + void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* These are saved copies of LR, PRIMASK, and xPSR used during + * signal processing. + * + * REVISIT: Because there is only one copy of these save areas, + * only a single signal handler can be active. This precludes + * queuing of signal actions. As a result, signals received while + * another signal handler is executing will be ignored! + */ + + uint32_t saved_pc; + uint32_t saved_primask; + uint32_t saved_xpsr; +#ifdef CONFIG_BUILD_PROTECTED + uint32_t saved_lr; + + /* This is the saved address to use when returning from a user-space + * signal handler. + */ + + uint32_t sigreturn; +#endif + +#ifdef CONFIG_LIB_SYSCALL + /* The following array holds the return address and the exc_return value + * needed to return from each nested system call. + */ + + uint8_t nsyscalls; + struct xcpt_syscall_s syscall[CONFIG_SYS_NNEST]; +#endif + + /* Register save area */ + + uint32_t regs[XCPTCONTEXT_REGS]; +}; +#endif + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Name: up_irq_save, up_irq_restore, and friends. + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() and + * leave_critical section(), are probably what you really want. + */ + +/* Get/set the PRIMASK register */ + +static inline uint8_t getprimask(void) inline_function; +static inline uint8_t getprimask(void) +{ + uint32_t primask; + __asm__ __volatile__ + ( + "\tmrs %0, primask\n" + : "=r" (primask) + : + : "memory"); + + return (uint8_t)primask; +} + +static inline void setprimask(uint32_t primask) inline_function; +static inline void setprimask(uint32_t primask) +{ + __asm__ __volatile__ + ( + "\tmsr primask, %0\n" + : + : "r" (primask) + : "memory"); +} + +/* Disable IRQs */ + +static inline void up_irq_disable(void) inline_function; +static inline void up_irq_disable(void) +{ + __asm__ __volatile__ ("\tcpsid i\n"); +} + +/* Save the current primask state & disable IRQs */ + +static inline irqstate_t up_irq_save(void) inline_function; +static inline irqstate_t up_irq_save(void) +{ + unsigned short primask; + + /* Return the current value of primask register and set + * bit 0 of the primask register to disable interrupts + */ + + __asm__ __volatile__ + ( + "\tmrs %0, primask\n" + "\tcpsid i\n" + : "=r" (primask) + : + : "memory"); + + return primask; +} + +/* Enable IRQs */ + +static inline void up_irq_enable(void) inline_function; +static inline void up_irq_enable(void) +{ + __asm__ __volatile__ ("\tcpsie i\n"); +} + +/* Restore saved primask state */ + +static inline void up_irq_restore(irqstate_t flags) inline_function; +static inline void up_irq_restore(irqstate_t flags) +{ + /* If bit 0 of the primask is 0, then we need to restore + * interrupts. + */ + + __asm__ __volatile__ + ( + "\tmsr primask, %0\n" + : + : "r" (flags) + : "memory"); +} + +/* Get/set IPSR */ + +static inline uint32_t getipsr(void) inline_function; +static inline uint32_t getipsr(void) +{ + uint32_t ipsr; + __asm__ __volatile__ + ( + "\tmrs %0, ipsr\n" + : "=r" (ipsr) + : + : "memory"); + + return ipsr; +} + +/* Get/set CONTROL */ + +static inline uint32_t getcontrol(void) inline_function; +static inline uint32_t getcontrol(void) +{ + uint32_t control; + __asm__ __volatile__ + ( + "\tmrs %0, control\n" + : "=r" (control) + : + : "memory"); + + return control; +} + +static inline void setcontrol(uint32_t control) inline_function; +static inline void setcontrol(uint32_t control) +{ + __asm__ __volatile__ + ( + "\tmsr control, %0\n" + : + : "r" (control) + : "memory"); +} + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_ARMV6_M_IRQ_H */ diff --git a/arch/arm/include/phy62xx/chip.h b/arch/arm/include/phy62xx/chip.h new file mode 100644 index 00000000000..5fc8abc2fc3 --- /dev/null +++ b/arch/arm/include/phy62xx/chip.h @@ -0,0 +1,40 @@ +/**************************************************************************** + * arch/arm/include/phy62xx/chip.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_INCLUDE_PHY62XX_CHIP_H +#define __ARCH_ARM_INCLUDE_PHY62XX_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Prototypes + ****************************************************************************/ +#define NVIC_SYSH_PRIORITY_MIN 0xc0 /* All bits[7:6] set is minimum priority */ +#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */ +#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */ +#define NVIC_SYSH_PRIORITY_STEP 0x40 /* Two bits of interrupt priority used */ + +/* Get customizations for each supported chip */ + +#endif /* __ARCH_ARM_INCLUDE_STM32F0L0G0_CHIP_H */ diff --git a/arch/arm/include/phy62xx/irq.h b/arch/arm/include/phy62xx/irq.h new file mode 100644 index 00000000000..8835115bff7 --- /dev/null +++ b/arch/arm/include/phy62xx/irq.h @@ -0,0 +1,107 @@ +/**************************************************************************** + * arch/arm/include/phy62xx/irq.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* This file should never be included directly but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_PHY62XX_IRQ_H +#define __ARCH_ARM_INCLUDE_PHY62XX_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ +# include + +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Prototypes + ****************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map + * directly to bits in the NVIC. This does, however, waste several words of + * memory in the IRQ to handle mapping tables. + */ + +/* Common Processor Exceptions (vectors 0-15) */ + +#define PHY62XX_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG_FEATURES) */ + + /* Vector 0: Reset stack pointer value */ + + /* Vector 1: Reset (not handler as an IRQ) */ + +#define PHY62XX_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */ +#define PHY62XX_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */ + + /* Vectors 4-10: Reserved */ + +#define PHY62XX_IRQ_SVCALL (11) /* Vector 11: SVC call */ + + /* Vector 12-13: Reserved */ + +#define PHY62XX_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */ +#define PHY62XX_IRQ_SYSTICK (15) /* Vector 15: System tick */ + +/* External interrupts (vectors >= 16) */ + +#define PHY62XX_IRQ_EXTINT (16) /* Vector number of the first external interrupt */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* Include MCU-specific external interrupt definitions */ + +#define NR_IRQS (PHY62XX_IRQ_EXTINT + PHY62XX_IRQ_NEXTINT) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +typedef void (*vic_vector_t)(uint32_t *regs); + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_INCLUDE_STM32F0L0G0_IRQ_H */ diff --git a/arch/arm/include/phy62xx/phy62xx_irq.h b/arch/arm/include/phy62xx/phy62xx_irq.h new file mode 100644 index 00000000000..12d03949938 --- /dev/null +++ b/arch/arm/include/phy62xx/phy62xx_irq.h @@ -0,0 +1,104 @@ +/**************************************************************************** + * arch/arm/include/phy62xx/phy62xx_irq.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* This file should never be included directly but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_STM32F0L0G0_STM32F0_IRQ_H +#define __ARCH_ARM_INCLUDE_STM32F0L0G0_STM32F0_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Prototypes + ****************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map + * directly to bits in the NVIC. This does, however, waste several words of + * memory in the IRQ to handle mapping tables. + * + * Processor Exceptions (vectors 0-15). These common definitions can be + * found in nuttx/arch/arm/include/stm32f0l0g0/irq.h + */ + +#define PHY62XX_IRQ_BB_IRQn (PHY62XX_IRQ_EXTINT + 4) /* 4: RCC and CRS */ +#define PHY62XX_IRQ_KSCAN_IRQn (PHY62XX_IRQ_EXTINT + 5) /* 5: EXTI0_1 */ +#define PHY62XX_IRQ_RTC_IRQn (PHY62XX_IRQ_EXTINT + 6) /* 6: EXTI2_3 */ +#define PHY62XX_IRQ_WDT_IRQn (PHY62XX_IRQ_EXTINT + 10) /* 10: DMA2_CH2 */ +#define PHY62XX_IRQ_UART0_IRQn (PHY62XX_IRQ_EXTINT + 11) /* 11: DMA1_CH4 */ +#define PHY62XX_IRQ_I2C0_IRQn (PHY62XX_IRQ_EXTINT + 12) /* 12: ADC */ +#define PHY62XX_IRQ_I2C1_IRQn (PHY62XX_IRQ_EXTINT + 13) /* 13: TIM1_BRK_UP_TRG_COM */ +#define PHY62XX_IRQ_SPI0_IRQn (PHY62XX_IRQ_EXTINT + 14) /* 14: TIM1_CC */ +#define PHY62XX_IRQ_SPI1_IRQn (PHY62XX_IRQ_EXTINT + 15) /* 15: TIM2 */ +#define PHY62XX_IRQ_GPIO_IRQn (PHY62XX_IRQ_EXTINT + 16) /* 16: TIM3 */ +#define PHY62XX_IRQ_UART1_IRQn (PHY62XX_IRQ_EXTINT + 17) /* 17: TIM6 */ +#define PHY62XX_IRQ_SPIF_IRQn (PHY62XX_IRQ_EXTINT + 18) /* 17: DAC */ +#define PHY62XX_IRQ_DMAC_IRQn (PHY62XX_IRQ_EXTINT + 19) /* 18: TIM7 */ +#define PHY62XX_IRQ_TIM1_IRQn (PHY62XX_IRQ_EXTINT + 20) /* 20: TIM15 */ +#define PHY62XX_IRQ_TIM2_IRQn (PHY62XX_IRQ_EXTINT + 21) /* 21: TIM16 */ +#define PHY62XX_IRQ_TIM3_IRQn (PHY62XX_IRQ_EXTINT + 22) /* 22: TIM17 */ +#define PHY62XX_IRQ_TIM4_IRQn (PHY62XX_IRQ_EXTINT + 23) /* 23: I2C1 */ +#define PHY62XX_IRQ_TIM5_IRQn (PHY62XX_IRQ_EXTINT + 24) /* 24: I2C2 */ +#define PHY62XX_IRQ_TIM6_IRQn (PHY62XX_IRQ_EXTINT + 25) /* 25: SPI1 */ + +#define PHY62XX_IRQ_AES_IRQn (PHY62XX_IRQ_EXTINT + 28) /* 28: USART2 */ +#define PHY62XX_IRQ_ADCC_IRQn (PHY62XX_IRQ_EXTINT + 29) /* 29: USART3 */ +#define PHY62XX_IRQ_QDEC_IRQn (PHY62XX_IRQ_EXTINT + 30) /* 30: HDMI CAN */ +#define PHY62XX_IRQ_RNG_IRQn (PHY62XX_IRQ_EXTINT + 31) /* 31: USB */ + +#define PHY62XX_IRQ_NEXTINT (32) /* 32 external interrupts */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +typedef void (*vic_vector_t)(uint32_t *regs); + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_INCLUDE_STM32F0L0G0_STM32F0_IRQ_H */ diff --git a/arch/arm/src/phy62xx/Kconfig b/arch/arm/src/phy62xx/Kconfig new file mode 100644 index 00000000000..b2cc7181d2c --- /dev/null +++ b/arch/arm/src/phy62xx/Kconfig @@ -0,0 +1,27 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "PHY62xx Configuration Options" + +choice + prompt "only PHY 6222 Chip Selection" + default ARCH_CHIP_PHY6222 + depends on ARCH_CHIP_PHY62XX + +config ARCH_CHIP_PHY6222 + bool "PHY6222" +endchoise + +config PHY6222_BLE + bool "enable ble" + default n + +config PHYPLUS_STUB + bool "enable phyplus stub" + default y + +#config PHYPLUS_DOWNLOAD +# bool "enable phyplus ble lib file download from server" +# default n diff --git a/arch/arm/src/phy62xx/Make.defs b/arch/arm/src/phy62xx/Make.defs new file mode 100644 index 00000000000..b2410740e7a --- /dev/null +++ b/arch/arm/src/phy62xx/Make.defs @@ -0,0 +1,112 @@ +############################################################################ +# arch/arm/src/phy62xx/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + + +CMN_ASRCS = phy62xx_exception.S phy62xx_start.S arm_saveusercontext.S arm_fullcontextrestore.S +CMN_ASRCS += arm_switchcontext.S vfork.S + +CMN_CSRCS = arm_allocateheap.c arm_assert.c arm_blocktask.c arm_copyfullstate.c +CMN_CSRCS += arm_createstack.c arm_mdelay.c arm_udelay.c arm_exit.c +CMN_CSRCS += arm_initialize.c arm_initialstate.c arm_interruptcontext.c +CMN_CSRCS += arm_puts.c arm_modifyreg8.c arm_modifyreg16.c arm_modifyreg32.c +CMN_CSRCS += arm_releasepending.c arm_releasestack.c arm_reprioritizertr.c +CMN_CSRCS += arm_schedulesigaction.c arm_sigdeliver.c arm_stackframe.c +CMN_CSRCS += arm_systemreset.c arm_unblocktask.c arm_usestack.c arm_doirq.c +#CMN_CSRCS += arm_hardfault.c arm_svcall.c arm_vectors.c arm_vfork.c +CMN_CSRCS += phy62xx_hardfault.c arm_svcall.c arm_vectors.c arm_vfork.c +#CMN_CSRCS += arm_etherstub.c + +ifeq ($(CONFIG_BUILD_PROTECTED),y) +CMN_CSRCS += arm_task_start.c arm_pthread_start.c +CMN_CSRCS += arm_pthread_exit.c +CMN_CSRCS += arm_signal_dispatch.c +CMN_UASRCS += arm_signal_handler.S +endif + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += arm_checkstack.c +endif + +ifeq ($(CONFIG_DEBUG_FEATURES),y) +CMN_CSRCS += arm_dumpnvic.c +endif + +CHIP_CSRCS = start.c gpio.c irq.c timer.c clock.c uart.c pwrmgr.c idle.c my_printf.c flash.c +CHIP_CSRCS += jump_table.c +CHIP_CSRCS += pplus_mtd_flash.c +ifeq ($(CONFIG_PHY6222_BLE),y) +#CHIP_CSRCS += phy62xx_ble.c phy62xx_ble_hcitl.c +#CHIP_CSRCS += phy62xx_ble_patch.c phy62xx_ble_hci_event_patch.c rf_phy_driver.c +CHIP_CSRCS += phy62xx_ble.c phy62xx_ble_patch.c rf_phy_driver.c +endif + +ifeq ($(CONFIG_TIMER),y) +CHIP_CSRCS += phyplus_tim.c +CHIP_CSRCS += phyplus_timer_lowerhalf.c +CHIP_CSRCS += phyplus_timerisr.c +endif + +ifeq ($(CONFIG_DEV_GPIO),y) +CHIP_CSRCS += phyplus_gpio.c +endif + +ifeq ($(CONFIG_PHYPLUS_STUB),y) +CHIP_CSRCS += phyplus_stub.c +endif + +INCLUDES += $(shell $(INCDIR) "$(CC)" $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)include) +INCLUDES += $(shell $(INCDIR) "$(CC)" $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)ble$(DELIM)controller) +INCLUDES += $(shell $(INCDIR) "$(CC)" $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)ble$(DELIM)hci) +INCLUDES += $(shell $(INCDIR) "$(CC)" $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)ble$(DELIM)include) +INCLUDES += $(shell $(INCDIR) "$(CC)" $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)osal$(DELIM)include) + + +CFLAGS += -ffunction-sections +CFLAGS += -DCFG_CP +CFLAGS += -DPHY_MCU_TYPE=MCU_BUMBEE_M0 +CFLAGS += -DHOST_CONFIG=4 +CFLAGS += -DHCI_TL_NONE=1 +CFLAGS += -DMTU_SIZE=247 +CFLAGS += -DENABLE_LOG_ROMx=0 +CFLAGS += -DPHY_MCU_TYPE=MCU_BUMBEE_M0 +CFLAGS += -DCFG_SLEEP_MODE=PWR_MODE_NO_SLEEP +CFLAGS += -DDEBUG_INFO=1 +CFLAGS += -DUSE_SYS_TICK +CFLAGS += -DHUGE_MODE=0 +CFLAGS += -DMAX_NUM_LL_CONN=1 +CFLAGS += -DUSE_ROMSYM_ALIAS +#LDFLAGS += "$(ARCH_SRCDIR)$(DELIM)board$(DELIM)bb_rom_sym_m0.gdbsym" +LDFLAGS += "$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)bb_rom_sym_m0.gdbsym" +LDFLAGS += -Wl,-Map="../../../phyplus_build.map" +LDFLAGS += -Wl,--gc-sections + +.buildlib: + $(Q) if [ -d ../../../../../phy62xxble ]; then \ + echo "##############build lib internally##############"; \ + make -C ../../../../../phy62xxble; \ + else \ + echo "############download lib form server############"; \ + curl -L -o libphy62xxble.a http://www.phyplusinc.com/phyplus/libphy62xxble.a; \ + cp -a libphy62xxble.a ../../../staging; \ + fi + +context:: .buildlib + + diff --git a/arch/arm/src/phy62xx/bb_rom_sym_m0.gdbsym b/arch/arm/src/phy62xx/bb_rom_sym_m0.gdbsym new file mode 100644 index 00000000000..d6da1dfe3da --- /dev/null +++ b/arch/arm/src/phy62xx/bb_rom_sym_m0.gdbsym @@ -0,0 +1,988 @@ +_symrom_bx_to_application = 0x000000d5; +_symrom_memset = 0x00000eb7; +_symrom_strlen = 0x00000ec9; +_symrom_strcmp = 0x00000ed7; +_symrom_memcmp = 0x00000ef3; +_symrom_strncmp = 0x00000f0d; +_symrom_strtok = 0x00000f2d; +_symrom_strtoul = 0x00000f89; +_symrom__strtoul = 0x00001009; +_symrom_GPIO_IRQHandler = 0x0000112d; +_symrom_HCI_CommandCompleteEvent = 0x00001175; +_symrom_HCI_CommandStatusEvent = 0x000011fd; +_symrom_HCI_DataBufferOverflowEvent = 0x00001251; +_symrom_HCI_DisconnectCmd = 0x0000128d; +_symrom_HCI_EXT_AdvEventNoticeCmd = 0x000012a1; +_symrom_HCI_EXT_BuildRevisionCmd = 0x000012a9; +_symrom_HCI_EXT_ClkDivOnHaltCmd = 0x000012e5; +_symrom_HCI_EXT_ConnEventNoticeCmd = 0x0000130d; +_symrom_HCI_EXT_DeclareNvUsageCmd = 0x00001315; +_symrom_HCI_EXT_DecryptCmd = 0x00001339; +_symrom_HCI_EXT_DelaySleepCmd = 0x0000137d; +_symrom_HCI_EXT_DisconnectImmedCmd = 0x000013a5; +_symrom_HCI_EXT_EnablePTMCmd = 0x000013cd; +_symrom_HCI_EXT_EndModemTestCmd = 0x000013e1; +_symrom_HCI_EXT_HaltDuringRfCmd = 0x00001409; +_symrom_HCI_EXT_ModemHopTestTxCmd = 0x00001431; +_symrom_HCI_EXT_ModemTestRxCmd = 0x00001459; +_symrom_HCI_EXT_ModemTestTxCmd = 0x00001481; +_symrom_HCI_EXT_NumComplPktsLimitCmd = 0x000014a5; +_symrom_HCI_EXT_OnePktPerEvtCmd = 0x000014c9; +_symrom_HCI_EXT_OverlappedProcessingCmd = 0x000014f5; +_symrom_HCI_EXT_PERbyChanCmd = 0x0000151d; +_symrom_HCI_EXT_PacketErrorRateCmd = 0x00001541; +_symrom_HCI_EXT_ResetSystemCmd = 0x00001575; +_symrom_HCI_EXT_SaveFreqTuneCmd = 0x0000159d; +_symrom_HCI_EXT_SetBDADDRCmd = 0x000015c5; +_symrom_HCI_EXT_SetFastTxResponseTimeCmd = 0x00001601; +_symrom_HCI_EXT_SetFreqTuneCmd = 0x00001629; +_symrom_HCI_EXT_SetLocalSupportedFeaturesCmd = 0x00001651; +_symrom_HCI_EXT_SetMaxDtmTxPowerCmd = 0x00001679; +_symrom_HCI_EXT_SetRxGainCmd = 0x000016a1; +_symrom_HCI_EXT_SetSCACmd = 0x000016d1; +_symrom_HCI_EXT_SetSlaveLatencyOverrideCmd = 0x000016f9; +_symrom_HCI_EXT_SetTxPowerCmd = 0x00001721; +_symrom_HCI_ExtTaskRegister = 0x00001751; +_symrom_HCI_GAPTaskRegister = 0x0000175d; +_symrom_HCI_HardwareErrorEvent = 0x00001769; +_symrom_HCI_HostBufferSizeCmd = 0x000017b1; +_symrom_HCI_HostNumCompletedPktCmd = 0x000017e1; +_symrom_HCI_Init = 0x0000183d; +_symrom_HCI_L2CAPTaskRegister = 0x00001879; +_symrom_HCI_LE_AddDevToPeriodicAdvListCmd = 0x00001885; +_symrom_HCI_LE_AddDevToResolvingListCmd = 0x000018a1; +_symrom_HCI_LE_AddWhiteListCmd = 0x000018bd; +_symrom_HCI_LE_ClearAdvSetsCmd = 0x000018e1; +_symrom_HCI_LE_ClearPeriodicAdvListCmd = 0x000018fd; +_symrom_HCI_LE_ClearResolvingListCmd = 0x00001919; +_symrom_HCI_LE_ClearWhiteListCmd = 0x00001935; +_symrom_HCI_LE_ConnUpdateCmd = 0x00001951; +_symrom_HCI_LE_Connection_CTE_Request_EnableCmd = 0x0000196d; +_symrom_HCI_LE_Connection_CTE_Response_EnableCmd = 0x00001999; +_symrom_HCI_LE_ConnectionlessCTE_TransmitEnableCmd = 0x000019c1; +_symrom_HCI_LE_ConnectionlessCTE_TransmitParamCmd = 0x000019dd; +_symrom_HCI_LE_ConnectionlessIQ_SampleEnableCmd = 0x00001a01; +_symrom_HCI_LE_CreateConnCancelCmd = 0x00001a31; +_symrom_HCI_LE_CreateConnCmd = 0x00001a4d; +_symrom_HCI_LE_EncryptCmd = 0x00001a89; +_symrom_HCI_LE_ExtendedCreateConnectionCmd = 0x00001ac1; +_symrom_HCI_LE_LtkReqNegReplyCmd = 0x00001b09; +_symrom_HCI_LE_LtkReqReplyCmd = 0x00001b31; +_symrom_HCI_LE_PeriodicAdvertisingCreateSyncCancelCmd = 0x00001b59; +_symrom_HCI_LE_PeriodicAdvertisingCreateSyncCmd = 0x00001b75; +_symrom_HCI_LE_PeriodicAdvertisingTerminateSyncCmd = 0x00001b9d; +_symrom_HCI_LE_READ_Anatenna_InfoCmd = 0x00001bb9; +_symrom_HCI_LE_RandCmd = 0x00001bd9; +_symrom_HCI_LE_ReadAdvChanTxPowerCmd = 0x00001c09; +_symrom_HCI_LE_ReadBufSizeCmd = 0x00001c29; +_symrom_HCI_LE_ReadChannelMapCmd = 0x00001c4d; +_symrom_HCI_LE_ReadLocalSupportedFeaturesCmd = 0x00001c99; +_symrom_HCI_LE_ReadMaxDataLengthCmd = 0x00001cb9; +_symrom_HCI_LE_ReadMaximumAdvDataLengthCmd = 0x00001ce9; +_symrom_HCI_LE_ReadNumberOfSupportAdvSetCmd = 0x00001d11; +_symrom_HCI_LE_ReadPeerResolvableAddressCmd = 0x00001d31; +_symrom_HCI_LE_ReadPeriodicAdvListSizeCmd = 0x00001d51; +_symrom_HCI_LE_ReadPhyMode = 0x00001d71; +_symrom_HCI_LE_ReadRemoteUsedFeaturesCmd = 0x00001db1; +_symrom_HCI_LE_ReadResolvingListSizeCmd = 0x00001dc5; +_symrom_HCI_LE_ReadSuggestedDefaultDataLengthCmd = 0x00001de5; +_symrom_HCI_LE_ReadSupportedStatesCmd = 0x00001e15; +_symrom_HCI_LE_ReadWhiteListSizeCmd = 0x00001e3d; +_symrom_HCI_LE_Read_Rf_Path_CompensationCmd = 0x00001e5d; +_symrom_HCI_LE_Read_Transmit_PowerCmd = 0x00001e7d; +_symrom_HCI_LE_ReceiverTestCmd = 0x00001e9d; +_symrom_HCI_LE_RemoveAdvSetCmd = 0x00001eb1; +_symrom_HCI_LE_RemovePeriodicAdvListCmd = 0x00001ecd; +_symrom_HCI_LE_RemoveResolvingListCmd = 0x00001ee9; +_symrom_HCI_LE_RemoveWhiteListCmd = 0x00001f0d; +_symrom_HCI_LE_SetAddressResolutionEnableCmd = 0x00001f31; +_symrom_HCI_LE_SetAdvDataCmd = 0x00001f4d; +_symrom_HCI_LE_SetAdvEnableCmd = 0x00001f69; +_symrom_HCI_LE_SetAdvParamCmd = 0x00001f85; +_symrom_HCI_LE_SetDataLengthCmd = 0x00001fb1; +_symrom_HCI_LE_SetDefaultPhyMode = 0x00001fd9; +_symrom_HCI_LE_SetEventMaskCmd = 0x00001ff5; +_symrom_HCI_LE_SetExtAdvDataCmd = 0x0000202d; +_symrom_HCI_LE_SetExtAdvEnableCmd = 0x0000204d; +_symrom_HCI_LE_SetExtAdvParamCmd = 0x0000206d; +_symrom_HCI_LE_SetExtAdvSetRandomAddressCmd = 0x000020c1; +_symrom_HCI_LE_SetExtScanRspDataCmd = 0x000020dd; +_symrom_HCI_LE_SetExtendedScanEnableCmd = 0x000020fd; +_symrom_HCI_LE_SetExtendedScanParametersCmd = 0x00002119; +_symrom_HCI_LE_SetHostChanClassificationCmd = 0x0000213d; +_symrom_HCI_LE_SetPeriodicAdvDataCmd = 0x00002159; +_symrom_HCI_LE_SetPeriodicAdvEnableCmd = 0x00002175; +_symrom_HCI_LE_SetPeriodicAdvParameterCmd = 0x00002191; +_symrom_HCI_LE_SetPhyMode = 0x000021ad; +_symrom_HCI_LE_SetRandomAddressCmd = 0x000021c5; +_symrom_HCI_LE_SetResolvablePrivateAddressTimeoutCmd = 0x000021e9; +_symrom_HCI_LE_SetScanEnableCmd = 0x00002219; +_symrom_HCI_LE_SetScanParamCmd = 0x00002235; +_symrom_HCI_LE_SetScanRspDataCmd = 0x00002255; +_symrom_HCI_LE_Set_ConnectionCTE_ReceiveParamCmd = 0x00002271; +_symrom_HCI_LE_Set_ConnectionCTE_TransmitParamCmd = 0x0000229d; +_symrom_HCI_LE_Set_Privacy_ModeCmd = 0x000022c5; +_symrom_HCI_LE_StartEncyptCmd = 0x000022e1; +_symrom_HCI_LE_TestEndCmd = 0x000022f5; +_symrom_HCI_LE_TransmitterTestCmd = 0x0000231d; +_symrom_HCI_LE_WriteSuggestedDefaultDataLengthCmd = 0x00002339; +_symrom_HCI_LE_Write_Rf_Path_CompensationCmd = 0x00002355; +_symrom_HCI_NumOfCompletedPacketsEvent = 0x00002371; +_symrom_HCI_PPLUS_AdvEventDoneNoticeCmd = 0x00002401; +_symrom_HCI_PPLUS_ConnEventDoneNoticeCmd = 0x00002421; +_symrom_HCI_PPLUS_DateLengthChangedNoticeCmd = 0x00002461; +_symrom_HCI_PPLUS_ExtendTRXCmd = 0x000024a1; +_symrom_HCI_PPLUS_PhyUpdateNoticeCmd = 0x000024bd; +_symrom_HCI_ProcessEvent = 0x000024fd; +_symrom_HCI_ReadBDADDRCmd = 0x00002551; +_symrom_HCI_ReadLocalSupportedCommandsCmd = 0x00002571; +_symrom_HCI_ReadLocalSupportedFeaturesCmd = 0x00002589; +_symrom_HCI_ReadLocalVersionInfoCmd = 0x000025ad; +_symrom_HCI_ReadRemoteVersionInfoCmd = 0x000025f5; +_symrom_HCI_ReadRssiCmd = 0x00002625; +_symrom_HCI_ReadTransmitPowerLevelCmd = 0x00002651; +_symrom_HCI_ResetCmd = 0x0000267d; +_symrom_HCI_ReverseBytes = 0x000026a9; +_symrom_HCI_SMPTaskRegister = 0x000026c9; +_symrom_HCI_SendCommandCompleteEvent = 0x000026d5; +_symrom_HCI_SendCommandStatusEvent = 0x0000277d; +_symrom_HCI_SendControllerToHostEvent = 0x0000279d; +_symrom_HCI_SendDataPkt = 0x000027e9; +_symrom_HCI_SetControllerToHostFlowCtrlCmd = 0x00002819; +_symrom_HCI_SetEventMaskCmd = 0x0000285d; +_symrom_HCI_TestAppTaskRegister = 0x0000288d; +_symrom_HCI_ValidConnTimeParams = 0x00002899; +_symrom_HCI_VendorSpecifcCommandCompleteEvent = 0x000028d9; +_symrom_HCI_bm_alloc = 0x000028e9; +_symrom_HardFault_Handler = 0x000028f1; +_symrom_HardFault_IRQHandler = 0x00002909; +_symrom_LL_AddResolvingListLDevice = 0x000029dd; +_symrom_LL_AddWhiteListDevice = 0x00002a95; +_symrom_LL_AdvReportCback = 0x00002b11; +_symrom_LL_CTE_Report_FailedCback = 0x00002ca1; +_symrom_LL_ChanMapUpdate = 0x00002d0d; +_symrom_LL_ClearAdvSets = 0x00002e2d; +_symrom_LL_ClearResolvingList = 0x00002f41; +_symrom_LL_ClearWhiteList = 0x00002fbd; +_symrom_LL_ConnActive = 0x00003011; +_symrom_LL_ConnParamUpdateCback = 0x00003039; +_symrom_LL_ConnUpdate = 0x000030e5; +_symrom_LL_ConnectionCompleteCback = 0x000031b9; +_symrom_LL_ConnectionIQReportCback = 0x000032d5; +_symrom_LL_Connection_CTE_Request_Enable = 0x000033e5; +_symrom_LL_Connection_CTE_Response_Enable = 0x00003499; +_symrom_LL_ConnectionlessCTE_TransmitEnable = 0x00003505; +_symrom_LL_ConnectionlessCTE_TransmitParam = 0x000035e5; +_symrom_LL_ConnectionlessIQReportCback = 0x000036c1; +_symrom_LL_ConnectionlessIQ_SampleEnable = 0x000037c5; +_symrom_LL_CreateConn = 0x00003901; +_symrom_LL_CreateConn0 = 0x00003949; +_symrom_LL_CreateConnCancel = 0x00003c91; +_symrom_LL_CtrlToHostFlowControl = 0x00003d59; +_symrom_LL_DataLengthChangeCback = 0x00003d71; +_symrom_LL_DirectTestEnd = 0x00003e3d; +_symrom_LL_DirectTestTxTest = 0x00003e95; +_symrom_LL_Disconnect = 0x00003eb1; +_symrom_LL_DisconnectCback = 0x00003f41; +_symrom_LL_ENC_AES128_Encrypt = 0x00003fc5; +_symrom_LL_ENC_AES128_Encrypt0 = 0x00003fdd; +_symrom_LL_ENC_Decrypt = 0x000040ed; +_symrom_LL_ENC_Decrypt0 = 0x00004105; +_symrom_LL_ENC_Encrypt = 0x00004261; +_symrom_LL_ENC_Encrypt0 = 0x00004278; +_symrom_LL_ENC_GenDeviceIV = 0x000043c1; +_symrom_LL_ENC_GenDeviceSKD = 0x000043f1; +_symrom_LL_ENC_GenerateNonce = 0x00004421; +_symrom_LL_ENC_GeneratePseudoRandNum = 0x00004459; +_symrom_LL_ENC_GenerateTrueRandNum = 0x00004469; +_symrom_LL_ENC_LoadKey = 0x00004489; +_symrom_LL_ENC_ReverseBytes = 0x000044e1; +_symrom_LL_ENC_sm_ah = 0x00004501; +_symrom_LL_EXT_AdvEventNotice = 0x00004543; +_symrom_LL_EXT_BuildRevision = 0x00004547; +_symrom_LL_EXT_ClkDivOnHalt = 0x0000454b; +_symrom_LL_EXT_ConnEventNotice = 0x0000454f; +_symrom_LL_EXT_DeclareNvUsage = 0x00004553; +_symrom_LL_EXT_Decrypt = 0x00004557; +_symrom_LL_EXT_DelaySleep = 0x0000455b; +_symrom_LL_EXT_DisconnectImmed = 0x0000455f; +_symrom_LL_EXT_EndModemTest = 0x00004563; +_symrom_LL_EXT_HaltDuringRf = 0x00004567; +_symrom_LL_EXT_Init_IQ_pBuff = 0x0000456d; +_symrom_LL_EXT_MapPmIoPort = 0x00004581; +_symrom_LL_EXT_ModemHopTestTx = 0x00004585; +_symrom_LL_EXT_ModemTestRx = 0x00004589; +_symrom_LL_EXT_ModemTestTx = 0x0000458d; +_symrom_LL_EXT_NumComplPktsLimit = 0x00004591; +_symrom_LL_EXT_OnePacketPerEvent = 0x000045ad; +_symrom_LL_EXT_OverlappedProcessing = 0x000045b1; +_symrom_LL_EXT_PERbyChan = 0x000045b5; +_symrom_LL_EXT_PacketErrorRate = 0x000045b9; +_symrom_LL_EXT_PacketErrorRateCback = 0x000045bd; +_symrom_LL_EXT_ResetSystem = 0x000045f9; +_symrom_LL_EXT_SaveFreqTune = 0x000045fd; +_symrom_LL_EXT_SetBDADDR = 0x00004601; +_symrom_LL_EXT_SetFastTxResponseTime = 0x00004605; +_symrom_LL_EXT_SetFreqTune = 0x00004609; +_symrom_LL_EXT_SetLocalSupportedFeatures = 0x0000460d; +_symrom_LL_EXT_SetMaxDtmTxPower = 0x00004611; +_symrom_LL_EXT_SetRxGain = 0x00004615; +_symrom_LL_EXT_SetRxGainCback = 0x00004619; +_symrom_LL_EXT_SetSCA = 0x00004635; +_symrom_LL_EXT_SetSlaveLatencyOverride = 0x00004639; +_symrom_LL_EXT_SetTxPower = 0x0000463d; +_symrom_LL_EXT_SetTxPowerCback = 0x00004679; +_symrom_LL_EncChangeCback = 0x00004699; +_symrom_LL_EncKeyRefreshCback = 0x00004715; +_symrom_LL_EncLtkNegReply = 0x0000478d; +_symrom_LL_EncLtkReply = 0x000047d9; +_symrom_LL_EncLtkReqCback = 0x00004831; +_symrom_LL_Encrypt = 0x000048e5; +_symrom_LL_ExtAdvReportCback = 0x00004a8d; +_symrom_LL_ExtendedCreateConnection = 0x00004bfd; +_symrom_LL_IRQHandler = 0x00004e25; +_symrom_LL_Init = 0x00004eb1; +_symrom_LL_InitConnectContext = 0x00005045; +_symrom_LL_InitExtendedAdv = 0x0000511d; +_symrom_LL_InitExtendedScan = 0x000051b5; +_symrom_LL_InitPeriodicAdv = 0x000051c5; +_symrom_LL_NumEmptyWlEntries = 0x00005291; +_symrom_LL_PLUS_DisableSlaveLatency = 0x000052a5; +_symrom_LL_PLUS_EnableSlaveLatency = 0x00005435; +_symrom_LL_PLUS_GetAdvDataExtendData = 0x0000548d; +_symrom_LL_PLUS_GetScanRequestExtendData = 0x00005495; +_symrom_LL_PLUS_GetScanerAddr = 0x000054bd; +_symrom_LL_PLUS_PerStasReadByChn = 0x000054d5; +_symrom_LL_PLUS_PerStatsReset = 0x00005519; +_symrom_LL_PLUS_PerStats_Init = 0x00005535; +_symrom_LL_PLUS_SetAdvDataFilterCB = 0x00005545; +_symrom_LL_PLUS_SetScanRequestData = 0x00005551; +_symrom_LL_PLUS_SetScanRequestFilterCB = 0x00005579; +_symrom_LL_PLUS_SetScanRsqData = 0x00005585; +_symrom_LL_PLUS_SetScanRsqDataByIndex = 0x000055b1; +_symrom_LL_PeriodicAdvertisingCreateSync = 0x000055bd; +_symrom_LL_PeriodicAdvertisingCreateSyncCancel = 0x0000560d; +_symrom_LL_PeriodicAdvertisingTerminateSync = 0x00005635; +_symrom_LL_PhyUpdate = 0x00005655; +_symrom_LL_PhyUpdate0 = 0x0000566d; +_symrom_LL_PhyUpdateCompleteCback = 0x00005725; +_symrom_LL_PrdAdvReportCback = 0x000057c9; +_symrom_LL_PrdAdvSyncEstablishedCback = 0x000058b5; +_symrom_LL_PrdAdvSyncLostCback = 0x00005989; +_symrom_LL_ProcessEvent = 0x000059f1; +_symrom_LL_PseudoRand = 0x00005dd9; +_symrom_LL_READ_Anatenna_Info = 0x00005ddd; +_symrom_LL_RX_bm_alloc = 0x00005df1; +_symrom_LL_Rand = 0x00005e05; +_symrom_LL_RandCback = 0x00005e65; +_symrom_LL_ReadAdvChanTxPower = 0x00005e89; +_symrom_LL_ReadBDADDR = 0x00005eb9; +_symrom_LL_ReadCarrSens = 0x00005edd; +_symrom_LL_ReadChanMap = 0x00005ef9; +_symrom_LL_ReadFoff = 0x00005f31; +_symrom_LL_ReadLocalSupportedFeatures = 0x00005f71; +_symrom_LL_ReadLocalVersionInfo = 0x00005f8d; +_symrom_LL_ReadMaximumAdvDataLength = 0x00005fa5; +_symrom_LL_ReadNumberOfSupportAdvSet = 0x00005fc5; +_symrom_LL_ReadPeerResolvableAddress = 0x00005fe1; +_symrom_LL_ReadPeriodicAdvListSize = 0x00006005; +_symrom_LL_ReadRemoteUsedFeatures = 0x00006021; +_symrom_LL_ReadRemoteUsedFeaturesCompleteCback = 0x00006061; +_symrom_LL_ReadRemoteVersionInfo = 0x000060d5; +_symrom_LL_ReadRemoteVersionInfoCback = 0x00006131; +_symrom_LL_ReadResolvingListSize = 0x000061a9; +_symrom_LL_ReadRssi = 0x000061b1; +_symrom_LL_ReadSupportedStates = 0x000061e5; +_symrom_LL_ReadTxPowerLevel = 0x00006269; +_symrom_LL_ReadWlSize = 0x000062e5; +_symrom_LL_Read_Rf_Path_Compensation = 0x00006305; +_symrom_LL_Read_Transmit_Power = 0x00006329; +_symrom_LL_RemoveAdvSet = 0x00006335; +_symrom_LL_RemovePeriodicAdvListDevice = 0x00006409; +_symrom_LL_RemoveResolvingListDevice = 0x000064a5; +_symrom_LL_RemoveWhiteListDevice = 0x00006561; +_symrom_LL_RemoveWhiteListDevice0 = 0x00006579; +_symrom_LL_Reset = 0x000065f1; +_symrom_LL_Reset0 = 0x00006609; +_symrom_LL_RxDataCompleteCback = 0x00006791; +_symrom_LL_SetAddressResolutionEnable = 0x00006831; +_symrom_LL_SetAdvControl = 0x00006881; +_symrom_LL_SetAdvControl0 = 0x00006899; +_symrom_LL_SetAdvData = 0x00006a05; +_symrom_LL_SetAdvParam = 0x00006a6d; +_symrom_LL_SetAdvParam0 = 0x00006a9d; +_symrom_LL_SetDataLengh = 0x00006df9; +_symrom_LL_SetDataLengh0 = 0x00006e11; +_symrom_LL_SetDefaultPhyMode = 0x00006ead; +_symrom_LL_SetExtAdvData = 0x00006edd; +_symrom_LL_SetExtAdvEnable = 0x00006fc5; +_symrom_LL_SetExtAdvParam = 0x00007205; +_symrom_LL_SetExtAdvSetRandomAddress = 0x000073a9; +_symrom_LL_SetExtScanRspData = 0x000073f5; +_symrom_LL_SetExtendedScanEnable = 0x00007471; +_symrom_LL_SetExtendedScanParameters = 0x000074b5; +_symrom_LL_SetPeriodicAdvData = 0x0000751d; +_symrom_LL_SetPeriodicAdvEnable = 0x000075cd; +_symrom_LL_SetPeriodicAdvParameter = 0x00007715; +_symrom_LL_SetPhyMode = 0x000077e1; +_symrom_LL_SetPhyMode0 = 0x000077fd; +_symrom_LL_SetRandomAddress = 0x000078c9; +_symrom_LL_SetResolvablePrivateAddressTimeout = 0x00007929; +_symrom_LL_SetScanControl = 0x00007935; +_symrom_LL_SetScanControl0 = 0x0000794d; +_symrom_LL_SetScanParam = 0x00007a59; +_symrom_LL_SetScanParam0 = 0x00007a75; +_symrom_LL_SetScanRspData = 0x00007b15; +_symrom_LL_SetTxPowerLevel = 0x00007b65; +_symrom_LL_Set_ConnectionCTE_ReceiveParam = 0x00007b91; +_symrom_LL_Set_ConnectionCTE_TransmitParam = 0x00007c99; +_symrom_LL_StartEncrypt = 0x00007e01; +_symrom_LL_TX_bm_alloc = 0x00007f01; +_symrom_LL_TxData = 0x00007f1d; +_symrom_LL_WriteSuggestedDefaultDataLength = 0x00007fb9; +_symrom_LL_Write_Rf_Path_Compensation = 0x00007fe5; +_symrom_LL_evt_schedule = 0x00007ff9; +_symrom_LL_extAdvTimerExpProcess = 0x000080b5; +_symrom_LL_extInitTimerExpProcess = 0x000080b9; +_symrom_LL_extScanTimerExpProcess = 0x000080bb; +_symrom_LL_master_conn_event = 0x000080bd; +_symrom_LL_prdAdvTimerExpProcess = 0x0000826d; +_symrom_LL_prdScanTimerExpProcess = 0x00008271; +_symrom_LL_set_default_conn_params = 0x00008275; +_symrom_LL_slave_conn_event = 0x000082b9; +_symrom_NMI_Handler = 0x00008481; +_symrom_PendSV_Handler = 0x000084cd; +_symrom_TIM1_IRQHandler = 0x00008545; +_symrom_WaitRTCCount = 0x00008901; +_symrom___ARM_common_switch8 = 0x00008961; +_symrom__spif_read_status_reg = 0x0000961d; +_symrom__spif_wait_nobusy = 0x00009645; +_symrom_app_sleep_process = 0x00009769; +_symrom_app_wakeup_process = 0x00009779; +_symrom_ate_fun_test = 0x00009789; +_symrom_ate_sleep_process = 0x00009d11; +_symrom_ate_wakeup_process = 0x0000a121; +_symrom_bit_to_byte = 0x0000a1e9; +_symrom_ble_crc24_gen = 0x0000a201; +_symrom_ble_main = 0x0000a2e1; +_symrom_boot_init = 0x0000a361; +_symrom_boot_init0 = 0x0000a379; +_symrom_boot_m0 = 0x0000a3c1; +_symrom_byte_to_bit = 0x0000a535; +_symrom_calculate_whiten_seed = 0x0000a549; +_symrom_clear_timer = 0x0000a5c1; +_symrom_clear_timer_int = 0x0000a5cb; +_symrom_clk_get_pclk = 0x0000a5d1; +_symrom_clk_init = 0x0000a5ed; +_symrom_clk_set_pclk_div = 0x0000a681; +_symrom_clk_spif_ref_clk = 0x0000a6a1; +_symrom_config_RTC = 0x0000a6f9; +_symrom_config_RTC0 = 0x0000a711; +_symrom_rom_crc16 = 0x0000a755; +_symrom_debug_print = 0x0000a791; +_symrom_disableSleep = 0x0000a921; +_symrom_drv_disable_irq = 0x0000a975; +_symrom_drv_enable_irq = 0x0000a99d; +_symrom_drv_irq_init = 0x0000a9c9; +_symrom_dwc_connect = 0x0000a9fd; +_symrom_dwc_data_process = 0x0000aa35; +_symrom_dwc_loop = 0x0000abd1; +_symrom_efuse_read = 0x0000ace1; +_symrom_enableSleep = 0x0000aead; +_symrom_enterSleepProcess = 0x0000aeb9; +_symrom_enter_sleep_off_mode = 0x0000afa1; +_symrom_enter_sleep_off_mode0 = 0x0000afb9; +_symrom_getMcuPrecisionCount = 0x0000afe9; +_symrom_getPN23RandNumber = 0x0000aff5; +_symrom_getRxBufferFree = 0x0000b01d; +_symrom_getRxBufferSize = 0x0000b031; +_symrom_getSleepMode = 0x0000b051; +_symrom_getTxBufferFree = 0x0000b05d; +_symrom_getTxBufferSize = 0x0000b071; +_symrom_get_rx_read_ptr = 0x0000b0b1; +_symrom_get_rx_write_ptr = 0x0000b0b9; +_symrom_get_sleep_flag = 0x0000b0c1; +_symrom_get_timer_count = 0x0000b0cd; +_symrom_get_timer_int = 0x0000b0d1; +_symrom_get_tx_read_ptr = 0x0000b0d9; +_symrom_get_tx_write_ptr = 0x0000b0e1; +_symrom_gpio_cfg_analog_io = 0x0000b0e9; +_symrom_gpio_dir = 0x0000b119; +_symrom_gpio_fmux_control = 0x0000b15d; +_symrom_gpio_fmux_set = 0x0000b179; +_symrom_gpio_in_trigger = 0x0000b1b1; +_symrom_gpio_init = 0x0000b219; +_symrom_gpio_interrupt_set = 0x0000b22d; +_symrom_gpio_pull_set = 0x0000b249; +_symrom_gpio_read = 0x0000b291; +_symrom_gpio_wakeup_set = 0x0000b2b5; +_symrom_gpio_write = 0x0000b319; +_symrom_hciInitEventMasks = 0x0000b52d; +_symrom_isSleepAllow = 0x0000b555; +_symrom_isTimer1Running = 0x0000b561; +_symrom_isTimer4Running = 0x0000b571; +_symrom_jump_area_init = 0x0000b581; +_symrom_ll24BitTimeCompare = 0x0000b5a9; +_symrom_llAdjSlaveLatencyValue = 0x0000b609; +_symrom_llAllocConnId = 0x0000b629; +_symrom_llAllocateSyncHandle = 0x0000b679; +_symrom_llAtLeastTwoChans = 0x0000b6a9; +_symrom_llCalcMaxScanTime = 0x0000b6ed; +_symrom_llCalcScaFactor = 0x0000b745; +_symrom_llCalcTimerDrift = 0x0000b76d; +_symrom_llCheckForLstoDuringSL = 0x0000b7b1; +_symrom_llCheckWhiteListUsage = 0x0000b7ed; +_symrom_llConnCleanup = 0x0000b809; +_symrom_llConnTerminate = 0x0000b839; +_symrom_llConnTerminate0 = 0x0000b851; +_symrom_llConvertCtrlProcTimeoutToEvent = 0x0000b87d; +_symrom_llConvertLstoToEvent = 0x0000b899; +_symrom_llDeleteSyncHandle = 0x0000b8bd; +_symrom_llDequeueCtrlPkt = 0x0000b8ed; +_symrom_llDequeueDataQ = 0x0000b929; +_symrom_llEnqueueCtrlPkt = 0x0000b953; +_symrom_llEnqueueDataQ = 0x0000b98b; +_symrom_llEqAlreadyValidAddr = 0x0000b9b1; +_symrom_llEqSynchWord = 0x0000b9b5; +_symrom_llEqualBytes = 0x0000b9c9; +_symrom_llEventDelta = 0x0000b9e9; +_symrom_llEventInRange = 0x0000b9fd; +_symrom_llGenerateCRC = 0x0000ba1b; +_symrom_llGenerateValidAccessAddr = 0x0000ba3d; +_symrom_llGetNextAdvChn = 0x0000ba6d; +_symrom_llGetNextAuxAdvChn = 0x0000bac1; +_symrom_llGetNextDataChan = 0x0000bae5; +_symrom_llGetNextDataChanCSA2 = 0x0000bb23; +_symrom_llGtSixConsecZerosOrOnes = 0x0000bb81; +_symrom_llGtTwentyFourTransitions = 0x0000bbb3; +_symrom_llInitFeatureSet = 0x0000bbe5; +_symrom_llInitFeatureSet2MPHY = 0x0000bc1d; +_symrom_llInitFeatureSetCodedPHY = 0x0000bc45; +_symrom_llInitFeatureSetDLE = 0x0000bc6d; +_symrom_llLtTwoChangesInLastSixBits = 0x0000bc89; +_symrom_llMasterEvt_TaskEndOk = 0x0000bcb9; +_symrom_llMemCopyDst = 0x0000be05; +_symrom_llMemCopySrc = 0x0000be1b; +_symrom_llOneBitSynchWordDiffer = 0x0000be35; +_symrom_llPduLengthManagmentReset = 0x0000be4d; +_symrom_llPduLengthUpdate = 0x0000bf01; +_symrom_llPendingUpdateParam = 0x0000c00d; +_symrom_llPhyModeCtrlReset = 0x0000c051; +_symrom_llPhyModeCtrlUpdateNotify = 0x0000c0b9; +_symrom_llProcessChanMap = 0x0000c185; +_symrom_llProcessMasterControlPacket = 0x0000c1d1; +_symrom_llProcessMasterControlPacket0 = 0x0000c1e9; +_symrom_llProcessMasterControlProcedures = 0x0000c5b9; +_symrom_llProcessMasterControlProcedures0 = 0x0000c5d1; +_symrom_llProcessRxData = 0x0000ca85; +_symrom_llProcessSlaveControlPacket = 0x0000cc31; +_symrom_llProcessSlaveControlPacket0 = 0x0000cc49; +_symrom_llProcessSlaveControlProcedures = 0x0000d169; +_symrom_llProcessSlaveControlProcedures0 = 0x0000d181; +_symrom_llProcessTxData = 0x0000d4d1; +_symrom_llProcessTxData0 = 0x0000d4e9; +_symrom_llReleaseAllConnId = 0x0000d55d; +_symrom_llReleaseConnId = 0x0000d561; +_symrom_llReplaceCtrlPkt = 0x0000d5f5; +_symrom_llResetConnId = 0x0000d60d; +_symrom_llResetRfCounters = 0x0000d6ed; +_symrom_llSecAdvAllow = 0x0000d701; +_symrom_llSetNextDataChan = 0x0000d769; +_symrom_llSetNextPhyMode = 0x0000d839; +_symrom_llSetupAdv = 0x0000d8a9; +_symrom_llSetupAdvExtIndPDU = 0x0000d949; +_symrom_llSetupAuxAdvIndPDU = 0x0000db4d; +_symrom_llSetupAuxChainIndPDU = 0x0000dda1; +_symrom_llSetupAuxConnectReqPDU = 0x0000df91; +_symrom_llSetupAuxConnectRspPDU = 0x0000e025; +_symrom_llSetupAuxScanRspPDU = 0x0000e09d; +_symrom_llSetupAuxSyncIndPDU = 0x0000e109; +_symrom_llSetupAuxSyncIndPDU0 = 0x0000e121; +_symrom_llSetupCTEReq = 0x0000e2c1; +_symrom_llSetupCTERsp = 0x0000e38d; +_symrom_llSetupConn = 0x0000e457; +_symrom_llSetupDataLenghtReq = 0x0000e459; +_symrom_llSetupDataLenghtRsp = 0x0000e4d5; +_symrom_llSetupDirectedAdvEvt = 0x0000e551; +_symrom_llSetupEncReq = 0x0000e6a1; +_symrom_llSetupEncRsp = 0x0000e725; +_symrom_llSetupExtAdvEvent = 0x0000e7b1; +_symrom_llSetupExtInit = 0x0000eb09; +_symrom_llSetupExtScan = 0x0000eb81; +_symrom_llSetupFeatureSetReq = 0x0000ec01; +_symrom_llSetupFeatureSetRsp = 0x0000ec63; +_symrom_llSetupInit = 0x0000ecc1; +_symrom_llSetupNextMasterEvent = 0x0000ed39; +_symrom_llSetupNextSlaveEvent = 0x0000ede1; +_symrom_llSetupNonConnectableAdvEvt = 0x0000ef65; +_symrom_llSetupPauseEncReq = 0x0000f075; +_symrom_llSetupPauseEncRsp = 0x0000f0c5; +_symrom_llSetupPhyReq = 0x0000f121; +_symrom_llSetupPhyRsp = 0x0000f177; +_symrom_llSetupPhyUpdateInd = 0x0000f1cd; +_symrom_llSetupPrdAdvEvent = 0x0000f239; +_symrom_llSetupPrdScan = 0x0000f3b9; +_symrom_llSetupRejectExtInd = 0x0000f44d; +_symrom_llSetupRejectInd = 0x0000f479; +_symrom_llSetupScan = 0x0000f4a5; +_symrom_llSetupScanInit = 0x0000f54d; +_symrom_llSetupScannableAdvEvt = 0x0000f55d; +_symrom_llSetupSecAdvEvt = 0x0000f66d; +_symrom_llSetupSecConnectableAdvEvt = 0x0000f6e9; +_symrom_llSetupSecInit = 0x0000f7c1; +_symrom_llSetupSecNonConnectableAdvEvt = 0x0000f875; +_symrom_llSetupSecScan = 0x0000f94d; +_symrom_llSetupSecScannableAdvEvt = 0x0000fa19; +_symrom_llSetupStartEncReq = 0x0000faf1; +_symrom_llSetupStartEncRsp = 0x0000fb15; +_symrom_llSetupSyncInfo = 0x0000fb59; +_symrom_llSetupTermInd = 0x0000fc2d; +_symrom_llSetupUndirectedAdvEvt = 0x0000fc91; +_symrom_llSetupUnknownRsp = 0x0000fda5; +_symrom_llSetupUpdateChanReq = 0x0000fdf9; +_symrom_llSetupUpdateParamReq = 0x0000fe6d; +_symrom_llSetupVersionIndReq = 0x0000ff05; +_symrom_llSlaveEvt_TaskAbort = 0x0000ff79; +_symrom_llSlaveEvt_TaskEndOk = 0x0000ff95; +_symrom_llTrxNumAdaptiveConfig = 0x00010181; +_symrom_llValidAccessAddr = 0x0001019b; +_symrom_llWaitUs = 0x000101e1; +_symrom_llWriteTxData = 0x00010209; +_symrom_ll_CalcRandomAddr = 0x0001028f; +_symrom_ll_ResolveRandomAddrs = 0x000102cd; +_symrom_ll_addTask = 0x00010315; +_symrom_ll_add_adv_task = 0x00010445; +_symrom_ll_add_adv_task_periodic = 0x00010461; +_symrom_ll_adptive_adj_next_time = 0x0001047d; +_symrom_ll_adptive_smart_window = 0x000104fd; +_symrom_ll_adv_scheduler = 0x000105ad; +_symrom_ll_adv_scheduler_periodic = 0x000105c9; +_symrom_ll_allocAuxAdvTimeSlot = 0x000105e5; +_symrom_ll_allocAuxAdvTimeSlot_prd = 0x00010679; +_symrom_ll_debug_output = 0x00010719; +_symrom_ll_deleteTask = 0x00010731; +_symrom_ll_delete_adv_task = 0x00010765; +_symrom_ll_delete_adv_task_periodic = 0x00010781; +_symrom_ll_ext_adv_schedule_next_event = 0x0001079d; +_symrom_ll_ext_init_schedule_next_event = 0x000107c1; +_symrom_ll_ext_scan_schedule_next_event = 0x000107dd; +_symrom_ll_generateExtAdvDid = 0x000107f9; +_symrom_ll_generateTxBuffer = 0x00010801; +_symrom_ll_getFirstAdvChn = 0x000109c1; +_symrom_ll_getRPAListEntry = 0x000109cd; +_symrom_ll_get_next_active_conn = 0x00010a39; +_symrom_ll_get_next_timer = 0x00010aa1; +_symrom_ll_hw_clr_irq = 0x00010add; +_symrom_ll_hw_config = 0x00010aed; +_symrom_ll_hw_get_anchor = 0x00010b6d; +_symrom_ll_hw_get_fsm_status = 0x00010b79; +_symrom_ll_hw_get_iq_RawSample = 0x00010b89; +_symrom_ll_hw_get_irq_status = 0x00010bbd; +_symrom_ll_hw_get_last_ack = 0x00010bcd; +_symrom_ll_hw_get_loop_cycle = 0x00010be9; +_symrom_ll_hw_get_loop_time = 0x00010bf5; +_symrom_ll_hw_get_nAck = 0x00010c01; +_symrom_ll_hw_get_rfifo_depth = 0x00010c11; +_symrom_ll_hw_get_rfifo_info = 0x00010c25; +_symrom_ll_hw_get_rxPkt_CrcErr_num = 0x00010c45; +_symrom_ll_hw_get_rxPkt_CrcOk_num = 0x00010c55; +_symrom_ll_hw_get_rxPkt_Total_num = 0x00010c69; +_symrom_ll_hw_get_rxPkt_num = 0x00010c79; +_symrom_ll_hw_get_rxPkt_stats = 0x00010c85; +_symrom_ll_hw_get_snNesn = 0x00010c9d; +_symrom_ll_hw_get_tfifo_info = 0x00010cad; +_symrom_ll_hw_get_tfifo_wrptr = 0x00010ccd; +_symrom_ll_hw_get_tr_mode = 0x00010cdd; +_symrom_ll_hw_get_txAck = 0x00010ced; +_symrom_ll_hw_go = 0x00010cf9; +_symrom_ll_hw_ign_rfifo = 0x00010df9; +_symrom_ll_hw_process_RTO = 0x00010e05; +_symrom_ll_hw_read_rfifo = 0x00010e6d; +_symrom_ll_hw_read_rfifo_pplus = 0x00010ee9; +_symrom_ll_hw_read_rfifo_zb = 0x00010f51; +_symrom_ll_hw_read_tfifo_packet = 0x00010fad; +_symrom_ll_hw_read_tfifo_rtlp = 0x00010ff5; +_symrom_ll_hw_rst_rfifo = 0x000110b1; +_symrom_ll_hw_rst_tfifo = 0x000110e9; +_symrom_ll_hw_set_ant_pattern = 0x000110f5; +_symrom_ll_hw_set_ant_switch_mode = 0x00011101; +_symrom_ll_hw_set_ant_switch_timing = 0x00011115; +_symrom_ll_hw_set_crc_fmt = 0x0001112d; +_symrom_ll_hw_set_cte_rxSupp = 0x0001113d; +_symrom_ll_hw_set_cte_txSupp = 0x00011155; +_symrom_ll_hw_set_empty_head = 0x00011169; +_symrom_ll_hw_set_irq = 0x00011175; +_symrom_ll_hw_set_loop_nack_num = 0x00011181; +_symrom_ll_hw_set_loop_timeout = 0x0001118d; +_symrom_ll_hw_set_pplus_pktfmt = 0x000111a1; +_symrom_ll_hw_set_rtlp = 0x000111cd; +_symrom_ll_hw_set_rtlp_1st = 0x0001121d; +_symrom_ll_hw_set_rtx = 0x00011265; +_symrom_ll_hw_set_rx_timeout = 0x00011279; +_symrom_ll_hw_set_rx_timeout_1st = 0x00011285; +_symrom_ll_hw_set_rx_tx_interval = 0x00011291; +_symrom_ll_hw_set_srx = 0x000112a5; +_symrom_ll_hw_set_stx = 0x000112b9; +_symrom_ll_hw_set_tfifo_space = 0x000112cd; +_symrom_ll_hw_set_timing = 0x000112e5; +_symrom_ll_hw_set_trlp = 0x00011381; +_symrom_ll_hw_set_trx = 0x000113c9; +_symrom_ll_hw_set_trx_settle = 0x000113dd; +_symrom_ll_hw_set_tx_rx_interval = 0x000113f1; +_symrom_ll_hw_set_tx_rx_release = 0x00011405; +_symrom_ll_hw_trigger = 0x00011421; +_symrom_ll_hw_trx_settle_config = 0x00011445; +_symrom_ll_hw_tx2rx_timing_config = 0x00011489; +_symrom_ll_hw_update = 0x000114dd; +_symrom_ll_hw_update_rtlp_mode = 0x00011539; +_symrom_ll_hw_update_trlp_mode = 0x00011579; +_symrom_ll_hw_write_tfifo = 0x000115c1; +_symrom_ll_isAddrInWhiteList = 0x00011649; +_symrom_ll_isFirstAdvChn = 0x000116a9; +_symrom_ll_isIrkAllZero = 0x000116c7; +_symrom_ll_isLegacyAdv = 0x000116dd; +_symrom_ll_parseExtHeader = 0x000116ed; +_symrom_ll_prd_adv_schedule_next_event = 0x000117a9; +_symrom_ll_prd_scan_schedule_next_event = 0x000117cd; +_symrom_ll_processBasicIRQ = 0x000117e9; +_symrom_ll_processExtAdvIRQ = 0x00013401; +_symrom_ll_processExtInitIRQ = 0x00013405; +_symrom_ll_processExtScanIRQ = 0x00013409; +_symrom_ll_processMissMasterEvt = 0x0001340d; +_symrom_ll_processMissSlaveEvt = 0x000134ed; +_symrom_ll_processPrdAdvIRQ = 0x000135f5; +_symrom_ll_processPrdScanIRQ = 0x000135f9; +_symrom_ll_readLocalIRK = 0x000135fd; +_symrom_ll_readPeerIRK = 0x00013661; +_symrom_ll_read_rxfifo = 0x000136c5; +_symrom_ll_schedule_next_event = 0x00013761; +_symrom_ll_scheduler = 0x00013771; +_symrom_ll_updateAuxAdvTimeSlot = 0x00013a11; +_symrom_ll_updateExtAdvRemainderTime = 0x00013a39; +_symrom_log_clr_putc = 0x00013ab9; +_symrom_log_debug_level = 0x00013ac5; +_symrom_log_get_debug_level = 0x00013ad9; +_symrom_log_printf = 0x00013ae5; +_symrom_log_set_putc = 0x00013b05; +_symrom_log_vsprintf = 0x00013b11; +_symrom_move_to_master_function = 0x00013f09; +_symrom_move_to_slave_function = 0x0001406d; +_symrom_osalAddTimer = 0x00014439; +_symrom_osalDeleteTimer = 0x000144a9; +_symrom_osalFindTimer = 0x000144b5; +_symrom_osalTimeUpdate = 0x000144d5; +_symrom_osalTimeUpdate1 = 0x00014541; +_symrom_osalTimerInit = 0x0001457d; +_symrom_osalTimerUpdate = 0x00014589; +_symrom_osal_CbTimerInit = 0x00014621; +_symrom_osal_CbTimerProcessEvent = 0x00014641; +_symrom_osal_CbTimerStart = 0x000146a9; +_symrom_osal_CbTimerStop = 0x00014711; +_symrom_osal_CbTimerUpdate = 0x00014751; +_symrom_osal_ConvertUTCSecs = 0x000147a1; +_symrom_osal_ConvertUTCTime = 0x00014841; +_symrom_osal_GetSystemClock = 0x00014949; +_symrom_osal_bm_adjust_header = 0x00014955; +_symrom_osal_bm_adjust_tail = 0x0001497d; +_symrom_osal_bm_alloc = 0x000149a9; +_symrom_osal_bm_free = 0x000149d9; +_symrom_osal_buffer_uint24 = 0x00014a21; +_symrom_osal_buffer_uint32 = 0x00014a2f; +_symrom_osal_build_uint16 = 0x00014a41; +_symrom_osal_build_uint32 = 0x00014a4d; +_symrom_osal_clear_event = 0x00014a89; +_symrom_osal_getClock = 0x00014abd; +_symrom_osal_get_timeoutEx = 0x00014ac9; +_symrom_osal_init_system = 0x00014aed; +_symrom_osal_isbufset = 0x00014b1d; +_symrom_osal_mem_alloc = 0x00014b3d; +_symrom_osal_mem_free = 0x00014c01; +_symrom_osal_mem_init = 0x00014c25; +_symrom_osal_mem_kick = 0x00014c8d; +_symrom_osal_mem_set_heap = 0x00014cb5; +_symrom_osal_memcmp = 0x00014ccd; +_symrom_osal_memcpy = 0x00014ce9; +_symrom_osal_memdup = 0x00014cf9; +_symrom_osal_memset = 0x00014d15; +_symrom_osal_msg_allocate = 0x00014d1d; +_symrom_osal_msg_deallocate = 0x00014d43; +_symrom_osal_msg_dequeue = 0x00014d65; +_symrom_osal_msg_enqueue = 0x00014d91; +_symrom_osal_msg_enqueue_max = 0x00014dc3; +_symrom_osal_msg_extract = 0x00014e6d; +_symrom_osal_msg_find = 0x00014e9d; +_symrom_osal_msg_push = 0x00014ed1; +_symrom_osal_msg_push_front = 0x00014eeb; +_symrom_osal_msg_receive = 0x00014ef5; +_symrom_osal_msg_send = 0x00014f59; +_symrom_osal_next_timeout = 0x00014f7d; +_symrom_osal_pwrmgr_device = 0x00014fa5; +_symrom_osal_pwrmgr_init = 0x00014fb1; +_symrom_osal_pwrmgr_powerconserve = 0x00014fc1; +_symrom_osal_pwrmgr_task_state = 0x000150f9; +_symrom_osal_rand = 0x00015129; +_symrom_osal_revmemcpy = 0x00015145; +_symrom_osal_run_system = 0x00015159; +_symrom_osal_self = 0x000151f5; +_symrom_osal_setClock = 0x00015201; +_symrom_osal_set_event = 0x0001520d; +_symrom_osal_start_reload_timer = 0x00015259; +_symrom_osal_start_system = 0x00015285; +_symrom_osal_start_timerEx = 0x0001528b; +_symrom_osal_stop_timerEx = 0x000152b3; +_symrom_osal_strlen = 0x000152dd; +_symrom_osal_timer_num_active = 0x000152e5; +_symrom_phy_sec_app_key = 0x00015315; +_symrom_phy_sec_decrypt = 0x0001531d; +_symrom_phy_sec_efuse_lock = 0x0001532d; +_symrom_phy_sec_encrypt = 0x00015339; +_symrom_phy_sec_init = 0x00015349; +_symrom_phy_sec_key_valid = 0x0001540d; +_symrom_prog_process_data = 0x00015b19; +_symrom_prog_uart_command = 0x00015c51; +_symrom_prog_uart_fct_command = 0x00015c71; +_symrom_prog_uart_handle = 0x00015c8d; +_symrom_read_LL_remainder_time = 0x00015cbd; +_symrom_read_current_fine_time = 0x00015cc9; +_symrom_read_ll_adv_remainder_time = 0x00015cf1; +_symrom_reset_conn_buf = 0x00015cfd; +_symrom_rf_phy_change_cfg = 0x00016085; +_symrom_rom_board_init = 0x00016a09; +_symrom_rtc_clear = 0x00016ab5; +_symrom_rtc_config_prescale = 0x00016ad1; +_symrom_rtc_get_counter = 0x00016b15; +_symrom_rtc_start = 0x00016b25; +_symrom_rtc_stop = 0x00016b35; +_symrom_setSleepMode = 0x00016b45; +_symrom_set_access_address = 0x00016b51; +_symrom_set_channel = 0x00016b5d; +_symrom_set_crc_seed = 0x00016b9d; +_symrom_set_gpio_pull_down_ate = 0x00016bb5; +_symrom_set_gpio_pull_up_ate = 0x00016bcb; +_symrom_set_int = 0x00016be1; +_symrom_set_max_length = 0x00016bed; +_symrom_set_sleep_flag = 0x00016c01; +_symrom_set_timer = 0x00016c2d; +_symrom_set_whiten_seed = 0x00016cc9; +_symrom_spif_cmd = 0x00016d49; +_symrom_spif_config = 0x00016dc5; +_symrom_spif_erase_all = 0x00016ea1; +_symrom_spif_erase_block64 = 0x00016ed1; +_symrom_spif_erase_chip = 0x00016f55; +_symrom_spif_erase_sector = 0x00016fa9; +_symrom_spif_flash_size = 0x00017029; +_symrom_spif_flash_status_reg_0 = 0x0001703d; +_symrom_spif_flash_status_reg_1 = 0x00017047; +_symrom_spif_init = 0x00017051; +_symrom_spif_rddata = 0x0001713d; +_symrom_spif_read = 0x00017165; +_symrom_spif_read_dma = 0x0001717d; +_symrom_spif_release_deep_sleep = 0x000172cd; +_symrom_spif_set_deep_sleep = 0x00017349; +_symrom_spif_wrdata = 0x0001736d; +_symrom_spif_write = 0x00017395; +_symrom_spif_write_dma = 0x0001744d; +_symrom_spif_write_protect = 0x000174f9; +_symrom_sram_ret_patch = 0x00017591; +_symrom_update_rx_read_ptr = 0x00017609; +_symrom_update_rx_write_ptr = 0x00017635; +_symrom_update_tx_read_ptr = 0x00017659; +_symrom_update_tx_write_ptr = 0x00017685; +_symrom_wakeupProcess = 0x000176a9; +_symrom_wakeupProcess0 = 0x000176c5; +_symrom_wakeup_init = 0x000178a5; +_symrom_wakeup_init0 = 0x000178bd; +_symrom_zigbee_crc16_gen = 0x0001798d; +_symrom_supportedCmdsTable = 0x00017c00; +_symrom_hciCmdTable = 0x00017c44; +_symrom_SCA = 0x00017c4c; +_symrom_hclk_per_us = 0x1fff0818; +_symrom_hclk_per_us_shift = 0x1fff081c; +_symrom_s_prog_time_save = 0x1fff0828; +_symrom_s_prog_timeout = 0x1fff082c; +_symrom_DFL_ENTRY_BASE = 0x1fff0830; +_symrom_receive_timeout_flag = 0x1fff0850; +_symrom_osal_sys_tick = 0x1fff0860; +_symrom_g_timer4_irq_pending_time = 0x1fff0864; +_symrom_g_hclk = 0x1fff0874; +_symrom_m_in_critical_region = 0x1fff0878; +_symrom_s_rom_debug_level = 0x1fff0888; +_symrom_s_spif_ctx = 0x1fff0894; +_symrom_osal_qHead = 0x1fff08b8; +_symrom_baseTaskID = 0x1fff08c0; +_symrom_OSAL_timeSeconds = 0x1fff08cc; +_symrom_ll_remain_time = 0x1fff08e4; +_symrom_pwrmgr_attribute = 0x1fff08e8; +_symrom_timerHead = 0x1fff08f0; +_symrom_hciPTMenabled = 0x1fff08f8; +_symrom_ctrlToHostEnable = 0x1fff08f9; +_symrom_numHostBufs = 0x1fff08fa; +_symrom_hciCtrlCmdToken = 0x1fff08fc; +_symrom_bleEvtMask = 0x1fff0900; +_symrom_pHciEvtMask = 0x1fff0904; +_symrom_hciTaskID = 0x1fff090c; +_symrom_hciTestTaskID = 0x1fff090d; +_symrom_hciGapTaskID = 0x1fff090e; +_symrom_hciL2capTaskID = 0x1fff090f; +_symrom_hciSmpTaskID = 0x1fff0910; +_symrom_hciExtTaskID = 0x1fff0911; +_symrom_g_maxConnNum = 0x1fff0914; +_symrom_g_maxPktPerEventTx = 0x1fff0915; +_symrom_g_maxPktPerEventRx = 0x1fff0916; +_symrom_g_blePktVersion = 0x1fff0917; +_symrom_g_llRlEnable = 0x1fff0918; +_symrom_g_llScanMode = 0x1fff0919; +_symrom_g_llAdvMode = 0x1fff091a; +_symrom_LL_TaskID = 0x1fff091b; +_symrom_llState = 0x1fff091c; +_symrom_numComplPkts = 0x1fff091d; +_symrom_numComplPktsLimit = 0x1fff091e; +_symrom_fastTxRespTime = 0x1fff091f; +_symrom_g_llWlDeviceNum = 0x1fff0920; +_symrom_g_llRlDeviceNum = 0x1fff0921; +_symrom_rxFifoFlowCtrl = 0x1fff0922; +_symrom_llSecondaryState = 0x1fff0923; +_symrom_g_extAdvNumber = 0x1fff0924; +_symrom_g_perioAdvNumber = 0x1fff0925; +_symrom_g_schExtAdvNum = 0x1fff0926; +_symrom_g_currentExtAdv = 0x1fff0927; +_symrom_g_schExtAdvNum_periodic = 0x1fff0928; +_symrom_g_currentExtAdv_periodic = 0x1fff0929; +_symrom_g_llPrdAdvDeviceNum = 0x1fff092a; +_symrom_g_llRlTimeout = 0x1fff092c; +_symrom_g_advSetMaximumLen = 0x1fff0930; +_symrom_conn_param = 0x1fff0934; +_symrom_g_pExtendedAdvInfo = 0x1fff0938; +_symrom_g_pPeriodicAdvInfo = 0x1fff093c; +_symrom_g_pLLcteISample = 0x1fff0940; +_symrom_g_pLLcteQSample = 0x1fff0944; +_symrom_g_llHdcDirAdvTime = 0x1fff0948; +_symrom_g_pAdvSchInfo = 0x1fff094c; +_symrom_g_advPerSlotTick = 0x1fff0950; +_symrom_g_advSlotPeriodic = 0x1fff0954; +_symrom_g_pAdvSchInfo_periodic = 0x1fff0958; +_symrom_g_timerExpiryTick = 0x1fff095c; +_symrom_chanMapUpdate = 0x1fff0960; +_symrom_ownPublicAddr = 0x1fff0965; +_symrom_ownRandomAddr = 0x1fff096b; +_symrom_verInfo = 0x1fff0972; +_symrom_peerInfo = 0x1fff0978; +_symrom_g_currentAdvTimer = 0x1fff0980; +_symrom_g_currentTimerTask = 0x1fff0984; +_symrom_g_adv_taskID = 0x1fff0988; +_symrom_g_conn_taskID = 0x1fff0989; +_symrom_g_smartWindowRTOCnt = 0x1fff098a; +_symrom_isPeerRpaStore = 0x1fff098b; +_symrom_g_same_rf_channel_flag = 0x1fff098c; +_symrom_g_currentPeerAddrType = 0x1fff098d; +_symrom_g_currentLocalAddrType = 0x1fff098e; +_symrom_storeRpaListIndex = 0x1fff098f; +_symrom_llTaskState = 0x1fff0990; +_symrom_g_adv_taskEvent = 0x1fff0992; +_symrom_g_conn_taskEvent = 0x1fff0994; +_symrom_llWaitingIrq = 0x1fff0998; +_symrom_ISR_entry_time = 0x1fff099c; +_symrom_slave_conn_event_recv_delay = 0x1fff09a0; +_symrom_g_smartWindowLater = 0x1fff09a4; +_symrom_g_smartWindowActiveCnt = 0x1fff09a8; +_symrom_g_smartWindowPreAnchPoint = 0x1fff09ac; +_symrom_g_getPn23_cnt = 0x1fff09b0; +_symrom_g_getPn23_seed = 0x1fff09b4; +_symrom_llScanTime = 0x1fff09b8; +_symrom_p_perStatsByChan = 0x1fff09bc; +_symrom_LL_PLUS_AdvDataFilterCBack = 0x1fff09c0; +_symrom_LL_PLUS_ScanRequestFilterCBack = 0x1fff09c4; +_symrom_g_new_master_delta = 0x1fff09c8; +_symrom_llScanT1 = 0x1fff09cc; +_symrom_llCurrentScanChn = 0x1fff09d0; +_symrom_g_currentLocalRpa = 0x1fff09d4; +_symrom_g_currentPeerRpa = 0x1fff09da; +_symrom_currentPeerRpa = 0x1fff09e0; +_symrom_g_dle_taskID = 0x1fff09e6; +_symrom_g_dle_taskEvent = 0x1fff09e8; +_symrom_g_phyChg_taskID = 0x1fff09ea; +_symrom_g_phyChg_taskEvent = 0x1fff09ec; +_symrom_g_smartWindowSize = 0x1fff09f0; +_symrom_g_smartWindowSizeNew = 0x1fff09f4; +_symrom_g_smartWindowActive = 0x1fff09f8; +_symrom_g_interAuxPduDuration = 0x1fff09fc; +_symrom_g_rfTxPathCompensation = 0x1fff0a00; +_symrom_g_rfRxPathCompensation = 0x1fff0a02; +_symrom_connUpdateTimer = 0x1fff0a04; +_symrom_sleep_flag = 0x1fff0a0c; +_symrom_g_wakeup_rtc_tick = 0x1fff0a10; +_symrom_g_counter_traking_avg = 0x1fff0a14; +_symrom_g_TIM2_IRQ_TIM3_CurrCount = 0x1fff0a18; +_symrom_g_TIM2_IRQ_to_Sleep_DeltTick = 0x1fff0a1c; +_symrom_g_TIM2_IRQ_PendingTick = 0x1fff0a20; +_symrom_g_osal_tick_trim = 0x1fff0a24; +_symrom_g_osalTickTrim_mod = 0x1fff0a28; +_symrom_rtc_mod_value = 0x1fff0a2c; +_symrom_g_counter_traking_cnt = 0x1fff0a30; +_symrom_sleep_tick = 0x1fff0a34; +_symrom_counter_tracking = 0x1fff0a38; +_symrom_forever_write = 0x1fff0a3c; +_symrom_g_TIM2_wakeup_delay = 0x1fff0a40; +_symrom_g_rfPhyTpCal0 = 0x1fff0a44; +_symrom_g_rfPhyTpCal1 = 0x1fff0a45; +_symrom_g_rfPhyTpCal0_2Mbps = 0x1fff0a46; +_symrom_g_rfPhyTpCal1_2Mbps = 0x1fff0a47; +_symrom_g_rfPhyTxPower = 0x1fff0a48; +_symrom_g_rfPhyPktFmt = 0x1fff0a49; +_symrom_g_system_clk = 0x1fff0a4a; +_symrom_g_rfPhyClkSel = 0x1fff0a4b; +_symrom_g_rxAdcClkSel = 0x1fff0a4c; +_symrom_g_dtmModeType = 0x1fff0a4d; +_symrom_g_dtmLength = 0x1fff0a4e; +_symrom_g_dtmExtLen = 0x1fff0a4f; +_symrom_g_dtmPKT = 0x1fff0a50; +_symrom_g_dtmTxPower = 0x1fff0a51; +_symrom_g_dtmRssi = 0x1fff0a52; +_symrom_g_dtmCarrSens = 0x1fff0a53; +_symrom_g_dtmPktIntv = 0x1fff0a54; +_symrom_g_dtmPktCount = 0x1fff0a56; +_symrom_g_dtmRxCrcNum = 0x1fff0a58; +_symrom_g_dtmRxTONum = 0x1fff0a5a; +_symrom_g_dtmRsp = 0x1fff0a5c; +_symrom_g_dtmFoff = 0x1fff0a5e; +_symrom_g_rfPhyRxDcIQ = 0x1fff0a60; +_symrom_g_dtmTick = 0x1fff0a64; +_symrom_g_rfPhyFreqOffSet = 0x1fff0a68; +_symrom_g_rfPhyDtmCmd = 0x1fff0a69; +_symrom_g_rfPhyDtmEvt = 0x1fff0a6b; +_symrom_g_dtmCmd = 0x1fff0a6d; +_symrom_g_dtmFreq = 0x1fff0a6e; +_symrom_g_dtmCtrl = 0x1fff0a6f; +_symrom_g_dtmPara = 0x1fff0a70; +_symrom_g_dtmEvt = 0x1fff0a71; +_symrom_g_dtmStatus = 0x1fff0a72; +_symrom_g_dtmTpCalEnable = 0x1fff0a73; +_symrom_g_dtmPerAutoIntv = 0x1fff0a74; +_symrom_g_dtmAccessCode = 0x1fff0a78; +_symrom_g_system_reset_cause = 0x1fff0a80; +_symrom_cbTimers = 0x1fff0afc; +_symrom_g_llSleepContext = 0x1fff0b74; +_symrom_syncInfo = 0x1fff0b84; +_symrom_scanSyncInfo = 0x1fff0b96; +_symrom_adv_param = 0x1fff0ba6; +_symrom_scanInfo = 0x1fff0bbc; +_symrom_initInfo = 0x1fff0bd4; +_symrom_extScanInfo = 0x1fff0be8; +_symrom_extInitInfo = 0x1fff0c10; +_symrom_g_llPeriodAdvSyncInfo = 0x1fff0c50; +_symrom_g_ll_conn_ctx = 0x1fff0d30; +_symrom_deviceFeatureSet = 0x1fff0e48; +_symrom_g_llWhitelist = 0x1fff0e51; +_symrom_g_llResolvinglist = 0x1fff0e89; +_symrom_g_pmCounters = 0x1fff0ffc; +_symrom_g_llPduLen = 0x1fff1084; +_symrom_g_llPeriodicAdvlist = 0x1fff10a0; +_symrom_rfCounters = 0x1fff10e0; +_symrom_ext_adv_hdr = 0x1fff10ec; +_symrom_dataPkt = 0x1fff1118; +_symrom_cachedTRNGdata = 0x1fff1138; +_symrom_whiten_seed = 0x1fff1144; +_symrom_g_tx_adv_buf = 0x1fff116c; +_symrom_g_tx_ext_adv_buf = 0x1fff1278; +_symrom_tx_scanRsp_desc = 0x1fff1384; +_symrom_g_rx_adv_buf = 0x1fff1490; diff --git a/arch/arm/src/phy62xx/ble/controller/ll.h b/arch/arm/src/phy62xx/ble/controller/ll.h new file mode 100644 index 00000000000..703247a2f24 --- /dev/null +++ b/arch/arm/src/phy62xx/ble/controller/ll.h @@ -0,0 +1,3479 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/******************************************************************************* + Filename: ll.h + Revised: + Revision: + + Description: This file contains the Link Layer (LL) API for the Bluetooth + Low Energy (BLE) Controller. It provides the defines, types, + and functions for all supported Bluetooth Low Energy (BLE) + commands. + + This API is based on the Bluetooth Core Specification, + V4.0.0, Vol. 6. + + +*******************************************************************************/ + +#ifndef LL_H +#define LL_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + INCLUDES +*/ +#include "bcomdef.h" +#include "timer.h" +#include "ll_def.h" +/******************************************************************************* + MACROS +*/ + +// check if connection parameter ranges for CI (min/max), SL, and LSTO are valid +#define LL_INVALID_CONN_TIME_PARAM( ciMin, ciMax, sl, lsto ) \ + (((ciMin) < LL_CONN_INTERVAL_MIN) || \ + ((ciMin) > LL_CONN_INTERVAL_MAX) || \ + ((ciMax) < LL_CONN_INTERVAL_MIN) || \ + ((ciMax) > LL_CONN_INTERVAL_MAX) || \ + ((ciMax) < (ciMin)) || \ + ((sl) > LL_SLAVE_LATENCY_MAX) || \ + ((lsto) < LL_CONN_TIMEOUT_MIN) || \ + ((lsto) > LL_CONN_TIMEOUT_MAX)) + +// check if the CI/SL/LSTO combination is valid +// based on: LSTO > (1 + Slave Latency) * (Connection Interval * 2) +// Note: The CI * 2 requirement based on ESR05 V1.0, Erratum 3904. +// Note: LSTO time is normalized to units of 1.25ms (i.e. 10ms = 8 * 1.25ms). +#define LL_INVALID_CONN_TIME_PARAM_COMBO( ci, sl, lsto ) \ + ((uint32)((lsto)*8) <= ((uint32)(1+(sl)) * (uint32)((ci)*2))) + +#define LL_TIME_DELTA(T1, T2) ((T2 >= T1) ? (T2 - T1) : (BASE_TIME_UNITS - T1 + T2)) + + +/******************************************************************************* + CONSTANTS +*/ + +/* +** LL API Status Codes +** +** Note: These status values map directly to the HCI Error Codes. +** Per the Bluetooth Core Specification, V4.0.0, Vol. 2, Part D. +*/ +#define LL_STATUS_SUCCESS 0x00 // Success +#define LL_STATUS_ERROR_UNKNOWN_CONN_HANDLE 0x02 // Unknown Connection Identifier +#define LL_STATUS_ERROR_INACTIVE_CONNECTION 0x02 // Unknown Connection Identifier for now; may be needed for multiple connections +#define LL_STATUS_ERROR_AUTH_FAILURE 0x05 // Authentication Failure +#define LL_STATUS_ERROR_PIN_OR_KEY_MISSING 0x06 // Pin or Key Missing +#define LL_STATUS_ERROR_OUT_OF_CONN_RESOURCES 0x07 // Memory Capacity Exceeded +#define LL_STATUS_ERROR_OUT_OF_TX_MEM 0x07 // Memory Capacity Exceeded +#define LL_STATUS_ERROR_OUT_OF_RX_MEM 0x07 // Memory Capacity Exceeded +#define LL_STATUS_ERROR_OUT_OF_HEAP 0x07 // Memory Capacity Exceeded +#define LL_STATUS_ERROR_WL_TABLE_FULL 0x07 // Memory Capacity Exceeded +#define LL_STATUS_ERROR_RL_TABLE_FULL 0x07 // Memory Capacity Exceeded +#define LL_STATUS_ERROR_PAL_TABLE_FULL 0x07 // Memory Capacity Exceeded +#define LL_STATUS_ERROR_TX_DATA_QUEUE_FULL 0x07 // Memory Capacity Exceeded +#define LL_STATUS_ERROR_TX_DATA_QUEUE_EMPTY 0x07 // Memory Capacity Exceeded +#define LL_STATUS_ERROR_CONNECTION_TIMEOUT 0x08 // Connection Timeout +#define LL_STATUS_ERROR_CONNECTION_LIMIT_EXCEEDED 0x09 // Connection Limit Exceeded +#define LL_STATUS_ERROR_COMMAND_DISALLOWED 0x0C // Command Disallowed +#define LL_STATUS_ERROR_DUE_TO_LIMITED_RESOURCES 0x0D // Command Rejected Due To Limited Resources +#define LL_STATUS_ERROR_DUE_TO_DELAYED_RESOURCES 0x0D // Command Delayed Due To Limited Resources +#define LL_STATUS_ERROR_FEATURE_NOT_SUPPORTED 0x11 // Unsupported Feature or Parameter Value +#define LL_STATUS_ERROR_UNEXPECTED_PARAMETER 0x12 // Invalid HCI Command Parameters +#define LL_STATUS_ERROR_ILLEGAL_PARAM_COMBINATION 0x12 // Invalid HCI Command Parameters +#define LL_STATUS_ERROR_BAD_PARAMETER 0x12 // Invalid HCI Command Parameters or 0x30: Parameter Out of Mandatory Range? +#define LL_STATUS_ERROR_UNKNOWN_ADV_EVT_TYPE 0x12 // Invalid HCI Command Parameters or 0x30: Parameter Out of Mandatory Range? +#define LL_STATUS_ERROR_PEER_TERM 0x13 // Remote User Terminated Connection +#define LL_STATUS_ERROR_PEER_DEVICE_TERM_LOW_RESOURCES 0x14 // Remote Device Terminated Connection Due To Low Resources +#define LL_STATUS_ERROR_PEER_DEVICE_TERM_POWER_OFF 0x15 // Remote Device Terminated Connection Due To Power Off +#define LL_STATUS_ERROR_HOST_TERM 0x16 // Connection Terminated By Local Host +#define LL_STATUS_ERROR_UNSUPPORTED_REMOTE_FEATURE 0x1A // Unsupported Remote Feature + +// 2020-01-23 add error Code +#define LL_STATUS_ERROR_INVALID_LMP_LL_PARAMETER 0x1E + +#define LL_STATUS_ERROR_WL_ENTRY_NOT_FOUND 0x1F // Unspecified Error +#define LL_STATUS_ERROR_WL_TABLE_EMPTY 0x1F // Unspecified Error +#define LL_STATUS_ERROR_RL_ENTRY_NOT_FOUND 0x1F // Unspecified Error +#define LL_STATUS_ERROR_RL_TABLE_EMPTY 0x1F // Unspecified Error +#define LL_STATUS_ERROR_RNG_FAILURE 0x1F // Unspecified Error +#define LL_STATUS_ERROR_DISCONNECT_IMMEDIATE 0x1F // Unspecified Error +#define LL_STATUS_ERROR_DATA_PACKET_QUEUED 0x1F // Unspecified Error + +// 2020-01-23 add error Code +#define LL_STATUS_ERROR_UNSUPPORT_LMP_LL_PARAMETER 0x20 + +#define LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE 0x21 // Role Change Not Allowed +#define LL_STATUS_ERROR_LL_TIMEOUT 0x22 // Link Layer Response Timeout +#define LL_STATUS_ERROR_LL_TIMEOUT_HOST 0x22 // Link Layer Response Timeout +#define LL_STATUS_ERROR_LL_TIMEOUT_PEER 0x22 // Link Layer Response Timeout +#define LL_STATUS_ERROR_LL_PROCEDURE_COLLISION 0x23 // Link Layer Procedure collision + + +#define LL_STATUS_ERROR_INSTANT_PASSED 0x28 // Instant Passed +#define LL_STATUS_ERROR_INSTANT_PASSED_HOST 0x28 // Instant Passed +#define LL_STATUS_ERROR_INSTANT_PASSED_PEER 0x28 // Instant Passed +#define LL_STATUS_ERROR_KEY_PAIRING_NOT_SUPPORTED 0x29 // Pairing With Unit Key Not Supported +#define LL_STATUS_ERROR_DIFF_TRANSACTION_COLLISION 0x2A // Link Layer collision in same procedure + + +#define LL_STATUS_ERROR_NO_ADV_CHAN_FOUND 0x30 // Parameter Out Of Mandatory Range +#define LL_STATUS_ERROR_PARAM_OUT_OF_RANGE 0x30 // Parameter Out Of Mandatory Range +#define LL_STATUS_ERROR_UPDATE_CTRL_PROC_PENDING 0x3A // Controller Busy +#define LL_STATUS_ERROR_CTRL_PROC_ALREADY_ACTIVE 0x3A // Controller Busy +#define LL_STATUS_ERROR_VER_INFO_REQ_ALREADY_PENDING 0x3A // Controller Busy +#define LL_STATUS_ERROR_UNACCEPTABLE_CONN_INTERVAL 0x3B // Unacceptable Connection Interval +#define LL_STATUS_ERROR_DIRECTED_ADV_TIMEOUT 0x3C // Directed Advertising Timeout +#define LL_STATUS_ERROR_CONN_TERM_DUE_TO_MIC_FAILURE 0x3D // Connection Terminated Due To MIC Failure +#define LL_STATUS_ERROR_CONN_FAILED_TO_BE_ESTABLISHED 0x3E // Connection Failed To Be Established +#define LL_STATUS_ERROR_SYNC_FAILED_TO_BE_ESTABLISHED 0x3E // Connection Failed To Be Established +#define LL_STATUS_ERROR_CONN_TIMING_FAILURE 0x3F // MAC Connection Failed +#define LL_STATUS_ERROR_COARSE_CLK_ADJ_REJECT 0x40 // Coarse Clock Adjustment Rejected but Will Try to Adjust Using Clock Dragging +#define LL_STATUS_ERROR_TYPE0_SUBMAP_NOT_DEF 0x41 // Type0 Submap Not Defined +#define LL_STATUS_ERROR_UNKNOWN_ADV_ID 0x42 // Unknown Advertising Identifier +#define LL_STATUS_ERROR_LIMIT_REACHED 0x43 // Limit Reached +#define LL_STATUS_ERROR_OP_CANCEL_BY_HOST 0x44 // Operation Cancelled by Host +#define LL_STATUS_ERROR_PACKET_TOO_LONG 0x45 // Packet Too Long + +// Internal +#define LL_STATUS_DISABLE_LATENCY_INACTIVE_CONN 0x81 +#define LL_STATUS_DISABLE_LATENCY_DISABLED 0x82 +#define LL_STATUS_DISABLE_LATENCY_PENDING 0x83 +#define LL_STATUS_DISABLE_LATENCY_MISS_EVT 0x84 + +#define LL_STATUS_DISABLE_LATENCY_FAIL 0x8F +#define LL_STATUS_WARNING_WAITING_LLIRQ 0xFE // only used internally, so value doesn't matter + +#define LL_STATUS_WARNING_TX_DISABLED 0xFF // only used internally, so value doesn't matter +#define LL_STATUS_WARNING_FLAG_UNCHANGED 0xFF // only used internally, so value doesn't matter + +// Encryption Key Request Reason Codes +#define LL_ENC_KEY_REQ_ACCEPTED LL_STATUS_SUCCESS +#define LL_ENC_KEY_REQ_REJECTED LL_STATUS_ERROR_PIN_OR_KEY_MISSING +#define LL_ENC_KEY_REQ_UNSUPPORTED_FEATURE LL_STATUS_ERROR_UNSUPPORTED_REMOTE_FEATURE + +// Disconnect Reason Codes +#define LL_SUPERVISION_TIMEOUT_TERM LL_STATUS_ERROR_CONNECTION_TIMEOUT +#define LL_PEER_REQUESTED_TERM LL_STATUS_ERROR_PEER_TERM +#define LL_PEER_REQUESTED_LOW_RESOURCES_TERM LL_STATUS_ERROR_PEER_DEVICE_TERM_LOW_RESOURCES +#define LL_PEER_REQUESTED_POWER_OFF_TERM LL_STATUS_ERROR_PEER_DEVICE_TERM_POWER_OFF +#define LL_HOST_REQUESTED_TERM LL_STATUS_ERROR_HOST_TERM +#define LL_CTRL_PKT_TIMEOUT_TERM LL_STATUS_ERROR_LL_TIMEOUT +#define LL_CTRL_PKT_TIMEOUT_HOST_TERM LL_STATUS_ERROR_LL_TIMEOUT_HOST +#define LL_CTRL_PKT_TIMEOUT_PEER_TERM LL_STATUS_ERROR_LL_TIMEOUT_PEER +#define LL_CTRL_PKT_INSTANT_PASSED_TERM LL_STATUS_ERROR_INSTANT_PASSED +#define LL_CTRL_PKT_INSTANT_PASSED_HOST_TERM LL_STATUS_ERROR_INSTANT_PASSED_HOST +#define LL_CTRL_PKT_INSTANT_PASSED_PEER_TERM LL_STATUS_ERROR_INSTANT_PASSED_PEER +#define LL_UNACCEPTABLE_CONN_INTERVAL_TERM LL_STATUS_ERROR_UNACCEPTABLE_CONN_INTERVAL +#define LL_MIC_FAILURE_TERM LL_STATUS_ERROR_CONN_TERM_DUE_TO_MIC_FAILURE +#define LL_CONN_ESTABLISHMENT_FAILED_TERM LL_STATUS_ERROR_CONN_FAILED_TO_BE_ESTABLISHED + +// Disconnect API Parameter +#define LL_DISCONNECT_AUTH_FAILURE LL_STATUS_ERROR_AUTH_FAILURE +#define LL_DISCONNECT_REMOTE_USER_TERM LL_STATUS_ERROR_PEER_TERM +#define LL_DISCONNECT_REMOTE_DEV_LOW_RESOURCES LL_STATUS_ERROR_PEER_DEVICE_TERM_LOW_RESOURCES +#define LL_DISCONNECT_REMOTE_DEV_POWER_OFF LL_STATUS_ERROR_PEER_DEVICE_TERM_POWER_OFF +#define LL_DISCONNECT_UNSUPPORTED_REMOTE_FEATURE LL_STATUS_ERROR_UNSUPPORTED_REMOTE_FEATURE +#define LL_DISCONNECT_KEY_PAIRING_NOT_SUPPORTED LL_STATUS_ERROR_KEY_PAIRING_NOT_SUPPORTED +#define LL_DISCONNECT_UNACCEPTABLE_CONN_INTERVAL LL_STATUS_ERROR_UNACCEPTABLE_CONN_INTERVAL + + +// LL Advertiser Events +#define LL_ADV_CONNECTABLE_UNDIRECTED_EVT 0 +#define LL_ADV_CONNECTABLE_HDC_DIRECTED_EVT 1 // High Duty Cycle +#define LL_ADV_SCANNABLE_UNDIRECTED_EVT 2 +#define LL_ADV_NONCONNECTABLE_UNDIRECTED_EVT 3 +#define LL_ADV_CONNECTABLE_LDC_DIRECTED_EVT 4 // Low Duty Cycle + +// LL Address Type +#define LL_DEV_ADDR_TYPE_PUBLIC 0 +#define LL_DEV_ADDR_TYPE_RANDOM 1 +#define LL_DEV_ADDR_TYPE_RPA_PUBLIC 2 // Controller generates Resolvable Private Address based on the local IRK from resolving list. If resolving list contains no matching entry, use public address +#define LL_DEV_ADDR_TYPE_RPA_RANDOM 3 // Controller generates Resolvable Private Address based on the local IRK from resolving list. If resolving list contains no matching entry, use random address from LE_Set_Random_Address. + + + +// Advertiser White List Policy +#define LL_ADV_WL_POLICY_ANY_REQ 0 // any scan request or connect request +#define LL_ADV_WL_POLICY_WL_SCAN_REQ 1 // any connect request, white list scan request +#define LL_ADV_WL_POLICY_WL_CONNECT_REQ 2 // any scan request, white list connect request +#define LL_ADV_WL_POLICY_WL_ALL_REQ 3 // white list scan request and connect request + +// Scanner White List Policy +#define LL_SCAN_WL_POLICY_ANY_ADV_PKTS 0 +#define LL_SCAN_WL_POLICY_USE_WHITE_LIST 1 +#define LL_SCAN_WL_POLICY_BLE42_1 2 +#define LL_SCAN_WL_POLICY_BLE42_2 3 + + +// Initiator White List Policy +#define LL_INIT_WL_POLICY_USE_PEER_ADDR 0 +#define LL_INIT_WL_POLICY_USE_WHITE_LIST 1 + +// Black List Control +#define LL_SET_BLACKLIST_DISABLE 0 +#define LL_SET_BLACKLIST_ENABLE 1 + +// Advertiser Commands +#define LL_ADV_MODE_OFF 0 +#define LL_ADV_MODE_ON 1 +#define LL_ADV_MODE_RESERVED 2 + +// LL Scan Commands +#define LL_SCAN_STOP 0 +#define LL_SCAN_START 1 + +// LL Scan Filtering +#define LL_FILTER_REPORTS_DISABLE 0 +#define LL_FILTER_REPORTS_ENABLE 1 + +// LL Scan Types +#define LL_SCAN_PASSIVE 0 +#define LL_SCAN_ACTIVE 1 + +// LL Tx Power Types +#define LL_READ_CURRENT_TX_POWER_LEVEL 0 +#define LL_READ_MAX_TX_POWER_LEVEL 1 + +// Data Fragmentation Flag +#define LL_DATA_FIRST_PKT_HOST_TO_CTRL 0 +#define LL_DATA_CONTINUATION_PKT 1 +#define LL_DATA_FIRST_PKT_CTRL_TO_HOST 2 + +// Connection Complete Role +#define LL_LINK_CONNECT_COMPLETE_MASTER 0 +#define LL_LINK_CONNECT_COMPLETE_SLAVE 1 + +// Encryption Related +#define LL_ENCRYPTION_OFF 0 +#define LL_ENCRYPTION_ON 1 + +// Feature Set Related +#define LL_MAX_FEATURE_SET_SIZE 8 // in bytes +// +#define LL_FEATURE_RFU 0 // all bits in a byte +#define LL_FEATURE_ENCRYPTION 1 // byte 0, bit 0 +#define LL_FEATURE_EXT_REJECT_IND 4 // byte 0, bit 0 +#define LL_FEATURE_DATA_LENGTH_EXTENSION 0x20 // byte 0, bit 0 + +#define LL_FEATURE_2M_PHY 0x01 // byte 1, bit 0 +#define LL_FEATURE_CODED_PHY 0x08 // byte 1, bit 3 + +#define LL_FEATURE_CSA2 0x40 // byte 1, bit 6 + +// 2020-01-15 add +// CODE PHY feature +#define LL_FEATURE_CODE_PHY_IDX 1 // byte 1 +#define LL_FEATURE_CODE_PHY 0x08 +// extended advertisingCTE feature +#define LL_FEATURE_EXT_ADV_IDX 1 +#define LL_FEATURE_EXT_ADV 0x10 +// periodic advertising +#define LL_FEATURE_PRD_ADV_IDX 1 +#define LL_FEATURE_PRD_ADV 0x20 +// Channel selection Algorithm #2 +#define LL_FEATURE_CSA2_IDX 1 +#define LL_FEATURE_CSA2 0x40 + +// CTE FEATURE +#define LL_CTE_FEATURE_IDX 2 +#define LL_CONN_CTE_REQ 0x02 +#define LL_CONN_CTE_RSP 0x04 +#define LL_CONNLESS_CTE_TRANSMITER 0x08 +#define LL_CONNLESS_CTE_RECEIVER 0x10 +#define LL_AOD_SUPPORT 0x20 +#define LL_AOA_SUPPORT 0x40 + + +// Receive Flow Control +#define LL_DISABLE_RX_FLOW_CONTROL 0 +#define LL_ENABLE_RX_FLOW_CONTROL 1 + +// Direct Test Mode +#define LL_DIRECT_TEST_NUM_RF_CHANS 40 // PHY_NUM_RF_CHANS +#define LL_DIRECT_TEST_MAX_PAYLOAD_LEN 37 +// +#define LL_DIRECT_TEST_PAYLOAD_PRBS9 0 +#define LL_DIRECT_TEST_PAYLOAD_0x0F 1 +#define LL_DIRECT_TEST_PAYLOAD_0x55 2 +#define LL_DIRECT_TEST_PAYLOAD_PRBS15 3 +#define LL_DIRECT_TEST_PAYLOAD_0xFF 4 +#define LL_DIRECT_TEST_PAYLOAD_0x00 5 +#define LL_DIRECT_TEST_PAYLOAD_0xF0 6 +#define LL_DIRECT_TEST_PAYLOAD_0xAA 7 +#define LL_DIRECT_TEST_PAYLOAD_UNDEFINED 0xFF +// +#define LL_DIRECT_TEST_MODE_TX 0 +#define LL_DIRECT_TEST_MODE_RX 1 +// +#define LL_RF_RSSI_UNDEFINED PHY_RSSI_VALUE_INVALID + +// Vendor Specific +#define LL_EXT_RX_GAIN_STD 0 +#define LL_EXT_RX_GAIN_HIGH 1 +// +#define LL_EXT_TX_POWER_MINUS_23_DBM 0 +#define LL_EXT_TX_POWER_MINUS_6_DBM 1 +#define LL_EXT_TX_POWER_0_DBM 2 +#define LL_EXT_TX_POWER_4_DBM 3 + + +// +#define LL_EXT_DISABLE_ONE_PKT_PER_EVT 0 +#define LL_EXT_ENABLE_ONE_PKT_PER_EVT 1 +// +#define LL_EXT_DISABLE_CLK_DIVIDE_ON_HALT 0 +#define LL_EXT_ENABLE_CLK_DIVIDE_ON_HALT 1 +// +#define LL_EXT_NV_NOT_IN_USE 0 +#define LL_EXT_NV_IN_USE 1 +// +#define LL_EXT_DISABLE_FAST_TX_RESP_TIME 0 +#define LL_EXT_ENABLE_FAST_TX_RESP_TIME 1 +// +#define LL_EXT_DISABLE_SL_OVERRIDE 0 +#define LL_EXT_ENABLE_SL_OVERRIDE 1 +// +#define LL_EXT_TX_MODULATED_CARRIER 0 +#define LL_EXT_TX_UNMODULATED_CARRIER 1 +// +#define LL_EXT_SET_FREQ_TUNE_DOWN 0 +#define LL_EXT_SET_FREQ_TUNE_UP 1 + +// +#define LL_EXT_PER_RESET 0 +#define LL_EXT_PER_READ 1 +// +#define LL_EXT_HALT_DURING_RF_DISABLE 0 +#define LL_EXT_HALT_DURING_RF_ENABLE 1 +// +#define LL_EXT_SET_USER_REVISION 0 +#define LL_EXT_READ_BUILD_REVISION 1 +// +#define LL_EXT_RESET_SYSTEM_DELAY 100 // in ms +#define LL_EXT_RESET_SYSTEM_HARD 0 +#define LL_EXT_RESET_SYSTEM_SOFT 1 +// +#define LL_EXT_DISABLE_OVERLAPPED_PROCESSING 0 +#define LL_EXT_ENABLE_OVERLAPPED_PROCESSING 1 +// +#define LL_EXT_DISABLE_NUM_COMPL_PKTS_ON_EVENT 0 +#define LL_EXT_ENABLE_NUM_COMPL_PKTS_ON_EVENT 1 + + +/* +** Event Parameters +*/ + +// Advertising Report Data +#define LL_ADV_RPT_ADV_IND LL_ADV_CONNECTABLE_UNDIRECTED_EVT +#define LL_ADV_RPT_ADV_DIRECT_IND LL_ADV_CONNECTABLE_HDC_DIRECTED_EVT +#define LL_ADV_RPT_ADV_SCANNABLE_IND LL_ADV_SCANNABLE_UNDIRECTED_EVT +#define LL_ADV_RPT_ADV_NONCONN_IND LL_ADV_NONCONNECTABLE_UNDIRECTED_EVT +#define LL_ADV_RPT_SCAN_RSP (LL_ADV_NONCONNECTABLE_UNDIRECTED_EVT + 1) +#define LL_ADV_RPT_INVALID 0xFF +// +#define LL_RSSI_NOT_AVAILABLE 127 + +// Sleep Clock Accuracy (SCA) +#define LL_SCA_500_PPM 0 +#define LL_SCA_250_PPM 1 +#define LL_SCA_150_PPM 2 +#define LL_SCA_100_PPM 3 +#define LL_SCA_75_PPM 4 +#define LL_SCA_50_PPM 5 +#define LL_SCA_30_PPM 6 +#define LL_SCA_20_PPM 7 + + +// Default SCA +//#define LL_SCA_MASTER_DEFAULT 5 // 50ppm (ordinal value) +#define LL_SCA_MASTER_DEFAULT 0 // 500ppm (ordinal value) +#define LL_SCA_SLAVE_DEFAULT 500 // 500ppm + +// LL Advertiser Channels +#define LL_ADV_CHAN_37 1 +#define LL_ADV_CHAN_38 2 +#define LL_ADV_CHAN_39 4 +#define LL_ADV_CHAN_ALL (LL_ADV_CHAN_37 | LL_ADV_CHAN_38 | LL_ADV_CHAN_39) +#define LL_ADV_CHAN_MAP_DEFAULT LL_ADV_CHAN_ALL + +#define LL_ADV_CHAN_FIRST 37 +#define LL_ADV_CHAN_LAST 39 + +// max future number of events for an update to parameters or data channel +#define LL_MAX_UPDATE_COUNT_RANGE 32767 + +// Extended Header Flags +#define LE_EXT_HDR_ADVA_PRESENT_BITMASK 0x01 +#define LE_EXT_HDR_TARGETA_PRESENT_BITMASK 0x02 +#define LE_EXT_HDR_CTE_INFO_PRESENT_BITMASK 0x04 +#define LE_EXT_HDR_ADI_PRESENT_BITMASK 0x08 +#define LE_EXT_HDR_AUX_PTR_PRESENT_BITMASK 0x10 +#define LE_EXT_HDR_SYNC_INFO_PRESENT_BITMASK 0x20 +#define LE_EXT_HDR_TX_PWR_PRESENT_BITMASK 0x40 +#define LE_EXT_HDR_RFU_PRESENT_BITMASK 0x80 + + + +// extended advertisement Macros +#define LE_ADV_PROP_CONN_BITMASK 0x00000001 +#define LE_ADV_PROP_SCAN_BITMASK 0x00000002 +#define LE_ADV_PROP_DIRECT_BITMASK 0x00000004 +#define LE_ADV_PROP_HI_DC_CONN_BITMASK 0x00000008 +#define LE_ADV_PROP_LEGACY_BITMASK 0x00000010 +#define LE_ADV_PROP_ANON_BITMASK 0x00000020 // applicable to extended adv only +#define LE_ADV_PROP_TX_POWER_BITMASK 0x00000040 // applicable to extended adv & periodic adv + +/* TODO: update according to spec + 0x00 Intermediate fragment of fragmented extended advertising data + 0x01 First fragment of fragmented extended advertising data + 0x02 Last fragment of fragmented extended advertising data + 0x03 Complete extended advertising data + 0x04 Unchanged data (just update the Advertising DID) */ + +#define BLE_EXT_ADV_OP_INTERM_FRAG 0x00 +#define BLE_EXT_ADV_OP_FIRST_FRAG 0x01 +#define BLE_EXT_ADV_OP_LAST_FRAG 0x02 +#define BLE_EXT_ADV_OP_COMPLETE_DATA 0x03 +#define BLE_EXT_ADV_OP_UNCHANGED_DATA 0x04 + +#define BLE_EXT_ADV_FRAG_ENABLED 0x00 +#define BLE_EXT_ADV_FRAG_DISABLED 0x01 + +#define LL_EXT_ADV_MODE_NOCONN_NOSC 0 +#define LL_EXT_ADV_MODE_AUX_CONN_RSP 0 +#define LL_EXT_ADV_MODE_CONN 1 +#define LL_EXT_ADV_MODE_SC 2 +#define LL_EXT_ADV_MODE_RFU 3 + +// AuxPtr +// channel Idx(6bits) | CA(1bit) | offset Unit(1 bit) | Aux offset(13bits) | Aux PHY +#define LL_AUX_PTR_CHN_IDX_SHIFT 0 +#define LL_AUX_PTR_CA_SHIFT 6 +#define LL_AUX_PTR_OFFSET_UNIT_SHIFT 7 +#define LL_AUX_PTR_AUX_OFFSET_SHIFT 8 +#define LL_AUX_PTR_AUX_PHY_SHIFT 21 + +#define LL_AUX_PTR_CHN_IDX_MASK 0x3F +#define LL_AUX_PTR_CA_MASK 0x1 +#define LL_AUX_PTR_OFFSET_UNIT_MASK 0x1 +#define LL_AUX_PTR_AUX_OFFSET_MASK 0x1FFF +#define LL_AUX_PTR_AUX_PHY_MASK 0x7 + + +// for Periodic scanner +#define LL_PERIODIC_ADV_CREATE_SYNC_USING_ADV_LIST_BITMASK 0x00000001 +#define LL_PERIODIC_ADV_CREATE_SYNC_INIT_RPT_DISABLE_BITMASK 0x00000002 + +/* +** Miscellaneous +*/ +#define BLE_PKT40_LEN 42 +#define BLE_PKT51_LEN 262 + +#define BLE_PKT_VERSION_4_0 0 +#define BLE_PKT_VERSION_5_1 1 + + +//====== add after BBB ROM code release +#define LL_EXT_ADV_PROP_ADV_IND 0x13 //0b00010011 +#define LL_EXT_ADV_PROP_ADV_LDC_ADV 0x15 //0b00010101 +#define LL_EXT_ADV_PROP_ADV_HDC_ADV 0x1d //0b00011101 +#define LL_EXT_ADV_PROP_ADV_SCAN_IND 0x12 //0b00010010 +#define LL_EXT_ADV_PROP_ADV_NOCONN_IND 0x10 //0b00010000 + +#define LL_CHN_SEL_ALGORITHM_1 0 +#define LL_CHN_SEL_ALGORITHM_2 1 + + +/******************************************************************************* + TYPEDEFS +*/ + + + +/******************************************************************************* + LOCAL VARIABLES +*/ + +/******************************************************************************* + GLOBAL VARIABLES +*/ +/******************************************************************************* + LL OSAL Functions +*/ + +/******************************************************************************* + @fn LL_Init + + @brief This is the Link Layer task initialization called by OSAL. It + must be called once when the software system is started and + before any other function in the LL API is called. + + input parameters + + @param taskId - Task identifier assigned by OSAL. + + output parameters + + @param None. + + @return None. +*/ +extern void LL_Init( uint8 taskId ); + + +/******************************************************************************* + @fn LL_ProcessEvent + + @brief This is the Link Layer process event handler called by OSAL. + + input parameters + + @param taskId - Task identifier assigned by OSAL. + events - Event flags to be processed by this task. + + output parameters + + @param None. + + @return Unprocessed event flags. +*/ +extern uint16 LL_ProcessEvent( uint8 task_id, uint16 events ); + + +/******************************************************************************* + LL API for HCI +*/ + +/******************************************************************************* + @fn LL_TX_bm_alloc API + + @brief This API is used to allocate memory using buffer management. + + Note: This function should never be called by the application. + It is only used by HCI and L2CAP_bm_alloc. + + input parameters + + @param size - Number of bytes to allocate from the heap. + + output parameters + + @param None. + + @return Pointer to buffer, or NULL. +*/ +extern void* LL_TX_bm_alloc( uint16 size ); + + +/******************************************************************************* + @fn LL_RX_bm_alloc API + + @brief This API is used to allocate memory using buffer management. + + Note: This function should never be called by the application. + It is only used by HCI and L2CAP_bm_alloc. + + input parameters + + @param size - Number of bytes to allocate from the heap. + + output parameters + + @param None. + + @return Pointer to buffer, or NULL. +*/ +extern void* LL_RX_bm_alloc( uint16 size ); + + +/******************************************************************************* + @fn LL_Reset API + + @brief This function is used by the HCI to reset and initialize the + LL Controller. + + input parameters + + @param None. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS +*/ +extern llStatus_t LL_Reset( void ); + + +/******************************************************************************* + @fn LL_ReadBDADDR API + + @brief This API is called by the HCI to read the controller's + own public device address. + + Note: The device's address is stored in NV memory. + + input parameters + + @param None. + + output parameters + + @param bdAddr - A pointer to a buffer to hold this device's address. + + @return LL_STATUS_SUCCESS +*/ +extern llStatus_t LL_ReadBDADDR( uint8* bdAddr ); + + +/******************************************************************************* + + @fn LL_SetRandomAddress API + + @brief This function is used to save this device's random address. It + is provided by the Host for devices that are unable to store a + IEEE assigned public address in NV memory. + + input parameters + + @param devAddr - Pointer to a random address (LSO..MSO). + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS + +*/ +extern llStatus_t LL_SetRandomAddress( uint8* devAddr ); + +/******************************************************************************* + @fn LL_ClearWhiteList API + + @brief This API is called by the HCI to clear the White List. + + Note: If Scanning is enabled using filtering, and the white + list policy is "Any", then this command will be + disallowed. + + input parameters + + @param None. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS +*/ +extern llStatus_t LL_ClearWhiteList( void ); + + +/******************************************************************************* + @fn LL_AddWhiteListDevice API + + @brief This API is called by the HCI to add a device address and its + type to the White List. + + input parameters + + @param devAddr - Pointer to a 6 byte device address. + @param addrType - Public or Random device address. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_WL_TABLE_FULL +*/ +extern llStatus_t LL_AddWhiteListDevice( uint8* devAddr, + uint8 addrType ); + +/******************************************************************************* + @fn LL_RemoveWhiteListDevice API + + @brief This API is called by the HCI to remove a device address and + it's type from the White List. + + input parameters + + @param devAddr - Pointer to a 6 byte device address. + @param addrType - Public or Random device address. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_WL_TABLE_EMPTY, + LL_STATUS_ERROR_WL_ENTRY_NOT_FOUND +*/ +extern llStatus_t LL_RemoveWhiteListDevice( uint8* devAddr, + uint8 addrType ); + + +/******************************************************************************* + @fn LL_ReadWlSize API + + @brief This API is called by the HCI to get the total number of white + list entries that can be stored in the Controller. + + input parameters + + @param None. + + output parameters + + @param *numEntries - Total number of available White List entries. + + @return LL_STATUS_SUCCESS +*/ +extern llStatus_t LL_ReadWlSize( uint8* numEntries ); + + +/******************************************************************************* + @fn LL_NumEmptyWlEntries API + + @brief This API is called by the HCI to get the number of White List + entries that are empty. + + input parameters + + @param None. + + output parameters + + @param *numEmptyEntries - number of empty entries in the White List. + + @return LL_STATUS_SUCCESS +*/ +extern llStatus_t LL_NumEmptyWlEntries( uint8* numEmptyEntries ); + + +/******************************************************************************* + @fn LL_Encrypt API + + @brief This API is called by the HCI to request the LL to encrypt the + data in the command using the key given in the command. + + Note: The parameters are byte ordered MSO to LSO. + + input parameters + + @param *key - A 128 bit key to be used to calculate the + session key. + @param *plaintextData - A 128 bit block that is to be encrypted. + + output parameters + + @param *encryptedData - A 128 bit block that is encrypted. + + @param None. + + @return LL_STATUS_SUCCESS +*/ +extern llStatus_t LL_Encrypt( uint8* key, + uint8* plaintextData, + uint8* encryptedData ); + + +/******************************************************************************* + @fn LL_Rand API + + @brief This API is called by the HCI to request the LL Controller to + provide a data block with random content. + + Note: If the radio is in use, then this operation has to be + delayed until the radio finishes. + + input parameters + + @param *randData - Pointer to buffer to place a random block of data. + @param dataLen - The length of the random data block, from 1-255. + + output parameters + + @param *randData - Pointer to buffer containing a block of true random + data. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_DUE_TO_LIMITED_RESOURCES, + LL_STATUS_ERROR_COMMAND_DISALLOWED, + LL_STATUS_ERROR_BAD_PARAMETER, LL_STATUS_ERROR_RNG_FAILURE +*/ +extern llStatus_t LL_Rand( uint8* randData, + uint8 dataLen ); + + +/******************************************************************************* + @fn LL_ReadSupportedStates API + + @brief This function is used to provide the HCI with the Link Layer + supported states and supported state/role combinations. + + input parameters + + @param None. + + output parameters + + @param *states - Eight byte Bit map of supported states/combos. + + @return LL_STATUS_SUCCESS +*/ +extern llStatus_t LL_ReadSupportedStates( uint8* states ); + + +/******************************************************************************* + @fn LL_ReadLocalSupportedFeatures API + + @brief This API is called by the HCI to read the controller's + Features Set. The Controller indicates which features it + supports. + + input parameters + + @param featureSet - A pointer to the Feature Set where each bit: + 0: Feature not supported. + 1: Feature supported by controller. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS +*/ +extern llStatus_t LL_ReadLocalSupportedFeatures( uint8* featureSet ); + + +/******************************************************************************* + @fn LL_ReadLocalVersionInfo API + + @brief This API is called by the HCI to read the controller's + Version information. + + input parameters + + @param None. + + output parameters + + @param verNum - Version of the Bluetooth Controller specification. + @param comId - Company identifier of the manufacturer of the + Bluetooth Controller. + @param subverNum - A unique value for each implementation or revision + of an implementation of the Bluetooth Controller. + + @return LL_STATUS_SUCCESS +*/ +extern llStatus_t LL_ReadLocalVersionInfo( uint8* verNum, + uint16* comId, + uint16* subverNum ); + + +/******************************************************************************* + @fn LL_CtrlToHostFlowControl API + + @brief This function is used to indicate if the LL enable/disable + receive FIFO processing. This function provides support for + Controller to Host flow control. + + input parameters + + @param mode: LL_ENABLE_RX_FLOW_CONTROL, LL_DISABLE_RX_FLOW_CONTROL + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS +*/ +extern llStatus_t LL_CtrlToHostFlowControl( uint8 mode ); + +/******************************************************************************* + @fn LL_ReadRemoteVersionInfo API + + @brief This API is called by the HCI to read the peer controller's + Version Information. If the peer's Version Information has + already been received by its request for our Version + Information, then this data is already cached and can be + directly returned to the Host. If the peer's Version Information + is not already cached, then it will be requested from the peer, + and when received, returned to the Host via the + LL_ReadRemoteVersionInfoCback callback. + + Note: Only one Version Indication is allowed for a connection. + + input parameters + + @param None. + + output parameters + + @param connId - The LL connection ID on which to send this data. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_VER_IND_ALREADY_SENT +*/ +extern llStatus_t LL_ReadRemoteVersionInfo( uint16 connId ); + +/******************************************************************************* + @fn LL_ReadTxPowerLevel + + @brief This function is used to read a connection's current transmit + power level or the maximum transmit power level. + + input parameters + + @param connId - The LL connection handle. + @param type - LL_READ_CURRENT_TX_POWER_LEVEL or + LL_READ_MAX_TX_POWER_LEVEL + @param *txPower - A signed value from -30..+20, in dBm. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_PARAM_OUT_OF_RANGE, + LL_STATUS_ERROR_INACTIVE_CONNECTION +*/ +llStatus_t LL_ReadTxPowerLevel( uint8 connId, + uint8 type, + int8* txPower ); + +// A1 ROM metal change add +/******************************************************************************* + @fn LL_SetTxPowerLevel + + @brief This function is used to set transmit power level + + input parameters + + @param txPower - The transmit power level to be set + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_INACTIVE_CONNECTION +*/ +llStatus_t LL_SetTxPowerLevel( int8 txPower ); + +/******************************************************************************* + @fn LL_ReadChanMap API + + @brief This API is called by the HCI to read the channel map that the + LL controller is using for the LL connection. + + input parameters + + @param connId - The LL connection handle. + + output parameters + + @param chanMap - A five byte array containing one bit per data channel + where a 1 means the channel is "used" and a 0 means + the channel is "unused". + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_INACTIVE_CONNECTION +*/ +extern llStatus_t LL_ReadChanMap( uint8 connId, + uint8* chanMap ); + + + +/******************************************************************************* + @fn LL_ReadRssi API + + @brief This API is called by the HCI to request RSSI. If there is an + active connection for the given connection ID, then the RSSI of + the last received data packet in the LL will be returned. If a + receiver Modem Test is running, then the RF RSSI for the last + received data will be returned. If no valid RSSI value is + available, then LL_RSSI_NOT_AVAILABLE will be returned. + + input parameters + + @param connId - The LL connection ID on which to read last RSSI. + + output parameters + + @param *lastRssi - The last data RSSI received. + Range: -127dBm..+20dBm, 127=Not Available. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_INACTIVE_CONNECTION +*/ +extern llStatus_t LL_ReadRssi( uint16 connId, + int8* lastRssi ); +extern llStatus_t LL_ReadFoff( uint16 connId, + uint16* foff ); +extern llStatus_t LL_ReadCarrSens( uint16 connId, + uint8* carrSense ); + +/******************************************************************************* + @fn LL_Disconnect API + + @brief This API is called by the HCI to terminate a LL connection. + + input parameters + + @param connId - The LL connection ID on which to send this data. + @param reason - The reason for the Host connection termination. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_INACTIVE_CONNECTION + LL_STATUS_ERROR_CTRL_PROC_ALREADY_ACTIVE +*/ +extern llStatus_t LL_Disconnect( uint16 connId, + uint8 reason ); + +/******************************************************************************* + @fn LL_TxData API + + @brief This API is called by the HCI to transmit a buffer of data on a + given LL connection. If fragmentation is supported, the HCI must + also indicate whether this is the first Host packet, or a + continuation Host packet. When fragmentation is not supported, + then a start packet should always specified. If the device is in + a connection as a Master and the current connection ID is the + connection for this data, or is in a connection as a Slave, then + the data is written to the TX FIFO (even if the radio is + curerntly active). If this is a Slave connection, and Fast TX is + enabled and Slave Latency is being used, then the amount of time + to the next event is checked. If there's at least a connection + interval plus some overhead, then the next event is re-aligned + to the next event boundary. Otherwise, in all cases, the buffer + pointer will be retained for transmission, and the callback + event LL_TxDataCompleteCback will be generated to the HCI when + the buffer pointer is no longer needed by the LL. + + Note: If the return status is LL_STATUS_ERROR_OUT_OF_TX_MEM, + then the HCI must not release the buffer until it receives + the LL_TxDataCompleteCback callback, which indicates the + LL has copied the transmit buffer. + + Note: The HCI should not call this routine if a buffer is still + pending from a previous call. This is fatal! + + Note: If the connection should be terminated within the LL + before the Host knows, attempts by the HCI to send more + data (after receiving a LL_TxDataCompleteCback) will + fail (LL_STATUS_ERROR_INACTIVE_CONNECTION). + + input parameters + + @param connId - The LL connection ID on which to send this data. + @param *pBuf - A pointer to the data buffer to transmit. + @param pktLen - The number of bytes to transmit on this connection. + @param fragFlag - LL_DATA_FIRST_PKT_HOST_TO_CTRL: + Indicates buffer is the start of a + Host-to-Controller packet. + LL_DATA_CONTINUATION_PKT: + Indicates buffer is a continuation of a + Host-to-Controller packet. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_INACTIVE_CONNECTION, + LL_STATUS_ERROR_OUT_OF_TX_MEM, + LL_STATUS_ERROR_UNEXPECTED_PARAMETER +*/ +extern llStatus_t LL_TxData( uint16 connId, + uint8* pBuf, + uint8 pktLen, + uint8 fragFlag ); + + +/******************************************************************************* + @fn LL_DirectTestTxTest API + + @brief This function is used to initiate a BLE PHY level Transmit Test + in Direct Test Mode where the DUT generates test reference + packets at fixed intervals. This test will make use of the + nanoRisc Raw Data Transmit and Receive task. + + Note: The BLE device is to transmit at maximum power. + Note: A LL reset should be issued when done using DTM! + + input parameters + + @param txFreq - Tx RF frequency k=0..39, where F=2402+(k*2MHz). + @param payloadLen - Number of bytes (0..37)in payload for each packet. + @param payloadType - The type of pattern to transmit. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE +*/ +extern llStatus_t LL_DirectTestTxTest( uint8 txFreq, + uint8 payloadLen, + uint8 payloadType ); + + +/******************************************************************************* + @fn LL_DirectTestRxTest API + + @brief This function is used to initiate a BLE PHY level Receive Test + in Direct Test Mode where the DUT receives test reference + packets at fixed intervals. This test will make use of the + nanoRisc Raw Data Transmit and Receive task. The received + packets are verified based on the CRC, and metrics are kept. + + Note: A LL reset should be issued when done using DTM! + + input parameters + + @param rxFreq - Rx RF frequency k=0..39, where F=2402+(k*2MHz). + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE +*/ +extern llStatus_t LL_DirectTestRxTest( uint8 rxFreq ); + + +/******************************************************************************* + @fn LL_DirectTestEnd API + + @brief This function is used to end the Direct Test Transmit or Direct + Test Receive tests executing in Direct Test mode. When the raw + task is ended, the LL_DirectTestEndDoneCback callback is called. + If a Direct Test mode operation is not currently active, an + error is returned. + + Note: A LL reset is issued upon completion! + + input parameters + + @param None. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE +*/ +extern llStatus_t LL_DirectTestEnd( void ); + + +/******************************************************************************* + @fn LL_SetAdvParam API + + @brief This API is called by the HCI to set the Advertiser's + parameters. + + input parameters + @param advIntervalMin - The minimum Adv interval. + @param advIntervalMax - The maximum Adv interval. + @param advEvtType - The type of advertisment event. + @param ownAddrType - The Adv's address type of public or random. + @param directAddrType - Only used for directed advertising. + @param *directAddr - Only used for directed advertising (NULL otherwise). + @param advChanMap - A byte containing 1 bit per advertising + channel. A bit set to 1 means the channel is + used. The bit positions define the advertising + channels as follows: + Bit 0: 37, Bit 1: 38, Bit 2: 39. + @param advWlPolicy - The Adv white list filter policy. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_NO_ADV_CHAN_FOUND +*/ +extern llStatus_t LL_SetAdvParam( uint16 advIntervalMin, + uint16 advIntervalMax, + uint8 advEvtType, + uint8 ownAddrType, + uint8 directAddrType, + uint8* directAddr, + uint8 advChanMap, + uint8 advWlPolicy ); + +/******************************************************************************* + @fn LL_SetAdvData API + + @brief This API is called by the HCI to set the Advertiser's data. + + Note: If the Advertiser is restarted without intervening calls + to this routine to make updates, then the previously + defined data will be reused. + + Note: If the data happens to be changed while advertising, then + the new data will be sent on the next advertising event. + + input parameters + + @param advDataLen - The number of scan response bytes: 0..31. + @param advData - Pointer to the advertiser data, or NULL. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER +*/ +extern llStatus_t LL_SetAdvData( uint8 advDataLen, + uint8* advData ); + +/******************************************************************************* + @fn LL_SetScanRspData API + + @brief This API is called by the HCI to set the Advertiser's Scan + Response data. + + Note: If the Advertiser is restarted without intervening calls + to this routine to make updates, then the previously + defined data will be reused. + + input parameters + + @param scanRspLen - The number of scan response bytes: 0..31. + @param *scanRspData - Pointer to the scan response data. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER +*/ +extern llStatus_t LL_SetScanRspData( uint8 scanRspLen, + uint8* scanRspData ); + +/******************************************************************************* + @fn LL_SetAdvControl API + + @brief This API is called by the HCI to request the Controller to start + or stop advertising. + + input parameters + + @param advMode - LL_ADV_MODE_ON or LL_ADV_MODE_OFF. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_UNEXPECTED_PARAMETER, + LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE, + LL_STATUS_ERROR_COMMAND_DISALLOWED +*/ +extern llStatus_t LL_SetAdvControl( uint8 advMode ); + +/******************************************************************************* + @fn LL_ReadAdvChanTxPower + + @brief This function is used to read the transmit power level used + for BLE advertising channel packets. Currently, only two + settings are possible, a standard setting of 0 dBm, and a + maximum setting of 4 dBm. + + input parameters + + @param *txPower - A non-null pointer. + + output parameters + + @param *txPower - A signed value from -20..+10, in dBm. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_PARAM_OUT_OF_RANGE +*/ +extern llStatus_t LL_ReadAdvChanTxPower( int8* txPower ); + +/******************************************************************************* + @fn LL_SetScanParam API + + @brief This API is called by the HCI to set the Scanner's parameters. + + input parameters + + @param scanType - Passive or Active scan type. + @param scanInterval - Time between scan events. + @param scanWindow - Duration of a scan. When the same as the scan + interval, then scan continuously. + @param ownAddrType - Address type (Public or Random) to use in the + SCAN_REQ packet. + @param advWlPolicy - Either allow all Adv packets, or only those that + are in the white list. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER +*/ +extern llStatus_t LL_SetScanParam( uint8 scanType, + uint16 scanInterval, + uint16 scanWindow, + uint8 ownAddrType, + uint8 advWlPolicy ); + +/******************************************************************************* + @fn LL_SetScanControl API + + @brief This API is called by the HCI to start or stop the Scanner. It + also specifies whether the LL will filter duplicate advertising + reports to the Host, or generate a report for each packet + received. + + input parameters + + @param scanMode - LL_SCAN_START or LL_SCAN_STOP. + @param filterReports - LL_FILTER_REPORTS_DISABLE or + LL_FILTER_REPORTS_ENABLE + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_UNEXPECTED_PARAMETER, + LL_STATUS_ERROR_OUT_OF_TX_MEM, + LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE +*/ +extern llStatus_t LL_SetScanControl( uint8 scanMode, + uint8 filterReports ); + +/******************************************************************************* + @fn LL_EncLtkReply API + + @brief This API is called by the HCI to provide the controller with + the Long Term Key (LTK) for encryption. This command is + actually a reply to the link layer's LL_EncLtkReqCback, which + provided the random number and encryption diversifier received + from the Master during an encryption setup. + + Note: The key parameter is byte ordered LSO to MSO. + + input parameters + + @param connId - The LL connection ID on which to send this data. + @param *key - A 128 bit key to be used to calculate the session key. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS +*/ +extern llStatus_t LL_EncLtkReply( uint16 connId, + uint8* key ); + +/******************************************************************************* + @fn LL_EncLtkNegReply API + + @brief This API is called by the HCI to indicate to the controller + that the Long Term Key (LTK) for encryption can not be provided. + This command is actually a reply to the link layer's + LL_EncLtkReqCback, which provided the random number and + encryption diversifier received from the Master during an + encryption setup. How the LL responds to the negative reply + depends on whether this is part of a start encryption or a + re-start encryption after a pause. For the former, an + encryption request rejection is sent to the peer device. For + the latter, the connection is terminated. + + input parameters + + @param connId - The LL connection ID on which to send this data. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS +*/ +extern llStatus_t LL_EncLtkNegReply( uint16 connId ); + +/******************************************************************************* + @fn LL_CreateConn API + + @brief This API is called by the HCI to create a connection. + + input parameters + + @param scanInterval - The scan interval. + @param scanWindow - The scan window. + @param initWlPolicy - Filter Adv address directly or using WL. + @param peerAddrType - Peer address is Public or Random. + @param *peerAddr - The Adv address, or NULL for WL policy. + @param ownAddrType - This device's address is Public or Random. + @param connIntervalMin - Defines minimum connection interval value. + @param connIntervalMax - Defines maximum connection interval value. + @param connLatency - The connection's Slave Latency. + @param connTimeout - The connection's Supervision Timeout. + @param minLength - Info parameter about min length of connection. + @param maxLength - Info parameter about max length of connection. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE, + LL_STATUS_ERROR_ILLEGAL_PARAM_COMBINATION, + LL_STATUS_ERROR_BAD_PARAMETER +*/ +extern llStatus_t LL_CreateConn( uint16 scanInterval, + uint16 scanWindow, + uint8 initWlPolicy, + uint8 peerAddrType, + uint8* peerAddr, + uint8 ownAddrType, + uint16 connIntervalMin, + uint16 connIntervalMax, + uint16 connLatency, + uint16 connTimeout, + uint16 minLength, + uint16 maxLength ); + +/******************************************************************************* + @fn LL_CreateConnCancel API + + @brief This API is called by the HCI to cancel a previously given LL + connection creation command that is still pending. This command + should only be used after the LL_CreateConn command as been + issued, but before the LL_ConnComplete callback. + + input parameters + + @param None. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_COMMAND_DISALLOWED +*/ +extern llStatus_t LL_CreateConnCancel( void ); + +/******************************************************************************* + @fn LL_ConnActive + + @brief This API is called by the HCI to check if a connection + given by the connection handle is active. + + input parameters + + @param connId - Connection handle. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_INACTIVE_CONNECTION +*/ +extern llStatus_t LL_ConnActive( uint16 connId ); + +/******************************************************************************* + @fn LL_ConnUpdate API + + @brief This API is called by the HCI to update the connection + parameters by initiating a connection update control procedure. + + input parameters + + @param connId - The connection ID on which to send this data. + @param connIntervalMin - Defines minimum connection interval value. + @param connIntervalMax - Defines maximum connection interval value. + @param connLatency - The connection's Slave Latency. + @param connTimeout - The connection's Supervision Timeout. + @param minLength - Info parameter about min length of connection. + @param maxLength - Info parameter about max length of connection. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_INACTIVE_CONNECTION + LL_STATUS_ERROR_CTRL_PROC_ALREADY_ACTIVE, + LL_STATUS_ERROR_ILLEGAL_PARAM_COMBINATION +*/ +extern llStatus_t LL_ConnUpdate( uint16 connId, + uint16 connIntervalMin, + uint16 connIntervalMax, + uint16 connLatency, + uint16 connTimeout, + uint16 minLength, + uint16 maxLength ); + +/******************************************************************************* + @fn LL_ChanMapUpdate API + + @brief This API is called by the HCI to update the Host data channels + initiating an Update Data Channel control procedure. + + Note: While it isn't specified, it is assumed that the Host + expects an update channel map on all active connections. + + Note: This LL currently only supports one connection. + + input parameters + + @param chanMap - A five byte array containing one bit per data channel + where a 1 means the channel is "used". + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_ILLEGAL_PARAM_COMBINATION +*/ +extern llStatus_t LL_ChanMapUpdate( uint8* chanMap ); + +/******************************************************************************* + @fn LL_StartEncrypt API + + @brief This API is called by the Master HCI to setup encryption and to + update encryption keys in the LL connection. If the connection + is already in encryption mode, then this command will first + pause the encryption before subsequently running the encryption + setup. + + Note: The parameters are byte ordered LSO to MSO. + + input parameters + + @param connId - The LL connection ID on which to send this data. + @param *rand - Random vector used in device identification. + @param *eDiv - Encrypted diversifier. + @param *key - A 128 bit key to be used to calculate the session key. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_FEATURE_NOT_SUPPORTED +*/ +extern llStatus_t LL_StartEncrypt( uint16 connId, + uint8* rand, + uint8* eDiv, + uint8* ltk ); + +/******************************************************************************* + @fn LL_ReadRemoteUsedFeatures API + + @brief This API is called by the Master HCI to initiate a feature + setup control process. + + input parameters + + @param connId - The LL connection ID on which to send this data. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS +*/ +extern llStatus_t LL_ReadRemoteUsedFeatures( uint16 connId ); + + +/* +** Vendor Specific Command API +*/ + +/******************************************************************************* + @fn LL_EXT_SetRxGain Vendor Specific API + + @brief This function is used to to set the RF RX gain. + + input parameters + + @param rxGain - LL_EXT_RX_GAIN_STD, LL_EXT_RX_GAIN_HIGH + + output parameters + + @param cmdComplete - Boolean to indicate the command is still pending. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER +*/ +extern llStatus_t LL_EXT_SetRxGain( uint8 rxGain, + uint8* cmdComplete ); + + +/******************************************************************************* + @fn LL_EXT_SetTxPower Vendor Specific API + + @brief This function is used to to set the RF TX power. + + input parameters + + @param txPower - LL_EXT_TX_POWER_0_DBM, LL_EXT_TX_POWER_4_DBM + + output parameters + + @param cmdComplete - Boolean to indicate the command is still pending. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER +*/ +extern llStatus_t LL_EXT_SetTxPower( uint8 txPower, + uint8* cmdComplete ); + + + +/******************************************************************************* + @fn LL_EXT_OnePacketPerEvent Vendor Specific API + + @brief This function is used to enable or disable allowing only one + packet per event. + + input parameters + + @param control - LL_EXT_ENABLE_ONE_PKT_PER_EVT, + LL_EXT_DISABLE_ONE_PKT_PER_EVT + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER +*/ +extern llStatus_t LL_EXT_OnePacketPerEvent( uint8 control ); + + + +/******************************************************************************* + @fn LL_EXT_ClkDivOnHalt Vendor Specific API + + @brief This function is used to enable or disable dividing down the + system clock while halted. + + Note: This command is disallowed if haltDuringRf is not defined. + + input parameters + + @param control - LL_EXT_ENABLE_CLK_DIVIDE_ON_HALT, + LL_EXT_DISABLE_CLK_DIVIDE_ON_HALT + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_COMMAND_DISALLOWED +*/ +extern llStatus_t LL_EXT_ClkDivOnHalt( uint8 control ); + + +/******************************************************************************* + @fn LL_EXT_DeclareNvUsage Vendor Specific API + + @brief This HCI Extension API is used to indicate to the Controller + whether or not the Host will be using the NV memory during BLE + operations. + + input parameters + + @param mode - HCI_EXT_NV_IN_USE, HCI_EXT_NV_NOT_IN_USE + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_COMMAND_DISALLOWED +*/ +extern llStatus_t LL_EXT_DeclareNvUsage( uint8 mode ); + + +/******************************************************************************* + @fn LL_EXT_Decrypt API + + @brief This API is called by the HCI to request the LL to decrypt the + data in the command using the key given in the command. + + Note: The parameters are byte ordered MSO to LSO. + + input parameters + + @param *key - A 128 bit key to be used to calculate the + session key. + @param *encryptedData - A 128 bit block that is encrypted. + + output parameters + + @param *plaintextData - A 128 bit block that is to be encrypted. + + @param None. + + @return LL_STATUS_SUCCESS +*/ +extern llStatus_t LL_EXT_Decrypt( uint8* key, + uint8* encryptedData, + uint8* plaintextData ); + + +/******************************************************************************* + @fn LL_EXT_SetLocalSupportedFeatures API + + @brief This API is called by the HCI to indicate to the Controller + which features can or can not be used. + + Note: Not all features indicated by the Host to the Controller + are valid. If invalid, they shall be ignored. + + input parameters + + @param featureSet - A pointer to the Feature Set where each bit: + 0: Feature shall not be used. + 1: Feature can be used. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS +*/ +extern llStatus_t LL_EXT_SetLocalSupportedFeatures( uint8* featureSet ); + + +/******************************************************************************* + @fn LL_EXT_SetFastTxResponseTime API + + @brief This API is used to enable or disable the fast TX response + time feature. This can be helpful when a short connection + interval is used in combination with slave latency. In such + a scenario, the response time for sending the TX data packet + can effectively shorten or eliminate slave latency, thereby + increasing power consumption. By disabling, this feature + trades fast response time for less power consumption. + + input parameters + + @param control - LL_EXT_ENABLE_FAST_TX_RESP_TIME, + LL_EXT_DISABLE_FAST_TX_RESP_TIME + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_COMMAND_DISALLOWED, + LL_STATUS_ERROR_BAD_PARAMETER +*/ +extern llStatus_t LL_EXT_SetFastTxResponseTime( uint8 control ); + +/******************************************************************************* + @fn LL_EXT_SetSlaveLatencyOverride API + + @brief This API is used to enable or disable the suspention of slave + latency. This can be helpful when the Slave application knows + it will soon receive something that needs to be handled without + delay. + + input parameters + + @param control - LL_EXT_DISABLE_SL_OVERRIDE, + LL_EXT_ENABLE_SL_OVERRIDE + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_COMMAND_DISALLOWED, + LL_STATUS_ERROR_BAD_PARAMETER +*/ +extern llStatus_t LL_EXT_SetSlaveLatencyOverride( uint8 control ); + +/******************************************************************************* + @fn LL_EXT_ModemTestTx + + @brief This API is used start a continuous transmitter modem test, + using either a modulated or unmodulated carrier wave tone, at + the frequency that corresponds to the specified RF channel. Use + LL_EXT_EndModemTest command to end the test. + + Note: A LL reset will be issued by LL_EXT_EndModemTest! + Note: The BLE device will transmit at maximum power. + Note: This API can be used to verify this device meets Japan's + TELEC regulations. + + input parameters + + @param cwMode - LL_EXT_TX_MODULATED_CARRIER, + LL_EXT_TX_UNMODULATED_CARRIER + txFreq - Transmit RF channel k=0..39, where BLE F=2402+(k*2MHz). + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE +*/ +extern llStatus_t LL_EXT_ModemTestTx( uint8 cwMode, + uint8 txFreq ); + + +/******************************************************************************* + @fn LL_EXT_ModemHopTestTx + + @brief This API is used to start a continuous transmitter direct test + mode test using a modulated carrier wave and transmitting a + 37 byte packet of Pseudo-Random 9-bit data. A packet is + transmitted on a different frequency (linearly stepping through + all RF channels 0..39) every 625us. Use LL_EXT_EndModemTest + command to end the test. + + Note: A LL reset will be issued by LL_EXT_EndModemTest! + Note: The BLE device will transmit at maximum power. + Note: This API can be used to verify this device meets Japan's + TELEC regulations. + + input parameters + + @param None. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE +*/ +extern llStatus_t LL_EXT_ModemHopTestTx( void ); + + +/******************************************************************************* + @fn LL_EXT_ModemTestRx + + @brief This API is used to start a continuous receiver modem test + using a modulated carrier wave tone, at the frequency that + corresponds to the specific RF channel. Any received data is + discarded. Receiver gain may be adjusted using the + LL_EXT_SetRxGain command. RSSI may be read during this test by + using the LL_ReadRssi command. Use LL_EXT_EndModemTest command + to end the test. + + Note: A LL reset will be issued by LL_EXT_EndModemTest! + Note: The BLE device will transmit at maximum power. + + input parameters + + @param rxFreq - Receiver RF channel k=0..39, where BLE F=2402+(k*2MHz). + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE +*/ +extern llStatus_t LL_EXT_ModemTestRx( uint8 rxFreq ); + + +/******************************************************************************* + @fn LL_EXT_EndModemTest + + @brief This API is used to shutdown a modem test. A complete link + layer reset will take place. + + input parameters + + @param None. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE +*/ +extern llStatus_t LL_EXT_EndModemTest( void ); + + +/******************************************************************************* + @fn LL_EXT_SetBDADDR + + @brief This API is used to set this device's BLE address (BDADDR). + + Note: This command is only allowed when the device's state is + Standby. + + input parameters + + @param bdAddr - A pointer to a buffer to hold this device's address. + An invalid address (i.e. all FF's) will restore this + device's address to the address set at initialization. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_COMMAND_DISALLOWED +*/ +extern llStatus_t LL_EXT_SetBDADDR( uint8* bdAddr ); + + +/******************************************************************************* + @fn LL_EXT_SetSCA + + @brief This API is used to set this device's Sleep Clock Accuracy. + + Note: For a slave device, this value is directly used, but only + if power management is enabled. For a master device, this + value is converted into one of eight ordinal values + representing a SCA range, as specified in Table 2.2, + Vol. 6, Part B, Section 2.3.3.1 of the Core specification. + + Note: This command is only allowed when the device is not in a + connection. + + Note: The device's SCA value remains unaffected by a HCI_Reset. + + input parameters + + @param scaInPPM - This device's SCA in PPM from 0..500. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER, + LL_STATUS_ERROR_COMMAND_DISALLOWED +*/ +extern llStatus_t LL_EXT_SetSCA( uint16 scaInPPM ); + + +/******************************************************************************* + @fn LL_EXT_SetFreqTune + + @brief This API is used to set the Frequncy Tuning up or down. If the + current setting is already at the max/min value, then no + update is performed. + + Note: This is a Production Test Mode only command! + + input parameters + + @param step - LL_EXT_SET_FREQ_TUNE_UP or LL_EXT_SET_FREQ_TUNE_DOWN + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER +*/ +extern llStatus_t LL_EXT_SetFreqTune( uint8 step ); + + +/******************************************************************************* + @fn LL_EXT_SaveFreqTune + + @brief This API is used to save the current Frequency Tuning value to + flash memory. It is restored on reboot or wake from sleep. + + Note: This is a Production Test Mode only command! + + input parameters + + @param None. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_COMMAND_DISALLOWED +*/ +extern llStatus_t LL_EXT_SaveFreqTune( void ); + + +/******************************************************************************* + @fn LL_EXT_SetMaxDtmTxPower Vendor Specific API + + @brief This function is used to set the max RF TX power to be used + when using Direct Test Mode. + + input parameters + + @param txPower - LL_EXT_TX_POWER_MINUS_23_DBM, + LL_EXT_TX_POWER_MINUS_6_DBM, + LL_EXT_TX_POWER_0_DBM, + LL_EXT_TX_POWER_4_DBM + + output parameters + + @param cmdComplete - Boolean to indicate the command is still pending. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER +*/ +extern llStatus_t LL_EXT_SetMaxDtmTxPower( uint8 txPower ); + + + +/******************************************************************************* + @fn LL_EXT_DisconnectImmed Vendor Specific API + + @brief This function is used to disconnect the connection immediately. + + Note: The connection (if valid) is immediately terminated + without notifying the remote device. The Host is still + notified. + + input parameters + + @param connId - The LL connection ID on which to send this data. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_INACTIVE_CONNECTION +*/ +extern llStatus_t LL_EXT_DisconnectImmed( uint16 connId ); + +/******************************************************************************* + @fn LL_EXT_PacketErrorRate Vendor Specific API + + @brief This function is used to Reset or Read the Packet Error Rate + counters for a connection. When Reset, the counters are cleared; + when Read, the total number of packets received, the number of + packets received with a CRC error, the number of events, and the + number of missed events are returned via a callback. + + Note: The counters are only 16 bits. At the shortest connection + interval, this provides a bit over 8 minutes of data. + + input parameters + + @param connId - The LL connection ID on which to send this data. + @param command - LL_EXT_PER_RESET, LL_EXT_PER_READ + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_INACTIVE_CONNECTION +*/ +extern llStatus_t LL_EXT_PacketErrorRate( uint16 connId, uint8 command ); + +/******************************************************************************* + @fn LL_EXT_PERbyChan Vendor Specific API + + @brief This API is called by the HCI to start or end Packet Error Rate + by Channel counter accumulation for a connection. If the + pointer is not NULL, it is assumed there is sufficient memory + for the PER data, per the type perByChan_t. If NULL, then + the operation is considered disabled. + + Note: It is the user's responsibility to make sure there is + sufficient memory for the data, and that the counters + are cleared prior to first use. + + Note: The counters are only 16 bits. At the shortest connection + interval, this provides a bit over 8 minutes of data. + + input parameters + + @param connId - The LL connection ID on which to send this data. + @param perByChan - Pointer to PER by Channel data, or NULL. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_INACTIVE_CONNECTION +*/ +extern llStatus_t LL_EXT_PERbyChan( uint16 connId, perByChan_t* perByChan ); + + + +/******************************************************************************* + @fn LL_EXT_HaltDuringRf Vendor Specfic API + + @brief This function is used to enable or disable halting the + CPU during RF. The system defaults to enabled. + + input parameters + + @param mode - LL_EXT_HALT_DURING_RF_ENABLE, + LL_EXT_HALT_DURING_RF_DISABLE + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_COMMAND_DISALLOWED, + LL_STATUS_ERROR_BAD_PARAMETER +*/ +extern llStatus_t LL_EXT_HaltDuringRf( uint8 mode ); + +/******************************************************************************* + @fn LL_EXT_AdvEventNotice Vendor Specific API + + @brief This API is called to enable or disable a notification to the + specified task using the specified task event whenever a Adv + event ends. A non-zero taskEvent value is taken to be "enable", + while a zero valued taskEvent is taken to be "disable". + + input parameters + + @param taskID - User's task ID. + @param taskEvent - User's task event. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER +*/ +extern llStatus_t LL_EXT_AdvEventNotice( uint8 taskID, uint16 taskEvent ); + +/******************************************************************************* + @fn LL_EXT_ConnEventNotice Vendor Specific API + + @brief This API is called to enable or disable a notification to the + specified task using the specified task event whenever a + Connection event ends. A non-zero taskEvent value is taken to + be "enable", while a zero valued taskEvent is taken to be + "disable". + + Note: Currently, only a Slave connection is supported. + + input parameters + + @param taskID - User's task ID. + @param taskEvent - User's task event. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_INACTIVE_CONNECTION, + LL_STATUS_ERROR_BAD_PARAMETER +*/ +extern llStatus_t LL_EXT_ConnEventNotice( uint8 taskID, uint16 taskEvent ); + + + +/******************************************************************************* + @fn LL_EXT_BuildRevision Vendor Specific API + + @brief This API is used to to set a user revision number or read the + build revision number. + + input parameters + + @param mode - LL_EXT_SET_USER_REVISION | + LL_EXT_READ_BUILD_REVISION + @param userRevNum - A 16 bit value the user can set as their own + revision number + + output parameters + + @param buildRev - Pointer to returned build revision, if any. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER +*/ +extern llStatus_t LL_EXT_BuildRevision( uint8 mode, uint16 userRevNum, uint8* buildRev ); + + +/******************************************************************************* + @fn LL_EXT_DelaySleep Vendor Specific API + + @brief This API is used to to set the sleep delay. + + input parameters + + @param delay - 0 .. 1000, in milliseconds. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER +*/ +extern llStatus_t LL_EXT_DelaySleep( uint16 delay ); + + +/******************************************************************************* + @fn LL_EXT_ResetSystem Vendor Specific API + + @brief This API is used to to issue a soft or hard system reset. + + input parameters + + @param mode - LL_EXT_RESET_SYSTEM_HARD | LL_EXT_RESET_SYSTEM_SOFT + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_STATUS_ERROR_BAD_PARAMETER +*/ +extern llStatus_t LL_EXT_ResetSystem( uint8 mode ); + + +/******************************************************************************* + @fn LL_EXT_OverlappedProcessing Vendor Specific API + + @brief This API is used to enable or disable overlapped processing. + + input parameters + + @param mode - LL_EXT_ENABLE_OVERLAPPED_PROCESSING | + LL_EXT_DISABLE_OVERLAPPED_PROCESSING + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS +*/ +extern llStatus_t LL_EXT_OverlappedProcessing( uint8 mode ); + +/******************************************************************************* + @fn LL_EXT_NumComplPktsLimit Vendor Specific API + + @brief This API is used to set the minimum number of + completed packets which must be met before a Number of + Completed Packets event is returned. If the limit is not + reach by the end of the connection event, then a Number of + Completed Packets event will be returned (if non-zero) based + on the flushOnEvt flag. + + input parameters + + @param limit - From 1 to LL_MAX_NUM_DATA_BUFFERS. + @param flushOnEvt - LL_EXT_DISABLE_NUM_COMPL_PKTS_ON_EVENT | + LL_EXT_ENABLE_NUM_COMPL_PKTS_ON_EVENT + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS, LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS +*/ +extern llStatus_t LL_EXT_NumComplPktsLimit( uint8 limit, + uint8 flushOnEvt ); + + +/* +** LL Callbacks to HCI +*/ + +/******************************************************************************* + @fn LL_ConnectionCompleteCback Callback + + @brief This Callback is used by the LL to indicate to the Host that + a new connection has been created. For the Slave, this means + a CONNECT_REQ message was received from an Initiator. For the + Master, this means a CONNECT_REQ message was sent in response + to a directed or undirected message addressed to the Initiator. + + input parameters + + @param reasonCode - LL_STATUS_SUCCESS or ? + @param connId - The LL connection ID for new connection. + @param role - LL_LINK_CONNECT_COMPLETE_MASTER or + LL_LINK_CONNECT_COMPLETE_SLAVE. + @param peerAddrType - Peer address type (public or random). + @param peerAddr - Peer address. + @param connInterval - Connection interval. + @param slaveLatency - The connection's Slave Latency. + @param connTimeout - The connection's Supervision Timeout. + @param clockAccuracy - The sleep clock accurracy of the Master. Only + valid on the Slave. Set to 0x00 for the Master. + + output parameters + + @param None. + + @return None. +*/ +extern void LL_ConnectionCompleteCback( uint8 reasonCode, + uint16 connId, + uint8 role, + uint8 peerAddrType, + uint8* peerAddr, + uint16 connInterval, + uint16 slaveLatency, + uint16 connTimeout, + uint8 clockAccuracy ); + +/******************************************************************************* + @fn LL_DisconnectCback Callback + + @brief This Callback is used by the LL to indicate to the Host that + the connection has been terminated. The cause is given by the + reason code. + + input parameters + + @param connId - The LL connection ID. + @param reason - The reason the connection was terminated. + + output parameters + + @param None. + + @return None. +*/ +extern void LL_DisconnectCback( uint16 connId, + uint8 reason ); + +/******************************************************************************* + @fn LL_ConnParamUpdateCback Callback + + @brief This Callback is used by the LL to indicate to the Host that + the update parameters control procedure has completed. It is + always made to the Master's Host when the update request has + been sent. It is only made to the Slave's Host when the update + results in a change to the connection interval, and/or the + connection latency, and/or the connection timeout. + + input parameters + + @param connId - The LL connection ID. + @param connInterval - Connection interval. + @param connLatency - The connection's Slave Latency. + @param connTimeout - The connection's Supervision Timeout. + + output parameters + + @param None. + + @return None. +*/ +extern void LL_ConnParamUpdateCback( uint16 connId, + uint16 connInterval, + uint16 connLatency, + uint16 connTimeout ); + +/******************************************************************************* + @fn LL_ReadRemoteVersionInfoCback Callback + + @brief This Callback is used by the LL to indicate to the Host the + requested peer's Version information. + + input parameters + + @param status - Status of callback. + @param connId - The LL connection ID. + @param verNum - Version of the Bluetooth Controller specification. + @param comId - Company identifier of the manufacturer of the + Bluetooth Controller. + @param subverNum - A unique value for each implementation or revision + of an implementation of the Bluetooth Controller. + + output parameters + + @param None. + + @return None. +*/ +extern void LL_ReadRemoteVersionInfoCback( uint8 status, + uint16 connId, + uint8 verNum, + uint16 comId, + uint16 subverNum ); + +/******************************************************************************* + @fn LL_EncChangeCback Callback + + @brief This Callback is used by the LL to indicate to the Host that + an encryption change has taken place. This results when + the host performs a LL_StartEncrypt when encryption is not + already enabled. + + Note: If the key request was rejected, then encryption will + remain off. + + input parameters + + @param connId - The LL connection ID for new connection. + @param reason - LL_ENC_KEY_REQ_ACCEPTED or LL_ENC_KEY_REQ_REJECTED. + @param encEnab - LL_ENCRYPTION_OFF or LL_ENCRYPTION_ON. + + output parameters + + @param None. + + @return None. +*/ +extern void LL_EncChangeCback( uint16 connId, + uint8 reason, + uint8 encEnab ); + +/******************************************************************************* + @fn LL_EncKeyRefreshCback Callback + + @brief This Callback is used by the LL to indicate to the Host that + an encryption key change has taken place. This results when + the host performs a LL_StartEncrypt when encryption is already + enabled. + + input parameters + + @param connId - The LL connection ID for new connection. + @param reason - LL_ENC_KEY_REQ_ACCEPTED. + + output parameters + + @param None. + + @return None. +*/ +extern void LL_EncKeyRefreshCback( uint16 connId, + uint8 reason ); + +/******************************************************************************* + @fn LL_AdvReportCback Callback + + @brief This Callback is used by the LL to provide information about + advertisers from which an advertising packet was received. + + input parameters + + @param eventType - Type of advertisement packet received by Scanner + or Initiator, and scan response for Initiator. + @param advAddrType - Advertiser address type (public or random). + @param advAddr - Advertiser address. + @param dataLen - Size in bytes of advertisement packet. + @param data - Advertisement data. + @param rssi - RSSI value (-127..20dBm), or not available + + output parameters + + @param None. + + @return None. +*/ +extern void LL_AdvReportCback( uint8 eventType, + uint8 advAddrType, + uint8* advAddr, + uint8 dataLen, + uint8* data, + int8 rssi ); + +void LL_AdvSetTerminatedCback(uint8 status, + uint8 adv_handle, + uint16 connHandle, + uint8 Num_Completed_Extended_Advertising_Events); + +extern void LL_ExtAdvReportCback( uint8 advEvt, + uint8 advAddrType, + uint8* advAddr, + uint8 primaryPHY, + uint8 secondaryPHY, + uint8 advertisingSID, + uint8 txPower, + int8 rssi, + uint16 periodicAdvertisingInterval, + uint8 directAddrType, + uint8* directAddr, + uint8 dataLen, + uint8* rptData); + +void LL_PrdAdvReportCback(uint16 syncHandle, + uint8 txPower, + uint8 rssi, + uint8 cteType, + uint8 dataStatus, + uint8 dataLength, + uint8* data + ); + +void LL_PrdAdvSyncEstablishedCback(uint8 status, + uint16 syncHandle, + uint8 advertisingSID, + uint8 advertiserAddressType, + uint8* advertiserAddress, + uint8 advertiserPHY, + uint16 periodicAdvertisingInterval, + uint8 advertiserClockAccuracy + ); + +void LL_PrdAdvSyncLostCback(uint16 syncHandle); + +void LL_ChannelSelectionAlgorithmCback(uint16 connHandle, + uint8 chnSel + ); + +void LL_EnhConnectionCompleteCback( uint8 reasonCode, + uint16 connHandle, + uint8 role, + uint8 peerAddrType, + uint8* peerAddr, + uint8* localRpaAddr, + uint8* peerRpaAddr, + uint16 connInterval, + uint16 slaveLatency, + uint16 connTimeout, + uint8 clockAccuracy ); + +/****************************************************************************** + fn: LL_ConnectionlessIQReportCback + + brief: 1ã€usd by the controller to report IQ Information from the CTE of the + received advertising packet + 2ã€report IQ Information from the CTE of a received Test Mode packet + + date:2020-01-14 + + input parameters: + syncHandle : Identifying the periodic advertising train + chan_idx : the index of the channel on which the packet has received + rssi : rssi of the packet , units 0.1 dBm + rssi_antID : Antenna ID + cte_type : AOA/AOD CTE Type, AOD with 1us or 2us slots + slot_duration : switching and sampling slots with 1us or 2us + packet_status : indicates whether the received packet had a valid CRC + and if not , whether the controller has determined the + position and size of the CTE + PE_Cnt : the value of paEventCounter + sampCnt : total number of sample pairs + ISample : the list of the I Sample of the report packets + QSample : the list of the Q Sample of the report packets + + + output parameters: + + Note: Controller shall not generate this event for packets that have a bad CRC + + return hciStatus_t + + ******************************************************************************/ +void LL_ConnectionlessIQReportCback( uint16 syncHandle, + uint8 chan_idx, + int16 rssi, + uint8 rssi_antID, + uint8 cte_type, + uint8 slot_duration, + uint8 packet_status, + uint16 PE_Cnt, + uint8 sampCnt, + uint16* ISample, + uint16* QSample); + + +/***************************************************************************************** + fn: LL_ConnectionIQReportCback + + date:2020-01-14 + + brief: used by the controller to report the IQ samples from the CTE of a received packet. + + input parameters: + connHandle : identifies the connections that corresponds to the reported information + rx_PHY : receiver PHY for the connection 1M or 2M + data_chan_idx: the index of data channel on which the data physical channel PDU has received + rssi : rssi of the packet , units 0.1 dBm + rssi_antID : id of the antenna on which the RSSI is measured + cte_type : AOA/AOD CTE Type, AOD with 1us or 2us slots + slot_duration: switching and sampling slots with 1us or 2us + packet_status: indicates whether the received packet had a valid CRC + and if not , whether the controller has determined the + position and size of the CTE + connEventCounter:the value of connection event counter + sampCnt : total number of sample pairs + ISample : the list of the I Sample of the report packets + QSample : the list of the Q Sample of the report packets + + + output parameters: + + + return hciStatus_t + + *****************************************************************************************/ +void LL_ConnectionIQReportCback( uint16 connHandle, + uint8 rx_PHY, + uint8 data_chan_idx, + int16 rssi, + uint8 rssi_antID, + uint8 cte_type, + uint8 slot_duration, + uint8 packet_status, + uint16 connEventCounter, + uint8 sampCnt, + uint16* ISample, + uint16* QSample); + + +/***************************************************************************************** + fn: LL_CTE_Report_FailedCback + + date:2020-01-14 + + brief: used by the controller to report an issue following a request to a peer device + to reply with a packet containing an LL_CTE_RSP PDU and a CTE + + + input parameters: + status : received LL_CTE_RSP PDU status + connHandle : connection handle + + output parameters: + + + return hciStatus_t + + *****************************************************************************************/ +void LL_CTE_Report_FailedCback( uint8 status,uint16 connHandle); + +/******************************************************************************* + @fn LL_ReadRemoteUsedFeaturesCompleteCback Callback + + @brief This Callback is used by the LL to indicate to the Host that + the Read Remote Feature Support command as completed. + + input parameters + + @param status - SUCCESS or control procedure timeout. + @param connId - The LL connection ID for new connection. + @param featureSet - A pointer to the Feature Set. + + output parameters + + @param None. + + @return None. +*/ +extern void LL_ReadRemoteUsedFeaturesCompleteCback( uint8 status, + uint16 connId, + uint8* featureSet ); + + + +/******************************************************************************* + @fn LL_EncLtkReqCback Callback + + @brief This Callback is used by the LL to provide to the Host the + Master's random number and encryption diversifier, and to + request the Host's Long Term Key (LTK). + + input parameters + + @param connId - The LL connection ID for new connection. + @param randNum - Random vector used in device identification. + @param encDiv - Encrypted diversifier. + + output parameters + + @param None. + + @return None. +*/ +extern void LL_EncLtkReqCback( uint16 connId, + uint8* randNum, + uint8* encDiv ); + + +/******************************************************************************* + @fn LL_DirectTestEndDone Callback + + @brief This Callback is used by the LL to notify the HCI that the + Direct Test End command has completed. + + + input parameters + + @param numPackets - The number of packets received. Zero for transmit. + @param mode - LL_DIRECT_TEST_MODE_TX or LL_DIRECT_TEST_MODE_RX. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS +*/ +extern void LL_DirectTestEndDoneCback( uint16 numPackets, + uint8 mode ); + +/******************************************************************************* + @fn LL_DataLengthChange Callback + + +*/ + +extern void LL_DataLengthChangeCback(uint16 connHandle, + uint16 MaxTxOctets, + uint16 MaxTxTime, + uint16 MaxRxOctets, + uint16 MaxRxTime); + + +/******************************************************************************* + @fn LL_TxDataCompleteCback Callback + + @brief This Callback is used by the LL to indicate to the HCI that + the HCI's buffer is free for its own use again. + + input parameters + + @param connId - The LL connection ID on which to send this data. + @param *pBuf - A pointer to the data buffer to transmit, or NULL. + + output parameters + + @param None. + + @return None. + ******************************************************************************/ +extern void LL_TxDataCompleteCback( uint16 connId, + uint8* pBuf ); + +/******************************************************************************* + @fn LL_RxDataCompleteCback Callback + + @brief This Callback is used by the LL to indicate to the HCI that + data has been received and placed in the buffer provided by + the HCI. + + input parameters + + @param connId - The LL connection ID on which data was received. + @param *pBuf - A pointer to the receive data buffer provided by + the HCI. + @param len - The number of bytes received on this connection. + @param fragFlag - LL_DATA_FIRST_PKT indicates buffer is the start of + a Host packet. + LL_DATA_CONTINUATION_PKT: Indicates buffer is a + continuation of a Host packet. + @param rssi - The RSSI of this received packet as a signed byte. + Range: -127dBm..+20dBm, 127=Not Available. + + output parameters + + @param **pBuf - A double pointer updated to the next receive data + buffer, or NULL if no next buffer is available. + + @return None. +*/ +extern void LL_RxDataCompleteCback( uint16 connId, + uint8* ppBuf, + uint8 len, + uint8 fragFlag, + int8 rssi ); + + + +/******************************************************************************* + @fn LL_RandCback API + + @brief This Callback is used by the LL to notify the HCI that the true + random number command has been completed. + + Note: The length is always given by B_RANDOM_NUM_SIZE. + + input parameters + + @param *randData - Pointer to buffer to place a random block of data. + + output parameters + + @param None. + + @return None. +*/ +extern void LL_RandCback( uint8* randData ); + + +/******************************************************************************* + @fn LL_EXT_SetRxGainCback Callback + + @brief This Callback is used by the LL to notify the HCI that the set + RX gain command has been completed. + + input parameters + + @param None. + + output parameters + + @param None. + + @return None. +*/ +extern void LL_EXT_SetRxGainCback( void ); + + +/******************************************************************************* + @fn LL_EXT_SetTxPowerCback Callback + + @brief This Callback is used by the LL to notify the HCI that the set + TX power command has been completed. + + input parameters + + @param None. + + output parameters + + @param None. + + @return None. +*/ +extern void LL_EXT_SetTxPowerCback( void ); + + +/******************************************************************************* + @fn LL_EXT_PacketErrorRateCback Callback + + @brief This Callback is used by the LL to notify the HCI that the + Packet Error Rate Read command has been completed. + + Note: The counters are only 16 bits. At the shortest connection + interval, this provides a bit over 8 minutes of data. + + input parameters + + @param numPkts - Number of Packets received. + @param numCrcErr - Number of Packets received with a CRC error. + @param numEvents - Number of Connection Events. + @param numPkts - Number of Missed Connection Events. + + output parameters + + @param None. + + @return None. +*/ +extern void LL_EXT_PacketErrorRateCback( uint16 numPkts, + uint16 numCrcErr, + uint16 numEvents, + uint16 numMissedEvts ); + + +/******************************************************************************* + @fn LL_EXT_ExtendRfRangeCback Callback + + @brief This Callback is used by the LL to notify the HCI that the + Extend Rf Range command has been completed. + + input parameters + + @param None. + + output parameters + + @param None. + + @return None. +*/ +//extern void LL_EXT_ExtendRfRangeCback( void ); + +/******************************************************************************* + @fn LL_PLUS_PerStats_Init + + @brief Used to init linklayer per stats + + input parameters + + @param None. + + output parameters + + @param None. + + @return None. +*/ +extern void LL_PLUS_PerStats_Init(perStatsByChan_t* p_per); +/******************************************************************************* + @fn LL_PLUS_PerStatsReset + + @brief Used to reset linklayer per stats + + input parameters + + @param None. + + output parameters + + @param None. + + @return None. +*/ +extern void LL_PLUS_PerStatsReset(void); + + +/******************************************************************************* + @fn LL_PLUS_PerStasReadByChn + + @brief read per stats by data channel id + + input parameters + + @param None. + + output parameters + + @param None. + + @return None. +*/ +extern void LL_PLUS_PerStasReadByChn(uint8 chnId,perStats_t* perStats); + +extern LL_PLUS_AdvDataFilterCB_t LL_PLUS_AdvDataFilterCBack; +extern void LL_PLUS_SetAdvDataFilterCB(LL_PLUS_AdvDataFilterCB_t AdvDataFilterCBack); +extern uint8_t* LL_PLUS_GetAdvDataExtendData(void); +extern void LL_PLUS_SetScanRequestData(uint8 dLen,uint8* pData); + + +extern LL_PLUS_ScanRequestFilterCB_t LL_PLUS_ScanRequestFilterCBack; +extern void LL_PLUS_SetScanRequestFilterCB(LL_PLUS_ScanRequestFilterCB_t ScanRequestFilterCBack); +extern uint8 LL_PLUS_GetScanRequestExtendData(uint8* pData); +extern void LL_PLUS_GetScanerAddr(uint8* pData); +extern void LL_PLUS_SetScanRsqData(uint8 dLen,uint8* pData); + +extern void LL_PLUS_SetScanRsqDataByIndex(uint8 dIdx,uint8 data); + + + +//DLE +extern llStatus_t LL_SetDataLengh( uint16 connId,uint16 TxOctets,uint16 TxTime ); +//extern uint8 LL_PLUS_GetLocalPduDataLength(ll_pdu_length_ctrl_t* pduLen); +extern llStatus_t LL_WriteSuggestedDefaultDataLength(uint16 TxOctets,uint16 TxTime); +extern void LL_DataLengthChangeCback( uint16 connHandle, + uint16 MaxTxOctets, + uint16 MaxTxTime, + uint16 MaxRxOctets, + uint16 MaxRxTime); + + + +//PHY UPDATE + +extern llStatus_t LL_SetDefaultPhyMode( uint16 connId,uint8 allPhy,uint8 txPhy, uint8 rxPhy); +extern llStatus_t LL_SetPhyMode( uint16 connId,uint8 allPhy,uint8 txPhy, uint8 rxPhy,uint16 phyOptions); + + +extern llStatus_t LL_PhyUpdate( uint16 connId ); +extern void LL_PhyUpdateCompleteCback( uint16 connHandle, + uint8 status, + uint8 txPhy, + uint8 rxPhy); + +// Resolving list +extern llStatus_t LL_AddResolvingListLDevice( uint8 addrType, + uint8* devAddr, + uint8* peerIrk, + uint8* localIrk); +extern llStatus_t LL_RemoveResolvingListDevice( uint8* devAddr, + uint8 addrType ); + +extern llStatus_t LL_ClearResolvingList( void ); + +extern llStatus_t LL_ReadPeerResolvableAddress( uint8* peerRpa ); + +extern llStatus_t LL_ReadLocalResolvableAddress( uint8* localRpa ); + +extern llStatus_t LL_ReadResolvingListSize( uint8* numEntries ); + +extern llStatus_t LL_SetAddressResolutionEnable( uint8 enable ); + + +extern llStatus_t LL_SetResolvablePrivateAddressTimeout( uint16 rpaTimeout ); + +extern llStatus_t LL_PLUS_DisableSlaveLatency(uint8 connId); + +extern llStatus_t LL_PLUS_EnableSlaveLatency(uint8 connId); + +// extended advertisement +llStatus_t LL_InitExtendedAdv( extAdvInfo_t* extAdvInfo, + uint8 extAdvNumber, + uint16 advSetMaxLen); +llStatus_t LL_SetExtAdvSetRandomAddress( uint8 adv_handle, + uint8* random_address); +llStatus_t LL_SetExtAdvParam( uint8 adv_handle, + uint16 adv_event_properties, + uint32 primary_advertising_interval_Min, // 3 octets + uint32 primary_advertising_interval_Max, // 3 octets + uint8 primary_advertising_channel_map, + uint8 own_address_type, + uint8 peer_address_type, + uint8* peer_address, + uint8 advertising_filter_policy, + int8 advertising_tx_power, + uint8 primary_advertising_PHY, + uint8 secondary_advertising_max_skip, + uint8 secondary_advertising_PHY, + uint8 advertising_SID, + uint8 scan_request_notification_enable, + int8* selectTxPwr); +llStatus_t LL_SetExtAdvData( uint8 adv_handle, + uint8 operation, + uint8 fragment_preference, + uint8 advertising_data_length, + uint8* advertising_data); +llStatus_t LL_SetExtScanRspData( uint8 adv_handle, + uint8 operation, + uint8 fragment_preference, + uint8 scan_rsp_data_length, + uint8* scan_rsp_data); +llStatus_t LL_SetExtAdvEnable(uint8 enable, + uint8 number_of_sets, + uint8* advertising_handle, + uint16* duration, + uint8* max_extended_advertising_events); +llStatus_t LL_ReadMaximumAdvDataLength( uint16* length ); +llStatus_t LL_ReadNumberOfSupportAdvSet( uint8* number ); +llStatus_t LL_RemoveAdvSet( uint8 adv_handle); +llStatus_t LL_ClearAdvSets(void); + +llStatus_t LL_SetExtendedScanParameters(uint8 own_address_type, + uint8 scanning_filter_policy, + uint8 scanning_PHYs, + uint8* scan_type, + uint16* scan_interval, + uint16* scan_window); +llStatus_t LL_SetExtendedScanEnable(uint8 enable, + uint8 filter_duplicates, + uint16 duration, + uint16 period); +llStatus_t LL_ExtendedCreateConnection(uint8 initiator_filter_policy, + uint8 own_address_type, + uint8 peer_address_type, + uint8* peer_address, + uint8 initiating_PHYs, + uint16* scan_interval, + uint16* scan_window, + uint16* conn_interval_min, + uint16* conn_interval_max, + uint16* conn_latency, + uint16* supervision_timeout, + uint16* minimum_CE_length, + uint16* maximum_CE_length); + + +// extended adv +void llSetupAdvExtIndPDU(extAdvInfo_t* pAdvInfo, periodicAdvInfo_t* pPrdAdv); + +void llSetupAuxAdvIndPDU(extAdvInfo_t* pAdvInfo, periodicAdvInfo_t* pPrdAdv); + +void llSetupAuxChainIndPDU(extAdvInfo_t* pAdvInfo, periodicAdvInfo_t* pPrdAdv); + +void llSetupAuxSyncIndPDU(extAdvInfo_t* pAdvInfo, periodicAdvInfo_t* pPrdAdv); + +void llSetupAuxConnectReqPDU(void); + +void llSetupAuxConnectRspPDU(extAdvInfo_t* pAdvInfo); + +void llSetupAuxScanRspPDU(extAdvInfo_t* pAdvInfo); + +uint8 ll_isLegacyAdv(extAdvInfo_t* pExtAdv); + +/******************************************************************************* + @fn LL_InitConnectContext + + @brief This function initialize the LL connection-orient context + + input parameters + + @param pConnContext - connection-orient context, the memory is allocated by application + maxConnNum - the size of connect-orient context + maxPktPerEventTx/Rx - number of packets transmit/receive per connection event + + output parameters + + @param None. + + @return None. +*/ +llStatus_t LL_InitConnectContext(llConnState_t* pConnContext, + uint8* pConnBuffer, + uint8 maxConnNum, + uint8 maxPktPerEventTx, + uint8 maxPktPerEventRx, + uint8 blePktVersion); + +// extended scan +llStatus_t LL_InitExtendedScan(uint8* scanDataBuffer, + uint16 scanDataBufferLength); + +llStatus_t LL_InitPeriodicAdv(extAdvInfo_t* extAdvInfo, + periodicAdvInfo_t* periodicAdvInfo, + uint8 periodicAdvSetNumber, + uint16 advSetMaxLen); + + +// Periodic Adv +llStatus_t LL_SetPeriodicAdvParameter(uint8 adv_handle, + uint16 interval_min, + uint16 interval_max, + uint16 adv_event_properties); + + +llStatus_t LL_SetPeriodicAdvData(uint8 adv_handle, + uint8 operation, + uint8 advertising_data_length, + uint8* advertising_data); + + + +llStatus_t LL_SetPeriodicAdvEnable(uint8 enable, + uint8 advertising_handle); + + +// periodic scan +llStatus_t LL_PeriodicAdvertisingCreateSync(uint8 options, + uint8 advertising_SID, + uint8 advertiser_Address_Type, + uint8* advertiser_Address, + uint16 skip, + uint16 sync_Timeout, + uint8 sync_CTE_Type); + +llStatus_t LL_PeriodicAdvertisingCreateSyncCancel(void); + +llStatus_t LL_PeriodicAdvertisingTerminateSync( uint16 sync_handle); + +// Periodic advertiser list +extern llStatus_t LL_AddDevToPeriodicAdvList(uint8 addrType, + uint8* devAddr, + uint8 sid); +extern llStatus_t LL_RemovePeriodicAdvListDevice(uint8 addrType, + uint8* devAddr, + uint8 sid); + +extern llStatus_t LL_ClearPeriodicAdvList( void ); + +extern llStatus_t LL_ReadPeriodicAdvListSize( uint8* numEntries ); + + +/***************************************************************************************** + fn: LL_ConnectionlessCTE_TransmitParamCmd + + date:2020-01-15 + + brief: set CTE Parameters in any periodic advertising + 1ã€CTE Type + 2ã€CTE Length + 3ã€CTE antenna switching pattern + + input parameters: + advertising handle : Identify advertising set 0x0-0xEF + CTE_Length : CTE Length in 8us 0x2-0x14 + CTE_Type : 0:AOA CTE , 1:AoD CTE with 1us,2:AoD CTE with 2us, + CTE_Count : how many CTE packet in each PA event 0x1-0x10 + Switch_Pattern_LEN : number of Antenna IDs in the pattern + : AOD CTE, AOA shall be ignored + : 0x2-0x4B + Antenna_IDs[i] : List of Antenna IDs in the pattern + : AOD CTE, AOA shall be ignored + + output parameters: + Status :LL_STATUS_SUCCESS or other error codes + + + return LL_STATUS_SUCCESS or other error codes + + *****************************************************************************************/ +llStatus_t LL_ConnectionlessCTE_TransmitParam( uint8 advertising_handle, + uint8 len, + uint8 type, + uint8 count, + uint8 Pattern_LEN, + uint8* AnaIDs); + + +/***************************************************************************************** + fn: LL_ConnectionlessCTE_TransmitEnable + + date:2020-01-16 + + brief: Controller enable or disable CTE in PA + + input parameters: + advertising handle : Identify advertising set in which CTE is enable or disable + : 0x0-0xEF + enable : 0 : disable , 1: enable + + + output parameters: + Status :LL_STATUS_SUCCESS or other error codes + + + return LL_STATUS_SUCCESS or other error codes + + *****************************************************************************************/ +llStatus_t LL_ConnectionlessCTE_TransmitEnable( uint8 advertising_handle, + uint8 enable); + + +/***************************************************************************************** + fn: LL_ConnectionlessIQ_SampleEnable + + date:2020-01-17 + + brief: Controller enable or disable capturing IQ Samples from the CTE of PA pcakets + + input parameters: + sync_handle : periodic advertising handle + Range:0x0 - 0x0EFF + slot_Duration : switching and sampling slot 0x1:1us,0x2:2us,Other:RFU + enable : 0x0:IQ Sampling disable, 0x1:IQ Sampling enable + MaxSampledCTEs : max number of CTE in each PA event that the controller + should collect and report + Range : 0x0-0x10 + 0x0 : sample and report all available CTE + pattern_len : number of Antenna IDs in the pattern + Range:0x2 - 0x4B + AnaIDs : list of Antenna IDs in the pattern + + + output parameters: + status : LL_STATUS_SUCCESS or other error codes + sync_handle : Periodic advertising handle + + + return LL_STATUS_SUCCESS or other error codes + + + *****************************************************************************************/ +llStatus_t LL_ConnectionlessIQ_SampleEnable( uint16 sync_handle, + uint8 enable, + uint8 slot_Duration, + uint8 MaxSampledCTEs, + uint8 pattern_len, + uint8* AnaIDs); + + +/***************************************************************************************** + fn: LL_Set_ConnectionCTE_ReceiveParam + + date:2020-01-19 + + brief: enable or disable sampling received CTE fields on the connection + set antenna switching pattern + set switching and sampling slot durations + + input parameters: + connHandle : connection handle Range 0x0 - 0x0EFF + enable : sampling enable 0:disable , 1:enable + slot_Duration : switching and sampling slot 0:1us, 1: 2us + pattern_len : the number of Antenna IDs in the pattern + Range: 0x2-0x4B + AnaIDs : list of Antenna IDs in the pattern + + + output parameters: + Status : LL_STATUS_SUCCESS or other error codes + connHandle : Connection Handle + + + return llStatus_t + + + *****************************************************************************************/ +llStatus_t LL_Set_ConnectionCTE_ReceiveParam( uint16 connHandle, + uint8 enable, + uint8 slot_Duration, + uint8 pattern_len, + uint8* AnaIDs); + + +/***************************************************************************************** + fn: LL_Connection_CTE_Request_Enable + + date:2020-01-19 + + brief: request Controller to start or stop initiating the CTE request + procedure on connection + + input parameters: + connHandle : connection Handle + Range:0x0 - 0x0EFF + enable : Enable or disable CTE request for the connection + 0:disable,1:enable + Interval : define whether the CTE request procedure is initiated + only once or periodically. + Range:0x0 - 0xFFFF + 0x0 : Initiate the CTE request procedure once + 0x1 - 0xFFFF : Requested interval for initiating the CTE + procedure in number of connection events + Range: + len : minimum length of the CTE in 8us units + Range: 0x2 - 0x14 + type : indicate the type of CTE that the controller shall + request from the remote device + 0x0:AOA CTE + 0x1:AOD CTE with 1us + 0x2:AOD CTE with 2us + + + output parameters: + Status : 0x0 : command succeed , 0x1 - 0xff : other error code + connHandle : connection handle + + + return llStatus_t + + + *****************************************************************************************/ +llStatus_t LL_Connection_CTE_Request_Enable( uint16 connHandle, + uint8 enable, + uint16 Interval, + uint8 len, + uint8 type); + + + +/***************************************************************************************** + fn: LL_Set_ConnectionCTE_TransmitParam + + date:2000-01-19 + + brief: used to set the antenna switching pattern and permitted CTE type + + input parameters: + connHandle : connection Handle, Range: 0x0 - 0x0EFF + type : bit set for CTE type , bit 0 : AOA CTE response, + bit 1 : AOD CTE response with 1us slots + bit 2 : AOD CTE response with 2us slots + pattern_len : the number of Antenna IDs in the pattern + AnaIDs : list of Antenna IDs in the pattern + + + output parameters: + Status : 0 : success, other error code + ConnHandle : connection handle + + + return llStatus_t + + + *****************************************************************************************/ +llStatus_t LL_Set_ConnectionCTE_TransmitParam( uint16 connHandle, + uint8 type, + uint8 pattern_len, + uint8* AnaIDs); + + +/***************************************************************************************** + fn: LL_Connection_CTE_Response_Enable + + date:2020-01-19 + + brief: request the controller to respond to LL_CTE_REQ with LL_CTE_RSP on the + specified connection + + input parameters: + connHandle : connection Handle + Range:0x0 - 0x0EFF + enable : enable or disable CTE response for the connection + + + output parameters: + status : 0x0 : command succeed , 0x1 - 0xff : other error code + connHandle : connection handle + + + + return llStatus_t + + + *****************************************************************************************/ +llStatus_t LL_Connection_CTE_Response_Enable( uint16 connHandle,uint8 enable); + + +/***************************************************************************************** + fn: HCI_LE_READ_Anatenna_InfoCmd + + date:2020-01-19 + + brief: Host read the switching rates, the sampling reate, the number of antennae, + and the maxumum length of a transmitted CTE supported by the controller + + input parameters: + None + + + output parameters: + status : 0x0 : command succeed , 0x1 - 0xff : other error code + switch_sample_rate : bit number indicate supported switching and sampling rate + bit 0 : 1us switching AOD transmission + bit 1 : 1us sampling AOD reception + bit 2 : 1us switching and sampling AOA reception + Antenna_len : number of Antennae supported by the controller + MAX_Pattern_len : MAX length of antenna switching pattern spooorted by the controller + MAX_CTE_LEN : MAX length or a transmitted CTE supported in 8us units + + + return llStatus_t + + + *****************************************************************************************/ +llStatus_t LL_READ_Anatenna_Info( uint8* param ); + + +// RF path compensation configuration +llStatus_t LL_Read_Rf_Path_Compensation(uint8* param); + +llStatus_t LL_Write_Rf_Path_Compensation( int16 tx_compensation, int16 rx_compensation); + +llStatus_t LL_Set_Privacy_Mode(uint8 peerIdType, + uint8* peerIdAddr, + uint8 privacyMode); + +llStatus_t LL_Read_Transmit_Power( uint8* param); + +void LL_EXT_Init_IQ_pBuff(uint16* ibuf,uint16* qbuf); + + +#ifdef __cplusplus +} +#endif + +#endif /* LL_H */ + + diff --git a/arch/arm/src/phy62xx/ble/controller/ll_buf.h b/arch/arm/src/phy62xx/ble/controller/ll_buf.h new file mode 100644 index 00000000000..58fe80779ce --- /dev/null +++ b/arch/arm/src/phy62xx/ble/controller/ll_buf.h @@ -0,0 +1,137 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +#ifndef _LL_BUF_H_ +#define _LL_BUF_H_ +#include + +#define MAX_ADV_BUF 1 // buffer advertisement packet +#define TYP_CONN_BUF_LEN 4 // typical packet number per connection event +#define MAX_LL_BUF_LEN 8 // maximum LL buffer for Rx/Tx packet + + +//#define LL_CTRL_PDU_LEN 29 //V4.0/4.2: 2octets header + 27 octets payload +//#define LL_ADV_PDU_LEN 39 //V4.0/4.2: 2octets header + 37 octets payload +//#define LL_DATA_PDU_LEN 33 //V4.0 : 2octets header + 31 octets payload + +// for Rx FIFO, HW will pack zero bytes to align 4bytes boarder +// BLE 4.0, PDU length < 39, 3Bytes CRC will also be read. +// note that PDU head is write in "rxheader/txheader" field, the buffer need (39 + 3 - 2) = 40 bytes, +// add 2 bytes to align 4 bytes edge +//#define BLE_PACKET_BUF_LEN 42 +//257+3-2=256 +// BLE5.0, PDU length: maximum 257 octets, 3 octets CRC, 2 octets PDU head is write in "rxheader/txheader" field +//#define BLE_PACKET_BUF_LEN 258 //(257+3-2) + +// BLE 5.1, PDU length: 2-258 octets, 3 octets CRC, 2 octets PDU head is write in "rxheader/txheader" field +// length should align to word edge, so + 3 octet +#define BLE_PACKET_BUF_LEN 262 //(258+3-2) + 3 + + +#define RX_BUF_LEN BLE_PACKET_BUF_LEN +#define TX_BUF_LEN BLE_PACKET_BUF_LEN +#define TX_CTRL_BUF_LEN 34 //(27+4+3) + +#define LL_PDU_LENGTH_SUPPORTED_MAX_TX_OCTECTS 251 +#define LL_PDU_LENGTH_SUPPORTED_MAX_RX_OCTECTS 251 +#define LL_PDU_LENGTH_SUPPORTED_MAX_TX_TIME 2120 +#define LL_PDU_LENGTH_SUPPORTED_MAX_RX_TIME 2120 + +#define LL_PDU_LENGTH_INITIAL_MAX_TX_OCTECTS 27 +#define LL_PDU_LENGTH_INITIAL_MAX_RX_OCTECTS 27 +#define LL_PDU_LENGTH_INITIAL_MAX_TX_TIME 328 +#define LL_PDU_LENGTH_INITIAL_MAX_RX_TIME 328 + +// BBB update +struct ll_pkt_desc +{ + uint32_t valid; // mean a valid data received from ble + uint16_t header; + uint8_t data[2]; +}; + + +struct buf_rx_desc +{ + uint32_t valid; // mean a valid data received from ble + /// rx header + uint16_t rxheader; + uint8_t data[RX_BUF_LEN ]; // for v4.2 BLE, set to 256 +}; + +struct buf_tx_desc +{ + uint32_t valid; // means a valid data to wait for send to ble + //uint32_t sent; // means tha data has been sent before + /// tx header + uint16_t txheader; + /// data + uint8_t data[TX_BUF_LEN]; +}; + +typedef struct +{ + uint16_t header; + //uint8_t data[TX_BUF_LEN]; + uint8_t data[TX_CTRL_BUF_LEN]; +} __attribute__((aligned(4))) ctrl_packet_buf; + +typedef struct +{ + #if 0 + struct buf_tx_desc tx_conn_desc[MAX_LL_BUF_LEN]; // new Tx data buffer + struct buf_rx_desc rx_conn_desc[MAX_LL_BUF_LEN]; + + struct buf_tx_desc tx_not_ack_pkt; + struct buf_tx_desc tx_ntrm_pkts[MAX_LL_BUF_LEN]; + #endif + struct ll_pkt_desc* tx_conn_desc[MAX_LL_BUF_LEN]; // new Tx data buffer + struct ll_pkt_desc* rx_conn_desc[MAX_LL_BUF_LEN]; + + struct ll_pkt_desc* tx_not_ack_pkt; + struct ll_pkt_desc* tx_ntrm_pkts[MAX_LL_BUF_LEN]; + + + uint8_t ntrm_cnt; // number of packets not transmit + + uint8_t tx_write; + uint8_t tx_read; + uint8_t tx_loop; // flag for write ptr & read ptr work in the same virtual buffer bank + + uint8_t rx_write; + uint8_t rx_read; + uint8_t rx_loop; // flag for write ptr & read ptr work in the same virtual buffer bank +} llLinkBuf_t; + + + +#endif diff --git a/arch/arm/src/phy62xx/ble/controller/ll_common.h b/arch/arm/src/phy62xx/ble/controller/ll_common.h new file mode 100644 index 00000000000..22a290d466d --- /dev/null +++ b/arch/arm/src/phy62xx/ble/controller/ll_common.h @@ -0,0 +1,372 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +#ifndef _LL_H_ +#define _LL_H_ + +#include "types.h" +#include "mcu.h" +#include "ll.h" +#include "ll_def.h" + +#define LL_DATA_PDU( pktHdr ) ((pktHdr) != LL_DATA_PDU_HDR_LLID_CONTROL_PKT) +#define LL_CTRL_PDU( pktHdr ) ((pktHdr) == LL_DATA_PDU_HDR_LLID_CONTROL_PKT) +#define LL_INVALID_LLID( pktHdr ) ((pktHdr) == LL_DATA_PDU_HDR_LLID_RESERVED) + + +void LL_IRQHandler(void); + +void move_to_slave_function(void); + +void LL_slave_conn_event(void); + +void LL_master_conn_event(void); + +void LL_set_default_conn_params(llConnState_t* connPtr); + +//void ll_setMem(uint8_t *buf, uint8_t v, int n); + +//void ll_cpyMem(uint8_t *dst, uint8_t *src, int n); + +void LL_evt_schedule(void); + +llStatus_t llSetupAdv( void ); + +void llConvertLstoToEvent( llConnState_t* connPtr, + connParam_t* connParams ); + +void llSlaveEvt_TaskEndOk( void ); + +// for master process +void llMasterEvt_TaskEndOk( void ); + +// Connection Management +extern llConnState_t* llAllocConnId( void ); +extern void llReleaseConnId( llConnState_t* connPtr ); +extern void llReleaseAllConnId( void ); +extern uint16 llGetMinCI( uint16 connInterval ); +extern uint8 llGetNextConn( void ); +extern void llConnCleanup( llConnState_t* connPtr ); +extern void llConnTerminate( llConnState_t* connPtr, uint8 reason ); +extern uint8 llPendingUpdateParam( void ); +extern void llInitFeatureSet( void ); +extern uint32 llGenerateValidAccessAddr( void ); +extern uint32 llGenerateCRC( void ); +extern uint8 llEventInRange( uint16 curEvent, uint16 nextEvent, uint16 updateEvent ); +extern uint16 llEventDelta( uint16 eventA, uint16 eventB ); +extern void llConvertLstoToEvent( llConnState_t* connPtr, connParam_t* connParams ); +extern void llConvertCtrlProcTimeoutToEvent( llConnState_t* connPtr ); + +// Task Setup +extern llStatus_t llSetupAdv( void ); +extern void llSetupDirectedAdvEvt( void ); +extern void llSetupUndirectedAdvEvt( void ); +extern void llSetupNonConnectableAdvEvt( void ); +extern void llSetupScannableAdvEvt( void ); +extern void llSetupScan( uint8 chan ); +extern void llSetupScanInit( void ); +extern void llSetupInit( uint8 connId ); +extern void llSetupConn( void ); +// A2 added +extern uint8 llSetupSecNonConnectableAdvEvt( void ); +// A2 multi-connection +extern uint8 llSetupSecConnectableAdvEvt( void ); +extern uint8 llSetupSecScannableAdvEvt( void ); + + +extern void llSetupSecScan( uint8 chan ); +extern uint32 llCalcMaxScanTime(void); +extern uint8 llSecAdvAllow(void); +// A2 multi-connection +extern uint8 llSetupSecAdvEvt( void ); + +extern void llSetupSecInit( uint8 chan ); +extern uint8_t ll_get_next_active_conn(uint8_t current_conn_id); +extern uint32 ll_get_next_timer(uint8 current_conn_id); + +extern void ll_scheduler(uint32 time); + +extern void ll_addTask(uint8 connId, uint32 time); +extern void ll_deleteTask(uint8 connId); + +// extended adv scheduler functions +void ll_adv_scheduler(void); + +void ll_add_adv_task(extAdvInfo_t* pExtAdv); + +void ll_delete_adv_task(uint8 index); + +uint8 llSetupExtAdvEvent(extAdvInfo_t* pAdvInfo); + +// periodic adv functions +void ll_add_adv_task_periodic(periodicAdvInfo_t* pPrdAdv, extAdvInfo_t* pExtAdv); + +void ll_add_adv_task_periodic(periodicAdvInfo_t* pPrdAdv, extAdvInfo_t* pExtAdv); + +void ll_delete_adv_task_periodic(uint8 index); + +uint8 llSetupPrdAdvEvent(periodicAdvInfo_t* pPrdAdv, extAdvInfo_t* pExtAdv); + +void ll_adv_scheduler_periodic(void); + + +// extended scan functions +extern void llSetupExtScan( uint8 chan ); + +extern void llSetupExtInit(void); + +extern void llSetupPrdScan( void ); + +extern uint16 llAllocateSyncHandle(void); + +extern uint8 llDeleteSyncHandle(uint16 sync_handle); + + + +// Data Management +extern uint8 llEnqueueDataQ( llDataQ_t* pDataQ, txData_t* pTxData ); +extern uint8 llEnqueueHeadDataQ( llDataQ_t* pDataQ, txData_t* pTxData ); +extern txData_t* llDequeueDataQ( llDataQ_t* pDataQ ); +extern uint8 llDataQEmpty( llDataQ_t* pDataQ ); +extern uint8 llWriteTxData ( llConnState_t* connPtr, uint8 pktHdr, uint8 pktLen, uint8* pBuf ); +extern uint8* llMemCopySrc( uint8* pDst, uint8* pSrc, uint8 len ); +extern uint8* llMemCopyDst( uint8* pDst, uint8* pSrc, uint8 len ); +extern void llProcessMasterControlPacket( llConnState_t* connPtr, uint8* pBuf ); +extern void llProcessSlaveControlPacket( llConnState_t* connPtr, uint8* pBuf ); +extern void llProcessTxData( llConnState_t* connPtr, uint8 context ); +extern uint8 llProcessRxData( void ); + +// Control Procedure Setup +extern uint8 llSetupUpdateParamReq( llConnState_t* connPtr ); // M +extern uint8 llSetupUpdateChanReq( llConnState_t* connPtr ); // M +extern uint8 llSetupEncReq( llConnState_t* connPtr ); // M +extern uint8 llSetupEncRsp( llConnState_t* connPtr ); // S +extern uint8 llSetupStartEncReq( llConnState_t* connPtr ); // S +extern uint8 llSetupStartEncRsp( llConnState_t* connPtr ); // M, S +extern uint8 llSetupPauseEncReq( llConnState_t* connPtr ); // M +extern uint8 llSetupPauseEncRsp( llConnState_t* connPtr ); // S +extern uint8 llSetupRejectInd( llConnState_t* connPtr,uint8 errCode); // S +extern uint8 llSetupFeatureSetReq( llConnState_t* connPtr ); // M, S +extern uint8 llSetupFeatureSetRsp( llConnState_t* connPtr ); // M, S +extern uint8 llSetupVersionIndReq( llConnState_t* connPtr ); // M +extern uint8 llSetupTermInd( llConnState_t* connPtr ); // M, S +extern uint8 llSetupUnknownRsp( llConnState_t* connPtr ); // M, S + +extern uint8 llSetupDataLenghtReq( llConnState_t* connPtr );//M,S +extern uint8 llSetupDataLenghtRsp( llConnState_t* connPtr );//M,S +extern uint8 llSetupPhyReq( llConnState_t* connPtr ); //M,S +extern uint8 llSetupPhyRsp( llConnState_t* connPtr ); //M,S +extern uint8 llSetupPhyUpdateInd( llConnState_t* connPtr );//M +extern uint8 llSetupRejectExtInd( llConnState_t* connPtr,uint8 errCode); + +// Control Procedure Management +extern void llEnqueueCtrlPkt( llConnState_t* connPtr, uint8 ctrlType ); +extern void llDequeueCtrlPkt( llConnState_t* connPtr ); +extern void llReplaceCtrlPkt( llConnState_t* connPtr, uint8 ctrlType ); + + +// Data Channel Management +extern void llProcessChanMap( llConnState_t* connPtr, uint8* chanMap ); +extern uint8 llGetNextDataChan( llConnState_t* connPtr, uint16 numEvents ); +extern void llSetNextDataChan( llConnState_t* connPtr ); +extern uint8 llAtLeastTwoChans( uint8* chanMap ); + +//2020-01-20 add for LL CTE +extern uint8 llSetupCTEReq( llConnState_t* connPtr ); +extern uint8 llSetupCTERsp( llConnState_t* connPtr ); + + + +uint8_t llTimeCompare(int base_time, int fine_time); +uint32_t calculateTimeDelta(int base_time, int fine_time); + +void llSetNextDataChan( llConnState_t* connPtr ); + +// White List Related +extern llStatus_t llCheckWhiteListUsage( void ); + +// function add by HZF +void llResetConnId( uint8 connId ); +void llResetRfCounters(void); +extern void llInitFeatureSet( void ); + + +extern uint16 llCalcScaFactor( uint8 masterSCA ); + + +extern void llCalcTimerDrift( uint32 connInterval, + uint16 slaveLatency, + uint8 sleepClkAccuracy, + uint32* timerDrift ); + + +// add by HZF +uint8 llGetNextAdvChn(uint8 cur_chn); + +// Tx loop buffer process +void update_tx_write_ptr(llConnState_t* connPtr); + +void update_tx_read_ptr(llConnState_t* connPtr); + +uint8_t getTxBufferSize(llConnState_t* connPtr); +uint8_t getTxBufferFree(llConnState_t* connPtr); + +uint8_t get_tx_read_ptr(llConnState_t* connPtr); + +uint8_t get_tx_write_ptr(llConnState_t* connPtr); + +// Rx loop buffer process +void update_rx_write_ptr(llConnState_t* connPtr); + +void update_rx_read_ptr(llConnState_t* connPtr); + +uint8_t getRxBufferSize(llConnState_t* connPtr); +uint8_t getRxBufferFree(llConnState_t* connPtr); + +uint8_t get_rx_read_ptr(llConnState_t* connPtr); + +uint8_t get_rx_write_ptr(llConnState_t* connPtr); + +// reset buffer +void reset_conn_buf(uint8 index); + +void ll_schedule_next_event(int time); + +uint16 ll_generateTxBuffer(int txFifo_vacancy, uint16* pSave_ptr); + +void ll_read_rxfifo(void); +void ll_hw_read_tfifo_rtlp(void); +int ll_hw_read_tfifo_packet(uint8* pkt); + +// function in ll_slaveEndCause.c +uint8 llSetupNextSlaveEvent( void ); +uint8 llProcessSlaveControlProcedures( llConnState_t* connPtr ); +uint8 llCheckForLstoDuringSL( llConnState_t* connPtr ); + +// function in ll_hwItf.c +void ll_hw_process_RTO(uint32 ack_num); +void ll_debug_output(uint32 state); + +void llAdjSlaveLatencyValue( llConnState_t* connPtr ); + +//function for DLE add by ZQ +void llPduLengthManagmentReset(void); +void llTrxNumAdaptiveConfig(void); +void llPduLengthUpdate(uint16 connHandle); +//uint8 LL_PLUS_GetLocalPduDataLength(ll_pdu_length_ctrl_t * pduLen); + +//function for PHY UPDATE add by ZQ +void llPhyModeCtrlReset(void); +void llPhyModeCtrlUpdateNotify(llConnState_t* connPtr, uint8 status); +//llStatus_t LL_PLUS_GetLocalPhyMode(ll_phy_ctrl_t * phyCtrl); +void llSetNextPhyMode( llConnState_t* connPtr ); +extern void llInitFeatureSetDLE(uint8 enable); +extern void llInitFeatureSet2MPHY(uint8 enable); +extern void llInitFeatureSetCodedPHY(uint8 enable); + +// function for whitelist +extern uint8 ll_isAddrInWhiteList(uint8 addrType, uint8* addr); + +// function for resolving list +uint8 ll_readLocalIRK(uint8** localIrk, uint8* peerAddr, uint8 peerAddrType); +uint8 ll_readPeerIRK(uint8** peerIrk, uint8* peerAddr, uint8 peerAddrType); +uint8_t ll_getRPAListEntry(uint8* peerAddr); + +uint8_t ll_isIrkAllZero(uint8* irk); + +uint8_t ll_CalcRandomAddr( uint8* pIRK, uint8* pNewAddr ); +uint8_t ll_ResolveRandomAddrs(uint8* pIRK, uint8* pAddr); + +uint16 ll_generateExtAdvDid(uint16 old); + +// extended advertiser process +uint8 LL_extAdvTimerExpProcess(void); + +uint8 LL_prdAdvTimerExpProcess(void); + +uint8 LL_prdScanTimerExpProcess(void); + +uint8 ll_isFirstAdvChn(uint8 chnMap, uint8 chan); + +uint8 ll_getFirstAdvChn(uint8 chnMap); + +void ll_ext_adv_schedule_next_event(int time); + +void ll_prd_adv_schedule_next_event(int time); + +void ll_ext_scan_schedule_next_event(int time); + +void ll_ext_init_schedule_next_event(int time); + +void ll_prd_scan_schedule_next_event(int time); + + +uint8 ll_allocAuxAdvTimeSlot(uint8 index); + +void ll_updateAuxAdvTimeSlot(uint8 index); + +void ll_updateExtAdvRemainderTime(uint32 time); + + +uint8 ll_allocAuxAdvTimeSlot_prd(uint8 index); + +void LL_extScanTimerExpProcess(void); + +void LL_extInitTimerExpProcess(void); + +void ll_parseExtHeader(uint8* payload, uint16 length); + +uint8 llGetNextAuxAdvChn(uint8 current); + + +/****************************************************************************** + fn: llGetNextDataChanCSA2 + + brief: 2020-01-07 add for CSA 2 + + input parameters: counter : event counter( PA Counter or connection counter) + chan_id : current data or periodic advertising channel Identifier, + calculate from Access Address + chan_map: PA or connection channel map + cMap_tab: current chan map table that is in use for connection or PA event + chanCnt : used channel count + + output parameters: None + + + return uint8 : next channel index + + ******************************************************************************/ +uint8 llGetNextDataChanCSA2(uint16_t counter,uint16_t chan_id,uint8* chan_map,uint8* cMap_tab,uint8 chanCnt); + +#endif + diff --git a/arch/arm/src/phy62xx/ble/controller/ll_debug.h b/arch/arm/src/phy62xx/ble/controller/ll_debug.h new file mode 100644 index 00000000000..8424913e739 --- /dev/null +++ b/arch/arm/src/phy62xx/ble/controller/ll_debug.h @@ -0,0 +1,101 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/** + **************************************************************************************** + + @file ll_debug.h + + @brief This file defines the status used for debug + + + $Rev: $ + + **************************************************************************************** +*/ + + +#ifndef _LL_DEBUG_H_ +#define _LL_DEBUG_H_ + +#define DEBUG_ENTER_SYSTEM_SLEEP 0 +#define DEBUG_ENTER_MCU_SLEEP 1 +#define DEBUG_WAKEUP 2 + +#define DEBUG_ISR_EXIT 3 +#define DEBUG_ISR_ENTRY 4 + +#define DEBUG_LL_HW_STX 5 +#define DEBUG_LL_HW_SRX 6 + +#define DEBUG_LL_HW_TRX 7 +#define DEBUG_LL_HW_RTX 8 +#define DEBUG_LL_HW_TRLP 9 +#define DEBUG_LL_HW_TRLP_EMPT 10 +#define DEBUG_LL_HW_RTLP 11 +#define DEBUG_LL_HW_RTLP_1ST 12 +#define DEBUG_LL_HW_RTLP_EMPT 13 + +#define DEBUG_LL_HW_SET_STX 14 +#define DEBUG_LL_HW_SET_SRX 15 + +#define DEBUG_LL_HW_SET_TRX 16 +#define DEBUG_LL_HW_SET_RTX 17 +#define DEBUG_LL_HW_SET_TRLP 18 +#define DEBUG_LL_HW_SET_TRLP_EMPT 19 +#define DEBUG_LL_HW_SET_RTLP 20 +#define DEBUG_LL_HW_SET_RTLP_1ST 21 +#define DEBUG_LL_HW_SET_RTLP_EMPT 22 + +#define DEBUG_LL_STATE_IDLE 30 +#define DEBUG_LL_STATE_ADV_UNDIRECTED 31 +#define DEBUG_LL_STATE_ADV_DIRECTED 32 +#define DEBUG_LL_STATE_ADV_SCAN 33 +#define DEBUG_LL_STATE_ADV_NONCONN 34 +#define DEBUG_LL_STATE_SCAN 35 +#define DEBUG_LL_STATE_INIT 36 +#define DEBUG_LL_STATE_CONN_SLAVE 37 +#define DEBUG_LL_STATE_CONN_MASTER 38 +#define DEBUG_LL_STATE_DIRECT_TEST_MODE_TX 39 +#define DEBUG_LL_STATE_DIRECT_TEST_MODE_RX 40 +#define DEBUG_LL_STATE_MODEM_TEST_TX 41 +#define DEBUG_LL_STATE_MODEM_TEST_RX 42 +#define DEBUG_LL_STATE_MODEM_TEST_TX_FREQ_HOPPING 43 + +#define DEBUG_LL_SEND_ADV 44 + +#define DEBUG_LL_TIMER_EXPIRY_ENTRY 50 +#define DEBUG_LL_TIMER_EXPIRY_EXIT 51 + + + +#endif // _LL_DEBUG_H_ diff --git a/arch/arm/src/phy62xx/ble/controller/ll_def.h b/arch/arm/src/phy62xx/ble/controller/ll_def.h new file mode 100644 index 00000000000..45082a3c06a --- /dev/null +++ b/arch/arm/src/phy62xx/ble/controller/ll_def.h @@ -0,0 +1,1599 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + + +#ifndef LL_DEF_H_ +#define LL_DEF_H_ + +#include "types.h" +//#include "comdef.h" +#include "bcomdef.h" +#include "ll_buf.h" + +#if (MAX_NUM_LL_CONN_ROM_LIMT > 1) + #define MULTI_ROLE +#endif + +#define MAX_NUM_LL_PRD_ADV_SYNC 2 // for periodic adv listener + +#define LL_INVALID_CONNECTION_ID 0xFF + + +#define LL_PKT_PREAMBLE_LEN 1 +#define LL_PKT_SYNCH_LEN 4 +#define LL_PKT_LLID_LEN 1 +#define LL_PKT_HDR_LEN 2 +#define LL_PKT_MIC_LEN 4 +#define LL_PKT_CRC_LEN 3 + +#define LL_DATA_PDU_HDR_LLID_RESERVED 0 +#define LL_DATA_PDU_HDR_LLID_DATA_PKT_NEXT 1 +#define LL_DATA_PDU_HDR_LLID_DATA_PKT_FIRST 2 +#define LL_DATA_PDU_HDR_LLID_CONTROL_PKT 3 + + +///adv header shift and mask +#define PDU_TYPE_SHIFT 0 +#define PDU_TYPE_MASK 0xf +#define CHSEL_SHIFT 5 +#define CHSEL_MASK 0x20 +#define TX_ADD_SHIFT 6 +#define TX_ADD_MASK 0x40 +#define RX_ADD_SHIFT 7 +#define RX_ADD_MASK 0x80 +#define LENGTH_SHIFT 8 +#define LENGTH_MASK 0xFf00 + +// macro for bit operations +#define SET_BITS(p,f,l,m) p=(f<>l + +// Receive Flow Control +#define LL_RX_FLOW_CONTROL_DISABLED 0 +#define LL_RX_FLOW_CONTROL_ENABLED 1 + +//LL packet type +#define ADV_IND 0 //Connectable Undirected Event +#define ADV_DIRECT_IND 1 //Connectable Directed Event +#define ADV_NONCONN_IND 2 //Non-connectable Undirected Event +#define ADV_SCAN_REQ 3 +#define ADV_AUX_SCAN_REQ 3 +#define ADV_SCAN_RSP 4 +#define ADV_CONN_REQ 5 +#define ADV_AUX_CONN_REQ 5 +#define ADV_SCAN_IND 6 //Scannable Undirected Event +#define ADV_EXT_TYPE 7 +#define ADV_AUX_CONN_RSP 8 + +// LL state defines +#define LL_STATE_IDLE 0x00 +#define LL_STATE_ADV_UNDIRECTED 0x01 +#define LL_STATE_ADV_DIRECTED 0x02 +#define LL_STATE_ADV_SCAN 0x03 +#define LL_STATE_ADV_NONCONN 0x04 +#define LL_STATE_SCAN 0x05 +#define LL_STATE_INIT 0x06 +#define LL_STATE_CONN_SLAVE 0x07 +#define LL_STATE_CONN_MASTER 0x08 +#define LL_STATE_DIRECT_TEST_MODE_TX 0x09 +#define LL_STATE_DIRECT_TEST_MODE_RX 0x0A +#define LL_STATE_MODEM_TEST_TX 0x0B +#define LL_STATE_MODEM_TEST_RX 0x0C +#define LL_STATE_MODEM_TEST_TX_FREQ_HOPPING 0x0D + +#define LL_STATE_ADV_EXT 0x0E +#define LL_STATE_ADV_PERIODIC 0x0F + +/* +** LL Buffers Supported +*/ +#define LL_MAX_NUM_DATA_BUFFERS 12 +#define LL_MAX_NUM_CMD_BUFFERS 1 + +/* +** LL API Parameters +*/ + +// LL Parameter Limits +#define LL_ADV_CONN_INTERVAL_MIN 32 // 20ms in 625us +#define LL_ADV_CONN_INTERVAL_MAX 16384 // 10.24s in 625us +#define LL_ADV_NONCONN_INTERVAL_MIN 160 // 100ms in 625us +#define LL_ADV_NONCONN_INTERVAL_MAX 16384 // 10.24s in 625us +// temporary macro define : align to version 5.1 non-conn intv 20ms +// affect function LL_SetAdvControl +#define LL_ADV_V51_NONCONN_INTERVAL_MIN 32 +#define LL_ADV_DELAY_MIN 0 // in ms +#define LL_ADV_DELAY_MAX 10 // in ms +#define LL_SCAN_INTERVAL_MIN 4 // 2.5ms in 625us +#define LL_SCAN_INTERVAL_MAX 16384 // 10.24s in 625us +#define LL_SCAN_WINDOW_MIN 4 // 2.5ms in 625us +#define LL_SCAN_WINDOW_MAX 16384 // 10.24s in 625us +#define LL_CONN_INTERVAL_MIN 6 // 7.5ms in 1.25ms +#define LL_CONN_INTERVAL_MAX 3200 // 4s in 1.25ms +#define LL_CONN_TIMEOUT_MIN 10 // 100ms in 10ms +#define LL_CONN_TIMEOUT_MAX 3200 // 32s in 10ms +#define LL_SLAVE_LATENCY_MIN 0 +#define LL_SLAVE_LATENCY_MAX 499 +#define LL_HOP_LENGTH_MIN 5 +#define LL_HOP_LENGTH_MAX 16 +#define LL_INSTANT_NUMBER_MIN 6 + +#define LL_ADV_INTERVAL_DEFAULT 160 // 100ms in 625us ticks +#define LL_SCAN_INTERVAL_DEFAULT 640 // 400ms in 625us ticks +// LL Advertiser Channels +#define LL_ADV_CHAN_37 1 +#define LL_ADV_CHAN_38 2 +#define LL_ADV_CHAN_39 4 +#define LL_ADV_CHAN_ALL (LL_ADV_CHAN_37 | LL_ADV_CHAN_38 | LL_ADV_CHAN_39) + +#define LL_MAX_NUM_DATA_CHAN 37 // 0 - 36 + +// Advertiser Synchronization Word +#define ADV_SYNCH_WORD 0x8E89BED6 // Adv channel sync +#define ADV_CRC_INIT_VALUE 0x00555555 // not needed; handled by NR hardware automatically + +// Packet Lengths +#define LL_DEVICE_ADDR_LEN 6 +#define LL_MAX_ADV_DATA_LEN 31 +#define LL_MAX_ADV_PAYLOAD_LEN (LL_DEVICE_ADDR_LEN + LL_MAX_ADV_DATA_LEN) +#define LL_MAX_SCAN_DATA_LEN 31 +#define LL_MAX_SCAN_PAYLOAD_LEN (LL_DEVICE_ADDR_LEN + LL_MAX_SCAN_DATA_LEN) +#define LL_MAX_LINK_DATA_LEN 27 // ZQ 20181030 for DLE feature +//replaced by g_llPduLen.local.MaxTxOctets + +// =============== add in A2 for simultaneous slave and adv/scan +#define LL_SEC_STATE_IDLE 0x00 +#define LL_SEC_STATE_SCAN 0x01 +#define LL_SEC_STATE_ADV 0x02 +#define LL_SEC_STATE_SCAN_PENDING 0x03 +#define LL_SEC_STATE_ADV_PENDING 0x04 +#define LL_SEC_STATE_IDLE_PENDING 0x05 +#define LL_SEC_STATE_INIT 0x06 +#define LL_SEC_STATE_INIT_PENDING 0x07 + +// ============= for multi-role +#define LL_ROLE_SLAVE 0x01 +#define LL_ROLE_MASTER 0x02 +#define LL_ROLE_INVALID 0xFF + +#define LL_INVALID_TIME 0xFFFFFFFF + +#define LL_TASK_MASTER_DURATION 3000 +#define LL_TASK_SLAVE_DURATION 2700 + + +enum +{ + LL_SCH_PRIO_LOW = 0, + LL_SCH_PRIO_MED, + LL_SCH_PRIO_HIGH, + LL_SCH_PRIO_IMMED, + LL_SCH_PRIO_LAST +}; + + +// ===== A2 End + +// 2020-01-15 CTE Macro define +#define LL_CTE_MAX_ANTENNA_LEN 8 +#define LL_CTE_MAX_ANT_ID (LL_CTE_MAX_ANTENNA_LEN - 1) +#define LL_CTE_MAX_PATTERN_LEN 16 +#define LL_CTE_MIN_SUPP_LEN 0x2 +#define LL_CTE_MAX_SUPP_LEN 0x14 // CTE MAX Support length in 8us units( MAX 160us) +#define LL_CTE_SUPP_LEN_UNIT 0x08 +#define LL_CTE_MAX_PA_INTV_CNT 0x10 +#define LL_CTE_MAX_IQ_SAMP_CNT 0x10 +#define LL_CTE_ENABLE 0x1 +#define LL_CTE_DISABLE 0x0 +#define LL_IQ_SAMP_ENABLE 0x1 +#define LL_IQ_SAMP_DISABLE 0x0 +#define LL_CONN_IQSAMP_ENABLE 0x1 +#define LL_CONN_IQSAMP_DISENABLE 0x0 +#define LL_CONN_IQTX_ENABLE 0x1 +#define LL_CONN_IQTX_DISENABLE 0x0 +#define LL_CONN_CTE_REQ_ENABLE 0x1 +#define LL_CONN_CTE_REQ_DISENABLE 0x0 +#define LL_CONN_CTE_RSP_ENABLE 0x1 +#define LL_CONN_CTE_RSP_DISENABLE 0x0 +#define LL_IQ_SW_SAMP_1US 0x1 +#define LL_IQ_SW_SAMP_2US 0x2 +#define LL_CONTROLLER_SUPP_1US_AOD_TX 0x1 +#define LL_CONTROLLER_SUPP_1US_AOD_SAMP 0x2 +#define LL_CONTROLLER_SUPP_1US_AOA_TX_SAMP 0x4 + +// 2020-01-20 add for Extended advertising +#define LL_SECOND_ADV_PHY_1M 0x1 +#define LL_SECOND_ADV_PHY_2M 0x2 +#define LL_SECOND_ADV_PHY_CODE 0x3 +#define LL_PHY_1M 0x1 +#define LL_PHY_2M 0x2 +#define LL_PHY_CODE 0x3 + + +//LL connecction control type +#define LL_CONNECTION_UPDATE_REQ 0 +#define LL_CHANNEL_MAP_REQ 1 +#define LL_TERMINATE_IND 2 +#define LL_ENC_REQ 3 +#define LL_ENC_RSP 4 +#define LL_START_ENC_REQ 5 +#define LL_START_ENC_RSP 6 +#define LL_UNKNOWN_RSP 7 +#define LL_FEATURE_REQ 8 +#define LL_FEATURE_RSP 9 +#define LL_PAUSE_ENC_REQ 10 +#define LL_PAUSE_ENC_RSP 11 +#define LL_VERSION_IND 12 +#define LL_REJECT_IND 13 +#define LL_SLAVE_FEATURE_REQ 14 +#define LL_CONNECTION_PARAM_REQ 15 +#define LL_CONNECTION_PARAM_RSP 16 +#define LL_REJECT_IND_EXT 17 +#define LL_PING_REQ 18 +#define LL_PING_RSP 19 +#define LL_LENGTH_REQ 20 +#define LL_LENGTH_RSP 21 +#define LL_PHY_REQ 22 +#define LL_PHY_RSP 23 +#define LL_PHY_UPDATE_IND 24 + + +#define LL_CONNECT_REQ_PAYLOAD_LEN 18 +#define LL_CONN_UPDATE_REQ_PAYLOAD_LEN 12 +#define LL_CHAN_MAP_REQ_PAYLOAD_LEN 8 +#define LL_TERM_IND_PAYLOAD_LEN 2 +#define LL_ENC_REQ_PAYLOAD_LEN 23 +#define LL_ENC_RSP_PAYLOAD_LEN 13 +#define LL_START_ENC_REQ_PAYLOAD_LEN 1 +#define LL_START_ENC_RSP_PAYLOAD_LEN 1 +#define LL_PAUSE_ENC_REQ_PAYLOAD_LEN 1 +#define LL_PAUSE_ENC_RSP_PAYLOAD_LEN 1 +#define LL_REJECT_IND_PAYLOAD_LEN 2 +#define LL_REJECT_EXT_IND_PAYLOAD_LEN 3 +#define LL_FEATURE_REQ_PAYLOAD_LEN 9 +#define LL_FEATURE_RSP_PAYLOAD_LEN 9 +#define LL_VERSION_IND_PAYLOAD_LEN 6 +#define LL_UNKNOWN_RSP_PAYLOAD_LEN 2 +#define LL_LENGTH_REQ_PAYLOAD_LEN 9 +#define LL_LENGTH_RSP_PAYLOAD_LEN 9 +#define LL_PHY_REQ_PAYLOAD_LEN 3 +#define LL_PHY_RSP_PAYLOAD_LEN 3 +#define LL_PHY_UPDATE_IND_PAYLOAD_LEN 5 + +// 2020-01-20 add for CTE +#define LL_CTE_REQ_LEN 2 +#define LL_CTE_RSP_LEN 1 + +#define LL_MAX_NUM_CTRL_PROC_PKTS 4 +#define LL_CTRL_UNDEFINED_PKT 0xFF + +// LL Events +#define LL_EVT_POST_PROCESS_NR 0x0001 +#define LL_EVT_DIRECTED_ADV_FAILED 0x0002 +#define LL_EVT_SLAVE_CONN_CREATED 0x0004 +#define LL_EVT_NEXT_INTERVAL 0x0008 +#define LL_EVT_MASTER_CONN_CANCELLED 0x0010 +#define LL_EVT_TASK_TIMER_FENCE_EXPIRED 0x0020 +#define LL_EVT_SLAVE_CONN_CREATED_BAD_PARAM 0x0040 +#define LL_EVT_START_32KHZ_XOSC_DELAY 0x0080 +#define LL_EVT_32KHZ_XOSC_DELAY 0x0100 +#define LL_EVT_RESET_SYSTEM_HARD 0x0200 +#define LL_EVT_RESET_SYSTEM_SOFT 0x0400 + +#define LL_EVT_MASTER_CONN_CREATED 0x0800 +#define LL_EVT_SECONDARY_SCAN 0x1000 +#define LL_EVT_SECONDARY_ADV 0x2000 +#define LL_EVT_SECONDARY_INIT 0x4000 +#define LL_EVT_RPA_TIMEOUT 0x8000 + + + +#define LL_ADV_NONCONN_STATE 0x00 +#define LL_ADV_DISCOV_STATE 0x01 +#define LL_ADV_UNDIRECT_STATE 0x02 +#define LL_ADV_HDC_DIRECT_STATE 0x03 +#define LL_SCAN_PASSIVE_STATE 0x04 +#define LL_SCAN_ACTIVE_STATE 0x05 +#define LL_INIT_STATE 0x06 // connection state in master role also supported +#define LL_SLAVE_STATE 0x07 +// +#define LL_ADV_NONCONN_SCAN_PASSIVE_STATE 0x10 +#define LL_ADV_DISCOV_SCAN_PASSIVE_STATE 0x11 +#define LL_ADV_UNDIRECT_SCAN_PASSIVE_STATE 0x12 +#define LL_ADV_HDC_DIRECT_SCAN_PASSIVE_STATE 0x13 +#define LL_ADV_NONCONN_SCAN_ACTIVE_STATE 0x14 +#define LL_ADV_DISCOV_SCAN_ACTIVE_STATE 0x15 +#define LL_ADV_UNDIRECT_SCAN_ACTIVE_STATE 0x16 +#define LL_ADV_HDC_DIRECT_SCAN_ACTIVE_STATE 0x17 +// +#define LL_ADV_NONCONN_INIT_STATE 0x20 +#define LL_ADV_DISCOV_INIT_STATE 0x21 +#define LL_ADV_NONCONN_MASTER_STATE 0x22 +#define LL_ADV_DISCOV_MASTER_STATE 0x23 +#define LL_ADV_NONCONN_SLAVE_STATE 0x24 +#define LL_ADV_DISCOV_SLAVE_STATE 0x25 +#define LL_SCAN_PASSIVE_INIT_STATE 0x26 +#define LL_SCAN_ACTIVE_INIT_STATE 0x27 +// +#define LL_SCAN_PASSIVE_MASTER_STATE 0x30 +#define LL_SCAN_ACTIVE_MASTER_STATE 0x31 +#define LL_SCAN_PASSIVE_SLAVE_STATE 0x32 +#define LL_SCAN_ACTIVE_SLAVE_STATE 0x33 +#define LL_INIT_MASTER_STATE 0x34 // master role and master role combination also supported +// +#define LL_ADV_LDC_DIRECT_STATE 0x35 +#define LL_ADV_LDC_DIRECT_SCAN_PASSIVE_STATE 0x36 +#define LL_ADV_LDC_DIRECT_SCAN_ACTIVE_STATE 0x37 + +#define HCI_RX_PKT_HDR_SIZE 5 +#define LL_NUM_BYTES_FOR_CHAN_MAP 5 //(LL_MAX_NUM_ADV_CHAN+LL_MAX_NUM_DATA_CHAN)/sizeof(uint8) + +#define LL_CTRL_PROC_STATUS_SUCCESS 0 +#define LL_CTRL_PROC_STATUS_TERMINATE 1 + +// A2 multi-connection +#define LL_PROC_LINK_KEEP 0 +#define LL_PROC_LINK_TERMINATE 1 + +#define LL_TX_DATA_CONTEXT_POST_PROCESSING 2 + +#define LL_TX_DATA_CONTEXT_SEND_DATA 0 + +#define LL_LINK_SETUP_TIMEOUT 5 // 6 connection intervals (i.e. 0..5) + +// Setup Next Slave Procedure Actions +#define LL_SETUP_NEXT_LINK_STATUS_SUCCESS 0 +#define LL_SETUP_NEXT_LINK_STATUS_TERMINATE 1 + + +// Data PDU Control Packet Types +#define LL_CTRL_CONNECTION_UPDATE_REQ 0 // M +#define LL_CTRL_CHANNEL_MAP_REQ 1 // M +#define LL_CTRL_TERMINATE_IND 2 // M, S +#define LL_CTRL_ENC_REQ 3 // M +#define LL_CTRL_ENC_RSP 4 // , S +#define LL_CTRL_START_ENC_REQ 5 // , S +#define LL_CTRL_START_ENC_RSP 6 // M, S +#define LL_CTRL_UNKNOWN_RSP 7 // M, S +#define LL_CTRL_FEATURE_REQ 8 // M +#define LL_CTRL_FEATURE_RSP 9 // , S , also could be M in ver4.2 ... HZF +#define LL_CTRL_PAUSE_ENC_REQ 10 // M +#define LL_CTRL_PAUSE_ENC_RSP 11 // , S +#define LL_CTRL_VERSION_IND 12 // M, S +#define LL_CTRL_REJECT_IND 13 // , S + +// BLE 4.2 +#define LL_CTRL_SLAVE_FEATURE_REQ 14 +#define LL_CTRL_CONNECTION_PARAM_REQ 15 +#define LL_CTRL_CONNECTION_PARAM_RSP 16 +#define LL_CTRL_REJECT_EXT_IND 17 +#define LL_CTRL_PING_REQ 18 +#define LL_CTRL_PING_RSP 19 +#define LL_CTRL_LENGTH_REQ 20 +#define LL_CTRL_LENGTH_RSP 21 +// BLE 5.0 +#define LL_CTRL_PHY_REQ 22 +#define LL_CTRL_PHY_RSP 23 +#define LL_CTRL_PHY_UPDATE_IND 24 +#define LL_CTRL_MIN_USED_CHANNELS_IND 25 + +// TODO 2020-02-07 change , default: 26 +#define LL_CTRL_TERMINATE_RX_WAIT_FOR_TX_ACK 0xFE //26 // M (internal to LL only) + +// 2020-01-19 add for CTE +#define LL_CTRL_CTE_REQ 0x1A +#define LL_CTRL_CTE_RSP 0x1B + +// control procedure timeout in coarse timer ticks +#define LL_MAX_CTRL_PROC_TIMEOUT 64000 // 40s + +// Encryption Related +#define LL_ENC_RAND_LEN 8 +#define LL_ENC_EDIV_LEN 2 +#define LL_ENC_LTK_LEN 16 +#define LL_ENC_IRK_LEN 16 + +#define LL_ENC_IV_M_LEN 4 +#define LL_ENC_IV_S_LEN 4 +#define LL_ENC_IV_LINK_LEN 4 +#define LL_ENC_IV_LEN (LL_ENC_IV_M_LEN + LL_ENC_IV_S_LEN) +#define LL_ENC_SKD_M_LEN 8 +#define LL_ENC_SKD_S_LEN 8 +#define LL_ENC_SKD_LINK_LEN 8 +#define LL_ENC_SKD_LEN (LL_ENC_SKD_M_LEN + LL_ENC_SKD_S_LEN) +#define LL_ENC_SK_LEN 16 +#define LL_ENC_NONCE_LEN 13 +#define LL_END_NONCE_IV_OFFSET 5 +#define LL_ENC_MIC_LEN LL_PKT_MIC_LEN +// +#define LL_ENC_IV_M_OFFSET LL_ENC_IV_S_LEN +#define LL_ENC_IV_S_OFFSET 0 +#define LL_ENC_SKD_M_OFFSET LL_ENC_SKD_S_LEN +#define LL_ENC_SKD_S_OFFSET 0 +// +#define LL_ENC_BLOCK_LEN 16 +#define LL_ENC_CCM_BLOCK_LEN LL_ENC_BLOCK_LEN +#define LL_ENC_BLOCK_B0_FLAGS 0x49 +#define LL_ENC_BLOCK_A0_FLAGS 0x01 + +// Resolving Private Address list +#define LEN_24BIT 3 // Number of bytes in a 24 bit number +#define PRAND_SIZE LEN_24BIT // PRAND size in the Private Resolvable Address calculation + +// Address header bits +#define RANDOM_ADDR_HDR 0xC0 // Used for LL RANDOM Address +#define STATIC_ADDR_HDR 0xC0 // Host Static Address, same as RANDOM address +#define PRIVATE_RESOLVE_ADDR_HDR 0x40 + + +// Extended advertiser setting +#define LL_MAX_ADVERTISER_SET_LENGTH 0x672 // spec range: 0x1F ~ 0x672 +#define LL_INVALID_ADV_SET_HANDLE 0xFF + + +//////////////////// for scan +// Scanner Advertisment Channels +#define LL_SCAN_ADV_CHAN_37 37 +#define LL_SCAN_ADV_CHAN_38 38 +#define LL_SCAN_ADV_CHAN_39 39 + + +// add by HZF for whitelist +#define LL_WHITELIST_ENTRY_NUM 8 + +// BBB ROM code: resolving list size +#define LL_RESOLVINGLIST_ENTRY_NUM 8 + +// Periodic advertiser list size +#define LL_PRD_ADV_ENTRY_NUM 8 + + +struct bd_addr +{ + uint8_t addr[6]; +}; + + +typedef struct +{ + uint8_t peerAddrType; // peer device address type of public or random + uint8_t peerAddr[ 6 ]; // peer device address +} peerInfo_t; + +#define NETWORK_PRIVACY_MODE 0 +#define DEVICE_PRIVACY_MODE 1 +// BBB ROM code add +typedef struct +{ + uint8_t localIrk[16]; + uint8_t peerIrk[16]; + uint8_t peerAddrType; // peer device address type of public or random + uint8_t peerAddr[6]; // peer device address + + uint8_t privacyMode; // privacy mode, Network privacy mode or Device privacy mode + + // ==== add after BBB ROM code freeze + uint8_t localRpa[6]; // local resolvable address +} resolvingListInfo_t; + +// Periodic Advertiser list +typedef struct +{ + uint8_t addrType; // Advertising address type + uint8_t addr[6]; // Advertising address + uint8_t sid; // Advertising SID +} periodicAdvertiserListInfo_t; + +/// Advertising parameters +typedef struct +{ + uint8_t active; + + uint16_t advInterval; // the advertiser interval, based on advIntMin and advIntMax + /// Advertising type + uint16_t advMode; // flag to indicate if currently advertising + + uint8_t ownAddrType; // own device address type of public or random + uint8_t ownAddr[LL_DEVICE_ADDR_LEN]; // own device address + + uint8_t advChanMap; // saved Adv channel map; note, only lower three bits used + + uint8_t advEvtType; //connectable directed, undirected, discoverable, or non-connectable + + uint8_t wlPolicy; // white list policy for Adv + uint16_t scaValue; // Slave SCA in PPM + + uint8_t advDataLen; // advertiser data length + + // Scan Repsonse Parameters + uint8_t scanRspLen; // scan response data length + + // add by HZF + uint8 advNextChan; + + // multi-connection + uint8 connId; + +} advInfo_t; + +/// Extended Advertising parameters +typedef struct +{ +// uint8_t advHandle; // range: 0x00 - 0xEF + uint8_t advertisingSID; // range: 0x00 - 0x0F + + uint16_t advEventProperties; // adv event type + + uint32_t priAdvIntMin; // 3 octets, minimum primary adv interval + uint32_t priAdvgIntMax; // 3 octets, maximum primary adv interval + + uint8_t priAdvChnMap; + + uint8_t ownAddrType; // own device address type of public or random + uint8_t isOwnRandomAddressSet; // own random address type set flag. The address is set by HCI_LE_SET_ADVERTISING_SET_RANDOM_ADDRESS + uint8_t ownRandomAddress[LL_DEVICE_ADDR_LEN]; + + uint8_t peerAddrType; + uint8_t peerAddress[LL_DEVICE_ADDR_LEN]; + + uint8_t wlPolicy; // white list policy for Adv + + int8 advTxPower; + + uint8_t primaryAdvPHY; + uint8_t secondaryAdvPHY; + + uint8_t secondaryAdvMaxSkip; // the maximum number of advertising events that can be skipped before the AUX_ADV_IND can be sent + + uint8_t scanReqNotificationEnable; + +} extAdvParameter_t; + +/// data of Advertising set or scan response data +typedef struct +{ +// uint8_t advHandle; + uint8_t dataComplete; // all data of advert set received + uint8 fragmentPreference; + + uint16 advertisingDataLength; + uint8* advertisingData; + + // LL generated + uint16 DIDInfo; // 12bits +} advSetData_t; + +/// extended adv parameters, include spec parameters & implemented-specific parameters +typedef struct +{ + uint8_t advHandle; + + extAdvParameter_t parameter; + advSetData_t data; // only for extended adv + uint16 scanRspMaxLength; // length of scan rsp data + uint8* scanRspData; + + // ===================== advertisement enable info + uint32_t duration; // unit us, note spec parameter is 10ms unit + uint8_t maxExtAdvEvents; + + // ================= advertisement context parameters + uint8_t isPeriodic; // is the adv parameters for periodic adv + uint8_t active; // extended adv enable or not + uint32_t primary_advertising_interval; + + uint16_t adv_event_counter; // counter for extend adv event + uint32_t adv_event_duration; // duration of advertise + + int8 tx_power; // range -127 ~ 127 dBm, will be filled to field TxPower + + uint8_t sendingAuxAdvInd; + + // below parameters only applicable to extended adv, not for periodic adv + uint8_t currentChn; // current adv channel + + uint8_t auxChn; // 1st aux PDU channel No. + uint16_t currentAdvOffset; // current read ptr of adv data set, for fill AUX_XXX_IND PDUs +} extAdvInfo_t; + +typedef struct +{ + uint16 syncPacketOffset : 13; // 13bits + uint16 offsetUnit : 1; // 1 bit + uint16 offsetAdj : 1; // 1 bit + uint16 rfu : 1; // 1 bit +} syncInfoOffset_t; + +typedef struct +{ + uint8 chn_map : 5; // 5bits + uint8 sca : 3; // 3 bit +} chanMap4_t; + +typedef struct +{ + syncInfoOffset_t offset; + + uint16 interval; + + uint8 chn_map[4]; + chanMap4_t chn_map4; + + uint8 AA[4]; + uint8 crcInit[3]; + + uint16 event_counter; +} syncInfo_t; + +/// data of periodic Advertising set +typedef struct +{ + uint8 dataComplete; // all data of advert set received + + uint16 advertisingDataLength; + uint8* advertisingData; +} periodicAdvSetData_t; + +// 2020-01-15 add for connection & connectionless parameter +typedef struct +{ + // common +// uint16 handle; // syncConnHandle for connectionless , connHandle for connection + uint8 enable; // + uint8 CTE_Length; // connectionless transmit CTE length or connection request and response CTE Length + uint8 CTE_Type; // AOA, ADO 1us , AOD 2us + uint8 CTE_Count; // number of CTE to transmit in each PA interval + // IQ Sample:max number of CTE to sample and report in each PA interval + uint8 CTE_Count_Idx; // record the number of times that the CTE send , max equal to CTE_Count + uint8 pattern_LEN; + uint8 AntID[LL_CTE_MAX_PATTERN_LEN]; + + uint8 slot_Duration; // switching and sampling slot 1us or 2us + + // connectionless transmit param +// uint8 advSet; // identify connectionless advertising set + // CTEInfo_t merge to periodicAdvInfo_t , advSet not used + + // connection CTE request & response enable command + uint16 CTE_Request_Intv; + +} CTEInfo_t; + + +// periodic adv: data + parameters + enable flag +// note that periodic adv also need extended adv parameters + enable +typedef struct +{ + uint8_t advHandle; + + periodicAdvSetData_t data; + + uint16 adv_interval_min; + uint16 adv_interval_max; + uint16_t adv_event_properties; // adv event type + + // ================= advertisement context parameters + uint8_t active; // extended adv enable or not + uint32_t adv_interval; + + uint8_t secondaryAdvPHY; // reserved, should we copy this setting from ext adv info? ext adv may be disabled while keep periodic adv alive + + uint8 chn_map[5]; // 37 bits + uint8_t chanMapTable[LL_MAX_NUM_DATA_CHAN]; + uint8_t numUsedChans; // count of the number of usable data channels + uint8 sca; // 3 bit + + uint32 AA; + uint32 crcInit; + + uint8_t tx_power; // not setting now, reserve for TxPwr field + + uint16_t periodic_adv_event_counter; // counter for periodic adv event + uint8 pa_current_chn; // current periodic adv channel + + uint8_t currentChn; // current adv channel + + uint16_t currentAdvOffset; // current read ptr of adv data set, for fill AUX_XXX_IND PDUs + + // 2020-01-15 CTE global variable + CTEInfo_t PrdCTEInfo; +} periodicAdvInfo_t; + +/////////////////////////////////////////////////////////// +// Scanner Event Parameters +typedef struct +{ +// taskInfo_t *llTask; // pointer to associated task block + uint8 ownAddrType; // own device address type of public or random + uint8 ownAddr[ LL_DEVICE_ADDR_LEN ]; // own device address + uint8 initPending; // flag to indicate if Scan needs to be initialized + uint8 scanMode; // flag to indicate if currently scanning + uint8 scanType; // passive or active scan + uint16 scanInterval; // the interval between scan events + uint16 scanWindow; // the duration of a scan event + uint8 wlPolicy; // white list policy for Scan + uint8 filterReports; // flag to indicate if duplicate Adv packet reports are to be filtered + uint16 scanBackoffUL; // backoff upper limit count + uint8 nextScanChan; // advertising channel to be used by scanner + uint8 numSuccess; // for adjusting backoff count by tracking successive successes + uint8 numFailure; // for adjusting backoff count by tracking successive failures + uint16 currentBackoff; // current back off count, uint16 because the upper limit is 256 +} scanInfo_t; + +/////////////////////////////////////////////////////////// +// Extended Scanner Parameters +#define LL_MAX_EXTENDED_SCAN_PHYS 2 +#define LL_MAX_EXTENDED_INIT_PHYS 3 +#define LL_SCAN_PHY_1M_BITMASK 0x01 +#define LL_CONN_PHY_2M_BITMASK 0x02 // only for init +#define LL_SCAN_PHY_CODED_BITMASK 0x04 +typedef struct +{ + uint8 enable; + uint8 ownAddrType; // own device address type of public or random + uint8 ownAddr[ LL_DEVICE_ADDR_LEN ]; // own device address + uint8 wlPolicy; // white list policy for Scan + + uint8 numOfScanPHY; + uint8 scanPHYs[LL_MAX_EXTENDED_SCAN_PHYS]; // scan PHYs + + uint8 scanType[LL_MAX_EXTENDED_SCAN_PHYS]; // passive or active scan + uint16 scanInterval[LL_MAX_EXTENDED_SCAN_PHYS]; // the interval between scan events + uint16 scanWindow[LL_MAX_EXTENDED_SCAN_PHYS]; // the duration of a scan event + + uint8 filterDuplicate; // Duplicate filtering setting + uint16 duration; // scan duration in a scan period + uint16 period; // scan period + + // scan context + uint8 current_index; // current scan parameter index, 0 or 1 + uint8 current_scan_PHY; + uint8 current_chn; + + // TODO: check below members are required or not + uint16 adv_data_offset; // offset of long adv data + uint16 adv_data_buf_len; // adv data buffer size + uint8* adv_data; +} extScanInfo_t; + +typedef struct +{ + uint8 valid; + uint8 options; + uint8 advertising_SID; + uint8 advertiser_Address_Type; + uint8 advertiser_Address[LL_DEVICE_ADDR_LEN]; + uint16 skip; + uint16 sync_Timeout; + uint8 sync_CTE_Type; +} scannerSyncInfo_t; + +typedef struct +{ + uint8 header; + + uint8 advA[LL_DEVICE_ADDR_LEN]; + uint8 targetA[LL_DEVICE_ADDR_LEN]; + uint8 cteInfo; + uint16 adi; + + struct + { + uint8 chn_idx; + uint8 ca; + uint8 offset_unit; + uint16 aux_offset; + uint8 aux_phy; + } auxPtr; + + uint8 syncInfo[18]; + + uint8 txPower; +} extAdvHdr_t; + +/////////////////// Initiator Event Parameters +typedef struct +{ + uint8 ownAddrType; // own device address type of public or random + uint8 ownAddr[ LL_DEVICE_ADDR_LEN ]; // own device address + // + uint8 initPending; // flag to indicate if Scan needs to be initialized + uint8 scanMode; // flag to indicate if currently scanning + uint16 scanInterval; // the interval between scan events + uint16 scanWindow; // the duration of a scan event + uint8 nextScanChan; // advertising channel to be used by scanner + uint8 wlPolicy; // white list policy for Init + uint8 connId; // allocated connection ID + uint8 scaValue; // Master SCA as an ordinal value for PPM +} initInfo_t; + + +typedef struct +{ + uint8 ownAddrType; // own device address type of public or random + uint8 ownAddr[ LL_DEVICE_ADDR_LEN ]; // own device address + + uint8 wlPolicy; // white list policy for Init +// uint8 initPending; // flag to indicate if Scan needs to be initialized + uint8 scanMode; // flag to indicate if currently scanning + + uint8 numOfScanPHY; + uint8 initPHYs[LL_MAX_EXTENDED_SCAN_PHYS]; // scan PHYs + uint16 scanInterval[LL_MAX_EXTENDED_SCAN_PHYS]; // the interval between scan events + uint16 scanWindow[LL_MAX_EXTENDED_SCAN_PHYS]; // the duration of a scan event + + uint16 conn_interval_min[LL_MAX_EXTENDED_SCAN_PHYS]; + uint16 conn_interval_max[LL_MAX_EXTENDED_SCAN_PHYS]; + uint16 conn_latency[LL_MAX_EXTENDED_SCAN_PHYS]; + uint16 supervision_timeout[LL_MAX_EXTENDED_SCAN_PHYS]; + uint16 minimum_CE_length[LL_MAX_EXTENDED_SCAN_PHYS]; + uint16 maximum_CE_length[LL_MAX_EXTENDED_SCAN_PHYS]; + + // initiator parameters for 2Mbps PHY + uint8 is_2M_parameter_present; + uint16 conn_interval_min_2Mbps; + uint16 conn_interval_max_2Mbps; + uint16 conn_latency_2Mbps; + uint16 supervision_timeout_2Mbps; + uint16 minimum_CE_length_2Mbps; + uint16 maximum_CE_length_2Mbps; + + // scan context + uint8 current_index; // current scan parameter index, 0 or 1 + uint8 current_scan_PHY; + uint8 current_chn; + + uint8 connId; // allocated connection ID + uint8 scaValue; // Master SCA as an ordinal value for PPM +} extInitInfo_t; +///////////////////////////////////////////////////////////////// + +typedef struct +{ + uint8_t winSize; // window size + uint16_t winOffset; // window offset + uint16_t connInterval; // connection interval + uint16_t slaveLatency; // number of connection events the slave can ignore + uint16_t connTimeout; // supervision connection timeout +} connParam_t; + +typedef struct +{ + uint8_t verNum; // controller spec version + uint16_t comId; // company identifier + uint16_t subverNum; // implementation version +} verInfo_t; + +typedef struct +{ + uint8_t connId; // connection ID + uint8_t termIndRcvd; // indicates a TERMINATE_IND was received + uint8_t reason; // reason code to return to Host when connection finally ends +} termInfo_t; + +// TX Data +typedef struct txData_t +{ + struct txData_t* pNext; // pointer to next Tx data entry on queue +} txData_t; + +// Data Packet Queue +typedef struct +{ + txData_t* head; // pointer to head of queue + txData_t* tail; // pointer to tail of queue +} llDataQ_t; + + +// Version Information Exchange +typedef struct +{ + uint8_t peerInfoValid; // flag to indicate the peer's version information is valid + uint8_t hostRequest; // flag to indicate the host has requested the peer's version information + uint8_t verInfoSent; // flag to indicate this device's version information has been sent +} verExchange_t; + +// Feature Set Data +typedef struct +{ + uint8_t featureRspRcved; // flag to indicate the Feature Request has been responded to + uint8_t featureSet[ 8 ]; +} featureSet_t; + +// Channel Map +typedef struct +{ + uint8_t chanMap[ 5 ]; // bit map corresponding to the data channels 0..39 +} chanMap_t; + +// Control Procedure Information +typedef struct +{ + uint8_t ctrlPktActive; // flag that indicates a control packet is being processed + uint8_t ctrlPkts[ LL_MAX_NUM_CTRL_PROC_PKTS ]; // queue of control packets to be processed + uint8_t ctrlPktCount; // number of queued control packets + uint16_t ctrlTimeoutVal; // timeout in CI events for control procedure for this connection + uint16_t ctrlTimeout; // timeout counter in CI events for control procedure +} ctrlPktInfo_t; + +typedef struct +{ + uint16_t MaxTxOctets; + uint16_t MaxTxTime; + uint16_t MaxRxOctets; + uint16_t MaxRxTime; +} ll_pdu_length_ctrl_t; + +typedef struct +{ + ll_pdu_length_ctrl_t local; + ll_pdu_length_ctrl_t remote; + ll_pdu_length_ctrl_t suggested; // global setting + uint8_t isProcessingReq; + uint8_t isWatingRsp; + uint8_t isChanged; + uint8_t dummy[1]; +} llPduLenManagment_t; + +typedef struct +{ + uint8_t allPhy; + uint8_t txPhy; + uint8_t rxPhy; + uint8_t dummy[1]; +} ll_phy_ctrl_t; + +typedef struct +{ + uint8_t m2sPhy; + uint8_t s2mPhy; + uint16_t instant; +} ll_phy_update_ind_t; + +typedef struct +{ + ll_phy_ctrl_t def; + ll_phy_ctrl_t local; + ll_phy_ctrl_t req; + ll_phy_ctrl_t rsp; + uint16_t phyOptions; + uint8_t isChanged; + uint8_t isProcessingReq; + uint8_t isWatingRsp; + uint8_t status; + uint8_t dummy[2]; + +} llPhyModeManagment_t; + +// 2020-02-21 add for CTE req & rsp logic +typedef struct +{ + uint8_t isChanged; + uint8_t isProcessingReq; + uint8_t isWatingRsp; // wait other Ctrl command procedure + uint8_t errorCode; +} llCTEModeManagement_t; + +// for timer drift adjust +typedef struct +{ + uint32 coarse; // number of 625us ticks at SFD capture + uint16 fine; // number of 31.25ns ticks at SFD capture +} sysTime_t; + +// Encryption +typedef struct +{ + // Note: IV and SKD provide enough room for the full IV and SKD. When the + // Master and Slave values are provided, the result is one combined + // (concatenated) value. + uint8 IV[ LL_ENC_IV_LEN ]; // combined master and slave IV values concatenated + uint8 SKD [ LL_ENC_SKD_LEN ]; // combined master and slave SKD values concatenated + uint8 RAND[ LL_ENC_RAND_LEN ]; // random vector from Master + uint8 EDIV[ LL_ENC_EDIV_LEN ]; // encrypted diversifier from Master + uint8 nonce[ LL_ENC_NONCE_LEN ]; // current nonce with current IV value + uint8 SK[ LL_ENC_SK_LEN ]; // session key derived from LTK and SKD + uint8 LTK[ LL_ENC_LTK_LEN ]; // Long Term Key from Host + uint8 SKValid; // flag that indicates the Session Key is valid + uint8 LTKValid; // Long Term Key is valid + uint32 txPktCount; // used for nonce formation during encryption (Note: 39 bits!)?? + uint32 rxPktCount; // used for nonce formation during encryption (Note: 39 bits!)?? + uint8 encRestart; // flag to indicate if an encryption key change took place + uint8 encRejectErrCode; // error code for rejecting encryption request + // ALT: COULD USE ONE VARIABLE AND STATES FOR THESE FLAGS; IF SO, THE + // CONTROL PROCEDURE WOULD NEED TO BE REWORKED. + uint8 startEncRspRcved; // flag to indicate the Start Request has been responded to + uint8 pauseEncRspRcved; // flag to indicate the Pause Request has been responded to + uint8 encReqRcved; // flag to indicate an Enc Req was received in a Enc Pause procedure + + + uint8 startEncReqRcved; // flag to indicate the Start Request has been responded to + uint8 rejectIndRcved; // flag to indicate the Start Encryption needs to be aborted + +} encInfo_t; + +// Packet Error Rate Information - General +typedef struct +{ + uint16 numPkts; // total number of packets + uint16 numCrcErr; // total number of packets with CRC error + uint16 numEvents; // total number of connection events + uint16 numMissedEvts; // total number of missed connection events +} perInfo_t; + +typedef struct +{ + // adv channel statistics + int ll_send_undirect_adv_cnt; + int ll_send_nonconn_adv_cnt; + int ll_send_scan_adv_cnt; + int ll_send_hdc_dir_adv_cnt; + int ll_send_ldc_dir_adv_cnt; + + // adv in conn event + int ll_send_conn_adv_cnt; + int ll_conn_adv_pending_cnt; + + // scan in conn event + int ll_conn_scan_pending_cnt; + + // slave counter + int ll_recv_scan_req_cnt; + int ll_send_scan_rsp_cnt; + int ll_recv_conn_req_cnt; + int ll_send_conn_rsp_cnt; + + // whitelist + int ll_filter_scan_req_cnt; + int ll_filter_conn_req_cnt; + + // scan + int ll_recv_adv_pkt_cnt; + int ll_send_scan_req_cnt; + int ll_recv_scan_rsp_cnt; + + + // connection event counters + int ll_conn_succ_cnt; // LL accept connect, but not always sync succ + + int ll_link_lost_cnt; + int ll_link_estab_fail_cnt; + + // connection packet statistics +// int ll_recv_ctrl_pkt_cnt; +// int ll_recv_data_pkt_cnt; +// int ll_recv_invalid_pkt_cnt; +// +// int ll_recv_abnormal_cnt; +// +// int ll_send_data_pkt_cnt; +// +// int ll_conn_event_cnt; +// int ll_recv_crcerr_event_cnt; // CRC error detected in the connection event +// int ll_conn_event_timeout_cnt; // timeout connection event countt + + int ll_rx_peer_cnt; // scan/conn request counter, to consider whether we need it + + // LL <-> HCI packets statistics +// int ll_to_hci_pkt_cnt; +// int ll_hci_to_ll_pkt_cnt; +// +// int ll_hci_buffer_alloc_err_cnt; + + //ll_hw err cnt + int ll_evt_shc_err; + + //ll_hw err cnt + int ll_trigger_err; + int ll_rfifo_rst_err; + int ll_rfifo_rst_cnt; + int ll_rfifo_read_err; + + // reserve counter + int ll_tbd_cnt1; + int ll_tbd_cnt2; + int ll_tbd_cnt3; + int ll_tbd_cnt4; + int ll_tbd_cnt5; + int ll_tbd_cnt6; + int ll_tbd_cnt7; + int ll_tbd_cnt8; + +} llGlobalStatistics_t; + +// ======= multi-connection +typedef struct +{ + // connection packet statistics + uint32_t ll_recv_ctrl_pkt_cnt; + uint32_t ll_recv_data_pkt_cnt; + uint32_t ll_recv_invalid_pkt_cnt; + + uint32_t ll_recv_abnormal_cnt; + + uint32_t ll_send_data_pkt_cnt; + + uint32_t ll_conn_event_cnt; + uint32_t ll_recv_crcerr_event_cnt; // CRC error detected in the connection event + uint32_t ll_conn_event_timeout_cnt; // timeout connection event countt + + // LL <-> HCI packets statistics + uint32_t ll_to_hci_pkt_cnt; + uint32_t ll_hci_to_ll_pkt_cnt; + + uint32_t ll_hci_buffer_alloc_err_cnt; + + uint32_t ll_miss_master_evt_cnt; + uint32_t ll_miss_slave_evt_cnt; + + + // reserve counter + uint32_t ll_tbd_cnt1; + uint32_t ll_tbd_cnt2; + uint32_t ll_tbd_cnt3; + uint32_t ll_tbd_cnt4; + +} llLinkStatistics_t; + +typedef struct +{ + uint8_t chanMap[5]; + uint16_t chanMapUpdateEvent; // event count to indicate when to apply pending chan map update + uint8_t chanMapUpdated; +} preChanMapUpdate_t; + + +// Connection Data +typedef struct +{ + uint8_t rx_timeout; // ----- + uint8_t rx_crcok; // ----- + uint8_t allocConn; // flag to indicate if this connection is allocated + uint8_t active; // flag to indicate if this connection is active + uint8_t connId; // connection ID + uint8_t firstPacket; // flag to indicate when the first packet has been received. 0 means TURE, 1 means FALSE + + uint16_t currentEvent; // current event number + uint16_t nextEvent; // next active event number + uint16_t lastCurrentEvent; + uint16_t expirationEvent; // event at which the LSTO has expired + uint16_t expirationValue; // number of events to a LSTO expiration + + + uint16_t scaFactor; // SCA factor for timer drift calculation + uint32_t timerDrift; // saved timer drift adjustment to avoid recalc + uint32_t accuTimerDrift; // accumulate timer drift + // Connection Parameters + uint32_t lastTimeToNextEvt; // the time to next event from the previous connection event + uint8_t slaveLatencyAllowed; // flag to indicate slave latency is permitted + uint16_t slaveLatency; // current slave latency; 0 means inactive + uint8_t lastSlaveLatency; // last slave latency value used + uint16_t slaveLatencyValue; // current slave latency value (when enabled) + + uint32_t accessAddr; // saved synchronization word to be used by Slave + uint32_t initCRC; // connection CRC initialization value (24 bits) + + uint8_t sleepClkAccuracy; // peer's sleep clock accurracy; used by own device to determine timer drift + connParam_t curParam; + + // current connection parameters + // Channel Map + uint8_t nextChan; // the channel for the next active connection event + uint8_t currentChan; // the channel for the currently completed connection event + uint8_t lastCurrentChan; // the channel for the last currentChan for disable slavelatency usage + + uint8_t numUsedChans; // count of the number of usable data channels + // uint8_t hopLength; // used for finding next data channel at next connection event + uint8_t chanMapTable[LL_MAX_NUM_DATA_CHAN]; // current chan map table that is in use for this connection + + uint8_t chanMap[5]; + + chanMap_t chanMapUpdate; // slave chanMapUpdate for different connId + preChanMapUpdate_t preChanMapUpdate; // used for disable latency + uint8_t hop; + + // TX Related + uint8_t txDataEnabled; // flag that indicates whether data output is allowed + llDataQ_t txDataQ; // queue of Tx Data packets + // RX Related + uint8_t rxDataEnabled; // flag that indicates whether data input is allowed + uint8_t lastRssi; // last data packet RSSI received on this connection + + uint16_t foff; // A2 add, sync qualitiy indicator, estimated by rx BB + uint8_t carrSens; // A2 add, estimated freq offset by rx BB ,foff-512-->[-512 511]KHz + + // Control Packet Information + ctrlPktInfo_t ctrlPktInfo; // information for control procedure processing + // Parameter Update Control Procedure + uint8_t pendingParamUpdate; // flag to indicate connection parameter update is pending + uint16_t paramUpdateEvent; // event count to indicate when to apply pending param update + connParam_t paramUpdate; // update parameters + // Channel Map Update Control Procedure + uint8_t pendingChanUpdate; // flag to indicate connection channel map update is pending + uint16 chanMapUpdateEvent; // event count to indicate when to apply pending chan map update + // Encryption Data Control Procedure + uint8 encEnabled; // flag to indicate that encryption is enabled for this connection + encInfo_t encInfo; // structure that holds encryption related data + // Feature Set + featureSet_t featureSetInfo; // feature set for this connection + // Version Information + verExchange_t verExchange; // version information exchange + verInfo_t verInfo; // peer version information + // Termination Control Procedure + termInfo_t termInfo; // structure that holds connection termination data + // Unknnown Control Packet + uint8 unknownCtrlType; // value of unknown control type + // Packet Error Rate + perInfo_t perInfo; // PER + + uint8_t isCollision; + uint8_t rejectOpCode; + + ll_phy_update_ind_t phyUpdateInfo; // ll_phy update + // Parameter Update Control Procedure + uint8_t pendingPhyModeUpdate; // flag to indicate connection ll phy update is pending + uint16_t phyModeUpdateEvent; + + uint8_t sn_nesn; // use to save last sn/nesn in new IC + + // for new IC + uint8_t llMode; // for RTLP & TRLP loop, may need change the HW engine mode. + + // =============== A2 multi connection + uint8_t ctrlDataIsProcess ; // seding a control packet or not + uint8_t ctrlDataIsPending ; // control packet is pending to be sent +// uint8_t dummy[2]; // for 4-bytes align + + int anchor_point_base_time; // do we need it? + int anchor_point_fine_time; // do we need it? + + int next_event_base_time; // do we need it? + int next_event_fine_time; // do we need it? + + ctrl_packet_buf ctrlData; + llLinkBuf_t ll_buf; + + // DLE + llPduLenManagment_t llPduLen; + llPhyModeManagment_t llPhyModeCtrl; + + // add after BBB ROM release, PHY format + uint8_t llRfPhyPktFmt; + // add after BBB ROM release, channel selection algorithm + uint8_t channel_selection; + + llLinkStatistics_t pmCounter; + + // 2020-01-19 add for CTE + // llCTE_ReqFlag,llCTE_RspFlag only indicate CTE Request and Response enable or disable status + uint8 llCTE_ReqFlag; + uint8 llCTE_RspFlag; + // CTE REQ & RSP Control + llCTEModeManagement_t llCTEModeCtrl; + CTEInfo_t llConnCTE; + + // reserved variables + uint32 llTbd1; + uint32 llTbd2; + uint32 llTbd3; + uint32 llTbd4; +} llConnState_t; + +typedef struct +{ + uint8 rsc_idx; // connection ID, reserved for dynamic resource allocate + uint8 priority; + uint8 linkRole; // link role, slave(LL_ROLE_SLAVE) or master(LL_ROLE_MASTER) + + uint32 task_period; // schedule period, calculate from connection interval, in us. required??? + uint32 task_duration; // task duration + uint32 remainder; // remainder time + +// uint32 lastTimerValue; // last timer configure value + +} llScheduleInfo_t; + +// Per BLE LL Connection (max number is BLE_LL_MAX_NUM_LL_CONNS) +typedef struct +{ + uint8 numLLConns; // number of allocated connections + uint8 numLLMasterConns; // number of master, to check whether we need it + uint8 currentConn; // the LL connection currently in use + + llScheduleInfo_t scheduleInfo[MAX_NUM_LL_CONN_ROM_LIMT]; // scheduler information + + // ========== common link parameter for all master connection + uint16 connInterval; // connection interval + uint16 slaveLatency; // number of connection events the slave can ignore + uint16 connTimeout; // supervision connection timeout + + uint32 per_slot_time; // delta T per resource slot + + uint32 timerExpiryTick; // last LL timer expiry tick in 1s timer + uint32 current_timer; // LL timer initial load value + +} llConns_t; + +// for extended/periodic adv shceduler +typedef struct +{ +// uint8 advInfoIdx; // index in the adv parameters array +// uint8 advSetIdx; // index in the adv parameters array + uint8 adv_handler; + extAdvInfo_t* pAdvInfo; + +// uint8 eventType; // adv event type + +// uint32 task_period; // schedule period, calculate from connection interval, in us. required??? +// uint32 task_duration; // task duration + uint32 nextEventRemainder; // remainder time + uint32 auxPduRemainder; // remainder time + +} llAdvScheduleInfo_t; + +typedef struct +{ +// uint8 advInfoIdx; // index in the adv parameters array +// uint8 advSetIdx; // index in the adv parameters array + uint8 adv_handler; + periodicAdvInfo_t* pAdvInfo_prd; + extAdvInfo_t* pAdvInfo; + +// uint32 task_period; // schedule period, calculate from connection interval, in us. required??? +// uint32 task_duration; // task duration + uint32 nextEventRemainder; // primary channel PDU remainder time + uint32 auxPduRemainder; // auxilary channel PDU remainder time + +} llPeriodicAdvScheduleInfo_t; + +// periodic scanner context +typedef struct +{ + uint16 syncHandler; + uint8 valid; // the syncInfo is valid or not + uint8 syncEstOk; // sync the periodic adv event OK? + uint8 event1stFlag; // indicate LL is searching AUX_SYNC_IND PDU + + uint16 skip; + uint32 syncTimeout; // unit us, need *1250 when convert from HCI value + uint8 syncCteType; + +// syncInfoOffset_t offset; + + uint32 advInterval; // periodic adv event interval, unit us, need *1250 when convert from air interface PDU value + + uint8 chnMap[5]; + + uint8_t chanMapTable[LL_MAX_NUM_DATA_CHAN]; + uint8_t numUsedChans; // count of the number of usable data channels + + uint8 sca; + + uint8 accessAddress[4]; + uint16 channelIdentifier; + uint8 crcInit[3]; + + uint8 advPhy; + uint8 current_channel; // current scan channel, for AUX_CHAIN_IND, it may different with 1st PDU channel + uint8 currentEventChannel; // current periodic adv event 1st PDU channel + uint16 eventCounter; // periodic adv event counter + + uint16 syncLostTime; + + uint32 nextEventRemainder; // next periodic advertisement event remainder time + + // 2020-01-17 add for CTE Sampling + CTEInfo_t IQSampleInfo; +} llPeriodicScannerInfo_t; + +// ===== BBB ROM code added +typedef struct +{ + uint8 isTimer1RecoverRequired; + uint32 timer1Remainder; + +// uint8 isTimer2RecoverRequired; +// uint32 timer2Remainder; +// +// uint8 isTimer3RecoverRequired; +// uint32 timer3Remainder; + + uint8 isTimer4RecoverRequired; + uint32 timer4Remainder; +} llSleepContext; + +typedef uint8 llStatus_t; + +// Packet Error Rate Information By Channel +typedef struct +{ + uint16 numPkts[ LL_MAX_NUM_DATA_CHAN ]; + uint16 numCrcErr[ LL_MAX_NUM_DATA_CHAN ]; +} perByChan_t; + +typedef struct +{ + uint16 rxNumPkts[ LL_MAX_NUM_DATA_CHAN ]; + uint16 rxNumCrcErr[ LL_MAX_NUM_DATA_CHAN ]; + uint16 txNumRetry[ LL_MAX_NUM_DATA_CHAN ]; + uint16 TxNumAck[ LL_MAX_NUM_DATA_CHAN ]; + uint16 rxToCnt[ LL_MAX_NUM_DATA_CHAN ]; + uint16 connEvtCnt[ LL_MAX_NUM_DATA_CHAN ]; + + +} perStatsByChan_t; + +typedef struct +{ + uint16 rxNumPkts; + uint16 rxNumCrcErr; + uint16 txNumRetry; + uint16 TxNumAck; + uint16 rxToCnt; + uint16 connEvtCnt; + + +} perStats_t; + + +typedef enum +{ + LE_1M_PHY= 0x01, + LE_2M_PHY= 0x02, + LE_CODED_PHY=0x04, + +} PhyModeCtrl_e; + +typedef uint8_t ( *LL_PLUS_AdvDataFilterCB_t )(void); + +typedef uint8_t ( *LL_PLUS_ScanRequestFilterCB_t )(void); + + +// Counters +typedef struct +{ + uint8 numTxDone; // TX pkts ACK'ed (auto-empty not counted) + uint8 numTxAck; // TX pkts ACK'ed (both auto-empty and TX FIFO packets) + uint8 numTxCtrlAck; // TX control pkts ACK'ed + uint8 numTxCtrl; // TX control pkts TX'ed + uint8 numTxRetrans; // retrans + auto-empty retrans + uint8 numTx; // trans (incl. auto-empty) + retrans (incl. auto-empty) + uint8 numRxOk; // non-empty correctly RX'ed and not ignored data and control pkts + uint8 numRxCtrl; // correctly RX'ed control pkts + uint8 numRxNotOk; // RX'ed with bad CRC + uint8 numRxIgnored; // correctly RX'ed, but ignored + uint8 numRxEmpty; // correctly RX'ed empty packets + uint8 numRxFifoFull; // correctly RX'ed but discarded due to full RX FIFO +} rfCounters_t; + + +// global variables +extern uint8_t LL_TaskID; +extern uint8_t llState; +extern peerInfo_t peerInfo; +extern advInfo_t adv_param; +extern scanInfo_t scanInfo; // scan data +extern initInfo_t initInfo; // Initiator info +extern extScanInfo_t extScanInfo; // extended Scanner info +extern extInitInfo_t extInitInfo; // extended Initiator info +extern chanMap_t chanMapUpdate; +extern featureSet_t deviceFeatureSet; +//extern preChanMapUpdate_t preChanMapUpdate[]; + +extern uint8 g_maxConnNum; +extern uint8 g_maxPktPerEventTx; +extern uint8 g_maxPktPerEventRx; +extern llConnState_t* conn_param; + +extern uint8 numComplPkts; +extern uint8 numComplPktsLimit; + +extern verInfo_t verInfo; + +extern rfCounters_t rfCounters; + +extern llConns_t g_ll_conn_ctx; + +extern llGlobalStatistics_t g_pmCounters; + +extern llPduLenManagment_t g_llPduLen; +//extern llPhyModeManagment_t g_llPhyModeCtrl; + +extern peerInfo_t g_llWhitelist[]; +// Resolving list +extern resolvingListInfo_t g_llResolvinglist[]; +extern uint8 g_llRlEnable; +extern uint8 g_llRlDeviceNum; // current device number in resolving list, should not exceed LL_RESOLVINGLIST_ENTRY_NUM +extern uint16 g_llRlTimeout; + +// extended advertiser +extern extAdvInfo_t* g_pExtendedAdvInfo; +extern periodicAdvInfo_t* g_pPeriodicAdvInfo; +extern uint8 g_extAdvNumber; // number of ext adv set +extern uint8 g_perioAdvNumber; // number of periodic adv set + +extern uint16 g_advSetMaximumLen; + +// extended adv scheduler context +extern llAdvScheduleInfo_t* g_pAdvSchInfo; +extern uint8 g_schExtAdvNum; // current schedule extended adv number +extern uint8 g_currentExtAdv; // current schedule extended adv index + +// ==== periodic adv scheduler context +extern llPeriodicAdvScheduleInfo_t* g_pAdvSchInfo_periodic; // periodic adv scheduler info +extern uint8 g_schExtAdvNum_periodic; // current scheduler periodic adv number +extern uint8 g_currentExtAdv_periodic; // current scheduler periodic adv index + +extern uint32 g_advPerSlotTick; // us +extern uint32 g_advSlotPeriodic; // us +extern uint32 g_currentAdvTimer; // us +extern uint32 g_timerExpiryTick; // us + +extern uint8 g_currentTimerTask; + +extern llSleepContext g_llSleepContext; + + +extern llPeriodicScannerInfo_t g_llPeriodAdvSyncInfo[]; +// =========== BBB ROM code +#define LL_TASK_EXTENDED_ADV 0x01 +#define LL_TASK_PERIODIC_ADV 0x02 + +#define LL_TASK_EXTENDED_SCAN 0x03 +#define LL_TASK_EXTENDED_INIT 0x04 +#define LL_TASK_PERIODIC_SCAN 0x05 +//#define LL_TASK_SLAVE_CONN 0x03 +//#define LL_TASK_MASTER_CONN 0x04 +#define LL_TASK_OTHERS 0x10 +#define LL_TASK_INVALID 0xFF +extern uint8 llTaskState; + +extern extAdvHdr_t ext_adv_hdr; + +// 2020-02-15 add for connectionless IQ Sample buffer +extern uint16* g_pLLcteISample; +extern uint16* g_pLLcteQSample; +#endif + + + + + + + + + + + + + + diff --git a/arch/arm/src/phy62xx/ble/controller/ll_enc.h b/arch/arm/src/phy62xx/ble/controller/ll_enc.h new file mode 100644 index 00000000000..ace879b4e0b --- /dev/null +++ b/arch/arm/src/phy62xx/ble/controller/ll_enc.h @@ -0,0 +1,124 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/******************************************************************************* + Filename: ll_enc.h + Revised: + Revision: + + Description: This file contains the Link Layer (LL) types, contants, + API's etc. for the Bluetooth Low Energy (BLE) Controller + CCM encryption and decryption. + + This API is based on ULP BT LE D09R23. + + +*******************************************************************************/ + +#ifndef LL_ENC_H +#define LL_ENC_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + INCLUDES +*/ +#include "bcomdef.h" +#include "ll_def.h" + +/******************************************************************************* + MACROS +*/ + +/******************************************************************************* + CONSTANTS +*/ + +#define LL_ENC_TX_DIRECTION_MASTER 1 +#define LL_ENC_TX_DIRECTION_SLAVE 0 +#define LL_ENC_RX_DIRECTION_MASTER 0 +#define LL_ENC_RX_DIRECTION_SLAVE 1 + +#define LL_ENC_DATA_BANK_MASK 0xFF7F + +#define LL_ENC_TRUE_RAND_BUF_SIZE ((LL_ENC_IV_LEN/2) + (LL_ENC_SKD_LEN/2)) + +// Generate Session Key using LTK for key and SKD for plaintext. +#define LL_ENC_GenerateSK LL_ENC_AES128_Encrypt + +/******************************************************************************* + TYPEDEFS +*/ + +/******************************************************************************* + LOCAL VARIABLES +*/ + +/******************************************************************************* + GLOBAL VARIABLES +*/ +extern uint8 dataPkt[2*LL_ENC_BLOCK_LEN]; +extern uint8 cachedTRNGdata[ LL_ENC_TRUE_RAND_BUF_SIZE ]; + +/******************************************************************************* + Functions +*/ + +// Random Number Generation +extern uint8 LL_ENC_GeneratePseudoRandNum( void ); +extern uint8 LL_ENC_GenerateTrueRandNum( uint8* buf, uint8 len ); + +// CCM Encryption +extern void LL_ENC_AES128_Encrypt( uint8* key, uint8* plaintext, uint8* ciphertext ); +extern void LL_ENC_AES128_Decrypt( uint8* key, uint8* ciphertext, uint8* plaintext ); +extern void LL_ENC_LoadEmptyIV( void ); +extern void LL_ENC_ReverseBytes( uint8* buf, uint8 len ); +extern void LL_ENC_GenDeviceSKD( uint8* SKD ); +extern void LL_ENC_GenDeviceIV( uint8* IV ); +extern void LL_ENC_GenerateNonce( uint32 pktCnt, uint8 direction, uint8* nonce ); +extern void LL_ENC_EncryptMsg( uint8* nonce, uint8 pktLen, uint8* pbuf, uint8* mic ); +extern void LL_ENC_DecryptMsg( uint8* nonce, uint8 pktLen, uint8* pBuf, uint8* mic ); +extern void LL_ENC_Encrypt( llConnState_t* connPtr, uint8 pktHdr, uint8 pktLen, uint8* pBuf ); +extern uint8 LL_ENC_Decrypt( llConnState_t* connPtr, uint8 pktHdr, uint8 pktLen, uint8* pBuf ); +extern void LL_ENC_sm_ah( uint8* pK, uint8* pR, uint8* pAh ); +// + +extern void LL_ENC_MoveData( uint8* pDst, uint8* pSrc, uint16 len ); + +#ifdef __cplusplus +} +#endif + +#endif /* LL_ENC_H */ diff --git a/arch/arm/src/phy62xx/ble/controller/ll_hw_drv.h b/arch/arm/src/phy62xx/ble/controller/ll_hw_drv.h new file mode 100644 index 00000000000..0d654806c75 --- /dev/null +++ b/arch/arm/src/phy62xx/ble/controller/ll_hw_drv.h @@ -0,0 +1,244 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +#ifndef _LL_HW_DRV_H_ +#define _LL_HW_DRV_H_ + +#include "types.h" +#include "ll_def.h" +#include "bus_dev.h" +#include "rf_phy_driver.h" + +// LL_HW_REGISTER_ADDRESS +#define BB_HW_BASE 0x40030000 //BB_HW Base address +#define LL_HW_BASE 0x40031000 //LL_HW Base address +#define LL_HW_TFIFO (LL_HW_BASE+0x400) +#define LL_HW_RFIFO (LL_HW_BASE+0xC00) + +#define LL_HW_WRT_EMPTY_PKT *(volatile uint32_t *)(LL_HW_TFIFO) = 0x00000001 + +//LL_HW_MODE +#define LL_HW_STX 0x0000 +#define LL_HW_SRX 0x0001 + +#define LL_HW_TRX 0x0010 +#define LL_HW_RTX 0x0012 + +#define LL_HW_TRLP 0x0020 +#define LL_HW_TRLP_EMPT 0x0022 + +#define LL_HW_RTLP 0x0030 +#define LL_HW_RTLP_1ST 0x0031 +#define LL_HW_RTLP_EMPT 0x0032 + +#define HCLK16M + +//#define LL_HW_CYCLES_PER_US CYCLES_PER_US +#ifdef HCLK16M + #define LL_HW_HCLK_PER_US 16 // + #define LL_HW_HCLK_PER_US_BITS 4 +#else + #define LL_HW_HCLK_PER_US 32 // + #define LL_HW_HCLK_PER_US_BITS 5 +#endif + +#define LL_HW_FIFO_MARGIN 70 // + + +// LL_HW_IRQ_STATUS +#define LIRQ_MD 0x0001 //bit00 +#define LIRQ_CERR 0x0002 //bit01 +#define LIRQ_RTO 0x0004 //bit02 +#define LIRQ_RFULL 0x0008 //bit03 +#define LIRQ_RHALF 0x0010 //bit04 +#define LIRQ_BIT5 0x0020 //bit05 +#define LIRQ_BIT6 0x0040 //bit06 +#define LIRQ_BIT7 0x0080 //bit07 +#define LIRQ_TD 0x0100 //bit08 +#define LIRQ_RD 0x0200 //bit09 +#define LIRQ_COK 0x0400 //bit10 +#define LIRQ_CERR2 0x0800 //bit11 +#define LIRQ_LTO 0x1000 //bit12 +#define LIRQ_NACK 0x2000 //bit13 +#define LIRQ_BIT14 0x4000 //bit14 +#define LIRQ_BIT15 0x8000 //bit15 + +#define LL_HW_IRQ_MASK 0x3FFF //total 14bit + +// LL_HW_RFIFO_CTRL +#define LL_HW_IGN_EMP 0x0001 //bit0 +#define LL_HW_IGN_CRC 0x0002 //bit1 +#define LL_HW_IGN_SSN 0x0004 //bit2 +#define LL_HW_IGN_ALL 0x0007 //bit2 +#define LL_HW_IGN_NONE 0x0000 + +// LL_MD_RX_INI +#define LL_HW_MD_RX_SET0 0x4000 //set md_rx ini=0 and md_rx_soft=0 +#define LL_HW_MD_RX_SET1 0x4440 //set md_rx ini=1 and md_rx_soft=1 + +//LL FIFO DEPTH CONFIG +#define LL_HW_FIFO_TX_2K_RX_2K 0x0200 //TX FIFO 512 Word +#define LL_HW_FIFO_TX_3K_RX_1K 0x0300 //TX FIFO 768 Word +#define LL_HW_FIFO_TX_1K_RX_3K 0x0100 //TX FIFO 256 Word + +//BB CRC Format Setting +#define LL_HW_CRC_BLE_FMT 0x02 +#define LL_HW_CRC_ZB_FMT 0x03 +#define LL_HW_CRC_16_FMT 0x04 +#define LL_HW_CRC_NULL 0x00 + + +//ANT SWITCH SLOT +#define LL_HW_ANT_WIN_1us 4 +#define LL_HW_ANT_SW_CTE_OFF 0x00 +#define LL_HW_ANT_SW_CTE_AUTO 0x01 +#define LL_HW_ANT_SW_TX_MANU 0x02 +#define LL_HW_ANT_SW_RX_MANU 0x04 + +//CTE Supplement Config +#define CTE_SUPP_AUTO 0xC0 +#define CTE_SUPP_LEN_SET 0x00 +#define CTE_SUPP_NULL 0x00 + +#define CONNLESS_CTE_TYPE_AOA 0x00 +#define CONNLESS_CTE_TYPE_AOD_1us 0x01 +#define CONNLESS_CTE_TYPE_AOD_2us 0x02 +#define CONN_CTE_TYPE_AOA 0x01 +#define CONN_CTE_TYPE_AOD_1us 0x02 +#define CONN_CTE_TYPE_AOD_2us 0x04 + + +// 2020-01-21 add for CONN CTE REQ TYPE +#define CTE_REQ_TYPE_AOA 0x00 +#define CTE_REQ_TYPE_AOD_1US 0x01 +#define CTE_REQ_TYPE_AOD_2US 0x02 + +#define BLE_HEAD_WITH_CTE(x) (((x & 0x20)==0x00) ? 0:1) + + + +void ll_hw_set_stx(void); +void ll_hw_set_srx(void); +void ll_hw_set_trx(void); +void ll_hw_set_rtx(void); +void ll_hw_set_trlp(uint8_t snNesn,uint8_t txPktNum,uint8_t rxPktNum,uint8_t mdRx); +void ll_hw_set_rtlp(uint8_t snNesn,uint8_t txPktNum,uint8_t rxPktNum,uint8_t mdRx,uint32_t rdCntIni); +void ll_hw_set_rtlp_1st(uint8_t snNesn,uint8_t txPktNum,uint8_t rxPktNum,uint8_t mdRx); +void ll_hw_config(uint8_t ll_mode,uint8_t snNesn,uint8_t txPktNum,uint8_t rxPktNum,uint8_t mdRx,uint32_t rdCntIni); + + + +void ll_hw_go(void); +void ll_hw_trigger(void); +void ll_hw_clr_irq(void); +void ll_hw_set_irq(uint32_t mask); +void ll_hw_set_empty_head(uint16_t txHeader); +void ll_hw_set_rx_timeout_1st(uint32_t rxTimeOut); +void ll_hw_set_rx_timeout(uint32_t rxTimeOut); +void ll_hw_set_tx_rx_release(uint16_t txTime,uint16_t rxTime); +void ll_hw_set_rx_tx_interval(uint32_t intvTime); +void ll_hw_set_tx_rx_interval(uint32_t intvTime); +void ll_hw_set_trx_settle(uint8_t tmBb,uint8_t tmAfe,uint8_t tmPll); +void ll_hw_set_loop_timeout(uint32_t loopTimeOut); +void ll_hw_set_loop_nack_num(uint8_t nAckNum); +void ll_hw_set_timing(uint8_t pktFmt); + +void ll_hw_set_tfifo_space(uint16 space); + +void ll_hw_set_ant_switch_mode(uint8_t mode); +void ll_hw_set_ant_switch_timing(uint8_t antWin,uint8_t antDly); +void ll_hw_set_ant_pattern(uint32_t ant1, uint32_t ant0); + +void ll_hw_set_cte_rxSupp(uint8_t rxSupp); +void ll_hw_set_cte_txSupp(uint8_t txSupp); +uint8_t ll_hw_get_iq_RawSample(uint16_t* p_iSample, uint16_t* p_qSample); + + +void ll_hw_rst_rfifo(void); +void ll_hw_rst_tfifo(void); + +void ll_hw_ign_rfifo(uint8_t ignCtrl); + +void ll_hw_get_tfifo_info(int* rdPtr,int* wrPtr,int* wrDepth); +void ll_hw_get_rfifo_info(int* rdPtr,int* wrPtr,int* rdDepth); +void ll_hw_get_rxPkt_stats(uint8_t* crcErrNum,uint8_t* rxTotalNum,uint8_t* rxPktNum); + +uint8_t ll_hw_read_rfifo(uint8_t* rxPkt, uint16_t* pktLen, uint32_t* pktFoot0, uint32_t* pktFoot1); +uint8_t ll_hw_read_rfifo_zb(uint8_t* rxPkt, uint16_t* pktLen, uint32_t* pktFoot0, uint32_t* pktFoot1); +uint8_t ll_hw_read_rfifo_pplus(uint8_t* rxPkt, uint16_t* pktLen, uint32_t* pktFoot0, uint32_t* pktFoot1); + +uint8_t ll_hw_write_tfifo(uint8_t* rxPkt, uint16_t pktLen); + +void ll_hw_set_crc_fmt(uint8_t txCrc,uint8_t rxCrc); +void ll_hw_set_pplus_pktfmt(uint8_t plen); + +uint8_t ll_hw_get_snNesn(void); +uint8_t ll_hw_get_txAck(void); +uint8_t ll_hw_get_nAck(void); +uint8_t ll_hw_get_rxPkt_num(void); +uint32_t ll_hw_get_anchor(void); +uint32_t ll_hw_get_irq_status(void); +uint8_t ll_hw_get_fsm_status(void); +uint8_t ll_hw_get_last_ack(void); +uint32_t ll_hw_get_loop_cycle(void); + +uint8_t ll_hw_get_rxPkt_Total_num(void); +uint8_t ll_hw_get_rxPkt_CrcErr_num(void); +uint8_t ll_hw_get_rxPkt_CrcOk_num(void); + +uint8_t ll_hw_get_iq_RawSample(uint16_t* p_iSample, uint16_t* p_qSample); + +uint8_t ll_hw_update_rtlp_mode(uint8_t llMode); +uint8_t ll_hw_update_trlp_mode(uint8_t llMode); +uint8_t ll_hw_update(uint8_t llMode,uint8_t* txAck,uint8_t* rxRec,uint8_t* snNesn); + + +void byte_to_bit(uint8_t byteIn,uint8_t* bitOut); +void bit_to_byte(uint8_t* bitIn,uint8_t* byteOut); +void zigbee_crc16_gen(uint8_t* dataIn,int length,uint8_t* seed,uint8_t* crcCode); + + +// copy from rf.h by Zeng jiaping +void set_tx_rx_mode(uint8_t mode); + +void set_channel(uint32_t channel); + +void set_access_address( uint32_t access); +void set_crc_seed(uint32_t seed); +void set_whiten_seed(uint32_t channel); + +void set_max_length(uint32_t length); + +void calculate_whiten_seed(void); + + +#endif diff --git a/arch/arm/src/phy62xx/ble/controller/ll_sleep.h b/arch/arm/src/phy62xx/ble/controller/ll_sleep.h new file mode 100644 index 00000000000..cd4d72aecad --- /dev/null +++ b/arch/arm/src/phy62xx/ble/controller/ll_sleep.h @@ -0,0 +1,124 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + + +#ifndef LL_SLEEP__H_ +#define LL_SLEEP__H_ + +#include "OSAL_PwrMgr.h" + +#include "ll_def.h" +#include "ll_common.h" + +/******************************************************************************* + MACROS +*/ + +// convert 625us units to 32kHz units without round: the ratio of 32 kHz ticks +// to 625 usec ticks is 32768/1600 = 20.48 or 512/25 +#define LL_SLEEP_625US_TO_32KHZ( us ) ((((uint32) (us)) * 512) / 25) + +// convert 31.25ns units to 32kHz units without round: the ratio of 31.25ns usec +// ticks to 32 kHz ticks is 32M/32768 = 976.5625 or 15625/16, but using 976 is +// close enough given the accuracy +#define LL_SLEEP_31_25NS_TO_32KHZ( ns ) (((uint32) (ns)) / 976) + + +// 32KHz timer: +// crystal: 32768Hz +// RC : 32768Hz Should be same as Xtal +// timer1 - 4 : 4MHz +#define TIMER_TO_32K_CRYSTAL 122 // 122.0703 +#define TIMER_TO_32K_RC 122 // 125 + +#define STD_RC32_8_CYCLE_16MHZ_CYCLE 3906 // standard 16Mhz cycles for 8 RC32KHz tick +#define STD_CRY32_8_CYCLE_16MHZ_CYCLE 3906 // standard 16Mhz cycles for 8 crystal 32KHz tick +#define ERR_THD_RC32_CYCLE 200 // error threshold for N+x rcosc tracking cycle + + +#define CRY32_8_CYCLE_16MHZ_CYCLE_MAX (3906 + 196) // tracking value range std +/- 5% +#define CRY32_8_CYCLE_16MHZ_CYCLE_MIN (3906 - 196) + +#define STD_RC32_16_CYCLE_16MHZ_CYCLE (7812) // standard 16Mhz cycles for 16 RC32KHz tick +#define STD_CRY32_16_CYCLE_16MHZ_CYCLE (7812) // standard 16Mhz cycles for 16 crystal 32KHz tick + + +#define CRY32_16_CYCLE_16MHZ_CYCLE_MAX (7812 + 391) // tracking value range std +/- 5% +#define CRY32_16_CYCLE_16MHZ_CYCLE_MIN (7812 - 391) + +#define SLEEP_MAGIC 0x032141B6 + + +/******************************************************************************* + TYPEDEFS +*/ +typedef enum +{ + MCU_SLEEP_MODE, + SYSTEM_SLEEP_MODE, + SYSTEM_OFF_MODE +} Sleep_Mode; + + + +/******************************************************************************* + Functions +*/ + +// is sleep allow +uint8 isSleepAllow(void); + +void enableSleep(void); + +void disableSleep(void); + +void setSleepMode(Sleep_Mode mode); + +Sleep_Mode getSleepMode(void); + +void enterSleepProcess(uint32 time); + +void wakeupProcess(void); + +void set_sleep_flag(int flag); + +unsigned int get_sleep_flag(void); + +void config_RTC(uint32 time); + +void enter_sleep_off_mode(Sleep_Mode mode); + +#endif // LL_SLEEP__H_ + + + + diff --git a/arch/arm/src/phy62xx/ble/controller/rf_phy_driver.h b/arch/arm/src/phy62xx/ble/controller/rf_phy_driver.h new file mode 100644 index 00000000000..8a3d8717c65 --- /dev/null +++ b/arch/arm/src/phy62xx/ble/controller/rf_phy_driver.h @@ -0,0 +1,527 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/******************************************************************************* + @file rf_phy_driver.h + @brief Contains all functions support for PHYPLUS RF_PHY_DRIVER + @version 1.0 + @date 24. Aug. 2017 + @author Zhongqi Yang + + + +*******************************************************************************/ +#ifndef __RF_PHY_DRIVER_H_ +#define __RF_PHY_DRIVER_H_ + + + + +/******************************************************************************* + INCLUDES +*/ + + +#include "rom_sym_def.h" +#include "clock.h" +#include "ll_hw_drv.h" +#include "jump_function.h" +#include "version.h" + + +typedef enum _RF_PHY_CLK_SEL +{ + RF_PHY_CLK_SEL_16M_XTAL = 0, + RF_PHY_CLK_SEL_32M_DBL_B = 1, + RF_PHY_CLK_SEL_32M_DBL = 2, + RF_PHY_CLK_SEL_32M_DLL = 3 +} rfphy_clk_t; + +typedef enum _RX_ADC_CLK_SEL +{ + RX_ADC_CLK_SEL_16M_XTAL = 0, + RX_ADC_CLK_SEL_32M_DBL_B = 1, + RX_ADC_CLK_SEL_32M_DBL = 2, + RX_ADC_CLK_SEL_32M_DLL = 3 +} rxadc_clk_t; + + + + +/******************************************************************************* + Global Var +*/ +extern volatile uint8_t g_rfPhyTpCal0; //** two point calibraion result0 **// +extern volatile uint8_t g_rfPhyTpCal1; //** two point calibraion result1 **// +extern volatile uint8_t g_rfPhyTpCal0_2Mbps; //** two point calibraion result0 **// +extern volatile uint8_t g_rfPhyTpCal1_2Mbps; //** two point calibraion result1 **// +extern volatile uint8_t g_rfPhyTxPower; //** rf pa output power setting [0x00 0x1f] **// +extern volatile uint8_t g_rfPhyPktFmt; //** rf_phy pkt format config **// +extern volatile uint32 g_rfPhyRxDcIQ; //** rx dc offset cal result **// +extern volatile int8_t g_rfPhyFreqOffSet; + +extern volatile sysclk_t g_system_clk; +extern volatile rfphy_clk_t g_rfPhyClkSel; +extern volatile rxadc_clk_t g_rxAdcClkSel; + +extern volatile uint8_t g_rfPhyDtmCmd[]; +extern volatile uint8_t g_rfPhyDtmEvt[]; +extern volatile uint8_t g_dtmModeType ; +extern volatile uint8_t g_dtmCmd ; +extern volatile uint8_t g_dtmFreq ; +extern volatile uint8_t g_dtmLength ; +extern volatile uint8_t g_dtmExtLen ; +extern volatile uint16_t g_dtmPktIntv ; +extern volatile uint8_t g_dtmPKT ; +extern volatile uint8_t g_dtmCtrl ; +extern volatile uint8_t g_dtmPara ; +extern volatile uint8_t g_dtmEvt ; +extern volatile uint8_t g_dtmStatus ; +extern volatile uint16_t g_dtmPktCount ; +extern volatile uint16_t g_dtmRxCrcNum ; +extern volatile uint16_t g_dtmRxTONum ; +extern volatile uint16_t g_dtmRsp ; +extern volatile uint8_t g_dtmTxPower ;//RF_PHY_TX_POWER_EXTRA_MAX;//according to the rfdrv +extern volatile uint16_t g_dtmFoff ; +extern volatile uint8_t g_dtmRssi ; +extern volatile uint8_t g_dtmCarrSens ; +extern volatile uint8_t g_dtmTpCalEnable ; //default enable tpcal +extern volatile uint32_t g_dtmTick ; +extern volatile uint32_t g_dtmPerAutoIntv ; +extern volatile uint32_t g_dtmAccessCode ; + +extern volatile uint8_t g_rc32kCalRes ; +/******************************************************************************* + MACRO +*/ +#define RF_PHY_EXT_PREAMBLE_US (8) // ext ble preamble length + +#define PHY_REG_RD(x) *(volatile uint32_t *)(x) +#define PHY_REG_WT(x,y) *(volatile uint32_t *)(x) = (y) +#define RF_CHN_TO_FREQ(x) + +#define DCDC_REF_CLK_SETTING(x) subWriteReg(0x4000f014,25,25, (0x01&(x))) +#define DCDC_CONFIG_SETTING(x) subWriteReg(0x4000f014,18,15, (0x0f&(x))) + +/* + crystal 16M matching cap control for ana. + 5'b0 means 5pF,5'b11110 means 17pF.step size is 2.step value is 0.8pF. +*/ +#define XTAL16M_CAP_SETTING(x) subWriteReg(0x4000f0bc, 4, 0, (0x1f&(x))) + +#define XTAL16M_CURRENT_SETTING(x) subWriteReg(0x4000f0bc, 6, 5, (0x03&(x))) +#define DIG_LDO_CURRENT_SETTING(x) subWriteReg(0x4000f014,22,21, (0x03&(x))) + +#define RF_PHY_LO_LDO_SETTING(x) subWriteReg(0x400300cc,11,10, (0x03&(x))) +#define RF_PHY_PA_VTRIM_SETTING(x) subWriteReg(0x400300dc, 9, 7, (0x03&(x))) +#define RF_PHY_LNA_LDO_SETTING(x) subWriteReg(0x400300dc, 6, 5, (0x03&(x))) + + +#define RF_PHY_TPCAL_CALC(tp0,tp1,chn) ((tp0)>(tp1) ?(((tp0<<5)-(tp0-tp1)*(chn)+16)>>5) : tp0 ) +//DTM STATE +#define RF_PHY_DTM_IDL 0 +#define RF_PHY_DTM_CMD 1 +#define RF_PHY_DTM_EVT 2 +#define RF_PHY_DTM_TEST 3 + +#define RF_PHY_DTM_SYNC_WORD 0x71764129 +#define RF_PHY_DTM_PRBS9_SEED 0xffffffff +#define RF_PHY_DTM_CRC_WT 0x00555555 + +//DTM MODE TYPE +#define RF_PHY_DTM_MODE_RESET 0 +#define RF_PHY_DTM_MODE_TX_BURST 2 +#define RF_PHY_DTM_MODE_TX_CTMOD 4 +#define RF_PHY_DTM_MODE_TX_SINGLE 6 +#define RF_PHY_DTM_MODE_RX_PER 8 +#define RF_PHY_DTM_MODE_TEST_END 10 +#define RF_PHY_DTM_MODE_SET_LENGTH_UP2BIT 12 + +#define RF_PHY_DTM_MODE_SET_PHY_1M 16 +#define RF_PHY_DTM_MODE_SET_PHY_2M 18 +#define RF_PHY_DTM_MODE_SET_PHY_500K 20 +#define RF_PHY_DTM_MODE_SET_PHY_125K 22 +#define RF_PHY_DTM_MODE_SET_PHY_ZB 24 + +#define RF_PHY_DTM_MODE_ASSUME_TX_MOD_INDX_STANDARD 32 +#define RF_PHY_DTM_MODE_ASSUME_TX_MOD_INDX_STABLE 34 +#define RF_PHY_DTM_MODE_READ_SUPPORTED_TEST_CASE 36 +#define RF_PHY_DTM_MODE_READ_MAX_TX_OCTETS 38 +#define RF_PHY_DTM_MODE_READ_MAX_TX_TIME 40 +#define RF_PHY_DTM_MODE_READ_MAX_RX_OCTETS 42 +#define RF_PHY_DTM_MODE_READ_MAX_RX_TIME 44 + +#define RF_PHY_DTM_MODE_SET_ACCCODE_0 114 +#define RF_PHY_DTM_MODE_SET_ACCCODE_1 116 +#define RF_PHY_DTM_MODE_SET_ACCCODE_2 118 +#define RF_PHY_DTM_MODE_SET_ACCCODE_3 120 + +#define RF_PHY_DTM_MODE_SET_FREQ_FOFF 122 +#define RF_PHY_DTM_MODE_SET_TPCAL_MANUAL 124 +#define RF_PHY_DTM_MODE_SET_XTAL_CAP 126 +#define RF_PHY_DTM_MODE_SET_TX_POWER 128 +#define RF_PHY_DTM_MODE_GET_FOFF 130 +#define RF_PHY_DTM_MODE_GET_TPCAL 132 +#define RF_PHY_DTM_MODE_GET_RSSI 134 +#define RF_PHY_DTM_MODE_GET_CARR_SENS 136 +#define RF_PHY_DTM_MODE_GET_PER_AUTO 138 + +#define RF_PHY_DTM_MODE_ATE_SET_PKTFMT 0xd0 //208 +#define RF_PHY_DTM_MODE_ATE_SET_TXPOWER 0xd1 + +#define RF_PHY_DTM_MODE_ATE_TX_BURST 0xe0 //224 +#define RF_PHY_DTM_MODE_ATE_TX_MOD 0xe1 +#define RF_PHY_DTM_MODE_ATE_TX_CARR 0xe2 +#define RF_PHY_DTM_MODE_ATE_RX_AUTOGAIN 0xe3 +#define RF_PHY_DTM_MODE_ATE_RX_FIXGAIN 0xe4 +#define RF_PHY_DTM_MODE_ATE_RX_DEMOD 0xe5 +#define RF_PHY_DTM_MODE_ATE_RX2TX 0xe6 +#define RF_PHY_DTM_MODE_ATE_TX2RX 0xe7 + +#define RF_PHY_DTM_MODE_ATE_RESET 0xef + +#define RF_PHY_DTM_MODE_ERROR 254 + + +/******************************************************************************* + CONSTANTS +*/ +#define PKT_FMT_ZIGBEE 0 +#define PKT_FMT_BLE1M 1 +#define PKT_FMT_BLE2M 2 +#define PKT_FMT_BLR500K 3 +#define PKT_FMT_BLR125K 4 + + +#if (SDK_VER_CHIP==__DEF_CHIP_QFN32__) + #define RF_PHY_TX_POWER_EXTRA_MAX 0x3f + #define RF_PHY_TX_POWER_MAX 0x1f + #define RF_PHY_TX_POWER_MIN 0x00 + + #define RF_PHY_TX_POWER_5DBM 0x3f + #define RF_PHY_TX_POWER_0DBM 0x1f + #define RF_PHY_TX_POWER_N2DBM 0x0f + #define RF_PHY_TX_POWER_N5DBM 0x0a + #define RF_PHY_TX_POWER_N20DBM 0x01 + + #elif(SDK_VER_CHIP==__DEF_CHIP_TSOP16__) + #define RF_PHY_TX_POWER_EXTRA_MAX 0x3f + #define RF_PHY_TX_POWER_MAX 0x1f + #define RF_PHY_TX_POWER_MIN 0x00 + + #define RF_PHY_TX_POWER_5DBM 0x1d + #define RF_PHY_TX_POWER_4DBM 0x17 + #define RF_PHY_TX_POWER_3DBM 0x15 + #define RF_PHY_TX_POWER_0DBM 0x0d + + #define RF_PHY_TX_POWER_N2DBM 0x0a + #define RF_PHY_TX_POWER_N5DBM 0x06 + #define RF_PHY_TX_POWER_N6DBM 0x05 + #define RF_PHY_TX_POWER_N10DBM 0x03 + #define RF_PHY_TX_POWER_N15DBM 0x02 + #define RF_PHY_TX_POWER_N20DBM 0x01 +#else + #warning" CHECK Chip Version " +#endif + +#define RF_PHY_FREQ_FOFF_00KHZ 0 +#define RF_PHY_FREQ_FOFF_20KHZ 5 +#define RF_PHY_FREQ_FOFF_40KHZ 10 +#define RF_PHY_FREQ_FOFF_60KHZ 15 +#define RF_PHY_FREQ_FOFF_80KHZ 20 +#define RF_PHY_FREQ_FOFF_100KHZ 25 +#define RF_PHY_FREQ_FOFF_120KHZ 30 +#define RF_PHY_FREQ_FOFF_140KHZ 35 +#define RF_PHY_FREQ_FOFF_160KHZ 40 +#define RF_PHY_FREQ_FOFF_180KHZ 45 +#define RF_PHY_FREQ_FOFF_200KHZ 50 +#define RF_PHY_FREQ_FOFF_N20KHZ -5 +#define RF_PHY_FREQ_FOFF_N40KHZ -10 +#define RF_PHY_FREQ_FOFF_N60KHZ -15 +#define RF_PHY_FREQ_FOFF_N80KHZ -20 +#define RF_PHY_FREQ_FOFF_N100KHZ -25 +#define RF_PHY_FREQ_FOFF_N120KHZ -30 +#define RF_PHY_FREQ_FOFF_N140KHZ -35 +#define RF_PHY_FREQ_FOFF_N160KHZ -40 +#define RF_PHY_FREQ_FOFF_N180KHZ -45 +#define RF_PHY_FREQ_FOFF_N200KHZ -50 + + +#define RF_PHY_DTM_MANUL_NULL 0x00 +#define RF_PHY_DTM_MANUL_FOFF 0x01 +#define RF_PHY_DTM_MANUL_TXPOWER 0x02 +#define RF_PHY_DTM_MANUL_XTAL_CAP 0x04 +#define RF_PHY_DTM_MANUL_MAX_GAIN 0x08 + +#define RF_PHY_DTM_MANUL_ALL 0xFF +/******************************************************************************* + FUNCION DEFINE +*/ +/************************************************************************************** + @fn rf_phy_ini + + @brief This function process for rf phy ini call api + + input parameters + + @param None. + + output parameters + + @param None. + + @return None. +*/ +void rf_phy_ini (void); + +/************************************************************************************** + @fn rf_phy_ana_cfg + + @brief This function process for rf phy analog block config, + include PLL, RX_FRONT_END,PA Power. + + input parameters + + @param None. + + output parameters + + @param None. + + @return None. +*/ +void rf_phy_ana_cfg (void); + +/************************************************************************************** + @fn rf_phy_bb_cfg + + @brief This function process for rf phy baseband tx and rx config. + + input parameters + + @param pktMod:0 for Zigbee, 1 for BLE1M, 2 for BLE2M, 3or4 for BLELR. + + output parameters + + @param None. + + @return None. +*/ +void rf_phy_bb_cfg (uint8_t pktFmt); + + +void rf_phy_change_cfg0(uint8_t pktFmt); +/************************************************************************************** + @fn rf_tpCal_cfg + + @brief This function process for rf tpCal config + + input parameters + + @param rfChn: two point calibration rf channel setting(0-80)->2400-2480MHz. + + output parameters + + @param None. + + @return None. +*/ +void rf_tpCal_cfg (uint8_t rfChn); + +/************************************************************************************** + @fn rf_tp_cal + + @brief This function process for tx tp calibration. + + input parameters + + @param rfChn : rfFreq=2400+rfChn + fDev : used to config the tpCal fDelt, 0 for 0.5M, 1 for 1M + + + output parameters + + @param none + + @return kCal : cal result for rfChn. +*/ +uint8_t rf_tp_cal (uint8_t rfChn,uint8_t fDev); + +/************************************************************************************** + @fn rf_rxDcoc_cfg + + @brief This function process for rx dc offset calibration and canncellation config. + + input parameters + + @param rfChn : rfFreq=2400+rfChn + bwSet : used to config rx complex filter bandwitdh. 1 for 1MHz, other for 2MHz + + + output parameters + + @param dcCal : cal result for rxdc, dcQ[13:8],dcI[5:0] + + @return none +*/ +void rf_rxDcoc_cfg (uint8_t rfChn,uint8_t bwSet,volatile uint32* dcCal); + +/************************************************************************************** + @fn rf_tpCal_gen_cap_arrary + + @brief This function process for tx tp calibration,genearte the tpCal cap arrary. + + input parameters + + @param + + output parameters + + @param none + + @return kCal : cal result for rfChn. +*/ +void rf_tpCal_gen_cap_arrary(void); + +/************************************************************************************** + @fn rf_phy_direct_test + + @brief This function process for rf phy direct test. + + input parameters + + @param none + + output parameters + + @param none + + @return none +*/ +void rf_phy_direct_test (void); + +/************************************************************************************** + @fn rf_phy_dtm_cmd_parse + + @brief This function process for rf phy direct test,cmd parse + + input parameters + + @param none + + output parameters + + @param none + + @return none +*/ +void rf_phy_dtm_cmd_parse(void); + +/************************************************************************************** + @fn rf_phy_dtm_evt_send + + @brief This function process for rf phy direct test, test mode trigged + + input parameters + + @param none + + output parameters + + @param none + + @return none +*/ +void rf_phy_dtm_evt_send (uint8_t dtmType); + +/************************************************************************************** + @fn rf_phy_dtm_trigged + + @brief This function process for rf phy direct test, test mode trigged + + input parameters + + @param none + + output parameters + + @param none + + @return none +*/ +void rf_phy_dtm_trigged (void); + +/************************************************************************************** + @fn rf_phy_get_pktFoot + + @brief This function process to get pkt foot + + input parameters + + @param none + + output parameters + + @param rssi : recv signal strength indicator(-dBm) + foff : estimated freq offset by rx BB ,foff-512-->[-512 511]KHz + carrSens: sync qualitiy indicator, estimated by rx BB. + + @return none +*/ +void rf_phy_get_pktFoot (uint8* rssi, uint16* foff,uint8* carrSens); +void rf_phy_get_pktFoot_fromPkt(uint32 pktFoot0, uint32 pktFoot1,uint8* rssi, uint16* foff,uint8* carrSens); + +/************************************************************************************** + @fn rf_phy_set_txPower + + @brief This function process for rf phy tx power config + + input parameters + + @param txPower : tx pa power setting (0~0x1f) + + output parameters + + @param none + + @return none +*/ +void rf_phy_set_txPower (uint8 txPower); + +uint8_t rf_phy_direct_test_ate(uint32_t cmdWord,uint8_t regPatchNum,uint32_t* regPatchAddr,uint32_t* regPatchVal,uint8_t* dOut); + +void rf_phy_dtm_zigbee_pkt_gen(void); + +void TRNG_INIT(void); + +uint8_t TRNG_Rand(uint8_t* buf,uint8_t len); +#endif diff --git a/arch/arm/src/phy62xx/ble/hci/hci_data.h b/arch/arm/src/phy62xx/ble/hci/hci_data.h new file mode 100644 index 00000000000..a1316765c0d --- /dev/null +++ b/arch/arm/src/phy62xx/ble/hci/hci_data.h @@ -0,0 +1,109 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/******************************************************************************* + Filename: hci_c_data.h + Revised: $Date: 2011-08-22 08:41:40 -0700 (Mon, 22 Aug 2011) $ + Revision: $Revision: 27235 $ + + Description: This file handles HCI data for the BLE Controller. + + +*******************************************************************************/ + +#ifndef HCI_C_DATA_H +#define HCI_C_DATA_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + INCLUDES +*/ + +/******************************************************************************* + MACROS +*/ + +/******************************************************************************* + CONSTANTS +*/ + +/******************************************************************************* + TYPEDEFS +*/ + +/******************************************************************************* + LOCAL VARIABLES +*/ + +/******************************************************************************* + GLOBAL VARIABLES +*/ + +/* +** HCI Data API +*/ + + +/******************************************************************************* + @fn HCI_ReverseBytes + + @brief This function is used to reverse the order of the bytes in + an array in place. + + input parameters + + @param *buf - Pointer to buffer containing bytes to be reversed. + @param len - Number of bytes in buffer. + + Note: The length must be even. + + Note: The maximum length is 128 bytes. + + output parameters + + @param None. + + @return None. +*/ +extern void HCI_ReverseBytes( uint8* buf, + uint8 len ); + + +#ifdef __cplusplus +} +#endif + +#endif /* HCI_C_DATA_H */ diff --git a/arch/arm/src/phy62xx/ble/hci/hci_event.h b/arch/arm/src/phy62xx/ble/hci/hci_event.h new file mode 100644 index 00000000000..69c78d56cc7 --- /dev/null +++ b/arch/arm/src/phy62xx/ble/hci/hci_event.h @@ -0,0 +1,303 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/******************************************************************************* + Filename: hci_c_event.h + Revised: $Date: 2012-05-01 12:13:50 -0700 (Tue, 01 May 2012) $ + Revision: $Revision: 30418 $ + + Description: This file contains the HCI Event types, contants, + external functions etc. for the BLE Controller. + + +*******************************************************************************/ + +#ifndef HCI_C_EVENT_H +#define HCI_C_EVENT_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + INCLUDES +*/ +#include "hci_tl.h" + +extern uint32 bleEvtMask; +extern uint8 pHciEvtMask[]; + +/******************************************************************************* + MACROS +*/ + +/******************************************************************************* + CONSTANTS +*/ + +// Event Mask Default Values +#define BT_EVT_MASK_BYTE0 0xFF +#define BT_EVT_MASK_BYTE1 0xFF +#define BT_EVT_MASK_BYTE2 0xFF +#define BT_EVT_MASK_BYTE3 0xFF +#define BT_EVT_MASK_BYTE4 0xFF +#define BT_EVT_MASK_BYTE5 0x9F +#define BT_EVT_MASK_BYTE6 0x00 +#define BT_EVT_MASK_BYTE7 0x20 +// +#define LE_EVT_MASK_DEFAULT 0x00005F + +/******************************************************************************* + TYPEDEFS +*/ + +/******************************************************************************* + LOCAL VARIABLES +*/ + +/******************************************************************************* + GLOBAL VARIABLES +*/ + +/* +** Internal Functions +*/ + +extern void hciInitEventMasks( void ); + +/* +** HCI Controller Events +*/ + +/******************************************************************************* + @fn HCI_DataBufferOverflowEvent + + @brief This function sends the Data Buffer Overflow Event to the Host. + + input parameters + + @param linkType - HCI_LINK_TYPE_SCO_BUFFER_OVERFLOW, + HCI_LINK_TYPE_ACL_BUFFER_OVERFLOW + + output parameters + + @param None. + + @return None. +*/ +extern void HCI_DataBufferOverflowEvent( uint8 linkType ); + + +/******************************************************************************* + @fn HCI_NumOfCompletedPacketsEvent + + @brief This function sends the Number of Completed Packets Event to + the Host. + + Note: Currently, the number of handles is always one. + + input parameters + + @param numHandles - Number of handles. + @param handlers - Array of connection handles. + @param numCompletedPkts - Array of number of completed packets for + each handle. + + output parameters + + @param None. + + @return None. +*/ +extern void HCI_NumOfCompletedPacketsEvent( uint8 numHandles, + uint16* handlers, + uint16* numCompletedPackets ); + + +/******************************************************************************* + @fn HCI_CommandCompleteEvent + + @brief This function sends a Command Complete Event to the Host. + + input parameters + + @param opcode - The opcode of the command that generated this event. + @param numParam - The number of parameters in the event. + @param param - The event parameters associated with the command. + + output parameters + + @param None. + + @return None. +*/ +extern void HCI_CommandCompleteEvent( uint16 opcode, + uint8 numParam, + uint8* param ); + + +/******************************************************************************* + @fn HCI_VendorSpecifcCommandCompleteEvent + + @brief This function sends a Vendor Specific Command Complete Event to + the Host. + + input parameters + + @param opcode - The opcode of the command that generated this event. + @param numParam - The number of parameters in the event. + @param param - The event parameters associated with the command. + + output parameters + + @param None. + + @return None. +*/ +extern void HCI_VendorSpecifcCommandCompleteEvent( uint16 opcode, + uint8 len, + uint8* param ); + + +/******************************************************************************* + @fn HCI_CommandStatusEvent + + @brief This function sends a Command Status Event to the Host. + + input parameters + + @param status - The resulting status of the comamnd. + @param opcode - The opcode of the command that generated this event. + + output parameters + + @param None. + + @return None. +*/ +extern void HCI_CommandStatusEvent( uint8 status, + uint16 opcode ); + + +/******************************************************************************* + @fn HCI_HardwareErrorEvent + + @brief This function sends a Hardware Error Event to the Host. + + input parameters + + @param hwErrorCode - The hardware error code. + + output parameters + + @param None. + + @return None. +*/ +extern void HCI_HardwareErrorEvent( uint8 hwErrorCode ); + + +/******************************************************************************* + @fn HCI_SendCommandStatusEvent + + @brief This generic function sends a Command Status event to the Host. + It is provided as a direct call so the Host can use it directly. + + input parameters + + @param eventCode - The event code. + @param status - The resulting status of the comamnd. + @param opcode - The opcode of the command that generated this event. + + output parameters + + @param None. + + @return None. +*/ +extern void HCI_SendCommandStatusEvent ( uint8 eventCode, + uint16 status, + uint16 opcode ); + + +/******************************************************************************* + @fn HCI_SendCommandCompleteEvent + + @brief This generic function sends a Command Complete or a Vendor + Specific Command Complete Event to the Host. + + input parameters + + @param eventCode - The event code. + @param opcode - The opcode of the command that generated this event. + @param numParam - The number of parameters in the event. + @param param - The event parameters associated with the command. + + output parameters + + @param None. + + @return None. +*/ +extern void HCI_SendCommandCompleteEvent ( uint8 eventCode, + uint16 opcode, + uint8 numParam, + uint8* param ); + + +/******************************************************************************* + @fn HCI_SendControllerToHostEvent + + @brief This generic function sends a Controller to Host Event. + + input parameters + + @param eventCode - Bluetooth event code. + @param dataLen - Length of dataField. + @param pData - Pointer to data. + + output parameters + + @param None. + + @return None. +*/ +extern void HCI_SendControllerToHostEvent( uint8 eventCode, + uint8 dataLen, + uint8* pData ); + +#ifdef __cplusplus +} +#endif + +#endif /* HCI_C_EVENT_H */ diff --git a/arch/arm/src/phy62xx/ble/hci/hci_host.h b/arch/arm/src/phy62xx/ble/hci/hci_host.h new file mode 100644 index 00000000000..ceac0514e41 --- /dev/null +++ b/arch/arm/src/phy62xx/ble/hci/hci_host.h @@ -0,0 +1,91 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + + +/************************************************************************************************* +**************************************************************************************************/ +#ifndef HCI_HOST_H +#define HCI_HOST_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ +#include "OSAL.h" +#include "osal_bufmgr.h" +#include "hci.h" +#include "hci_task.h" + + +/********************************************************************* + MACROS +*/ + +/********************************************************************* + CONSTANTS +*/ + +/* HCI packet header length */ +#define HCI_EVT_HEADER_LEN 3 /* packet type + evt code(1) + len(1) */ +#define HCI_DATA_HEADER_LEN 5 /* packet type + connection handle(2) + len(2) */ + +/* First 12 bits of the HCI data packet is connection handle */ +#define HCI_CONNECTION_HANDLE_MASK 0x0FFF +#define HCI_PB_MASK 0x03 +/********************************************************************* + TYPEDEFS +*/ + +/********************************************************************* + GLOBAL VARIABLES +*/ + + +/********************************************************************* + FUNCTIONS - API +*/ + + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* HCI_HOST_H */ + + diff --git a/arch/arm/src/phy62xx/ble/hci/hci_task.h b/arch/arm/src/phy62xx/ble/hci/hci_task.h new file mode 100644 index 00000000000..9917ba289a4 --- /dev/null +++ b/arch/arm/src/phy62xx/ble/hci/hci_task.h @@ -0,0 +1,116 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/************************************************************************************************* +**************************************************************************************************/ +#ifndef HCI_TASK_H +#define HCI_TASK_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ +#include "OSAL.h" +#include "hci.h" +#include "uart.h" +#include "hci_host.h" + +#include "hal.h" // added by ZJP + + +/********************************************************************* + MACROS +*/ + +/********************************************************************* + CONSTANTS +*/ + + +/* UART port */ +#define HCI_UART_PORT HAL_UART_PORT_0 +#define HCI_UART_BR HAL_UART_BR_38400 +#define HCI_UART_FC TRUE +#define HCI_UART_FC_THRESHOLD 48 +#define HCI_UART_RX_BUF_SIZE 128 +#define HCI_UART_TX_BUF_SIZE 128 +#define HCI_UART_IDLE_TIMEOUT 6 +#define HCI_UART_INT_ENABLE TRUE + +/* HCI Event List */ +#define HCI_EVENT_SEND_DATA 0x01 +#define HCI_EVENT_SEND_CMD 0x02 +#define HCI_HOST_PARSE_EVT 0x04 +#define HCI_HOST_INCOMING_EVT 0x08 +#define HCI_HOST_INCOMING_DATA 0x10 + + +/* Define the osal queue size for data and cmd */ +#define HCI_HOST_MAX_DATAQUEUE_SIZE 20 +#define HCI_HOST_MAX_CMDQUEUE_SIZE 20 + +/********************************************************************* + TYPEDEFS +*/ + +/********************************************************************* + GLOBAL VARIABLES +*/ +osal_msg_q_t HCI_HostDataQueue; + +uint8 hciHostNumQueuedData; /* Number of data packets queued */ +const uint8 hciHostMaxNumDataQueue; /* Max number of data packets queued */ + +/********************************************************************* + FUNCTIONS - API +*/ +extern Status_t HCI_AddDataQueue( void* buf ); +extern Status_t HCI_AddCmdQueue( void* buf ); + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* HCI_TASK_H */ + + + + + + diff --git a/arch/arm/src/phy62xx/ble/hci/hci_tl.h b/arch/arm/src/phy62xx/ble/hci/hci_tl.h new file mode 100644 index 00000000000..8feda0a2fe1 --- /dev/null +++ b/arch/arm/src/phy62xx/ble/hci/hci_tl.h @@ -0,0 +1,430 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/******************************************************************************* + Filename: hci_tl.h + Revised: $Date: 2012-04-20 15:24:45 -0700 (Fri, 20 Apr 2012) $ + Revision: $Revision: 30292 $ + + Description: This file contains the types, contants, external functions + etc. for the BLE HCI Transport Layer. + +*******************************************************************************/ + +#ifndef HCI_TL_H +#define HCI_TL_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + INCLUDES +*/ + +#include "hci.h" +#include "OSAL.h" +#include "uart.h" +#include "hci_data.h" +#include "hci_event.h" + +extern uint8 hciTaskID; +// +extern uint8 hciTestTaskID; +extern uint8 hciGapTaskID; +extern uint8 hciL2capTaskID; +extern uint8 hciSmpTaskID; + +/******************************************************************************* + MACROS +*/ + +#define HCI_ASSERT(condition) HAL_ASSERT(condition) + +/******************************************************************************* + CONSTANTS +*/ + +// OSAL Task Events +#define HCI_TX_PROCESS_EVENT 0x0001 +#define HCI_TEST_UART_SEND_EVENT 0x0002 +#define HCI_BDADDR_UPDATED_EVENT 0x4000 +#define HCI_OSAL_MSG_EVENT SYS_EVENT_MSG + +// OSAL Message Header Events +#define HCI_CTRL_TO_HOST_EVENT 0x01 +#define HCI_HOST_TO_CTRL_CMD_EVENT 0x02 +#define HCI_HOST_TO_CTRL_DATA_EVENT 0x03 + +#define HCI_BDADDR_LEN 6 + +// Max Allowed HCI Packet +#define HCI_MAX_CMD_PKT_SIZE 0xFF +#define HCI_MAX_DATA_PKT_SIZE 0xFFFF + +// Max Data Length in Packet +#define HCI_DATA_MAX_DATA_LENGTH 27 + +// +// Minimum length for CMD packet is 1+2+1 +// | Packet Type (1) | OPCode(2) | Length(1) | +// +#define HCI_CMD_MIN_LENGTH 4 + +// +// Minimum length for EVENT packet is 1+1+1 +// | Packet Type (1) | Event Code(1) | Length(1) | +// +#define HCI_EVENT_MIN_LENGTH 3 + +// +// Minimum length for DATA packet is 1+2+2 +// | Packet Type (1) | Handler(2) | Length(2) | +// +#define HCI_DATA_MIN_LENGTH 5 + +// Max Number of Connections +#define HCI_MAX_NUM_CONNECTIONS 0x03 +// +#define HCI_TX_DATA_ANY_CONNECTION 0xFF + +// HCI Packet Types +#define HCI_CMD_PACKET 0x01 +#define HCI_ACL_DATA_PACKET 0x02 +#define HCI_SCO_DATA_PACKET 0x03 +#define HCI_EVENT_PACKET 0x04 + +/* +** HCI Command Opcodes +*/ + +// Link Control Commands +#define HCI_DISCONNECT 0x0406 +#define HCI_READ_REMOTE_VERSION_INFO 0x041D + +// Controller and Baseband Commands +#define HCI_SET_EVENT_MASK 0x0C01 +#define HCI_RESET 0x0C03 +#define HCI_READ_TRANSMIT_POWER 0x0C2D +#define HCI_SET_CONTROLLER_TO_HOST_FLOW_CONTROL 0x0C31 +#define HCI_HOST_BUFFER_SIZE 0x0C33 +#define HCI_HOST_NUM_COMPLETED_PACKETS 0x0C35 + +// Information Parameters +#define HCI_READ_LOCAL_VERSION_INFO 0x1001 +#define HCI_READ_LOCAL_SUPPORTED_COMMANDS 0x1002 +#define HCI_READ_LOCAL_SUPPORTED_FEATURES 0x1003 +#define HCI_READ_BDADDR 0x1009 + +// Status Parameters +#define HCI_READ_RSSI 0x1405 + +// LE Commands +#define HCI_LE_SET_EVENT_MASK 0x2001 +#define HCI_LE_READ_BUFFER_SIZE 0x2002 +#define HCI_LE_READ_LOCAL_SUPPORTED_FEATURES 0x2003 +#define HCI_LE_SET_RANDOM_ADDR 0x2005 +#define HCI_LE_SET_ADV_PARAM 0x2006 +#define HCI_LE_READ_ADV_CHANNEL_TX_POWER 0x2007 +#define HCI_LE_SET_ADV_DATA 0x2008 +#define HCI_LE_SET_SCAN_RSP_DATA 0x2009 +#define HCI_LE_SET_ADV_ENABLE 0x200A +#define HCI_LE_SET_SCAN_PARAM 0x200B +#define HCI_LE_SET_SCAN_ENABLE 0x200C +#define HCI_LE_CREATE_CONNECTION 0x200D +#define HCI_LE_CREATE_CONNECTION_CANCEL 0x200E +#define HCI_LE_READ_WHITE_LIST_SIZE 0x200F +#define HCI_LE_CLEAR_WHITE_LIST 0x2010 +#define HCI_LE_ADD_WHITE_LIST 0x2011 +#define HCI_LE_REMOVE_WHITE_LIST 0x2012 +#define HCI_LE_CONNECTION_UPDATE 0x2013 +#define HCI_LE_SET_HOST_CHANNEL_CLASSIFICATION 0x2014 +#define HCI_LE_READ_CHANNEL_MAP 0x2015 +#define HCI_LE_READ_REMOTE_USED_FEATURES 0x2016 +#define HCI_LE_ENCRYPT 0x2017 +#define HCI_LE_RAND 0x2018 +#define HCI_LE_START_ENCRYPTION 0x2019 +#define HCI_LE_LTK_REQ_REPLY 0x201A +#define HCI_LE_LTK_REQ_NEG_REPLY 0x201B +#define HCI_LE_READ_SUPPORTED_STATES 0x201C +#define HCI_LE_RECEIVER_TEST 0x201D +#define HCI_LE_TRANSMITTER_TEST 0x201E +#define HCI_LE_TEST_END 0x201F + +#define HCI_LE_SET_DATA_LENGTH 0x2022 +#define HCI_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH 0x2023 +#define HCI_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH 0x2024 + +// 0x2025, 0x2026 for P256 & DHkey + +#define HCI_LE_ADD_DEVICE_TO_RESOLVING_LIST 0x2027 +#define HCI_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST 0x2028 +#define HCI_LE_CLEAR_RESOLVING_LIST 0x2029 +#define HCI_LE_READ_RESOLVING_LIST_SIZE 0x202A +#define HCI_LE_READ_PEER_RESOLVABLE_ADDRESS 0x202B // optional +#define HCI_LE_READ_LOCAL_RESOLVABLE_ADDRESS 0x202C // optional +#define HCI_LE_SET_ADDRESS_RESOLUTION_ENABLE 0x202D +#define HCI_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TO 0x202E + +#define HCI_LE_READ_MAXIMUM_DATA_LENGTH 0x202F +#define HCI_LE_READ_PHY 0x2030 +#define HCI_LE_SET_DEFAULT_PHY 0x2031 +#define HCI_LE_SET_PHY 0x2032 + + +#define HCI_LE_SET_ADVERTISING_SET_RANDOM_ADDRESS 0x2035 +#define HCI_LE_SET_EXTENDER_ADVERTISING_PARAMETERS 0x2036 +#define HCI_LE_SET_EXTENDED_ADVERTISING_DATA 0x2037 +#define HCI_LE_Set_EXTENDED_SCAN_RESPONSE_DATA 0x2038 +#define HCI_LE_Set_EXTENDED_ADVERTISING_ENABLE 0x2039 +#define HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH 0x203A +#define HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS 0x203B +#define HCI_LE_REMOVE_ADVERTISING_SET 0x203C +#define HCI_LE_CLEAR_ADVERTISING_SETS 0x203D + +#define HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS 0x203E +#define HCI_LE_SET_PERIODIC_ADVERTISING_DATA 0x203F +#define HCI_LE_Set_PERIODIC_ADVERTISING_ENABLE 0x2040 + +#define HCI_LE_SET_EXTENDED_SCAN_PARAMETERS 0x2041 +#define HCI_LE_SET_EXTENDED_SCAN_ENABLE 0x2042 +#define HCI_LE_EXTENDED_CREATE_CONNECTION 0x2043 + +#define HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC 0x2044 +#define HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL 0x2045 +#define HCI_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC 0x2046 + +#define HCI_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST 0x2047 +#define HCI_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST 0x2048 +#define HCI_LE_CLEAR_PERIODIC_ADVERTISER_LIST 0x2049 +#define HCI_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE 0x204A + + +/* Power config */ +#define HCI_LE_READ_TRANSMIT_POWER 0x204B +#define HCI_LE_READ_RF_PATH_COMPENSATION 0x204C +#define HCI_LE_WRITE_RF_PATH_COMPENSATION 0x204D + +/* privacy mode */ +#define HCI_LE_SET_PRIVACY_MODE 0x204E + + +/* CTE */ +#define HCI_LE_SET_CONNLESS_CTE_TRANS_PARAMETER 0x2051 +#define HCI_LE_SET_CONNLESS_CTE_TRANS_ENABLE 0x2052 +#define HCI_LE_SET_CONNLESS_IQ_SAMPLE_ENABLE 0x2053 +#define HCI_LE_SET_CONNCTE_RECV_PARAMETER 0x2054 +#define HCI_LE_SET_CONN_CTE_TRANSMIT_PARAMETER 0x2055 +#define HCI_LE_CONN_CTE_REQUEST_ENABLE 0x2056 +#define HCI_LE_CONN_CTE_RESPONSE_ENABLE 0x2057 +#define HCI_LE_READ_ANTENNA_INFO 0x2058 + +// LE Vendor Specific LL Extension Commands +#define HCI_EXT_SET_RX_GAIN 0xFC00 +#define HCI_EXT_SET_TX_POWER 0xFC01 +#define HCI_EXT_ONE_PKT_PER_EVT 0xFC02 +#define HCI_EXT_CLK_DIVIDE_ON_HALT 0xFC03 +#define HCI_EXT_DECLARE_NV_USAGE 0xFC04 +#define HCI_EXT_DECRYPT 0xFC05 +#define HCI_EXT_SET_LOCAL_SUPPORTED_FEATURES 0xFC06 +#define HCI_EXT_SET_FAST_TX_RESP_TIME 0xFC07 +#define HCI_EXT_MODEM_TEST_TX 0xFC08 +#define HCI_EXT_MODEM_HOP_TEST_TX 0xFC09 +#define HCI_EXT_MODEM_TEST_RX 0xFC0A +#define HCI_EXT_END_MODEM_TEST 0xFC0B +#define HCI_EXT_SET_BDADDR 0xFC0C +#define HCI_EXT_SET_SCA 0xFC0D +#define HCI_EXT_ENABLE_PTM 0xFC0E // Not a supported HCI command! Application only. +#define HCI_EXT_SET_FREQ_TUNE 0xFC0F +#define HCI_EXT_SAVE_FREQ_TUNE 0xFC10 +#define HCI_EXT_SET_MAX_DTM_TX_POWER 0xFC11 +#define HCI_EXT_MAP_PM_IO_PORT 0xFC12 +#define HCI_EXT_DISCONNECT_IMMED 0xFC13 +#define HCI_EXT_PER 0xFC14 +#define HCI_EXT_PER_BY_CHAN 0xFC15 // Not a supported HCI command! Application only. +#define HCI_EXT_EXTEND_RF_RANGE 0xFC16 +#define HCI_EXT_ADV_EVENT_NOTICE 0xFC17 // Not a supported HCI command! Application only. +#define HCI_EXT_CONN_EVENT_NOTICE 0xFC18 // Not a supported HCI command! Application only. +#define HCI_EXT_HALT_DURING_RF 0xFC19 +#define HCI_EXT_OVERRIDE_SL 0xFC1A +#define HCI_EXT_BUILD_REVISION 0xFC1B +#define HCI_EXT_DELAY_SLEEP 0xFC1C +#define HCI_EXT_RESET_SYSTEM 0xFC1D +#define HCI_EXT_OVERLAPPED_PROCESSING 0xFC1E +#define HCI_EXT_NUM_COMPLETED_PKTS_LIMIT 0xFC1F + +/* +** HCI Event Codes +*/ + +// BT Events +#define HCI_DISCONNECTION_COMPLETE_EVENT_CODE 0x05 +#define HCI_ENCRYPTION_CHANGE_EVENT_CODE 0x08 +#define HCI_READ_REMOTE_INFO_COMPLETE_EVENT_CODE 0x0C +#define HCI_COMMAND_COMPLETE_EVENT_CODE 0x0E +#define HCI_COMMAND_STATUS_EVENT_CODE 0x0F +#define HCI_BLE_HARDWARE_ERROR_EVENT_CODE 0x10 +#define HCI_NUM_OF_COMPLETED_PACKETS_EVENT_CODE 0x13 +#define HCI_DATA_BUFFER_OVERFLOW_EVENT 0x1A +#define HCI_KEY_REFRESH_COMPLETE_EVENT_CODE 0x30 + +// LE Event Code (for LE Meta Events) +#define HCI_LE_EVENT_CODE 0x3E + +// LE Meta Event Codes +#define HCI_BLE_CONNECTION_COMPLETE_EVENT 0x01 +#define HCI_BLE_ADV_REPORT_EVENT 0x02 +#define HCI_BLE_CONN_UPDATE_COMPLETE_EVENT 0x03 +#define HCI_BLE_READ_REMOTE_FEATURE_COMPLETE_EVENT 0x04 +#define HCI_BLE_LTK_REQUESTED_EVENT 0x05 +#define HCI_BLE_REMOTE_CONN_PARAMETER_REQUEST_EVENT 0X06 +#define HCI_BLE_DATA_LENGTH_CHANGE_EVENT 0x07 +#define HCI_BLE_READ_LOCAL_P256_PUB_KEY_COMPLETE_EVENT 0x08 +#define HCI_BLE_GENERATE_DHKEY_COMPLETE_EVENT 0x09 + +#define HCI_BLE_ENHANCED_CONNECTION_COMPLETE_EVENT 0x0A +#define HCI_BLE_DIRECTED_ADVERTISING_REPORT_EVENT 0x0B + +#define HCI_BLE_PHY_UPDATE_COMPLETE_EVENT 0x0C + +#define HCI_BLE_EXT_ADV_REPORT_EVENT 0x0D +#define HCI_BLE_PERIODIC_ADV_SYNC_ESTABLISHED_EVENT 0x0E +#define HCI_BLE_PERIODIC_ADV_REPORT_EVENT 0x0F +#define HCI_BLE_PERIODIC_ADV_SYNC_LOST_EVENT 0x10 + +#define HCI_LE_ADVERTISING_SET_TERMINATED 0x12 +#define HCI_LE_SCAN_REQUEST_RECEIVED 0x13 +#define HCI_LE_CHANNEL_SELECTION_ALGORITHM_EVENT 0x14 + +//2020-01-14 AOA/AOD Report event +#define HCI_LE_CONNECTIONLESS_IQ_REPORT_EVENT 0x15 +#define HCI_LE_CONNECTION_IQ_REPORT_EVENT 0x16 +#define HCI_LE_CTE_REQUEST_FAILED_REPORT 0x17 + + +// Vendor Specific Event Code +#define HCI_VE_EVENT_CODE 0xFF + +// LE Vendor Specific LL Extension Events +#define HCI_EXT_SET_RX_GAIN_EVENT 0x0400 +#define HCI_EXT_SET_TX_POWER_EVENT 0x0401 +#define HCI_EXT_ONE_PKT_PER_EVT_EVENT 0x0402 +#define HCI_EXT_CLK_DIVIDE_ON_HALT_EVENT 0x0403 +#define HCI_EXT_DECLARE_NV_USAGE_EVENT 0x0404 +#define HCI_EXT_DECRYPT_EVENT 0x0405 +#define HCI_EXT_SET_LOCAL_SUPPORTED_FEATURES_EVENT 0x0406 +#define HCI_EXT_SET_FAST_TX_RESP_TIME_EVENT 0x0407 +#define HCI_EXT_MODEM_TEST_TX_EVENT 0x0408 +#define HCI_EXT_MODEM_HOP_TEST_TX_EVENT 0x0409 +#define HCI_EXT_MODEM_TEST_RX_EVENT 0x040A +#define HCI_EXT_END_MODEM_TEST_EVENT 0x040B +#define HCI_EXT_SET_BDADDR_EVENT 0x040C +#define HCI_EXT_SET_SCA_EVENT 0x040D +#define HCI_EXT_ENABLE_PTM_EVENT 0x040E // Not a supported HCI command! Application only. +#define HCI_EXT_SET_FREQ_TUNE_EVENT 0x040F +#define HCI_EXT_SAVE_FREQ_TUNE_EVENT 0x0410 +#define HCI_EXT_SET_MAX_DTM_TX_POWER_EVENT 0x0411 +#define HCI_EXT_MAP_PM_IO_PORT_EVENT 0x0412 +#define HCI_EXT_DISCONNECT_IMMED_EVENT 0x0413 +#define HCI_EXT_PER_EVENT 0x0414 +#define HCI_EXT_PER_BY_CHAN_EVENT 0x0415 // Not a supported HCI command! Application only. +#define HCI_EXT_EXTEND_RF_RANGE_EVENT 0x0416 +#define HCI_EXT_ADV_EVENT_NOTICE_EVENT 0x0417 // Not a supported HCI command! Application only. +#define HCI_EXT_CONN_EVENT_NOTICE_EVENT 0x0418 // Not a supported HCI command! Application only. +#define HCI_EXT_HALT_DURING_RF_EVENT 0x0419 +#define HCI_EXT_OVERRIDE_SL_EVENT 0x041A +#define HCI_EXT_BUILD_REVISION_EVENT 0x041B +#define HCI_EXT_DELAY_SLEEP_EVENT 0x041C +#define HCI_EXT_RESET_SYSTEM_EVENT 0x041D +#define HCI_EXT_OVERLAPPED_PROCESSING_EVENT 0x041E +#define HCI_EXT_NUM_COMPLETED_PKTS_LIMIT_EVENT 0x041F + +/******************************************************************************* + TYPEDEFS +*/ + +/******************************************************************************* + LOCAL VARIABLES +*/ + +/******************************************************************************* + GLOBAL VARIABLES +*/ + +/* +** HCI OSAL API +*/ + +/******************************************************************************* + @fn HCI_Init + + @brief This is the HCI OSAL task initialization routine. + + input parameters + + @param taskID - The HCI OSAL task identifer. + + output parameters + + @param None. + + @return None. +*/ +extern void HCI_Init( uint8 taskID ); + + +/******************************************************************************* + @fn HCI_ProcessEvent + + @brief This is the HCI OSAL task process event handler. + + input parameters + + @param taskID - The HCI OSAL task identifer. + @param events - HCI OSAL task events. + + output parameters + + @param None. + + @return Unprocessed events. +*/ +extern uint16 HCI_ProcessEvent( uint8 task_id, + uint16 events ); + + +#ifdef __cplusplus +} +#endif + +#endif /* HCI_TL_H */ diff --git a/arch/arm/src/phy62xx/ble/host/att_internal.h b/arch/arm/src/phy62xx/ble/host/att_internal.h new file mode 100644 index 00000000000..71054360e82 --- /dev/null +++ b/arch/arm/src/phy62xx/ble/host/att_internal.h @@ -0,0 +1,91 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/************************************************************************************************** + + +**************************************************************************************************/ + +#ifndef ATT_INTERNAL_H +#define ATT_INTERNAL_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ +#include "osal_cbTimer.h" + +#include "l2cap.h" +#include "att.h" + +/********************************************************************* + MACROS +*/ + +/********************************************************************* + CONSTANTS +*/ + +/********************************************************************* + TYPEDEFS +*/ + +// Function prototype to build an attribute protocol message +typedef uint16 (*attBuildMsg_t)( uint8* pBuf, uint8* pMsg ); + +/********************************************************************* + VARIABLES +*/ + +/********************************************************************* + FUNCTIONS +*/ + +extern uint16 attBuildExecuteWriteRsp( uint8* pBuf, uint8* pMsg ); + +extern uint16 attBuildHandleValueCfm( uint8* pBuf, uint8* pMsg ); + +extern bStatus_t attSendMsg( uint16 connHandle, attBuildMsg_t pfnBuildMsg, + uint8 opcode, uint8* pMsg ); + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* ATT_INTERNAL_H */ diff --git a/arch/arm/src/phy62xx/ble/host/gap_internal.h b/arch/arm/src/phy62xx/ble/host/gap_internal.h new file mode 100644 index 00000000000..b196ebbf8e1 --- /dev/null +++ b/arch/arm/src/phy62xx/ble/host/gap_internal.h @@ -0,0 +1,501 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/************************************************************************************************** +**************************************************************************************************/ + +#ifndef GAP_INTERNAL_H +#define GAP_INTERNAL_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ +#include "bcomdef.h" +#include "hci.h" +#include "l2cap.h" +#include "gap.h" + +/********************************************************************* + MACROS +*/ + +/********************************************************************* + CONSTANTS +*/ + +// GAP OSAL Events +#define GAP_OSAL_TIMER_SCAN_DURATION_EVT 0x0001 +#define GAP_END_ADVERTISING_EVT 0x0002 +#define GAP_CHANGE_RESOLVABLE_PRIVATE_ADDR_EVT 0x0004 + +#define ADDRTYPE_RANDOM 1 // Not public + +#define GAP_PRIVATE_ADDR_CHANGE_RESOLUTION 0xEA60 // Timer resolution is 1 minute + +#define ADV_TOKEN_HDR 2 + +// Address header bits +#define RANDOM_ADDR_HDR 0xC0 // Used for LL RANDOM Address +#define STATIC_ADDR_HDR 0xC0 // Host Static Address, same as RANDOM address +#define PRIVATE_RESOLVE_ADDR_HDR 0x40 + +#if defined ( TESTMODES ) +// GAP TestModes +#define GAP_TESTMODE_OFF 0 // No Test mode +#define GAP_TESTMODE_NO_RESPONSE 1 // Don't respond to any GAP message +#endif // TESTMODES + +// L2CAP Connection Parameters Update Request event +#define L2CAP_PARAM_UPDATE 0xFFFF + +/********************************************************************* + TYPEDEFS +*/ + +typedef struct gapAdvToken +{ + struct gapAdvToken* pNext; // Pointer to next item in link list + gapAdvDataToken_t* pToken; // Pointer to data token +} gapAdvToken_t; + +/** Advertising and Scan Response Data **/ +typedef struct +{ + uint8 dataLen; // Number of bytes used in "dataField" + uint8 dataField[B_MAX_ADV_LEN]; // Data field of the advertisement or SCAN_RSP +} gapAdvertisingData_t; + +typedef struct +{ + uint8 dataLen; // length (in bytes) of "dataField" + uint8 dataField[1]; // This is just a place holder size + // The dataField will be allocated bigger +} gapAdvertRecData_t; + +// Temporary advertising record +typedef struct +{ + uint8 eventType; // Avertisement or SCAN_RSP + uint8 addrType; // Advertiser's address type + uint8 addr[B_ADDR_LEN]; // Advertiser's address + gapAdvertRecData_t* pAdData; // Advertising data field. This space is allocated. + gapAdvertRecData_t* pScanData; // SCAN_RSP data field. This space is allocated. +} gapAdvertRec_t; + +typedef enum +{ + GAP_ADSTATE_SET_PARAMS, // Setting the advertisement parameters + GAP_ADSTATE_SET_MODE, // Turning on advertising + GAP_ADSTATE_ADVERTISING, // Currently Advertising + GAP_ADSTATE_ENDING // Turning off advertising +} gapAdvertStatesIDs_t; + +// Advertising State Information +typedef struct +{ + uint8 taskID; // App that started an advertising period + gapAdvertStatesIDs_t state; // Make Discoverable state + gapAdvertisingParams_t params; // Advertisement parameters +} gapAdvertState_t; + +typedef struct +{ + uint8 state; // Authentication states + uint16 connectionHandle; // Connection Handle from controller, + smLinkSecurityReq_t secReqs; // Pairing Control info + + // The following are only used if secReqs.bondable == BOUND, which means that + // the device is already bound and we should use the security information and + // keys + smSecurityInfo_t* pSecurityInfo; // BOUND - security information + smIdentityInfo_t* pIdentityInfo; // BOUND - identity information + smSigningInfo_t* pSigningInfo; // Signing information +} gapAuthStateParams_t; + +// Callback when an HCI Command Event has been received on the Central. +typedef uint8 (*gapProcessHCICmdEvt_t)( uint16 cmdOpcode, hciEvt_CmdComplete_t* pMsg ); + +// Callback when an Scanning Report has been received on the Central. +typedef void (*gapProcessScanningEvt_t)( hciEvt_BLEAdvPktReport_t* pMsg ); + +// Callback to cancel a connection initiation on the Central. +typedef bStatus_t (*gapCancelLinkReq_t)( uint8 taskID, uint16 connectionHandle ); + +// Callback when a connection-related event has been received on the Central. +typedef uint8(*gapProcessConnEvt_t)( uint16 cmdOpcode, hciEvt_CommandStatus_t* pMsg ); + +// Callback when an HCI Command Command Event on the Peripheral. +typedef uint8 (*gapProcessHCICmdCompleteEvt_t)( hciEvt_CmdComplete_t* pMsg ); + +// Callback when an Advertising Event has been received on the Peripheral. +typedef void (*gapProcessAdvertisingEvt_t)( uint8 timeout ); + +// Callback when a Set Advertising Params has been received on the Peripheral. +typedef bStatus_t (*gapSetAdvParams_t)( void ); + +// Central callback structure - must be setup by the Central. +typedef struct +{ + gapProcessHCICmdEvt_t pfnProcessHCICmdEvt; // When HCI Command Event received + gapProcessScanningEvt_t pfnProcessScanningEvt; // When Scanning Report received +} gapCentralCBs_t; + +// Central connection-related callback structure - must be setup by the Central. +typedef struct +{ + gapCancelLinkReq_t pfnCancelLinkReq; // When cancel connection initiation requested + gapProcessConnEvt_t pfnProcessConnEvt; // When connection-related event received +} gapCentralConnCBs_t; + +// Peripheral callback structure - must be setup by the Peripheral. +typedef struct +{ + gapProcessHCICmdCompleteEvt_t pfnProcessHCICmdCompleteEvt; // When HCI Command Complete Event received + gapProcessAdvertisingEvt_t pfnProcessAdvertisingEvt; // When Advertising Event received + gapSetAdvParams_t pfnSetAdvParams; // When Set Advertising Params received +} gapPeripheralCBs_t; + +/********************************************************************* + GLOBAL VARIABLES +*/ + +extern uint8 gapTaskID; +extern uint8 gapUnwantedTaskID; + +extern uint8 gapAppTaskID; // default task ID to send events +extern uint8 gapProfileRole; // device GAP Profile Role(s) + +extern uint8 gapDeviceAddrMode; // ADDRTYPE_PUBLIC, ADDRTYPE_STATIC, +// ADDRTYPE_PRIVATE_NONRESOLVE +// or ADDRTYPE_PRIVATE_RESOLVE + +// Central Peripheral variables +extern gapDevDiscReq_t* pGapDiscReq; +extern gapEstLinkReq_t* pEstLink; +extern gapCentralConnCBs_t* pfnCentralConnCBs; + +// Peripheral variables +extern gapAdvertState_t* pGapAdvertState; +extern gapPeripheralCBs_t* pfnPeripheralCBs; + +// Common variables +extern gapAuthStateParams_t* pAuthLink[]; +extern uint16 gapPrivateAddrChangeTimeout; +extern uint8 gapAutoAdvPrivateAddrChange; + +/********************************************************************* + FUNCTIONS - API +*/ + +/********************************************************************* + Application Level Functions +*/ + +/* + gapSetScanParamStatus - Process HCI Command Complete Event status for + the call to HCI_BLESetScanParamCmd(). +*/ +extern uint8 gapSetScanParamStatus( uint8 status ); + +/* + gapSetAdvParamsStatus - Process HCI Command Complete Event status for + the call to HCI_BLESetAdvParamCmd(). +*/ +extern uint8 gapSetAdvParamsStatus( uint8 status ); + +/* + gapWriteAdvEnableStatus - Process HCI Command Complete Event status for + the call to HCI_BLEWriteAdvEnableCmd(). +*/ +extern uint8 gapWriteAdvEnableStatus( uint8 status, uint16 interval ); + +/* + gapWriteAdvDataStatus - Process HCI Command Complete Event status for + the call to HCI_BLEWriteAdvDataCmd() or + HCI_BLEWriteScanRspDataCmd(). +*/ +extern void gapWriteAdvDataStatus( uint8 adType, uint8 status ); + +/* + gapReadBD_ADDRStatus - Process the HCI Command Complete Event for the + call to HCI_ReadBDADDRCmd(). +*/ +extern uint8 gapReadBD_ADDRStatus( uint8 status, uint8* pBdAddr ); + +/* + gapReadBufSizeCmdStatus - Process the HCI Command Complete Event for the + call to HCI_BLEReadBufSizeCmd(). +*/ +extern uint8 gapReadBufSizeCmdStatus( hciRetParam_LeReadBufSize_t* pCmdStat ); + +/* + gapProcessConnectionCompleteEvt - Process the HCI Connection Complete + event for the call to HCI_BLECreateLLConnCmd(). +*/ +extern void gapProcessConnectionCompleteEvt( hciEvt_BLEConnComplete_t* pPkt ); + +/* + gapProcessConnUpdateCompleteEvt - Process the HCI Connection Parameters + Update Complete event for the call to HCI_BLEUpdateLLConnCmd(). +*/ +extern void gapProcessConnUpdateCompleteEvt( hciEvt_BLEConnUpdateComplete_t* pPkt ); + +/* + gapProcessDisconnectCompleteEvt - Process the LL Disconnection Complete Event + for the call to HCI_DisconnectCmd(). +*/ +extern void gapProcessDisconnectCompleteEvt( hciEvt_DisconnComplete_t* pPkt ); + +/* + gapProcessCreateLLConnCmdStatus - Process the status for the HCI_BLECreateLLConnCmd(). +*/ +extern void gapProcessCreateLLConnCmdStatus( uint8 status ); + +/* + gapProcessConnUpdateCmdStatus - Process the status for the HCI_LE_ConnUpdateCmd(). +*/ +extern void gapProcessConnUpdateCmdStatus( uint8 status ); + +/* + gapProcessNewAddr - Process message SM +*/ +extern bStatus_t gapProcessNewAddr( uint8* pNewAddr ); + +/* + gapAddAddrAdj - Add the top two bits based on the address type. +*/ +extern uint8 gapAddAddrAdj( uint8 addrType, uint8* pAddr ); + +/* + gapDetermineAddrType - Convert from LL address type to host address type. +*/ +extern uint8 gapDetermineAddrType( uint8 addrType, uint8* pAddr ); + +/* + gapProcessRandomAddrComplete - Process message HCI +*/ +extern void gapProcessRandomAddrComplete( uint8 status ); + +/* + gapGetSRK - Get pointer to the SRK +*/ +extern uint8* gapGetSRK( void ); + +/* + gapGetSignCounter - Get the signature counter +*/ +extern uint32 gapGetSignCounter( void ); + +/* + gapIncSignCounter - Increment the signature counter +*/ +extern void gapIncSignCounter( void ); + +/* + gapUpdateConnSignCounter - Update a connection's signature's counter +*/ +extern void gapUpdateConnSignCounter( uint16 connHandle, uint32 newSignCounter ); + +/* + gapLinkCheck - linkDB callback function +*/ +extern void gapLinkCheck( uint16 connectionHandle, uint8 changeType ); + +/* + gapGetDevAddressMode - Get the device address mode. +*/ +extern uint8 gapGetDevAddressMode( void ); + +/* + gapGetDevAddress - Get the device address. + real - TRUE if you always want BD_ADDR, FALSE will allow random addresses. +*/ +extern uint8* gapGetDevAddress( uint8 real ); + +/* + gapGetIRK - Get the device's IRK. +*/ +extern uint8* gapGetIRK( void ); + +/* + gapPasskeyNeededCB - Callback function to ask for passkey +*/ +extern void gapPasskeyNeededCB( uint16 connectionHandle, uint8 type ); + +/* + gapPairingCompleteCB - Callback function to inform pairing process complete. +*/ +extern void gapPairingCompleteCB( uint8 status, uint8 initiatorRole, + uint16 connectionHandle, + uint8 authState, + smSecurityInfo_t* pEncParams, + smSecurityInfo_t* pDevEncParams, + smIdentityInfo_t* pIdInfo, + smSigningInfo_t* pSigningInfo ); + +/* + gapTerminateConnComplete - Process command complete for HCI_BLECreateLLConnCancelCmd. +*/ +extern void gapTerminateConnComplete( void ); + +/* + gapSendSlaveSecurityReqEvent - Generate a Slave Security Request event to the app. +*/ +extern void gapSendSlaveSecurityReqEvent( uint8 taskID, uint16 connHandle, uint8* pDevAddr, uint8 authReq ); + +/* + gapSetAdvParams - Send the advertisement parameters to the LL. +*/ +extern bStatus_t gapSetAdvParams( void ); + +/* + gapAddAdvToken - Add token to the end of the list. +*/ +extern bStatus_t gapAddAdvToken( gapAdvDataToken_t* pToken ); + +/* + gapDeleteAdvToken - Remove a token from the list. +*/ +extern gapAdvDataToken_t* gapDeleteAdvToken( uint8 ADType ); + +/* + gapFindAdvToken - Find a Advertisement data token from the advertisement type. +*/ +extern gapAdvToken_t* gapFindAdvToken( uint8 ADType ); + +/* + gapCalcAdvTokenDataLen - Find a Advertisement data token from the advertisement type. +*/ +extern void gapCalcAdvTokenDataLen( uint8* pAdLen, uint8* pSrLen ); + +/* + gapValidADType - Is a Advertisement Data Type valid. +*/ +extern uint8 gapValidADType( uint8 adType ); + +/* + gapBuildADTokens - Is a Advertisement Data Type valid. +*/ +extern bStatus_t gapBuildADTokens( void ); + +/* + gapSendBondCompleteEvent - Indicate that a bond has occurred. +*/ +extern void gapSendBondCompleteEvent( uint8 status, uint16 connectionHandle ); + +/* + gapSendPairingReqEvent - Indicate that an unexpected Pairing Request was received. +*/ +extern void gapSendPairingReqEvent( uint8 status, uint16 connectionHandle, + uint8 ioCap, + uint8 oobDataFlag, + uint8 authReq, + uint8 maxEncKeySize, + keyDist_t keyDist ); + +/* + gapFindADType - Find Advertisement Data Type field in advertising data + field. +*/ +extern uint8* gapFindADType( uint8 adType, uint8* pAdLen, + uint8 dataLen, uint8* pDataField ); + +/* + gapRegisterCentral - Register Central's processing function with GAP task +*/ +extern void gapRegisterCentral( gapCentralCBs_t* pfnCBs ); + +/* + gapRegisterCentralConn - Register Central's connection-related processing function with GAP task +*/ +extern void gapRegisterCentralConn( gapCentralConnCBs_t* pfnCBs); + +/* + gapRegisterPeripheral - Register Peripheral's processing function with GAP task +*/ +extern void gapRegisterPeripheral( gapPeripheralCBs_t* pfnCBs ); + +/* + gapIsAdvertising - Check if we are currently advertising. +*/ +extern uint8 gapIsAdvertising( void ); + +/* + gapIsScanning - Check if we are currently scanning. +*/ +extern uint8 gapIsScanning( void ); + +/* + gapCancelLinkReq - Cancel a connection create request. +*/ +extern bStatus_t gapCancelLinkReq( uint8 taskID, uint16 connectionHandle ); + +/* + gapFreeEstLink - Free the establish link memory. +*/ +extern void gapFreeEstLink( void ); + +/* + sendEstLinkEvent - Build and send the GAP_LINK_ESTABLISHED_EVENT to the app. +*/ +extern void sendEstLinkEvent( uint8 status, uint8 taskID, uint8 devAddrType, + uint8* pDevAddr, uint16 connectionHandle, + uint16 connInterval, uint16 connLatency, + uint16 connTimeout, uint16 clockAccuracy ); + +/* + gapSendLinkUpdateEvent - Build and send the GAP_LINK_PARAM_UPDATE_EVENT to the app. + +*/ +extern void gapSendLinkUpdateEvent( uint8 status, uint16 connectionHandle, + uint16 connInterval, uint16 connLatency, + uint16 connTimeout ); + +/* + gapProcessL2CAPSignalEvt - Process L2CAP Signaling messages. +*/ +extern void gapProcessL2CAPSignalEvt( l2capSignalEvent_t* pCmd ); + + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* GAP_INTERNAL_H */ diff --git a/arch/arm/src/phy62xx/ble/host/gapgattserver.h b/arch/arm/src/phy62xx/ble/host/gapgattserver.h new file mode 100644 index 00000000000..490bd10a0e8 --- /dev/null +++ b/arch/arm/src/phy62xx/ble/host/gapgattserver.h @@ -0,0 +1,212 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/************************************************************************************************** + Filename: gapgattserver.h + Revised: + Revision: + + Description: This file contains GAP GATT attribute definitions + and prototypes. + + + +**************************************************************************************************/ + +#ifndef GAPGATTSERVER_H +#define GAPGATTSERVER_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ + +/********************************************************************* + CONSTANTS +*/ + +#define GAP_DEVICE_NAME_LEN (20+1) + +// Privacy Flag States +#define GAP_PRIVACY_DISABLED 0x00 +#define GAP_PRIVACY_ENABLED 0x01 + +// GAP GATT Server Parameters +#define GGS_DEVICE_NAME_ATT 0 // RW uint8[GAP_DEVICE_NAME_LEN] +#define GGS_APPEARANCE_ATT 1 // RW uint16 +#define GGS_PERI_PRIVACY_FLAG_ATT 2 // RW uint8 +#define GGS_RECONNCT_ADDR_ATT 3 // RW uint8[B_ADDR_LEN] +#define GGS_PERI_CONN_PARAM_ATT 4 // RW sizeof(gapPeriConnectParams_t) +#define GGS_PERI_PRIVACY_FLAG_PROPS 5 // RW uint8 +#define GGS_W_PERMIT_DEVICE_NAME_ATT 6 // W uint8 +#define GGS_W_PERMIT_APPEARANCE_ATT 7 // W uint8 +#define GGS_W_PERMIT_PRIVACY_FLAG_ATT 8 // W uint8 + +// GAP Services bit fields +#define GAP_SERVICE 0x00000001 + +// Attribute ID used with application's callback when attribute value is changed OTA +#define GGS_DEVICE_NAME_ID 0 +#define GGS_APPEARANCE_ID 1 + +#if defined ( TESTMODES ) +// GGS TestModes +#define GGS_TESTMODE_OFF 0 // No Test mode +#define GGS_TESTMODE_W_PERMIT_DEVICE_NAME 1 // Make Device Name attribute writable +#define GGS_TESTMODE_W_PERMIT_APPEARANCE 2 // Make Appearance attribute writable +#define GGS_TESTMODE_W_PERMIT_PRIVACY_FLAG 3 // Make Peripheral Privacy Flag attribute writable with authentication +#endif // TESTMODES + +/********************************************************************* + TYPEDEFS +*/ +// Callback to notify when attribute value is changed over the air. +typedef void (*ggsAttrValueChange_t)( uint8 attrId ); + +// GAP GATT Server callback structure +typedef struct +{ + ggsAttrValueChange_t pfnAttrValueChange; // When attribute value is changed OTA +} ggsAppCBs_t; + +/********************************************************************* + MACROS +*/ + +/********************************************************************* + Profile Callbacks +*/ + +/********************************************************************* + API FUNCTIONS +*/ + +/** + @brief Set a GAP GATT Server 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 will be cast to + uint16 pointer).
+ + @return bStatus_t +*/ +extern bStatus_t GGS_SetParameter( uint8 param, uint8 len, void* value ); + +/** + @brief Get a GAP GATT Server 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 will be cast to + uint16 pointer).
+ + @return bStatus_t +*/ +extern bStatus_t GGS_GetParameter( uint8 param, void* value ); + +/** + @brief Add function for the GAP GATT Service. + + @param services - services to add. This is a bit map and can + contain more than one service. + + @return SUCCESS: Service added successfully.
+ INVALIDPARAMETER: Invalid service field.
+ FAILURE: Not enough attribute handles available.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t GGS_AddService( uint32 services ); + +/** + @brief Delete function for the GAP GATT Service. + + @param services - services to delete. This is a bit map and can + contain more than one service. + + @return SUCCESS: Service deleted successfully.
+ FAILURE: Service not found.
+*/ +extern bStatus_t GGS_DelService( uint32 services ); + +/** + @brief Registers the application callback function. + + Note: Callback registration is needed only when the + Device Name is made writable. The application + will be notified when the Device Name is changed + over the air. + + @param appCallbacks - pointer to application callbacks. + + @return none +*/ +extern void GGS_RegisterAppCBs( ggsAppCBs_t* appCallbacks ); + +/** + @brief Set a GGS Parameter value. Use this function to change + the default GGS parameter values. + + @param value - new GGS param value + + @return void +*/ +extern void GGS_SetParamValue( uint16 value ); + +/** + @brief Get a GGS Parameter value. + + @param none + + @return GGS Parameter value +*/ +extern uint16 GGS_GetParamValue( void ); + +/********************************************************************* + TASK FUNCTIONS - Don't call these. These are system functions. +*/ + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* GAPGATTSERVER_H */ diff --git a/arch/arm/src/phy62xx/ble/host/gatt_internal.h b/arch/arm/src/phy62xx/ble/host/gatt_internal.h new file mode 100644 index 00000000000..85a8f124cbe --- /dev/null +++ b/arch/arm/src/phy62xx/ble/host/gatt_internal.h @@ -0,0 +1,115 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/************************************************************************************************** +**************************************************************************************************/ + +#ifndef GATT_INTERNAL_H +#define GATT_INTERNAL_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ +#include "osal_cbTimer.h" + +#include "att.h" +#include "gatt.h" + +/********************************************************************* + MACROS +*/ +#define TIMER_VALID( id ) ( ( (id) != INVALID_TIMER_ID ) && \ + ( (id) != TIMEOUT_TIMER_ID ) ) + +#define TIMER_STATUS( id ) ( (id) == TIMEOUT_TIMER_ID ? bleTimeout : \ + (id) == INVALID_TIMER_ID ? SUCCESS : blePending ) + +/********************************************************************* + CONSTANTS +*/ + +/********************************************************************* + TYPEDEFS +*/ +// Srtucture for Attribute Version Information attribute +typedef struct +{ + uint8 attVersion; // Attribute Protocol Version + uint8 gattVersion; // Generic Attribute Profile Version + uint16 manufacturerName; // Manufacturer Name +} gattVersionInfo_t; + +// Function prototype to parse an attribute protocol request message +typedef bStatus_t (*gattParseReq_t)( uint8 sig, uint8 cmd, uint8* pParams, uint16 len, attMsg_t* pMsg ); + +// Function prototype to parse an attribute protocol response message +typedef bStatus_t (*gattParseRsp_t)( uint8* pParams, uint16 len, attMsg_t* pMsg ); + +// Function prototype to process an attribute protocol message +typedef bStatus_t (*gattProcessMsg_t)( uint16 connHandle, attPacket_t* pPkt ); + +// Function prototype to process an attribute protocol request message +typedef bStatus_t (*gattProcessReq_t)( uint16 connHandle, attMsg_t* pMsg ); + +/********************************************************************* + VARIABLES +*/ +extern uint8 gattTaskID; + +/********************************************************************* + FUNCTIONS +*/ +extern void gattRegisterServer( gattProcessMsg_t pfnProcessMsg ); + +extern void gattRegisterClient( gattProcessMsg_t pfnProcessMsg ); + +extern bStatus_t gattNotifyEvent( uint8 taskId, uint16 connHandle, uint8 status, + uint8 method, gattMsg_t* pMsg ); + +extern void gattStartTimer( pfnCbTimer_t pfnCbTimer, uint8* pData, + uint16 timeout, uint8* pTimerId ); + +extern void gattStopTimer( uint8* pTimerId ); + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* GATT_INTERNAL_H */ diff --git a/arch/arm/src/phy62xx/ble/host/gatt_profile_uuid.h b/arch/arm/src/phy62xx/ble/host/gatt_profile_uuid.h new file mode 100644 index 00000000000..a6928072036 --- /dev/null +++ b/arch/arm/src/phy62xx/ble/host/gatt_profile_uuid.h @@ -0,0 +1,265 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/************************************************************************************************** + Filename: gatt_profile_uuid.h + Revised: + Revision: + + Description: This file contains GATT Profile UUID types. + + + +**************************************************************************************************/ + +#ifndef GATT_PROFILE_UUID_H +#define GATT_PROFILE_UUID_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ + +/********************************************************************* + CONSTANTS +*/ + +/* + WARNING: The 16-bit UUIDs are assigned by the Bluetooth SIG and published + in the Bluetooth Assigned Numbers page. Do not change these values. + Changing them will cause Bluetooth interoperability issues. +*/ + +/** + GATT Service UUIDs +*/ +#define IMMEDIATE_ALERT_SERV_UUID 0x1802 // Immediate Alert +#define LINK_LOSS_SERV_UUID 0x1803 // Link Loss +#define TX_PWR_LEVEL_SERV_UUID 0x1804 // Tx Power +#define CURRENT_TIME_SERV_UUID 0x1805 // Current Time Service +#define REF_TIME_UPDATE_SERV_UUID 0x1806 // Reference Time Update Service +#define NEXT_DST_CHANGE_SERV_UUID 0x1807 // Next DST Change Service +#define GLUCOSE_SERV_UUID 0x1808 // Glucose +#define THERMOMETER_SERV_UUID 0x1809 // Health Thermometer +#define DEVINFO_SERV_UUID 0x180A // Device Information +#define NWA_SERV_UUID 0x180B // Network Availability +#define HEARTRATE_SERV_UUID 0x180D // Heart Rate +#define PHONE_ALERT_STS_SERV_UUID 0x180E // Phone Alert Status Service +#define BATT_SERV_UUID 0x180F // Battery Service +#define BLOODPRESSURE_SERV_UUID 0x1810 // Blood Pressure +#define ALERT_NOTIF_SERV_UUID 0x1811 // Alert Notification Service +#define HID_SERV_UUID 0x1812 // Human Interface Device +#define SCAN_PARAM_SERV_UUID 0x1813 // Scan Parameters +#define RSC_SERV_UUID 0x1814 // Running Speed and Cadence +#define CSC_SERV_UUID 0x1816 // Cycling Speed and Cadence +#define CYCPWR_SERV_UUID 0x1818 // Cycling Power +#define LOC_NAV_SERV_UUID 0x1819 // Location and Navigation + +/** + GATT Characteristic UUIDs +*/ +#define ALERT_LEVEL_UUID 0x2A06 // Alert Level +#define TX_PWR_LEVEL_UUID 0x2A07 // Tx Power Level +#define DATE_TIME_UUID 0x2A08 // Date Time +#define DAY_OF_WEEK_UUID 0x2A09 // Day of Week +#define DAY_DATE_TIME_UUID 0x2A0A // Day Date Time +#define EXACT_TIME_256_UUID 0x2A0C // Exact Time 256 +#define DST_OFFSET_UUID 0x2A0D // DST Offset +#define TIME_ZONE_UUID 0x2A0E // Time Zone +#define LOCAL_TIME_INFO_UUID 0x2A0F // Local Time Information +#define TIME_WITH_DST_UUID 0x2A11 // Time with DST +#define TIME_ACCURACY_UUID 0x2A12 // Time Accuracy +#define TIME_SOURCE_UUID 0x2A13 // Time Source +#define REF_TIME_INFO_UUID 0x2A14 // Reference Time Information +#define TIME_UPDATE_CTRL_PT_UUID 0x2A16 // Time Update Control Point +#define TIME_UPDATE_STATE_UUID 0x2A17 // Time Update State +#define GLUCOSE_MEAS_UUID 0x2A18 // Glucose Measurement +#define BATT_LEVEL_UUID 0x2A19 // Battery Level +#define TEMP_MEAS_UUID 0x2A1C // Temperature Measurement +#define TEMP_TYPE_UUID 0x2A1D // Temperature Type +#define IMEDIATE_TEMP_UUID 0x2A1E // Intermediate Temperature +#define MEAS_INTERVAL_UUID 0x2A21 // Measurement Interval +#define BOOT_KEY_INPUT_UUID 0x2A22 // Boot Keyboard Input Report +#define SYSTEM_ID_UUID 0x2A23 // System ID +#define MODEL_NUMBER_UUID 0x2A24 // Model Number String +#define SERIAL_NUMBER_UUID 0x2A25 // Serial Number String +#define FIRMWARE_REV_UUID 0x2A26 // Firmware Revision String +#define HARDWARE_REV_UUID 0x2A27 // Hardware Revision String +#define SOFTWARE_REV_UUID 0x2A28 // Software Revision String +#define MANUFACTURER_NAME_UUID 0x2A29 // Manufacturer Name String +#define IEEE_11073_CERT_DATA_UUID 0x2A2A // IEEE 11073-20601 Regulatory Certification Data List +#define CURRENT_TIME_UUID 0x2A2B // Current Time +#define SCAN_REFRESH_UUID 0x2A31 // Scan Refresh +#define BOOT_KEY_OUTPUT_UUID 0x2A32 // Boot Keyboard Output Report +#define BOOT_MOUSE_INPUT_UUID 0x2A33 // Boot Mouse Input Report +#define GLUCOSE_CONTEXT_UUID 0x2A34 // Glucose Measurement Context +#define BLOODPRESSURE_MEAS_UUID 0x2A35 // Blood Pressure Measurement +#define IMEDIATE_CUFF_PRESSURE_UUID 0x2A36 // Intermediate Cuff Pressure +#define HEARTRATE_MEAS_UUID 0x2A37 // Heart Rate Measurement +#define BODY_SENSOR_LOC_UUID 0x2A38 // Body Sensor Location +#define HEARTRATE_CTRL_PT_UUID 0x2A39 // Heart Rate Control Point +#define NETWORK_AVAIL_UUID 0x2A3E // Network Availability +#define ALERT_STATUS_UUID 0x2A3F // Alert Status +#define RINGER_CTRL_PT_UUID 0x2A40 // Ringer Control Point +#define RINGER_SETTING_UUID 0x2A41 // Ringer Setting +#define ALERT_CAT_ID_BMASK_UUID 0x2A42 // Alert Category ID Bit Mask +#define ALERT_CAT_ID_UUID 0x2A43 // Alert Category ID +#define ALERT_NOTIF_CTRL_PT_UUID 0x2A44 // Alert Notification Control Point +#define UNREAD_ALERT_STATUS_UUID 0x2A45 // Unread Alert Status +#define NEW_ALERT_UUID 0x2A46 // New Alert +#define SUP_NEW_ALERT_CAT_UUID 0x2A47 // Supported New Alert Category +#define SUP_UNREAD_ALERT_CAT_UUID 0x2A48 // Supported Unread Alert Category +#define BLOODPRESSURE_FEATURE_UUID 0x2A49 // Blood Pressure Feature +#define HID_INFORMATION_UUID 0x2A4A // HID Information +#define REPORT_MAP_UUID 0x2A4B // Report Map +#define HID_CTRL_PT_UUID 0x2A4C // HID Control Point +#define REPORT_UUID 0x2A4D // Report +#define PROTOCOL_MODE_UUID 0x2A4E // Protocol Mode +#define SCAN_INTERVAL_WINDOW_UUID 0x2A4F // Scan Interval Window +#define PNP_ID_UUID 0x2A50 // PnP ID +#define GLUCOSE_FEATURE_UUID 0x2A51 // Glucose Feature +#define RECORD_CTRL_PT_UUID 0x2A52 // Record Access Control Point +#define RSC_MEAS_UUID 0x2A53 // RSC Measurement +#define RSC_FEATURE_UUID 0x2A54 // RSC Feature +#define SC_CTRL_PT_UUID 0x2A55 // SC Control Point +#define CSC_MEAS_UUID 0x2A5B // CSC Measurement +#define CSC_FEATURE_UUID 0x2A5C // CSC Feature +#define SENSOR_LOC_UUID 0x2A5D // Sensor Location +#define CYCPWR_MEAS_UUID 0x2A63 // Cycling Power Measurement +#define CYCPWR_VECTOR_UUID 0x2A64 // Cycling Power Vector +#define CYCPWR_FEATURE_UUID 0x2A65 // Cycling Power Feature +#define CYCPWR_CTRL_PT_UUID 0x2A66 // Cycling Power Control Point +#define LOC_SPEED_UUID 0x2A67 // Location and Speed +#define NAV_UUID 0x2A68 // Navigation +#define POS_QUALITY_UUID 0x2A69 // Position Quality +#define LN_FEATURE_UUID 0x2A6A // LN Feature +#define LN_CTRL_PT_UUID 0x2A6B // LN Control Point + +/** + GATT Unit UUIDs +*/ +#define GATT_UNITLESS_UUID 0x2700 // , +#define GATT_UNIT_LENGTH_METER_UUID 0x2701 // m, m +#define GATT_UNIT_MASS_KGRAM_UUID 0x2702 // kg, kg +#define GATT_UNIT_TIME_SECOND_UUID 0x2703 // s, s +#define GATT_UNIT_ELECTRIC_CURRENT_A_UUID 0x2704 // A, A +#define GATT_UNIT_THERMODYN_TEMP_K_UUID 0x2705 // K, K +#define GATT_UNIT_AMOUNT_SUBSTANCE_M_UUID 0x2706 // mol, mol +#define GATT_UNIT_LUMINOUS_INTENSITY_C_UUID 0x2707 // cd, cd + +#define GATT_UNIT_AREA_SQ_MTR_UUID 0x2710 // m^2, m^2 +#define GATT_UNIT_VOLUME_CUBIC_MTR_UUID 0x2711 // m^3, m^3 +#define GATT_UNIT_VELOCITY_MPS_UUID 0x2712 // m/s, m s^-1 +#define GATT_UNIT_ACCELERATION_MPS_SQ_UUID 0x2713 // m/s^2, m s^-2 +#define GATT_UNIT_WAVENUMBER_RM_UUID 0x2714 // ó, m^-1 +#define GATT_UNIT_DENSITY_KGPCM_UUID 0x2715 // p, kg m^-3 +#define GATT_UNIT_SURFACE_DENSITY_KGPSM_UUID 0x2716 // pA, kg m^-2 +#define GATT_UNIT_SPECIFIC_VOLUME_CMPKG_UUID 0x2717 // v, m^3 kg^-1 +#define GATT_UNIT_CURRENT_DENSITY_APSM_UUID 0x2718 // j, A m^-2 +#define GATT_UNIT_MAG_FIELD_STRENGTH_UUID 0x2719 // H, A m +#define GATT_UNIT_AMOUNT_CONC_MPCM_UUID 0x271A // c, mol m^-3 +#define GATT_UNIT_MASS_CONC_KGPCM_UUID 0x271B // c, kg m^-3 +#define GATT_UNIT_LUMINANCE_CPSM_UUID 0x271C // Lv, cd m^-2 +#define GATT_UNIT_REFRACTIVE_INDEX_UUID 0x271D // n, 1 +#define GATT_UNIT_RELATIVE_PERMEABLILTY_UUID 0x271E // u, 1 +#define GATT_UNIT_PLANE_ANGLE_RAD_UUID 0x2720 // rad, m m-1 +#define GATT_UNIT_SOLID_ANGLE_STERAD_UUID 0x2721 // sr, m2 m-2 +#define GATT_UNIT_FREQUENCY_HTZ_UUID 0x2722 // Hz, s-1 +#define GATT_UNIT_FORCE_NEWTON_UUID 0x2723 // N, m kg s-2 +#define GATT_UNIT_PRESSURE_PASCAL_UUID 0x2724 // Pa, N/m2 = m2 kg s-2 +#define GATT_UNIT_ENERGY_JOULE_UUID 0x2725 // J, N m = m2 kg s-2 +#define GATT_UNIT_POWER_WATT_UUID 0x2726 // W, J/s = m2 kg s-3 +#define GATT_UNIT_E_CHARGE_C_UUID 0x2727 // C, sA +#define GATT_UNIT_E_POTENTIAL_DIF_V_UUID 0x2728 // V, W/A = m2 kg s-3 A-1 + +#define GATT_UNIT_CELSIUS_TEMP_DC_UUID 0x272F // oC, t/oC = T/K - 273.15 + +#define GATT_UNIT_TIME_MINUTE_UUID 0x2760 // min, 60 s +#define GATT_UNIT_TIME_HOUR_UUID 0x2761 // h, 3600 s +#define GATT_UNIT_TIME_DAY_UUID 0x2762 // d, 86400 s +#define GATT_UNIT_PLANE_ANGLE_DEGREE_UUID 0x2763 // o, (pi/180) rad +#define GATT_UNIT_PLANE_ANGLE_MINUTE_UUID 0x2764 // ', (pi/10800) rad +#define GATT_UNIT_PLANE_ANGLE_SECOND_UUID 0x2765 // '', (pi/648000) rad +#define GATT_UNIT_AREA_HECTARE_UUID 0x2766 // ha, 10^4 m^2 +#define GATT_UNIT_VOLUME_LITRE_UUID 0x2767 // l, 10^-3 m^3 +#define GATT_UNIT_MASS_TONNE_UUID 0x2768 // t, 10^3 kg + +#define GATT_UINT_LENGTH_YARD_UUID 0x27A0 // yd, 0.9144 m +#define GATT_UNIT_LENGTH_PARSEC_UUID 0x27A1 // pc, 3.085678 × 1016 m +#define GATT_UNIT_LENGTH_INCH_UUID 0x27A2 // in, 0.0254 m +#define GATT_UNIT_LENGTH_FOOT_UUID 0x27A3 // ft, 0.3048 m +#define GATT_UNIT_LENGTH_MILE_UUID 0x27A4 // mi, 1609.347 m +#define GATT_UNIT_PRESSURE_PFPSI_UUID 0x27A5 // psi, 6.894757 × 103 Pa +#define GATT_UNIT_VELOCITY_KMPH_UUID 0x27A6 // km/h, 0.2777778 m^s-1 +#define GATT_UNIT_VELOCITY_MPH_UUID 0x27A7 // mi/h, 0.44704 m^ s-1 +#define GATT_UNIT_ANGULAR_VELOCITY_RPM_UUID 0x27A8 // r/min, 0.1047198 rad s-1 +#define GATT_UNIT_ENERGY_GCAL_UUID 0x27A9 // +#define GATT_UNIT_ENERGY_KCAL_UUID 0x27AA // kcal, 4190.02 J +#define GATT_UNIT_ENERGY_KWH_UUID 0x27AB // kWh, 3600000 J +#define GATT_UNIT_THERMODYN_TEMP_DF_UUID 0x27AC // oF, t/oF = T/K × 1.8 - 459.67 +#define GATT_UNIT_PERCENTAGE_UUID 0x27AD // % +#define GATT_UNIT_PER_MILE_UUID 0x27AE // +#define GATT_UNIT_PERIOD_BPM_UUID 0x27AF // +#define GATT_UNIT_E_CHARGE_AH_UUID 0x27B0 // +#define GATT_UNIT_MASS_DENSITY_MGPD_UUID 0x27B1 // +#define GATT_UNIT_MASS_DENSITY_MMPL_UUID 0x27B2 // +#define GATT_UNIT_TIME_YEAR_UUID 0x27B3 // +#define GATT_UNIT_TIME_MONTH_UUID 0x27B4 // + +/********************************************************************* + MACROS +*/ + +/********************************************************************* + TYPEDEFS +*/ + +/********************************************************************* + VARIABLES +*/ + +/********************************************************************* + FUNCTIONS +*/ + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* GATT_PROFILE_UUID_H */ diff --git a/arch/arm/src/phy62xx/ble/host/gattservapp.h b/arch/arm/src/phy62xx/ble/host/gattservapp.h new file mode 100644 index 00000000000..41d15e21bfc --- /dev/null +++ b/arch/arm/src/phy62xx/ble/host/gattservapp.h @@ -0,0 +1,659 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/** + @headerfile: gattservapp.h + $Date: + $Revision: + + @mainpage BLE GATT Server Application API + + Description: This file contains the GATT Server Application (GATTServApp) + definitions and prototypes.

+ + +**************************************************************************************************/ + +#ifndef GATTSERVAPP_H +#define GATTSERVAPP_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ +#include "bcomdef.h" +#include "OSAL.h" + +/********************************************************************* + CONSTANTS +*/ + +/** @defgroup GATT_SERV_MSG_EVENT_DEFINES GATT Server Message IDs + @{ +*/ + +#define GATT_CLIENT_CHAR_CFG_UPDATED_EVENT 0x00 //!< Sent when a Client Characteristic Configuration is updated. This event is sent as an OSAL message defined as gattCharCfgUpdatedEvent_t. + +/** @} End GATT_SERV_MSG_EVENT_DEFINES */ + + +/** @defgroup GATT_PROP_BITMAPS_DEFINES GATT Characteristic Properties Bit Fields + @{ +*/ + +#define GATT_PROP_BCAST 0x01 //!< Permits broadcasts of the Characteristic Value +#define GATT_PROP_READ 0x02 //!< Permits reads of the Characteristic Value +#define GATT_PROP_WRITE_NO_RSP 0x04 //!< Permits writes of the Characteristic Value without response +#define GATT_PROP_WRITE 0x08 //!< Permits writes of the Characteristic Value with response +#define GATT_PROP_NOTIFY 0x10 //!< Permits notifications of a Characteristic Value without acknowledgement +#define GATT_PROP_INDICATE 0x20 //!< Permits indications of a Characteristic Value with acknowledgement +#define GATT_PROP_AUTHEN 0x40 //!< Permits signed writes to the Characteristic Value +#define GATT_PROP_EXTENDED 0x80 //!< Additional characteristic properties are defined in the Characteristic Extended Properties Descriptor + +/** @} End GATT_PROP_BITMAPS_DEFINES */ + +/** @defgroup GATT_EXT_PROP_BITMAPS_DEFINES GATT Characteristic Extended Properties Bit Fields + @{ +*/ + +#define GATT_EXT_PROP_RELIABLE_WRITE 0x0001 //!< Permits reliable writes of the Characteristic Value +#define GATT_EXT_PROP_WRITABLE_AUX 0x0002 //!< Permits writes to the characteristic descriptor + +/** @} End GATT_EXT_PROP_BITMAPS_DEFINES */ + +/** @defgroup GATT_CLIENT_CFG_BITMAPS_DEFINES GATT Client Characteristic Configuration Bit Fields + @{ +*/ + +#define GATT_CLIENT_CFG_NOTIFY 0x0001 //!< The Characteristic Value shall be notified +#define GATT_CLIENT_CFG_INDICATE 0x0002 //!< The Characteristic Value shall be indicated + +/** @} End GATT_CLIENT_CFG_BITMAPS_DEFINES */ + +/** @defgroup GATT_SERV_CFG_BITMAPS_DEFINES GATT Server Characteristic Configuration Bit Fields + @{ +*/ + +#define GATT_SERV_CFG_BCAST 0x0001 //!< The Characteristic Value shall be broadcast when the server is in the broadcast procedure if advertising data resources are available + +/** @} End GATT_SERV_CFG_BITMAPS_DEFINES */ + +#define GATT_CFG_NO_OPERATION 0x0000 // No operation + +/** @defgroup GATT_FORMAT_TYPES_DEFINES GATT Characteristic Format Types + @{ +*/ + +#define GATT_FORMAT_BOOL 0x01 //!< Unsigned 1 bit; 0 = false, 1 = true +#define GATT_FORMAT_2BIT 0x02 //!< Unsigned 2 bit integer +#define GATT_FORMAT_NIBBLE 0x03 //!< Unsigned 4 bit integer +#define GATT_FORMAT_UINT8 0x04 //!< Unsigned 8 bit integer +#define GATT_FORMAT_UINT12 0x05 //!< Unsigned 12 bit integer +#define GATT_FORMAT_UINT16 0x06 //!< Unsigned 16 bit integer +#define GATT_FORMAT_UINT24 0x07 //!< Unsigned 24 bit integer +#define GATT_FORMAT_UINT32 0x08 //!< Unsigned 32 bit integer +#define GATT_FORMAT_UINT48 0x09 //!< Unsigned 48 bit integer +#define GATT_FORMAT_UINT64 0x0a //!< Unsigned 64 bit integer +#define GATT_FORMAT_UINT128 0x0b //!< Unsigned 128 bit integer +#define GATT_FORMAT_SINT8 0x0c //!< Signed 8 bit integer +#define GATT_FORMAT_SINT12 0x0d //!< Signed 12 bit integer +#define GATT_FORMAT_SINT16 0x0e //!< Signed 16 bit integer +#define GATT_FORMAT_SINT24 0x0f //!< Signed 24 bit integer +#define GATT_FORMAT_SINT32 0x10 //!< Signed 32 bit integer +#define GATT_FORMAT_SINT48 0x11 //!< Signed 48 bit integer +#define GATT_FORMAT_SINT64 0x12 //!< Signed 64 bit integer +#define GATT_FORMAT_SINT128 0x13 //!< Signed 128 bit integer +#define GATT_FORMAT_FLOAT32 0x14 //!< IEEE-754 32 bit floating point +#define GATT_FORMAT_FLOAT64 0x15 //!< IEEE-754 64 bit floating point +#define GATT_FORMAT_SFLOAT 0x16 //!< IEEE-11073 16 bit SFLOAT +#define GATT_FORMAT_FLOAT 0x17 //!< IEEE-11073 32 bit FLOAT +#define GATT_FORMAT_DUINT16 0x18 //!< IEEE-20601 format +#define GATT_FORMAT_UTF8S 0x19 //!< UTF-8 string +#define GATT_FORMAT_UTF16S 0x1a //!< UTF-16 string +#define GATT_FORMAT_STRUCT 0x1b //!< Opaque structure + +/** @} End GATT_FORMAT_TYPES_DEFINES */ + +/** @defgroup GATT_NS_TYPES_DEFINES GATT Namespace Types + @{ +*/ + +#define GATT_NS_NONE 0x00 //!< No namespace +#define GATT_NS_BT_SIG 0x01 //!< Bluetooth SIG namespace + +/** @} End GATT_NS_TYPES_DEFINES */ + +/** @defgroup GATT_NS_BT_DESC_DEFINES GATT Bluetooth Namespace Descriptions + @{ +*/ + +#define GATT_NS_BT_DESC_UNKNOWN 0x0000 //!< The description is unknown + +/** @} End GATT_NS_BT_DESC_DEFINES */ + +// All profile services bit fields +#define GATT_ALL_SERVICES 0xFFFFFFFF + +// GATT Services bit fields +#define GATT_SERVICE 0x00000001 + +#if defined ( TESTMODES ) +// GATT Test Modes +#define GATT_TESTMODE_OFF 0 // Test mode off +#define GATT_TESTMODE_NO_RSP 1 // Ignore incoming request +#define GATT_TESTMODE_PREPARE_WRITE 2 // Forward Prepare Write Request right away +#define GATT_TESTMODE_MAX_MTU_SIZE 3 // Use Max ATT MTU size with Exchange MTU Rsp +#define GATT_TESTMODE_CORRUPT_PW_DATA 4 // Corrupt incoming Prepare Write Request data +#endif + +// GATT Server Parameters +#define GATT_PARAM_NUM_PREPARE_WRITES 0 // RW uint8 + +/********************************************************************* + VARIABLES +*/ + +/********************************************************************* + MACROS +*/ + +// The number of attribute records in a given attribute table +#define GATT_NUM_ATTRS( attrs ) ( sizeof( attrs ) / sizeof( gattAttribute_t ) ) + +// The handle of a service is the handle of the first attribute +#define GATT_SERVICE_HANDLE( attrs ) ( (attrs)[0].handle ) + +// The handle of the first included service (i = 1) is the value of the second attribute +#define GATT_INCLUDED_HANDLE( attrs, i ) ( *((uint16 *)((attrs)[(i)].pValue)) ) + +/********************************************************************* + TYPEDEFS +*/ + +/** + @defgroup GATT_SERV_APP_CB_API GATT Server App Callback API Functions + + @{ +*/ + +/** + @brief Callback function prototype to read an attribute value. + + @param connHandle - connection request was received on + @param pAttr - pointer to attribute + @param pValue - pointer to data to be read (to be returned) + @param pLen - length of data (to be returned) + @param offset - offset of the first octet to be read + @param maxLen - maximum length of data to be read + + @return SUCCESS: Read was successfully.
+ Error, otherwise: ref ATT_ERR_CODE_DEFINES.
+*/ +typedef bStatus_t (*pfnGATTReadAttrCB_t)( uint16 connHandle, gattAttribute_t* pAttr, + uint8* pValue, uint16* pLen, uint16 offset, + uint8 maxLen ); +/** + @brief Callback function prototype to write an attribute value. + + @param connHandle - connection request was received on + @param pAttr - pointer to attribute + @param pValue - pointer to data to be written + @param pLen - length of data + @param offset - offset of the first octet to be written + + @return SUCCESS: Write was successfully.
+ Error, otherwise: ref ATT_ERR_CODE_DEFINES.
+*/ +typedef bStatus_t (*pfnGATTWriteAttrCB_t)( uint16 connHandle, gattAttribute_t* pAttr, + uint8* pValue, uint16 len, uint16 offset ); +/** + @brief Callback function prototype to authorize a Read or Write operation + on a given attribute. + + @param connHandle - connection request was received on + @param pAttr - pointer to attribute + @param opcode - request opcode (ATT_READ_REQ or ATT_WRITE_REQ) + + @return SUCCESS: Operation authorized.
+ ATT_ERR_INSUFFICIENT_AUTHOR: Authorization required.
+*/ +typedef bStatus_t (*pfnGATTAuthorizeAttrCB_t)( uint16 connHandle, gattAttribute_t* pAttr, + uint8 opcode ); +/** + @} +*/ + +/** + GATT Structure for Characteristic Presentation Format Value. +*/ +typedef struct +{ + uint8 format; //!< Format of the value of this characteristic + int8 exponent; //!< A sign integer which represents the exponent of an integer + uint16 unit; //!< Unit of this attribute as defined in the data dictionary + uint8 nameSpace; //!< Name space of the description + uint16 desc; //!< Description of this attribute as defined in a higher layer profile +} gattCharFormat_t; + +/** + GATT Structure for Client Characteristic Configuration. +*/ +typedef struct +{ + uint16 connHandle; //!< Client connection handle + uint8 value; //!< Characteristic configuration value for this client +} gattCharCfg_t; + +/** + GATT Structure for service callback functions - must be setup by the application + and used when GATTServApp_RegisterService() is called. +*/ +typedef struct +{ + pfnGATTReadAttrCB_t pfnReadAttrCB; //!< Read callback function pointer + pfnGATTWriteAttrCB_t pfnWriteAttrCB; //!< Write callback function pointer + pfnGATTAuthorizeAttrCB_t pfnAuthorizeAttrCB; //!< Authorization callback function pointer +} gattServiceCBs_t; + +/** + GATT Server App event header format. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< GATT_SERV_MSG_EVENT and status + uint16 connHandle; //!< Connection message was received on + uint8 method; //!< GATT type of command. Ref: @ref GATT_SERV_MSG_EVENT_DEFINES +} gattEventHdr_t; + +/** + GATT_CLIENT_CHAR_CFG_UPDATED_EVENT message format. This message is sent to + the app when a Client Characteristic Configuration is updated. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< GATT_SERV_MSG_EVENT and status + uint16 connHandle; //!< Connection message was received on + uint8 method; //!< GATT_CLIENT_CHAR_CFG_UPDATED_EVENT + uint16 attrHandle; //!< attribute handle + uint16 value; //!< attribute new value +} gattClientCharCfgUpdatedEvent_t; + + + +typedef void (*gattServMsgCB_t)( gattMsgEvent_t* pMsg); + +/********************************************************************* + VARIABLES +*/ + +/********************************************************************* + API FUNCTIONS +*/ + +/** + @defgroup GATT_SERV_APP_API GATT Server App API Functions + + @{ +*/ + +/** + @brief Register your task ID to receive event messages + from the GATT Server Application. + + @param taskID - Default task ID to send events. + + @return none +*/ +extern void GATTServApp_RegisterForMsg( uint8 taskID ); + +/** + @brief Register a service's attribute list and callback functions with + the GATT Server Application. + + @param pAttrs - Array of attribute records to be registered + @param numAttrs - Number of attributes in array + @param pServiceCBs - Service callback function pointers + + @return SUCCESS: Service registered successfully.
+ INVALIDPARAMETER: Invalid service field.
+ FAILURE: Not enough attribute handles available.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t GATTServApp_RegisterService( gattAttribute_t* pAttrs, uint16 numAttrs, + CONST gattServiceCBs_t* pServiceCBs ); +/** + @brief Deregister a service's attribute list and callback functions from + the GATT Server Application. + + NOTE: It's the caller's responsibility to free the service attribute + list returned from this API. + + @param handle - handle of service to be deregistered + @param p2pAttrs - pointer to array of attribute records (to be returned) + + @return SUCCESS: Service deregistered successfully. + FAILURE: Service not found. +*/ +bStatus_t GATTServApp_DeregisterService( uint16 handle, gattAttribute_t** p2pAttrs ); + +/** + @brief Find the attribute record within a service attribute + table for a given attribute value pointer. + + @param pAttrTbl - pointer to attribute table + @param numAttrs - number of attributes in attribute table + @param pValue - pointer to attribute value + + @return Pointer to attribute record. NULL, if not found. +*/ +extern gattAttribute_t* GATTServApp_FindAttr( gattAttribute_t* pAttrTbl, + uint16 numAttrs, uint8* pValue ); +/** + @brief Add function for the GATT Service. + + @param services - services to add. This is a bit map and can + contain more than one service. + + @return SUCCESS: Service added successfully.
+ INVALIDPARAMETER: Invalid service field.
+ FAILURE: Not enough attribute handles available.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t GATTServApp_AddService( uint32 services ); + +/** + @brief Delete function for the GATT Service. + + @param services - services to delete. This is a bit map and can + contain more than one service. + + @return SUCCESS: Service deleted successfully.
+ FAILURE: Service not found.
+*/ +extern bStatus_t GATTServApp_DelService( uint32 services ); + +/** + @brief Set a GATT Server parameter. + + @param param - Profile parameter ID + @param len - length of data to right + @param pValue - 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 will be cast + to uint16 pointer). + + @return SUCCESS: Parameter set successful + FAILURE: Parameter in use + INVALIDPARAMETER: Invalid parameter + bleInvalidRange: Invalid value + bleMemAllocError: Memory allocation failed +*/ +extern bStatus_t GATTServApp_SetParameter( uint8 param, uint8 len, void* pValue ); + +/** + @brief Get a GATT Server parameter. + + @param param - Profile parameter ID + @param pValue - 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 will be + cast to uint16 pointer). + + @return SUCCESS: Parameter get successful + INVALIDPARAMETER: Invalid parameter +*/ +extern bStatus_t GATTServApp_GetParameter( uint8 param, void* pValue ); + +/** + @brief Update the Client Characteristic Configuration for a given + Client. + + Note: This API should only be called from the Bond Manager. + + @param connHandle - connection handle. + @param attrHandle - attribute handle. + @param value - characteristic configuration value. + + @return SUCCESS: Parameter get successful + INVALIDPARAMETER: Invalid parameter +*/ +extern bStatus_t GATTServApp_UpdateCharCfg( uint16 connHandle, uint16 attrHandle, uint16 value ); + +/** + @brief Initialize the client characteristic configuration table. + + Note: Each client has its own instantiation of the Client + Characteristic Configuration. Reads/Writes of the Client + Characteristic Configuration only only affect the + configuration of that client. + + @param connHandle - connection handle (0xFFFF for all connections). + @param charCfgTbl - client characteristic configuration table. + + @return none +*/ +extern void GATTServApp_InitCharCfg( uint16 connHandle, gattCharCfg_t* charCfgTbl ); + +/** + @brief Read the client characteristic configuration for a given + client. + + Note: Each client has its own instantiation of the Client + Characteristic Configuration. Reads of the Client + Characteristic Configuration only shows the configuration + for that client. + + @param connHandle - connection handle. + @param charCfgTbl - client characteristic configuration table. + + @return attribute value +*/ +extern uint16 GATTServApp_ReadCharCfg( uint16 connHandle, gattCharCfg_t* charCfgTbl ); + +/** + @brief Write the client characteristic configuration for a given + client. + + Note: Each client has its own instantiation of the Client + Characteristic Configuration. Writes of the Client + Characteristic Configuration only only affect the + configuration of that client. + + @param connHandle - connection handle. + @param charCfgTbl - client characteristic configuration table. + @param value - attribute new value. + + @return Success or Failure +*/ +extern uint8 GATTServApp_WriteCharCfg( uint16 connHandle, gattCharCfg_t* charCfgTbl, uint16 value ); + +/** + @brief Process the client characteristic configuration + write request for a given client. + + @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. + @param validCfg - valid configuration. + + @return Success or Failure +*/ +extern bStatus_t GATTServApp_ProcessCCCWriteReq( uint16 connHandle, gattAttribute_t* pAttr, + uint8* pValue, uint8 len, uint16 offset, + uint16 validCfg ); + +/** + @brief Process Client Charateristic Configuration change. + + @param charCfgTbl - characteristic configuration table. + @param pValue - pointer to attribute value. + @param authenticated - whether an authenticated link is required. + @param attrTbl - attribute table. + @param numAttrs - number of attributes in attribute table. + @param taskId - task to be notified of confirmation. + + @return Success or Failure +*/ +extern bStatus_t GATTServApp_ProcessCharCfg( gattCharCfg_t* charCfgTbl, uint8* pValue, + uint8 authenticated, gattAttribute_t* attrTbl, + uint16 numAttrs, uint8 taskId ); + +/** + @brief Build and send the GATT_CLIENT_CHAR_CFG_UPDATED_EVENT to + the application. + + @param connHandle - connection handle + @param attrHandle - attribute handle + @param value - attribute new value + + @return none +*/ +extern void GATTServApp_SendCCCUpdatedEvent( uint16 connHandle, uint16 attrHandle, uint16 value ); + +/** + @brief Send out a Service Changed Indication. + + @param connHandle - connection to use + @param taskId - task to be notified of confirmation + + @return SUCCESS: Indication was sent successfully.
+ FAILURE: Service Changed attribute not found.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A confirmation is pending with this client.
+*/ +extern bStatus_t GATTServApp_SendServiceChangedInd( uint16 connHandle, uint8 taskId ); + +/** + @brief Read an attribute. If the format of the attribute value + is unknown to GATT Server, use the callback function + provided by the Service. + + @param connHandle - connection message was received on + @param pAttr - pointer to attribute + @param service - handle of owner service + @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 +*/ +extern uint8 GATTServApp_ReadAttr( uint16 connHandle, gattAttribute_t* pAttr, + uint16 service, uint8* pValue, uint16* pLen, + uint16 offset, uint8 maxLen ); + +/** + @brief Write attribute data + + @param connHandle - connection message was received on + @param handle - attribute handle + @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 +*/ +extern uint8 GATTServApp_WriteAttr( uint16 connHandle, uint16 handle, + uint8* pValue, uint16 len, uint16 offset ); + +/** + @} +*/ + +/** + @brief Set a GATT Server Application Parameter value. Use this + function to change the default GATT parameter values. + + @param value - new param value + + @return void +*/ +extern void GATTServApp_SetParamValue( uint16 value ); + +/** + @brief Get a GATT Server Application Parameter value. + + @param none + + @return GATT Parameter value +*/ +extern uint16 GATTServApp_GetParamValue( void ); + +/* ------------------------------------------------------------------- + TASK API - These functions must only be called by OSAL. +*/ + +/** + @internal + + @brief Initialize the GATT Server Test Application. + + @param taskId - Task identifier for the desired task + + @return void + +*/ +extern void GATTServApp_Init( uint8 taskId ); + +/** + @internal + + @brief GATT Server 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 OSAL assigned task ID. + @param events - events to process. This is a bit map and can + contain more than one event. + + @return none +*/ +extern uint16 GATTServApp_ProcessEvent( uint8 taskId, uint16 events ); + +bStatus_t gattServApp_RegisterCB(gattServMsgCB_t cb); + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* GATTSERVAPP_H */ diff --git a/arch/arm/src/phy62xx/ble/host/gatttest.h b/arch/arm/src/phy62xx/ble/host/gatttest.h new file mode 100644 index 00000000000..f9bdaf4892a --- /dev/null +++ b/arch/arm/src/phy62xx/ble/host/gatttest.h @@ -0,0 +1,180 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/************************************************************************************************** +**************************************************************************************************/ + +#ifndef GATTTEST_H +#define GATTTEST_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ +#include "bcomdef.h" +#include "OSAL.h" + +/********************************************************************* + CONSTANTS +*/ +// Length of attribute +#define GATT_TEST_ATTR_LEN 20 + +// Length of long attribute +#define GATT_TEST_LONG_ATTR_LEN 50 + +// GATT Test Services bit fields +#define GATT_TEST_SERVICE 0x00000001 // GATT Test +#define GATT_BATT_STATE_SERVICE 0x00000002 // Battery State +#define GATT_THERMO_HUMID_SERVICE 0x00000004 // Thermometer Humidity +#define GATT_WEIGHT_SERVICE 0x00000008 // Weight +#define GATT_POSITION_SERVICE 0x00000010 // Position +#define GATT_ALERT_SERVICE 0x00000020 // Alert +#define GATT_MANUFACT_SENSOR_SERVICE 0x00000040 // Sensor Manufacturer +#define GATT_MANUFACT_SCALES_SERVICE 0x00000080 // Scales Manufacturer +#define GATT_ADDRESS_SERVICE 0x00000100 // Address +#define GATT_128BIT_UUID1_SERVICE 0x00000200 // 128-bit UUID 1 +#define GATT_128BIT_UUID2_SERVICE 0x00000400 // 128-bit UUID 2 +#define GATT_128BIT_UUID3_SERVICE 0x00000800 // 128-bit UUID 3 + +/********************************************************************* + VARIABLES +*/ + +/********************************************************************* + MACROS +*/ + +/********************************************************************* + TYPEDEFS +*/ + +/********************************************************************* + VARIABLES +*/ + +/********************************************************************* + FUNCTIONS +*/ + +/** + @brief Add function for the GATT Test Services. + + @param services - services to add. This is a bit map and can + contain more than one service. + + @return SUCCESS: Service added successfully. + INVALIDPARAMETER: Invalid service field. + FAILURE: Not enough attribute handles available. + bleMemAllocError: Memory allocation error occurred. +*/ +extern bStatus_t GATTTest_AddService( uint32 services ); + +/** + @brief Delete function for the GATT Test Services. + + @param services - services to delete. This is a bit map and can + contain more than one service. + + @return SUCCESS: Service deleted successfully. + FAILURE: Service not found. +*/ +extern bStatus_t GATTTest_DelService( uint32 services ); + +/* ------------------------------------------------------------------- + TASK API - These functions must only be called by OSAL. +*/ + +/** + @internal + + @brief Initialize the GATT Test Application. + + @param taskId - Task identifier for the desired task + + @return void + +*/ +extern void GATTTest_Init( uint8 taskId ); + +/** + @internal + + @brief GATT Test 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 OSAL assigned task ID. + @param events - events to process. This is a bit map and can + contain more than one event. + + @return none +*/ +extern uint16 GATTTest_ProcessEvent( uint8 task_id, uint16 events ); + +/** + @brief Add function for the GATT Qualification Services. + + @param services - services to add. This is a bit map and can + contain more than one service. + + @return SUCCESS: Service added successfully. + INVALIDPARAMETER: Invalid service field. + FAILURE: Not enough attribute handles available. + bleMemAllocError: Memory allocation error occurred. +*/ +extern bStatus_t GATTQual_AddService( uint32 services ); + +/** + @brief Delete function for the GATT Qualification Services. + + @param services - services to delete. This is a bit map and can + contain more than one service. + + @return SUCCESS: Service deleted successfully. + FAILURE: Service not found. +*/ +extern bStatus_t GATTQual_DelService( uint32 services ); + + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* GATTTEST_H */ diff --git a/arch/arm/src/phy62xx/ble/host/l2cap_internal.h b/arch/arm/src/phy62xx/ble/host/l2cap_internal.h new file mode 100644 index 00000000000..a134b776b32 --- /dev/null +++ b/arch/arm/src/phy62xx/ble/host/l2cap_internal.h @@ -0,0 +1,304 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/************************************************************************************************** +**************************************************************************************************/ + +#ifndef L2CAP_INTERNAL_H +#define L2CAP_INTERNAL_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ +#include "hci.h" +#include "l2cap.h" + +/********************************************************************* + MACROS +*/ + +// Macro to see if a given channel is a fixed channel +#define FIX_CHANNEL( CID ) ( (CID) == L2CAP_CID_GENERIC ||\ + (CID) == L2CAP_CID_SIG ||\ + (CID) == L2CAP_CID_ATT ||\ + (CID) == L2CAP_CID_SMP ) + +// Marco to convert a channel ID to an index into L2CAP Channel table +#define CID_TO_INDEX( CID ) ( (CID) - BASE_DYNAMIC_CID ) + +// Marco to convert a fixed channel ID to an index into L2CAP Fixed Channel table +#define FCID_TO_INDEX( CID ) ( (CID) - L2CAP_CID_ATT ) + +// Macro to return the record maintained a given fix channel +#define FIX_CHANNEL_REC( CID ) ( l2capFixedChannels[FCID_TO_INDEX( CID )] ) + +/********************************************************************* + CONSTANTS +*/ +// Signaling command header: Code (1 byte) + Identifier (1 byte) + Length (2 bytes) +#define SIGNAL_HDR_SIZE 4 + +// Maximum size of data field of Signaling commands +#define SIGNAL_DATA_SIZE ( L2CAP_SIG_MTU_SIZE - SIGNAL_HDR_SIZE ) + +/********************************************************************* + L2CAP Channel States: states used for l2capChannel 'state' field +*/ +// Closed - no channel associated with this CID +#define L2CAP_CLOSED 0x00 + +// Waiting for Echo Response +#define L2CAP_W4_ECHO_RSP 0x01 + +// Waiting for Info Response +#define L2CAP_W4_INFO_RSP 0x02 + +// Waiting for Connection Parameter Update Response +#define L2CAP_W4_PARAM_UPDATE_RSP 0x03 + +/********************************************************************* + TYPEDEFS +*/ + +// L2CAP Channel structure. Allocated one per application connection +// between two devices. CID assignment is relative to a particular device +// and a device can assign CIDs independently from other devices (except +// for the reserved CIDs). The CIDs are dynamically allocated in the range +// from 0x0040 to 0xFFFF. +typedef struct +{ + // Channel info + uint8 state; // Channel connection state + uint16 CID; // Local channel id + uint8 id; // Local identifier - matches responses with requests + + // Link info + uint16 connHandle; // link connection handle + + // Application info + uint8 taskId; // task that channel belongs to + + // Timer id + uint8 timerId; +} l2capChannel_t; + +// L2CAP Fixed Channel structure. Allocated one for each fixed channel. +typedef struct +{ + uint16 CID; // channel id + uint8 taskId; // task registered with channel +} l2capFixedChannel_t; + +// Signaling packet header format +typedef struct +{ + uint8 opcode; // type of command + uint8 id; // identifier - matches responses with requests + uint16 len; // length of data field (doesn't cover Code, Identifier and Length fields) +} l2capSignalHdr_t; + +/** + @brief Callback function prototype for building a Signaling command. + + @param pBuf - pointer to buffer to hold command data + @param pData - pointer to command data + + @return length of the command data +*/ +typedef uint16 (*pfnL2CAPBuildCmd_t)( uint8* pBuf, uint8* pData ); + +/********************************************************************* + GLOBAL VARIABLES +*/ +extern uint8 l2capTaskID; +extern l2capChannel_t l2capChannels[]; +extern l2capFixedChannel_t l2capFixedChannels[]; + +/********************************************************************* + FUNCTIONS - API +*/ + +/* + Send L2CAP Command. +*/ +extern bStatus_t l2capSendCmd( uint16 connHandle, uint8 opcode, uint8 id, + uint8* pCmd, pfnL2CAPBuildCmd_t pfnBuildCmd ); +/* + Send L2CAP Request. +*/ +extern bStatus_t l2capSendReq( uint16 connHandle, uint8 opcode, uint8* pReq, + pfnL2CAPBuildCmd_t pfnBuildCmd, uint8 state, uint8 taskId ); +/* + Build Echo Request. +*/ +extern uint16 l2capBuildEchoReq( uint8* pBuf, uint8* pCmd ); + +/* + Build Info Request. +*/ +extern uint16 l2capBuildInfoReq( uint8* pBuf, uint8* pCmd ); + +/* + Build Parameter Update Request. +*/ +extern uint16 l2capBuildParamUpdateReq( uint8* pBuf, uint8* pData ); + +/* + Encapsulate and send L2CAP packet. +*/ +extern bStatus_t l2capEncapSendData( uint16 connHandle, l2capPacket_t* pPkt ); + +/* + Parse L2CAP packet. +*/ +extern uint8 l2capParsePacket( l2capPacket_t* pPkt, hciDataEvent_t* pHciMsg ); + +/* + Parse L2CAP Signaling header. +*/ +extern void l2capParseSignalHdr( l2capSignalHdr_t* pHdr, uint8* pData ); + +/* + Build Echo Response. +*/ +extern uint16 l2capBuildEchoRsp( uint8* pBuf, uint8* pCmd ); + +/* + Parse Command Reject. +*/ +extern bStatus_t l2capParseCmdReject( l2capSignalCmd_t* pCmd, uint8* pData, uint16 len ); + +/* + Parse Echo Response. +*/ +extern bStatus_t l2capParseEchoRsp( l2capSignalCmd_t* pCmd, uint8* pData, uint16 len ); + +/* + Parse Information Response. +*/ +extern bStatus_t l2capParseInfoRsp( l2capSignalCmd_t* pCmd, uint8* pData, uint16 len ); + +/* + Parse Connection Parameter Update Response. +*/ +extern bStatus_t l2capParseParamUpdateRsp( l2capSignalCmd_t* pCmd, uint8* pData, uint16 len ); + +/* + Find a channel using the local identifier. +*/ +extern l2capChannel_t* l2capFindLocalId( uint8 id ); + +/* + Free a channel. +*/ +extern void l2capFreeChannel( l2capChannel_t* pChannel ); + +/* + Stop an active timer for a given channel. +*/ +extern void l2capStopTimer( l2capChannel_t* pChannel ); + +/* + Handle an incoming packet error. +*/ +extern void l2capHandleRxError( uint16 connHandle ); + +/* + Forward a data message to upper layer application. +*/ +extern bStatus_t l2capNotifyData( uint8 taskId, uint16 connHandle, l2capPacket_t* pPkt ); + +/* + Send a Signaling command to upper layer application. +*/ +extern void l2capNotifySignal( uint8 taskId, uint16 connHandle, uint8 status, + uint8 opcode, uint8 id, l2capSignalCmd_t* pCmd ); + +extern void* L2CAP_Fragment_bm_alloc( uint16 size ); + +extern uint8 L2CAP_Fragment_SendDataPkt( uint16 connHandle, uint8 fragFlg,uint16 pktLen, uint8* pBuf ); + + +/********************************************************************* + @fn l2capInfoRsp + + @brief Send Info Response. + + Use like: l2capInfoRsp( uint16 connHandle, uint8 id, l2capInfoRsp_t *pInfoRsp ); + + @param connHandle - connection to use + @param id - identifier received in request + @param pInfoRsp - pointer to Info Response to be sent + + @return SUCCESS: Request was sent successfully. + INVALIDPARAMETER: Data can not fit into one packet. + MSG_BUFFER_NOT_AVAIL: No HCI buffer is available. + bleNotConnected: Connection is down. + bleMemAllocError: Memory allocation error occurred. +*/ +#define l2capInfoRsp( connHandle, id, pInfoRsp ) l2capSendCmd( (connHandle), L2CAP_INFO_RSP, (id),\ + (uint8 *)(pInfoRsp), L2CAP_BuildInfoRsp ) + +/********************************************************************* + @fn l2capEchoRsp + + @brief Send Ehco Response. + + Use like: l2capEchoRsp( uint16 connHandle, uint8 id, l2capEchoRsp_t *pEchoRsp ); + + @param connHandle - connection to use + @param id - identifier received in request + @param pEchoRsp - pinter to Echo Response to be sent + + @return SUCCESS: Request was sent successfully. + INVALIDPARAMETER: Data can not fit into one packet. + MSG_BUFFER_NOT_AVAIL: No HCI buffer is available. + bleNotConnected: Connection is down. + bleMemAllocError: Memory allocation error occurred. +*/ +#define l2capEchoRsp( connHandle, id, pEchoRsp ) l2capSendCmd( (connHandle), L2CAP_ECHO_RSP, (id),\ + (uint8 *)(pEchoRsp), l2capBuildEchoRsp ) + + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* L2CAP_INTERNAL_H */ diff --git a/arch/arm/src/phy62xx/ble/host/linkdb.h b/arch/arm/src/phy62xx/ble/host/linkdb.h new file mode 100644 index 00000000000..0d8f252719f --- /dev/null +++ b/arch/arm/src/phy62xx/ble/host/linkdb.h @@ -0,0 +1,236 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/************************************************************************************************** + Filename: linkdb.h + Revised: + Revision: + + Description: This file contains the linkDB interface. + + +**************************************************************************************************/ + +#ifndef LINKDB_H +#define LINKDB_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ + +/********************************************************************* + MACROS +*/ + +/********************************************************************* + CONSTANTS +*/ + +// Special case connection handles +#define INVALID_CONNHANDLE 0xFFFF // Invalid connection handle, used for no connection handle +#define LOOPBACK_CONNHANDLE 0xFFFE // Loopback connection handle, used to loopback a message + +// Link state flags +#define LINK_NOT_CONNECTED 0x00 // Link isn't connected +#define LINK_CONNECTED 0x01 // Link is connected +#define LINK_AUTHENTICATED 0x02 // Link is authenticated +#define LINK_BOUND 0x04 // Link is bonded +#define LINK_ENCRYPTED 0x10 // Link is encrypted + +// Link Database Status callback changeTypes +#define LINKDB_STATUS_UPDATE_NEW 0 // New connection created +#define LINKDB_STATUS_UPDATE_REMOVED 1 // Connection was removed +#define LINKDB_STATUS_UPDATE_STATEFLAGS 2 // Connection state flag changed + +// Link Authentication Errors +#define LINKDB_ERR_INSUFFICIENT_AUTHEN 0x05 // Link isn't even encrypted +#define LINBDB_ERR_INSUFFICIENT_KEYSIZE 0x0c // Link is encrypted but the key size is too small +#define LINKDB_ERR_INSUFFICIENT_ENCRYPTION 0x0f // Link is encrypted but it's not authenticated + +/********************************************************************* + TYPEDEFS +*/ + +typedef struct +{ + uint8 srk[KEYLEN]; // Signature Resolving Key + uint32 signCounter; // Sign Counter +} linkSec_t; + +typedef struct +{ + uint8 ltk[KEYLEN]; // Long Term Key + uint16 div; // Diversifier + uint8 rand[B_RANDOM_NUM_SIZE]; // random number + uint8 keySize; // LTK Key Size +} encParams_t; + +typedef struct +{ + uint8 taskID; // Application that controls the link + uint16 connectionHandle; // Controller connection handle + uint8 stateFlags; // LINK_CONNECTED, LINK_AUTHENTICATED... + uint8 role; // 2020-04-22 add (case for multi-role SMP ) + uint8 addrType; // Address type of connected device + uint8 addr[B_ADDR_LEN]; // Other Device's address + uint16 connInterval; // The connection's interval (n * 1.23 ms) + linkSec_t sec; // Connection Security related items + encParams_t* pEncParams; // pointer to LTK, ediv, rand. if needed. +} linkDBItem_t; + +// function pointer used to register for a status callback +typedef void (*pfnLinkDBCB_t)( uint16 connectionHandle, uint8 changeType ); + +// function pointer used to perform specialized link database searches +typedef void (*pfnPerformFuncCB_t)( linkDBItem_t* pLinkItem ); + +/********************************************************************* + GLOBAL VARIABLES +*/ + +/********************************************************************* + PUBLIC FUNCTIONS +*/ +/* + linkDB_Init - Initialize the Link Database. +*/ +extern void linkDB_Init( void ); + +/* + linkDB_Register - Register with this function to receive a callback when + status changes on a connection. +*/ +extern uint8 linkDB_Register( pfnLinkDBCB_t pFunc ); + +/* + linkDB_Add - Adds a record to the link database. +*/ +extern uint8 linkDB_Add( uint8 taskID, uint16 connectionHandle, uint8 stateFlags, uint8 role, + uint8 addrType, uint8* pAddr, uint16 connInterval ); + +/* + linkDB_Remove - Removes a record from the link database. +*/ +extern uint8 linkDB_Remove( uint16 connectionHandle ); + +/* + linkDB_Update - This function is used to update the stateFlags of + a link record. +*/ +extern uint8 linkDB_Update( uint16 connectionHandle, uint8 newState ); + +/* + linkDB_NumActive - returns the number of active connections. +*/ +extern uint8 linkDB_NumActive( void ); + +/* + linkDB_Find - Find link database item (link information) + + returns a pointer to the link item, NULL if not found +*/ +extern linkDBItem_t* linkDB_Find( uint16 connectionHandle ); + +/* + linkDB_FindFirst - Find the first link that matches the taskID. + + returns a pointer to the link item, NULL if not found +*/ +extern linkDBItem_t* linkDB_FindFirst( uint8 taskID ); + +/* + linkDB_State - Check to see if a physical link is in a specific state. + + returns TRUE is the link is in state. FALSE, otherwise. +*/ +extern uint8 linkDB_State( uint16 connectionHandle, uint8 state ); + +/* + linkDB_Authen - Check to see if the physical link is encrypted and authenticated. + returns SUCCESS if the link is authenticated or + bleNotConnected - connection handle is invalid, + LINKDB_ERR_INSUFFICIENT_AUTHEN - link is not encrypted, + LINBDB_ERR_INSUFFICIENT_KEYSIZE - key size encrypted is not large enough, + LINKDB_ERR_INSUFFICIENT_ENCRYPTION - link is encrypted, but not authenticated +*/ +extern uint8 linkDB_Authen( uint16 connectionHandle, uint8 keySize, uint8 mitmRequired ); + +/* + linkDB_PerformFunc - Perform a function of each connection in the link database. +*/ +extern void linkDB_PerformFunc( pfnPerformFuncCB_t cb ); + +/* + linkDB_Up - Check to see if a physical link is up (connected). + Use like: uint8 linkDB_Up( uint16 connectionHandle ); + connectionHandle - controller link connection handle. + returns TRUE if the link is up. FALSE, otherwise. +*/ +#define linkDB_Up( connectionHandle ) linkDB_State( (connectionHandle), LINK_CONNECTED ) + +/* + linkDB_Encrypted - Check to see if the physical link is encrypted. + Use like: linkDB_Encrypted( uint16 connectionHandle ); + connectionHandle - controller link connection handle. + returns TRUE if the link is encrypted. FALSE, otherwise. +*/ +#define linkDB_Encrypted( connectionHandle ) linkDB_State( (connectionHandle), LINK_ENCRYPTED ) + +/* + linkDB_Authenticated - Check to see if the physical link is authenticated. + Use like: linkDB_Authenticated( uint16 connectionHandle ); + connectionHandle - controller link connection handle. + returns TRUE if the link is authenticated. FALSE, otherwise. +*/ +#define linkDB_Authenticated( connectionHandle ) linkDB_State( (connectionHandle), LINK_AUTHENTICATED ) + +/* + linkDB_Bonded - Check to see if the physical link is bonded. + Use like: linkDB_Bonded( uint16 connectionHandle ); + connectionHandle - controller link connection handle. + returns TRUE if the link is bonded. FALSE, otherwise. +*/ +#define linkDB_Bonded( connectionHandle ) linkDB_State( (connectionHandle), LINK_BOUND ) + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* LINKDB_H */ diff --git a/arch/arm/src/phy62xx/ble/host/sm_internal.h b/arch/arm/src/phy62xx/ble/host/sm_internal.h new file mode 100644 index 00000000000..07a5fc26d34 --- /dev/null +++ b/arch/arm/src/phy62xx/ble/host/sm_internal.h @@ -0,0 +1,392 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/************************************************************************************************** +**************************************************************************************************/ + +#ifndef SM_INTERNAL_H +#define SM_INTERNAL_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ +#include "bcomdef.h" +#include "l2cap.h" +#include "smp.h" +#include "linkdb.h" + +/********************************************************************* + MACROS +*/ + +/********************************************************************* + CONSTANTS +*/ + +// Security Manager Task Events +#define SM_TIMEOUT_EVT 0x0001 // Message timeout event +#define SM_PAIRING_STATE_EVT 0x0002 // Event used to progress to the next pairing state + +// Pairing states +#define SM_PAIRING_STATE_INITIALIZE 0 // Pairing has started +#define SM_PAIRING_STATE_PAIRING_REQ_SENT 1 // Initiator: Pairing Request has been sent, Responder: waiting for Pairing Request. +#define SM_PAIRING_STATE_WAIT_CONFIRM 2 // Waiting for Confirm message +#define SM_PAIRING_STATE_WAIT_PASSKEY 3 // Waiting for Passkey from app/profile +#define SM_PAIRING_STATE_WAIT_CONFIRM_PASSKEY 4 // Received Initiator Confirm message and waiting for Passkey from app/profile (responder only) +#define SM_PAIRING_STATE_WAIT_RANDOM 5 // Waiting for Random message +#define SM_PAIRING_STATE_WAIT_STK 6 // Waiting for STK process to finish +#define SM_PAIRING_STATE_WAIT_SLAVE_ENCRYPTION_INFO 7 // Waiting for Slave Encryption Info to be sent +#define SM_PAIRING_STATE_WAIT_SLAVE_MASTER_INFO 8 // Waiting for Slave Master Info to be sent +#define SM_PAIRING_STATE_WAIT_SLAVE_IDENTITY_INFO 9 // Waiting for Slave Identity Info to be sent +#define SM_PAIRING_STATE_WAIT_SLAVE_IDENTITY_ADDR_INFO 10 // Waiting for Slave Identity Addr Info to be sent +#define SM_PAIRING_STATE_WAIT_SLAVE_SIGNING_INFO 11 // Waiting for Slave Signing Info to be sent +#define SM_PAIRING_STATE_WAIT_MASTER_ENCRYPTION_INFO 12 // Waiting for Master Encryption Info to be sent +#define SM_PAIRING_STATE_WAIT_MASTER_MASTER_INFO 13 // Waiting for Master Master Info to be sent +#define SM_PAIRING_STATE_WAIT_MASTER_IDENTITY_INFO 14 // Waiting for Master Identity Info to be sent +#define SM_PAIRING_STATE_WAIT_MASTER_IDENTITY_ADDR_INFO 15 // Waiting for Master Identity Addr Info to be sent +#define SM_PAIRING_STATE_WAIT_MASTER_SIGNING_INFO 16 // Waiting for Master Signing Info to be sent +#define SM_PAIRING_STATE_WAIT_ENCRYPT 17 // Waiting for LTK process to finish +#define SM_PAIRING_STATE_DONE 18 // Closing out the pairing process + +#if defined ( TESTMODES ) +// SM TestModes +#define SM_TESTMODE_OFF 0 // No Test mode +#define SM_TESTMODE_NO_RESPONSE 1 // Don't respond to any SM message +#define SM_TESTMODE_SEND_BAD_CONFIRM 2 // Force a bad confirm value in the Confirm Message +#define SM_TESTMODE_BAD_CONFIRM_VERIFY 3 // Force a bad confirm check of the received Confirm Message +#define SM_TESTMODE_SEND_CONFIRM 4 // Force a SMP Confirm message +#endif // TESTMODES + +// Pairing Types +#define SM_PAIRING_TYPE_INIT 0 // Pairing has been started but the type hasn't been determined yet +#define SM_PAIRING_TYPE_JUST_WORKS 1 // Pairing is Just Works +#define SM_PAIRING_TYPE_PASSKEY_INITIATOR_INPUTS 2 // Pairing is MITM Passkey with initiator inputs passkey +#define SM_PAIRING_TYPE_PASSKEY_RESPONDER_INPUTS 3 // Pairing is MITM Passkey with responder inputs passkey +#define SM_PAIRING_TYPE_PASSKEY_BOTH_INPUTS 4 // Pairing is MITM Passkey with both initiator and responder input passkey +#define SM_PAIRING_TYPE_OOB 5 // Pairing is MITM OOB + +#define SM_PAIRING_STATE_WAIT 500 // The default wait time between key distribution messages. + +/********************************************************************* + TYPEDEFS +*/ + +typedef struct +{ + uint8 confirm[KEYLEN]; // calculated confirm value + uint8 rand[SMP_RANDOM_LEN]; // First MRand or Srand, then RAND +} devPairing_t; + +typedef struct +{ + // From the start + uint8 initiator; // TRUE if initiator + uint8 state; // Pairing state + uint8 taskID; // Task ID of the app/profile that requested the pairing + + uint8 timerID; // 2021-03-29 add , timerid for simultaneously SMP for multi-role(the same as single connection ) + uint8 stateID; // 2021-03-29 add , stateid for simultaneously SMP pairing state change idx + uint16 connectionHandle; // Connection Handle from controller, + smLinkSecurityReq_t* pSecReqs; // Pairing Control info + uint8 tk[KEYLEN]; // Holds tk from app + uint8 authState; // uses SM_AUTH_STATE_AUTHENTICATED & SM_AUTH_STATE_BONDING + + // During pairing + smpPairingReq_t* pPairDev; // Info of paired device. + uint8 type; // ie. SM_PAIRING_TYPE_JUST_WORKS + + // device information + devPairing_t myComp; // This device's pairing components + devPairing_t devComp; // The other device's components + + // Encrypt Params + smSecurityInfo_t* pEncParams; // Your (device's) encryption parameters + smSecurityInfo_t* pDevEncParams; // Connected device's encryption parameters + smIdentityInfo_t* pIdInfo; // Connected device's identity parameters + smSigningInfo_t* pSigningInfo; // Connected device's signing parameters + +} smPairingParams_t; + +// Callback when an SMP message has been received on the Initiator or Responder. +typedef uint8 (*smProcessMsg_t)( linkDBItem_t* pLinkItem, uint8 cmdID, smpMsgs_t* pParsedMsg ); + +// Callback to send next key message, and sets state for next event on the Initiator or Responder. +typedef void (*smSendNextKeyInfo_t)( uint16 connectionHandle ); + +// Callback to send Start Encrypt through HCI on the Initiator. +typedef bStatus_t (*smStartEncryption_t)( uint16 connHandle, uint8* pLTK, uint16 div, + uint8* pRandNum, uint8 keyLen ); + +// Callback when an HCI BLE LTK Request has been received on the Responder. +typedef uint8 (*smProcessLTKReq_t)( uint16 connectionHandle, uint8* pRandom, uint16 encDiv ); + +// Initiator callback structure - must be setup by the Initiator. +typedef struct +{ + smProcessMsg_t pfnProcessMsg; // When SMP message received + smSendNextKeyInfo_t pfnSendNextKeyInfo; // When need to send next key message + smStartEncryption_t pfnStartEncryption; // When Start Encrypt requested +} smInitiatorCBs_t; + +// Responder callback structure - must be setup by the Initiator. +typedef struct +{ + smProcessMsg_t pfnProcessMsg; // When SMP message received + smSendNextKeyInfo_t pfnSendNextKeyInfo; // When need to send next key message + smProcessLTKReq_t pfnProcessLTKReq; // When HCI BLE LTK Request received +} smResponderCBs_t; + +/********************************************************************* + GLOBAL VARIABLES +*/ + +// Security Manager's OSAL task ID +extern uint8 smTaskID; + +extern smPairingParams_t* pPairingParams[]; + +extern smResponderCBs_t* pfnResponderCBs; + +/********************************************************************* + FUNCTIONS - API +*/ + +/********************************************************************* + Application Level Functions +*/ + +/* + smLinkCheck - link database callback function. +*/ +extern void smLinkCheck( uint16 connectionHandle, uint8 changeType ); + +/* + smProcessRandComplete - Process the HCI Random Complete Event. +*/ +extern uint8 smProcessRandComplete( uint8 status, uint8* rand ); + +/* + smTimedOut - Process the SM timeout. +*/ +extern void smTimedOut( uint16 connectionHandle ); + +/* + smStartRspTimer - Start the SM Response Timer. +*/ +extern void smStartRspTimer( uint16 connectionHandle ); + +/* + smStopRspTimer - Stop the SM Response Timer. +*/ +extern void smStopRspTimer( uint16 connectionHandle ); + +/* + smProcessDataMsg - Process incoming L2CAP messages. +*/ +extern void smProcessDataMsg( l2capDataEvent_t* pMsg ); + +/* + smProcessEncryptChange - Process the HCI BLE Encrypt Change Event. +*/ +extern uint8 smProcessEncryptChange( uint16 connectionHandle, uint8 reason ); + +/* + smInProcess - Is SM already processing something? +*/ +extern uint8 smInProcess( void ); + +/* + sm_d1 - SM diversifying function d1 +*/ +extern bStatus_t sm_d1( uint8* pK, uint16 d, uint8* pD1 ); + +/* + sm_ah - Random address hash function +*/ +extern bStatus_t sm_ah( uint8* pK, uint8* pR, uint8* pAh ); + +/* + sm_dm - SM DIV Maxk generation function dm +*/ +extern bStatus_t sm_dm( uint8* pK, uint8* pR, uint16* pDm ); + +/* + sm_c1 - SM Confirm value generation function c1 +*/ +extern bStatus_t sm_c1( uint16 connectionHandle,uint8* pK, uint8* pR, uint8* pC1 ); + +/* + sm_c1new - SM Confirm value generation function c1 +*/ +extern bStatus_t sm_c1new( uint8* pK, uint8* pR, uint8* pRes, uint8* pReq, + uint8 iat, uint8* pIA, uint8 rat, uint8* pRA, uint8* pC1 ); +/* + sm_s1 - SM key generation function s1 +*/ +extern bStatus_t sm_s1( uint8* pK, uint8* pR1, uint8* pR2, uint8* pS1 ); + +/* + smGenerateRandBuf - generate a buffer of random numbers +*/ +extern void smGenerateRandBuf( uint8* pRandNum, uint8 len ); + +/* + smEncLTK - start LTK Encryption +*/ +extern void smEncLTK( uint16 connectionHandle ); + +/* + smNextPairingState - trigger next state machine +*/ +extern void smNextPairingState( uint16 connectionHandle ); + +/* + smAuthReqToUint8 - conversion function +*/ +extern uint8 smAuthReqToUint8( authReq_t* pAuthReq ); + +/* + smUint8ToAuthReq - conversion function +*/ +extern void smUint8ToAuthReq( authReq_t* pAuthReq, uint8 authReqUint8 ); + +/* + smpResponderProcessPairingReq - Process an incoming Pairing Request message +*/ +extern uint8 smpResponderProcessPairingReq( uint16 connectionHandle,smpPairingReq_t* pParsedMsg ); + +/* + smSendFailAndEnd - Send the pairing failed message and end existing pairing +*/ +extern bStatus_t smSendFailAndEnd( uint16 connHandle, smpPairingFailed_t* pFailedMsg ); + +/* + generateRandMsg - Generate a Pairing Random +*/ +extern bStatus_t smGenerateRandMsg( uint16 connectionHandle); + +/* + smSavePairInfo - Save the Pairing Req or Rsp information +*/ +extern bStatus_t smSavePairInfo( uint16 connectionHandle,smpPairingReq_t* pPair ); + +/* + generateConfirm - Generate a Pairing Confirm +*/ +extern bStatus_t smGenerateConfirm( uint16 connectionHandle ); + +/* + smEndPairing - Pairing mode has ended. Yeah. Notify the GAP and free + up the memory used. +*/ +extern void smEndPairing( uint16 connectionHandle,uint8 status ); + +/* + determineKeySize - Determine the maximum encryption key size +*/ +extern uint8 smDetermineKeySize( uint16 connectionHandle ); + +/* + smGeneratePairingReqRsp - Generate a pairing req or response +*/ +extern bStatus_t smGeneratePairingReqRsp( uint16 connectionHandle ); + +/* + smPairingSendEncInfo - Send SM Encryption Information message +*/ +extern void smPairingSendEncInfo( uint16 connHandle, uint8* pLTK ); + +/* + smPairingSendMasterID - Send SM Master Identification message +*/ +extern void smPairingSendMasterID( uint16 connHandle, uint16 ediv, uint8* pRand ); + +/* + smPairingSendIdentityInfo - Send SM Identity Information message +*/ +extern void smPairingSendIdentityInfo( uint16 connHandle, uint8* pIRK ); + +/* + smPairingSendIdentityAddrInfo - Send SM Identity Addr Information message +*/ +extern void smPairingSendIdentityAddrInfo( uint16 connHandle, uint8 addrType, uint8* pMACAddr ); + +/* + smPairingSendSingingInfo - Send SM Signing Information message +*/ +extern void smPairingSendSingingInfo( uint16 connHandle, uint8* pSRK ); + +/* + smPairingSendEncInfo - Send SM Encryption Information message +*/ +extern void smPairingSendEncInfo( uint16 connHandle, uint8* pLTK ); + +/* + smProcessPairingReq - Process Pairing Request +*/ +extern void smProcessPairingReq( linkDBItem_t* pLinkItem, gapPairingReq_t* pPairReq ); + +/* + smStartEncryption - Perform Encrypt through HCI +*/ +extern bStatus_t smStartEncryption( uint16 connHandle, uint8* pLTK, uint16 div, + uint8* pRandNum, uint8 keyLen ); + +/* + smRegisterInitiator - egister Initiator's processing function with SM task +*/ +extern void smRegisterInitiator( smInitiatorCBs_t* pfnCBs ); + +/* + smRegisterResponder - Register Responder's processing function with SM task +*/ +extern void smRegisterResponder( smResponderCBs_t* pfnCBs ); + +/* + smp timerout callback for SMP Timeout and pairing state +*/ +extern void smTo_timerCB( uint8* pData ); +extern void smState_timerCB( uint8* pData ); + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* SM_INTERNAL_H */ diff --git a/arch/arm/src/phy62xx/ble/host/smp.h b/arch/arm/src/phy62xx/ble/host/smp.h new file mode 100644 index 00000000000..a725d17e7ee --- /dev/null +++ b/arch/arm/src/phy62xx/ble/host/smp.h @@ -0,0 +1,408 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/************************************************************************************************** +**************************************************************************************************/ + +#ifndef SMP_H +#define SMP_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ +#include "bcomdef.h" + +#include "sm_internal.h" + +/********************************************************************* + MACROS +*/ + +/********************************************************************* + CONSTANTS +*/ + +// Code field of the SMP Command format +#define SMP_PAIRING_REQ 0x01 +#define SMP_PAIRING_RSP 0x02 +#define SMP_PAIRING_CONFIRM 0x03 +#define SMP_PAIRING_RANDOM 0x04 +#define SMP_PAIRING_FAILED 0x05 +#define SMP_ENCRYPTION_INFORMATION 0x06 +#define SMP_MASTER_IDENTIFICATION 0x07 +#define SMP_IDENTITY_INFORMATION 0x08 +#define SMP_IDENTITY_ADDR_INFORMATION 0x09 +#define SMP_SIGNING_INFORMATION 0x0A +#define SMP_SECURITY_REQUEST 0x0B + +// Pairing Request & Response - IO Capabilities +#define SMP_IO_CAP_DISPLAY_ONLY 0x00 +#define SMP_IO_CAP_DISPLAY_YES_NO 0x01 +#define SMP_IO_CAP_KEYBOARD_ONLY 0x02 +#define SMP_IO_CAP_NO_INPUT_NO_OUTPUT 0x03 +#define SMP_IO_CAP_KEYBOARD_DISPLAY 0x04 + +// Pairing Request & Response - Out Of Bound (OOB) data flag values +#define SMP_OOB_AUTH_DATA_NOT_PRESENT 0x00 +#define SMP_OOB_AUTH_DATA_REMOTE_DEVICE_PRESENT 0x01 + +// Pairing Request & Response - authReq field +// - This field contains 2 sub-fields: +// bonding flags - bits 1 & 0 +#define SMP_AUTHREQ_BONDING 0x01 +// Man-In-The-Middle (MITM) - bit 2 +#define SMP_AUTHREQ_MITM 0x04 + +#define SMP_CONFIRM_LEN 16 +#define SMP_RANDOM_LEN 16 + +// Pairing Failed - "reason" field +#define SMP_PAIRING_FAILED_PASSKEY_ENTRY_FAILED 0x01 //!< The user input of the passkey failed, for example, the user cancelled the operation. +#define SMP_PAIRING_FAILED_OOB_NOT_AVAIL 0x02 //!< The OOB data is not available +#define SMP_PAIRING_FAILED_AUTH_REQ 0x03 //!< The pairing procedure can't be performed as authentication requirements can't be met due to IO capabilities of one or both devices +#define SMP_PAIRING_FAILED_CONFIRM_VALUE 0x04 //!< The confirm value doesn't match the calculated compare value +#define SMP_PAIRING_FAILED_NOT_SUPPORTED 0x05 //!< Pairing isn't supported by the device +#define SMP_PAIRING_FAILED_ENC_KEY_SIZE 0x06 //!< The resultant encryption key size is insufficient for the security requirements of this device. +#define SMP_PAIRING_FAILED_CMD_NOT_SUPPORTED 0x07 //!< The SMP command received is not supported on this device. +#define SMP_PAIRING_FAILED_UNSPECIFIED 0x08 //!< Pairing failed due to an unspecified reason +#define SMP_PAIRING_FAILED_REPEATED_ATTEMPTS 0x09 //!< Pairing or authenication procedure is disallowed because too little time has elapsed since the last pairing request or security request. + +#define SMP_PAIRING_FAILED_LOCAL_KEY_FAILURE 0x0A // Local value - not sent over the air + +// Message lengths +#define SMP_PAIRING_REQ_LEN 7 +#define SMP_PAIRING_RSP_LEN 7 +#define SMP_PAIRING_CONFIRM_LEN 17 +#define SMP_PAIRING_RANDOM_LEN 17 +#define SMP_PAIRING_FAILED_LEN 2 +#define SMP_ENCRYPTION_INFORMATION_LEN 17 +#define SMP_MASTER_IDENTIFICATION_LEN 11 +#define SMP_IDENTITY_INFORMATION_LEN 17 +#define SMP_IDENTITY_ADDR_INFORMATION_LEN 8 +#define SMP_SIGNING_INFORMATION_LEN 17 +#define SMP_SECURITY_REQUEST_LEN 2 + +// Macros to use the smSendSMMsg() function to send all of the Security Manager Protocol messages +#define smSendPairingReq( connHandle, msgStruct ) \ + smSendSMMsg( (connHandle), SMP_PAIRING_REQ_LEN, \ + (smpMsgs_t *)(msgStruct), \ + (pfnSMBuildCmd_t)(smpBuildPairingReq) ) + +#define smSendPairingRsp( connHandle, msgStruct ) \ + smSendSMMsg( (connHandle), SMP_PAIRING_RSP_LEN, \ + (smpMsgs_t *)(msgStruct), \ + (pfnSMBuildCmd_t)(smpBuildPairingRsp) ) + +#define smSendPairingConfirm( connHandle, msgStruct ) \ + smSendSMMsg( (connHandle), SMP_PAIRING_CONFIRM_LEN, \ + (smpMsgs_t *)(msgStruct), \ + (pfnSMBuildCmd_t)(smpBuildPairingConfirm) ) + +#define smSendPairingRandom( connHandle, msgStruct ) \ + smSendSMMsg( (connHandle), SMP_PAIRING_RANDOM_LEN, \ + (smpMsgs_t *)(msgStruct), \ + (pfnSMBuildCmd_t)(smpBuildPairingRandom) ) + +#define smSendPairingFailed( connHandle, msgStruct ) \ + smSendSMMsg( (connHandle), SMP_PAIRING_FAILED_LEN, \ + (smpMsgs_t *)(msgStruct), \ + (pfnSMBuildCmd_t)(smpBuildPairingFailed) ) + +#define smSendEncInfo( connHandle, msgStruct ) \ + smSendSMMsg( (connHandle), SMP_ENCRYPTION_INFORMATION_LEN, \ + (smpMsgs_t *)(msgStruct), \ + (pfnSMBuildCmd_t)(smpBuildEncInfo) ) + +#define smSendMasterID( connHandle, msgStruct ) \ + smSendSMMsg( (connHandle), SMP_MASTER_IDENTIFICATION_LEN, \ + (smpMsgs_t *)(msgStruct), \ + (pfnSMBuildCmd_t)(smpBuildMasterID) ) + +#define smSendIdentityInfo( connHandle, msgStruct ) \ + smSendSMMsg( (connHandle), SMP_IDENTITY_INFORMATION_LEN, \ + (smpMsgs_t *)(msgStruct), \ + (pfnSMBuildCmd_t)(smpBuildIdentityInfo) ) + +#define smSendIdentityAddrInfo( connHandle, msgStruct ) \ + smSendSMMsg( (connHandle), SMP_IDENTITY_ADDR_INFORMATION_LEN, \ + (smpMsgs_t *)(msgStruct), \ + (pfnSMBuildCmd_t)(smpBuildIdentityAddrInfo) ) + +#define smSendSigningInfo( connHandle, msgStruct ) \ + smSendSMMsg( (connHandle), SMP_SIGNING_INFORMATION_LEN, \ + (smpMsgs_t *)(msgStruct), \ + (pfnSMBuildCmd_t)(smpBuildSigningInfo) ) + +#define smSendSecurityReq( connHandle, msgStruct ) \ + smSendSMMsg( (connHandle), SMP_SECURITY_REQUEST_LEN, \ + (smpMsgs_t *)(msgStruct), \ + (pfnSMBuildCmd_t)(smpBuildSecurityReq) ) + +/********************************************************************* + TYPEDEFS +*/ + +// Pairing Request +typedef struct +{ + uint8 ioCapability; // ex. SMP_IO_CAP_DISPLAY_YES_NO + uint8 oobDataFlag; // Out of Bound data flag + authReq_t authReq; // Authentication fields + uint8 maxEncKeySize; // Encryption Key size max bytes (7 - 16) + keyDist_t keyDist; // Key Distribution Field - bit struct +} smpPairingReq_t; + +// Pairing Response - same as Pairing Request +typedef smpPairingReq_t smpPairingRsp_t; + +// Pairing Confirm +typedef struct +{ + uint8 confirmValue[SMP_CONFIRM_LEN]; +} smpPairingConfirm_t; + +// Pairing Random +typedef struct +{ + uint8 randomValue[SMP_RANDOM_LEN]; +} smpPairingRandom_t; + +// Pairing Failed +typedef struct +{ + uint8 reason; +} smpPairingFailed_t; + +// Encryption Information +typedef struct +{ + uint8 ltk[KEYLEN]; +} smpEncInfo_t; + +// Master Identification +typedef struct +{ + uint16 ediv; + uint16 rand[B_RANDOM_NUM_SIZE]; +} smpMasterID_t; + +// Identity Information +typedef struct +{ + uint8 irk[KEYLEN]; +} smpIdentityInfo_t; + +// Identity Address Information +typedef struct +{ + uint8 addrType; + uint8 bdAddr[B_ADDR_LEN]; +} smpIdentityAddrInfo_t; + +// Signing Information +typedef struct +{ + uint8 signature[KEYLEN]; +} smpSigningInfo_t; + +// Slave Security Request +typedef struct +{ + authReq_t authReq; +} smpSecurityReq_t; + +// Union with all of the SM messages. +typedef union +{ + smpPairingReq_t pairingReq; + smpPairingReq_t pairingRsp; + smpPairingConfirm_t pairingConfirm; + smpPairingRandom_t pairingRandom; + smpPairingFailed_t pairingFailed; + smpEncInfo_t encInfo; + smpMasterID_t masterID; + smpIdentityInfo_t idInfo; + smpIdentityAddrInfo_t idAddrInfo; + smpSigningInfo_t signingInfo; + smpSecurityReq_t secReq; +} smpMsgs_t; + +typedef uint8 (*pfnSMBuildCmd_t)( smpMsgs_t* pMsgStruct, uint8* pBuf ); + +/********************************************************************* + GLOBAL VARIABLES +*/ +extern smpPairingReq_t pairingReg; + +/********************************************************************* + FUNCTIONS +*/ + +/* + smpBuildPairingReq - Build an SM Pairing Request +*/ +extern bStatus_t smpBuildPairingReq( smpPairingReq_t* pPairingReq, uint8* pBuf ); + +/* + smpBuildPairingRsp - Build an SM Pairing Response +*/ +extern bStatus_t smpBuildPairingRsp( smpPairingRsp_t* pPairingRsp, uint8* pBuf ); + +/* + smpBuildPairingReqRsp - Build an SM Pairing Request or Response +*/ +extern bStatus_t smpBuildPairingReqRsp( uint8 opCode, smpPairingReq_t* pPairingReq, uint8* pBuf ); + +/* + smpParsePairingReq - Parse an SM Pairing Request +*/ +extern bStatus_t smpParsePairingReq( uint8* pBuf, smpPairingReq_t* pPairingReq ); + +/* + smpParsePairingRsp - Parse an SM Pairing Response +*/ +#define smpParsePairingRsp( a, b ) smpParsePairingReq( (a), (b) ) + +/* + smpBuildPairingConfirm - Build an SM Pairing Confirm +*/ +extern bStatus_t smpBuildPairingConfirm( smpPairingConfirm_t* pPairingConfirm, + uint8* pBuf ); + +/* + smpParsePairingConfirm - Parse an SM Pairing Confirm +*/ +extern bStatus_t smpParsePairingConfirm( uint8* pBuf, + smpPairingConfirm_t* pPairingConfirm ); + +/* + smpBuildPairingRandom - Build an SM Pairing Random +*/ +extern bStatus_t smpBuildPairingRandom( smpPairingRandom_t* pPairingRandom, + uint8* pBuf ); + +/* + smpParsePairingRandom - Parse an SM Pairing Random +*/ +extern bStatus_t smpParsePairingRandom( uint8* pBuf, + smpPairingRandom_t* pPairingRandom ); + +/* + smpBuildPairingFailed - Build an SM Pairing Failed +*/ +extern bStatus_t smpBuildPairingFailed( smpPairingFailed_t* pPairingFailed, + uint8* pBuf ); + +/* + smpParsePairingFailed - Parse an SM Pairing Failed +*/ +extern bStatus_t smpParsePairingFailed( uint8* pBuf, + smpPairingFailed_t* pPairingFailed ); + +/* + smpBuildEncInfo - Build an SM Encryption Information +*/ +extern bStatus_t smpBuildEncInfo( smpEncInfo_t* pEncInfo, uint8* pBuf ); + +/* + smpParseEncInfo - Parse an SM Encryption Information +*/ +extern bStatus_t smpParseEncInfo( uint8* buf, smpEncInfo_t* encInfo ); + +/* + smpBuildMasterID - Build an SM Master Identification +*/ +extern bStatus_t smpBuildMasterID( smpMasterID_t* pMasterID, uint8* pBuf ); + +/* + smpParseMasterID - Parse an SM Master Identification +*/ +extern bStatus_t smpParseMasterID( uint8* pBuf, smpMasterID_t* pMasterID ); + +/* + smpBuildIdentityInfo - Build an SM Identity Information +*/ +extern bStatus_t smpBuildIdentityInfo( smpIdentityInfo_t* pIdInfo, uint8* pBuf ); + +/* + smpBuildIdentityAddrInfo - Build an SM Identity Address Information +*/ +extern bStatus_t smpBuildIdentityAddrInfo( smpIdentityAddrInfo_t* pIdInfo, uint8* pBuf ); + +/* + smpParseIdentityInfo - Parse an SM Identity Information +*/ +extern bStatus_t smpParseIdentityInfo( uint8* pBuf, smpIdentityInfo_t* pIdInfo ); + +/* + smpParseIdentityAddrInfo - Parse an SM Identity Address Information +*/ +extern bStatus_t smpParseIdentityAddrInfo( uint8* pBuf, smpIdentityAddrInfo_t* pIdInfo ); + +/* + smpBuildSigningInfo - Build an SM Signing Information +*/ +extern bStatus_t smpBuildSigningInfo( smpSigningInfo_t* pSigningInfo, uint8* pBuf ); + +/* + smpParseSigningInfo - Parse an SM Signing Information +*/ +extern bStatus_t smpParseSigningInfo( uint8* pBuf, smpSigningInfo_t* pSigningInfo ); + +/* + smpBuildSecurityReq - Build an SM Slave Security Request +*/ +extern bStatus_t smpBuildSecurityReq( smpSecurityReq_t* pSecReq, uint8* pBuf ); + +/* + smpParseSecurityReq - Parse an SM Slave Security Request +*/ +extern bStatus_t smpParseSecurityReq( uint8* pBuf, smpSecurityReq_t* pSecReq ); + +/* + smSendSMMsg - Generic Send L2CAP SM message function +*/ +extern bStatus_t smSendSMMsg( uint16 connHandle, uint8 bufLen, smpMsgs_t* pMsg, pfnSMBuildCmd_t buildFn ); + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* SMP_H */ diff --git a/arch/arm/src/phy62xx/ble/include/att.h b/arch/arm/src/phy62xx/ble/include/att.h new file mode 100644 index 00000000000..83540597ad3 --- /dev/null +++ b/arch/arm/src/phy62xx/ble/include/att.h @@ -0,0 +1,1279 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/** + @headerfile: att.h + + +**************************************************************************************************/ + +#ifndef ATT_H +#define ATT_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ +#include "bcomdef.h" +#include "OSAL.h" + +#include "l2cap.h" + +/********************************************************************* + CONSTANTS +*/ + +// The Exchanging MTU Size is defined as the maximum size of any packet +// transmitted between a client and a server. A higher layer specification +// defines the default ATT MTU value. The ATT MTU value should be within +// the range 23 to 517 inclusive. +#define ATT_MTU_SIZE L2CAP_MTU_SIZE //!< Minimum ATT MTU size +#define ATT_MAX_MTU_SIZE 517 //!< Maximum ATT MTU size +#define ATT_MTU_SIZE_MIN 23 +/** @defgroup ATT_METHOD_DEFINES ATT Methods + @{ +*/ + +#define ATT_ERROR_RSP 0x01 //!< ATT Error Response +#define ATT_EXCHANGE_MTU_REQ 0x02 //!< ATT Exchange MTU Request +#define ATT_EXCHANGE_MTU_RSP 0x03 //!< ATT Exchange MTU Response +#define ATT_FIND_INFO_REQ 0x04 //!< ATT Find Information Request +#define ATT_FIND_INFO_RSP 0x05 //!< ATT Find Information Response +#define ATT_FIND_BY_TYPE_VALUE_REQ 0x06 //!< ATT Find By Type Vaue Request +#define ATT_FIND_BY_TYPE_VALUE_RSP 0x07 //!< ATT Find By Type Vaue Response +#define ATT_READ_BY_TYPE_REQ 0x08 //!< ATT Read By Type Request +#define ATT_READ_BY_TYPE_RSP 0x09 //!< ATT Read By Type Response +#define ATT_READ_REQ 0x0a //!< ATT Read Request +#define ATT_READ_RSP 0x0b //!< ATT Read Response +#define ATT_READ_BLOB_REQ 0x0c //!< ATT Read Blob Request +#define ATT_READ_BLOB_RSP 0x0d //!< ATT Read Blob Response +#define ATT_READ_MULTI_REQ 0x0e //!< ATT Read Multiple Request +#define ATT_READ_MULTI_RSP 0x0f //!< ATT Read Multiple Response +#define ATT_READ_BY_GRP_TYPE_REQ 0x10 //!< ATT Read By Group Type Request +#define ATT_READ_BY_GRP_TYPE_RSP 0x11 //!< ATT Read By Group Type Response +#define ATT_WRITE_REQ 0x12 //!< ATT Write Request +#define ATT_WRITE_RSP 0x13 //!< ATT Write Response +#define ATT_PREPARE_WRITE_REQ 0x16 //!< ATT Prepare Write Request +#define ATT_PREPARE_WRITE_RSP 0x17 //!< ATT Prepare Write Response +#define ATT_EXECUTE_WRITE_REQ 0x18 //!< ATT Execute Write Request +#define ATT_EXECUTE_WRITE_RSP 0x19 //!< ATT Execute Write Response +#define ATT_HANDLE_VALUE_NOTI 0x1b //!< ATT Handle Value Notification +#define ATT_HANDLE_VALUE_IND 0x1d //!< ATT Handle Value Indication +#define ATT_HANDLE_VALUE_CFM 0x1e //!< ATT Handle Value Confirmation + +#define ATT_WRITE_CMD 0x52 //!< ATT Write Command +#define ATT_SIGNED_WRITE_CMD 0xD2 //!< ATT Signed Write Command + +/** @} End ATT_METHOD_DEFINES */ + +/*** Opcode fields: bitmasks ***/ +// Method (bits 5-0) +#define ATT_METHOD_BITS 0x3f + +// Command Flag (bit 6) +#define ATT_CMD_FLAG_BIT 0x40 + +// Authentication Signature Flag (bit 7) +#define ATT_AUTHEN_SIG_FLAG_BIT 0x80 + +// Size of 16-bit Bluetooth UUID +#define ATT_BT_UUID_SIZE 2 + +// Size of 128-bit UUID +#define ATT_UUID_SIZE 16 + +// ATT Response or Confirmation timeout +#define ATT_MSG_TIMEOUT 30 + +// Authentication Signature status for received PDU; it's TRUE or FALSE for PDU to be sent +#define ATT_SIG_NOT_INCLUDED 0x00 // Signature not included +#define ATT_SIG_VALID 0x01 // Included signature valid +#define ATT_SIG_INVALID 0x02 // Included signature not valid + +/********************************************************************* + Error Response: Error Code +*/ + +/** @defgroup ATT_ERR_CODE_DEFINES ATT Error Codes + @{ +*/ + +#define ATT_ERR_INVALID_HANDLE 0x01 //!< Attribute handle value given was not valid on this attribute server +#define ATT_ERR_READ_NOT_PERMITTED 0x02 //!< Attribute cannot be read +#define ATT_ERR_WRITE_NOT_PERMITTED 0x03 //!< Attribute cannot be written +#define ATT_ERR_INVALID_PDU 0x04 //!< The attribute PDU was invalid +#define ATT_ERR_INSUFFICIENT_AUTHEN 0x05 //!< The attribute requires authentication before it can be read or written +#define ATT_ERR_UNSUPPORTED_REQ 0x06 //!< Attribute server doesn't support the request received from the attribute client +#define ATT_ERR_INVALID_OFFSET 0x07 //!< Offset specified was past the end of the attribute +#define ATT_ERR_INSUFFICIENT_AUTHOR 0x08 //!< The attribute requires an authorization before it can be read or written +#define ATT_ERR_PREPARE_QUEUE_FULL 0x09 //!< Too many prepare writes have been queued +#define ATT_ERR_ATTR_NOT_FOUND 0x0a //!< No attribute found within the given attribute handle range +#define ATT_ERR_ATTR_NOT_LONG 0x0b //!< Attribute cannot be read or written using the Read Blob Request or Prepare Write Request +#define ATT_ERR_INSUFFICIENT_KEY_SIZE 0x0c //!< The Encryption Key Size used for encrypting this link is insufficient +#define ATT_ERR_INVALID_VALUE_SIZE 0x0d //!< The attribute value length is invalid for the operation +#define ATT_ERR_UNLIKELY 0x0e //!< The attribute request that was requested has encountered an error that was very unlikely, and therefore could not be completed as requested +#define ATT_ERR_INSUFFICIENT_ENCRYPT 0x0f //!< The attribute requires encryption before it can be read or written +#define ATT_ERR_UNSUPPORTED_GRP_TYPE 0x10 //!< The attribute type is not a supported grouping attribute as defined by a higher layer specification +#define ATT_ERR_INSUFFICIENT_RESOURCES 0x11 //!< Insufficient Resources to complete the request + +/*** Reserved for future use: 0x12 - 0x7F ***/ + +/*** Application error code defined by a higher layer specification: 0x80-0x9F ***/ + +#define ATT_ERR_INVALID_VALUE 0x80 //!< The attribute value is invalid for the operation + +/** @} End ATT_ERR_CODE_DEFINES */ + +/********************************************************************* + Find Information Response: UUID Format +*/ +// Handle and 16-bit Bluetooth UUID +#define ATT_HANDLE_BT_UUID_TYPE 0x01 + +// Handle and 128-bit UUID +#define ATT_HANDLE_UUID_TYPE 0x02 + +// Maximum number of handle and 16-bit UUID pairs in a single Find Info Response +#define ATT_MAX_NUM_HANDLE_BT_UUID ( ( ATT_MTU_SIZE_MIN - 2 ) / ( 2 + ATT_BT_UUID_SIZE ) ) + +// Maximum number of handle and 128-bit UUID pairs in a single Find Info Response +#define ATT_MAX_NUM_HANDLE_UUID ( ( ATT_MTU_SIZE_MIN - 2 ) / ( 2 + ATT_UUID_SIZE ) ) + +/********************************************************************* + Find By Type Value Response: Handles Infomation (Found Attribute Handle and Group End Handle) +*/ +// Maximum number of handles info in a single Find By Type Value Response +#define ATT_MAX_NUM_HANDLES_INFO ( ( ATT_MTU_SIZE - 1 ) / 4 ) + +/********************************************************************* + Read Multiple Request: Handles +*/ +// Maximum number of handles in a single Read Multiple Request +#define ATT_MAX_NUM_HANDLES ( ( ATT_MTU_SIZE - 1 ) / 2 ) + +// Minimum number of handles in a single Read Multiple Request +#define ATT_MIN_NUM_HANDLES 2 + +/********************************************************************* + Execute Write Request: Flags +*/ +// Cancel all prepared writes +#define ATT_CANCEL_PREPARED_WRITES 0x00 + +// Immediately write all pending prepared values +#define ATT_WRITE_PREPARED_VALUES 0x01 + +#if defined ( TESTMODES ) +// ATT Test Modes +#define ATT_TESTMODE_OFF 0 // Test mode off +#define ATT_TESTMODE_UNAUTHEN_SIG 1 // Do not authenticate incoming signature +#endif + +/********************************************************************* + Size of mandatory fields of ATT requests +*/ +// Length of Read By Type Request's fixed fields: First handle number (2) + Last handle number (2) +#define READ_BY_TYPE_REQ_FIXED_SIZE 4 + +// Length of Prepare Write Request's fixed size: Attribute Handle (2) + Value Offset (2) +#define PREPARE_WRITE_REQ_FIXED_SIZE 4 + +/********************************************************************* + VARIABLES +*/ +extern CONST uint8 btBaseUUID[ATT_UUID_SIZE]; + +/********************************************************************* + MACROS +*/ + +/********************************************************************* + TYPEDEFS +*/ + +/** + Attribute Protocol PDU format. +*/ +typedef struct +{ + uint8 sig; //!< Authentication Signature status (not included (0), valid (1), invalid (2)) + uint8 cmd; //!< Command Flag + uint8 method; //!< Method + uint16 len; //!< Length of Attribute Parameters + uint8* pParams; //!< Attribute Parameters +} attPacket_t; + +/** + Attribute Type format (2 or 16 octet UUID). +*/ +typedef struct +{ + uint8 len; //!< Length of UUID + uint8 uuid[ATT_UUID_SIZE]; //!< 16 or 128 bit UUID +} attAttrType_t; + +/** + Attribute Type format (2-octet Bluetooth UUID). +*/ +typedef struct +{ + uint8 len; //!< Length of UUID + uint8 uuid[ATT_BT_UUID_SIZE]; //!< 16 bit UUID +} attAttrBtType_t; + +/** + Error Response format. +*/ +typedef struct +{ + uint8 reqOpcode; //!< Request that generated this error response + uint16 handle; //!< Attribute handle that generated error response + uint8 errCode; //!< Reason why the request has generated error response +} attErrorRsp_t; + +/** + Exchange MTU Request format. +*/ +typedef struct +{ + uint16 clientRxMTU; //!< Client receive MTU size +} attExchangeMTUReq_t; + +/** + Exchange MTU Response format. +*/ +typedef struct +{ + uint16 serverRxMTU; //!< Server receive MTU size +} attExchangeMTURsp_t; + +typedef struct +{ + uint16 clientMTU; + uint16 serverMTU; +} attMTU_t; + +/** + Find Information Request format. +*/ +typedef struct +{ + uint16 startHandle; //!< First requested handle number (must be first field) + uint16 endHandle; //!< Last requested handle number +} attFindInfoReq_t; + +/** + Handle and its 16-bit Bluetooth UUIDs. +*/ +typedef struct +{ + uint16 handle; //!< Handle + uint8 uuid[ATT_BT_UUID_SIZE]; //!< 2-octet Bluetooth UUID +} attHandleBtUUID_t; + +/** + Handle and its 128-bit UUID. +*/ +typedef struct +{ + uint16 handle; //!< Handle + uint8 uuid[ATT_UUID_SIZE]; //!< 16-octect UUID +} attHandleUUID_t; + +/** + Info data format for Find Information Response (handle-UUID pair). +*/ +typedef union +{ + attHandleBtUUID_t btPair[ATT_MAX_NUM_HANDLE_BT_UUID]; //!< A list of 1 or more handles with their 16-bit Bluetooth UUIDs + attHandleUUID_t pair[ATT_MAX_NUM_HANDLE_UUID]; //!< A list of 1 or more handles with their 128-bit UUIDs +} attFindInfo_t; + +/** + Find Information Response format. +*/ +typedef struct +{ + uint8 numInfo; //!< Number of attribute handle-UUID pairs found + uint8 format; //!< Format of information data + attFindInfo_t info; //!< Information data whose format is determined by format field +} attFindInfoRsp_t; + +/** + Find By Type Value Request format. +*/ +typedef struct +{ + uint16 startHandle; //!< First requested handle number (must be first field) + uint16 endHandle; //!< Last requested handle number + attAttrBtType_t type; //!< 2-octet UUID to find +// uint8 len; //!< Length of value + uint16 len; //!< Length of value + uint8 value[ATT_MTU_SIZE-7]; //!< Attribute value to find +} attFindByTypeValueReq_t; + +/** + Handles Infomation format. +*/ +typedef struct +{ + uint16 handle; //!< Found attribute handle + uint16 grpEndHandle; //!< Group end handle +} attHandlesInfo_t; + +/** + Find By Type Value Response format. +*/ +typedef struct +{ + uint8 numInfo; //!< Number of handles information found + attHandlesInfo_t handlesInfo[ATT_MAX_NUM_HANDLES_INFO]; //!< List of 1 or more handles information +} attFindByTypeValueRsp_t; + +/** + Read By Type Request format. +*/ +typedef struct +{ + uint16 startHandle; //!< First requested handle number (must be first field) + uint16 endHandle; //!< Last requested handle number + attAttrType_t type; //!< Requested type (2 or 16 octet UUID) +} attReadByTypeReq_t; + +/** + Read By Type Response format. +*/ +typedef struct +{ + uint8 numPairs; //!< Number of attribute handle-UUID pairs found +// uint8 len; //!< Size of each attribute handle-value pair + uint16 len; + uint8 dataList[ATT_MTU_SIZE-2]; //!< List of 1 or more attribute handle-value pairs +} attReadByTypeRsp_t; + +/** + Read Request format. +*/ +typedef struct +{ + uint16 handle; //!< Handle of the attribute to be read (must be first field) +} attReadReq_t; + +/** + Read Response format. +*/ +typedef struct +{ +// uint8 len; //!< Length of value + uint16 len; + uint8 value[ATT_MTU_SIZE-1]; //!< Value of the attribute with the handle given +} attReadRsp_t; + +/** + Read Blob Req format. +*/ +typedef struct +{ + uint16 handle; //!< Handle of the attribute to be read (must be first field) + uint16 offset; //!< Offset of the first octet to be read +} attReadBlobReq_t; + +/** + Read Blob Response format. +*/ +typedef struct +{ +// uint8 len; //!< Length of value + uint16 len; + uint8 value[ATT_MTU_SIZE-1]; //!< Part of the value of the attribute with the handle given +} attReadBlobRsp_t; + +/** + Read Multiple Request format. +*/ +typedef struct +{ + uint16 handle[ATT_MAX_NUM_HANDLES]; //!< Set of two or more attribute handles (must be first field) + uint8 numHandles; //!< Number of attribute handles +} attReadMultiReq_t; + +/** + Read Multiple Response format. +*/ +typedef struct +{ +// uint8 len; //!< Length of values + uint16 len; + uint8 values[ATT_MTU_SIZE-1]; //!< Set of two or more values +} attReadMultiRsp_t; + +/** + Read By Group Type Request format. +*/ +typedef struct +{ + uint16 startHandle; //!< First requested handle number (must be first field) + uint16 endHandle; //!< Last requested handle number + attAttrType_t type; //!< Requested group type (2 or 16 octet UUID) +} attReadByGrpTypeReq_t; + +/** + Read By Group Type Response format. +*/ +typedef struct +{ + uint8 numGrps; //!< Number of attribute handle, end group handle and value sets found +// uint8 len; //!< Length of each attribute handle, end group handle and value set + uint16 len; + uint8 dataList[ATT_MTU_SIZE-2]; //!< List of 1 or more attribute handle, end group handle and value +} attReadByGrpTypeRsp_t; + +/** + Write Request format. +*/ +typedef struct +{ + uint16 handle; //!< Handle of the attribute to be written (must be first field) +// uint8 len; //!< Length of value + uint16 len; + uint8 value[ATT_MTU_SIZE-3]; //!< Value of the attribute to be written + uint8 sig; //!< Authentication Signature status (not included (0), valid (1), invalid (2)) + uint8 cmd; //!< Command Flag +} attWriteReq_t; + +/** + Prepare Write Request format. +*/ +typedef struct +{ + uint16 handle; //!< Handle of the attribute to be written (must be first field) + uint16 offset; //!< Offset of the first octet to be written +// uint8 len; //!< Length of value + uint16 len; + uint8 value[ATT_MTU_SIZE-5]; //!< Part of the value of the attribute to be written +} attPrepareWriteReq_t; + +/** + Prepare Write Response format. +*/ +typedef struct +{ + uint16 handle; //!< Handle of the attribute that has been read + uint16 offset; //!< Offset of the first octet to be written +// uint8 len; //!< Length of value + uint16 len; + uint8 value[ATT_MTU_SIZE-5]; //!< Part of the value of the attribute to be written +} attPrepareWriteRsp_t; + +/** + Execute Write Request format. +*/ +typedef struct +{ + uint8 flags; //!< 0x00 - cancel all prepared writes. + //!< 0x01 - immediately write all pending prepared values. +} attExecuteWriteReq_t; + +/** + Handle Value Notification format. +*/ +typedef struct +{ + uint16 handle; //!< Handle of the attribute that has been changed (must be first field) +// uint8 len; //!< Length of value + uint16 len; //!< Length of value + uint8 value[ATT_MTU_SIZE-3]; //!< New value of the attribute +} attHandleValueNoti_t; + +/** + Handle Value Indication format. +*/ +typedef struct +{ + uint16 handle; //!< Handle of the attribute that has been changed (must be first field) +// uint8 len; //!< Length of value + uint16 len; + uint8 value[ATT_MTU_SIZE-3]; //!< New value of the attribute +} attHandleValueInd_t; + +/** + ATT Message format. It's a union of all attribute protocol messages used + between the attribute protocol and upper layer profile/application. +*/ +typedef union +{ + // Request messages + attExchangeMTUReq_t exchangeMTUReq; //!< ATT Exchange MTU Request + attFindInfoReq_t findInfoReq; //!< ATT Find Information Request + attFindByTypeValueReq_t findByTypeValueReq; //!< ATT Find By Type Vaue Request + attReadByTypeReq_t readByTypeReq; //!< ATT Read By Type Request + attReadReq_t readReq; //!< ATT Read Request + attReadBlobReq_t readBlobReq; //!< ATT Read Blob Request + attReadMultiReq_t readMultiReq; //!< ATT Read Multiple Request + attReadByGrpTypeReq_t readByGrpTypeReq; //!< ATT Read By Group Type Request + attWriteReq_t writeReq; //!< ATT Write Request + attPrepareWriteReq_t prepareWriteReq; //!< ATT Prepare Write Request + attExecuteWriteReq_t executeWriteReq; //!< ATT Execute Write Request + + // Response messages + attErrorRsp_t errorRsp; //!< ATT Error Response + attExchangeMTURsp_t exchangeMTURsp; //!< ATT Exchange MTU Response + attFindInfoRsp_t findInfoRsp; //!< ATT Find Information Response + attFindByTypeValueRsp_t findByTypeValueRsp; //!< ATT Find By Type Vaue Response + attReadByTypeRsp_t readByTypeRsp; //!< ATT Read By Type Response + attReadRsp_t readRsp; //!< ATT Read Response + attReadBlobRsp_t readBlobRsp; //!< ATT Read Blob Response + attReadMultiRsp_t readMultiRsp; //!< ATT Read Multiple Response + attReadByGrpTypeRsp_t readByGrpTypeRsp; //!< ATT Read By Group Type Response + attPrepareWriteRsp_t prepareWriteRsp; //!< ATT Prepare Write Response + + // Indication and Notification messages + attHandleValueNoti_t handleValueNoti; //!< ATT Handle Value Notification + attHandleValueInd_t handleValueInd; //!< ATT Handle Value Indication +} attMsg_t; + +/********************************************************************* + VARIABLES +*/ + +/********************************************************************* + API FUNCTIONS +*/ + +/* ------------------------------------------------------------------- + General Utility APIs +*/ + +/* + Parse an attribute protocol message. +*/ +extern uint8 ATT_ParsePacket( l2capDataEvent_t* pL2capMsg, attPacket_t* pPkt ); + +/* + Compare two UUIDs. The UUIDs are converted if necessary. +*/ +extern uint8 ATT_CompareUUID( const uint8* pUUID1, uint16 len1, + const uint8* pUUID2, uint16 len2 ); +/* + Convert a 16-bit UUID to 128-bit UUID. +*/ +extern uint8 ATT_ConvertUUIDto128( const uint8* pUUID16, uint8* pUUID128 ); + +/* + Convert a 128-bit UUID to 16-bit UUID. +*/ +extern uint8 ATT_ConvertUUIDto16( const uint8* pUUID128, uint8* pUUID16 ); + + +/* ------------------------------------------------------------------- + Attribute Client Utility APIs +*/ + +/* + Build Error Response. +*/ +extern uint16 ATT_BuildErrorRsp( uint8* pBuf, uint8* pMsg ); + +/* + Parse Error Response. +*/ +extern bStatus_t ATT_ParseErrorRsp( uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Build Exchange MTU Request. +*/ +extern uint16 ATT_BuildExchangeMTUReq( uint8* pBuf, uint8* pMsg ); + +/* + Build Exchange MTU Respnose. +*/ +extern uint16 ATT_BuildExchangeMTURsp( uint8* pBuf, uint8* pMsg ); + +/* + Parse Exchange MTU Response. +*/ +extern bStatus_t ATT_ParseExchangeMTURsp( uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Build Find Information Request. +*/ +extern uint16 ATT_BuildFindInfoReq( uint8* pBuf, uint8* pMsg ); + +/* + Parse Find Information Response. +*/ +extern bStatus_t ATT_ParseFindInfoRsp( uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Build Find Information Response. +*/ +extern uint16 ATT_BuildFindInfoRsp( uint8* pBuf, uint8* pMsg ); + +/* + Build Find By Type Value Request. +*/ +extern uint16 ATT_BuildFindByTypeValueReq( uint8* pBuf, uint8* pMsg ); + +/* + Build Find By Type Value Response. +*/ +extern uint16 ATT_BuildFindByTypeValueRsp( uint8* pBuf, uint8* pMsg ); + +/* + Parse Find By Type Value Response. +*/ +extern bStatus_t ATT_ParseFindByTypeValueRsp( uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Build Read By Type Request. +*/ +extern uint16 ATT_BuildReadByTypeReq( uint8* pBuf, uint8* pMsg ); + +/* + Build Read By Type Response. +*/ +extern uint16 ATT_BuildReadByTypeRsp( uint8* pBuf, uint8* pMsg ); + +/* + Parse Read By Type Response. +*/ +extern bStatus_t ATT_ParseReadByTypeRsp( uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Build Read Request. +*/ +extern uint16 ATT_BuildReadReq( uint8* pBuf, uint8* pMsg ); + +/* + Build Read Response. +*/ +extern uint16 ATT_BuildReadRsp( uint8* pBuf, uint8* pMsg ); + +/* + Parse Read Response. +*/ +extern bStatus_t ATT_ParseReadRsp( uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Build Read Blob Request. +*/ +extern uint16 ATT_BuildReadBlobReq( uint8* pBuf, uint8* pMsg ); + +/* + Build Read Blob Response. +*/ +extern uint16 ATT_BuildReadBlobRsp( uint8* pBuf, uint8* pMsg ); + +/* + Parse Read Blob Response. +*/ +extern bStatus_t ATT_ParseReadBlobRsp( uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Build Read Multiple Request. +*/ +extern uint16 ATT_BuildReadMultiReq( uint8* pBuf, uint8* pMsg ); + +/* + Build Read Multiple Response. +*/ +extern uint16 ATT_BuildReadMultiRsp( uint8* pBuf, uint8* pMsg ); + +/* + Parse Read Multiple Response. +*/ +extern bStatus_t ATT_ParseReadMultiRsp( uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Build Read By Group Type Response. +*/ +extern uint16 ATT_BuildReadByGrpTypeRsp( uint8* pBuf, uint8* pMsg ); + +/* + Parse Read By Group Type Response. +*/ +extern bStatus_t ATT_ParseReadByGrpTypeRsp( uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Build Write Request. +*/ +extern uint16 ATT_BuildWriteReq( uint8* pBuf, uint8* pMsg ); + +/* + Parse Write Response. +*/ +extern bStatus_t ATT_ParseWriteRsp( uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Build Prepare Write Request. +*/ +extern uint16 ATT_BuildPrepareWriteReq( uint8* pBuf, uint8* pMsg ); + +/* + Build Prepare Write Response. +*/ +extern uint16 ATT_BuildPrepareWriteRsp( uint8* pBuf, uint8* pMsg ); + +/* + Parse Prepare Write Response. +*/ +extern bStatus_t ATT_ParsePrepareWriteRsp( uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Build Execute Write Request. +*/ +extern uint16 ATT_BuildExecuteWriteReq( uint8* pBuf, uint8* pMsg ); + +/* + Parse Execute Write Response. +*/ +extern bStatus_t ATT_ParseExecuteWriteRsp( uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Build Handle Value Indication. +*/ +extern uint16 ATT_BuildHandleValueInd( uint8* pBuf, uint8* pMsg ); + +/* + Parse Handle Value Indication. +*/ +extern bStatus_t ATT_ParseHandleValueInd( uint8 sig, uint8 cmd, uint8* pParams, uint16 len, attMsg_t* pMsg ); + + +/* ------------------------------------------------------------------- + Attribute Server Utility APIs +*/ + +/* + Parse Exchange MTU Request. +*/ +extern bStatus_t ATT_ParseExchangeMTUReq( uint8 sig, uint8 cmd, uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Parse Find Information Request. +*/ +extern bStatus_t ATT_ParseFindInfoReq( uint8 sig, uint8 cmd, uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Parse Find By Type Value Request. +*/ +extern bStatus_t ATT_ParseFindByTypeValueReq( uint8 sig, uint8 cmd, uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Parse Read By Type Request. +*/ +extern bStatus_t ATT_ParseReadByTypeReq( uint8 sig, uint8 cmd, uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Parse Read Request. +*/ +extern bStatus_t ATT_ParseReadReq( uint8 sig, uint8 cmd, uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Parse Write Blob Request. +*/ +extern bStatus_t ATT_ParseReadBlobReq( uint8 sig, uint8 cmd, uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Parse Read Multiple Request. +*/ +extern bStatus_t ATT_ParseReadMultiReq( uint8 sig, uint8 cmd, uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Parse Write Request. +*/ +extern bStatus_t ATT_ParseWriteReq( uint8 sig, uint8 cmd, uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Parse Execute Write Request. +*/ +extern bStatus_t ATT_ParseExecuteWriteReq( uint8 sig, uint8 cmd, uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Parse Prepare Write Request. +*/ +extern bStatus_t ATT_ParsePrepareWriteReq( uint8 sig, uint8 cmd, uint8* pParams, uint16 len, attMsg_t* pMsg ); + +/* + Parse Handle Value Confirmation. +*/ +extern bStatus_t ATT_ParseHandleValueCfm( uint8* pParams, uint16 len, attMsg_t* pMsg ); + + +/* ------------------------------------------------------------------- + Attribute Client Public APIs +*/ + +/** + @defgroup ATT_CLIENT_API ATT Client API Functions + + @{ +*/ + +/** + @brief Send Exchange MTU Request. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_ExchangeMTUReq( uint16 connHandle, attExchangeMTUReq_t* pReq ); + +/** + @brief Send Find Information Request. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_FindInfoReq( uint16 connHandle, attFindInfoReq_t* pReq ); + +/** + @brief Send Find By Type Value Request. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_FindByTypeValueReq( uint16 connHandle, attFindByTypeValueReq_t* pReq ); + +/** + @brief Send Read By Type Request. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_ReadByTypeReq( uint16 connHandle, attReadByTypeReq_t* pReq ); + +/** + @brief Send Read Request. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_ReadReq( uint16 connHandle, attReadReq_t* pReq ); + +/** + @brief Send Read Blob Request. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_ReadBlobReq( uint16 connHandle, attReadBlobReq_t* pReq ); + +/** + @brief Send Read Multiple Request. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_ReadMultiReq( uint16 connHandle, attReadMultiReq_t* pReq ); + +/** + @brief Send Read By Group Type Request. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_ReadByGrpTypeReq( uint16 connHandle, attReadByGrpTypeReq_t* pReq ); + +/** + @brief Send Write Request. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+ bleLinkEncrypted: Connection is already encrypted.
+*/ +extern bStatus_t ATT_WriteReq( uint16 connHandle, attWriteReq_t* pReq ); + +/** + @brief Send Prepare Write Request. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_PrepareWriteReq( uint16 connHandle, attPrepareWriteReq_t* pReq ); + +/** + @brief Send Execute Write Request. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_ExecuteWriteReq( uint16 connHandle, attExecuteWriteReq_t* pReq ); + +/** + @brief Send Handle Value Confirmation. + + @param connHandle - connection to use + + @return SUCCESS: Confirmation was sent successfully.
+ INVALIDPARAMETER: Invalid confirmation field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_HandleValueCfm( uint16 connHandle ); + +/** + @} +*/ + +/* ------------------------------------------------------------------- + Attribute Server Public APIs +*/ + +/** + @defgroup ATT_SERVER_API ATT Server API Functions + + @{ +*/ + +/** + @brief Send Error Response. + + @param connHandle - connection to use + @param pRsp - pointer to error response to be sent + + @return SUCCESS: Response was sent successfully.
+ INVALIDPARAMETER: Invalid response field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_ErrorRsp( uint16 connHandle, attErrorRsp_t* pRsp ); + +/** + @brief Send Exchange MTU Response. + + @param connHandle - connection to use + @param pRsp - pointer to request to be sent + + @return SUCCESS: Response was sent successfully.
+ INVALIDPARAMETER: Invalid response field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_ExchangeMTURsp( uint16 connHandle, attExchangeMTURsp_t* pRsp ); + +/** + @brief Send Find Information Response. + + @param connHandle - connection to use + @param pRsp - pointer to response to be sent + + @return SUCCESS: Response was sent successfully.
+ INVALIDPARAMETER: Invalid response field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_FindInfoRsp( uint16 connHandle, attFindInfoRsp_t* pRsp ); + +/** + @brief Send Find By Tyep Value Response. + + @param connHandle - connection to use + @param pRsp - pointer to response to be sent + + @return SUCCESS: Response was sent successfully.
+ INVALIDPARAMETER: Invalid response field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_FindByTypeValueRsp( uint16 connHandle, attFindByTypeValueRsp_t* pRsp ); + +/** + @brief Send Read By Type Respond. + + @param connHandle - connection to use + @param pRsp - pointer to response to be sent + + @return SUCCESS: Response was sent successfully.
+ INVALIDPARAMETER: Invalid response field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_ReadByTypeRsp( uint16 connHandle, attReadByTypeRsp_t* pRsp ); + +/** + @brief Send Read Response. + + @param connHandle - connection to use + @param pRsp - pointer to response to be sent + + @return SUCCESS: Response was sent successfully.
+ INVALIDPARAMETER: Invalid response field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_ReadRsp( uint16 connHandle, attReadRsp_t* pRsp ); + +/** + @brief Send Read Blob Response. + + @param connHandle - connection to use + @param pRsp - pointer to response to be sent + + @return SUCCESS: Response was sent successfully.
+ INVALIDPARAMETER: Invalid response field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_ReadBlobRsp( uint16 connHandle, attReadBlobRsp_t* pRsp ); + +/** + @brief Send Read Multiple Response. + + @param connHandle - connection to use + @param pRsp - pointer to response to be sent + + @return SUCCESS: Response was sent successfully.
+ INVALIDPARAMETER: Invalid response field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_ReadMultiRsp( uint16 connHandle, attReadMultiRsp_t* pRsp ) ; + +/** + @brief Send Read By Group Type Respond. + + @param connHandle - connection to use + @param pRsp - pointer to response to be sent + + @return SUCCESS: Response was sent successfully.
+ INVALIDPARAMETER: Invalid response field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_ReadByGrpTypeRsp( uint16 connHandle, attReadByGrpTypeRsp_t* pRsp ); + +/** + @brief Send Write Response. + + @param connHandle - connection to use + + @return SUCCESS: Response was sent successfully.
+ INVALIDPARAMETER: Invalid response field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_WriteRsp( uint16 connHandle ); + +/** + @brief Send Prepare Write Response. + + @param connHandle - connection to use + @param pRsp - pointer to response to be sent + + @return SUCCESS: Response was sent successfully.
+ INVALIDPARAMETER: Invalid response field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_PrepareWriteRsp( uint16 connHandle, attPrepareWriteRsp_t* pRsp ); + +/** + @brief Send Execute Write Response. + + @param connHandle - connection to use + + @return SUCCESS: Response was sent successfully.
+ INVALIDPARAMETER: Invalid response field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_ExecuteWriteRsp( uint16 connHandle ); + +/** + @brief Send Handle Value Notification. + + @param connHandle - connection to use + @param pNoti - pointer to notification to be sent + + @return SUCCESS: Notification was sent successfully.
+ INVALIDPARAMETER: Invalid notification field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_HandleValueNoti( uint16 connHandle, attHandleValueNoti_t* pNoti ); + +/** + @brief Send Handle Value Indication. + + @param connHandle - connection to use + @param pInd - pointer to indication to be sent + + @return SUCCESS: Indication was sent successfully.
+ INVALIDPARAMETER: Invalid indication field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t ATT_HandleValueInd( uint16 connHandle, attHandleValueInd_t* pInd ); + +/** + @} +*/ + +/** + @brief Set a ATT Parameter value. Use this function to change + the default ATT parameter values. + + @param value - new param value + + @return void +*/ +extern void ATT_SetParamValue( uint16 value ); + +/** + @brief Get a ATT Parameter value. + + @param none + + @return ATT Parameter value +*/ +extern uint16 ATT_GetParamValue( void ); + +extern uint16 ATT_GetCurrentMTUSize( uint16 connHandle ); +extern void ATT_UpdateMtuSize(uint16 connHandle, uint16 mtuSize); +extern void ATT_SetMTUSizeMax(uint16 mtuSize); +extern void ATT_MTU_SIZE_UPDATE(uint8 mtuSize); + +extern void ATT_InitMtuSize(void); + +//extern uint16 g_ATT_MTU_SIZE; +extern uint16 g_ATT_MTU_SIZE_MAX; +extern uint16 g_ATT_MAX_NUM_HANDLES; +extern uint16 g_ATT_MAX_NUM_HANDLES_INFO; +//extern uint16 g_ATT_MAX_NUM_HANDLE_BT_UUID; +extern attMTU_t g_attMtuClientServer; + + +// for multi-role +extern uint16 gAttMtuSize[]; + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* ATT_H */ diff --git a/arch/arm/src/phy62xx/ble/include/bcomdef.h b/arch/arm/src/phy62xx/ble/include/bcomdef.h new file mode 100644 index 00000000000..b0a8d7efdf8 --- /dev/null +++ b/arch/arm/src/phy62xx/ble/include/bcomdef.h @@ -0,0 +1,281 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/** + @headerfile: bcomdef.h + + +**************************************************************************************************/ + +#ifndef BCOMDEF_H +#define BCOMDEF_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/********************************************************************* + INCLUDES +*/ +#include "rom_sym_def.h" + +#include "comdef.h" +#include "log.h" + +//#define LOG_DEBUG(...) +//#define LOG(...) +//#define OM_LOG(...) +/********************************************************************* + CONSTANTS +*/ + + + +#define CTRL_CONFIG ( ADV_NCONN_CFG | ADV_CONN_CFG | SCAN_CFG | INIT_CFG ) + +//#if defined ( HOST_CONFIG ) +// // Set the Controller Configuration + +/* + // #if ( HOST_CONFIG == ( CENTRAL_CFG | PERIPHERAL_CFG ) ) + // #define CTRL_CONFIG ( ADV_NCONN_CFG | ADV_CONN_CFG | SCAN_CFG | INIT_CFG ) + // #elif ( HOST_CONFIG == ( CENTRAL_CFG | BROADCASTER_CFG ) ) + // #define CTRL_CONFIG ( ADV_NCONN_CFG | SCAN_CFG | INIT_CFG ) + // #elif ( HOST_CONFIG == ( PERIPHERAL_CFG | OBSERVER_CFG ) ) + // #define CTRL_CONFIG ( ADV_NCONN_CFG | ADV_CONN_CFG | SCAN_CFG ) + // #elif ( HOST_CONFIG == ( BROADCASTER_CFG | OBSERVER_CFG ) ) + // #define CTRL_CONFIG ( ADV_NCONN_CFG | SCAN_CFG ) + // #elif ( HOST_CONFIG == CENTRAL_CFG ) + // #define CTRL_CONFIG ( SCAN_CFG | INIT_CFG ) + // #elif ( HOST_CONFIG == PERIPHERAL_CFG ) + // #define CTRL_CONFIG ( ADV_NCONN_CFG | ADV_CONN_CFG ) + // #elif ( HOST_CONFIG == OBSERVER_CFG ) + // #define CTRL_CONFIG SCAN_CFG + // #elif ( HOST_CONFIG == BROADCASTER_CFG ) + // #define CTRL_CONFIG ADV_NCONN_CFG + // #else + // #error "Build Configuration Error: Invalid Host Role!" + // #endif + + //#else + // // Controller Sanity Check: Stop build when no configuration is defined. + // #if !defined( CTRL_CONFIG ) || !( CTRL_CONFIG & ( ADV_NCONN_CFG | \ + // ADV_CONN_CFG | \ + // SCAN_CFG | \ + // INIT_CFG ) ) + // #error "Build Configuration Error: At least one Controller build component required!" + // #endif // no Controller build components defined + //#endif +*/ + +#if !defined ( MAX_NUM_LL_CONN ) +#if ( CTRL_CONFIG & INIT_CFG ) +#define MAX_NUM_LL_CONN 8 +#elif ( !( CTRL_CONFIG & INIT_CFG ) && ( CTRL_CONFIG & ADV_CONN_CFG ) ) +#define MAX_NUM_LL_CONN 1 +#else // no connection needed +#define MAX_NUM_LL_CONN 0 +#endif // CTRL_CONFIG=INIT_CFG +#endif // !MAX_NUM_LL_CONN + +#define MAX_NUM_LL_CONN_ROM_LIMT 16 //hard code for BBB ROM define + +#if (MAX_NUM_LL_CONN_ROM_LIMT MAX_NUM_LL_CONN_ROM" +#endif + +/** @defgroup BLE_COMMON_DEFINES BLE Common Defines + @{ +*/ +//! Default Public and Random Address Length +#define B_ADDR_LEN 6 + +//! Default key length +#define KEYLEN 16 + +//! BLE Channel Map length +#define B_CHANNEL_MAP_LEN 5 + +//! BLE Event mask length +#define B_EVENT_MASK_LEN 8 + +//! BLE Local Name length +#define B_LOCAL_NAME_LEN 248 + +//! BLE Maximum Advertising Packet Length +#define B_MAX_ADV_LEN 31 + +#define B_MAX_EXT_ADV_LEN 229 +#define B_MAX_PERIOD_ADV_LEN 247 + +// 2020-01-14 AOA/AOD IQ Sample LEN +#define B_MAX_IQ_LEN 0x52 + +//! BLE Random Number Size +#define B_RANDOM_NUM_SIZE 8 + +//! BLE Feature Supported length +#define B_FEATURE_SUPPORT_LENGTH 8 + +/** @defgroup BLE_STATUS_VALUES BLE Default BLE Status Values + returned as bStatus_t + @{ +*/ +#define bleInvalidTaskID INVALID_TASK //!< Task ID isn't setup properly +#define bleNotReady 0x10 //!< Not ready to perform task +#define bleAlreadyInRequestedMode 0x11 //!< Already performing that task +#define bleIncorrectMode 0x12 //!< Not setup properly to perform that task +#define bleMemAllocError 0x13 //!< Memory allocation error occurred +#define bleNotConnected 0x14 //!< Can't perform function when not in a connection +#define bleNoResources 0x15 //!< There are no resource available +#define blePending 0x16 //!< Waiting +#define bleTimeout 0x17 //!< Timed out performing function +#define bleInvalidRange 0x18 //!< A parameter is out of range +#define bleLinkEncrypted 0x19 //!< The link is already encrypted +#define bleProcedureComplete 0x1A //!< The Procedure is completed + +// GAP Status Return Values - returned as bStatus_t +#define bleGAPUserCanceled 0x30 //!< The user canceled the task +#define bleGAPConnNotAcceptable 0x31 //!< The connection was not accepted +#define bleGAPBondRejected 0x32 //!< The bound information was rejected. + +// ATT Status Return Values - returned as bStatus_t +#define bleInvalidPDU 0x40 //!< The attribute PDU is invalid +#define bleInsufficientAuthen 0x41 //!< The attribute has insufficient authentication +#define bleInsufficientEncrypt 0x42 //!< The attribute has insufficient encryption +#define bleInsufficientKeySize 0x43 //!< The attribute has insufficient encryption key size + +// L2CAP Status Return Values - returned as bStatus_t + +#define INVALID_TASK_ID 0xFF //!< Task ID isn't setup properly +/** @} End BLE_STATUS_VALUES */ + +/** @defgroup BLE_NV_IDS BLE Non-volatile IDs + @{ +*/ +// Device NV Items - Range 0 - 0x1F +#define BLE_NVID_IRK 0x02 //!< The Device's IRK +#define BLE_NVID_CSRK 0x03 //!< The Device's CSRK +#define BLE_NVID_SIGNCOUNTER 0x04 //!< The Device's Sign Counter + +// Bonding NV Items - Range 0x20 - 0x5F - This allows for 10 bondings +#define BLE_NVID_GAP_BOND_START 0x20 //!< Start of the GAP Bond Manager's NV IDs +#define BLE_NVID_GAP_BOND_END 0x5f //!< End of the GAP Bond Manager's NV IDs Range + +// GATT Configuration NV Items - Range 0x70 - 0x79 - This must match the number of Bonding entries +#define BLE_NVID_GATT_CFG_START 0x70 //!< Start of the GATT Configuration NV IDs +#define BLE_NVID_GATT_CFG_END 0x79 //!< End of the GATT Configuration NV IDs +/** @} End BLE_NV_IDS */ + +/********************************************************************* + BLE OSAL GAP GLOBAL Events +*/ +#define GAP_EVENT_SIGN_COUNTER_CHANGED 0x4000 //!< The device level sign counter changed + + +/** @defgroup BLE_MSG_IDS BLE OSAL Message ID Events + Reserved Message ID Event Values:
+ 0xC0 - Key Presses
+ 0xE0 to 0xFC - App
+ @{ +*/ +// GAP - Messages IDs (0xD0 - 0xDF) +#define GAP_MSG_EVENT 0xD0 //!< Incoming GAP message + +// SM - Messages IDs (0xC1 - 0xCF) +#define SM_NEW_RAND_KEY_EVENT 0xC1 //!< New Rand Key Event message + +// GATT - Messages IDs (0xB0 - 0xBF) +#define GATT_MSG_EVENT 0xB0 //!< Incoming GATT message +#define GATT_SERV_MSG_EVENT 0xB1 //!< Incoming GATT Serv App message + +// L2CAP - Messages IDs (0xA0 - 0xAF) +#define L2CAP_DATA_EVENT 0xA0 //!< Incoming data on a channel +#define L2CAP_SIGNAL_EVENT 0xA2 //!< Incoming Signaling message + +// HCI - Messages IDs (0x90 - 0x9F) +#define HCI_DATA_EVENT 0x90 //!< HCI Data Event message +#define HCI_GAP_EVENT_EVENT 0x91 //!< GAP Event message +#define HCI_SMP_EVENT_EVENT 0x92 //!< SMP Event message +#define HCI_EXT_CMD_EVENT 0x93 //!< HCI Extended Command Event message +/** @} End BLE_MSG_IDS */ + +/********************************************************************* + TYPEDEFS +*/ + +//! BLE Generic Status return: @ref BLE_STATUS_VALUES +typedef Status_t bStatus_t; + +/** @} End GAP_MSG_EVENT_DEFINES */ + + +/********************************************************************* + System Events +*/ + +/********************************************************************* + Global System Messages +*/ + +/********************************************************************* + MACROS +*/ + +#define TI_BASE_UUID_128( uuid ) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, \ + 0x00, 0x40, 0x51, 0x04, LO_UINT16( uuid ), HI_UINT16( uuid ), 0x00, 0xF0 + +/********************************************************************* + GLOBAL VARIABLES +*/ + +/********************************************************************* + FUNCTIONS +*/ + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* BCOMDEF_H */ diff --git a/arch/arm/src/phy62xx/ble/include/gap.h b/arch/arm/src/phy62xx/ble/include/gap.h new file mode 100644 index 00000000000..e097448fd24 --- /dev/null +++ b/arch/arm/src/phy62xx/ble/include/gap.h @@ -0,0 +1,1182 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/** + @headerfile: gap.h + $Date: + $Revision: + +*/ + + +#ifndef GAP_H +#define GAP_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* ------------------------------------------------------------------- + INCLUDES +*/ +#include "bcomdef.h" +#include "OSAL.h" +#include "sm.h" + +/* ------------------------------------------------------------------- + MACROS +*/ + +/* ------------------------------------------------------------------- + CONSTANTS +*/ + +/** @defgroup BLE_GAP_DEFINES BLE GAP Constants and Structures + @{ +*/ + +/** @defgroup GAP_MSG_EVENT_DEFINES GAP Message IDs + @{ +*/ +#define GAP_DEVICE_INIT_DONE_EVENT 0x00 //!< Sent when the Device Initialization is complete. This event is sent as an OSAL message defined as gapDeviceInitDoneEvent_t. +#define GAP_DEVICE_DISCOVERY_EVENT 0x01 //!< Sent when the Device Discovery Process is complete. This event is sent as an OSAL message defined as gapDevDiscEvent_t. +#define GAP_ADV_DATA_UPDATE_DONE_EVENT 0x02 //!< Sent when the Advertising Data or SCAN_RSP Data has been updated. This event is sent as an OSAL message defined as gapAdvDataUpdateEvent_t. +#define GAP_MAKE_DISCOVERABLE_DONE_EVENT 0x03 //!< Sent when the Make Discoverable Request is complete. This event is sent as an OSAL message defined as gapMakeDiscoverableRspEvent_t. +#define GAP_END_DISCOVERABLE_DONE_EVENT 0x04 //!< Sent when the Advertising has ended. This event is sent as an OSAL message defined as gapEndDiscoverableRspEvent_t. +#define GAP_LINK_ESTABLISHED_EVENT 0x05 //!< Sent when the Establish Link Request is complete. This event is sent as an OSAL message defined as gapEstLinkReqEvent_t. +#define GAP_LINK_TERMINATED_EVENT 0x06 //!< Sent when a connection was terminated. This event is sent as an OSAL message defined as gapTerminateLinkEvent_t. +#define GAP_LINK_PARAM_UPDATE_EVENT 0x07 //!< Sent when an Update Parameters Event is received. This event is sent as an OSAL message defined as gapLinkUpdateEvent_t. +#define GAP_RANDOM_ADDR_CHANGED_EVENT 0x08 //!< Sent when a random address was changed. This event is sent as an OSAL message defined as gapRandomAddrEvent_t. +#define GAP_SIGNATURE_UPDATED_EVENT 0x09 //!< Sent when the device's signature counter is updated. This event is sent as an OSAL message defined as gapSignUpdateEvent_t. +#define GAP_AUTHENTICATION_COMPLETE_EVENT 0x0A //!< Sent when the Authentication (pairing) process is complete. This event is sent as an OSAL message defined as gapAuthCompleteEvent_t. +#define GAP_PASSKEY_NEEDED_EVENT 0x0B //!< Sent when a Passkey is needed. This is part of the pairing process. This event is sent as an OSAL message defined as gapPasskeyNeededEvent_t. +#define GAP_SLAVE_REQUESTED_SECURITY_EVENT 0x0C //!< Sent when a Slave Security Request is received. This event is sent as an OSAL message defined as gapSlaveSecurityReqEvent_t. +#define GAP_DEVICE_INFO_EVENT 0x0D //!< Sent during the Device Discovery Process when a device is discovered. This event is sent as an OSAL message defined as gapDeviceInfoEvent_t. +#define GAP_BOND_COMPLETE_EVENT 0x0E //!< Sent when the bonding(bound) process is complete. This event is sent as an OSAL message defined as gapBondCompleteEvent_t. +#define GAP_PAIRING_REQ_EVENT 0x0F //!< Sent when an unexpected Pairing Request is received. This event is sent as an OSAL message defined as gapPairingReqEvent_t. +/** @} End GAP_MSG_EVENT_DEFINES */ + +/** @defgroup GAP_CONN_HANDLE_DEFINES GAP Special Connection Handles + Used by GAP_TerminateLinkReq() + @{ +*/ +#define GAP_CONNHANDLE_INIT 0xFFFE //!< terminates a link create +#define GAP_CONNHANDLE_ALL 0xFFFF //!< terminates all links for the matching task ID. +/** @} End GAP_CONN_HANDLE_DEFINES */ + +/** @defgroup GAP_PROFILE_ROLE_DEFINES GAP Profile Roles + Bit mask values + @{ +*/ +#define GAP_PROFILE_BROADCASTER 0x01 //!< A device that sends advertising events only. +#define GAP_PROFILE_OBSERVER 0x02 //!< A device that receives advertising events only. +#define GAP_PROFILE_PERIPHERAL 0x04 //!< A device that accepts the establishment of an LE physical link using the connection establishment procedure +#define GAP_PROFILE_CENTRAL 0x08 //!< A device that supports the Central role initiates the establishment of a physical connection +/** @} End GAP_PROFILE_ROLE_DEFINES */ + +/** + @defgroup GAP_PARAMETER_ID_DEFINES GAP Parameter IDs + Used in place of gapParamIDs_t. + @{ +*/ +// Timers +#define TGAP_GEN_DISC_ADV_MIN 0 //!< Minimum time to remain advertising, when in Discoverable mode (mSec). Setting this parameter to 0 turns off the timeout (default). +#define TGAP_LIM_ADV_TIMEOUT 1 //!< Maximum time to remain advertising, when in Limited Discoverable mode. In seconds (default 180 seconds) +#define TGAP_GEN_DISC_SCAN 2 //!< Minimum time to perform scanning, when performing General Discovery proc (mSec) +#define TGAP_LIM_DISC_SCAN 3 //!< Minimum time to perform scanning, when performing Limited Discovery proc (mSec) +#define TGAP_CONN_EST_ADV_TIMEOUT 4 //!< Advertising timeout, when performing Connection Establishment proc (mSec) +#define TGAP_CONN_PARAM_TIMEOUT 5 //!< Link Layer connection parameter update notification timer, connection parameter update proc (mSec) + +// Constants +#define TGAP_LIM_DISC_ADV_INT_MIN 6 //!< Minimum advertising interval, when in limited discoverable mode (n * 0.625 mSec) +#define TGAP_LIM_DISC_ADV_INT_MAX 7 //!< Maximum advertising interval, when in limited discoverable mode (n * 0.625 mSec) +#define TGAP_GEN_DISC_ADV_INT_MIN 8 //!< Minimum advertising interval, when in General discoverable mode (n * 0.625 mSec) +#define TGAP_GEN_DISC_ADV_INT_MAX 9 //!< Maximum advertising interval, when in General discoverable mode (n * 0.625 mSec) +#define TGAP_CONN_ADV_INT_MIN 10 //!< Minimum advertising interval, when in Connectable mode (n * 0.625 mSec) +#define TGAP_CONN_ADV_INT_MAX 11 //!< Maximum advertising interval, when in Connectable mode (n * 0.625 mSec) +#define TGAP_CONN_SCAN_INT 12 //!< Scan interval used during Link Layer Initiating state, when in Connectable mode (n * 0.625 mSec) +#define TGAP_CONN_SCAN_WIND 13 //!< Scan window used during Link Layer Initiating state, when in Connectable mode (n * 0.625 mSec) +#define TGAP_CONN_HIGH_SCAN_INT 14 //!< Scan interval used during Link Layer Initiating state, when in Connectable mode, high duty scan cycle scan paramaters (n * 0.625 mSec) +#define TGAP_CONN_HIGH_SCAN_WIND 15 //!< Scan window used during Link Layer Initiating state, when in Connectable mode, high duty scan cycle scan paramaters (n * 0.625 mSec) +#define TGAP_GEN_DISC_SCAN_INT 16 //!< Scan interval used during Link Layer Scanning state, when in General Discovery proc (n * 0.625 mSec) +#define TGAP_GEN_DISC_SCAN_WIND 17 //!< Scan window used during Link Layer Scanning state, when in General Discovery proc (n * 0.625 mSec) +#define TGAP_LIM_DISC_SCAN_INT 18 //!< Scan interval used during Link Layer Scanning state, when in Limited Discovery proc (n * 0.625 mSec) +#define TGAP_LIM_DISC_SCAN_WIND 19 //!< Scan window used during Link Layer Scanning state, when in Limited Discovery proc (n * 0.625 mSec) +#define TGAP_CONN_EST_ADV 20 //!< Advertising interval, when using Connection Establishment proc (n * 0.625 mSec). Obsolete - Do not use. +#define TGAP_CONN_EST_INT_MIN 21 //!< Minimum Link Layer connection interval, when using Connection Establishment proc (n * 1.25 mSec) +#define TGAP_CONN_EST_INT_MAX 22 //!< Maximum Link Layer connection interval, when using Connection Establishment proc (n * 1.25 mSec) +#define TGAP_CONN_EST_SCAN_INT 23 //!< Scan interval used during Link Layer Initiating state, when using Connection Establishment proc (n * 0.625 mSec) +#define TGAP_CONN_EST_SCAN_WIND 24 //!< Scan window used during Link Layer Initiating state, when using Connection Establishment proc (n * 0.625 mSec) +#define TGAP_CONN_EST_SUPERV_TIMEOUT 25 //!< Link Layer connection supervision timeout, when using Connection Establishment proc (n * 10 mSec) +#define TGAP_CONN_EST_LATENCY 26 //!< Link Layer connection slave latency, when using Connection Establishment proc (in number of connection events) +#define TGAP_CONN_EST_MIN_CE_LEN 27 //!< Local informational parameter about min len of connection needed, when using Connection Establishment proc (n * 0.625 mSec) +#define TGAP_CONN_EST_MAX_CE_LEN 28 //!< Local informational parameter about max len of connection needed, when using Connection Establishment proc (n * 0.625 mSec) +#define TGAP_PRIVATE_ADDR_INT 29 //!< Minimum Time Interval between private (resolvable) address changes. In minutes (default 15 minutes) +#define TGAP_CONN_PAUSE_CENTRAL 30 //!< Central idle timer. In seconds (default 1 second) +#define TGAP_CONN_PAUSE_PERIPHERAL 31 //!< Minimum time upon connection establishment before the peripheral starts a connection update procedure. In seconds (default 5 seconds) + +// Proprietary +#define TGAP_SM_TIMEOUT 32 //!< SM Message Timeout (milliseconds). Default 30 seconds. +#define TGAP_SM_MIN_KEY_LEN 33 //!< SM Minimum Key Length supported. Default 7. +#define TGAP_SM_MAX_KEY_LEN 34 //!< SM Maximum Key Length supported. Default 16. +#define TGAP_FILTER_ADV_REPORTS 35 //!< Filter duplicate advertising reports. Default TRUE. +#define TGAP_SCAN_RSP_RSSI_MIN 36 //!< Minimum RSSI required for scan responses to be reported to the app. Default -127. +#define TGAP_REJECT_CONN_PARAMS 37 //!< Whether or not to reject Connection Parameter Update Request received on Central device. Default FALSE. + +#if !defined ( TESTMODES ) +#define TGAP_AUTH_TASK_ID 38 //!< Task ID override for Task Authentication control (for stack internal use only) +#define TGAP_PARAMID_MAX 39 //!< ID MAX-valid Parameter ID +#else +#define TGAP_GAP_TESTCODE 38 //!< GAP TestCodes - puts GAP into a test mode +#define TGAP_SM_TESTCODE 39 //!< SM TestCodes - puts SM into a test mode +#define TGAP_AUTH_TASK_ID 40 //!< Task ID override for Task Authentication control (for stack internal use only) +#define TGAP_PARAMID_MAX 41 //!< ID MAX-valid Parameter ID + +#define TGAP_GATT_TESTCODE 100 //!< GATT TestCodes - puts GATT into a test mode (paramValue maintained by GATT) +#define TGAP_ATT_TESTCODE 101 //!< ATT TestCodes - puts ATT into a test mode (paramValue maintained by ATT) +#define TGAP_GGS_TESTCODE 102 //!< GGS TestCodes - puts GGS into a test mode (paramValue maintained by GGS) +#endif + +/** @} End GAP_PARAMETER_ID_DEFINES */ + +/** @defgroup GAP_DEVDISC_MODE_DEFINES GAP Device Discovery Modes + @{ +*/ +#define DEVDISC_MODE_NONDISCOVERABLE 0x00 //!< No discoverable setting +#define DEVDISC_MODE_GENERAL 0x01 //!< General Discoverable devices +#define DEVDISC_MODE_LIMITED 0x02 //!< Limited Discoverable devices +#define DEVDISC_MODE_ALL 0x03 //!< Not filtered +/** @} End GAP_DEVDISC_MODE_DEFINES */ + +/** @defgroup GAP_ADDR_TYPE_DEFINES GAP Address Types + @{ +*/ +#define ADDRTYPE_PUBLIC 0x00 //!< Use the BD_ADDR +#define ADDRTYPE_STATIC 0x01 //!< Static address +#define ADDRTYPE_PRIVATE_NONRESOLVE 0x02 //!< Generate Non-Resolvable Private Address +#define ADDRTYPE_PRIVATE_RESOLVE 0x03 //!< Generate Resolvable Private Address +/** @} End GAP_ADDR_TYPE_DEFINES */ + +/** @defgroup GAP_ADVERTISEMENT_TYPE_DEFINES GAP Advertising Event Types + for eventType field in gapAdvertisingParams_t + @{ +*/ +#define GAP_ADTYPE_ADV_IND 0x00 //!< Connectable undirected advertisement +#define GAP_ADTYPE_ADV_HDC_DIRECT_IND 0x01 //!< Connectable high duty cycle directed advertisement +#define GAP_ADTYPE_ADV_SCAN_IND 0x02 //!< Scannable undirected advertisement +#define GAP_ADTYPE_ADV_NONCONN_IND 0x03 //!< Non-Connectable undirected advertisement +#define GAP_ADTYPE_ADV_LDC_DIRECT_IND 0x04 //!< Connectable low duty cycle directed advertisement +/** @} End GAP_ADVERTISEMENT_TYPE_DEFINES */ + +/** @defgroup GAP_ADVERTISEMENT_REPORT_TYPE_DEFINES GAP Advertising Report Event Types + for eventType field in gapDevRec_t and gapDeviceInfoEvent_t + @{ +*/ +#define GAP_ADRPT_ADV_IND 0x00 //!< Connectable undirected advertisement +#define GAP_ADRPT_ADV_DIRECT_IND 0x01 //!< Connectable directed advertisement +#define GAP_ADRPT_ADV_SCAN_IND 0x02 //!< Scannable undirected advertisement +#define GAP_ADRPT_ADV_NONCONN_IND 0x03 //!< Non-Connectable undirected advertisement +#define GAP_ADRPT_SCAN_RSP 0x04 //!< Scan Response +/** @} End GAP_ADVERTISEMENT_REPORT_TYPE_DEFINES */ + +/** @defgroup GAP_FILTER_POLICY_DEFINES GAP Advertiser Filter Scan Parameters + @{ +*/ +#define GAP_FILTER_POLICY_ALL 0x00 //!< Allow Scan Request from Any, Allow Connect Request from Any (default). +#define GAP_FILTER_POLICY_WHITE_SCAN 0x01 //!< Allow Scan Request from White List Only, Allow Connect from Any +#define GAP_FILTER_POLICY_WHITE_CON 0x02 //!< Allow Scan Request from Any, Connect from White List Only +#define GAP_FILTER_POLICY_WHITE 0x03 //!< Allow Scan Request and Connect from White List Only +/** @} End GAP_FILTER_POLICY_DEFINES */ + +//! Advertiser Channel Map +#define ADV_CHANMAP_SIZE 5 + +//! Maximum Pairing Passcode/Passkey value. Range of a passkey can be 0 - 999,999. +#define GAP_PASSCODE_MAX 999999 + +/** Sign Counter Initialized - Sign counter hasn't been used yet. Used when setting up + a connection's signing information. +*/ +#define GAP_INIT_SIGN_COUNTER 0xFFFFFFFF + +/** @defgroup GAP_ADVCHAN_DEFINES GAP Advertisement Channel Map + @{ +*/ +#define GAP_ADVCHAN_37 0x01 //!< Advertisement Channel 37 +#define GAP_ADVCHAN_38 0x02 //!< Advertisement Channel 38 +#define GAP_ADVCHAN_39 0x04 //!< Advertisement Channel 39 +#define GAP_ADVCHAN_ALL (GAP_ADVCHAN_37 | GAP_ADVCHAN_38 | GAP_ADVCHAN_39) //!< All Advertisement Channels Enabled +/** @} End GAP_ADVCHAN_DEFINES */ + +/** @defgroup GAP_WHITELIST_DEFINES GAP White List Options + @{ +*/ +#define WL_NOTUSED 0x00 //!< White list not used but the advertiser's address in this command is used +#define WL_USED 0x01 //!< White list is used and the advertiser's address in this command is not used. +/** @} End GAP_WHITELIST_DEFINES */ + +/** @defgroup GAP_ADTYPE_DEFINES GAP Advertisment Data Types + These are the data type identifiers for the data tokens in the advertisement data field. + @{ +*/ +#define GAP_ADTYPE_FLAGS 0x01 //!< Discovery Mode: @ref GAP_ADTYPE_FLAGS_MODES +#define GAP_ADTYPE_16BIT_MORE 0x02 //!< Service: More 16-bit UUIDs available +#define GAP_ADTYPE_16BIT_COMPLETE 0x03 //!< Service: Complete list of 16-bit UUIDs +#define GAP_ADTYPE_32BIT_MORE 0x04 //!< Service: More 32-bit UUIDs available +#define GAP_ADTYPE_32BIT_COMPLETE 0x05 //!< Service: Complete list of 32-bit UUIDs +#define GAP_ADTYPE_128BIT_MORE 0x06 //!< Service: More 128-bit UUIDs available +#define GAP_ADTYPE_128BIT_COMPLETE 0x07 //!< Service: Complete list of 128-bit UUIDs +#define GAP_ADTYPE_LOCAL_NAME_SHORT 0x08 //!< Shortened local name +#define GAP_ADTYPE_LOCAL_NAME_COMPLETE 0x09 //!< Complete local name +#define GAP_ADTYPE_POWER_LEVEL 0x0A //!< TX Power Level: 0xXX: -127 to +127 dBm +#define GAP_ADTYPE_OOB_CLASS_OF_DEVICE 0x0D //!< Simple Pairing OOB Tag: Class of device (3 octets) +#define GAP_ADTYPE_OOB_SIMPLE_PAIRING_HASHC 0x0E //!< Simple Pairing OOB Tag: Simple Pairing Hash C (16 octets) +#define GAP_ADTYPE_OOB_SIMPLE_PAIRING_RANDR 0x0F //!< Simple Pairing OOB Tag: Simple Pairing Randomizer R (16 octets) +#define GAP_ADTYPE_SM_TK 0x10 //!< Security Manager TK Value +#define GAP_ADTYPE_SM_OOB_FLAG 0x11 //!< Secutiry Manager OOB Flags +#define GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE 0x12 //!< Min and Max values of the connection interval (2 octets Min, 2 octets Max) (0xFFFF indicates no conn interval min or max) +#define GAP_ADTYPE_SIGNED_DATA 0x13 //!< Signed Data field +#define GAP_ADTYPE_SERVICES_LIST_16BIT 0x14 //!< Service Solicitation: list of 16-bit Service UUIDs +#define GAP_ADTYPE_SERVICES_LIST_128BIT 0x15 //!< Service Solicitation: list of 128-bit Service UUIDs +#define GAP_ADTYPE_SERVICE_DATA 0x16 //!< Service Data +#define GAP_ADTYPE_APPEARANCE 0x19 //!< Appearance +#define GAP_ADTYPE_MANUFACTURER_SPECIFIC 0xFF //!< Manufacturer Specific Data: first 2 octets contain the Company Identifier Code followed by the additional manufacturer specific data +/** @} End GAP_ADTYPE_DEFINES */ + +/** @defgroup GAP_ADTYPE_FLAGS_MODES GAP ADTYPE Flags Discovery Modes + @{ +*/ +#define GAP_ADTYPE_FLAGS_LIMITED 0x01 //!< Discovery Mode: LE Limited Discoverable Mode +#define GAP_ADTYPE_FLAGS_GENERAL 0x02 //!< Discovery Mode: LE General Discoverable Mode +#define GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED 0x04 //!< Discovery Mode: BR/EDR Not Supported +/** @} End GAP_ADTYPE_FLAGS_MODES */ + +/** @defgroup GAP_APPEARANCE_VALUES GAP Appearance Values + @{ +*/ +#define GAP_APPEARE_UNKNOWN 0x0000 //!< Unknown +#define GAP_APPEARE_GENERIC_PHONE 0x0040 //!< Generic Phone +#define GAP_APPEARE_GENERIC_COMPUTER 0x0080 //!< Generic Computer +#define GAP_APPEARE_GENERIC_WATCH 0x00C0 //!< Generic Watch +#define GAP_APPEARE_WATCH_SPORTS 0x00C1 //!< Watch: Sports Watch +#define GAP_APPEARE_GENERIC_CLOCK 0x0100 //!< Generic Clock +#define GAP_APPEARE_GENERIC_DISPLAY 0x0140 //!< Generic Display +#define GAP_APPEARE_GENERIC_RC 0x0180 //!< Generic Remote Control +#define GAP_APPEARE_GENERIC_EYE_GALSSES 0x01C0 //!< Generic Eye-glasses +#define GAP_APPEARE_GENERIC_TAG 0x0200 //!< Generic Tag +#define GAP_APPEARE_GENERIC_KEYRING 0x0240 //!< Generic Keyring +#define GAP_APPEARE_GENERIC_MEDIA_PLAYER 0x0280 //!< Generic Media Player +#define GAP_APPEARE_GENERIC_BARCODE_SCANNER 0x02C0 //!< Generic Barcode Scanner +#define GAP_APPEARE_GENERIC_THERMOMETER 0x0300 //!< Generic Thermometer +#define GAP_APPEARE_GENERIC_THERMO_EAR 0x0301 //!< Thermometer: Ear +#define GAP_APPEARE_GENERIC_HR_SENSOR 0x0340 //!< Generic Heart rate Sensor +#define GAP_APPEARE_GENERIC_HRS_BELT 0x0341 //!< Heart Rate Sensor: Heart Rate Belt +#define GAP_APPEARE_GENERIC_BLOOD_PRESSURE 0x0380 //!< Generic Blood Pressure +#define GAP_APPEARE_GENERIC_BP_ARM 0x0381 //!< Blood Pressure: Arm +#define GAP_APPEARE_GENERIC_BP_WRIST 0x0382 //!< Blood Pressure: Wrist +#define GAP_APPEARE_GENERIC_HID 0x03C0 //!< Generic Human Interface Device (HID) +#define GAP_APPEARE_HID_KEYBOARD 0x03C1 //!< HID Keyboard +#define GAP_APPEARE_HID_MOUSE 0x03C2 //!< HID Mouse +#define GAP_APPEARE_HID_JOYSTIC 0x03C3 //!< HID Joystick +#define GAP_APPEARE_HID_GAMEPAD 0x03C4 //!< HID Gamepad +#define GAP_APPEARE_HID_DIGITIZER_TYABLET 0x03C5 //!< HID Digitizer Tablet +#define GAP_APPEARE_HID_DIGITAL_CARDREADER 0x03C6 //!< HID Card Reader +#define GAP_APPEARE_HID_DIGITAL_PEN 0x03C7 //!< HID Digital Pen +#define GAP_APPEARE_HID_BARCODE_SCANNER 0x03C8 //!< HID Barcode Scanner +/** @} End GAP_APPEARANCE_VALUES */ + +/* ------------------------------------------------------------------- + TYPEDEFS - Initialization and Configuration +*/ + +/** + GAP Parameters IDs: @ref GAP_PARAMETER_ID_DEFINES +*/ +typedef uint16 gapParamIDs_t; + +/** + GAP event header format. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status + uint8 opcode; //!< GAP type of command. Ref: @ref GAP_MSG_EVENT_DEFINES +} gapEventHdr_t; + +/** + GAP_RANDOM_ADDR_CHANGED_EVENT message format. This message is sent to the + app when the random address changes. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status + uint8 opcode; //!< GAP_RANDOM_ADDR_CHANGED_EVENT + uint8 addrType; //!< Address type: @ref GAP_ADDR_TYPE_DEFINES + uint8 newRandomAddr[B_ADDR_LEN]; //!< the new calculated private addr +} gapRandomAddrEvent_t; + +/** + Connection parameters for the peripheral device. These numbers are used + to compare against connection events and request connection parameter + updates with the master. +*/ +typedef struct +{ + /** Minimum value for the connection event (interval. 0x0006 - 0x0C80 * 1.25 ms) */ + uint16 intervalMin; + /** Maximum value for the connection event (interval. 0x0006 - 0x0C80 * 1.25 ms) */ + uint16 intervalMax; + /** Number of LL latency connection events (0x0000 - 0x03e8) */ + uint16 latency; + /** Connection Timeout (0x000A - 0x0C80 * 10 ms) */ + uint16 timeout; +} gapPeriConnectParams_t; + +/** + GAP_DEVICE_INIT_DONE_EVENT message format. This message is sent to the + app when the Device Initialization is done [initiated by calling + GAP_DeviceInit()]. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status + uint8 opcode; //!< GAP_DEVICE_INIT_DONE_EVENT + uint8 devAddr[B_ADDR_LEN]; //!< Device's BD_ADDR + uint16 dataPktLen; //!< HC_LE_Data_Packet_Length + uint8 numDataPkts; //!< HC_Total_Num_LE_Data_Packets +} gapDeviceInitDoneEvent_t; + +/** + GAP_SIGNATURE_UPDATED_EVENT message format. This message is sent to the + app when the signature counter has changed. This message is to inform the + application in case it wants to save it to be restored on reboot or reconnect. + This message is sent to update a connection's signature counter and to update + this device's signature counter. If devAddr == BD_ADDR, then this message pertains + to this device. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status + uint8 opcode; //!< GAP_SIGNATURE_UPDATED_EVENT + uint8 addrType; //!< Device's address type for devAddr + uint8 devAddr[B_ADDR_LEN]; //!< Device's BD_ADDR, could be own address + uint32 signCounter; //!< new Signed Counter +} gapSignUpdateEvent_t; + +/** + GAP_DEVICE_INFO_EVENT message format. This message is sent to the + app during a Device Discovery Request, when a new advertisement or scan + response is received. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status + uint8 opcode; //!< GAP_DEVICE_INFO_EVENT + uint8 eventType; //!< Advertisement Type: @ref GAP_ADVERTISEMENT_REPORT_TYPE_DEFINES + uint8 addrType; //!< address type: @ref GAP_ADDR_TYPE_DEFINES + uint8 addr[B_ADDR_LEN]; //!< Address of the advertisement or SCAN_RSP + int8 rssi; //!< Advertisement or SCAN_RSP RSSI + uint8 dataLen; //!< Length (in bytes) of the data field (evtData) + uint8* pEvtData; //!< Data field of advertisement or SCAN_RSP +} gapDeviceInfoEvent_t; + +/* ------------------------------------------------------------------- + TYPEDEFS - Device Discovery +*/ + +/** + Type of device discovery (Scan) to perform. +*/ +typedef struct +{ + uint8 taskID; //!< Requesting App's Task ID, used to return results + uint8 mode; //!< Discovery Mode: @ref GAP_DEVDISC_MODE_DEFINES + uint8 activeScan; //!< TRUE for active scanning + uint8 whiteList; //!< TRUE to only allow advertisements from devices in the white list. +} gapDevDiscReq_t; + +/** + Type of device discovery (Scan) to perform. +*/ +typedef struct +{ + uint8 eventType; //!< Indicates advertising event type used by the advertiser: @ref GAP_ADVERTISEMENT_REPORT_TYPE_DEFINES + uint8 addrType; //!< Address Type: @ref GAP_ADDR_TYPE_DEFINES + uint8 addr[B_ADDR_LEN]; //!< Device's Address +} gapDevRec_t; + +/** + GAP_DEVICE_DISCOVERY_EVENT message format. This message is sent to the + Application after a scan is performed. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status + uint8 opcode; //!< GAP_DEVICE_DISCOVERY_EVENT + uint8 numDevs; //!< Number of devices found during scan + gapDevRec_t* pDevList; //!< array of device records +} gapDevDiscEvent_t; + +/** + Advertising Parameters +*/ +typedef struct +{ + uint8 eventType; //!< Advertise Event Type: @ref GAP_ADVERTISEMENT_TYPE_DEFINES + uint8 initiatorAddrType; //!< Initiator's address type: @ref GAP_ADDR_TYPE_DEFINES + uint8 initiatorAddr[B_ADDR_LEN]; //!< Initiator's addr - used only with connectable directed eventType (ADV_EVTTYPE_CONNECTABLE_DIRECTED). + uint8 channelMap; //!< Channel Map: Bit mask @ref GAP_ADVCHAN_DEFINES + uint8 filterPolicy; //!< Filer Policy: @ref GAP_FILTER_POLICY_DEFINES. Ignored when directed advertising is used. +} gapAdvertisingParams_t; + +/** + GAP_MAKE_DISCOVERABLE_DONE_EVENT message format. This message is sent to the + app when the Advertise config is complete. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status + uint8 opcode; //!< GAP_MAKE_DISCOVERABLE_DONE_EVENT + uint16 interval; //!< actual advertising interval selected by controller +} gapMakeDiscoverableRspEvent_t; + +/** + GAP_END_DISCOVERABLE_DONE_EVENT message format. This message is sent to the + app when the Advertising has stopped. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status + uint8 opcode; //!< GAP_END_DISCOVERABLE_DONE_EVENT +} gapEndDiscoverableRspEvent_t; + +/** + GAP_ADV_DATA_UPDATE_DONE_EVENT message format. This message is sent to the + app when Advertising Data Update is complete. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status + uint8 opcode; //!< GAP_ADV_DATA_UPDATE_DONE_EVENT + uint8 adType; //!< TRUE if advertising data, FALSE if SCAN_RSP +} gapAdvDataUpdateEvent_t; + +/* ------------------------------------------------------------------- + TYPEDEFS - Link Establishment +*/ + +/** + Establish Link Request parameters +*/ +typedef struct +{ + uint8 taskID; //!< Requesting App/Profile's Task ID + uint8 highDutyCycle; //!< TRUE to high duty cycle scan, FALSE if not. + uint8 whiteList; //!< Determines use of the white list: @ref GAP_WHITELIST_DEFINES + uint8 addrTypePeer; //!< Address type of the advertiser: @ref GAP_ADDR_TYPE_DEFINES + uint8 peerAddr[B_ADDR_LEN]; //!< Advertiser's address +} gapEstLinkReq_t; + +/** + Update Link Parameters Request parameters +*/ +typedef struct +{ + uint16 connectionHandle; //!< Connection handle of the update + uint16 intervalMin; //!< Minimum Connection Interval + uint16 intervalMax; //!< Maximum Connection Interval + uint16 connLatency; //!< Connection Latency + uint16 connTimeout; //!< Connection Timeout +} gapUpdateLinkParamReq_t; + +/** + GAP_LINK_ESTABLISHED_EVENT message format. This message is sent to the app + when the link request is complete.
+
+ For an Observer, this message is sent to complete the Establish Link Request.
+ For a Peripheral, this message is sent to indicate that a link has been created. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status + uint8 opcode; //!< GAP_LINK_ESTABLISHED_EVENT + uint8 devAddrType; //!< Device address type: @ref GAP_ADDR_TYPE_DEFINES + uint8 devAddr[B_ADDR_LEN]; //!< Device address of link + uint16 connectionHandle; //!< Connection Handle from controller used to ref the device + uint16 connInterval; //!< Connection Interval + uint16 connLatency; //!< Conenction Latency + uint16 connTimeout; //!< Connection Timeout + uint8 clockAccuracy; //!< Clock Accuracy +} gapEstLinkReqEvent_t; + +/** + GAP_LINK_PARAM_UPDATE_EVENT message format. This message is sent to the app + when the connection parameters update request is complete. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status + uint8 opcode; //!< GAP_LINK_PARAM_UPDATE_EVENT + uint8 status; //!< bStatus_t + uint16 connectionHandle; //!< Connection handle of the update + uint16 connInterval; //!< Requested connection interval + uint16 connLatency; //!< Requested connection latency + uint16 connTimeout; //!< Requested connection timeout +} gapLinkUpdateEvent_t; + +/** + GAP_LINK_TERMINATED_EVENT message format. This message is sent to the + app when a link to a device is terminated. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status + uint8 opcode; //!< GAP_LINK_TERMINATED_EVENT + uint16 connectionHandle; //!< connection Handle + uint8 reason; //!< termination reason from LL +} gapTerminateLinkEvent_t; + +/* ------------------------------------------------------------------- + TYPEDEFS - Authentication, Bounding and Pairing +*/ + +/** + GAP_PASSKEY_NEEDED_EVENT message format. This message is sent to the + app when a Passkey is needed from the app's user interface. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status + uint8 opcode; //!< GAP_PASSKEY_NEEDED_EVENT + uint8 deviceAddr[B_ADDR_LEN]; //!< address of device to pair with, and could be either public or random. + uint16 connectionHandle; //!< Connection handle + uint8 uiInputs; //!< Pairing User Interface Inputs - Ask user to input passcode + uint8 uiOutputs; //!< Pairing User Interface Outputs - Display passcode +} gapPasskeyNeededEvent_t; + +/** + GAP_AUTHENTICATION_COMPLETE_EVENT message format. This message is sent to the app + when the authentication request is complete. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status + uint8 opcode; //!< GAP_AUTHENTICATION_COMPLETE_EVENT + uint16 connectionHandle; //!< Connection Handle from controller used to ref the device + uint8 authState; //!< TRUE if the pairing was authenticated (MITM) + smSecurityInfo_t* pSecurityInfo; //!< BOUND - security information from this device + smSigningInfo_t* pSigningInfo; //!< Signing information + smSecurityInfo_t* pDevSecInfo; //!< BOUND - security information from connected device + smIdentityInfo_t* pIdentityInfo; //!< BOUND - identity information +} gapAuthCompleteEvent_t; + +/** + securityInfo and identityInfo are only used if secReqs.bondable == BOUND, which means that + the device is already bound and we should use the security information and keys. +*/ +typedef struct +{ + uint16 connectionHandle; //!< Connection Handle from controller, + smLinkSecurityReq_t secReqs; //!< Pairing Control info +} gapAuthParams_t; + +/** + GAP_SLAVE_REQUESTED_SECURITY_EVENT message format. This message is sent to the app + when a Slave Security Request is received. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status + uint8 opcode; //!< GAP_SLAVE_REQUESTED_SECURITY_EVENT + uint16 connectionHandle; //!< Connection Handle + uint8 deviceAddr[B_ADDR_LEN]; //!< address of device requesting security + uint8 authReq; //!< Authentication Requirements: Bit 2: MITM, Bits 0-1: bonding (0 - no bonding, 1 - bonding) + +} gapSlaveSecurityReqEvent_t; + +/** + GAP_BOND_COMPLETE_EVENT message format. This message is sent to the + app when a bonding is complete. This means that a key is loaded and the link is encrypted. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status + uint8 opcode; //!< GAP_BOND_COMPLETE_EVENT + uint16 connectionHandle; //!< connection Handle +} gapBondCompleteEvent_t; + +/** + Pairing Request fields - the parsed fields of the SMP Pairing Request command. +*/ +typedef struct +{ + uint8 ioCap; //!< Pairing Request ioCap field + uint8 oobDataFlag; //!< Pairing Request OOB Data Flag field + uint8 authReq; //!< Pairing Request Auth Req field + uint8 maxEncKeySize; //!< Pairing Request Maximum Encryption Key Size field + keyDist_t keyDist; //!< Pairing Request Key Distribution field +} gapPairingReq_t; + +/** + GAP_PAIRING_REQ_EVENT message format.
+
+ This message is sent to the + app when an unexpected Pairing Request is received. The application is + expected to setup for a Security Manager pairing/bonding.
+
+ To setup an SM Pairing, the application should call GAP_Authenticate() with these "pairReq" fields.
+
+ NOTE: This message should only be sent to peripheral devices. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< GAP_MSG_EVENT and status + uint8 opcode; //!< GAP_PAIRING_REQ_EVENT + uint16 connectionHandle; //!< connection Handle + gapPairingReq_t pairReq; //!< The Pairing Request fields received. +} gapPairingReqEvent_t; + +/** + GAP Advertisement/Scan Response Data Token - These data items are stored as low byte first (OTA + format). The data space for these items are passed in and maintained by + the calling application +*/ +typedef struct +{ + uint8 adType; //!< ADTYPE value: @ref GAP_ADTYPE_DEFINES + uint8 attrLen; //!< Number of bytes in the attribute data + uint8* pAttrData; //!< pointer to Attribute data +} gapAdvDataToken_t; + +/** @} End BLE_GAP_DEFINES */ + +/* ------------------------------------------------------------------- + GLOBAL VARIABLES +*/ + +/** + @defgroup GAP_API GAP API Functions + + @{ +*/ + +/* ------------------------------------------------------------------- + FUNCTIONS - Initialization and Configuation +*/ + +/** + @brief Called to setup the device. Call just once on initialization. + + NOTE: When initialization is complete, the calling app will be + sent the GAP_DEVICE_INIT_DONE_EVENT + + @param taskID - Default task ID to send events. + @param profileRole - GAP Profile Roles: @ref GAP_PROFILE_ROLE_DEFINES + @param maxScanResponses - maximum number to scan responses + we can receive during a device discovery. + @param pIRK - pointer to Identity Root Key, NULLKEY (all zeroes) if the app + wants the GAP to generate the key. + @param pSRK - pointer to Sign Resolving Key, NULLKEY if the app + wants the GAP to generate the key. + @param pSignCounter - 32 bit value used in the SM Signing + algorithm that shall be initialized to zero and incremented + with every new signing. This variable must also be maintained + by the application. + + @return SUCCESS - Processing, expect GAP_DEVICE_INIT_DONE_EVENT,
+ INVALIDPARAMETER - for invalid profile role or role combination,
+ bleIncorrectMode - trouble communicating with HCI +*/ +extern bStatus_t GAP_DeviceInit( uint8 taskID, + uint8 profileRole, + uint8 maxScanResponses, + uint8* pIRK, + uint8* pSRK, + uint32* pSignCounter ); + +/** + @brief Called to setup a GAP Advertisement/Scan Response data token. + + NOTE: The data in these items are stored as low byte first (OTA format). + The passed in structure "token" should be allocated by the calling app/profile + and not released until after calling GAP_RemoveAdvToken(). + + @param pToken - Advertisement/Scan response token to write. + + @return SUCCESS - advertisement token added to the GAP list
+ INVALIDPARAMETER - Invalid Advertisement Type or pAttrData is NULL
+ INVALID_MEM_SIZE - The tokens take up too much space and don't fit into Advertisment data and Scan Response Data
+ bleInvalidRange - token ID already exists.
+ bleIncorrectMode - not a peripheral device
+ bleMemAllocError - memory allocation failure, +*/ +extern bStatus_t GAP_SetAdvToken( gapAdvDataToken_t* pToken ); + +/** + @brief Called to read a GAP Advertisement/Scan Response data token. + + @param adType - Advertisement type to get + + @return pointer to the advertisement data token structure, NULL if not found. +*/ +extern gapAdvDataToken_t* GAP_GetAdvToken( uint8 adType ); + +/** + @brief Called to remove a GAP Advertisement/Scan Response data token. + + @param adType - Advertisement type to remove + + @return pointer to the token structure removed from the GAP ADType list + NULL if the requested adType wasn't found. +*/ +extern gapAdvDataToken_t* GAP_RemoveAdvToken( uint8 adType ); + +/** + @brief Called to rebuild and load Advertisement and Scan Response data from existing + GAP Advertisement Tokens. + + @return SUCCESS or bleIncorrectMode +*/ +extern bStatus_t GAP_UpdateAdvTokens( void ); + +/** + @brief Set a GAP Parameter value. Use this function to change + the default GAP parameter values. + + @param paramID - parameter ID: @ref GAP_PARAMETER_ID_DEFINES + @param paramValue - new param value + + @return SUCCESS or INVALIDPARAMETER (invalid paramID) +*/ +extern bStatus_t GAP_SetParamValue( gapParamIDs_t paramID, uint16 paramValue ); + +/** + @brief Get a GAP Parameter value. + + @param paramID - parameter ID: @ref GAP_PARAMETER_ID_DEFINES + + @return GAP Parameter value or 0xFFFF if invalid +*/ +extern uint16 GAP_GetParamValue( gapParamIDs_t paramID ); + +/** + @brief Setup the device's address type. If ADDRTYPE_PRIVATE_RESOLVE + is selected, the address will change periodically. + + @param addrType - @ref GAP_ADDR_TYPE_DEFINES + @param pStaticAddr - Only used with ADDRTYPE_STATIC + or ADDRTYPE_PRIVATE_NONRESOLVE type.
+ NULL to auto generate otherwise the application + can specify the address value + + @return SUCCESS: address type updated,
+ bleNotReady: Can't be called until GAP_DeviceInit() is called + and the init process is completed,
+ bleIncorrectMode: can't change with an active connection,
+ or INVALIDPARAMETER.
+ + If return value isn't SUCCESS, the address type remains + the same as before this call. +*/ +extern bStatus_t GAP_ConfigDeviceAddr( uint8 addrType, uint8* pStaticAddr ); + +/** + @brief Register your task ID to receive extra (unwanted) + HCI status and complete events. + + @param taskID - Default task ID to send events. + + @return none +*/ +extern void GAP_RegisterForHCIMsgs( uint8 taskID ); + +/* ------------------------------------------------------------------- + FUNCTIONS - Device Discovery +*/ + +/** + @brief Start a device discovery scan. + + @param pParams - Device Discovery parameters + + @return SUCCESS: scan started,
+ bleIncorrectMode: invalid profile role,
+ bleAlreadyInRequestedMode: not available
+*/ +extern bStatus_t GAP_DeviceDiscoveryRequest( gapDevDiscReq_t* pParams ); + +/** + @brief Cancel an existing device discovery request. + + @param taskID - used to return GAP_DEVICE_DISCOVERY_EVENT + + @return SUCCESS: cancel started,
+ bleInvalidTaskID: Not the task that started discovery,
+ bleIncorrectMode: not in discovery mode
+*/ +extern bStatus_t GAP_DeviceDiscoveryCancel( uint8 taskID ); + +/** + @brief Setup or change advertising. Also starts advertising. + + @param taskID - used to return GAP_DISCOVERABLE_RESPONSE_EVENT + @param pParams - advertising parameters + + @return SUCCESS: advertising started,
+ bleIncorrectMode: invalid profile role,
+ bleAlreadyInRequestedMode: not available at this time,
+ bleNotReady: advertising data isn't set up yet.
+*/ +extern bStatus_t GAP_MakeDiscoverable( uint8 taskID, gapAdvertisingParams_t* pParams ); + +/** + @brief Setup or change advertising and scan response data. + + NOTE: if the return status from this function is SUCCESS, + the task isn't complete until the GAP_ADV_DATA_UPDATE_DONE_EVENT + is sent to the calling application task. + + @param taskID - task ID of the app requesting the change + @param adType - TRUE - advertisement data, FALSE - scan response data + @param dataLen - Octet length of advertData + @param pAdvertData - advertising or scan response data + + @return SUCCESS: data accepted,
+ bleIncorrectMode: invalid profile role,
+*/ +extern bStatus_t GAP_UpdateAdvertisingData( uint8 taskID, uint8 adType, + uint8 dataLen, uint8* pAdvertData ); + +/** + @brief Stops advertising. + + @param taskID - of task that called GAP_MakeDiscoverable + + @return SUCCESS: stopping discoverable mode,
+ bleIncorrectMode: not in discoverable mode,
+ bleInvalidTaskID: not correct task
+*/ +extern bStatus_t GAP_EndDiscoverable( uint8 taskID ); + +/** + @brief Resolves a private address against an IRK. + + @param pIRK - pointer to the IRK + @param pAddr - pointer to the Resovable Private address + + @return SUCCESS: match,
+ FAILURE: don't match,
+ INVALIDPARAMETER: parameters invalid
+*/ +extern bStatus_t GAP_ResolvePrivateAddr( uint8* pIRK, uint8* pAddr ); + +/* ------------------------------------------------------------------- + FUNCTIONS - Link Establishment +*/ + +/** + @brief Establish a link to a slave device. + + @param pParams - link establishment parameters + + @return SUCCESS: started establish link process,
+ bleIncorrectMode: invalid profile role,
+ bleNotReady: a scan is in progress,
+ bleAlreadyInRequestedMode: can’t process now,
+ bleNoResources: Too many links
+*/ +extern bStatus_t GAP_EstablishLinkReq( gapEstLinkReq_t* pParams ); + +/** + @brief Terminate a link connection. + + @param taskID - requesting app's task id. + @param connectionHandle - connection handle of link to terminate + or @ref GAP_CONN_HANDLE_DEFINES + @param reason - terminate reason. + + @return SUCCESS: Terminate started,
+ bleIncorrectMode: No Link to terminate,
+ bleInvalidTaskID: not app that established link
+*/ +extern bStatus_t GAP_TerminateLinkReq( uint8 taskID, uint16 connectionHandle, uint8 reason ); + +/** + @brief Update the link parameters to a slave device. + + @param pParams - link update parameters + + @return SUCCESS: started update link process,
+ bleIncorrectMode: invalid profile role,
+ bleNotConnected: not in a connection
+*/ +extern bStatus_t GAP_UpdateLinkParamReq( gapUpdateLinkParamReq_t* pParams ); + +/** + @brief Returns the number of active connections. + + @return Number of active connections. +*/ +extern uint8 GAP_NumActiveConnections( void ); + +/* ------------------------------------------------------------------- + FUNCTIONS - Pairing +*/ + +/** + @brief Start the Authentication process with the requested device. + This function is used to Initiate/Allow pairing. + Called by both master and slave device (Central and Peripheral). + + NOTE: This function is called after the link is established. + + @param pParams - Authentication parameters + @param pPairReq - Enter these parameters if the Pairing Request was already received. + NULL, if waiting for Pairing Request or if initiating. + + @return SUCCESS,
+ bleIncorrectMode: Not correct profile role,
+ INVALIDPARAMETER,
+ bleNotConnected,
+ bleAlreadyInRequestedMode,
+ FAILURE - not workable.
+*/ +extern bStatus_t GAP_Authenticate( gapAuthParams_t* pParams, gapPairingReq_t* pPairReq ); + +/** + @brief Send a Pairing Failed message and end any existing pairing. + + @param connectionHandle - connection handle. + @param reason - Pairing Failed reason code. + + @return SUCCESS - function was successful,
+ bleMemAllocError - memory allocation error,
+ INVALIDPARAMETER - one of the parameters were invalid,
+ bleNotConnected - link not found,
+ bleInvalidRange - one of the parameters were not within range. +*/ +extern bStatus_t GAP_TerminateAuth( uint16 connectionHandle, uint8 reason ); + +/** + @brief Update the passkey in string format. This function is called by the + application/profile in response to receiving the + GAP_PASSKEY_NEEDED_EVENT message. + + NOTE: This function is the same as GAP_PasscodeUpdate(), except that + the passkey is passed in as a string format. + + @param pPasskey - new passkey - pointer to numeric string (ie. "019655" ). + This string's range is "000000" to "999999". + @param connectionHandle - connection handle. + + @return SUCCESS: will start pairing with this entry,
+ bleIncorrectMode: Link not found,
+ INVALIDPARAMETER: passkey == NULL or passkey isn't formatted properly.
+*/ +extern bStatus_t GAP_PasskeyUpdate( uint8* pPasskey, uint16 connectionHandle ); + +/** + @brief Update the passkey in a numeric value (not string). + This function is called by the application/profile in response + to receiving the GAP_PASSKEY_NEEDED_EVENT message. + + NOTE: This function is the same as GAP_PasskeyUpdate(), except that + the passkey is passed in as a non-string format. + + @param passcode - not string - range: 0 - 999,999. + @param connectionHandle - connection handle. + + @return SUCCESS: will start pairing with this entry,
+ bleIncorrectMode: Link not found,
+ INVALIDPARAMETER: passkey == NULL or passkey isn't formatted properly.
+*/ +extern bStatus_t GAP_PasscodeUpdate( uint32 passcode, uint16 connectionHandle ); + +/** + @brief Generate a Slave Requested Security message to the master. + + @param connectionHandle - connection handle. + @param authReq - Authentication Requirements: Bit 2: MITM, Bits 0-1: bonding (0 - no bonding, 1 - bonding) + + @return SUCCESS: will send,
+ bleNotConnected: Link not found,
+ bleIncorrectMode: wrong GAP role, must be a Peripheral Role
+*/ +extern bStatus_t GAP_SendSlaveSecurityRequest( uint16 connectionHandle, uint8 authReq ); + +/** + @brief Set up the connection to accept signed data. + + NOTE: This function is called after the link is established. + + @param connectionHandle - connection handle of the signing information + @param authenticated - TRUE if the signing information is authenticated, FALSE otherwise + @param pParams - signing parameters + + @return SUCCESS,
+ bleIncorrectMode: Not correct profile role,
+ INVALIDPARAMETER,
+ bleNotConnected,
+ FAILURE: not workable.
+*/ +extern bStatus_t GAP_Signable( uint16 connectionHandle, uint8 authenticated, smSigningInfo_t* pParams ); + +/** + @brief Set up the connection's bound paramaters. + + NOTE: This function is called after the link is established. + + @param connectionHandle - connection handle of the signing information + @param authenticated - this connection was previously authenticated + @param pParams - the connected device's security parameters + @param startEncryption - whether or not to start encryption + + @return SUCCESS,
+ bleIncorrectMode: Not correct profile role,
+ INVALIDPARAMETER,
+ bleNotConnected,
+ FAILURE: not workable.
+*/ +extern bStatus_t GAP_Bond( uint16 connectionHandle, uint8 authenticated, + smSecurityInfo_t* pParams, uint8 startEncryption ); + +/** + @} End GAP_API +*/ + +/* ------------------------------------------------------------------- + Internal API - These functions are only called from gap.c module. +*/ + +/** + @internal + + @brief Setup the device configuration parameters. + + @param taskID - Default task ID to send events. + @param profileRole - GAP Profile Roles + + @return SUCCESS or bleIncorrectMode +*/ +extern bStatus_t GAP_ParamsInit( uint8 taskID, uint8 profileRole ); + +/** + @internal + + @brief Setup the device security configuration parameters. + + @param pIRK - pointer to Identity Root Key, NULLKEY (all zeroes) if the app + wants the GAP to generate the key. + @param pSRK - pointer to Sign Resolving Key, NULLKEY if the app + wants the GAP to generate the key. + @param pSignCounter - 32 bit value used in the SM Signing + algorithm that shall be initialized to zero and incremented + with every new signing. This variable must also be maintained + by the application. + + @return none +*/ +extern void GAP_SecParamsInit( uint8* pIRK, uint8* pSRK, uint32* pSignCounter ); + +/** + @internal + + @brief Initialize the GAP Peripheral Dev Manager. + + @param none + + @return SUCCESS or bleMemAllocError +*/ +extern bStatus_t GAP_PeriDevMgrInit( void ); + +/** + @internal + + @brief Initialize the GAP Central Dev Manager. + + @param maxScanResponses - maximum number to scan responses + we can receive during a device discovery. + + @return SUCCESS or bleMemAllocError +*/ +extern bStatus_t GAP_CentDevMgrInit( uint8 maxScanResponses ); + +/** + @internal + + @brief Register the GAP Central Connection processing functions. + + @param none + + @return none +*/ +extern void GAP_CentConnRegister( void ); + + +/* ------------------------------------------------------------------- + TASK API - These functions must only be called OSAL. +*/ + +/** + @internal + + @brief GAP Task initialization function. + + @param taskID - GAP task ID. + + @return void +*/ +extern void GAP_Init( uint8 task_id ); + +/** + @internal + + @brief GAP Task event processing function. + + @param taskID - GAP task ID + @param events - GAP events. + + @return events not processed +*/ +extern uint16 GAP_ProcessEvent( uint8 task_id, uint16 events ); + + +/* ------------------------------------------------------------------- + -------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* GAP_H */ diff --git a/arch/arm/src/phy62xx/ble/include/gatt.h b/arch/arm/src/phy62xx/ble/include/gatt.h new file mode 100644 index 00000000000..b0995dee505 --- /dev/null +++ b/arch/arm/src/phy62xx/ble/include/gatt.h @@ -0,0 +1,1407 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/** + @headerfile: gatt.h + $Date: + $Revision: + + @mainpage BLE GATT API + + Description: This file contains Generic Attribute Profile (GATT) + definitions and prototypes.

+ + +*/ + +#ifndef GATT_H +#define GATT_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ +#include "bcomdef.h" +#include "OSAL.h" + +#include "att.h" + +/********************************************************************* + CONSTANTS +*/ + +/** @defgroup GATT_PERMIT_BITMAPS_DEFINES GATT Attribute Access Permissions Bit Fields + @{ +*/ + +#define GATT_PERMIT_READ 0x01 //!< Attribute is Readable +#define GATT_PERMIT_WRITE 0x02 //!< Attribute is Writable +#define GATT_PERMIT_AUTHEN_READ 0x04 //!< Read requires Authentication +#define GATT_PERMIT_AUTHEN_WRITE 0x08 //!< Write requires Authentication +#define GATT_PERMIT_AUTHOR_READ 0x10 //!< Read requires Authorization +#define GATT_PERMIT_AUTHOR_WRITE 0x20 //!< Write requires Authorization +#define GATT_PERMIT_ENCRYPT_READ 0x40 //!< Read requires Encryption +#define GATT_PERMIT_ENCRYPT_WRITE 0x80 //!< Write requires Encryption + +/** @} End GATT_PERMIT_BITMAPS_DEFINES */ + + +/** @defgroup GATT_NUM_PREPARE_WRITES_DEFINES GATT Maximum Number of Prepare Writes + @{ +*/ +#define PREPARE_QUEUE_STATIC +#if !defined( GATT_MAX_NUM_PREPARE_WRITES ) +#define GATT_MAX_NUM_PREPARE_WRITES 1//20 //!< GATT Maximum number of attributes that Attribute Server can prepare for writing per Attribute Client +#endif + +/** @} End GATT_NUM_PREPARE_WRITES_DEFINES */ + + +/** @defgroup GATT_ENCRYPT_KEY_SIZE_DEFINES GATT Encryption Key Size + @{ +*/ + +#define GATT_ENCRYPT_KEY_SIZE 16 //!< GATT Encryption Key Size used for encrypting a link + +/** @} End GATT_ENCRYPT_KEY_SIZE_DEFINES */ + + +/** @defgroup GATT_MAX_ATTR_SIZE_DEFINES GATT Maximum Attribute Value Length + @{ +*/ + +#define GATT_MAX_ATTR_SIZE 512 //!< GATT Maximum length of an attribute value + +/** @} End GATT_MAX_ATTR_SIZE_DEFINES */ + +// GATT Maximum number of connections (including loopback) +#define GATT_MAX_NUM_CONN ( MAX_NUM_LL_CONN + 1 ) + +// GATT Base Method +#define GATT_BASE_METHOD 0x40 + +// Attribute handle defintions +#define GATT_INVALID_HANDLE 0x0000 // Invalid attribute handle +#define GATT_MIN_HANDLE 0x0001 // Minimum attribute handle +#define GATT_MAX_HANDLE 0xFFFF // Maximum attribute handle + +/********************************************************************* + VARIABLES +*/ + +/********************************************************************* + MACROS +*/ + +// Attribute Access Permissions +#define gattPermitRead( a ) ( (a) & GATT_PERMIT_READ ) +#define gattPermitWrite( a ) ( (a) & GATT_PERMIT_WRITE ) +#define gattPermitAuthenRead( a ) ( (a) & GATT_PERMIT_AUTHEN_READ ) +#define gattPermitAuthenWrite( a ) ( (a) & GATT_PERMIT_AUTHEN_WRITE ) +#define gattPermitAuthorRead( a ) ( (a) & GATT_PERMIT_AUTHOR_READ ) +#define gattPermitAuthorWrite( a ) ( (a) & GATT_PERMIT_AUTHOR_WRITE ) +#define gattPermitEncryptRead( a ) ( (a) & GATT_PERMIT_ENCRYPT_READ ) +#define gattPermitEncryptWrite( a ) ( (a) & GATT_PERMIT_ENCRYPT_WRITE ) + +// Check for different UUID types +#define gattPrimaryServiceType( t ) ( ATT_CompareUUID( primaryServiceUUID, ATT_BT_UUID_SIZE, \ + (t).uuid, (t).len ) ) +#define gattSecondaryServiceType( t ) ( ATT_CompareUUID( secondaryServiceUUID, ATT_BT_UUID_SIZE, \ + (t).uuid, (t).len ) ) +#define gattCharacterType( t ) ( ATT_CompareUUID( characterUUID, ATT_BT_UUID_SIZE, \ + (t).uuid, (t).len ) ) +#define gattIncludeType( t ) ( ATT_CompareUUID( includeUUID, ATT_BT_UUID_SIZE, \ + (t).uuid, (t).len ) ) +#define gattServiceType( t ) ( gattPrimaryServiceType( (t) ) || \ + gattSecondaryServiceType( (t) ) ) + +/********************************************************************* + TYPEDEFS +*/ + +/** + GATT Read By Type Request format. +*/ +typedef struct +{ + uint8 discCharsByUUID; //!< Whether this is a GATT Discover Characteristics by UUID sub-procedure + attReadByTypeReq_t req; //!< Read By Type Request +} gattReadByTypeReq_t; + +/** + GATT Prepare Write Request format. +*/ +typedef struct +{ + uint16 handle; //!< Handle of the attribute to be written (must be first field) + uint16 offset; //!< Offset of the first octet to be written + uint8 len; //!< Length of value + uint8* pValue; //!< Part of the value of the attribute to be written (must be allocated) +} gattPrepareWriteReq_t; + +/** + GATT Write Long Request format. Do not change the order of the members. +*/ +typedef struct +{ + uint8 reliable; //!< Whether reliable writes requested (always FALSE for Write Long) + gattPrepareWriteReq_t req; //!< GATT Prepare Write Request + uint16 lastOffset; //!< Offset of last Prepare Write Request sent +} gattWriteLongReq_t; + +/** + GATT Reliable Writes Request format. Do not change the order of the members. +*/ +typedef struct +{ + uint8 reliable; //!< Whether reliable writes requested (always TRUE for Reliable Writes) + attPrepareWriteReq_t* pReqs; //!< Arrary of Prepare Write Requests (must be allocated) + uint8 numReqs; //!< Number of Prepare Write Requests + uint8 index; //!< Index of last Prepare Write Request sent + uint8 flags; //!< 0x00 - cancel all prepared writes. + //!< 0x01 - immediately write all pending prepared values. +} gattReliableWritesReq_t; + +/** + GATT Message format. It's a union of all attribute protocol/profile messages + used between the attribute protocol/profile and upper layer application. +*/ +typedef union +{ + // Request messages + attExchangeMTUReq_t exchangeMTUReq; //!< ATT Exchange MTU Request + attFindInfoReq_t findInfoReq; //!< ATT Find Information Request + attFindByTypeValueReq_t findByTypeValueReq; //!< ATT Find By Type Vaue Request + attReadByTypeReq_t readByTypeReq; //!< ATT Read By Type Request + attReadReq_t readReq; //!< ATT Read Request + attReadBlobReq_t readBlobReq; //!< ATT Read Blob Request + attReadMultiReq_t readMultiReq; //!< ATT Read Multiple Request + attReadByGrpTypeReq_t readByGrpTypeReq; //!< ATT Read By Group Type Request + attWriteReq_t writeReq; //!< ATT Write Request + attPrepareWriteReq_t prepareWriteReq; //!< ATT Prepare Write Request + attExecuteWriteReq_t executeWriteReq; //!< ATT Execute Write Request + gattReadByTypeReq_t gattReadByTypeReq; //!< GATT Read By Type Request + gattWriteLongReq_t gattWriteLongReq; //!< GATT Long Write Request + gattReliableWritesReq_t gattReliableWritesReq; //!< GATT Reliable Writes Request + + // Response messages + attErrorRsp_t errorRsp; //!< ATT Error Response + attExchangeMTURsp_t exchangeMTURsp; //!< ATT Exchange MTU Response + attFindInfoRsp_t findInfoRsp; //!< ATT Find Information Response + attFindByTypeValueRsp_t findByTypeValueRsp; //!< ATT Find By Type Vaue Response + attReadByTypeRsp_t readByTypeRsp; //!< ATT Read By Type Response + attReadRsp_t readRsp; //!< ATT Read Response + attReadBlobRsp_t readBlobRsp; //!< ATT Read Blob Response + attReadMultiRsp_t readMultiRsp; //!< ATT Read Multiple Response + attReadByGrpTypeRsp_t readByGrpTypeRsp; //!< ATT Read By Group Type Response + attPrepareWriteRsp_t prepareWriteRsp; //!< ATT Prepare Write Response + + // Indication and Notification messages + attHandleValueNoti_t handleValueNoti; //!< ATT Handle Value Notification + attHandleValueInd_t handleValueInd; //!< ATT Handle Value Indication +} gattMsg_t; + +/** + GATT OSAL GATT_MSG_EVENT message format. This message is used to forward an + incoming attribute protocol/profile message up to upper layer application. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< GATT_MSG_EVENT and status + uint16 connHandle; //!< Connection message was received on + uint8 method; //!< Type of message + gattMsg_t msg; //!< Attribute protocol/profile message +} gattMsgEvent_t; + +/** + GATT Attribute Type format. +*/ +typedef struct +{ + uint8 len; //!< Length of UUID + const uint8* uuid; //!< Pointer to UUID +} gattAttrType_t; + +/** + GATT Attribute format. +*/ +typedef struct attAttribute_t +{ + gattAttrType_t type; //!< Attribute type (2 or 16 octet UUIDs) + uint8 permissions; //!< Attribute permissions + uint16 handle; //!< Attribute handle - assigned internally by attribute server + uint8* const pValue; //!< Attribute value - encoding of the octet array is defined in + //!< the applicable profile. The maximum length of an attribute + //!< value shall be 512 octets. +} gattAttribute_t; + +/** + GATT Service format. +*/ +typedef struct +{ + uint16 numAttrs; //!< Number of attributes in attrs + + /** Array of attribute records. + NOTE: The list must start with a Service attribute followed by + all attributes associated with this Service attribute. + */ + gattAttribute_t* attrs; +} gattService_t; + +/********************************************************************* + VARIABLES +*/ + +/********************************************************************* + API FUNCTIONS +*/ + +/* ------------------------------------------------------------------- + GATT Client Public APIs +*/ + +/** + @defgroup GATT_CLIENT_API GATT Client API Functions + + @{ +*/ + +/** + @brief Initialize the Generic Attribute Profile Client. + + @return SUCCESS +*/ +extern bStatus_t GATT_InitClient( void ); + +/** + @brief Register to receive incoming ATT Indications or Notifications + of attribute values. + + @param taskId ? task to forward indications or notifications to + + @return void +*/ +extern void GATT_RegisterForInd( uint8 taskId ); + +/** + @brief The Prepare Write Request is used to request the server to + prepare to write the value of an attribute. + + Note: This function is needed only for GATT testing. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + @param taskId - task to be notified of response + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A response is pending with this server.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_PrepareWriteReq( uint16 connHandle, attPrepareWriteReq_t* pReq, uint8 taskId ); + +/** + @brief The Execute Write Request is used to request the server to + write or cancel the write of all the prepared values currently + held in the prepare queue from this client. + + Note: This function is needed only for GATT testing. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + @param taskId - task to be notified of response + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A response is pending with this server.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_ExecuteWriteReq( uint16 connHandle, attExecuteWriteReq_t* pReq, uint8 taskId ); + +/** + @} +*/ + +/* ------------------------------------------------------------------- + GATT Server Public APIs +*/ + +/** + @defgroup GATT_SERVER_API GATT Server API Functions + + @{ +*/ + +/** + @brief Initialize the Generic Attribute Profile Server. + + @return SUCCESS +*/ +extern bStatus_t GATT_InitServer( void ); + +/** + @brief Register a service attribute list with the GATT Server. A service + is composed of characteristics or references to other services. + Each characteristic contains a value and may contain optional + information about the value. There are two types of services: + primary service and secondary service. + + A service definition begins with a service declaration and ends + before the next service declaration or the maximum Attribute Handle. + + A characteristic definition begins with a characteristic declaration + and ends before the next characteristic or service declaration or + maximum Attribute Handle. + + The attribute server will only keep a pointer to the attribute + list, so the calling application will have to maintain the code + and RAM associated with this list. + + @param pService - pointer to service attribute list to be registered + + @return SUCCESS: Service registered successfully.
+ INVALIDPARAMETER: Invalid service field.
+ FAILURE: Not enough attribute handles available.
+ bleMemAllocError: Memory allocation error occurred.
+*/ +extern bStatus_t GATT_RegisterService( gattService_t* pService ); + +/** + @brief Deregister a service attribute list with the GATT Server. + + NOTE: It's the caller's responsibility to free the service attribute + list returned from this API. + + @param handle - handle of service to be deregistered + @param pService - pointer to deregistered service (to be returned) + + @return SUCCESS: Service deregistered successfully.
+ FAILURE: Service not found.
+*/ +extern bStatus_t GATT_DeregisterService( uint16 handle, gattService_t* pService ); + +/** + @brief Register to receive incoming ATT Requests. + + @param taskId ? task to forward requests to + + @return void +*/ +extern void GATT_RegisterForReq( uint8 taskId ); + +/** + @brief Verify the permissions of an attribute for reading. + + @param connHandle - connection to use + @param permissions - attribute permissions + + @return SUCCESS: Attribute can be read.
+ ATT_ERR_READ_NOT_PERMITTED: Attribute cannot be read.
+ ATT_ERR_INSUFFICIENT_AUTHEN: Attribute requires authentication.
+ ATT_ERR_INSUFFICIENT_KEY_SIZE: Key Size used for encrypting is insufficient.
+ ATT_ERR_INSUFFICIENT_ENCRYPT: Attribute requires encryption.
+*/ +extern bStatus_t GATT_VerifyReadPermissions( uint16 connHandle, uint8 permissions ); + +/** + @brief Verify the permissions of an attribute for writing. + + @param connHandle - connection to use + @param permissions - attribute permissions + @param pReq - pointer to write request + + @return SUCCESS: Attribute can be written.
+ ATT_ERR_READ_NOT_PERMITTED: Attribute cannot be written.
+ ATT_ERR_INSUFFICIENT_AUTHEN: Attribute requires authentication.
+ ATT_ERR_INSUFFICIENT_KEY_SIZE: Key Size used for encrypting is insufficient.
+ ATT_ERR_INSUFFICIENT_ENCRYPT: Attribute requires encryption.
+*/ +extern bStatus_t GATT_VerifyWritePermissions( uint16 connHandle, uint8 permissions, attWriteReq_t* pReq ); + +/** + @brief Send out a Service Changed Indication. + + @param connHandle - connection to use + @param taskId - task to be notified of confirmation + + @return SUCCESS: Indication was sent successfully.
+ FAILURE: Service Changed attribute not found.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A confirmation is pending with this client.
+*/ +extern uint8 GATT_ServiceChangedInd( uint16 connHandle, uint8 taskId ); + +/** + @brief Find the attribute record for a given handle and UUID. + + @param startHandle - first handle to look for + @param endHandle - last handle to look for + @param pUUID - pointer to UUID to look for + @param len - length of UUID + @param pHandle - handle of owner of attribute (to be returned) + + @return Pointer to attribute record. NULL, otherwise. +*/ +extern gattAttribute_t* GATT_FindHandleUUID( uint16 startHandle, uint16 endHandle, const uint8* pUUID, + uint16 len, uint16* pHandle ); +/** + @brief Find the attribute record for a given handle + + @param handle - handle to look for + @param pHandle - handle of owner of attribute (to be returned) + + @return Pointer to attribute record. NULL, otherwise. +*/ +extern gattAttribute_t* GATT_FindHandle( uint16 handle, uint16* pHandle ); + +/** + @brief Find the next attribute of the same type for a given attribute. + + @param pAttr - pointer to attribute to find a next for + @param endHandle - last handle to look for + @param service - handle of owner service + @param pLastHandle - handle of last attribute (to be returned) + + @return Pointer to next attribute record. NULL, otherwise. +*/ +extern gattAttribute_t* GATT_FindNextAttr( gattAttribute_t* pAttr, uint16 endHandle, + uint16 service, uint16* pLastHandle ); +/** + @brief Get the number of attributes for a given service + + @param handle - service handle to look for + + @return Number of attributes. 0, otherwise. +*/ +extern uint16 GATT_ServiceNumAttrs( uint16 handle ); + +/** + @} +*/ + +/* ------------------------------------------------------------------- + GATT Server Sub-Procedure APIs +*/ + +/** + @defgroup GATT_SERVER_SUB_PROCEDURE_API GATT Server Sub-Procedure API Functions + + @{ +*/ + +/** + @brief This sub-procedure is used when a server is configured to + indicate a characteristic value to a client and expects an + attribute protocol layer acknowledgement that the indication + was successfully received. + + The ATT Handle Value Indication is used in this sub-procedure. + + If the return status from this function is SUCCESS, the calling + application task will receive an OSAL GATT_MSG_EVENT message. + The type of the message will be ATT_HANDLE_VALUE_CFM. + + Note: This sub-procedure is complete when ATT_HANDLE_VALUE_CFM + (with SUCCESS or bleTimeout status) is received by the + calling application task. + + @param connHandle - connection to use + @param pInd - pointer to indication to be sent + @param authenticated - whether an authenticated link is required + @param taskId - task to be notified of response + + @return SUCCESS: Indication was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A confirmation is pending with this client.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_Indication( uint16 connHandle, attHandleValueInd_t* pInd, + uint8 authenticated, uint8 taskId ); +/** + @brief This sub-procedure is used when a server is configured to + notify a characteristic value to a client without expecting + any attribute protocol layer acknowledgement that the + notification was successfully received. + + The ATT Handle Value Notification is used in this sub-procedure. + + Note: A notification may be sent at any time and does not + invoke a confirmation. + + No confirmation will be sent to the calling application task for + this sub-procedure. + + @param connHandle - connection to use + @param pNoti - pointer to notification to be sent + @param authenticated - whether an authenticated link is required + + @return SUCCESS: Notification was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_Notification( uint16 connHandle, attHandleValueNoti_t* pNoti, + uint8 authenticated ); +/** + @} +*/ + +/* ------------------------------------------------------------------- + GATT Client Sub-Procedure APIs +*/ + +/** + @defgroup GATT_CLIENT_SUB_PROCEDURE_API GATT Client Sub-Procedure API Functions + + @{ +*/ + +/** + @brief This sub-procedure is used by the client to set the ATT_MTU + to the maximum possible value that can be supported by both + devices when the client supports a value greater than the + default ATT_MTU for the Attribute Protocol. This sub-procedure + shall only be initiated once during a connection. + + The ATT Exchange MTU Request is used by this sub-procedure. + + If the return status from this function is SUCCESS, the calling + application task will receive an OSAL GATT_MSG_EVENT message. + The type of the message will be either ATT_EXCHANGE_MTU_RSP or + ATT_ERROR_RSP (if an error occurred on the server). + + Note: This sub-procedure is complete when either ATT_EXCHANGE_MTU_RSP + (with SUCCESS or bleTimeout status) or ATT_ERROR_RSP (with + SUCCESS status) is received by the calling application task. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + @param taskId - task to be notified of response + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A response is pending with this server.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_ExchangeMTU( uint16 connHandle, attExchangeMTUReq_t* pReq, uint8 taskId ); + +/** + @brief This sub-procedure is used by a client to discover all + the primary services on a server. + + The ATT Read By Group Type Request is used with the Attribute + Type parameter set to the UUID for "Primary Service". The + Starting Handle is set to 0x0001 and the Ending Handle is + set to 0xFFFF. + + If the return status from this function is SUCCESS, the calling + application task will receive multiple OSAL GATT_MSG_EVENT messages. + The type of the messages will be either ATT_READ_BY_GRP_TYPE_RSP + or ATT_ERROR_RSP (if an error occurred on the server). + + Note: This sub-procedure is complete when either ATT_READ_BY_GRP_TYPE_RSP + (with bleProcedureComplete or bleTimeout status) or ATT_ERROR_RSP + (with SUCCESS status) is received by the calling application + task. + + @param connHandle - connection to use + @param taskId - task to be notified of response + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A response is pending with this server.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_DiscAllPrimaryServices( uint16 connHandle, uint8 taskId ); + +/** + @brief This sub-procedure is used by a client to discover a specific + primary service on a server when only the Service UUID is + known. The primary specific service may exist multiple times + on a server. The primary service being discovered is identified + by the service UUID. + + The ATT Find By Type Value Request is used with the Attribute + Type parameter set to the UUID for "Primary Service" and the + Attribute Value set to the 16-bit Bluetooth UUID or 128-bit + UUID for the specific primary service. The Starting Handle shall + be set to 0x0001 and the Ending Handle shall be set to 0xFFFF. + + If the return status from this function is SUCCESS, the calling + application task will receive multiple OSAL GATT_MSG_EVENT messages. + The type of the messages will be either ATT_FIND_BY_TYPE_VALUE_RSP + or ATT_ERROR_RSP (if an error occurred on the server). + + Note: This sub-procedure is complete when either ATT_FIND_BY_TYPE_VALUE_RSP + (with bleProcedureComplete or bleTimeout status) or ATT_ERROR_RSP + (with SUCCESS status) is received by the calling application task. + + @param connHandle - connection to use + @param pValue - pointer to value to look for + @param len - length of value + @param taskId - task to be notified of response + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A response is pending with this server.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_DiscPrimaryServiceByUUID( uint16 connHandle, uint8* pValue, + uint8 len, uint8 taskId ); +/** + @brief This sub-procedure is used by a client to find include + service declarations within a service definition on a + server. The service specified is identified by the service + handle range. + + The ATT Read By Type Request is used with the Attribute + Type parameter set to the UUID for "Included Service". The + Starting Handle is set to starting handle of the specified + service and the Ending Handle is set to the ending handle + of the specified service. + + If the return status from this function is SUCCESS, the calling + application task will receive multiple OSAL GATT_MSG_EVENT messages. + The type of the messages will be either ATT_READ_BY_TYPE_RSP + or ATT_ERROR_RSP (if an error occurred on the server). + + Note: This sub-procedure is complete when either ATT_READ_BY_TYPE_RSP + (with bleProcedureComplete or bleTimeout status) or ATT_ERROR_RSP + (with SUCCESS status) is received by the calling application task. + + @param connHandle - connection to use + @param startHandle - starting handle + @param endHandle - end handle + @param taskId - task to be notified of response + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A response is pending with this server.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_FindIncludedServices( uint16 connHandle, uint16 startHandle, + uint16 endHandle, uint8 taskId ); +/** + @brief This sub-procedure is used by a client to find all the + characteristic declarations within a service definition on + a server when only the service handle range is known. The + service specified is identified by the service handle range. + + The ATT Read By Type Request is used with the Attribute Type + parameter set to the UUID for "Characteristic". The Starting + Handle is set to starting handle of the specified service and + the Ending Handle is set to the ending handle of the specified + service. + + If the return status from this function is SUCCESS, the calling + application task will receive multiple OSAL GATT_MSG_EVENT messages. + The type of the messages will be either ATT_READ_BY_TYPE_RSP + or ATT_ERROR_RSP (if an error occurred on the server). + + Note: This sub-procedure is complete when either ATT_READ_BY_TYPE_RSP + (with bleProcedureComplete or bleTimeout status) or ATT_ERROR_RSP + (with SUCCESS status) is received by the calling application task. + + @param connHandle - connection to use + @param startHandle - starting handle + @param endHandle - end handle + @param taskId - task to be notified of response + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A response is pending with this server.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_DiscAllChars( uint16 connHandle, uint16 startHandle, + uint16 endHandle, uint8 taskId ); +/** + @brief This sub-procedure is used by a client to discover service + characteristics on a server when only the service handle + ranges are known and the characteristic UUID is known. + The specific service may exist multiple times on a server. + The characteristic being discovered is identified by the + characteristic UUID. + + The ATT Read By Type Request is used with the Attribute Type + is set to the UUID for "Characteristic" and the Starting + Handle and Ending Handle parameters is set to the service + handle range. + + If the return status from this function is SUCCESS, the calling + application task will receive multiple OSAL GATT_MSG_EVENT messages. + The type of the messages will be either ATT_READ_BY_TYPE_RSP + or ATT_ERROR_RSP (if an error occurred on the server). + + Note: This sub-procedure is complete when either ATT_READ_BY_TYPE_RSP + (with bleProcedureComplete or bleTimeout status) or ATT_ERROR_RSP + (with SUCCESS status) is received by the calling application task. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + @param taskId - task to be notified of response + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A response is pending with this server.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_DiscCharsByUUID( uint16 connHandle, attReadByTypeReq_t* pReq, uint8 taskId ); + +/** + @brief This sub-procedure is used by a client to find all the + characteristic descriptor’s Attribute Handles and Attribute + Types within a characteristic definition when only the + characteristic handle range is known. The characteristic + specified is identified by the characteristic handle range. + + The ATT Find Information Request is used with the Starting + Handle set to starting handle of the specified characteristic + and the Ending Handle set to the ending handle of the specified + characteristic. The UUID Filter parameter is NULL (zero length). + + If the return status from this function is SUCCESS, the calling + application task will receive multiple OSAL GATT_MSG_EVENT messages. + The type of the messages will be either ATT_FIND_INFO_RSP or + ATT_ERROR_RSP (if an error occurred on the server). + + Note: This sub-procedure is complete when either ATT_FIND_INFO_RSP + (with bleProcedureComplete or bleTimeout status) or ATT_ERROR_RSP + (with SUCCESS status) is received by the calling application task. + + @param connHandle - connection to use + @param startHandle - starting handle + @param endHandle - end handle + @param taskId - task to be notified of response + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A response is pending with this server.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_DiscAllCharDescs( uint16 connHandle, uint16 startHandle, + uint16 endHandle, uint8 taskId ); +/** + @brief This sub-procedure is used to read a Characteristic Value + from a server when the client knows the Characteristic Value + Handle. The ATT Read Request is used with the Attribute Handle + parameter set to the Characteristic Value Handle. The Read + Response returns the Characteristic Value in the Attribute + Value parameter. + + The Read Response only contains a Characteristic Value that + is less than or equal to (ATT_MTU ? 1) octets in length. If + the Characteristic Value is greater than (ATT_MTU ? 1) octets + in length, the Read Long Characteristic Value procedure may + be used if the rest of the Characteristic Value is required. + + If the return status from this function is SUCCESS, the calling + application task will receive an OSAL GATT_MSG_EVENT message. + The type of the message will be either ATT_READ_RSP or + ATT_ERROR_RSP (if an error occurred on the server). + + Note: This sub-procedure is complete when either ATT_READ_RSP + (with SUCCESS or bleTimeout status) or ATT_ERROR_RSP (with + SUCCESS status) is received by the calling application task. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + @param taskId - task to be notified of response + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A response is pending with this server.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_ReadCharValue( uint16 connHandle, attReadReq_t* pReq, uint8 taskId ); + +/** + @brief This sub-procedure is used to read a Characteristic Value + from a server when the client only knows the characteristic + UUID and does not know the handle of the characteristic. + + The ATT Read By Type Request is used to perform the sub-procedure. + The Attribute Type is set to the known characteristic UUID and + the Starting Handle and Ending Handle parameters shall be set + to the range over which this read is to be performed. This is + typically the handle range for the service in which the + characteristic belongs. + + If the return status from this function is SUCCESS, the calling + application task will receive an OSAL GATT_MSG_EVENT messages. + The type of the message will be either ATT_READ_BY_TYPE_RSP + or ATT_ERROR_RSP (if an error occurred on the server). + + Note: This sub-procedure is complete when either ATT_READ_BY_TYPE_RSP + (with SUCCESS or bleTimeout status) or ATT_ERROR_RSP (with + SUCCESS status) is received by the calling application task. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + @param taskId - task to be notified of response + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A response is pending with this server.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_ReadUsingCharUUID( uint16 connHandle, attReadByTypeReq_t* pReq, uint8 taskId ); +/** + @brief This sub-procedure is used to read a Characteristic Value from + a server when the client knows the Characteristic Value Handle + and the length of the Characteristic Value is longer than can + be sent in a single Read Response Attribute Protocol message. + + The ATT Read Blob Request is used in this sub-procedure. + + If the return status from this function is SUCCESS, the calling + application task will receive multiple OSAL GATT_MSG_EVENT messages. + The type of the messages will be either ATT_READ_BLOB_RSP or + ATT_ERROR_RSP (if an error occurred on the server). + + Note: This sub-procedure is complete when either ATT_READ_BLOB_RSP + (with bleProcedureComplete or bleTimeout status) or ATT_ERROR_RSP + (with SUCCESS status) is received by the calling application task. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + @param taskId - task to be notified of response + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A response is pending with this server.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_ReadLongCharValue( uint16 connHandle, attReadBlobReq_t* pReq, uint8 taskId ); + +/** + @brief This sub-procedure is used to read multiple Characteristic Values + from a server when the client knows the Characteristic Value + Handles. The Attribute Protocol Read Multiple Requests is used + with the Set Of Handles parameter set to the Characteristic Value + Handles. The Read Multiple Response returns the Characteristic + Values in the Set Of Values parameter. + + The ATT Read Multiple Request is used in this sub-procedure. + + If the return status from this function is SUCCESS, the calling + application task will receive an OSAL GATT_MSG_EVENT message. + The type of the message will be either ATT_READ_MULTI_RSP + or ATT_ERROR_RSP (if an error occurred on the server). + + Note: This sub-procedure is complete when either ATT_READ_MULTI_RSP + (with SUCCESS or bleTimeout status) or ATT_ERROR_RSP (with + SUCCESS status) is received by the calling application task. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + @param taskId - task to be notified of response + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A response is pending with this server.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_ReadMultiCharValues( uint16 connHandle, attReadMultiReq_t* pReq, uint8 taskId ); + +/** + @brief This sub-procedure is used to write a Characteristic Value + to a server when the client knows the Characteristic Value + Handle and the client does not need an acknowledgement that + the write was successfully performed. This sub-procedure + only writes the first (ATT_MTU ? 3) octets of a Characteristic + Value. This sub-procedure can not be used to write a long + characteristic; instead the Write Long Characteristic Values + sub-procedure should be used. + + The ATT Write Command is used for this sub-procedure. The + Attribute Handle parameter shall be set to the Characteristic + Value Handle. The Attribute Value parameter shall be set to + the new Characteristic Value. + + No response will be sent to the calling application task for this + sub-procedure. If the Characteristic Value write request is the + wrong size, or has an invalid value as defined by the profile, + then the write will not succeed and no error will be generated + by the server. + + @param connHandle - connection to use + @param pReq - pointer to command to be sent + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_WriteNoRsp( uint16 connHandle, attWriteReq_t* pReq ); + +/** + @brief This sub-procedure is used to write a Characteristic Value + to a server when the client knows the Characteristic Value + Handle and the ATT Bearer is not encrypted. This sub-procedure + shall only be used if the Characteristic Properties authenticated + bit is enabled and the client and server device share a bond as + defined in the GAP. + + This sub-procedure only writes the first (ATT_MTU ? 15) octets + of an Attribute Value. This sub-procedure cannot be used to + write a long Attribute. + + The ATT Write Command is used for this sub-procedure. The + Attribute Handle parameter shall be set to the Characteristic + Value Handle. The Attribute Value parameter shall be set to + the new Characteristic Value authenticated by signing the + value, as defined in the Security Manager. + + No response will be sent to the calling application task for this + sub-procedure. If the authenticated Characteristic Value that is + written is the wrong size, or has an invalid value as defined by + the profile, or the signed value does not authenticate the client, + then the write will not succeed and no error will be generated by + the server. + + @param connHandle - connection to use + @param pReq - pointer to command to be sent + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ bleMemAllocError: Memory allocation error occurred.
+ bleLinkEncrypted: Connection is already encrypted.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_SignedWriteNoRsp( uint16 connHandle, attWriteReq_t* pReq ); + +/** + @brief This sub-procedure is used to write a characteristic value + to a server when the client knows the characteristic value + handle. This sub-procedure only writes the first (ATT_MTU-3) + octets of a characteristic value. This sub-procedure can not + be used to write a long attribute; instead the Write Long + Characteristic Values sub-procedure should be used. + + The ATT Write Request is used in this sub-procedure. The + Attribute Handle parameter shall be set to the Characteristic + Value Handle. The Attribute Value parameter shall be set to + the new characteristic. + + If the return status from this function is SUCCESS, the calling + application task will receive an OSAL GATT_MSG_EVENT message. + The type of the message will be either ATT_WRITE_RSP + or ATT_ERROR_RSP (if an error occurred on the server). + + Note: This sub-procedure is complete when either ATT_WRITE_RSP + (with SUCCESS or bleTimeout status) or ATT_ERROR_RSP (with + SUCCESS status) is received by the calling application task. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + @param taskId - task to be notified of response + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A response is pending with this server.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_WriteCharValue( uint16 connHandle, attWriteReq_t* pReq, uint8 taskId ); + +/** + @brief This sub-procedure is used to write a Characteristic Value to + a server when the client knows the Characteristic Value Handle + but the length of the Characteristic Value is longer than can + be sent in a single Write Request Attribute Protocol message. + + The ATT Prepare Write Request and Execute Write Request are + used to perform this sub-procedure. + + If the return status from this function is SUCCESS, the calling + application task will receive multiple OSAL GATT_MSG_EVENT messages. + The type of the messages will be either ATT_PREPARE_WRITE_RSP, + ATT_EXECUTE_WRITE_RSP or ATT_ERROR_RSP (if an error occurred on + the server). + + Note: This sub-procedure is complete when either ATT_PREPARE_WRITE_RSP + (with bleTimeout status), ATT_EXECUTE_WRITE_RSP (with SUCCESS + or bleTimeout status), or ATT_ERROR_RSP (with SUCCESS status) + is received by the calling application task. + + Note: The 'pReq->pValue' pointer will be freed when the sub-procedure + is complete. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + @param taskId - task to be notified of response + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A response is pending with this server.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_WriteLongCharValue( uint16 connHandle, gattPrepareWriteReq_t* pReq, uint8 taskId ); + +/** + @brief This sub-procedure is used to write a Characteristic Value to + a server when the client knows the Characteristic Value Handle, + and assurance is required that the correct Characteristic Value + is going to be written by transferring the Characteristic Value + to be written in both directions before the write is performed. + This sub-procedure can also be used when multiple values must + be written, in order, in a single operation. + + The sub-procedure has two phases, the first phase prepares the + characteristic values to be written. Once this is complete, + the second phase performs the execution of all of the prepared + characteristic value writes on the server from this client. + + In the first phase, the ATT Prepare Write Request is used. + In the second phase, the attribute protocol Execute Write + Request is used. + + If the return status from this function is SUCCESS, the calling + application task will receive multiple OSAL GATT_MSG_EVENT messages. + The type of the messages will be either ATT_PREPARE_WRITE_RSP, + ATT_EXECUTE_WRITE_RSP or ATT_ERROR_RSP (if an error occurred on + the server). + + Note: This sub-procedure is complete when either ATT_PREPARE_WRITE_RSP + (with bleTimeout status), ATT_EXECUTE_WRITE_RSP (with SUCCESS + or bleTimeout status), or ATT_ERROR_RSP (with SUCCESS status) + is received by the calling application task. + + Note: The 'pReqs' pointer will be freed when the sub-procedure is + complete. + + @param connHandle - connection to use + @param pReqs - pointer to requests to be sent (must be allocated) + @param numReqs - number of requests in pReq + @param flags - execute write request flags + @param taskId - task to be notified of response + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A response is pending with this server.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_ReliableWrites( uint16 connHandle, attPrepareWriteReq_t* pReqs, + uint8 numReqs, uint8 flags, uint8 taskId ); +/** + @brief This sub-procedure is used to read a characteristic descriptor + from a server when the client knows the characteristic descriptor + declaration’s Attribute handle. + + The ATT Read Request is used for this sub-procedure. The Read + Request is used with the Attribute Handle parameter set to the + characteristic descriptor handle. The Read Response returns the + characteristic descriptor value in the Attribute Value parameter. + + If the return status from this function is SUCCESS, the calling + application task will receive an OSAL GATT_MSG_EVENT message. + The type of the message will be either ATT_READ_RSP or + ATT_ERROR_RSP (if an error occurred on the server). + + Note: This sub-procedure is complete when either ATT_READ_RSP + (with SUCCESS or bleTimeout status) or ATT_ERROR_RSP (with + SUCCESS status) is received by the calling application task. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + @param taskId - task to be notified of response + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A response is pending with this server.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_ReadCharDesc( uint16 connHandle, attReadReq_t* pReq, uint8 taskId ); + +/** + @brief This sub-procedure is used to read a characteristic descriptor + from a server when the client knows the characteristic descriptor + declaration’s Attribute handle and the length of the characteristic + descriptor declaration is longer than can be sent in a single Read + Response attribute protocol message. + + The ATT Read Blob Request is used to perform this sub-procedure. + The Attribute Handle parameter shall be set to the characteristic + descriptor handle. The Value Offset parameter shall be the offset + within the characteristic descriptor to be read. + + If the return status from this function is SUCCESS, the calling + application task will receive multiple OSAL GATT_MSG_EVENT messages. + The type of the messages will be either ATT_READ_BLOB_RSP or + ATT_ERROR_RSP (if an error occurred on the server). + + Note: This sub-procedure is complete when either ATT_READ_BLOB_RSP + (with bleProcedureComplete or bleTimeout status) or ATT_ERROR_RSP + (with SUCCESS status) is received by the calling application task. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + @param taskId - task to be notified of response + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A response is pending with this server.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_ReadLongCharDesc( uint16 connHandle, attReadBlobReq_t* pReq, uint8 taskId ); + +/** + @brief This sub-procedure is used to write a characteristic + descriptor value to a server when the client knows the + characteristic descriptor handle. + + The ATT Write Request is used for this sub-procedure. The + Attribute Handle parameter shall be set to the characteristic + descriptor handle. The Attribute Value parameter shall be + set to the new characteristic descriptor value. + + If the return status from this function is SUCCESS, the calling + application task will receive an OSAL GATT_MSG_EVENT message. + The type of the message will be either ATT_WRITE_RSP + or ATT_ERROR_RSP (if an error occurred on the server). + + Note: This sub-procedure is complete when either ATT_WRITE_RSP + (with SUCCESS or bleTimeout status) or ATT_ERROR_RSP (with + SUCCESS status) is received by the calling application task. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + @param taskId - task to be notified of response + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.
+ MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A response is pending with this server.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_WriteCharDesc( uint16 connHandle, attWriteReq_t* pReq, uint8 taskId ); + +/** + @brief This sub-procedure is used to write a Characteristic Value to + a server when the client knows the Characteristic Value Handle + but the length of the Characteristic Value is longer than can + be sent in a single Write Request Attribute Protocol message. + + The ATT Prepare Write Request and Execute Write Request are + used to perform this sub-procedure. + + If the return status from this function is SUCCESS, the calling + application task will receive multiple OSAL GATT_MSG_EVENT messages. + The type of the messages will be either ATT_PREPARE_WRITE_RSP, + ATT_EXECUTE_WRITE_RSP or ATT_ERROR_RSP (if an error occurred on + the server). + + Note: This sub-procedure is complete when either ATT_PREPARE_WRITE_RSP + (with bleTimeout status), ATT_EXECUTE_WRITE_RSP (with SUCCESS + or bleTimeout status), or ATT_ERROR_RSP (with SUCCESS status) + is received by the calling application task. + + Note: The 'pReq->pValue' pointer will be freed when the sub-procedure + is complete. + + @param connHandle - connection to use + @param pReq - pointer to request to be sent + @param taskId - task to be notified of response + + @return SUCCESS: Request was sent successfully.
+ INVALIDPARAMETER: Invalid connection handle or request field.v + MSG_BUFFER_NOT_AVAIL: No HCI buffer is available.
+ bleNotConnected: Connection is down.
+ blePending: A response is pending with this server.
+ bleMemAllocError: Memory allocation error occurred.
+ bleTimeout: Previous transaction timed out.
+*/ +extern bStatus_t GATT_WriteLongCharDesc( uint16 connHandle, gattPrepareWriteReq_t* pReq, uint8 taskId ); + +/** + @} +*/ + +/* ------------------------------------------------------------------- + GATT Flow Control APIs +*/ + +/** + @defgroup GATT_FLOW_CTRL_API GATT Flow Control API Functions + + @{ +*/ + +/** + @brief This API is used by the Application to turn flow control on + or off for GATT messages sent from the Host to the Application. + + Note: If the flow control is enabled then the Application must + call the GATT_AppCompletedMsg() API when it completes + processing an incoming GATT message. + + @param flowCtrlMode ? flow control mode: TRUE or FALSE + + @return void +*/ +extern void GATT_SetHostToAppFlowCtrl( uint16 hostBufSize,uint8 flowCtrlMode ); + +/** + @brief This API is used by the Application to notify GATT that + the processing of a message has been completed. + + @param pMsg ? pointer to the processed GATT message + + @return void +*/ +extern void GATT_AppCompletedMsg( gattMsgEvent_t* pMsg ); + +/** + @} +*/ + +/* ------------------------------------------------------------------- + Internal API - This function is only called from GATT Qualification modules. +*/ + +/** + @internal + + @brief Set the next available attribute handle. + + @param handle - next attribute handle. + + @return none +*/ +extern void GATT_SetNextHandle( uint16 handle ); + +/* ------------------------------------------------------------------- + TASK API - These functions must only be called by OSAL. +*/ + +/** + @internal + + @brief GATT Task initialization function. + + @param taskId - GATT task ID. + + @return void +*/ +extern void GATT_Init( uint8 taskId ); + +/** + @internal + + @brief GATT Task event processing function. + + @param taskId - GATT task ID + @param events - GATT events. + + @return events not processed +*/ +extern uint16 GATT_ProcessEvent( uint8 taskId, uint16 events ); + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* GATT_H */ diff --git a/arch/arm/src/phy62xx/ble/include/gatt_uuid.h b/arch/arm/src/phy62xx/ble/include/gatt_uuid.h new file mode 100644 index 00000000000..a5aa7995375 --- /dev/null +++ b/arch/arm/src/phy62xx/ble/include/gatt_uuid.h @@ -0,0 +1,167 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/************************************************************************************************** + Filename: gatt_uuid.h + Revised: + Revision: + + Description: This file contains Generic Attribute Profile (GATT) + UUID types. + + +**************************************************************************************************/ + +#ifndef GATT_UUID_H +#define GATT_UUID_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ + +/********************************************************************* + CONSTANTS +*/ + +/* + WARNING: The 16-bit UUIDs are assigned by the Bluetooth SIG and published + in the Bluetooth Assigned Numbers page. Do not change these values. + Changing them will cause Bluetooth interoperability issues. +*/ + +/** + GATT Services +*/ +#define GAP_SERVICE_UUID 0x1800 // Generic Access Profile +#define GATT_SERVICE_UUID 0x1801 // Generic Attribute Profile + +/** + GATT Declarations +*/ +#define GATT_PRIMARY_SERVICE_UUID 0x2800 // Primary Service +#define GATT_SECONDARY_SERVICE_UUID 0x2801 // Secondary Service +#define GATT_INCLUDE_UUID 0x2802 // Include +#define GATT_CHARACTER_UUID 0x2803 // Characteristic + +/** + GATT Descriptors +*/ +#define GATT_CHAR_EXT_PROPS_UUID 0x2900 // Characteristic Extended Properties +#define GATT_CHAR_USER_DESC_UUID 0x2901 // Characteristic User Description +#define GATT_CLIENT_CHAR_CFG_UUID 0x2902 // Client Characteristic Configuration +#define GATT_SERV_CHAR_CFG_UUID 0x2903 // Server Characteristic Configuration +#define GATT_CHAR_FORMAT_UUID 0x2904 // Characteristic Presentation Format +#define GATT_CHAR_AGG_FORMAT_UUID 0x2905 // Characteristic Aggregate Format +#define GATT_VALID_RANGE_UUID 0x2906 // Valid Range +#define GATT_EXT_REPORT_REF_UUID 0x2907 // External Report Reference Descriptor +#define GATT_REPORT_REF_UUID 0x2908 // Report Reference Descriptor + +/** + GATT Characteristics +*/ +#define DEVICE_NAME_UUID 0x2A00 // Device Name +#define APPEARANCE_UUID 0x2A01 // Appearance +#define PERI_PRIVACY_FLAG_UUID 0x2A02 // Peripheral Privacy Flag +#define RECONNECT_ADDR_UUID 0x2A03 // Reconnection Address +#define PERI_CONN_PARAM_UUID 0x2A04 // Peripheral Preferred Connection Parameters +#define SERVICE_CHANGED_UUID 0x2A05 // Service Changed + +/********************************************************************* + MACROS +*/ + +/********************************************************************* + TYPEDEFS +*/ + +/********************************************************************* + VARIABLES +*/ + +/** + GATT Services +*/ +extern CONST uint8 gapServiceUUID[]; +extern CONST uint8 gattServiceUUID[]; + +/** + GATT Attribute Types +*/ +extern CONST uint8 primaryServiceUUID[]; +extern CONST uint8 secondaryServiceUUID[]; +extern CONST uint8 includeUUID[]; +extern CONST uint8 characterUUID[]; + +/** + GATT Characteristic Descriptors +*/ +extern CONST uint8 charExtPropsUUID[]; +extern CONST uint8 charUserDescUUID[]; +extern CONST uint8 clientCharCfgUUID[]; +extern CONST uint8 servCharCfgUUID[]; +extern CONST uint8 charFormatUUID[]; +extern CONST uint8 charAggFormatUUID[]; +extern CONST uint8 validRangeUUID[]; +extern CONST uint8 extReportRefUUID[]; +extern CONST uint8 reportRefUUID[]; + +/** + GATT Characteristic Types +*/ +extern CONST uint8 deviceNameUUID[]; +extern CONST uint8 appearanceUUID[]; +extern CONST uint8 periPrivacyFlagUUID[]; +extern CONST uint8 reconnectAddrUUID[]; +extern CONST uint8 periConnParamUUID[]; +extern CONST uint8 serviceChangedUUID[]; +extern CONST uint8 manuNameUUID[]; +extern CONST uint8 serialNumUUID[]; +extern CONST uint8 manuAddrUUID[]; + +/********************************************************************* + FUNCTIONS +*/ +extern const uint8* GATT_FindUUIDRec( const uint8* pUUID, uint8 len ); + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* GATT_UUID_H */ diff --git a/arch/arm/src/phy62xx/ble/include/hci.h b/arch/arm/src/phy62xx/ble/include/hci.h new file mode 100644 index 00000000000..5eb1daf7bab --- /dev/null +++ b/arch/arm/src/phy62xx/ble/include/hci.h @@ -0,0 +1,3150 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/******************************************************************************* + Filename: hci.h + Revised: + Revision: + + Description: This file contains the Host Controller Interface (HCI) API. + It provides the defines, types, and functions for all + supported Bluetooth Low Energy (BLE) commands. + + All Bluetooth and BLE commands are based on: + Bluetooth Core Specification, V4.0.0, Vol. 2, Part E. + + +*******************************************************************************/ + +#ifndef HCI_H +#define HCI_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + INCLUDES +*/ +#include "bcomdef.h" +#include "OSAL.h" +#include "ll.h" +//#include "hal_assert.h" + +/******************************************************************************* + MACROS +*/ + +/******************************************************************************* + CONSTANTS +*/ + +/* +** HCI Status +** +** Per the Bluetooth Core Specification, V4.0.0, Vol. 2, Part D. +*/ +#define HCI_SUCCESS 0x00 +#define HCI_ERROR_CODE_UNKNOWN_HCI_CMD 0x01 +#define HCI_ERROR_CODE_UNKNOWN_CONN_ID 0x02 +#define HCI_ERROR_CODE_HW_FAILURE 0x03 +#define HCI_ERROR_CODE_PAGE_TIMEOUT 0x04 +#define HCI_ERROR_CODE_AUTH_FAILURE 0x05 +#define HCI_ERROR_CODE_PIN_KEY_MISSING 0x06 +#define HCI_ERROR_CODE_MEM_CAP_EXCEEDED 0x07 +#define HCI_ERROR_CODE_CONN_TIMEOUT 0x08 +#define HCI_ERROR_CODE_CONN_LIMIT_EXCEEDED 0x09 +#define HCI_ERROR_CODE_SYNCH_CONN_LIMIT_EXCEEDED 0x0A +#define HCI_ERROR_CODE_ACL_CONN_ALREADY_EXISTS 0x0B +#define HCI_ERROR_CODE_CMD_DISALLOWED 0x0C +#define HCI_ERROR_CODE_CONN_REJ_LIMITED_RESOURCES 0x0D +#define HCI_ERROR_CODE_CONN_REJECTED_SECURITY_REASONS 0x0E +#define HCI_ERROR_CODE_CONN_REJECTED_UNACCEPTABLE_BDADDR 0x0F +#define HCI_ERROR_CODE_CONN_ACCEPT_TIMEOUT_EXCEEDED 0x10 +#define HCI_ERROR_CODE_UNSUPPORTED_FEATURE_PARAM_VALUE 0x11 +#define HCI_ERROR_CODE_INVALID_HCI_CMD_PARAMS 0x12 +#define HCI_ERROR_CODE_REMOTE_USER_TERM_CONN 0x13 +#define HCI_ERROR_CODE_REMOTE_DEVICE_TERM_CONN_LOW_RESOURCES 0x14 +#define HCI_ERROR_CODE_REMOTE_DEVICE_TERM_CONN_POWER_OFF 0x15 +#define HCI_ERROR_CODE_CONN_TERM_BY_LOCAL_HOST 0x16 +#define HCI_ERROR_CODE_REPEATED_ATTEMPTS 0x17 +#define HCI_ERROR_CODE_PAIRING_NOT_ALLOWED 0x18 +#define HCI_ERROR_CODE_UNKNOWN_LMP_PDU 0x19 +#define HCI_ERROR_CODE_UNSUPPORTED_REMOTE_FEATURE 0x1A +#define HCI_ERROR_CODE_SCO_OFFSET_REJ 0x1B +#define HCI_ERROR_CODE_SCO_INTERVAL_REJ 0x1C +#define HCI_ERROR_CODE_SCO_AIR_MODE_REJ 0x1D +#define HCI_ERROR_CODE_INVALID_LMP_PARAMS 0x1E +#define HCI_ERROR_CODE_UNSPECIFIED_ERROR 0x1F +#define HCI_ERROR_CODE_UNSUPPORTED_LMP_PARAM_VAL 0x20 +#define HCI_ERROR_CODE_ROLE_CHANGE_NOT_ALLOWED 0x21 +#define HCI_ERROR_CODE_LMP_LL_RESP_TIMEOUT 0x22 +#define HCI_ERROR_CODE_LMP_ERR_TRANSACTION_COLLISION 0x23 +#define HCI_ERROR_CODE_LMP_PDU_NOT_ALLOWED 0x24 +#define HCI_ERROR_CODE_ENCRYPT_MODE_NOT_ACCEPTABLE 0x25 +#define HCI_ERROR_CODE_LINK_KEY_CAN_NOT_BE_CHANGED 0x26 +#define HCI_ERROR_CODE_REQ_QOS_NOT_SUPPORTED 0x27 +#define HCI_ERROR_CODE_INSTANT_PASSED 0x28 +#define HCI_ERROR_CODE_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED 0x29 +#define HCI_ERROR_CODE_DIFFERENT_TRANSACTION_COLLISION 0x2A +#define HCI_ERROR_CODE_RESERVED1 0x2B +#define HCI_ERROR_CODE_QOS_UNACCEPTABLE_PARAM 0x2C +#define HCI_ERROR_CODE_QOS_REJ 0x2D +#define HCI_ERROR_CODE_CHAN_ASSESSMENT_NOT_SUPPORTED 0x2E +#define HCI_ERROR_CODE_INSUFFICIENT_SECURITY 0x2F +#define HCI_ERROR_CODE_PARAM_OUT_OF_MANDATORY_RANGE 0x30 +#define HCI_ERROR_CODE_RESERVED2 0x31 +#define HCI_ERROR_CODE_ROLE_SWITCH_PENDING 0x32 +#define HCI_ERROR_CODE_RESERVED3 0x33 +#define HCI_ERROR_CODE_RESERVED_SLOT_VIOLATION 0x34 +#define HCI_ERROR_CODE_ROLE_SWITCH_FAILED 0x35 +#define HCI_ERROR_CODE_EXTENDED_INQUIRY_RESP_TOO_LARGE 0x36 +#define HCI_ERROR_CODE_SIMPLE_PAIRING_NOT_SUPPORTED_BY_HOST 0x37 +#define HCI_ERROR_CODE_HOST_BUSY_PAIRING 0x38 +#define HCI_ERROR_CODE_CONN_REJ_NO_SUITABLE_CHAN_FOUND 0x39 +#define HCI_ERROR_CODE_CONTROLLER_BUSY 0x3A +#define HCI_ERROR_CODE_UNACCEPTABLE_CONN_INTERVAL 0x3B +#define HCI_ERROR_CODE_DIRECTED_ADV_TIMEOUT 0x3C +#define HCI_ERROR_CODE_CONN_TERM_MIC_FAILURE 0x3D +#define HCI_ERROR_CODE_CONN_FAILED_TO_ESTABLISH 0x3E +#define HCI_ERROR_CODE_MAC_CONN_FAILED 0x3F + +/* +** Max Buffers Supported +*/ +#define HCI_MAX_NUM_DATA_BUFFERS LL_MAX_NUM_DATA_BUFFERS +#define HCI_MAX_NUM_CMD_BUFFERS LL_MAX_NUM_CMD_BUFFERS + +/* +** HCI Command API Parameters +*/ + +// Send Data Packet Boundary Flags +#define FIRST_PKT_HOST_TO_CTRL LL_DATA_FIRST_PKT_HOST_TO_CTRL +#define CONTINUING_PKT LL_DATA_CONTINUATION_PKT +#define FIRST_PKT_CTRL_TO_HOST LL_DATA_FIRST_PKT_CTRL_TO_HOST + +// Receive Data Packet +#define HCI_RSSI_NOT_AVAILABLE LL_RSSI_NOT_AVAILABLE + +// Disconnect Reasons +#define HCI_DISCONNECT_AUTH_FAILURE HCI_ERROR_CODE_AUTH_FAILURE +#define HCI_DISCONNECT_REMOTE_USER_TERM HCI_ERROR_CODE_REMOTE_USER_TERM_CONN +#define HCI_DISCONNECT_REMOTE_DEV_LOW_RESOURCES HCI_ERROR_CODE_REMOTE_DEVICE_TERM_CONN_LOW_RESOURCES +#define HCI_DISCONNECT_REMOTE_DEV_POWER_OFF HCI_ERROR_CODE_REMOTE_DEVICE_TERM_CONN_POWER_OFF +#define HCI_DISCONNECT_UNSUPPORTED_REMOTE_FEATURE HCI_ERROR_CODE_UNSUPPORTED_REMOTE_FEATURE +#define HCI_DISCONNECT_KEY_PAIRING_NOT_SUPPORTED HCI_ERROR_CODE_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED +#define HCI_DISCONNECT_UNACCEPTABLE_CONN_INTERVAL HCI_ERROR_CODE_UNACCEPTABLE_CONN_INTERVAL + +// Tx Power Types +#define HCI_READ_CURRENT_TX_POWER_LEVEL LL_READ_CURRENT_TX_POWER_LEVEL +#define HCI_READ_MAX_TX_POWER_LEVEL LL_READ_MAX_TX_POWER_LEVEL + +// Host Flow Control +#define HCI_CTRL_TO_HOST_FLOW_CTRL_OFF 0 +#define HCI_CTRL_TO_HOST_FLOW_CTRL_ACL_ON_SYNCH_OFF 1 +#define HCI_CTRL_TO_HOST_FLOW_CTRL_ACL_OFF_SYNCH_ON 2 +#define HCI_CTRL_TO_HOST_FLOW_CTRL_ACL_ON_SYNCH_ON 3 + +// Device Address Type +#define HCI_PUBLIC_DEVICE_ADDRESS LL_DEV_ADDR_TYPE_PUBLIC +#define HCI_RANDOM_DEVICE_ADDRESS LL_DEV_ADDR_TYPE_RANDOM + +// Advertiser Events +#define HCI_CONNECTABLE_UNDIRECTED_ADV LL_ADV_CONNECTABLE_UNDIRECTED_EVT +#define HCI_CONNECTABLE_DIRECTED_HDC_ADV LL_ADV_CONNECTABLE_DIRECTED_HDC_EVT +#define HCI_SCANNABLE_UNDIRECTED LL_ADV_SCANNABLE_UNDIRECTED_EVT +#define HCI_NONCONNECTABLE_UNDIRECTED_ADV LL_ADV_NONCONNECTABLE_UNDIRECTED_EVT +#define HCI_CONNECTABLE_DIRECTED_LDC_ADV LL_ADV_CONNECTABLE_DIRECTED_LDC_EVT + +// Advertiser Channels +#define HCI_ADV_CHAN_37 LL_ADV_CHAN_37 +#define HCI_ADV_CHAN_38 LL_ADV_CHAN_38 +#define HCI_ADV_CHAN_39 LL_ADV_CHAN_39 +#define HCI_ADV_CHAN_ALL (LL_ADV_CHAN_37 | LL_ADV_CHAN_38 | LL_ADV_CHAN_39) + +// Advertiser White List Policy +#define HCI_ADV_WL_POLICY_ANY_REQ LL_ADV_WL_POLICY_ANY_REQ +#define HCI_ADV_WL_POLICY_WL_SCAN_REQ LL_ADV_WL_POLICY_WL_SCAN_REQ +#define HCI_ADV_WL_POLICY_WL_CONNECT_REQ LL_ADV_WL_POLICY_WL_CONNECT_REQ +#define HCI_ADV_WL_POLICY_WL_ALL_REQ LL_ADV_WL_POLICY_WL_ALL_REQ + +// Advertiser Commands +#define HCI_ENABLE_ADV LL_ADV_MODE_ON +#define HCI_DISABLE_ADV LL_ADV_MODE_OFF + +// Scan Types +#define HCI_SCAN_PASSIVE LL_SCAN_PASSIVE +#define HCI_SCAN_ACTIVE LL_SCAN_ACTIVE + +// Scan White List Policy +#define HCI_SCAN_WL_POLICY_ANY_ADV_PKTS LL_SCAN_WL_POLICY_ANY_ADV_PKTS +#define HCI_SCAN_WL_POLICY_USE_WHITE_LIST LL_SCAN_WL_POLICY_USE_WHITE_LIST + +// Scan Filtering +#define HCI_FILTER_REPORTS_DISABLE LL_FILTER_REPORTS_DISABLE +#define HCI_FILTER_REPORTS_ENABLE LL_FILTER_REPORTS_ENABLE + +// Scan Commands +#define HCI_SCAN_STOP LL_SCAN_STOP +#define HCI_SCAN_START LL_SCAN_START + +// Initiator White List Policy +#define HCI_INIT_WL_POLICY_USE_PEER_ADDR LL_INIT_WL_POLICY_USE_PEER_ADDR +#define HCI_INIT_WL_POLICY_USE_WHITE_LIST LL_INIT_WL_POLICY_USE_WHITE_LIST + +// Encryption Related +#define HCI_ENCRYPTION_OFF LL_ENCRYPTION_OFF +#define HCI_ENCRYPTION_ON LL_ENCRYPTION_ON + +// Direct Test Mode +#define HCI_DTM_NUMBER_RF_CHANS LL_DIRECT_TEST_NUM_RF_CHANS +#define HCI_DIRECT_TEST_MAX_PAYLOAD_LEN LL_DIRECT_TEST_MAX_PAYLOAD_LEN +// +#define HCI_DIRECT_TEST_PAYLOAD_PRBS9 LL_DIRECT_TEST_PAYLOAD_PRBS9 +#define HCI_DIRECT_TEST_PAYLOAD_0x0F LL_DIRECT_TEST_PAYLOAD_0x0F +#define HCI_DIRECT_TEST_PAYLOAD_0x55 LL_DIRECT_TEST_PAYLOAD_0x55 +#define HCI_DIRECT_TEST_PAYLOAD_PRBS15 LL_DIRECT_TEST_PAYLOAD_PRBS15 +#define HCI_DIRECT_TEST_PAYLOAD_0xFF LL_DIRECT_TEST_PAYLOAD_0xFF +#define HCI_DIRECT_TEST_PAYLOAD_0x00 LL_DIRECT_TEST_PAYLOAD_0x00 +#define HCI_DIRECT_TEST_PAYLOAD_0xF0 LL_DIRECT_TEST_PAYLOAD_0xF0 +#define HCI_DIRECT_TEST_PAYLOAD_0xAA LL_DIRECT_TEST_PAYLOAD_0xAA + +// Vendor Specific +#define HCI_EXT_RX_GAIN_STD LL_EXT_RX_GAIN_STD +#define HCI_EXT_RX_GAIN_HIGH LL_EXT_RX_GAIN_HIGH +// +#define HCI_EXT_TX_POWER_MINUS_23_DBM LL_EXT_TX_POWER_MINUS_23_DBM +#define HCI_EXT_TX_POWER_MINUS_6_DBM LL_EXT_TX_POWER_MINUS_6_DBM +#define HCI_EXT_TX_POWER_0_DBM LL_EXT_TX_POWER_0_DBM +#define HCI_EXT_TX_POWER_4_DBM LL_EXT_TX_POWER_4_DBM +// +#define HCI_EXT_ENABLE_ONE_PKT_PER_EVT LL_EXT_ENABLE_ONE_PKT_PER_EVT +#define HCI_EXT_DISABLE_ONE_PKT_PER_EVT LL_EXT_DISABLE_ONE_PKT_PER_EVT +// +#define HCI_EXT_ENABLE_CLK_DIVIDE_ON_HALT LL_EXT_ENABLE_CLK_DIVIDE_ON_HALT +#define HCI_EXT_DISABLE_CLK_DIVIDE_ON_HALT LL_EXT_DISABLE_CLK_DIVIDE_ON_HALT +// +#define HCI_EXT_NV_IN_USE LL_EXT_NV_IN_USE +#define HCI_EXT_NV_NOT_IN_USE LL_EXT_NV_NOT_IN_USE +// +#define HCI_EXT_ENABLE_FAST_TX_RESP_TIME LL_EXT_ENABLE_FAST_TX_RESP_TIME +#define HCI_EXT_DISABLE_FAST_TX_RESP_TIME LL_EXT_DISABLE_FAST_TX_RESP_TIME +// +#define HCI_EXT_ENABLE_SL_OVERRIDE LL_EXT_ENABLE_SL_OVERRIDE +#define HCI_EXT_DISABLE_SL_OVERRIDE LL_EXT_DISABLE_SL_OVERRIDE +// +#define HCI_EXT_TX_MODULATED_CARRIER LL_EXT_TX_MODULATED_CARRIER +#define HCI_EXT_TX_UNMODULATED_CARRIER LL_EXT_TX_UNMODULATED_CARRIER +// +#define HCI_PTM_SET_FREQ_TUNE_DOWN LL_EXT_SET_FREQ_TUNE_DOWN +#define HCI_PTM_SET_FREQ_TUNE_UP LL_EXT_SET_FREQ_TUNE_UP +// +#define HCI_EXT_PM_IO_PORT_P0 LL_EXT_PM_IO_PORT_P0 +#define HCI_EXT_PM_IO_PORT_P1 LL_EXT_PM_IO_PORT_P1 +#define HCI_EXT_PM_IO_PORT_P2 LL_EXT_PM_IO_PORT_P2 +#define HCI_EXT_PM_IO_PORT_NONE LL_EXT_PM_IO_PORT_NONE +// +#define HCI_EXT_PM_IO_PORT_PIN0 LL_EXT_PM_IO_PORT_PIN0 +#define HCI_EXT_PM_IO_PORT_PIN1 LL_EXT_PM_IO_PORT_PIN1 +#define HCI_EXT_PM_IO_PORT_PIN2 LL_EXT_PM_IO_PORT_PIN2 +#define HCI_EXT_PM_IO_PORT_PIN3 LL_EXT_PM_IO_PORT_PIN3 +#define HCI_EXT_PM_IO_PORT_PIN4 LL_EXT_PM_IO_PORT_PIN4 +#define HCI_EXT_PM_IO_PORT_PIN5 LL_EXT_PM_IO_PORT_PIN5 +#define HCI_EXT_PM_IO_PORT_PIN6 LL_EXT_PM_IO_PORT_PIN6 +#define HCI_EXT_PM_IO_PORT_PIN7 LL_EXT_PM_IO_PORT_PIN7 +// +#define HCI_EXT_PER_RESET LL_EXT_PER_RESET +#define HCI_EXT_PER_READ LL_EXT_PER_READ +// +#define HCI_EXT_HALT_DURING_RF_DISABLE LL_EXT_HALT_DURING_RF_DISABLE +#define HCI_EXT_HALT_DURING_RF_ENABLE LL_EXT_HALT_DURING_RF_ENABLE +// +#define HCI_EXT_SET_USER_REVISION LL_EXT_SET_USER_REVISION +#define HCI_EXT_READ_BUILD_REVISION LL_EXT_READ_BUILD_REVISION +// +#define HCI_EXT_RESET_SYSTEM_HARD LL_EXT_RESET_SYSTEM_HARD +#define HCI_EXT_RESET_SYSTEM_SOFT LL_EXT_RESET_SYSTEM_SOFT +// +#define HCI_EXT_DISABLE_OVERLAPPED_PROCESSING LL_EXT_DISABLE_OVERLAPPED_PROCESSING +#define HCI_EXT_ENABLE_OVERLAPPED_PROCESSING LL_EXT_ENABLE_OVERLAPPED_PROCESSING +// +#define HCI_EXT_DISABLE_NUM_COMPL_PKTS_ON_EVENT LL_EXT_DISABLE_NUM_COMPL_PKTS_ON_EVENT +#define HCI_EXT_ENABLE_NUM_COMPL_PKTS_ON_EVENT LL_EXT_ENABLE_NUM_COMPL_PKTS_ON_EVENT + +/* +** HCI Event Parameters +*/ + +// HCI Link Type for Buffer Overflow +#define HCI_LINK_TYPE_SCO_BUFFER_OVERFLOW 0 +#define HCI_LINK_TYPE_ACL_BUFFER_OVERFLOW 1 + +/******************************************************************************* + TYPEDEFS +*/ + +typedef uint8 hciStatus_t; + +/* +** LE Events +*/ + +// LE Connection Complete Event +typedef struct +{ + osal_event_hdr_t hdr; + uint8 BLEEventCode; + uint8 status; + uint16 connectionHandle; + uint8 role; + uint8 peerAddrType; + uint8 peerAddr[B_ADDR_LEN]; + uint16 connInterval; + uint16 connLatency; + uint16 connTimeout; + uint8 clockAccuracy; +} hciEvt_BLEConnComplete_t; + +// LE Connection Complete Event +typedef struct +{ + osal_event_hdr_t hdr; + uint8 BLEEventCode; + uint8 status; + uint16 connectionHandle; + uint8 role; + uint8 peerAddrType; + uint8 peerAddr[B_ADDR_LEN]; + uint8 localRpaAddr[B_ADDR_LEN]; + uint8 peerRpaAddr[B_ADDR_LEN]; + uint16 connInterval; + uint16 connLatency; + uint16 connTimeout; + uint8 clockAccuracy; +} hciEvt_BLEEnhConnComplete_t; + +// LE Advertising Report Event +typedef struct +{ + uint8 eventType; // advertisment or scan response event type + uint8 addrType; // public or random address type + uint8 addr[B_ADDR_LEN]; // device address + uint8 dataLen; // length of report data + uint8 rspData[B_MAX_ADV_LEN]; // report data given by dataLen + int8 rssi; // report RSSI +} hciEvt_DevInfo_t; + +typedef struct +{ + osal_event_hdr_t hdr; + uint8 BLEEventCode; + uint8 numDevices; + hciEvt_DevInfo_t* devInfo; // pointer to the array of devInfo +} hciEvt_BLEAdvPktReport_t; + +// LE Connection Update Complete Event +typedef struct +{ + osal_event_hdr_t hdr; + uint8 BLEEventCode; + uint8 status; + uint16 connectionHandle; + uint16 connInterval; + uint16 connLatency; + uint16 connTimeout; +} hciEvt_BLEConnUpdateComplete_t; + +// LE Read Remote Used Features Complete Event +typedef struct +{ + osal_event_hdr_t hdr; + uint8 BLEEventCode; + uint8 status; + uint16 connectionHandle; + uint8 features[8]; +} hciEvt_BLEReadRemoteFeatureComplete_t; + +// LE Encryption Change Event +typedef struct +{ + osal_event_hdr_t hdr; + uint8 BLEEventCode; + uint16 connHandle; + uint8 reason; + uint8 encEnable; +} hciEvt_EncryptChange_t; + +// LE Long Term Key Requested Event +typedef struct +{ + osal_event_hdr_t hdr; + uint8 BLEEventCode; + uint16 connHandle; + uint8 random[B_RANDOM_NUM_SIZE]; + uint16 encryptedDiversifier; +} hciEvt_BLELTKReq_t; + +// LE DATE LENGTH CHANGE Event +typedef struct +{ + osal_event_hdr_t hdr; + uint8 BLEEventCode; + uint16 connHandle; + uint16 MaxTxOctets; + uint16 MaxTxTime; + uint16 MaxRxOctets; + uint16 MaxRxTime; +} hciEvt_BLEDataLenChange_t; + +// LE PHY UPDATE Complete Event +typedef struct +{ + osal_event_hdr_t hdr; + uint8 BLEEventCode; + uint8 status; + uint16 connHandle; + uint8 txPhy; + uint8 rxPhy; +} hciEvt_BLEPhyUpdateComplete_t; + +// LE PHY UPDATE Complete Event +typedef struct +{ + osal_event_hdr_t hdr; + uint8 BLEEventCode; +} hciEvt_BLEEvent_Hdr_t; + +// Number of Completed Packets Event +typedef struct +{ + osal_event_hdr_t hdr; + uint8 numHandles; + uint16* pConnectionHandle; // pointer to the connection handle array + uint16* pNumCompletedPackets; // pointer to the number of completed packets array +} hciEvt_NumCompletedPkt_t; + +// Command Complete Event +typedef struct +{ + osal_event_hdr_t hdr; + uint8 numHciCmdPkt; // number of HCI Command Packet + uint16 cmdOpcode; + uint8* pReturnParam; // pointer to the return parameter +} hciEvt_CmdComplete_t; + +// Command Status Event +typedef struct +{ + osal_event_hdr_t hdr; + uint8 cmdStatus; + uint8 numHciCmdPkt; + uint16 cmdOpcode; +} hciEvt_CommandStatus_t; + +// Hardware Error Event +typedef struct +{ + osal_event_hdr_t hdr; + uint8 hardwareCode; +} hciEvt_HardwareError_t; + +// Disconnection Complete Event +typedef struct +{ + osal_event_hdr_t hdr; + uint8 status; + uint16 connHandle; // connection handle + uint8 reason; +} hciEvt_DisconnComplete_t; + +// Data Buffer Overflow Event +typedef struct +{ + osal_event_hdr_t hdr; + uint8 linkType; // synchronous or asynchronous buffer overflow +} hciEvt_BufferOverflow_t; + +// Data structure for HCI Command Complete Event Return Parameter +typedef struct +{ + uint8 status; + uint16 dataPktLen; + uint8 numDataPkts; +} hciRetParam_LeReadBufSize_t; + +typedef struct +{ + uint16 eventType; // advertisment or scan response event type + uint8 addrType; // public or random address type + uint8 addr[B_ADDR_LEN]; // device address + uint8 primaryPHY; + uint8 secondaryPHY; + uint8 advertisingSID; + uint8 txPower; + int8 rssi; // report RSSI + uint16 periodicAdvertisingInterval; + uint8 directAddrType; + uint8 directAddr[B_ADDR_LEN]; + uint8 dataLen; // length of report data + uint8 rptData[B_MAX_EXT_ADV_LEN]; // report data given by dataLen +} hciEvt_ExtAdvRptInfo_t; + +// Extended adv report +typedef struct +{ + osal_event_hdr_t hdr; + uint8 BLEEventCode; + uint8 numReports; + hciEvt_ExtAdvRptInfo_t* rptInfo; // pointer to the array of devInfo +} hciEvt_BLEExtAdvPktReport_t; + + +typedef struct +{ + osal_event_hdr_t hdr; + uint8 BLEEventCode; + uint8 status; + uint16 syncHandle; + uint8 advertisingSID; + uint8 advertiserAddressType; + uint8 advertiserAddress[B_ADDR_LEN]; + uint8 advertiserPHY; + uint16 periodicAdvertisingInterval; + uint8 advertiserClockAccuracy; +} hciEvt_BLEPrdAdvSyncEstabPkt_t; + +typedef struct +{ + osal_event_hdr_t hdr; + uint8 BLEEventCode; + uint16 syncHandle; +} hciEvt_BLEPrdAdvSyncLostPkt_t; + +// 2020-4-22 LE Advertising Set Terminated event +typedef struct +{ + osal_event_hdr_t hdr; + uint8 BLEEventCode; + uint8 status; + uint8 adv_handle; + uint16 connHandle; // connection handle + uint8 Num_Completed_Extended_Advertising_Events; +} hciEvt_AdvSetTerminated_t; + +// 2020-4-22 LE Channel Selection Algorithm event +typedef struct +{ + osal_event_hdr_t hdr; + uint8 BLEEventCode; + uint16 connHandle; // connection handle + uint8 chn_sel; +} hciEvt_ChannelSelAlgo_t; + +// 2020-01-14 LE IQ report event structure +typedef struct +{ + uint16 Handle; // syncHandle for connectionless handle , connection for connection Handle + uint8 chan_idx; + int16 rssi; + uint8 rssi_antID; + uint8 cte_type; + uint8 slot_duration; + uint8 packet_status; + uint16 EventCnt; // paEventcounter or connEventCounter + uint8 sampCnt; + uint8 ISample[B_MAX_IQ_LEN]; + uint8 QSample[B_MAX_IQ_LEN]; +} hciEvt_IQReportPkt_t; + +// 2020-01-14 LE Connectionless IQ report event structure +typedef struct +{ + osal_event_hdr_t hdr; + uint8 BLEEventCode; + hciEvt_IQReportPkt_t ConnectionlessIQ; +} hciEvt_BLEConnectionlessIQ_Pkt_t; + +// 2020-01-14 LE Connection IQ report event structure +typedef struct +{ + osal_event_hdr_t hdr; + uint8 BLEEventCode; + uint8 RX_PHY; + hciEvt_IQReportPkt_t ConnectionIQ; +} hciEvt_BLEConnectionIQ_Pkt_t; + +// 2020-01-14 LE Connection IQ report event structure +typedef struct +{ + osal_event_hdr_t hdr; + uint8 BLEEventCode; + uint8 status; + uint16 connHandle; +} hciEvt_BLE_CTEReport_Pkt_t; + + +typedef struct +{ + uint16 syncHandle; + uint8 txPower; + uint8 rssi; + uint8 cteType; + uint8 dataStatus; + uint8 dataLength; + uint8 data[B_MAX_PERIOD_ADV_LEN]; +} hciEvt_PrdAdvRptInfo_t; + + + +// Periodic adv report +typedef struct +{ + osal_event_hdr_t hdr; + uint8 BLEEventCode; + hciEvt_PrdAdvRptInfo_t* rptInfo; // pointer to the array of devInfo +} hciEvt_BLEPrdAdvPktReport_t; + +typedef struct +{ + osal_event_hdr_t hdr; + uint8* pData; +} hciPacket_t; + +typedef struct +{ + osal_event_hdr_t hdr; + uint8 pktType; + uint16 connHandle; + uint8 pbFlag; + uint16 pktLen; + uint8* pData; +} hciDataPacket_t; + +// OSAL HCI_DATA_EVENT message format. This message is used to forward incoming +// data messages up to an application +typedef struct +{ + osal_event_hdr_t hdr; // OSAL event header + uint16 connHandle; // connection handle + uint8 pbFlag; // data packet boundary flag + uint16 len; // length of data packet + uint8* pData; // data packet given by len +} hciDataEvent_t; + + + + +/******************************************************************************* + LOCAL VARIABLES +*/ + +/******************************************************************************* + GLOBAL VARIABLES +*/ + +/* +** HCI Support Functions +*/ + +/******************************************************************************* + @fn HCI_bm_alloc API + + @brief This API is used to allocate memory using buffer management. + + Note: This function should never be called by the application. + It is only used by HCI and L2CAP_bm_alloc. + + input parameters + + @param size - Number of bytes to allocate from the heap. + + output parameters + + @param None. + + @return Pointer to buffer, or NULL. +*/ +extern void* HCI_bm_alloc( uint16 size ); + + +/******************************************************************************* + @fn HCI_ValidConnTimeParams API + + @brief This API is used to check that the connection time parameter + ranges are valid, and that the connection time parameter + combination is valid. + + Note: Only connIntervalMax is used as part of the time parameter + combination check. + + input parameters + + @param connIntervalMin - Minimum connection interval. + @param connIntervalMax - Maximum connection interval. + @param connLatency - Connection slave latency. + @param connTimeout - Connection supervision timeout. + + output parameters + + @param None. + + @return TRUE: Connection time parameter check is valid. + FALSE: Connection time parameter check is invalid. +*/ +extern uint8 HCI_ValidConnTimeParams( uint16 connIntervalMin, + uint16 connIntervalMax, + uint16 connLatency, + uint16 connTimeout ); + + +/******************************************************************************* + @fn HCI_TestAppTaskRegister + + @brief HCI vendor specific registration for HCI Test Application. + + input parameters + + @param taskID - The HCI Test Application OSAL task identifer. + + output parameters + + @param None. + + @return None. +*/ +extern void HCI_TestAppTaskRegister( uint8 taskID ); + + +/******************************************************************************* + @fn HCI_GAPTaskRegister + + @brief HCI vendor specific registration for Host GAP. + + input parameters + + @param taskID - The Host GAP OSAL task identifer. + + output parameters + + @param None. + + @return None. +*/ +extern void HCI_GAPTaskRegister( uint8 taskID ); + + +/******************************************************************************* + + @fn HCI_L2CAPTaskRegister + + @brief HCI vendor specific registration for Host L2CAP. + + input parameters + + @param taskID - The Host L2CAP OSAL task identifer. + + output parameters + + @param None. + + @return None. + +*/ +extern void HCI_L2CAPTaskRegister( uint8 taskID ); + + +/******************************************************************************* + @fn HCI_SMPTaskRegister + + @brief HCI vendor specific registration for Host SMP. + + input parameters + + @param taskID - The Host SMP OSAL task identifer. + + output parameters + + @param None. + + @return None. +*/ +extern void HCI_SMPTaskRegister( uint8 taskID ); + + +/******************************************************************************* + @fn HCI_ExtTaskRegister + + @brief HCI vendor specific registration for Host extended commands. + + input parameters + + @param taskID - The Host Extended Command OSAL task identifer. + + output parameters + + @param None. + + @return None. +*/ +extern void HCI_ExtTaskRegister( uint8 taskID ); + + +/******************************************************************************* + @fn HCI_SendDataPkt API + + @brief This API is used to send a ACL data packet over a connection. + + Note: Empty packets are not sent. + + Related Events: HCI_NumOfCompletedPacketsEvent + + input parameters + + @param connHandle - Connection ID (handle). + @param pbFlag - Packet Boundary Flag. + @param pktLen - Number of bytes of data to transmit. + @param *pData - Pointer to data buffer to transmit. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_SendDataPkt( uint16 connHandle, + uint8 pbFlag, + uint16 pktLen, + uint8* pData ); + + + +/* +** HCI API +*/ + +/******************************************************************************* + @fn HCI_DisconnectCmd API + + @brief This BT API is used to terminate a connection. + + Related Events: HCI_CommandStatusEvent, + DisconnectEvent + + input parameters + + @param connHandle - Connection handle. + @param reason - Reason for disconnection: + HCI_DISCONNECT_AUTH_FAILURE, + HCI_DISCONNECT_REMOTE_USER_TERM, + HCI_DISCONNECT_REMOTE_DEV_POWER_OFF, + HCI_DISCONNECT_UNSUPPORTED_REMOTE_FEATURE, + HCI_DISCONNECT_KEY_PAIRING_NOT_SUPPORTED + HCI_DISCONNECT_UNACCEPTABLE_CONN_INTERVAL + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_DisconnectCmd( uint16 connHandle, + uint8 reason ); + + +/******************************************************************************* + @fn HCI_ReadRemoteVersionInfoCmd API + + @brief This BT API is used to request version information from the + the remote device in a connection. + + Related Events: HCI_CommandStatusEvent, + ReadRemoteVersionInfoEvent + + input parameters + + @param connHandle - Connection handle. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_ReadRemoteVersionInfoCmd( uint16 connHandle ); + + + +/******************************************************************************* + @fn HCI_SetEventMaskCmd API + + @brief This BT API is used to set the HCI event mask, which is used to + determine which events are supported. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param pMask - Pointer to an eight byte event mask. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_SetEventMaskCmd( uint8* pMask ); + + +/******************************************************************************* + @fn HCI_Reset API + + @brief This BT API is used to reset the Link Layer. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param None. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_ResetCmd( void ); + + + +/******************************************************************************* + @fn HCI_ReadTransmitPowerLevelCmd API + + @brief This BT API is used to read the transmit power level. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param connHandle - Connection handle. + @param txPwrType - HCI_READ_CURRENT_TX_POWER_LEVEL, + HCI_READ_MAXIMUM_TX_POWER_LEVEL + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_ReadTransmitPowerLevelCmd( uint16 connHandle, + uint8 txPwrType ); + + +/******************************************************************************* + @fn HCI_SetControllerToHostFlowCtrlCmd API + + @brief This BT API is used by the Host to turn flow control on or off + for data sent from the Controller to Host. + + Note: This command is currently not supported. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param flowControlEnable - HCI_CTRL_TO_HOST_FLOW_CTRL_OFF, + HCI_CTRL_TO_HOST_FLOW_CTRL_ACL_ON_SYNCH_OFF, + HCI_CTRL_TO_HOST_FLOW_CTRL_ACL_OFF_SYNCH_ON, + HCI_CTRL_TO_HOST_FLOW_CTRL_ACL_ON_SYNCH_ON + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_SetControllerToHostFlowCtrlCmd( uint8 flowControlEnable ); + + +/******************************************************************************* + @fn HCI_HostBufferSizeCmd API + + @brief This BT API is used by the Host to notify the Controller of the + maximum size ACL buffer size the Controller can send to the + Host. + + Note: This command is currently ignored by the Controller. It + is assumed that the Host can always handle the maximum + BLE data packet size. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param hostAclPktLen - Host ACL data packet length. + @param hostSyncPktLen - Host SCO data packet length . + @param hostTotalNumAclPkts - Host total number of ACL data packets. + @param hostTotalNumSyncPkts - Host total number of SCO data packets. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_HostBufferSizeCmd( uint16 hostAclPktLen, + uint8 hostSyncPktLen, + uint16 hostTotalNumAclPkts, + uint16 hostTotalNumSyncPkts ); + + +/******************************************************************************* + @fn HCI_HostNumCompletedPktCmd API + + @brief This BT API is used by the Host to notify the Controller of the + number of HCI data packets that have been completed for each + connection handle since this command was previously sent to the + controller. + + The Host_Number_Of_Conpleted_Packets command is a special + command. No event is normally generated after the command + has completed. The command should only be issued by the + Host if flow control in the direction from controller to + the host is on and there is at least one connection, or + if the controller is in local loopback mode. + + Note: It is assumed that there will be at most only one handle. + Even if more than one handle is provided, the Controller + does not track Host buffers as a function of connection + handles (and isn't required to do so). + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param numHandles - Number of connection handles. + @param connHandles - Array of connection handles. + @param numCompletedPkts - Array of number of completed packets. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_HostNumCompletedPktCmd( uint8 numHandles, + uint16* connHandles, + uint16* numCompletedPkts ); + + +/******************************************************************************* + @fn HCI_ReadLocalVersionInfoCmd API + + @brief This BT API is used to read the local version information. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param None. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_ReadLocalVersionInfoCmd( void ); + + +/******************************************************************************* + @fn HCI_ReadLocalSupportedCommandsCmd API + + @brief This BT API is used to read the locally supported commands. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param None. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_ReadLocalSupportedCommandsCmd( void ); + + +/******************************************************************************* + @fn HCI_ReadLocalSupportedFeaturesCmd API + + @brief This BT API is used to read the locally supported features. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param None. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_ReadLocalSupportedFeaturesCmd( void ); + + +/******************************************************************************* + @fn HCI_ReadBDADDRCmd API + + @brief This BT API is used to read this device's BLE address (BDADDR). + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param None. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_ReadBDADDRCmd( void ); + + +/******************************************************************************* + @fn HCI_ReadRssiCmd API + + @brief This BT API is used to read the RSSI of the last packet + received on a connection given by the connection handle. If + the Receiver Modem test is running (HCI_EXT_ModemTestRx), then + the RF RSSI for the last received data will be returned. If + there is no RSSI value, then HCI_RSSI_NOT_AVAILABLE will be + returned. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param connHandle - Connection handle. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_ReadRssiCmd( uint16 connHandle ); + +/* +** HCI Low Energy Commands +*/ + +/******************************************************************************* + @fn HCI_LE_SetEventMaskCmd API + + @brief This LE API is used to set the HCI LE event mask, which is used + to determine which LE events are supported. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param pEventMask - Pointer to LE event mask of 8 bytes. + + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_SetEventMaskCmd( uint8* pEventMask ); + + +/******************************************************************************* + @fn HCI_LE_ReadBufSizeCmd API + + @brief This LE API is used by the Host to determine the maximum ACL + data packet size allowed by the Controller. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param None. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_ReadBufSizeCmd( void ); + + +/******************************************************************************* + @fn HCI_LE_ReadLocalSupportedFeaturesCmd API + + @brief This LE API is used to read the LE locally supported features. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param None. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_ReadLocalSupportedFeaturesCmd( void ); + + +/******************************************************************************* + @fn HCI_LE_SetRandomAddressCmd API + + @brief This LE API is used to set this device's Random address. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param pRandAddr - Pointer to random address. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_SetRandomAddressCmd( uint8* pRandAddr ); + + + +/******************************************************************************* + @fn HCI_LE_SetAdvParamCmd API + + @brief This LE API is used to set the Advertising parameters. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param advIntervalMin - Minimum allowed advertising interval. + @param advIntervalMax - Maximum allowed advertising interval. + @param advType - HCI_CONNECTABLE_UNDIRECTED_ADV, + HCI_CONNECTABLE_DIRECTED_HDC_ADV, + HCI_SCANNABLE_UNDIRECTED, + HCI_NONCONNECTABLE_UNDIRECTED_ADV + HCI_CONNECTABLE_DIRECTED_LDC_ADV + @param ownAddrType - HCI_PUBLIC_DEVICE_ADDRESS, + HCI_RANDOM_DEVICE_ADDRESS + @param directAddrType - HCI_PUBLIC_DEVICE_ADDRESS, + HCI_RANDOM_DEVICE_ADDRESS + @param directAddr - Pointer to address of device when using + directed advertising. + @param advChannelMap - HCI_ADV_CHAN_37, + HCI_ADV_CHAN_38, + HCI_ADV_CHAN_39, + HCI_ADV_CHAN_37 | HCI_ADV_CHAN_38, + HCI_ADV_CHAN_37 | HCI_ADV_CHAN_39, + HCI_ADV_CHAN_38 | HCI_ADV_CHAN_39, + HCI_ADV_CHAN_ALL + @param advFilterPolicy - HCI_ADV_WL_POLICY_ANY_REQ, + HCI_ADV_WL_POLICY_WL_SCAN_REQ, + HCI_ADV_WL_POLICY_WL_CONNECT_REQ, + HCI_ADV_WL_POLICY_WL_ALL_REQ + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_SetAdvParamCmd( uint16 advIntervalMin, + uint16 advIntervalMax, + uint8 advType, + uint8 ownAddrType, + uint8 directAddrType, + uint8* directAddr, + uint8 advChannelMap, + uint8 advFilterPolicy ); + + +/******************************************************************************* + @fn HCI_LE_SetAdvDataCmd API + + @brief This LE API is used to set the Advertising data. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param dataLen - Length of Advertising data. + @param pData - Pointer to Advertising data. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_SetAdvDataCmd( uint8 dataLen, + uint8* pData ); + + +/******************************************************************************* + @fn HCI_LE_SetScanRspDataCmd API + + @brief This LE API is used to set the Advertising Scan Response data. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param dataLen - Length of Scan Response data. + @param pData - Pointer to Scan Response data. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_SetScanRspDataCmd( uint8 dataLen, + uint8* pData ); + + +/******************************************************************************* + @fn HCI_LE_SetAdvEnableCmd API + + @brief This LE API is used to turn Advertising on or off. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param advEnable - HCI_ENABLE_ADV, HCI_DISABLE_ADV + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_SetAdvEnableCmd( uint8 advEnable ); + + +/******************************************************************************* + @fn HCI_LE_ReadAdvChanTxPowerCmd API + + @brief This LE API is used to read transmit power when Advertising. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param None. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_ReadAdvChanTxPowerCmd( void ); + + +/******************************************************************************* + @fn HCI_LE_SetScanParamCmd API + + @brief This LE API is used to set the Scan parameters. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param scanType - HCI_SCAN_PASSIVE, HCI_SCAN_ACTIVE + @param scanInterval - Time between scan events. + @param scanWindow - Time of scan before scan event ends. + Note: When the scanWindow equals the scanInterval + then scanning is continuous. + @param ownAddrType - This device's address. + @param filterPolicy - HCI_SCAN_PASSIVE, HCI_SCAN_ACTIVE + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_SetScanParamCmd( uint8 scanType, + uint16 scanInterval, + uint16 scanWindow, + uint8 ownAddrType, + uint8 filterPolicy ); + + +/******************************************************************************* + @fn HCI_LE_SetScanEnableCmd API + + @brief This LE API is used to turn Scanning on or off. + + Related Events: HCI_CommandCompleteEvent, + AdvReportEvent + + input parameters + + @param scanEnable - HCI_SCAN_START, HCI_SCAN_STOP + @param filterDuplicates - HCI_FILTER_REPORTS_ENABLE, + HCI_FILTER_REPORTS_DISABLE + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_SetScanEnableCmd( uint8 scanEnable, + uint8 filterDuplicates ); + + +/******************************************************************************* + @fn HCI_LE_CreateConnCmd API + + @brief This LE API is used to create a connection. + + Related Events: HCI_CommandStatusEvent, + ConnectionCompleteEvent + + input parameters + + @param scanInterval - Time between Init scan events. + @param scanWindow - Time of scan before Init scan event ends. + Note: When the scanWindow equals the + scanInterval then scanning is + continuous. + @param initFilterPolicy - HCI_INIT_WL_POLICY_USE_PEER_ADDR, + HCI_INIT_WL_POLICY_USE_WHITE_LIST + @param addrTypePeer - HCI_PUBLIC_DEVICE_ADDRESS, + HCI_RANDOM_DEVICE_ADDRESS + @param peerAddr - Pointer to peer device's address. + @param ownAddrType - HCI_PUBLIC_DEVICE_ADDRESS, + HCI_RANDOM_DEVICE_ADDRESS + @param connIntervalMin - Minimum allowed connection interval. + @param connIntervalMax - Maximum allowed connection interval. + @param connLatency - Number of skipped events (slave latency). + @param connTimeout - Connection supervision timeout. + @param minLen - Info parameter about min length of conn. + @param maxLen - Info parameter about max length of conn. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_CreateConnCmd( uint16 scanInterval, + uint16 scanWindow, + uint8 initFilterPolicy, + uint8 addrTypePeer, + uint8* peerAddr, + uint8 ownAddrType, + uint16 connIntervalMin, + uint16 connIntervalMax, + uint16 connLatency, + uint16 connTimeout, + uint16 minLen, + uint16 maxLen ); + + +/******************************************************************************* + @fn HCI_LE_CreateConnCancelCmd API + + @brief This LE API is used to cancel a create connection. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param None. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_CreateConnCancelCmd( void ); + + +/******************************************************************************* + @fn HCI_LE_ReadWhiteListSizeCmd API + + @brief This LE API is used to read the white list. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param None. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_ReadWhiteListSizeCmd( void ); + + +/******************************************************************************* + @fn HCI_LE_ClearWhiteListCmd API + + @brief This LE API is used to clear the white list. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param None. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_ClearWhiteListCmd( void ); + + +/******************************************************************************* + @fn HCI_LE_AddWhiteListCmd API + + @brief This LE API is used to add a white list entry. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param addrType - HCI_PUBLIC_DEVICE_ADDRESS, HCI_RANDOM_DEVICE_ADDRESS + @param devAddr - Pointer to address of device to put in white list. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_AddWhiteListCmd( uint8 addrType, + uint8* devAddr ); + + +/******************************************************************************* + @fn HCI_LE_RemoveWhiteListCmd API + + @brief This LE API is used to remove a white list entry. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param addrType - HCI_PUBLIC_DEVICE_ADDRESS, HCI_RANDOM_DEVICE_ADDRESS + @param devAddr - Pointer to address of device to remove from the + white list. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_RemoveWhiteListCmd( uint8 addrType, + uint8* devAddr ); + + + +/******************************************************************************* + @fn HCI_LE_ConnUpdateCmd API + + @brief This LE API is used to update the connection parameters. + + Related Events: HCI_CommandStatusEvent, + ConnectionUpdateCompleteEvent + + input parameters + + @param connHandle - Time between Init scan events. + @param connIntervalMin - Minimum allowed connection interval. + @param connIntervalMax - Maximum allowed connection interval. + @param connLatency - Number of skipped events (slave latency). + @param connTimeout - Connection supervision timeout. + @param minLen - Info parameter about min length of conn. + @param maxLen - Info parameter about max length of conn. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_ConnUpdateCmd( uint16 connHandle, + uint16 connIntervalMin, + uint16 connIntervalMax, + uint16 connLatency, + uint16 connTimeout, + uint16 minLen, + uint16 maxLen ); + + +/******************************************************************************* + @fn HCI_LE_SetHostChanClassificationCmd API + + @brief This LE API is used to update the current data channel map. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param chanMap - Pointer to the new channel map. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_SetHostChanClassificationCmd( uint8* chanMap ); + + +/******************************************************************************* + @fn HCI_LE_ReadChannelMapCmd API + + @brief This LE API is used to read a connection's data channel map. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param connHandle - Connection handle. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_ReadChannelMapCmd( uint16 connHandle ); + +/******************************************************************************* + @fn HCI_LE_ReadRemoteUsedFeaturesCmd API + + @brief This LE API is used to read the remote device's used features. + + Related Events: HCI_CommandStatusEvent, + ReadRemoteUsedFeaturesCompleteEvent + + input parameters + + @param connHandle - Connection handle. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_ReadRemoteUsedFeaturesCmd( uint16 connHandle ); + + +/******************************************************************************* + @fn HCI_LE_EncryptCmd API + + @brief This LE API is used to perform an encryption using AES128. + + Note: Input parameters are ordered MSB..LSB. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param key - Pointer to 16 byte encryption key. + @param plainText - Pointer to 16 byte plaintext data. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_EncryptCmd( uint8* key, + uint8* plainText ); + + +/******************************************************************************* + @fn HCI_LE_RandCmd API + + @brief This LE API is used to generate a random number. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param None. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_RandCmd( void ); + + + +/******************************************************************************* + @fn HCI_LE_StartEncyptCmd API + + @brief This LE API is used to start encryption in a connection. + + Related Events: HCI_CommandStatusEvent, + EncChangeEvent or + EncKeyRefreshEvent + + input parameters + + @param connHandle - Connection handle. + @param random - Pointer to eight byte Random number. + @param encDiv - Pointer to two byte Encrypted Diversifier. + @param ltk - Pointer to 16 byte Long Term Key. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_StartEncyptCmd( uint16 connHandle, + uint8* random, + uint8* encDiv, + uint8* ltk ); + +/******************************************************************************* + @fn HCI_LE_LtkReqReplyCmd API + + @brief This LE API is used by the Host to send to the Controller a + positive LTK reply. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param connHandle - Connection handle. + @param ltk - Pointer to 16 byte Long Term Key. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_LtkReqReplyCmd( uint16 connHandle, + uint8* ltk ); + +/******************************************************************************* + @fn HCI_LE_LtkReqNegReplyCmd API + + @brief This LE API is used by the Host to send to the Controller a + negative LTK reply. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param connHandle - Connectin handle. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_LtkReqNegReplyCmd( uint16 connHandle ); + + +/******************************************************************************* + @fn HCI_LE_ReadSupportedStatesCmd API + + @brief This LE API is used to read the Controller's supported states. + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param None. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_ReadSupportedStatesCmd( void ); + + +/******************************************************************************* + @fn HCI_LE_ReceiverTestCmd API + + @brief This LE API is used to start the receiver Direct Test Mode test. + + Note: A HCI reset should be issued when done using DTM! + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param rxFreq - Rx RF frequency: + k=0..HCI_DTM_NUMBER_RF_CHANS-1, where: F=2402+(k*2MHz) + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_ReceiverTestCmd( uint8 rxFreq ); + + +/******************************************************************************* + @fn HCI_LE_TransmitterTestCmd API + + @brief This LE API is used to start the transmit Direct Test Mode test. + + Note: The BLE device is to transmit at maximum power! + + Note: A HCI reset should be issued when done using DTM! + + input parameters + + @param txFreq - Tx RF frequency: + k=0..HCI_DTM_NUMBER_RF_CHANS-1, where: + F=2402+(k*2MHz) + @param dataLen - Test data length in bytes: + 0..HCI_DIRECT_TEST_MAX_PAYLOAD_LEN + @param payloadType - Type of packet payload, per Direct Test Mode spec: + HCI_DIRECT_TEST_PAYLOAD_PRBS9, + HCI_DIRECT_TEST_PAYLOAD_0x0F, + HCI_DIRECT_TEST_PAYLOAD_0x55, + HCI_DIRECT_TEST_PAYLOAD_PRBS15, + HCI_DIRECT_TEST_PAYLOAD_0xFF, + HCI_DIRECT_TEST_PAYLOAD_0x00, + HCI_DIRECT_TEST_PAYLOAD_0xF0, + HCI_DIRECT_TEST_PAYLOAD_0xAA + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_TransmitterTestCmd( uint8 txFreq, + uint8 dataLen, + uint8 pktPayload ); + + +/******************************************************************************* + @fn HCI_LE_TestEndCmd API + + @brief This LE API is used to end the Direct Test Mode test. + + Note: A HCI reset should be issued when done using DTM! + + Related Events: HCI_CommandCompleteEvent + + input parameters + + @param None. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_LE_TestEndCmd( void ); + + +// BBB ROM code add +extern hciStatus_t HCI_LE_AddDevToResolvingListCmd( uint8 addrType, + uint8* devAddr, + uint8* peerIrk, + uint8* localIrk); + + +extern hciStatus_t HCI_LE_RemoveResolvingListCmd( uint8 addrType, + uint8* devAddr ); + +extern hciStatus_t HCI_LE_ClearResolvingListCmd( void ); + +extern hciStatus_t HCI_LE_ReadResolvingListSizeCmd( void ); + +extern hciStatus_t HCI_LE_SetAddressResolutionEnableCmd( uint8 enable ); + +extern hciStatus_t HCI_LE_SetResolvablePrivateAddressTimeoutCmd( uint16 rpaTimeout ); + + +/* +** HCI for Extended Adv +*/ +// +extern hciStatus_t HCI_LE_SetExtAdvSetRandomAddressCmd( uint8 adv_handle, + uint8* random_address); + +extern hciStatus_t HCI_LE_SetExtAdvParamCmd( uint8 adv_handle, + uint16 adv_event_properties, + uint32 primary_advertising_interval_Min, // 3 octets + uint32 primary_advertising_interval_Max, // 3 octets + uint8 primary_advertising_channel_map, + uint8 own_address_type, + uint8 peer_address_type, + uint8* peer_address, + uint8 advertising_filter_policy, + int8 advertising_tx_power, // update 2020-04-08 + uint8 primary_advertising_PHY, + uint8 secondary_advertising_max_skip, + uint8 secondary_advertising_PHY, + uint8 advertising_SID, + uint8 scan_request_notification_enable + ); + +// +extern hciStatus_t HCI_LE_SetExtAdvDataCmd( uint8 adv_handle, + uint8 operation, + uint8 fragment_preference, + uint8 advertising_data_length, + uint8* advertising_data + ); +// +extern hciStatus_t HCI_LE_SetExtScanRspDataCmd( uint8 adv_handle, + uint8 operation, + uint8 fragment_preference, + uint8 scan_rsp_data_length, + uint8* scan_rsp_data + ); + +// +extern hciStatus_t HCI_LE_SetExtAdvEnableCmd( uint8 enable, + uint8 number_of_sets, + uint8* advertising_handle, + uint16* duration, + uint8* max_extended_advertising_events); + +// +extern hciStatus_t HCI_LE_ReadMaximumAdvDataLengthCmd( void ); + +// +extern hciStatus_t HCI_LE_ReadNumberOfSupportAdvSetCmd( void ); + +// +extern hciStatus_t HCI_LE_RemoveAdvSetCmd( uint8 adv_handle); + +// +extern hciStatus_t HCI_LE_ClearAdvSetsCmd( void); + + +extern hciStatus_t HCI_LE_SetExtendedScanParametersCmd(uint8 own_address_type, + uint8 scanning_filter_policy, + uint8 scanning_PHYs, + uint8* scan_sype, + uint16* scan_interval, + uint16* scan_window); + +extern hciStatus_t HCI_LE_SetExtendedScanEnableCmd(uint8 enable, + uint8 filter_duplicates, + uint16 duration, + uint16 period); + +extern hciStatus_t HCI_LE_ExtendedCreateConnectionCmd(uint8 initiator_filter_policy, + uint8 own_address_type, + uint8 peer_address_type, + uint8* peer_address, + uint8 initiating_PHYs, + uint16* scan_interval, + uint16* scan_window, + uint16* conn_interval_min, + uint16* conn_interval_max, + uint16* conn_latency, + uint16* supervision_timeout, + uint16* minimum_CE_length, + uint16* maximum_CE_length); + +// +extern hciStatus_t HCI_LE_SetPeriodicAdvParameterCmd( uint8 adv_handle, + uint16 interval_min, + uint16 interval_max, + uint16 adv_event_properties + ); + +extern hciStatus_t HCI_LE_SetPeriodicAdvDataCmd( uint8 adv_handle, + uint8 operation, + uint8 advertising_data_length, + uint8* advertising_data + ); + +extern hciStatus_t HCI_LE_SetPeriodicAdvEnableCmd( uint8 enable, + uint8 advertising_handle); + + +extern hciStatus_t HCI_LE_PeriodicAdvertisingCreateSyncCmd(uint8 Options, + uint8 Advertising_SID, + uint8 Advertiser_Address_Type, + uint8* Advertiser_Address, + uint16 Skip, + uint16 Sync_Timeout, + uint8 Sync_CTE_Type); + +extern hciStatus_t HCI_LE_PeriodicAdvertisingCreateSyncCancelCmd(void); + +extern hciStatus_t HCI_LE_PeriodicAdvertisingTerminateSyncCmd(uint16 sync_handle); + +extern hciStatus_t HCI_LE_AddDevToPeriodicAdvListCmd( uint8 addrType, + uint8* devAddr, + uint8 sid); +extern hciStatus_t HCI_LE_RemovePeriodicAdvListCmd( uint8 addrType, + uint8* devAddr, + uint8 sid); +extern hciStatus_t HCI_LE_ClearPeriodicAdvListCmd( void ); +extern hciStatus_t HCI_LE_ReadPeriodicAdvListSizeCmd( void ); + + +/****************************************************************************** + fn: HCI_LE_ConnectionlessCTE_TransmitParamcmd + + brief: set CTE Parameters in any periodic advertising + 1ã€CTE Type + 2ã€CTE Length + 3ã€CTE antenna switching pattern + + input parameters: + advertising handle : Identify advertising set 0x0-0xEF + CTE_Length : CTE Length in 8us 0x2-0x14 + CTE_Type : 0:AOA CTE , 1:AoD CTE with 1us,2:AoD CTE with 2us, + CTE_Count : how many CTE packet in each PA event 0x1-0x10 + Switch_Pattern_LEN : number of Antenna IDs in the pattern + : AOD CTE, AOA shall be ignored + : 0x2-0x4B + Antenna_IDs[i] : List of Antenna IDs in the pattern + : AOD CTE, AOA shall be ignored + + output parameters: + Status :HCI_SUCCESS or other error codes + + + return hciStatus_t : HCI_SUCCESS + + ******************************************************************************/ +hciStatus_t HCI_LE_ConnectionlessCTE_TransmitParamCmd( uint8 advertising_handle, + uint8 len, + uint8 type, + uint8 count, + uint8 Pattern_LEN, + uint8* AnaIDs); + + +/****************************************************************************** + fn: HCI_LE_ConnectionlessCTE_TransmitEnableCmd + + brief: Controller enable or disable CTE in PA + + input parameters: + advertising handle : Identify advertising set in which CTE is enable or disable + : 0x0-0xEF + enable : 0 : disable , 1: enable + + + output parameters: + Status :HCI_SUCCESS or other error codes + + + return hciStatus_t : HCI_SUCCESS or other error codes + + ******************************************************************************/ +hciStatus_t HCI_LE_ConnectionlessCTE_TransmitEnableCmd( uint8 advertising_handle, + uint8 enable); + + + +/****************************************************************************** + fn: HCI_LE_ConnectionlessIQ_SampleEnableCmd + + brief: Controller enable or disable capturing IQ Samples from the CTE of PA pcakets + + input parameters: + sync_handle : periodic advertising handle + Range:0x0 - 0x0EFF + slot_Duration : switching and sampling slot 0x1:1us,0x2:2us,Other:RFU + enable : 0x0:IQ Sampling disable, 0x1:IQ Sampling enable + MaxSampledCTEs : max number of CTE in each PA event that the controller + should collect and report + Range : 0x0-0x10 + 0x0 : sample and report all available CTE + pattern_len : number of Antenna IDs in the pattern + Range:0x2 - 0x4B + AnaIDs : list of Antenna IDs in the pattern + + + output parameters: + status : HCI_SUCCESS or other error codes + sync_handle : Periodic advertising handle + + + return hciStatus_t : HCI_SUCCESS + + ******************************************************************************/ +hciStatus_t HCI_LE_ConnectionlessIQ_SampleEnableCmd( uint16 sync_handle, + uint8 enable, + uint8 slot_Duration, + uint8 MaxSampledCTEs, + uint8 pattern_len, + uint8* AnaIDs); + + +/****************************************************************************** + fn: HCI_LE_ConnectionCTE_ReceiveParamCmd + + brief: enable or disable sampling received CTE fields on the connection + set antenna switching pattern + set switching and sampling slot durations + + input parameters: + connHandle : connection handle Range 0x0 - 0x0EFF + enable : sampling enable 0:disable , 1:enable + slot_Duration : switching and sampling slot 0:1us, 1: 2us + pattern_len : the number of Antenna IDs in the pattern + Range: 0x2-0x4B + AnaIDs : list of Antenna IDs in the pattern + + + output parameters: + Status : HCI_SUCCESS or other error codes + connHandle : Connection Handle + + + return hciStatus_t + + ******************************************************************************/ +hciStatus_t HCI_LE_Set_ConnectionCTE_ReceiveParamCmd( uint16 connHandle, + uint8 enable, + uint8 slot_Duration, + uint8 pattern_len, + uint8* AnaIDs); + + + +/****************************************************************************** + fn: HCI_LE_Set_ConnectionCTE_TransmitParamCmd + + brief: used to set the antenna switching pattern and permitted CTE type + + input parameters: + connHandle : connection Handle, Range: 0x0 - 0x0EFF + type : bit set for CTE type , bit 0 : AOA CTE response, + bit 1 : AOD CTE response with 1us slots + bit 2 : AOD CTE response with 2us slots + pattern_len : the number of Antenna IDs in the pattern + AnaIDs : list of Antenna IDs in the pattern + + + output parameters: + Status : 0 : success, other error code + ConnHandle : connection handle + + + return hciStatus_t + + ******************************************************************************/ +hciStatus_t HCI_LE_Set_ConnectionCTE_TransmitParamCmd( uint16 connHandle, + uint8 type, + uint8 pattern_len, + uint8* AnaIDs); + + + + +/****************************************************************************** + fn: HCI_LE_Connection_CTE_Request_EnableCmd + + brief: request Controller to start or stop initiating the CTE request + procedure on connection + + input parameters: + connHandle : connection Handle + Range:0x0 - 0x0EFF + enable : Enable or disable CTE request for the connection + 0:disable,1:enable + Interval : define whether the CTE request procedure is initiated + only once or periodically. + Range:0x0 - 0xFFFF + 0x0 : Initiate the CTE request procedure once + 0x1 - 0xFFFF : Requested interval for initiating the CTE + procedure in number of connection events + Range: + len : minimum length of the CTE in 8us units + Range: 0x2 - 0x14 + type : indicate the type of CTE that the controller shall + request from the remote device + 0x0:AOA CTE + 0x1:AOD CTE with 1us + 0x2:AOD CTE with 2us + + + output parameters: + Status : 0x0 : command succeed , 0x1 - 0xff : other error code + connHandle : connection handle + + + return hciStatus_t + + ******************************************************************************/ +hciStatus_t HCI_LE_Connection_CTE_Request_EnableCmd( uint16 connHandle, + uint8 enable, + uint16 Interval, + uint8 len, + uint8 type); + + +/****************************************************************************** + fn: HCI_LE_Connection_CTE_Response_EnableCmd + + brief: request the controller to respond to LL_CTE_REQ with LL_CTE_RSP on the + specified connection + + input parameters: + connHandle : connection Handle + Range:0x0 - 0x0EFF + enable : enable or disable CTE response for the connection + + + output parameters: + status : 0x0 : command succeed , 0x1 - 0xff : other error code + connHandle : connection handle + + + + return hciStatus_t + + ******************************************************************************/ +hciStatus_t HCI_LE_Connection_CTE_Response_EnableCmd( uint16 connHandle, + uint8 enable); + + +/****************************************************************************** + fn: HCI_LE_READ_Anatenna_InfoCmd + + brief: Host read the switching rates, the sampling reate, the number of antennae, + and the maxumum length of a transmitted CTE supported by the controller + + input parameters: + None + + + output parameters: + status : 0x0 : command succeed , 0x1 - 0xff : other error code + switch_sample_rate : bit number indicate supported switching and sampling rate + bit 0 : 1us switching AOD transmission + bit 1 : 1us sampling AOD reception + bit 2 : 1us switching and sampling AOA reception + Antenna_len : number of Antennae supported by the controller + MAX_Pattern_len : MAX length of antenna switching pattern spooorted by the controller + MAX_CTE_LEN : MAX length or a transmitted CTE supported in 8us units + + + return hciStatus_t + + ******************************************************************************/ +hciStatus_t HCI_LE_READ_Anatenna_InfoCmd(void); + +#if (PHY_MCU_TYPE == MCU_BUMBEE_M0) +/* +** HCI Vendor Specific Comamnds: Link Layer Extensions +*/ + +/******************************************************************************* + @fn HCI_EXT_SetRxGainCmd API + + @brief This HCI Extension API is used to set the receiver gain. + + Related Events: HCI_VendorSpecifcCommandCompleteEvent + + input parameters + + @param rxGain - HCI_EXT_RX_GAIN_STD, HCI_EXT_RX_GAIN_HIGH + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_SetRxGainCmd( uint8 rxGain ); + + +/******************************************************************************* + @fn HCI_EXT_SetTxPowerCmd API + + @brief This HCI Extension API is used to set the transmit power. + + Related Events: HCI_VendorSpecifcCommandCompleteEvent + + input parameters + + @param txPower - LL_EXT_TX_POWER_MINUS_23_DBM, + LL_EXT_TX_POWER_MINUS_6_DBM, + LL_EXT_TX_POWER_0_DBM, + LL_EXT_TX_POWER_4_DBM + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_SetTxPowerCmd( uint8 txPower ); + + +/******************************************************************************* + @fn HCI_EXT_OnePktPerEvtCmd API + + @brief This HCI Extension API is used to set whether a connection will + be limited to one packet per event. + + Related Events: HCI_VendorSpecifcCommandCompleteEvent + + input parameters + + @param control - HCI_EXT_ENABLE_ONE_PKT_PER_EVT, + HCI_EXT_DISABLE_ONE_PKT_PER_EVT + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_OnePktPerEvtCmd( uint8 control ); + + +/******************************************************************************* + @fn HCI_EXT_ClkDivOnHaltCmd API + + @brief This HCI Extension API is used to set whether the system clock + will be divided when the MCU is halted. + + Related Events: HCI_VendorSpecifcCommandCompleteEvent + + input parameters + + @param control - HCI_EXT_ENABLE_CLK_DIVIDE_ON_HALT, + HCI_EXT_DISABLE_CLK_DIVIDE_ON_HALT + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_ClkDivOnHaltCmd( uint8 control ); + + +/******************************************************************************* + @fn HCI_EXT_DeclareNvUsageCmd API + + @brief This HCI Extension API is used to indicate to the Controller + whether or not the Host will be using the NV memory during BLE + operations. + + Related Events: HCI_VendorSpecifcCommandCompleteEvent + + input parameters + + @param mode - HCI_EXT_NV_IN_USE, HCI_EXT_NV_NOT_IN_USE + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_DeclareNvUsageCmd( uint8 mode ); + + +/******************************************************************************* + @fn HCI_EXT_DecryptCmd API + + @brief This HCI Extension API is used to decrypt encrypted data using + AES128. + + Related Events: HCI_VendorSpecifcCommandCompleteEvent + + input parameters + + @param key - Pointer to 16 byte encryption key. + @param encText - Pointer to 16 byte encrypted data. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_DecryptCmd( uint8* key, + uint8* encText ); + + +/******************************************************************************* + @fn HCI_EXT_SetLocalSupportedFeaturesCmd API + + @brief This HCI Extension API is used to write this devie's supported + features. + + Related Events: HCI_VendorSpecifcCommandCompleteEvent + + input parameters + + @param localFeatures - Pointer to eight bytes of local features. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_SetLocalSupportedFeaturesCmd( uint8* localFeatures ); + + +/******************************************************************************* + @fn HCI_EXT_SetFastTxResponseTimeCmd API + + @brief This HCI Extension API is used to set whether transmit data is + sent as soon as possible even when slave latency is used. + + Related Events: HCI_VendorSpecifcCommandCompleteEvent + + input parameters + + @param control - HCI_EXT_ENABLE_FAST_TX_RESP_TIME, + HCI_EXT_DISABLE_FAST_TX_RESP_TIME + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_SetFastTxResponseTimeCmd( uint8 control ); + +/******************************************************************************* + @fn HCI_EXT_SetSlaveLatencyOverrideCmd API + + @brief This HCI Extension API is used to to enable or disable + suspending slave latency. + + Related Events: HCI_VendorSpecifcCommandCompleteEvent + + input parameters + + @param control - HCI_EXT_ENABLE_SL_OVERRIDE, + HCI_EXT_DISABLE_SL_OVERRIDE + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_SetSlaveLatencyOverrideCmd( uint8 control ); + + +/******************************************************************************* + @fn HCI_EXT_ModemTestTxCmd + + @brief This API is used start a continuous transmitter modem test, + using either a modulated or unmodulated carrier wave tone, at + the frequency that corresponds to the specified RF channel. Use + HCI_EXT_EndModemTest command to end the test. + + Note: A Controller reset will be issued by HCI_EXT_EndModemTest! + Note: The BLE device will transmit at maximum power. + Note: This API can be used to verify this device meets Japan's + TELEC regulations. + + Related Events: HCI_VendorSpecifcCommandCompleteEvent + + input parameters + + @param cwMode - HCI_EXT_TX_MODULATED_CARRIER, + HCI_EXT_TX_UNMODULATED_CARRIER + txFreq - Transmit RF channel k=0..39, where BLE F=2402+(k*2MHz). + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_ModemTestTxCmd( uint8 cwMode, + uint8 txFreq ); + + +/******************************************************************************* + @fn HCI_EXT_ModemHopTestTxCmd + + @brief This API is used to start a continuous transmitter direct test + mode test using a modulated carrier wave and transmitting a + 37 byte packet of Pseudo-Random 9-bit data. A packet is + transmitted on a different frequency (linearly stepping through + all RF channels 0..39) every 625us. Use HCI_EXT_EndModemTest + command to end the test. + + Note: A Controller reset will be issued by HCI_EXT_EndModemTest! + Note: The BLE device will transmit at maximum power. + Note: This API can be used to verify this device meets Japan's + TELEC regulations. + + input parameters + + @param None. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_ModemHopTestTxCmd( void ); + + +/******************************************************************************* + @fn HCI_EXT_ModemTestRxCmd + + @brief This API is used to start a continuous receiver modem test + using a modulated carrier wave tone, at the frequency that + corresponds to the specific RF channel. Any received data is + discarded. Receiver gain may be adjusted using the + HCI_EXT_SetRxGain command. RSSI may be read during this test + by using the HCI_ReadRssi command. Use HCI_EXT_EndModemTest + command to end the test. + + Note: A Controller reset will be issued by HCI_EXT_EndModemTest! + Note: The BLE device will transmit at maximum power. + + input parameters + + @param rxFreq - Receiver RF channel k=0..39, where BLE F=2402+(k*2MHz). + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_ModemTestRxCmd( uint8 rxFreq ); + + +/******************************************************************************* + @fn HCI_EXT_EndModemTestCmd + + @brief This API is used to shutdown a modem test. A complete Controller + reset will take place. + + input parameters + + @param None. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_EndModemTestCmd( void ); + + +/******************************************************************************* + @fn HCI_EXT_SetBDADDRCmd + + @brief This API is used to set this device's BLE address (BDADDR). + + Note: This command is only allowed when the device's state is + Standby. + + Related Events: HCI_VendorSpecifcCommandCompleteEvent + + input parameters + + @param bdAddr - A pointer to a buffer to hold this device's address. + An invalid address (i.e. all FF's) will restore this + device's address to the address set at initialization. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_SetBDADDRCmd( uint8* bdAddr ); + + +/******************************************************************************* + @fn HCI_EXT_SetSCACmd + + @brief This API is used to set this device's Sleep Clock Accuracy. + + Note: For a slave device, this value is directly used, but only + if power management is enabled. For a master device, this + value is converted into one of eight ordinal values + representing a SCA range, as specified in Table 2.2, + Vol. 6, Part B, Section 2.3.3.1 of the Core specification. + + Note: This command is only allowed when the device is not in a + connection. + + Note: The device's SCA value remains unaffected by a HCI_Reset. + + input parameters + + @param scaInPPM - A SCA value in PPM from 0..500. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_SetSCACmd( uint16 scaInPPM ); + + +/******************************************************************************* + @fn HCI_EXT_EnablePTMCmd + + @brief This HCI Extension API is used to enable Production Test Mode. + + Note: This function can only be directly called from the + application and is not available via an external transport + interface such as RS232. Also, no vendor specific + command complete will be returned. + + input parameters + + @param None. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_EnablePTMCmd( void ); + + +/******************************************************************************* + @fn HCI_EXT_SetFreqTuneCmd + + @brief This HCI Extension API is used to set the frequency tuning up + or down. Setting the mode up/down decreases/increases the amount + of capacitance on the external crystal oscillator. + + Note: This is a Production Test Mode only command! + + input parameters + + @param step - HCI_PTM_SET_FREQ_TUNE_UP, HCI_PTM_SET_FREQ_TUNE_DOWN + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_SetFreqTuneCmd( uint8 step ); + + +/******************************************************************************* + @fn HCI_EXT_SaveFreqTuneCmd + + @brief This HCI Extension API is used to save the frequency tuning + value to flash. + + Note: This is a Production Test Mode only command! + + input parameters + + @param None. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_SaveFreqTuneCmd( void ); + + +/******************************************************************************* + @fn HCI_EXT_SetMaxDtmTxPowerCmd API + + @brief This HCI Extension API is used to set the maximum transmit + output power for Direct Test Mode. + + Related Events: HCI_VendorSpecifcCommandCompleteEvent + + input parameters + + @param txPower - LL_EXT_TX_POWER_MINUS_23_DBM, + LL_EXT_TX_POWER_MINUS_6_DBM, + LL_EXT_TX_POWER_0_DBM, + LL_EXT_TX_POWER_4_DBM + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_SetMaxDtmTxPowerCmd( uint8 txPower ); + + +/******************************************************************************* + +*/ +extern llStatus_t HCI_EXT_MapPmIoPortCmd( uint8 ioPort, uint8 ioPin ); + + +/******************************************************************************* + @fn HCI_EXT_DisconnectImmedCmd API + + @brief This HCI Extension API is used to disconnect the connection + immediately. + + Note: The connection (if valid) is immediately terminated + without notifying the remote device. The Host is still + notified. + + input parameters + + @param connHandle - Connection handle. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_DisconnectImmedCmd( uint16 connHandle ); + + +/******************************************************************************* + @fn HCI_EXT_PacketErrorRate Vendor Specific API + + @brief This function is used to Reset or Read the Packet Error Rate + counters for a connection. + + Note: The counters are only 16 bits. At the shortest connection + interval, this provides a bit over 8 minutes of data. + + input parameters + + @param connHandle - The LL connection ID on which to send this data. + @param command - HCI_EXT_PER_RESET, HCI_EXT_PER_READ + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_PacketErrorRateCmd( uint16 connHandle, uint8 command ); + + + +/******************************************************************************* + @fn HCI_EXT_PERbyChanCmd Vendor Specific API + + @brief This HCI Extension API is used to start or end Packet Error Rate + by Channel counter accumulation for a connection. If the + pointer is not NULL, it is assumed there is sufficient memory + for the PER data, per the type perByChan_t. If NULL, then + the operation is considered disabled. + + Note: It is the user's responsibility to make sure there is + sufficient memory for the data, and that the counters + are cleared prior to first use. + + Note: The counters are only 16 bits. At the shortest connection + interval, this provides a bit over 8 minutes of data. + + input parameters + + @param connHandle - The LL connection ID on which to send this data. + @param perByChan - Pointer to PER by Channel data, or NULL. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_PERbyChanCmd( uint16 connHandle, perByChan_t* perByChan ); + + +/******************************************************************************* +*/ +extern hciStatus_t HCI_EXT_ExtendRfRangeCmd( void ); + + +/******************************************************************************* + @fn HCI_EXT_HaltDuringRfCmd API + + @brief This HCI Extension API is used to enable or disable halting the + CPU during RF. The system defaults to enabled. + + Related Events: HCI_VendorSpecifcCommandCompleteEvent + + input parameters + + @param mode - HCI_EXT_HALT_DURING_RF_ENABLE, + HCI_EXT_HALT_DURING_RF_DISABLE + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_HaltDuringRfCmd( uint8 mode ); + + +/******************************************************************************* + @fn HCI_EXT_AdvEventNoticeCmd Vendor Specific API + + @brief This HCI Extension API is used to enable or disable a + notification to the specified task using the specified task + event whenever a Adv event ends. A non-zero taskEvent value is + taken to be "enable", while a zero valued taskEvent is taken + to be "disable". + + input parameters + + @param taskID - User's task ID. + @param taskEvent - User's task event. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_AdvEventNoticeCmd( uint8 taskID, uint16 taskEvent ); + + +/******************************************************************************* + @fn HCI_EXT_ConnEventNoticeCmd Vendor Specific API + + @brief This HCI Extension API is used to enable or disable a + notification to the specified task using the specified task + event whenever a Connection event ends. A non-zero taskEvent + value is taken to be "enable", while a zero valued taskEvent + taken to be "disable". + + Note: Currently, only a Slave connection is supported. + + input parameters + + @param taskID - User's task ID. + @param taskEvent - User's task event. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_ConnEventNoticeCmd( uint8 taskID, uint16 taskEvent ); + + +/******************************************************************************* + @fn HCI_EXT_BuildRevisionCmd Vendor Specific API + + @brief This HCI Extension API is used set a user revision number or + read the build revision number. + + input parameters + + @param mode - HCI_EXT_SET_USER_REVISION | HCI_EXT_READ_BUILD_REVISION + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_BuildRevisionCmd( uint8 mode, uint16 userRevNum ); + + +/******************************************************************************* + @fn HCI_EXT_DelaySleepCmd Vendor Specific API + + @brief This HCI Extension API is used set the sleep delay. + + input parameters + + @param delay - 0..1000, in milliseconds. + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_DelaySleepCmd( uint16 delay ); + + +/******************************************************************************* + @fn HCI_EXT_ResetSystemCmd Vendor Specific API + + @brief This HCI Extension API is used to issue a soft or hard + system reset. + + input parameters + + @param mode - HCI_EXT_RESET_SYSTEM_HARD | HCI_EXT_RESET_SYSTEM_SOFT + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_ResetSystemCmd( uint8 mode ); + + + +/******************************************************************************* + @fn HCI_EXT_OverlappedProcessingCmd Vendor Specific API + + @brief This HCI Extension API is used to enable or disable overlapped + processing. + + input parameters + + @param mode - HCI_EXT_ENABLE_OVERLAPPED_PROCESSING | + HCI_EXT_DISABLE_OVERLAPPED_PROCESSING + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_OverlappedProcessingCmd( uint8 mode ); + +/******************************************************************************* + @fn HCI_EXT_NumComplPktsLimitCmd Vendor Specific API + + @brief This HCI Extension API is used to set the minimum number of + completed packets which must be met before a Number of + Completed Packets event is returned. If the limit is not + reach by the end of the connection event, then a Number of + Completed Packets event will be returned (if non-zero) based + on the flushOnEvt flag. + + input parameters + + @param limit - From 1 to HCI_MAX_NUM_DATA_BUFFERS. + @param flushOnEvt - HCI_EXT_DISABLE_NUM_COMPL_PKTS_ON_EVENT | + HCI_EXT_ENABLE_NUM_COMPL_PKTS_ON_EVENT + + output parameters + + @param None. + + @return hciStatus_t +*/ +extern hciStatus_t HCI_EXT_NumComplPktsLimitCmd( uint8 limit, + uint8 flushOnEvt ); + + +/******************************************************************************* + @fn HCI_PPLUS_AdvEventDoneNoticeCmd Vendor Specific API + + @brief This HCI Extension API is used to enable or disable a notification to the + specified task using the specified task event whenever a Adv event ends. + A non-zero taskEvent value is taken to be "enable", while a zero valued + taskEvent is taken to be "disable". + + input parameters + + @param taskID - User's task ID. + @param taskEvent - User's task event. + + output parameters + + @param None. + + @return hciStatus_t +*/ +hciStatus_t HCI_PPLUS_AdvEventDoneNoticeCmd( uint8 taskID, uint16 taskEvent ); + +/******************************************************************************* + @fn HCI_PPLUS_ConnEventDoneNoticeCmd Vendor Specific API + + @brief This HCI Extension API is used to enable or disable a notification to the + specified task using the specified task event whenever a Connection event + ends. A non-zero taskEvent value is taken to be "enable", while a zero valued + taskEvent is taken to be "disable". + + input parameters + + @param taskID - User's task ID. + @param taskEvent - User's task event. + + output parameters + + @param None. + + @return hciStatus_t +*/ +hciStatus_t HCI_PPLUS_ConnEventDoneNoticeCmd( uint8 taskID, uint16 taskEvent ); + +/******************************************************************************* + This HCI Extension API is used to enable or disable a notification to the + specified task using the specified task event whenever a Connection event + ends. A non-zero taskEvent value is taken to be "enable", while a zero valued + taskEvent is taken to be "disable". + +*/ +hciStatus_t HCI_PPLUS_DateLengthChangedNoticeCmd( uint8 taskID, uint16 taskEvent ); + +/******************************************************************************* + This HCI Extension API is used to enable or disable a notification to the + specified task using the specified task event whenever a Connection event + ends. A non-zero taskEvent value is taken to be "enable", while a zero valued + taskEvent is taken to be "disable". + +*/ +hciStatus_t HCI_PPLUS_PhyUpdateNoticeCmd( uint8 taskID, uint16 taskEvent ); + + +/******************************************************************************* + @fn HCI_PPLUS_ExtendTRXCmd Vendor Specific API + + @brief This HCI Extension API is used to enable or disable Tx/Rx packets limit + per connection event to 8(default is 4). + + input parameters + + @param enable - TRUE: 8Tx/8Rx; FALSE: 4Tx/4Rx + + output parameters + + @param None. + + @return hciStatus_t +*/ +hciStatus_t HCI_PPLUS_ExtendTRXCmd( uint8 enable ); + +#endif /*#if (PHY_MCU_TYPE == MCU_BUMBEE_M0)*/ + +/******************************************************************************* +*/ +hciStatus_t HCI_LE_SetDataLengthCmd( uint16 connHandle, + uint16 TxOctets, + uint16 TxTime ); + + +/******************************************************************************* +*/ +hciStatus_t HCI_LE_ReadMaxDataLengthCmd(void); + +/******************************************************************************* + This LE API is used to read Suggested Default max Data length + + Public function defined in hci.h. +*/ +hciStatus_t HCI_LE_ReadSuggestedDefaultDataLengthCmd(void); + +/******************************************************************************* + This LE API is used to write Suggested Default Data length + + Public function defined in hci.h. +*/ +hciStatus_t HCI_LE_WriteSuggestedDefaultDataLengthCmd(uint16 suggestedMaxTxOctets,uint16 suggestedMaxTxTime); + + +/******************************************************************************* + This LE API is used to set DefaultPhyMode + + Public function defined in hci.h. +*/ +hciStatus_t HCI_LE_SetDefaultPhyMode( uint16 connId,uint8 allPhy,uint8 txPhy, uint8 rxPhy); + + +/******************************************************************************* + This LE API is used to Set PHY Mode + + Public function defined in hci.h. +*/ +hciStatus_t HCI_LE_SetPhyMode( uint16 connId,uint8 allPhy,uint8 txPhy, uint8 rxPhy,uint16 phyOptions); + +/******************************************************************************* + This LE API is used to Read PHY Mode + + Public function defined in hci.h. +*/ +hciStatus_t HCI_LE_ReadPhyMode( uint16 connId); + + + +#ifdef __cplusplus +} +#endif + +#endif /* HCI_H */ diff --git a/arch/arm/src/phy62xx/ble/include/l2cap.h b/arch/arm/src/phy62xx/ble/include/l2cap.h new file mode 100644 index 00000000000..f228948d140 --- /dev/null +++ b/arch/arm/src/phy62xx/ble/include/l2cap.h @@ -0,0 +1,500 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/************************************************************************************************** + Filename: l2cap.h + Revised: + Revision: + + Description: This file contains the L2CAP definitions. + + + **************************************************************************************************/ + +#ifndef L2CAP_H +#define L2CAP_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ +#include "bcomdef.h" +#include "OSAL.h" + +#include "log.h" +/********************************************************************* + CONSTANTS +*/ +#ifndef MTU_SIZE +#define MTU_SIZE 23 +#endif +#if( MTU_SIZE < 23 ) +#error "MTU_SIZE define error" +#endif + +// Minimum supported information payload for the Basic information frame (B-frame) +#define L2CAP_MTU_SIZE MTU_SIZE + +// Minimum supported information payload for the Control frame (C-frame) +#define L2CAP_SIG_MTU_SIZE 23 + +// Basic L2CAP header: Length (2 bytes) + Channel ID (2 bytes) +#define L2CAP_HDR_SIZE 4 + +// Minimum size of PDU received from lower layer protocol (incoming +// packet), or delivered to lower layer protocol (outgoing packet). +#define L2CAP_PDU_SIZE ( L2CAP_HDR_SIZE + L2CAP_MTU_SIZE ) + +// L2CAP Channel Identifiers. Identifiers from 0x0001 to 0x003F are +// reserved for specific L2CAP functions. Identifiers 0x0001-0x0003 +// are reserved by BR/EDR. +#define L2CAP_CID_NULL 0x0000 // Illegal Identifier +#define L2CAP_CID_ATT 0x0004 // Attribute Protocol +#define L2CAP_CID_SIG 0x0005 // L2CAP Signaling +#define L2CAP_CID_SMP 0x0006 // Security Management Protocol +#define L2CAP_CID_GENERIC 0x0007 // Generic Fixed Channel + +// L2CAP Dynamic Channel Identifiers +#define L2CAP_BASE_DYNAMIC_CID 0x0040 +#define L2CAP_LAST_DYNAMIC_CID ( BASE_DYNAMIC_CID + L2CAP_NUM_CHANNELS - 1 ) + +// Number of Fixed channels: one for each of ATT, Signaling, SMP channels and one Generic Channel +#define L2CAP_NUM_FIXED_CHANNELS 4 + +// Number of Protocols supported -- for future use +#define L2CAP_NUM_PROTOCOLS 0 + +// Number of Auxiliary channels: one for each of Echo Request, Information +// Request and Connection Parameter Update Request +#define L2CAP_NUM_AUX_CHANNELS 3 + +// Number of Dynamic channels: one per each protocol supported on each physical connection +#define L2CAP_NUM_DYNAMIC_CHANNELS ( L2CAP_NUM_PROTOCOLS * MAX_NUM_LL_CONN ) + +// Total number of L2CAP channels: Dynamic channels plus Auxiliary channels +#define L2CAP_NUM_CHANNELS ( L2CAP_NUM_DYNAMIC_CHANNELS + L2CAP_NUM_AUX_CHANNELS ) + +// L2CAP Response Timeout expired (RTX) value for Signaling commands (in seconds). +// The RTX timer is used for response timeout or to terminate a dynamic channel +// when the remote device is unresponsive to signaling requests. Its value may +// range from 1 to 60 seconds. +#define L2CAP_RTX_TIMEOUT 30 + +// L2CAP Signaling Codes (type of commands) +#define L2CAP_CMD_REJECT 0x01 +#define L2CAP_ECHO_REQ 0x08 // No longer supported +#define L2CAP_ECHO_RSP 0x09 // No longer supported +#define L2CAP_INFO_REQ 0x0a // No longer supported +#define L2CAP_INFO_RSP 0x0b // No longer supported +#define L2CAP_PARAM_UPDATE_REQ 0x12 +#define L2CAP_PARAM_UPDATE_RSP 0x13 + +/********************************************************************* + Command Reject: Reason Codes +*/ +// Command not understood +#define L2CAP_REJECT_CMD_NOT_UNDERSTOOD 0x0000 + +// Signaling MTU exceeded +#define L2CAP_REJECT_SIGNAL_MTU_EXCEED 0x0001 + +// Invalid CID in request +#define L2CAP_REJECT_INVALID_CID 0x0002 + +/********************************************************************* + Information Request/Response: Info Type +*/ +// Connectionless MTU +#define L2CAP_INFO_CONNLESS_MTU 0x0001 + +// Extended features supported +#define L2CAP_INFO_EXTENDED_FEATURES 0x0002 + +// Fixed channels supported +#define L2CAP_INFO_FIXED_CHANNELS 0x0003 + +/********************************************************************* + Information Response: Extended Features Mask Values +*/ +// Fixed channels are supported +#define L2CAP_FIXED_CHANNELS 0x00000080 + +// Length of Extended Features bit mask +#define L2CAP_EXTENDED_FEATURES_SIZE 4 + +/********************************************************************* + Information Response: Fixed Channels Mask Values +*/ +// Fixed Channel ATT is supported +#define L2CAP_FIXED_CHANNELS_ATT 0x10 + +// Fixed Channel L2CAP Signaling is supported +#define L2CAP_FIXED_CHANNELS_SIG 0x20 + +// Fixed Channel SMP is supported +#define L2CAP_FIXED_CHANNELS_SMP 0x40 + +// Length of Fixed Channels bit mask +#define L2CAP_FIXED_CHANNELS_SIZE 8 + +/********************************************************************* + Information Response: Result Values +*/ +// Success +#define L2CAP_INFO_SUCCESS 0x0000 + +// Not supported +#define L2CAP_INFO_NOT_SUPPORTED 0x0001 + +/********************************************************************* + Connection Parameter Update Response: Result values +*/ +// Connection Parameters accepted +#define L2CAP_CONN_PARAMS_ACCEPTED 0x0000 + +// Connection Parameters rejected +#define L2CAP_CONN_PARAMS_REJECTED 0x0001 + + +/********************************************************************* + VARIABLES +*/ + +/********************************************************************* + MACROS +*/ + +/********************************************************************* + TYPEDEFS +*/ + +// Invalid CID in Request format +typedef struct +{ + uint16 localCID; // Destination CID from the rejected command + uint16 remoteCID; // Source CID from the rejected command +} l2capInvalidCID_t; + +// Command Reject Reason Data format +typedef union +{ + uint16 signalMTU; // Maximum Signaling MTU + l2capInvalidCID_t invalidCID; // Invalid CID in Request +} l2capReasonData_t; + +// Command Reject format +typedef struct +{ + uint16 reason; // Reason + l2capReasonData_t reasonData; // Reason Data + + // Shorthand access for union members +#define maxSignalMTU reasonData.signalMTU +#define invalidLocalCID reasonData.invalidCID.localCID +#define invalidRemoteCID reasonData.invalidCID.remoteCID +} l2capCmdReject_t; + +// Echo Request format +typedef struct +{ + uint8* pData; // Optional data field + uint16 len; // Length of data +} l2capEchoReq_t; + +// Echo Response format +typedef struct +{ + uint8* pData; // Optional data field -- must be freed by the application + uint16 len; // Length of data +} l2capEchoRsp_t; + +// Information Request format +typedef struct +{ + uint16 infoType; // Information type +} l2capInfoReq_t; + +// Information Response Data field +typedef union +{ + uint16 connectionlessMTU; // Connectionless MTU + uint32 extendedFeatures; // Extended features supported + uint8 fixedChannels[L2CAP_FIXED_CHANNELS_SIZE]; // Fixed channels supported +} l2capInfo_t; + +// Information Response format +typedef struct +{ + uint16 result; // Result + uint16 infoType; // Information type + l2capInfo_t info; // Content of Info field depends on infoType +} l2capInfoRsp_t; + +// Connection Parameter Update Request format +typedef struct +{ + uint16 intervalMin; // Minimum Interval + uint16 intervalMax; // Maximum Interval + uint16 slaveLatency; // Slave Latency + uint16 timeoutMultiplier; // Timeout Multiplier +} l2capParamUpdateReq_t; + +// Connection Parameter Update Response format +typedef struct +{ + uint16 result; // Result +} l2capParamUpdateRsp_t; + +// Union of all L2CAP Signaling commands +typedef union +{ + // Requests + l2capEchoReq_t echoReq; + l2capInfoReq_t infoReq; + l2capParamUpdateReq_t updateReq; + + // Responses + l2capCmdReject_t cmdReject; + l2capEchoRsp_t echoRsp; + l2capInfoRsp_t infoRsp; + l2capParamUpdateRsp_t updateRsp; +} l2capSignalCmd_t; + +// OSAL L2CAP_SIGNAL_EVENT message format. This message is used to deliver an +// incoming Signaling command up to an upper layer application. +typedef struct +{ + osal_event_hdr_t hdr; // L2CAP_SIGNAL_EVENT and status + uint16 connHandle; // connection message was received on + uint8 id; // identifier to match responses with requests + uint8 opcode; // type of command + l2capSignalCmd_t cmd; // command data +} l2capSignalEvent_t; + +// L2CAP packet structure +typedef struct +{ + uint16 CID; // local channel id + uint8* pPayload; // pointer to information payload. This contains the payload + // received from the upper layer protocol (outgoing packet), + // or delivered to the upper layer protocol (incoming packet). + uint16 len; // length of information payload +} l2capPacket_t; + +// OSAL L2CAP_DATA_EVENT message format. This message is used to forward an +// incoming data packet up to an upper layer application. +typedef struct +{ + osal_event_hdr_t hdr; // L2CAP_DATA_EVENT and status + uint16 connHandle; // connection packet was received on + l2capPacket_t pkt; // received packet +} l2capDataEvent_t; + + +typedef struct +{ + uint16 cIdx; // reassemble packet current idx + l2capPacket_t pkt; // received packet +} l2capReassemblePkt_t; + +typedef struct +{ + uint8 len; // pkt len + uint8* ptr ; // pkt point +} segmentBuff_t; + +typedef struct +{ + segmentBuff_t pkt[10];//251/27->9.2 + uint8 depth; + uint8 idx; + uint8* pBufScr; //source buffer ptr + uint8 fragment; +} l2capSegmentBuff_t; + + +typedef struct +{ + uint32 reassembleInCnt; + uint32 reassembleOutCnt; + uint32 reassembleErrIdx; + uint32 reassembleErrCID; + uint32 reassembleErrInComp; + uint32 reassembleErrMiss; + uint32 resssambleMemAlocErr; + + uint32 segmentInCnt; + uint32 segmentOutCnt; + uint32 segmentErrCnt; + uint32 fragmentSendCounter; + uint32 segmentMemAlocErr; + uint32 segmentSentToLinkLayerErr; + +} l2capSARDbugCnt_t; +//typedef enum +//{ +// DATA_IN_YBUF_FIRST = 0, // YBUF fisrt bufin fisrt shift out +// DATA_IN_XBUF_FIRST = 1 +//} SegmentBuffOrder_t; + +//typedef struct +//{ +// l2capSegmentBuff_t xBuf; +// l2capSegmentBuff_t yBuf; +// SegmentBuffOrder_t order; //which buffer +// +//}l2capSegmentPkt_t; + + + +/********************************************************************* + VARIABLES +*/ + +/********************************************************************* + FUNCTIONS +*/ + +/* + Initialize L2CAP layer. +*/ +extern void L2CAP_Init( uint8 taskId ); + +/* + L2CAP Task event processing function. +*/ +extern uint16 L2CAP_ProcessEvent( uint8 taskId, uint16 events ); + +/* + Register a protocol/application with an L2CAP channel. +*/ +extern bStatus_t L2CAP_RegisterApp( uint8 taskId, uint16 CID ); + +/* + Send L2CAP Data Packet. +*/ +extern bStatus_t L2CAP_SendData( uint16 connHandle, l2capPacket_t* pPkt ); + +/* + Send Command Reject. +*/ +extern bStatus_t L2CAP_CmdReject( uint16 connHandle, uint8 id, l2capCmdReject_t* pCmdReject ); + +/* + Build Command Reject. +*/ +extern uint16 L2CAP_BuildCmdReject( uint8* pBuf, uint8* pCmd ); + +/* + Send L2CAP Echo Request. +*/ +extern bStatus_t L2CAP_EchoReq( uint16 connHandle, l2capEchoReq_t* pEchoReq, uint8 taskId ); + +/* + Send L2CAP Information Request. +*/ +extern bStatus_t L2CAP_InfoReq( uint16 connHandle, l2capInfoReq_t* pInfoReq, uint8 taskId ); + +/* + Build Information Response. +*/ +extern uint16 L2CAP_BuildInfoRsp( uint8* pBuf, uint8* pCmd ); + +/* + Parse Information Request. +*/ +extern bStatus_t L2CAP_ParseInfoReq( l2capSignalCmd_t* pCmd, uint8* pData, uint16 len ); + +/* + Send L2CAP Connection Parameter Update Request. +*/ +extern bStatus_t L2CAP_ConnParamUpdateReq( uint16 connHandle, l2capParamUpdateReq_t* pUpdateReq, uint8 taskId ); + +/* + Parse Connection Parameter Update Request. +*/ +extern bStatus_t L2CAP_ParseParamUpdateReq( l2capSignalCmd_t* pCmd, uint8* pData, uint16 len ); + +/* + Send L2CAP Connection Parameter Update Response. +*/ +extern bStatus_t L2CAP_ConnParamUpdateRsp( uint16 connHandle, uint8 id, l2capParamUpdateRsp_t* pUpdateRsp ); + +/* + Build Connection Parameter Update Response. +*/ +extern uint16 L2CAP_BuildParamUpdateRsp( uint8* pBuf, uint8* pData ); + +/* + Allocate a block of memory at the L2CAP layer. +*/ +extern void* L2CAP_bm_alloc( uint16 size ); + +/* + This API is used by the upper layer to turn flow control on + or off for data packets sent from the Controller to the Host. +*/ +extern void L2CAP_SetControllerToHostFlowCtrl( uint16 hostBuffSize, uint8 flowCtrlMode ); +/* + This API is used by the upper layer to turn flow control on + or off for data packets sent from the Controller to the Host. + support DLE update +*/ +extern void L2CAP_SetControllerToHostFlowCtrl_DLE( uint16 hostBuffSize, uint8 flowCtrlMode ); +/* + This API is used by the upper layer to notify L2CAP of the + number of data packets that have been completed for connection + handle since this API was previously called. +*/ +extern void L2CAP_HostNumCompletedPkts( uint16 connHandle, uint16 numCompletedPkts ); + + +extern uint8 l2capPktToSegmentBuff(uint16 connHandle,l2capSegmentBuff_t* pSegBuf, uint8 blen,uint8* pBuf); +extern uint8 l2capSegmentBuffToLinkLayer(uint16 connHandle, l2capSegmentBuff_t* pSegBuf); +extern void l2capPocessFragmentTxData(uint16 connHandle); +extern void l2capSarBufReset(void); +extern void L2CAP_ReassemblePkt_Reset(uint16 connHandle); +extern void L2CAP_SegmentPkt_Reset(uint16 connHandle); + +extern void L2CAP_ExtendFramgents_Config(uint8 flag); +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* L2CAP_H */ diff --git a/arch/arm/src/phy62xx/ble/include/sm.h b/arch/arm/src/phy62xx/ble/include/sm.h new file mode 100644 index 00000000000..f3e22fc22eb --- /dev/null +++ b/arch/arm/src/phy62xx/ble/include/sm.h @@ -0,0 +1,390 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/** + @headerfile: sm.h + $Date: + $Revision: + + @mainpage BLE SM API + + This file contains the interface to the SM. + + + +*/ + +#ifndef SM_H +#define SM_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* ------------------------------------------------------------------- + INCLUDES +*/ +#include "bcomdef.h" +#include "OSAL.h" + +/* ------------------------------------------------------------------- + MACROS +*/ + +/* ------------------------------------------------------------------- + CONSTANTS +*/ +/** @defgroup SM_IO_CAP_DEFINES SM I/O Capabilities + @{ +*/ +#define DISPLAY_ONLY 0x00 //!< Display Only Device +#define DISPLAY_YES_NO 0x01 //!< Display and Yes and No Capable +#define KEYBOARD_ONLY 0x02 //!< Keyboard Only +#define NO_INPUT_NO_OUTPUT 0x03 //!< No Display or Input Device +#define KEYBOARD_DISPLAY 0x04 //!< Both Keyboard and Display Capable +/** @} End SM_IO_CAP_DEFINES */ + +#define SM_AUTH_MITM_MASK(a) (((a) & 0x04) >> 2) + +/** @defgroup SM_PASSKEY_TYPE_DEFINES SM Passkey Types (Bit Masks) + @{ +*/ +#define SM_PASSKEY_TYPE_INPUT 0x01 //!< Input the passkey +#define SM_PASSKEY_TYPE_DISPLAY 0x02 //!< Display the passkey +/** @} End SM_PASSKEY_TYPE_DEFINES */ + +/** @defgroup SM_BONDING_FLAGS_DEFINES SM AuthReq Bonding Flags + Bonding flags 0x02 and 0x03 are reserved. + @{ +*/ +#define SM_AUTH_REQ_NO_BONDING 0x00 //!< No bonding +#define SM_AUTH_REQ_BONDING 0x01 //!< Bonding +/** @} End SM_BONDING_FLAGS_DEFINES */ + +#define PASSKEY_LEN 6 //! Passkey Character Length (ASCII Characters) + +#define SM_AUTH_STATE_CT2 0x20 +#define SM_AUTH_STATE_KEYPRESS 0x10 +#define SM_AUTH_STATE_SC 0x08 +#define SM_AUTH_STATE_AUTHENTICATED 0x04 //! Authenticate requested +#define SM_AUTH_STATE_BONDING 0x01 //! Bonding requested + +/* ------------------------------------------------------------------- + General TYPEDEFS +*/ + +/** + SM_NEW_RAND_KEY_EVENT message format. This message is sent to the + requesting task. +*/ +typedef struct +{ + osal_event_hdr_t hdr; //!< SM_NEW_RAND_KEY_EVENT and status + uint8 newKey[KEYLEN]; //!< New key value - if status is SUCCESS +} smNewRandKeyEvent_t; + +/** + Key Distribution field - True or False fields +*/ +typedef struct +{ + unsigned int sEncKey:1; //!< Set to distribute slave encryption key + unsigned int sIdKey:1; //!< Set to distribute slave identity key + unsigned int sSign:1; //!< Set to distribute slave signing key + unsigned int sReserved:5; // bug fixed 2018-11-26, reserved bits should be saved for upward compatibility + + unsigned int mEncKey:1; //!< Set to distribute master encryption key + unsigned int mIdKey:1; //!< Set to distribute master identity key + unsigned int mSign:1; //!< Set to distribute master signing key + unsigned int mReserved:5; // bug fixed 2018-11-26, reserved bits should be saved for upward compatibility +} keyDist_t; + +/** + Link Security Requirements +*/ +typedef struct +{ + uint8 ioCaps; //!< I/O Capabilities (ie. + uint8 oobAvailable; //!< True if Out-of-band key available + uint8 oob[KEYLEN]; //!< Out-Of-Bounds key + uint8 authReq; //!< Authentication Requirements + keyDist_t keyDist; //!< Key Distribution mask + uint8 maxEncKeySize; //!< Maximum Encryption Key size (7-16 bytes) +} smLinkSecurityReq_t; + +/** + Link Security Information +*/ +typedef struct +{ + uint8 ltk[KEYLEN]; //!< Long Term Key (LTK) + uint16 div; //!< LTK Diversifier + uint8 rand[B_RANDOM_NUM_SIZE]; //!< LTK random number + uint8 keySize; //!< LTK Key Size (7-16 bytes) +} smSecurityInfo_t; + +/** + Link Identity Information +*/ +typedef struct +{ + uint8 irk[KEYLEN]; //!< Identity Resolving Key (IRK) + uint8 bd_addr[B_ADDR_LEN]; //!< The advertiser may set this to zeroes to not disclose its BD_ADDR (public address). +} smIdentityInfo_t; + +/** + Signing Information +*/ +typedef struct +{ + uint8 srk[KEYLEN]; //!< Signature Resolving Key (CSRK) + uint32 signCounter; //!< Sign Counter +} smSigningInfo_t; + +/** + Pairing Request & Response - authReq field +*/ +typedef struct +{ + unsigned int bonding:2; //!< Bonding flags + unsigned int mitm:1; //!< Man-In-The-Middle (MITM) + unsigned int reserved:5; //!< Reserved - don't use +} authReq_t; + +/* ------------------------------------------------------------------- + GLOBAL VARIABLES +*/ + +/** + @defgroup SM_API Security Manager API Functions + + @{ +*/ + +/* ------------------------------------------------------------------- + FUNCTIONS - MASTER API - Only use these in a master device +*/ + +/** + @brief Initialize SM Initiator on a master device. + + @return SUCCESS +*/ +extern bStatus_t SM_InitiatorInit( void ); + +/** + @brief Start the pairing process. This function is also + called if the device is already bound. + + NOTE: Only one pairing process at a time per device. + + @param initiator - TRUE to start pairing as Initiator. + @param taskID - task ID to send results. + @param connectionHandle - Link's connection handle + @param pSecReqs - Security parameters for pairing + + @return SUCCESS,
+ INVALIDPARAMETER,
+ bleAlreadyInRequestedMode +*/ +extern bStatus_t SM_StartPairing( uint8 initiator, + uint8 taskID, + uint16 connectionHandle, + smLinkSecurityReq_t* pSecReqs ); + +/** + @brief Send Start Encrypt through HCI + + @param connHandle - Connection Handle + @param pLTK - pointer to 16 byte lkt + @param div - div or ediv + @param pRandNum - pointer to 8 byte random number + @param keyLen - length of LTK (bytes) + + @return SUCCESS,
+ INVALIDPARAMETER,
+ other from HCI/LL +*/ +extern bStatus_t SM_StartEncryption( uint16 connHandle, uint8* pLTK, + uint16 div, uint8* pRandNum, uint8 keyLen ); + + +/* ------------------------------------------------------------------- + FUNCTIONS - SLAVE API - Only use these in a slave device +*/ + +/** + @brief Initialize SM Responder on a slave device. + + @return SUCCESS +*/ +extern bStatus_t SM_ResponderInit( void ); + +/* ------------------------------------------------------------------- + FUNCTIONS - GENERAL API - both master and slave +*/ + +/** + @brief Generate a key with a random value. + + @param taskID - task ID to send results. + + @return SUCCESS,
+ bleNotReady,
+ bleMemAllocError,
+ FAILURE +*/ +extern bStatus_t SM_NewRandKey( uint8 taskID ); + +/** + @brief Calculate a new Private Resolvable address. + + @param pIRK - Identity Root Key. + @param pNewAddr - pointer to place to put new calc'd address + + @return SUCCESS - if started,
+ INVALIDPARAMETER +*/ +extern bStatus_t SM_CalcRandomAddr( uint8* pIRK, uint8* pNewAddr ); + +/** + @brief Resolve a Private Resolveable Address. + + @param pIRK - pointer to the IRK + @param pAddr - pointer to the random address + + @return SUCCESS - match,
+ FAILURE - don't match,
+ INVALIDPARAMETER - parameters invalid +*/ +extern bStatus_t SM_ResolveRandomAddrs( uint8* pIRK, uint8* pAddr ); + +/** + @brief Encrypt the plain text data with the key.. + + @param pKey - key data + @param pPlainText - Plain text data + @param pResult - place to put the encrypted result + + @return SUCCESS - if started,
+ INVALIDPARAMETER - one of the parameters are NULL,
+ bleAlreadyInRequestedMode,
+ bleMemAllocError +*/ +extern bStatus_t SM_Encrypt( uint8* pKey, uint8* pPlainText, uint8* pResult ); + +/** + @brief Generate an outgoing Authentication Signature. + + @param pData - message data + @param len - length of pData + @param pAuthenSig - place to put new signature + + @return SUCCESS - signature authentication generated,
+ INVALIDPARAMETER - pData or pAuthenSig is NULL,
+ bleMemAllocError +*/ +extern bStatus_t SM_GenerateAuthenSig( uint8* pData, uint8 len, uint8* pAuthenSig ); + +/** + @brief Verify an Authentication Signature. + + @param connHandle - connection to verify against. + @param authentication - TRUE if requires an authenticated CSRK, FALSE if not + @param pData - message data + @param len - length of pData + @param pAuthenSig - message signature to verify + + @return SUCCESS - signature authentication verified,
+ FAILURE - if not verified,
+ bleNotConnected - Connection not found,
+ INVALIDPARAMETER - pData or pAuthenSig is NULL, or signCounter is invalid,
+ bleMemAllocError +*/ +extern bStatus_t SM_VerifyAuthenSig( uint16 connHandle, + uint8 authentication, + uint8* pData, + uint16 len, + uint8* pAuthenSig ); + +/** + @brief Update the passkey for the pairing process. + + @param pPasskey - pointer to the 6 digit passkey + @param connectionHandle - connection handle to link. + + @return SUCCESS,
+ bleIncorrectMode - Not pairing,
+ INVALIDPARAMETER - link is incorrect +*/ +extern bStatus_t SM_PasskeyUpdate( uint8* pPasskey, uint16 connectionHandle ); + +/** + @} End SM_API +*/ + +/* ------------------------------------------------------------------- + TASK API - These functions must only be called OSAL. +*/ + +/** + @internal + + @brief SM Task Initialization Function. + + @param taskID - SM task ID. + + @return void +*/ +extern void SM_Init( uint8 task_id ); + +/** + @internal + + @brief SM Task event processing function. + + @param taskID - SM task ID + @param events - SM events. + + @return events not processed +*/ +extern uint16 SM_ProcessEvent( uint8 task_id, uint16 events ); + +/* ------------------------------------------------------------------- + -------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* SM_H */ diff --git a/arch/arm/src/phy62xx/bus_dev.h b/arch/arm/src/phy62xx/bus_dev.h new file mode 100644 index 00000000000..2aa6240f9d5 --- /dev/null +++ b/arch/arm/src/phy62xx/bus_dev.h @@ -0,0 +1,139 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/************************************************************************************************** + Filename: bus_dev.h + Revised: + Revision: + + Description: This file contains the SoC MCU relate definitions + + **************************************************************************************************/ + +#ifndef __BUS_DEV_H__ +#define __BUS_DEV_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mcu.h" + +enum +{ + RSTC_COLD_UP = 0, + RSTC_WARM_UP = 1, + RSTC_OFF_MODE = 2, + RSTC_WAKE_IO = 3, + RSTC_WAKE_RTC = 4, + RSTC_WARM_NDWC = 5 //user mode, no dwc + +}; + +/* ------------------------- Interrupt Number Definition ------------------------ */ + +typedef enum IRQn +{ + /* ------------------- Cortex-M0 Processor Exceptions Numbers ------------------- */ + NonMaskableInt_IRQn = -14, /* 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /* 3 HardFault Interrupt */ + + + + SVCall_IRQn = -5, /* 11 SV Call Interrupt */ + + PendSV_IRQn = -2, /* 14 Pend SV Interrupt */ + SysTick_IRQn = -1, /* 15 System Tick Interrupt */ + + /* ---------------------- PHY BUMBEE M0 Interrupt Numbers --------------------- */ + BB_IRQn = 4, /* Base band Interrupt */ + KSCAN_IRQn = 5, /* Key scan Interrupt */ + RTC_IRQn = 6, /* RTC Timer Interrupt */ + + WDT_IRQn = 10, /* Watchdog Timer Interrupt */ + UART0_IRQn = 11, /* UART0 Interrupt */ + I2C0_IRQn = 12, /* I2C0 Interrupt */ + I2C1_IRQn = 13, /* I2C1 Interrupt */ + SPI0_IRQn = 14, /* SPI0 Interrupt */ + SPI1_IRQn = 15, /* SPI1 Interrupt */ + GPIO_IRQn = 16, /* GPIO Interrupt */ + UART1_IRQn = 17, /* UART1 Interrupt */ + SPIF_IRQn = 18, /* SPIF Interrupt */ + DMAC_IRQn = 19, /* DMAC Interrupt */ + TIM1_IRQn = 20, /* Timer1 Interrupt */ + TIM2_IRQn = 21, /* Timer2 Interrupt */ + TIM3_IRQn = 22, /* Timer3 Interrupt */ + TIM4_IRQn = 23, /* Timer4 Interrupt */ + TIM5_IRQn = 24, /* Timer5 Interrupt */ + TIM6_IRQn = 25, /* Timer6 Interrupt */ + + AES_IRQn = 28, /* AES Interrupt */ + ADCC_IRQn = 29, /* ADC Interrupt */ + QDEC_IRQn = 30, /* QDEC Interrupt */ + RNG_IRQn = 31 /* RNG Interrupt */ +} IRQn_Type; + +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +#define NVIC_DisableIRQ(irqid) up_disable_irq(irqid) +#define NVIC_EnableIRQ(irqid) up_enable_irq(irqid) +#define NVIC_SetPriority(i,p) + +#if 0 +#if (PHY_MCU_TYPE == MCU_BUMBEE_M0) +#define ATTRIBUTE_ISR +#include "core_bumbee_m0.h" +#endif +#if(PHY_MCU_TYPE == MCU_BUMBEE_CK802) +#define ATTRIBUTE_ISR __attribute__((isr)) +#include "core_802.h" +#endif +#endif //0 + +#if (PHY_MCU_TYPE == MCU_BUMBEE_M0 || PHY_MCU_TYPE == MCU_BUMBEE_CK802) +#include "mcu_phy_bumbee.h" +#elif ((PHY_MCU_TYPE == MCU_PRIME_A1) ||(PHY_MCU_TYPE == MCU_PRIME_A2)) +#include "mcu_phy_prime.h" +#endif + +#endif diff --git a/arch/arm/src/phy62xx/chip.h b/arch/arm/src/phy62xx/chip.h new file mode 100644 index 00000000000..c6782e29dfd --- /dev/null +++ b/arch/arm/src/phy62xx/chip.h @@ -0,0 +1,41 @@ +/**************************************************************************** + * arch/arm/src/phy62xx/chip.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_PHY62XX_CHIP_H +#define __ARCH_ARM_SRC_PHY62XX_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/* Include the chip capabilities file */ + +#include + +#define ARMV6M_PERIPHERAL_INTERRUPTS 32 + +/* Include the memory map file. + * Other chip hardware files should then include this file for the proper + * setup. + */ + +#endif /* __ARCH_ARM_SRC_PHY62XX_CHIP_H */ diff --git a/arch/arm/src/phy62xx/clock.c b/arch/arm/src/phy62xx/clock.c new file mode 100644 index 00000000000..5dfacd55a4e --- /dev/null +++ b/arch/arm/src/phy62xx/clock.c @@ -0,0 +1,226 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ +#include "clock.h" +#include "gpio.h" +//#include "global_config.h" +#include "error.h" + +extern uint32_t hclk,pclk; +extern uint32_t osal_sys_tick; + +void hal_clk_gate_enable(MODULE_e module) +{ + if(module < MOD_CP_CPU) + { + AP_PCR->SW_CLK |= BIT(module); + } + else if(module < MOD_PCLK_CACHE) + { + AP_PCR->SW_CLK1 |= BIT(module-MOD_CP_CPU); + } + else if(module < MOD_USR0) + { + AP_PCR->CACHE_CLOCK_GATE |= BIT(module-MOD_PCLK_CACHE); + } +} + +void hal_clk_gate_disable(MODULE_e module) +{ + if(module < MOD_CP_CPU) + { + AP_PCR->SW_CLK &= ~(BIT(module)); + } + else if(module < MOD_PCLK_CACHE) + { + AP_PCR->SW_CLK1 &= ~(BIT(module-MOD_CP_CPU)); + } + else if(module < MOD_USR0) + { + AP_PCR->CACHE_CLOCK_GATE &= ~(BIT(module-MOD_PCLK_CACHE)); + } +} + +int hal_clk_gate_get(MODULE_e module) +{ + if(module < MOD_CP_CPU) + { + return (AP_PCR->SW_CLK & BIT(module)); + } + else if(module < MOD_PCLK_CACHE) + { + return (AP_PCR->SW_CLK1 & BIT(module-MOD_CP_CPU)); + } + //else if(module < MOD_USR0) + else + { + return (AP_PCR->CACHE_CLOCK_GATE & BIT(module-MOD_PCLK_CACHE)); + } +} + +void hal_clk_get_modules_state(uint32_t* buff) +{ + *buff = AP_PCR->SW_CLK; + *(buff+1) = AP_PCR->SW_CLK1; + *(buff+2) = AP_PCR->CACHE_CLOCK_GATE; +} + +void hal_clk_reset(MODULE_e module) +{ + if(module < MOD_CP_CPU) + { + if((module >= MOD_TIMER5) &&(module <= MOD_TIMER6)) + { + AP_PCR->SW_RESET0 &= ~BIT(5); + AP_PCR->SW_RESET0 |= BIT(5); + } + else + { + AP_PCR->SW_RESET0 &= ~BIT(module); + AP_PCR->SW_RESET0 |= BIT(module); + } + } + else if(module < MOD_PCLK_CACHE) + { + if((module >= MOD_TIMER1) &&(module <= MOD_TIMER4)) + { + AP_PCR->SW_RESET2 &= ~BIT(4); + AP_PCR->SW_RESET2 |= BIT(4); + } + else + { + AP_PCR->SW_RESET2 &= ~BIT(module-MOD_CP_CPU); + AP_PCR->SW_RESET2 |= BIT(module-MOD_CP_CPU); + } + } + else if(module < MOD_USR0) + { + AP_PCR->CACHE_RST &= ~BIT(1-(module-MOD_HCLK_CACHE)); + AP_PCR->CACHE_RST |= BIT(1-(module-MOD_HCLK_CACHE)); + } +} + + +void hal_rtc_clock_config(CLK32K_e clk32Mode) +{ + if(clk32Mode == CLK_32K_RCOSC) + { + subWriteReg(&(AP_AON->PMCTL0),31,27,0x05); + subWriteReg(&(AP_AON->PMCTL2_0),16,7,0x3fb); + subWriteReg(&(AP_AON->PMCTL2_0),6,6,0x01); + //pGlobal_config[LL_SWITCH]|=RC32_TRACKINK_ALLOW|LL_RC32K_SEL; + } + else if(clk32Mode == CLK_32K_XTAL) + { + // P16 P17 for 32K XTAL input + hal_gpio_pull_set(P16,FLOATING); + hal_gpio_pull_set(P17,FLOATING); + subWriteReg(&(AP_AON->PMCTL2_0),9,8,0x03); //software control 32k_clk + subWriteReg(&(AP_AON->PMCTL2_0),6,6,0x00); //disable software control + subWriteReg(&(AP_AON->PMCTL0),31,27,0x16); + //pGlobal_config[LL_SWITCH]&=0xffffffee; + } + + //ZQ 20200812 for rc32k wakeup + subWriteReg(&(AP_AON->PMCTL0),28,28,0x1);//turn on 32kxtal + subWriteReg(&(AP_AON->PMCTL1),18,17,0x0);// reduce 32kxtl bias current +} + + + +uint32_t hal_systick(void) +{ + return 10000;//osal_sys_tick; +} + +uint32_t hal_ms_intv(uint32_t tick) +{ + uint32_t diff = 0; +/* + if(osal_sys_tick < tick) + { + diff = 0xffffffff- tick; + diff = osal_sys_tick + diff; + } + else + { + diff = osal_sys_tick - tick; + } +*/ + return diff*625/1000; +} + +/************************************************************************************** + @fn WaitMs + + @brief This function process for wait program msecond,use RTC + + input parameters + + @param uint32_t msecond: the msecond value + + output parameters + + @param None. + + @return None. + **************************************************************************************/ + +void WaitMs(uint32_t msecond) +{ + //WaitRTCCount((msecond<<15)/1000); +} + +void WaitUs(uint32_t wtTime) +{ + uint32_t T0,currTick,deltTick; + //T0 = read_current_time(); + T0 =(TIME_BASE - ((AP_TIM3->CurrentCount) >> 2)); + + while(1) + { + currTick = (TIME_BASE - ((AP_TIM3->CurrentCount) >> 2)); + deltTick = TIME_DELTA(currTick,T0); + + if(deltTick>wtTime) + break; + } +} + +void hal_system_soft_reset(void) +{ + _HAL_CS_ALLOC_(); + HAL_ENTER_CRITICAL_SECTION(); + AP_PCR->SW_RESET1 = 0; + + while(1); +} + diff --git a/arch/arm/src/phy62xx/clock.h b/arch/arm/src/phy62xx/clock.h new file mode 100644 index 00000000000..184f7b3204b --- /dev/null +++ b/arch/arm/src/phy62xx/clock.h @@ -0,0 +1,136 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ +#ifndef _HAL_CLOCK_H +#define _HAL_CLOCK_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "types.h" +#include "bus_dev.h" +//#include "common.h" + +typedef enum +{ + CLK_32K_XTAL = 0, + CLK_32K_RCOSC = 1, + +} CLK32K_e; + +typedef enum +{ + XTAL_16M = 0, + DBL_B_32M = 1, + DBL_32 = 2, + DLL_32M = 3, + +} ClkSrc_e; + +typedef enum _SYSCLK_SEL +{ + SYS_CLK_RC_32M = 0, + SYS_CLK_DLL_32M = 1, + SYS_CLK_XTAL_16M = 2, + SYS_CLK_DLL_48M = 3, + SYS_CLK_DLL_64M = 4, + SYS_CLK_DLL_96M = 5, + SYS_CLK_8M = 6, + SYS_CLK_4M = 7, + SYS_CLK_NUM = 8, +} sysclk_t; + +typedef enum +{ + HCLK_CHANGE = 0, + AP_CLK_CHANGE = 1, + CP_CLK_CHANGE = 2, +} clk_update_Type_t; + +typedef struct _clk_Evt_t +{ + uint8_t flag; + +} clk_Evt_t; + +typedef void (*clk_Hdl_t)(clk_Evt_t* pev); + +typedef struct _clk_Contex_t +{ + bool enable; + clk_Hdl_t evt_handler; +} clk_Ctx_t; + + +#define CLAER_RTC_COUNT AP_AON->RTCCTL |= BIT(1) +#define RUN_RTC AP_AON->RTCCTL |= BIT(0) +#define STOP_RTC AP_AON->RTCCTL &= ~BIT(0) + +#define hal_system_init clk_init +extern volatile uint32_t g_hclk; +#define clk_get_hclk() g_hclk +uint32_t clk_get_pclk(void); + +void hal_clk_gate_enable(MODULE_e module); +void hal_clk_gate_disable(MODULE_e module); +int hal_clk_gate_get(MODULE_e module); +void hal_clk_get_modules_state(uint32_t* buff); +void hal_clk_reset(MODULE_e module); +void hal_clk_rf_config(ClkSrc_e sel); +void hal_clk_rxadc_config(ClkSrc_e sel); + +bool hal_clk_set_pclk(uint32_t div); +int hal_clk_init(sysclk_t hclk_sel,clk_Hdl_t evt_handler); +void hal_rtc_clock_config(CLK32K_e clk32Mode); + +uint32_t hal_systick(void); +uint32_t hal_ms_intv(uint32_t tick); + +extern uint32_t rtc_get_counter(void); +void WaitMs(uint32_t msecond); +void WaitUs(uint32_t wtTime); +void hal_system_soft_reset(void); + + +extern int clk_init(sysclk_t h_system_clk_sel); +extern void WaitRTCCount(uint32_t rtcDelyCnt); +extern int clk_spif_ref_clk(sysclk_t spif_ref_sel); +extern uint32_t getMcuPrecisionCount(void); + + +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/arch/arm/src/phy62xx/core_bumbee_m0.h b/arch/arm/src/phy62xx/core_bumbee_m0.h new file mode 100644 index 00000000000..af609bc3be2 --- /dev/null +++ b/arch/arm/src/phy62xx/core_bumbee_m0.h @@ -0,0 +1,88 @@ + +#ifndef PHY_BUMBEE_M0_H +#define PHY_BUMBEE_M0_H + +#ifdef __cplusplus +extern "C" { +#endif + + + + + +/* ================================================================================ */ +/* ================ Processor and Core Peripheral Section ================ */ +/* ================================================================================ */ + +/* ------- Start of section using anonymous unions and disabling warnings ------- */ +#if defined (__CC_ARM) +#pragma push +#pragma anon_unions +#elif defined (__ICCARM__) +#pragma language=extended +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc11-extensions" +#pragma clang diagnostic ignored "-Wreserved-id-macro" +#elif defined (__GNUC__) +/* anonymous unions are enabled by default */ +#elif defined (__TMS470__) +/* anonymous unions are enabled by default */ +#elif defined (__TASKING__) +#pragma warning 586 +#elif defined (__CSMC__) +/* anonymous unions are enabled by default */ +#else +#warning Not supported compiler type +#endif + + +/* -------- Configuration of the Cortex-M0 Processor and Core Peripherals ------- */ +//#define __CM0_REV 0x0000U /* Core revision r0p0 */ +//#define __MPU_PRESENT 0U /* MPU present or not */ +//#define __VTOR_PRESENT 0U /* no VTOR present*/ +#define __NVIC_PRIO_BITS 2U /* Number of Bits used for Priority Levels */ +//#define __Vendor_SysTickConfig 0U /* Set to 1 if different SysTick Config is used */ + +#include "core_cm0.h" /* Processor and core peripherals */ +#include "system_ARMCM0.h" /* System Header */ + +#define NVIC_GetPendingIRQs() (NVIC->ISPR[0U]) +#define NVIC_ClearPendingIRQs(icpr) (NVIC->ICPR[0U] = (unsigned int)icpr) +#define NVIC_SetPendingIRQs(ispr) (NVIC->ISPR[0U] = (unsigned int)ispr) + +#define NVIC_GetEnableIRQs() (NVIC->ISER[0U]) +#define NVIC_DisableIRQs(irqs) (NVIC->ICER[0U] = (unsigned int)irqs) +#define NVIC_EnableIRQs(iser) (NVIC->ISER[0U] = (unsigned int)iser) + +#define NVIC_ClearWakeupIRQ(irqn) +#define NVIC_SetWakeupIRQ(irqn) + + +/* -------- End of section using anonymous unions and disabling warnings -------- */ +#if defined (__CC_ARM) +#pragma pop +#elif defined (__ICCARM__) +/* leave anonymous unions enabled */ +#elif (__ARMCC_VERSION >= 6010050) +#pragma clang diagnostic pop +#elif defined (__GNUC__) +/* anonymous unions are enabled by default */ +#elif defined (__TMS470__) +/* anonymous unions are enabled by default */ +#elif defined (__TASKING__) +#pragma warning restore +#elif defined (__CSMC__) +/* anonymous unions are enabled by default */ +#else +#warning Not supported compiler type +#endif + + + + +#ifdef __cplusplus +} +#endif + +#endif /* PHY_BUMBEE_M0 */ diff --git a/arch/arm/src/phy62xx/error.h b/arch/arm/src/phy62xx/error.h new file mode 100644 index 00000000000..489e06797e3 --- /dev/null +++ b/arch/arm/src/phy62xx/error.h @@ -0,0 +1,106 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + + +/******************************************************************************* + @file error.h + @brief Global error definition + @version 0.0 + @date 11. Feb. 2018 + @author Eagle.Lao + + + +*******************************************************************************/ + +#ifndef _PPLUS_ERROR_H +#define _PPLUS_ERROR_H + +#define PPlus_SUCCESS (0) /*Success*/ +#define PPlus_ERR_FATAL (1) /*unrecoverable error*/ +#define PPlus_ERR_INTERNAL (2) /*Internal Error*/ +#define PPlus_ERR_NO_MEM (3) /*No Memory for operation*/ +#define PPlus_ERR_NOT_FOUND (4) /*Not found*/ +#define PPlus_ERR_NOT_SUPPORTED (5) /*Not supported*/ +#define PPlus_ERR_INVALID_PARAM (6) /*Invalid Parameter*/ +#define PPlus_ERR_INVALID_STATE (7) /*Invalid state, operation disallowed in this state*/ +#define PPlus_ERR_INVALID_LENGTH (8) /*Invalid Length*/ +#define PPlus_ERR_INVALID_FLAGS (9) /*Invalid Flags*/ +#define PPlus_ERR_INVALID_DATA (10) /*Invalid Data*/ +#define PPlus_ERR_DATA_SIZE (11) /*Data size exceeds limit*/ +#define PPlus_ERR_DATA_ALIGN (12) /*Data alignment is not correct*/ +#define PPlus_ERR_TIMEOUT (13) /*Operation timed out*/ +#define PPlus_ERR_NULL (14) /*Null Pointer*/ +#define PPlus_ERR_FORBIDDEN (15) /*Forbidden Operation*/ +#define PPlus_ERR_INVALID_ADDR (16) /*Bad Memory Address*/ +#define PPlus_ERR_BUSY (17) /*Busy*/ +#define PPlus_ERR_NOT_REGISTED (18) /*not registed*/ +#define PPlus_ERR_IO_CONFILCT (19) /*IO config error*/ +#define PPlus_ERR_IO_FAIL (20) /*IO fail error*/ +#define PPlus_ERR_NOT_IMPLEMENTED (22) /*Function is not provide now*/ +#define PPlus_ERR_SPI_FLASH (23) /*spi falsh operation error*/ +#define PPlus_ERR_UNINITIALIZED (24) +#define PPlus_ERR_FS_WRITE_FAILED (31) +#define PPlus_ERR_FS_CONTEXT (32) +#define PPlus_ERR_FS_FULL (33) +#define PPlus_ERR_FS_PARAMETER (34) +#define PPlus_ERR_FS_NOT_ENOUGH_SIZE (35) +#define PPlus_ERR_FS_EXIST_SAME_ID (36) +#define PPlus_ERR_FS_NOT_FIND_ID (37) +#define PPlus_ERR_FS_BUFFER_TOO_SMALL (38) +#define PPlus_ERR_FS_UNINITIALIZED (39) +#define PPlus_ERR_FS_HAVE_INITED (40) +#define PPlus_ERR_FS_IN_INT (41) +#define PPlus_ERR_FS_RESERVED_ERROR (42) +#define PPlus_ERR_VERSION (43) +#define PPlus_ERR_NO_DEV (44) + +#define PPlus_ERR_SECURE_CRYPTO (50) +#define PPlus_ERR_ACCESS_REJECTED (51) + + +#define PPlus_ERR_BLE_NOT_READY (80) /*BLE not ready error*/ +#define PPlus_ERR_BLE_BUSY (81) /*BLE operation failed becuase of busy*/ +#define PPlus_ERR_BLE_FAIL (82) /*BLE operation failed*/ + +#define PPlus_ERR_OTA_INVALID_STATE (100) /*state machine error when OTA*/ +#define PPlus_ERR_OTA_DATA_SIZE (101) /*data size is not correct*/ +#define PPlus_ERR_OTA_CRC (102) /*bad checksum(crc)*/ +#define PPlus_ERR_OTA_NO_APP (103) /*No application data*/ +#define PPlus_ERR_OTA_BAD_DATA (104) /*bad application data*/ +#define PPlus_ERR_OTA_UNKNOW_CMD (105) /*unknow command*/ +#define PPlus_ERR_OTA_CRYPTO (106) /*crypto verify error*/ +#define PPlus_ERR_KEY_VERIFY (107) /*security boot key verify fail*/ +#define PPlus_ERR_DOUBLE_CONFIRM (108) /*security boot double key verify fail*/ +#define PPlus_ERR_OTA_MIC (109) /*bad checksum(mic)*/ +#endif + diff --git a/arch/arm/src/phy62xx/flash.c b/arch/arm/src/phy62xx/flash.c new file mode 100644 index 00000000000..1930e36a1e8 --- /dev/null +++ b/arch/arm/src/phy62xx/flash.c @@ -0,0 +1,306 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/******************************************************************************* + @file flash.c + @brief Contains all functions support for flash driver + @version 0.0 + @date 27. Nov. 2017 + @author qing.han + + + +*******************************************************************************/ +#include "rom_sym_def.h" +#include +#include "types.h" +#include "flash.h" +#include "log.h" +#include "pwrmgr.h" +#include "error.h" + + +#define SPIF_WAIT_IDLE_CYC (32) + +#define SPIF_STATUS_WAIT_IDLE(n) \ + do \ + { \ + while((AP_SPIF->fcmd &0x02)==0x02); \ + { \ + volatile int delay_cycle = n; \ + while (delay_cycle--){;} \ + } \ + while ((AP_SPIF->config & 0x80000000) == 0);\ + } while (0); + + +#define HAL_CACHE_ENTER_BYPASS_SECTION() do{ \ + _HAL_CS_ALLOC_();\ + HAL_ENTER_CRITICAL_SECTION();\ + AP_CACHE->CTRL0 = 0x02; \ + AP_PCR->CACHE_RST = 0x02;\ + AP_PCR->CACHE_BYPASS = 1; \ + }while(0); + + +#define HAL_CACHE_EXIT_BYPASS_SECTION() do{ \ + _HAL_CS_ALLOC_();\ + HAL_ENTER_CRITICAL_SECTION();\ + AP_CACHE->CTRL0 = 0x00;\ + AP_PCR->CACHE_RST = 0x03;\ + AP_PCR->CACHE_BYPASS = 0;\ + HAL_EXIT_CRITICAL_SECTION();\ + }while(0); + +#define spif_wait_nobusy(flg, tout_ns, return_val) {if(_spif_wait_nobusy_x(flg, tout_ns)){if(return_val){ return return_val;}}} + +static xflash_Ctx_t s_xflashCtx = {.spif_ref_clk=SYS_CLK_DLL_64M,.rd_instr=XFRD_FCMD_READ_DUAL}; + +chipMAddr_t g_chipMAddr; + +static void hal_cache_tag_flush(void); + + + +static void __RAMRUN hal_cache_tag_flush(void) +{ + _HAL_CS_ALLOC_(); + HAL_ENTER_CRITICAL_SECTION(); + uint32_t cb = AP_PCR->CACHE_BYPASS; + volatile int dly = 8; + + if(cb==0) + { + AP_PCR->CACHE_BYPASS = 1; + } + + AP_CACHE->CTRL0 = 0x02; + + while (dly--) {;}; + + AP_CACHE->CTRL0 = 0x03; + + dly = 8; + + while (dly--) {;}; + + AP_CACHE->CTRL0 = 0x00; + + if(cb==0) + { + AP_PCR->CACHE_BYPASS = 0; + } + + HAL_EXIT_CRITICAL_SECTION(); +} + + +static uint8_t __RAMRUN _spif_read_status_reg_x(void) +{ + uint8_t status; + spif_cmd(FCMD_RDST, 0, 2, 0, 0, 0); + SPIF_STATUS_WAIT_IDLE(SPIF_WAIT_IDLE_CYC); + spif_rddata(&status, 1); + return status; +} + +static int __RAMRUN _spif_wait_nobusy_x(uint8_t flg, uint32_t tout_ns) +{ + uint8_t status; + volatile int tout = (int )(tout_ns); + + for(; tout ; tout --) + { + status = _spif_read_status_reg_x(); + + if((status & flg) == 0) + return PPlus_SUCCESS; + + //insert polling interval + //5*32us + WaitRTCCount(5); + } + + return PPlus_ERR_BUSY; +} +void __RAMRUN hal_spif_init(void) +{ + uint32_t tmp = 0; + //*(volatile uint32_t *) 0x4000c800 = 0x80080081; //enable qspi(divisor 4) + + *(volatile uint32_t *) 0x4000c804 = 0x801003B; // Device Read Instruction Register , Dual IO + return PPlus_SUCCESS; +#if 0 + //*(volatile uint32_t *) 0x4000c800 = 0x80280081; //enable qspi(divisor 12) + //return 0; + *(volatile uint32_t *) 0x4000c890 = 0x6000001; // config flash: WREN 06h + //*(volatile uint32_t *) 0x4000c890 = 0x50000001; // config flash: Write Enable for Volatile Status Reg 50h + *(volatile uint32_t *) 0x4000c8a8 = 0x200; // config Flash Command Write Data Register (Lower) + *(volatile uint32_t *) 0x4000c890 = 0x1009001; // config flash: write status reg 01h QE=1 + while ((tmp&2)!= 0x2) // QE = 1 ? + { + *(int *) 0x4000c890 = 0x35900001; // Read Status Reg-2 35h + tmp = *(uint32_t *) 0x4000c8a0; + } + *(volatile uint32_t *) 0x4000c828 = 0x10; // M5-4 Mode Bit Configuration Register + *(volatile uint32_t *) 0x4000c804 = 0x41220EB; // Device Read Instruction Register + return PPlus_SUCCESS; + + + //load defualt configure + while(1){//wait spif idle + if(AP_SPIF->config &BIT(31)){ + WaitUs(1); + break; + } + } +#endif + +} + +void __RAMRUN hal_cache_init(void) +{ + volatile int dly=100; + hal_spif_init(); + //clock gate + hal_clk_gate_enable(MOD_HCLK_CACHE); + hal_clk_gate_enable(MOD_PCLK_CACHE); + //cache rst ahp + AP_PCR->CACHE_RST=0x02; + + while(dly--) {}; + + AP_PCR->CACHE_RST=0x03; + + hal_cache_tag_flush(); + + //cache enable + AP_PCR->CACHE_BYPASS = 0; +} + +static void __RAMRUN hw_spif_cache_config(void) +{ + spif_config(s_xflashCtx.spif_ref_clk,/*div*/1,s_xflashCtx.rd_instr,0,0); + AP_SPIF->wr_completion_ctrl=0xff010005;//set longest polling interval + NVIC_DisableIRQ(SPIF_IRQn); + NVIC_SetPriority((IRQn_Type)SPIF_IRQn, IRQ_PRIO_HAL); + hal_cache_init(); +} +int __RAMRUN hal_spif_cache_init(void)//xflash_Ctx_t cfg) +{ + //memset(&(s_xflashCtx), 0, sizeof(s_xflashCtx)); + //memcpy(&(s_xflashCtx), &cfg, sizeof(s_xflashCtx)); + hw_spif_cache_config(); + hal_pwrmgr_register(MOD_SPIF, NULL, hw_spif_cache_config); + return PPlus_SUCCESS; +} + +int __RAMRUN hal_flash_read(uint32_t addr, uint8_t* data, uint32_t size) +{ + volatile uint8_t* u8_spif_addr = (volatile uint8_t*)((addr & 0x7ffff) | FLASH_BASE_ADDR); + uint32_t cb = AP_PCR->CACHE_BYPASS; + #if(SPIF_FLASH_SIZE==FLASH_SIZE_1MB) + uint32_t remap = addr & 0xf80000; + + if (remap) + { + AP_SPIF->remap = remap; + AP_SPIF->config |= 0x10000; + } + + #endif + + //read flash addr direct access + //bypass cache + HAL_CACHE_ENTER_BYPASS_SECTION(); + + for(int i=0; iremap = 0; + AP_SPIF->config &= ~0x10000ul; + } + + #endif + return PPlus_SUCCESS; +} + +int __RAMRUN hal_flash_write(uint32_t addr, uint8_t* data, uint32_t size) +{ + uint8_t retval; + HAL_CACHE_ENTER_BYPASS_SECTION(); + SPIF_STATUS_WAIT_IDLE(SPIF_WAIT_IDLE_CYC); + spif_wait_nobusy(SFLG_WIP, SPIF_TIMEOUT, PPlus_ERR_BUSY); + retval = spif_write(addr,data,size); + SPIF_STATUS_WAIT_IDLE(SPIF_WAIT_IDLE_CYC); + spif_wait_nobusy(SFLG_WIP, SPIF_TIMEOUT, PPlus_ERR_BUSY); + HAL_CACHE_EXIT_BYPASS_SECTION(); + return retval; +} + +int __RAMRUN hal_flash_erase_sector(unsigned int addr) +{ + uint8_t retval; + uint32_t cb = AP_PCR->CACHE_BYPASS; + HAL_CACHE_ENTER_BYPASS_SECTION(); + SPIF_STATUS_WAIT_IDLE(SPIF_WAIT_IDLE_CYC); + spif_wait_nobusy(SFLG_WIP, SPIF_TIMEOUT, PPlus_ERR_BUSY); + retval = spif_erase_sector(addr); + SPIF_STATUS_WAIT_IDLE(SPIF_WAIT_IDLE_CYC); + spif_wait_nobusy(SFLG_WELWIP, SPIF_TIMEOUT, PPlus_ERR_BUSY); + HAL_CACHE_EXIT_BYPASS_SECTION(); + + if(cb == 0) + { + hal_cache_tag_flush(); + } + + return retval; +} + + +int __RAMRUN flash_write_word(unsigned int offset, uint32_t value) +{ + uint32_t temp = value; + offset &= 0x00ffffff; + return (hal_flash_write (offset, (uint8_t*) &temp, 4)); +} + + + diff --git a/arch/arm/src/phy62xx/flash.h b/arch/arm/src/phy62xx/flash.h new file mode 100644 index 00000000000..d74771f0866 --- /dev/null +++ b/arch/arm/src/phy62xx/flash.h @@ -0,0 +1,174 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/******************************************************************************* + @file flash.h + @brief Contains all functions support for flash driver + @version 0.0 + @date 27. Nov. 2017 + @author qing.han + + + +*******************************************************************************/ +#ifndef _FLASH_H_ +#define _FLASH_H_ + +#include "rom_sym_def.h" +#include "clock.h" +#include "types.h" +#include "gpio.h" + +#define CHIP_MADDR_LEN 6 +#define CHIP_ID_FLASH_ADDRESS 0x11000800 +#define CHIP_MADDR_FLASH_ADDRESS (CHIP_ID_FLASH_ADDRESS+CHIP_ID_LENGTH*4) + +#define FLASH_SIZE_256KB (0) +#define FLASH_SIZE_512KB (1) +#define FLASH_SIZE_1MB (2) + +#define SPIF_FLASH_SIZE FLASH_SIZE_512KB + +#define SPIF_TIMEOUT (0x7ffffff)//1000000 + +#define SFLG_WIP 1 +#define SFLG_WEL 2 +#define SFLG_WELWIP 3 + +//define flash ucds +#define FLASH_BASE_ADDR (0x11000000) +#define FLASH_UCDS_ADDR_BASE 0x11005000 + +#define CHIP_ID_LENGTH 64 +#define CHIP_ID_PID_LEN 16 +#define CHIP_ID_LID_LEN 10 +#define CHIP_ID_MID_LEN 16 +#define CHIP_ID_TID_LEN 14 +#define CHIP_ID_SID_LEN 8 + +#define CHIP_MADDR_LEN 6 + +//xip flash read instrcution +#define XFRD_FCMD_READ 0x0000003 +#define XFRD_FCMD_READ_DUAL 0x801003B +#define XFRD_FCMD_READ_QUAD 0x801006B + + +#define FCMD_RESET 0x99 //reset +#define FCMD_ENRST 0x66 //enable reset +#define FCMD_WREN 0x06 //write enable +#define FCMD_WRDIS 0x04 //write disable +#define FCMD_VSRWREN 0x50 //Volatile SR Write Enable + + +#define FCMD_CERASE 0x60 //(or 0xC7)chip erase +#define FCMD_SERASE 0x20 //sector erase +#define FCMD_BERASE32 0x52 //block erease 32k +#define FCMD_BERASE64 0xD8 + +#define FCMD_DPWRDN 0xB9 //deep power down +#define FCMD_RLSDPD 0xAB //release from powerdown(and read device id) +#define FCMD_WRST 0x01 //write status +#define FCMD_RDID 0x9F //read ID +#define FCMD_RDST 0x05 //read status +#define FCMD_RDST_H 0x35 //read status high byte +#define FCMD_PPROG 0x02 //page program +#define FCMD_READ 0x03 //read +#define FCMD_READF 0x0B //fast read +#define FCMD_READDO 0x3B //dual output fast read +#define FCMD_READDIO 0xBB //dual I/O fast read +#define FCMD_READQO 0x6B //quad output fast read +#define FCMD_READQIO 0xeB //quad I/O fast read +#define FCMD_READQIOW 0xe7 //quad I/O fast read word + +typedef struct +{ + sysclk_t spif_ref_clk; // + uint32_t rd_instr; +} xflash_Ctx_t; + +typedef enum{ + CHIP_ID_UNCHECK, + CHIP_ID_EMPTY, + CHIP_ID_VALID, + CHIP_ID_INVALID, +}CHIP_ID_STATUS_e; + +typedef struct{ + CHIP_ID_STATUS_e chipMAddrStatus; + uint8_t mAddr[CHIP_MADDR_LEN]; +}chipMAddr_t; + + + +extern int _spif_wait_nobusy(uint8_t flg, uint32_t tout_ns); +extern int spif_write(uint32_t addr, uint8_t* data, uint32_t size); +extern int spif_write_dma(uint32_t addr, uint8_t* data, uint32_t size); +extern int spif_read(uint32_t addr, uint8_t* data, uint32_t size); +extern int spif_read_dma(uint32_t addr, uint8_t* data, uint32_t size); +extern int spif_erase_sector(unsigned int addr); +extern int spif_erase_block64(unsigned int addr); +extern int spif_erase_all(void); +extern uint8_t spif_flash_status_reg_0(void); +extern int spif_write_protect(bool en); +extern void spif_cmd(uint8_t op, uint8_t addrlen, uint8_t rdlen, uint8_t wrlen, uint8_t mbit, uint8_t dummy); +extern void spif_rddata(uint8_t* data, uint8_t len); +extern int spif_config(sysclk_t ref_clk, uint8_t div, uint32_t rd_instr, uint8_t mode_bit, uint8_t QE); +int hal_spif_cache_init(void);//xflash_Ctx_t cfg); + +int hal_flash_write(uint32_t addr, uint8_t* data, uint32_t size); +int hal_flash_write_by_dma(uint32_t addr, uint8_t* data, uint32_t size); +int hal_flash_read(uint32_t addr, uint8_t* data, uint32_t size); +int hal_flash_erase_sector(unsigned int addr); +int hal_flash_erase_block64(unsigned int addr); +int flash_write_word(unsigned int offset, uint32_t value); + +CHIP_ID_STATUS_e chip_id_one_bit_hot_convter(uint8_t* b,uint32_t w); + +void LL_PLUS_LoadMACFromFlash(uint32_t addr); + +CHIP_ID_STATUS_e LL_PLUS_LoadMACFromChipMAddr(void); + + +void check_chip_mAddr(void); +void LOG_CHIP_MADDR(void); + + +#endif + + + + + + + + diff --git a/arch/arm/src/phy62xx/global_config.h b/arch/arm/src/phy62xx/global_config.h new file mode 100644 index 00000000000..811ee230919 --- /dev/null +++ b/arch/arm/src/phy62xx/global_config.h @@ -0,0 +1,233 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/** + **************************************************************************************** + + @file global_config.h + + @brief This file contains the definitions of index of global configuration which + will be configured in APP project. + + + $Rev: $ + + **************************************************************************************** +*/ + + +#ifndef _GLOBAL_CONFIG_H_ +#define _GLOBAL_CONFIG_H_ + +#include "types.h" + +/******************************************************************************* + software configuration parameters definition +*/ + +#define CONFIG_BASE_ADDR 0x1fff0400 + +#define SOFT_PARAMETER_NUM 256 +// parameter index of configuration array +#define ADV_CHANNEL_INTERVAL 0 // interval between adv channel in the same adv event +#define SCAN_RSP_DELAY 1 // to adjust scan req -> scan rsp delay +#define CONN_REQ_TO_SLAVE_DELAY 2 // to calibrate the delay between conn req & 1st slave conn event +#define SLAVE_CONN_DELAY 3 // to adjust the delay between 2 slave connection events +#define SLAVE_CONN_DELAY_BEFORE_SYNC 4 // to adjust the delay between 2 slave connection events before 1st anchor is acquired +#define MAX_SLEEP_TIME 5 // maximum sleep time in us +#define MIN_SLEEP_TIME 6 // minimum sleep time in us +#define WAKEUP_ADVANCE 7 // wakeup advance time, to cover HW delay, crystal settle time, sw delay, ... etc. +#define WAKEUP_DELAY 8 // cycles of SW delay to wait crystal settle + +#define HDC_DIRECT_ADV_INTERVAL 9 +#define LDC_DIRECT_ADV_INTERVAL 10 + + +#define LL_SWITCH 11 // Link Layer switch, 1 enable, 0 disable +#define NON_ADV_CHANNEL_INTERVAL 12 // interval between non-adv channel in the same adv event + +#define CLOCK_SETTING 14 // HCLK +#define LL_HW_BB_DELAY 15 +#define LL_HW_AFE_DELAY 16 +#define LL_HW_PLL_DELAY 17 + +#define LL_HW_RTLP_LOOP_TIMEOUT 18 +#define LL_HW_RTLP_1ST_TIMEOUT 19 + +#define MIN_TIME_TO_STABLE_32KHZ_XOSC 20 + +#define LL_TX_PKTS_PER_CONN_EVT 21 +#define LL_RX_PKTS_PER_CONN_EVT 22 + + +// ============= A1 ROM metal change add +#define DIR_ADV_DELAY 23 + + +#define LL_TX_PWR_TO_REG_BIAS 24 + + +#define LL_SMART_WINDOW_COEF_ALPHA 25 +#define LL_SMART_WINDOW_TARGET 26 +#define LL_SMART_WINDOW_INCREMENT 27 +#define LL_SMART_WINDOW_LIMIT 28 +#define LL_SMART_WINDOW_ACTIVE_THD 29 +#define LL_SMART_WINDOW_ACTIVE_RANGE 30 + +#define LL_SMART_WINDOW_FIRST_WINDOW 31 + +#define LL_HW_Tx_TO_RX_INTV 32 +#define LL_HW_Rx_TO_TX_INTV 33 + +#define INITIAL_STACK_PTR 34 +#define ALLOW_TO_SLEEP_TICK_RC32K 35 + +#define LL_HW_BB_DELAY_ADV 36 +#define LL_HW_AFE_DELAY_ADV 37 +#define LL_HW_PLL_DELAY_ADV 38 + +// For scan & master, add 2018-6-15 +#define LL_ADV_TO_SCAN_REQ_DELAY 39 +#define LL_ADV_TO_CONN_REQ_DELAY 40 + +#define LL_MOVE_TO_MASTER_DELAY 41 + +#define LL_HW_TRLP_LOOP_TIMEOUT 42 + +#define LL_CONN_REQ_WIN_SIZE 43 +#define LL_CONN_REQ_WIN_OFFSET 44 + +#define LL_MASTER_PROCESS_TARGET 45 +#define LL_MASTER_TIRQ_DELAY 46 + +//for PHY updated add 2018-11-07 +#define LL_HW_BB_DELAY_2MPHY 47 +#define LL_HW_AFE_DELAY_2MPHY 48 +#define LL_HW_PLL_DELAY_2MPHY 49 + +#define LL_HW_Tx_TO_RX_INTV_2MPHY 50 +#define LL_HW_Rx_TO_TX_INTV_2MPHY 51 + +#define LL_HW_BB_DELAY_500KPHY 52 +#define LL_HW_AFE_DELAY_500KPHY 53 +#define LL_HW_PLL_DELAY_500KPHY 54 + +#define LL_HW_Tx_TO_RX_INTV_500KPHY 55 +#define LL_HW_Rx_TO_TX_INTV_500KPHY 56 + +#define LL_HW_BB_DELAY_125KPHY 57 +#define LL_HW_AFE_DELAY_125KPHY 58 +#define LL_HW_PLL_DELAY_125KPHY 59 + +#define LL_HW_Tx_TO_RX_INTV_125KPHY 60 +#define LL_HW_Rx_TO_TX_INTV_125KPHY 61 + +#define LL_HW_TRLP_TO_GAP 62 +#define LL_HW_RTLP_TO_GAP 63 + +#define LL_TRX_NUM_ADAPTIVE_CONFIG 64 +#define OSAL_SYS_TICK_WAKEUP_TRIM 65 + +// ==== A2 add, for secondary adv/scan +#define LL_NOCONN_ADV_EST_TIME 70 +#define LL_NOCONN_ADV_MARGIN 71 +#define LL_SEC_SCAN_MARGIN 72 +#define LL_MIN_SCAN_TIME 73 +// Bumblebee ROM code +#define LL_CONN_ADV_EST_TIME 74 +#define LL_SCANABLE_ADV_EST_TIME 75 + + + +#define MAC_ADDRESS_LOC 80 + +// ==== For Extended Adv & Periodic adv +#define LL_EXT_ADV_INTER_PRI_CHN_INT 81 +#define LL_EXT_ADV_INTER_AUX_CHN_INT 82 +#define LL_EXT_ADV_RSC_POOL_PERIOD 83 +#define LL_EXT_ADV_RSC_POOL_UNIT 84 + +#define LL_EXT_ADV_TASK_DURATION 86 +#define LL_PRD_ADV_TASK_DURATION 87 +#define LL_CONN_TASK_DURATION 88 + +#define TIMER_ISR_ENTRY_TIME 90 // time from HW timer expiry to ISR entry, unit: us +#define LL_MULTICONN_MASTER_PREEMP 91 +#define LL_MULTICONN_SLAVE_PREEMP 92 + +#define LL_EXT_ADV_INTER_SEC_CHN_INT 93 +#define LL_EXT_ADV_PRI_2_SEC_CHN_INT 94 + +#define LL_EXT_ADV_RSC_PERIOD 95 +#define LL_EXT_ADV_RSC_SLOT_DURATION 96 + +#define LL_PRD_ADV_RSC_PERIOD 97 +#define LL_PRD_ADV_RSC_SLOT_DURATION 98 + +#define LL_EXT_ADV_PROCESS_TARGET 99 +#define LL_PRD_ADV_PROCESS_TARGET 100 + + + + + + + + + +// ============== + +#define RC32_TRACKINK_ALLOW 0x00000001 // enable tracking RC 32KHz clock with 16MHz hclk +#define SLAVE_LATENCY_ALLOW 0x00000002 // slave latency allow switch +#define LL_DEBUG_ALLOW 0x00000004 // enable invoke RAM project debug output fucntion +#define LL_WHITELIST_ALLOW 0x00000008 // enable whitelist filter +#define LL_RC32K_SEL 0x00000010 // select RC32K RTC, otherwise select crystal 32K RTC +#define SIMUL_CONN_ADV_ALLOW 0x00000020 // allow send adv in connect state +#define SIMUL_CONN_SCAN_ALLOW 0x00000040 // allow scan in connect state + +#define GAP_DUP_RPT_FILTER_DISALLOW 0x00000100 // duplicate report filter in GAP layer, allow default + +// delete 2018-7-17, should use enum H_SYSCLK_SEL +//enum +//{ +// CLOCK_16MHZ = 0, +// CLOCK_32MHZ = 1, +// CLOCK_48MHZ = 2, +// CLOCK_64MHZ = 3, +// CLOCK_96MHZ = 4, +// CLOCK_32MHZ_DBL=5 +//}; + +//extern uint32 global_config[SOFT_PARAMETER_NUM]; +extern uint32* pGlobal_config; // note: app project needn't this variable + +#endif // _GLOBAL_CONFIG_H_ diff --git a/arch/arm/src/phy62xx/gpio.c b/arch/arm/src/phy62xx/gpio.c new file mode 100644 index 00000000000..6ef20ec9630 --- /dev/null +++ b/arch/arm/src/phy62xx/gpio.c @@ -0,0 +1,628 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/******************************************************************************* + @file gpio.c + @brief Contains all functions support for gpio and iomux driver + @version 0.0 + @date 19. Oct. 2017 + @author qing.han + + + +*******************************************************************************/ +#include "types.h" +#include "string.h" +#include "mcu.h" +#include "clock.h" +#include "gpio.h" +#include "pwrmgr.h" +#include "error.h" +#include "log.h" +#include "jump_function.h" + + +extern uint32_t s_gpio_wakeup_src_group1,s_gpio_wakeup_src_group2; + + +enum +{ + GPIO_PIN_ASSI_NONE = 0, + GPIO_PIN_ASSI_OUT, + GPIO_PIN_ASSI_IN, +}; + +typedef struct +{ + bool enable; + uint8_t pin_state; + gpioin_Hdl_t posedgeHdl; + gpioin_Hdl_t negedgeHdl; + +} gpioin_Ctx_t; + +typedef struct +{ + bool state; + uint8_t pin_assignments[NUMBER_OF_PINS]; + gpioin_Ctx_t irq_ctx[NUMBER_OF_PINS]; + +} gpio_Ctx_t; + +typedef struct +{ + uint8_t reg_i; + uint8_t bit_h; + uint8_t bit_l; + +} PULL_TypeDef; + +static gpio_Ctx_t m_gpioCtx = +{ + .state = FALSE, + .pin_assignments = {0,}, +}; + +const uint8_t c_gpio_index[GPIO_NUM] = {0,1,2,3,7,9,10,11,14,15,16,17,18,20,23,24,25,26,27,31,32,33,34}; + +const PULL_TypeDef c_gpio_pull[GPIO_NUM]= +{ + {0,2,1}, //p0 + {0,5,4}, //p1 + {0,8,7}, //p2 + {0,11,10},//p3 + {0,23,22},//p7 + {0,29,28},//p9 + {1,2,1}, //p10 + {1,5,4}, //p11 + {1,14,13},//p14 + {1,17,16},//p15 + {1,20,19},//p16 + {1,23,22},//p17 + {1,26,25},//p18 + {2,2,1}, //p20 + {2,11,10},//p23 + {2,14,13},//p24 + {2,17,16},//p25 + {2,20,19},//p26 + {2,23,22},//p27 + {3,5,4}, //p31 + {3,8,7}, //p32 + {3,11,10},//p33 + {3,14,13},//p34 +}; + +const signed char retention_reg[GPIO_NUM][2]= +{ + {0,13},//p0 + {0,14},//p1 + {0,16},//p2 + {0,17},//p3 + {0,19},//p7 + {0,20},//p9 + {1,7},//p10 + {1,8},//p11 + {1,10},//p14 + {1,11},//p15 + {1,28},//p16 + {1,29},//p17 + {2,4},//p18 + {2,5},//p20 + {2,7},//p23 + {2,8},//p24 + {2,25},//p25 + {2,26},//p26 + {2,28},//p27 + {2,29},//p31 + {3,1},//p32 + {3,2},//p33 + {3,23},//p34 +}; + +static int hal_gpio_interrupt_disable(gpio_pin_e pin) +{ + subWriteReg(&(AP_GPIO->intmask),pin,pin,1); + subWriteReg(&(AP_GPIO->inten),pin,pin,0); + return PPlus_SUCCESS; +} + +void hal_gpio_write(gpio_pin_e pin, uint8_t en) +{ +// hal_gpio_pin_init(pin,GPIO_OUTPUT); + if(en) + AP_GPIO->swporta_dr |= BIT(pin); + else + AP_GPIO->swporta_dr &= ~BIT(pin); + + hal_gpio_pin_init(pin,GPIO_OUTPUT); +} + +void hal_gpio_fast_write(gpio_pin_e pin, uint8_t en) +{ + if(en) + AP_GPIO->swporta_dr |= BIT(pin); + else + AP_GPIO->swporta_dr &= ~BIT(pin); +} + +bool hal_gpio_read(gpio_pin_e pin) +{ + uint32_t r; + + if(AP_GPIO->swporta_ddr & BIT(pin)) + r = AP_GPIO->swporta_dr; + else + r = AP_GPIO->ext_porta; + + return (int)((r>> pin) &1); +} + +void hal_gpio_fmux(gpio_pin_e pin, bit_action_e value) +{ + if(value) + { +// if((pin == P2) || (pin == P3)) +// hal_gpio_pin2pin3_control(pin,1); + AP_IOMUX->full_mux0_en |= BIT(pin); + } + else + AP_IOMUX->full_mux0_en &= ~BIT(pin); +} + +void hal_gpio_fmux_set(gpio_pin_e pin,gpio_fmux_e type) +{ + uint8_t h = 0,l = 0; + uint32_t reg_index; + uint32_t bit_index; + + if(pin != GPIO_DUMMY) + { + reg_index = pin / 4; + bit_index = pin % 4; + l = 8 * bit_index; + h = l + 5; + subWriteReg(&(AP_IOMUX->gpio_sel[reg_index]),h,l,type); + hal_gpio_fmux(pin, Bit_ENABLE); + } +} + +int hal_gpio_pin_init(gpio_pin_e pin,gpio_dir_t type) +{ + if((type == GPIO_INPUT)&&(m_gpioCtx.pin_assignments[pin] == GPIO_PIN_ASSI_OUT)) + { + return PPlus_ERR_INVALID_STATE; + } + + hal_gpio_fmux(pin,Bit_DISABLE); + + if((pin == P2) || (pin == P3)) + hal_gpio_pin2pin3_control(pin,1); + + hal_gpio_cfg_analog_io(pin,Bit_DISABLE); + + if(type == GPIO_OUTPUT) + { + AP_GPIO->swporta_ddr |= BIT(pin); + //m_gpioCtx.pin_assignments[pin] = GPIO_PIN_ASSI_OUT; + } + else + { + AP_GPIO->swporta_ddr &= ~BIT(pin); + m_gpioCtx.pin_assignments[pin] = GPIO_PIN_ASSI_IN; + } + + return PPlus_SUCCESS; +} + +static void hal_gpio_wakeup_control(gpio_pin_e pin, bit_action_e value) +{ + if(pin < P32) + { + if (value) + AP_AON->REG_S9 |= BIT(c_gpio_index[pin]); + else + AP_AON->REG_S9 &= ~BIT(c_gpio_index[pin]); + } + else + { + if (value) + AP_AON->REG_S10 |= BIT(c_gpio_index[pin] - 32); + else + AP_AON->REG_S10 &= ~BIT(c_gpio_index[pin] - 32); + } +} + +void hal_gpio_ds_control(gpio_pin_e pin, bit_action_e value) +{ + if(value) + AP_IOMUX->pad_ps0 |= BIT(pin); + else + AP_IOMUX->pad_ps0 &= ~BIT(pin); +} + +int hal_gpioretention_unregister(gpio_pin_e pin) +{ + if(m_gpioCtx.pin_assignments[pin] == GPIO_PIN_ASSI_IN) + return PPlus_ERR_INVALID_PARAM; + + m_gpioCtx.pin_assignments[pin] = GPIO_PIN_ASSI_NONE; + hal_gpio_pin_init(pin,GPIO_INPUT); + return PPlus_SUCCESS; +} + + +int hal_gpioin_unregister(gpio_pin_e pin) +{ + gpioin_Ctx_t* p_irq_ctx = &(m_gpioCtx.irq_ctx[0]); + + if (pin > (NUMBER_OF_PINS - 1)) + return PPlus_ERR_NOT_SUPPORTED; + + hal_gpioin_disable(pin); + p_irq_ctx[pin].negedgeHdl = NULL; + p_irq_ctx[pin].posedgeHdl = NULL; + return PPlus_SUCCESS; +} + +int hal_gpio_cfg_analog_io(gpio_pin_e pin, bit_action_e value) +{ + if((pin < P11) || (pin > P25)) + return PPlus_ERR_INVALID_PARAM; + + if(value) + { + hal_gpio_pull_set(pin,GPIO_FLOATING); + AP_IOMUX->Analog_IO_en |= BIT(pin - P11); + } + else + { + AP_IOMUX->Analog_IO_en &= ~BIT(pin - P11); + } + + return PPlus_SUCCESS; +} + + +void hal_gpio_pull_set(gpio_pin_e pin, gpio_pupd_e type) +{ + uint8_t i = c_gpio_pull[pin].reg_i; + uint8_t h = c_gpio_pull[pin].bit_h; + uint8_t l = c_gpio_pull[pin].bit_l; + + if(pin < P31) + subWriteReg(&(AP_AON->IOCTL[i]),h,l,type); + else + subWriteReg(&(AP_AON->PMCTL0),h,l,type); +} + +void hal_gpio_wakeup_set(gpio_pin_e pin, gpio_polarity_e type) +{ + uint8_t i = c_gpio_pull[pin].reg_i; + uint8_t p = c_gpio_pull[pin].bit_l-1; + + if (m_gpioCtx.pin_assignments[pin] != GPIO_PIN_ASSI_IN) + return; + + AP_GPIO->inttype_level |= BIT(pin);//edge sensitive + + if(pin < P31) + { + if(POL_FALLING == type) + AP_AON->IOCTL[i] |= BIT(p); + else + AP_AON->IOCTL[i] &= ~BIT(p); + } + else + { + if(POL_FALLING == type) + AP_AON->PMCTL0 |= BIT(p); + else + AP_AON->PMCTL0 &= ~BIT(p); + } + + hal_gpio_wakeup_control(pin,Bit_ENABLE);//enable wakeup function +} + +void hal_gpio_pin2pin3_control(gpio_pin_e pin, uint8_t en)//0:sw,1:other func +{ + if(en) + AP_IOMUX->gpio_pad_en |= BIT(pin-2); + else + AP_IOMUX->gpio_pad_en &= ~BIT(pin-2); +} + + +static void hal_gpio_retention_enable(gpio_pin_e pin,uint8_t en) +{ + if(en) + { + if((pin == P32)||(pin == P33)||(pin == P34)) + { + AP_AON->PMCTL0 |= BIT(retention_reg[pin][1]); + } + else + { + AP_AON->IOCTL[retention_reg[pin][0]] |= BIT(retention_reg[pin][1]); + } + } + else + { + if((pin == P32)||(pin == P33)||(pin == P34)) + { + AP_AON->PMCTL0 &= ~BIT(retention_reg[pin][1]); + } + else + { + AP_AON->IOCTL[retention_reg[pin][0]] &= ~BIT(retention_reg[pin][1]); + } + } +} + +int hal_gpioin_disable(gpio_pin_e pin) +{ + gpioin_Ctx_t* p_irq_ctx = &(m_gpioCtx.irq_ctx[0]); + + if (pin > (NUMBER_OF_PINS - 1)) + return PPlus_ERR_NOT_SUPPORTED; + + p_irq_ctx[pin].enable = FALSE; + m_gpioCtx.pin_assignments[pin] = GPIO_PIN_ASSI_NONE; + hal_gpio_pin_init(pin, GPIO_INPUT); + return hal_gpio_interrupt_disable(pin); +} + +static int hal_gpio_interrupt_enable(gpio_pin_e pin, gpio_polarity_e type) +{ + uint32_t gpio_tmp; + + if (pin >= NUMBER_OF_PINS) + return PPlus_ERR_NOT_SUPPORTED; + + gpio_tmp = AP_GPIO->inttype_level; + gpio_tmp |= (1 << pin); //edge sensitive + AP_GPIO->inttype_level = gpio_tmp; + gpio_tmp = AP_GPIO->intmask; + gpio_tmp &= ~(1 << pin); //unmask interrupt + AP_GPIO->intmask = gpio_tmp; + gpio_tmp = AP_GPIO->int_polarity; + + if (type == POL_RISING ) + gpio_tmp |= (1 << pin); + else + gpio_tmp &= ~(1 << pin); + + AP_GPIO->int_polarity = gpio_tmp; + gpio_tmp = AP_GPIO->inten; + gpio_tmp |= (1 << pin); //enable interrupt + AP_GPIO->inten = gpio_tmp; + return PPlus_SUCCESS; +} + +static void hal_gpioin_event_pin(gpio_pin_e pin, gpio_polarity_e type) +{ + gpioin_Ctx_t* p_irq_ctx = &(m_gpioCtx.irq_ctx[0]); + + if (p_irq_ctx[pin].posedgeHdl && (type == POL_RISING )) + { + p_irq_ctx[pin].posedgeHdl(pin,POL_RISING );//LOG("POS\n"); + } + else if (p_irq_ctx[pin].negedgeHdl && (type == POL_FALLING)) + { + p_irq_ctx[pin].negedgeHdl(pin,POL_FALLING);//LOG("NEG\n"); + } +} + +static void hal_gpioin_wakeup_trigger(gpio_pin_e pin) +{ + uint8_t pin_state = (uint8_t)hal_gpio_read(pin); + gpio_polarity_e type = pin_state ? POL_RISING : POL_FALLING; + + if (m_gpioCtx.irq_ctx[pin].pin_state != pin_state) + hal_gpioin_event_pin(pin, type); +} + +static void hal_gpioin_event(uint32 int_status, uint32 polarity) +{ + int i; + gpioin_Ctx_t* p_irq_ctx = &(m_gpioCtx.irq_ctx[0]); +// LOG("GI:%x,%x\n",int_status,polarity); + + for (i = 0; i < NUMBER_OF_PINS; i++) + { + if (int_status & (1ul << i)) + { + gpio_polarity_e type = (polarity & BIT(i)) ? POL_RISING : POL_FALLING; + hal_gpioin_event_pin((gpio_pin_e)i, type); + + //reconfig interrupt + if (p_irq_ctx[i].posedgeHdl && p_irq_ctx[i].negedgeHdl) //both raise and fall + { + type = (type == POL_RISING) ? POL_FALLING : POL_RISING ; + hal_gpio_interrupt_enable((gpio_pin_e)i, type); + } + else if (p_irq_ctx[i].posedgeHdl) //raise + { + hal_gpio_interrupt_enable((gpio_pin_e)i, POL_RISING ); + } + else if (p_irq_ctx[i].negedgeHdl) //fall + { + hal_gpio_interrupt_enable((gpio_pin_e)i, POL_FALLING); + } + } + } +} + +static void hal_gpio_sleep_handler(void) +{ + int i; + gpio_polarity_e pol; + + for (i = 0; i < NUMBER_OF_PINS; i++) + { + //config wakeup + if (m_gpioCtx.pin_assignments[i] == GPIO_PIN_ASSI_OUT) + { + hal_gpio_retention_enable((gpio_pin_e)i,Bit_ENABLE); + } + + if (m_gpioCtx.pin_assignments[i] == GPIO_PIN_ASSI_IN) + { + pol = hal_gpio_read((gpio_pin_e)i) ? POL_FALLING : POL_RISING ; + hal_gpio_wakeup_set((gpio_pin_e)i, pol); + m_gpioCtx.irq_ctx[i].pin_state = hal_gpio_read((gpio_pin_e)i); + } + } +} + +static void hal_gpio_wakeup_handler(void) +{ + int i; + NVIC_SetPriority(GPIO_IRQn, IRQ_PRIO_HAL); + NVIC_EnableIRQ(GPIO_IRQn); + + for (i = 0; i < NUMBER_OF_PINS; i++) + { + if((i == 2) || (i == 3)) + hal_gpio_pin2pin3_control((gpio_pin_e)i,1); + + if (m_gpioCtx.pin_assignments[i] == GPIO_PIN_ASSI_OUT) + { + bool pol = hal_gpio_read((gpio_pin_e)i); + hal_gpio_write((gpio_pin_e)i,pol); + hal_gpio_retention_enable((gpio_pin_e)i,Bit_DISABLE); + } + + if (m_gpioCtx.irq_ctx[i].enable) + { + hal_gpioin_enable((gpio_pin_e)i); //resume gpio irq + hal_gpioin_wakeup_trigger((gpio_pin_e)i);//trigger gpio irq manually + } + } +} + +void __attribute__((used)) hal_GPIO_IRQHandler(void) +{ + uint32 polarity = AP_GPIO->int_polarity; + uint32 st = AP_GPIO->int_status; + AP_GPIO->porta_eoi = st;//clear interrupt + hal_gpioin_event(st, polarity); +} + +int hal_gpioin_enable(gpio_pin_e pin) +{ + gpioin_Ctx_t* p_irq_ctx = &(m_gpioCtx.irq_ctx[0]); + gpio_polarity_e type = POL_FALLING; + uint32 pinVal = 0; + + if (p_irq_ctx[pin].posedgeHdl == NULL && p_irq_ctx[pin].negedgeHdl == NULL) + return PPlus_ERR_NOT_REGISTED; + + m_gpioCtx.pin_assignments[pin] = GPIO_PIN_ASSI_IN; + p_irq_ctx[pin].enable = TRUE; + hal_gpio_pin_init(pin, GPIO_INPUT); + + //hal_gpio_pull_set(pin, PULL_DOWN); //??need disccuss + if (p_irq_ctx[pin].posedgeHdl && p_irq_ctx[pin].negedgeHdl) //both raise and fall + { + pinVal = hal_gpio_read(pin); + type = pinVal ? POL_FALLING : POL_RISING ; + } + else if (p_irq_ctx[pin].posedgeHdl) //raise + { + type = POL_RISING ; + } + else if (p_irq_ctx[pin].negedgeHdl) //fall + { + type = POL_FALLING; + } + + hal_gpio_interrupt_enable(pin, type); + return PPlus_SUCCESS; +} + +int hal_gpioretention_register(gpio_pin_e pin) +{ + if(m_gpioCtx.pin_assignments[pin] == GPIO_PIN_ASSI_IN) + return PPlus_ERR_INVALID_PARAM; + + m_gpioCtx.pin_assignments[pin] = GPIO_PIN_ASSI_OUT; + hal_gpio_pin_init(pin,GPIO_OUTPUT); + return PPlus_SUCCESS; +} + + +int hal_gpioin_register(gpio_pin_e pin, gpioin_Hdl_t posedgeHdl, gpioin_Hdl_t negedgeHdl) +{ + int ret; + gpioin_Ctx_t* p_irq_ctx = &(m_gpioCtx.irq_ctx[0]); + hal_gpioin_disable(pin); + p_irq_ctx[pin].posedgeHdl = posedgeHdl; + p_irq_ctx[pin].negedgeHdl = negedgeHdl; + ret = hal_gpioin_enable(pin); + JUMP_FUNCTION(GPIO_IRQ_HANDLER) = (uint32_t)&hal_GPIO_IRQHandler; + + if (ret != PPlus_SUCCESS) + hal_gpioin_disable(pin); + + return ret; +} + +int hal_gpio_init(void) +{ + if (m_gpioCtx.state) + return PPlus_ERR_INVALID_STATE; + + memset(&m_gpioCtx, 0, sizeof(m_gpioCtx)); + m_gpioCtx.state = TRUE; + //disable all channel irq,unmask all channel + AP_GPIO->intmask = 0; + //disable all wakeup pin + AP_WAKEUP->io_wu_mask_31_0 = 0; + AP_WAKEUP->io_wu_mask_34_32 = 0; + NVIC_SetPriority(GPIO_IRQn, IRQ_PRIO_HAL); + NVIC_EnableIRQ(GPIO_IRQn); + hal_pwrmgr_register(MOD_GPIO, hal_gpio_sleep_handler, hal_gpio_wakeup_handler); + return PPlus_SUCCESS; +} + +void hal_gpio_debug_mux(Freq_Type_e fre,bool en) +{ + if(en) + AP_IOMUX->debug_mux_en |= BIT(fre); + else + AP_IOMUX->debug_mux_en &= ~BIT(fre); +} + +void hal_gpioin_set_flag(gpio_pin_e pin) +{ + m_gpioCtx.pin_assignments[pin] = GPIO_PIN_ASSI_IN; +} diff --git a/arch/arm/src/phy62xx/gpio.h b/arch/arm/src/phy62xx/gpio.h new file mode 100644 index 00000000000..99203017825 --- /dev/null +++ b/arch/arm/src/phy62xx/gpio.h @@ -0,0 +1,220 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/******************************************************************************* + @file gpio.h + @brief Contains all functions support for gpio and iomux driver + @version 0.0 + @date 19. Oct. 2017 + @author qing.han + + + +*******************************************************************************/ +#ifndef __GPIO_H__ +#define __GPIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "bus_dev.h" +#include "error.h" + +#define NUMBER_OF_PINS 23 + +typedef enum +{ + GPIO_P00 = 0, P0 = GPIO_P00, + GPIO_P01 = 1, P1 = GPIO_P01, + GPIO_P02 = 2, P2 = GPIO_P02, + GPIO_P03 = 3, P3 = GPIO_P03, + GPIO_P07 = 4, P7 = GPIO_P07, + GPIO_P09 = 5, P9 = GPIO_P09, + GPIO_P10 = 6, P10 = GPIO_P10, + GPIO_P11 = 7, P11 = GPIO_P11, Analog_IO_0 = GPIO_P11, + GPIO_P14 = 8, P14 = GPIO_P14, Analog_IO_1 = GPIO_P14, + GPIO_P15 = 9, P15 = GPIO_P15, Analog_IO_2 = GPIO_P15, + GPIO_P16 = 10, P16 = GPIO_P16, Analog_IO_3 = GPIO_P16,XTALI = GPIO_P16, + GPIO_P17 = 11, P17 = GPIO_P17, Analog_IO_4 = GPIO_P17,XTALO = GPIO_P17, + GPIO_P18 = 12, P18 = GPIO_P18, Analog_IO_5 = GPIO_P18, + GPIO_P20 = 13, P20 = GPIO_P20, Analog_IO_6 = GPIO_P20, + GPIO_P23 = 14, P23 = GPIO_P23, Analog_IO_7 = GPIO_P23, + GPIO_P24 = 15, P24 = GPIO_P24, Analog_IO_8 = GPIO_P24, + GPIO_P25 = 16, P25 = GPIO_P25, Analog_IO_9 = GPIO_P25, + GPIO_P26 = 17, P26 = GPIO_P26, + GPIO_P27 = 18, P27 = GPIO_P27, + GPIO_P31 = 19, P31 = GPIO_P31, + GPIO_P32 = 20, P32 = GPIO_P32, + GPIO_P33 = 21, P33 = GPIO_P33, + GPIO_P34 = 22, P34 = GPIO_P34, + GPIO_NUM = 23, + GPIO_DUMMY = 0xff, +} gpio_pin_e; + +typedef enum +{ + FMUX_IIC0_SCL= 0, + FMUX_IIC0_SDA= 1, + FMUX_IIC1_SCL= 2, + FMUX_IIC1_SDA= 3, + FMUX_UART0_TX=4, FMUX_UART_TX=4, + FMUX_UART0_RX=5, FMUX_UART_RX=5, + FMUX_RF_RX_EN=6, + FMUX_RF_TX_EN=7, + FMUX_UART1_TX=8, + FMUX_UART1_RX=9, + FMUX_PWM0=10, + FMUX_PWM1=11, + FMUX_PWM2=12, + FMUX_PWM3=13, + FMUX_PWM4=14, + FMUX_PWM5=15, + FMUX_SPI_0_SCK=16, + FMUX_SPI_0_SSN=17, + FMUX_SPI_0_TX=18, + FMUX_SPI_0_RX=19, + FMUX_SPI_1_SCK=20, + FMUX_SPI_1_SSN=21, + FMUX_SPI_1_TX=22, + FMUX_SPI_1_RX=23, + FMUX_CHAX=24, + FMUX_CHBX=25, + FMUX_CHIX=26, + FMUX_CHAY=27, + FMUX_CHBY=28, + FMUX_CHIY=29, + FMUX_CHAZ=30, + FMUX_CHBZ=31, + FMUX_CHIZ=32, + FMUX_CLK1P28M=33, + FMUX_ADCC=34, + FMUX_ANT_SEL_0=35, + FMUX_ANT_SEL_1=36, + FMUX_ANT_SEL_2=37, + +} gpio_fmux_e; + +typedef enum +{ + FRE_HCLK_DIV8 = 0, + FRE_PCLK_DIV4 = 1, + FRE_CLK_1P28M = 2, + FRE_CLK_RC32K = 6, + FRE_XTAL_CLK32768 = 7, +} Freq_Type_e; + +typedef enum +{ + GPIO_INPUT = 0, + GPIO_OUTPUT = 1 +} gpio_dir_t; + +typedef enum +{ + POL_FALLING = 0, POL_ACT_LOW = 0, + POL_RISING = 1, POL_ACT_HIGH = 1 +} gpio_polarity_e; + +typedef enum +{ + Bit_DISABLE = 0, + Bit_ENABLE, +} bit_action_e; + +typedef enum +{ + GPIO_FLOATING = 0x00, //no pull + GPIO_PULL_UP_S = 0x01, //pull up strong + GPIO_PULL_UP = 0x02, //pull up weak + GPIO_PULL_DOWN = 0x03, +} gpio_pupd_e; + +typedef struct +{ + gpio_pin_e pin; + gpio_pupd_e type; +} ioinit_cfg_t; + + +#define NEGEDGE POL_FALLING +#define POSEDGE POL_RISING +#define IO_Wakeup_Pol_e gpio_polarity_e + +#define FLOATING GPIO_FLOATING +#define WEAK_PULL_UP GPIO_PULL_UP +#define STRONG_PULL_UP GPIO_PULL_UP_S +#define PULL_DOWN GPIO_PULL_DOWN +#define GPIO_Pin_e gpio_pin_e +#define OEN GPIO_OUTPUT +#define IE GPIO_INPUT +#define Fmux_Type_e gpio_fmux_e +#define GPIO_Wakeup_Pol_e gpio_polarity_e +#define BitAction_e bit_action_e +typedef void (*gpioin_Hdl_t)(gpio_pin_e pin,gpio_polarity_e type); + +void hal_gpio_write(gpio_pin_e pin, uint8_t en); +void hal_gpio_fast_write(gpio_pin_e pin, uint8_t en); +bool hal_gpio_read(gpio_pin_e pin); +void hal_gpio_fmux(gpio_pin_e pin, bit_action_e value); +void hal_gpio_fmux_set(gpio_pin_e pin,gpio_fmux_e type); + +int hal_gpio_pin_init(gpio_pin_e pin,gpio_dir_t type); +void hal_gpio_ds_control(gpio_pin_e pin, bit_action_e value); + +int hal_gpio_cfg_analog_io(gpio_pin_e pin, bit_action_e value) ; +void hal_gpio_pull_set(gpio_pin_e pin, gpio_pupd_e type) ; +void hal_gpio_wakeup_set(gpio_pin_e pin, gpio_polarity_e type); + +void hal_gpio_pin2pin3_control(gpio_pin_e pin, uint8_t en); +int hal_gpioin_disable(gpio_pin_e pin); + +void __attribute__((used)) hal_GPIO_IRQHandler(void); +int hal_gpioin_enable(gpio_pin_e pin); +int hal_gpioin_register(gpio_pin_e pin, gpioin_Hdl_t posedgeHdl, gpioin_Hdl_t negedgeHdl); +int hal_gpioretention_unregister(gpio_pin_e pin); +int hal_gpioretention_register(gpio_pin_e pin); +int hal_gpioin_unregister(gpio_pin_e pin); +int hal_gpio_init(void); +void hal_gpio_debug_mux(Freq_Type_e fre,bool en); + + +//rom api +extern int gpio_write(gpio_pin_e pin, uint8_t en); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/arch/arm/src/phy62xx/idle.c b/arch/arm/src/phy62xx/idle.c new file mode 100644 index 00000000000..495e18554d0 --- /dev/null +++ b/arch/arm/src/phy62xx/idle.c @@ -0,0 +1,95 @@ +/**************************************************************************** + * arch/arm/src/stm32f0l0g0/stm32_idle.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +#include "arm_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Does the board support an IDLE LED to indicate that the board is in the + * IDLE state? + */ + +#if defined(CONFIG_ARCH_LEDS) && defined(LED_IDLE) +# define BEGIN_IDLE() board_autoled_on(LED_IDLE) +# define END_IDLE() board_autoled_off(LED_IDLE) +#else +# define BEGIN_IDLE() +# define END_IDLE() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when there is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + nxsched_process_timer(); +#else + +/* If the g_dma_inprogress is zero, then there is no DMA in progress. This + * value is needed in the IDLE loop to determine if the IDLE loop should + * go into lower power power consumption modes. According to the LPC17xx + * User Manual: "The DMA controller can continue to work in Sleep mode, and + * has access to the peripheral SRAMs and all peripheral registers. The + * flash memory and the Main SRAM are not available in Sleep mode, they are + * disabled in order to save power." + */ + +//#ifdef CONFIG_STM32F0L0G0_GPDMA +// if (g_dma_inprogress == 0) +//#endif + { + /* Sleep until an interrupt occurs in order to save power */ + + BEGIN_IDLE(); + asm("WFI"); + END_IDLE(); + } +#endif +} diff --git a/arch/arm/src/phy62xx/irq.c b/arch/arm/src/phy62xx/irq.c new file mode 100644 index 00000000000..b78d7144fa3 --- /dev/null +++ b/arch/arm/src/phy62xx/irq.c @@ -0,0 +1,414 @@ +/**************************************************************************** + * arch/arm/src/phy62xx/phy62xx_irq.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "nvic.h" +#include "arm_arch.h" +#include "arm_internal.h" +#include "jump_function.h" + +/*#include "phy62xx_irq.h"*/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Get a 32-bit version of the default priority */ + +#define DEFPRIORITY32 \ + (NVIC_SYSH_PRIORITY_DEFAULT << 24 | NVIC_SYSH_PRIORITY_DEFAULT << 16 | \ + NVIC_SYSH_PRIORITY_DEFAULT << 8 | NVIC_SYSH_PRIORITY_DEFAULT) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_current_regs[] holds a references to the current interrupt level + * register storage structure. If is non-NULL only during interrupt + * processing. Access to g_current_regs[] must be through the macro + * CURRENT_REGS for portability. + */ + +volatile uint32_t *g_current_regs[1]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: phy62xx_dumpnvic + * + * Description: + * Dump some interesting NVIC registers + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG_IRQ_INFO) +static void phy62xx_dumpnvic(const char *msg, int irq) +{ + irqstate_t flags; + + flags = enter_critical_section(); + + irqinfo("NVIC (%s, irq=%d):\n", msg, irq); + irqinfo(" ISER: %08x ICER: %08x\n", + getreg32(ARMV6M_NVIC_ISER), getreg32(ARMV6M_NVIC_ICER)); + irqinfo(" ISPR: %08x ICPR: %08x\n", + getreg32(ARMV6M_NVIC_ISPR), getreg32(ARMV6M_NVIC_ICPR)); + irqinfo(" IRQ PRIO: %08x %08x %08x %08x\n", + getreg32(ARMV6M_NVIC_IPR0), getreg32(ARMV6M_NVIC_IPR1), + getreg32(ARMV6M_NVIC_IPR2), getreg32(ARMV6M_NVIC_IPR3)); + irqinfo(" %08x %08x %08x %08x\n", + getreg32(ARMV6M_NVIC_IPR4), getreg32(ARMV6M_NVIC_IPR5), + getreg32(ARMV6M_NVIC_IPR6), getreg32(ARMV6M_NVIC_IPR7)); + + irqinfo("SYSCON:\n"); + irqinfo(" CPUID: %08x\n", + getreg32(ARMV6M_SYSCON_CPUID)); + irqinfo(" ICSR: %08x AIRCR: %08x\n", + getreg32(ARMV6M_SYSCON_ICSR), getreg32(ARMV6M_SYSCON_AIRCR)); + irqinfo(" SCR: %08x CCR: %08x\n", + getreg32(ARMV6M_SYSCON_SCR), getreg32(ARMV6M_SYSCON_CCR)); + irqinfo(" SHPR2: %08x SHPR3: %08x\n", + getreg32(ARMV6M_SYSCON_SHPR2), getreg32(ARMV6M_SYSCON_SHPR3)); + + leave_critical_section(flags); +} + +#else +# define phy62xx_dumpnvic(msg, irq) +#endif + +/**************************************************************************** + * Name: phy62xx_nmi, phy62xx_busfault, phy62xx_usagefault, phy62xx_pendsv, + * phy62xx_dbgmonitor, phy62xx_pendsv, phy62xx_reserved + * + * Description: + * Handlers for various exceptions. None are handled and all are fatal + * error conditions. The only advantage these provided over the default + * unexpected interrupt handler is that they provide a diagnostic output. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_FEATURES +static int phy62xx_nmi(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + _err("PANIC!!! NMI received\n"); + PANIC(); + return 0; +} + +static int phy62xx_pendsv(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + _err("PANIC!!! PendSV received\n"); + PANIC(); + return 0; +} + +static int phy62xx_reserved(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + _err("PANIC!!! Reserved interrupt\n"); + PANIC(); + return 0; +} +#endif + +/**************************************************************************** + * Name: phy62xx_clrpend + * + * Description: + * Clear a pending interrupt at the NVIC. + * + ****************************************************************************/ + +static inline void phy62xx_clrpend(int irq) +{ + /* This will be called on each interrupt exit whether the interrupt can be + * enambled or not. So this assertion is necessarily lame. + */ + + DEBUGASSERT((unsigned)irq < NR_IRQS); + + /* Check for an external interrupt */ + + if (irq >= PHY62XX_IRQ_EXTINT && irq < (PHY62XX_IRQ_EXTINT + 32)) + { + /* Set the appropriate bit in the ISER register to enable the + * interrupt + */ + + putreg32((1 << (irq - PHY62XX_IRQ_EXTINT)), ARMV6M_NVIC_ICPR); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ +extern void exception_common(void); +extern void exception_common_inline(void); + +#define svc(code) asm volatile("svc %[immediate]"::[immediate]"I"(code)) +#define SVC_CALL_WR 0 + +/*irqid 0~31*/ +int irq_priority(int irqid, uint8_t priority) +{ +#if 0 + uint32_t val = (uint32_t)(priority<<6); + int idx = (irqid)/4; + int idx_mod = irqid % 4; + uint32_t regaddr = ARMV6M_NVIC_IPR(idx); + uint32_t regval = getreg32(regaddr); + regval &= ~(0xffUL << (idx_mod*8)); + regval |= (val << (idx_mod*8)); + putreg32(regval, regaddr); +#endif + return 0; +} +void LL_IRQHandler1(void); +void TIM1_IRQHandler1(void); +void TIM3_IRQHandler1(void); + +void up_irqinitialize(void) +{ + uint32_t regaddr; + int i; + + /* Disable all interrupts */ + + putreg32(0xffffffff, ARMV6M_NVIC_ICER); + + /* Set all interrupts (and exceptions) to the default priority */ + + putreg32(DEFPRIORITY32, ARMV6M_SYSCON_SHPR2); + putreg32(DEFPRIORITY32, ARMV6M_SYSCON_SHPR3); + + /* Now set all of the interrupt lines to the default priority */ + + for (i = 0; i < 8; i++) + { + regaddr = ARMV6M_NVIC_IPR(i); + putreg32(DEFPRIORITY32, regaddr); + } + + /*register jump table irq handler*/ + JUMP_FUNCTION(NMI_HANDLER) = (uint32_t)&exception_common_inline; + JUMP_FUNCTION(HARDFAULT_HANDLER) = (uint32_t)&exception_common; + JUMP_FUNCTION(SVC_HANDLER) = (uint32_t)&exception_common_inline; + JUMP_FUNCTION(PENDSV_HANDLER) = (uint32_t)&exception_common_inline; + JUMP_FUNCTION(SYSTICK_HANDLER) = (uint32_t)&exception_common_inline; + + /* Vectors 16 - 47 external irq handler */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 0 ) = (unsigned)&exception_common_inline, /*16+0 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 1 ) = (unsigned)&exception_common_inline, /*16+1 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 2 ) = (unsigned)&exception_common_inline, /*16+2 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 3 ) = (unsigned)&exception_common_inline, /*16+3 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 4 ) = (unsigned)&exception_common , /*16+4 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 5 ) = (unsigned)&exception_common_inline, /*16+5 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 6 ) = (unsigned)&exception_common_inline, /*16+6 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 7 ) = (unsigned)&exception_common_inline, /*16+7 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 8 ) = (unsigned)&exception_common_inline, /*16+8 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 9 ) = (unsigned)&exception_common_inline, /*16+9 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 10) = (unsigned)&exception_common_inline, /*16+10 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 11) = (unsigned)&exception_common , /*16+11 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 12) = (unsigned)&exception_common_inline, /*16+12 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 13) = (unsigned)&exception_common_inline, /*16+13 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 14) = (unsigned)&exception_common_inline, /*16+14 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 15) = (unsigned)&exception_common_inline, /*16+15 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 16) = (unsigned)&exception_common , /*16+16 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 17) = (unsigned)&exception_common_inline, /*16+17 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 18) = (unsigned)&exception_common , /*16+18 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 19) = (unsigned)&exception_common_inline, /*16+19 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 20) = (unsigned)&exception_common , /*16+20 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 21) = (unsigned)&exception_common , /*16+21 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 22) = (unsigned)&exception_common , /*16+22 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 23) = (unsigned)&exception_common , /*16+23 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 24) = (unsigned)&exception_common_inline, /*16+24 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 25) = (unsigned)&exception_common_inline, /*16+25 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 26) = (unsigned)&exception_common_inline, /*16+26 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 27) = (unsigned)&exception_common_inline, /*16+27 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 28) = (unsigned)&exception_common_inline, /*16+28 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 29) = (unsigned)&exception_common_inline, /*16+29 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 30) = (unsigned)&exception_common_inline, /*16+30 */ + JUMP_FUNCTION(V0_IRQ_HANDLER + 31) = (unsigned)&exception_common_inline, /*16+31 */ + + + + + /* currents_regs is non-NULL only while processing an interrupt */ + + CURRENT_REGS = NULL; + + /* Attach the SVCall and Hard Fault exception handlers. The SVCall + * exception is used for performing context switches; The Hard Fault + * must also be caught because a SVCall may show up as a Hard Fault + * under certain conditions. + */ + + irq_attach(PHY62XX_IRQ_SVCALL, arm_svcall, NULL); + irq_attach(PHY62XX_IRQ_HARDFAULT, arm_hardfault, NULL); + + /* Attach all other processor exceptions (except reset and sys tick) */ + +#ifdef CONFIG_DEBUG_FEATURES + irq_attach(PHY62XX_IRQ_NMI, phy62xx_nmi, NULL); + irq_attach(PHY62XX_IRQ_PENDSV, phy62xx_pendsv, NULL); + irq_attach(PHY62XX_IRQ_RESERVED, phy62xx_reserved, NULL); +#endif + + phy62xx_dumpnvic("initial", NR_IRQS); + + /* Initialize logic to support a second level of interrupt decoding for + * configured pin interrupts. + */ + +#ifdef CONFIG_STM32F0L0G0_GPIOIRQ + phy62xx_gpioirqinitialize(); +#endif + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + + /* And finally, enable interrupts */ + + irq_attach(PHY62XX_IRQ_BB_IRQn, LL_IRQHandler1, NULL); + irq_attach(PHY62XX_IRQ_TIM1_IRQn, TIM1_IRQHandler1, NULL); + irq_attach(PHY62XX_IRQ_TIM3_IRQn, TIM3_IRQHandler1, NULL); + irq_priority((IRQn_Type)BB_IRQn, IRQ_PRIO_REALTIME); + irq_priority((IRQn_Type)TIM1_IRQn, IRQ_PRIO_HIGH); //ll_EVT + irq_priority((IRQn_Type)TIM2_IRQn, IRQ_PRIO_HIGH); //OSAL_TICK + irq_priority((IRQn_Type)TIM3_IRQn, IRQ_PRIO_APP); //OSAL_TICK + irq_priority((IRQn_Type)TIM4_IRQn, IRQ_PRIO_HIGH); //LL_EXA_ADV + NVIC_EnableIRQ((IRQn_Type)BB_IRQn); + NVIC_EnableIRQ((IRQn_Type)TIM1_IRQn); //ll_EVT + //NVIC_EnableIRQ((IRQn_Type)TIM2_IRQn); //OSAL_TICK + NVIC_EnableIRQ((IRQn_Type)TIM3_IRQn); // + //NVIC_EnableIRQ((IRQn_Type)TIM4_IRQn); //LL_EXA_ADV + //svc(SVC_CALL_WR); + up_irq_enable(); + + + + + +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + DEBUGASSERT((unsigned)irq < NR_IRQS); + + /* Check for an external interrupt */ + + if (irq >= PHY62XX_IRQ_EXTINT && irq < (PHY62XX_IRQ_EXTINT + 32)) + { + /* Set the appropriate bit in the ICER register to disable the + * interrupt + */ + + putreg32((1 << (irq - PHY62XX_IRQ_EXTINT)), ARMV6M_NVIC_ICER); + } + + /* Handle processor exceptions. Only SysTick can be disabled */ + + else if (irq == PHY62XX_IRQ_SYSTICK) + { + modifyreg32(ARMV6M_SYSTICK_CSR, SYSTICK_CSR_ENABLE, 0); + } + + phy62xx_dumpnvic("disable", irq); +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + /* This will be called on each interrupt exit whether the interrupt can be + * enabled or not. So this assertion is necessarily lame. + */ + + DEBUGASSERT((unsigned)irq < NR_IRQS); + + /* Check for external interrupt */ + + if (irq >= PHY62XX_IRQ_EXTINT && irq < (PHY62XX_IRQ_EXTINT + 32)) + { + /* Set the appropriate bit in the ISER register to enable the + * interrupt + */ + + putreg32((1 << (irq - PHY62XX_IRQ_EXTINT)), ARMV6M_NVIC_ISER); + } + + /* Handle processor exceptions. Only SysTick can be disabled */ + + else if (irq == PHY62XX_IRQ_SYSTICK) + { + modifyreg32(ARMV6M_SYSTICK_CSR, 0, SYSTICK_CSR_ENABLE); + } + + phy62xx_dumpnvic("enable", irq); +} + +/**************************************************************************** + * Name: arm_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void arm_ack_irq(int irq) +{ + phy62xx_clrpend(irq); +} diff --git a/arch/arm/src/phy62xx/jump_function.h b/arch/arm/src/phy62xx/jump_function.h new file mode 100644 index 00000000000..af7a27883bd --- /dev/null +++ b/arch/arm/src/phy62xx/jump_function.h @@ -0,0 +1,618 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/** + **************************************************************************************** + + @file jump_fucntion.h + + @brief This file contains the definitions of the macros and functions that are + architecture dependent. The implementation of those is implemented in the + appropriate architecture directory. + + + $Rev: $ + + **************************************************************************************** +*/ + + +#ifndef _JUMP_FUNC_H_ +#define _JUMP_FUNC_H_ +#include +#include "types.h" +#include "ll_def.h" +#include "ll_sleep.h" + +#include "hci.h" +#include "l2cap.h" + +// ===================== MACROS ======================= +#define JUMP_BASE_ADDR 0x1fff0000 +#define JUMP_FUNCTION(x) (*(uint32 *)(JUMP_BASE_ADDR + (x << 2))) + +// ROM function entries + + +// 0 - 10 for common +#define OSAL_INIT_TASKS 1 +#define TASKS_ARRAY 2 +#define TASK_COUNT 3 +#define TASK_EVENTS 4 +#define OSAL_MEM_INIT 5 + +#define LL_INIT 11 +#define LL_PROCESS_EVENT 12 +#define LL_RESET 13 +#define LL_TXDATA 14 +#define LL_DISCONNECT 15 +#define LL_SET_ADV_PARAM 16 +#define LL_SET_ADV_DATA 17 +#define LL_SET_ADV_CONTROL 18 +#define LL_SET_DEFAULT_CONN_PARAM 19 + +#define LL_EXT_SET_TX_POWER 20 + +#define LL_CLEAR_WHITE_LIST 21 +#define LL_ADD_WHITE_LIST_DEV 22 +#define LL_REMOVE_WHITE_LIST_DEV 23 +#define LL_READ_WHITE_LIST_SIZE 24 +#define LL_NUM_EMPTY_WL_ENTRIES 25 + +#define LL_SLAVE_EVT_ENDOK 26 +#define LL_SETUP_NEXT_SLAVE_EVT 27 +#define LL_CHK_LSTO_DURING_SL 28 +#define LL_PROCESS_SLAVE_CTRL_PROC 29 + +#define LL_PROCESS_SLAVE_CTRL_PKT 30 +#define LL_SLAVE_EVT_ABORT 31 +#define LL_PROCESS_RX_DATA 32 +#define LL_PROCESS_TX_DATA 33 +#define LL_CONN_TERMINATE 34 +#define LL_WRITE_TX_DATA 35 + +#define LL_EVT_SCHEDULE 36 +#define LL_MOVE_TO_SLAVE_FUNCTION 37 +#define LL_SLAVE_CONN_EVENT 38 + +#define LL_SETUP_ADV 39 + +#define LL_SETUP_UNDIRECT_ADV 40 +#define LL_SETUP_NOCONN_ADV 41 + +#define LL_SETUP_SCAN_ADV 42 +#define LL_SETUP_DIRECT_ADV 43 + +#define LL_CALC_TIMER_DRIFT 44 +#define LL_GENERATE_TX_BUFFER 45 +#define LL_READ_RX_FIFO 46 +#define LL_READ_TX_FIFO_RTLP 47 +#define LL_READ_TX_FIFO_PKT 48 + +#define LL_HW_PROCESS_RTO 49 + +#define LL_HW_SET_TIMING 50 +#define LL_RELEASE_CONN_ID 51 + +#define LL_READ_TX_PWR_LVL 52 // A1 ROM metal change add +#define LL_READ_ADV_TX_PWR_LVL 53 // A1 ROM metal change add +#define LL_READ_RSSI 54 // A1 ROM metal change add +#define LL_READ_REMOTE_USE_FEATURES 55 // A1 ROM metal change add +#define LL_ENCRYPT 56 // A1 ROM metal change add + +#define LL_DIRECT_TEST_END 57 // A1 ROM metal change add +#define LL_DIRECT_TEST_TX_TEST 58 // A1 ROM metal change add +#define LL_DIRECT_TEST_RX_TEST 59 // A1 ROM metal change add + +#define OSAL_POWER_CONSERVE 60 +#define ENTER_SLEEP_PROCESS 61 +#define WAKEUP_PROCESS 62 +#define CONFIG_RTC 63 +#define ENTER_SLEEP_OFF_MODE 64 // A1 ROM metal change add + +#define HAL_PROCESS_POLL 65 // A1 ROM metal change add +#define LL_HW_GO 66 // A1 ROM metal change add +#define LL_HW_TRIGGER 67 // A1 ROM metal change add +#define LL_SET_TX_PWR_LVL 68 // A1 ROM metal change add + +// LL AES +#define LL_AES128_ENCRYPT 70 // A1 ROM metal change add +#define LL_GEN_TRUE_RANDOM 71 // A1 ROM metal change add +#define LL_GEN_DEVICE_SKD 72 // A1 ROM metal change add +#define LL_GEN_DEVICE_IV 73 // A1 ROM metal change add +#define LL_GENERATE_NOUNCE 74 // A1 ROM metal change add +#define LL_ENC_ENCRYPT 75 // A1 ROM metal change add +#define LL_ENC_DECRYPT 76 // A1 ROM metal change add + +// host entries +#define SMP_INIT 80 +#define SMP_PROCESS_EVENT 81 + +// l2cap entries +#define L2CAP_PARSE_PACKET 82 +#define L2CAP_ENCAP_PACKET 83 +#define L2CAP_PKT_TO_SEGBUFF 84 +#define L2CAP_SEGBUFF_TO_LINKLAYER 85 +#define L2CAP_PROCESS_FREGMENT_TX_DATA 86 + +//gap linkmgr entries +#define GAP_LINK_MGR_PROCESS_CONNECT_EVT 87 +#define GAP_LINK_MGR_PROCESS_DISCONNECT_EVT 88 + +// hci tl +#define HCI_INIT 90 // A1 ROM metal change add +#define HCI_PROCESS_EVENT 91 // A1 ROM metal change add + + + +// app entries +#define APP_SLEEP_PROCESS 100 +#define APP_WAKEUP_PROCESS 101 +#define RF_INIT 102 +#define WAKEUP_INIT 103 +#define BOOT_INIT 104 +#define DEBUG_PRINT 105 +#define RF_CALIBRATTE 106 // A1 ROM metal change add +#define RF_PHY_CHANGE 107 // A1 ROM metal change add + +// LL master, A2 ROM metal change add +#define LL_MASTER_EVT_ENDOK 110 +#define LL_SETUP_NEXT_MASTER_EVT 111 +#define LL_PROCESS_MASTER_CTRL_PROC 112 +#define LL_PROCESS_MASTER_CTRL_PKT 113 +#define LL_MOVE_TO_MASTER_FUNCTION 114 +#define LL_MASTER_CONN_EVENT 115 + +#define LL_SET_SCAN_CTRL 116 +#define LL_SET_SCAN_PARAM 117 + +#define LL_CREATE_CONN 118 +#define LL_CREATE_CONN_CANCEL 119 + +#define LL_START_ENCRYPT 120 + +#define LL_SETUP_SCAN 121 + +#define LL_SETUP_SEC_NOCONN_ADV 122 +#define LL_SETUP_SEC_SCAN 123 +#define LL_SEC_ADV_ALLOW 124 +#define LL_CALC_MAX_SCAN_TIME 125 + +// A2 multi-connection +#define LL_SETUP_SEC_ADV_ENTRY 126 +#define LL_SETUP_SEC_CONN_ADV 127 +#define LL_SETUP_SEC_SCANNABLE_ADV 128 + + + + +//DLE +#define LL_SET_DATA_LENGTH 130 +#define LL_PDU_LENGTH_UPDATE 131 +#define LL_TRX_NUM_ADJUST 132 +//PHY UPDATE +#define LL_SET_PHY_MODE 133 +#define LL_PHY_MODE_UPDATE 134 +#define LL_SET_NEXT_PHY_MODE 135 + +#define LL_ADP_ADJ_NEXT_TIME 136 +#define LL_ADP_SMART_WINDOW 137 +#define LL_SET_NEXT_DATA_CHN 138 +#define LL_PLUS_DISABLE_LATENCY 139 +#define LL_PLUS_ENABLE_LATENCY 140 + +#define LL_SETUP_EXT_ADV_EVENT 141 +#define LL_SETUP_PRD_ADV_EVENT 142 +#define LL_SETUP_ADV_EXT_IND_PDU 143 +#define LL_SETUP_AUX_ADV_IND_PDU 144 +#define LL_SETUP_AUX_SYNC_IND_PDU 145 +#define LL_SETUP_AUX_CHAIN_IND_PDU 146 +#define LL_SETUP_AUX_CONN_REQ_PDU 147 +#define LL_SETUP_AUX_CONN_RSP_PDU 148 + +#define LL_SCHEDULER 149 +#define LL_ADD_TASK 150 +#define LL_DEL_TASK 151 + +#define LL_ADV_SCHEDULER 152 +#define LL_ADV_ADD_TASK 153 +#define LL_ADV_DEL_TASK 154 + +#define LL_ADV_SCHEDULER_PRD 155 +#define LL_ADV_ADD_TASK_PRD 156 +#define LL_ADV_DEL_TASK_PRD 157 + +#define LL_GET_NEXT_AUX_CHN 158 +#define LL_SETUP_AUX_SCAN_RSP_PDU 159 + +#define LL_PROCESSBASICIRQ_SRX 160 +#define LL_PROCESSBASICIRQ_SECADVTRX 161 +#define LL_PROCESSBASICIRQ_SCANTRX 162 + +// 2020-02-13 Add for CTE +#define LL_CONNLESS_CTE_TX_PARAM 203 +#define LL_CONNLESS_CTE_TX_ENABLE 204 +#define LL_CONNLESS_IQ_SAMPLE_ENABLE 205 +#define LL_CONN_CTE_RECV_PARAM 206 +#define LL_CONN_CTE_REQ_EN 207 +#define LL_CONN_CTE_TX_PARAM 208 +#define LL_CONN_CTE_RSP_EN 209 + +//OSAL +#define OSAL_SET_EVENT 210 +#define OSAL_MSG_SEND 211 +#define HAL_DRV_IRQ_INIT 212 +#define HAL_DRV_IRQ_ENABLE 213 +#define HAL_DRV_IRQ_DISABLE 214 + +// interrupt request handler +#define NMI_HANDLER 219 +#define HARDFAULT_HANDLER 220 +#define SVC_HANDLER 221 +#define PENDSV_HANDLER 222 +#define SYSTICK_HANDLER 223 + +#define V0_IRQ_HANDLER 224 +#define V1_IRQ_HANDLER 225 +#define V2_IRQ_HANDLER 226 +#define V3_IRQ_HANDLER 227 +#define V4_IRQ_HANDLER 228 +#define V5_IRQ_HANDLER 229 +#define V6_IRQ_HANDLER 230 +#define V7_IRQ_HANDLER 231 +#define V8_IRQ_HANDLER 232 +#define V9_IRQ_HANDLER 233 +#define V10_IRQ_HANDLER 234 +#define V11_IRQ_HANDLER 235 +#define V12_IRQ_HANDLER 236 +#define V13_IRQ_HANDLER 237 +#define V14_IRQ_HANDLER 238 +#define V15_IRQ_HANDLER 239 +#define V16_IRQ_HANDLER 240 +#define V17_IRQ_HANDLER 241 +#define V18_IRQ_HANDLER 242 +#define V19_IRQ_HANDLER 243 +#define V20_IRQ_HANDLER 244 +#define V21_IRQ_HANDLER 245 +#define V22_IRQ_HANDLER 246 +#define V23_IRQ_HANDLER 247 +#define V24_IRQ_HANDLER 248 +#define V25_IRQ_HANDLER 249 +#define V26_IRQ_HANDLER 250 +#define V27_IRQ_HANDLER 251 +#define V28_IRQ_HANDLER 252 +#define V29_IRQ_HANDLER 253 +#define V30_IRQ_HANDLER 254 +#define V31_IRQ_HANDLER 255 + +// ================== FUNCTIONS ================================== +void move_to_slave_function0(void); +void LL_slave_conn_event0(void); +llStatus_t llSetupAdv0(void); +void llSetupUndirectedAdvEvt0(void); +void llSetupNonConnectableAdvEvt0( void ); +void llSetupScannableAdvEvt0( void ); +void llSetupDirectedAdvEvt0( void ); +void LL_evt_schedule0(void); + +void llCalcTimerDrift0( uint32 connInterval, + uint16 slaveLatency, + uint8 sleepClkAccuracy, + uint32* timerDrift ) ; + +uint16 ll_generateTxBuffer0(int txFifo_vacancy, uint16* pSave_ptr); + +void ll_hw_read_tfifo_rtlp0(void); + +void ll_read_rxfifo0(void); + +int ll_hw_read_tfifo_packet0(uint8* pkt); + +void ll_hw_process_RTO0(uint32 ack_num); + +void LL_set_default_conn_params0(llConnState_t* connPtr); + +// ===== +void enterSleepProcess0(uint32 time); + +void wakeupProcess0(void); + +void config_RTC0(uint32 time); + +void enter_sleep_off_mode0(Sleep_Mode mode); + +void llSlaveEvt_TaskEndOk0( void ); + +uint8 llSetupNextSlaveEvent0( void ); + +uint8 llCheckForLstoDuringSL0( llConnState_t* connPtr ); + +uint8 llProcessSlaveControlProcedures0( llConnState_t* connPtr ); + +void llProcessSlaveControlPacket0( llConnState_t* connPtr, + uint8* pBuf ); + +void llSlaveEvt_TaskAbort0(void ); + +// ------ +void llMasterEvt_TaskEndOk0( void ); +void llProcessMasterControlPacket0( llConnState_t* connPtr, + uint8* pBuf ); +uint8 llProcessMasterControlProcedures0( llConnState_t* connPtr ); +uint8 llSetupNextMasterEvent0( void ); + +void move_to_master_function0(void); +void LL_master_conn_event0(void); + +llStatus_t LL_SetScanControl0( uint8 scanMode, + uint8 filterReports ); +llStatus_t LL_SetScanParam0( uint8 scanType, + uint16 scanInterval, + uint16 scanWindow, + uint8 ownAddrType, + uint8 scanWlPolicy ); + +llStatus_t LL_CreateConn0( uint16 scanInterval, + uint16 scanWindow, + uint8 initWlPolicy, + uint8 peerAddrType, + uint8* peerAddr, + uint8 ownAddrType, + uint16 connIntervalMin, + uint16 connIntervalMax, + uint16 connLatency, + uint16 connTimeout, + uint16 minLength, + uint16 maxLength ); +llStatus_t LL_CreateConnCancel0( void ); + +llStatus_t LL_StartEncrypt0( uint16 connId, + uint8* rand, + uint8* eDiv, + uint8* ltk ); + +void llSetupScan0( uint8 chan ); + +// ================== ll.c +void LL_Init0( uint8 taskId ); +uint16 LL_ProcessEvent0( uint8 task_id, uint16 events ); +llStatus_t LL_Reset0( void ); +llStatus_t LL_TxData0( uint16 connId, uint8* pBuf, uint8 pktLen, uint8 fragFlag ); +llStatus_t LL_Disconnect0( uint16 connId, uint8 reason ); +llStatus_t LL_SetAdvParam0( uint16 advIntervalMin, + uint16 advIntervalMax, + uint8 advEvtType, + uint8 ownAddrType, + uint8 directAddrType, + uint8* directAddr, + uint8 advChanMap, + uint8 advWlPolicy ); +llStatus_t LL_SetAdvData0( uint8 advDataLen, uint8* advData ); +llStatus_t LL_SetAdvControl0( uint8 advMode ); + +llStatus_t LL_EXT_SetTxPower0( uint8 txPower, uint8* cmdComplete ); + +llStatus_t LL_ClearWhiteList0( void ); +llStatus_t LL_AddWhiteListDevice0( uint8* devAddr, uint8 addrType ); +llStatus_t LL_RemoveWhiteListDevice0( uint8* devAddr, uint8 addrType ); +llStatus_t LL_ReadWlSize0( uint8* numEntries ); +llStatus_t LL_ReadTxPowerLevel0( uint8 connId, uint8 type, int8* txPower ); +llStatus_t LL_SetTxPowerLevel0( int8 txPower ); +llStatus_t LL_ReadAdvChanTxPower0( int8* txPower ); +llStatus_t LL_ReadRssi0( uint16 connId, int8* lastRssi ); +llStatus_t LL_ReadRemoteUsedFeatures0( uint16 connId ); +llStatus_t LL_Encrypt0( uint8* key, uint8* plaintextData, uint8* encryptedData ); + +llStatus_t LL_DirectTestEnd0( void ); +llStatus_t LL_DirectTestTxTest0( uint8 txFreq, uint8 payloadLen, uint8 payloadType ); +llStatus_t LL_DirectTestRxTest0( uint8 rxFreq ); + +// ================ ll_common.c +void llProcessTxData0( llConnState_t* connPtr, uint8 context ); +uint8 llProcessRxData0( void ); +uint8 llWriteTxData0( llConnState_t* connPtr, + uint8 pktHdr, + uint8 pktLen, + uint8* pBuf ); +void llConnTerminate0( llConnState_t* connPtr, uint8 reason ); +void llReleaseConnId0( llConnState_t* connPtr ); + +// ================ ll_enc.c +void LL_ENC_AES128_Encrypt0( uint8* key, + uint8* plaintext, + uint8* ciphertext ); +uint8 LL_ENC_GenerateTrueRandNum0( uint8* buf, + uint8 len ); +void LL_ENC_GenDeviceSKD0( uint8* SKD ); +void LL_ENC_GenDeviceIV0( uint8* IV ); +void LL_ENC_GenerateNonce0( uint32 pktCnt, + uint8 direction, + uint8* nonce ); +void LL_ENC_Encrypt0( llConnState_t* connPtr, + uint8 pktHdr, + uint8 pktLen, + uint8* pBuf ); +uint8 LL_ENC_Decrypt0( llConnState_t* connPtr, + uint8 pktHdr, + uint8 pktLen, + uint8* pBuf ); + +// =================== osal +void osal_pwrmgr_powerconserve0( void ) ; + +// =================== ll_hw_drv.c +void ll_hw_set_timing0(uint8 pktFmt); +void ll_hw_go0(void); +void ll_hw_trigger0(void); + +// ================== SMP functions +void SM_Init0( uint8 task_id ); +uint16 SM_ProcessEvent0( uint8 task_id, uint16 events ); + +// ================== HCI_TL functions +void HCI_Init0( uint8 task_id ); +uint16 HCI_ProcessEvent0( uint8 task_id, uint16 events ); + + +// ======= OSAL memory +void osal_mem_init0(void); + +// =========== ROM -> APP function +void app_sleep_process(void); + +void app_wakeup_process(void); + +void rf_init(void); + +void boot_init0(void); + +void wakeup_init0(void); + +void debug_print(uint32 state); + +void rf_calibrate0(void); + +void rf_phy_change_cfg(uint8 pktFmt); + +// ========== A2, for conn-adv, conn-scan +uint8 llSetupSecNonConnectableAdvEvt0( void ); +uint8 llSecAdvAllow0(void); +uint32 llCalcMaxScanTime0(void); +void llSetupSecScan0( uint8 chan ); + +uint8 llSetupSecAdvEvt0( void ); +uint8 llSetupSecConnectableAdvEvt0( void ); +uint8 llSetupSecScannableAdvEvt0( void ); + + + +//=============== gap_linkmgr.c +void gapProcessDisconnectCompleteEvt0( hciEvt_DisconnComplete_t* pPkt ); +void gapProcessConnectionCompleteEvt0( hciEvt_BLEConnComplete_t* pPkt ); + + +//=============== l2cap_util.c +uint8 l2capParsePacket0( l2capPacket_t* pPkt, hciDataEvent_t* pHciMsg ); +uint8 l2capEncapSendData0( uint16 connHandle, l2capPacket_t* pPkt ); +uint8 l2capPktToSegmentBuff0(uint16 connHandle, l2capSegmentBuff_t* pSegBuf, uint8 blen,uint8* pBuf); +void l2capPocessFragmentTxData0(uint16 connHandle); +uint8 l2capSegmentBuffToLinkLayer0(uint16 connHandle, l2capSegmentBuff_t* pSegBuf); +void l2capPocessFragmentTxData0(uint16 connHandle); + +//=============== DLE +llStatus_t LL_SetDataLengh0( uint16 connId,uint16 TxOctets,uint16 TxTime ); +void llPduLengthUpdate0(uint16 connHandle); +void llTrxNumAdaptiveConfig0(void); + +//===============LL ADJ WINDOW +void ll_adptive_adj_next_time0(uint32 nextTime); +void ll_adptive_smart_window0(uint32 irq_status,uint32 anchor_point); +void llSetNextDataChan0( llConnState_t* connPtr ); + +//=============== PHY UPDATE +llStatus_t LL_SetPhyMode0( uint16 connId,uint8 allPhy,uint8 txPhy, uint8 rxPhy,uint16 phyOptions); +llStatus_t LL_PhyUpdate0( uint16 connId ); +void llSetNextPhyMode0( llConnState_t* connPtr ); + +llStatus_t LL_PLUS_DisableSlaveLatency0(uint8 connId); +llStatus_t LL_PLUS_EnableSlaveLatency0(uint8 connId); + +// ================= BBB +void ll_scheduler0(uint32 time); +void ll_addTask0(uint8 connId, uint32 time); +void ll_deleteTask0(uint8 connId); + +void ll_adv_scheduler0(void); +void ll_add_adv_task0(extAdvInfo_t* pExtAdv); +void ll_delete_adv_task0(uint8 index); + +void ll_adv_scheduler_periodic0(void); +void ll_add_adv_task_periodic0(periodicAdvInfo_t* pPrdAdv, extAdvInfo_t* pExtAdv); +void ll_delete_adv_task_periodic0(uint8 index); +uint8 llSetupExtAdvEvent0(extAdvInfo_t* pAdvInfo); +uint8 llSetupPrdAdvEvent0(periodicAdvInfo_t* pPrdAdv, extAdvInfo_t* pExtAdv); + +void llSetupAdvExtIndPDU0(extAdvInfo_t* pAdvInfo, periodicAdvInfo_t* pPrdAdv); +void llSetupAuxAdvIndPDU0(extAdvInfo_t* pAdvInfo, periodicAdvInfo_t* pPrdAdv); +void llSetupAuxChainIndPDU0(extAdvInfo_t* pAdvInfo, periodicAdvInfo_t* pPrdAdv); +void llSetupAuxSyncIndPDU0(extAdvInfo_t* pAdvInfo, periodicAdvInfo_t* pPrdAdv); +void llSetupAuxConnectReqPDU0(void); +void llSetupAuxScanRspPDU0(extAdvInfo_t* pAdvInfo); +void llSetupAuxConnectRspPDU0(extAdvInfo_t* pAdvInfo); + +uint8 llGetNextAuxAdvChn0(uint8 current); + + +//=============== OSAL +uint8 osal_set_event0( uint8 task_id, uint16 event_flag ); +uint8 osal_msg_send0( uint8 destination_task, uint8* msg_ptr ); + +//=============== _HAL_IRQ_ +void drv_irq_init0(void); +int drv_enable_irq0(void); +int drv_disable_irq0(void); + +// 2020-02-13 cte jumpfunction +llStatus_t LL_ConnectionlessCTE_TransmitParam0( uint8 advertising_handle, + uint8 len, + uint8 type, + uint8 count, + uint8 Pattern_LEN, + uint8* AnaIDs); + +llStatus_t LL_ConnectionlessCTE_TransmitEnable0( uint8 advertising_handle,uint8 enable); +llStatus_t LL_ConnectionlessIQ_SampleEnable0( uint16 sync_handle, + uint8 enable, + uint8 slot_Duration, + uint8 MaxSampledCTEs, + uint8 pattern_len, + uint8* AnaIDs); +llStatus_t LL_Set_ConnectionCTE_ReceiveParam0( uint16 connHandle, + uint8 enable, + uint8 slot_Duration, + uint8 pattern_len, + uint8* AnaIDs); +llStatus_t LL_Connection_CTE_Request_Enable0( uint16 connHandle, + uint8 enable, + uint16 Interval, + uint8 len, + uint8 type); + +llStatus_t LL_Set_ConnectionCTE_TransmitParam0( uint16 connHandle, + uint8 type, + uint8 pattern_len, + uint8* AnaIDs); + +llStatus_t LL_Connection_CTE_Response_Enable0( uint16 connHandle,uint8 enable); + + +#endif // _JUMP_FUNC_H_ diff --git a/arch/arm/src/phy62xx/jump_table.c b/arch/arm/src/phy62xx/jump_table.c new file mode 100644 index 00000000000..cfc0afe2bb3 --- /dev/null +++ b/arch/arm/src/phy62xx/jump_table.c @@ -0,0 +1,142 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + + +/************************************************************************************************** + Filename: jump_table.c + Revised: + Revision: + + Description: Jump table that holds function pointers and veriables used in ROM code. + + +**************************************************************************************************/ + +/******************************************************************************* + * INCLUDES + */ + + +/******************************************************************************* + * MACROS + */ +typedef unsigned int uint32_t; +#define LOG +static void hard_fault(void) +{ + + while(1){ + ; + } +} + +/******************************************************************************* + * ANTS + */ +// jump table, this table save the function entry which will be called by ROM code +// item 1 - 4 for OSAL task entry +// item 224 - 255 for ISR(Interrupt Service Routine) entry +// others are reserved by ROM code +uint32_t* jump_table_base[256] __attribute__((section(".jumptbls"))) = +{ + ( uint32_t*)0, // 0. write Log + ( uint32_t*)0, // 1. init entry of app + ( uint32_t*)0, // 2. task list + ( uint32_t*)0, // 3. task count + ( uint32_t*)0, // 4. task events + 0, 0, 0, 0, 0, // 5 - 9, reserved by phyplus + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10 - 19, reserved by phyplus + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 - 29, reserved by phyplus + 0, 0, 0, 0, 0, 0, 0, 0, // <30 - - 37> + 0, 0, + 0, 0, 0, 0, 0, 0, //40 - 45 + 0, 0, 0, 0, //46 - 49 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 50 - 59, reserved by phyplus + 0, // < 60 - + 0, + 0, + 0, + 0, 0, 0, 0, 0, 0, // -69>, reserved by phyplus + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 70 -79, reserved by phyplus + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80 - 89, reserved by phyplus + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 90 - 99, reserved by phyplus + ( uint32_t*)0, // <100 - + ( uint32_t*)0, + ( uint32_t*)0, + 0, + 0, + 0, + 0, 0, 0, 0, // - 109, reserved by phyplus + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 110 -119, reserved by phyplus + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 120 -129, reserved by phyplus + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 130 -139, reserved by phyplus + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 140 -149, reserved by phyplus + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 150 -159, reserved by phyplus + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 160 -169, reserved by phyplus + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 170 -179, reserved by phyplus + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 180 -189, reserved by phyplus + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 190 -199, reserved by phyplus + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 200 - 209, reserved by phyplus + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 210 - 219, reserved by phyplus + ( uint32_t*)0, 0, 0, 0, 0, 0, ( uint32_t*)1234, 0, // 220 - 227 + 0, + ( uint32_t*)0, // 228 - 229 + 0, 0, 0, ( uint32_t*)0, 0, // 230 - 234 + ( uint32_t*)0, // 235 uart irq handler + ( uint32_t*)0, + ( uint32_t*)0, + ( uint32_t*)1122, + ( uint32_t*)0, // 236 - 239 + ( uint32_t*)0x67656961, //240 gpio interrupt handler + 0, 0, 0, 0, 0, 0, 0, 0, 0, // 241 - 249, for ISR entry + 0, 0, 0, ( uint32_t*)0, 0, 0 // 250 - 255, for ISR entry +}; + + + +/******************************************************************************* + * Prototypes + */ + + +/******************************************************************************* + * LOCAL VARIABLES + */ + + +/********************************************************************* + * EXTERNAL VARIABLES + */ +//uint32_t global_config[256] __attribute__((section(".gcfgtbls")))={0}; + + + diff --git a/arch/arm/src/phy62xx/log.h b/arch/arm/src/phy62xx/log.h new file mode 100644 index 00000000000..c72a5530ddc --- /dev/null +++ b/arch/arm/src/phy62xx/log.h @@ -0,0 +1,149 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/******************************************************************************* + @file log.h + @brief Contains all functions support for uart driver + @version 0.0 + @date 31. Jan. 2018 + @author eagle.han + + + +*******************************************************************************/ +#ifndef ENABLE_LOG_ROM +#ifndef __LOG_H__ +#define __LOG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "uart.h" +void dbg_printf_(const char* format, ...); +void dbg_printf_init(void); +void my_dump_byte(uint8_t* pData, int dlen); +#ifndef DEBUG_INFO +#error "DEBUG_INFO undefined!" +#endif +typedef void(*std_putc)(char* data, uint16_t size); + +#if 0 + #if(DEBUG_INFO == 1) + #define AT_LOG(...) + #define LOG_DEBUG(...) + #define LOG(...) dbg_printf_(__VA_ARGS__) + #define LOG_INIT() dbg_printf_init() + #define LOG_DUMP_BYTE(a,b) my_dump_byte(a,b) + #elif(DEBUG_INFO == 2) + + #define AT_LOG(...) dbg_printf_(__VA_ARGS__) + #define LOG_DEBUG(...) dbg_printf_(__VA_ARGS__) + #define LOG(...) + #define LOG_INIT() dbg_printf_init() + #define LOG_DUMP_BYTE(a,b) my_dump_byte(a,b) + #elif(DEBUG_INFO == 3) + #define LOG(...) dbg_printf_(__VA_ARGS__) + #define AT_LOG(...) dbg_printf_(__VA_ARGS__) + #define LOG_DEBUG(...) dbg_printf_(__VA_ARGS__) + #define LOG_INIT() dbg_printf_init() + #define LOG_DUMP_BYTE(a,b) my_dump_byte(a,b) + #else + + #endif +#else +#define AT_LOG(...) +#define LOG_DEBUG(...) +#define LOG(...) +#define LOG_INIT() //{clk_gate_enable(MOD_UART);clk_reset(MOD_UART);clk_gate_disable(MOD_UART);} +#define LOG_DUMP_BYTE(a,b) +#define LOG_BLE(...) printf(__VA_ARGS__) +#endif + +#ifdef __cplusplus +} +#endif + +#endif //__LOG_H__ + +#else + +#ifndef __PHY_LOG_H +#define __PHY_LOG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "types.h" +#include "uart.h" +#include +#include + +#define LOG_LEVEL_NONE 0 //no log output*/ +#define LOG_LEVEL_ERROR 1 //only log error*/ +#define LOG_LEVEL_DEBUG 2 //output debug info and error info*/ +#define LOG_LEVEL_LOG 3 //output all infomation*/ + +#define LOG_INIT() {hal_uart_init(115200,P9,P10,NULL);} + +#if 0//DEBUG_FPGA +#define LOG(...) do{;}while(0); +#else + +//conditional output +#define LOG(...) {if(s_rom_debug_level == LOG_LEVEL_LOG) log_printf(__VA_ARGS__);} +#define LOG_DEBUG(...) {if(s_rom_debug_level >= LOG_LEVEL_DEBUG) log_printf(__VA_ARGS__);} +#define LOG_ERROR(...) {if(s_rom_debug_level >= LOG_LEVEL_ERROR) log_printf(__VA_ARGS__);} + +//tx data anyway +#define PRINT(...) {SWU_TX(); log_printf(__VA_ARGS__);} +#endif + +extern volatile uint32_t s_rom_debug_level; + +typedef void(*std_putc)(char* data, int size); + +void log_vsprintf(std_putc putc, const char* fmt, va_list args); +void log_printf(const char* format, ...); +void log_set_putc(std_putc putc); +void log_clr_putc(std_putc putc); +int log_debug_level(uint8_t level); +uint32_t log_get_debug_level(void); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/arch/arm/src/phy62xx/mcu.h b/arch/arm/src/phy62xx/mcu.h new file mode 100644 index 00000000000..127657bc0ac --- /dev/null +++ b/arch/arm/src/phy62xx/mcu.h @@ -0,0 +1,125 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/************************************************************************************************** + Filename: bus_dev.h + Revised: + Revision: + + Description: Describe the purpose and contents of the file. + + + +**************************************************************************************************/ + +#ifndef _HAL_MCU_H +#define _HAL_MCU_H + + + +/* ------------------------------------------------------------------------------------------------ + Includes + ------------------------------------------------------------------------------------------------ +*/ +#include "types.h" +#include +#include "rom_sym_def.h" + +//enum{ +// MCU_UNDEF = 0, +// MCU_PRIME_A1 = 1, +// MCU_PRIME_A2 = 2, +// MCU_BUMBEE_M0, +// MCU_BUMBEE_CK802 +//}; + +#define MCU_UNDEF 0 +#define MCU_PRIME_A1 1 +#define MCU_PRIME_A2 2 +#define MCU_BUMBEE_M0 3 +#define MCU_BUMBEE_CK802 4 + + +#define SRAM_BASE_ADDR 0x1fff0000 +#define SRAM_END_ADDR 0x1fffffff + +#define ROM_SRAM_JUMPTABLE SRAM_BASE_ADDR +#define ROM_SRAM_GLOBALCFG (ROM_SRAM_JUMPTABLE+0x400) +#define ROM_SRAM_JUMPTABLE_MIRROR 0x1fffd000 +#define ROM_SRAM_GLOBALCFG_MIRROR (ROM_SRAM_JUMPTABLE_MIRROR+0x400) + +#define ROM_SRAM_HEAP 0x1fffe000 +#define ROM_SRAM_HEAP_SIZE (1024*8) +#define ROM_SRAM_DWC_BUF 0x1ffffc00 + + +#define APP_SRAM_START_ADDR 0x1fff2000 + + +/* ------------------------------------------------------------------------------------------------ + Target Defines + ------------------------------------------------------------------------------------------------ +*/ + +#define MAXMEMHEAP 4096 + +#define HAL_ISER *((volatile uint32_t *)(0xe000e100)) +#define HAL_ICER *((volatile uint32_t *)(0xe000e180)) + +//subWriteReg: write value to register zone: bit[high:low] +#define subWriteReg(addr,high,low,value) write_reg(addr,read_reg(addr)&\ + (~((((unsigned int)1<<((high)-(low)+1))-1)<<(low)))|\ + ((unsigned int)(value)<<(low))) + +#define TIME_BASE (0x003fffff) // 24bit count shift 2 bit as 1us/bit +#define TIME_DELTA(x,y) ( (x>=y) ? x-y : TIME_BASE-y+x ) + + +extern void drv_irq_init(void); +extern int drv_enable_irq(void); +extern int drv_disable_irq(void); +#include +//extern irqstate_t up_irq_save(void); +//extern void up_irq_restore(irqstate_t flags); + +#define HAL_CRITICAL_SECTION_INIT() drv_irq_init() +//#define HAL_ENTER_CRITICAL_SECTION() //drv_disable_irq() +//#define HAL_EXIT_CRITICAL_SECTION() //drv_enable_irq() + +#define _HAL_CS_ALLOC_() uint32_t cs; +#define HAL_ENTER_CRITICAL_SECTION() cs = up_irq_save(); +#define HAL_EXIT_CRITICAL_SECTION() up_irq_restore(cs) + + +/************************************************************************************************** +*/ +#endif diff --git a/arch/arm/src/phy62xx/mcu_phy_bumbee.h b/arch/arm/src/phy62xx/mcu_phy_bumbee.h new file mode 100644 index 00000000000..12eec5d3f34 --- /dev/null +++ b/arch/arm/src/phy62xx/mcu_phy_bumbee.h @@ -0,0 +1,873 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ +#ifndef __MCU_BUMBEE_M0__ +#define __MCU_BUMBEE_M0__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "types.h" + +typedef enum +{ + MOD_NONE = 0, MOD_CK802_CPU = 0, + MOD_DMA = 3, + MOD_AES = 4, + MOD_IOMUX = 7, + MOD_UART0 = 8, + MOD_I2C0 = 9, + MOD_I2C1 = 10, + MOD_SPI0 = 11, + MOD_SPI1 = 12, + MOD_GPIO = 13, + MOD_QDEC = 15, + MOD_ADCC = 17, + MOD_PWM = 18, + MOD_SPIF = 19, + MOD_VOC = 20, + MOD_TIMER5 = 21, + MOD_TIMER6 = 22, + MOD_UART1 = 25, + + MOD_CP_CPU = 0+32, + MOD_BB = MOD_CP_CPU+3, + MOD_TIMER = MOD_CP_CPU+4, + MOD_WDT = MOD_CP_CPU+5, + MOD_COM = MOD_CP_CPU+6, + MOD_KSCAN = MOD_CP_CPU+7, + MOD_BBREG = MOD_CP_CPU+9, + BBLL_RST = MOD_CP_CPU+10,//can reset,but not gate in here + BBTX_RST = MOD_CP_CPU+11,//can reset,but not gate in here + BBRX_RST = MOD_CP_CPU+12,//can reset,but not gate in here + BBMIX_RST = MOD_CP_CPU+13,//can reset,but not gate in here + MOD_TIMER1 = MOD_CP_CPU+21, + MOD_TIMER2 = MOD_CP_CPU+22, + MOD_TIMER3 = MOD_CP_CPU+23, + MOD_TIMER4 = MOD_CP_CPU+24, + + MOD_PCLK_CACHE = 0+64, + MOD_HCLK_CACHE = MOD_PCLK_CACHE+1, + + MOD_USR0 = 0+96, + MOD_USR1 = MOD_USR0+1, + MOD_USR2 = MOD_USR0+2, + MOD_USR3 = MOD_USR0+3, + MOD_USR4 = MOD_USR0+4, + MOD_USR5 = MOD_USR0+5, + MOD_USR6 = MOD_USR0+6, + MOD_USR7 = MOD_USR0+7, + MOD_USR8 = MOD_USR0+8, + MOD_SYSTEM = 0xFF, +} MODULE_e; + +//SW_CLK -->0x4000f008 +#define _CLK_NONE (BIT(0)) +#define _CLK_CK802_CPU (BIT(0)) +#define _CLK_DMA (BIT(3)) +#define _CLK_AES (BIT(4)) +#define _CLK_IOMUX (BIT(7)) +#define _CLK_UART0 (BIT(8)) +#define _CLK_I2C0 (BIT(9)) +#define _CLK_I2C1 (BIT(10)) +#define _CLK_SPI0 (BIT(11)) +#define _CLK_SPI1 (BIT(12)) +#define _CLK_GPIO (BIT(13)) +#define _CLK_QDEC (BIT(15)) +#define _CLK_ADCC (BIT(17)) +#define _CLK_PWM (BIT(18)) +#define _CLK_SPIF (BIT(19)) +#define _CLK_VOC (BIT(20)) +#define _CLK_TIMER5 (BIT(21)) +#define _CLK_TIMER6 (BIT(22)) +#define _CLK_UART1 (BIT(25)) + + +//SW_CLK1 -->0x4000f014 +#define _CLK_M0_CPU (BIT(0)) +#define _CLK_BB (BIT(3)) +#define _CLK_TIMER (BIT(4)) +#define _CLK_WDT (BIT(5)) +#define _CLK_COM (BIT(6)) +#define _CLK_KSCAN (BIT(7)) +#define _CLK_BBREG (BIT(9)) +#define _CLK_TIMER1 (BIT(21)) +#define _CLK_TIMER2 (BIT(22)) +#define _CLK_TIMER3 (BIT(23)) +#define _CLK_TIMER4 (BIT(24)) + +#define BB_IRQ_HANDLER V4_IRQ_HANDLER +#define KSCAN_IRQ_HANDLER V5_IRQ_HANDLER +#define RTC_IRQ_HANDLER V6_IRQ_HANDLER +#define CP_COM_IRQ_HANDLER V7_IRQ_HANDLER +#define AP_COM_IRQ_HANDLER V8_IRQ_HANDLER +#define WDT_IRQ_HANDLER V10_IRQ_HANDLER +#define UART0_IRQ_HANDLER V11_IRQ_HANDLER +#define I2C0_IRQ_HANDLER V12_IRQ_HANDLER +#define I2C1_IRQ_HANDLER V13_IRQ_HANDLER +#define SPI0_IRQ_HANDLER V14_IRQ_HANDLER +#define SPI1_IRQ_HANDLER V15_IRQ_HANDLER +#define GPIO_IRQ_HANDLER V16_IRQ_HANDLER +#define UART1_IRQ_HANDLER V17_IRQ_HANDLER +#define SPIF_IRQ_HANDLER V18_IRQ_HANDLER +#define DMAC_IRQ_HANDLER V19_IRQ_HANDLER +#define TIM1_IRQ_HANDLER V20_IRQ_HANDLER +#define TIM2_IRQ_HANDLER V21_IRQ_HANDLER +#define TIM3_IRQ_HANDLER V22_IRQ_HANDLER +#define TIM4_IRQ_HANDLER V23_IRQ_HANDLER +#define TIM5_IRQ_HANDLER V24_IRQ_HANDLER +#define TIM6_IRQ_HANDLER V25_IRQ_HANDLER +#define AES_IRQ_HANDLER V28_IRQ_HANDLER +#define ADCC_IRQ_HANDLER V29_IRQ_HANDLER +#define QDEC_IRQ_HANDLER V30_IRQ_HANDLER + +/******************************************************************************* + TYPEDEFS +*/ +/******************************************************************************/ +/* Device Specific Peripheral registers structures */ +/******************************************************************************/ +typedef struct +{ + __IO uint32_t CH0_AP_MBOX; //0x00 + __IO uint32_t CH0_CP_MBOX; //0x04 + __IO uint32_t CH1_AP_MBOX; //0x08 + __IO uint32_t CH1_CP_MBOX; //0x0c + __IO uint32_t AP_STATUS; //0x10 + __IO uint32_t CP_STATUS; //0x14 + __IO uint32_t AP_INTEN; //0x18 + __IO uint32_t CP_INTEN; //0x1c + __IO uint32_t remap; //0x20 + __IO uint32_t RXEV_EN; //0x24 + __IO uint32_t STCALIB; //0x28 + __IO uint32_t PERI_MASTER_SELECT; //0x2c +} AP_COM_TypeDef; + +typedef struct +{ + __IO uint32_t CTRL0;//0x40 + __IO uint32_t CTRL1;//0x44 + uint32_t reserverd[13]; + __IO uint32_t REMAP_TABLE;//0x7c + __IO uint32_t REMAP_CTRL[32];//0x80 +} AP_CACHE_TypeDef; + +typedef struct +{ + __IO uint8_t CR; //0x0 + uint8_t RESERVED0[3]; + __IO uint32_t TORR; //0x4 + __O uint32_t CCVR; //0x8 + __IO uint32_t CRR; //0xc + uint8_t STAT; //0x10 + uint8_t reserverd1[3]; + __IO uint8_t EOI; //0x14 + uint8_t reserverd2[3]; +} AP_WDT_TypeDef; + + + +typedef struct +{ + __IO uint32_t SW_RESET0; //0x0 + __IO uint32_t SW_RESET1; //0x4 + __IO uint32_t SW_CLK; //0x8 + __IO uint32_t SW_RESET2; //0xc + __IO uint32_t SW_RESET3; //0x10 + __IO uint32_t SW_CLK1; //0x14 + __IO uint32_t APB_CLK; //0x18 + __IO uint32_t APB_CLK_UPDATE; //0x1c + __IO uint32_t CACHE_CLOCK_GATE;//0x20 + __IO uint32_t CACHE_RST;//0x24 + __IO uint32_t CACHE_BYPASS;//0x28 +} AP_PCR_TypeDef; + +typedef struct +{ + __IO uint32_t LoadCount; //0x0 + __IO uint32_t CurrentCount; //0x4 + __IO uint32_t ControlReg; //0x8 + __IO uint32_t EOI; //0xc + __IO uint32_t status; //0x10 + +} AP_TIM_TypeDef; + +typedef struct +{ + __IO uint32_t IntStatus; + __IO uint32_t EOI; + __IO uint32_t unMaskIntStatus; + __IO uint32_t version; +} AP_TIM_SYS_TypeDef; + + +#if defined ( __CC_ARM ) +#pragma anon_unions +#endif + +/*------------- Universal Asynchronous Receiver Transmitter (UARTx) -----------*/ + +typedef struct +{ + union + { + __I uint8_t RBR; + __IO uint8_t THR; + __IO uint8_t DLL; + uint32_t RESERVED0; //0x0 + }; + union + { + __IO uint8_t DLM; + __IO uint32_t IER; //0x4 + }; + union + { + __I uint32_t IIR; //0x8 + __IO uint8_t FCR; + }; + __IO uint8_t LCR; //0xc + uint8_t RESERVED1[3];//Reserved + __IO uint32_t MCR; //0x10 + + __I uint8_t LSR; //0x14 + uint8_t RESERVED2[3];//Reserved + __IO uint32_t MSR; //0x18 + + __IO uint8_t SCR; //0x1c + uint8_t RESERVED3[3];//Reserved + + __IO uint32_t LPDLL; //0x20 + + __IO uint32_t LPDLH; //0x24 + + __IO uint32_t recerved[2]; + + union + { + __IO uint32_t SRBR[16]; // 0x30~60xc + __IO uint32_t STHR[16]; + }; + __IO uint32_t rFAR; //0x70 + + __IO uint32_t TFR; //0x74 + + __IO uint32_t RFW; // 0x78 + + __IO uint32_t USR; // 0x7c + + __IO uint32_t TFL; + + __IO uint32_t RFL; + + __IO uint32_t SRR; + + __IO uint32_t SRTS; + + __IO uint32_t SBCR; + + __IO uint32_t SDMAM; + + __IO uint32_t SFE; + + __IO uint32_t SRT; + + __IO uint32_t STET; //0xa0 + + __IO uint32_t HTX; + + __IO uint32_t DMASA; //0xa8 + + __IO uint32_t reserved[18]; + + __IO uint32_t CPR; //0xf4 + + __IO uint32_t UCV; + + __IO uint32_t CTR; + +} AP_UART_TypeDef; + + +/*------------- Inter-Integrated Circuit (I2C) setup by zjp-------------------------------*/ +typedef struct +{ + __IO uint32_t IC_CON; + __IO uint32_t IC_TAR; + __IO uint32_t IC_SAR; + __IO uint32_t IC_HS_MADDR; + __IO uint32_t IC_DATA_CMD; //0x10 + __IO uint32_t IC_SS_SCL_HCNT; + __IO uint32_t IC_SS_SCL_LCNT; + __IO uint32_t IC_FS_SCL_HCNT; + __IO uint32_t IC_FS_SCL_LCNT; //0x20 + __IO uint32_t IC_HS_SCL_HCNT; + __IO uint32_t IC_HS_SCL_LCNT; + __IO uint32_t IC_INTR_STAT; + __IO uint32_t IC_INTR_MASK; //0x30 + __IO uint32_t IC_RAW_INTR_STAT; + __IO uint32_t IC_RX_TL; + __IO uint32_t IC_TX_TL; + __IO uint32_t IC_CLR_INTR; //0x40 + __IO uint32_t IC_CLR_UNDER; + __IO uint32_t IC_CLR_RX_OVER; + __IO uint32_t IC_CLR_TX_OVER; + __IO uint32_t IC_CLR_RD_REG; //0x50 + __IO uint32_t IC_CLR_TX_ABRT; + __IO uint32_t IC_CLR_RX_DONE; + __IO uint32_t IC_CLR_ACTIVITY; + __IO uint32_t IC_CLR_STOP_DET; //0x60 + __IO uint32_t IC_CLR_START_DET; + __IO uint32_t IC_CLR_GEN_CALL; + __IO uint32_t IC_ENABLE; + __IO uint32_t IC_STATUS; //0x70 + __IO uint32_t IC_TXFLR; + __IO uint32_t IC_RXFLR; + __IO uint32_t IC_SDA_HOLD; + __IO uint32_t IC_TX_ABRT_SOURCE; //0x80 + __IO uint32_t IC_SLV_DATA_NACK_ONLY; + __IO uint32_t IC_DMA_CR; + __IO uint32_t IC_DMA_TDLR; + __IO uint32_t IC_DMA_RDLR; //0x90 + __IO uint32_t IC_SDA_SETUP; + __IO uint32_t IC_ACK_GENERAL_CALL; + __IO uint32_t IC_ENABLE_STATUS; + __IO uint32_t IC_FS_SPKLEN; //0xa0 + __IO uint32_t IC_HS_SPKLEN; + +} AP_I2C_TypeDef; + + +/*------------- Inter IC Sound (I2S) -----------------------------------------*/ +typedef struct +{ + __IO uint32_t IER; + __IO uint32_t IRER; + __IO uint32_t ITER; + __IO uint32_t CER; + __IO uint32_t CCR; + __IO uint32_t RXFFR; + __IO uint32_t TXFFR; + +} AP_I2S_BLOCK_TypeDef; + +typedef struct +{ + union + { + __IO uint32_t LRBR; //0x20 + __IO uint32_t LTHR; //0x20 + }; + union + { + __IO uint32_t RRBR; // 0x24 + __IO uint32_t RTHR; //0x24 + }; + __IO uint32_t RER; //0x28 + __IO uint32_t TER; //0x2c + __IO uint32_t RCR; //0x30 + __IO uint32_t TCR; //0x34 + __IO uint32_t ISR; //0x38 + __IO uint32_t IMR; //0x3c + __IO uint32_t ROR; //0x40 + __IO uint32_t TOR; //0x44 + __IO uint32_t RFCR; //0x48 + __IO uint32_t TFCR; //0x4c + __IO uint32_t RFF; //0x50 + __IO uint32_t TFF; //0x54 + +} AP_I2S_TypeDef; + + +/*------------- General Purpose Input/Output (GPIO) --------------------------*/ +typedef struct +{ + __IO uint32_t swporta_dr; //0x00 + __IO uint32_t swporta_ddr; //0x04 + __IO uint32_t swporta_ctl; //0x08 + uint32_t reserved8[9]; //0x18-0x2c portC&D + __IO uint32_t inten; //0x30 + __IO uint32_t intmask; //0x34 + __IO uint32_t inttype_level; //0x38 + __IO uint32_t int_polarity; //0x3c + __I uint32_t int_status; //0x40 + __IO uint32_t raw_instatus; //0x44 + __IO uint32_t debounce; //0x48 + __O uint32_t porta_eoi; //0x4c + __I uint32_t ext_porta; //0x50 + uint32_t reserved9[3]; //0x58 0x5c + __IO uint32_t ls_sync; //0x60 + __I uint32_t id_code; //0x64 + uint32_t reserved10[1]; //0x68 + __I uint32_t ver_id_code; //0x6c + __I uint32_t config_reg2; //0x70 + __I uint32_t config_reg1; //0x74 +} AP_GPIO_TypeDef; + + +/*-------------------- (SPI) --------------------------------*/ +typedef struct +{ + __IO uint16_t CR0; //0x0 /*!< Offset: 0x000 Control Register 0 (R/W) */ + uint16_t reserved1; + __IO uint16_t CR1; //0x04 /*!< Offset: 0x004 Control Register 1 (R/W) */ + uint16_t reserved2; + __IO uint8_t SSIEN; //0x08 + uint8_t reserved3[3]; + __IO uint8_t MWCR; // 0x0c + uint8_t reserved4[3]; + __IO uint8_t SER; //0x10 + uint8_t reserved5[3]; + __IO uint32_t BAUDR; //0x14 + __IO uint32_t TXFTLR; //0x18 + __IO uint32_t RXFTLR; //0x1c + __O uint32_t TXFLR; //0x20 + __O uint32_t RXFLR; //0x24 + + __IO uint8_t SR; //0x28 + uint8_t reserved7[3]; + __IO uint32_t IMR; //0x2c + __IO uint32_t ISR; //0x30 + __IO uint32_t RISR; //0x34 + __IO uint32_t TXOICR; //0x38 + __IO uint32_t RXOICR; //0x3c + __IO uint32_t RXUICR; //0x40 + __IO uint32_t MSTICR; //0x44 + __IO uint32_t ICR; //0x48 + __IO uint32_t DMACR; //0x4c + __IO uint32_t DMATDLR; //0x50 + __IO uint32_t DMARDLR; //0x54 + __IO uint32_t IDR; //0x5c + __IO uint32_t SSI_COM_VER; //0x5c + __IO uint32_t DataReg; + +} AP_SSI_TypeDef; + + +typedef struct +{ + __IO uint32_t Analog_IO_en;//0x00 + __IO uint32_t SPI_debug_en;//0x04 + __IO uint32_t debug_mux_en;//0x08 + __IO uint32_t full_mux0_en;//0x0c + __IO uint32_t full_mux1_en;//0x10 reserved in some soc + __IO uint32_t gpio_pad_en; //0x14 + __IO uint32_t gpio_sel[9]; //0x18 + __IO uint32_t pad_pe0;//0x3c + __IO uint32_t pad_pe1;//0x40 + __IO uint32_t pad_ps0;//0x44 + __IO uint32_t pad_ps1;//0x48 + __IO uint32_t keyscan_in_en;//0x4c + __IO uint32_t keyscan_out_en;//0x50 +} IOMUX_TypeDef; + + +typedef struct +{ + __IO uint32_t PWROFF; //0x00 + __IO uint32_t PWRSLP; //0x04 + __IO uint32_t IOCTL[3]; //0x08 0x0c 0x10 + __IO uint32_t PMCTL0; //0x14 + __IO uint32_t PMCTL1; //0x18 + __IO uint32_t PMCTL2_0; //0x1c + __IO uint32_t PMCTL2_1; //0x20 + __IO uint32_t RTCCTL; //0x24 + __IO uint32_t RTCCNT; //0x28 + __IO uint32_t RTCCC0; //0x2c + __IO uint32_t RTCCC1; //0x30 + __IO uint32_t RTCCC2; //0x34 + __IO uint32_t RTCFLAG; //0x38 + __IO uint32_t reserved[25]; + __IO uint32_t REG_S9; //0xa0 + __IO uint32_t REG_S10; //0xa4 + __IO uint32_t REG_S11; //0xa8 + __IO uint32_t IDLE_REG; //0xac + __IO uint32_t GPIO_WAKEUP_SRC[2]; //0xb0 b4 + __IO uint32_t PCLK_CLK_GATE; //0xb8 + __IO uint32_t XTAL_16M_CTRL; //0xbc + __IO uint32_t SLEEP_R[4]; //0xc0 c4 c8 cc + +} AP_AON_TypeDef; + + +typedef struct +{ + __IO uint32_t RTCCTL; //0x24 + __IO uint32_t RTCCNT; //0x28 + __IO uint32_t RTCCC0; //0x2c + __IO uint32_t RTCCC1; //0x30 + __IO uint32_t RTCCC2; //0x34 + __IO uint32_t RTCFLAG; //0x38 +} AP_RTC_TypeDef; + +typedef struct +{ + __IO uint32_t io_wu_mask_31_0; //0xa0 + __IO uint32_t io_wu_mask_34_32; //0xa4 +} AP_Wakeup_TypeDef; + +typedef struct +{ + __IO uint32_t CLKSEL; //0x3c + __IO uint32_t CLKHF_CTL0; //0x40 + __IO uint32_t CLKHF_CTL1; //0x44 + __IO uint32_t ANA_CTL; //0x48 + __IO uint32_t mem_0_1_dvs; //0x4c + __IO uint32_t mem_2_3_4_dvs; //0x50 + __IO uint32_t efuse_cfg; //0x54 + __IO uint32_t chip_state; //0x58 + __IO uint32_t cal_rw; //0x5c + __IO uint32_t cal_ro0; //0x60 + __IO uint32_t cal_ro1; //0x64 + __IO uint32_t cal_ro2; //0x68 + __IO uint32_t ADC_CTL0; //0x6c + __IO uint32_t ADC_CTL1; //0x70 + __IO uint32_t ADC_CTL2; //0x74 + __IO uint32_t ADC_CTL3; //0x78 + __IO uint32_t ADC_CTL4; //0x7c + uint32_t reserved1[48]; + __IO uint32_t EFUSE_PROG[2];//0x140 + uint32_t reserved2[6]; + __IO uint32_t EFUSE0[2];//0x160 + __IO uint32_t EFUSE1[2];//0x168 + __IO uint32_t EFUSE2[2];//0x170 + __IO uint32_t EFUSE3[2];//0x178 + __IO uint32_t SECURTY_STATE;//0x180 +} AP_PCRM_TypeDef; + +typedef struct +{ + __IO uint32_t enable; //0x00 + __IO uint32_t reserve0[2]; //0x04~0x08 + __IO uint32_t control_1; //0x0c + __IO uint32_t control_2; //0x10 + __IO uint32_t control_3; //0x14 + __IO uint32_t control_4; //0x18 + __IO uint32_t compare_reset; //0x1c + __IO uint32_t int_pointer_ch0_ch3; //0x20 + __IO uint32_t int_pointer_ch4_ch7; //0x24 + //__IO uint32_t int_pointer[2]; //0x20~0x24 + __IO uint32_t reserve1[3]; //0x28~0x30 + __IO uint32_t intr_mask; //0x34 + __IO uint32_t intr_clear; //0x38 + __IO uint32_t intr_status; //0x3c + __IO uint32_t compare_cfg[8]; //0x40~0x5c +} AP_ADCC_TypeDef; + +typedef struct +{ + __IO uint32_t config; //0x0,QSPI Configuration Register,R/W + __IO uint32_t read_instr; //0x4,Device Read Instruction Register,R/W + __IO uint32_t write_instr; //0x8,Device Write Instruction Register,R/W + __IO uint32_t delay; //0xC,QSPI Device Delay Register,R/W + __IO uint32_t rddata_capture; //0x10,Read Data Capture Register,R/W + __IO uint32_t dev_size; //0x14,Device Size Register,R/W + __IO uint32_t sram_part; //0x18,SRAM Partition Register,R/W + __IO uint32_t indirect_ahb_addr_trig; //0x1C,Indirect AHB Address Trigger Register,R/W + __IO uint32_t dma_peripheral; //0x20,DMA Peripheral Register,R/W + __IO uint32_t remap; //0x24,Remap Address Register,R/W + __IO uint32_t mode_bit; //0x28,Mode Bit Register,R/W + __IO uint32_t sram_fill_level; //0x2C,SRAM Fill Level Register,RO + __IO uint32_t tx_threshold; //0x30,TX Threshold Register,R/W + __IO uint32_t rx_threshold; //0x34,RX Threshold Register,R/W + __IO uint32_t wr_completion_ctrl; //0x38,Write Completion Control Register,R/W + __IO uint32_t poll_expire; //0x3C,Polling Expiration Register,R/W + __IO uint32_t int_status; //0x40,Interrupt Status Register,R/W + __IO uint32_t int_mask; //0x44,Interrupt Mask,R/W + __I uint32_t n1[2]; //0x48~0x4c,Empty + __IO uint32_t low_wr_protection; //0x50,Lower Write Protection Register,R/W + __IO uint32_t up_wr_protection; //0x54,Upper Write Protection Register,R/W + __IO uint32_t wr_protection; //0x58,Write Protection Register,R/W + __I uint32_t n2; //0x5c,Empty + __IO uint32_t indirect_rd; //0x60,Indirect Read Transfer Register,R/W + __IO uint32_t indirect_rd_watermark; //0x64,Indirect Read Transfer Watermark Register,R/W + __IO uint32_t indirect_rd_start_addr; //0x68,Indirect Read Transfer Start Address Register,R/W + __IO uint32_t indirect_rd_num; //0x6C,Indirect Read Transfer Number Bytes Register,R/W + __IO uint32_t indirect_wr; //0x70,Indirect Write Transfer Register,R/W + __IO uint32_t indirect_wr_watermark; //0x74,Indirect Write Transfer Watermark Register,R/W + __IO uint32_t indirect_wr_start_addr; //0x78,Indirect Write Transfer Start Address Register,R/W + __IO uint32_t indirect_wr_cnt; //0x7C,Indirect Write Transfer Count Register,R/W + __IO uint32_t indirect_ahb_trig_addr_range; //0x80,Indirect AHB Trigger Address Range Register,R/W + __I uint32_t n3[3]; //0x84~0x8c,Empty + __IO uint32_t fcmd; //0x90,Flash Command Register,R/W + __IO uint32_t fcmd_addr; //0x94,Flash Command Address Registers,R/W + __I uint32_t n4[2]; //0x98~0x9c,Empty + __IO uint32_t fcmd_rddata[2]; //0xA0,Flash Command Read Data Register (low-a0, up-a4),RO + __IO uint32_t fcmd_wrdata[2]; //0xA8,Flash Command Write Data Register (low-a8, up-ac),R/W + __IO uint32_t poll_fstatus; //0xB0,Polling Flash Status Register,RO + //__IO uint32_t ; //0xFC,Module ID Register,RO +} AP_SPIF_TypeDef; + +typedef struct +{ + __IO uint32_t ctrl0; //0xc0 + __IO uint32_t ctrl1; //0xc4 + __IO uint32_t mk_in_en; //0xc8 + __IO uint32_t mkc[6]; //0xcc~0xe0 +} AP_KSCAN_TypeDef; + +typedef struct +{ + __IO uint32_t pwmen; +} AP_PWM_TypeDef; + + +typedef struct +{ + __IO uint32_t ctrl0; + __IO uint32_t ctrl1; +} AP_PWMCTRL_TypeDef; + + + +typedef struct +{ + __IO uint32_t SAR; + __IO uint32_t SAR_H; + __IO uint32_t DAR; + __IO uint32_t DAR_H; + __IO uint32_t LLP; + __IO uint32_t LLP_H; + __IO uint32_t CTL; + __IO uint32_t CTL_H; + __IO uint32_t SSTAT; + __IO uint32_t SSTAT_H; + __IO uint32_t DSTAT; + __IO uint32_t DSTAT_L; + __IO uint32_t SSTATAR; + __IO uint32_t SSTATAR_H; + __IO uint32_t DSTATAR; + __IO uint32_t DSTATAR_H; + __IO uint32_t CFG; + __IO uint32_t CFG_H; + __IO uint32_t rsv[4]; + +} AP_DMA_CH_TypeDef; + +typedef struct +{ + + __IO uint32_t RawTfr; //0x2c0 + __IO uint32_t RawTfr_H; //0x2c4 + __IO uint32_t RawBlock; //0x2c8 + __IO uint32_t RawBlock_H; //0x2cc + __IO uint32_t RawSrcTran; //0x2d0 + __IO uint32_t RawSrcTran_H; //0x2d4 + __IO uint32_t RawDstTran; //0x2d8 + __IO uint32_t RawDstTran_H; //0x2dc + __IO uint32_t RawErr; //0x2e0 + __IO uint32_t RawErr_H; //0x2e4 + + __IO uint32_t StatusTfr; //0x2e8 + __IO uint32_t StatusTfr_H; //0x2ec + __IO uint32_t StatusBlock; //0x2f0 + __IO uint32_t StatusBlock_H; //0x2f4 + __IO uint32_t StatusSrcTran; //0x2f8 + __IO uint32_t StatusSrcTran_H; //0x2fc + __IO uint32_t StatusDstTran; //0x300 + __IO uint32_t StatusDstTran_H; //0x304 + __IO uint32_t StatusErr; //0x308 + __IO uint32_t StatusErr_H; //0x30c + + __IO uint32_t MaskTfr; //0x310 + __IO uint32_t MaskTfr_H; //0x314 + __IO uint32_t MaskBlock; //0x318 + __IO uint32_t MaskBlock_H; //0x31c + __IO uint32_t MaskSrcTran; //0x320 + __IO uint32_t MaskSrcTran_H; //0x324 + __IO uint32_t MaskDstTran; //0x328 + __IO uint32_t MaskDstTran_H; //0x32c + __IO uint32_t MaskErr; //0x330 + __IO uint32_t MaskErr_H; //0x334 + + __IO uint32_t ClearTfr; //0x338 + __IO uint32_t ClearTfr_H; //0x33c + __IO uint32_t ClearBlock; //0x340 + __IO uint32_t ClearBlock_H; //0x344 + __IO uint32_t ClearSrcTran; //0x348 + __IO uint32_t ClearSrcTran_H; //0x34c + __IO uint32_t ClearDstTran; //0x350 + __IO uint32_t ClearDstTran_H; //0x354 + __IO uint32_t ClearErr; //0x358 + __IO uint32_t ClearErr_H; //0x35c + __IO uint32_t StatusInt; //0x360 + __IO uint32_t StatusInt_H; //0x364 + +} AP_DMA_INT_TypeDef; + +typedef struct +{ + __IO uint32_t ReqSrcReg; //0x368 + __IO uint32_t ReqSrcReg_H; //0x36c + __IO uint32_t ReqDstReg; //0x370 + __IO uint32_t ReqDstReg_H; //0x374 + __IO uint32_t SglReqSrcReg; //0x378 + __IO uint32_t SglReqSrcReg_H; //0x37c + __IO uint32_t SglReqDstReg; //0x380 + __IO uint32_t SglReqDstReg_H; //0x384 + __IO uint32_t LstSrcReg; //0x388 + __IO uint32_t LstSrcReg_H; //0x38c + __IO uint32_t LstDstReg; //0x390 + __IO uint32_t LstDstReg_H; //0x394 + +} AP_DMA_SW_HANDSHAKE_TypeDef; + +typedef struct +{ + __IO uint32_t DmaCfgReg; //0x398 + __IO uint32_t DmaCfgReg_H; //0x39c + __IO uint32_t ChEnReg; //0x3a0 + __IO uint32_t ChEnReg_H; //0x3a4 + __IO uint32_t DmaIdReg; //0x3a8 + __IO uint32_t DmaIdReg_H; //0x3ac + __IO uint32_t DmaTestReg; //0x3b0 + __IO uint32_t DmaTestReg_H; //0x3b4 + __IO uint32_t rsv1[4]; + __IO uint32_t DMA_COMP_PARAMS_6; //0x3c8 + __IO uint32_t DMA_COMP_PARAMS_6_H; //0x3cc + __IO uint32_t DMA_COMP_PARAMS_5; //0x3d0 + __IO uint32_t DMA_COMP_PARAMS_5_H; //0x3d4 + __IO uint32_t DMA_COMP_PARAMS_4; //0x3d8 + __IO uint32_t DMA_COMP_PARAMS_4_H; //0x3dc + __IO uint32_t DMA_COMP_PARAMS_3; //0x3e0 + __IO uint32_t DMA_COMP_PARAMS_3_H; //0x3e4 + __IO uint32_t DMA_COMP_PARAMS_2; //0x3e8 + __IO uint32_t DMA_COMP_PARAMS_2_H; //0x3ec + __IO uint32_t DMA_COMP_PARAMS_1; //0x3f0 + __IO uint32_t DMA_COMP_PARAMS_1_H; //0x3f4 + __IO uint32_t DMA_ID; //0x3f8 + __IO uint32_t DMA_ID_H; //0x3fc +} AP_DMA_MISC_TypeDef; + + +#if defined ( __CC_ARM ) +#pragma no_anon_unions +#endif + + +/******************************************************************************/ +/* Peripheral memory map(AP) */ +/******************************************************************************/ +/* Base addresses */ +#define AP_APB0_BASE (0x40000000UL) +#define SPIF_BASE_ADDR (0x11000000) /*spif*/ + +#define AP_PCR_BASE (AP_APB0_BASE + 0x0000)/*pcr*//* APB0 peripherals */ + +#define AP_TIM1_BASE (AP_APB0_BASE + 0x1000) +#define AP_TIM2_BASE (AP_APB0_BASE + 0x1014) +#define AP_TIM3_BASE (AP_APB0_BASE + 0x1028) +#define AP_TIM4_BASE (AP_APB0_BASE + 0x103c) +#define AP_TIM5_BASE (AP_APB0_BASE + 0x1050) +#define AP_TIM6_BASE (AP_APB0_BASE + 0x1064) +#define AP_TIM_SYS_BASE (AP_APB0_BASE + 0x10a0) + +#define AP_WDT_BASE (AP_APB0_BASE + 0x2000) +#define AP_COM_BASE (AP_APB0_BASE + 0x3000)/*com*/ +#define AP_IOMUX_BASE (AP_APB0_BASE + 0x3800)/*iomux*/ +#define AP_UART0_BASE (AP_APB0_BASE + 0x4000)/*uart0*/ +#define AP_I2C0_BASE (AP_APB0_BASE + 0x5000)/*i2c0*/ +#define AP_I2C1_BASE (AP_APB0_BASE + 0x5800)/*i2c1*/ +#define AP_SPI0_BASE (AP_APB0_BASE + 0x6000)/*spi0*/ +#define AP_SPI1_BASE (AP_APB0_BASE + 0x7000)/*spi1*/ +#define AP_GPIOA_BASE (AP_APB0_BASE + 0x8000)/*gpio*/ +#define AP_UART1_BASE (AP_APB0_BASE + 0x9000)/*uart1*/ +#define AP_DMIC_BASE (AP_APB0_BASE + 0xA000) +#define AP_QDEC_BASE (AP_APB0_BASE + 0xB000)/*qdec*/ +#define AP_CACHE_BASE (AP_APB0_BASE + 0xC000) +#define AP_SPIF_BASE (AP_APB0_BASE + 0xC800)/*spif*/ +#define AP_KSCAN_BASE (AP_APB0_BASE + 0xD0C0)/*kscan*/ +#define AP_PWM_BASE (AP_APB0_BASE + 0xE000)/*pwm*/ +#define AP_AON_BASE (AP_APB0_BASE + 0xF000)/*aon*/ +#define AP_RTC_BASE (AP_APB0_BASE + 0xF024)/*rtc*/ +#define AP_PCRM_BASE (AP_APB0_BASE + 0xF03c)/*pcrm*/ +#define AP_WAKEUP_BASE (AP_APB0_BASE + 0xF0a0)/*wakeup*/ +#define AP_DMAC_BASE (AP_APB0_BASE + 0x10000)/*dmac*/ +#define ADCC_BASE_ADDR (AP_APB0_BASE + 0x50000)/*adcc*/ + +/*bb_top*/ +/*linklayer*/ + +#define SRAM0_BASE_ADDRESS 0x1FFF0000 +#define SRAM1_BASE_ADDRESS 0x1FFF4000 +#define SRAM2_BASE_ADDRESS 0x1FFF8000 + + +///////////////////////////////////////////////////////////// +#define AP_PCR ((AP_PCR_TypeDef *) AP_PCR_BASE) + +#define AP_TIM1 ((AP_TIM_TypeDef *) AP_TIM1_BASE) +#define AP_TIM2 ((AP_TIM_TypeDef *) AP_TIM2_BASE) +#define AP_TIM3 ((AP_TIM_TypeDef *) AP_TIM3_BASE) +#define AP_TIM4 ((AP_TIM_TypeDef *) AP_TIM4_BASE) +#define AP_TIM5 ((AP_TIM_TypeDef *) AP_TIM5_BASE) +#define AP_TIM6 ((AP_TIM_TypeDef *) AP_TIM6_BASE) +#define AP_TIMS ((AP_TIM_SYS_TypeDef *) AP_TIM_SYS_BASE) + +#define AP_WDT ((AP_WDT_TypeDef *) AP_WDT_BASE) +#define AP_COM ((AP_COM_TypeDef *) AP_COM_BASE) +#define AP_IOMUX ((IOMUX_TypeDef *) AP_IOMUX_BASE) +#define AP_UART0 ((AP_UART_TypeDef *) AP_UART0_BASE) +#define AP_I2C0 ((AP_I2C_TypeDef *) AP_I2C0_BASE) +#define AP_I2C1 ((AP_I2C_TypeDef *) AP_I2C1_BASE) +#define AP_SPI0 ((AP_SSI_TypeDef *) AP_SPI0_BASE) +#define AP_SPI1 ((AP_SSI_TypeDef *) AP_SPI1_BASE) +#define AP_GPIO ((AP_GPIO_TypeDef *) AP_GPIOA_BASE) +#define AP_UART1 ((AP_UART_TypeDef *) AP_UART1_BASE) +#define AP_CACHE ((AP_CACHE_TypeDef *) AP_CACHE_BASE) +#define AP_SPIF ((AP_SPIF_TypeDef *) AP_SPIF_BASE) +#define AP_KSCAN ((AP_KSCAN_TypeDef *) AP_KSCAN_BASE) +#define AP_PWM ((AP_PWM_TypeDef *) AP_PWM_BASE) +#define AP_PWM_CTRL(n) ((AP_PWMCTRL_TypeDef *) (AP_PWM_BASE + 4 + n*12)) +#define AP_AON ((AP_AON_TypeDef *) AP_AON_BASE) +#define AP_RTC ((AP_RTC_TypeDef *) AP_RTC_BASE) +#define AP_PCRM ((AP_PCRM_TypeDef *) AP_PCRM_BASE) +#define AP_WAKEUP ((AP_Wakeup_TypeDef*) AP_WAKEUP_BASE) +#define AP_ADCC ((AP_ADCC_TypeDef *) ADCC_BASE_ADDR) + +#define AP_DMA_CH_CFG(n) ((AP_DMA_CH_TypeDef *) (AP_DMAC_BASE+0x58*n)) +#define AP_DMA_INT ((AP_DMA_INT_TypeDef *) (AP_DMAC_BASE+0x2c0)) +#define AP_DMA_SW_HANDSHAKE ((AP_DMA_SW_HANDSHAKE_TypeDef *) (AP_DMAC_BASE+0x368)) +#define AP_DMA_MISC ((AP_DMA_MISC_TypeDef *) (AP_DMAC_BASE+0x398)) + +/******************************************************************************/ +/* Peripheral memory map(CP) */ +/******************************************************************************/ +/* Base addresses */ +#define IRQ_PRIO_REALTIME 0 +#define IRQ_PRIO_HIGH 1 +#define IRQ_PRIO_HAL 2 +#define IRQ_PRIO_THREAD 3 +#define IRQ_PRIO_APP 3 + + +#endif diff --git a/arch/arm/src/phy62xx/my_printf.c b/arch/arm/src/phy62xx/my_printf.c new file mode 100644 index 00000000000..69835f4b249 --- /dev/null +++ b/arch/arm/src/phy62xx/my_printf.c @@ -0,0 +1,439 @@ + +#include "rom_sym_def.h" +#include "types.h" +#include +#include +#include "uart.h" +#include "log.h" + + + +#define ZEROPAD 1 // Pad with zero +#define SIGN 2 // Unsigned/signed long +#define PLUS 4 // Show plus +#define SPACE 8 // Space if plus +#define LEFT 16 // Left justified +#define SPECIAL 32 // 0x +#define LARGE 64 // Use 'ABCDEF' instead of 'abcdef' +#define is_digit(c) ((c) >= '0' && (c) <= '9') +static const char* digits = "0123456789abcdefghijklmnopqrstuvwxyz"; +static const char* upper_digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + +static size_t _strnlen(const char* s, size_t count) +{ + const char* sc; + + for (sc = s; *sc != '\0' && count--; ++sc); + + return sc - s; +} +static int skip_atoi(const char** s) +{ + int i = 0; + + while (is_digit(**s)) i = i * 10 + *((*s)++) - '0'; + + return i; +} +static void number(std_putc putc, long num, int base, int size, int precision, int type) +{ + char c, sign, tmp[66]; + const char* dig = digits; + int i; + char tmpch; + + if (type & LARGE) dig = upper_digits; + + if (type & LEFT) type &= ~ZEROPAD; + + if (base < 2 || base > 36) return; + + c = (type & ZEROPAD) ? '0' : ' '; + sign = 0; + + if (type & SIGN) + { + if (num < 0) + { + sign = '-'; + num = -num; + size--; + } + else if (type & PLUS) + { + sign = '+'; + size--; + } + else if (type & SPACE) + { + sign = ' '; + size--; + } + } + + if (type & SPECIAL) + { + if (base == 16) + size -= 2; + else if (base == 8) + size--; + } + + i = 0; + + if (num == 0) + tmp[i++] = '0'; + else + { + while (num != 0) + { + tmp[i++] = dig[((unsigned long)num) % (unsigned)base]; + num = ((unsigned long)num) / (unsigned)base; + } + } + + if (i > precision) precision = i; + + size -= precision; + + if (!(type & (ZEROPAD | LEFT))) + { + while (size-- > 0) + { + tmpch = ' '; + putc(&tmpch, 1); + } + } + + if (sign) + { + putc(&sign, 1); + } + + if (type & SPECIAL) + { + if (base == 8) + { + tmpch = '0'; + putc(&tmpch, 1); + } + else if (base == 16) + { + tmpch = '0'; + putc(&tmpch, 1); + tmpch = digits[33]; + putc(&tmpch, 1); + } + } + + if (!(type & LEFT)) + { + while (size-- > 0) + { + putc(&c, 1); + } + } + + while (i < precision--) + { + tmpch = '0'; + putc(&tmpch, 1); + } + + while (i-- > 0) + { + tmpch = tmp[i]; + putc(&tmpch, 1); + } + + while (size-- > 0) + { + tmpch = ' '; + putc(&tmpch, 1); + } +} + + + +static void log_vsprintf(std_putc putc, const char* fmt, va_list args) +{ + int len; + unsigned long num; + int base; + char* s; + int flags; // Flags to number() + int field_width; // Width of output field + int precision; // Min. # of digits for integers; max number of chars for from string + int qualifier; // 'h', 'l', or 'L' for integer fields + char* tmpstr = NULL; + int tmpstr_size = 0; + char tmpch; + + for (; *fmt; fmt++) + { + if (*fmt != '%') + { + if (tmpstr == NULL) + { + tmpstr = (char*)fmt; + tmpstr_size = 0; + } + + tmpstr_size ++; + continue; + } + else if (tmpstr_size) + { + putc(tmpstr, tmpstr_size); + tmpstr = NULL; + tmpstr_size = 0; + } + + // Process flags + flags = 0; +repeat: + fmt++; // This also skips first '%' + + switch (*fmt) + { + case '-': + flags |= LEFT; + goto repeat; + + case '+': + flags |= PLUS; + goto repeat; + + case ' ': + flags |= SPACE; + goto repeat; + + case '#': + flags |= SPECIAL; + goto repeat; + + case '0': + flags |= ZEROPAD; + goto repeat; + } + + // Get field width + field_width = -1; + + if (is_digit(*fmt)) + field_width = skip_atoi(&fmt); + else if (*fmt == '*') + { + fmt++; + field_width = va_arg(args, int); + + if (field_width < 0) + { + field_width = -field_width; + flags |= LEFT; + } + } + + // Get the precision + precision = -1; + + if (*fmt == '.') + { + ++fmt; + + if (is_digit(*fmt)) + precision = skip_atoi(&fmt); + else if (*fmt == '*') + { + ++fmt; + precision = va_arg(args, int); + } + + if (precision < 0) precision = 0; + } + + // Get the conversion qualifier + qualifier = -1; + + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') + { + qualifier = *fmt; + fmt++; + } + + // Default base + base = 10; + + switch (*fmt) + { + case 'c': + if (!(flags & LEFT)) + { + while (--field_width > 0) + { + tmpch = ' '; + putc(&tmpch, 1); + } + } + + tmpch = (unsigned char)va_arg(args, int); + putc(&tmpch, 1); + + while (--field_width > 0) + { + tmpch = ' '; + putc(&tmpch, 1); + } + + continue; + + case 's': + s = va_arg(args, char*); + + if (!s) + s = ""; + + len = _strnlen(s, precision); + + if (!(flags & LEFT)) + { + while (len < field_width--) + { + tmpch = ' '; + putc(&tmpch, 1); + } + } + + putc(s, len); + + while (len < field_width--) + { + tmpch = ' '; + putc(&tmpch, 1); + } + + continue; + + case 'p': + if (field_width == -1) + { + field_width = 2 * sizeof(void*); + flags |= ZEROPAD; + } + + number(putc,(unsigned long)va_arg(args, void*), 16, field_width, precision, flags); + continue; + + case 'n': + continue; + + case 'A': + continue; + + // Integer number formats - set up the flags and "break" + case 'o': + base = 8; + break; + + case 'X': + flags |= LARGE; + + case 'x': + base = 16; + break; + + case 'd': + case 'i': + flags |= SIGN; + + case 'u': + break; + + default: + if (*fmt != '%') + { + tmpch = '%'; + putc(&tmpch, 1); + } + + if (*fmt) + { + tmpch = *fmt; + putc(&tmpch, 1); + } + else + { + --fmt; + } + + continue; + } + + if (qualifier == 'l') + num = va_arg(args, unsigned long); + else if (qualifier == 'h') + { + if (flags & SIGN) + num = va_arg(args, int); + else + num = va_arg(args, unsigned int); + } + else if (flags & SIGN) + num = va_arg(args, int); + else + num = va_arg(args, unsigned int); + + number(putc, num, base, field_width, precision, flags); + } + + if (tmpstr_size) + { + putc(tmpstr, tmpstr_size); + tmpstr = NULL; + tmpstr_size = 0; + } +} + +static void _uart_putc(char* data, uint16_t size) +{ + hal_uart_send_buff(UART0, (uint8_t*)data, size); +} + +void dbg_printf_(const char* format, ...) +{ + va_list args; + va_start(args, format); + log_vsprintf(_uart_putc, format, args); + va_end(args); +} + +void dbg_printf_init(void) +{ + uart_Cfg_t cfg = + { + .tx_pin = P9, + .rx_pin = P10, + .rts_pin = GPIO_DUMMY, + .cts_pin = GPIO_DUMMY, + .baudrate = 115200, + .use_fifo = TRUE, + .hw_fwctrl = FALSE, + .use_tx_buf = FALSE, + .parity = FALSE, + .evt_handler = NULL, + }; + hal_uart_init(cfg, UART0);//uart init +} + +void my_dump_byte(uint8_t* pData, int dlen) +{ + for(int i=0; imember)) +#else /* 32-bit devices */ +#define osal_offsetof(type, member) ((uint32) &(((type *) 0)->member)) +#endif + +#define OSAL_MSG_NEXT(msg_ptr) ((osal_msg_hdr_t *) (msg_ptr) - 1)->next + +#define OSAL_MSG_Q_INIT(q_ptr) *(q_ptr) = NULL + +#define OSAL_MSG_Q_EMPTY(q_ptr) (*(q_ptr) == NULL) + +#define OSAL_MSG_Q_HEAD(q_ptr) (*(q_ptr)) + +#define OSAL_MSG_LEN(msg_ptr) ((osal_msg_hdr_t *) (msg_ptr) - 1)->len + +#define OSAL_MSG_ID(msg_ptr) ((osal_msg_hdr_t *) (msg_ptr) - 1)->dest_id + +/********************************************************************* + CONSTANTS +*/ + +/*** Interrupts ***/ +#define INTS_ALL 0xFF + +/********************************************************************* + TYPEDEFS +*/ +typedef struct +{ + void* next; + uint16 len; + uint8 dest_id; +} osal_msg_hdr_t; + +typedef struct +{ + uint8 event; + uint8 status; +} osal_event_hdr_t; + +typedef void* osal_msg_q_t; + +/********************************************************************* + GLOBAL VARIABLES +*/ + +/********************************************************************* + FUNCTIONS +*/ + +/*** Message Management ***/ + +/* + Task Message Allocation +*/ +extern uint8* osal_msg_allocate(uint16 len ); + +/* + Task Message Deallocation +*/ +extern uint8 osal_msg_deallocate( uint8* msg_ptr ); + +/* + Send a Task Message +*/ +extern uint8 osal_msg_send( uint8 destination_task, uint8* msg_ptr ); + +/* + Push a Task Message to head of queue +*/ +extern uint8 osal_msg_push_front( uint8 destination_task, uint8* msg_ptr ); + +/* + Receive a Task Message +*/ +extern uint8* osal_msg_receive( uint8 task_id ); + +/* + Find in place a matching Task Message / Event. +*/ +extern osal_event_hdr_t* osal_msg_find(uint8 task_id, uint8 event); + +/* + Enqueue a Task Message +*/ +extern void osal_msg_enqueue( osal_msg_q_t* q_ptr, void* msg_ptr ); + +/* + Enqueue a Task Message Up to Max +*/ +extern uint8 osal_msg_enqueue_max( osal_msg_q_t* q_ptr, void* msg_ptr, uint8 max ); + +/* + Dequeue a Task Message +*/ +extern void* osal_msg_dequeue( osal_msg_q_t* q_ptr ); + +/* + Push a Task Message to head of queue +*/ +extern void osal_msg_push( osal_msg_q_t* q_ptr, void* msg_ptr ); + +/* + Extract and remove a Task Message from queue +*/ +extern void osal_msg_extract( osal_msg_q_t* q_ptr, void* msg_ptr, void* prev_ptr ); + + +/*** Task Synchronization ***/ + +/* + Set a Task Event +*/ +extern uint8 osal_set_event( uint8 task_id, uint16 event_flag ); + + +/* + Clear a Task Event +*/ +extern uint8 osal_clear_event( uint8 task_id, uint16 event_flag ); + + +/*** Interrupt Management ***/ + +/* + Register Interrupt Service Routine (ISR) +*/ +extern uint8 osal_isr_register( uint8 interrupt_id, void (*isr_ptr)( uint8* ) ); + +/* + Enable Interrupt +*/ +extern uint8 osal_int_enable( uint8 interrupt_id ); + +/* + Disable Interrupt +*/ +extern uint8 osal_int_disable( uint8 interrupt_id ); + + +/*** Task Management ***/ + +/* + Initialize the Task System +*/ +extern uint8 osal_init_system( void ); + +/* + System Processing Loop +*/ +#if defined (ZBIT) +extern __declspec(dllexport) void osal_start_system( void ); +#else +extern void osal_start_system( void ); +#endif + +/* + One Pass Throu the OSAL Processing Loop +*/ +extern void osal_run_system( void ); + +/* + Get the active task ID +*/ +extern uint8 osal_self( void ); + + +/*** Helper Functions ***/ + +/* + String Length +*/ +extern int osal_strlen( char* pString ); + +/* + Memory copy +*/ +extern void* osal_memcpy( void*, const void GENERIC*, unsigned int ); + +/* + Memory Duplicate - allocates and copies +*/ +extern void* osal_memdup( const void GENERIC* src, unsigned int len ); + +/* + Reverse Memory copy +*/ +extern void* osal_revmemcpy( void*, const void GENERIC*, unsigned int ); + +/* + Memory compare +*/ +extern uint8 osal_memcmp( const void GENERIC* src1, const void GENERIC* src2, unsigned int len ); + +/* + Memory set +*/ +extern void* osal_memset( void* dest, uint8 value, int len ); + +/* + Build a uint16 out of 2 bytes (0 then 1). +*/ +extern uint16 osal_build_uint16( uint8* swapped ); + +/* + Build a uint32 out of sequential bytes. +*/ +extern uint32 osal_build_uint32( uint8* swapped, uint8 len ); + +/* + Convert long to ascii string +*/ +#if !defined ( ZBIT ) && !defined ( ZBIT2 ) && !defined (UBIT) +extern uint8* _ltoa( uint32 l, uint8* buf, uint8 radix ); +#endif + +/* + Random number generator +*/ +extern uint16 osal_rand( void ); + +/* + Buffer an uint32 value - LSB first. +*/ +extern uint8* osal_buffer_uint32( uint8* buf, uint32 val ); + +/* + Buffer an uint24 value - LSB first +*/ +extern uint8* osal_buffer_uint24( uint8* buf, uint24 val ); + +/* + Is all of the array elements set to a value? +*/ +extern uint8 osal_isbufset( uint8* buf, uint8 val, uint8 len ); + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* OSAL_H */ diff --git a/arch/arm/src/phy62xx/osal/include/OSAL_Clock.h b/arch/arm/src/phy62xx/osal/include/OSAL_Clock.h new file mode 100644 index 00000000000..d1d900a275a --- /dev/null +++ b/arch/arm/src/phy62xx/osal/include/OSAL_Clock.h @@ -0,0 +1,111 @@ +/****************************************************************************** + Filename: OSAL_Clock.h + Revised: + Revision: + + Description: OSAL Clock definition and manipulation functions. + + + +******************************************************************************/ + +#ifndef OSAL_CLOCK_H +#define OSAL_CLOCK_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ + +/********************************************************************* + MACROS +*/ + +#define IsLeapYear(yr) (!((yr) % 400) || (((yr) % 100) && !((yr) % 4))) + +/********************************************************************* + CONSTANTS +*/ + +/********************************************************************* + TYPEDEFS +*/ + +// number of seconds since 0 hrs, 0 minutes, 0 seconds, on the +// 1st of January 2000 UTC +typedef unsigned int UTCTime; // to confirm , int is 32bits long + +// To be used with +typedef struct +{ + uint8 seconds; // 0-59 + uint8 minutes; // 0-59 + uint8 hour; // 0-23 + uint8 day; // 0-30 + uint8 month; // 0-11 + uint16 year; // 2000+ +} UTCTimeStruct; + +/********************************************************************* + GLOBAL VARIABLES +*/ + +/********************************************************************* + FUNCTIONS +*/ + +/* + Updates the OSAL clock and Timers from the MAC 320us timer tick. +*/ +extern void osalTimeUpdate( void ); + +/* + Set the new time. This will only set the seconds portion + of time and doesn't change the factional second counter. + newTime - number of seconds since 0 hrs, 0 minutes, + 0 seconds, on the 1st of January 2000 UTC +*/ +extern void osal_setClock( UTCTime newTime ); + +/* + Gets the current time. This will only return the seconds + portion of time and doesn't include the factional second counter. + returns: number of seconds since 0 hrs, 0 minutes, + 0 seconds, on the 1st of January 2000 UTC +*/ +extern UTCTime osal_getClock( void ); + +/* + Converts UTCTime to UTCTimeStruct + + secTime - number of seconds since 0 hrs, 0 minutes, + 0 seconds, on the 1st of January 2000 UTC + tm - pointer to breakdown struct +*/ +extern void osal_ConvertUTCTime( UTCTimeStruct* tm, UTCTime secTime ); + +/* + Converts UTCTimeStruct to UTCTime (seconds since 00:00:00 01/01/2000) + + tm - pointer to UTC time struct +*/ +extern UTCTime osal_ConvertUTCSecs( UTCTimeStruct* tm ); + +/* + Update/Adjust the osal clock and timers + Msec - elapsed time in milli seconds +*/ +extern void osalAdjustTimer( uint32 Msec ); + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* OSAL_CLOCK_H */ diff --git a/arch/arm/src/phy62xx/osal/include/OSAL_Memory.h b/arch/arm/src/phy62xx/osal/include/OSAL_Memory.h new file mode 100644 index 00000000000..6e0440a5707 --- /dev/null +++ b/arch/arm/src/phy62xx/osal/include/OSAL_Memory.h @@ -0,0 +1,126 @@ +/************************************************************************************************** + Filename: OSAL_Memory.h + Revised: + Revision: + + Description: This module defines the OSAL memory control functions. + + + +**************************************************************************************************/ + +#ifndef OSAL_MEMORY_H +#define OSAL_MEMORY_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ +#include "comdef.h" + +/********************************************************************* + CONSTANTS +*/ + +#if !defined ( OSALMEM_METRICS ) +#define OSALMEM_METRICS FALSE +#endif + +/********************************************************************* + MACROS +*/ + +//#define osal_stack_used() OnBoard_stack_used() + +/********************************************************************* + TYPEDEFS +*/ + +typedef struct +{ + // The 15 LSB's of 'val' indicate the total item size, including the header, in 8-bit bytes. + unsigned short len : 15; // unsigned short len : 15; + // The 1 MSB of 'val' is used as a boolean to indicate in-use or freed. + unsigned short inUse : 1; // unsigned short inUse : 1; +} osalMemHdrHdr_t; + +typedef union +{ + /* Dummy variable so compiler forces structure to alignment of largest element while not wasting + space on targets when the halDataAlign_t is smaller than a UINT16. + */ + halDataAlign_t alignDummy; + uint32 val; // uint16 // TODO: maybe due to 4 byte alignment requirement in M0, this union should be 4 byte, change from uint16 to uint32, investigate more later - 04-25 + osalMemHdrHdr_t hdr; +} osalMemHdr_t; + +/********************************************************************* + GLOBAL VARIABLES +*/ + +/********************************************************************* + FUNCTIONS +*/ + +/* + Initialize memory manager. +*/ +void osal_mem_init( void ); + +/* + Setup efficient search for the first free block of heap. +*/ +void osal_mem_kick( void ); + +/* + Allocate a block of memory. +*/ +void* osal_mem_alloc( uint16 size ); + +/* + Free a block of memory. +*/ +void osal_mem_free( void* ptr ); + + +// ====== A2 metal change add +/* + Set osal memory buffer +*/ +void osal_mem_set_heap(osalMemHdr_t* hdr, uint32 size); + +#if ( OSALMEM_METRICS ) +/* + Return the maximum number of blocks ever allocated at once. +*/ +uint16 osal_heap_block_max( void ); + +/* + Return the current number of blocks now allocated. +*/ +uint16 osal_heap_block_cnt( void ); + +/* + Return the current number of free blocks. +*/ +uint16 osal_heap_block_free( void ); + +/* + Return the current number of bytes allocated. +*/ +uint16 osal_heap_mem_used( void ); +#endif + + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef OSAL_MEMORY_H */ diff --git a/arch/arm/src/phy62xx/osal/include/OSAL_Nv.h b/arch/arm/src/phy62xx/osal/include/OSAL_Nv.h new file mode 100644 index 00000000000..a70ddb14e3e --- /dev/null +++ b/arch/arm/src/phy62xx/osal/include/OSAL_Nv.h @@ -0,0 +1,83 @@ +/************************************************************************************************** + Filename: OSAL_Nv.h + Revised: + Revision: + + Description: This module defines the OSAL nv control functions. + + + +**************************************************************************************************/ + +#ifndef OSAL_NV_H +#define OSAL_NV_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ + +#include "hal_types.h" + +/********************************************************************* + CONSTANTS +*/ + +/********************************************************************* + MACROS +*/ + +/********************************************************************* + TYPEDEFS +*/ + +/********************************************************************* + GLOBAL VARIABLES +*/ + +/********************************************************************* + FUNCTIONS +*/ + +/* + Initialize NV service +*/ +extern void osal_nv_init( void* p ); + +/* + Initialize an item in NV +*/ +extern uint8 osal_nv_item_init( uint16 id, uint16 len, void* buf ); + +/* + Read an NV attribute +*/ +extern uint8 osal_nv_read( uint16 id, uint16 offset, uint16 len, void* buf ); + +/* + Write an NV attribute +*/ +extern uint8 osal_nv_write( uint16 id, uint16 offset, uint16 len, void* buf ); + +/* + Get the length of an NV item. +*/ +extern uint16 osal_nv_item_len( uint16 id ); + +/* + Delete an NV item. +*/ +extern uint8 osal_nv_delete( uint16 id, uint16 len ); + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* OSAL_NV.H */ diff --git a/arch/arm/src/phy62xx/osal/include/OSAL_PwrMgr.h b/arch/arm/src/phy62xx/osal/include/OSAL_PwrMgr.h new file mode 100644 index 00000000000..18d08f17261 --- /dev/null +++ b/arch/arm/src/phy62xx/osal/include/OSAL_PwrMgr.h @@ -0,0 +1,112 @@ +/************************************************************************************************** + Filename: OSAL_PwrMgr.h + Revised: + Revision: + + Description: This file contains the OSAL Power Management API. + + + **************************************************************************************************/ + +#ifndef OSAL_PWRMGR_H +#define OSAL_PWRMGR_H + +#include "comdef.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ + +/********************************************************************* + MACROS +*/ + +/********************************************************************* + TYPEDEFS +*/ + +/* These attributes define sleep beheaver. The attributes can be changed + for each sleep cycle or when the device characteristic change. +*/ +typedef struct +{ + uint16 pwrmgr_task_state; + uint16 pwrmgr_next_timeout; + uint16 accumulated_sleep_time; + uint8 pwrmgr_device; +} pwrmgr_attribute_t; + +/* With PWRMGR_ALWAYS_ON selection, there is no power savings and the + device is most likely on mains power. The PWRMGR_BATTERY selection allows + the HAL sleep manager to enter SLEEP LITE state or SLEEP DEEP state. +*/ +#define PWRMGR_ALWAYS_ON 0 +#define PWRMGR_BATTERY 1 + +/* The PWRMGR_CONSERVE selection turns power savings on, all tasks have to + agree. The PWRMGR_HOLD selection turns power savings off. +*/ +#define PWRMGR_CONSERVE 0 +#define PWRMGR_HOLD 1 + + +/********************************************************************* + GLOBAL VARIABLES +*/ + +/* This global variable stores the power management attributes. +*/ +extern pwrmgr_attribute_t pwrmgr_attribute; + +/********************************************************************* + FUNCTIONS +*/ + +/* + Initialize the power management system. + This function is called from OSAL. + +*/ +extern void osal_pwrmgr_init( void ); + +/* + This function is called by each task to state whether or not this + task wants to conserve power. The task will call this function to + vote whether it wants the OSAL to conserve power or it wants to + hold off on the power savings. By default, when a task is created, + its own power state is set to conserve. If the task always wants + to converse power, it doesn't need to call this function at all. + It is important for the task that changed the power manager task + state to PWRMGR_HOLD to switch back to PWRMGR_CONSERVE when the + hold period ends. +*/ +extern uint8 osal_pwrmgr_task_state( uint8 task_id, uint8 state ); + +/* + This function is called on power-up, whenever the device characteristic + change (ex. Battery backed coordinator). This function works with the timer + to set HAL's power manager sleep state when power saving is entered. + This function should be called form HAL initialization. After power up + initialization, it should only be called from NWK or ZDO. +*/ +extern void osal_pwrmgr_device( uint8 pwrmgr_device ); + +/* + This function is called from the main OSAL loop when there are + no events scheduled and shouldn't be called from anywhere else. +*/ +extern void osal_pwrmgr_powerconserve( void ); + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* OSAL_PWRMGR_H */ diff --git a/arch/arm/src/phy62xx/osal/include/OSAL_Tasks.h b/arch/arm/src/phy62xx/osal/include/OSAL_Tasks.h new file mode 100644 index 00000000000..2eb50da457d --- /dev/null +++ b/arch/arm/src/phy62xx/osal/include/OSAL_Tasks.h @@ -0,0 +1,65 @@ +/************************************************************************************************** + Filename: OSAL_Tasks.h + Revised: + Revision: + + Description: This file contains the OSAL Task definition and manipulation functions. + + +**************************************************************************************************/ + +#ifndef OSAL_TASKS_H +#define OSAL_TASKS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ + +/********************************************************************* + MACROS +*/ + +/********************************************************************* + CONSTANTS +*/ +#define TASK_NO_TASK 0xFF + +/********************************************************************* + TYPEDEFS +*/ + +/* + Event handler function prototype +*/ +typedef unsigned short (*pTaskEventHandlerFn)( unsigned char task_id, unsigned short event ); + +/********************************************************************* + GLOBAL VARIABLES +*/ + +extern const pTaskEventHandlerFn tasksArr[]; +extern const uint8 tasksCnt; +extern uint16* tasksEvents; + +/********************************************************************* + FUNCTIONS +*/ + +/* + Call each of the tasks initailization functions. +*/ +extern void osalInitTasks( void ); + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* OSAL_TASKS_H */ diff --git a/arch/arm/src/phy62xx/osal/include/OSAL_Timers.h b/arch/arm/src/phy62xx/osal/include/OSAL_Timers.h new file mode 100644 index 00000000000..1b20b130201 --- /dev/null +++ b/arch/arm/src/phy62xx/osal/include/OSAL_Timers.h @@ -0,0 +1,138 @@ +/************************************************************************************************** + Filename: OSAL_Timers.h + Revised: + Revision: + + Description: This file contains the OSAL Timer definition and manipulation functions. + + + +**************************************************************************************************/ + +#ifndef OSAL_TIMERS_H +#define OSAL_TIMERS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ + +/********************************************************************* + MACROS +*/ + +/********************************************************************* + CONSTANTS + the unit is chosen such that the 320us tick equivalent can fit in + 32 bits. +*/ +#define OSAL_TIMERS_MAX_TIMEOUT 0x28f5c28e /* unit is ms*/ + + +/********************************************************************* + TYPEDEFS +*/ +typedef union +{ + uint32 time32; + uint16 time16[2]; + uint8 time8[4]; +} osalTime_t; + +typedef struct +{ + void* next; + osalTime_t timeout; + uint16 event_flag; + uint8 task_id; + uint32 reloadTimeout; +} osalTimerRec_t; + + +/********************************************************************* + GLOBAL VARIABLES +*/ + +/********************************************************************* + FUNCTIONS +*/ + +/* + Initialization for the OSAL Timer System. +*/ + +extern osalTimerRec_t* osalFindTimer( uint8 task_id, uint16 event_flag ); + +extern void osalTimerInit( void ); + +/* + Set a Timer +*/ +extern uint8 osal_start_timerEx( uint8 task_id, uint16 event_id, uint32 timeout_value ); + +/* + Set a timer that reloads itself. +*/ +extern uint8 osal_start_reload_timer( uint8 taskID, uint16 event_id, uint32 timeout_value ); + +/* + Stop a Timer +*/ +extern uint8 osal_stop_timerEx( uint8 task_id, uint16 event_id ); + +/* + Get the tick count of a Timer. +*/ +extern uint32 osal_get_timeoutEx( uint8 task_id, uint16 event_id ); + +/* + Simulated Timer Interrupt Service Routine +*/ + +extern void osal_timer_ISR( void ); + +/* + Adjust timer tables +*/ +extern void osal_adjust_timers( void ); + +/* + Update timer tables +*/ +extern void osalTimerUpdate( uint32 updateTime ); + +/* + Count active timers +*/ +extern uint8 osal_timer_num_active( void ); + +/* + Set the hardware timer interrupts for sleep mode. + These functions should only be called in OSAL_PwrMgr.c +*/ +extern void osal_sleep_timers( void ); +extern void osal_unsleep_timers( void ); + +/* + Read the system clock - returns milliseconds +*/ +extern uint32 osal_GetSystemClock( void ); + +/* + Get the next OSAL timer expiration. + This function should only be called in OSAL_PwrMgr.c +*/ +extern uint32 osal_next_timeout( void ); + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* OSAL_TIMERS_H */ diff --git a/arch/arm/src/phy62xx/osal/include/comdef.h b/arch/arm/src/phy62xx/osal/include/comdef.h new file mode 100644 index 00000000000..c5be2ce70a2 --- /dev/null +++ b/arch/arm/src/phy62xx/osal/include/comdef.h @@ -0,0 +1,131 @@ +/************************************************************************************************** + Filename: comdef.h + Revised: + Revision: + + Description: Type definitions and macros. + + + +**************************************************************************************************/ + +#ifndef COMDEF_H +#define COMDEF_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + + +/********************************************************************* + INCLUDES +*/ + +/* HAL */ + +#include "types.h" + + +/********************************************************************* + Lint Keywords +*/ +#define VOID (void) + +#define NULL_OK +#define INP +#define OUTP +#ifndef UNUSED + #define UNUSED +#endif +#define ONLY +#define READONLY +#define SHARED +#define KEEP +#define RELAX + + + + +/********************************************************************* + CONSTANTS +*/ + +#ifndef false +#define false 0 +#endif + +#ifndef true +#define true 1 +#endif + +#ifndef CONST +#define CONST const +#endif + +#ifndef GENERIC +#define GENERIC +#endif + +/*** Generic Status Return Values ***/ +#define SUCCESS 0x00 +#define FAILURE 0x01 +#define INVALIDPARAMETER 0x02 +#define INVALID_TASK 0x03 +#define MSG_BUFFER_NOT_AVAIL 0x04 +#define INVALID_MSG_POINTER 0x05 +#define INVALID_EVENT_ID 0x06 +#define INVALID_INTERRUPT_ID 0x07 +#define NO_TIMER_AVAIL 0x08 +#define NV_ITEM_UNINIT 0x09 +#define NV_OPER_FAILED 0x0A +#define INVALID_MEM_SIZE 0x0B +#define NV_BAD_ITEM_LEN 0x0C + +/********************************************************************* + TYPEDEFS +*/ + +// Generic Status return +typedef uint8 Status_t; + +// Data types +typedef int32 int24; +typedef uint32 uint24; + +/********************************************************************* + Global System Events +*/ + +#define SYS_EVENT_MSG 0x8000 // A message is waiting event + +/********************************************************************* + Global Generic System Messages +*/ + +#define KEY_CHANGE 0xC0 // Key Events + +// OSAL System Message IDs/Events Reserved for applications (user applications) +// 0xE0 – 0xFC + +/********************************************************************* + MACROS +*/ + +/********************************************************************* + GLOBAL VARIABLES +*/ + +/********************************************************************* + FUNCTIONS +*/ + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* COMDEF_H */ diff --git a/arch/arm/src/phy62xx/osal/include/comdef.h.bak b/arch/arm/src/phy62xx/osal/include/comdef.h.bak new file mode 100644 index 00000000000..2950c2de526 --- /dev/null +++ b/arch/arm/src/phy62xx/osal/include/comdef.h.bak @@ -0,0 +1,131 @@ +/************************************************************************************************** + Filename: comdef.h + Revised: + Revision: + + Description: Type definitions and macros. + + + +**************************************************************************************************/ + +#ifndef COMDEF_H +#define COMDEF_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + + +/********************************************************************* + INCLUDES +*/ +#include +/* HAL */ + +#include "types.h" + + +/********************************************************************* + Lint Keywords +*/ +#define VOID (void) + +#define NULL_OK +#define INP +#define OUTP +#ifndef UNUSED + #define UNUSED +#endif +#define ONLY +#define READONLY +#define SHARED +#define KEEP +#define RELAX + + + + +/********************************************************************* + CONSTANTS +*/ + +#ifndef false +#define false 0 +#endif + +#ifndef true +#define true 1 +#endif + +#ifndef CONST +#define CONST const +#endif + +#ifndef GENERIC +#define GENERIC +#endif + +/*** Generic Status Return Values ***/ +#define SUCCESS 0x00 +#define FAILURE 0x01 +#define INVALIDPARAMETER 0x02 +#define INVALID_TASK 0x03 +#define MSG_BUFFER_NOT_AVAIL 0x04 +#define INVALID_MSG_POINTER 0x05 +#define INVALID_EVENT_ID 0x06 +#define INVALID_INTERRUPT_ID 0x07 +#define NO_TIMER_AVAIL 0x08 +#define NV_ITEM_UNINIT 0x09 +#define NV_OPER_FAILED 0x0A +#define INVALID_MEM_SIZE 0x0B +#define NV_BAD_ITEM_LEN 0x0C + +/********************************************************************* + TYPEDEFS +*/ + +// Generic Status return +typedef uint8 Status_t; + +// Data types +typedef int32 int24; +typedef uint32 uint24; + +/********************************************************************* + Global System Events +*/ + +#define SYS_EVENT_MSG 0x8000 // A message is waiting event + +/********************************************************************* + Global Generic System Messages +*/ + +#define KEY_CHANGE 0xC0 // Key Events + +// OSAL System Message IDs/Events Reserved for applications (user applications) +// 0xE0 – 0xFC + +/********************************************************************* + MACROS +*/ + +/********************************************************************* + GLOBAL VARIABLES +*/ + +/********************************************************************* + FUNCTIONS +*/ + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* COMDEF_H */ diff --git a/arch/arm/src/phy62xx/osal/include/osal_bufmgr.h b/arch/arm/src/phy62xx/osal/include/osal_bufmgr.h new file mode 100644 index 00000000000..089f825ce8a --- /dev/null +++ b/arch/arm/src/phy62xx/osal/include/osal_bufmgr.h @@ -0,0 +1,80 @@ +/************************************************************************************************** + Filename: osal_bufmgr.h + Revised: + Revision: + + Description: This file contains the buffer management definitions. + + + +**************************************************************************************************/ + +#ifndef OSAL_BUFMGR_H +#define OSAL_BUFMGR_H + +#include "comdef.h" +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ + +/********************************************************************* + CONSTANTS +*/ + + +/********************************************************************* + VARIABLES +*/ + + +/********************************************************************* + MACROS +*/ + + +/********************************************************************* + TYPEDEFS +*/ + + +/********************************************************************* + VARIABLES +*/ + +/********************************************************************* + FUNCTIONS +*/ + +/* + Allocate a block of memory. +*/ +extern void* osal_bm_alloc( uint16 size ); + +/* + Add or remove header space for the payload pointer. +*/ +extern void* osal_bm_adjust_header( void* payload_ptr, int16 size ); + +/* + Add or remove tail space for the payload pointer. +*/ +extern void* osal_bm_adjust_tail( void* payload_ptr, int16 size ); + +/* + Free a block of memory. +*/ +extern void osal_bm_free( void* payload_ptr ); + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* OSAL_BUFMGR_H */ diff --git a/arch/arm/src/phy62xx/osal/include/osal_cbtimer.h b/arch/arm/src/phy62xx/osal/include/osal_cbtimer.h new file mode 100644 index 00000000000..bfc16e47b69 --- /dev/null +++ b/arch/arm/src/phy62xx/osal/include/osal_cbtimer.h @@ -0,0 +1,102 @@ +/************************************************************************************************** + Filename: osal_cbtimer.h + Revised: + Revision: + + Description: This file contains the Callback Timer definitions. + + + **************************************************************************************************/ + +#ifndef OSAL_CBTIMER_H +#define OSAL_CBTIMER_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ + +/********************************************************************* + CONSTANTS +*/ +// Invalid timer id +#define INVALID_TIMER_ID 0xFF + +// Timed out timer +#define TIMEOUT_TIMER_ID 0xFE + +/********************************************************************* + VARIABLES +*/ + +/********************************************************************* + MACROS +*/ +#define OSAL_CBTIMER_NUM_TASKS 1 // set by HZF, align to TI project setting +#if ( OSAL_CBTIMER_NUM_TASKS == 0 ) +#error "Callback Timer module shouldn't be included (no callback timer is needed)!" +#elif ( OSAL_CBTIMER_NUM_TASKS == 1 ) +#define OSAL_CBTIMER_PROCESS_EVENT( a ) ( a ) +#elif ( OSAL_CBTIMER_NUM_TASKS == 2 ) +#define OSAL_CBTIMER_PROCESS_EVENT( a ) ( a ), ( a ) +#else +#error "Maximum of 2 callback timer tasks are supported! Modify it here." +#endif + +/********************************************************************* + TYPEDEFS +*/ + +// Callback Timer function prototype. Callback function will be called +// when the associated timer expires. +// +// pData - pointer to data registered with timer +// +typedef void (*pfnCbTimer_t)( uint8* pData ); + +/********************************************************************* + VARIABLES +*/ + +/********************************************************************* + FUNCTIONS +*/ + +/* + Callback Timer task initialization function. +*/ +extern void osal_CbTimerInit( uint8 taskId ); + +/* + Callback Timer task event processing function. +*/ +extern uint16 osal_CbTimerProcessEvent( uint8 taskId, uint16 events ); + +/* + Function to start a timer to expire in n mSecs. +*/ +extern Status_t osal_CbTimerStart( pfnCbTimer_t pfnCbTimer, uint8* pData, + uint32 timeout, uint8* pTimerId ); + +/* + Function to update a timer that has already been started. +*/ +extern Status_t osal_CbTimerUpdate( uint8 timerId, uint32 timeout ); + +/* + Function to stop a timer that has already been started. +*/ +extern Status_t osal_CbTimerStop( uint8 timerId ); + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* OSAL_CBTIMER_H */ diff --git a/arch/arm/src/phy62xx/osal/include/osal_snv.h b/arch/arm/src/phy62xx/osal/include/osal_snv.h new file mode 100644 index 00000000000..0168d63aa8f --- /dev/null +++ b/arch/arm/src/phy62xx/osal/include/osal_snv.h @@ -0,0 +1,110 @@ +/************************************************************************************************** + Filename: OSAL_snv.h + Revised: + Revision: + + Description: This module defines the OSAL snv control functions. + + + +**************************************************************************************************/ +#ifndef OSAL_SNV_H +#define OSAL_SNV_H + +#include "comdef.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + INCLUDES +*/ + +//#include "hal_types.h" + +/********************************************************************* + CONSTANTS +*/ + +/********************************************************************* + MACROS +*/ + +/********************************************************************* + TYPEDEFS +*/ +#ifdef OSAL_SNV_UINT16_ID +typedef uint16 osalSnvId_t; +typedef uint16 osalSnvLen_t; +#else +typedef uint8 osalSnvId_t; +typedef uint8 osalSnvLen_t; +#endif + +/********************************************************************* + GLOBAL VARIABLES +*/ + +/********************************************************************* + FUNCTIONS +*/ + +/********************************************************************* + @fn osal_snv_init + + @brief Initialize NV service. + + @return SUCCESS if initialization succeeds. FAILURE, otherwise. +*/ +extern uint8 osal_snv_init( void ); + +/********************************************************************* + @fn osal_snv_read + + @brief Read data from NV. + + @param id - Valid NV item Id. + @param len - Length of data to read. + @param *pBuf - Data is read into this buffer. + + @return SUCCESS if successful. + Otherwise, NV_OPER_FAILED for failure. +*/ +extern uint8 osal_snv_read( osalSnvId_t id, osalSnvLen_t len, void* pBuf); + +/********************************************************************* + @fn osal_snv_write + + @brief Write a data item to NV. + + @param id - Valid NV item Id. + @param len - Length of data to write. + @param *pBuf - Data to write. + + @return SUCCESS if successful, NV_OPER_FAILED if failed. +*/ +extern uint8 osal_snv_write( osalSnvId_t id, osalSnvLen_t len, void* pBuf); + +/********************************************************************* + @fn osal_snv_compact + + @brief Compacts NV if its usage has reached a specific threshold. + + @param threshold - compaction threshold + + @return SUCCESS if successful, + NV_OPER_FAILED if failed, or + INVALIDPARAMETER if threshold invalid. +*/ +extern uint8 osal_snv_compact( uint8 threshold ); + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* OSAL_SNV.H */ diff --git a/arch/arm/src/phy62xx/osal/snv/osal_snv.c b/arch/arm/src/phy62xx/osal/snv/osal_snv.c new file mode 100644 index 00000000000..42b412055eb --- /dev/null +++ b/arch/arm/src/phy62xx/osal/snv/osal_snv.c @@ -0,0 +1,141 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + + +#include +#include "osal.h" +#include "flash.h" +#include "error.h" +#include "osal_snv.h" +#include "log.h" + +#ifndef USE_FS + #define USE_FS 1 +#endif +#ifdef USE_FS + #include "fs.h" +#endif + + +#if (USE_FS == 0) +#define NVM_BASE_ADDR 0x1103C000 //16K bytes + + +uint8 osal_snv_init( void ) +{ + return PPlus_ERR_FATAL; +} + +uint8 osal_snv_read( osalSnvId_t id, osalSnvLen_t len, void* pBuf) +{ + (void)(id); + (void)(len); + (void)(pBuf); + return PPlus_ERR_FATAL; +} + +uint8 osal_snv_write( osalSnvId_t id, osalSnvLen_t len, void* pBuf) +{ + (void)(id); + (void)(len); + (void)(pBuf); + return PPlus_ERR_FATAL; +} + +uint8 osal_snv_compact( uint8 threshold ) +{ + return SUCCESS; +} + +#else + +uint8 osal_snv_init( void ) +{ + if(!hal_fs_initialized()) + return NV_OPER_FAILED; + + return SUCCESS; +} + +uint8 osal_snv_read( osalSnvId_t id, osalSnvLen_t len, void* pBuf) +{ + int ret; + LOG("osal_snv_read:%x\n",id); + ret = hal_fs_item_read((uint16_t)id,(uint8_t*) pBuf, (uint16_t)len,NULL); + + if(ret != PPlus_SUCCESS) + { + LOG("rd_ret:%d\n",ret); + return NV_OPER_FAILED; + } + + LOG_DUMP_BYTE(pBuf, len); + return SUCCESS; +} + +uint8 osal_snv_write( osalSnvId_t id, osalSnvLen_t len, void* pBuf) +{ + int ret = PPlus_SUCCESS; + LOG("osal_snv_write:%x,%d\n",id,len); + LOG_DUMP_BYTE(pBuf, len); + + if(hal_fs_get_free_size() < len+32) + { + if(hal_fs_get_garbage_size(NULL) > len+32) + { + hal_fs_garbage_collect(); + } + else + { + return NV_OPER_FAILED; + } + } + + ret = hal_fs_item_write((uint16_t) id, (uint8_t*) pBuf, (uint16_t) len); + + if(ret !=0) + { + LOG("wr_ret:%d\n",ret); + return NV_OPER_FAILED; + } + + //LOG("Success\n"); + return SUCCESS; +} + +uint8 osal_snv_compact( uint8 threshold ) +{ + return 0; +} + +#endif + diff --git a/arch/arm/src/phy62xx/phy6222_irq.h b/arch/arm/src/phy62xx/phy6222_irq.h new file mode 100644 index 00000000000..57427252f77 --- /dev/null +++ b/arch/arm/src/phy62xx/phy6222_irq.h @@ -0,0 +1,370 @@ +/**************************************************************************** + * arch/arm/include/armv6-m/irq.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* This file should never be included directly but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_ARMV6_M_IRQ_H +#define __ARCH_ARM_INCLUDE_ARMV6_M_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#ifndef __ASSEMBLY__ +# include +# include +#endif + +#include + +/**************************************************************************** + * Pre-processor Prototypes + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* If this is a kernel build, + * how many nested system calls should we support? + */ + +#ifndef CONFIG_SYS_NNEST +# define CONFIG_SYS_NNEST 2 +#endif + +/* IRQ Stack Frame Format *************************************************** + * + * The following additional registers are stored by the interrupt handling + * logic. + */ + +#define REG_R13 (0) /* R13 = SP at time of interrupt */ +#define REG_PRIMASK (1) /* PRIMASK */ +#define REG_R4 (2) /* R4 */ +#define REG_R5 (3) /* R5 */ +#define REG_R6 (4) /* R6 */ +#define REG_R7 (5) /* R7 */ +#define REG_R8 (6) /* R8 */ +#define REG_R9 (7) /* R9 */ +#define REG_R10 (8) /* R10 */ +#define REG_R11 (9) /* R11 */ + +/* In the kernel build, we may return to either privileged or unprivileged + * modes. + */ + +#ifdef CONFIG_BUILD_PROTECTED +# define REG_EXC_RETURN (10) /* EXC_RETURN */ +# define SW_XCPT_REGS (11) +#else +# define SW_XCPT_REGS (10) +#endif + +/* The total number of registers saved by software */ + +#define SW_XCPT_SIZE (4 * SW_XCPT_REGS) + +/* On entry into an IRQ, the hardware automatically saves the following + * registers on the stack in this (address) order: + */ + +#define REG_DUMMY0 (SW_XCPT_REGS+0) /* DUMMY */ +#define REG_DUMMY1 (SW_XCPT_REGS+1) /* DUMMY */ +#define REG_R0 (SW_XCPT_REGS+0+2) /* R0 */ +#define REG_R1 (SW_XCPT_REGS+1+2) /* R1 */ +#define REG_R2 (SW_XCPT_REGS+2+2) /* R2 */ +#define REG_R3 (SW_XCPT_REGS+3+2) /* R3 */ +#define REG_R12 (SW_XCPT_REGS+4+2) /* R12 */ +#define REG_R14 (SW_XCPT_REGS+5+2) /* R14 = LR */ +#define REG_R15 (SW_XCPT_REGS+6+2) /* R15 = PC */ +#define REG_XPSR (SW_XCPT_REGS+7+2) /* xPSR */ + +#define HW_XCPT_REGS (10) +#define HW_XCPT_SIZE (4 * HW_XCPT_REGS) + +#define XCPTCONTEXT_REGS (HW_XCPT_REGS + SW_XCPT_REGS) +#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS) + +/* Alternate register names */ + +#define REG_A1 REG_R0 +#define REG_A2 REG_R1 +#define REG_A3 REG_R2 +#define REG_A4 REG_R3 +#define REG_V1 REG_R4 +#define REG_V2 REG_R5 +#define REG_V3 REG_R6 +#define REG_V4 REG_R7 +#define REG_V5 REG_R8 +#define REG_V6 REG_R9 +#define REG_V7 REG_R10 +#define REG_SB REG_R9 +#define REG_SL REG_R10 +#define REG_FP REG_R11 +#define REG_IP REG_R12 +#define REG_SP REG_R13 +#define REG_LR REG_R14 +#define REG_PC REG_R15 + +/* The PIC register is usually R10. It can be R9 is stack checking is enabled + * or if the user changes it with -mpic-register on the GCC command line. + */ + +#define REG_PIC REG_R10 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* This structure represents the return state from a system call */ + +#ifdef CONFIG_LIB_SYSCALL +struct xcpt_syscall_s +{ + uint32_t excreturn; /* The EXC_RETURN value */ + uint32_t sysreturn; /* The return PC */ +}; +#endif + +/* The following structure is included in the TCB and defines the complete + * state of the thread. + */ + +struct xcptcontext +{ + /* The following function pointer is non-zero if there + * are pending signals to be processed. + */ + + void *sigdeliver; /* Actual type is sig_deliver_t */ + + /* These are saved copies of LR, PRIMASK, and xPSR used during + * signal processing. + * + * REVISIT: Because there is only one copy of these save areas, + * only a single signal handler can be active. This precludes + * queuing of signal actions. As a result, signals received while + * another signal handler is executing will be ignored! + */ + + uint32_t saved_pc; + uint32_t saved_primask; + uint32_t saved_xpsr; +#ifdef CONFIG_BUILD_PROTECTED + uint32_t saved_lr; + + /* This is the saved address to use when returning from a user-space + * signal handler. + */ + + uint32_t sigreturn; +#endif + +#ifdef CONFIG_LIB_SYSCALL + /* The following array holds the return address and the exc_return value + * needed to return from each nested system call. + */ + + uint8_t nsyscalls; + struct xcpt_syscall_s syscall[CONFIG_SYS_NNEST]; +#endif + + /* Register save area */ + + uint32_t regs[XCPTCONTEXT_REGS]; +}; +#endif + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Name: up_irq_save, up_irq_restore, and friends. + * + * NOTE: This function should never be called from application code and, + * as a general rule unless you really know what you are doing, this + * function should not be called directly from operation system code either: + * Typically, the wrapper functions, enter_critical_section() and + * leave_critical section(), are probably what you really want. + */ + +/* Get/set the PRIMASK register */ + +static inline uint8_t getprimask(void) inline_function; +static inline uint8_t getprimask(void) +{ + uint32_t primask; + __asm__ __volatile__ + ( + "\tmrs %0, primask\n" + : "=r" (primask) + : + : "memory"); + + return (uint8_t)primask; +} + +static inline void setprimask(uint32_t primask) inline_function; +static inline void setprimask(uint32_t primask) +{ + __asm__ __volatile__ + ( + "\tmsr primask, %0\n" + : + : "r" (primask) + : "memory"); +} + +/* Disable IRQs */ + +static inline void up_irq_disable(void) inline_function; +static inline void up_irq_disable(void) +{ + __asm__ __volatile__ ("\tcpsid i\n"); +} + +/* Save the current primask state & disable IRQs */ +typedef void (*gpiowr_t)(int id, unsigned int en); +#if 0 +static inline irqstate_t up_irq_save(void) inline_function; +static inline irqstate_t up_irq_save(void) +{ + unsigned short primask; + + /* Return the current value of primask register and set + * bit 0 of the primask register to disable interrupts + */ + ((gpiowr_t)0x0000b319)(12,1); + + __asm__ __volatile__ + ( + "\tmrs %0, primask\n" + "\tcpsid i\n" + : "=r" (primask) + : + : "memory"); + + return primask; +} +#endif +/* Enable IRQs */ + +static inline void up_irq_enable(void) inline_function; +static inline void up_irq_enable(void) +{ + __asm__ __volatile__ ("\tcpsie i\n"); +} + +/* Restore saved primask state */ +#if 0 +static inline void up_irq_restore(irqstate_t flags) inline_function; +static inline void up_irq_restore(irqstate_t flags) +{ + /* If bit 0 of the primask is 0, then we need to restore + * interrupts. + */ + + __asm__ __volatile__ + ( + "\tmsr primask, %0\n" + : + : "r" (flags) + : "memory"); + ((gpiowr_t)0x0000b319)(12,0); +} +#endif +/* Get/set IPSR */ + +static inline uint32_t getipsr(void) inline_function; +static inline uint32_t getipsr(void) +{ + uint32_t ipsr; + __asm__ __volatile__ + ( + "\tmrs %0, ipsr\n" + : "=r" (ipsr) + : + : "memory"); + + return ipsr; +} + +/* Get/set CONTROL */ + +static inline uint32_t getcontrol(void) inline_function; +static inline uint32_t getcontrol(void) +{ + uint32_t control; + __asm__ __volatile__ + ( + "\tmrs %0, control\n" + : "=r" (control) + : + : "memory"); + + return control; +} + +static inline void setcontrol(uint32_t control) inline_function; +static inline void setcontrol(uint32_t control) +{ + __asm__ __volatile__ + ( + "\tmsr control, %0\n" + : + : "r" (control) + : "memory"); +} + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_ARMV6_M_IRQ_H */ + diff --git a/arch/arm/src/phy62xx/phy62xx_ble.c b/arch/arm/src/phy62xx/phy62xx_ble.c new file mode 100644 index 00000000000..bc6b6eb912b --- /dev/null +++ b/arch/arm/src/phy62xx/phy62xx_ble.c @@ -0,0 +1,290 @@ + + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include "OSAL.h" +#include "hci_tl.h" +#include "jump_function.h" + +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_UART_BTH4) + #include +#endif + +#define BLE_BUF_SIZE 512 +struct pplus_ble_priv_s +{ + struct bt_driver_s drv; /* NuttX BT/BLE driver data */ +}; + + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static int pplus_ble_send(struct bt_driver_s *drv, + enum bt_buf_type_e type, + void *data, size_t len); + +static void pplus_ble_close(struct bt_driver_s *drv); +static int pplus_ble_open(struct bt_driver_s *drv); + +static struct pplus_ble_priv_s g_pplus_ble = +{ + .drv = + { + .head_reserve = H4_HEADER_SIZE, + .open = pplus_ble_open, + .send = pplus_ble_send, + } +}; + +/**************************************************************************** + * Name: pplus_ble_recv_cb + * + * Description: + * BLE receive callback function when BLE hardware receive packet + * + * Input Parameters: + * data - BLE packet data pointer + * len - BLE packet length + * + * Returned Value: + * 0 on success or a negated value on failure. + * + ****************************************************************************/ + +int pplus_ble_recv_cb_h4(uint8_t *data, uint16_t len) +{ + int ret; + struct pplus_ble_priv_s *priv = &g_pplus_ble; + + ret = bt_netdev_receive(&priv->drv, BT_EVT, + &data[H4_HEADER_SIZE], + len - H4_HEADER_SIZE); + if (ret < 0) + { + wlerr("Failed to receive ret=%d\n", ret); + } + + return ret; +} + +int pplus_ble_recv_cb_acl(uint8_t *data, uint16_t len) +{ + int ret; + struct pplus_ble_priv_s *priv = &g_pplus_ble; + + ret = bt_netdev_receive(&priv->drv, BT_ACL_IN, + &data[H4_HEADER_SIZE], + len - H4_HEADER_SIZE); + if (ret < 0) + { + wlerr("Failed to receive ret=%d\n", ret); + } + + return ret; + +} +uint8 pplus_ble_recv_msg( uint8 destination_task, uint8 *msg_ptr ) +{ + UNUSED(destination_task); + int ret = 0; + hciPacket_t* hci_msg = (hciPacket_t*) msg_ptr; + uint8_t* pdata = hci_msg->pData; + uint8_t dataLength; + uint16_t hcipkt_len; + + //gpio_write(P25, 1); + + + if(pdata[0] == H4_EVT) + { + dataLength = pdata[2]; + hcipkt_len = HCI_EVENT_MIN_LENGTH + dataLength; + +// logx("len %d\n",dataLength); +// for(int k = 0;khead_reserve; + //printf("pplus_ble_send"); + + if ((len + H4_HEADER_SIZE) > BLE_BUF_SIZE) + { + return -EINVAL; + } + + if (type == BT_CMD) + { + //*hdr = H4_CMD; + hciProcessHostToCtrlCmd((uint8_t*)data); + } + else if (type == BT_ACL_OUT) + { + uint16_t connHandle, param; + uint8_t pbFlag; + uint16_t pktLen; + uint8_t *acldata = (uint8_t*)data; + uint8_t *send_buf = NULL; + + param = BUILD_UINT16(acldata[0], acldata[1]); + connHandle = param & 0xfff; + pbFlag = (param & 0x3000) >> 12; + pktLen = BUILD_UINT16(acldata[2], acldata[3]); + + send_buf = (uint8_t *)HCI_bm_alloc(pktLen); + + if (!send_buf) { + return -ENOMEM; + } + + memcpy(send_buf, &acldata[4], pktLen); + + int ret = LL_TxData(connHandle, send_buf, pktLen, pbFlag); + + if (ret == HCI_SUCCESS ) { + osal_bm_free(send_buf); + return -ret; + } + } + else + { + return -EINVAL; + } + + + + return len; +} + +/**************************************************************************** + * Name: pplus_ble_close + * + * Description: + * ESP32-C3 BLE close callback function for BT driver. + * + * Input Parameters: + * drv - BT driver pointer + * + * Returned Value: + * None + * + ****************************************************************************/ +static void pplus_ble_close(struct bt_driver_s *drv) +{ +} + +/**************************************************************************** + * Name: pplus_ble_open + * + * Description: + * ESP32-C3 BLE open callback function for BT driver. + * + * Input Parameters: + * drv - BT driver pointer + * + * Returned Value: + * OK on success or a negated value on failure. + * + ****************************************************************************/ + +static int pplus_ble_open(struct bt_driver_s *drv) +{ + return OK; +} + + +extern uint8_t hciCtrlCmdToken; +int drv_disable_irq1(void) +{ + return 0; +} +int drv_enable_irq1(void) +{ + return 0; +} + +int pplus_ble_initialize(void) +{ + int ret; + + JUMP_FUNCTION(OSAL_MSG_SEND) = pplus_ble_recv_msg; + JUMP_FUNCTION(HAL_DRV_IRQ_DISABLE) = drv_disable_irq1; + JUMP_FUNCTION(HAL_DRV_IRQ_ENABLE) = drv_enable_irq1; + hciCtrlCmdToken = 1; +#if defined(CONFIG_UART_BTH4) + ret = uart_bth4_register("/dev/ttyBLE", &g_pplus_ble.drv); +#else + ret = bt_netdev_register(&g_pplus_ble.drv); +#endif + if (ret < 0) + { + wlerr("bt_netdev_register error: %d\n", ret); + return ret; + } + + return OK; +} + + + diff --git a/arch/arm/src/phy62xx/phy62xx_ble_hcitl_swap.c b/arch/arm/src/phy62xx/phy62xx_ble_hcitl_swap.c new file mode 100644 index 00000000000..77c68e5b7a6 --- /dev/null +++ b/arch/arm/src/phy62xx/phy62xx_ble_hcitl_swap.c @@ -0,0 +1,1628 @@ + +typedef hciStatus_t (*hciFunc_t)( uint8* pBuf ); +typedef struct +{ + uint16 opCode; + hciFunc_t hciFunc; +} hciCmdFunc_t; +typedef const hciCmdFunc_t cmdPktTable_t; + + + + + +void HCI_CommandCompleteEvent( uint16 opcode, uint8 numParam, uint8* param ); +void HCI_CommandStatusEvent( hciStatus_t status, uint16 opcode); + + +hciStatus_t hciDisconnect( uint8* pBuf ) +{ + llStatus_t ll_st = LL_Disconnect(BUILD_UINT16(pBuf[0],pBuf[1]), pBuf[2]); + HCI_CommandStatusEvent( ll_st, HCI_DISCONNECT ); + return( HCI_SUCCESS ); + +} + + + +hciStatus_t hciReadRemoteVersionInfo( uint8* pBuf ) +{ + hciStatus_t status; + HCI_CommandStatusEvent( HCI_SUCCESS, HCI_READ_REMOTE_VERSION_INFO ); + status = LL_ReadRemoteVersionInfo(BUILD_UINT16(pBuf[0], pBuf[1])); + + // check if something went wrong + // Note: If success is returned, then Command Complete is handled by Callback. + if ( status != HCI_SUCCESS ) + { + HCI_CommandCompleteEvent( HCI_READ_REMOTE_VERSION_INFO, sizeof(status), &status ); + } + + return( HCI_SUCCESS ); +} + + + +hciStatus_t hciSetEventMask( uint8* pBuf ) +{ + uint8_t* pMask = pBuf; + + hciStatus_t status; + + // check parameters + if( pMask != NULL ) + { + (void)osal_memcpy( pHciEvtMask, pMask, B_EVENT_MASK_LEN ); + status = HCI_SUCCESS; + } + else // bad parameters + { + status = HCI_ERROR_CODE_INVALID_HCI_CMD_PARAMS; + } + + HCI_CommandCompleteEvent( HCI_SET_EVENT_MASK, sizeof(status), &status ); + return( HCI_SUCCESS ); + +} + + +hciStatus_t hciReset( uint8* pBuf ) +{ + hciStatus_t status; + // unused input parameter; PC-Lint error 715. + (void)pBuf; + + // reset the Link Layer + status = LL_Reset(); + // reset the Bluetooth and the BLE event mask bits + hciInitEventMasks(); + // initialize Controller to Host flow control flag and counter + ctrlToHostEnable = FALSE; + numHostBufs = 0; + // complete the command + HCI_CommandCompleteEvent( HCI_RESET, sizeof(status), &status); + return( HCI_SUCCESS ); +} + + + +hciStatus_t hciReadTransmitPowerLevel( uint8* pBuf ) +{ + // 0: Status + // 1: Connection Handle LSB + // 2: Connection Handle MSB + // 3: Transmit Power Level + uint8 rtnParam[4]; + rtnParam[0] = LL_ReadTxPowerLevel( BUILD_UINT16(pBuf[0],pBuf[1]), + pBuf[2] , + (int8*)&(rtnParam[3]) ); + rtnParam[1] = pBuf[0]; + rtnParam[2] = pBuf[1]; + HCI_CommandCompleteEvent( HCI_READ_TRANSMIT_POWER, sizeof(rtnParam), rtnParam ); + return( HCI_SUCCESS ); + +} + +hciStatus_t hciSetControllerToHostFlowCtrl( uint8* pBuf ) +{ + hciStatus_t status = HCI_SUCCESS; + uint8 flowControlEnable = pBuf[0]; + + // check parameters + if ( (flowControlEnable == HCI_CTRL_TO_HOST_FLOW_CTRL_OFF) || + (flowControlEnable == HCI_CTRL_TO_HOST_FLOW_CTRL_ACL_ON_SYNCH_OFF) || + (flowControlEnable == HCI_CTRL_TO_HOST_FLOW_CTRL_ACL_OFF_SYNCH_ON) || + (flowControlEnable == HCI_CTRL_TO_HOST_FLOW_CTRL_ACL_ON_SYNCH_ON) ) + { + // check the parameter + if( flowControlEnable == HCI_CTRL_TO_HOST_FLOW_CTRL_OFF ) + { + // disable flow control + ctrlToHostEnable = FALSE; + } + else if ( flowControlEnable == HCI_CTRL_TO_HOST_FLOW_CTRL_ACL_ON_SYNCH_OFF ) + { + // enable flow control + ctrlToHostEnable = TRUE; + } + else // other two combinations not supported + { + // so indidicate + status = HCI_ERROR_CODE_UNSUPPORTED_FEATURE_PARAM_VALUE; + } + } + else // bad parameters + { + status = HCI_ERROR_CODE_INVALID_HCI_CMD_PARAMS; + } + + HCI_CommandCompleteEvent( HCI_SET_CONTROLLER_TO_HOST_FLOW_CONTROL, sizeof(status), &status); + return( HCI_SUCCESS );} + + +hciStatus_t hciHostBufferSize( uint8* pBuf ) +{ + uint16 hostTotalNumAclPkts = BUILD_UINT16(pBuf[3], pBuf[4]); + + + hciStatus_t status; + + // check parameters + // Note: Only Number of ACL Packets is supported. The rest of the parameters + // are ignored for now. + if ( hostTotalNumAclPkts == 0 ) + { + status = HCI_ERROR_CODE_INVALID_HCI_CMD_PARAMS; + } + else // parameter okay + { + status = HCI_SUCCESS; + // so save in a counter + numHostBufs = hostTotalNumAclPkts; + } + + HCI_CommandCompleteEvent( HCI_HOST_BUFFER_SIZE, sizeof(status), &status ); + return( HCI_SUCCESS ); + +} + + +hciStatus_t hciHostNumCompletedPkt( uint8* pBuf ) +{ + uint16 connHandles, numCompletedPkts; + uint8 numHandles = pBuf[0]; + connHandles = BUILD_UINT16(pBuf[1], pBuf[2]); + numCompletedPkts = BUILD_UINT16(pBuf[3], pBuf[4]); + + + if ( (numHandles != 0) && (connHandles != NULL) && + ((numCompletedPkts != NULL) && (*numCompletedPkts != 0)) ) + { + // check if flow control is enabled + if ( ctrlToHostEnable == TRUE ) + { + // check if the number of Host buffers was previously exhausted + if ( numHostBufs == 0 ) + { + // yes, so disable LL Rx flow control + (void)LL_CtrlToHostFlowControl( LL_DISABLE_RX_FLOW_CONTROL ); + } + + for (uint8 i=0; i LL_MAX_ADV_SET || number_of_sets == 0) + return 0x12; + + for (int i = 0; i < number_of_sets; i++) + { + adv_handler[i] = pBuf[2 + i * 4]; + duration[i] = BUILD_UINT16(pBuf[3 + i * 4], pBuf[4 + i * 4]); + max_ext_adv_evt[i] = pBuf[5 + i * 4]; + } + + return HCI_LE_SetExtAdvEnableCmd (pBuf[0], + number_of_sets, // uint8 number_of_sets, + adv_handler, // uint8 *advertising_handle, + duration, // uint16 *duration, + max_ext_adv_evt // uint8 *max_extended_advertising_events + ); +} + +hciStatus_t hciLEReadMaximumAdvDataLength ( uint8* pBuf ) +{ + return HCI_LE_ReadMaximumAdvDataLengthCmd(); +} + +hciStatus_t hciLEReadNumberOfSupportAdvSet ( uint8* pBuf ) +{ + return HCI_LE_ReadNumberOfSupportAdvSetCmd(); +} + +hciStatus_t hciLERemoveAdvSet ( uint8* pBuf ) +{ + return HCI_LE_RemoveAdvSetCmd(pBuf[0]); +} + +hciStatus_t hciLEClearAdvSets ( uint8* pBuf ) +{ + return HCI_LE_ClearAdvSetsCmd(); +} + + +hciStatus_t hciLESetPeriodicAdvParameter ( uint8* pBuf ) +{ + return HCI_LE_SetPeriodicAdvParameterCmd(pBuf[0], + BUILD_UINT16(pBuf[1], pBuf[2]), + BUILD_UINT16(pBuf[3], pBuf[4]), + BUILD_UINT16(pBuf[5], pBuf[6]) + ); +} + +hciStatus_t hciLESetPeriodicAdvData ( uint8* pBuf ) +{ + return HCI_LE_SetPeriodicAdvDataCmd (pBuf[0], + pBuf[1], + pBuf[2], + &pBuf[3]); +} + +hciStatus_t hciLESetPeriodicAdvEnable ( uint8* pBuf ) +{ + return HCI_LE_SetPeriodicAdvEnableCmd (pBuf[0], + pBuf[1] + ); +} + +hciStatus_t hciLESetExtendedScanParameters ( uint8* pBuf ) +{ + uint8 scanPhy, numPhy, offset = 3; + uint8 scan_types[2]; + uint16 scan_interval[2], scan_window[2]; + scanPhy = pBuf[2]; + numPhy = (scanPhy & LL_SCAN_PHY_1M_BITMASK) + ((scanPhy & LL_SCAN_PHY_CODED_BITMASK) >> 2); + + for (int i = 0; i < numPhy; i++) + { + scan_types[i] = pBuf[offset]; + offset ++; + scan_interval[i] = BUILD_UINT16(pBuf[offset], pBuf[offset + 1]); + offset += 2; + scan_window[i] = BUILD_UINT16(pBuf[offset], pBuf[offset + 1]); + offset += 2; + } + + return HCI_LE_SetExtendedScanParametersCmd(pBuf[0], + pBuf[1], + pBuf[2], + scan_types, // uint8 *scan_sype, + scan_interval, // uint16 *scan_interval + scan_window); // uint16 *scan_window +} + +hciStatus_t hciLESetExtendedScanEnableCmd ( uint8* pBuf ) +{ + return HCI_LE_SetExtendedScanEnableCmd (pBuf[0], + pBuf[1], + BUILD_UINT16(pBuf[2], pBuf[3]), + BUILD_UINT16(pBuf[4], pBuf[5])); +} + +hciStatus_t hciLEExtendedCreateConnection ( uint8* pBuf ) +{ + uint8 initPhy = pBuf[9], numPhy; + uint8 offset; + uint16 scan_interval[3]; + uint16 scan_window[3]; + uint16 conn_interval_min[3]; + uint16 conn_interval_max[3]; + uint16 conn_latency[3]; + uint16 supervision_timeout[3]; + uint16 minimum_CE_length[3]; + uint16 maximum_CE_length[3]; + numPhy = (initPhy & 0x01) + + ((initPhy & 0x02) >> 1) + + ((initPhy & 0x04) >> 2); + offset = 10; + + for (int i = 0; i < numPhy; i++) + { + scan_interval[i] = BUILD_UINT16(pBuf[offset], pBuf[offset + 1]); + offset += 2; + scan_window[i] = BUILD_UINT16(pBuf[offset], pBuf[offset + 1]); + offset += 2; + conn_interval_min[i] = BUILD_UINT16(pBuf[offset], pBuf[offset + 1]); + offset += 2; + conn_interval_max[i] = BUILD_UINT16(pBuf[offset], pBuf[offset + 1]); + offset += 2; + conn_latency[i] = BUILD_UINT16(pBuf[offset], pBuf[offset + 1]); + offset += 2; + supervision_timeout[i] = BUILD_UINT16(pBuf[offset], pBuf[offset + 1]); + offset += 2; + minimum_CE_length[i] = BUILD_UINT16(pBuf[offset], pBuf[offset + 1]); + offset += 2; + maximum_CE_length[i] = BUILD_UINT16(pBuf[offset], pBuf[offset + 1]); + offset += 2; + } + + return HCI_LE_ExtendedCreateConnectionCmd(pBuf[0], // uint8 initiator_filter_policy, + pBuf[1], // uint8 own_address_type, + pBuf[2], // uint8 peer_address_type, + &pBuf[3], // uint8 *peer_address, + pBuf[9], // uint8 initiating_PHYs, + scan_interval, // uint16 *scan_interval, + scan_window, // uint16 *scan_window, + conn_interval_min, // uint16 *conn_interval_min, + conn_interval_max, // uint16 *conn_interval_max, + conn_latency, // uint16 *conn_latency, + supervision_timeout, // uint16 *supervision_timeout, + minimum_CE_length, // uint16 *minimum_CE_length, + maximum_CE_length); // uint16 *maximum_CE_length) +} + + +hciStatus_t hciLEPeriodicAdvertisingCreateSync ( uint8* pBuf ) +{ + return HCI_LE_PeriodicAdvertisingCreateSyncCmd (pBuf[0], + pBuf[1], + pBuf[2], + &pBuf[3], + BUILD_UINT16(pBuf[9], pBuf[10]), + BUILD_UINT16(pBuf[11], pBuf[12]), + pBuf[13]); +} + +hciStatus_t hciLEPeriodicAdvertisingCreateSyncCancel ( uint8* pBuf ) +{ + return HCI_LE_PeriodicAdvertisingCreateSyncCancelCmd (); +} + +hciStatus_t hciLEPeriodicAdvertisingTerminateSync ( uint8* pBuf ) +{ + return HCI_LE_PeriodicAdvertisingTerminateSyncCmd (BUILD_UINT16(pBuf[0], pBuf[1])); +} + + +hciStatus_t hciLEAddDevToPeriodicAdvList ( uint8* pBuf ) +{ + return HCI_LE_AddDevToPeriodicAdvListCmd (pBuf[0], + &pBuf[1], + pBuf[7]); +} + +hciStatus_t hciLERemovePeriodicAdvList ( uint8* pBuf ) +{ + return HCI_LE_RemovePeriodicAdvListCmd (pBuf[0], + &pBuf[1], + pBuf[7]); +} + +hciStatus_t hciLEClearPeriodicAdvList ( uint8* pBuf ) +{ + return HCI_LE_ClearPeriodicAdvListCmd (); +} + +hciStatus_t hciLEReadPeriodicAdvListSize ( uint8* pBuf ) +{ + return HCI_LE_ReadPeriodicAdvListSizeCmd (); +} + + +hciStatus_t hciLEReadTransmitPower ( uint8* pBuf ) +{ + return HCI_LE_Read_Transmit_PowerCmd (); +} + +hciStatus_t hciLEReadRfPathCompensation ( uint8* pBuf ) +{ + return HCI_LE_Read_Rf_Path_CompensationCmd (); +} + +hciStatus_t hciLEWriteRfPathCompensation ( uint8* pBuf ) +{ + return HCI_LE_Write_Rf_Path_CompensationCmd (BUILD_UINT16(pBuf[0], pBuf[1]), + BUILD_UINT16(pBuf[2], pBuf[3])); +} + +hciStatus_t hciLESetPrivacyMode ( uint8* pBuf ) +{ + return HCI_LE_Set_Privacy_ModeCmd (pBuf[0], + &pBuf[1], + pBuf[7]); +} + + + + + +hciStatus_t hciLE_ConnectionlessCTE_TransmitParamCmd(uint8* pBuf) +{ + return (HCI_LE_ConnectionlessCTE_TransmitParamCmd( pBuf[0], // uint8 advertising_handle, + pBuf[1], // uint8 len, + pBuf[2], // uint8 type, + pBuf[3], // uint8 count, + pBuf[4], // uint8 Pattern_LEN, + &pBuf[5] // uint8 *AnaIDs) + )); +} +hciStatus_t hciLE_ConnectionlessCTE_TransmitEnableCmd(uint8* pBuf) +{ + return (HCI_LE_ConnectionlessCTE_TransmitEnableCmd( pBuf[0], // uint8 advertising_handle, + pBuf[1] // uint8 enable) + )); +} +hciStatus_t hciLE_ConnectionlessIQ_SampleEnableCmd(uint8* pBuf) +{ + return (HCI_LE_ConnectionlessIQ_SampleEnableCmd( BUILD_UINT16(pBuf[0],pBuf[1]),// uint16 sync_handle, + pBuf[2], // uint8 enable, + pBuf[3], // uint8 slot_Duration, + pBuf[4], // uint8 MaxSampledCTEs, + pBuf[5], // uint8 pattern_len, + &pBuf[6] // uint8 *AnaIDs) + )); +} + +hciStatus_t hciLESet_ConnectionCTE_ReceiveParam(uint8* pBuf ) +{ + // record for BQB + llConnState_t* connPtr; + // MAS BV 65 + static uint8 cnt=0; + connPtr = connPtr = &conn_param[0]; + + if( (pBuf[2] == 1) && (connPtr->llConnCTE.enable) ) + connPtr->llConnCTE.enable = FALSE; + +// if( pBuf[2] == 1 ) +// { +// ll_hw_set_cte_rxSupp( CTE_SUPP_AUTO ); +// if( cnt == 0 ) +// { +// connPtr->llConnCTE.CTE_Length = 2; +// cnt = 1; +// } +// else if( cnt == 1 ) +// { +// connPtr->llConnCTE.CTE_Length = 0x0A; +// cnt = 2; +// } +// else if( cnt == 2) +// connPtr->llConnCTE.CTE_Length = 0x14; +// connPtr->llConnCTE.CTE_Type = 0; +// } + return (HCI_LE_Set_ConnectionCTE_ReceiveParamCmd(BUILD_UINT16(pBuf[0],pBuf[1]), //connHandle, + pBuf[2], // enable, + pBuf[3], // slot_Duration, + pBuf[4], // pattern_len, + &pBuf[5])); // *AnaIDs); +} + +hciStatus_t hciLESet_ConnectionCTE_TransmitParam(uint8* pBuf) +{ + return (HCI_LE_Set_ConnectionCTE_TransmitParamCmd( BUILD_UINT16(pBuf[0],pBuf[1]), // connHandle, + pBuf[2], // type, + pBuf[3], //pattern_len, + &pBuf[4])); // *AnaIDs +} + + +// 2020-02-13 periodic cte req & rsp +extern unsigned int CTE_Count_Idx; +hciStatus_t hciLE_ConnectionCTERequestEnable(uint8* pBuf) +{ + // record for BQB + llConnState_t* connPtr; + connPtr = connPtr = &conn_param[0]; + + if( (pBuf[2] == 1) && (connPtr->llCTE_ReqFlag) ) + connPtr->llCTE_ReqFlag= FALSE; + + CTE_Count_Idx = 0; + return (HCI_LE_Connection_CTE_Request_EnableCmd( BUILD_UINT16(pBuf[0],pBuf[1]), // connHandle, + pBuf[2], // enable, + BUILD_UINT16(pBuf[3],pBuf[4]), // Interval, + pBuf[5], // len, + pBuf[6])); // type +} +hciStatus_t hciLE_ConnectionCTEResponseEnable(uint8* pBuf) +{ + // record for BQB + llConnState_t* connPtr; + connPtr = connPtr = &conn_param[0]; + + if( (pBuf[2] == 0) && (connPtr->llConnCTE.enable) ) + connPtr->llConnCTE.enable = FALSE; + + return (HCI_LE_Connection_CTE_Response_EnableCmd(BUILD_UINT16(pBuf[0],pBuf[1]),pBuf[2])); +} + +hciStatus_t hciLE_READ_Anatenna_Info(uint8* pBuf) +{ + return (HCI_LE_READ_Anatenna_InfoCmd()); +} + + + +hciStatus_t hciLESetPrdAdvRecvEnableCmd ( uint8* pBuf ) +{ + return HCI_LE_SetPrdAdvRecvEnableCmd(BUILD_UINT16(pBuf[0], pBuf[1]), + pBuf[2]); +} + + +hciStatus_t hciExtSetRxGain( uint8* pBuf ) +{ + return HCI_EXT_SetRxGainCmd( pBuf[0] ); +} + +hciStatus_t hciExtSetTxPower( uint8* pBuf ) +{ + return HCI_EXT_SetTxPowerCmd( pBuf[0] ); +} + +hciStatus_t hciExtExtendRfRange( uint8* pBuf ) +{ + // unused input parameter; PC-Lint error 715. + (void)pBuf; + return HCI_EXT_ExtendRfRangeCmd(); +} + + +hciStatus_t hciExtHaltDuringRf( uint8* pBuf ) +{ + return HCI_EXT_HaltDuringRfCmd( pBuf[0] ); +} + +hciStatus_t hciExtOnePktPerEvt( uint8* pBuf ) +{ + return HCI_EXT_OnePktPerEvtCmd( pBuf[0] ); +} + +hciStatus_t hciExtClkDivOnHalt( uint8* pBuf ) +{ + return HCI_EXT_ClkDivOnHaltCmd( pBuf[0] ); +} + + +hciStatus_t hciExtDeclareNvUsage( uint8* pBuf ) +{ + return HCI_EXT_DeclareNvUsageCmd( pBuf[0] ); +} + +hciStatus_t hciExtDecrypt( uint8* pBuf ) +{ + // reverse byte order of key (MSB..LSB required) + HCI_ReverseBytes( &pBuf[0], KEYLEN ); + // reverse byte order of encText (MSB..LSB required) + HCI_ReverseBytes( &pBuf[KEYLEN], KEYLEN ); + return HCI_EXT_DecryptCmd( &pBuf[0], + &pBuf[KEYLEN] ); +} + + +hciStatus_t hciExtSetLocalSupportedFeatures( uint8* pBuf ) +{ + return HCI_EXT_SetLocalSupportedFeaturesCmd( pBuf ); +} + + +hciStatus_t hciExtSetFastTxResponseTime( uint8* pBuf ) +{ + return HCI_EXT_SetFastTxResponseTimeCmd( pBuf[0] ); +} + +hciStatus_t hciExtSetSlaveLatencyOverride( uint8* pBuf ) +{ + return HCI_EXT_SetSlaveLatencyOverrideCmd( pBuf[0] ); +} + + +hciStatus_t hciExtModemTestTx( uint8* pBuf ) +{ + return HCI_EXT_ModemTestTxCmd( pBuf[0], pBuf[1] ); +} + + +hciStatus_t hciExtModemHopTestTx( uint8* pBuf ) +{ + return HCI_EXT_ModemHopTestTxCmd(); +} + + +hciStatus_t hciExtModemtestRx( uint8* pBuf ) +{ + return HCI_EXT_ModemTestRxCmd( pBuf[0] ); +} + + +hciStatus_t hciExtEndModemTest( uint8* pBuf ) +{ + return HCI_EXT_EndModemTestCmd(); +} + + +hciStatus_t hciExtSetBDADDR( uint8* pBuf ) +{ + return HCI_EXT_SetBDADDRCmd( pBuf ); +} + + +hciStatus_t hciExtSetSCA( uint8* pBuf ) +{ + return HCI_EXT_SetSCACmd( BUILD_UINT16(pBuf[0], pBuf[1]) ); +} + + +hciStatus_t hciExtSetMaxDtmTxPower( uint8* pBuf ) +{ + return HCI_EXT_SetMaxDtmTxPowerCmd( pBuf[0] ); +} + + + +hciStatus_t hciExtMapPmIoPort( uint8* pBuf ) +{ +// return HCI_EXT_MapPmIoPortCmd( pBuf[0], +// pBuf[1] ); + return (HCI_SUCCESS); +} + + +hciStatus_t hciExtSetFreqTune( uint8* pBuf ) +{ + return HCI_EXT_SetFreqTuneCmd( pBuf[0] ); +} + + +hciStatus_t hciExtSaveFreqTune( uint8* pBuf ) +{ + return HCI_EXT_SaveFreqTuneCmd(); +} + + +hciStatus_t hciExtDisconnectImmed( uint8* pBuf ) +{ + return HCI_EXT_DisconnectImmedCmd ( BUILD_UINT16(pBuf[0], + pBuf[1]) ); +} + + +hciStatus_t hciExtPER( uint8* pBuf ) +{ + return HCI_EXT_PacketErrorRateCmd ( BUILD_UINT16(pBuf[0], + pBuf[1]), + pBuf[2] ); +} + + +hciStatus_t hciExtOverlappedProcessing( uint8* pBuf ) +{ + return HCI_EXT_OverlappedProcessingCmd ( pBuf[0] ); +} + + +hciStatus_t hciExtNumComplPktsLimit( uint8* pBuf ) +{ + return HCI_EXT_NumComplPktsLimitCmd( pBuf[0], + pBuf[1] ); +} + + + +hciStatus_t hciExtBuildRevision( uint8* pBuf ) +{ + // unused input parameter; PC-Lint error 715. + (void)pBuf; + return HCI_EXT_BuildRevisionCmd( pBuf[0], BUILD_UINT16( pBuf[1], + pBuf[2]) ); +} + + +hciStatus_t hciExtDelaySleep( uint8* pBuf ) +{ + return HCI_EXT_DelaySleepCmd( BUILD_UINT16(pBuf[0], pBuf[1]) ); +} + + +hciStatus_t hciExtResetSystem( uint8* pBuf ) +{ + return HCI_EXT_ResetSystemCmd( pBuf[0] ); +} + + +// ================ +hciStatus_t hciLEReadMaxDataLength ( uint8* pBuf ) +{ + return HCI_LE_ReadMaxDataLengthCmd (); +} + + +// HCI Packet Opcode Jump Table +cmdPktTable_t hciCmdTable[] = +{ + // Linker Control Commands + {HCI_DISCONNECT, hciDisconnect }, + {HCI_READ_REMOTE_VERSION_INFO, hciReadRemoteVersionInfo }, + + // Controller and Baseband Commands + {HCI_SET_EVENT_MASK, hciSetEventMask }, + {HCI_RESET, hciReset }, + + {HCI_READ_TRANSMIT_POWER, hciReadTransmitPowerLevel }, + {HCI_SET_CONTROLLER_TO_HOST_FLOW_CONTROL, hciSetControllerToHostFlowCtrl }, + {HCI_HOST_BUFFER_SIZE, hciHostBufferSize }, + {HCI_HOST_NUM_COMPLETED_PACKETS, hciHostNumCompletedPkt }, + {HCI_SET_EVENT_MASK_PAGE2,hciSetEventMaskPage2}, + + +// Informational Parameters + {HCI_READ_LOCAL_VERSION_INFO, hciReadLocalVersionInfo }, + {HCI_READ_LOCAL_SUPPORTED_COMMANDS, hciReadLocalSupportedCommands }, + {HCI_READ_LOCAL_SUPPORTED_FEATURES, hciReadLocalSupportedFeatures }, + {HCI_READ_BDADDR, hciReadBDADDR }, + {HCI_READ_RSSI, hciReadRssi }, + + // LE Commands + {HCI_LE_SET_EVENT_MASK, hciLESetEventMask }, + {HCI_LE_READ_BUFFER_SIZE, hciLEReadBufSize }, + {HCI_LE_READ_LOCAL_SUPPORTED_FEATURES, hciLEReadLocalSupportedFeatures }, + {HCI_LE_SET_RANDOM_ADDR, hciLESetRandomAddr }, + + {HCI_LE_SET_ADV_PARAM, hciLESetAdvParam }, + {HCI_LE_SET_ADV_DATA, hciLESetAdvData }, + {HCI_LE_SET_SCAN_RSP_DATA, hciLESetScanRspData }, + {HCI_LE_SET_ADV_ENABLE, hciLESetAdvEnab }, + {HCI_LE_READ_ADV_CHANNEL_TX_POWER, hciLEReadAdvChanTxPower }, + + {HCI_LE_SET_SCAN_PARAM, hciLESetScanParam }, + {HCI_LE_SET_SCAN_ENABLE, hciLESetScanEnable }, + + {HCI_LE_CREATE_CONNECTION, hciLECreateConn }, + {HCI_LE_CREATE_CONNECTION_CANCEL, hciLECreateConnCancel }, + + {HCI_LE_READ_WHITE_LIST_SIZE, hciLEReadWhiteListSize }, + {HCI_LE_CLEAR_WHITE_LIST, hciLEClearWhiteList }, + {HCI_LE_ADD_WHITE_LIST, hciLEAddWhiteList }, + {HCI_LE_REMOVE_WHITE_LIST, hciLERemoveWhiteList }, + + {HCI_LE_CONNECTION_UPDATE, hciLEConnUpdate }, + {HCI_LE_SET_HOST_CHANNEL_CLASSIFICATION, hciLESetHostChanClass }, + {HCI_LE_READ_CHANNEL_MAP, hciLEReadChanMap }, + {HCI_LE_READ_REMOTE_USED_FEATURES, hciLEReadRemoteUsedFeatures }, + + {HCI_LE_ENCRYPT, hciLEEncrypt }, + {HCI_LE_RAND, hciLERand }, + + {HCI_LE_START_ENCRYPTION, hciLEStartEncrypt }, + + {HCI_LE_LTK_REQ_REPLY, hciLELtkReqReply }, + {HCI_LE_LTK_REQ_NEG_REPLY, hciLELtkReqNegReply }, + + {HCI_LE_READ_SUPPORTED_STATES, hciLEReadSupportedStates }, + {HCI_LE_RECEIVER_TEST, hciLEReceiverTest }, + {HCI_LE_TRANSMITTER_TEST, hciLETransmitterTest }, + {HCI_LE_TEST_END, hciLETestEnd }, + {HCI_LE_SET_DATA_LENGTH, hciLESetDataLength }, + + {HCI_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH, hciLEReadSuggestedDefaultDataLength }, + {HCI_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH, hciLEWriteSuggestedDefaultDataLength }, + {HCI_LE_READ_PHY, hciLEReadPhyMode }, + {HCI_LE_SET_DEFAULT_PHY, hciLESetDefaultPhyMode }, + {HCI_LE_SET_PHY, hciLESetPhyMode }, + +// ===== 2020-07 add, RPA + {HCI_LE_ADD_DEVICE_TO_RESOLVING_LIST, hciLEAddDeviceToRL }, + {HCI_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST, hciLERemoveDeviceFromRL }, + {HCI_LE_CLEAR_RESOLVING_LIST, hciLEClearRL }, + {HCI_LE_READ_RESOLVING_LIST_SIZE, hciLEReadRLSize }, + {HCI_LE_READ_PEER_RESOLVABLE_ADDRESS, hciLEReadPeerRA }, + {HCI_LE_READ_LOCAL_RESOLVABLE_ADDRESS, hciLEReadLocalRA }, + {HCI_LE_SET_ADDRESS_RESOLUTION_ENABLE, hciLESetAddrResolutionEnable }, + {HCI_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TO, hciLESetRpaTo }, + {HCI_LE_READ_MAXIMUM_DATA_LENGTH, hciLEReadMaxDataLength }, + + + // extended adv + {HCI_LE_SET_ADVERTISING_SET_RANDOM_ADDRESS, hciLESetAdvSetRandomAddress}, + {HCI_LE_SET_EXTENDER_ADVERTISING_PARAMETERS, hciLESetExtAdvParam }, + {HCI_LE_SET_EXTENDED_ADVERTISING_DATA, hciLESetExtAdvData }, + {HCI_LE_Set_EXTENDED_SCAN_RESPONSE_DATA, hciLESetExtScanRspData }, + {HCI_LE_Set_EXTENDED_ADVERTISING_ENABLE, hciLESetExtAdvEnable }, + {HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH, hciLEReadMaximumAdvDataLength}, + {HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS, hciLEReadNumberOfSupportAdvSet}, + {HCI_LE_REMOVE_ADVERTISING_SET, hciLERemoveAdvSet }, + {HCI_LE_CLEAR_ADVERTISING_SETS, hciLEClearAdvSets }, + + // periodic adv + {HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS, hciLESetPeriodicAdvParameter}, + {HCI_LE_SET_PERIODIC_ADVERTISING_DATA, hciLESetPeriodicAdvData }, + {HCI_LE_Set_PERIODIC_ADVERTISING_ENABLE, hciLESetPeriodicAdvEnable }, + + // extended scan + {HCI_LE_SET_EXTENDED_SCAN_PARAMETERS, hciLESetExtendedScanParameters }, + {HCI_LE_SET_EXTENDED_SCAN_ENABLE, hciLESetExtendedScanEnableCmd }, + {HCI_LE_EXTENDED_CREATE_CONNECTION, hciLEExtendedCreateConnection }, + + // periodic scan + {HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC, hciLEPeriodicAdvertisingCreateSync }, + {HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL, hciLEPeriodicAdvertisingCreateSyncCancel }, + {HCI_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC, hciLEPeriodicAdvertisingTerminateSync }, + + {HCI_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST, hciLEAddDevToPeriodicAdvList }, + {HCI_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST, hciLERemovePeriodicAdvList }, + {HCI_LE_CLEAR_PERIODIC_ADVERTISER_LIST, hciLEClearPeriodicAdvList }, + {HCI_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE, hciLEReadPeriodicAdvListSize }, + + {HCI_LE_READ_TRANSMIT_POWER, hciLEReadTransmitPower }, + {HCI_LE_READ_RF_PATH_COMPENSATION, hciLEReadRfPathCompensation }, + {HCI_LE_WRITE_RF_PATH_COMPENSATION, hciLEWriteRfPathCompensation }, + + {HCI_LE_SET_PRIVACY_MODE, hciLESetPrivacyMode}, + + // 2020-10-27 CTE + {HCI_LE_SET_CONNLESS_CTE_TRANS_PARAMETER, hciLE_ConnectionlessCTE_TransmitParamCmd }, + {HCI_LE_SET_CONNLESS_CTE_TRANS_ENABLE, hciLE_ConnectionlessCTE_TransmitEnableCmd}, + {HCI_LE_SET_CONNLESS_IQ_SAMPLE_ENABLE, hciLE_ConnectionlessIQ_SampleEnableCmd}, + {HCI_LE_SET_CONNCTE_RECV_PARAMETER, hciLESet_ConnectionCTE_ReceiveParam}, + {HCI_LE_SET_CONN_CTE_TRANSMIT_PARAMETER, hciLESet_ConnectionCTE_TransmitParam}, + {HCI_LE_CONN_CTE_REQUEST_ENABLE, hciLE_ConnectionCTERequestEnable}, + {HCI_LE_CONN_CTE_RESPONSE_ENABLE, hciLE_ConnectionCTEResponseEnable}, + {HCI_LE_READ_ANTENNA_INFO, hciLE_READ_Anatenna_Info}, + {HCI_LE_SET_PERIODIC_ADV_RECV_ENABLE, hciLESetPrdAdvRecvEnableCmd}, + + // Vendor Specific Commands + {HCI_EXT_SET_RX_GAIN, hciExtSetRxGain }, + {HCI_EXT_SET_TX_POWER, hciExtSetTxPower }, + {HCI_EXT_EXTEND_RF_RANGE, hciExtExtendRfRange }, + {HCI_EXT_HALT_DURING_RF, hciExtHaltDuringRf }, + + {HCI_EXT_ONE_PKT_PER_EVT, hciExtOnePktPerEvt }, + + {HCI_EXT_CLK_DIVIDE_ON_HALT, hciExtClkDivOnHalt }, + {HCI_EXT_DECLARE_NV_USAGE, hciExtDeclareNvUsage }, + + {HCI_EXT_DECRYPT, hciExtDecrypt }, + {HCI_EXT_SET_LOCAL_SUPPORTED_FEATURES, hciExtSetLocalSupportedFeatures }, + + {HCI_EXT_SET_FAST_TX_RESP_TIME, hciExtSetFastTxResponseTime }, + {HCI_EXT_OVERRIDE_SL, hciExtSetSlaveLatencyOverride }, + + {HCI_EXT_MODEM_TEST_TX, hciExtModemTestTx }, + {HCI_EXT_MODEM_HOP_TEST_TX, hciExtModemHopTestTx }, + {HCI_EXT_MODEM_TEST_RX, hciExtModemtestRx }, + {HCI_EXT_END_MODEM_TEST, hciExtEndModemTest }, + {HCI_EXT_SET_BDADDR, hciExtSetBDADDR }, + + {HCI_EXT_SET_SCA, hciExtSetSCA }, + + {HCI_EXT_SET_MAX_DTM_TX_POWER, hciExtSetMaxDtmTxPower }, + {HCI_EXT_MAP_PM_IO_PORT , hciExtMapPmIoPort }, + {HCI_EXT_SET_FREQ_TUNE, hciExtSetFreqTune }, + {HCI_EXT_SAVE_FREQ_TUNE, hciExtSaveFreqTune }, + + {HCI_EXT_DISCONNECT_IMMED, hciExtDisconnectImmed }, + {HCI_EXT_PER, hciExtPER }, + {HCI_EXT_OVERLAPPED_PROCESSING, hciExtOverlappedProcessing }, + {HCI_EXT_NUM_COMPLETED_PKTS_LIMIT, hciExtNumComplPktsLimit }, + + {HCI_EXT_BUILD_REVISION, hciExtBuildRevision }, + {HCI_EXT_DELAY_SLEEP, hciExtDelaySleep }, + // TEMP: OVERLAPPED PROCESSING HOLDER + {HCI_EXT_RESET_SYSTEM, hciExtResetSystem }, + + // Last Table Entry Delimiter + {0xFFFF, NULL } +}; + + +void hciProcessHostToCtrlCmd( uint8_t* pData ) +{ + uint16 cmdOpCode; + uint8 status; + uint8 i = 0; + // retrieve opcode + cmdOpCode = BUILD_UINT16 (pData[1], pData[2]); + + // lookup corresponding function + while ((hciCmdTable[i].opCode != 0xFFFF) && (hciCmdTable[i].hciFunc != NULL)) + { + // there's a valid entry at this index, but check if it's the one we want + if (hciCmdTable[i].opCode == cmdOpCode) + { + // it is, so jump to this function + (void)(hciCmdTable[i].hciFunc)(&pData[4]); + // done + break; + } + + // next... + i++; + } + + // check if a matching opcode was found + if ((hciCmdTable[i].opCode == 0xFFFF) && (hciCmdTable[i].hciFunc == NULL)) + { + // none found, so return error + status = BT_HCI_ERR_UNKNOWN_CMD; + HCI_CommandCompleteEvent ( cmdOpCode, 1, &status); + } + + return; +} + + + diff --git a/arch/arm/src/phy62xx/phy62xx_ble_patch.c b/arch/arm/src/phy62xx/phy62xx_ble_patch.c new file mode 100644 index 00000000000..d4a806c0c69 --- /dev/null +++ b/arch/arm/src/phy62xx/phy62xx_ble_patch.c @@ -0,0 +1,8521 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +#include +#include + +//#include "common.h" +//#include "uart.h" +//#include "dma.h" +//#include "flash.h" +//#include "gpio_rom.h" +//#include "i2c.h" +//#include "i2s.h" +//#include "spi.h" +//#include "timer.h" +#include "rom_sym_def.h" + +#include "types.h" +#include "ll.h" +#include "rf_phy_driver.h" +#include "global_config.h" +#include "jump_function.h" +#include "uart.h" +#include "ll_sleep.h" +#include "ll_debug.h" +#include "ll.h" +#include "bus_dev.h" +#include "ll_hw_drv.h" +#include "gpio.h" +#include "ll_enc.h" +#include "OSAL_Clock.h" +#include "osal_bufmgr.h" +#include "OSAL_Memory.h" +#include "log.h" +#include "hci.h" +#include "hci_tl.h" +#include "version.h" +#include "flash.h" +#include "gatt.h" +#include "att.h" +#include "error.h" +#include "clock.h" +#include +#include +#include +//======================================================== +// build config +//#define __BUILD_RF_LIB_SLA__ (0x1) +//#define __BUILD_RF_LIB_MST__ (0x2) +//#define __BUILD_RF_LIB_MULTI__ ( __BUILD_RF_LIB_MST__ | __BUILD_RF_LIB_SLA__ ) +// +//#ifndef __BUILD_PATCH_CFG__ +// #define __BUILD_PATCH_CFG__ __BUILD_RF_LIB_MST__ +//#endif + + +#define DBG_BUILD_LL_TIMING 0 //0x01 for enable LL timing debug + +int hal_uart_send_buff(UART_INDEX_e uart_index,uint8_t* buff,uint16_t len); + +#define logx(...) {char tmp_str[128]; sprintf(tmp_str, __VA_ARGS__); hal_uart_send_buff(0, tmp_str , strlen(tmp_str)+1);} + +// ====================== +#define DBG_GPIO_WRITE(a,b) gpio_write((a),(b)) +//#define DBG_GPIO_WRITE(a,b) +#define DBGIO_LL_TRIG P23 +#define DBGIO_LL_IRQ P24 +#define DBGIO_APP_WAKEUP P18 +#define DBGIO_APP_SLEEP P20 +#define DBGIO_DIS_IRQ P11 +#define DBGIO_EN_IRQ P34 + +#define LL_HW_MODE_STX 0x00 +#define LL_HW_MODE_SRX 0x01 +#define LL_HW_MODE_TRX 0x02 +#define LL_HW_MODE_RTX 0x03 +#define LL_HW_MODE_TRLP 0x04 +#define LL_HW_MODE_RTLP 0x05 + +// =============== add in A2 for simultaneous slave and adv/scan +#define LL_SEC_STATE_IDLE 0x00 +#define LL_SEC_STATE_SCAN 0x01 +#define LL_SEC_STATE_ADV 0x02 +#define LL_SEC_STATE_SCAN_PENDING 0x03 +#define LL_SEC_STATE_ADV_PENDING 0x04 +#define LL_SEC_STATE_IDLE_PENDING 0x05 +#define LL_SEC_STATE_INIT 0x06 +#define LL_SEC_STATE_INIT_PENDING 0x07 + +#define WFI() __WFI() + +#define LL_MODE_INVALID 0xFF +#define LL_MODE_LEGACY 0x00 +#define LL_MODE_EXTENDED 0x01 + +#define LL_COPY_DEV_ADDR_LE( dstPtr, srcPtr ) { \ + (dstPtr)[0] = (srcPtr)[0]; \ + (dstPtr)[1] = (srcPtr)[1]; \ + (dstPtr)[2] = (srcPtr)[2]; \ + (dstPtr)[3] = (srcPtr)[3]; \ + (dstPtr)[4] = (srcPtr)[4]; \ + (dstPtr)[5] = (srcPtr)[5];} + +#define LL_WINDOW_SIZE 2 // 2.5ms in 1.25ms ticks + +#define LL_CALC_NEXT_SCAN_CHN(chan) { chan ++; \ + chan = (chan > LL_SCAN_ADV_CHAN_39) ? LL_SCAN_ADV_CHAN_37 : chan;} + +#define CONN_CSA2_ALLOW 0x00000080 + +//------------------------------------------------------------------------------------ +//extern rom function +// +//extern int gpio_write(gpio_pin_e pin, bit_action_e en); +extern uint8 ll_processExtAdvIRQ(uint32_t irq_status); +extern uint8 ll_processPrdAdvIRQ(uint32_t irq_status); +extern uint8 ll_processExtScanIRQ(uint32_t irq_status); +extern uint8 ll_processExtInitIRQ(uint32_t irq_status); +extern uint8 ll_processPrdScanIRQ(uint32_t irq_status); +extern uint8 ll_processBasicIRQ(uint32_t irq_status); +extern int clear_timer_int(AP_TIM_TypeDef* TIMx); +extern uint8 isTimer1Running(void); +extern uint8 isTimer4Running(void); +extern void clear_timer(AP_TIM_TypeDef* TIMx); + +extern uint8 ll_processMissMasterEvt(uint8 connId); +extern uint8 ll_processMissSlaveEvt(uint8 connId); +extern int gpio_write(GPIO_Pin_e pin, uint8_t en); +extern void ll_hw_tx2rx_timing_config(uint8 pkt); +extern void wakeup_init0(void); +extern void enter_sleep_off_mode0(Sleep_Mode mode); +extern void spif_release_deep_sleep(void); +extern void spif_set_deep_sleep(void); + +extern uint8 ll_hw_get_tr_mode(void); +extern int ll_hw_get_rfifo_depth(void); +extern void move_to_master_function(void); + +extern struct buf_tx_desc g_tx_adv_buf; +extern struct buf_tx_desc g_tx_ext_adv_buf; +extern struct buf_tx_desc tx_scanRsp_desc; + +extern struct buf_rx_desc g_rx_adv_buf; + +extern chipMAddr_t g_chipMAddr; + +extern uint8 g_llAdvMode; +extern uint32_t g_llHdcDirAdvTime; +//----------------------------------------------------------------------------------- +//extern rom variable +// +uint32* pGlobal_config = NULL; + +const unsigned char libRevisionDate[]=__DATE__; +const unsigned char libRevisionTime[]=__TIME__; + +uint8 CreateConn_Flag = FALSE; +uint32_t g_t_llhwgo = 0; + +extern uint32 hclk_per_us; +extern uint32 hclk_per_us_shift; +extern volatile uint8 g_clk32K_config; +///////////////////////// + +extern uint32 sleep_flag; +extern uint32 osal_sys_tick; +extern uint32 ll_remain_time; + +extern uint32 llWaitingIrq; +extern uint32 ISR_entry_time; + +extern uint32 counter_tracking; + +extern uint32_t __initial_sp; +extern uint32_t g_smartWindowSize; +extern volatile uint8_t g_same_rf_channel_flag; +extern uint32_t g_TIM2_IRQ_TIM3_CurrCount; +extern uint32_t g_TIM2_IRQ_to_Sleep_DeltTick; +extern uint32_t g_TIM2_IRQ_PendingTick; +extern uint32_t g_osal_tick_trim; +extern uint32_t g_osalTickTrim_mod; +extern uint32_t g_TIM2_wakeup_delay; +extern uint32_t rtc_mod_value; +extern uint32_t g_counter_traking_cnt; +extern uint32_t sleep_tick; +extern uint32_t g_wakeup_rtc_tick; +extern int slave_conn_event_recv_delay; +extern uint8 g_llScanMode; +extern uint8 g_currentPeerAddrType; +extern uint8 g_currentPeerRpa[LL_DEVICE_ADDR_LEN]; +extern uint8 ownRandomAddr[]; +extern uint16_t ll_hw_get_tfifo_wrptr(void); +extern uint32_t llCurrentScanChn; +extern uint8 ownPublicAddr[]; +extern uint32_t llScanTime; +extern uint32_t llScanT1; +extern uint8 isPeerRpaStore; +extern uint8 currentPeerRpa[LL_DEVICE_ADDR_LEN]; +extern uint8 storeRpaListIndex; +extern uint8 g_currentLocalAddrType; +extern uint8 g_currentLocalRpa[LL_DEVICE_ADDR_LEN]; +//extern llPduLenManagment_t g_llPduLen; +extern uint8_t llSecondaryState; // secondary state of LL + +uint8 ll_processBasicIRQ_SRX(uint32_t irq_status) +{ + uint8 ret=0; + typedef uint8 (*my_function)(uint32_t ); + my_function pFunc = NULL; + pFunc = (my_function)(JUMP_FUNCTION(LL_PROCESSBASICIRQ_SRX)); + + if (pFunc != NULL) + ret = pFunc(irq_status); + else + ret = ll_processBasicIRQ(irq_status); + + return ret; +} + +uint8 ll_processBasicIRQ_secondaryAdvTRX(uint32_t irq_status) +{ + uint8 ret=0; + typedef uint8 (*my_function)(uint32_t ); + my_function pFunc = NULL; + pFunc = (my_function)(JUMP_FUNCTION(LL_PROCESSBASICIRQ_SECADVTRX)); + + if (pFunc != NULL) + ret = pFunc(irq_status); + else + ret = ll_processBasicIRQ(irq_status); + + return ret; +} + +uint8 ll_processBasicIRQ_ScanTRX(uint32_t irq_status) +{ + uint8 ret=0; + typedef uint8 (*my_function)(uint32_t ); + my_function pFunc = NULL; + pFunc = (my_function)(JUMP_FUNCTION(LL_PROCESSBASICIRQ_SCANTRX)); + + if (pFunc != NULL) + ret = pFunc(irq_status); + else + ret = ll_processBasicIRQ(irq_status); + + return ret; +} + +//---------------------------------------------------------------------------------------------- +//patch + +void ll_hw_go1(void) +{ + //*(volatile uint32_t *)0x4000f0b8 = 0; // pclk_clk_gate_en + //20190115 ZQ recorded ll re-trigger + //DBG_GPIO_WRITE(DBGIO_LL_TRIG,1); + //DBG_GPIO_WRITE(DBGIO_LL_TRIG,0); + if(llWaitingIrq==TRUE) + { + g_pmCounters.ll_trigger_err++; + //llWaitingIrq = FALSE; + //return; + } + + g_t_llhwgo = read_current_fine_time(); + *(volatile uint32_t*)(LL_HW_BASE+ 0x14) = LL_HW_IRQ_MASK; //clr irq status + *(volatile uint32_t*)(LL_HW_BASE+ 0x0c) = 0x0001; //mask irq :only use mode done + *(volatile uint32_t*)(LL_HW_BASE+ 0x00) = 0x0001; //trig + + if(CreateConn_Flag) + { + osal_memcpy((uint8*)&g_tx_adv_buf.data[0], &initInfo.ownAddr[0], 6); + CreateConn_Flag= FALSE; + } + + //2018-05-23 ZQ + //fix negative rfPhyFreqOff bug, when in scan_rsq case, ll_hw_go will be excuted before set_channel() + //so do not change the tx_rx_foff + //next metal change could modified the set_channel() to deal with the tx_rx_foff + uint8_t rfChnIdx = PHY_REG_RD(0x400300b4)&0xff; + + if(!g_same_rf_channel_flag) + { + if(g_rfPhyFreqOffSet>=0) + PHY_REG_WT(0x400300b4, (g_rfPhyFreqOffSet<<16)+(g_rfPhyFreqOffSet<<8)+rfChnIdx); + else + PHY_REG_WT(0x400300b4, ((255+g_rfPhyFreqOffSet)<<16)+((255+g_rfPhyFreqOffSet)<<8)+(rfChnIdx-1) ); + } + + //2018-02-09 ZQ + //considering the ll_trigger timing, Trigger first, then set the tp_cal cap + + if(rfChnIdx<2) + { + rfChnIdx=2; + } + else if(rfChnIdx>80) + { + rfChnIdx=80; + } + + if(g_rfPhyPktFmt==PKT_FMT_BLE2M) + subWriteReg(0x40030094,7,0,RF_PHY_TPCAL_CALC(g_rfPhyTpCal0_2Mbps,g_rfPhyTpCal1_2Mbps,(rfChnIdx-2)>>1)); + else + subWriteReg(0x40030094,7,0,RF_PHY_TPCAL_CALC(g_rfPhyTpCal0,g_rfPhyTpCal1,(rfChnIdx-2)>>1)); + + int llModeLast; + llModeLast = ll_hw_get_tr_mode(); + extern uint8_t rxFifoFlowCtrl; + extern uint8 ctrlToHostEnable; + + if (llModeLast == LL_HW_MODE_RTLP || llModeLast == LL_HW_MODE_TRLP) + { + if (ctrlToHostEnable && rxFifoFlowCtrl) + { + set_max_length(0); + } + + //for codedphy rxtimeout + llConnState_t* connPtr; + connPtr = &conn_param[g_ll_conn_ctx.currentConn]; + + if (connPtr->llRfPhyPktFmt == PKT_FMT_BLR125K || connPtr->llRfPhyPktFmt == PKT_FMT_BLR500K) + { + ll_hw_set_rx_timeout(350); + } + } + + if((llModeLast == LL_HW_MODE_TRX)&&((llState == LL_STATE_ADV_UNDIRECTED ||llState == LL_STATE_ADV_SCAN ||llState == LL_STATE_ADV_DIRECTED)|| llSecondaryState == LL_SEC_STATE_ADV)) + { + ll_hw_set_rx_timeout(108); + } + + // fix slave scan rsp addr type bug + // if (llModeLast == LL_HW_MODE_STX && + // (llState == LL_STATE_ADV_UNDIRECTED || + // llState == LL_STATE_ADV_SCAN ) + // ) + // { + // if(adv_param.ownAddrType == LL_DEV_ADDR_TYPE_PUBLIC) + // { + // SET_BITS(tx_scanRsp_desc.txheader, LL_DEV_ADDR_TYPE_PUBLIC, TX_ADD_SHIFT, TX_ADD_MASK); + // } + // else if(adv_param.ownAddrType == LL_DEV_ADDR_TYPE_RANDOM) + // { + // SET_BITS(tx_scanRsp_desc.txheader, LL_DEV_ADDR_TYPE_RANDOM, TX_ADD_SHIFT, TX_ADD_MASK); + // } + DBG_GPIO_WRITE(DBGIO_LL_TRIG,1); + DBG_GPIO_WRITE(DBGIO_LL_TRIG,0); + // } + // + //disable scan backoff + scanInfo.currentBackoff=1; +} + +extern int slave_conn_event_recv_delay; +void ll_adptive_adj_next_time1(uint32_t next_time) +{ + (void)(next_time); + uint32_t loop_time,anchor_point; + + // read loop timeout counter, system clock may be 16MHz, 32MHz, 64MHz and 48MHz, 96MHz + if (hclk_per_us_shift != 0) + { + loop_time = ll_hw_get_loop_cycle() >> hclk_per_us_shift; // convert to us + } + else + { + loop_time = ll_hw_get_loop_cycle() / hclk_per_us; // convert to us + } + + if (hclk_per_us_shift != 0) + { + anchor_point = ll_hw_get_anchor() >> hclk_per_us_shift; // convert to us + } + else + { + anchor_point = ll_hw_get_anchor() / hclk_per_us; // convert to us + } + + //================================================== + //DO NOT ADD LOG PRINTF In this FUNCTION + //================================================== + llConnState_t* connPtr; + // get connection information + connPtr = &conn_param[g_ll_conn_ctx.currentConn]; + + //no anche point + if (connPtr->rx_timeout) + { + connPtr->pmCounter.ll_tbd_cnt1++; + slave_conn_event_recv_delay = LL_TIME_DELTA(g_t_llhwgo, ISR_entry_time)-370+160;//160:timer1 irq->hwgo trigger + } + else + { + connPtr->pmCounter.ll_tbd_cnt1 = 0; +// slave_conn_event_recv_delay = loop_time - anchor_point+pGlobal_config[SLAVE_CONN_DELAY]; + slave_conn_event_recv_delay = LL_TIME_DELTA(g_t_llhwgo, ISR_entry_time) - anchor_point + pGlobal_config[SLAVE_CONN_DELAY]; + + } + + // slave_conn_event_recv_delay -= 370; + //slave_conn_event_recv_delay += (connPtr->curParam.connInterval >> 2); + // slave_conn_event_recv_delay += pGlobal_config[SLAVE_CONN_DELAY]; + + // if( connPtr->firstPacket ) + // { + // slave_conn_event_recv_delay+=500; + // } + + //only adj for the 1st rxtimeout + if (1 == connPtr->pmCounter.ll_tbd_cnt1) + { + slave_conn_event_recv_delay += 500; + slave_conn_event_recv_delay += 1500; + } + else if( connPtr->pmCounter.ll_tbd_cnt1 > 0 ) + { + slave_conn_event_recv_delay += 1000; + } + + //adj for ntrm pkt, each pkt cost 50us in wt tfifo + //if(connPtr->rx_timeout) + //slave_conn_event_recv_delay += ((connPtr->ll_buf.ntrm_cnt) * 50); +} + +void llConnTerminate1( llConnState_t* connPtr, + uint8 reason ) +{ + /* + ZQ:20210622 + process chanmp update passed instant(core 4.2 should term link, since core 5.0 just update the ) + just update chanmap do not trigger ll conn termination + */ + if( reason == LL_CTRL_PKT_INSTANT_PASSED_PEER_TERM + && ((uint16)(connPtr->chanMapUpdateEvent - connPtr->currentEvent) >= LL_MAX_UPDATE_COUNT_RANGE ) + &&((!osal_memcmp(connPtr->chanMap,connPtr->chanMapUpdate.chanMap,5)))) + { + llProcessChanMap(connPtr, connPtr->chanMapUpdate.chanMap); + } + else + { + llConnTerminate0(connPtr,reason); + } +} + +/* + fix secAdv evt rfphyPkt error issue +*/ +//extern uint8 llSetupSecAdvEvt0( void ); +uint8 llSetupSecAdvEvt1( void ) +{ + uint8 ret = FALSE; + + if (llState == LL_STATE_IDLE) + { + if (adv_param.advEvtType == LL_ADV_CONNECTABLE_UNDIRECTED_EVT) + llState = LL_STATE_ADV_UNDIRECTED; + else if (adv_param.advEvtType == LL_ADV_NONCONNECTABLE_UNDIRECTED_EVT) + llState = LL_STATE_ADV_NONCONN; + else if (adv_param.advEvtType == LL_ADV_SCANNABLE_UNDIRECTED_EVT) + llState = LL_STATE_ADV_SCAN; + + llSetupAdv(); + llSecondaryState = LL_SEC_STATE_IDLE; + return TRUE; + } + else + { + llConnState_t* connPtr; + connPtr = &conn_param[g_ll_conn_ctx.currentConn]; + g_rfPhyPktFmt = LE_1M_PHY; + //support rf phy change + rf_phy_change_cfg0(g_rfPhyPktFmt); + + if (adv_param.advEvtType == LL_ADV_CONNECTABLE_UNDIRECTED_EVT) + ret = llSetupSecConnectableAdvEvt(); + else if (adv_param.advEvtType == LL_ADV_NONCONNECTABLE_UNDIRECTED_EVT) + ret = llSetupSecNonConnectableAdvEvt(); + else if (adv_param.advEvtType == LL_ADV_SCANNABLE_UNDIRECTED_EVT) + ret = llSetupSecScannableAdvEvt(); + else + return FALSE; // other type adv should not here + + g_rfPhyPktFmt = connPtr->llRfPhyPktFmt; + } + + return ret; +} + +//fix sec_scan rfphy issue +void llSetupSecScan1( uint8 chan ) +{ + uint32 scanTime; + // Hold off interrupts. + _HAL_CS_ALLOC_(); + HAL_ENTER_CRITICAL_SECTION(); + scanTime = scanInfo.scanWindow * 625; + +// if(llWaitingIrq) +// { +// LOG("==== error, mode: %d\n", scanInfo.scanMode); +// } + + if (llState == LL_STATE_IDLE) + { + llState = LL_STATE_SCAN; + llSecondaryState = LL_SEC_STATE_IDLE; + } + else + { + // calculate scan time + scanTime = llCalcMaxScanTime(); + + if (scanTime) // trigger scan + { + llSecondaryState = LL_SEC_STATE_SCAN; + } + else // no enough time to scan, pending + { + llSecondaryState = LL_SEC_STATE_SCAN_PENDING; + g_pmCounters.ll_conn_scan_pending_cnt ++; + HAL_EXIT_CRITICAL_SECTION( ); + return; + } + } + + if (scanTime > scanInfo.scanWindow * 625) + scanTime = scanInfo.scanWindow * 625; + + llConnState_t* connPtr; + connPtr = &conn_param[g_ll_conn_ctx.currentConn]; + g_rfPhyPktFmt = LE_1M_PHY; + //support rf phy change + rf_phy_change_cfg0(g_rfPhyPktFmt); + // reset all FIFOs; all data is forfeit + ll_hw_rst_tfifo(); + ll_hw_rst_rfifo(); + set_crc_seed(ADV_CRC_INIT_VALUE); // crc seed for adv is same for all channels + set_access_address(ADV_SYNCH_WORD); + set_channel(chan); + set_whiten_seed(chan); + set_max_length(0xff); + ll_hw_set_rx_timeout(scanTime); // maximum scan time, note that actual scan time may exceed the limit if timer expiry when LL engine receiving a report + ll_hw_set_srx(); + ll_hw_ign_rfifo(LL_HW_IGN_CRC|LL_HW_IGN_EMP); + ll_hw_go(); + llScanT1 = read_current_fine_time(); + g_rfPhyPktFmt = connPtr->llRfPhyPktFmt; + llWaitingIrq = TRUE; + HAL_EXIT_CRITICAL_SECTION(); +// uint32 remainTime = read_LL_remainder_time(); +// LOG("<%d %d>", scanTime, remainTime); + return; +} + +extern int32 connUpdateTimer; +/******************************************************************************* + GLOBAL VARIABLES +*/ + +extern perStatsByChan_t* p_perStatsByChan; +extern uint8 g_conn_taskID; +extern uint16 g_conn_taskEvent; + + +extern volatile sysclk_t g_system_clk; + +uint32_t sysclk_get_clk(void) +{ + switch(g_system_clk){ + case SYS_CLK_RC_32M: + case SYS_CLK_DLL_32M: + return 32000000; + case SYS_CLK_XTAL_16M: + return 16000000; + case SYS_CLK_DLL_48M: + return 48000000; + case SYS_CLK_DLL_64M: + return 64000000; + default: + break; + + } + return 16000000; +} + + +/******************************************************************************* + Prototypes +*/ +extern uint8 llProcessMasterControlProcedures( llConnState_t* connPtr ); +extern uint8 llSetupNextMasterEvent( void ); +/******************************************************************************* + @fn llMasterEvt_TaskEndOk + + @brief This function is used to handle the PHY task done end cause + TASK_ENDOK that can result from one of three causes. First, a + a packet was successfully received with MD=0 (i.e. no more Slave + data) after having transmitted a packet with MD=0. Second, a + received packet did not fit in the RX FIFO after transmitting + a packet with MD=0. Third, a packet was received from the Slave + while BLE_L_CONF.ENDC is true or after Timer 2 Event 2 occurs. + + Note: The TASK_ENDOK end cause will also handle the TASK_NOSYNC, + TASK_RXERR, and TASK_MAXNACK end causes as well. + + input parameters + + @param None. + + output parameters + + @param None. + + @return None. +*/ +void llMasterEvt_TaskEndOk1( void ) +{ + llConnState_t* connPtr; + uint16 numPkts; + int i; + uint32_t T2, schedule_time; + // get connection information + connPtr = &conn_param[g_ll_conn_ctx.currentConn]; + // advance the connection event count + connPtr->currentEvent = connPtr->nextEvent; + // get the total number of received packets + // Note: Since Auto-Flush is enabled, numRxFifoFull is incremented instead of + // numRxOk when there's no room in the FIFO. When Auto-Flush is + // disabled and there's no room in the FIFO, only numRxFifoFull is + // incremented for any kind of received packet. + numPkts = ( rfCounters.numRxOk + + rfCounters.numRxNotOk + + rfCounters.numRxEmpty + + rfCounters.numRxIgnored + + rfCounters.numRxFifoFull ); + // collect packet error information + connPtr->perInfo.numPkts += numPkts; + connPtr->perInfo.numCrcErr += rfCounters.numRxNotOk; + // + connPtr->perInfo.numEvents++; + +// // check if PER by Channel is enabled +// if ( connPtr->perInfoByChan != NULL ) +// { +// connPtr->perInfoByChan->numPkts[ PHY_GET_DATA_CHAN() ] += numPkts; +// connPtr->perInfoByChan->numCrcErr[ PHY_GET_DATA_CHAN() ] += rfCounters.numRxNotOk; +// } + + // check if any data has been received + // Note: numRxOk includes numRxCtrl + // Note: numRxNotOk removed as 4.5.2 of spec says the timer is reset upon + // receipt of a "valid packet", which is taken to mean no CRC error. + if ( rfCounters.numRxOk || rfCounters.numRxIgnored || + rfCounters.numRxEmpty || rfCounters.numRxFifoFull + || connPtr->rx_crcok != 0) // ever Rx CRC OK packet + { + // yes, so update the supervision expiration count + connPtr->expirationEvent = connPtr->currentEvent + connPtr->expirationValue; + // clear flag that indicates we received first packet + // Note: The first packet only really needs to be signalled when a new + // connection is formed. However, there's no harm in resetting it + // every time in order to simplify the control logic. + // Note: True-Low logic is used here to be consistent with nR's language. + connPtr->firstPacket = 0; + + //20181206 ZQ add phy change nofity + //receiver ack notifty the host + if(connPtr->llPhyModeCtrl.isChanged==TRUE) + { + connPtr->llPhyModeCtrl.isChanged = FALSE; + llPhyModeCtrlUpdateNotify(connPtr,LL_STATUS_SUCCESS); + } + } + else // no data received, or packet received with CRC error + { + // check if we received any packets with a CRC error + if ( rfCounters.numRxNotOk ) + { + // clear flag that indicates we received first packet + // Note: The first packet only really needs to be signalled when a new + // connection is formed. However, there's no harm in resetting it + // every time in order to simplify the control logic. + // Note: True-Low logic is used here to be consistent with nR's language. + connPtr->firstPacket = 0; + } + else // no packet was received + { + // collect packet error information, TI use HCI ext to get this information. No used by PHY+ now + connPtr->perInfo.numMissedEvts++; + } + + // check if we have a Supervision Timeout + if ( connPtr->expirationEvent == connPtr->currentEvent ) // 20201011�� should be "==" + { + // check if the connection has already been established + if ( connPtr->firstPacket == 0 ) + { + // yes, so terminate with LSTO + llConnTerminate( connPtr, LL_SUPERVISION_TIMEOUT_TERM ); + } + else // no, so this is a failure to establish the connection + { + // so terminate immediately with failure to establish connection + llConnTerminate( connPtr, LL_CONN_ESTABLISHMENT_FAILED_TERM ); + } + +//#ifdef MULTI_ROLE + ll_scheduler(LL_INVALID_TIME); // link is terminated, update scheduler info +//#endif + return; + } + } + + /* + ** Process RX Data Packets + */ + // check if there is any data in the Rx FIFO + uint8_t buffer_size; + buffer_size = getRxBufferSize(connPtr); + + for ( i = 0; i < buffer_size; i ++) // note: i < getRxBufferSize() will fail the loop + { + // there is, so process it; check if data was processed + if ( llProcessRxData() == FALSE ) + { + // it wasn't, so we're done +// ll_scheduler(LL_INVALID_TIME); + break; + } + } + + // check if this connection was terminated + if ( !connPtr->active ) + { +//#ifdef MULTI_ROLE + ll_scheduler(LL_INVALID_TIME); +//#endif + return; + } + + /* + ** Check Control Procedure Processing + */ + if ( llProcessMasterControlProcedures( connPtr ) == LL_CTRL_PROC_STATUS_TERMINATE ) + { +//#ifdef MULTI_ROLE + ll_scheduler(LL_INVALID_TIME); // link is termainte, update schedle info +//#endif + return; + } + else if(connPtr->ctrlDataIsPending == 1) + { + uint8 pktLenctrl; + uint8* pBufctrl = connPtr->ctrlData.data; + pktLenctrl = LL_REJECT_EXT_IND_PAYLOAD_LEN; + + if((connPtr->ctrlData .header == (pktLenctrl << 8 | LL_DATA_PDU_HDR_LLID_CONTROL_PKT))&&(*pBufctrl == LL_CTRL_REJECT_EXT_IND)) + { + uint8 ctrlerrorcode = *(pBufctrl + 1); + *(pBufctrl + 1) = connPtr->rejectOpCode; + *(pBufctrl + 2) = ctrlerrorcode; + } + } + + /* + ** Process TX Data Packets + */ + // copy any pending data to the TX FIFO + llProcessTxData( connPtr, LL_TX_DATA_CONTEXT_POST_PROCESSING ); + + // if any fragment l2cap pkt, copy to TX FIFO + //l2capPocessFragmentTxData((uint16)connPtr->connId); + + /* + ** Setup Next Slave Event Timing + */ + + // update next event, calculate time to next event, calculate timer drift, + // update anchor points, setup NR T2E1 and T2E2 events + if ( llSetupNextMasterEvent() == LL_SETUP_NEXT_LINK_STATUS_TERMINATE ) // PHY+ always return success here + { + // this connection is terminated, so nothing to schedule +//#ifdef MULTI_ROLE + ll_scheduler(LL_INVALID_TIME); +//#endif + return; + } + + /* + ** Schedule Next Task + */ +//#ifdef MULTI_ROLE +// schedule_time = ll_get_next_timer(g_ll_conn_ctx.currentConn); + schedule_time = (connPtr->curParam.connInterval + connUpdateTimer) * 625; + T2 = read_current_fine_time(); + // TODO: don't know the cause, here need add 32us to gain accurate timing + //2020.11.11,Jie,master conInterval-5us + ll_scheduler(schedule_time - 10 - LL_TIME_DELTA(g_ll_conn_ctx.timerExpiryTick, T2) ); // 10us: rough delay from timer expire to timer ISR +//#endif + return; +} + +uint8_t ll_hw_read_rfifo1(uint8_t* rxPkt, uint16_t* pktLen, uint32_t* pktFoot0, uint32_t* pktFoot1) +{ + int rdPtr, wrPtr, rdDepth, blen, wlen; + uint32_t* p_rxPkt = (uint32_t*)rxPkt; + ll_hw_get_rfifo_info(&rdPtr, &wrPtr, &rdDepth); + + if(rdDepth > 0) + { + *p_rxPkt++ = *(volatile uint32_t*)(LL_HW_RFIFO); + uint8_t sp =0;//BLE_HEAD_WITH_CTE(rxPkt[0]); + blen = rxPkt[1]+sp; //get the byte length for header + wlen = 1+ ( (blen+2+3-1) >>2 ); //+2 for Header, +3 for crc + + //compared the wlen and HW_WTR + //20190115 ZQ + if( (wlen+2) >rdDepth) + { + g_pmCounters.ll_rfifo_read_err++; + rxPkt[0] = 0; + *pktFoot0 = 0; + *pktFoot1 = 0; + *pktLen = 0; + return 0; + } + + while(p_rxPkt < (uint32_t*)rxPkt + wlen) + { + *p_rxPkt++ = *(volatile uint32_t*)(LL_HW_RFIFO); + } + + *pktFoot0 = *(volatile uint32_t*)(LL_HW_RFIFO); + *pktFoot1 = *(volatile uint32_t*)(LL_HW_RFIFO); + *pktLen = blen + 2; + return wlen; + } + else + { + rxPkt[0] = 0; + *pktFoot0 = 0; + *pktFoot1 = 0; + *pktLen = 0; + return 0; + } +} + +/******************************************************************************* + @fn ll_processBasicIRQ_SRX + + @brief Interrupt Request Handler for Link Layer + + input parameters + + @param None. + + output parameters + + @param None. + + @return None +*/ +uint8 ll_processBasicIRQ_SRX0(uint32_t irq_status) +{ + uint8 mode; + uint32_t T2, delay; + llConnState_t* connPtr; + connPtr = &conn_param[0]; // To update + _HAL_CS_ALLOC_(); + HAL_ENTER_CRITICAL_SECTION(); + mode = ll_hw_get_tr_mode(); + + if (mode == LL_HW_MODE_SRX + && (llState == LL_STATE_SCAN || llState == LL_STATE_INIT)) + { + ll_debug_output(DEBUG_LL_HW_SRX); + uint8_t rpaListIndex = LL_RESOLVINGLIST_ENTRY_NUM; + uint8_t bWlRlCheckOk = TRUE; + uint8_t* peerAddr; + + // ============= scan case + if (llState == LL_STATE_SCAN) + { + uint8 bSendingScanReq = FALSE; + + // check status + if ((irq_status & LIRQ_RD) && (irq_status & LIRQ_COK)) // bug correct 2018-10-15 + { + // rx done + uint8_t packet_len, pdu_type; + uint16_t pktLen; + uint32_t pktFoot0, pktFoot1; + // read packet + // cost 21-26us(measure with GPIO), depneds on the length of ADV + packet_len = ll_hw_read_rfifo1((uint8_t*)(&(g_rx_adv_buf.rxheader)), + &pktLen, + &pktFoot0, + &pktFoot1); + // check receive pdu type + pdu_type = g_rx_adv_buf.rxheader & 0x0f; + + if(ll_hw_get_rfifo_depth()>0) + { + g_pmCounters.ll_rfifo_read_err++; + packet_len=0; + pktLen=0; + } + + if (packet_len != 0 + && ((pdu_type == ADV_IND) + || (pdu_type == ADV_NONCONN_IND) + || (pdu_type == ADV_SCAN_IND) + || (pdu_type == ADV_DIRECT_IND))) + { + uint8 addrType; // peer address type + uint8_t txAdd = (g_rx_adv_buf.rxheader & TX_ADD_MASK) >> TX_ADD_SHIFT; // adv PDU header, bit 6: TxAdd, 0 - public, 1 - random + peerAddr = &g_rx_adv_buf.data[0]; // AdvA + addrType = txAdd; + + // Resolving list checking + // case 1: receive ScanA using RPA + if (txAdd == LL_DEV_ADDR_TYPE_RANDOM && + (g_rx_adv_buf.data[5] & RANDOM_ADDR_HDR) == PRIVATE_RESOLVE_ADDR_HDR) + { + bWlRlCheckOk = TRUE; + + if (g_llRlEnable == TRUE) + { + rpaListIndex = ll_getRPAListEntry(&g_rx_adv_buf.data[0]); + + if (rpaListIndex < LL_RESOLVINGLIST_ENTRY_NUM) + { + peerAddr = &g_llResolvinglist[rpaListIndex].peerAddr[0]; + // refer to HCI LE Advertising Report Event, RPA address type should be + // 0x02: Public Identity Address (Corresponds to Resolved Private Address) + // 0x03: Random (static) Identity Address (Corresponds to Resolved Private Address) + addrType = g_llResolvinglist[rpaListIndex].peerAddrType + 2; + bWlRlCheckOk = TRUE; + } + else + { + bWlRlCheckOk = FALSE; + } + } + } + else // case 2: receive ScanA using device ID, or scan device not using RPA + { + bWlRlCheckOk = TRUE; + + for (int i = 0; i < LL_RESOLVINGLIST_ENTRY_NUM; i++) + { + if ( g_llResolvinglist[i].peerAddr[0] == g_rx_adv_buf.data[0] + && g_llResolvinglist[i].peerAddr[1] == g_rx_adv_buf.data[1] + && g_llResolvinglist[i].peerAddr[2] == g_rx_adv_buf.data[2] + && g_llResolvinglist[i].peerAddr[3] == g_rx_adv_buf.data[3] + && g_llResolvinglist[i].peerAddr[4] == g_rx_adv_buf.data[4] + && g_llResolvinglist[i].peerAddr[5] == g_rx_adv_buf.data[5]) + { + // the device ID in the RPA list + if (g_llResolvinglist[i].privacyMode == DEVICE_PRIVACY_MODE || + ll_isIrkAllZero(g_llResolvinglist[i].peerIrk)) + rpaListIndex = i; + else + bWlRlCheckOk = FALSE; // the device in the RPA list but not using RPA, reject it + + break; + } + } + } + + // check white list + if ((pGlobal_config[LL_SWITCH] & LL_WHITELIST_ALLOW) + && (scanInfo.wlPolicy == LL_SCAN_WL_POLICY_USE_WHITE_LIST) + && (bWlRlCheckOk == TRUE)) + { + // check white list + bWlRlCheckOk = ll_isAddrInWhiteList(txAdd, peerAddr); + } + + /* 20201218 Jie,direct adv report when no whitelist filter + else if(pdu_type == ADV_DIRECT_IND) // direct adv only report addr & addr type match the whitelist + bWlRlCheckOk = FALSE; + */ + // if valid, trigger osal event to report adv + if (bWlRlCheckOk == TRUE) + { + uint8 advEventType; + int8 rssi; + llCurrentScanChn = scanInfo.nextScanChan; + + // active scan scenario, send scan req + if (scanInfo.scanType == LL_SCAN_ACTIVE + && (pdu_type== ADV_IND + || pdu_type == ADV_SCAN_IND )) + { + // back off process + scanInfo.currentBackoff = (scanInfo.currentBackoff > 0) ? (scanInfo.currentBackoff - 1) : 0; + + if (scanInfo.currentBackoff == 0) // back off value = 0, send scan req + { + g_tx_adv_buf.txheader = 0xC03; + //ZQ 20181012: add AdvFilterCB + uint8_t retAdvFilter = 1; + + if(LL_PLUS_AdvDataFilterCBack) + { + //!!!CATION!!! + //timing critical + //txbuf will be changed + retAdvFilter = LL_PLUS_AdvDataFilterCBack(); + } + + if(retAdvFilter) + { + g_same_rf_channel_flag = TRUE; + ll_hw_set_tx_rx_interval(10); + ll_hw_set_rx_timeout(158); + set_max_length(0xFF); // add 2020-03-10 + T2 = read_current_fine_time(); + delay = (T2 > ISR_entry_time) ? (T2 - ISR_entry_time) : (BASE_TIME_UNITS - ISR_entry_time + T2); + delay = 118 - delay - pGlobal_config[LL_ADV_TO_SCAN_REQ_DELAY]; + ll_hw_set_trx(); // set LL HW as single TRx mode + ll_hw_set_trx_settle(delay, // set BB delay, about 80us in 16MHz HCLK + pGlobal_config[LL_HW_AFE_DELAY], + pGlobal_config[LL_HW_PLL_DELAY]); //RxAFE,PLL + ll_hw_go(); + g_pmCounters.ll_send_scan_req_cnt++; + llWaitingIrq = TRUE; + // reset Rx/Tx FIFO + ll_hw_rst_rfifo(); + ll_hw_rst_tfifo(); + ll_hw_ign_rfifo(LL_HW_IGN_CRC | LL_HW_IGN_EMP); + + // construct SCAN REQ packet + //g_tx_adv_buf.txheader = 0xCC3; + +// //20181012 ZQ: change the txheader according to the adtype +// g_tx_adv_buf.txheader |=(((g_rx_adv_buf.rxheader&0x40)<<1) +// | (scanInfo.ownAddrType<< TX_ADD_SHIFT & TX_ADD_MASK)); + + // fill scanA, using RPA or device ID address // TODO: move below code before ll_hw_go? + if (rpaListIndex < LL_RESOLVINGLIST_ENTRY_NUM && + !ll_isIrkAllZero(g_llResolvinglist[rpaListIndex].localIrk) + && (scanInfo.ownAddrType == LL_DEV_ADDR_TYPE_RPA_PUBLIC + || scanInfo.ownAddrType == LL_DEV_ADDR_TYPE_RPA_RANDOM)) + { + // for resolving private address case, calculate the scanA with Local IRK + ll_CalcRandomAddr(g_llResolvinglist[rpaListIndex].localIrk, &g_tx_adv_buf.data[0]); + SET_BITS(g_tx_adv_buf.txheader, LL_DEV_ADDR_TYPE_RANDOM, TX_ADD_SHIFT, TX_ADD_MASK); + } + else + { + //2020.10.26 Jie,TX_ADD update + if (scanInfo.ownAddrType == LL_DEV_ADDR_TYPE_PUBLIC || scanInfo.ownAddrType == LL_DEV_ADDR_TYPE_RPA_PUBLIC) + { + osal_memcpy((uint8*)&g_tx_adv_buf.data[0], &ownPublicAddr[0], 6); + SET_BITS(g_tx_adv_buf.txheader, LL_DEV_ADDR_TYPE_PUBLIC, TX_ADD_SHIFT, TX_ADD_MASK); + } + else + { + osal_memcpy((uint8*)&g_tx_adv_buf.data[0], &ownRandomAddr[0], 6); + SET_BITS(g_tx_adv_buf.txheader, LL_DEV_ADDR_TYPE_RANDOM, TX_ADD_SHIFT, TX_ADD_MASK); + } + } + + g_tx_adv_buf.txheader |= (txAdd << RX_ADD_SHIFT & RX_ADD_MASK); + // AdvA, for SCAN REQ, it should identical to the ADV_IND/ADV_SCAN_IND + g_tx_adv_buf.data[6] = g_rx_adv_buf.data[0]; + g_tx_adv_buf.data[7] = g_rx_adv_buf.data[1]; + g_tx_adv_buf.data[8] = g_rx_adv_buf.data[2]; + g_tx_adv_buf.data[9] = g_rx_adv_buf.data[3]; + g_tx_adv_buf.data[10] = g_rx_adv_buf.data[4]; + g_tx_adv_buf.data[11] = g_rx_adv_buf.data[5]; + //write Tx FIFO + ll_hw_write_tfifo((uint8*)&(g_tx_adv_buf.txheader), + ((g_tx_adv_buf.txheader & 0xff00) >> 8) + 2); // payload length + header length(2) + bSendingScanReq = TRUE; + g_same_rf_channel_flag = FALSE; + } + } + } + + // convert pdu type to GAP enum + switch (pdu_type) + { + case ADV_IND: + advEventType = LL_ADV_RPT_ADV_IND; + break; + + case ADV_SCAN_IND: + advEventType = LL_ADV_RPT_ADV_SCANNABLE_IND; + break; + + case ADV_DIRECT_IND: + advEventType = LL_ADV_RPT_ADV_DIRECT_IND; + break; + + case ADV_NONCONN_IND: + advEventType = LL_ADV_RPT_ADV_NONCONN_IND; + break; + + case ADV_SCAN_RSP: + advEventType = LL_ADV_RPT_INVALID; + break; + + default: + advEventType = LL_ADV_RPT_ADV_IND; + break; + } + + rssi = -(pktFoot1 >> 24); + // below function cost 51us/66us(measure with GPIO) + LL_AdvReportCback( advEventType, // event type + addrType, // Adv address type (TxAdd) + &peerAddr[0], // Adv address (AdvA) + pktLen - 8, // length of rest of the payload, 2 - header, 6 - advA + &g_rx_adv_buf.data[6], // rest of payload + rssi ); // RSSI + g_pmCounters.ll_recv_adv_pkt_cnt ++; + } + } + else + { + // invalid ADV PDU type +// llSetupScan(); + } + } + + // if not waiting for scan rsp, schedule next scan + if (!bSendingScanReq) + { + // not sending SCAN REQ, update scan time + llScanTime += ((ISR_entry_time > llScanT1) ? (ISR_entry_time - llScanT1) : (BASE_TIME_UNITS - llScanT1 + ISR_entry_time)); + + if (llScanTime >= scanInfo.scanWindow * 625) + { + // calculate next scan channel + LL_CALC_NEXT_SCAN_CHN(scanInfo.nextScanChan); + + // schedule next scan event + if (scanInfo.scanWindow == scanInfo.scanInterval) // scanWindow == scanInterval, trigger immediately + LL_evt_schedule(); + else +// set_timer4((scanInfo.scanInterval - scanInfo.scanWindow) * 625); + ll_schedule_next_event((scanInfo.scanInterval - scanInfo.scanWindow) * 625); + + // reset scan total time + llScanTime = 0; + } + else + { +// AT_LOG("%03x %x %d %d %d %d\n",irq_status,*(volatile uint32_t *)(0x40031054),ll_hw_get_anchor(), +// g_rfifo_rst_cnt,(uint32_t)ISR_entry_time,read_current_fine_time()); + llSetupScan(scanInfo.nextScanChan); + } + } + } + // =========== initiator case + else if (llState == LL_STATE_INIT) + { + uint8 bConnecting = FALSE; + uint8 bMatchAdv = FALSE; // RPA checking OK in previous adv event, and new adv event identical to the old one + connPtr = &conn_param[initInfo.connId]; // connId is allocated when create conn + + // check status + if ((irq_status & LIRQ_RD) && (irq_status & LIRQ_COK)) // bug correct 2018-10-15 + { + // rx done + uint8_t packet_len, pdu_type; + uint16_t pktLen; + uint32_t pktFoot0, pktFoot1; + // read packet + // cost 21-26us(measure with GPIO), depneds on the length of ADV + packet_len = ll_hw_read_rfifo((uint8_t*)(&(g_rx_adv_buf.rxheader)), + &pktLen, + &pktFoot0, + &pktFoot1); + // check receive pdu type + pdu_type = g_rx_adv_buf.rxheader & 0x0f; + + if(ll_hw_get_rfifo_depth() > 0) + { + g_pmCounters.ll_rfifo_read_err++; + packet_len=0; + pktLen=0; + } + + if (packet_len != 0 + && ((pdu_type == ADV_IND) || pdu_type == ADV_DIRECT_IND)) + { + uint8_t txAdd = (g_rx_adv_buf.rxheader & TX_ADD_MASK) >> TX_ADD_SHIFT; // adv PDU header, bit 6: TxAdd, 0 - public, 1 - random + uint8_t chSel = (g_rx_adv_buf.rxheader & CHSEL_MASK) >> CHSEL_SHIFT; + rpaListIndex = LL_RESOLVINGLIST_ENTRY_NUM; + peerAddr = &g_rx_adv_buf.data[0]; // AdvA + g_currentPeerAddrType = txAdd; + + // ================= Resolving list checking + // case 1: receive InitA using RPA + if (txAdd == LL_DEV_ADDR_TYPE_RANDOM && + ((g_rx_adv_buf.data[5] & RANDOM_ADDR_HDR) == PRIVATE_RESOLVE_ADDR_HDR)) + { + bWlRlCheckOk = TRUE; + + if (g_llRlEnable == TRUE) + { + // if the RPA checking is done in previous scan, compare + if (isPeerRpaStore == TRUE && + currentPeerRpa[0] == g_rx_adv_buf.data[0] + && currentPeerRpa[1] == g_rx_adv_buf.data[1] + && currentPeerRpa[2] == g_rx_adv_buf.data[2] + && currentPeerRpa[3] == g_rx_adv_buf.data[3] + && currentPeerRpa[4] == g_rx_adv_buf.data[4] + && currentPeerRpa[5] == g_rx_adv_buf.data[5]) + { + rpaListIndex = storeRpaListIndex; + peerAddr = &g_llResolvinglist[rpaListIndex].peerAddr[0]; + g_currentPeerAddrType = g_llResolvinglist[rpaListIndex].peerAddrType + 2; + bWlRlCheckOk = TRUE; + bMatchAdv = TRUE; + } + else // resolve the address + { + rpaListIndex = ll_getRPAListEntry(&g_rx_adv_buf.data[0]); // spend 30us(48MHz) when the 1st item match + + if (rpaListIndex < LL_RESOLVINGLIST_ENTRY_NUM) + { + peerAddr = &g_llResolvinglist[rpaListIndex].peerAddr[0]; + g_currentPeerAddrType = g_llResolvinglist[rpaListIndex].peerAddrType + 2; + bWlRlCheckOk = TRUE; + } + else + { + bWlRlCheckOk = FALSE; + } + } + } + } + // case 2: receive InitA using device ID, or init device not using RPA + else + { + for (int i = 0; i < LL_RESOLVINGLIST_ENTRY_NUM; i++) + { + if ( g_llResolvinglist[i].peerAddr[0] == g_rx_adv_buf.data[0] + && g_llResolvinglist[i].peerAddr[1] == g_rx_adv_buf.data[1] + && g_llResolvinglist[i].peerAddr[2] == g_rx_adv_buf.data[2] + && g_llResolvinglist[i].peerAddr[3] == g_rx_adv_buf.data[3] + && g_llResolvinglist[i].peerAddr[4] == g_rx_adv_buf.data[4] + && g_llResolvinglist[i].peerAddr[5] == g_rx_adv_buf.data[5]) + { + // the device ID in the RPA list + if (g_llResolvinglist[i].privacyMode == NETWORK_PRIVACY_MODE && + !ll_isIrkAllZero(g_llResolvinglist[i].peerIrk)) + bWlRlCheckOk = FALSE; + else + rpaListIndex = i; + } + } + } + + // ====== for direct adv, also check initA == own addr + if (pdu_type == ADV_DIRECT_IND && bWlRlCheckOk == TRUE && bMatchAdv != TRUE) + { + //20201228,Jie,add RXADD check for direct IND + uint8_t rxAdd = (g_rx_adv_buf.rxheader & RX_ADD_MASK) >> RX_ADD_SHIFT; + + // initA is resolvable address case + if (rxAdd == LL_DEV_ADDR_TYPE_RANDOM &&((g_rx_adv_buf.data[11] & RANDOM_ADDR_HDR) == PRIVATE_RESOLVE_ADDR_HDR)) + { + // should not use RPA case + if (initInfo.ownAddrType != LL_DEV_ADDR_TYPE_RPA_PUBLIC && initInfo.ownAddrType != LL_DEV_ADDR_TYPE_RPA_RANDOM) + bWlRlCheckOk = FALSE; + + if (rpaListIndex >= LL_RESOLVINGLIST_ENTRY_NUM + || (ll_isIrkAllZero(g_llResolvinglist[rpaListIndex].localIrk)) // all-0 local IRK + || (ll_ResolveRandomAddrs(g_llResolvinglist[rpaListIndex].localIrk, &g_rx_adv_buf.data[6]) != SUCCESS)) // resolve failed + bWlRlCheckOk = FALSE; + } + else + { + uint8* localAddr; + + // should not use device ID case + if ((initInfo.ownAddrType == LL_DEV_ADDR_TYPE_RPA_PUBLIC || initInfo.ownAddrType == LL_DEV_ADDR_TYPE_RPA_RANDOM ) + && (rpaListIndex < LL_RESOLVINGLIST_ENTRY_NUM + && !ll_isIrkAllZero(g_llResolvinglist[rpaListIndex].localIrk))) + { + bWlRlCheckOk = FALSE; + } + + if (rxAdd == LL_DEV_ADDR_TYPE_RANDOM) + localAddr = ownRandomAddr; + else + localAddr = ownPublicAddr; + + if (g_rx_adv_buf.data[6] != localAddr[0] + || g_rx_adv_buf.data[7] != localAddr[1] + || g_rx_adv_buf.data[8] != localAddr[2] + || g_rx_adv_buf.data[9] != localAddr[3] + || g_rx_adv_buf.data[10] != localAddr[4] + || g_rx_adv_buf.data[11] != localAddr[5]) + { + bWlRlCheckOk = FALSE; + } + } + } + + // initiator, 2 types of filter process: 1. connect to peer address set by host 2. connect to address in whitelist only + // 1. connect to peer address set by host + if (initInfo.wlPolicy == LL_INIT_WL_POLICY_USE_PEER_ADDR + && bWlRlCheckOk == TRUE) + { + if (peerAddr[0] != peerInfo.peerAddr[0] + || peerAddr[1] != peerInfo.peerAddr[1] + || peerAddr[2] != peerInfo.peerAddr[2] + || peerAddr[3] != peerInfo.peerAddr[3] + || peerAddr[4] != peerInfo.peerAddr[4] + || peerAddr[5] != peerInfo.peerAddr[5]) + { + // not match, not init connect + bWlRlCheckOk = FALSE; + } + } + // 2. connect to address in whitelist only + else if (initInfo.wlPolicy == LL_INIT_WL_POLICY_USE_WHITE_LIST && + bWlRlCheckOk == TRUE) + { + // if advA in whitelist list, connect + // check white list + bWlRlCheckOk = ll_isAddrInWhiteList(txAdd, peerAddr); + + //2020.10.26,Jie,update peer addr + if (bWlRlCheckOk == TRUE) + { + peerInfo.peerAddrType = txAdd; + peerInfo.peerAddr[0] = peerAddr[0]; + peerInfo.peerAddr[1] = peerAddr[1]; + peerInfo.peerAddr[2] = peerAddr[2]; + peerInfo.peerAddr[3] = peerAddr[3]; + peerInfo.peerAddr[4] = peerAddr[4]; + peerInfo.peerAddr[5] = peerAddr[5]; + } + } + + if (bWlRlCheckOk == TRUE) + { + g_same_rf_channel_flag = TRUE; + + // channel selection algorithm decision + if ((pGlobal_config[LL_SWITCH] & CONN_CSA2_ALLOW) + && chSel == LL_CHN_SEL_ALGORITHM_2) + { + conn_param[initInfo.connId].channel_selection = LL_CHN_SEL_ALGORITHM_2; + SET_BITS(g_tx_adv_buf.txheader, LL_CHN_SEL_ALGORITHM_2, CHSEL_SHIFT, CHSEL_MASK); + } + else + { + conn_param[initInfo.connId].channel_selection = LL_CHN_SEL_ALGORITHM_1; + SET_BITS(g_tx_adv_buf.txheader, LL_CHN_SEL_ALGORITHM_1, CHSEL_SHIFT, CHSEL_MASK); + } + + // calculate initA if using RPA list, otherwise copy the address stored in initInfo + if (rpaListIndex < LL_RESOLVINGLIST_ENTRY_NUM && + !ll_isIrkAllZero(g_llResolvinglist[rpaListIndex].localIrk) && + (initInfo.ownAddrType == LL_DEV_ADDR_TYPE_RPA_PUBLIC || initInfo.ownAddrType == LL_DEV_ADDR_TYPE_RPA_RANDOM)) + { + // for resolving private address case, calculate the scanA with Local IRK + ll_CalcRandomAddr(g_llResolvinglist[rpaListIndex].localIrk, &g_tx_adv_buf.data[0]); + SET_BITS(g_tx_adv_buf.txheader, LL_DEV_ADDR_TYPE_RANDOM, TX_ADD_SHIFT, TX_ADD_MASK); +// osal_memcpy( &g_currentLocalRpa[0], &g_tx_adv_buf.data[0], 6); + g_currentLocalAddrType = LL_DEV_ADDR_TYPE_RPA_RANDOM; + } + else + { + if (initInfo.ownAddrType == LL_DEV_ADDR_TYPE_PUBLIC || initInfo.ownAddrType == LL_DEV_ADDR_TYPE_RPA_PUBLIC) + { + osal_memcpy((uint8*)&g_tx_adv_buf.data[0], &ownPublicAddr[0], 6); + SET_BITS(g_tx_adv_buf.txheader, LL_DEV_ADDR_TYPE_PUBLIC, TX_ADD_SHIFT, TX_ADD_MASK); + } + else + { + osal_memcpy((uint8*)&g_tx_adv_buf.data[0], &ownRandomAddr[0], 6); + SET_BITS(g_tx_adv_buf.txheader, LL_DEV_ADDR_TYPE_RANDOM, TX_ADD_SHIFT, TX_ADD_MASK); + } + + g_currentLocalAddrType = LL_DEV_ADDR_TYPE_RANDOM; // not accute local type, for branch selection in enh conn complete event + } + + // send conn req + T2 = read_current_fine_time(); + delay = (T2 > ISR_entry_time) ? (T2 - ISR_entry_time) : (BASE_TIME_UNITS - ISR_entry_time + T2); + + if (delay > 118 - pGlobal_config[LL_ADV_TO_CONN_REQ_DELAY] - pGlobal_config[LL_HW_PLL_DELAY]) // not enough time + { + // not enough time to send conn req, store the RPA + isPeerRpaStore = TRUE; + storeRpaListIndex = rpaListIndex; + osal_memcpy(¤tPeerRpa[0], &g_rx_adv_buf.data[0], 6); +// LOG("store %d\n", storeRpaListIndex); + g_same_rf_channel_flag = FALSE; + //LOG("<%d>", delay); + } + else + { + delay = 118 - delay - pGlobal_config[LL_ADV_TO_CONN_REQ_DELAY]; + ll_hw_set_trx_settle(delay, // set BB delay, about 80us in 16MHz HCLK + pGlobal_config[LL_HW_AFE_DELAY], + pGlobal_config[LL_HW_PLL_DELAY]); //RxAFE,PLL + // reset Rx/Tx FIFO + ll_hw_rst_rfifo(); + ll_hw_rst_tfifo(); + // send conn req + ll_hw_set_stx(); // set LL HW as single Tx mode + ll_hw_go(); + llWaitingIrq = TRUE; + // AdvA, offset 6 + osal_memcpy((uint8*)&g_tx_adv_buf.data[6], &g_rx_adv_buf.data[0], 6); + //2020.8.11 Jie:add init req header for RxAdd + SET_BITS(g_tx_adv_buf.txheader, txAdd, RX_ADD_SHIFT, RX_ADD_MASK); + //write Tx FIFO + ll_hw_write_tfifo((uint8*)&(g_tx_adv_buf.txheader), + ((g_tx_adv_buf.txheader & 0xff00) >> 8) + 2); // payload length + header length(2) + + if (g_currentPeerAddrType >= 0x02) + osal_memcpy(&g_currentPeerRpa[0], &g_rx_adv_buf.data[0], 6); + + if (g_currentLocalAddrType == LL_DEV_ADDR_TYPE_RPA_RANDOM) + osal_memcpy( &g_currentLocalRpa[0], &g_tx_adv_buf.data[0], 6); + + move_to_master_function(); + isPeerRpaStore = FALSE; + bConnecting = TRUE; + g_same_rf_channel_flag = FALSE; + } + } + } + else if (packet_len != 0 + && (pdu_type == ADV_DIRECT_IND)) // TODO: add process of direct ADV + { + } + } + + // scan again if not start connect + if (!bConnecting) // if not waiting for scan rsp, schedule next scan + { + if (initInfo.scanMode == LL_SCAN_STOP) + { + // scan has been stopped + llState = LL_STATE_IDLE; // for single connection case, set the LL state idle + // release the associated allocated connection + llReleaseConnId(connPtr); // new for multi-connection + g_ll_conn_ctx.numLLMasterConns --; + (void)osal_set_event( LL_TaskID, LL_EVT_MASTER_CONN_CANCELLED ); // inform high layer + } + else + { + // not sending SCAN REQ, update scan time + llScanTime += ((ISR_entry_time > llScanT1) ? (ISR_entry_time - llScanT1) : (BASE_TIME_UNITS - llScanT1 + ISR_entry_time)); + + if (llScanTime >= initInfo.scanWindow * 625) + { + // calculate next scan channel + LL_CALC_NEXT_SCAN_CHN(initInfo.nextScanChan); + + // schedule next scan event + if (initInfo.scanWindow == initInfo.scanInterval) // scanWindow == scanInterval, trigger immediately + LL_evt_schedule(); + else +// set_timer4((initInfo.scanInterval - initInfo.scanWindow) * 625); + ll_schedule_next_event((initInfo.scanInterval - initInfo.scanWindow) * 625); + + // reset scan total time + llScanTime = 0; + } + else + llSetupScan(initInfo.nextScanChan); + } + } + } + } + + // post ISR process + if (!llWaitingIrq) // bug fixed 2018-05-04, only clear IRQ status when no config new one + ll_hw_clr_irq(); + + HAL_EXIT_CRITICAL_SECTION(); + return TRUE; +} + +uint8 llSetupStartEncRsp( llConnState_t* connPtr ) +{ + uint8 pktLen; + uint8* pBuf = connPtr->ctrlData.data; + // Note: No need to check if there's enough room in the TX FIFO since it was + // forced to empty prior to beginning encryption control procedure. + // write control type as payload + *pBuf = LL_CTRL_START_ENC_RSP; + // encrypt PDU with authentication check + LL_ENC_Encrypt( connPtr, + LL_DATA_PDU_HDR_LLID_CONTROL_PKT, + LL_START_ENC_RSP_PAYLOAD_LEN, + pBuf ); // input no-encrypt data pBuf, output in the same buffer + pktLen = LL_START_ENC_RSP_PAYLOAD_LEN + LL_ENC_MIC_LEN; + connPtr->ctrlDataIsPending = 1; + connPtr->ctrlData .header = pktLen << 8 | LL_DATA_PDU_HDR_LLID_CONTROL_PKT; + + // control procedure timeout value only needed for Master after Start Enc Response +// if ( llState == LL_STATE_CONN_MASTER ) + if( connPtr->llTbd1 != LL_LINK_CONNECT_COMPLETE_MASTER ) + { + // set the control packet timeout for 40s relative to our present time + // Note: This is done in terms of connection events. + // Note: Core Spec V4.0 now indicates that each LL control PDU that is queued + // for transmission resets the procedure response timeout timer. + connPtr->ctrlPktInfo.ctrlTimeout = connPtr->ctrlPktInfo.ctrlTimeoutVal; + } + + return( TRUE ); +} + +uint8 llProcessSlaveControlProcedures1( llConnState_t* connPtr ) +{ + // check if there are any control packets ready for processing + while ( connPtr->ctrlPktInfo.ctrlPktCount > 0 ) + { + // processing based on control packet type at the head of the queue + switch( connPtr->ctrlPktInfo.ctrlPkts[ 0 ] ) + { + case LL_CTRL_TERMINATE_IND: + + // check if the control packet procedure is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // we have already place packet on TX FIFO, so check if its been ACK'ed + if ( rfCounters.numTxCtrlAck ) + { + // yes, so process the termination + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_HOST_REQUESTED_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else // no done yet + { + // check if a termination control procedure timeout has occurred + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_HOST_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else // no control procedure timeout yet + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + connPtr->ctrlPktInfo.ctrlPktActive = llSetupTermInd( connPtr ); + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + // Note: Unreachable statement generates compiler warning! + //break; + + case LL_CTRL_ENC_RSP: + + // check if the control packet procedure is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if it has been transmitted yet + // Note: This does not mean this packet has been ACK'ed or NACK'ed. + if ( rfCounters.numTxCtrl ) + { + // done with this control packet, so remove from the processing queue + // Note: By dequeueing here, it is possible to get another control + // packet at the head of the queue. This is techincally not + // supposed to happen if the spec is followed. + // ALT: COULD MAKE MORE BULLET PROOF. SINCE THE REPLACE ROUTINE + // CAN'T BE USED UNTIL THE LTK IS RECEIVED BY THE HOST, A + // DUMMY CONTROL PACKET THAT SITS AT THE HEAD UNTIL IT IS + // REPLACE COULD BE USED INSTEAD. + //llReplaceCtrlPkt( connPtr, LL_CTRL_DUMMY_PLACE_HOLDER ); + llDequeueCtrlPkt( connPtr ); + // notify the Host with RAND and EDIV after sending the RSP + // Note: Need to wait for the Host reply to determine if the LTK + // is available or not. + LL_EncLtkReqCback( connPtr->connId, + connPtr->encInfo.RAND, + connPtr->encInfo.EDIV ); + } + else // not done yet + { + // check if a update param req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_PEER_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + connPtr->ctrlPktInfo.ctrlPktActive = llSetupEncRsp( connPtr ); + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + case LL_CTRL_START_ENC_REQ: + + // check if the control packet procedure is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if it has been transmitted yet + // Note: This only means the packet has been transmitted, not that it + // has been ACK'ed or NACK'ed. + if ( rfCounters.numTxCtrl ) + { + // enable encryption once start encryption request is sent + // Note: We can not receive data once the encryption control + // procedure has begun, so there is no risk of a race + // condition here. + connPtr->encEnabled = TRUE; + // clear packet counters + connPtr->encInfo.txPktCount = 0; + connPtr->encInfo.rxPktCount = 0; + } + + // not done until the LL_CTRL_START_ENC_RSP is received, so check it + // Note: The following code can not be in the previous "if" statement + // since it is possible that numTxCtrl could be true, yet the + // flag startEncRspRcved isn't. Then on the next event, + // numTxCtrl wouldn't be true, and we would never check the + // startEncRspRcved flag again. Since we can't get the + // LL_START_ENC_RSP until we send the LL_CTRL_START_ENC_REQ, + // this isn't an issue. + if ( connPtr->encInfo.startEncRspRcved == TRUE ) + { + // replace control procedure at head of queue to prevent interleaving + llReplaceCtrlPkt( connPtr, LL_CTRL_START_ENC_RSP ); + } + else // not done yet + { + // check if a start enc req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_PEER_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // first, check if the SK has been calculated + if ( connPtr->encInfo.SKValid == TRUE ) + { + // so try to begin the last step of the encryption procedure + if ( llSetupStartEncReq( connPtr ) == TRUE ) + { + // ready the flag that indicates that we've received the response + connPtr->encInfo.startEncRspRcved = FALSE; + // the control packet is now active + connPtr->ctrlPktInfo.ctrlPktActive = TRUE; + } + + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrl. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrl, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + else // SK isn't valid yet, so see if we've received the LTK yet + { + if ( connPtr->encInfo.LTKValid ) + { + // generate the Session Key (i.e. SK = AES128(LTK, SKD)) + LL_ENC_GenerateSK( connPtr->encInfo.LTK, + connPtr->encInfo.SKD, + connPtr->encInfo.SK ); + // indicate the SK is valid, and drop through + connPtr->encInfo.SKValid = TRUE; + } + else // not done yet + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + + break; + + case LL_CTRL_START_ENC_RSP: + + // check if the control packet procedure is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if it has been transmitted yet + // Note: This only means the packet has been transmitted, not that it + // has been ACK'ed or NACK'ed. + if ( rfCounters.numTxCtrl ) + { + // packet TX'ed, so we are done with the encryption procedure + // re-activate slave latency + connPtr->slaveLatency = connPtr->slaveLatencyValue; + // remove control packet from processing queue and drop through + llDequeueCtrlPkt( connPtr ); + // set flag to allow outgoing data transmissions + connPtr->txDataEnabled = TRUE; + // okay to receive data again + connPtr->rxDataEnabled = TRUE; + + // notify the Host + if ( connPtr->encInfo.encRestart == TRUE ) + { + // a key change was requested + LL_EncKeyRefreshCback( connPtr->connId, + LL_ENC_KEY_REQ_ACCEPTED ); + } + else + { + // a new encryption was requested + LL_EncChangeCback( connPtr->connId, + LL_ENC_KEY_REQ_ACCEPTED, + LL_ENCRYPTION_ON ); + } + + // clear the restart flag in case of another key change request, + // and all other encryption flags + // Note: But in reality, there isn't a disable encryption in BLE, + // so once encryption is enabled, any call to LL_StartEncrypt + // will result in an encryption key change callback. + connPtr->encInfo.encRestart = FALSE; + connPtr->encInfo.encReqRcved = FALSE; + connPtr->encInfo.pauseEncRspRcved = FALSE; + connPtr->encInfo.startEncRspRcved = FALSE; + } + else // not done yet + { + // check if a update param req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_PEER_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + connPtr->ctrlPktInfo.ctrlPktActive = llSetupStartEncRsp( connPtr ); + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + case LL_CTRL_PAUSE_ENC_RSP: + + // check if the control packet procedure is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // not done until the LL_CTRL_PAUSE_ENC_RSP is received, so check it + if ( connPtr->encInfo.pauseEncRspRcved == TRUE ) + { + // done with this control packet, so remove from the processing + // queue and drop through (so the encrypton response can be + // processed) + // ALT: COULD REPLACE HEAD OF QUEUE WITH DUMMY SO NO OTHER CONTROL + // PROCEDURE CAN INTERLEAVE BEFORE THE ENC_REQ IS RECEIVED. + llDequeueCtrlPkt( connPtr ); + } + else // not received yet, so decrement and check control procedure timeout + { + // check if a start enc req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_PEER_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there + // Note: All pending transmissions must also be finished before this + // packet is placed in the TX FIFO. + if ( llSetupPauseEncRsp( connPtr ) == TRUE ) + { + // clear the flag that indicates an Encryption Request has been + // received, which is used by this control procedure to restart the + // control procedure timeout + connPtr->encInfo.pauseEncRspRcved = FALSE; + // disable encryption + // Note: Not really necessary as no data is supposed to be sent + // or received. + connPtr->encEnabled = FALSE; + // the control packet is now active; drop through + connPtr->ctrlPktInfo.ctrlPktActive = TRUE; + } + else // not done yet + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + + break; + + case LL_CTRL_REJECT_IND: + + // check if the control packet procedure is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if it has been transmitted yet + // Note: This only means the packet has been transmitted, not that it + // has been ACK'ed or NACK'ed. + // Note: The control procedure does not end until the Reject is ACKed. + // However, if the ACK is a data packet, it will be tossed + // unless data is allowed hereafter. So to avoid this, only + // the confirmed transmission of this will be used to qualify + // the related flags, but a new procedure will not be able to + // begin until this procedure completes, per the spec. + if ( rfCounters.numTxCtrl ) + { + // disable encryption + // Note: Never really enabled so this isn't necessary. + connPtr->encEnabled = FALSE; + // set flag to allow outgoing data transmissions + connPtr->txDataEnabled = TRUE; + // okay to receive data again + connPtr->rxDataEnabled = TRUE; + } + + // we have already place packet on TX FIFO, so check if its been ACK'ed + if ( rfCounters.numTxCtrlAck ) + { + // done with this control packet, so remove from the processing + // queue and drop through + llDequeueCtrlPkt( connPtr ); + } + else // not ack'ed yet + { + // check if a control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_PEER_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + connPtr->ctrlPktInfo.ctrlPktActive = llSetupRejectInd( connPtr,connPtr->encInfo.encRejectErrCode); + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + // should be LL_CTRL_SLAVE_FEATURE_REQ +// case LL_CTRL_FEATURE_REQ: // for v4.2, slave may send LL_CTRL_FEATURE_REQ msg. to be test later......... HZF +// // check if the control packet procedure is active +// if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) +// { +// // we have already placed a packet on TX FIFO, so wait now until we +// // get the slave's LL_CTRL_FEATURE_RSP +// if ( connPtr->featureSetInfo.featureRspRcved == TRUE ) +// { +// // notify the Host +// LL_ReadRemoteUsedFeaturesCompleteCback( LL_STATUS_SUCCESS, +// connPtr->connId, +// connPtr->featureSetInfo.featureSet ); + +// // done with this control packet, so remove from the processing queue +// llDequeueCtrlPkt( connPtr ); +// } +// else // no done yet +// { +// // check if a update param req control procedure timeout has occurred +// // Note: No need to cleanup control packet info as we are done. +// if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) +// { +// // indicate a control procedure timeout on this request +// // Note: The parameters are not valid. +// LL_ReadRemoteUsedFeaturesCompleteCback( LL_CTRL_PKT_TIMEOUT_TERM, +// connPtr->connId, +// connPtr->featureSetInfo.featureSet ); +// // we're done waiting, so end it all +// // Note: No need to cleanup control packet info as we are done. +// llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_HOST_TERM ); + +// return( LL_CTRL_PROC_STATUS_TERMINATE ); +// } +// else +// { +// // control packet stays at head of queue, so exit here +// return( LL_CTRL_PROC_STATUS_SUCCESS ); +// } +// } +// } +// else // control packet has not been put on the TX FIFO yet +// { +// // so try to put it there; being active depends on a success +// connPtr->ctrlPktInfo.ctrlPktActive = llSetupFeatureSetReq( connPtr ); + +// // set flag while we wait for response +// // Note: It is okay to repeatedly set this flag in the event the +// // setup routine hasn't completed yet (e.g. if the TX FIFO +// // has not yet become empty). +// connPtr->featureSetInfo.featureRspRcved = FALSE; + +// // Note: Two cases are possible: +// // a) We successfully placed the packet in the TX FIFO. +// // b) We did not. +// // +// // In case (a), it may be possible that a previously just +// // completed control packet happened to complete based on +// // rfCounters.numTxCtrlAck. Since the current control +// // procedure is now active, it could falsely detect +// // rfCounters.numTxCtrlAck, when in fact this was from the +// // previous control procedure. Consequently, return. +// // +// // In case (b), the control packet stays at the head of the +// // queue, and there's nothing more to do. Consequently, return. +// // +// // So, in either case, return. +// return( LL_CTRL_PROC_STATUS_SUCCESS ); +// } + +// break; + + case LL_CTRL_FEATURE_RSP: + + // check if the control packet procedure is is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if it has been transmitted yet + // Note: This does not mean this packet has been ACK'ed or NACK'ed. + if ( rfCounters.numTxCtrl ) + { + // packet TX'ed, so use this flag on the Slave to indicate that + // the feature response procedure has already taken place on this + // connection + // Note: This is being done to support the HCI extension command + // LL_EXT_SetLocalSupportedFeatures so that the user can + // update the local supported features even after a connection + // is formed. This update will be used as long as a feature + // response feature has not been performed by the Master. Once + // performed, the connection feature set is fixed! + connPtr->featureSetInfo.featureRspRcved = TRUE; + // ALT: COULD RE-ACTIVATE SL (IF ENABLED) RIGHT HERE. + connPtr->slaveLatency = connPtr->slaveLatencyValue; + // remove control packet from processing queue and drop through + llDequeueCtrlPkt( connPtr ); + } + else // not done yet + { + // check if a start enc req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_PEER_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + // Note: There is no control procedure timeout associated with this + // control packet. + connPtr->ctrlPktInfo.ctrlPktActive = llSetupFeatureSetRsp( connPtr ); + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + // Version Information Indication + case LL_CTRL_VERSION_IND: + + // check if the control packet procedure is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if the peer's version information is valid + if ( connPtr->verExchange.peerInfoValid == TRUE ) + { + // yes, so check if the host has requested this information + if ( connPtr->verExchange.hostRequest == TRUE ) + { + // yes, so provide it + LL_ReadRemoteVersionInfoCback( LL_STATUS_SUCCESS, + connPtr->connId, + connPtr->verInfo.verNum, + connPtr->verInfo.comId, + connPtr->verInfo.subverNum ); + } + + // in any case, dequeue this control procedure + llDequeueCtrlPkt( connPtr ); + } + else // no done yet + { + // check if a update param req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // we're done waiting, so complete the callback with error + LL_ReadRemoteVersionInfoCback( LL_CTRL_PKT_TIMEOUT_TERM, + connPtr->connId, + connPtr->verInfo.verNum, + connPtr->verInfo.comId, + connPtr->verInfo.subverNum ); + // and end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_HOST_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // since we are in the process of sending the version indication, + // it is okay to set this flag here even if it is set repeatedly + // in the of llSetupVersionIndReq failures + connPtr->verExchange.verInfoSent = TRUE; + // so try to put it there; being active depends on a success + connPtr->ctrlPktInfo.ctrlPktActive = llSetupVersionIndReq( connPtr ); + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + case LL_CTRL_LENGTH_REQ: + + // check if the control packet procedure is is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if it has been transmitted yet + // Note: This does not mean this packet has been ACK'ed or NACK'ed. + if ( rfCounters.numTxCtrl ) + { + connPtr->llPduLen.isWatingRsp=TRUE; + // remove control packet from processing queue and drop through + llDequeueCtrlPkt( connPtr ); + } + else // not done yet + { + // check if a start enc req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_PEER_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + // Note: There is no control procedure timeout associated with this + // control packet. + connPtr->ctrlPktInfo.ctrlPktActive = llSetupDataLenghtReq( connPtr ); + connPtr->llPduLen.isWatingRsp=FALSE; + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + case LL_CTRL_LENGTH_RSP: + + // check if the control packet procedure is is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if it has been transmitted yet + // Note: This does not mean this packet has been ACK'ed or NACK'ed. + if ( rfCounters.numTxCtrl ) + { + connPtr->llPduLen.isProcessingReq=FALSE; + llPduLengthUpdate((uint16)connPtr->connId); + // remove control packet from processing queue and drop through + llDequeueCtrlPkt( connPtr ); + } + else // not done yet + { + // check if a start enc req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_PEER_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + // Note: There is no control procedure timeout associated with this + // control packet. + connPtr->ctrlPktInfo.ctrlPktActive = llSetupDataLenghtRsp( connPtr ); + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + case LL_CTRL_PHY_REQ: + + // check if the control packet procedure is is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if it has been transmitted yet + // Note: This does not mean this packet has been ACK'ed or NACK'ed. + if ( rfCounters.numTxCtrl ) + { + connPtr->llPhyModeCtrl.isWatingRsp=TRUE; + // remove control packet from processing queue and drop through + llDequeueCtrlPkt( connPtr ); + } + else // not done yet + { + // check if a start enc req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_PEER_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + // Note: There is no control procedure timeout associated with this + // control packet. + connPtr->ctrlPktInfo.ctrlPktActive = llSetupPhyReq( connPtr ); + connPtr->llPhyModeCtrl.isWatingRsp=FALSE; + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + case LL_CTRL_PHY_RSP: + + // check if the control packet procedure is is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if it has been transmitted yet + // Note: This does not mean this packet has been ACK'ed or NACK'ed. + if ( rfCounters.numTxCtrl ) + { + connPtr->llPhyModeCtrl.isProcessingReq=FALSE; + connPtr->llPhyModeCtrl.isWatingRsp=TRUE; + // remove control packet from processing queue and drop through + llDequeueCtrlPkt( connPtr ); + } + else // not done yet + { + // check if a start enc req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_PEER_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + // Note: There is no control procedure timeout associated with this + // control packet. + connPtr->ctrlPktInfo.ctrlPktActive = llSetupPhyRsp( connPtr ); + connPtr->llPhyModeCtrl.isWatingRsp=FALSE; + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + case LL_CTRL_CTE_REQ: + + // check if the control packet procedure is is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if it has been transmitted yet + // Note: This does not mean this packet has been ACK'ed or NACK'ed. + if ( rfCounters.numTxCtrl ) + { + // connPtr->llPhyModeCtrl.isWatingRsp=TRUE; + // remove control packet from processing queue and drop through + llDequeueCtrlPkt( connPtr ); + } + else // not done yet + { + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + osal_memset( &(connPtr->llCTEModeCtrl), 0, sizeof( connPtr->llCTEModeCtrl )); + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_PEER_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + connPtr->ctrlPktInfo.ctrlPktActive = llSetupCTEReq( connPtr ); + connPtr->llCTEModeCtrl.isWatingRsp = TRUE; + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + case LL_CTRL_CTE_RSP: + + // check if the control packet procedure is is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if it has been transmitted yet + // Note: This does not mean this packet has been ACK'ed or NACK'ed. + if ( rfCounters.numTxCtrl ) + { + connPtr->llCTEModeCtrl.isWatingRsp = FALSE; + connPtr->llCTEModeCtrl.isProcessingReq = FALSE; + // remove control packet from processing queue and drop through + // 2020-02-12 comment:after send CONN CTE RSP , then clear txSupp + ll_hw_set_cte_txSupp( CTE_SUPP_NULL); + llDequeueCtrlPkt( connPtr ); + } + else // not done yet + { + } + } + else // control packet has not been put on the TX FIFO yet + { + connPtr->ctrlPktInfo.ctrlPktActive = llSetupCTERsp( connPtr ); + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + case LL_CTRL_UNKNOWN_RSP: + + // try to place control packet in the TX FIFO + // Note: Since there are no dependencies for this control packet, we + // do not have to bother with the active flag. + if ( llSetupUnknownRsp( connPtr ) == TRUE ) + { + // all we have to do is put this control packet on the TX FIFO, so + // remove control packet from the processing queue and drop through + llDequeueCtrlPkt( connPtr ); + } + else // not done yet + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + // Dummy Place Holder + //case LL_CTRL_DUMMY_PLACE_HOLDER: + // // dummy packet stays at head of queue, so exit here + // Note: Unreachable statement generates compiler warning! + //break; + // return( LL_CTRL_PROC_STATUS_SUCCESS ); + + default: + break; + } + } + + return( LL_CTRL_PROC_STATUS_SUCCESS ); +} + +uint8 llProcessMasterControlProcedures1( llConnState_t* connPtr ) +{ + // check if there are any control packets ready for processing + while ( connPtr->ctrlPktInfo.ctrlPktCount > 0 ) + { + // processing based on control packet type at the head of the queue + switch( connPtr->ctrlPktInfo.ctrlPkts[ 0 ] ) + { + case LL_CTRL_TERMINATE_IND: + + // check if the control packet procedure is is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // we have already place packet on TX FIFO, so check if its been ACK'ed + if ( rfCounters.numTxCtrlAck ) + { + // done with this control packet, so remove from the processing queue + llDequeueCtrlPkt( connPtr ); + // yes, so process the termination + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_HOST_REQUESTED_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else // no done yet + { + // check if a termination control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_HOST_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + connPtr->ctrlPktInfo.ctrlPktActive = llSetupTermInd( connPtr ); + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + // Note: Unreachable statement generates compiler warning! + //break; + + /* + ** Connection Update Request + */ + case LL_CTRL_CONNECTION_UPDATE_REQ: + +// LOG("CONN UPD"); + // check if the control packet procedure is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // we have already placed a packet on TX FIFO, so check if its been ACK'ed + if ( rfCounters.numTxCtrlAck ) + { + // yes, so adjust all time values to units of 625us + connPtr->paramUpdate.winSize <<= 1; + connPtr->paramUpdate.winOffset <<= 1; + connPtr->paramUpdate.connInterval <<= 1; + connPtr->paramUpdate.connTimeout <<= 4; + // and activate the update + connPtr->pendingParamUpdate = TRUE; + // done with this control packet, so remove from the processing queue + llDequeueCtrlPkt( connPtr ); + } + else // no done yet + { + // Core Spec V4.0 now indicates there is no control procedure + // timeout. However, it still seems prudent to monitor for the + // instant while waiting for the slave's ACK. + if ( connPtr->nextEvent == connPtr->paramUpdateEvent ) + { + // this event is the instant, and the control procedure still + // has not been ACK'ed, we the instant has passed + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_INSTANT_PASSED_HOST_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else // continue waiting for the slave's ACK + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + connPtr->ctrlPktInfo.ctrlPktActive = llSetupUpdateParamReq( connPtr ); + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + /* + ** Channel Map Update Request + */ + case LL_CTRL_CHANNEL_MAP_REQ: + + // check if the control packet procedure is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // we have already placed a packet on TX FIFO, so check if its been ACK'ed + if ( rfCounters.numTxCtrlAck ) + { + // yes, so activate the update + connPtr->pendingChanUpdate = TRUE; + // done with this control packet, so remove from the processing queue + llDequeueCtrlPkt( connPtr ); + } + else // no done yet + { + // Core Spec V4.0 now indicates there is no control procedure + // timeout. However, it still seems prudent to monitor for the + // instant while waiting for the slave's ACK. + if ( connPtr->nextEvent == connPtr->chanMapUpdateEvent ) + { + // this event is the instant, and the control procedure still + // has not been ACK'ed, we the instant has passed + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_INSTANT_PASSED_HOST_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else // continue waiting for the slave's ACK + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + connPtr->ctrlPktInfo.ctrlPktActive = llSetupUpdateChanReq( connPtr ); + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + /* + ** Encryption Request + */ + case LL_CTRL_ENC_REQ: + +// LOG("1 ENC_REQ->"); + // check if the control packet procedure is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if it has been transmitted yet + // Note: This does not mean this packet has been ACK'ed or NACK'ed. + if ( rfCounters.numTxCtrl ) + { + // set flag to discard all incoming data transmissions + connPtr->rxDataEnabled = FALSE; + } + + // we have already placed a packet on TX FIFO, so wait now until we + // get the slave's LL_START_ENC_REQ + if ( connPtr->encInfo.startEncReqRcved == TRUE ) + { + // clear packet counters + connPtr->encInfo.txPktCount = 0; + connPtr->encInfo.rxPktCount = 0; + // enable encryption + connPtr->encEnabled = TRUE; + // replace control procedure at head of queue to prevent interleaving + llReplaceCtrlPkt( connPtr, LL_CTRL_START_ENC_RSP ); + } + else if ( connPtr->encInfo.rejectIndRcved == TRUE ) + { + // the slave's Host has failed to provide an LTK, so the encryption + // setup has been rejected; end the start encryption procedure + // done with this control packet, so remove from the processing queue + llDequeueCtrlPkt( connPtr ); + // disable encryption + // Note: Not really necessary as no data is supposed to be sent + // or received. + connPtr->encEnabled = FALSE; + // set flag to allow outgoing transmissions again + connPtr->txDataEnabled = TRUE; + // set flag to allow all incoming data transmissions + connPtr->rxDataEnabled = TRUE; + + // check the rejection indication error code + if ( connPtr->encInfo.encRejectErrCode == LL_STATUS_ERROR_PIN_OR_KEY_MISSING ) + { + // notify the Host + LL_EncChangeCback( connPtr->connId, + LL_ENC_KEY_REQ_REJECTED, + LL_ENCRYPTION_OFF ); + } + else // LL_STATUS_ERROR_UNSUPPORTED_REMOTE_FEATURE + { + // notify the Host + LL_EncChangeCback( connPtr->connId, + LL_ENC_KEY_REQ_UNSUPPORTED_FEATURE, + LL_ENCRYPTION_OFF ); + } + } + else if ( connPtr->termInfo.termIndRcvd == TRUE ) + { + // the slave's Host has failed to provide an LTK, so the encryption + // setup has been rejected; end the start encryption procedure + // done with this control packet, so remove from the processing queue + llDequeueCtrlPkt( connPtr ); + } + else // no done yet + { + // check if a update param req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // notify the Host + if ( connPtr->encInfo.encRestart == TRUE ) + { + // a key change was requested + LL_EncKeyRefreshCback( connPtr->connId, + LL_CTRL_PKT_TIMEOUT_TERM ); + } + else + { + // a new encryption was requested + LL_EncChangeCback( connPtr->connId, + LL_CTRL_PKT_TIMEOUT_TERM, + LL_ENCRYPTION_OFF ); + } + + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_HOST_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + connPtr->ctrlPktInfo.ctrlPktActive = llSetupEncReq( connPtr ); + // set a flag to indicate we have received LL_START_ENC_REQ + // Note: The LL_ENC_RSP will be received first, which will result in + // the master calculating its IVm and SKDm, concatenating it + // with the slave's IVs and SKDs, and calculating the SK from + // the LTK and SKD. After that, we will receive the + // LL_START_ENC_REQ from the slave. So, it is okay to stay in + // this control procedure until LL_START_ENC_REQ is received. + // Note: It is okay to repeatedly set this flag in the event the + // setup routine hasn't completed yet (e.g. if the TX FIFO + // has not yet become empty). + connPtr->encInfo.startEncReqRcved = FALSE; + connPtr->encInfo.rejectIndRcved = FALSE; + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + /* + ** Encryption Start Response + */ + case LL_CTRL_START_ENC_RSP: + +// LOG("1 START_ENC_RSP->"); + // check if the control packet procedure is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // we have already placed a packet on TX FIFO, so wait now until we + // get the slave's LL_START_ENC_RSP + if ( connPtr->encInfo.startEncRspRcved == TRUE ) + { + // done with this control packet, so remove from the processing queue + llDequeueCtrlPkt( connPtr ); + // we're done with encryption procedure, so clear flags + connPtr->encInfo.encReqRcved = FALSE; + connPtr->encInfo.pauseEncRspRcved = FALSE; + connPtr->encInfo.startEncReqRcved = FALSE; + connPtr->encInfo.startEncRspRcved = FALSE; + connPtr->encInfo.rejectIndRcved = FALSE; + } + else // no done yet + { + // check if a update param req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // notify the Host + if ( connPtr->encInfo.encRestart == TRUE ) + { + // a key change was requested + LL_EncKeyRefreshCback( connPtr->connId, + LL_CTRL_PKT_TIMEOUT_TERM ); + } + else + { + // a new encryption was requested + LL_EncChangeCback( connPtr->connId, + LL_CTRL_PKT_TIMEOUT_TERM, + LL_ENCRYPTION_OFF ); + } + + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_HOST_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + // Note: The llSetupStartEncRsp routine will *not* reset the control + // timeout value since the entire encryption procedure starts + // with the master sending the LL_ENC_REQ, and ends when the + // master receives the LL_START_ENC_RSP from the slave. + connPtr->ctrlPktInfo.ctrlPktActive = llSetupStartEncRsp( connPtr ); + // set a flag to indicate we have received LL_START_ENC_RSP + // Note: It is okay to repeatedly set this flag in the event the + // setup routine hasn't completed yet (e.g. if the TX FIFO + // has not yet become empty). + connPtr->encInfo.startEncRspRcved = FALSE; + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + /* + ** Encryption Pause Request + */ + case LL_CTRL_PAUSE_ENC_REQ: + + // check if the control packet procedure is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // we have already placed a packet on TX FIFO, so wait now until we + // get the slave's LL_PAUSE_ENC_RSP + if ( connPtr->encInfo.pauseEncRspRcved == TRUE ) + { + // disable encryption + connPtr->encEnabled = FALSE; + // replace control procedure at head of queue to prevent interleaving + llReplaceCtrlPkt( connPtr, LL_CTRL_PAUSE_ENC_RSP ); + } + else // no done yet + { + // check if a update param req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // notify the Host + if ( connPtr->encInfo.encRestart == TRUE ) + { + // a key change was requested + LL_EncKeyRefreshCback( connPtr->connId, + LL_CTRL_PKT_TIMEOUT_TERM ); + } + else + { + // a new encryption was requested + LL_EncChangeCback( connPtr->connId, + LL_CTRL_PKT_TIMEOUT_TERM, + LL_ENCRYPTION_OFF ); + } + + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_HOST_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + // Note: The llSetupStartEncRsp routine will *not* reset the control + // timeout value since the entire encryption procedure starts + // with the master sending the LL_ENC_REQ, and ends when the + // master receives the LL_START_ENC_RSP from the slave. + connPtr->ctrlPktInfo.ctrlPktActive = llSetupPauseEncReq( connPtr ); + // set a flag to indicate we have received LL_START_ENC_RSP + // Note: It is okay to repeatedly set this flag in the event the + // setup routine hasn't completed yet (e.g. if the TX FIFO + // has not yet become empty). + connPtr->encInfo.pauseEncRspRcved = FALSE; + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + /* + ** Encryption Pause Response + */ + case LL_CTRL_PAUSE_ENC_RSP: + + // check if the control packet procedure is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if it has been transmitted yet + // Note: This only means the packet has been transmitted, not that it + // has been ACK'ed or NACK'ed. + if ( rfCounters.numTxCtrl ) + { + // replace control procedure at head of queue to prevent interleaving + llReplaceCtrlPkt( connPtr, LL_CTRL_ENC_REQ ); + } + else // no done yet + { + // check if a update param req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // notify the Host + if ( connPtr->encInfo.encRestart == TRUE ) + { + // a key change was requested + LL_EncKeyRefreshCback( connPtr->connId, + LL_CTRL_PKT_TIMEOUT_TERM ); + } + else + { + // a new encryption was requested + LL_EncChangeCback( connPtr->connId, + LL_CTRL_PKT_TIMEOUT_TERM, + LL_ENCRYPTION_OFF ); + } + + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_HOST_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + connPtr->ctrlPktInfo.ctrlPktActive = llSetupPauseEncRsp( connPtr ); + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + /* + ** Feature Set Request + */ + case LL_CTRL_FEATURE_REQ: + + // check if the control packet procedure is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // we have already placed a packet on TX FIFO, so wait now until we + // get the slave's LL_CTRL_FEATURE_RSP + if ( connPtr->featureSetInfo.featureRspRcved == TRUE ) + { + // notify the Host + LL_ReadRemoteUsedFeaturesCompleteCback( LL_STATUS_SUCCESS, + connPtr->connId, + connPtr->featureSetInfo.featureSet ); + // done with this control packet, so remove from the processing queue + llDequeueCtrlPkt( connPtr ); + } + else // no done yet + { + // check if a update param req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // indicate a control procedure timeout on this request + // Note: The parameters are not valid. + LL_ReadRemoteUsedFeaturesCompleteCback( LL_CTRL_PKT_TIMEOUT_TERM, + connPtr->connId, + connPtr->featureSetInfo.featureSet ); + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_HOST_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // add by HZF, read device feature set + for (int i=0; ifeatureSetInfo.featureSet[i] = deviceFeatureSet.featureSet[i]; + } + + // so try to put it there; being active depends on a success + connPtr->ctrlPktInfo.ctrlPktActive = llSetupFeatureSetReq( connPtr ); + // set flag while we wait for response + // Note: It is okay to repeatedly set this flag in the event the + // setup routine hasn't completed yet (e.g. if the TX FIFO + // has not yet become empty). + connPtr->featureSetInfo.featureRspRcved = FALSE; + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + case LL_CTRL_FEATURE_RSP: // new for BLE4.2, feature req could be init by slave + + // check if the control packet procedure is is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if it has been transmitted yet + // Note: This does not mean this packet has been ACK'ed or NACK'ed. + if ( rfCounters.numTxCtrl ) + { + // packet TX'ed, so use this flag on the Slave to indicate that + // the feature response procedure has already taken place on this + // connection + // Note: This is being done to support the HCI extension command + // LL_EXT_SetLocalSupportedFeatures so that the user can + // update the local supported features even after a connection + // is formed. This update will be used as long as a feature + // response feature has not been performed by the Master. Once + // performed, the connection feature set is fixed! + connPtr->featureSetInfo.featureRspRcved = TRUE; + // ALT: COULD RE-ACTIVATE SL (IF ENABLED) RIGHT HERE. +// connPtr->slaveLatency = connPtr->slaveLatencyValue; + // remove control packet from processing queue and drop through + llDequeueCtrlPkt( connPtr ); + } + else // not done yet + { + // check if a start enc req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_PEER_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + // Note: There is no control procedure timeout associated with this + // control packet. + connPtr->ctrlPktInfo.ctrlPktActive = llSetupFeatureSetRsp( connPtr ); + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + /* + ** Vendor Information Exchange (Request or Reply) + */ + case LL_CTRL_VERSION_IND: + + // check if the control packet procedure is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if the peer's version information is valid + if ( connPtr->verExchange.peerInfoValid == TRUE ) + { + // yes, so check if the host has requested this information + if ( connPtr->verExchange.hostRequest == TRUE ) + { + // yes, so provide it + LL_ReadRemoteVersionInfoCback( LL_STATUS_SUCCESS, + connPtr->connId, + connPtr->verInfo.verNum, + connPtr->verInfo.comId, + connPtr->verInfo.subverNum ); + } + + // in any case, dequeue this control procedure + llDequeueCtrlPkt( connPtr ); + } + else // no done yet + { + // check if a update param req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // we're done waiting, so complete the callback with error + LL_ReadRemoteVersionInfoCback( LL_CTRL_PKT_TIMEOUT_TERM, + connPtr->connId, + connPtr->verInfo.verNum, + connPtr->verInfo.comId, + connPtr->verInfo.subverNum ); + // and end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_HOST_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // since we are in the process of sending the version indication, + // it is okay to set this flag here even if it is set repeatedly + // in the of llSetupVersionIndReq failures + connPtr->verExchange.verInfoSent = TRUE; +// // so try to put it there; being active depends on a success +// connPtr->ctrlPktInfo.ctrlPktActive = llSetupPingReq(connPtr);// llSetupVersionIndReq( connPtr ); + connPtr->ctrlPktInfo.ctrlPktActive = llSetupVersionIndReq( connPtr ); + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + case LL_CTRL_LENGTH_REQ: + + // check if the control packet procedure is is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if it has been transmitted yet + // Note: This does not mean this packet has been ACK'ed or NACK'ed. + if ( rfCounters.numTxCtrl ) + { + connPtr->llPduLen.isWatingRsp=TRUE; + // remove control packet from processing queue and drop through + llDequeueCtrlPkt( connPtr ); + } + else // not done yet + { + // check if a start enc req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_PEER_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + // Note: There is no control procedure timeout associated with this + // control packet. + connPtr->ctrlPktInfo.ctrlPktActive = llSetupDataLenghtReq( connPtr ); + connPtr->llPduLen.isWatingRsp=FALSE; + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + case LL_CTRL_LENGTH_RSP: + + // check if the control packet procedure is is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if it has been transmitted yet + // Note: This does not mean this packet has been ACK'ed or NACK'ed. + if ( rfCounters.numTxCtrl ) + { + connPtr->llPduLen.isProcessingReq=FALSE; + llPduLengthUpdate((uint16)connPtr->connId); + // remove control packet from processing queue and drop through + llDequeueCtrlPkt( connPtr ); + } + else // not done yet + { + // check if a start enc req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_PEER_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + // Note: There is no control procedure timeout associated with this + // control packet. + connPtr->ctrlPktInfo.ctrlPktActive = llSetupDataLenghtRsp( connPtr ); + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + // LL PHY UPDATE REQ + case LL_CTRL_PHY_REQ: + + // check if the control packet procedure is is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if it has been transmitted yet + // Note: This does not mean this packet has been ACK'ed or NACK'ed. + if ( rfCounters.numTxCtrl ) + { + connPtr->llPhyModeCtrl.isWatingRsp=TRUE; + // remove control packet from processing queue and drop through + llDequeueCtrlPkt( connPtr ); + } + else // not done yet + { + // check if a start enc req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_PEER_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + // Note: There is no control procedure timeout associated with this + // control packet. + connPtr->ctrlPktInfo.ctrlPktActive = llSetupPhyReq( connPtr ); + connPtr->llPhyModeCtrl.isWatingRsp=FALSE; + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + case LL_CTRL_PHY_UPDATE_IND: + + // check if the control packet procedure is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // we have already placed a packet on TX FIFO, so check if its been ACK'ed + if ( rfCounters.numTxCtrlAck ) + { + //20181206 ZQ phy update no change case + if( connPtr->phyUpdateInfo.m2sPhy== 0 + && connPtr->phyUpdateInfo.s2mPhy== 0) + { + connPtr->phyUpdateInfo.m2sPhy=connPtr->llPhyModeCtrl.local.txPhy; + connPtr->phyUpdateInfo.s2mPhy=connPtr->llPhyModeCtrl.local.rxPhy; + llPhyModeCtrlUpdateNotify(connPtr,LL_STATUS_SUCCESS); + } + else + { + // yes, so activate the update + connPtr->pendingPhyModeUpdate = TRUE; + } + + connPtr->llPhyModeCtrl.isWatingRsp=FALSE; + connPtr->llPhyModeCtrl.isProcessingReq=FALSE; + // done with this control packet, so remove from the processing queue + llDequeueCtrlPkt( connPtr ); + } + else // no done yet + { + // Core Spec V4.0 now indicates there is no control procedure + // timeout. However, it still seems prudent to monitor for the + // instant while waiting for the slave's ACK. + if ( connPtr->nextEvent == connPtr->phyModeUpdateEvent ) + { + // this event is the instant, and the control procedure still + // has not been ACK'ed, we the instant has passed + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_INSTANT_PASSED_HOST_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else // continue waiting for the slave's ACK + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + // so try to put it there; being active depends on a success + connPtr->ctrlPktInfo.ctrlPktActive = llSetupPhyUpdateInd( connPtr ); + // Note: Two cases are possible: + // a) We successfully placed the packet in the TX FIFO. + // b) We did not. + // + // In case (a), it may be possible that a previously just + // completed control packet happened to complete based on + // rfCounters.numTxCtrlAck. Since the current control + // procedure is now active, it could falsely detect + // rfCounters.numTxCtrlAck, when in fact this was from the + // previous control procedure. Consequently, return. + // + // In case (b), the control packet stays at the head of the + // queue, and there's nothing more to do. Consequently, return. + // + // So, in either case, return. + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + // REJECT EXT IND --> PHY UPDATE COLLSION + case LL_CTRL_REJECT_EXT_IND: + + // check if the control packet procedure is is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if it has been transmitted yet + // Note: This does not mean this packet has been ACK'ed or NACK'ed. + if ( rfCounters.numTxCtrl ) + { + connPtr->isCollision=TRUE; + // remove control packet from processing queue and drop through + llDequeueCtrlPkt( connPtr ); + } + else // not done yet + { + // check if a start enc req control procedure timeout has occurred + // Note: No need to cleanup control packet info as we are done. + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_PEER_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + if(connPtr->llPhyModeCtrl.isWatingRsp==TRUE) + { + connPtr->ctrlPktInfo.ctrlPktActive = llSetupRejectExtInd( connPtr,LL_STATUS_ERROR_LL_PROCEDURE_COLLISION); + } + else if(connPtr->pendingChanUpdate==TRUE || + connPtr->pendingParamUpdate==TRUE ) + { + connPtr->ctrlPktInfo.ctrlPktActive = llSetupRejectExtInd( connPtr,LL_STATUS_ERROR_DIFF_TRANSACTION_COLLISION); + } + else if( connPtr->llCTEModeCtrl.isWatingRsp == TRUE) + { + // 2020-01-23 add for CTE + connPtr->ctrlPktInfo.ctrlPktActive = llSetupRejectExtInd( connPtr,connPtr->llCTEModeCtrl.errorCode ); + connPtr->llCTEModeCtrl.errorCode = LL_STATUS_SUCCESS; + } + else + { + //should not be here + } + + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + case LL_CTRL_CTE_REQ: + + // check if the control packet procedure is is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if it has been transmitted yet + // Note: This does not mean this packet has been ACK'ed or NACK'ed. + if ( rfCounters.numTxCtrl ) + { + // connPtr->llCTEModeCtrl.isWatingRsp = TRUE; + // remove control packet from processing queue and drop through + llDequeueCtrlPkt( connPtr ); + } + else // not done yet + { + // + if ( --connPtr->ctrlPktInfo.ctrlTimeout == 0 ) + { + osal_memset( &(connPtr->llCTEModeCtrl), 0, sizeof( connPtr->llCTEModeCtrl )); + // we're done waiting, so end it all + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, LL_CTRL_PKT_TIMEOUT_PEER_TERM ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + else + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + } + } + else // control packet has not been put on the TX FIFO yet + { + connPtr->ctrlPktInfo.ctrlPktActive = llSetupCTEReq( connPtr ); + connPtr->llCTEModeCtrl.isWatingRsp = TRUE; + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + case LL_CTRL_CTE_RSP: + + // check if the control packet procedure is is active + if ( connPtr->ctrlPktInfo.ctrlPktActive == TRUE ) + { + // yes, so check if it has been transmitted yet + // Note: This does not mean this packet has been ACK'ed or NACK'ed. + if ( rfCounters.numTxCtrl ) + { + connPtr->llCTEModeCtrl.isProcessingReq = FALSE; + // remove control packet from processing queue and drop through + llDequeueCtrlPkt( connPtr ); + } + else // not done yet + { + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + } + else // control packet has not been put on the TX FIFO yet + { + connPtr->ctrlPktInfo.ctrlPktActive = llSetupCTERsp( connPtr ); + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + /* + ** Unknown Control Type Response + */ + case LL_CTRL_UNKNOWN_RSP: + + // try to place control packet in the TX FIFO + // Note: Since there are no dependencies for this control packet, we + // do not have to bother with the active flag. + if ( llSetupUnknownRsp( connPtr ) == TRUE ) + { + // all we have to do is put this control packet on the TX FIFO, so + // remove control packet from the processing queue and drop through + llDequeueCtrlPkt( connPtr ); + } + else // not done yet + { + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + } + + break; + + /* + ** Control Internal - Wait for Control ACK + */ + case LL_CTRL_TERMINATE_RX_WAIT_FOR_TX_ACK: + + // check if the control packet has been ACK'ed (i.e. is not pending) + // Note: Normally this routine is used for control procedures where + // control packets are sent by this role. This is a special case + // where a terminate indication was received, but we must as a + // master wait for our ACK to be sent before terminating. + if ( rfCounters.numTxCtrlAck == 1) // ctrl packet has been acked + { + // yes, so terminate + // Note: No need to cleanup control packet info as we are done. + llConnTerminate( connPtr, connPtr->termInfo.reason ); + return( LL_CTRL_PROC_STATUS_TERMINATE ); + } + + // control packet stays at head of queue, so exit here + return( LL_CTRL_PROC_STATUS_SUCCESS ); + + // Note: Unreachable statement generates compiler warning! + //break; + + // Dummy Place Holder + //case LL_CTRL_DUMMY_PLACE_HOLDER: + // // dummy packet stays at head of queue, so exit here + // return( LL_CTRL_PROC_STATUS_SUCCESS ); + // Note: Unreachable statement generates compiler warning! + //break; + default: + #ifdef DEBUG + // fatal error - a unknown control procedure value was used + LL_ASSERT( FALSE ); + #endif // DEBUG + break; + } + } + + return( LL_CTRL_PROC_STATUS_SUCCESS ); +} + +static void llAdjBoffUpperLimitFailure1( void ) +{ + // first, since this was a failure, clear the number of consecutive successes + scanInfo.numSuccess = 0; + + // check if we received two failures in a row + if ( ++scanInfo.numFailure == 2 ) + { + // yes, so double backoff upper limit + scanInfo.scanBackoffUL <<= 1; + + // maximum is 256 + if ( scanInfo.scanBackoffUL > 256 ) + { + scanInfo.scanBackoffUL = 256; + } + + // reset consecutive count + scanInfo.numFailure = 0; + } + + g_pmCounters.ll_tbd_cnt4++; + return; +} + +static void llAdjBoffUpperLimitSuccess1( void ) +{ + // first, since this is a success, clear the number of consecutive failures + scanInfo.numFailure = 0; + + // check if we received two successful in a row + if ( ++scanInfo.numSuccess == 2 ) + { + // yes, so half backoff upper limit + scanInfo.scanBackoffUL >>= 1; + + // however, the minimum is 1 + if ( scanInfo.scanBackoffUL == 0 ) + { + scanInfo.scanBackoffUL = 1; + } + + // reset consecutive count + scanInfo.numSuccess = 0; + } + + return; +} + +static void llGenerateNextBackoffCount1( void ) +{ + // determine the new backoff count constrained by upper limit + // Note: Backoff and Upper Limit can be 1..256. + if ( scanInfo.scanBackoffUL == 1 ) + { + scanInfo.currentBackoff = 1; + } + else // backoff count is a random number from 1..UL + { + scanInfo.currentBackoff = ((uint16)LL_ENC_GeneratePseudoRandNum() % scanInfo.scanBackoffUL) + 1; + } + +// hal_uart_tx("scanBackoffUL = "); +// hal_uart_send_int(scanInfo.scanBackoffUL); +// hal_uart_tx(",currentBackoff = "); +// hal_uart_send_int(scanInfo.currentBackoff); +// hal_uart_tx("\r\n"); + return; +} + +uint8 ll_processBasicIRQ_ScanTRX0(uint32_t irq_status ) +{ + _HAL_CS_ALLOC_(); + HAL_ENTER_CRITICAL_SECTION(); + ll_debug_output(DEBUG_LL_HW_TRX); + llScanTime += ((ISR_entry_time > llScanT1) ? (ISR_entry_time - llScanT1) : (BASE_TIME_UNITS - llScanT1 + ISR_entry_time)); + + // check whether receives SCAN RSP + if (irq_status & LIRQ_COK) // bug correct 2018-10-15 + { + // rx done + uint8_t packet_len, pdu_type; + uint16_t pktLen; + uint32_t pktFoot0, pktFoot1; + // read packet + packet_len = ll_hw_read_rfifo1((uint8_t*)(&(g_rx_adv_buf.rxheader)), + &pktLen, + &pktFoot0, + &pktFoot1); + // check receive pdu type + pdu_type = g_rx_adv_buf.rxheader & 0x0f; + + if(ll_hw_get_rfifo_depth()>0) + { + g_pmCounters.ll_rfifo_read_err++; + packet_len=0; + pktLen=0; + } + + if (packet_len > 0 && pdu_type == ADV_SCAN_RSP) + { + // receives SCAN_RSP + uint8 advEventType; + uint8 rpaListIndex; + uint8* peerAddr; + uint8 addrType = (g_rx_adv_buf.rxheader & TX_ADD_MASK) >> TX_ADD_SHIFT; + uint8 dataLen = pktLen - 8; + int8 rssi = -(pktFoot1 >> 24); + uint8 bCheckOk = TRUE; + peerAddr = &g_rx_adv_buf.data[0]; + + //=== + // AdvA of SCAN_RSP should also be checked here. Refer to 4.4.3.2 Active Scanning + // After sending a scan request PDU the Link Layer listens for a scan response + //PDU from that advertiser. If the scan response PDU was not received from that + //advertiser, it is considered a failure; otherwise it is considered a success. + + // check AdvA in Scan Rsp is identical to Scan Req + if (g_rx_adv_buf.data[0] != g_tx_adv_buf.data[6] || + g_rx_adv_buf.data[1] != g_tx_adv_buf.data[7] || + g_rx_adv_buf.data[2] != g_tx_adv_buf.data[8] || + g_rx_adv_buf.data[3] != g_tx_adv_buf.data[9] || + g_rx_adv_buf.data[4] != g_tx_adv_buf.data[10] || + g_rx_adv_buf.data[5] != g_tx_adv_buf.data[11] + ) + bCheckOk = FALSE; + + // RPA checking. Note that we do not check whether it is the same RPA index + if (addrType == LL_DEV_ADDR_TYPE_RANDOM && + (g_rx_adv_buf.data[5] & RANDOM_ADDR_HDR) == PRIVATE_RESOLVE_ADDR_HDR) + { + if (g_llRlEnable == TRUE) + { + rpaListIndex = ll_getRPAListEntry(&g_rx_adv_buf.data[0]); + + if (rpaListIndex < LL_RESOLVINGLIST_ENTRY_NUM) + { + peerAddr = &g_llResolvinglist[rpaListIndex].peerAddr[0]; + // refer to HCI LE Advertising Report Event, RPA address type should be + // 0x02: Public Identity Address (Corresponds to Resolved Private Address) + // 0x03: Random (static) Identity Address (Corresponds to Resolved Private Address) + addrType = g_llResolvinglist[rpaListIndex].peerAddrType + 2; + bCheckOk = TRUE; + } + else + bCheckOk = FALSE; + } + } + + //=== + + if (bCheckOk == TRUE) + { + advEventType = LL_ADV_RPT_SCAN_RSP; + // below function cost 51us/66us(measure with GPIO) + LL_AdvReportCback( advEventType, // event type + addrType, // Adv address type (TxAdd) + peerAddr, // Adv address (AdvA) + dataLen, // length of rest of the payload + &g_rx_adv_buf.data[6], // rest of payload + rssi ); // RSSI + g_pmCounters.ll_recv_scan_rsp_cnt ++; + llAdjBoffUpperLimitSuccess1(); + } + } + else + llAdjBoffUpperLimitFailure1(); + } + else + llAdjBoffUpperLimitFailure1(); + + // update back off value according to new backoff upperLimit + llGenerateNextBackoffCount1(); + + if (llScanTime >= scanInfo.scanWindow * 625) + { + // calculate next scan channel + LL_CALC_NEXT_SCAN_CHN(scanInfo.nextScanChan); + + // schedule next scan event + if (scanInfo.scanWindow == scanInfo.scanInterval) // scanWindow == scanInterval, trigger immediately + LL_evt_schedule(); + else +// set_timer4((scanInfo.scanInterval - scanInfo.scanWindow) * 625); + ll_schedule_next_event((scanInfo.scanInterval - scanInfo.scanWindow) * 625); + + // reset scan total time + llScanTime = 0; + } + else + llSetupScan(scanInfo.nextScanChan); + + // post ISR process + if (!llWaitingIrq) // bug fixed 2018-05-04, only clear IRQ status when no config new one + ll_hw_clr_irq(); + + HAL_EXIT_CRITICAL_SECTION(); + return TRUE; +} + +uint8 ll_processBasicIRQ_secondaryAdvTRX0(uint32_t irq_status ) +{ + _HAL_CS_ALLOC_(); + HAL_ENTER_CRITICAL_SECTION(); + uint32_t T2, delay; +// secondary adv state, connectable adv or scannable adv + uint8_t packet_len, pdu_type, txAdd; + uint16_t pktLen; + uint32_t pktFoot0, pktFoot1; + int calibra_time; // this parameter will be provided by global_config + //int i; + // 2021-02-23 + // bugfix for multi-role secondary advertising + // bug-case : a device in advertising and receive another device's scan request + uint8 adv_sch_flag = TRUE; + // read packet + packet_len = ll_hw_read_rfifo((uint8_t*)(&(g_rx_adv_buf.rxheader)), + &pktLen, + &pktFoot0, + &pktFoot1); + + if(ll_hw_get_rfifo_depth() > 0) + { + g_pmCounters.ll_rfifo_read_err++; + packet_len=0; + pktLen=0; + } + + // check receive pdu type + pdu_type = g_rx_adv_buf.rxheader & PDU_TYPE_MASK; + txAdd = (g_rx_adv_buf.rxheader & TX_ADD_MASK) >> TX_ADD_SHIFT; // adv PDU header, bit 6: TxAdd, 0 - public, 1 - random + + if (packet_len > 0 // any better checking rule for rx anything? + && (irq_status & LIRQ_COK) + && pdu_type == ADV_SCAN_REQ) +// && (llState == LL_STATE_ADV_UNDIRECTED +// || llState == LL_STATE_ADV_SCAN)) + { + // 1. scan req + g_pmCounters.ll_recv_scan_req_cnt ++; + + // check AdvA + if (g_rx_adv_buf.data[6] != adv_param.ownAddr[0] + || g_rx_adv_buf.data[7] != adv_param.ownAddr[1] + || g_rx_adv_buf.data[8] != adv_param.ownAddr[2] + || g_rx_adv_buf.data[9] != adv_param.ownAddr[3] + || g_rx_adv_buf.data[10] != adv_param.ownAddr[4] + || g_rx_adv_buf.data[11] != adv_param.ownAddr[5]) + { + } + else + { +//=== + uint8_t rpaListIndex, bWlRlCheckOk; + uint8_t* peerAddr = &g_rx_adv_buf.data[0]; // ScanA + adv_sch_flag = FALSE; + + // === Resolving list checking + if (txAdd == LL_DEV_ADDR_TYPE_RANDOM + && (g_rx_adv_buf.data[5] & RANDOM_ADDR_HDR) == PRIVATE_RESOLVE_ADDR_HDR) + { + bWlRlCheckOk = TRUE; + + // if ScanA is resolvable private address + if (g_llRlEnable == TRUE) + { + bWlRlCheckOk = FALSE; + rpaListIndex = ll_getRPAListEntry(&g_rx_adv_buf.data[0]); + + if (rpaListIndex < LL_RESOLVINGLIST_ENTRY_NUM) + { + peerAddr = &g_llResolvinglist[rpaListIndex].peerAddr[0]; + bWlRlCheckOk = TRUE; + } + } + } + else // ScanA is device Identity, if the device ID in the RPA list, check whether RPA should be used + { + bWlRlCheckOk = TRUE; + + for (int i = 0; i < LL_RESOLVINGLIST_ENTRY_NUM; i++) + { + if (g_llResolvinglist[i].peerAddr[0] == g_rx_adv_buf.data[0] + && g_llResolvinglist[i].peerAddr[1] == g_rx_adv_buf.data[1] + && g_llResolvinglist[i].peerAddr[2] == g_rx_adv_buf.data[2] + && g_llResolvinglist[i].peerAddr[3] == g_rx_adv_buf.data[3] + && g_llResolvinglist[i].peerAddr[4] == g_rx_adv_buf.data[4] + && g_llResolvinglist[i].peerAddr[5] == g_rx_adv_buf.data[5] + && g_llResolvinglist[i].peerAddrType == txAdd) + { + if (g_llResolvinglist[i].privacyMode == NETWORK_PRIVACY_MODE && + !ll_isIrkAllZero(g_llResolvinglist[i].peerIrk)) + bWlRlCheckOk = FALSE; + + break; + } + } + } + + // === check white list + if ((pGlobal_config[LL_SWITCH] & LL_WHITELIST_ALLOW) + && (adv_param.wlPolicy == LL_ADV_WL_POLICY_WL_SCAN_REQ + || adv_param.wlPolicy == LL_ADV_WL_POLICY_WL_ALL_REQ) + && (bWlRlCheckOk == TRUE)) + { + // check white list + bWlRlCheckOk = ll_isAddrInWhiteList(txAdd, peerAddr); + } + + if (bWlRlCheckOk == FALSE) // if not in white list, do nothing + { + g_pmCounters.ll_filter_scan_req_cnt ++; + } + else + { + g_pmCounters.ll_rx_peer_cnt++; + uint8 retScanRspFilter=1; + + if(LL_PLUS_ScanRequestFilterCBack) + { + retScanRspFilter = LL_PLUS_ScanRequestFilterCBack(); + } + + if(retScanRspFilter) + { + // send scan rsp + ll_hw_set_stx(); // set LL HW as single Tx mode + g_same_rf_channel_flag = TRUE; + // calculate the delay + T2 = read_current_fine_time(); + delay = (T2 > ISR_entry_time) ? (T2 - ISR_entry_time) : (BASE_TIME_UNITS - ISR_entry_time + T2); + calibra_time = pGlobal_config[SCAN_RSP_DELAY]; // consider rx_done to ISR time, SW delay after read_current_fine_time(), func read_current_fine_time() delay ... + delay = 118 - delay - calibra_time; // IFS = 150us, Tx tail -> Rx done time: about 32us + ll_hw_set_trx_settle(delay, // set BB delay, about 80us in 16MHz HCLK + pGlobal_config[LL_HW_AFE_DELAY], + pGlobal_config[LL_HW_PLL_DELAY]); //RxAFE,PLL + ll_hw_go(); + llWaitingIrq = TRUE; + g_same_rf_channel_flag = FALSE; + // reset Rx/Tx FIFO + ll_hw_rst_rfifo(); + ll_hw_rst_tfifo(); + //write Tx FIFO + ll_hw_write_tfifo((uint8*)&(tx_scanRsp_desc.txheader), + ((tx_scanRsp_desc.txheader & 0xff00) >> 8) + 2); // payload length + header length(2) + ll_debug_output(DEBUG_LL_HW_SET_STX); + g_pmCounters.ll_send_scan_rsp_cnt ++; + } + } + } + } + else if (pdu_type == ADV_CONN_REQ + && (irq_status & LIRQ_COK) ) +// && (llState == LL_STATE_ADV_UNDIRECTED +// || llState == LL_STATE_ADV_DIRECTED)) + { + uint8_t* peerAddr; + uint8_t bWlRlCheckOk = TRUE; + // 2. connect req + g_pmCounters.ll_recv_conn_req_cnt ++; + + // check AdvA + if (g_rx_adv_buf.data[6] != adv_param.ownAddr[0] + || g_rx_adv_buf.data[7] != adv_param.ownAddr[1] + || g_rx_adv_buf.data[8] != adv_param.ownAddr[2] + || g_rx_adv_buf.data[9] != adv_param.ownAddr[3] + || g_rx_adv_buf.data[10] != adv_param.ownAddr[4] + || g_rx_adv_buf.data[11] != adv_param.ownAddr[5]) + { + // nothing to do + } + else + { + uint8_t rpaListIndex = LL_RESOLVINGLIST_ENTRY_NUM; + peerAddr = &g_rx_adv_buf.data[0]; // initA + adv_sch_flag = FALSE; + + // ====== check Resolving list + if (txAdd == LL_DEV_ADDR_TYPE_RANDOM && + (g_rx_adv_buf.data[5] & RANDOM_ADDR_HDR) == PRIVATE_RESOLVE_ADDR_HDR) + { + bWlRlCheckOk = TRUE; + + if (g_llRlEnable == TRUE) + { + bWlRlCheckOk = FALSE; + rpaListIndex = ll_getRPAListEntry(&g_rx_adv_buf.data[0]); + + if (rpaListIndex < LL_RESOLVINGLIST_ENTRY_NUM) + { + // save resolved peer address + peerAddr = &g_llResolvinglist[rpaListIndex].peerAddr[0]; + // if resolved address success, map the peer address type to 0x02 or 0x03 + g_currentPeerAddrType = g_llResolvinglist[rpaListIndex].peerAddrType + 2; + osal_memcpy( &g_currentPeerRpa[0], &g_rx_adv_buf.data[0], 6); // save latest peer RPA + bWlRlCheckOk = TRUE; + } + } + } + else // InitA is device Identity, check whether the device Addr in the RPA list, if it is + { + // in the RPA list and network privacy mode is selected and non all-0 IRK, check failed + bWlRlCheckOk = TRUE; + + for (int i = 0; i < LL_RESOLVINGLIST_ENTRY_NUM; i++) + { + if (g_llResolvinglist[i].peerAddr[0] == g_rx_adv_buf.data[0] + && g_llResolvinglist[i].peerAddr[1] == g_rx_adv_buf.data[1] + && g_llResolvinglist[i].peerAddr[2] == g_rx_adv_buf.data[2] + && g_llResolvinglist[i].peerAddr[3] == g_rx_adv_buf.data[3] + && g_llResolvinglist[i].peerAddr[4] == g_rx_adv_buf.data[4] + && g_llResolvinglist[i].peerAddr[5] == g_rx_adv_buf.data[5] + && g_llResolvinglist[i].peerAddrType == txAdd) + { + if (g_llResolvinglist[i].privacyMode == NETWORK_PRIVACY_MODE && + !ll_isIrkAllZero(g_llResolvinglist[i].peerIrk)) + bWlRlCheckOk = FALSE; + + break; + } + } + } + + // ====== check white list + if ((pGlobal_config[LL_SWITCH] & LL_WHITELIST_ALLOW) + && (llState == LL_STATE_ADV_UNDIRECTED) + && (adv_param.wlPolicy == LL_ADV_WL_POLICY_WL_CONNECT_REQ + || adv_param.wlPolicy == LL_ADV_WL_POLICY_WL_ALL_REQ) + && (bWlRlCheckOk == TRUE)) + { + // check white list + bWlRlCheckOk = ll_isAddrInWhiteList(txAdd, peerAddr); + } + + // fixed bug 2018-09-25, LL/CON/ADV/BV-04-C, for direct adv, initA should equal peer Addr + if (llState == LL_STATE_ADV_DIRECTED) + { + if (//txAdd != peerInfo.peerAddrType // for (extended) set adv param, peer addr type could only be 0x0 or 0x01 + peerAddr[0] != peerInfo.peerAddr[0] + || peerAddr[1] != peerInfo.peerAddr[1] + || peerAddr[2] != peerInfo.peerAddr[2] + || peerAddr[3] != peerInfo.peerAddr[3] + || peerAddr[4] != peerInfo.peerAddr[4] + || peerAddr[5] != peerInfo.peerAddr[5]) + { + bWlRlCheckOk = FALSE; + } + } + + if (bWlRlCheckOk == FALSE) // if not in white list, do nothing + { + g_pmCounters.ll_filter_conn_req_cnt ++; + } + else + { + // increment statistics counter + g_pmCounters.ll_rx_peer_cnt++; + // bug fixed 2018-01-23, peerAddrType should read TxAdd + peerInfo.peerAddrType = txAdd; // adv PDU header, bit 6: TxAdd, 0 - public, 1 - random + osal_memcpy(peerInfo.peerAddr, &peerAddr[0], 6); + move_to_slave_function(); // move to slave role for connection state + } + } + } + + //test for fast adv +// else //if(llState == LL_STATE_ADV_UNDIRECTED) + if( adv_sch_flag ) + { + // adv in next channel, or schedule next adv event + uint8 i = 0; + + while (!(adv_param.advChanMap & (1 << i))) i ++; // get the 1st adv channel + + // adv_param.advNextChan stores the next adv channel, when adv the last adv channel, advNextChan should equal 1st adv channel + if (adv_param.advNextChan != (LL_ADV_CHAN_FIRST + i)) // not finish adv the last channel, continue adv + { + llSetupSecAdvEvt(); + } + else + { + if (llSecondaryState == LL_SEC_STATE_IDLE_PENDING) // advertise last channel and transiting to IDLE + llSecondaryState = LL_SEC_STATE_IDLE; + else // otherwise, schedule next adv + osal_start_timerEx(LL_TaskID, LL_EVT_SECONDARY_ADV, (adv_param.advInterval * 5) >> 3); // * 625 / 1000 + } + } + + // post ISR process + if (!llWaitingIrq) // bug fixed 2018-05-04, only clear IRQ status when no config new one + ll_hw_clr_irq(); + + HAL_EXIT_CRITICAL_SECTION(); + return TRUE; +} + +void LL_IRQHandler1(void) +{ + uint32 irq_status; + int8 ret; + ISR_entry_time = read_current_fine_time(); + //*(volatile uint32_t *)0x4000f0b8 = 1; // pclk_clk_gate_en + ll_debug_output(DEBUG_ISR_ENTRY); + DBG_GPIO_WRITE(DBGIO_LL_IRQ,1); + irq_status = ll_hw_get_irq_status(); + + + if (!(irq_status & LIRQ_MD)) // only process IRQ of MODE DONE + { + ll_hw_clr_irq(); // clear irq status + return; + } + + llWaitingIrq = FALSE; + + if (llTaskState == LL_TASK_EXTENDED_ADV) + { + ret = ll_processExtAdvIRQ(irq_status); + + // TODO: consider whether need process secondary adv/scan here + if (ret == TRUE) + return; + } + else if (llTaskState == LL_TASK_EXTENDED_SCAN) + { + ret = ll_processExtScanIRQ(irq_status); + + // TODO: consider whether need process secondary adv/scan here + if (ret == TRUE) + return; + } + else if (llTaskState == LL_TASK_EXTENDED_INIT) + { + ret = ll_processExtInitIRQ(irq_status); + + // TODO: consider whether need process secondary adv/scan here + if (ret == TRUE) + return; + } + else if (llTaskState == LL_TASK_PERIODIC_ADV) + { + ret = ll_processPrdAdvIRQ(irq_status); + + // TODO: consider whether need process secondary adv/scan here + if (ret == TRUE) + return; + } + else if (llTaskState == LL_TASK_PERIODIC_SCAN) + { + ret = ll_processPrdScanIRQ(irq_status); + + // TODO: consider whether need process secondary adv/scan here + if (ret == TRUE) + return; + } + else + { + uint8 mode; + mode = ll_hw_get_tr_mode(); + + if(mode == LL_HW_MODE_SRX && (llState == LL_STATE_SCAN || llState == LL_STATE_INIT)) + { + ret = ll_processBasicIRQ_SRX(irq_status); + } + else if((llSecondaryState == LL_SEC_STATE_ADV || llSecondaryState == LL_SEC_STATE_IDLE_PENDING) + && (mode == LL_HW_MODE_TRX ) + && (adv_param.advEvtType == LL_ADV_CONNECTABLE_UNDIRECTED_EVT || adv_param.advEvtType == LL_ADV_SCANNABLE_UNDIRECTED_EVT)) + { + // JIRA bugfix : BBBSDKREL-294 + ret = ll_processBasicIRQ_secondaryAdvTRX(irq_status); + } + else if (mode == LL_HW_MODE_TRX && + (llState == LL_STATE_SCAN)) + { + ret = ll_processBasicIRQ_ScanTRX(irq_status); + } + else + { + ret = ll_processBasicIRQ(irq_status); + } + + //test for fast adv + if( mode == LL_HW_MODE_TRX + && llState == LL_STATE_ADV_UNDIRECTED + && 0==(irq_status&LIRQ_COK) ) + { + uint8_t firstAdvChan = (adv_param.advChanMap&LL_ADV_CHAN_37) !=0 ? 37 : + (adv_param.advChanMap&LL_ADV_CHAN_38) !=0 ? 38 : 39; + + if(adv_param.advNextChan>firstAdvChan) + { + ll_schedule_next_event(50); //20180623 modified by ZQ + } + } + } + + // ================ Post ISR process: secondary pending state process + // conn-adv case 2: other ISR, there is pending secondary advertise event, make it happen + if (llSecondaryState == LL_SEC_STATE_ADV_PENDING) + { + if (llSecAdvAllow()) // for multi-connection case, it is possible still no enough time for adv + { + llSetupSecAdvEvt(); + ll_hw_set_rx_timeout(88); + llSecondaryState = LL_SEC_STATE_ADV; + } + } + // there is pending scan event, make it happen, note that it may stay pending if there is no enough idle time + else if (llSecondaryState == LL_SEC_STATE_SCAN_PENDING) + { + // trigger scan + llSetupSecScan(scanInfo.nextScanChan); + } + // there is pending init event, make it happen, note that it may stay pending if there is no enough idle time + else if (llSecondaryState == LL_SEC_STATE_INIT_PENDING) + { + // trigger scan + llSetupSecInit(initInfo.nextScanChan); + } + + DBG_GPIO_WRITE(DBGIO_LL_IRQ,0); + ll_debug_output(DEBUG_ISR_EXIT); +} + +//-------------------------------------- +extern uint32 llWaitingIrq; +extern uint32_t g_wakeup_rtc_tick; + +extern uint32 counter_tracking; +extern uint32_t g_counter_traking_avg; +extern uint32_t g_counter_traking_cnt; +extern uint32_t g_TIM2_IRQ_TIM3_CurrCount; +extern uint32_t g_TIM2_IRQ_to_Sleep_DeltTick; +extern uint32 read_ll_adv_remainder_time(void); +#define ROM_SLEEP_TICK *(volatile uint32_t *)(0x1fff0a14) + +__attribute__((weak)) void l2capPocessFragmentTxData(uint16 connHandle) +{ + //do nothing +} + +#if 0 +extern int m_in_critical_region; +int drv_disable_irq1(void) +{ + __disable_irq(); + DBG_GPIO_WRITE(DBGIO_DIS_IRQ,1); + DBG_GPIO_WRITE(DBGIO_DIS_IRQ,0); + m_in_critical_region++; + return m_in_critical_region; +} + +int drv_enable_irq1(void) +{ + m_in_critical_region--; + + if (m_in_critical_region == 0) + { + __enable_irq(); + DBG_GPIO_WRITE(DBGIO_EN_IRQ,1); + DBG_GPIO_WRITE(DBGIO_EN_IRQ,0); + } + + return m_in_critical_region; +} +extern void TIM1_IRQHandler(void); +void TIM1_IRQHandler1(void) +{ + gpio_write(P20,1); + TIM1_IRQHandler(); + gpio_write(P20,0); +} +#endif + +/******************************************************************************* + @fn ll_scheduler + + @brief schedule next task, if current connection will be free, input + parameter should be LL_INVALID_TIME. The function is invoked + after old connection task end, it will not add new task but may + delete exist task + + input parameters + + @param time - schedule time for current connection + + output parameters + + @param None. + + @return None. +*/ + + +void ll_scheduler1(uint32 time) +{ + uint32 T1, T2, delta, min, prio_adj; + uint8 i, next, temp,conn_temp; + T1 = read_current_fine_time(); + + // timer1 is running, normally it should not occur + if (isTimer1Running()) + { + LOG("=== ASSERT FAIL, timer1 running when invoke ll_scheduler ===\n"); + g_pmCounters.ll_evt_shc_err++; + return; + } + + // if timer1 is not running, calculate the time elapse since last timer expiry + delta = g_ll_conn_ctx.current_timer + LL_TIME_DELTA(g_ll_conn_ctx.timerExpiryTick, T1) + pGlobal_config[TIMER_ISR_ENTRY_TIME]; + // update current context + g_ll_conn_ctx.scheduleInfo[g_ll_conn_ctx.currentConn].remainder = time; // if current conn terminal, the parameter "time" shall be LL_INVALID_TIME + min = time; + + if (time == LL_INVALID_TIME) + { + ll_deleteTask(g_ll_conn_ctx.currentConn); + g_ll_conn_ctx.currentConn = LL_INVALID_CONNECTION_ID; + } + + conn_temp = next = g_ll_conn_ctx.currentConn; + + if (next != LL_INVALID_CONNECTION_ID) + { + // if we want master or slave connection has higher schedule priority, set LL_MASTER_PREEMPHASIS/LL_SLAVE_PREEMPHASIS + if (g_ll_conn_ctx.scheduleInfo[next].linkRole == LL_ROLE_MASTER) + min = (time > pGlobal_config[LL_MULTICONN_MASTER_PREEMP]) ? (time - pGlobal_config[LL_MULTICONN_MASTER_PREEMP]) : 0; + + if (g_ll_conn_ctx.scheduleInfo[next].linkRole == LL_ROLE_SLAVE) + min = (time > pGlobal_config[LL_MULTICONN_SLAVE_PREEMP]) ? (time - pGlobal_config[LL_MULTICONN_SLAVE_PREEMP]) : 0; + } + + // update schedule task list and get the earliest task + for (i = 0; i < g_maxConnNum; i++) + { + if ((i != g_ll_conn_ctx.currentConn) && conn_param[i].active) + { + // task conflict process + // if there is no enough time for new task, invoke relate slave/master conn event process function +// if (g_ll_conn_ctx.scheduleInfo[i].remainder < delta + g_ll_conn_ctx.scheduleInfo[i].task_duration) + if (g_ll_conn_ctx.scheduleInfo[i].remainder < delta + 40) // 40 : margin for process delay, unit: us + { + // no enough time to process the event, regard the event as missed and update the conn context and timer + uint8 ret = LL_PROC_LINK_KEEP; + + if (g_ll_conn_ctx.scheduleInfo[i].linkRole == LL_ROLE_MASTER) + { + // temporary update g_ll_conn_ctx.currentConn to current connection ID because + // ll_processMissMasterEvt will invoke function using global variable g_ll_conn_ctx.currentConn + temp = g_ll_conn_ctx.currentConn; + g_ll_conn_ctx.currentConn = i; + ret = ll_processMissMasterEvt(i); +// if( delta > g_ll_conn_ctx.scheduleInfo[i].remainder) +// { +// llConnState_t *connPtr = &conn_param[i]; +// uint8 missCE = (( delta - g_ll_conn_ctx.scheduleInfo[i].remainder) / ( connPtr->curParam.connInterval*625 )) + 1; +// for(uint8 misI = 0;misI g_ll_conn_ctx.scheduleInfo[i].remainder) + { + llConnState_t* connPtr = &conn_param[i]; + uint8 missCE = (( delta - g_ll_conn_ctx.scheduleInfo[i].remainder) / ( connPtr->curParam.connInterval*625 )) + 1; + + for(uint8 misI = 0; misI prio_adj) ? (g_ll_conn_ctx.scheduleInfo[i].remainder - prio_adj) : 0; + } + } + } + + if (min == LL_INVALID_TIME) // all task may be delete, not start timer + { + return; + } + + T2 = read_current_fine_time(); + // calculate the time elapse since enter this function. + delta = LL_TIME_DELTA(T1, T2); + _HAL_CS_ALLOC_(); + HAL_ENTER_CRITICAL_SECTION(); + uint8 rem_l_delta_flag = FALSE; + uint8 rem_l_delta_value = 0; + + if (g_ll_conn_ctx.scheduleInfo[next].remainder <= delta) // TODO: should not go here, if this issue detected, root cause should be invest + { +// set_timer1(20); + set_timer(AP_TIM1,20); + g_ll_conn_ctx.current_timer = 20; + rem_l_delta_flag = TRUE; + rem_l_delta_value = next; +// LOG("-T %d:20,",next); + } + else + { +// set_timer1(g_ll_conn_ctx.scheduleInfo[next].remainder - delta); + set_timer(AP_TIM1,g_ll_conn_ctx.scheduleInfo[next].remainder - delta); + //logx("-S%d,%d\n",next,g_ll_conn_ctx.scheduleInfo[next].remainder - delta); + + // update connection context & schedule info + g_ll_conn_ctx.current_timer = g_ll_conn_ctx.scheduleInfo[next].remainder - delta; + } + + g_ll_conn_ctx.currentConn = next; + + // set ll state according to current connection LL state + if (g_ll_conn_ctx.scheduleInfo[g_ll_conn_ctx.currentConn].linkRole == LL_ROLE_SLAVE) + llState = LL_STATE_CONN_SLAVE; + else if (g_ll_conn_ctx.scheduleInfo[g_ll_conn_ctx.currentConn].linkRole == LL_ROLE_MASTER) + llState = LL_STATE_CONN_MASTER; + + // the task is scheduled, set the priority as low + g_ll_conn_ctx.scheduleInfo[g_ll_conn_ctx.currentConn].priority = LL_SCH_PRIO_LOW; + + // take into account the time between start timer1 and T1 + for (i = 0; i < g_maxConnNum; i++) + { + if (conn_param[i].active) + { +// if( g_ll_conn_ctx.scheduleInfo[i].remainder >= delta ) +// g_ll_conn_ctx.scheduleInfo[i].remainder -= delta; + if( ( g_ll_conn_ctx.scheduleInfo[i].remainder < delta ) && ( rem_l_delta_flag == FALSE)) + { + if (g_ll_conn_ctx.scheduleInfo[i].linkRole == LL_ROLE_MASTER) + ll_processMissMasterEvt(i); + else + ll_processMissSlaveEvt(i); + } + + if( ( rem_l_delta_value == i ) && ( rem_l_delta_flag == TRUE) ) + g_ll_conn_ctx.scheduleInfo[i].remainder = 0; + else + g_ll_conn_ctx.scheduleInfo[i].remainder -= delta; + + conn_param[i].llTbd2 = g_ll_conn_ctx.scheduleInfo[i].remainder; + /*record if error scheduler time*/ + // if( g_ll_conn_ctx.scheduleInfo[i].remainder > 500000) + // llConnTerminate(&conn_param[i],LL_SUPERVISION_TIMEOUT_TERM); + } + } + + // add for co-master intv bug fix + if( g_ll_conn_ctx.scheduleInfo[conn_temp].linkRole != LL_ROLE_MASTER ) + { + HAL_EXIT_CRITICAL_SECTION(); + return; + } + + int8 k=0; + + for (k = g_maxConnNum-1; k >= 0; k--) + { + if ((conn_param[k].active) && (g_ll_conn_ctx.scheduleInfo[k].linkRole == LL_ROLE_MASTER )) + { + break; + } + } + + i=k; + + if( conn_temp == i ) + { + uint8 jm=i; + uint8 fist_m=0; + // current master --> first master true value + uint32 tv_Masters = 0,tv_diff = 0,first_reminder = 0; + + for (i = 0; i < g_maxConnNum; i++) + { + if ((conn_param[i].active) && (g_ll_conn_ctx.scheduleInfo[i].linkRole == LL_ROLE_MASTER )) + break; + } + + first_reminder = g_ll_conn_ctx.scheduleInfo[i].remainder; + fist_m = i; + + for (i=fist_m+1; i < jm+1 ; i++) + { + if ((conn_param[i].active) && (g_ll_conn_ctx.scheduleInfo[i].linkRole == LL_ROLE_MASTER )) + { + tv_Masters = first_reminder + g_ll_conn_ctx.per_slot_time * 625 * (i - fist_m); + + if( tv_Masters > g_ll_conn_ctx.scheduleInfo[i].remainder) + tv_diff = tv_Masters - g_ll_conn_ctx.scheduleInfo[i].remainder; + else + tv_diff = g_ll_conn_ctx.scheduleInfo[i].remainder - tv_Masters; + + // < 1000 : filter scecondary first create master connection & miss process master event + if(tv_diff < 1000) + { + if( g_ll_conn_ctx.scheduleInfo[i].remainder > tv_Masters ) + { + g_ll_conn_ctx.scheduleInfo[i].remainder -= tv_diff; + } + else if( g_ll_conn_ctx.scheduleInfo[i].remainder < tv_Masters ) + { + g_ll_conn_ctx.scheduleInfo[i].remainder += tv_diff; + } + } + } + } + } + + HAL_EXIT_CRITICAL_SECTION(); +} + +#define CRY32_2_CYCLE_16MHZ_CYCLE_MAX (976 + 98) // tracking value range std +/- 20% +#define CRY32_2_CYCLE_16MHZ_CYCLE_MIN (976 - 98) +#define CRY32_2_CYCLE_DELTA_LMT (19) + +uint32_t g_xtal16M_tmp=0; +static void check_16MXtal_by_rcTracking(void) +{ + /* + for fiset wakeupini, not do rcCal, just skip the rcTacking + + */ + if(g_rc32kCalRes==0xFF) + { + WaitRTCCount(60); + return; + } + + uint32_t temp,temp1; + uint32_t temp31,temp32,temp33; + uint32_t temp_min,temp_max; + // ======== enable tracking 32KHz RC timer with 16MHz crystal clock + temp = *(volatile uint32_t*)0x4000f040; + *(volatile uint32_t*)0x4000f040 = temp | BIT(18); + temp = *(volatile uint32_t*)0x4000f05C; + *(volatile uint32_t*)0x4000f05C = (temp & 0xfffefe00) | 0x0028; + WaitRTCCount(3); + temp31 = (*(volatile uint32_t*)0x4000f064 & 0x1ffff); + WaitRTCCount(3); + temp32 = (*(volatile uint32_t*)0x4000f064 & 0x1ffff); + WaitRTCCount(3); + temp33 = (*(volatile uint32_t*)0x4000f064 & 0x1ffff); + + while(1) + { + temp_min = (temp31 >=temp32) ? (temp32):(temp31); + temp_min = (temp_min >=temp33) ? (temp33):(temp_min); + temp_max = (temp31 >=temp32) ? (temp31):(temp32); + temp_max = (temp_max >=temp33) ? (temp_max):(temp33); + + if( temp31>CRY32_2_CYCLE_16MHZ_CYCLE_MIN && + temp31CRY32_2_CYCLE_16MHZ_CYCLE_MIN && + temp32 CRY32_2_CYCLE_16MHZ_CYCLE_MIN && + temp33 =temp1 ? (g_xtal16M_tmp*6 -temp1):(temp1-g_xtal16M_tmp*6))= DLL_ENABLE_MAX) + { + while(1); + //NVIC_SystemReset(); + } + + //disable DLL + subWriteReg(0x4000f044,7,7,0); + WaitRTCCount(3); + //update g_xtal16M_tmp + temp = *(volatile uint32_t*)0x4000f05C; + *(volatile uint32_t*)0x4000f05C = (temp & 0xfffefe00) | 0x0028 ; + WaitRTCCount(3); + g_xtal16M_tmp = (*(volatile uint32_t*)0x4000f064 & 0x1ffff); + subWriteReg(0x4000f05C,3,3,0); + } +} + +#if 0 + uint32_t rtcCntTemp[10]; +#endif +// now we split the initial fucntion to 3 kinds: +// 1. boot init function: which should be init when system boot. note: not include wakeup init function +// 2. wakeup init function: which should be init when wakeup from system sleep +// 3. parameter which should be init in APP, include: RF, board, ... +// summary: +// - normal boot, need: 1 + 2 + 3 +// - wakeup, need: 2 + 3 + +// init paramaters every time wakeup + +uint32_t tracking_cnt=0; +void wakeup_init1() +{ + uint8_t pktFmt = 1; // packet format 1: BLE 1M + uint32 temp; + //int int_state; + // =========== clk gate for low power + //*(volatile uint32_t *) 0x40000008 = 0x01e92190; + // enable rng analog block. RNG analog need > 200us before stable, and it consume few current, so open it at wakeup + //*(volatile uint32_t *) 0x4000f048 |= 1 << 23; + // =========== config PCRM +// *(volatile uint32_t *) 0x4000f040 = 0x501fb000; //enable xtal out +// *(volatile uint32_t *) 0x4000f044 = 0x01ade8b0; //switch rf,adc to doubler,32M +//---by ZQ 2017-10-17 + //*(volatile uint32_t *) 0x4000f040 = 0x501fb820; // enable xtal out + // set the xtal cap to zero for faster settle + // set [16] manually enable ac strigger f 20180613 by ZQ + //*(volatile uint32_t *) 0x4000f044 = 0x01bdf8b0;//0x01bef830; // switch rf,adc to doubler, dll_off, dll_ldo on + // dll will be turn on in rf_ini after xtal settle + //*(volatile uint32_t *) 0x4000f044 = 0x00be0830; //[26:22] 0x02,[21:18]0x0f,[16:12]0x00,[7:4]0x03 + //< 22>:sel_rf_clk_16M; + //< 23>:sel_rf_dbl_clk_32M; + //< 24>:sel_rxadc_dbl_clk_32M; + //< 25>:sel_rxadc_dbl_clk_32M_polarity; + //< 26>:sel_rf_dbl_clk_32M_polarity + // < 18>:en_rf_clk; + // < 19>:en_rxadc_clk_32M; + // < 20>:sel_cp_clk_32M; + // < 21>:sel_dig_dble_clk_32M; + // < 12>:en_cp_dll_clk; + // < 13>:en_dig_clk_32M; + // < 14>:en_dig_clk_48M; + // < 15>:en_dig_clk_64M; + // < 16>:en_dig_clk_96M; + #if (DBG_BUILD_LL_TIMING) + //====== for timing debug============ + gpio_write(DBG_PIN_SYS_CLK_SWITCH, 1); + gpio_write(DBG_PIN_SYS_CLK_SWITCH, 0); + //PHY_REG_WT(AP_IOMUX_BASE+8,1);//en debugMux[0] + #endif + //each rtc count is about 30.5us + //after 15count , xtal will be feedout to dll and doubler + //WaitRTCCount(pGlobal_config[WAKEUP_DELAY]); + #if 0 + volatile uint32_t delay=0; + + for(uint8_t i=0; i<10; i++) + { + delay=500; + rtcCntTemp[i]=rtc_get_counter(); + + while(delay -- > 0) {}; + } + + #endif + + if(g_system_clk == SYS_CLK_XTAL_16M) + { + WaitRTCCount(pGlobal_config[WAKEUP_DELAY]); + } + else + { + uint32_t tracking_c1,tracking_c2; + tracking_c1 = rtc_get_counter(); + check_16MXtal_by_rcTracking(); + check_96MXtal_by_rcTracking(); + tracking_c2 = rtc_get_counter(); + tracking_cnt = (tracking_c2>=tracking_c1) ? (tracking_c2-tracking_c1) : (0xffffffff-tracking_c1+tracking_c2); + pGlobal_config[WAKEUP_ADVANCE] =1650+30*tracking_cnt; + } + + // ============ config BB Top + *(volatile uint32_t*) 0x40030000 = 0x3d068001; // set tx pkt =2 + *(volatile uint32_t*) 0x400300bc = 0x834; //[7:0] pll_tm [11:8] rxafe settle + *(volatile uint32_t*) 0x400300a4 = 0x140; //[6] for tpm_en + clk_init(g_system_clk); + // ================= clock selection + // hclk_sel select hclk source. 0---rc 32m 1----dll 32m 2---xtal 16m 3---dll 48m 4----dll 64m 5----dll 96m +// switch (pGlobal_config[CLOCK_SETTING]) +// { +// case SYS_CLK_XTAL_16M: +//// *(int *) 0x4000f03C = 0x18001; // clock selection +// *(int *) 0x4000f03C = 0x10002; // clock selection +// break; +// case SYS_CLK_DBL_32M: +// case SYS_CLK_DLL_32M: +// *(int *) 0x4000f03C = 0x10001; // clock selection +// break; +// case SYS_CLK_DLL_48M: +// *(int *) 0x4000f03C = 0x10003; // clock selection +// break; +// case SYS_CLK_DLL_64M: +// *(int *) 0x4000f03C = 0x10004; // clock selection +// break; +// case SYS_CLK_DLL_96M: +// *(int *) 0x4000f03C = 0x10005; // clock selection +// break; +// default: +// *(int *) 0x4000f03C = 0x10002; // clock selection +// break; +// } + // ========== init timers + set_timer(AP_TIM2, 625); // OSAL 625us tick + set_timer(AP_TIM3, BASE_TIME_UNITS); // 1s timer + // =========== open interrupt mask + //int_state = 0x14; + //set_int(int_state); + //should use NVIC_EnableIRQn() + NVIC_EnableIRQ(BB_IRQn); + NVIC_EnableIRQ(TIM1_IRQn); + NVIC_EnableIRQ(TIM2_IRQn); + NVIC_EnableIRQ(TIM4_IRQn); + // =========== ll HW setting + set_max_length(0xff); + ll_hw_set_empty_head(0x0001); + //time related setting + ll_hw_set_rx_timeout_1st( 500); + ll_hw_set_rx_timeout( 88); //ZQ 20180606, reduce rx timeout for power saving + //preamble + syncword=40us, sync process = 8us + //timeout should be larger then 48us, + //ll_hw_set_rx_timeout( 268); //for ble shoulde be larger than 80+128. if sync, the timeout timer stop. + // (80 + 128) - BLE 5.0 preamble + access time, 60 for HW process delay + // this time doesn't consider HW startup time, it is set in other regs + ll_hw_set_loop_timeout( 30000); +// ll_hw_set_tx_rx_release (10, 1); +// ll_hw_set_rx_tx_interval( 57); //T_IFS=150us for BLE 1M +// ll_hw_set_tx_rx_interval( 65); //T_IFS=150us for BLE 1M +// ll_hw_set_trx_settle (57, 8, 52); //TxBB,RxAFE,PLL + ll_hw_set_timing(pktFmt); + ll_hw_ign_rfifo(LL_HW_IGN_SSN | LL_HW_IGN_CRC | LL_HW_IGN_EMP); + // ======== enable tracking 32KHz RC timer with 16MHz crystal clock + temp = *(volatile uint32_t*)0x4000f05C; + *(volatile uint32_t*)0x4000f05C = (temp & 0xfffefe00) | 0x0108; //[16] 16M [8:4] cnt [3] track_en_rc32k + //get wakeup tracking counter + // if (pGlobal_config[LL_SWITCH] & RC32_TRACKINK_ALLOW) + // { + // WaitRTCCount(17); + // uint32_t counter_tracking_wakeup = *(volatile uint32_t *)0x4000f064 & 0x1ffff; + // counter_tracking = (counter_tracking_wakeup + counter_tracking)>>1; + // } +} + +void config_RTC1(uint32 time) +{ +// *((volatile uint32_t *)(0xe000e100)) |= INT_BIT_RTC; // remove, we don't use RTC interrupt + //align to rtc clock edge + WaitRTCCount(1); + + //update for cal ll next time after wakeup + ll_remain_time = read_LL_remainder_time(); + + // comparator configuration + sleep_tick = *(volatile uint32_t *) 0x4000f028; // read current RTC counter + g_TIM2_IRQ_to_Sleep_DeltTick = (g_TIM2_IRQ_TIM3_CurrCount>(AP_TIM3->CurrentCount)) + ? (g_TIM2_IRQ_TIM3_CurrCount-(AP_TIM3->CurrentCount)): 0; + + AP_AON->RTCCC0 = sleep_tick + time; //set RTC comparatr0 value + +// *(volatile uint32_t *) 0x4000f024 |= 1 << 20; //enable comparator0 envent +// *(volatile uint32_t *) 0x4000f024 |= 1 << 18; //counter overflow interrupt +// *(volatile uint32_t *) 0x4000f024 |= 1 << 15; //enable comparator0 inerrupt + + //*(volatile uint32_t *) 0x4000f024 |= 0x148000; // combine above 3 statement to save MCU time + AP_AON->RTCCTL |= BIT(15)|BIT(18)|BIT(20); + + //compensate for cal wakeup next_time + if (llState != LL_STATE_IDLE) + { + if(g_system_clk == SYS_CLK_XTAL_16M) + { + ll_remain_time -= 15; + } + else if(g_system_clk == SYS_CLK_DLL_48M) + { + ll_remain_time -= 5; + } + else + { + ll_remain_time -= 3; + } + } +} + +#if 0 +/******************************************************************************* + @fn wakeupProcess1 + + @brief wakeup from system sleep process function. + + + input parameters + + @param None + + output parameters + + @param None. + + @return None. +*/ +void wakeupProcess1(void) +{ + uint32 current_RTC_tick; + uint32 wakeup_time, wakeup_time0, next_time; + uint32 sleep_total; + uint32 dlt_tick; + //restore initial_sp according to the app_initial_sp : 20180706 ZQ + __set_MSP(pGlobal_config[INITIAL_STACK_PTR]); + HAL_CRITICAL_SECTION_INIT(); + + //==== 20180416 commented by ZQ + // to enable flash access after wakeup + // current consumption has been checked. No big different + //rom_set_flash_deep_sleep(); + + //=======fix sram_rent issue 20180323 + //hal_pwrmgr_RAM_retention_clr(); + //subWriteReg(0x4000f01c,21,17,0); + + if (sleep_flag != SLEEP_MAGIC) + { + // enter this branch not in sleep/wakeup scenario + set_sleep_flag(0); + // software reset + *(volatile uint32*)0x40000010 &= ~0x2; // bit 1: M0 cpu reset pulse, bit 0: M0 system reset pulse. + } + + // restore HW registers + wakeup_init0(); + //TODO:Move to wakeup_init0 + NVIC_SetPriority((IRQn_Type)BB_IRQn, IRQ_PRIO_REALTIME); + NVIC_SetPriority((IRQn_Type)TIM1_IRQn, IRQ_PRIO_HIGH); //ll_EVT + NVIC_SetPriority((IRQn_Type)TIM2_IRQn, IRQ_PRIO_HIGH); //OSAL_TICK + NVIC_SetPriority((IRQn_Type)TIM4_IRQn, IRQ_PRIO_HIGH); //LL_EXA_ADV + //wakeup flash + spif_release_deep_sleep(); + //===20180417 added by ZQ + // could be move into wakeup_init + // add the patch entry for tx2rx/rx2tx interval config + //2018-11-10 by ZQ + //config the tx2rx timing according to the g_rfPhyPktFmt + ll_hw_tx2rx_timing_config(g_rfPhyPktFmt); + // 20200812 ZQ + // DO NOT Turn OFF 32K Xtal + // if (pGlobal_config[LL_SWITCH] & LL_RC32K_SEL) + // { + // subWriteReg(0x4000f01c,16,7,0x3fb); //software control 32k_clk + // subWriteReg(0x4000f01c,6,6 ,0x01); //enable software control + // } + // else + // { + // subWriteReg(0x4000f01c,9,8,0x03); //software control 32k_clk + // subWriteReg(0x4000f01c,6,6,0x00); //disable software control + // } + //20181201 by ZQ + //restart the TIM2 to align the RTC + //---------------------------------------------------------- + //stop the 625 timer + AP_TIM2->ControlReg=0x0; + AP_TIM2->ControlReg=0x2; + AP_TIM2->LoadCount = 2500; + //---------------------------------------------------------- + //wait rtc cnt change + WaitRTCCount(1); + //---------------------------------------------------------- + //restart the 625 timer + AP_TIM2->ControlReg=0x3; + current_RTC_tick = rtc_get_counter(); + //g_TIM2_wakeup_delay= (AP_TIM2->CurrentCount)+12; //12 is used to align the rtc_tick + wakeup_time0 = read_current_fine_time(); + g_wakeup_rtc_tick = rtc_get_counter(); + // rf initial entry, will be set in app + rf_phy_ini(); + + if(current_RTC_tick>sleep_tick) + { + dlt_tick = current_RTC_tick - sleep_tick; + } + else + { + //dlt_tick = current_RTC_tick+0x00ffffff - sleep_tick; + dlt_tick = (0xffffffff - sleep_tick)+current_RTC_tick; + } + + //dlt_tick should not over 24bit + //otherwise, sleep_total will overflow !!! + if(dlt_tick>0x3fffff) + dlt_tick &=0x3fffff; + + if (pGlobal_config[LL_SWITCH] & RC32_TRACKINK_ALLOW) + { + //sleep_total = ((current_RTC_tick - sleep_tick) * counter_tracking) >> 7; // shift 4 for 16MHz -> 1MHz, shift 3 for we count 8 RTC tick + // sleep_total = ((((dlt_tick &0xffff0000)>>16)*counter_tracking)<<9) + // + (((dlt_tick &0xffff)*counter_tracking)>>7); + //counter_tracking default 16 cycle + sleep_total = ((((dlt_tick &0xffff0000)>>16)*counter_tracking)<<8) + + (((dlt_tick &0xffff)*counter_tracking)>>8); + } + else + { + // time = tick * 1000 0000 / f (us). f = 32000Hz for RC, f = 32768Hz for crystal. We also calibrate 32KHz RC to 32768Hz + //sleep_total = ((current_RTC_tick - sleep_tick) * TIMER_TO_32K_CRYSTAL) >> 2; + //fix sleep timing error + sleep_total = ( ( (dlt_tick<<7)-(dlt_tick<<2)-(dlt_tick<<1) +2) >>2 ) /* dlt_tick * (128-4-2)/4 */ + +( ( (dlt_tick<<3)+ dlt_tick +128) >>9 ) ; /* dlt_tick *9/512 */ + //+2,+128 for zero-mean quanization noise + } + + // restore systick + g_osal_tick_trim = (pGlobal_config[OSAL_SYS_TICK_WAKEUP_TRIM]+g_TIM2_IRQ_to_Sleep_DeltTick+2500-g_TIM2_IRQ_PendingTick)>>2; //16 is used to compensate the cal delay + g_osalTickTrim_mod+=(pGlobal_config[OSAL_SYS_TICK_WAKEUP_TRIM]+g_TIM2_IRQ_to_Sleep_DeltTick+2500-g_TIM2_IRQ_PendingTick)&0x03; //16 is used to compensate the cal delay + + if(g_osalTickTrim_mod>4) + { + g_osal_tick_trim+=1; + g_osalTickTrim_mod = g_osalTickTrim_mod%4; + } + + // restore systick + osal_sys_tick += (sleep_total+g_osal_tick_trim) / 625; // convert to 625us systick + rtc_mod_value += ((sleep_total+g_osal_tick_trim)%625); + + if(rtc_mod_value > 625) + { + osal_sys_tick += 1; + rtc_mod_value = rtc_mod_value%625; + } + + osalTimeUpdate(); + + // osal time update, not required. It will be updated when osal_run_system() is called after wakeup + + // TODO: should we consider widen the time drift window ???? + + //20190117 ZQ + if(llState != LL_STATE_IDLE) + { + // SW delay + wakeup_time = read_current_fine_time() - wakeup_time0; + next_time = 0; + + if (ll_remain_time > sleep_total + wakeup_time) + { + next_time = ll_remain_time - sleep_total - wakeup_time; + // restore LL timer + set_timer(AP_TIM1, next_time); + } + else + { + // should not be here + set_timer(AP_TIM1, 1000); + } + } + + if (g_llSleepContext.isTimer4RecoverRequired) + { + // SW delay + wakeup_time = read_current_fine_time() - wakeup_time0; + next_time = 0; + + if (g_llSleepContext.timer4Remainder > sleep_total + wakeup_time) + { + next_time = g_llSleepContext.timer4Remainder - sleep_total - wakeup_time; + // restore LL timer + set_timer(AP_TIM4, next_time); + } + else + { + // should not be here + set_timer(AP_TIM4, 1500); + // next_time = 0xffff; + } + + g_llSleepContext.isTimer4RecoverRequired = FALSE; + } + + // app could add operation after wakeup + app_wakeup_process(); +// uart_tx0(" 111 "); + ll_debug_output(DEBUG_WAKEUP); + set_sleep_flag(0); + // ==== measure value, from RTC counter meet comparator 0 -> here : 260us ~ 270us + // start task loop + osal_start_system(); +} +void enter_sleep_off_mode1(Sleep_Mode mode) +{ + if(mode==SYSTEM_SLEEP_MODE) + spif_set_deep_sleep(); + + enter_sleep_off_mode0(mode); +} +#endif +void LL_ENC_AES128_Encrypt1( uint8* key, + uint8* plaintext, + uint8* ciphertext ) +{ + //only turn on while working + AP_PCR->SW_CLK |= BIT(MOD_AES); + LL_ENC_AES128_Encrypt0(key,plaintext,ciphertext); + AP_PCR->SW_CLK &= ~BIT(MOD_AES); +} + +#define LL_ENC_BASE 0x40040000 // LL HW AES engine Base address + +#define LL_ENC_ENCRYPT_DONE_MASK 0x0001 +#define LL_ENC_DECRYPT_FAIL_MASK 0x0002 +#define LL_ENC_DECRYPT_SUCC_MASK 0x0004 +#define LL_ENC_SINGLE_MODE_DONE_MASK 0x0008 + +extern void LL_ENC_LoadKey( uint8* key ); +void LL_ENC_Encrypt1( llConnState_t* connPtr, uint8 pktHdr, uint8 pktLen, uint8* pBuf ) +{ + AP_PCR->SW_CLK |= BIT(MOD_AES); +// LL_ENC_Encrypt0(connPtr, pktHdr, pktLen, pBuf ); + { + uint8* pByte = NULL; + uint16 index; + int i, len; + uint32_t temp; + // disable AES + *(int*) 0x40040000 = 0x0; + // Load Key + // Note: Normally this would only need to be done once when the SK is derived + // from the LTK and SKD. However, when in sleep, the AES block loses + // this key. Also, when multiple connections are supported, the key + // will be different. + LL_ENC_LoadKey( connPtr->encInfo.SK ); + +// if ( llState == LL_STATE_CONN_MASTER ) + if( connPtr->llTbd1 == LL_LINK_CONNECT_COMPLETE_MASTER ) + { + // generate the nonce based on packet count, IV, and direction + LL_ENC_GenerateNonce( connPtr->encInfo.txPktCount, + LL_ENC_TX_DIRECTION_MASTER, + connPtr->encInfo.nonce ); + } + else // assumed llState == LL_STATE_CONN_SLAVE + { + // generate the nonce based on packet count, IV, and direction + LL_ENC_GenerateNonce( connPtr->encInfo.txPktCount, + LL_ENC_TX_DIRECTION_SLAVE, + connPtr->encInfo.nonce ); + } + + // confiig nounce + pByte = connPtr->encInfo.nonce; + *(volatile uint32_t*)(LL_ENC_BASE + 0x3c) = pByte[0] ; + pByte ++; + *(volatile uint32_t*)(LL_ENC_BASE + 0x38) = pByte[0] << 24 | pByte[1] << 16 | pByte[2] << 8 | pByte[3]; + pByte += 4; + *(volatile uint32_t*)(LL_ENC_BASE + 0x34) = pByte[0] << 24 | pByte[1] << 16 | pByte[2] << 8 | pByte[3]; + pByte += 4; + *(volatile uint32_t*)(LL_ENC_BASE + 0x30) = pByte[0] << 24 | pByte[1] << 16 | pByte[2] << 8 | pByte[3]; + // config plen & aad + *(volatile uint32_t*)(LL_ENC_BASE + 0x0c) = (pktLen << 8) | pktHdr; + // write packet to FIFO + len = pktLen; + index = 0; + + while (len >= 4) + { + *(volatile uint32_t*)(LL_ENC_BASE + 0x0100 + index) + = pBuf[index + 3] << 24 | pBuf[index + 2] << 16 | pBuf[index + 1] << 8 | pBuf[index]; + index += 4; + len -= 4; + } + + // to check the byte order + if(len == 3) + { + *(volatile uint32_t*)(LL_ENC_BASE + 0x0100 + index) + = pBuf[index + 2] << 16 | pBuf[index + 1] << 8 | pBuf[index]; + index += 4; + } + else if(len == 2) + { + *(volatile uint32_t*)(LL_ENC_BASE + 0x0100 + index) + = pBuf[index + 1] << 8 | pBuf[index] ; + index += 4; + } + else if(len == 1) + { + *(volatile uint32_t*)(LL_ENC_BASE + 0x0100 + index) + = pBuf[index] ; + index += 4; + } + + // AES FIFO legth is 256 bytes, set other bytes 0 + for (i = index; i < 0x100; i += 4) + { + *(volatile uint32_t*)(LL_ENC_BASE + 0x0100 + i) = 0x0; + } + + // set AES ctrl reg + *(int*) 0x40040004 = 0xf00; + // set interrupt enable + *(int*) 0x40040010 = 0xf; + // enable AES + *(int*) 0x40040000 = 0x1; + + // insert delay + // delay = 200; + // while (delay --); + + // query AES interrupt status register + while (*(volatile uint32_t*)(LL_ENC_BASE + 0x0014) == 0) ; + + // disable AES, if not disable AES, there is no output in FIFO + *(int*) 0x40040000 = 0x0; + // read back the encrypt result + index = 0; + len = pktLen + 4; // include 4 bytes MIC + + while (len > 0) + { + temp = *(volatile uint32_t*)(LL_ENC_BASE + 0x0100 + index); + pBuf[index ++] = temp & 0xff; + pBuf[index ++] = (temp >> 8) & 0xff; + pBuf[index ++] = (temp >> 16) & 0xff; + pBuf[index ++] = (temp >> 24) & 0xff; + len -= 4; + } + + // up the count for the next TX'ed data packet + // Note: This is supposed to be 39 bit counter, but for now, we don't + // envision receiving 550 billion packets during a connection! + connPtr->encInfo.txPktCount++; +// return; + } + AP_PCR->SW_CLK &= ~BIT(MOD_AES); +} +uint8 LL_ENC_Decrypt1( llConnState_t* connPtr, uint8 pktHdr, uint8 pktLen, uint8* pBuf ) +{ + AP_PCR->SW_CLK |= BIT(MOD_AES); +// uint8 ret = LL_ENC_Decrypt0( connPtr, pktHdr, pktLen, pBuf ); + { + uint8* pByte = NULL; + uint16 index; + int i, len; + uint32_t temp; + // disable AES + *(int*) 0x40040000 = 0x0; + // Load Key + // Note: Normally this would only need to be done once when the SK is derived + // from the LTK and SKD. However, when in sleep, the AES block loses + // this key. Also, when multiple connections are supported, the key + // will be different. + LL_ENC_LoadKey( connPtr->encInfo.SK ); + +// if ( llState == LL_STATE_CONN_MASTER ) + if( connPtr->llTbd1 == LL_LINK_CONNECT_COMPLETE_MASTER ) + { + // generate the nonce based on packet count, IV, and direction + LL_ENC_GenerateNonce( connPtr->encInfo.rxPktCount, + LL_ENC_RX_DIRECTION_MASTER, + connPtr->encInfo.nonce ); + } + else // assumed llState == LL_STATE_CONN_SLAVE + { + // generate the nonce based on packet count, IV, and direction + LL_ENC_GenerateNonce( connPtr->encInfo.rxPktCount, + LL_ENC_RX_DIRECTION_SLAVE, + connPtr->encInfo.nonce ); + } + + // confiig nounce + pByte = connPtr->encInfo.nonce; + *(volatile uint32_t*)(LL_ENC_BASE + 0x3c) = pByte[0]; // << 24 ; + pByte ++; + *(volatile uint32_t*)(LL_ENC_BASE + 0x38) = pByte[0] << 24 | pByte[1] << 16 | pByte[2] << 8 | pByte[3]; + pByte += 4; + *(volatile uint32_t*)(LL_ENC_BASE + 0x34) = pByte[0] << 24 | pByte[1] << 16 | pByte[2] << 8 | pByte[3]; + pByte += 4; + *(volatile uint32_t*)(LL_ENC_BASE + 0x30) = pByte[0] << 24 | pByte[1] << 16 | pByte[2] << 8 | pByte[3]; + // config plen & aad + *(volatile uint32_t*)(LL_ENC_BASE + 0x0c) = (pktLen << 8) | pktHdr; + // write packet to FIFO + len = pktLen + 4; // decrypt, add 4 for MIC field length + index = 0; + + while (len >= 4) + { + *(volatile uint32_t*)(LL_ENC_BASE + 0x0100 + index) + = pBuf[index + 3] << 24 | pBuf[index + 2] << 16 | pBuf[index + 1] << 8 | pBuf[index]; + index += 4; + len -= 4; + } + + // fill others bytes < 1 word + if(len == 3) + { + *(volatile uint32_t*)(LL_ENC_BASE + 0x0100 + index) + = pBuf[index + 2] << 16 | pBuf[index + 1] << 8 | pBuf[index]; + index += 4; + } + else if(len == 2) + { + *(volatile uint32_t*)(LL_ENC_BASE + 0x0100 + index) + = pBuf[index + 1] << 8 | pBuf[index] ; + index += 4; + } + else if(len == 1) + { + *(volatile uint32_t*)(LL_ENC_BASE + 0x0100 + index) + = pBuf[index] ; + index += 4; + } + + // AES FIFO legth is 256 bytes, set other bytes 0 + for (i = index; i < 0x100; i += 4) + { + *(volatile uint32_t*)(LL_ENC_BASE + 0x0100 + i) = 0x0; + } + + // set AES ctrl reg + *(int*) 0x40040004 = 0xf08; + // set interrupt enable + *(int*) 0x40040010 = 0xf; + // enable AES + *(int*) 0x40040000 = 0x1; + + // insert delay +// delay = 200; +// while (delay --); + + // query AES interrupt status register and wait decrypt finish + while (*(volatile uint32_t*)(LL_ENC_BASE + 0x0014) == 0) ; + + // read interrupt status reg + temp = *(volatile uint32_t*)(LL_ENC_BASE + 0x0014); + + if ((temp & LL_ENC_DECRYPT_FAIL_MASK) + || ((temp & LL_ENC_DECRYPT_SUCC_MASK) == 0)) + { + AP_PCR->SW_CLK &= ~BIT(MOD_AES); + return FALSE; + } + + // disable AES + *(int*) 0x40040000 = 0x0; + // read the decrypt result + index = 0; + len = pktLen; + + while (len > 0) + { + temp = *(volatile uint32_t*)(LL_ENC_BASE + 0x0100 + index); + pBuf[index ++] = temp & 0xff; + pBuf[index ++] = (temp >> 8) & 0xff; + pBuf[index ++] = (temp >> 16) & 0xff; + pBuf[index ++] = (temp >> 24) & 0xff; + len -= 4; + } + + // up the count for the next RX'ed data packet + // Note: This is supposed to be 39 bit counter, but for now, we don't + // envision receiving 550 billion packets during a connection! + connPtr->encInfo.rxPktCount++; + AP_PCR->SW_CLK &= ~BIT(MOD_AES); + return( TRUE ); + } +// AP_PCR->SW_CLK &= ~BIT(MOD_AES); +// return ret; +} + +//20200928 ZQ +//fix ADV_DIR_IND rxAdd setbit +llStatus_t LL_SetAdvParam1( uint16 advIntervalMin, + uint16 advIntervalMax, + uint8 advEvtType, + uint8 ownAddrType, + uint8 peerAddrType, + uint8* peerAddr, + uint8 advChanMap, + uint8 advWlPolicy ) +{ + uint8_t llState_reserve = llState; + llStatus_t ret; + ret=LL_SetAdvParam0( advIntervalMin, + advIntervalMax, + advEvtType, + ownAddrType, + peerAddrType, + peerAddr, + advChanMap, + advWlPolicy ); + llState=llState_reserve; + + if(advEvtType==LL_ADV_CONNECTABLE_HDC_DIRECTED_EVT + || advEvtType==LL_ADV_CONNECTABLE_LDC_DIRECTED_EVT) + { + SET_BITS(g_tx_adv_buf.txheader, peerInfo.peerAddrType, RX_ADD_SHIFT, RX_ADD_MASK); // RxAdd need't set + } + + return ret; +} + +llStatus_t LL_SetAdvControl1( uint8 advMode ) +{ + _HAL_CS_ALLOC_(); + //if random address isn't defined,can't set ownaddresstype to random + if ((advMode)&&(((adv_param.ownAddrType == LL_DEV_ADDR_TYPE_RANDOM) || + (adv_param.ownAddrType == LL_DEV_ADDR_TYPE_RPA_RANDOM)) && + ( (ownRandomAddr[0] == 0xFF) && + (ownRandomAddr[1] == 0xFF) && + (ownRandomAddr[2] == 0xFF) && + (ownRandomAddr[3] == 0xFF) && + (ownRandomAddr[4] == 0xFF) && + (ownRandomAddr[5] == 0xFF) ))) + { + return( LL_STATUS_ERROR_BAD_PARAMETER ); + } + + if (g_llAdvMode == LL_MODE_EXTENDED ) + return LL_STATUS_ERROR_COMMAND_DISALLOWED; + + g_llAdvMode = LL_MODE_LEGACY; + + // check if a direct test mode or modem test is in progress + if ( (llState == LL_STATE_DIRECT_TEST_MODE_TX) || + (llState == LL_STATE_DIRECT_TEST_MODE_RX) || + (llState == LL_STATE_MODEM_TEST_TX) || + (llState == LL_STATE_MODEM_TEST_RX) || + (llState == LL_STATE_MODEM_TEST_TX_FREQ_HOPPING) ) + { + return( LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE ); + } + + // 2021-4-19, check init/scan state should not enable/disable adv + if ( (llState == LL_STATE_SCAN) || + (llState == LL_STATE_INIT) ) + { + return( LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE ); + } + + // sanity checks again to be sure we don't start with bad parameters + if ( ( (adv_param.advEvtType != LL_ADV_CONNECTABLE_UNDIRECTED_EVT) && + (adv_param.advEvtType != LL_ADV_CONNECTABLE_HDC_DIRECTED_EVT) && + (adv_param.advEvtType != LL_ADV_NONCONNECTABLE_UNDIRECTED_EVT) && + (adv_param.advEvtType != LL_ADV_SCANNABLE_UNDIRECTED_EVT) && + (adv_param.advEvtType != LL_ADV_CONNECTABLE_LDC_DIRECTED_EVT) ) || + ( (adv_param.ownAddrType != LL_DEV_ADDR_TYPE_PUBLIC) && + (adv_param.ownAddrType != LL_DEV_ADDR_TYPE_RANDOM) && + (adv_param.ownAddrType != LL_DEV_ADDR_TYPE_RPA_PUBLIC) && + (adv_param.ownAddrType != LL_DEV_ADDR_TYPE_RPA_RANDOM)) || + ( ((adv_param.advEvtType == LL_ADV_NONCONNECTABLE_UNDIRECTED_EVT) || + (adv_param.advEvtType == LL_ADV_SCANNABLE_UNDIRECTED_EVT)) && + (adv_param.advInterval < LL_ADV_CONN_INTERVAL_MIN) ) ) // should use LL_ADV_NONCONN_INTERVAL_MIN after update it to 20ms + { + return( LL_STATUS_ERROR_BAD_PARAMETER ); + } + + #ifdef DEBUG_LL + LOG("llState = %d\n", llState); + #endif + + // check if we should begin advertising + switch( advMode ) + { + // Advertisment Mode is On + case LL_ADV_MODE_ON: + + // check if command makes sense + if ( adv_param.advMode == LL_ADV_MODE_ON ) + { + // this is unexpected; something is wrong + return( LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE ); + } + + //add llState setting + if((llState == LL_STATE_IDLE)) + { + switch(adv_param .advEvtType) + { + case LL_ADV_CONNECTABLE_UNDIRECTED_EVT: + llState=LL_STATE_ADV_UNDIRECTED; + ll_debug_output(DEBUG_LL_STATE_ADV_UNDIRECTED); + break; + + case LL_ADV_CONNECTABLE_HDC_DIRECTED_EVT: + case LL_ADV_CONNECTABLE_LDC_DIRECTED_EVT: + llState=LL_STATE_ADV_DIRECTED; + ll_debug_output(DEBUG_LL_STATE_ADV_DIRECTED); + break; + + case LL_ADV_NONCONNECTABLE_UNDIRECTED_EVT: + llState=LL_STATE_ADV_NONCONN; + ll_debug_output(DEBUG_LL_STATE_ADV_NONCONN); + break; + + case LL_ADV_SCANNABLE_UNDIRECTED_EVT: + llState=LL_STATE_ADV_SCAN; + ll_debug_output(DEBUG_LL_STATE_ADV_SCAN); + break; + + default: + llState=LL_STATE_IDLE; + ll_debug_output(DEBUG_LL_STATE_IDLE); + break; + } + } + + // llState changed when configure adv parameters + if (llState == LL_STATE_ADV_UNDIRECTED + || llState == LL_STATE_ADV_DIRECTED + || llState == LL_STATE_ADV_NONCONN + || llState == LL_STATE_ADV_SCAN ) // TODO: check this setting + { + g_llHdcDirAdvTime = 0; // for HDC direct adv + adv_param.advNextChan = LL_ADV_CHAN_LAST + 1; // set adv channel invalid + + if ( llSetupAdv() != LL_STATUS_SUCCESS ) + { + // indicate advertising is no longer active + adv_param.advMode = LL_ADV_MODE_OFF; + return( LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE ); + } + } + // add in A2, simultaneous conn event & scan/adv event + else if((llState == LL_STATE_CONN_SLAVE + || llState == LL_STATE_CONN_MASTER) + && (pGlobal_config[LL_SWITCH] & SIMUL_CONN_ADV_ALLOW)) + { + #ifdef DEBUG_LL + LOG("LL_SetAdvControl: start sec adv\r\n"); + #endif + + if (llSecondaryState != LL_SEC_STATE_IDLE) + return( LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE ); + + // adv event check + if (adv_param.advEvtType != LL_ADV_NONCONNECTABLE_UNDIRECTED_EVT + && adv_param.advEvtType != LL_ADV_SCANNABLE_UNDIRECTED_EVT + && adv_param.advEvtType != LL_ADV_CONNECTABLE_UNDIRECTED_EVT) + return( LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE ); + + // Note: we may need maximum slave number check here. If number of slave reach ceil, + // only no-connectable adv is allowed. The checking could be don't in host + llSecondaryState = LL_SEC_STATE_ADV; + adv_param.advNextChan = LL_ADV_CHAN_LAST + 1; // set adv channel invalid + osal_stop_timerEx( LL_TaskID, LL_EVT_SECONDARY_ADV ); + osal_set_event(LL_TaskID, LL_EVT_SECONDARY_ADV); // set adv event + } + else // other state + return (LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE); + + // indicate advertising is no longer active + adv_param.advMode = LL_ADV_MODE_ON; + + if (g_llRlDeviceNum > 0) + osal_start_timerEx( LL_TaskID, LL_EVT_RPA_TIMEOUT, g_llRlTimeout * 1000 ); + + break; + + case LL_ADV_MODE_OFF: + // check if command makes sense +// if ( adv_param.advMode == LL_ADV_MODE_OFF ) +// { +// // this is unexpected; something is wrong +// return( LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE ); +// } + HAL_ENTER_CRITICAL_SECTION(); + // free the associated task block + //llFreeTask( &advInfo.llTask ); + // indicate we are no longer actively advertising + adv_param.advMode = LL_ADV_MODE_OFF; + + if (llState != LL_STATE_CONN_SLAVE && + llState != LL_STATE_CONN_MASTER ) // no conn + adv case + { + llState = LL_STATE_IDLE; // if not in connect state, set idle to disable advertise + //ZQ 20190912 + //stop ll timer when idle, considering the scan-adv interleve case + clear_timer(AP_TIM1); + ll_debug_output(DEBUG_LL_STATE_IDLE); + } + + if(llSecondaryState!=LL_SEC_STATE_IDLE) // conn + adv case + { +// uint8 i; +// i = 0; +// while (!(adv_param.advChanMap & (1 << i))) i ++; // get the 1st adv channel in the adv channel map +// if ((llSecondaryState == LL_SEC_STATE_ADV) +// && (adv_param.advNextChan != (LL_ADV_CHAN_FIRST + i))) // last adv event is not finished +// llSecondaryState = LL_SEC_STATE_IDLE_PENDING; +// else + { + llSecondaryState = LL_SEC_STATE_IDLE; + osal_stop_timerEx( LL_TaskID, LL_EVT_SECONDARY_ADV ); // stop timer + } + } + + HAL_EXIT_CRITICAL_SECTION(); + osal_stop_timerEx(LL_TaskID, LL_EVT_RPA_TIMEOUT); + break; + + default: + // we have an invalid value for advertisement mode + return( LL_STATUS_ERROR_BAD_PARAMETER ); + } + + return( LL_STATUS_SUCCESS ); +} + + +#if 0 +//2020.10.22,Jie,fix phyupdate issue +llStatus_t LL_PhyUpdate1( uint16 connId ) +{ + llStatus_t status; + llConnState_t* connPtr; + uint8 phyMode; + + // make sure connection ID is valid + if ( (status=LL_ConnActive(connId)) != LL_STATUS_SUCCESS ) + { + return( status ); + } + + // get connection info + connPtr = &conn_param[connId ]; + + // check if an update control procedure is already pending + if ( ((connPtr->ctrlPktInfo.ctrlPktCount > 0) && + (connPtr->ctrlPktInfo.ctrlPkts[0] == LL_CTRL_PHY_UPDATE_IND)) || + (connPtr->pendingPhyModeUpdate == TRUE) ) + { + return( LL_STATUS_ERROR_CTRL_PROC_ALREADY_ACTIVE ); + } + + // we only support symmetric connection + // tx rx phy should be same + phyMode = connPtr->llPhyModeCtrl.req.txPhy & connPtr->llPhyModeCtrl.rsp.txPhy; + phyMode &= connPtr->llPhyModeCtrl.req.rxPhy & connPtr->llPhyModeCtrl.rsp.rxPhy; + + //20200727 Jie add for no change case + if((phyMode==0) || (phyMode == connPtr->llPhyModeCtrl.local.txPhy)) + { + //no change case + connPtr->phyUpdateInfo.m2sPhy = 0; + connPtr->phyUpdateInfo.s2mPhy = 0; + } + else if((phyMode&LE_2M_PHY)&&(connPtr->llPhyModeCtrl.local.txPhy != LE_2M_PHY)) + { + connPtr->phyUpdateInfo.m2sPhy = LE_2M_PHY; + connPtr->phyUpdateInfo.s2mPhy = LE_2M_PHY; + } + else if((phyMode&LE_CODED_PHY)&&(connPtr->llPhyModeCtrl.local.txPhy != LE_CODED_PHY)) + { + connPtr->phyUpdateInfo.m2sPhy = LE_CODED_PHY; + connPtr->phyUpdateInfo.s2mPhy = LE_CODED_PHY; + } + else + { + //no perferce can not support the tx/rx same time + connPtr->phyUpdateInfo.m2sPhy = LE_1M_PHY; + connPtr->phyUpdateInfo.s2mPhy = LE_1M_PHY; + } + + if(connPtr->phyUpdateInfo.m2sPhy==0) + { + connPtr->phyModeUpdateEvent = 0; + connPtr->phyUpdateInfo.instant = connPtr->phyModeUpdateEvent; + } + else + { + connPtr->phyModeUpdateEvent = (connPtr->curParam.slaveLatency+1) + + LL_INSTANT_NUMBER_MIN; + connPtr->phyUpdateInfo.instant = connPtr->phyModeUpdateEvent; + } + + // queue control packet for processing + llEnqueueCtrlPkt( connPtr, LL_CTRL_PHY_UPDATE_IND ); + return( LL_STATUS_SUCCESS ); +} +#endif + +//2020.10.22,Jie,fix scanparam ownaddr setting issue +llStatus_t LL_SetScanParam1( uint8 scanType, + uint16 scanInterval, + uint16 scanWindow, + uint8 ownAddrType, + uint8 scanWlPolicy ) +{ + llStatus_t ret; + ret = LL_SetScanParam0(scanType,scanInterval,scanWindow,ownAddrType,scanWlPolicy); +// LOG("%s,ret %d\n",__func__,ret); + + if(ret == LL_STATUS_SUCCESS) + { + scanInfo.ownAddrType = ownAddrType; + + if ( ownAddrType == LL_DEV_ADDR_TYPE_PUBLIC || ownAddrType == LL_DEV_ADDR_TYPE_RPA_PUBLIC) + { + LL_COPY_DEV_ADDR_LE( scanInfo.ownAddr, ownPublicAddr ); + } + else + { + LL_COPY_DEV_ADDR_LE( scanInfo.ownAddr, ownRandomAddr ); + } + } + + return ret; +} + +//2020.10.22,Jie, modify sanity check: +//add ownaddrtype; +//add LL_STATUS_ERROR_BAD_PARAMETER case +llStatus_t LL_SetScanControl1( uint8 scanMode, + uint8 filterReports ) +{ + _HAL_CS_ALLOC_(); +// LOG("%s,scanMode %d\n",__func__,scanMode); + if (g_llScanMode == LL_MODE_EXTENDED ) + return LL_STATUS_ERROR_COMMAND_DISALLOWED; + + g_llScanMode = LL_MODE_LEGACY; + + // check if a direct test mode or modem test is in progress + if ( (llState == LL_STATE_DIRECT_TEST_MODE_TX) || + (llState == LL_STATE_DIRECT_TEST_MODE_RX) || + (llState == LL_STATE_MODEM_TEST_TX) || + (llState == LL_STATE_MODEM_TEST_RX) || + (llState == LL_STATE_MODEM_TEST_TX_FREQ_HOPPING) ) + { + return( LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE ); + } + + // sanity checks again to be sure we don't start with bad parameters + if ( ( (scanInfo.scanType != LL_SCAN_PASSIVE) && + (scanInfo.scanType != LL_SCAN_ACTIVE)) || + ( (scanInfo.ownAddrType != LL_DEV_ADDR_TYPE_PUBLIC) && + (scanInfo.ownAddrType != LL_DEV_ADDR_TYPE_RANDOM) && + (scanInfo.ownAddrType != LL_DEV_ADDR_TYPE_RPA_PUBLIC) && + (scanInfo.ownAddrType != LL_DEV_ADDR_TYPE_RPA_RANDOM)) || + ( (scanInfo.scanInterval < LL_SCAN_WINDOW_MIN) || + (scanInfo.scanInterval > LL_SCAN_WINDOW_MAX)) || + ( (scanInfo.scanWindow < LL_SCAN_WINDOW_MIN) || + (scanInfo.scanWindow > LL_SCAN_WINDOW_MAX)) || + ( (scanInfo.scanWindow > scanInfo.scanInterval) ) || + ( (filterReports != LL_FILTER_REPORTS_DISABLE) && + (filterReports != LL_FILTER_REPORTS_ENABLE)) ) + { + return( LL_STATUS_ERROR_BAD_PARAMETER ); + } + + // check if we should begin scanning + switch( scanMode ) + { + // Scanning Mode is On + case LL_SCAN_START: + +// LOG("LL_SCAN_START\n"); + + // check if command makes sense + if ( scanInfo.scanMode == LL_SCAN_START ) + { + // this is unexpected; something is wrong + return( LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE ); + } + + //20200804 Jie :if random address isn't defined,can't set ownaddresstype to random + if (((scanInfo.ownAddrType == LL_DEV_ADDR_TYPE_RANDOM) || + (scanInfo.ownAddrType == LL_DEV_ADDR_TYPE_RPA_RANDOM)) && + ( (ownRandomAddr[0] == 0xFF) && + (ownRandomAddr[1] == 0xFF) && + (ownRandomAddr[2] == 0xFF) && + (ownRandomAddr[3] == 0xFF) && + (ownRandomAddr[4] == 0xFF) && + (ownRandomAddr[5] == 0xFF) )) + { + return( LL_STATUS_ERROR_BAD_PARAMETER ); + } + + // get a task block for this BLE state/role + // Note: There will always be a valid pointer, so no NULL check required. +// scanInfo.llTask = llAllocTask( LL_TASK_ID_SCANNER ); + + // check if no other tasks are currently active + if ( llState == LL_STATE_IDLE ) + { + // indicate Scan has not already been initalized + scanInfo.initPending = TRUE; + // save the scan filtering flag + scanInfo.filterReports = filterReports; + // add by HZF + scanInfo.nextScanChan = LL_SCAN_ADV_CHAN_37; + // set LL state + llState = LL_STATE_SCAN; + // Note: llState has been changed. + LL_evt_schedule(); + } + else if ((llState == LL_STATE_CONN_SLAVE + || llState == LL_STATE_CONN_MASTER) // HZF: if we should support adv + scan, add more state here + && (pGlobal_config[LL_SWITCH] & SIMUL_CONN_SCAN_ALLOW)) + { + if (llSecondaryState != LL_SEC_STATE_IDLE) + return( LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE ); + + scanInfo.nextScanChan = LL_SCAN_ADV_CHAN_37; + llSecondaryState = LL_SEC_STATE_SCAN; + osal_set_event(LL_TaskID, LL_EVT_SECONDARY_SCAN); + } + else + return( LL_STATUS_ERROR_UNEXPECTED_STATE_ROLE ); + + // indicate we are actively scanning + scanInfo.scanMode = LL_SCAN_START; + break; + + case LL_SCAN_STOP: +// LOG("LL_SCAN_STOP\n"); + HAL_ENTER_CRITICAL_SECTION(); + + if (llState == LL_STATE_SCAN) // no conn + scan case + { + llState = LL_STATE_IDLE; // if not in connect state, set idle to disable scan + //ZQ 20190912 + //stop ll timer when idle, considering the scan-adv interleve case + clear_timer(AP_TIM1); + ll_debug_output(DEBUG_LL_STATE_IDLE); + } + else if (llState == LL_STATE_CONN_SLAVE + || llState == LL_STATE_CONN_MASTER) // conn + scan case + { + llSecondaryState = LL_SEC_STATE_IDLE; + // bugfix for multi-role + osal_stop_timerEx(LL_TaskID, LL_EVT_SECONDARY_SCAN); + } + + // indicate we are no longer actively scanning + scanInfo.scanMode = LL_SCAN_STOP; + // A2 multiconn, should we consider current LL state to avoid change master/slave configuration + // now LL slave/master event use same parameter 88 + ll_hw_set_rx_timeout(88); + // HZF: should we stop scan task immediately, or wait scan IRQ then stop? Now use option 2. + HAL_EXIT_CRITICAL_SECTION(); + + while(read_reg(&llWaitingIrq) == TRUE); + + break; + + default: + // we have an invalid value for advertisement mode + return( LL_STATUS_ERROR_BAD_PARAMETER ); + } + + return( LL_STATUS_SUCCESS ); +} + +//2020.10.23 Jie,fix g_llPduLen.suggested.MaxTxTime setting error +llStatus_t LL_SetDataLengh1( uint16 connId,uint16 TxOctets,uint16 TxTime ) +{ + if(TxOctets > LL_PDU_LENGTH_SUPPORTED_MAX_TX_OCTECTS + || TxTime > LL_PDU_LENGTH_SUPPORTED_MAX_TX_TIME + || TxOctets < LL_PDU_LENGTH_INITIAL_MAX_TX_OCTECTS + || TxTime < LL_PDU_LENGTH_INITIAL_MAX_TX_TIME) + { + return(LL_STATUS_ERROR_PARAM_OUT_OF_RANGE); + } + else + { + g_llPduLen.suggested.MaxTxOctets= TxOctets; + g_llPduLen.suggested.MaxTxTime = TxTime; + return LL_SetDataLengh0( connId,TxOctets,TxTime ); + } +} + + +volatile int sstmp = 1; +void llProcessTxData2( llConnState_t *connPtr, uint8 context ) +{ + uint8 *pBuf; + + //HAL_ENTER_CRITICAL_SECTION(); + + // try to put as many packets into the TX FIFO as possible + while( connPtr->txDataQ.head != NULL ) + { + // point to packet header + pBuf = (uint8 *)(connPtr->txDataQ.head + 1); + + // check if TX is enabled and if there is room in TX FIFO + if(pBuf[7] == 0x21){ + sstmp++; + } + + if ( llWriteTxData( connPtr, pBuf[1], pBuf[0], &pBuf[2] ) == LL_STATUS_SUCCESS ) + { + // remove entry from TX queue and free the buffer + osal_bm_free( llDequeueDataQ( &connPtr->txDataQ ) ); + + numComplPkts ++; + + // update counter + connPtr->pmCounter.ll_hci_to_ll_pkt_cnt += numComplPkts; +// LOG("TX:%d\n", connPtr->connId); + + continue; + } + + // unable to complete the write, so keep packet on queue + break; + } + + // check if we completed any packets + // The Number of Completed Packets event is sent when the number of completed + // packets is equal to or greater than the user specified limit, which can + // range from 1 to the LL_MAX_NUM_DATA_BUFFERS (default is one). If the + // number of completed packets is less than the limit, then this event is only + // sent if the user indicated that this event to be sent at the end of the + // connection event. + // Note: Spec indicates that while the Controller has HCI data packets in its + // buffer, it must keep sending the Number Of Completed Packets event + // to the Host at least periodically, until it finally reports that all + // the pending ACL Data Packets have been transmitted or flushed. + // However, this can potentially waste a lot of time sending events + // with a number of completed packets set to zero, so for now, this + // will not be supported. + if ( (numComplPkts > 0) && + (numComplPkts >= numComplPktsLimit) ) // || + //((context == LL_TX_DATA_CONTEXT_POST_PROCESSING) && numComplPktsFlush)) ) + { + uint16 connId = connPtr->connId; + uint16 numCompletedPackets = numComplPkts; + + // and send credits to the Host + HCI_NumOfCompletedPacketsEvent( 1, + &connId, + &numCompletedPackets ); + + // clear count + numComplPkts = 0; + } + + //HAL_EXIT_CRITICAL_SECTION(); + + return; +} + + +void llProcessTxData1( llConnState_t* connPtr, uint8 context ) +{ + if(context==LL_TX_DATA_CONTEXT_SEND_DATA) + return; + + llProcessTxData2(connPtr,context); +} +/******************************************************************************* + @fn ll_generateTxBuffer1 + + @brief This function generate Tx data and find in Tx FIFO + there are 4 kinds of data: + 1. control data + 2. last no-ack data + 3. last no-transmit data + 4. new data + in the new RTLP buffer, the data should be in the below sequence: + 2 --> 3 --> 1 --> 4 (changed) + + input parameters + + @param txFifo_vacancy - allow max tx packet number. + + output parameters + + @param None. + + @return the pointer of 1st not transmit packet/new packet. + +*/ +uint16 ll_generateTxBuffer1(int txFifo_vacancy, uint16* pSave_ptr) +{ + int i, new_pkts_num, tx_num = 0; + llConnState_t* connPtr; + connPtr = &conn_param[g_ll_conn_ctx.currentConn]; + + // 0. write empty packet + if(connPtr->llMode == LL_HW_RTLP_EMPT + || connPtr->llMode == LL_HW_TRLP_EMPT) // TRLP case, to be confirmed/test + { + LL_HW_WRT_EMPTY_PKT; + connPtr->ll_buf.tx_not_ack_pkt->valid = 0; // empty mode, tx_not_ack buffer null or empty packet + tx_num ++; + } + // 1. write last not-ACK packet + else if (connPtr->ll_buf.tx_not_ack_pkt->valid != 0) // TODO: if the valid field could omit, move the not-ACK flag to buf. + { + ll_hw_write_tfifo((uint8*)&(connPtr->ll_buf.tx_not_ack_pkt->header), ((connPtr->ll_buf.tx_not_ack_pkt->header & 0xff00) >> 8) + 2); + //txFifo_vacancy --; + tx_num ++; + connPtr->ll_buf.tx_not_ack_pkt->valid = 0; + AT_LOG("write last not-ACK packet \n"); + } + + // 1st RTLP event, no porcess 0/1, it should be 0 because we have reset the TFIFO + // other case, it is 1st not transmit packet/new packet + *pSave_ptr = ll_hw_get_tfifo_wrptr(); + + // 3. write last not transmit packets + if (connPtr->ll_buf.ntrm_cnt > 0 + && txFifo_vacancy >= connPtr->ll_buf.ntrm_cnt) + { + for (i = 0; i < connPtr->ll_buf.ntrm_cnt ; i++) + { + ll_hw_write_tfifo((uint8*)&(connPtr->ll_buf.tx_ntrm_pkts[i]->header), ((connPtr->ll_buf.tx_ntrm_pkts[i]->header & 0xff00) >> 8) + 2); + } + + txFifo_vacancy -= connPtr->ll_buf.ntrm_cnt; + tx_num += connPtr->ll_buf.ntrm_cnt; + AT_LOG("write last not transmit packets\n"); + connPtr->ll_buf.ntrm_cnt = 0; + } + + rfCounters.numTxCtrl = 0; // add on 2017-11-15, set tx control packet number 0 + + // 2. write control packet + if ((connPtr->ll_buf.tx_not_ack_pkt->valid == 0 || // no tx not_ack packet, add on 2017-11-15 + (connPtr->ll_buf.tx_not_ack_pkt->header & 0x3) != LL_DATA_PDU_HDR_LLID_CONTROL_PKT) // last nack packet is not a control packet + && connPtr->ctrlDataIsPending // we only support 1 control procedure per connection + && !connPtr->ctrlDataIsProcess + && txFifo_vacancy > connPtr->ll_buf.ntrm_cnt) // tricky here: if the Tx FIFO is full and nothing is sent in last event, then it can't fill new packet(include ctrl pkt) in new event + { + // not in a control procedure, and there is control packet pending + // fill ctrl packet + ll_hw_write_tfifo((uint8*)&(connPtr->ctrlData .header), ((connPtr->ctrlData .header & 0xff00) >> 8) + 2); + txFifo_vacancy --; + tx_num ++; + // put Ctrl packet in TFIFO, change the control procedure status + connPtr->ctrlDataIsPending = 0; + connPtr->ctrlDataIsProcess = 1; + rfCounters.numTxCtrl = 1; // add 2017-11-15, if put new ctrl packet in FIFO, add the counter + } + + if (connPtr->ll_buf.ntrm_cnt != 0) + { + // should not be here, new packets should not be sent if there is not-transmit packets + return tx_num; + } + + // 4. write new data packets to FIFO + new_pkts_num = getTxBufferSize(connPtr); + + if ((new_pkts_num > 0) + && txFifo_vacancy > 0) + { + // fill the data packet to Tx FIFO + for (i = 0; i < new_pkts_num && i < txFifo_vacancy; i++) + { + uint8_t idx = get_tx_read_ptr(connPtr); + ll_hw_write_tfifo((uint8*)&(connPtr->ll_buf.tx_conn_desc[idx]->header), ((connPtr->ll_buf.tx_conn_desc[idx]->header & 0xff00) >> 8) + 2); + update_tx_read_ptr(connPtr); + tx_num++; + AT_LOG("write new data packets to FIFO\n"); + // update PM counter, add A1 ROM metal change + connPtr->pmCounter.ll_send_data_pkt_cnt ++; + } + } + + // 2020-02-13 periodic cte req & rsp + if( ( connPtr->llConnCTE.enable ) && ( connPtr->llCTE_ReqFlag )) + { + if( connPtr->llConnCTE.CTE_Request_Intv > 0 ) + { + if( connPtr->llConnCTE.CTE_Count_Idx < connPtr->llConnCTE.CTE_Request_Intv ) + connPtr->llConnCTE.CTE_Count_Idx++; + else + { + connPtr->llConnCTE.CTE_Count_Idx = 0; + llEnqueueCtrlPkt(connPtr, LL_CTRL_CTE_REQ ); + } + } + } + + return tx_num; +} + + +#if 0 +//2020.10.23 Jie,fix setphymode issue +llStatus_t LL_SetPhyMode1( uint16 connId,uint8 allPhy,uint8 txPhy, uint8 rxPhy,uint16 phyOptions) +{ + uint8 i; + llStatus_t status; + llConnState_t* connPtr; + + // make sure connection ID is valid + if ( (status=LL_ConnActive(connId)) != LL_STATUS_SUCCESS ) + { + return( status ); + } + + // get connection info + connPtr = &conn_param[connId]; + + // check if a feature response control procedure has taken place + if ( connPtr->featureSetInfo.featureRspRcved == FALSE ) + { + // it hasn't so re-load this device's local Feature Set to the + // connection as it may have been changed by the Host with HCI + // extenstion Set Local Feature Set command + for (i=0; ifeatureSetInfo.featureSet[i] = deviceFeatureSet.featureSet[i]; + } + } + + // check if dle is a supported feature set item + if( ( (connPtr->featureSetInfo.featureSet[1] & LL_FEATURE_2M_PHY) != LL_FEATURE_2M_PHY ) + && ( (connPtr->featureSetInfo.featureSet[1] & LL_FEATURE_CODED_PHY) != LL_FEATURE_CODED_PHY ) ) + { + return( LL_STATUS_ERROR_FEATURE_NOT_SUPPORTED ); + } + + // check if an updated parameters control procedure is already what's pending + if ( ((connPtr->ctrlPktInfo.ctrlPktCount > 0) && + (connPtr->ctrlPktInfo.ctrlPkts[0] == LL_CTRL_PHY_REQ)) || + (connPtr->pendingPhyModeUpdate== TRUE) || + (connPtr->llPhyModeCtrl.isWatingRsp == TRUE) || (connPtr->llPhyModeCtrl.isProcessingReq == TRUE) ) + { + return( LL_STATUS_ERROR_CTRL_PROC_ALREADY_ACTIVE ); + } + + //support Symmetric Only + if(allPhy==0 &&(txPhy!=rxPhy)) + { + return( LL_STATUS_ERROR_FEATURE_NOT_SUPPORTED ); + } + + //jie 2020.9.3 check unsupport phy + if ((txPhy > 0x07) || (rxPhy >0x07)) + { + return( LL_STATUS_ERROR_FEATURE_NOT_SUPPORTED ); + } + + uint8 tx_chance = (txPhy ^ connPtr->llPhyModeCtrl.local.txPhy) ^connPtr->llPhyModeCtrl.local.txPhy; + + if(tx_chance & LE_1M_PHY) + { + txPhy = LE_1M_PHY; + } + else if(tx_chance & LE_2M_PHY) + { + txPhy = LE_2M_PHY; + } + else if(tx_chance & LE_CODED_PHY) + { + txPhy = LE_CODED_PHY; + } + else + { + //nothing + } + + uint8 rx_chance = (rxPhy ^ connPtr->llPhyModeCtrl.local.rxPhy)^connPtr->llPhyModeCtrl.local.rxPhy; + + if(rx_chance & LE_1M_PHY) + { + rxPhy = LE_1M_PHY; + } + else if(rx_chance & LE_2M_PHY) + { + rxPhy = LE_2M_PHY; + } + else if(rx_chance & LE_CODED_PHY) + { + rxPhy = LE_CODED_PHY; + } + else + { + //nothing + } + + // how to check the required param? + //LL_TS_5.0.3 Table 4.43: PDU payload contents for each case variation for LE 2M PHY + connPtr->llPhyModeCtrl.req.allPhy = allPhy; + + if(connPtr->llPhyModeCtrl.req.allPhy==0) + { + connPtr->llPhyModeCtrl.req.txPhy = txPhy; + connPtr->llPhyModeCtrl.req.rxPhy = rxPhy; + } + else if(connPtr->llPhyModeCtrl.req.allPhy==1) + { + connPtr->llPhyModeCtrl.req.txPhy = rxPhy;//0; + connPtr->llPhyModeCtrl.req.rxPhy = rxPhy; + } + else if(connPtr->llPhyModeCtrl.req.allPhy==2) + { + connPtr->llPhyModeCtrl.req.txPhy = txPhy; + connPtr->llPhyModeCtrl.req.rxPhy = txPhy;//0; + } + else + { + //no prefer on both phy + connPtr->llPhyModeCtrl.req.txPhy = LE_1M_PHY;//0; + connPtr->llPhyModeCtrl.req.rxPhy = LE_1M_PHY;//0; + } + + connPtr->llPhyModeCtrl.phyOptions = phyOptions; + //update def.phy jie 2020.9.2 + connPtr->llPhyModeCtrl.def.allPhy = allPhy; + // connPtr->llPhyModeCtrl.def.txPhy = connPtr->llPhyModeCtrl.req.txPhy; + // connPtr->llPhyModeCtrl.def.rxPhy = connPtr->llPhyModeCtrl.req.rxPhy; + // setup an LL_CTRL_PHY_REQ + llEnqueueCtrlPkt( connPtr, LL_CTRL_PHY_REQ ); + return(LL_STATUS_SUCCESS); +} +#endif + + +/* 2020.11.11,Jie,fix ownaddr random address source issue +*/ +llStatus_t LL_CreateConn1( uint16 scanInterval, + uint16 scanWindow, + uint8 initWlPolicy, + uint8 peerAddrType, + uint8* peerAddr, + uint8 ownAddrType, + uint16 connIntervalMin, + uint16 connIntervalMax, + uint16 connLatency, + uint16 connTimeout, + uint16 minLength, // minimum length of connection needed for this LE conn, no use now + uint16 maxLength ) // maximum length of connection needed for this LE conn, no use now +{ + CreateConn_Flag = TRUE; + return LL_CreateConn0(scanInterval, + scanWindow, + initWlPolicy, + peerAddrType, + peerAddr, + ownAddrType, + connIntervalMin, + connIntervalMax, + connLatency, + connTimeout, + minLength, + maxLength ); +} + +#if 0 +//2020.11.12, add case LL_REJECT_IND_EXT +void llProcessMasterControlPacket1( llConnState_t* connPtr, + uint8* pBuf ) +{ + uint8 i; + uint8 opcode = *pBuf++; + uint8 iqCnt = 0; + + // check the type of control packet + switch( opcode ) + { + // Encryption Response + case LL_CTRL_ENC_RSP: + // concatenate slave's SKDs with SKDm + // Note: The SKDs MSO is the MSO of the SKD. + //PHY_READ_BYTE( (uint8 *)&connPtr->encInfo.SKD[LL_ENC_SKD_S_OFFSET], LL_ENC_SKD_S_LEN ); + pBuf = llMemCopySrc( (uint8*)&connPtr->encInfo.SKD[LL_ENC_SKD_S_OFFSET], pBuf, LL_ENC_SKD_S_LEN ); + // bytes are received LSO..MSO, but need to be maintained as + // MSO..LSO, per FIPS 197 (AES), so reverse the bytes + LL_ENC_ReverseBytes( &connPtr->encInfo.SKD[LL_ENC_SKD_S_OFFSET], LL_ENC_SKD_S_LEN ); + // concatenate the slave's IVs with IVm + // Note: The IVs MSO is the MSO of the IV. + //PHY_READ_BYTE( (uint8 *)&connPtr->encInfo.IV[LL_ENC_IV_S_OFFSET], LL_ENC_IV_S_LEN ); + pBuf = llMemCopySrc( (uint8*)&connPtr->encInfo.IV[LL_ENC_IV_S_OFFSET], pBuf, LL_ENC_IV_S_LEN ); + // bytes are received LSO..MSO, but need to be maintained as + // MSO..LSO, per FIPS 197 (AES), so reverse the bytes + // ALT: POSSIBLE TO MAINTAIN THE IV IN LSO..MSO ORDER SINCE THE NONCE + // IS FORMED THAT WAY. + LL_ENC_ReverseBytes( &connPtr->encInfo.IV[LL_ENC_IV_S_OFFSET], LL_ENC_IV_S_LEN ); + + // place the IV into the Nonce to be used for this connection + // Note: If a Pause Encryption control procedure is started, the + // old Nonce value will be used until encryption is disabled. + // Note: The IV is sequenced LSO..MSO within the Nonce. + // ALT: POSSIBLE TO MAINTAIN THE IV IN LSO..MSO ORDER SINCE THE NONCE + // IS FORMED THAT WAY. + for (i=0; iencInfo.nonce[ LL_END_NONCE_IV_OFFSET+i ] = + connPtr->encInfo.IV[ (LL_ENC_IV_LEN-i)-1 ]; + } + + // generate the Session Key (i.e. SK = AES128(LTK, SKD)) + LL_ENC_GenerateSK( connPtr->encInfo.LTK, + connPtr->encInfo.SKD, + connPtr->encInfo.SK ); + // LOG("LTK: %x\r\n", connPtr->encInfo.LTK); + // LOG("SKD: %x\r\n", connPtr->encInfo.SKD); + // LOG("SK: %x\r\n", connPtr->encInfo.SK[0], connPtr->encInfo.SK[1], connPtr->encInfo.SK[],connPtr->encInfo.SK[0], + // connPtr->encInfo.SK[0],connPtr->encInfo.SK[0],connPtr->encInfo.SK[0]); + // Note: Done for now; the slave will send LL_CTRL_START_ENC_REQ. + //LOG("ENC_RSP ->"); + break; + + // Start Encryption Request + case LL_CTRL_START_ENC_REQ: + // set a flag to indicate we've received this packet + connPtr->encInfo.startEncReqRcved = TRUE; + break; + + // Start Encryption Response + case LL_CTRL_START_ENC_RSP: + // set flag to allow outgoing data transmissions + connPtr->txDataEnabled = TRUE; + // okay to receive data again + connPtr->rxDataEnabled = TRUE; + // indicate we've received the start encryption response + connPtr->encInfo.startEncRspRcved = TRUE; + + // notify the Host + if ( connPtr->encInfo.encRestart == TRUE ) + { + // a key change was requested + LL_EncKeyRefreshCback( connPtr->connId, + LL_ENC_KEY_REQ_ACCEPTED ); + } + else + { + // a new encryption was requested + LL_EncChangeCback( connPtr->connId, + LL_ENC_KEY_REQ_ACCEPTED, + LL_ENCRYPTION_ON ); + } + + // clear the restart flag in case of another key change request + // Note: But in reality, there isn't a disable encryption in BLE, + // so once encryption is enabled, any call to LL_StartEncrypt + // will result in an encryption key change callback. + connPtr->encInfo.encRestart = FALSE; + //LOG("START_ENC_RSP ->"); + break; + + // Pause Encryption Response + case LL_CTRL_PAUSE_ENC_RSP: + // set a flag to indicate we have received LL_START_ENC_RSP + connPtr->encInfo.pauseEncRspRcved = TRUE; + break; + + // Reject Encryption Indication + /* + case LL_CTRL_REJECT_IND: + // either the slave's Host has failed to provide an LTK, or + // the encryption feature is not supported by the slave, so read + // the rejection indication error code + //connPtr->encInfo.encRejectErrCode = PHY_READ_BYTE_VAL(); + connPtr->encInfo.encRejectErrCode = *pBuf; + + // and end the start encryption procedure + connPtr->encInfo.rejectIndRcved = TRUE; + + break; + */ + + // Controller Feature Setup --> should be LL_CTRL_SLAVE_FEATURE_REQ + // case LL_CTRL_FEATURE_REQ: // new for BLE4.2, to test + + // for (i=0; ifeatureSetInfo.featureSet[i] = deviceFeatureSet.featureSet[i]; + // } + + // // logical-AND with master's feature set to indicate which of the + // // controller features in the master the slave requests to be used + // for (i=0; ifeatureSetInfo.featureSet[i] = + // *pBuf++ & deviceFeatureSet.featureSet[i]; + // } + + // // schedule the output of the control packet + // // Note: Features to be used will be taken on the next connection + // // event after the response is successfully transmitted. + // llEnqueueCtrlPkt( connPtr, LL_CTRL_FEATURE_RSP ); + + // break; + + case LL_CTRL_FEATURE_RSP: + { + uint8 peerFeatureSet[ LL_MAX_FEATURE_SET_SIZE ]; + // get the peer's device Feature Set + //for (i=0; ifeatureSetInfo.featureSet[i] = deviceFeatureSet.featureSet[i]; + } + + // logical-AND with slave's feature set to indicate which of the + // controller features in the master the slave requests to be + // used + // Note: For now, there is only one feature that is supported + // controller-to-controller. + // Note: If the peer supports the feature, then our setting is + // the controller-to-controller setting, so no action + // is required. + if ( !(peerFeatureSet[0] & LL_FEATURE_ENCRYPTION) ) + { + // this feature is not supported by the peer, so it doesn't + // matter if we support it or not, it should not be supported + connPtr->featureSetInfo.featureSet[0] &= ~LL_FEATURE_ENCRYPTION; + } + } + + // set flag to indicate the response has been received + connPtr->featureSetInfo.featureRspRcved = TRUE; + break; + + // Version Information Indication + case LL_CTRL_VERSION_IND: + + // check if the peer's version information has already been obtained + if ( connPtr->verExchange.peerInfoValid == TRUE ) + { + // it has, so something is wrong as the spec indicates that + // only one version indication should be sent for a connection + // unknown data PDU control packet received so save the type + connPtr->unknownCtrlType = opcode; + // schedule the output of the control packet + llEnqueueCtrlPkt( connPtr, LL_CTRL_UNKNOWN_RSP ); + } + else // the peer version info is invalid, so make it valid + { + // get the peer's version information and save it + //PHY_READ_BYTE( (uint8 *)&peerInfo.verInfo.verNum, 1 ); + connPtr->verInfo.verNum = *pBuf++; + //PHY_READ_BYTE( (uint8 *)&peerInfo.verInfo.comId, 2 ); + pBuf = llMemCopySrc( (uint8*)&connPtr->verInfo.comId, pBuf, 2 ); + //PHY_READ_BYTE( (uint8 *)&peerInfo.verInfo.subverNum, 2 ); + pBuf = llMemCopySrc( (uint8*)&connPtr->verInfo.subverNum, pBuf, 2 ); + // set a flag to indicate it is now valid + connPtr->verExchange.peerInfoValid = TRUE; + + // check if a version indication has been sent + if ( connPtr->verExchange.verInfoSent == FALSE ) + { + // no, so this is a peer's request for our version information + llEnqueueCtrlPkt( connPtr, LL_CTRL_VERSION_IND ); + } + } + + break; + + // Terminate Indication + case LL_CTRL_TERMINATE_IND: + // read the reason code + connPtr->termInfo.reason = *pBuf; + // set flag to indicate a termination indication was received + connPtr->termInfo.termIndRcvd = TRUE; + // received a terminate from peer host, so terminate after + // confirming we have sent an ACK + // Note: For the master, we have to ensure that this control + // packet was ACK'ed. For that, the nR has a new flag that + // is set when the control packet is received, and cleared + // when the control packet received is ACK'ed. + // Note: This is not an issue as a slave because the terminate + // packet will re-transmit until the slave ACK's. + // ALT: COULD REPLACE THIS CONTROL PROCEDURE AT THE HEAD OF THE + // QUEUE SO TERMINATE CAN TAKE PLACE ASAP. + //llReplaceCtrlPkt( connPtr, LL_CTRL_TERMINATE_RX_WAIT_FOR_TX_ACK ); + llEnqueueCtrlPkt( connPtr, LL_CTRL_TERMINATE_RX_WAIT_FOR_TX_ACK ); + break; + + // LL PDU Data Length Req + case LL_CTRL_LENGTH_REQ: + + // check if the feature response procedure has already been performed + // on this connection + if ( connPtr->featureSetInfo.featureRspRcved == FALSE ) + { + // it hasn't so re-load this device's local Feature Set to the + // connection as it may have been changed by the Host with HCI + // extenstion Set Local Feature Set command + for (i=0; ifeatureSetInfo.featureSet[i] = deviceFeatureSet.featureSet[i]; + } + } + + // check if supported DLE + if ( (connPtr->featureSetInfo.featureSet[0] & LL_FEATURE_DATA_LENGTH_EXTENSION) + != LL_FEATURE_DATA_LENGTH_EXTENSION ) + { + // unknown data PDU control packet received so save the type + connPtr->unknownCtrlType = opcode; + // schedule the output of the control packet + llEnqueueCtrlPkt( connPtr, LL_CTRL_UNKNOWN_RSP ); + } + else + { + if(connPtr->llPduLen.isProcessingReq==FALSE) + { + pBuf = llMemCopySrc( (uint8*)& (connPtr->llPduLen.remote.MaxRxOctets), pBuf, 2 ); + pBuf = llMemCopySrc( (uint8*)& (connPtr->llPduLen.remote.MaxRxTime), pBuf, 2 ); + pBuf = llMemCopySrc( (uint8*)& (connPtr->llPduLen.remote.MaxTxOctets), pBuf, 2 ); + pBuf = llMemCopySrc( (uint8*)& (connPtr->llPduLen.remote.MaxTxTime), pBuf, 2 ); + connPtr->llPduLen.isProcessingReq=TRUE; + llEnqueueCtrlPkt( connPtr, LL_CTRL_LENGTH_RSP ); + } + } + + break; + + // LL PDU Data Length RSP + case LL_CTRL_LENGTH_RSP: + + // check if supported DLE + if ( (connPtr->featureSetInfo.featureSet[0] & LL_FEATURE_DATA_LENGTH_EXTENSION) + != LL_FEATURE_DATA_LENGTH_EXTENSION ) + { + // unknown data PDU control packet received so save the type + connPtr->unknownCtrlType = opcode; + // schedule the output of the control packet + llEnqueueCtrlPkt( connPtr, LL_CTRL_UNKNOWN_RSP ); + } + else + { + if(connPtr->llPduLen.isWatingRsp==TRUE ) + { + pBuf = llMemCopySrc( (uint8*)& (connPtr->llPduLen.remote.MaxRxOctets), pBuf, 2 ); + pBuf = llMemCopySrc( (uint8*)& (connPtr->llPduLen.remote.MaxRxTime), pBuf, 2 ); + pBuf = llMemCopySrc( (uint8*)& (connPtr->llPduLen.remote.MaxTxOctets), pBuf, 2 ); + pBuf = llMemCopySrc( (uint8*)& (connPtr->llPduLen.remote.MaxTxTime), pBuf, 2 ); + llPduLengthUpdate((uint16)connPtr->connId); + connPtr->llPduLen.isWatingRsp=FALSE; + } + } + + break; + + // LL PHY UPDATE REQ + case LL_CTRL_PHY_REQ: + + // check if the feature response procedure has already been performed + // on this connection + if ( connPtr->featureSetInfo.featureRspRcved == FALSE ) + { + // it hasn't so re-load this device's local Feature Set to the + // connection as it may have been changed by the Host with HCI + // extenstion Set Local Feature Set command + for (i=0; ifeatureSetInfo.featureSet[i] = deviceFeatureSet.featureSet[i]; + } + } + + // check if supported PHY MODE UPDATE + if ( (connPtr->featureSetInfo.featureSet[1] & LL_FEATURE_2M_PHY) != LL_FEATURE_2M_PHY + && (connPtr->featureSetInfo.featureSet[1] & LL_FEATURE_CODED_PHY) != LL_FEATURE_CODED_PHY) + { + // unknown data PDU control packet received so save the type + connPtr->unknownCtrlType = opcode; + // schedule the output of the control packet + llEnqueueCtrlPkt( connPtr, LL_CTRL_UNKNOWN_RSP ); + } + else + { + //process for the protocol collision + //2018-11-10 by ZQ + if(connPtr->llPhyModeCtrl.isWatingRsp==TRUE || + connPtr->pendingChanUpdate==TRUE || + connPtr->pendingParamUpdate==TRUE ) + { + connPtr->isCollision=TRUE; + connPtr->rejectOpCode = LL_CTRL_PHY_REQ; + // schedule the output of the control packet + llEnqueueCtrlPkt( connPtr, LL_CTRL_REJECT_EXT_IND ); + } + else + { + if(connPtr->llPhyModeCtrl.isProcessingReq==FALSE) + { + connPtr->llPhyModeCtrl.req.txPhy=*pBuf++; + connPtr->llPhyModeCtrl.req.rxPhy=*pBuf++; + connPtr->llPhyModeCtrl.req.allPhy=connPtr->llPhyModeCtrl.def.allPhy; + connPtr->llPhyModeCtrl.rsp.txPhy=connPtr->llPhyModeCtrl.def.txPhy; + connPtr->llPhyModeCtrl.rsp.rxPhy=connPtr->llPhyModeCtrl.def.rxPhy; + //rsp and req will be used to determine the next phy mode + LL_PhyUpdate((uint16) connPtr->connId); + connPtr->llPhyModeCtrl.isProcessingReq=TRUE; + } + else + { + //should no be here + } + } + } + + break; + + // LL_CTRL_PHY_RSP + case LL_CTRL_PHY_RSP: + + // check if supported PHY MODE UPDATE + if ( (connPtr->featureSetInfo.featureSet[1] & LL_FEATURE_2M_PHY) != LL_FEATURE_2M_PHY + && (connPtr->featureSetInfo.featureSet[1] & LL_FEATURE_CODED_PHY) != LL_FEATURE_CODED_PHY) + { + // unknown data PDU control packet received so save the type + connPtr->unknownCtrlType = opcode; + // schedule the output of the control packet + llEnqueueCtrlPkt( connPtr, LL_CTRL_UNKNOWN_RSP ); + } + else + { + if(connPtr->llPhyModeCtrl.isWatingRsp==TRUE) + { + connPtr->llPhyModeCtrl.rsp.txPhy=*pBuf++; + connPtr->llPhyModeCtrl.rsp.rxPhy=*pBuf++; + LL_PhyUpdate((uint16) connPtr->connId); + connPtr->llPhyModeCtrl.isWatingRsp=FALSE; + } + else + { + //should no be here + } + } + + break; + + case LL_CTRL_CTE_REQ: + + // check if the feature response procedure has already been performed + // on this connection + if ( connPtr->featureSetInfo.featureRspRcved == FALSE ) + { + // it hasn't so re-load this device's local Feature Set to the + // connection as it may have been changed by the Host with HCI + // extenstion Set Local Feature Set command + for (i=0; ifeatureSetInfo.featureSet[i] = deviceFeatureSet.featureSet[i]; + } + } + + // check if supported CTE Response Feature + // if( connPtr->featureSetInfo.featureSet[LL_CTE_FEATURE_IDX] & LL_CONN_CTE_RSP) + if(( ( connPtr->featureSetInfo.featureSet[LL_CTE_FEATURE_IDX] & LL_CONN_CTE_RSP) != LL_CONN_CTE_RSP) || \ + ( connPtr->llCTE_RspFlag != TRUE )) + { + // unknown data PDU control packet received so save the type + connPtr->unknownCtrlType = opcode; + // schedule the output of the control packet + llEnqueueCtrlPkt( connPtr, LL_CTRL_UNKNOWN_RSP ); + } + else + { + // process for the protocol collision + // if other ctrl command procedure in processing , then reject + if(connPtr->llCTEModeCtrl.isWatingRsp==TRUE) + { + connPtr->isCollision=TRUE; + connPtr->rejectOpCode = LL_CTRL_CTE_REQ; + // schedule the output of the control packet + llEnqueueCtrlPkt( connPtr, LL_CTRL_REJECT_EXT_IND ); + } + else + { + if(connPtr->llCTEModeCtrl.isProcessingReq==FALSE) + { + uint8 CTE_tmp; + CTE_tmp = *pBuf++; + connPtr->llConnCTE.CTE_Length = CTE_tmp & 0x1F; + connPtr->llConnCTE.CTE_Type = CTE_tmp & 0xC0; + connPtr->llCTEModeCtrl.isProcessingReq=TRUE; + + if( ( connPtr->llConnCTE.enable ) && ( connPtr->llRfPhyPktFmt < LL_PHY_CODE )) + { + llEnqueueCtrlPkt( connPtr, LL_CTRL_CTE_RSP ); + } + else + { + if( connPtr->llRfPhyPktFmt >= LL_PHY_CODE ) + { + connPtr->llCTEModeCtrl.errorCode = LL_STATUS_ERROR_INVALID_LMP_LL_PARAMETER; + } + else + { + connPtr->llCTEModeCtrl.errorCode = LL_STATUS_ERROR_UNSUPPORT_LMP_LL_PARAMETER; + } + + connPtr->rejectOpCode = LL_CTRL_CTE_REQ; + // schedule the output of the control packet + llEnqueueCtrlPkt( connPtr, LL_CTRL_REJECT_EXT_IND ); + } + } + } + } + + break; + + case LL_CTRL_CTE_RSP: + if( connPtr->llCTEModeCtrl.isWatingRsp == TRUE ) + { + if( ( g_pLLcteISample != NULL ) && ( g_pLLcteQSample != NULL) ) + iqCnt = ll_hw_get_iq_RawSample( g_pLLcteISample, g_pLLcteQSample ); + + if( iqCnt > 0) + { + LL_ConnectionIQReportCback( connPtr->connId, + connPtr->llRfPhyPktFmt, + connPtr->currentChan, + connPtr->lastRssi, + // before CTE Transmit and sampling , no Antenna change , default 0 + 0, + connPtr->llConnCTE.CTE_Type, + connPtr->llConnCTE.slot_Duration, + // Packet_Status=0, CRC success,cause only CRC Correctly that can run here + 0, + connPtr->currentEvent, + iqCnt, + g_pLLcteISample, + g_pLLcteQSample); + } + else + { + // packet contain LL_CTE_RSP , but did not contain CTE field + // status = 0x0 : LL_CTE_RSP received successful , but without a CTE field + LL_CTE_Report_FailedCback( 0x0,connPtr->connId); + } + + connPtr->llCTEModeCtrl.isWatingRsp = FALSE; + } + + break; + + // Peer Device Received an Unknown Control Type + case LL_CTRL_UNKNOWN_RSP: + + // Note: There doesn't appear to be any action for this message, + // other than to ACK it. + if(connPtr->llPduLen.isWatingRsp) + { + llPduLengthUpdate((uint16)connPtr->connId); + connPtr->llPduLen.isWatingRsp=FALSE;//not support DLE + } + + if(connPtr->llPhyModeCtrl.isWatingRsp) + { + llPhyModeCtrlUpdateNotify(connPtr,LL_STATUS_ERROR_UNSUPPORTED_REMOTE_FEATURE); + connPtr->llPhyModeCtrl.isWatingRsp=FALSE;//not support PHY_UPDATE + } + + // 2020-01-23 add for CTE + if( connPtr->llCTEModeCtrl.isWatingRsp ) + { + connPtr->llCTEModeCtrl.isWatingRsp = FALSE; + } + + break; + + case LL_REJECT_IND: + case LL_REJECT_IND_EXT: + connPtr->rejectOpCode = *pBuf++; + uint8 errorcode = *pBuf++; + + if(connPtr->rejectOpCode == LL_CTRL_ENC_REQ) + { + // either the slave's Host has failed to provide an LTK, or + // the encryption feature is not supported by the slave, so read + // the rejection indication error code + //connPtr->encInfo.encRejectErrCode = PHY_READ_BYTE_VAL(); + connPtr->encInfo.encRejectErrCode = connPtr->rejectOpCode; + // and end the start encryption procedure + connPtr->encInfo.rejectIndRcved = TRUE; + LL_EncChangeCback( connPtr->connId, + errorcode, + LL_ENCRYPTION_OFF ); + } + else + { + //TBD + } + + //connPtr->isCollision=FALSE; + break; + + // Our Device Received an Unknown Control Type + default: + // unknown data PDU control packet received so save the type + connPtr->unknownCtrlType = opcode; + // schedule the output of the control packet + llEnqueueCtrlPkt( connPtr, LL_CTRL_UNKNOWN_RSP ); + break; + } + + return; +} +#endif + +static uint32 read_LL_remainder_time1(void) +{ + uint32 currentCount; + uint32 g_tim1_pass = read_current_fine_time(); + currentCount = AP_TIM1->CurrentCount; + + //if((currentCount < 6) || NVIC_GetPendingIRQ(TIM1_IRQn)) + // return 0; + //else + return (currentCount >> 2); +} + +uint8 llSecAdvAllow1(void) +{ + uint32 advTime, margin; + uint32 remainTime; + uint8 ret = FALSE; + // Hold off interrupts. + _HAL_CS_ALLOC_(); + HAL_ENTER_CRITICAL_SECTION(); + // read global config to get advTime and margin + advTime = pGlobal_config[LL_NOCONN_ADV_EST_TIME]; + margin = pGlobal_config[LL_NOCONN_ADV_MARGIN]; + // remain time before trigger LL HW + remainTime = read_LL_remainder_time1(); + + if ((remainTime > advTime + margin) + && !llWaitingIrq) + ret = TRUE; + else + { + llSecondaryState = LL_SEC_STATE_ADV_PENDING; + g_pmCounters.ll_conn_adv_pending_cnt ++; + } + + HAL_EXIT_CRITICAL_SECTION(); + return ret; +} + +uint32 llCalcMaxScanTime1(void) +{ + uint32 margin, scanTime; + uint32 remainTime; + margin = pGlobal_config[LL_SEC_SCAN_MARGIN]; + // Hold off interrupts. + _HAL_CS_ALLOC_(); + HAL_ENTER_CRITICAL_SECTION(); + // remain time before trigger LL HW + remainTime = read_LL_remainder_time1(); + scanTime = 0; + + if (remainTime > margin + pGlobal_config[LL_MIN_SCAN_TIME] + && !llWaitingIrq) + scanTime = remainTime - margin; + + HAL_EXIT_CRITICAL_SECTION(); + return (scanTime); +} + + + +llStatus_t LL_StartEncrypt1( uint16 connId, + uint8* rand, + uint8* eDiv, + uint8* ltk ) +{ + uint8 i; + llStatus_t status; + llConnState_t* connPtr; + + // make sure we're in Master role +// if ( llState != LL_STATE_CONN_MASTER ) +// { +// return( LL_STATUS_ERROR_COMMAND_DISALLOWED ); +// } + + // check parameters + if ( (rand == NULL) || (eDiv == NULL) || (ltk == NULL) ) + { + return( LL_STATUS_ERROR_BAD_PARAMETER ); + } + + // make sure connection ID is valid + if ( (status=LL_ConnActive(connId)) != LL_STATUS_SUCCESS ) + { + return( status ); + } + + // get connection info + connPtr = &conn_param[connId]; + + // check if a feature response control procedure has taken place + if ( connPtr->featureSetInfo.featureRspRcved == FALSE ) + { + // it hasn't so re-load this device's local Feature Set to the + // connection as it may have been changed by the Host with HCI + // extenstion Set Local Feature Set command + for (i=0; ifeatureSetInfo.featureSet[i] = deviceFeatureSet.featureSet[i]; + } + } + + // check if encryption is a supported feature set item + if ( (connPtr->featureSetInfo.featureSet[0] & LL_FEATURE_ENCRYPTION) != LL_FEATURE_ENCRYPTION ) + { + return( LL_STATUS_ERROR_FEATURE_NOT_SUPPORTED ); + } + + // cache the master's random vector + // Note: The RAND will be left in LSO..MSO order as this is assumed to be the + // order of the bytes that will be returned to the Host. + for (i=0; iencInfo.RAND[i] = rand[i]; + } + + // cache the master's encryption diversifier + // Note: The EDIV will be left in LSO..MSO order as this is assumed to be the + // order of the bytes that will be returned to the Host. + connPtr->encInfo.EDIV[0] = eDiv[0]; + connPtr->encInfo.EDIV[1] = eDiv[1]; + + // cache the master's long term key + // Note: The order of the bytes will be maintained as MSO..LSO + // per FIPS 197 (AES). + for (i=0; iencInfo.LTK[(LL_ENC_LTK_LEN-i)-1] = ltk[i]; + } + + // generate SKDm + // Note: The SKDm LSO is the LSO of the SKD. + // Note: Placement of result forms concatenation of SKDm and SKDs. + // Note: The order of the bytes will be maintained as MSO..LSO + // per FIPS 197 (AES). + LL_ENC_GenDeviceSKD( &connPtr->encInfo.SKD[ LL_ENC_SKD_M_OFFSET ] ); + // generate IVm + // Note: The IVm LSO is the LSO of the IV. + // Note: Placement of result forms concatenation of IVm and IVs. + // Note: The order of the bytes will be maintained as MSO..LSO + // per FIPS 197 (AES). + LL_ENC_GenDeviceIV( &connPtr->encInfo.IV[ LL_ENC_IV_M_OFFSET ] ); + // schedule a cache update of FIPS TRNG values for next SKD/IV usage + // postRfOperations |= LL_POST_RADIO_CACHE_RANDOM_NUM; + (void)LL_ENC_GenerateTrueRandNum( cachedTRNGdata, LL_ENC_TRUE_RAND_BUF_SIZE ); + // set flag to stop all outgoing transmissions + connPtr->txDataEnabled = FALSE; + // invalidate the existing session key, if any + connPtr->encInfo.SKValid = FALSE; + // indicate the LTK is not valid + connPtr->encInfo.LTKValid = FALSE; + + // check if we are already in encryption mode + if ( connPtr->encEnabled == TRUE ) + { + // set a flag to indicate this is a restart (i.e. pause-then-start) + connPtr->encInfo.encRestart = TRUE; + // setup a pause encryption control procedure + llEnqueueCtrlPkt( connPtr, LL_CTRL_PAUSE_ENC_REQ ); + } + else // no, so... + { + // clear flag to indicate this is an encryption setup + connPtr->encInfo.encRestart = FALSE; + // setup an encryption control procedure + llEnqueueCtrlPkt( connPtr, LL_CTRL_ENC_REQ ); + } + + return( LL_STATUS_SUCCESS ); +} + +void TIM1_IRQHandler1(void) +{; +// if(gpio_read( P18)){ +// gpio_write(P34,1); +// } +// HAL_ENTER_CRITICAL_SECTION() +// gpio_write(P25,1); +// gpio_write(P25,0); + + + if(AP_TIM1->status&0x1) + { + clear_timer_int(AP_TIM1); + clear_timer(AP_TIM1); + LL_evt_schedule(); + } +// HAL_EXIT_CRITICAL_SECTION(); +} + +void TIM3_IRQHandler1(void) +{ +// HAL_ENTER_CRITICAL_SECTION(); + if(AP_TIM3->status&0x1) + { + clear_timer_int(AP_TIM3); + //clear_timer(AP_TIM1); + } +// gpio_write(P20,1); +// gpio_write(P20,0); + +// HAL_EXIT_CRITICAL_SECTION(); +} + +uint8 osal_set_event1( uint8 task_id, uint16 event_flag ) +{ + uint16 *events; + uint8 task_cnt = *(uint8 *)JUMP_FUNCTION(TASK_COUNT); + _HAL_CS_ALLOC_(); + if ( task_id < task_cnt)//tasksCnt ) + { + HAL_ENTER_CRITICAL_SECTION(); // Hold off interrupts + events = *(uint16 **)(JUMP_FUNCTION(TASK_EVENTS)); + if (events != NULL) + events[task_id] |= event_flag; + //tasksEvents[task_id] |= event_flag; // Stuff the event bit(s) + HAL_EXIT_CRITICAL_SECTION(); // Release interrupts + osal_run_system(); + return ( SUCCESS ); + } + else + { + HAL_EXIT_CRITICAL_SECTION(); // Release interrupts + return ( INVALID_TASK ); + } +} + +void llSlaveEvt_TaskEndOk1( void ) +{ + llConnState_t *connPtr; + + uint32_t next_time; + uint32 sw_delay, T2; + int calibra_time, i; // this parameter will be calibrate provided by global_config + + // check if the connection is still valid + if (FALSE == conn_param[g_ll_conn_ctx.currentConn].active) + { + // connection may have already been ended by a reset + // HZF: if other procedure terminate the link, it should schedule the next event + return; + } + + // get connection information + connPtr = &conn_param[g_ll_conn_ctx.currentConn]; + + // advance the connection event count + connPtr->currentEvent = connPtr->nextEvent; + + // check if any data has been received + // Note: numRxOk includes numRxCtrl + // Note: numRxNotOk removed as 4.5.2 of spec says the LSTO is reset upon + // receipt of a "valid packet", which is taken to mean no CRC error. + if ( rfCounters.numRxOk || rfCounters.numRxIgnored || // we have only "numRxOk" + rfCounters.numRxEmpty || rfCounters.numRxFifoFull + || connPtr->rx_crcok != 0) // ever Rx CRC OK packet + { + // yes, so update the supervision expiration count + connPtr->expirationEvent = connPtr->currentEvent + connPtr->expirationValue; + + // clear flag that indicates we received first packet + // Note: The first packet only really needs to be signalled when a new + // connection is formed or a connection's parameters are updated. + // However, there's no harm in resetting it every time in order to + // simplify the control logic. + // Note: True-Low logic is used here to be consistent with nR's language. + connPtr->firstPacket = 0; + + // slave latency may have been disabled because a packet from the master + // was not received (see Core spec V4.0, Vol 6, Section 4.5.1), so restore + // the slave latency value; but note that if this is the beginning of a + // connection, you can not allow slave latency until the first NESN change + // has occurred from the master (i.e. until master ACK's slave) + if ( connPtr->slaveLatencyAllowed == TRUE ) + { + // activate slave latency + connPtr->slaveLatency = connPtr->slaveLatencyValue; + } + + //receiver ack notifty the host + if(connPtr->llPhyModeCtrl.isChanged==TRUE) + { + connPtr->llPhyModeCtrl.isChanged = FALSE; + llPhyModeCtrlUpdateNotify(connPtr,LL_STATUS_SUCCESS); + } + + } + else // either no packets received, or packets received with CRC error + { + // check if we received any packets with a CRC error + // Note: Spec change (section 4.5.5) indicates any packet received, + // regardless of CRC result, determines the anchor point. + if (connPtr->rx_timeout) // no packet was received from the master + { + // collect packet error information + connPtr->perInfo.numMissedEvts++; + + // so listen to every event until a packet is received + connPtr->slaveLatency = 0; + } + else // ( rfCounters.numRxNotOk ) // different to TI sequence + { + // clear flag that indicates we received first packet + // Note: The first packet only really needs to be signalled when a new + // connection is formed or a connection's parameters are updated. + // However, there's no harm in resetting it every time in order to + // simplify the control logic. + // Note: True-Low logic is used here to be consistent with nR's language. + connPtr->firstPacket = 0; + + // slave latency may have been disabled because a packet from the master + // was not received (see Core spec V4.0, Vol 6, Section 4.5.1), so restore + // the slave latency value; but note that if this is the beginning of a + // connection, you can not allow slave latency until the first NESN change + // has occurred from the master (i.e. until master ACK's slave) + if ( connPtr->slaveLatencyAllowed == TRUE ) + { + // activate slave latency + connPtr->slaveLatency = connPtr->slaveLatencyValue; + } + } + + // check if we have a Supervision Timeout + if ( connPtr->expirationEvent == connPtr->currentEvent ) + { + // check if either we already got the first packet in a connection or + // if this isn't the quick LSTO associated with connection establishment + // Note: The Slave reuses firstPacket when a Update Parameter control + // procedure is started, but in that case, the expiration event + // will be well past the event associated with connection + // establishement. + if ( (connPtr->firstPacket == 0) || + (connPtr->currentEvent != LL_LINK_SETUP_TIMEOUT) ) + { + // yes, so terminate with LSTO + llConnTerminate( connPtr, LL_SUPERVISION_TIMEOUT_TERM ); + g_pmCounters.ll_link_lost_cnt ++; + } + else // this is a failure to establish the connection + { + // so terminate immediately with failure to establish connection + llConnTerminate( connPtr, LL_CONN_ESTABLISHMENT_FAILED_TERM ); + g_pmCounters.ll_link_estab_fail_cnt ++; + } +//#ifdef MULTI_ROLE + ll_scheduler(LL_INVALID_TIME); +//#endif + return; + + } + } + + // for a new connection, slave latency isn't enabled until the master's NESN + // bit changes, which is equivalent to receiving a TX ACK; if this is an + // update parameters, slave latency is also disabled until any first packet arrives, + // however, to keep things simple for now, we will use the same ACK constraint + if (rfCounters.numTxAck > 0)//connPtr->firstPacket == 0) /// TODO: test the scenario + { + // set a flag to indicates it is now okay to use slave latency on this + // connection, if specified + // Note: This is now needed due to a change in spec (section 4.5.1) which + // requires that slave latency be disabled when a packet is not + // received from the master. Since this routine is common for END_OK + // and RX_TIMEOUT, there's no way to know if the first Master NESN + // bit change has taken place. This flag will indicate it has, so if + // a master packet is received, the slave latency value can be + // restored. + if (pGlobal_config[LL_SWITCH] & SLAVE_LATENCY_ALLOW) + connPtr->slaveLatencyAllowed = TRUE; + + // only update slave latency if no control procedure is active + // Note: When a control procedure is active, slave latency has to be + // disabled in case it exceeds the control procedure timeout. + // Note: Even when a control procedure is active, but a control transaction + // timeout isn't used, we can still skip setting SL since that kind + // of control procedure wouldn't have disabled slave latency to begin + // with. + // ALT: COULD RESET SL IN llProcessSlaveControlProcedures. + if ( (connPtr->ctrlPktInfo.ctrlPktActive == FALSE) && + (connPtr->pendingParamUpdate == FALSE) && + (connPtr->pendingChanUpdate == FALSE) && + (connPtr->pendingPhyModeUpdate == FALSE) ) + { + // at least one ACK, so Slave Latency is operational + // Note: This really only happens once for the very first connection + // interval, and when an update parameters procedure is taking place. + connPtr->slaveLatency = connPtr->slaveLatencyValue; + } + } + + // check if the nR performed a anchor point capture + // Note: This bit is cleared at the start of a new task. + // Note: The anchor capture will occur even if the RX FIFO was too full to + // accept the packet. +// if (connPtr->connected == 0)//rx_timeout ==1 ) // update by HZF 05-03, if not connected, disable slave latency + if (connPtr->firstPacket) // update by HZF 12-18, if not receive 1st packet(CRC OK or not), disable slave latency + { + connPtr->slaveLatency = 0; + } + + + /* + ** Process RX Data Packets + */ + uint8_t buffer_size; + buffer_size = getRxBufferSize(connPtr); + if (buffer_size > 0) // 2018-10-22, disable slave latency if receives some data/ctrl packet + connPtr->slaveLatencyAllowed = FALSE; + for ( i = 0; i < buffer_size; i ++) // note: i < getRxBufferSize() will fail the loop + { + // there is, so process it; check if data was processed + if ( llProcessRxData() == FALSE ) + { + // it wasn't, so we're done + break; + } + } + + // check if this connection was terminated + // HZF: when llProcessRxData(), the link may be terminated + if ( !connPtr->active ) + { +//#ifdef MULTI_ROLE + ll_scheduler(LL_INVALID_TIME); +//#endif + return; + } + + /* + ** Check Control Procedure Processing + */ + if ( llProcessSlaveControlProcedures( connPtr ) == LL_CTRL_PROC_STATUS_TERMINATE ) + { +//#ifdef MULTI_ROLE + ll_scheduler(LL_INVALID_TIME); +//#endif + + return; + } + + /* + ** Process TX Data Packets + */ + + // copy any pending data to the TX FIFO + llProcessTxData( connPtr, LL_TX_DATA_CONTEXT_POST_PROCESSING ); + + // if any fragment l2cap pkt, copy to TX FIFO + l2capPocessFragmentTxData((uint16)connPtr->connId); + + if (connPtr->rx_timeout) + connPtr->accuTimerDrift += connPtr->timerDrift; + else + connPtr->accuTimerDrift = 0; + + /* + ** Setup Next Slave Event Timing + */ + + // update next event, calculate time to next event, calculate timer drift, + // update anchor points, setup NR T2E1 and T2E2 events + if ( llSetupNextSlaveEvent() == LL_SETUP_NEXT_LINK_STATUS_TERMINATE ) + { +//#ifdef MULTI_ROLE + ll_scheduler(LL_INVALID_TIME); +//#endif + return; + } + + // schedule next connection event + // calculate the timer drift due to slave latency +// llCalcTimerDrift(conn_param[connId].curParam.connInterval, +// conn_param [connId].slaveLatency, +// conn_param [connId].scaFactor, +// (uint32 *)&conn_param [connId].timerDrift); // + + // calibrate time: + // 100 for SW process, 100 for timing advance, 60 for hw engine startup + calibra_time = 100 + 100 + 60 ; + // calculate the delay + T2 = read_current_fine_time(); + + sw_delay = (T2 > ISR_entry_time) ? (T2 - ISR_entry_time) : (BASE_TIME_UNITS - ISR_entry_time + T2); + + // schedule next connection event time + // ------> -----> (Interrupt trigger) ------> + // note that slaveLatency should be 0,i.e. no latency if there are data to send in slave + // should not use conn_param[connId].curParam.connInterval, lastTimeToNextEvt also cover conn parameter update case + next_time = connPtr->lastTimeToNextEvt * (connPtr->lastSlaveLatency + 1) * 625; + + // rx -> anchor: 110us + //next_time = next_time - slave_conn_event_recv_delay - sw_delay - 110 - calibra_time - conn_param[connId].timerDrift ; + + //used to adj next time for multi-link + ll_adptive_adj_next_time(next_time); + + int32_t adj_time = slave_conn_event_recv_delay + sw_delay + 110 + calibra_time + connPtr->timerDrift; + uint32 aaaa = next_time; + next_time = (next_time > adj_time || adj_time < 0) ? (next_time - adj_time) : 200; + +//#ifdef MULTI_ROLE +// DBG_GPIO_WRITE(DBGIO_LL_IRQ,0); + ll_scheduler(next_time); +// DBG_GPIO_WRITE(DBGIO_LL_IRQ,1); +// logx("n-%d-%d-%d\n",next_time,aaaa,adj_time); + logx("%d\n",next_time); + +//#else +// ll_schedule_next_event(next_time); +//#endif + + return; +} + + +// global configuration in SRAM, it could be change by application +// TODO: when integrate, the global_config should be set by APP project +uint32_t g_MAC_ADDRESS_LOC[2] = {0x55aa1234, 0x5c5c5c5c}; +__ATTR_SECTION_XIP__ void init_config(void) +{ + pGlobal_config = (uint32*)(CONFIG_BASE_ADDR); + int i; + + for (i = 0; i < 256; i ++) + pGlobal_config[i] = 0; + + //save the app initial_sp which will be used in wakeupProcess 20180706 by ZQ + pGlobal_config[INITIAL_STACK_PTR] = 0;//(uint32_t)&__initial_sp; + // LL switch setting + pGlobal_config[LL_SWITCH] = LL_DEBUG_ALLOW | SLAVE_LATENCY_ALLOW | LL_WHITELIST_ALLOW + | SIMUL_CONN_ADV_ALLOW | SIMUL_CONN_SCAN_ALLOW; //RC32_TRACKINK_ALLOW + + if(g_clk32K_config==CLK_32K_XTAL) + pGlobal_config[LL_SWITCH] &= 0xffffffee; + else + pGlobal_config[LL_SWITCH] |= RC32_TRACKINK_ALLOW | LL_RC32K_SEL; + + // sleep delay + pGlobal_config[MIN_TIME_TO_STABLE_32KHZ_XOSC] = 10; // 10ms, temporary set + // system clock setting + pGlobal_config[CLOCK_SETTING] = g_system_clk;//CLOCK_32MHZ; + //------------------------------------------------------------------------ + // wakeup time cose + // t1. HW_Wakeup->MCU relase 62.5us + // t2. wakeup_process in waitRTCCounter 30.5us*[WAKEUP_DELAY] about 500us + // t3. dll_en -> hclk_sel in hal_system_ini 100us in run as RC32M + // t4. sw prepare cal sleep tick initial rf_ini about 300us @16M this part depends on HCLK + // WAKEUP_ADVANCE should be larger than t1+t2+t3+t4 + //------------------------------------------------------------------------ + // wakeup advance time, in us + pGlobal_config[WAKEUP_ADVANCE] = 1350;//650;//600;//310; + + if(g_system_clk==SYS_CLK_XTAL_16M) + { + pGlobal_config[WAKEUP_DELAY] = 16; + } + else if(g_system_clk==SYS_CLK_DLL_48M) + { + pGlobal_config[WAKEUP_DELAY] = 16; + } + else if(g_system_clk==SYS_CLK_DLL_64M) + { + pGlobal_config[WAKEUP_DELAY] = 16; + } + + // sleep time, in us + pGlobal_config[MAX_SLEEP_TIME] = 30000000; + pGlobal_config[MIN_SLEEP_TIME] = 1600; + pGlobal_config[ALLOW_TO_SLEEP_TICK_RC32K] = 55;// 30.5 per tick + //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // LL engine settle time + pGlobal_config[LL_HW_BB_DELAY] = 54;//54-8; + pGlobal_config[LL_HW_AFE_DELAY] = 8; + pGlobal_config[LL_HW_PLL_DELAY] = 40;//45;//52; + // Tx2Rx and Rx2Tx interval + //Tx2Rx could be advanced a little + //Rx2Tx should be ensure T_IFS within150us+-2us + pGlobal_config[LL_HW_Rx_TO_TX_INTV] = 62-RF_PHY_EXT_PREAMBLE_US; + pGlobal_config[LL_HW_Tx_TO_RX_INTV] = 50;//65 + //------------------------------------------------2MPHY + // LL engine settle time + pGlobal_config[LL_HW_BB_DELAY_2MPHY] = 59; + pGlobal_config[LL_HW_AFE_DELAY_2MPHY] = 8; + pGlobal_config[LL_HW_PLL_DELAY_2MPHY] = 40;//45;//52; + // Tx2Rx and Rx2Tx interval + //Tx2Rx could be advanced a little + //Rx2Tx should be ensure T_IFS within150us+-2us + pGlobal_config[LL_HW_Rx_TO_TX_INTV_2MPHY] = 77-RF_PHY_EXT_PREAMBLE_US;//20200822 ZQ + pGlobal_config[LL_HW_Tx_TO_RX_INTV_2MPHY] = 57;//72 + //------------------------------------------------CODEPHY 500K + // LL engine settle time CODEPHY 500K + pGlobal_config[LL_HW_BB_DELAY_500KPHY] = 50;//54-8; + pGlobal_config[LL_HW_AFE_DELAY_500KPHY] = 8; + pGlobal_config[LL_HW_PLL_DELAY_500KPHY] = 40;//45;//52; + // Tx2Rx and Rx2Tx interval + //Tx2Rx could be advanced a little + //Rx2Tx should be ensure T_IFS within150us+-2us + pGlobal_config[LL_HW_Rx_TO_TX_INTV_500KPHY] = 2; + pGlobal_config[LL_HW_Tx_TO_RX_INTV_500KPHY] = 66;//72 + //------------------------------------------------CODEPHY 125K + // LL engine settle time CODEPHY 125K + pGlobal_config[LL_HW_BB_DELAY_125KPHY] = 30;//54-8; + pGlobal_config[LL_HW_AFE_DELAY_125KPHY] = 8; + pGlobal_config[LL_HW_PLL_DELAY_125KPHY] = 40;//45;//52; + // Tx2Rx and Rx2Tx interval + //Tx2Rx could be advanced a little + //Rx2Tx should be ensure T_IFS within150us+-2us + pGlobal_config[LL_HW_Rx_TO_TX_INTV_125KPHY] = 5; + pGlobal_config[LL_HW_Tx_TO_RX_INTV_125KPHY] = 66;//72 + // LL engine settle time, for advertisement + pGlobal_config[LL_HW_BB_DELAY_ADV] = 90; + pGlobal_config[LL_HW_AFE_DELAY_ADV] = 8; + pGlobal_config[LL_HW_PLL_DELAY_ADV] = 60; + // adv channel interval + pGlobal_config[ADV_CHANNEL_INTERVAL] = 1400;//6250; + pGlobal_config[NON_ADV_CHANNEL_INTERVAL] = 666;//6250; + + //20201207 Jie modify + if(g_system_clk==SYS_CLK_XTAL_16M) + { + // scan req -> scan rsp timing + pGlobal_config[SCAN_RSP_DELAY] = 13+RF_PHY_EXT_PREAMBLE_US;//23; + } + else if(g_system_clk==SYS_CLK_DLL_48M) + { + // scan req -> scan rsp timing + pGlobal_config[SCAN_RSP_DELAY] = 6 + RF_PHY_EXT_PREAMBLE_US + 6;//20201207 set //4; // 12 // 2019/3/19 A2: 12 --> 9 + } + else if(g_system_clk == SYS_CLK_DLL_64M) // 2019/3/26 add + { + pGlobal_config[SCAN_RSP_DELAY] = 4+RF_PHY_EXT_PREAMBLE_US;//2020.12.07 set //3; + } + + // conn_req -> slave connection event calibration time, will advance the receive window + pGlobal_config[CONN_REQ_TO_SLAVE_DELAY] = 300;//192;//500;//192; + // calibration time for 2 connection event, will advance the next conn event receive window + // SLAVE_CONN_DELAY for sync catch, SLAVE_CONN_DELAY_BEFORE_SYNC for sync not catch + //pGlobal_config[SLAVE_CONN_DELAY] = 300;//0;//1500;//0;//3000;//0; ---> update 11-20 + pGlobal_config[SLAVE_CONN_DELAY] = 1000;//0;//1500;//0;//3000;//0; ---> update 11-20 + pGlobal_config[SLAVE_CONN_DELAY_BEFORE_SYNC] = 500;//160 NG//500 OK //eagle + // RTLP timeout + pGlobal_config[LL_HW_RTLP_LOOP_TIMEOUT] = 50000; + pGlobal_config[LL_HW_RTLP_TO_GAP] = 1000; + //pGlobal_config[LL_HW_RTLP_1ST_TIMEOUT] = 2000 + pGlobal_config[SLAVE_CONN_DELAY] * 2;//500; +// pGlobal_config[LL_HW_RTLP_1ST_TIMEOUT] = 1000 + pGlobal_config[SLAVE_CONN_DELAY];//500;//eagle + pGlobal_config[LL_HW_RTLP_1ST_TIMEOUT] = 4500;//500;//eagle + + // direct adv interval configuration + pGlobal_config[HDC_DIRECT_ADV_INTERVAL] = 1000; + pGlobal_config[LDC_DIRECT_ADV_INTERVAL] = 6250; + // A1 ROM metal change for HDC direct adv, + pGlobal_config[DIR_ADV_DELAY] = 115; // in us, consider both direct adv broadcast time & SW delay, ... etc. + // A1 ROM metal change + pGlobal_config[LL_TX_PKTS_PER_CONN_EVT] = 6;//8; + pGlobal_config[LL_RX_PKTS_PER_CONN_EVT] = 6;//8; + pGlobal_config[LL_TRX_NUM_ADAPTIVE_CONFIG] = 8; //0: disable adaptive + //other: adaptive max limitation +// pGlobal_config[LL_TX_PWR_TO_REG_BIAS] = 0x15; // assume when g_rfPhyTxPower = 0x1f, tx power = 10dBm + //smart window configuration + pGlobal_config[LL_SMART_WINDOW_COEF_ALPHA] = 2; + pGlobal_config[LL_SMART_WINDOW_TARGET] = 600; + pGlobal_config[LL_SMART_WINDOW_INCREMENT] = 9; + pGlobal_config[LL_SMART_WINDOW_LIMIT] = 20000; + pGlobal_config[LL_SMART_WINDOW_ACTIVE_THD] = 8; + pGlobal_config[LL_SMART_WINDOW_ACTIVE_RANGE] = 0;//300 + pGlobal_config[LL_SMART_WINDOW_FIRST_WINDOW] = 5000; + g_smartWindowSize = pGlobal_config[LL_HW_RTLP_1ST_TIMEOUT] ; + + //====== A2 metal change add, for scanner & initiator + if(g_system_clk==SYS_CLK_XTAL_16M) + { + pGlobal_config[LL_ADV_TO_SCAN_REQ_DELAY] = 18+RF_PHY_EXT_PREAMBLE_US;//20; // 2019/3/19 A2: 20 --> 18 + pGlobal_config[LL_ADV_TO_CONN_REQ_DELAY] = 25+RF_PHY_EXT_PREAMBLE_US;//27; // 2019/3/19 A2: 27 --> 25 + } + else if(g_system_clk==SYS_CLK_DLL_48M) + { + pGlobal_config[LL_ADV_TO_SCAN_REQ_DELAY] = 8+RF_PHY_EXT_PREAMBLE_US;//12; // 2019/3/19 A2: 12 --> 10 + pGlobal_config[LL_ADV_TO_CONN_REQ_DELAY] = 11+RF_PHY_EXT_PREAMBLE_US; + } + else if(g_system_clk==SYS_CLK_DLL_64M) + { + pGlobal_config[LL_ADV_TO_SCAN_REQ_DELAY] = 6+RF_PHY_EXT_PREAMBLE_US; // 2019/3/26 add + pGlobal_config[LL_ADV_TO_CONN_REQ_DELAY] = 8+RF_PHY_EXT_PREAMBLE_US; + } + + // TRLP timeout + pGlobal_config[LL_HW_TRLP_LOOP_TIMEOUT] = 50000; // enough for 8Tx + 8Rx : (41 * 8 + 150) * 16 - 150 = 7498us + pGlobal_config[LL_HW_TRLP_TO_GAP] = 1000; + pGlobal_config[LL_MOVE_TO_MASTER_DELAY] = 100; + pGlobal_config[LL_CONN_REQ_WIN_SIZE] = 5; + pGlobal_config[LL_CONN_REQ_WIN_OFFSET] = 2; + pGlobal_config[LL_MASTER_PROCESS_TARGET] = 200; // reserve time for preparing master conn event, delay should be insert if needn't so long time + pGlobal_config[LL_MASTER_TIRQ_DELAY] = 0; // timer IRQ -> timer ISR delay + pGlobal_config[OSAL_SYS_TICK_WAKEUP_TRIM] = 56; // 0.125us + pGlobal_config[MAC_ADDRESS_LOC] = (uint32_t)(&g_MAC_ADDRESS_LOC[0]);//0x11004000; + // for simultaneous conn & adv/scan + pGlobal_config[LL_NOCONN_ADV_EST_TIME] = 1400*3; + pGlobal_config[LL_NOCONN_ADV_MARGIN] = 600; + pGlobal_config[LL_SEC_SCAN_MARGIN] = 2500;//1400; to avoid mesh proxy llTrigErr 0x15 + pGlobal_config[LL_MIN_SCAN_TIME] = 2000; + // BBB new + pGlobal_config[TIMER_ISR_ENTRY_TIME] = 30;//15; + pGlobal_config[LL_MULTICONN_MASTER_PREEMP] = 0; + pGlobal_config[LL_MULTICONN_SLAVE_PREEMP] = 0; + pGlobal_config[LL_EXT_ADV_TASK_DURATION] = 20000; + pGlobal_config[LL_PRD_ADV_TASK_DURATION] = 20000; + pGlobal_config[LL_CONN_TASK_DURATION] = 5000; + pGlobal_config[LL_EXT_ADV_INTER_PRI_CHN_INT] = 5000; + pGlobal_config[LL_EXT_ADV_INTER_SEC_CHN_INT] = 5000; + pGlobal_config[LL_EXT_ADV_PRI_2_SEC_CHN_INT] = 1500; + pGlobal_config[LL_EXT_ADV_RSC_PERIOD] = 1000000; + pGlobal_config[LL_EXT_ADV_RSC_SLOT_DURATION] = 10000; + pGlobal_config[LL_PRD_ADV_RSC_PERIOD] = 1000000; + pGlobal_config[LL_PRD_ADV_RSC_SLOT_DURATION] = 10000; + pGlobal_config[LL_EXT_ADV_PROCESS_TARGET] = 500; + pGlobal_config[LL_PRD_ADV_PROCESS_TARGET] = 500; + //------------------------------------------------------------------- + // patch function register + //-------------------------------------------------------------------- + JUMP_FUNCTION(LL_HW_GO) = (uint32_t)&ll_hw_go1; + //JUMP_FUNCTION(V4_IRQ_HANDLER) = (uint32_t)&LL_IRQHandler1; + JUMP_FUNCTION(OSAL_SET_EVENT) = (uint32_t)&osal_set_event1; + //JUMP_FUNCTION(V20_IRQ_HANDLER) = (uint32_t)&TIM1_IRQHandler1; + //JUMP_FUNCTION(V11_IRQ_HANDLER) = (uint32_t)&hal_UART0_IRQHandler; + extern void rf_calibrate1(void); + JUMP_FUNCTION(RF_CALIBRATTE) = (uint32_t)&rf_calibrate1; + JUMP_FUNCTION(RF_PHY_CHANGE) = (uint32_t)&rf_phy_change_cfg0; + //JUMP_FUNCTION(LL_GEN_TRUE_RANDOM) = (uint32_t)&LL_ENC_GenerateTrueRandNum1; + JUMP_FUNCTION(LL_AES128_ENCRYPT) = (uint32_t)&LL_ENC_AES128_Encrypt1; + JUMP_FUNCTION(LL_ENC_ENCRYPT) = (uint32_t)&LL_ENC_Encrypt1; + JUMP_FUNCTION(LL_ENC_DECRYPT) = (uint32_t)&LL_ENC_Decrypt1; + //JUMP_FUNCTION(LL_PROCESS_SLAVE_CTRL_PROC) = (uint32_t)&llProcessSlaveControlProcedures1; + //JUMP_FUNCTION(LL_PROCESS_TX_DATA) = (uint32_t)&llProcessTxData1; + //JUMP_FUNCTION(OSAL_POWER_CONSERVE) = (uint32_t)&osal_pwrmgr_powerconserve1; + //JUMP_FUNCTION(ENTER_SLEEP_OFF_MODE) = (uint32_t)&enter_sleep_off_mode1; + //JUMP_FUNCTION(ENTER_SLEEP_PROCESS) = (uint32_t)&enterSleepProcess1; + JUMP_FUNCTION(CONFIG_RTC) = (uint32_t)&config_RTC1; + JUMP_FUNCTION(LL_SCHEDULER) = (uint32_t)&ll_scheduler1; +// JUMP_FUNCTION(HAL_DRV_IRQ_ENABLE) = (uint32_t)&drv_enable_irq2; +// JUMP_FUNCTION(HAL_DRV_IRQ_DISABLE) = (uint32_t)&drv_disable_irq2; + //JUMP_FUNCTION(WAKEUP_INIT) = (uint32_t)&wakeup_init1; + //JUMP_FUNCTION(WAKEUP_PROCESS) = (uint32_t)&wakeupProcess1; + extern void l2capPocessFragmentTxData(uint16 connHandle); + JUMP_FUNCTION(L2CAP_PROCESS_FREGMENT_TX_DATA) = (uint32_t)&l2capPocessFragmentTxData; + //BQB bug fix,2020.11.17 + //JUMP_FUNCTION(LL_PHY_MODE_UPDATE) = (uint32_t)&LL_PhyUpdate1; + JUMP_FUNCTION(LL_SET_DATA_LENGTH) = (uint32_t)&LL_SetDataLengh1; + //JUMP_FUNCTION(LL_SET_PHY_MODE) = (uint32_t)&LL_SetPhyMode1; + JUMP_FUNCTION(LL_PROCESS_TX_DATA) = (uint32_t)&llProcessTxData1; + JUMP_FUNCTION(LL_GENERATE_TX_BUFFER) = (uint32_t)&ll_generateTxBuffer1; + JUMP_FUNCTION(LL_ADP_ADJ_NEXT_TIME) = (uint32_t)&ll_adptive_adj_next_time1; + JUMP_FUNCTION(LL_CONN_TERMINATE) = (uint32_t)&llConnTerminate1; +// JUMP_FUNCTION(LL_SLAVE_EVT_ENDOK) = (uint32_t)&llSlaveEvt_TaskEndOk1; +// ==================== + //disableSleep(); + //setSleepMode(MCU_SLEEP_MODE);//SYSTEM_SLEEP_MODE + enableSleep(); + setSleepMode(SYSTEM_SLEEP_MODE); +} + +void ll_patch_slave(void) +{ + JUMP_FUNCTION(LL_SET_ADV_PARAM) = (uint32_t)&LL_SetAdvParam1; + JUMP_FUNCTION(LL_CALC_MAX_SCAN_TIME) = (uint32_t)&llCalcMaxScanTime1; + JUMP_FUNCTION(LL_SEC_ADV_ALLOW) = (uint32_t)&llSecAdvAllow1; + JUMP_FUNCTION(LL_SET_ADV_CONTROL) = (uint32_t)&LL_SetAdvControl1; + JUMP_FUNCTION(LL_SETUP_SEC_ADV_ENTRY) = (uint32_t)&llSetupSecAdvEvt1; +} + +void ll_patch_master(void) +{ + JUMP_FUNCTION(LL_SET_ADV_PARAM) = (uint32_t)&LL_SetAdvParam1; + JUMP_FUNCTION(LL_SET_ADV_CONTROL) = (uint32_t)&LL_SetAdvControl1; + JUMP_FUNCTION(LL_MASTER_EVT_ENDOK) = (uint32_t)&llMasterEvt_TaskEndOk1; + JUMP_FUNCTION(LL_SET_SCAN_PARAM) = (uint32_t)&LL_SetScanParam1; + JUMP_FUNCTION(LL_SET_SCAN_CTRL) = (uint32_t)&LL_SetScanControl1; + //JUMP_FUNCTION(LL_PROCESS_MASTER_CTRL_PKT) = (uint32_t)&llProcessMasterControlPacket1; + JUMP_FUNCTION(LL_CREATE_CONN) = (uint32_t)&LL_CreateConn1; + JUMP_FUNCTION(LL_START_ENCRYPT) = (uint32_t)&LL_StartEncrypt1; + JUMP_FUNCTION(LL_ENC_DECRYPT) = (uint32_t)&LL_ENC_Decrypt1; + JUMP_FUNCTION(LL_PROCESS_MASTER_CTRL_PROC) = (uint32_t)&llProcessMasterControlProcedures1; + JUMP_FUNCTION(LL_PROCESS_SLAVE_CTRL_PROC) = (uint32_t)&llProcessSlaveControlProcedures1; + JUMP_FUNCTION(LL_PROCESSBASICIRQ_SRX) = (uint32_t )&ll_processBasicIRQ_SRX0; + JUMP_FUNCTION(LL_PROCESSBASICIRQ_SCANTRX) = (uint32_t )&ll_processBasicIRQ_ScanTRX0; + JUMP_FUNCTION(LL_SETUP_SEC_SCAN) = (uint32_t )&llSetupSecScan1; +} + +/* +void ll_patch_multi(void) +{ + ll_patch_slave(); + ll_patch_master(); + JUMP_FUNCTION(LL_SCHEDULER) = (uint32_t)&ll_scheduler1; + JUMP_FUNCTION(LL_PROCESSBASICIRQ_SECADVTRX) = (uint32_t )&ll_processBasicIRQ_secondaryAdvTRX0; +} +*/ + +void hal_rom_boot_init(void) +{ + extern void _rom_sec_boot_init(); + //_rom_sec_boot_init(); + ble_main(); +} +//----------------------------------------------------------------------- +// Patch for V105/V103 LL_ChanMapUpdate +// Copy chanMap to connPtr->chanMapUpdate.chaMap +hciStatus_t HCI_LE_SetHostChanClassificationCmd(uint8* chanMap) +{ + hciStatus_t status; + status = LL_ChanMapUpdate(chanMap); + + //patch for LL_ChanMapUpdate + if (status == LL_STATUS_SUCCESS) + { + // need to issue an update on all active connections, if any + for (uint8_t i = 0; i < g_maxConnNum; i++) + { + if (conn_param[i].active) + { + llConnState_t* connPtr = &conn_param[i]; + osal_memcpy((uint8_t*)&(connPtr->chanMapUpdate.chanMap[0]), chanMap, LL_NUM_BYTES_FOR_CHAN_MAP); + } + } + } + + //AT_LOG("ChanMap Patch %d \n", status); + HCI_CommandCompleteEvent(HCI_LE_SET_HOST_CHANNEL_CLASSIFICATION, sizeof(status), &status); + return (HCI_SUCCESS); +} + +/******************************************************************************* + @fn pplus_enter_programming_mode + + @brief force deive enter to programing mode. + + input parameters + + @param none. + + output parameters + + @param none. + + @return none. +void pplus_enter_programming_mode(void) +{ + typedef void (*uart_init_t)(int baud, GPIO_Pin_e tx_pin, GPIO_Pin_e rx_pin,uint32_t cb_addr); + typedef void (*uart_tx_t)(unsigned char* str); + typedef void (*uart_cmd_t)(void); + uart_init_t p_uart_init = (uart_init_t)0x0000b379; + uart_tx_t p_uart_tx = (uart_tx_t)0x0000b4f5; + uart_cmd_t p_uart_cmd = (uart_cmd_t)0x00015c51; + uint32_t _cb_addr = 0x00015c8d; + *(volatile unsigned int*) 0xe000e180 = 0xffffffff; + HAL_ENTER_CRITICAL_SECTION(); + osal_memset((void*)0x1fff0000, 0, 256*4); + HAL_EXIT_CRITICAL_SECTION(); + AP_CACHE->CTRL0 = 0x02; + AP_PCR->CACHE_RST = 0x02; + AP_PCR->CACHE_BYPASS = 1; + *(volatile unsigned int*) 0xe000e100 |= BIT(11); + p_uart_init(115200,P9, P10,_cb_addr); + *(volatile unsigned int*) 0x40004004 |= BIT(0); + p_uart_tx("cmd:"); + __set_MSP(0x1fff1830); + p_uart_cmd(); +} +*/ + + +int8 LL_PLUS_GetCurrentRSSI(void) +{ + uint8 rssi; + uint16 foff; + uint8 carrSens; + rf_phy_get_pktFoot(&rssi,&foff,&carrSens); + return -rssi; +} + +void LL_PLUS_GetCurrentPduDle(uint8_t connId, ll_pdu_length_ctrl_t* ppdu) +{ + if(LL_INVALID_CONNECTION_ID!=connId && ppdu!=NULL) + { + ppdu->MaxRxOctets = conn_param[connId].llPduLen.local.MaxRxOctets; + ppdu->MaxTxOctets = conn_param[connId].llPduLen.local.MaxTxOctets; + ppdu->MaxRxTime = conn_param[connId].llPduLen.local.MaxRxTime; + ppdu->MaxTxTime = conn_param[connId].llPduLen.local.MaxTxTime; + } +} + + +void LOG_PATCH_DATA_TIME(void) +{ + LOG("\n"); + LOG("PATCH_LIB:"); +// for(int i=0;i<12;i++) +// { +// LOG("%s",libRevisionDate[i]); +// } + LOG("%s",libRevisionDate); + LOG(" "); + LOG("%s",libRevisionTime); +// for(int i=0;i<12;i++) +// { +// LOG("%s",libRevisionTime[i]); +// } + LOG("\n"); +} + + +/* +extern inline uint32_t __psr(void) +{ + uint32_t i; + __asm + { + MRS i, psr + } + return i; +} +*/ +void rflib_vesion(uint8_t* major, uint8_t* minor, uint8_t* revision, char* test_build) +{ + *major = SDK_VER_MAJOR; + *minor = SDK_VER_MINOR; + *revision = SDK_VER_REVISION; + *test_build = '\0'; + #ifdef SDK_VER_TEST_BUILD + *test_build = SDK_VER_TEST_BUILD; + #endif +} + + +#define OSALMEM_BIGBLK_IDX 157 +// =========================================================== +// ptr: the header of osal heap +//uint32 osal_memory_statics(void *ptr) +/* +extern uint8 g_largeHeap[]; +uint32 osal_memory_statics(void) +{ + osalMemHdr_t* header, *current; + void* ptr; + uint32 sum_alloc = 0; + uint32 sum_free = 0; + uint32 max_block = 0; +// halIntState_t intState; + ptr = (void*)g_largeHeap; + header = (osalMemHdr_t*)ptr; + current = (osalMemHdr_t*)ptr; + +// HAL_ENTER_CRITICAL_SECTION1( intState ); // Hold off interrupts. + + do + { + if ((uint32)ptr > (uint32)header + 4096) + { + LOG("==========error: memory audit failed===============\r\n"); + break; + } + + // seek to the last block, return + if ( current->val == 0 ) /// val = 0, so len = 0 + { + break; + } + + if (current->hdr.inUse) + sum_alloc += current->hdr.len; + else + { + sum_free += current->hdr.len; + + if (current->hdr.len > max_block && (void*)(¤t->hdr) > (void*)(header + OSALMEM_BIGBLK_IDX)) + max_block = current->hdr.len; + } + + current = (osalMemHdr_t*)((uint8*)current + current->hdr.len); + } + while (1); + +// HAL_EXIT_CRITICAL_SECTION1( intState ); // Re-enable interrupts. +// printf("sum_alloc = %d, sum_free = %d, max_free_block = %d\r\n", sum_alloc, sum_free, max_block); + LOG("sum_alloc = %d, max_free_block = %d ", sum_alloc, max_block); + return sum_alloc; +} +*/ +llStatus_t LL_ConnUpdate1( uint16 connId, + uint16 connIntervalMin, + uint16 connIntervalMax, + uint16 connLatency, + uint16 connTimeout, + uint16 minLength, + uint16 maxLength ) +{ + llStatus_t status; + llConnState_t* connPtr; + // unused input parameter; PC-Lint error 715. + (void)minLength; + (void)maxLength; + + // make sure we're in Master role +// if ( llState != LL_STATE_CONN_MASTER ) +// { +// return( LL_STATUS_ERROR_COMMAND_DISALLOWED ); +// } + if (g_ll_conn_ctx.scheduleInfo[connId].linkRole != LL_ROLE_MASTER ) + return( LL_STATUS_ERROR_COMMAND_DISALLOWED ); + + // sanity checks again to be sure we don't start with bad parameters + if ( LL_INVALID_CONN_TIME_PARAM( connIntervalMin, + connIntervalMax, + connLatency, + connTimeout ) ) + { + return( LL_STATUS_ERROR_BAD_PARAMETER ); + } + + // make sure connection ID is valid + if ( (status=LL_ConnActive(connId)) != LL_STATUS_SUCCESS ) + { + return( status ); + } + + // get connection info + connPtr = &conn_param[connId]; + + // check if an updated parameters control procedure is already what's pending + if ( ((connPtr->ctrlPktInfo.ctrlPktCount > 0) && + (connPtr->ctrlPktInfo.ctrlPkts[0] == LL_CTRL_CONNECTION_UPDATE_REQ)) || + (connPtr->pendingParamUpdate == TRUE) ) + { + return( LL_STATUS_ERROR_CTRL_PROC_ALREADY_ACTIVE ); + } + + // check if CI/SL/LSTO is valid (i.e. meets the requirements) + // Note: LSTO > (1 + Slave Latency) * (Connection Interval * 2) + // Note: The CI * 2 requirement based on ESR05 V1.0, Erratum 3904. + // Note: LSTO time is normalized to units of 1.25ms (i.e. 10ms = 8 * 1.25ms). + if ( LL_INVALID_CONN_TIME_PARAM_COMBO(connIntervalMax, connLatency, connTimeout) ) + { + return( LL_STATUS_ERROR_ILLEGAL_PARAM_COMBINATION ); + } + + // if there is at least one connection, make sure this connection interval + // is a multiple/divisor of all other active connection intervals; also make + // sure that this connection's interval is not less than the allowed maximum + // connection interval as determined by the maximum number of allowed + // connections times the number of slots per connection. + if ( g_ll_conn_ctx.numLLMasterConns > 1 ) // if ( g_ll_conn_ctx.numLLConns > 0 ) + { + uint16 connInterval = (connIntervalMax << 1); // convert to 625us ticks + uint16 minCI = g_ll_conn_ctx.connInterval; + + // // first check if this connection interval is even legal + // // Note: The number of active connections is limited by the minCI. + // if ( (minCI / NUM_SLOTS_PER_MASTER) < llConns.numActiveConns ) + // { + // return( LL_STATUS_ERROR_UNACCEPTABLE_CONN_INTERVAL ); + // } + + // // does the CI need to be checked as a multiple of the minCI? + if ( connInterval >= minCI ) + { + // check if this connection's CI is valid (i.e. a multiple of minCI) + if ( connInterval % minCI ) + { + return( LL_STATUS_ERROR_UNACCEPTABLE_CONN_INTERVAL ); + } + } + else + return( LL_STATUS_ERROR_UNACCEPTABLE_CONN_INTERVAL ); + } + else + { + // only 1 master connection + g_ll_conn_ctx.connInterval = connIntervalMax; + g_ll_conn_ctx.per_slot_time = connPtr->curParam.connInterval * 2 / g_maxConnNum; // unit: 625us + } + + // no control procedure currently active, so set this one up + // set the window size (units of 1.25ms) + connPtr->paramUpdate.winSize = LL_WINDOW_SIZE; + // set the window offset (units of 1.25ms) +// connPtr->paramUpdate.winOffset = LL_WINDOW_OFFSET; + connPtr->paramUpdate.winOffset = 0; // multiconnection, this value could be 0 or x * old conn interval and should be less than new conn interval + // set the relative offset of the number of events for the parameter update + // Note: The absolute event number will be determined at the time the packet + // is placed in the TX FIFO. + // Note: The master should allow a minimum of 6 connection events that the + // slave will be listening for before the instant occurs. + connPtr->paramUpdateEvent = (connPtr->curParam.slaveLatency+1) + + LL_INSTANT_NUMBER_MIN; + // determine the connection interval based on min and max values + // Note: Range not used, so assume max value. + // Note: minLength and maxLength are informational. + connPtr->paramUpdate.connInterval = connIntervalMax; + // save the new connection slave latency to be used by the peer + connPtr->paramUpdate.slaveLatency = connLatency; + // save the new connection supervisor timeout + connPtr->paramUpdate.connTimeout = connTimeout; + // queue control packet for processing + llEnqueueCtrlPkt( connPtr, LL_CTRL_CONNECTION_UPDATE_REQ ); + return( LL_STATUS_SUCCESS ); +} + +hciStatus_t HCI_LE_ConnUpdateCmd( uint16 connHandle, + uint16 connIntervalMin, + uint16 connIntervalMax, + uint16 connLatency, + uint16 connTimeout, + uint16 minLen, + uint16 maxLen ) +{ + hciStatus_t status; + status = LL_ConnUpdate1( connHandle, + connIntervalMin, + connIntervalMax, + connLatency, + connTimeout, + minLen, + maxLen ); + HCI_CommandStatusEvent( status, HCI_LE_CONNECTION_UPDATE ); + return( HCI_SUCCESS ); +} + +CHIP_ID_STATUS_e chip_id_one_bit_hot_convter(uint8_t* b,uint32_t w) +{ + uint16 dh = w>>16; + uint16 dl = w&0xffff; + uint16 h1,h0,l1,l0; + h0=l0=0xff; + h1=l1=0; + + for(int i=0; i<16; i++) + { + l1+=((dl&(1<>i); + + if(l0==0xff && l1==1) + { + l0=i; + } + + h1+=((dh&(1<>i); + + if(h0==0xff && h1==1) + { + h0=i; + } + } + + if(l1==1 && h1==1) + { + *b=((h0<<4)+l0); + return CHIP_ID_VALID; + } + else if(l1==16 && h1==16) + { + return CHIP_ID_EMPTY; + } + else + { + return CHIP_ID_INVALID; + } +} + +/******************************************************************************* + @fn LL_PLUS_LoadMACFromFlash + + @brief Used to load MAC Address from Flash + + input parameters + + @param None. + + output parameters + + @param None. + + @return None. +*/ +void LL_PLUS_LoadMACFromFlash(uint32_t addr) +{ + volatile uint8_t* p_ownPublicAddr = (volatile uint8_t*)0x1fff0965; + uint32_t macAddr[2]; + macAddr[0]=*(volatile uint32_t*) (0x11000000+addr); + macAddr[1]=*(volatile uint32_t*) (0x11000000+addr+4); + *(p_ownPublicAddr++) = BREAK_UINT32(macAddr[0],3); + *(p_ownPublicAddr++) = BREAK_UINT32(macAddr[0],2); + *(p_ownPublicAddr++) = BREAK_UINT32(macAddr[0],1); + *(p_ownPublicAddr++) = BREAK_UINT32(macAddr[0],0); + *(p_ownPublicAddr++) = BREAK_UINT32(macAddr[1],1); + *(p_ownPublicAddr++) = BREAK_UINT32(macAddr[1],0); +} + + +/******************************************************************************* + @fn pplus_LoadMACFromChipMAddr + + @brief Used to load MAC Address from chip Maddr + + input parameters + + @param None. + + output parameters + + @param None. + + @return CHIP_ID_STATUS_e. +*/ +CHIP_ID_STATUS_e LL_PLUS_LoadMACFromChipMAddr(void) +{ + //check_chip_mAddr(); + volatile uint8_t* p_ownPublicAddr = (volatile uint8_t*)0x1fff0965; + + if(g_chipMAddr.chipMAddrStatus==CHIP_ID_VALID) + { + for(uint8_t i =0; i 16) + { + return PPlus_ERR_FATAL; + } + + TRNG_INIT(); + + for(i=0; i<16; i++) + t0+=s_trng_seed[i]; + + if(t0==0) + return PPlus_ERR_NULL; + + if(len>16) + return PPlus_ERR_DATA_SIZE; + + for(i=0; i<16; i++) + cryIn[i] =s_trng_iv[i]^s_company_id[i]; + + LL_ENC_AES128_Encrypt(s_trng_seed,cryIn,cryOut); + rand_len = len > 16 ? 16 : len; + osal_memcpy(buf,cryOut,rand_len); + TRNG_IV_Updata(); + return PPlus_SUCCESS; +} + + +// bugfix for multi-Role +/******************************************************************************* + @fn LL_EncLtkReply API + + @brief This API is called by the HCI to provide the controller with + the Long Term Key (LTK) for encryption. This command is + actually a reply to the link layer's LL_EncLtkReqCback, which + provided the random number and encryption diversifier received + from the Master during an encryption setup. + + Note: The key parameter is byte ordered LSO to MSO. + + input parameters + + @param connId - The LL connection ID on which to send this data. + @param *key - A 128 bit key to be used to calculate the session key. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS +*/ +llStatus_t LL_EncLtkReply( uint16 connId, + uint8* key ) +{ + uint8 i; + llStatus_t status; + llConnState_t* connPtr; + // get connection info + connPtr = &conn_param[ connId ]; + + // make sure we're in Master role +// if ( llState != LL_STATE_CONN_SLAVE ) + /* asynchronous send msg can not make sure llState = LL_STATE_CONN_SLAVE in multi-role */ + if( connPtr->llTbd1 != LL_LINK_CONNECT_COMPLETE_SLAVE ) + { + return( LL_STATUS_ERROR_COMMAND_DISALLOWED ); + } + + // check parameters + if ( key == NULL ) + { + return( LL_STATUS_ERROR_BAD_PARAMETER ); + } + + // make sure connection ID is valid + if ( (status=LL_ConnActive(connId)) != LL_STATUS_SUCCESS ) + { + return( status ); + } + + // ALT: COULD MAKE THIS PER CONNECTION. + + // save LTK + for (i=0; iencInfo.LTK[(LL_ENC_LTK_LEN-i)-1] = key[i]; + } + + // indicate the host has provided the key + connPtr->encInfo.LTKValid = TRUE; + // got the LTK, so schedule the start of encryption + // ALT: COULD MAKE THIS A REPLACE IF A DUMMY IS SITTING AT THE HEAD OF + // THE QUEUE. + llEnqueueCtrlPkt( connPtr, LL_CTRL_START_ENC_REQ ); + return( LL_STATUS_SUCCESS ); +} + +/******************************************************************************* + @fn LL_EncLtkNegReply API + + @brief This API is called by the HCI to indicate to the controller + that the Long Term Key (LTK) for encryption can not be provided. + This command is actually a reply to the link layer's + LL_EncLtkReqCback, which provided the random number and + encryption diversifier received from the Master during an + encryption setup. How the LL responds to the negative reply + depends on whether this is part of a start encryption or a + re-start encryption after a pause. For the former, an + encryption request rejection is sent to the peer device. For + the latter, the connection is terminated. + + input parameters + + @param connId - The LL connection ID on which to send this data. + + output parameters + + @param None. + + @return LL_STATUS_SUCCESS +*/ +llStatus_t LL_EncLtkNegReply( uint16 connId ) +{ + llStatus_t status; + llConnState_t* connPtr; + // get connection info + connPtr = &conn_param[ connId ]; + +// // make sure we're in Master role +// if ( llState != LL_STATE_CONN_SLAVE ) + /* asynchronous send msg can not make sure llState = LL_STATE_CONN_SLAVE in multi-role */ + if( connPtr->llTbd1 != LL_LINK_CONNECT_COMPLETE_SLAVE ) + { + return( LL_STATUS_ERROR_COMMAND_DISALLOWED ); + } + + // make sure connection ID is valid + if ( (status=LL_ConnActive(connId)) != LL_STATUS_SUCCESS ) + { + return( status ); + } + + // check if this is during a start or a re-start encryption procedure + if ( connPtr->encInfo.encRestart == TRUE ) + { + // indicate the peer requested this termination + connPtr->termInfo.reason = LL_ENC_KEY_REQ_REJECTED; + // queue control packet for processing + // ALT: COULD MAKE THIS A REPLACE IF A DUMMY IS SITTING AT THE HEAD OF + // THE QUEUE. + //llReplaceCtrlPkt( connPtr, LL_CTRL_TERMINATE_IND ); + llEnqueueCtrlPkt( connPtr, LL_CTRL_TERMINATE_IND ); + } + else // during a start encryption + { + // set the encryption rejection error code + connPtr->encInfo.encRejectErrCode = LL_STATUS_ERROR_PIN_OR_KEY_MISSING; // same as LL_ENC_KEY_REQ_REJECTED + // and reject the encryption request + // ALT: COULD MAKE THIS A REPLACE IF A DUMMY IS SITTING AT THE HEAD OF + // THE QUEUE. + //llReplaceCtrlPkt( connPtr, LL_CTRL_REJECT_IND ); + llEnqueueCtrlPkt( connPtr, LL_CTRL_REJECT_IND ); + } + + return( LL_STATUS_SUCCESS ); +} + +hciStatus_t HCI_LE_LtkReqReplyCmd( uint16 connHandle, + uint8* ltk ) +{ + // 0: Status + // 1: Connection Handle (LSB) + // 2: Connection Handle (MSB) + uint8 rtnParam[3]; + rtnParam[0] = LL_EncLtkReply( connHandle, ltk ); + rtnParam[1] = LO_UINT16( connHandle ); + rtnParam[2] = HI_UINT16( connHandle ); + HCI_CommandCompleteEvent( HCI_LE_LTK_REQ_REPLY, sizeof(rtnParam), rtnParam ); + return ( HCI_SUCCESS ); +} + + +/******************************************************************************* + This LE API is used by the Host to send to the Controller a negative LTK + reply. + + Public function defined in hci.h. +*/ +hciStatus_t HCI_LE_LtkReqNegReplyCmd( uint16 connHandle ) +{ + // 0: Status + // 1: Connection Handle (LSB) + // 2: Connection Handle (MSB) + uint8 rtnParam[3]; + rtnParam[0] = LL_EncLtkNegReply( connHandle ); + rtnParam[1] = LO_UINT16( connHandle ); + rtnParam[2] = HI_UINT16( connHandle ); + HCI_CommandCompleteEvent( HCI_LE_LTK_REQ_NEG_REPLY, sizeof(rtnParam), rtnParam ); + return( HCI_SUCCESS ); +} + + + diff --git a/arch/arm/src/phy62xx/phy62xx_exception.S b/arch/arm/src/phy62xx/phy62xx_exception.S new file mode 100644 index 00000000000..fb97ce52c97 --- /dev/null +++ b/arch/arm/src/phy62xx/phy62xx_exception.S @@ -0,0 +1,344 @@ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include "exc_return.h" + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .globl exception_common + .globl exception_common_inline + .file "arm_exception.S" + +/**************************************************************************** + * .text + ****************************************************************************/ + +/* Common exception handling logic. On entry here, the return stack is on either + * the PSP or the MSP and looks like the following: + * + * REG_XPSR + * REG_R15 + * REG_R14 + * REG_R12 + * REG_R3 + * REG_R2 + * REG_R1 + * MSP->REG_R0 + * + * And + * IPSR contains the IRQ number + * R14 Contains the EXC_RETURN value + * We are in handler mode and the current SP is the MSP + */ + + .text + .align 2 + .code 16 + .thumb_func + .type exception_common, function +exception_common: + + /* Complete the context save */ + + /* Get the current stack pointer. The EXC_RETURN value tells us whether + * the context is on the MSP or PSP. + */ + mrs r1, msp /* R1=The main stack pointer */ + + /* R1 is the current stack pointer. HW_XCPT_REGS were pushed onto the stack + * when the interrupt was taken so (R1)+HW_XCPT_SIZE is the value of the + * stack pointer before the interrupt. The total size of the context save + * area is XCPTCONTEXT_SIZE = SW_XCPT_SIZE + HW_XCPT_SIZE so (R1)-SW_XCPT_SIZE + * is the address of the beginning of the context save area. + */ + + /*stack layout:(*for SP position)*/ + /*init: *Jump(2W) + Exception(2W)*/ + /*before doIrq: *SW_XCpt(10W) + Exception(2W) + Jump(2W) + Exception(2W)*/ + /*after doIrq: *SW_XCpt(10W) + Jump(2W) + Exception(2W)*/ + /*stack layout:*/ + +2: + /* Save SP, PRIMASK, and R4-R7 in the context array */ + sub r1, #SW_XCPT_SIZE /* R1=Beginning of context array on the stack */ + //sub r1, #XCPTCONTEXT_SIZE //new data should duplicate hw exception stack + mov r2, #XCPTCONTEXT_SIZE /* R2=Size of the context array */ + add r2, r1 /* R2=MSP/PSP before the interrupt was taken */ + /* (ignoring the xPSR[9] alignment bit) */ + mrs r3, primask /* R3=Current PRIMASK setting */ + mov r0, r1 /* Copy the context array pointer */ + stmia r0!, {r2-r7} /* Save the SP, PRIMASK, and R4-R7 in the context array */ + + /* Save R8-R11 and the EXEC_RETURN value in the context array */ + + mov r2, r8 /* Copy high registers to low */ + mov r3, r9 + mov r4, r10 + mov r5, r11 + stmia r0!, {r2-r5} /* Save the high registers r8-r11 */ + + /*load hw interrupt stack*/ + //mov r3, r0 + //add r3, #40 /*total 10 word, 2 word is for jump table*/ + //ldmia r3!, {r4-r7} /* Fetch four registers from the HW save area */ + //stmia r0!, {r4-r7} + //ldmia r3!, {r4-r7} /* Fetch four registers from the HW save area */ + //stmia r0!, {r4-r7} + + /* Get the exception number in R0=IRQ, R1=register save area on stack */ + + mrs r0, ipsr /* R0=exception number */ + + /* If CONFIG_ARCH_INTERRUPTSTACK is defined, we will use a special interrupt + * stack pointer. The way that this is done here prohibits nested interrupts! + * Otherwise, we will use the stack that was current when the interrupt was taken. + */ + + msr msp, r1 /* We are using the main stack pointer */ + bl arm_doirq /* R0=IRQ, R1=register save area on stack */ + mrs r1, msp /* Recover R1=main stack pointer */ + + /* On return from arm_doirq, R0 will hold a pointer to register context + * array to use for the interrupt return. If that return value is the same + * as current stack pointer, then things are relatively easy. + */ + + cmp r0, r1 /* Context switch? */ + beq 3f /* Branch if no context switch */ + + /* We are returning with a pending context switch. This case is different + * because in this case, the register save structure does not lie on the + * stack but, rather within a TCB structure. We'll have to copy some + * values to the stack. + */ + + /* Copy the hardware-saved context to the new stack */ + + mov r2, #SW_XCPT_SIZE /* R2=Size of software-saved portion of the context array */ + add r1, r0, r2 /* R1=Address of HW save area in reg array */ + add r1, #8 /* skip dummy */ + ldr r2, [r0, #(4*REG_SP)] /* R2=Value of SP before the interrupt */ + sub r2, #(HW_XCPT_SIZE-8) /* R2=Address of HW save area on the return stack and skip dummy */ + ldmia r1!, {r4-r7} /* Fetch four registers from the HW save area */ + stmia r2!, {r4-r7} /* Copy four registers to the return stack */ + ldmia r1!, {r4-r7} /* Fetch four registers from the HW save area */ + stmia r2!, {r4-r7} /* Copy four registers to the return stack */ + + /* Restore the register contents */ + + mov r1, r0 + +3: + /* We are returning with no context switch. We simply need to "unwind" + * the same stack frame that we created at entry. + */ + + /* Recover R8-R11 and EXEC_RETURN (5 registers) */ + + mov r2, #(4*REG_R8) /* R2=Offset to R8 storage */ + add r0, r1, r2 /* R0=Address of R8 storage */ + + ldmia r0!, {r2-r5} /* Recover R8-R11 and R14 (5 registers)*/ + mov r8, r2 /* Move to position in high registers */ + mov r9, r3 + mov r10, r4 + mov r11, r5 + + + /* Recover SP (R2), PRIMASK (R3), and R4-R7. Determine the value of + * the stack pointer as it was on entry to the exception handler. + */ + + ldmia r1!, {r2-r7} /* Recover R4-R7 + 2 temp values */ + mov r1, #(HW_XCPT_SIZE-8) /* R1=Size of hardware-saved portion of the context array */ + sub r1, r2, r1 /* R1=Value of MSP/PSP on exception entry */ + + /* Restore the stack pointer. The EXC_RETURN value tells us whether the + * context is on the MSP or PSP. + */ + + msr msp, r1 /* R1=The main stack pointer */ + ldr r0, =EXC_RETURN_PRIVTHR /* R0=EXC_RETURN to privileged mode */ + mov r14, r0 /* R14=EXC_RETURN to privileged mode */ + + /* Restore the interrupt state */ + + msr primask, r3 /* Restore interrupts priority masking*/ + + /* Always return with R14 containing the special value that will: (1) + * return to thread mode, and (2) select the correct stack. + */ + + bx r14 /* And return */ + + .size exception_common, .-exception_common + +/**************************************************************************** + * Name: g_intstackalloc/g_intstacktop + * + * Description: + * Shouldn't happen + * + ****************************************************************************/ + + + .text + .align 2 + .code 16 + .thumb_func + .type exception_common_inline, function +exception_common_inline: + + /* Complete the context save */ + + /* Get the current stack pointer. The EXC_RETURN value tells us whether + * the context is on the MSP or PSP. + */ + mrs r1, msp /* R1=The main stack pointer */ + sub r1, #8 /* align to normal jumpfunction mode */ + + /* R1 is the current stack pointer. HW_XCPT_REGS were pushed onto the stack + * when the interrupt was taken so (R1)+HW_XCPT_SIZE is the value of the + * stack pointer before the interrupt. The total size of the context save + * area is XCPTCONTEXT_SIZE = SW_XCPT_SIZE + HW_XCPT_SIZE so (R1)-SW_XCPT_SIZE + * is the address of the beginning of the context save area. + */ + + /*stack layout:(*for SP position)*/ + /*init: *Jump(2W) + Exception(2W)*/ + /*before doIrq: *SW_XCpt(10W) + Exception(2W) + Jump(2W) + Exception(2W)*/ + /*after doIrq: *SW_XCpt(10W) + Jump(2W) + Exception(2W)*/ + /*stack layout:*/ + +2: + /* Save SP, PRIMASK, and R4-R7 in the context array */ + sub r1, #SW_XCPT_SIZE /* R1=Beginning of context array on the stack */ + //sub r1, #XCPTCONTEXT_SIZE //new data should duplicate hw exception stack + mov r2, #XCPTCONTEXT_SIZE /* R2=Size of the context array */ + add r2, r1 /* R2=MSP/PSP before the interrupt was taken */ + /* (ignoring the xPSR[9] alignment bit) */ + mrs r3, primask /* R3=Current PRIMASK setting */ + mov r0, r1 /* Copy the context array pointer */ + stmia r0!, {r2-r7} /* Save the SP, PRIMASK, and R4-R7 in the context array */ + + /* Save R8-R11 and the EXEC_RETURN value in the context array */ + + mov r2, r8 /* Copy high registers to low */ + mov r3, r9 + mov r4, r10 + mov r5, r11 + stmia r0!, {r2-r5} /* Save the high registers r8-r11 */ + + /*load hw interrupt stack*/ + //mov r3, r0 + //add r3, #40 /*total 10 word, 2 word is for jump table*/ + //ldmia r3!, {r4-r7} /* Fetch four registers from the HW save area */ + //stmia r0!, {r4-r7} + //ldmia r3!, {r4-r7} /* Fetch four registers from the HW save area */ + //stmia r0!, {r4-r7} + + /* Get the exception number in R0=IRQ, R1=register save area on stack */ + + mrs r0, ipsr /* R0=exception number */ + + /* If CONFIG_ARCH_INTERRUPTSTACK is defined, we will use a special interrupt + * stack pointer. The way that this is done here prohibits nested interrupts! + * Otherwise, we will use the stack that was current when the interrupt was taken. + */ + + msr msp, r1 /* We are using the main stack pointer */ + bl arm_doirq /* R0=IRQ, R1=register save area on stack */ + mrs r1, msp /* Recover R1=main stack pointer */ + + /* On return from arm_doirq, R0 will hold a pointer to register context + * array to use for the interrupt return. If that return value is the same + * as current stack pointer, then things are relatively easy. + */ + + cmp r0, r1 /* Context switch? */ + beq 3f /* Branch if no context switch */ + + /* We are returning with a pending context switch. This case is different + * because in this case, the register save structure does not lie on the + * stack but, rather within a TCB structure. We'll have to copy some + * values to the stack. + */ + + /* Copy the hardware-saved context to the new stack */ + + mov r2, #SW_XCPT_SIZE /* R2=Size of software-saved portion of the context array */ + add r1, r0, r2 /* R1=Address of HW save area in reg array */ + add r1, #8 /* skip dummy */ + ldr r2, [r0, #(4*REG_SP)] /* R2=Value of SP before the interrupt */ + sub r2, #(HW_XCPT_SIZE-8) /* R2=Address of HW save area on the return stack and skip dummy */ + ldmia r1!, {r4-r7} /* Fetch four registers from the HW save area */ + stmia r2!, {r4-r7} /* Copy four registers to the return stack */ + ldmia r1!, {r4-r7} /* Fetch four registers from the HW save area */ + stmia r2!, {r4-r7} /* Copy four registers to the return stack */ + + /* Restore the register contents */ + + mov r1, r0 + +3: + /* We are returning with no context switch. We simply need to "unwind" + * the same stack frame that we created at entry. + */ + + /* Recover R8-R11 and EXEC_RETURN (5 registers) */ + + mov r2, #(4*REG_R8) /* R2=Offset to R8 storage */ + add r0, r1, r2 /* R0=Address of R8 storage */ + + ldmia r0!, {r2-r5} /* Recover R8-R11 and R14 (5 registers)*/ + mov r8, r2 /* Move to position in high registers */ + mov r9, r3 + mov r10, r4 + mov r11, r5 + + + /* Recover SP (R2), PRIMASK (R3), and R4-R7. Determine the value of + * the stack pointer as it was on entry to the exception handler. + */ + + ldmia r1!, {r2-r7} /* Recover R4-R7 + 2 temp values */ + mov r1, #(HW_XCPT_SIZE-8) /* R1=Size of hardware-saved portion of the context array */ + sub r1, r2, r1 /* R1=Value of MSP/PSP on exception entry */ + + /* Restore the stack pointer. The EXC_RETURN value tells us whether the + * context is on the MSP or PSP. + */ + + msr msp, r1 /* R1=The main stack pointer */ + ldr r0, =EXC_RETURN_PRIVTHR /* R0=EXC_RETURN to privileged mode */ + mov r14, r0 /* R14=EXC_RETURN to privileged mode */ + + /* Restore the interrupt state */ + + msr primask, r3 /* Restore interrupts priority masking*/ + + /* Always return with R14 containing the special value that will: (1) + * return to thread mode, and (2) select the correct stack. + */ + + bx r14 /* And return */ + + .size exception_common_inline, .-exception_common_inline + +/**************************************************************************** + * Name: g_intstackalloc/g_intstacktop + * + * Description: + * Shouldn't happen + * + ****************************************************************************/ + + + .end diff --git a/arch/arm/src/phy62xx/phy62xx_hardfault.c b/arch/arm/src/phy62xx/phy62xx_hardfault.c new file mode 100644 index 00000000000..78657dcdcd1 --- /dev/null +++ b/arch/arm/src/phy62xx/phy62xx_hardfault.c @@ -0,0 +1,128 @@ +/**************************************************************************** + * arch/arm/src/armv6-m/arm_hardfault.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "arm_arch.h" +#include "nvic.h" +#include "arm_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +extern uint32_t _stextram; +extern uint32_t _etextram; + +#ifdef CONFIG_DEBUG_HARDFAULT_ALERT +# define hfalert(format, ...) _alert(format, ##__VA_ARGS__) +#else +# define hfalert(x...) +#endif + +#ifdef CONFIG_DEBUG_HARDFAULT_INFO +# define hfinfo(format, ...) _info(format, ##__VA_ARGS__) +#else +# define hfinfo(x...) +#endif + +#define INSN_SVC0 0xdf00 /* insn: svc 0 */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_hardfault + * + * Description: + * This is Hard Fault exception handler. It also catches SVC call + * exceptions that are performed in bad contexts. + * + ****************************************************************************/ + +int arm_hardfault(int irq, FAR void *context, FAR void *arg) +{ + uint32_t *regs = (uint32_t *)context; + + /* Get the value of the program counter where the fault occurred */ + + uint16_t *pc = (uint16_t *)regs[REG_PC] - 1; + + /* Check if the pc lies in known FLASH memory. + * REVISIT: What if the PC lies in "unknown" external memory? + */ + +#ifdef CONFIG_BUILD_PROTECTED + /* In the kernel build, SVCalls are expected in either the base, kernel + * FLASH region or in the user FLASH region. + */ + + if (((uintptr_t)pc >= (uintptr_t)&_stext && + (uintptr_t)pc < (uintptr_t)&_etext) || + ((uintptr_t)pc >= (uintptr_t)USERSPACE->us_textstart && + (uintptr_t)pc < (uintptr_t)USERSPACE->us_textend)) +#else + /* SVCalls are expected only from the base, kernel FLASH region */ + + if (((uintptr_t)pc >= (uintptr_t)&_stext && (uintptr_t)pc < (uintptr_t)&_etext) || + ((uintptr_t)pc >= (uintptr_t)&_stextram && (uintptr_t)pc < (uintptr_t)&_etextram)) +#endif + { + /* Fetch the instruction that caused the Hard fault */ + + uint16_t insn = *pc; + hfinfo(" PC: %p INSN: %04x\n", pc, insn); + + /* If this was the instruction 'svc 0', then forward processing + * to the SVCall handler + */ + + if (insn == INSN_SVC0) + { + hfinfo("Forward SVCall\n"); + return arm_svcall(irq, context, NULL); + } + } + +#if defined(CONFIG_DEBUG_HARDFAULT_ALERT) + /* Dump some hard fault info */ + + hfalert("\nHard Fault:\n"); + hfalert(" IRQ: %d regs: %p\n", irq, regs); + hfalert(" PRIMASK: %08x IPSR: %08x\n", + getprimask(), getipsr()); +#endif + + up_irq_save(); + hfalert("PANIC!!! Hard fault\n"); + PANIC(); + return OK; /* Won't get here */ +} diff --git a/arch/arm/src/phy62xx/phy62xx_start.S b/arch/arm/src/phy62xx/phy62xx_start.S new file mode 100644 index 00000000000..08a8b21a00f --- /dev/null +++ b/arch/arm/src/phy62xx/phy62xx_start.S @@ -0,0 +1,51 @@ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include "exc_return.h" + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .file "phy62xx_start.S" + +#if 0 + .text + .align 2 + .code 16 + .thumb_func + .globl __start + .type __start, function +__start: + + ldr r1, =(_ebss+CONFIG_IDLETHREAD_STACKSIZE) + msr msp, r1 /* r2>>sp */ + + bl c_start /* R0=IRQ, R1=register save area on stack */ + bx c_start + + .size __start, .__start + +#endif + + .text + .align 2 + .code 16 + .globl __start + .thumb_func + .type __start, function +__start: + + ldr r1, =(_ebss+CONFIG_IDLETHREAD_STACKSIZE) + msr msp, r1 /* r2>>sp */ + bl c_start /* R0=IRQ, R1=register save area on stack */ + + + .size __start, .-__start + + .end diff --git a/arch/arm/src/phy62xx/phyplus_gpio.c b/arch/arm/src/phy62xx/phyplus_gpio.c new file mode 100644 index 00000000000..cd725547a11 --- /dev/null +++ b/arch/arm/src/phy62xx/phyplus_gpio.c @@ -0,0 +1,415 @@ +/**************************************************************************** + * arch/arm/src/phy62xx/phyplus_gpio.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + *********************************335*******************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "gpio.h" +#include "chip.h" +#include "phyplus_stub.h" +#include "mcu_phy_bumbee.h" +#include "pwrmgr.h" +#include "phyplus_gpio.h" +#include "errno.h" + +#if defined(CONFIG_DEV_GPIO) + +/**************************************************************************** + * phy6222 internal used functions.. + ****************************************************************************/ + +static void hal_low_power_io_init(void) +{ + ioinit_cfg_t ioinit[] = + { + {GPIO_P02, GPIO_FLOATING }, + {GPIO_P03, GPIO_FLOATING }, + {GPIO_P09, GPIO_PULL_UP }, + {GPIO_P10, GPIO_PULL_UP }, + {GPIO_P11, GPIO_PULL_DOWN }, + {GPIO_P14, GPIO_PULL_DOWN }, + {GPIO_P15, GPIO_PULL_DOWN }, + {GPIO_P16, GPIO_FLOATING }, + {GPIO_P18, GPIO_PULL_DOWN }, + {GPIO_P20, GPIO_PULL_DOWN }, + {GPIO_P00, GPIO_PULL_DOWN }, + {GPIO_P01, GPIO_PULL_DOWN }, + {GPIO_P07, GPIO_PULL_DOWN }, + {GPIO_P17, GPIO_FLOATING }, + {GPIO_P23, GPIO_PULL_DOWN }, + {GPIO_P24, GPIO_PULL_DOWN }, + {GPIO_P25, GPIO_PULL_DOWN }, + {GPIO_P26, GPIO_PULL_DOWN }, + {GPIO_P27, GPIO_PULL_DOWN }, + {GPIO_P31, GPIO_PULL_DOWN }, + {GPIO_P32, GPIO_PULL_DOWN }, + {GPIO_P33, GPIO_PULL_DOWN }, + {GPIO_P34, GPIO_PULL_DOWN }, + }; + for (uint8_t i = 0; i < sizeof(ioinit) / sizeof(ioinit_cfg_t); i++) + { + hal_gpio_pull_set(ioinit[i].pin, ioinit[i].type); + } +} + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct phyplus_gpio_dev_s +{ + struct gpio_dev_s gpio; + uint8_t idx; + pin_interrupt_t callback; +}; + +static struct phyplus_gpio_dev_s g_phyplus_gpio_dev[GPIO_NUM]; +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int phyplus_gpin_read(FAR struct gpio_dev_s *dev, FAR bool *value); +static int phyplus_gpout_read(FAR struct gpio_dev_s *dev, FAR bool *value); +static int phyplus_gpout_write(FAR struct gpio_dev_s *dev, bool value); +static int phyplus_gpint_read(FAR struct gpio_dev_s *dev, FAR bool *value); +static int phyplus_gpint_attach(FAR struct gpio_dev_s *dev, + FAR pin_interrupt_t callback); +static int phyplus_gpint_enable(FAR struct gpio_dev_s *dev, bool enable); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct gpio_operations_s gpin_ops = +{ + .go_read = phyplus_gpin_read, + .go_write = NULL, + .go_attach = NULL, + .go_enable = NULL, +}; + +static const struct gpio_operations_s gpout_ops = +{ + .go_read = phyplus_gpout_read, + .go_write = phyplus_gpout_write, + .go_attach = NULL, + .go_enable = NULL, +}; + +static const struct gpio_operations_s gpint_ops = +{ + .go_read = phyplus_gpint_read, + .go_write = NULL, + .go_attach = phyplus_gpint_attach, + .go_enable = phyplus_gpint_enable, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int phyplus_gpio_interrupt(int irq, void *context, void *arg) +{ +#if 0 + FAR struct stm32gpint_dev_s *stm32gpint = + (FAR struct stm32gpint_dev_s *)arg; + + DEBUGASSERT(stm32gpint != NULL && stm32gpint->callback != NULL); + gpioinfo("Interrupt! callback=%p\n", stm32gpint->callback); + + stm32gpint->callback(&stm32gpint->stm32gpio.gpio, + stm32gpint->stm32gpio.id); +#endif + + FAR struct phyplus_gpio_dev_s *phyplus_gpint = + (FAR struct phyplus_gpio_dev_s *)arg; + + DEBUGASSERT(phyplus_gpint != NULL && phyplus_gpint->callback != NULL); + gpioinfo("Interrupt! callback=%p\n", phyplus_gpint->callback); + + phyplus_gpint->callback(&phyplus_gpint->gpio, + phyplus_gpint->idx); + + return 0; +} + +static int phyplus_gpin_read(FAR struct gpio_dev_s *dev, FAR bool *value) +{ +#if 0 + FAR struct stm32gpio_dev_s *stm32gpio = + (FAR struct stm32gpio_dev_s *)dev; + + DEBUGASSERT(stm32gpio != NULL && value != NULL); + DEBUGASSERT(stm32gpio->id < BOARD_NGPIOIN); + gpioinfo("Reading...\n"); + + *value = stm32_gpioread(g_gpioinputs[stm32gpio->id]); +#endif + FAR struct phyplus_gpio_dev_s *phyplus_gpin = + (FAR struct phyplus_gpio_dev_s *)dev; + + DEBUGASSERT(phyplus_gpin != NULL && value != NULL); + DEBUGASSERT(phyplus_gpin->idx < GPIO_NUM); + gpioinfo("Reading...\n"); + + *value = hal_gpio_read(phyplus_gpin->idx); + + return 0; +} + +static int phyplus_gpout_read(FAR struct gpio_dev_s *dev, FAR bool *value) +{ +#if 0 + FAR struct stm32gpio_dev_s *stm32gpio = + (FAR struct stm32gpio_dev_s *)dev; + + DEBUGASSERT(stm32gpio != NULL && value != NULL); + DEBUGASSERT(stm32gpio->id < BOARD_NGPIOOUT); + gpioinfo("Reading...\n"); + + *value = stm32_gpioread(g_gpiooutputs[stm32gpio->id]); +#endif + + FAR struct phyplus_gpio_dev_s *phyplus_gpout = + (FAR struct phyplus_gpio_dev_s *)dev; + + DEBUGASSERT(phyplus_gpout != NULL && value != NULL); + DEBUGASSERT(phyplus_gpout->idx < GPIO_NUM); + gpioinfo("Reading...\n"); + + *value = hal_gpio_read(phyplus_gpout->idx); + + return 0; +} + +static int phyplus_gpout_write(FAR struct gpio_dev_s *dev, bool value) +{ +#if 0 + FAR struct stm32gpio_dev_s *stm32gpio = + (FAR struct stm32gpio_dev_s *)dev; + + DEBUGASSERT(stm32gpio != NULL); + DEBUGASSERT(stm32gpio->id < BOARD_NGPIOOUT); + gpioinfo("Writing %d\n", (int)value); + + stm32_gpiowrite(g_gpiooutputs[stm32gpio->id], value); +#endif + + FAR struct phyplus_gpio_dev_s *phyplus_gpout = + (FAR struct phyplus_gpio_dev_s *)dev; + + DEBUGASSERT(phyplus_gpout != NULL); + DEBUGASSERT(phyplus_gpout->idx < GPIO_NUM); + gpioinfo("Writing %d\n", (int)value); + + hal_gpio_write(phyplus_gpout->idx, value); + + return 0; +} + +static int phyplus_gpint_read(FAR struct gpio_dev_s *dev, FAR bool *value) +{ +#if 0 + FAR struct stm32gpint_dev_s *stm32gpint = + (FAR struct stm32gpint_dev_s *)dev; + + DEBUGASSERT(stm32gpint != NULL && value != NULL); + DEBUGASSERT(stm32gpint->stm32gpio.id < BOARD_NGPIOINT); + gpioinfo("Reading int pin...\n"); + + *value = stm32_gpioread(g_gpiointinputs[stm32gpint->stm32gpio.id]); +#endif + + FAR struct phyplus_gpio_dev_s *phyplus_gpint = + (FAR struct phyplus_gpio_dev_s *)dev; + + DEBUGASSERT(phyplus_gpint != NULL && value != NULL); + DEBUGASSERT(phyplus_gpint->idx < GPIO_NUM); + gpioinfo("Reading int pin...\n"); + + *value = hal_gpio_read(phyplus_gpint->idx); + + return 0; +} + +static pin_interrupt_t phyplus_gpint_callback_register + (FAR struct gpio_dev_s *dev, uint8_t pin) +{ + return 0; +} + +static int phyplus_gpint_attach(FAR struct gpio_dev_s *dev, + pin_interrupt_t callback) +{ +#if 0 + /* do the regist callback things... */ + + FAR struct stm32gpint_dev_s *stm32gpint = + (FAR struct stm32gpint_dev_s *)dev; + + gpioinfo("Attaching the callback\n"); + + /* Make sure the interrupt is disabled */ + + stm32_gpiosetevent(g_gpiointinputs[stm32gpint->stm32gpio.id], false, + false, false, NULL, NULL); + + gpioinfo("Attach %p\n", callback); + stm32gpint->callback = callback; +#endif + + FAR struct phyplus_gpio_dev_s *phyplus_gpint = + (FAR struct phyplus_gpio_dev_s *)dev; + + gpioinfo("Attaching the callback\n"); + + /* Make sure the interrupt is disabled */ + + gpioinfo("Attach %p\n", callback); + phyplus_gpint->callback = callback; + + return 0; +} + +static int phyplus_gpint_enable(FAR struct gpio_dev_s *dev, bool enable) +{ +#if 0 + FAR struct stm32gpint_dev_s *stm32gpint = + (FAR struct stm32gpint_dev_s *)dev; + + if (enable) + { + if (stm32gpint->callback != NULL) + { + gpioinfo("Enabling the interrupt\n"); + + /* Configure the interrupt for rising edge */ + + stm32_gpiosetevent(g_gpiointinputs[stm32gpint->stm32gpio.id], + true, false, false, stm32gpio_interrupt, + &g_gpint[stm32gpint->stm32gpio.id]); + } + } + else + { + gpioinfo("Disable the interrupt\n"); + stm32_gpiosetevent(g_gpiointinputs[stm32gpint->stm32gpio.id], + false, false, false, NULL, NULL); + } +#endif + + return 0; +} + +static int phyplus_gpio_param_check( + FAR struct phyplus_gpio_param_s *phyplus_gpio_param) +{ + if (phyplus_gpio_param->pin_idx > NUMBER_OF_PINS) + { + return -PPlus_ERR_INVALID_PARAM; + } + + if (phyplus_gpio_param->mode > PHYPLUS_GPIO_INTERRUPT) + { + return -PPlus_ERR_INVALID_PARAM; + } + + if (phyplus_gpio_param->trig_mode > POL_RISING) + { + return -PPlus_ERR_INVALID_PARAM; + } + + if (phyplus_gpio_param->default_val > PIN_HIGH) + { + return -PPlus_ERR_INVALID_PARAM; + } + + if (phyplus_gpio_param->pin_pull > GPIO_PULL_DOWN) + { + return -PPlus_ERR_INVALID_PARAM; + } + + return PPlus_SUCCESS; +} + +int phyplus_gpio_register(FAR struct phyplus_gpio_param_s + *phyplus_gpio_param) +{ + int ret; + int pin_idx = 0; + ret = phyplus_gpio_param_check(phyplus_gpio_param); + if (0 != ret) + { + return -EPERM; + } + + pin_idx = phyplus_gpio_param->pin_idx; + if (phyplus_gpio_param->mode == PHYPLUS_GPIO_INPUT) + { + g_phyplus_gpio_dev[pin_idx].gpio.gp_pintype = GPIO_INPUT_PIN; + g_phyplus_gpio_dev[pin_idx].gpio.gp_ops = &gpin_ops; + g_phyplus_gpio_dev[pin_idx].idx = pin_idx; + } + else if (phyplus_gpio_param->mode == PHYPLUS_GPIO_OUTPUT) + { + g_phyplus_gpio_dev[pin_idx].gpio.gp_pintype = GPIO_OUTPUT_PIN; + g_phyplus_gpio_dev[pin_idx].gpio.gp_ops = &gpout_ops; + g_phyplus_gpio_dev[pin_idx].idx = pin_idx; + } + else if (phyplus_gpio_param->mode == PHYPLUS_GPIO_INTERRUPT) + { + g_phyplus_gpio_dev[pin_idx].gpio.gp_pintype = GPIO_INTERRUPT_PIN; + g_phyplus_gpio_dev[pin_idx].gpio.gp_ops = &gpint_ops; + g_phyplus_gpio_dev[pin_idx].idx = pin_idx; + } + + hal_gpio_pull_set(pin_idx, phyplus_gpio_param->pin_pull); + gpio_pin_register(&g_phyplus_gpio_dev[pin_idx].gpio, pin_idx); + return PPlus_SUCCESS; +} + +int phyplus_gpio_unregister(FAR struct phyplus_gpio_param_s + *phyplus_gpio_param) +{ + int ret; + gpio_pin_unregister( + &g_phyplus_gpio_dev[phyplus_gpio_param->pin_idx].gpio, + phyplus_gpio_param->pin_idx); + return PPlus_SUCCESS; +} + +int phyplus_gpio_init(void) +{ + hal_low_power_io_init(); + + hal_gpio_init(); + return PPlus_SUCCESS; +} + +#endif diff --git a/arch/arm/src/phy62xx/phyplus_gpio.h b/arch/arm/src/phy62xx/phyplus_gpio.h new file mode 100644 index 00000000000..27d2b8a6dab --- /dev/null +++ b/arch/arm/src/phy62xx/phyplus_gpio.h @@ -0,0 +1,58 @@ +/**************************************************************************** + * arch/arm/src/phy62xx/phyplus_gpio.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_SRC_INCLUDE_PHY62XX_PHYPLUS_GPIO_H +#define __ARCH_SRC_INCLUDE_PHY62XX_PHYPLUS_GPIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define PHYPLUS_GPIO_INPUT 0 +#define PHYPLUS_GPIO_OUTPUT 1 +#define PHYPLUS_GPIO_INTERRUPT 2 +#define PIN_LOW 0 +#define PIN_HIGH 1 + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +struct phyplus_gpio_param_s +{ + uint8_t pin_idx; /* range to 23 */ + uint8_t mode; /* input,output,interrupt */ + uint8_t trig_mode; /* raise, fall */ + uint8_t default_val; /* high, low */ + uint8_t pin_pull; /* gpio_pupd_e */ +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif + diff --git a/arch/arm/src/phy62xx/phyplus_stub.c b/arch/arm/src/phy62xx/phyplus_stub.c new file mode 100644 index 00000000000..55e0bc6a322 --- /dev/null +++ b/arch/arm/src/phy62xx/phyplus_stub.c @@ -0,0 +1,817 @@ +/**************************************************************************** + * arch/arm/src/phy62xx/phyplus_stub.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include 52 +#include +#include "phyplus_stub.h" +#include "phyplus_gpio.h" +#include "gpio.h" +#include "phyplus_tim.h" +#include "timer.h" +#include "mcu_phy_bumbee.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CMD_LEN 128 + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int phyplus_stub_open(FAR struct file *filep); +static int phyplus_stub_close(FAR struct file *filep); +static ssize_t phyplus_stub_read( + FAR struct file *filep, FAR char *buffer, size_t buflen); +static ssize_t phyplus_stub_write( + FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static off_t phyplus_stub_seek( + FAR struct file *filep, off_t offset, int whence); +static int phyplus_stub_ioctl( + FAR struct file *filep, int cmd, unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_stub_drvrops = +{ + phyplus_stub_open, /* open */ + phyplus_stub_close, /* close */ + phyplus_stub_read, /* read */ + phyplus_stub_write, /* write */ + phyplus_stub_seek, /* seek */ + phyplus_stub_ioctl, /* ioctl */ + NULL /* poll */ +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , NULL /* unlink */ +#endif +}; +static struct gpio_dev_s stub_dev; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + + /* fprintf(stderr, "USAGE: %s [] [-idx <1-23>]" + * "[-mode ] [-trig ]" + * "[-val ] [-pull ]", progname); + */ + +static int phyplus_parse_gpio_param(char *buff, + struct phyplus_gpio_param_s *gpio_param) +{ + char *ptr; + int temp_val; + + /* setup default params.. */ + + gpio_param->pin_idx = 0; + gpio_param->mode = PHYPLUS_GPIO_INPUT; + gpio_param->trig_mode = POL_FALLING; + gpio_param->default_val = 0; + gpio_param->pin_pull = GPIO_FLOATING; + ptr = strtok(buff, ","); + if (ptr != NULL) + { + if (0 == strncmp("idx", ptr, 3)) + { + ptr = ptr + 4; + temp_val = atoi(ptr); + if ((temp_val < 0) || (temp_val >= GPIO_NUM)) + { + fprintf(stderr, "parse gpio_idx failure"); + return -1; + } + else + { + gpio_param->pin_idx = temp_val; + } + } + else if(0 == strncmp("mode", ptr, 4)) + { + ptr = ptr + 5; + if (0 == strncmp(ptr, "input", 5)) + { + gpio_param->mode = PHYPLUS_GPIO_INPUT; + } + else if (0 == strncmp(ptr, "output", 6)) + { + gpio_param->mode = PHYPLUS_GPIO_OUTPUT; + } + else if (0 == strncmp(ptr, "interrupt", 9)) + { + gpio_param->mode = PHYPLUS_GPIO_INTERRUPT; + } + else + { + fprintf(stderr, "parse gpio_mode failure"); + return -1; + } + } + else if (0 == strncmp("trig", ptr, 4)) + { + ptr = ptr + 5; + if (0 == strncmp(ptr, "raise", 5)) + { + gpio_param->trig_mode = POL_RISING; + } + else if (0 == strncmp(ptr, "fall", 4)) + { + gpio_param->trig_mode = POL_FALLING; + } + else + { + fprintf(stderr, "parse gpio_trig failure"); + return -1; + } + } + else if (0 == strncmp("val", ptr, 3)) + { + ptr = ptr + 4; + temp_val = atoi(ptr); + if ((temp_val < 0) || (temp_val > 2)) + { + fprintf(stderr, "parse gpio_default_val failure"); + return -1; + } + else + { + gpio_param->pin_idx = temp_val; + } + } + else if (strncmp(ptr, "pull", 4) == 0) + { + ptr = ptr + 5; + if (0 == strncmp(ptr, "float", 5)) + { + gpio_param->pin_pull = GPIO_FLOATING; + } + else if (0 == strncmp(ptr, "strong_up", 9)) + { + gpio_param->pin_pull = GPIO_PULL_UP_S; + } + else if (0 == strncmp(ptr, "up", 2)) + { + gpio_param->pin_pull = GPIO_PULL_UP; + } + else if (0 == strncmp(ptr, "down", 4)) + { + gpio_param->pin_pull = GPIO_PULL_DOWN; + } + else + { + fprintf(stderr, "parse gpio_pull failure"); + return -1; + } + } + } + else + { + fprintf(stderr, "parse first param failure"); + return -1; + } + + while (ptr = strtok(NULL, ",")) + { + if (0 == strncmp("idx", ptr, 3)) + { + ptr = ptr + 4; + temp_val = atoi(ptr); + if ((temp_val < 0) || (temp_val >= GPIO_NUM)) + { + fprintf(stderr, "parse gpio_idx failure"); + return -1; + } + else + { + gpio_param->pin_idx = temp_val; + } + } + else if (0 == strncmp("mode", ptr, 4)) + { + ptr = ptr + 5; + if (0 == strncmp(ptr, "input", 5)) + { + gpio_param->mode = PHYPLUS_GPIO_INPUT; + } + else if (0 == strncmp(ptr, "output", 6)) + { + gpio_param->mode = PHYPLUS_GPIO_OUTPUT; + } + else if (0 == strncmp(ptr, "interrupt", 9)) + { + gpio_param->mode = PHYPLUS_GPIO_INTERRUPT; + } + else + { + fprintf(stderr, "parse gpio_mode failure"); + return -1; + } + } + else if (0 == strncmp("trig", ptr, 4)) + { + ptr = ptr + 5; + if (0 == strncmp(ptr, "raise", 5)) + { + gpio_param->trig_mode = POL_RISING; + } + else if (0 == strncmp(ptr, "fall", 4)) + { + gpio_param->trig_mode = POL_FALLING; + } + else + { + fprintf(stderr, "parse gpio_trig failure"); + return -1; + } + } + else if (0 == strncmp("val", ptr, 3)) + { + ptr = ptr + 4; + temp_val = atoi(ptr); + if ((temp_val < 0) || (temp_val > 2)) + { + fprintf(stderr, "parse gpio_default_val failure"); + return -1; + } + else + { + gpio_param->pin_idx = temp_val; + } + } + else if (strncmp(ptr, "pull", 4) == 0) + { + ptr = ptr + 5; + if (0 == strncmp(ptr, "float", 5)) + { + gpio_param->pin_pull = GPIO_FLOATING; + } + else if (0 == strncmp(ptr, "strong_up", 9)) + { + gpio_param->pin_pull = GPIO_PULL_UP_S; + } + else if (0 == strncmp(ptr, "up", 2)) + { + gpio_param->pin_pull = GPIO_PULL_UP; + } + else if (0 == strncmp(ptr, "down", 4)) + { + gpio_param->pin_pull = GPIO_PULL_DOWN; + } + else + { + fprintf(stderr, "parse gpio_pull failure"); + return -1; + } + } + } + + return 0; +} + +/* fprintf(stderr, "USAGE: %s [] [idx= <1-6>]" */ + +/* "[mode=] [val=<0-2^23>]" */ + +/* " [en=] [mask=]", progname); */ + +#if 0 +static int phyplus_parse_timer_param( + char *buff, struct AP_TIM_TYPEDEF *timer_param) +{ + char *ptr; + int temp_val; + + /* setup default params.. */ + + timer_param->idx = 0; + timer_param->enable = 0; + timer_param->mask = 0; + timer_param->mode = 0; /* 0:freerun, 1:count */ + timer_param->value = 0; + + ptr = strtok(buff, ","); + if (ptr != NULL) + { + if (0 == strncmp("idx", ptr, 3)) + { + ptr = ptr + 4; + temp_val = atoi(ptr); + if ((temp_val < 1) || (temp_val > 6)) + { + fprintf(stderr, "parse timer_idx failure"); + return -1; + } + else + { + timer_param->idx = temp_val; + } + } + else if (0 == strncmp("mode", ptr, 4)) + { + ptr = ptr + 5; + if (0 == strncmp(ptr, "freerun", 7)) + { + timer_param->mode = 0; + } + else if (0 == strncmp(ptr, "count", 5)) + { + timer_param->mode = 1; + } + else + { + fprintf(stderr, "parse timer_mode failure"); + return -1; + } + } + else if (0 == strncmp("enable", ptr, 6)) + { + ptr = ptr + 7; + if (0 == strncmp(ptr, "true", 4)) + { + timer_param->mode = 1; + } + else if (0 == strncmp(ptr, "false", 5)) + { + timer_param->mode = 0; + } + else + { + fprintf(stderr, "parse enable failure"); + return -1; + } + } + else if (0 == strncmp("mask", ptr, 4)) + { + ptr = ptr + 5; + if (0 == strncmp(ptr, "true", 4)) + { + timer_param->mask = 1; + } + else if (0 == strncmp(ptr, "false", 5)) + { + timer_param->mask = 0; + } + else + { + fprintf(stderr, "parse mask failure"); + return -1; + } + } + else if (0 == strncmp("value", ptr, 3)) + { + ptr = ptr + 4; + temp_val = atoi(ptr); + timer_param->idx = temp_val; + } + } + + while (ptr = strtok(NULL, ",")) + { + if (ptr != NULL) + { + if (0 == strncmp("idx", ptr, 3)) + { + ptr = ptr + 4; + temp_val = atoi(ptr); + if ((temp_val < 1) || (temp_val > 6)) + { + fprintf(stderr, "parse timer_idx failure"); + return -1; + } + else + { + timer_param->idx = temp_val; + } + } + else if (0 == strncmp("mode", ptr, 4)) + { + ptr = ptr + 5; + if (0 == strncmp(ptr, "freerun", 7)) + { + timer_param->mode = 0; + } + else if (0 == strncmp(ptr, "count", 5)) + { + timer_param->mode = 1; + } + else + { + fprintf(stderr, "parse timer_mode failure"); + return -1; + } + } + else if (0 == strncmp("enable", ptr, 6)) + { + ptr = ptr + 7; + if (0 == strncmp(ptr, "true", 4)) + { + timer_param->mode = 1; + } + else if (0 == strncmp(ptr, "false", 5)) + { + timer_param->mode = 0; + } + else + { + fprintf(stderr, "parse enable failure"); + return -1; + } + } + else if (0 == strncmp("mask", ptr, 4)) + { + ptr = ptr + 5; + if (0 == strncmp(ptr, "true", 4)) + { + timer_param->mask = 1; + } + else if (0 == strncmp(ptr, "false", 5)) + { + timer_param->mask = 0; + } + else + { + fprintf(stderr, "parse mask failure"); + return -1; + } + } + else if (0 == strncmp("value", ptr, 3)) + { + ptr = ptr + 4; + temp_val = atoi(ptr); + timer_param->idx = temp_val; + } + } + } + + return 0; +} +#endif + +static int phyplus_parse_params_and_action(char *buff) +{ + char *p = buff; + int ret = 0; + struct phyplus_gpio_param_s gpio_param; +#if 0 + struct AP_TIM_TYPEDEF timer_param; +#endif + if (0 == strncmp(buff, "reg_gpio", 8)) + { + p += 9; + ret = phyplus_parse_gpio_param(p, &gpio_param); + if (0 != ret) + { + fprintf(stderr, "parse gpio param failure"); + return -1; + } + + ret = phyplus_gpio_register(&gpio_param); + if (0 != ret) + { + fprintf(stderr, "gpio register failure"); + return -1; + } + } + else if (0 == strncmp(buff, "unreg_gpio", 10)) + { + p += 11; + ret = phyplus_parse_gpio_param(p, &gpio_param); + if (0 != ret) + { + fprintf(stderr, "parse gpio param failure"); + return -1; + } + + ret = phyplus_gpio_register(&gpio_param); + if (0 != ret) + { + fprintf(stderr, "gpio unregister failure"); + return -1; + } + } +#if 0 + else if (0 == strncmp(buff, "reg_timer", 9)) + { + p += 10; + ret = phyplus_parse_timer_param(p, &timer_param); + if (0 != ret) + { + fprintf(stderr, "parse timer param failure"); + return -1; + } + + ret = phyplus_timer_register(&gpio_param); + if (0 != ret) + { + fprintf(stderr, "timer register failure"); + return -1; + } + } + else if (0 == strncmp(buff, "unreg_timer", 11)) + { + p += 12; + ret = phyplus_parse_timer_param(p, &timer_param); + if (0 != ret) + { + fprintf(stderr, "parse timer param failure"); + return -1; + } + + ret = phyplus_timer_register(&timer_param); + if (0 != ret) + { + fprintf(stderr, "timer unregister failure"); + return -1; + } + } +#endif + + return 0; +} + +/**************************************************************************** + * Name: phyplus_stub_open + * + * Description: + * Standard character driver open method. + * + ****************************************************************************/ + +static int phyplus_stub_open(FAR struct file *filep) +{ + filep->f_pos = 0; + return OK; +} + +/**************************************************************************** + * Name: phyplus_stub_close + * + * Description: + * Standard character driver close method. + * + ****************************************************************************/ + +static int phyplus_stub_close(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: phyplus_gpio_read + * + * Description: + * Standard character driver read method. + * + ****************************************************************************/ + +static ssize_t phyplus_stub_read( + FAR struct file *filep, FAR char *buffer, size_t buflen) +{ + buffer[0] = 'T'; + buffer[1] = 'E'; + buffer[2] = 'S'; + buffer[3] = 'T'; + buffer[4] = '\0'; + filep->f_pos = 0; + + /* buffer[0] += '0'; + * filep->f_pos = 1; + */ + + return 1; +} + +/**************************************************************************** + * Name: phyplus_stub_write + * + * Description: + * Standard character driver write method. + * + * REVISIT: The read() method obeys the semantics of a file position and + * requires re-opening the driver or seeking to address 0. The write() + * method does not. This is an inconsistency. + * + ****************************************************************************/ + +static char phyplus_cmd[CMD_LEN]; + +static ssize_t phyplus_stub_write(FAR struct file *filep, + FAR const char *buffer, size_t buflen) +{ + FAR struct inode *inode; + FAR struct gpio_dev_s *dev; + int ret; + bool val; + static int cmd_pos = 0; + DEBUGASSERT(filep != NULL && filep->f_inode != NULL); + inode = filep->f_inode; + DEBUGASSERT(inode->i_private != NULL); + dev = inode->i_private; + + /* Verify that a buffer containing data was provided */ + + DEBUGASSERT(buffer != NULL); + + if (1 == buflen) + { + if ('#' == buffer[0]) + { + phyplus_cmd[cmd_pos] = '\0'; + ret = phyplus_parse_params_and_action(phyplus_cmd); + memset(phyplus_cmd, 0x0, CMD_LEN); + if (ret != 0) + { + fprintf(stderr, "phyplus action failed"); + } + } + else + { + phyplus_cmd[cmd_pos] = buffer[0]; + cmd_pos++; + } + } + + return 0; +} + +/**************************************************************************** + * Name: phyplus_stub_seek + * + * Description: + * Reset read flag on seek to 0 + * + * REVISIT: Seeking address zero is required to return addition GPIO + * values from read(). This, however, is an un-natural use of a file + * position since there is no file position associated with a GPIO. It + * also makes the read() method difficult to use programmatically. + * + ****************************************************************************/ + +static off_t phyplus_stub_seek(FAR struct file *filep, + off_t offset, int whence) +{ + /* Only SEEK_SET is supported, return ENOSYS for other valid options */ + + if (whence == SEEK_CUR || whence == SEEK_END) + { + return -ENOSYS; + } + + /* Only Offset zero makes sense, POSIX permits setting the file position + * beyond the end of the file, but that makes little sense here. + */ + + if (whence == SEEK_SET && offset == 0) + { + filep->f_pos = 0; + return 0; + } + + return -EINVAL; +} + +/**************************************************************************** + * Name: phyplus_stub_ioctl + * + * Description: + * Standard character driver ioctl method. + * + ****************************************************************************/ + +static int phyplus_stub_ioctl(FAR struct file *filep, + int cmd, unsigned long arg) +{ + FAR struct inode *inode; + FAR struct gpio_dev_s *dev; + irqstate_t flags; + pid_t pid; + int ret; + int i; + int j = 0; + + DEBUGASSERT(filep != NULL && filep->f_inode != NULL); + inode = filep->f_inode; + DEBUGASSERT(inode->i_private != NULL); + dev = inode->i_private; + + FAR struct phyplus_gpio_param_s *phyplus_gpio = + (FAR struct phyplus_gpio_param_s *)arg; +#if 0 + FAR struct phyplus_timer_param_s *phyplus_timer = + (FAR struct phyplus_timer_param_s *)arg; +#endif + + switch (cmd) + { + case PHYPLUS_GPIO_REGISTER: + ret = phyplus_gpio_register(phyplus_gpio); + break; + + case PHYPLUS_GPIO_UNREGISTER: + ret = phyplus_gpio_unregister(phyplus_gpio); + break; + case PHYPLUS_TIMER_REGISTER: + + /* ret = phyplus_timer_register(phyplus_timer); */ + + break; + case PHYPLUS_TIMER_UNREGISTER: + + /* ret = phyplus_timer_unregister(phyplus_timer); */ + + break; + + /* Unrecognized command */ + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: gpio_pin_register + * + * Description: + * Register GPIO pin device driver. + * + * - Input pin types will be registered at /dev/gpinN + * + * Where N is the provided minor number in the range of 0-99. + * + ****************************************************************************/ + +int phyplus_stub_register(FAR struct gpio_dev_s *dev) +{ + char devname[16]; + int ret; + snprintf(devname, 16, "/dev/phyplus"); + return register_driver(devname, &g_stub_drvrops, 0666, dev); +} + +/**************************************************************************** + * Name: gpio_pin_unregister + * + * Description: + * Unregister GPIO pin device driver. + * + * - Input pin types will be registered at /dev/gpinN + * - Output pin types will be registered at /dev/gpoutN + * - Interrupt pin types will be registered at /dev/gpintN + * + * Where N is the provided minor number in the range of 0-99. + * + * + ****************************************************************************/ + +void phyplus_stub_unregister(FAR struct gpio_dev_s *dev) +{ + char devname[16]; + snprintf(devname, 16, "/dev/phyplus"); + unregister_driver(devname); +} + +int phyplus_stub_init(void) +{ + int ret = 0; + struct gpio_dev_s stub_dev; + ret = phyplus_stub_register(&stub_dev); + return ret; +} + diff --git a/arch/arm/src/phy62xx/phyplus_stub.h b/arch/arm/src/phy62xx/phyplus_stub.h new file mode 100644 index 00000000000..7ecc982e279 --- /dev/null +++ b/arch/arm/src/phy62xx/phyplus_stub.h @@ -0,0 +1,57 @@ +#ifndef __INCLUDE_NUTTX_PHYPLUS_STUB_H +#define __INCLUDE_NUTTX_PHYPLUS_STUB_H + + + +enum phyplus_stub_e +{ + PHYPLUS_GPIO_REGISTER =0 , + PHYPLUS_GPIO_UNREGISTER, + PHYPLUS_TIMER_REGISTER, + PHYPLUS_TIMER_UNREGISTER, + PHYPLUS_MAX +}; + +/* +struct stub_operations_s +{ + + CODE int (*go_read)(FAR struct stub_dev_s *dev, FAR bool *value); + CODE int (*go_write)(FAR struct stub_dev_s *dev, bool value); + CODE int (*go_attach)(FAR struct stub_dev_s *dev, pin_interrupt_t callback); + CODE int (*go_enable)(FAR struct stub_dev_s *dev, bool enable); + CODE int (*go_setpintype)(FAR struct stub_dev_s *dev, enum stub_pintype_e pintype); +}; + +struct stub_dev_s +{ + FAR const struct stub_operations_s *gp_ops; +}; + + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + + +int stub_pin_register(FAR struct stub_dev_s *dev); + + + +void stub_pin_unregister(FAR struct stub_dev_s *dev); + + +#ifdef __cplusplus +} +#endif + +#endif +*/ + +//int phyplus_stub_init(void); + +#endif diff --git a/arch/arm/src/phy62xx/phyplus_tim.c b/arch/arm/src/phy62xx/phyplus_tim.c new file mode 100644 index 00000000000..a7e60328789 --- /dev/null +++ b/arch/arm/src/phy62xx/phyplus_tim.c @@ -0,0 +1,608 @@ +/**************************************************************************** + * arch/arm/src/phyplus/phyplus_tim.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "phyplus_tim.h" + +#include "mcu_phy_bumbee.h" +#include "arm_arch.h" + +struct phyplus_tim_priv_s +{ + const struct phyplus_tim_ops_s *ops; + uint32_t base; /* Timer register base address */ + bool inuse; /* Flag indicating if the timer is in use */ + // AP_TIM_TypeDef *timer; //chrade add 2021_0922 +}; + +/**************************************************************************** + * Private Function prototypes + ****************************************************************************/ +void phyplus_tim_start(FAR struct phyplus_tim_dev_s *dev); +void phyplus_tim_stop(FAR struct phyplus_tim_dev_s *dev); + +void phyplus_tim_clear(FAR struct phyplus_tim_dev_s *dev); +void phyplus_tim_setmode(FAR struct phyplus_tim_dev_s *dev, uint8_t mode); + +void phyplus_tim_getcounter(FAR struct phyplus_tim_dev_s *dev, uint32_t *value); +void phyplus_tim_setcounter(FAR struct phyplus_tim_dev_s *dev, uint32_t value); + +int phyplus_tim_setisr(FAR struct phyplus_tim_dev_s *dev, xcpt_t handler, void *arg); +void phyplus_tim_enableint(FAR struct phyplus_tim_dev_s *dev); +void phyplus_tim_disableint(FAR struct phyplus_tim_dev_s *dev); + +void phyplus_tim_ackint(FAR struct phyplus_tim_dev_s *dev); +//static int phyplus_tim_checkint(FAR struct phyplus_tim_dev_s *dev, int source); +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct phyplus_tim_ops_s phyplus_tim_ops = +{ + .start = phyplus_tim_start, //done.. + .stop = phyplus_tim_stop, //done.. + .clear = phyplus_tim_clear, //done.. + .setmode = phyplus_tim_setmode, //done.. + + .getcounter = phyplus_tim_getcounter, //done.. + .setcounter = phyplus_tim_setcounter, //done.. + + .setisr = phyplus_tim_setisr, //done.. + .enableint = phyplus_tim_enableint, + .disableint = phyplus_tim_disableint, + .ackint = phyplus_tim_ackint, +// .checkint = phyplus_tim_checkint +}; + +//#ifdef CONFIG_PHYPLUS_TIM1 +struct phyplus_tim_priv_s phyplus_tim1_priv = +{ + .ops = &phyplus_tim_ops, + .base = AP_TIM1, + .inuse = false, +}; +//#endif +//#ifdef CONFIG_PHYPLUS_TIM2 +struct phyplus_tim_priv_s phyplus_tim2_priv = +{ + .ops = &phyplus_tim_ops, + .base = AP_TIM2, + .inuse = false, +}; +//#endif + +//#ifdef CONFIG_PHYPLUS_TIM3 +struct phyplus_tim_priv_s phyplus_tim3_priv = +{ + .ops = &phyplus_tim_ops, + .base = AP_TIM3, + .inuse = false, +}; +//#endif + +//#ifdef CONFIG_PHYPLUS_TIM4 +struct phyplus_tim_priv_s phyplus_tim4_priv = +{ + .ops = &phyplus_tim_ops, + .base = AP_TIM4, + .inuse = false, +}; +//#endif + +//#ifdef CONFIG_PHYPLUS_TIM5 +struct phyplus_tim_priv_s phyplus_tim5_priv = +{ + .ops = &phyplus_tim_ops, + .base = AP_TIM5, + .inuse = false, +}; +//#endif + +//#ifdef CONFIG_PHYPLUS_TIM6 +struct phyplus_tim_priv_s phyplus_tim6_priv = +{ + .ops = &phyplus_tim_ops, + .base = AP_TIM6, + .inuse = false, +}; +//#endif + + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: phyplus_tim_getreg32 + * + * Description: + * Get a 32-bit register value by offset + * + ****************************************************************************/ + +//static uint32_t phyplus_tim_getreg32(FAR struct phyplus_tim_dev_s *dev, +// uint32_t offset) +uint32_t phyplus_tim_getreg32(FAR struct phyplus_tim_dev_s *dev, + uint32_t offset) +{ + DEBUGASSERT(dev); + + return getreg32(((struct phyplus_tim_priv_s *)dev)->base + offset); +} + + +/**************************************************************************** + * Name: phyplus_tim_putreg32 + * + * Description: + * Put a 32-bit register value by offset + * + ****************************************************************************/ + +//static void phyplus_tim_putreg32(FAR struct phyplus_tim_dev_s *dev, +// uint32_t offset, +// uint32_t value) +void phyplus_tim_putreg32(FAR struct phyplus_tim_dev_s *dev, + uint32_t offset, + uint32_t value) +{ + DEBUGASSERT(dev); + + putreg32(value, ((struct phyplus_tim_priv_s *)dev)->base + offset); +} + + +/**************************************************************************** + * Name: phyplus_tim_modifyreg32 + * + * Description: + * Modify a reg of 32 bits + * + ****************************************************************************/ + +//static void phyplus_tim_modifyreg32(FAR struct phyplus_tim_dev_s *dev, +// uint32_t offset, +// uint32_t clearbits, +// uint32_t setbits) +void phyplus_tim_modifyreg32(FAR struct phyplus_tim_dev_s *dev, + uint32_t offset, + uint32_t clearbits, + uint32_t setbits) +{ + DEBUGASSERT(dev); + + modifyreg32(((struct phyplus_tim_priv_s *)dev)->base + offset, + clearbits, setbits); +} + + +/**************************************************************************** + * Name: phyplus_tim_start + * + * Description: + * Releases the counter + * + ****************************************************************************/ +//done... +//static void phyplus_tim_start(FAR struct phyplus_tim_dev_s *dev) +void phyplus_tim_start(FAR struct phyplus_tim_dev_s *dev) +{ +syslog(LOG_ERR, "timer_enable\n"); + DEBUGASSERT(dev); + phyplus_tim_modifyreg32(dev, TIM_CONTROLREG_OFFSET, 0, TIM_ENABLE); +} + + +/**************************************************************************** + * Name: phyplus_tim_stop + * + * Description: + * Halts the counter + * + ****************************************************************************/ +//done... +//static void phyplus_tim_stop(FAR struct phyplus_tim_dev_s *dev) +void phyplus_tim_stop(FAR struct phyplus_tim_dev_s *dev) +{ +syslog(LOG_ERR, "timer_disable\n"); + DEBUGASSERT(dev); + phyplus_tim_modifyreg32(dev, TIM_CONTROLREG_OFFSET, TIM_ENABLE, 0); +} + +/**************************************************************************** + * Name: phyplus_tim_clear + * + * Description: + * Set the counter to zero instantly + * + ****************************************************************************/ + +//static void phyplus_tim_clear(FAR struct phyplus_tim_dev_s *dev) +void phyplus_tim_clear(FAR struct phyplus_tim_dev_s *dev) +{ + uint32_t clear_value = 0; + DEBUGASSERT(dev); + phyplus_tim_setcounter(dev, clear_value); + phyplus_tim_getreg32(dev, TIM_EOI_OFFSET); //clear the timer. +} + + +/**************************************************************************** + * Name: phyplus_tim_setmode + * + * Description: + * Set counter mode (up/down) + * + ****************************************************************************/ +//done... +//static void phyplus_tim_setmode(FAR struct phyplus_tim_dev_s *dev, uint8_t mode) +void phyplus_tim_setmode(FAR struct phyplus_tim_dev_s *dev, uint8_t mode) +{ + DEBUGASSERT(dev); + + if(mode==PHYPLUS_TIM_FREERUN) + { + phyplus_tim_modifyreg32(dev, TIM_CONTROLREG_OFFSET, TIM_MODE, 0); + } + else if(mode==PHYPLUS_TIM_COUNT) + { + phyplus_tim_modifyreg32(dev, TIM_CONTROLREG_OFFSET, 0, TIM_MODE); + } +} + + +/**************************************************************************** + * Name: phyplus_tim_getcounter + * + * Description: + * Get the current counter value + * + ****************************************************************************/ +//done... +//static void phyplus_tim_getcounter(FAR struct phyplus_tim_dev_s *dev, uint32_t *value) +void phyplus_tim_getcounter(FAR struct phyplus_tim_dev_s *dev, uint32_t *value) +{ + + DEBUGASSERT(dev); + + *value = phyplus_tim_getreg32(dev, TIM_COUNT_OFFSET); + +} + +/**************************************************************************** + * Name: phyplus_tim_setcounter + * + * Description: + * Set the value to be loaded to the counter + * If you want the counter to be loaded at an alarm, enable the alarm and + * the auto-reload before. + * I you want the counter to be loaded instantly, call phyplus_tim_reload_now + * after. + * + ****************************************************************************/ +//done... +//static void phyplus_tim_setcounter(FAR struct phyplus_tim_dev_s *dev, uint32_t value) +void phyplus_tim_setcounter(FAR struct phyplus_tim_dev_s *dev, uint32_t value) +{ + DEBUGASSERT(dev); + + phyplus_tim_putreg32(dev, TIM_COUNT_OFFSET, (uint32_t)value); + +} + +void phyplus_tim_getcurrent(FAR struct phyplus_tim_dev_s *dev, uint32_t *value) +{ + DEBUGASSERT(dev); + + *value = phyplus_tim_getreg32(dev, TIM_CURRENT_OFFSET); + +} + +void phyplus_tim_getcontrolreg(FAR struct phyplus_tim_dev_s *dev, uint32_t *value) +{ + DEBUGASSERT(dev); + + *value = phyplus_tim_getreg32(dev, TIM_CONTROLREG_OFFSET); + +} + +/**************************************************************************** + * Name: phyplus_tim_setisr + * + * Description: + * Allocates a level CPU Interrupt, connects the peripheral source to this + * Interrupt, register the callback and enables the Interruption. It does + * opposite if the handler and arg are NULL. + * + ****************************************************************************/ +//done.. +//static int phyplus_tim_setisr(FAR struct phyplus_tim_dev_s *dev, xcpt_t handler, FAR void *arg) +int phyplus_tim_setisr(FAR struct phyplus_tim_dev_s *dev, xcpt_t handler, FAR void *arg) +{ + FAR struct phyplus_tim_priv_s *tim = NULL; + int ret = OK; + int vectorno; + + DEBUGASSERT(dev); + + tim = (FAR struct phyplus_tim_priv_s *)dev; + + + + if(AP_TIM1==((struct phyplus_tim_priv_s *)dev)->base) + { + vectorno = PHY62XX_IRQ_TIM1_IRQn; + } + else if(AP_TIM2==((struct phyplus_tim_priv_s *)dev)->base) + { + vectorno = PHY62XX_IRQ_TIM2_IRQn; + } + else if(AP_TIM3==((struct phyplus_tim_priv_s *)dev)->base) + { + vectorno = PHY62XX_IRQ_TIM3_IRQn; + } + else if(AP_TIM4==((struct phyplus_tim_priv_s *)dev)->base) + { + vectorno = PHY62XX_IRQ_TIM4_IRQn; + } + else if(AP_TIM5==((struct phyplus_tim_priv_s *)dev)->base) + { + vectorno = PHY62XX_IRQ_TIM5_IRQn; + } + else if(AP_TIM6==((struct phyplus_tim_priv_s *)dev)->base) + { + vectorno = PHY62XX_IRQ_TIM6_IRQn; + }else{ + return -EINVAL; + } + +/* + switch (((struct phyplus_tim_priv_s *)dev)->base) + { +//#ifdef CONFIG_PHYPLUS_TIM1 + case AP_TIM1: + vectorno = PHY62XX_IRQ_TIM1_IRQn; + break; +//#endif +//#ifdef CONFIG_PHYPLUS_TIM2 + case AP_TIM2: + vectorno = PHY62XX_IRQ_TIM2_IRQn; + break; +//#endif +//#ifdef CONFIG_PHYPLUS_TIM3 + case AP_TIM3: + vectorno = PHY62XX_IRQ_TIM3_IRQn; + break; +//#endif +//#ifdef CONFIG_PHYPLUS_TIM4 + case AP_TIM4: + vectorno = PHY62XX_IRQ_TIM4_IRQn; + break; +//#endif +//#ifdef CONFIG_PHYPLUS_TIM5 + case AP_TIM5: + vectorno = PHY62XX_IRQ_TIM5_IRQn; + break; +//#endif +//#ifdef CONFIG_PHYPLUS_TIM6 + case AP_TIM6: + vectorno = PHY62XX_IRQ_TIM6_IRQn; + break; +//#endif + + default: + return -EINVAL; + } +*/ + + + /* Disable interrupt when callback is removed */ + + if (!handler) + { + up_disable_irq(vectorno); + irq_detach(vectorno); + return OK; + } + + /* Otherwise set callback and enable interrupt */ + + irq_attach(vectorno, handler, arg); + up_enable_irq(vectorno); + + return OK; + +} + + +/**************************************************************************** + * Name: phyplus_tim_enableint + * + * Description: + * Enables a level Interrupt at the alarm if it is set. + * + ****************************************************************************/ +//done... +//static void phyplus_tim_enableint(FAR struct phyplus_tim_dev_s *dev) +void phyplus_tim_enableint(FAR struct phyplus_tim_dev_s *dev) +{ + DEBUGASSERT(dev); + + /* Set the level interrupt bit */ + phyplus_tim_modifyreg32(dev, TIM_CURRENT_OFFSET, 0, TIM_MASK); + +} + +/**************************************************************************** + * Name: phyplus_tim_disableint + * + * Description: + * Disables a level Interrupt at the alarm if it is set. + * + ****************************************************************************/ + +//static void phyplus_tim_disableint(FAR struct phyplus_tim_dev_s *dev) +void phyplus_tim_disableint(FAR struct phyplus_tim_dev_s *dev) +{ + DEBUGASSERT(dev); + + /* Clear the level interrupt bit */ + phyplus_tim_modifyreg32(dev, TIM_CURRENT_OFFSET, TIM_MASK, 0); + +} + +/**************************************************************************** + * Name: phyplus_tim_ackint + * + * Description: + * + ****************************************************************************/ + +//static void phyplus_tim_ackint(FAR struct phyplus_tim_dev_s *dev) +void phyplus_tim_ackint(FAR struct phyplus_tim_dev_s *dev) +{ + DEBUGASSERT(dev); + + /* Clear the level interrupt bit */ + phyplus_tim_getreg32(dev, TIM_EOI_OFFSET); + +} + +/**************************************************************************** + * Name: phyplus_tim_init + * + * Description: + * Initialize TIMER device. + * + ****************************************************************************/ + +FAR struct phyplus_tim_dev_s *phyplus_tim_init(int timer) +{ + FAR struct phyplus_tim_priv_s *tim = NULL; + + /* First, take the data structure associated with the timer instance */ + syslog(LOG_ERR, "phyplus_tim_init 1\n"); + switch (timer) + { +//#ifdef CONFIG_PHYPLUS_TIM1 + case 1: + { + tim = &phyplus_tim1_priv; + break; + } +//#endif + +//#ifdef CONFIG_PHYPLUS_TIM2 + case 2: + { + tim = &phyplus_tim2_priv; + break; + } +//#endif + +//#ifdef CONFIG_PHYPLUS_TIM3 + case 3: + { + tim = &phyplus_tim3_priv; + break; + } +//#endif + +//#ifdef CONFIG_PHYPLUS_TIM4 + case 4: + { + tim = &phyplus_tim4_priv; + break; + } +//#endif + +//#ifdef CONFIG_PHYPLUS_TIM5 + case 5: + { + tim = &phyplus_tim5_priv; + break; + } +//#endif + +//#ifdef CONFIG_PHYPLUS_TIM6 + case 6: + { + tim = &phyplus_tim6_priv; + break; + } +//#endif + + default: + { + tmrerr("ERROR: unsupported TIMER %d\n", timer); + goto errout; + } + } + + /* Verify if it is in use */ + + if (tim->inuse == false) + { + tim->inuse = true; /* If it was not, now it is */ + } + else + { + tmrerr("ERROR: TIMER %d is already in use\n", timer); + tim = NULL; + } + syslog(LOG_ERR, "phyplus_tim_init 2\n"); + errout: + return (FAR struct phyplus_tim_dev_s *)tim; +} + +/**************************************************************************** + * Name: esp32_tim_deinit + * + * Description: + * Deinit TIMER device + * + ****************************************************************************/ + +void phyplus_tim_deinit(FAR struct phyplus_tim_dev_s *dev) +{ + FAR struct phyplus_tim_priv_s *tim = NULL; + + DEBUGASSERT(dev); + + tim = (FAR struct phyplus_tim_priv_s *)dev; + + tim->inuse = false; +} + + diff --git a/arch/arm/src/phy62xx/phyplus_tim.h b/arch/arm/src/phy62xx/phyplus_tim.h new file mode 100644 index 00000000000..588140ace06 --- /dev/null +++ b/arch/arm/src/phy62xx/phyplus_tim.h @@ -0,0 +1,126 @@ +/**************************************************************************** + * arch/arm/src/phy62xx/phyplus_tim.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_PHYPLUS_TIM_H +#define __ARCH_ARM_SRC_PHYPLUS_TIM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Helpers ******************************************************************/ + +/**************************************************************************** + * #define PHYPLUS_TIM_START(d) ((d)->ops->start(d)) + * #define PHYPLUS_TIM_STOP(d) ((d)->ops->stop(d)) + * #define PHYPLUS_TIM_CLEAR(d) ((d)->ops->clear(d)) + * #define PHYPLUS_TIM_SETMODE(d,mode) ((d)->ops->setmode(d,mode)) + * #define PHYPLUS_TIM_GETCOUNTER(d,value) ((d)->ops->getcounter(d,value)) + * #define PHYPLUS_TIM_SETCOUNTER(d,value) ((d)->ops->setcounter(d,value)) + * #define PHYPLUS_TIM_SETISR(d,hnd,arg) ((d)->ops->setisr(d,hnd,arg)) + * #define PHYPLUS_TIM_ENABLEINT(d) ((d)->ops->enableint(d)) + * #define PHYPLUS_TIM_DISABLEINT(d) ((d)->ops->disableint(d)) + * #define PHYPLUS_TIM_ACKINT(d) ((d)->ops->ackint(d)) + * #define PHYPLUS_TIM_SETISR(d,hnd,arg,s) ((d)->ops->setisr(d,hnd,arg,s)) + * #define PHYPLUS_TIM_ENABLEINT(d,s) ((d)->ops->enableint(d,s)) + * #define PHYPLUS_TIM_DISABLEINT(d,s) ((d)->ops->disableint(d,s)) + * #define PHYPLUS_TIM_ACKINT(d,s) ((d)->ops->ackint(d,s)) + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* register informations... */ + +#define TIM_COUNT_OFFSET 0x0000 +#define TIM_CURRENT_OFFSET 0x0004 +#define TIM_CONTROLREG_OFFSET 0x0008 +#define TIM_EOI_OFFSET 0x000c +#define TIM_STATUS_OFFSET 0x0010 + +#define TIM_ENABLE (BIT(0)) +#define TIM_MODE (BIT(1)) +#define TIM_MASK (BIT(2)) + +#define TIM_EOI (BIT(0)) +#define TIM_STATUS (BIT(0)) + +/* TIM Device Structure */ + +struct phyplus_tim_dev_s +{ + struct phyplus_tim_ops_s *ops; +}; + +typedef enum +{ + PHYPLUS_TIM_FREERUN = 0, + PHYPLUS_TIM_COUNT, +}phyplus_tim_mode_t; + +struct phyplus_tim_ops_s +{ + /* Basic Timers */ + + void (*start)(FAR struct phyplus_tim_dev_s *dev); + void (*stop)(FAR struct phyplus_tim_dev_s *dev); + void (*clear)(FAR struct phyplus_tim_dev_s *dev); + int (*setmode)(FAR struct phyplus_tim_dev_s *dev, phyplus_tim_mode_t mode); + void (*getcounter)(FAR struct phyplus_tim_dev_s *dev, uint32_t *value); + void (*setcounter)(FAR struct phyplus_tim_dev_s *dev, uint32_t *value); + int (*setisr)(FAR struct phyplus_tim_dev_s *dev, xcpt_t handler, void *arg); + void (*enableint)(FAR struct phyplus_tim_dev_s *dev); + void (*disableint)(FAR struct phyplus_tim_dev_s *dev); + void (*ackint)(FAR struct phyplus_tim_dev_s *dev); + +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +FAR struct phyplus_tim_dev_s *phyplus_tim_init(int timer); +void phyplus_tim_deinit(FAR struct phyplus_tim_dev_s *dev); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif diff --git a/arch/arm/src/phy62xx/phyplus_timer_lowerhalf.c b/arch/arm/src/phy62xx/phyplus_timer_lowerhalf.c new file mode 100644 index 00000000000..4910388e528 --- /dev/null +++ b/arch/arm/src/phy62xx/phyplus_timer_lowerhalf.c @@ -0,0 +1,590 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_tim_lowerhalf.c + * + * Copyright (C) 2015 Wail Khemir. All rights reserved. + * Copyright (C) 2015 Omni Hoverboards Inc. All rights reserved. + * Authors: Wail Khemir + * Paul Alexander Patience + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "phyplus_tim.h" +#include "phyplus_timer_lowerhalf.h" + +#if defined(CONFIG_TIMER) + +#define TMR_MAXTIMEOUT 0xffffff + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure provides the private representation of the "lower-half" + * driver state structure. This structure must be cast-compatible with the + * timer_lowerhalf_s structure. + */ + +struct phyplus_lowerhalf_s +{ + FAR const struct timer_ops_s *ops; /* Lower half operations */ + FAR struct phyplus_timer_dev_s *tim; /* pic32mz timer driver */ + tccb_t callback; /* Current user interrupt cb */ + FAR void *arg; /* Argument to upper half cb */ + bool started; /* True: Timer has been started */ + uint32_t timeout; /* Current timeout value (us) */ + +// bool enable; //start or stop +// bool mode; //freerun or count +// bool intrmask; //enable or disable +// uint32_t timeout; /* Current timeout value (us) */ +// uint32_t ticks; /* Timeout converted in ticks */ +// uint32_t freq; /* Timer's frequency (Hz) */ +// uint8_t width; /* Timer's width */ +// uint32_t maxticks; /* Maximum ticks for this timer */ +// bool started; /* True: Timer has been started */ + +}; + + + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int phyplus_timer_handler(int irq, void * context, void * arg); + +/* "Lower half" driver methods **********************************************/ + +static int phyplus_start(FAR struct timer_lowerhalf_s *lower); +static int phyplus_stop(FAR struct timer_lowerhalf_s *lower); +static int phyplus_getstatus(FAR struct timer_lowerhalf_s *lower, + FAR struct timer_status_s *status); +static int phyplus_settimeout(FAR struct timer_lowerhalf_s *lower, + uint32_t timeout); +static void phyplus_setcallback(FAR struct timer_lowerhalf_s *lower, + tccb_t callback, FAR void *arg); +//static int phyplus_ioctl(struct timer_lowerhalf_s *lower, int cmd, +// unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + + +/* "Lower half" driver methods */ +static const struct timer_ops_s g_timer_ops = +{ + .start =phyplus_start, + .stop = phyplus_stop, +#if 1 + .getstatus = phyplus_getstatus, +#else + .getstatus = NULL, +#endif + .settimeout = phyplus_settimeout, + .setcallback = phyplus_setcallback, +#if 1 + .ioctl = NULL, +#else + .ioctl = phyplus_ioctl, +#endif +}; + + +//#ifdef CONFIG_PHYPLUS_TIM1 +static struct phyplus_lowerhalf_s g_tim1_lowerhalf = +{ + .ops = &g_timer_ops, + +}; +//#endif + +//#ifdef CONFIG_PHYPLUS_TIM2 +static struct phyplus_lowerhalf_s g_tim2_lowerhalf = +{ + .ops = &g_timer_ops, + +}; +//#endif + +//#ifdef CONFIG_PHYPLUS_TIM3 +static struct phyplus_lowerhalf_s g_tim3_lowerhalf = +{ + .ops = &g_timer_ops, + +}; +//#endif + +//#ifdef CONFIG_PHYPLUS_TIM4 +static struct phyplus_lowerhalf_s g_tim4_lowerhalf = +{ + .ops = &g_timer_ops, + +}; +//#endif + +//#ifdef CONFIG_PHYPLUS_TIM5 +static struct phyplus_lowerhalf_s g_tim5_lowerhalf = +{ + .ops = &g_timer_ops, + +}; +//#endif + +//#ifdef CONFIG_PHYPLUS_TIM6 +static struct phyplus_lowerhalf_s g_tim6_lowerhalf = +{ + .ops = &g_timer_ops, + +}; +//#endif + + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: phyplus_timer_handler + * + * Description: + * timer interrupt handler + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ +//done.. +static int phyplus_timer_handler(int irq, void * context, void * arg) +{ + FAR struct phyplus_lowerhalf_s *lower = (struct phyplus_lowerhalf_s *) arg; + + //PHYPLUS_TIM_ACKINT(lower->tim); + phyplus_tim_ackint(lower->tim); + if (lower->callback && lower->callback(&lower->timeout, lower->arg)) + { + //PHYPLUS_TIM_SETCOUNTER(lower->tim, lower->timeout); + phyplus_tim_setcounter(lower->tim, lower->timeout); + } + else + { + phyplus_stop((struct timer_lowerhalf_s *)lower); + } + return OK; + +} + +/**************************************************************************** + * Name: phyplus_start + * + * Description: + * Start the timer, resetting the time to the current timeout, + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the + * "lower-half" driver state structure. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ +//done.. +static int phyplus_start(FAR struct timer_lowerhalf_s *lower) +{ + FAR struct phyplus_lowerhalf_s *priv = (FAR struct phyplus_lowerhalf_s *)lower; + if (!(priv->started)) + { +// PHYPLUS_TIM_SETMODE(priv->tim, PHYPLUS_TIM_COUNT); + phyplus_tim_setmode(priv->tim, PHYPLUS_TIM_COUNT); + if (priv->callback != NULL) + { +// PHYPLUS_TIM_SETISR(priv->tim, phyplus_timer_handler, priv); +// PHYPLUS_TIM_ENABLEINT(priv->tim); + phyplus_tim_setisr(priv->tim, phyplus_timer_handler, priv); + phyplus_tim_enableint(priv->tim); + phyplus_tim_start(priv->tim); //chrade add 2021_1008 + } + priv->started = true; + return OK; + } + return -EBUSY; +} + +/**************************************************************************** + * Name: phyplus_stop + * + * Description: + * Stop the timer + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the + * "lower-half" driver state structure. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ +//done.. +static int phyplus_stop(struct timer_lowerhalf_s *lower) +{ + struct phyplus_lowerhalf_s *priv = (struct phyplus_lowerhalf_s *)lower; + + if(priv->started) + { + //PHYPLUS_TIM_SETMODE(priv->tim, PHYPLUS_TIM_COUNT); + //PHYPLUS_TIM_DISABLEINT(priv->tim); + //PHYPLUS_TIM_SETISR(priv->tim, NULL, NULL); + phyplus_tim_stop(priv->tim); //chrade add 2021_1008 + + phyplus_tim_setmode(priv->tim, PHYPLUS_TIM_COUNT); + phyplus_tim_disableint(priv->tim); + phyplus_tim_setisr(priv->tim, NULL, NULL); + priv->started = false; + return OK; + } + return -ENODEV; +} + +/**************************************************************************** + * Name: phyplus_settimeout + * + * Description: + * Set a new timeout value (and reset the timer) + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the + * "lower-half" driver state structure. + * timeout - The new timeout value in microseconds. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ +//done.. +static int phyplus_settimeout(FAR struct timer_lowerhalf_s *lower, + uint32_t timeout) +{ + FAR struct phyplus_lowerhalf_s *priv = (FAR struct phyplus_lowerhalf_s *)lower; + + wdinfo("Entry: timeout=%" PRId32 "\n", timeout); + DEBUGASSERT(priv); + + /* Can this timeout be represented? */ + + if (timeout < 1 || timeout > TMR_MAXTIMEOUT) + { + wderr("ERROR: Cannot represent timeout=%" PRId32 " > %" PRId32 "\n", + timeout, TMR_MAXTIMEOUT); + return -ERANGE; + } + + if (priv->started) + { + wdwarn("WARNING: Watchdog is already started\n"); + return -EPERM; + } + + priv->timeout = timeout*4; + //PHYPLUS_TIM_SETCOUNTER(priv->tim, priv->timeout); + phyplus_tim_setcounter(priv->tim, priv->timeout); + return OK; +} + +/**************************************************************************** + * Name: phhyplus_setcallback + * + * Description: + * Call this user provided timeout callback. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the + * "lower-half" driver state structure. + * callback - The new timer expiration function pointer. If this + * function pointer is NULL, then the reset-on-expiration + * behavior is restored, + * arg - Argument that will be provided in the callback + * + * Returned Value: + * The previous timer expiration function pointer or NULL is there was + * no previous function pointer. + * + ****************************************************************************/ +//done.. +static void phyplus_setcallback(FAR struct timer_lowerhalf_s *lower, + tccb_t callback, FAR void *arg) +{ + FAR struct phyplus_lowerhalf_s *priv = (FAR struct phyplus_lowerhalf_s *)lower; + int ret = OK; + irqstate_t flags = enter_critical_section(); + + /* Save the new callback */ + + priv->callback = callback; + priv->arg = arg; + + if(callback != NULL && priv->started) + { + //ret = PHYPLUS_TIM_SETISR(priv->tim, phyplus_timer_handler, priv); + ret = phyplus_tim_setisr(priv->tim, phyplus_timer_handler, priv); + //PHYPLUS_TIM_ENABLEINT(priv->tim); //done + phyplus_tim_enableint(priv->tim); + } + else + { + //PHYPLUS_TIM_DISABLEINT(priv->tim); //done + phyplus_tim_disableint(priv->tim); //done + //ret = PHYPLUS_TIM_SETISR(priv->tim, NULL, NULL); + ret = phyplus_tim_setisr(priv->tim, NULL, NULL); + } + + leave_critical_section(flags); + assert(ret==OK); + +//#if 0 +// irqstate_t flags = enter_critical_section(); + + /* Save the new callback */ + +// priv->callback = callback; +// priv->arg = arg; + +// if (callback != NULL && priv->started) +// { +// STM32_TIM_SETISR(priv->tim, stm32_timer_handler, priv, 0); +// STM32_TIM_ENABLEINT(priv->tim, ATIM_DIER_UIE); +// } +// else +// { +// STM32_TIM_DISABLEINT(priv->tim, ATIM_DIER_UIE); +// STM32_TIM_SETISR(priv->tim, NULL, NULL, 0); +// } +// leave_critical_section(flags); +//#endif +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: phyplus_timer_initialize + * + * Description: + * Bind the configuration timer to a timer lower half instance and + * register the timer drivers at 'devpath' + * + * Input Parameters: + * devpath - The full path to the timer device. This should be of the + * form /dev/timer0 + * timer - the timer's number. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ +//done.. +int phyplus_timer_initialize(FAR const char *devpath, int timer) +{ + FAR struct phyplus_lowerhalf_s *lower; +syslog(LOG_ERR, "phuplus_timer_initialiize enter, timer=%d\n", timer); + switch (timer) + { +//#ifdef CONFIG_PHYPLUS_TIM1 + case 1: + lower = &g_tim1_lowerhalf; + break; +//#endif +//#ifdef CONFIG_PHYPLUS_TIM2 + case 2: + lower = &g_tim2_lowerhalf; + break; +//#endif +//#ifdef CONFIG_PHYPLUS_TIM3 + case 3: + lower = &g_tim3_lowerhalf; + break; +//#endif +//#ifdef CONFIG_PHYPLUS_TIM4 + case 4: + lower = &g_tim4_lowerhalf; + break; +//#endif +//#ifdef CONFIG_PHYPLUS_TIM5 + case 5: + lower = &g_tim5_lowerhalf; + break; +//#endif +//#ifdef CONFIG_PHYPLUS_TIM6 + case 6: + lower = &g_tim6_lowerhalf; + break; +//#endif + default: + syslog(LOG_ERR, "err1"); + return -ENODEV; + } + + /* Initialize the elements of lower half state structure */ + + lower->started = false; + lower->callback = NULL; +// lower->tim = stm32_tim_init(timer); + lower->tim = phyplus_tim_init(timer); + + if (lower->tim == NULL) + { + syslog(LOG_ERR, "err2"); + return -EINVAL; + } + + /* Register the timer driver as /dev/timerX. The returned value from + * timer_register is a handle that could be uswithed timer_unregister(). + * REVISIT: The returned handle is discard here. + */ + + FAR void *drvr = timer_register(devpath, + (FAR struct timer_lowerhalf_s *)lower); + if (drvr == NULL) + { + /* The actual cause of the failure may have been a failure to allocate + * perhaps a failure to register the timer driver (such as if the + * 'depath' were not unique). We know here but we return EEXIST to + * indicate the failure (implying the non-unique devpath). + */ + syslog(LOG_ERR, "err3"); + return -EEXIST; + } +syslog(LOG_ERR, "phuplus_timer_initialiize out\n"); + return OK; +} + + +//chrade add below test purpose... + +/**************************************************************************** + * Name: phyplus_getstatus + * + * Description: + * get timer status + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the + * "lower- half" driver state structure. + * status - The location to return the status information. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int phyplus_getstatus(FAR struct timer_lowerhalf_s *lower, + FAR struct timer_status_s *status) +{ + FAR struct phyplus_lowerhalf_s *priv = + (FAR struct stm32l4_lowerhalf_s *)lower; + uint32_t value; + + DEBUGASSERT(priv); + + /* Return the status bit */ + + status->flags = 0; + if (priv->started) + { + status->flags |= TCFLAGS_ACTIVE; + } + + if (priv->callback) + { + status->flags |= TCFLAGS_HANDLER; + } + + phyplus_tim_getcounter(priv->tim, &value); + status->timeout = value; + + /* Get the time remaining until the timer expires (in microseconds) */ + phyplus_tim_getcurrent(priv->tim, &value); + status->timeleft = value; + + + phyplus_tim_getcontrolreg(priv->tim, &value); + status->flags |= ((value&0xff)<<8); + + + return OK; +} + +//chrade add ends.. + +int phyplus_timer_register(FAR struct phyplus_timer_param_s *phyplus_timer_param) +{ + FAR const char *fmt; + char devname[16]; + int ret; + fmt = "/dev/timer%u"; + //vailed check: + if((phyplus_timer_param->timer_idx<1)||(phyplus_timer_param->timer_idx>6) ){ + return -ENODEV; + } + snprintf(devname, 16, fmt, (unsigned int)phyplus_timer_param->timer_idx); + return phyplus_timer_initialize(devname, phyplus_timer_param->timer_idx); +} + +int phyplus_timer_ungister(FAR struct phyplus_timer_param_s *phyplus_timer_param) +{ + + return phyplus_timer_uninitialize(phyplus_timer_param->timer_idx); +// return 0; +} + + + +#endif + diff --git a/arch/arm/src/phy62xx/phyplus_timer_lowerhalf.h b/arch/arm/src/phy62xx/phyplus_timer_lowerhalf.h new file mode 100644 index 00000000000..1d449face8e --- /dev/null +++ b/arch/arm/src/phy62xx/phyplus_timer_lowerhalf.h @@ -0,0 +1,13 @@ +#ifndef __INCLUDE_NUTTX_PHYPLUS_TIMER_H +#define __INCLUDE_NUTTX_PHYPLUS_TIMER_H + + +struct phyplus_timer_param_s +{ + uint8_t timer_idx; + +}; + +#endif + + diff --git a/arch/arm/src/phy62xx/phyplus_timerisr.c b/arch/arm/src/phy62xx/phyplus_timerisr.c new file mode 100644 index 00000000000..672720f8eb9 --- /dev/null +++ b/arch/arm/src/phy62xx/phyplus_timerisr.c @@ -0,0 +1,98 @@ +/**************************************************************************** + * arch/arm/src/tiva/common/tiva_timerisr.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "nvic.h" +#include "clock/clock.h" +#include "arm_internal.h" +#include "arm_arch.h" + +#include "chip.h" + +//#include "irq.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: phyplus_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ +//done... +static int phyplus_timerisr(int irq, uint32_t *regs, void *arg) +{ + /* Process timer interrupt */ + + nxsched_process_timer(); + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize the timer + * interrupt. + * + ****************************************************************************/ +//done... +void up_timer_initialize(void) +{ +// putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD); +// putreg32(0, NVIC_SYSTICK_CURRENT); + + irq_attach(PHY62XX_IRQ_SYSTICK, (xcpt_t)phyplus_timerisr, NULL); + + /* Enable SysTick interrupts: + * + * NVIC_SYSTICK_CTRL_CLKSOURCE=0 : Use the implementation defined clock + * source which, for the STM32F7, will be + * HCLK/8 + * NVIC_SYSTICK_CTRL_TICKINT=1 : Generate interrupts + * NVIC_SYSTICK_CTRL_ENABLE : Enable the counter + */ + +// regval = (NVIC_SYSTICK_CTRL_TICKINT | NVIC_SYSTICK_CTRL_ENABLE); +// putreg32(regval, NVIC_SYSTICK_CTRL); + + up_enable_irq(PHY62XX_IRQ_SYSTICK); + +} + diff --git a/arch/arm/src/phy62xx/phyplus_timerisr.h b/arch/arm/src/phy62xx/phyplus_timerisr.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/arch/arm/src/phy62xx/pplus_mtd_flash.c b/arch/arm/src/phy62xx/pplus_mtd_flash.c new file mode 100644 index 00000000000..fdead08ad81 --- /dev/null +++ b/arch/arm/src/phy62xx/pplus_mtd_flash.c @@ -0,0 +1,381 @@ + +/**************************************************************************** + * drivers/mtd/n25qxxx.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pplus_mtd_flash.h" +#include "flash.h" + +#include +#include +#include +#include + + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This type represents the state of the MTD device. + * The struct mtd_dev_s must appear at the beginning of the definition + * so that you can freely cast between pointers to struct mtd_dev_s and + * struct pplus_fls_dev_s. + */ + +struct pplus_fls_dev_s +{ + struct mtd_dev_s mtd; /* MTD interface */ + uint32_t offset; /*offset from flash start address*/ + uint32_t size; /*avaliable size for MTD*/ + uint16_t nsectors; /* Number of erase sectors */ + uint8_t sectorshift; /* Log2 of sector size */ + uint8_t pageshift; /* Log2 of page size */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int pplus_fls_readid(FAR struct pplus_fls_dev_s *priv); +static int pplus_fls_erase_sector(FAR struct pplus_fls_dev_s *priv, + off_t offset); +static int pplus_fls_erase_chip(FAR struct pplus_fls_dev_s *priv); + +/* MTD driver methods */ + +static int pplus_fls_erase(FAR struct mtd_dev_s *dev, + off_t startblock, + size_t nblocks); +static ssize_t pplus_fls_bread(FAR struct mtd_dev_s *dev, + off_t startblock, + size_t nblocks, + FAR uint8_t *buf); +static ssize_t pplus_fls_bwrite(FAR struct mtd_dev_s *dev, + off_t startblock, + size_t nblocks, + FAR const uint8_t *buf); +static ssize_t pplus_fls_read(FAR struct mtd_dev_s *dev, + off_t offset, + size_t nbytes, + FAR uint8_t *buffer); +static int pplus_fls_ioctl(FAR struct mtd_dev_s *dev, + int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pplus_fls_readid + ****************************************************************************/ + +static inline int pplus_fls_readid(struct pplus_fls_dev_s *priv) +{ + //fixed size and flash type + //256KB + //priv->sectorshift = 12; + //priv->pageshift = 8; + //priv->nsectors = 64; + return OK; +} + + +/**************************************************************************** + * Name: pplus_fls_erase_sector + ****************************************************************************/ + +static int pplus_fls_erase_sector(struct pplus_fls_dev_s *priv, off_t sector) +{ + off_t address; + uint8_t status; + + finfo("sector: %08lx\n", (unsigned long)sector); + + /* Get the address associated with the sector */ + + address = (off_t)((sector << priv->sectorshift) + priv->offset); + + hal_flash_erase_sector(address); + return OK; +} + +/**************************************************************************** + * Name: pplus_fls_erase_chip + ****************************************************************************/ + +static int pplus_fls_erase_chip(struct pplus_fls_dev_s *priv) +{ + uint8_t status; + off_t address = priv->offset; + int i; + + /* Erase the whole chip */ + + for(i = 0; i < priv->nsectors ; i ++) + { + hal_flash_erase_sector(address); + address += (1ul << priv->sectorshift); + } + + return OK; +} + + + + + +/**************************************************************************** + * Name: pplus_fls_erase + ****************************************************************************/ + +static int pplus_fls_erase(FAR struct mtd_dev_s *dev, + off_t startblock, + size_t nblocks) +{ + FAR struct pplus_fls_dev_s *priv = (FAR struct pplus_fls_dev_s *)dev; + size_t blocksleft = nblocks; + + finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); + while (blocksleft-- > 0) + { + /* Erase each sector */ + pplus_fls_erase_sector(priv, startblock); + startblock++; + } + + return (int)nblocks; +} + +/**************************************************************************** + * Name: pplus_fls_bread + ****************************************************************************/ + +static ssize_t pplus_fls_bread(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR uint8_t *buffer) +{ + FAR struct pplus_fls_dev_s *priv = (FAR struct pplus_fls_dev_s *)dev; + int ret; + finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); + + /* On this device, we can handle the block read just like the byte-oriented + * read + */ + ret = hal_flash_read(priv->offset + (startblock << priv->pageshift), buffer, nblocks << priv->pageshift); + + + return nblocks; +} + +/**************************************************************************** + * Name: pplus_fls_bwrite + ****************************************************************************/ + +static ssize_t pplus_fls_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, + size_t nblocks, FAR const uint8_t *buffer) +{ + FAR struct pplus_fls_dev_s *priv = (FAR struct pplus_fls_dev_s *)dev; + + finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); + + + int ret = hal_flash_write(priv->offset + (startblock << priv->pageshift), buffer, nblocks << priv->pageshift); + + if (ret) + { + ferr("ERROR: spif_write failed: %d\n", ret); + return -ret; + } + + return nblocks; +} + +/**************************************************************************** + * Name: pplus_fls_read + ****************************************************************************/ + +static ssize_t pplus_fls_read(FAR struct mtd_dev_s *dev, + off_t offset, + size_t nbytes, + FAR uint8_t *buffer) +{ + FAR struct pplus_fls_dev_s *priv = (FAR struct pplus_fls_dev_s *)dev; + int ret; + + finfo("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes); + + ret = hal_flash_read(priv->offset + offset, buffer, nbytes); + + if (ret < 0) + { + ferr("ERROR: pplus_fls_read_byte returned: %d\n", ret); + return (ssize_t)ret; + } + + finfo("return nbytes: %d\n", (int)nbytes); + return (ssize_t)nbytes; +} + +/**************************************************************************** + * Name: pplus_fls_ioctl + ****************************************************************************/ + +static int pplus_fls_ioctl(FAR struct mtd_dev_s *dev, + int cmd, + unsigned long arg) +{ + FAR struct pplus_fls_dev_s *priv = (FAR struct pplus_fls_dev_s *)dev; + int ret = -EINVAL; /* Assume good command with bad parameters */ + + finfo("cmd: %d \n", cmd); + + switch (cmd) + { + case MTDIOC_GEOMETRY: + { + FAR struct mtd_geometry_s *geo = + (FAR struct mtd_geometry_s *)((uintptr_t)arg); + + if (geo) + { + /* Populate the geometry structure with information need to + * know the capacity and how to access the device. + * + * NOTE: + * that the device is treated as though it where just an array + * of fixed size blocks. That is most likely not true, but + * the client will expect the device logic to do whatever is + * necessary to make it appear so. + */ + + + geo->blocksize = (1 << priv->pageshift); + geo->erasesize = (1 << priv->sectorshift); + geo->neraseblocks = priv->nsectors; + ret = OK; + + finfo("blocksize: %" PRId32 " erasesize: %" PRId32 + " neraseblocks: %" PRId32 "\n", + geo->blocksize, geo->erasesize, geo->neraseblocks); + } + break; + } + + case MTDIOC_BULKERASE: + { + /* Erase the entire device */ + ret = pplus_fls_erase_chip(priv); + break; + } + + default: + ret = -ENOTTY; /* Bad/unsupported command */ + break; + } + + finfo("return %d\n", ret); + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pplus_fls_initialize + * + * Description: + * Create an initialize MTD device instance for the internal FLASH. + * + * MTD devices are not registered in the file system, but are created as + * instances that can be bound to other functions (such as a block or + * character driver front end). + * Parameter: + * offset: offset from 0 of internal flash + * size: avaiable size for NVM + ****************************************************************************/ + +struct mtd_dev_s *pplus_fls_initialize(uint32_t offset, uint32_t size) +{ + FAR struct pplus_fls_dev_s *priv; + int ret; + + /* Allocate a state structure (we allocate the structure instead of using + * a fixed, static allocation so that we can handle multiple FLASH devices. + * The current implementation would handle only one FLASH part per QuadSPI + * device (only because of the QSPIDEV_FLASH(0) definition) and so would + * have to be extended to handle multiple FLASH parts on the same QuadSPI + * bus. + */ + + priv = (FAR struct pplus_fls_dev_s *) + kmm_zalloc(sizeof(struct pplus_fls_dev_s)); + if (priv) + { + /* Initialize the allocated structure (unsupported methods were + * nullified by kmm_zalloc). + */ + + priv->mtd.erase = pplus_fls_erase; + priv->mtd.bread = pplus_fls_bread; + priv->mtd.bwrite = pplus_fls_bwrite; + priv->mtd.read = pplus_fls_read; + priv->mtd.ioctl = pplus_fls_ioctl; + priv->mtd.name = "pplus_nvm"; + + priv->offset = offset; + priv->size = size; + priv->sectorshift = 12; + priv->pageshift = 8; + priv->nsectors = 64; + + + + /* Identify the FLASH chip and get its capacity */ + ret = pplus_fls_readid(priv); + + } + + /* Return the implementation-specific state structure as the MTD device */ + + finfo("Return %p\n", priv); + return (FAR struct mtd_dev_s *)priv; + +errout_with_priv: + kmm_free(priv); + return NULL; +} + diff --git a/arch/arm/src/phy62xx/pplus_mtd_flash.h b/arch/arm/src/phy62xx/pplus_mtd_flash.h new file mode 100644 index 00000000000..939ef60201a --- /dev/null +++ b/arch/arm/src/phy62xx/pplus_mtd_flash.h @@ -0,0 +1,9 @@ + +#ifndef __INCLUDE_PPLUS_MTD_FLASH_H +#define __INCLUDE_PPLUS_MTD_FLASH_H + + + + +#endif /*__INCLUDE_PPLUS_MTD_FLASH_H*/ + diff --git a/arch/arm/src/phy62xx/pwrmgr.c b/arch/arm/src/phy62xx/pwrmgr.c new file mode 100644 index 00000000000..68bea7fcd16 --- /dev/null +++ b/arch/arm/src/phy62xx/pwrmgr.c @@ -0,0 +1,528 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ +#include "rom_sym_def.h" +#include "types.h" +//#include "ll_sleep.h" +#include "bus_dev.h" +#include "string.h" + +#include "pwrmgr.h" +#include "error.h" +#include "gpio.h" +#include "log.h" +#include "clock.h" +#include "jump_function.h" +//#include "flash.h" + +#if(CFG_SLEEP_MODE == PWR_MODE_NO_SLEEP) + static uint8_t mPwrMode = PWR_MODE_NO_SLEEP; + #elif(CFG_SLEEP_MODE == PWR_MODE_SLEEP) + static uint8_t mPwrMode = PWR_MODE_SLEEP; + #elif(CFG_SLEEP_MODE == PWR_MODE_PWROFF_NO_SLEEP) + static uint8_t mPwrMode = PWR_MODE_PWROFF_NO_SLEEP; +#else + #error "CFG_SLEEP_MODE define incorrect" +#endif + +//#define CFG_FLASH_ENABLE_DEEP_SLEEP +#ifdef CFG_FLASH_ENABLE_DEEP_SLEEP + #warning "CONFIG FLASH ENABLE DEEP SLEEP !!!" +#endif + +typedef struct _pwrmgr_Context_t +{ + MODULE_e moudle_id; + bool lock; + pwrmgr_Hdl_t sleep_handler; + pwrmgr_Hdl_t wakeup_handler; +} pwrmgr_Ctx_t; + +static pwrmgr_Ctx_t mCtx[HAL_PWRMGR_TASK_MAX_NUM]; +static uint32_t sramRet_config; +static uint32_t s_config_swClk0 = DEF_CLKG_CONFIG_0; + +uint32_t s_config_swClk1 = DEF_CLKG_CONFIG_1; +uint32_t s_gpio_wakeup_src_group1,s_gpio_wakeup_src_group2; + + +int hal_pwrmgr_init(void) +{ +/* memset(&mCtx, 0, sizeof(mCtx)); + + switch(mPwrMode) + { + case PWR_MODE_NO_SLEEP: + case PWR_MODE_PWROFF_NO_SLEEP: + disableSleep(); + break; + + case PWR_MODE_SLEEP: + enableSleep(); + break; + } +*/ + return PPlus_SUCCESS; +} + +int hal_pwrmgr_clk_gate_config(MODULE_e module) +{ + /* if (module < MOD_CP_CPU) + { + s_config_swClk0 |= BIT(module); + } + else if (module < MOD_PCLK_CACHE) + { + s_config_swClk1 |= BIT(module - MOD_CP_CPU); + } + + */ + return PPlus_SUCCESS; +} + +bool hal_pwrmgr_is_lock(MODULE_e mod) +{ +/* int i; + int ret = FALSE; + + if(mPwrMode == PWR_MODE_NO_SLEEP || mPwrMode == PWR_MODE_PWROFF_NO_SLEEP ) + { + return TRUE; + } + + _HAL_CS_ALLOC_(); + HAL_ENTER_CRITICAL_SECTION(); + + for(i = 0; i< HAL_PWRMGR_TASK_MAX_NUM; i++) + { + if(mCtx[i].moudle_id == MOD_NONE) + break; + + if(mCtx[i].moudle_id == mod) + { + if(mCtx[i].lock == TRUE) + ret = TRUE; + + break; + } + } + + HAL_EXIT_CRITICAL_SECTION(); + */ + return 1;//ret; +} + + +int hal_pwrmgr_lock(MODULE_e mod) +{ + /* int i; + int ret = PPlus_ERR_NOT_REGISTED; + + if(mPwrMode == PWR_MODE_NO_SLEEP || mPwrMode == PWR_MODE_PWROFF_NO_SLEEP ) + { + disableSleep(); + return PPlus_SUCCESS; + } + + HAL_ENTER_CRITICAL_SECTION(); + + for(i = 0; i< HAL_PWRMGR_TASK_MAX_NUM; i++) + { + if(mCtx[i].moudle_id == MOD_NONE) + break; + + if(mCtx[i].moudle_id == mod) + { + mCtx[i].lock = TRUE; + disableSleep(); + //LOG("LOCK\n"); + ret = PPlus_SUCCESS; + break; + } + } + + HAL_EXIT_CRITICAL_SECTION(); + */ + return 1;//ret; +} + +int hal_pwrmgr_unlock(MODULE_e mod) +{ +/* int i, cnt = 0; + + if(mPwrMode == PWR_MODE_NO_SLEEP || mPwrMode == PWR_MODE_PWROFF_NO_SLEEP ) + { + disableSleep(); + return PPlus_SUCCESS; + } + + _HAL_CS_ALLOC_(); + HAL_ENTER_CRITICAL_SECTION(); + + for(i = 0; i< HAL_PWRMGR_TASK_MAX_NUM; i++) + { + if(mCtx[i].moudle_id == MOD_NONE) + break; + + if(mCtx[i].moudle_id == mod) + { + mCtx[i].lock = FALSE; + } + + if(mCtx[i].lock) + cnt ++; + } + + if(cnt == 0) + enableSleep(); + else + disableSleep(); + + HAL_EXIT_CRITICAL_SECTION(); + //LOG("sleep mode:%d\n", isSleepAllow()); + */ + return PPlus_SUCCESS; +} + +int hal_pwrmgr_register(MODULE_e mod, pwrmgr_Hdl_t sleepHandle, pwrmgr_Hdl_t wakeupHandle) +{ +/* int i; + pwrmgr_Ctx_t* pctx = NULL; + + for(i = 0; i< HAL_PWRMGR_TASK_MAX_NUM; i++) + { + if(mCtx[i].moudle_id == mod) + return PPlus_ERR_INVALID_STATE; + + if(mCtx[i].moudle_id == MOD_NONE) + { + pctx = &mCtx[i]; + break; + } + } + + if(pctx == NULL) + return PPlus_ERR_NO_MEM; + + pctx->lock = FALSE; + pctx->moudle_id = mod; + pctx->sleep_handler = sleepHandle; + pctx->wakeup_handler = wakeupHandle;*/ + return PPlus_SUCCESS; +} + +int hal_pwrmgr_unregister(MODULE_e mod) +{ + /* int i; + pwrmgr_Ctx_t* pctx = NULL; + + for(i = 0; i< HAL_PWRMGR_TASK_MAX_NUM; i++) + { + if(mCtx[i].moudle_id == mod) + { + pctx = &mCtx[i]; + break; + } + + if(mCtx[i].moudle_id == MOD_NONE) + { + return PPlus_ERR_NOT_REGISTED; + } + } + + if(pctx == NULL) + return PPlus_ERR_NOT_REGISTED; + + _HAL_CS_ALLOC_(); + HAL_ENTER_CRITICAL_SECTION(); + memcpy(pctx, pctx+1, sizeof(pwrmgr_Ctx_t)*(HAL_PWRMGR_TASK_MAX_NUM-i-1)); + HAL_EXIT_CRITICAL_SECTION();*/ + return PPlus_SUCCESS; +} + + +int __attribute__((used)) hal_pwrmgr_wakeup_process(void) +{ + /* int i; + #ifdef CFG_FLASH_ENABLE_DEEP_SLEEP + extern void spif_release_deep_sleep(void); + spif_release_deep_sleep(); + WaitRTCCount(8); + #endif + AP_PCR->SW_CLK = s_config_swClk0; + AP_PCR->SW_CLK1 = s_config_swClk1|0x01;//force set M0 CPU + s_gpio_wakeup_src_group1 = AP_AON->GPIO_WAKEUP_SRC[0]; + s_gpio_wakeup_src_group2 = AP_AON->GPIO_WAKEUP_SRC[1]; + //restore BB TIMER IRQ_PRIO + NVIC_SetPriority((IRQn_Type)BB_IRQn, IRQ_PRIO_REALTIME); + NVIC_SetPriority((IRQn_Type)TIM1_IRQn, IRQ_PRIO_HIGH); //ll_EVT + NVIC_SetPriority((IRQn_Type)TIM2_IRQn, IRQ_PRIO_HIGH); //OSAL_TICK + NVIC_SetPriority((IRQn_Type)TIM4_IRQn, IRQ_PRIO_HIGH); //LL_EXA_ADV + + for(i = 0; i< HAL_PWRMGR_TASK_MAX_NUM; i++) + { + if(mCtx[i].moudle_id == MOD_NONE) + { + return PPlus_ERR_NOT_REGISTED; + } + + if(mCtx[i].wakeup_handler) + mCtx[i].wakeup_handler(); + } +*/ + return PPlus_SUCCESS; +} + +int __attribute__((used)) hal_pwrmgr_sleep_process(void) +{ + /* int i; + //20181013 ZQ : + hal_pwrmgr_RAM_retention_set(); + + //LOG("Sleep\n"); + for(i = 0; i< HAL_PWRMGR_TASK_MAX_NUM; i++) + { + if(mCtx[i].moudle_id == MOD_NONE) + { + //return PPlus_ERR_NOT_REGISTED; + //found last module + break; + } + + if(mCtx[i].sleep_handler) + mCtx[i].sleep_handler(); + } + + #ifdef CFG_FLASH_ENABLE_DEEP_SLEEP + extern void spif_set_deep_sleep(void); + spif_set_deep_sleep(); + #endif + */ + return PPlus_SUCCESS; +} + +/************************************************************************************** + @fn hal_pwrmgr_RAM_retention + + @brief This function process for enable retention sram + + input parameters + + @param uint32_t sram: sram bit map + + output parameters + + @param None. + + @return refer error.h. + **************************************************************************************/ +int hal_pwrmgr_RAM_retention(uint32_t sram) +{ + /* + if(sram & 0xffffffe0) + { + sramRet_config = 0x00; + return PPlus_ERR_INVALID_PARAM; + } + + sramRet_config = sram; + */ + return PPlus_SUCCESS; +} + +int hal_pwrmgr_RAM_retention_clr(void) +{ + /* + subWriteReg(0x4000f01c,21,17,0); + */ + return PPlus_SUCCESS; +} + +int hal_pwrmgr_RAM_retention_set(void) +{ + /* + subWriteReg(0x4000f01c,21,17,sramRet_config); + */ + return PPlus_SUCCESS; +} + +int hal_pwrmgr_LowCurrentLdo_enable(void) +{ + /* + uint32_t retention_flag; + hal_flash_read(0x1100181c,(uint8_t*)&retention_flag,4); + + if(retention_flag == 0xffffffff) + { + subWriteReg(0x4000f014,26,26, 1); + } + + */ + return PPlus_SUCCESS; +} + +int hal_pwrmgr_LowCurrentLdo_disable(void) +{ + subWriteReg(0x4000f014,26,26, 0); + return PPlus_SUCCESS; +} +extern void gpio_wakeup_set(gpio_pin_e pin, gpio_polarity_e type); +extern void gpio_pull_set(gpio_pin_e pin, gpio_pupd_e type); + +void hal_pwrmgr_poweroff(pwroff_cfg_t* pcfg, uint8_t wakeup_pin_num) +{ +/* HAL_ENTER_CRITICAL_SECTION(); + subWriteReg(0x4000f01c,6,6,0x00); //disable software control + //(void)(wakeup_pin_num); + + for(uint8_t i = 0; i < wakeup_pin_num; i++ ) + { + if(pcfg[i].type==POL_FALLING) + gpio_pull_set(pcfg[i].pin,GPIO_PULL_UP_S); + else + gpio_pull_set(pcfg[i].pin,GPIO_PULL_DOWN); + + gpio_wakeup_set(pcfg[i].pin, pcfg[i].type); + } +*/ + /** + config reset casue as RSTC_OFF_MODE + reset path walkaround dwc + */ + AP_AON->SLEEP_R[0] = 2; + write_reg(0x4000f000,0x5a5aa5a5); + + while(1); +} +#if 0 + +#define STANDBY_WAIT_MS(a) WaitRTCCount((a)<<5) // 32us * 32 around 1ms +__attribute__((section("_section_standby_code_"))) pwroff_cfg_t s_pwroff_cfg[WAKEUP_PIN_MAX]; +__attribute__((section("_section_standby_code_"))) __attribute__((used)) uint8 pwroff_register_number=0; +__attribute__((section("_section_standby_code_"))) void wakeupProcess_standby(void) +{ + subWriteReg(0x4000f014,29,27,0x07); + STANDBY_WAIT_MS(5); + #ifdef CFG_FLASH_ENABLE_DEEP_SLEEP + extern void spif_release_deep_sleep(void); + spif_release_deep_sleep(); + STANDBY_WAIT_MS(15); + #endif + uint32_t volatile cnt=0; + uint8_t volatile find_flag=0; + uint8 pin_n=0; + extern bool gpio_read(gpio_pin_e pin); + + for(pin_n=0; pin_n(s_pwroff_cfg[pin_n].on_time>>5)) + { + write_reg(0x4000f030, 0x01); + break; + } + } + else + hal_pwrmgr_enter_standby(&s_pwroff_cfg[0],pwroff_register_number); + } + + set_sleep_flag(0); + AP_AON->SLEEP_R[0] = 4; + HAL_ENTER_CRITICAL_SECTION(); + AP_PCR->SW_RESET1 = 0; + + while(1); +} +extern void gpio_wakeup_set(gpio_pin_e pin, gpio_polarity_e type); +extern void gpio_pull_set(gpio_pin_e pin, gpio_pupd_e type); +__attribute__((section("_section_standby_code_"))) void hal_pwrmgr_enter_standby(pwroff_cfg_t* pcfg,uint8_t wakeup_pin_num) +{ + HAL_ENTER_CRITICAL_SECTION(); + subWriteReg(0x4000f01c,6,6,0x00); //disable software control + uint8_t i = 0; + + if(wakeup_pin_num>WAKEUP_PIN_MAX) + { + wakeup_pin_num=WAKEUP_PIN_MAX; + } + + for(i = 0; i < wakeup_pin_num; i++) + { + if(pcfg[i].type==POL_FALLING) + gpio_pull_set(pcfg[i].pin,GPIO_PULL_UP_S); + else + gpio_pull_set(pcfg[i].pin,GPIO_PULL_DOWN); + + gpio_wakeup_set(pcfg[i].pin, pcfg[i].type); + osal_memcpy(&s_pwroff_cfg[i],&(pcfg[i]),sizeof(pwroff_cfg_t)); + pwroff_register_number++; + } + + JUMP_FUNCTION(WAKEUP_PROCESS)= (uint32_t)&wakeupProcess_standby; + #ifdef CFG_FLASH_ENABLE_DEEP_SLEEP + extern void spif_set_deep_sleep(void); + spif_set_deep_sleep(); + WaitRTCCount(50); + #endif + subWriteReg(0x4000f014,29,27,0); + set_sleep_flag(1); + AP_AON->SLEEP_R[0] = 2; + subWriteReg(0x4000f01c,21,17,RET_SRAM0); + enter_sleep_off_mode(SYSTEM_SLEEP_MODE); + + while(1); +} + +#endif + + + diff --git a/arch/arm/src/phy62xx/pwrmgr.h b/arch/arm/src/phy62xx/pwrmgr.h new file mode 100644 index 00000000000..e4e71ae1f4e --- /dev/null +++ b/arch/arm/src/phy62xx/pwrmgr.h @@ -0,0 +1,101 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + + + +#ifndef _HAL_PWRMGR_HD +#define _HAL_PWRMGR_HD + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "bus_dev.h" +#include "gpio.h" + +#define PWR_MODE_NO_SLEEP 1 +#define PWR_MODE_SLEEP 2 +#define PWR_MODE_PWROFF_NO_SLEEP 4 + +//WAKEUP FROM STANDBY MODE +#define WAKEUP_PIN_MAX 3 + +#define HAL_PWRMGR_TASK_MAX_NUM 10 + +#define RET_SRAM0 BIT(0) /*32K, 0x1fff0000~0x1fff7fff*/ +#define RET_SRAM1 BIT(1) /*16K, 0x1fff8000~0x1fffbfff*/ +#define RET_SRAM2 BIT(2) /*16K, 0x1fffc000~0x1fffffff*/ + +#define DEF_CLKG_CONFIG_0 (_CLK_IOMUX|_CLK_UART0|_CLK_GPIO|_CLK_SPIF) + +#define DEF_CLKG_CONFIG_1 (_CLK_M0_CPU | _CLK_BB |_CLK_TIMER |_CLK_BBREG \ + |_CLK_TIMER1|_CLK_TIMER2|_CLK_TIMER3|_CLK_TIMER4|_CLK_COM) + +typedef struct +{ + gpio_pin_e pin; + gpio_polarity_e type; + uint16_t on_time; +} pwroff_cfg_t; + + +extern uint32_t g_system_reset_cause; + +typedef void (*pwrmgr_Hdl_t)(void); + +int hal_pwrmgr_init(void); +bool hal_pwrmgr_is_lock(MODULE_e mod); +int hal_pwrmgr_lock(MODULE_e mod); +int hal_pwrmgr_unlock(MODULE_e mod); +int hal_pwrmgr_register(MODULE_e mod, pwrmgr_Hdl_t sleepHandle, pwrmgr_Hdl_t wakeupHandle); +int hal_pwrmgr_unregister(MODULE_e mod); +int hal_pwrmgr_wakeup_process(void) __attribute__((weak)); +int hal_pwrmgr_sleep_process(void) __attribute__((weak)); +int hal_pwrmgr_RAM_retention(uint32_t sram); +int hal_pwrmgr_clk_gate_config(MODULE_e module); +int hal_pwrmgr_RAM_retention_clr(void); +int hal_pwrmgr_RAM_retention_set(void); +int hal_pwrmgr_LowCurrentLdo_enable(void); +int hal_pwrmgr_LowCurrentLdo_disable(void); + +void hal_pwrmgr_poweroff(pwroff_cfg_t* pcfg, uint8_t wakeup_pin_num); +void hal_pwrmgr_enter_standby(pwroff_cfg_t* pcfg,uint8_t wakeup_pin_num) ; + +#ifdef __cplusplus +} +#endif + + +#endif + + diff --git a/arch/arm/src/phy62xx/rf_phy_driver.c b/arch/arm/src/phy62xx/rf_phy_driver.c new file mode 100644 index 00000000000..1dc6b0bdaee --- /dev/null +++ b/arch/arm/src/phy62xx/rf_phy_driver.c @@ -0,0 +1,2381 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/******************************************************************************* + @file rf_phy_driver.c + @brief Contains all functions support for PHYPLUS RF_PHY_DRIVER + @version 1.0 + @date 24. Aug. 2017 + @author Zhongqi Yang + + + +*******************************************************************************/ + + +/******************************************************************************* + INCLUDES +*/ + +#include "rf_phy_driver.h" +#include "mcu.h" +#include "clock.h" +#include "timer.h" +#include "ll_hw_drv.h" + +/******************************************************************************* + BUILD CONFIG +*/ + +#define RF_PHY_DTM_CTRL_NONE 0x00 +#define RF_PHY_DTM_CTRL_UART 0x01 +#define RF_PHY_DTM_CTRL_HCI 0x02 + +#define RF_PHY_DTM_BB_SUPPORT_BLE1M 0x01 +#define RF_PHY_DTM_BB_SUPPORT_BLE2M 0x02 +#define RF_PHY_DTM_BB_SUPPORT_BLR500K 0x04 +#define RF_PHY_DTM_BB_SUPPORT_BLR125K 0x08 +#define RF_PHY_DTM_BB_SUPPORT_ZIGBEE 0x10 + +#define RF_PHY_DTM_BB_SUPPORT_BLR_CODED (RF_PHY_DTM_BB_SUPPORT_BLR500K|RF_PHY_DTM_BB_SUPPORT_BLR125K) +#define RF_PHY_DTM_BB_SUPPORT_BLE_5 (RF_PHY_DTM_BB_SUPPORT_BLE1M|RF_PHY_DTM_BB_SUPPORT_BLE2M|RF_PHY_DTM_BB_SUPPORT_BLR_CODED) +#define RF_PHY_DTM_BB_SUPPORT_FULL (RF_PHY_DTM_BB_SUPPORT_ZIGBEE|RF_PHY_DTM_BB_SUPPORT_BLE_5) + + +// TODO: move to phypuls_build_cfg.h +#define RF_PHY_DTM_CTRL_MOD RF_PHY_DTM_CTRL_UART +#define RF_PHY_DTM_BB_SUPPORT_MOD RF_PHY_DTM_BB_SUPPORT_BLE_5 + + +#define RF_PHY_CT_MONITER 0 // VCO corase tuning moniter counter +// 0 : disable moniter +// other: enable +#define RF_PHY_TIME_BASE TIME_BASE +#define RF_PHY_TIME_DELTA(x,y) TIME_DELTA(x,y) + +/******************************************************************************* + Global Var +*/ +//volatile uint8_t g_rfPhyTpCal0 = 0x2d; +//volatile uint8_t g_rfPhyTpCal1 = 0x23; +//volatile uint8_t g_rfPhyTpCal0_2Mbps = 0x47; +//volatile uint8_t g_rfPhyTpCal1_2Mbps = 0x45; +//volatile uint8_t g_rfPhyTxPower = 0x0f; +//volatile uint8_t g_rfPhyPktFmt = PKT_FMT_BLE1M; +//volatile uint32 g_rfPhyRxDcIQ = 0x20200000; +//volatile int8_t g_rfPhyFreqOffSet = RF_PHY_FREQ_FOFF_00KHZ; +//volatile sysclk_t g_system_clk = SYS_CLK_XTAL_16M; +//volatile rfphy_clk_t g_rfPhyClkSel = RF_PHY_CLK_SEL_16M_XTAL; +//volatile rxadc_clk_t g_rxAdcClkSel = RX_ADC_CLK_SEL_32M_DBL; +// volatile uint8_t g_rfPhyDtmCmd[2] = {0}; +// volatile uint8_t g_rfPhyDtmEvt[2] = {0}; + +// volatile uint8_t g_dtmModeType = 0; + +// volatile uint8_t g_dtmCmd = 0; +// volatile uint8_t g_dtmFreq = 0; +// volatile uint8_t g_dtmLength = 0; +// volatile uint8_t g_dtmExtLen = 0; + +// volatile uint16_t g_dtmPktIntv = 0; + + +// volatile uint8_t g_dtmPKT = 0; +// volatile uint8_t g_dtmCtrl = 0; +// volatile uint8_t g_dtmPara = 0; +// volatile uint8_t g_dtmEvt = 0; +// volatile uint8_t g_dtmStatus = 0; +// volatile uint16_t g_dtmPktCount = 0; +// volatile uint16_t g_dtmRxCrcNum = 0; +// volatile uint16_t g_dtmRxTONum = 0; +// volatile uint16_t g_dtmRsp = 0; + +// volatile uint8_t g_dtmTxPower = RF_PHY_TX_POWER_0DBM;//RF_PHY_TX_POWER_EXTRA_MAX;//according to the rfdrv +// volatile uint16_t g_dtmFoff = 0; +// volatile uint8_t g_dtmRssi = 0; +// volatile uint8_t g_dtmCarrSens = 0; +// volatile uint8_t g_dtmTpCalEnable = 1; //default enable tpcal + +// volatile uint32_t g_dtmTick = 0; +// volatile uint32_t g_dtmPerAutoIntv = 0; + +// volatile uint32_t g_dtmAccessCode = RF_PHY_DTM_SYNC_WORD; +volatile uint8_t g_dtmManualConfig = RF_PHY_DTM_MANUL_ALL; +volatile uint8_t g_rc32kCalRes = 0xff; +// extern volatile int uart_rx_wIdx; // +// extern volatile char *urx_buf; + +#if(RF_PHY_DTM_CTRL_MOD == RF_PHY_DTM_CTRL_UART) + #include "log.h" + #define MAX_UART_BUF_SIZE 32 + #define MAX_UART_BUF_ID (MAX_UART_BUF_SIZE-1) + #define _DTM_UART_ UART0 + #define DTM_OUT(x) hal_uart_send_byte(_DTM_UART_,x) + #define DTM_LOG_INIT(...) dbg_printf_init() + #define DTM_LOG(...) dbg_printf_(__VA_ARGS__) + #define CLR_UART_WIDX {uart_rx_wIdx=0;} + #define GET_UART_WIDX (uart_rx_wIdx) + #define DTM_ADD_IDX(a,b) {(a==b)? a=0:a++;} + static unsigned char urx_buf[MAX_UART_BUF_SIZE]; + static volatile uint32_t uart_rx_wIdx=0,uart_rx_rIdx=0; +#endif + +#if(RF_PHY_CT_MONITER) +#define CT_MONT_BUFF_SIZE 128 +volatile uint32_t g_rfPhy_ct_moniter_word_cnt = 0; +volatile uint32_t g_rfPhy_ct_moniter_word_target = 0; +volatile uint16_t g_rfPhy_ct_moniter_word_arry[CT_MONT_BUFF_SIZE] = {0}; +#endif + + +void rf_tpCal_cfg_avg(uint8 rfChn,uint8 cnt); +/************************************************************************************** + @fn rf_phy_ini + + @brief This function process for rf phy ini call api + + input parameters + + @param None. + + output parameters + + @param None. + + @return None. +*/ +void rf_phy_ini(void) +{ + g_rfPhyClkSel = RF_PHY_CLK_SEL_16M_XTAL; + g_rxAdcClkSel = RX_ADC_CLK_SEL_32M_DBL; + rf_phy_ana_cfg(); + rf_phy_set_txPower(g_rfPhyTxPower);//set to max power + rf_phy_bb_cfg(g_rfPhyPktFmt); + extern void ll_hw_tx2rx_timing_config(uint8 pkt); + ll_hw_tx2rx_timing_config(g_rfPhyPktFmt); +} + +/************************************************************************************** + @fn rf_tpCal_cfg + + @brief This function process for rf tpCal config + + input parameters + + @param rfChn: two point calibration rf channel setting(0-80)->2400-2480MHz. + + output parameters + + @param None. + + @return None. +*/ +void rf_tpCal_cfg(uint8 rfChn) +{ + if( g_rfPhyPktFmt==PKT_FMT_BLE1M + || g_rfPhyPktFmt==PKT_FMT_BLR500K + || g_rfPhyPktFmt==PKT_FMT_BLR125K) + { + //g_rfPhyTpCal0=rf_tp_cal(rfChn,0)+5; + //ZQ:debug 20180427 + g_rfPhyTpCal0=rf_tp_cal(rfChn,0)+8; + } + else if( g_rfPhyPktFmt==PKT_FMT_BLE2M ) + { + g_rfPhyTpCal0=rf_tp_cal(rfChn,1)+4; + } + else + { + //for ZIGBEE + g_rfPhyTpCal0=rf_tp_cal(rfChn,1)+4; + } +} + + +/************************************************************************************** + @fn rf_tpCal_cfg_avg + + @brief This function process for rf tpCal config + + input parameters + + @param rfChn: two point calibration rf channel setting(0-80)->2400-2480MHz. + + output parameters + + @param None. + + @return None. +*/ +void rf_tpCal_cfg_avg(uint8 rfChn,uint8 avgNum) +{ + volatile uint8_t i = 0; + volatile uint16_t tmp=0; + + if( g_rfPhyPktFmt==PKT_FMT_BLE1M + || g_rfPhyPktFmt==PKT_FMT_BLR500K + || g_rfPhyPktFmt==PKT_FMT_BLR125K) + { + //g_rfPhyTpCal0=rf_tp_cal(rfChn,0)+5; + //ZQ:debug 20180427 + for ( i=0; i<(1<>avgNum)+8; + } + else if( g_rfPhyPktFmt==PKT_FMT_BLE2M ) + { + for ( i=0; i<(1<>avgNum)+4; + } + else + { + //for ZIGBEE + for ( i=0; i<(1<>avgNum)+4; + } +} + + +/************************************************************************************** + @fn rf_tpCal_gen_cap_arrary + + @brief This function process for tx tp calibration,genearte the tpCal cap arrary. + + input parameters + + @param + + output parameters + + @param none + + @return kCal : cal result for rfChn. +*/ + +void rf_tpCal_gen_cap_arrary(void) +{ + g_rfPhyTpCal0=rf_tp_cal(/*/rfChn*/2,0)+2; + g_rfPhyTpCal1=rf_tp_cal(/*/rfChn*/66,0)+2; + g_rfPhyTpCal0_2Mbps=rf_tp_cal(/*/rfChn*/2,1)+2; + g_rfPhyTpCal1_2Mbps=rf_tp_cal(/*/rfChn*/66,1)+2; +} + +/************************************************************************************** + @fn rf_phy_ana_cfg + + @brief This function process for rf phy analog block config, + include PLL, RX_FRONT_END,PA Power. + + input parameters + + @param None. + + output parameters + + @param None. + + @return None. +*/ +void rf_phy_ana_cfg(void) +{ + //------------------------------------------------------------------- + // RF_PHY RX ADC CLOCK Config + subWriteReg(0x4000f040,18,18, 0x01); // xtal output to digital enable : ALWAYS Set 1 + subWriteReg(0x4000f044,25,24, g_rxAdcClkSel); + subWriteReg(0x4000f044,23,22, g_rfPhyClkSel); + subWriteReg(0x4000f044, 6, 5, 0x03); // trim dll/dbl ldo vout + + if( (g_rxAdcClkSel == RX_ADC_CLK_SEL_32M_DBL) + || (g_rxAdcClkSel == RX_ADC_CLK_SEL_32M_DBL_B) + || (g_rfPhyClkSel == RF_PHY_CLK_SEL_32M_DBL) + || (g_rfPhyClkSel == RF_PHY_CLK_SEL_32M_DBL_B) ) + { + // enable dbl for rf + subWriteReg(0x4000f044, 8, 8, 0x01); // DBL EN,DLL EN,DLL LDO EN + } + + if( (g_rxAdcClkSel == RX_ADC_CLK_SEL_32M_DLL) + || (g_rfPhyClkSel == RF_PHY_CLK_SEL_32M_DLL) + ) + { + // enable dll for rf + subWriteReg(0x4000f044, 7, 7, 0x01); // DLL ensable + } + + subWriteReg(0x4000f044, 19, 18, 0x03); // Rx adc clk en, rf phy clk en + #if 0 + + //Reserved????? + //20190111 ZQ + // for 48M case should set dbl clk polarity + //config sel_rxadc_dbl_clk_32M_polarity; + if((g_system_clk==SYS_CLK_DLL_48M) ) + { + subWriteReg(0x4000f044,26,25, 0x03); + } + else + { + subWriteReg(0x4000f044,26,25, 0x00); + } + + #endif + + if(g_rfPhyClkSel==RF_PHY_CLK_SEL_16M_XTAL && g_system_clk == SYS_CLK_DLL_48M) + subWriteReg( 0x4003008c,23,23,0x01); + else + subWriteReg( 0x4003008c,23,23,0x00); + + //------------------------------------------------------------------- + // PLL + PHY_REG_WT(0x400300cc,0x20000bc0); // i_pll_ctrl0 : + //PHY_REG_WT(0x400300cc,0x20000fc0); // i_pll_ctrl0 : + //------------------------------------------------------------------- + //TX PLL BW + PHY_REG_WT(0x400300d0,0x00000180); // i_pll_ctrl1 + PHY_REG_WT(0x400300d4,0x076a3e7a); // i_pll_ctrl2 pll lpf, boost vco current[7:4] + PHY_REG_WT(0x400300d8,0x04890000); // i_pll_ctrl3 vco/tp varactor + //------------------------------------------------------------------- + //RX PLL BW active when rx_en + PHY_REG_WT(0x40030104,0x00000180); // i_pll_ctrl5 + PHY_REG_WT(0x40030108,0x076a3e7a); // i_pll_ctrl6 pll lpf, boost vco current[7:4] + PHY_REG_WT(0x4003010c,0x04898000); // i_pll_ctrl7 vco/tp varactor + //------------------------------------------------------------------- + //VCO Coarse Tuning Setting + PHY_REG_WT(0x40030080,0x000024cc); //[11:10] vco coarse tune slot time + //[9:7] delay from pll reset ends to start vco coarse tune + + //------------------------------------------------------------------- + //PLL config for rfPhyClk=16M + if(g_rfPhyClkSel==RF_PHY_CLK_SEL_16M_XTAL) + { + subWriteReg(0x40030080, 0, 0, 1);//indicate 16M reference clk to rfpll + //PHY_REG_WT(0x400300d0,0x00000140); // i_pll_ctrl1 //double cp current to compensate for clock; + //PHY_REG_WT(0x40030104,0x00000140); // i_pll_ctrl5 //double cp current to compensate for clock; + } + + //------------------------------------------------------------------- + // Tx PA + //PHY_REG_WT(0x400300b8,0x0000f825); // pa ramp reg, txPower for 0dBm + PHY_REG_WT(0x400300b8,0x0825|(((g_rfPhyTxPower)&0x1f)<<12)); // pa ramp reg, txPower for g_rfPhyTxPower + //------------------------------------------------------------------- + // TP Modulation + //PHY_REG_WT(0x40030090,0x00020000); // reg dc 40000 for 2M + //PHY_REG_WT(0x40030094,0x00001025); // tp_cal val + //PHY_REG_WT(0x400300b0,0x01000003); // dac dly + //------------------------------------------------------------------- + // Rx FrontEnd + //PHY_REG_WT(0x400300dc,0x01be7f2f); // + PHY_REG_WT(0x400300dc,0x01a6fc2f); // boost TIA current + //------------------------------------------------------------------- + //PA override + //subWriteReg(0x400300a0,0,0,1); //pa override + //subWriteReg(0x400300a4,0,0,1); //pa on + //subWriteReg(0x400300a4,8,8,0); //pa set b +} + + + + +/************************************************************************************** + @fn rf_phy_bb_cfg + + @brief This function process for rf phy baseband tx and rx config. + + input parameters + + @param pktMod:0 for Zigbee, 1 for BLE1M, 2 for BLE2M, 3or4 for BLELR. + + output parameters + + @param None. + + @return None. +*/ +void rf_phy_bb_cfg(uint8_t pktFmt) +{ + //BW Sel and Gauss sel + if(pktFmt==0 || pktFmt==2) + { + PHY_REG_WT( 0x400300e0,0x00000080); // set pga bw use small bw for zigbee and BLE2M + subWriteReg( 0x400300d8,20,18,0x02); // tpm dac var + + if(g_rfPhyClkSel == RF_PHY_CLK_SEL_16M_XTAL) + PHY_REG_WT( 0x40030090,0x00080000); // set reg_dc + else + PHY_REG_WT( 0x40030090,0x00040000); // set reg_dc + + //PHY_REG_WT( 0x40030094,0x00001048); // tp_cal val + } + else if(pktFmt<5) + { + PHY_REG_WT( 0x400300e0,0x00000100); // set pga bw + subWriteReg( 0x400300d8,20,18,0x01); // tpm dac var + + //subWriteReg( 0x400300d8,20,18,0x02); // tpm dac var + if(g_rfPhyClkSel == RF_PHY_CLK_SEL_16M_XTAL) + PHY_REG_WT( 0x40030090,0x00040000); // set reg_dc + else + PHY_REG_WT( 0x40030090,0x00020000); // set reg_dc + + //PHY_REG_WT( 0x40030094,0x00001025); // tp_cal val + } + else + { + PHY_REG_WT( 0x400300e0,0x00000100); // set pga bw + subWriteReg( 0x400300d8,20,18,0x01); // tpm dac var + + if(g_rfPhyClkSel == RF_PHY_CLK_SEL_16M_XTAL) + PHY_REG_WT( 0x40030090,0x00040000); // set reg_dc + else + PHY_REG_WT( 0x40030090,0x00020000); // set reg_dc + } + + PHY_REG_WT( 0x400300b0,0x01000003); // dac dly + PHY_REG_WT( 0x40030094,0x00001000+g_rfPhyTpCal0); // tp_cal val + + //pktFmt Setting and syncThd + if(pktFmt==0) + { + PHY_REG_WT( 0x40030000,0x78068000); + PHY_REG_WT( 0x40030048,0x00000000); //clr crc and wtSeed + PHY_REG_WT( 0x40030040,0x000b2800); // disable gauss + PHY_REG_WT( 0x4003004c,0x3675ee07); + ll_hw_set_crc_fmt (LL_HW_CRC_ZB_FMT, LL_HW_CRC_ZB_FMT); + } + else if(pktFmt==1) + { + PHY_REG_WT( 0x40030000,0x3d068001); + PHY_REG_WT( 0x40030048,0x37555555); + PHY_REG_WT( 0x40030040,0x00032800); // enable gauss + PHY_REG_WT( 0x4003004c,0x8e89bed6); + ll_hw_set_crc_fmt (LL_HW_CRC_BLE_FMT, LL_HW_CRC_BLE_FMT); + } + else if(pktFmt==2) + { + PHY_REG_WT( 0x40030000,0x3d068002); + PHY_REG_WT( 0x40030048,0x37555555); + PHY_REG_WT( 0x40030040,0x00032800); // enable gauss + PHY_REG_WT( 0x4003004c,0x8e89bed6); + ll_hw_set_crc_fmt (LL_HW_CRC_BLE_FMT, LL_HW_CRC_BLE_FMT); + } + else if(pktFmt==3 || pktFmt==4) + { + //pktFmt=3 or pktFmt=4 + PHY_REG_WT( 0x40030000,0x98068000|pktFmt); //for tx set differnt phy + PHY_REG_WT( 0x40030004,0x50985a54); //for RSSI >-90 set higher syncThd=0x98 + PHY_REG_WT( 0x40030040,0x00032800); // enable gauss + PHY_REG_WT( 0x40030048,0x37555555); + PHY_REG_WT( 0x4003004c,0x8e89bed6); + ll_hw_set_crc_fmt (LL_HW_CRC_BLE_FMT, LL_HW_CRC_BLE_FMT); + } + else + { + PHY_REG_WT( 0x40030000,0x42068000|pktFmt); + PHY_REG_WT( 0x40030048,0x00555555); + PHY_REG_WT( 0x40030040,0x000b2800); // enable gauss + PHY_REG_WT( 0x4003004c,0x8e89bed6); + ll_hw_set_crc_fmt (LL_HW_CRC_BLE_FMT, LL_HW_CRC_BLE_FMT); + } + + //Agc Control Setting + if(pktFmt==0) + { + PHY_REG_WT( 0x40030050,0x22086680); + } + else if(pktFmt==2) + { + PHY_REG_WT( 0x40030050,0x22084580); + } + else + { + PHY_REG_WT( 0x40030050,0x22085580); + } + + // add by ZQ 20181030 for DLE feature + // set to 255 + // need considering the ADV PDU in BLE 5.0 + subWriteReg(0x4003000c,7,0, 0xff); + //AGC TAB with LNA two gain step,no bypass lna mode + //20200721 for tsop 6252 + PHY_REG_WT(0x40030054, 0x545c9ca4); + PHY_REG_WT(0x40030058, 0x4243444c); + PHY_REG_WT(0x4003005c, 0x464c5241); + PHY_REG_WT(0x40030060, 0x2e343a40); + PHY_REG_WT(0x40030064, 0x557f0028); + PHY_REG_WT(0x40030068, 0x3d43494f); + PHY_REG_WT(0x4003006c, 0x4c2b3137); + PHY_REG_WT(0x40030070, 0x343a4046); + PHY_REG_WT(0x40030074, 0x1c22282e); + #if 0 + PHY_REG_WT( 0x40030054,0x545c9ca4 ); + PHY_REG_WT( 0x40030058,0x03040c4c ); + PHY_REG_WT( 0x4003005c,0x464c5202 ); + PHY_REG_WT( 0x40030060,0x262e3a40 ); + PHY_REG_WT( 0x40030064,0x557f0020 ); + PHY_REG_WT( 0x40030068,0x3b43494f ); + PHY_REG_WT( 0x4003006c,0x4c23292f ); + PHY_REG_WT( 0x40030070,0x343a4046 ); + PHY_REG_WT( 0x40030074,0x191f252b ); + #endif + #if(RF_PHY_EXT_PREAMBLE_US) + + //ext preamble for BLE 1M/2M, nByte + if(pktFmt==PKT_FMT_BLE1M) + { + subWriteReg(0x40030040, 7, 5, (RF_PHY_EXT_PREAMBLE_US>>3) ); // 1byte -> 8us + } + else if(pktFmt == PKT_FMT_BLE2M) + { + subWriteReg(0x40030040, 7, 5, (RF_PHY_EXT_PREAMBLE_US>>2) );//2 byte -> 8us + } + + #endif +} + + +void rf_phy_change_cfg0(uint8_t pktFmt) +{ + //BW Sel and Gauss sel + if(pktFmt==PKT_FMT_BLE2M) + { + PHY_REG_WT( 0x400300e0,0x00000080); // set pga bw use small bw for zigbee and BLE2M + subWriteReg( 0x400300d8,20,18,0x02); // tpm dac var + + if(g_rfPhyClkSel == RF_PHY_CLK_SEL_16M_XTAL) + PHY_REG_WT( 0x40030090,0x00080000); // set reg_dc + else + PHY_REG_WT( 0x40030090,0x00040000); // set reg_dc + + //PHY_REG_WT( 0x40030094,0x00001048); // tp_cal val + } + else + { + PHY_REG_WT( 0x400300e0,0x00000080); // set pga bw + subWriteReg( 0x400300d8,20,18,0x01); // tpm dac var + + if(g_rfPhyClkSel == RF_PHY_CLK_SEL_16M_XTAL) + PHY_REG_WT( 0x40030090,0x00040000); // set reg_dc + else + PHY_REG_WT( 0x40030090,0x00020000); // set reg_dc + + //PHY_REG_WT( 0x40030094,0x00001025); // tp_cal val + } + + //pktFmt Setting and syncThd + if(pktFmt==PKT_FMT_BLE1M) + { + PHY_REG_WT( 0x40030000,0x3d068001); + } + else if(pktFmt==PKT_FMT_BLE2M) + { + PHY_REG_WT( 0x40030000,0x3d068002); + } + else + { + //pktFmt=3 or pktFmt=4 + PHY_REG_WT( 0x40030000,0x98068000|pktFmt); //for tx set differnt phy + } + + //Agc Control Setting + if(pktFmt==PKT_FMT_BLE1M) + { + PHY_REG_WT( 0x40030050,0x22086680); + } + else if(pktFmt==PKT_FMT_BLE2M) + { + PHY_REG_WT( 0x40030050,0x22084580); + } + else + { + PHY_REG_WT( 0x40030050,0x22085580); + } +} +/************************************************************************************** + @fn rf_tp_cal + + @brief This function process for tx tp calibration. + + input parameters + + @param rfChn : rfFreq=2400+rfChn + fDev : used to config the tpCal fDelt, 0 for 0.5M, 1 for 1M + + + output parameters + + @param none + + @return kCal : cal result for rfChn. +*/ +uint8_t rf_tp_cal(uint8_t rfChn, uint8_t fDev) +{ + PHY_REG_WT( 0x40030040,0x00030010); // enable test mode not to generate txdone + + if(fDev==1) + { + subWriteReg( 0x400300d8,20,18,0x02); // tpm dac var + PHY_REG_WT( 0x4003008c,0x0053407f); + } + else + { + subWriteReg( 0x400300d8,20,18,0x01); // tpm dac var + PHY_REG_WT( 0x4003008c,0x0073407f); + } + + if(g_rfPhyClkSel==RF_PHY_CLK_SEL_16M_XTAL && g_system_clk == SYS_CLK_DLL_48M) + subWriteReg( 0x4003008c,23,23,0x01); + else + subWriteReg( 0x4003008c,23,23,0x00); + + PHY_REG_WT( 0x400300b4,0xff&rfChn); // set rfFreq=2400+rfChn + PHY_REG_WT( 0x400300a0,0x0000000e); // set pll_auto override + //------------------------------------------------------------------------- + // Cal Trig + // + PHY_REG_WT( 0x400300a4,0x00000000); // clr tx_auto + PHY_REG_WT( 0x400300a4,0x00000114); // set tx_auto + //------------------------------------------------------------------------- + // Wait to Read Reslut + // When HCLK 16M --> 10000*3/16 around 2ms + volatile int timeOut = 10000; + + switch (g_system_clk) + { + case SYS_CLK_XTAL_16M: + timeOut=timeOut; + break; + + case SYS_CLK_RC_32M: + case SYS_CLK_DLL_32M: + timeOut=timeOut*2; + break; + #if (PHY_MCU_TYPE == MCU_BUMBEE_M0 || PHY_MCU_TYPE == MCU_BUMBEE_CK802) + + case SYS_CLK_4M: + break; + + case SYS_CLK_8M: + break; + #elif ((PHY_MCU_TYPE == MCU_PRIME_A1) ||(PHY_MCU_TYPE == MCU_PRIME_A2)) + + case SYS_CLK_DBL_32M: + timeOut=timeOut*2; + break; + #endif + + case SYS_CLK_DLL_48M: + timeOut=timeOut*3; + break; + + case SYS_CLK_DLL_64M: + timeOut=timeOut*4; + break; + + default: + timeOut=timeOut; + break; + } + + while(timeOut--) {}; + + uint8_t kCal = (0xff0000 & PHY_REG_RD(0x400300f4))>>16; + + PHY_REG_WT( 0x400300a4,0x00000000); // clr tx_auto + + PHY_REG_WT( 0x400300a0,0x00000000); // clr pll_auto override + + PHY_REG_WT( 0x4003008c,0x00104040); // clr tp_cal_en + + PHY_REG_WT( 0x400300a4,0x00000140); // clr tx_auto + + PHY_REG_WT( 0x40030040,0x00032800); + + #if(RF_PHY_EXT_PREAMBLE_US) + + //ext preamble for BLE 1M/2M, nByte + if(g_rfPhyPktFmt==PKT_FMT_BLE1M) + { + subWriteReg(0x40030040, 7, 5, (RF_PHY_EXT_PREAMBLE_US>>3) ); // 1byte -> 8us + } + else if(g_rfPhyPktFmt == PKT_FMT_BLE2M) + { + subWriteReg(0x40030040, 7, 5, (RF_PHY_EXT_PREAMBLE_US>>2) );//2 byte -> 8us + } + + #endif + + if(g_rfPhyClkSel==RF_PHY_CLK_SEL_16M_XTAL && g_system_clk == SYS_CLK_DLL_48M) + subWriteReg( 0x4003008c,23,23,0x01); + else + subWriteReg( 0x4003008c,23,23,0x00); + + return kCal; +} + + + + +/************************************************************************************** + @fn rf_rxDcoc_cfg + + @brief This function process for rx dc offset calibration and canncellation config. + + input parameters + + @param rfChn : rfFreq=2400+rfChn + bwSet : used to config rx complex filter bandwitdh. 1 for 1MHz, other for 2MHz + + + output parameters + + @param dcCal : cal result for rxdc, dcQ[13:8],dcI[5:0] + + @return none +*/ +void rf_rxDcoc_cfg(uint8_t rfChn, uint8_t bwSet, volatile uint32* dcCal) +{ + //-------------------------------------------------------------- + //rf_ana_cfg should be called before doing dcoc calibration + //-------------------------------------------------------------- + // restore the rxTimeOut setting, and set rxto to zero, not to generate rx_done + // + // + int rxTimeOut1st = PHY_REG_RD(0x40031024); + int rxTimeOut = PHY_REG_RD(0x40031028); + PHY_REG_WT(0x40031024,0x00000000); + PHY_REG_WT(0x40031028,0x00000000); + //-------------------------------------------------------------- + //rx close + // + PHY_REG_WT( 0x400300b4,0xff&rfChn); // set rfFreq=2400+rfChn + PHY_REG_WT( 0x400300a0,0x0000000e); // set pll_auto override + PHY_REG_WT( 0x400300a4,0x00000100); // clr trx_auto + PHY_REG_WT( 0x400300a8,0x00000040); // set lo override + PHY_REG_WT( 0x400300ac,0x00000050); // set rx lo and pll buff + PHY_REG_WT( 0x400300a4,0x0000012a); // rx close + //-------------------------------------------------------------- + //set filter bw and rx gain,dcoc cal control + // + uint16 fltPhy = 0; + + if(bwSet==1) + { + PHY_REG_WT( 0x400300e0,0x00000100); // set pga bw(0100:1M,1100:2M) + fltPhy = 0x034d; + } + else + { + PHY_REG_WT( 0x400300e0,0x00000080); // set pga bw(0100:1M,1100:2M) + fltPhy = 0x02ca; + } + + PHY_REG_WT( 0x400300c8,0x000001a4); // set to rx max gain + PHY_REG_WT( 0x400300c4,0x00002020); // dcoc dac controled by mix_sig_top for cal + PHY_REG_WT( 0x40030050,0x200c5680); // enlarge dcoc cal average time + // enlarge pga settle time + //-------------------------------------------------------------- + //wait for rf settle + // + volatile int cnt=1000; + + while(cnt--) {}; + + PHY_REG_WT( 0x40030078,(fltPhy<<22)|0x216564); // clr dcoc_en[0] , set to phase search mode[1] + + PHY_REG_WT( 0x40030078,(fltPhy<<22)|0x216565); // set dcoc_en[0], dcoc start + + //-------------------------------------------------------------- + //wait to read the cal result + // + cnt=10000; + + switch (g_system_clk) + { + case SYS_CLK_XTAL_16M: + cnt=cnt; + break; + + case SYS_CLK_RC_32M: + case SYS_CLK_DLL_32M: + cnt=cnt*2; + break; + #if (PHY_MCU_TYPE == MCU_BUMBEE_M0 || PHY_MCU_TYPE == MCU_BUMBEE_CK802) + + case SYS_CLK_4M: + break; + + case SYS_CLK_8M: + break; + #elif ((PHY_MCU_TYPE == MCU_PRIME_A1) ||(PHY_MCU_TYPE == MCU_PRIME_A2)) + + case SYS_CLK_DBL_32M: + cnt=cnt*2; + break; + #endif + + case SYS_CLK_DLL_48M: + cnt=cnt*3; + break; + + case SYS_CLK_DLL_64M: + cnt=cnt*4; + break; + + default: + cnt=cnt; + break; + } + + *dcCal = 0x20200000; // set the dc cal to default val + + while(cnt--) + { + if(3==(0x03 & (PHY_REG_RD(0x400300ec)>>30))) + { + *dcCal = PHY_REG_RD(0x400300ec)&0x3f3fffff; // get the dc cal result + PHY_REG_WT( 0x400300c4,0x00010000 | ((*dcCal)>>16)); // set to dcoc dac code + break; + } + } + + //-------------------------------------------------------------- + //end of cfg + // + PHY_REG_WT( 0x40030078,(fltPhy<<22)|0x216564); // clr dcoc_en[0] , set to phase search mode[1] + PHY_REG_WT( 0x400300a8,0x00000000); // clr lo override + PHY_REG_WT( 0x400300ac,0x00000000); // clr rx lo and pll buff + PHY_REG_WT( 0x400300c8,0x00000000); // set to rx max gain + PHY_REG_WT( 0x400300a4,0x00000100); // clr tx_auto + PHY_REG_WT( 0x400300a0,0x00000000); // clr pll_auto override + PHY_REG_WT( 0x400300a4,0x00000140); // clr tx_auto + PHY_REG_WT(0x40031024,rxTimeOut1st); + PHY_REG_WT(0x40031028,rxTimeOut); +} + +#if(RF_PHY_DTM_CTRL_MOD == RF_PHY_DTM_CTRL_UART) +/************************************************************************************** + @fn rf_phy_dtm_uart_irq + + @brief This function process for rf phy direct test uart irq. + + input parameters + + @param none + + output parameters + + @param none + + @return none +*/ +void DTM_UART_IRQHandler(void) +{ + uint8_t IRQ_ID= (AP_UART0->IIR & 0x0f); + + switch (IRQ_ID) + { + case RDA_IRQ: + case TIMEOUT_IRQ: + while(AP_UART0 ->LSR & 0x1) + { + urx_buf[uart_rx_wIdx]=(AP_UART0->RBR & 0xff); + DTM_ADD_IDX(uart_rx_wIdx, MAX_UART_BUF_ID); + } + + break; + + case BUSY_IRQ: + AP_UART0 -> USR; + break; + } +} +// static uint32_t dtm_read_current_time(void) +// { +// // return ((4000000-get_timer3_count())/4+2); +// return (RF_PHY_TIME_BASE - ((AP_TIM3->CurrentCount) >> 2) ) ; +// } + +#endif + +#if(RF_PHY_DTM_CTRL_MOD == RF_PHY_DTM_CTRL_UART) +/************************************************************************************** + @fn rf_phy_direct_test + + @brief This function process for rf phy direct test. + + input parameters + + @param none + + output parameters + + @param none + + @return none +*/ +void rf_phy_direct_test(void) +{ + int dtmState = 0; + uint32_t deltTick = 0; + uint32_t currTick = 0; + //enable received data available interrupt + DTM_LOG_INIT(); + DTM_LOG("\n===RF_PHY_DTM V1.1.2===\n"); + //clr UART IRQ, switch to ROM_UART_IRQ + JUMP_FUNCTION(UART0_IRQ_HANDLER) = (uint32_t)&DTM_UART_IRQHandler; + + if(RF_PHY_DTM_BB_SUPPORT_MOD&RF_PHY_DTM_BB_SUPPORT_BLE1M) + DTM_LOG("=== SUPPORT BLE 1M ===\n"); + + if(RF_PHY_DTM_BB_SUPPORT_MOD&RF_PHY_DTM_BB_SUPPORT_BLE2M) + DTM_LOG("=== SUPPORT BLE 2M ===\n"); + + if(RF_PHY_DTM_BB_SUPPORT_MOD&RF_PHY_DTM_BB_SUPPORT_BLR500K) + DTM_LOG("=== SUPPORT BLR 500K===\n"); + + if(RF_PHY_DTM_BB_SUPPORT_MOD&RF_PHY_DTM_BB_SUPPORT_BLR125K) + DTM_LOG("=== SUPPORT BLR 125K===\n"); + + if(RF_PHY_DTM_BB_SUPPORT_MOD&RF_PHY_DTM_BB_SUPPORT_ZIGBEE) + DTM_LOG("=== SUPPORT ZIGBEE ===\n"); + + //*(volatile int *) 0xe000e100 |= 0x800; + *(volatile int*) 0xe000e100 = 0x800; //only use uart irq + *(volatile unsigned int*) 0x40004004 |= 0x01; //ENABLE_ERBFI; + //set timer3 free run + //AP_TIM3->ControlReg = 0x05; + //24bit count down mode no IRQ + set_timer(AP_TIM3,RF_PHY_TIME_BASE); + NVIC_DisableIRQ(TIM3_IRQn); + //clear widx + CLR_UART_WIDX; + + while(1) + { + if( dtmState == RF_PHY_DTM_IDL) + { + if(GET_UART_WIDX>=2) + { + g_rfPhyDtmCmd[0]=urx_buf[0]; + g_rfPhyDtmCmd[1]=urx_buf[1]; + dtmState = RF_PHY_DTM_CMD; + CLR_UART_WIDX; + } + + //=================== cmd parsing ===================== + } + else if(dtmState == RF_PHY_DTM_CMD) + { + rf_phy_dtm_cmd_parse(); + dtmState = RF_PHY_DTM_EVT; + //=================== send event ===================== + } + else if(dtmState == RF_PHY_DTM_EVT) + { + rf_phy_dtm_evt_send(g_dtmModeType); + dtmState = RF_PHY_DTM_TEST; + //=================== TEST Start ===================== + } + else if(dtmState == RF_PHY_DTM_TEST) + { + rf_phy_dtm_trigged(); + g_dtmPktCount = 0; + uint8_t rssi; + uint8_t carrSens; + uint16_t foff; + uint8_t zgb_pkt_flg=0; + + //when new cmd arrived, state change + while(GET_UART_WIDX<2) + { + //TX BURST re-trigger + if(g_dtmModeType == RF_PHY_DTM_MODE_TX_BURST) + { + //============================================================ + //20180424-ZQ + //option 1 + ll_hw_set_trx_settle (100, 8, 80); //TxBB,RxAFE,PLL + //============================================================ + currTick = read_current_fine_time(); + deltTick = RF_PHY_TIME_DELTA(currTick,g_dtmTick); + + if( (ll_hw_get_irq_status() & LIRQ_MD) + && g_rfPhyPktFmt == PKT_FMT_ZIGBEE + && zgb_pkt_flg==0) + { + //ll_hw_rst_tfifo(); + //rf_phy_dtm_zigbee_pkt_gen(); + ll_hw_clr_irq(); + zgb_pkt_flg=1; + PHY_REG_WT( 0x4003105c,0x00000000); // clr rd_ini and rd_last + } + + if(deltTick>=g_dtmPktIntv) + { + if(!(g_rfPhyPktFmt==PKT_FMT_ZIGBEE)) + { + ll_hw_rst_tfifo(); + ll_hw_trigger(); +// if(g_rfPhyPktFmt==PKT_FMT_BLE2M) +// { +// //set tx_auto_ctrl0 first +// PHY_REG_WT( 0x400300a4,0x00000140); // clr tx_auto +// PHY_REG_WT( 0x400300a4,0x00000150); // clr tx_auto +// //wait a while then set tx_bb_en +// int delay=100;while(delay--){}; +// PHY_REG_WT( 0x400300a4,0x00000154); // clr tx_auto +// } +// else +// { +// ll_hw_trigger(); +// //PHY_REG_WT( 0x400300a0,0x0000000e); // clr pll_auto override +// //PHY_REG_WT( 0x400300a4,0x00000140); // clr tx_auto +// //PHY_REG_WT( 0x400300a4,0x00000154); // clr tx_auto +// +// } + } + else + { + ll_hw_trigger(); + //PHY_REG_WT( 0x400300a4,0x00000140); // clr tx_auto + //PHY_REG_WT( 0x400300a4,0x00000154); // clr tx_auto + zgb_pkt_flg=0; + } + + #if(RF_PHY_CT_MONITER) + WaitUs(350); + int32_t ct_word= (PHY_REG_RD(0x400300f4)&0x3ff); + + if(ct_word>0) + { + if(g_rfPhy_ct_moniter_word_cnt==0) + g_rfPhy_ct_moniter_word_target = ct_word; + + int32_t idx= (ct_word)-g_rfPhy_ct_moniter_word_target+(CT_MONT_BUFF_SIZE>>1); + g_rfPhy_ct_moniter_word_cnt++; + + if(idx<0) + { + LOG("e %d %d\n",ct_word,PHY_REG_RD(0x400300f8)&0xfffff); + g_rfPhy_ct_moniter_word_arry[0]++; + } + else if(idx>CT_MONT_BUFF_SIZE-1) + { + g_rfPhy_ct_moniter_word_arry[CT_MONT_BUFF_SIZE-1]++; + } + else + { + g_rfPhy_ct_moniter_word_arry[idx]++; + } + + if(g_rfPhy_ct_moniter_word_cnt>RF_PHY_CT_MONITER) + { + for (int i=0; i0) + LOG("%d %d\n",g_rfPhy_ct_moniter_word_target-(CT_MONT_BUFF_SIZE>>1)+i,g_rfPhy_ct_moniter_word_arry[i]); + + g_rfPhy_ct_moniter_word_arry[i]=0; + } + + g_rfPhy_ct_moniter_word_cnt=0; + } + } + + #endif + //g_dtmTick = read_current_time(); + g_dtmTick = g_dtmTick+g_dtmPktIntv; + + if(g_dtmTick>RF_PHY_TIME_BASE) + g_dtmTick = g_dtmTick-RF_PHY_TIME_BASE; + } + } + else if( g_dtmModeType == RF_PHY_DTM_MODE_RX_PER + || g_dtmModeType == RF_PHY_DTM_MODE_GET_PER_AUTO) + { + //fix max gain can imporve 2480 sensitivity + if(g_dtmManualConfig&RF_PHY_DTM_MANUL_MAX_GAIN) + { + subWriteReg(0x40030050, 4,0,0x10); //fix max gain + } + + subWriteReg(0x4000f018,14,9,0x3f);//rc32M clk slow + + if(ll_hw_get_irq_status()&LIRQ_MD) + { + if(ll_hw_get_irq_status()&LIRQ_COK) + { + g_dtmPktCount++; + rf_phy_get_pktFoot(&rssi,&foff,&carrSens); + } + else if(ll_hw_get_irq_status()&LIRQ_CERR) + { + g_dtmRxCrcNum++; + } + else if(ll_hw_get_irq_status()&LIRQ_RTO) + { + g_dtmRxTONum++; + } + else + { + //wrap the pktCount + g_dtmPktCount= (g_dtmPktCount==65535) ? 0 : g_dtmPktCount; + } + + if( g_dtmModeType == RF_PHY_DTM_MODE_GET_PER_AUTO) + { + currTick = read_current_fine_time(); + deltTick = RF_PHY_TIME_DELTA(currTick,g_dtmTick); + + if(deltTick>g_dtmPerAutoIntv) + { + rf_phy_dtm_evt_send(RF_PHY_DTM_MODE_TEST_END);//send pktCount + WaitUs(500); + rf_phy_dtm_evt_send(RF_PHY_DTM_MODE_GET_FOFF);//send FOFF + WaitUs(500); + rf_phy_dtm_evt_send(RF_PHY_DTM_MODE_GET_RSSI);//send RSSI + WaitUs(500); + rf_phy_dtm_evt_send(RF_PHY_DTM_MODE_GET_CARR_SENS);//send CARR_SENS + WaitUs(500); + g_dtmPktCount = 0; + g_dtmRxCrcNum = 0; + g_dtmRxTONum = 0; + g_dtmTick = read_current_fine_time(); + } + }//EndOfIF PER_AUTO + + ll_hw_clr_irq(); + ll_hw_trigger(); + + if(g_dtmPktCount>0) + { + g_dtmRssi = (g_dtmPktCount==1) ? rssi :((g_dtmRssi+rssi) >>1); + g_dtmFoff = (g_dtmPktCount==1) ? foff :((g_dtmFoff+foff) >>1); + g_dtmCarrSens = (g_dtmPktCount==1) ? carrSens :((g_dtmCarrSens+carrSens) >>1); + } + } + }//end of RX_PER + }//end of GET_UART_WIDX + + dtmState = RF_PHY_DTM_IDL; + } + }//end of while(1) +} + + +#endif + +#if(RF_PHY_DTM_CTRL_MOD == RF_PHY_DTM_CTRL_UART) +/************************************************************************************** + @fn rf_phy_dtm_cmd_parse + + @brief This function process for rf phy direct test,cmd parse + + input parameters + + @param none + + output parameters + + @param none + + @return none +*/ +void rf_phy_dtm_cmd_parse(void) +{ + g_dtmCmd = ((g_rfPhyDtmCmd[0] & 0xc0)>>6); // bit 15 14 + + //test setup and test end + if(g_dtmCmd == 0 || g_dtmCmd==3 ) + { + g_dtmCtrl = ((g_rfPhyDtmCmd[0] & 0x3f) ); // bit 13 8 + g_dtmPara = ((g_rfPhyDtmCmd[1] & 0xfc)>>2); // bit 7 2 + + //TEST SETUP + if(g_dtmCmd==0) + { + if(g_dtmCtrl==0 && g_dtmPara==0) + { + g_dtmModeType = RF_PHY_DTM_MODE_RESET; + } + else if(g_dtmCtrl==1) + { + g_dtmModeType = RF_PHY_DTM_MODE_SET_LENGTH_UP2BIT; + g_dtmExtLen = (g_dtmPara&0x3); + } + else if(g_dtmCtrl==2 && g_dtmPara ==0x01) + { + g_dtmModeType = RF_PHY_DTM_MODE_SET_PHY_1M; + g_rfPhyPktFmt = PKT_FMT_BLE1M; + } + else if(g_dtmCtrl==2 && g_dtmPara ==0x02) + { + g_dtmModeType = RF_PHY_DTM_MODE_SET_PHY_2M; + g_rfPhyPktFmt = (RF_PHY_DTM_BB_SUPPORT_BLE2M & RF_PHY_DTM_BB_SUPPORT_MOD) + ?PKT_FMT_BLE2M:PKT_FMT_BLE1M; + } + else if(g_dtmCtrl==2 && g_dtmPara ==0x03) + { + g_dtmModeType = RF_PHY_DTM_MODE_SET_PHY_125K; + g_rfPhyPktFmt = (RF_PHY_DTM_BB_SUPPORT_BLR125K & RF_PHY_DTM_BB_SUPPORT_MOD) + ?PKT_FMT_BLR125K:PKT_FMT_BLE1M; + } + else if(g_dtmCtrl==2 && g_dtmPara ==0x04) + { + g_dtmModeType = RF_PHY_DTM_MODE_SET_PHY_500K; + g_rfPhyPktFmt = (RF_PHY_DTM_BB_SUPPORT_BLR500K & RF_PHY_DTM_BB_SUPPORT_MOD) + ?PKT_FMT_BLR500K:PKT_FMT_BLE1M; + } + else if(g_dtmCtrl==2 && g_dtmPara ==0x20) + { + g_dtmModeType = RF_PHY_DTM_MODE_SET_PHY_ZB; + g_rfPhyPktFmt = (RF_PHY_DTM_BB_SUPPORT_ZIGBEE & RF_PHY_DTM_BB_SUPPORT_MOD) + ?PKT_FMT_ZIGBEE:PKT_FMT_BLE1M; + } + else if(g_dtmCtrl==3 && g_dtmPara ==0x00) + { + g_dtmModeType = RF_PHY_DTM_MODE_ASSUME_TX_MOD_INDX_STANDARD; + } + else if(g_dtmCtrl==3 && g_dtmPara ==0x01) + { + g_dtmModeType = RF_PHY_DTM_MODE_ASSUME_TX_MOD_INDX_STABLE; + } + else if(g_dtmCtrl==4 && g_dtmPara ==0x00) + { + g_dtmModeType = RF_PHY_DTM_MODE_READ_SUPPORTED_TEST_CASE; + } + else if(g_dtmCtrl==5 && g_dtmPara ==0x00) + { + g_dtmModeType = RF_PHY_DTM_MODE_READ_MAX_TX_OCTETS; + } + else if(g_dtmCtrl==5 && g_dtmPara ==0x01) + { + g_dtmModeType = RF_PHY_DTM_MODE_READ_MAX_TX_TIME; + } + else if(g_dtmCtrl==5 && g_dtmPara ==0x02) + { + g_dtmModeType = RF_PHY_DTM_MODE_READ_MAX_RX_OCTETS; + } + else if(g_dtmCtrl==5 && g_dtmPara ==0x03) + { + g_dtmModeType = RF_PHY_DTM_MODE_READ_MAX_RX_TIME; + } + else if(g_dtmCtrl==0x34) + { + uint8_t ret=g_dtmPara & 0x01; + + for(uint8_t pin=0; pin<23; pin++) + { + if((pin == P2) || (pin == P3)) + { + hal_gpio_pin2pin3_control((gpio_pin_e)pin,ret); + gpio_write((gpio_pin_e)pin,ret); + } + else if((pin == P9) || (pin == P10) || (pin == P16) || (pin == P17)) + { + continue; + } + else + gpio_write((gpio_pin_e)pin,ret); + } + } + else if(g_dtmCtrl==0x35) + { + uint8_t ret=g_dtmPara>>5; + uint8_t pin=g_dtmPara & 0x1f; + + if((pin == P2) || (pin == P3)) + hal_gpio_pin2pin3_control((gpio_pin_e)pin,ret); + + gpio_write((gpio_pin_e)pin,ret); + // PHYPLUSE DEFINED: RF_PHY_DTM_MODE_SET_ACCCODE_0 + } + else if(g_dtmCtrl==0x36) + { + g_dtmModeType = RF_PHY_DTM_MODE_SET_ACCCODE_0; + g_dtmAccessCode = (g_dtmAccessCode&(0xffffff00))|g_rfPhyDtmCmd[1]; + // PHYPLUSE DEFINED: RF_PHY_DTM_MODE_SET_ACCCODE_1 + } + else if(g_dtmCtrl==0x37) + { + g_dtmModeType = RF_PHY_DTM_MODE_SET_ACCCODE_1; + g_dtmAccessCode = (g_dtmAccessCode&(0xffff00ff))|(g_rfPhyDtmCmd[1]<<8); + // PHYPLUSE DEFINED: RF_PHY_DTM_MODE_SET_ACCCODE_2 + } + else if(g_dtmCtrl==0x38) + { + g_dtmModeType = RF_PHY_DTM_MODE_SET_ACCCODE_2; + g_dtmAccessCode = (g_dtmAccessCode&(0xff00ffff))|(g_rfPhyDtmCmd[1]<<16); + // PHYPLUSE DEFINED: RF_PHY_DTM_MODE_SET_ACCCODE_3 + } + else if(g_dtmCtrl==0x39) + { + g_dtmModeType = RF_PHY_DTM_MODE_SET_ACCCODE_3; + g_dtmAccessCode = (g_dtmAccessCode&(0x00ffffff))|(g_rfPhyDtmCmd[1]<<24); + // PHYPLUSE DEFINED: TX TEST MODE Set FREQ FOFF + } + else if(g_dtmCtrl==0x3a) + { + g_dtmModeType = RF_PHY_DTM_MODE_SET_FREQ_FOFF; + + if(g_dtmManualConfig & RF_PHY_DTM_MANUL_FOFF) + { + g_rfPhyFreqOffSet = (g_dtmPara-10)*5;//[0:1:20]-->[-50:5:50]-->[-200:20:200]KHz + } + + // PHYPLUSE DEFINED: TX TEST MODE Set TP_CAL MANUAL + } + else if(g_dtmCtrl==0x3b) + { + g_dtmModeType = RF_PHY_DTM_MODE_SET_TPCAL_MANUAL; + + if(g_dtmPara==0) + { + g_dtmTpCalEnable = 1; + } + else + { + g_dtmTpCalEnable = 0; + g_rfPhyTpCal0 = (g_dtmPara)<<1; + PHY_REG_WT( 0x40030094,0x00001000+g_rfPhyTpCal0); // tp_cal val + } + + // PHYPLUSE DEFINED: TX TEST MODE Set XTAL CAP + } + else if(g_dtmCtrl==0x3c) + { + g_dtmModeType = RF_PHY_DTM_MODE_SET_XTAL_CAP; + + if(g_dtmManualConfig & RF_PHY_DTM_MANUL_XTAL_CAP) + { + XTAL16M_CAP_SETTING(g_dtmPara); + } + + // PHYPLUSE DEFINED: TX TEST MODE Set TX POWER + } + else if(g_dtmCtrl==0x3d) + { + g_dtmModeType = RF_PHY_DTM_MODE_SET_TX_POWER; + + if(g_dtmManualConfig & RF_PHY_DTM_MANUL_TXPOWER) + { + g_dtmTxPower = g_dtmPara; + } + + // PHYPLUSE DEFINED: TX TEST MODE Continous Modulation + } + else if(g_dtmCtrl==0x3e) + { + g_dtmModeType = RF_PHY_DTM_MODE_TX_CTMOD; + g_dtmFreq = g_dtmPara; + // PHYPLUSE DEFINED: TX TEST MODE Single Tone + } + else if(g_dtmCtrl==0x3f) + { + g_dtmModeType = RF_PHY_DTM_MODE_TX_SINGLE; + g_dtmFreq = g_dtmPara; + } + else + { + g_dtmModeType = RF_PHY_DTM_MODE_ERROR; + } + + //TEST END + } + else + { + if(g_dtmCtrl==0 && g_dtmPara==0) + { + g_dtmModeType = RF_PHY_DTM_MODE_TEST_END; + // PHYPLUSE DEFINED: get foff + } + else if(g_dtmCtrl==0x3f && g_dtmPara==0) + { + g_dtmModeType = RF_PHY_DTM_MODE_GET_FOFF; + // PHYPLUSE DEFINED: get tpCal + } + else if(g_dtmCtrl==0x3f && g_dtmPara==1) + { + g_dtmModeType = RF_PHY_DTM_MODE_GET_TPCAL; + // PHYPLUSE DEFINED: get RSSI + } + else if(g_dtmCtrl==0x3f && g_dtmPara==2) + { + g_dtmModeType = RF_PHY_DTM_MODE_GET_RSSI; + // PHYPLUSE DEFINED: get CARR_SENS + } + else if(g_dtmCtrl==0x3f && g_dtmPara==3) + { + g_dtmModeType = RF_PHY_DTM_MODE_GET_CARR_SENS; + // PHYPLUSE DEFINED: get PER report Auto + } + else if(g_dtmCtrl==0x3f && g_dtmPara==4) + { + g_dtmModeType = RF_PHY_DTM_MODE_GET_PER_AUTO; + } + else + { + g_dtmModeType = RF_PHY_DTM_MODE_ERROR; + } + } + + //tx-rx test + } + else if( g_dtmCmd == 1 || g_dtmCmd == 2) + { + g_dtmFreq = ((g_rfPhyDtmCmd[0] & 0x3f) ); // bit 13 8 + g_dtmLength = ((g_rfPhyDtmCmd[1] & 0xfc)>>2); // bit 7 2 + g_dtmPKT = ((g_rfPhyDtmCmd[1] & 0x03) ); // bit 1 0 + + if(g_dtmPktCount==3 && (g_rfPhyPktFmt==PKT_FMT_BLR125K || g_rfPhyPktFmt==PKT_FMT_BLR500K )) + { + g_dtmPKT = 4;//all ones 'b 11111111 + } + + g_dtmModeType = (g_dtmCmd ==1 )? RF_PHY_DTM_MODE_RX_PER : RF_PHY_DTM_MODE_TX_BURST; + } +} + +#endif +//------------------------------------------------------------------------------------- + + +#if(RF_PHY_DTM_CTRL_MOD == RF_PHY_DTM_CTRL_UART) +/************************************************************************************** + @fn rf_phy_dtm_evt_send + + @brief This function process for rf phy direct test, test mode trigged + + input parameters + + @param none + + output parameters + + @param none + + @return none +*/ +void rf_phy_dtm_evt_send(uint8_t dtmType ) +{ + //clear Event Buf + g_rfPhyDtmEvt[0] = 0; + g_rfPhyDtmEvt[1] = 0; + + if(dtmType==RF_PHY_DTM_MODE_ERROR) + { + g_dtmEvt = 0; //status + g_dtmStatus = 1; //Error + } + else + { + if(dtmType == RF_PHY_DTM_MODE_TEST_END) + { + g_dtmEvt = 0x80; //report + g_dtmStatus = 0; + g_dtmRsp = g_dtmPktCount; + } + else if(dtmType == RF_PHY_DTM_MODE_GET_FOFF) + { + g_dtmEvt = 0x80; //report + g_dtmStatus = 0; + g_dtmRsp = g_dtmFoff; + } + else if(dtmType == RF_PHY_DTM_MODE_GET_TPCAL) + { + g_dtmEvt = 0x80; //report + g_dtmStatus = 0; + g_dtmRsp = g_rfPhyTpCal0; + } + else if(dtmType == RF_PHY_DTM_MODE_GET_RSSI ) + { + g_dtmEvt = 0x80; //report + g_dtmStatus = 0; + g_dtmRsp = g_dtmRssi; + } + else if(dtmType == RF_PHY_DTM_MODE_GET_CARR_SENS) + { + g_dtmEvt = 0x80; //report + g_dtmStatus = 0; + g_dtmRsp = g_dtmCarrSens; + } + else if(dtmType == RF_PHY_DTM_MODE_READ_SUPPORTED_TEST_CASE) + { + g_dtmEvt = 0x00; //status + g_dtmStatus = 0; + g_dtmRsp = 0x0c; //bit3,support stable modulation index + //bit2, support LE 2M PHY + //bit1, support LE PACKET LENGTH EXTENTION + } + else if(dtmType == RF_PHY_DTM_MODE_READ_MAX_TX_OCTETS) + { + g_dtmEvt = 0x00; //status + g_dtmStatus = 0; + g_dtmRsp = 27<<1; + } + else if(dtmType == RF_PHY_DTM_MODE_READ_MAX_TX_TIME) + { + g_dtmEvt = 0x00; //status + g_dtmStatus = 0; + g_dtmRsp = 1352<<1; + } + else if(dtmType == RF_PHY_DTM_MODE_READ_MAX_RX_OCTETS) + { + g_dtmEvt = 0x00; //status + g_dtmStatus = 0; + g_dtmRsp = 27<<1; + } + else if(dtmType == RF_PHY_DTM_MODE_READ_MAX_RX_TIME) + { + g_dtmEvt = 0x00; //status + g_dtmStatus = 0; + g_dtmRsp = 1352<<1; + } + else + { + g_dtmEvt = 0; //status + g_dtmStatus = 0; //Sucess + g_dtmRsp = g_dtmModeType; + } + } + + g_rfPhyDtmEvt[0] = g_rfPhyDtmEvt[0] | g_dtmEvt | (g_dtmRsp >> 8); + g_rfPhyDtmEvt[1] = g_rfPhyDtmEvt[1] | g_dtmStatus | (g_dtmRsp & 0xff); + DTM_OUT(g_rfPhyDtmEvt[0]); + DTM_OUT(g_rfPhyDtmEvt[1]); +} + + +#endif +//------------------------------------------------------------------------------------- + + +#if(RF_PHY_DTM_CTRL_MOD == RF_PHY_DTM_CTRL_UART) +/************************************************************************************** + @fn rf_phy_dtm_trigged + + @brief This function process for rf phy direct test, test mode trigged + + input parameters + + @param none + + output parameters + + @param none + + @return none +*/ +void rf_phy_dtm_trigged(void) +{ + //cal the pkt length and pkt interval + g_dtmLength = ((0x03&g_dtmExtLen)<<6)|(0x3f&g_dtmLength); + int pktLenUs =0; //(g_dtmLength+10)<<3; + uint8_t rfChn = 2+(g_dtmFreq<<1); + uint8_t preambleLen = 1; + +// if( pktLenUs <= 376 ) { g_dtmPktIntv = 625; +// }else if( pktLenUs <= 1000 ) { g_dtmPktIntv = 1250; +// }else if( pktLenUs <= 1624 ) { g_dtmPktIntv = 1875; +// }else if( pktLenUs <= 2120 ) { g_dtmPktIntv = 2500; +// }else { g_dtmPktIntv = 2500; +// } +// + if( g_rfPhyPktFmt==PKT_FMT_BLE1M) + { + pktLenUs = (g_dtmLength+1+4+2+3)<<3; + } + else if( g_rfPhyPktFmt==PKT_FMT_BLE2M) + { + pktLenUs = (g_dtmLength+2+4+2+3)<<2; + } + else if( g_rfPhyPktFmt==PKT_FMT_BLR500K) + { + pktLenUs = 80+296+((g_dtmLength+2+3)<<4)+6; + } + else if( g_rfPhyPktFmt==PKT_FMT_BLR125K) + { + pktLenUs = 80+296+((g_dtmLength+2+3)<<6)+24; + } + else + { + pktLenUs = (g_dtmLength+4+1+1)<<5;//per byte -> 2symbol ->32us + rfChn = 5+g_dtmFreq*5;//for zigbee + } + + g_dtmPktIntv = (((pktLenUs+249)+624)/625)*625;// ceil((L+249)/625) * 625 + + if(g_dtmModeType == RF_PHY_DTM_MODE_GET_PER_AUTO) + { + g_dtmPerAutoIntv = g_dtmPktIntv*1000; + g_dtmTick = read_current_fine_time(); + } + + PHY_REG_WT( 0x40030040,0x00030000); // close tx_bb test mode + PHY_REG_WT( 0x400300a0,0x0000000e); // clr pll_auto override + PHY_REG_WT( 0x400300a4,0x00000100); // clr tx_auto + PHY_REG_WT( 0x400300a0,0x00000000); // clr pll_auto override + PHY_REG_WT( 0x4003008c,0x00104040); // clr tp_cal_en + + if(g_dtmModeType == RF_PHY_DTM_MODE_RESET) + { + g_dtmPktCount = 0; + g_dtmRsp = 0; + g_dtmExtLen = 0; + g_dtmLength = 0; + g_dtmPktIntv = 0; + g_dtmTxPower = g_rfPhyTxPower; + g_dtmFoff = 0; + g_dtmRssi = 0; + g_dtmCarrSens = 0; + g_rfPhyPktFmt = PKT_FMT_BLE1M; + g_dtmPKT = 0; + DCDC_CONFIG_SETTING(0x0a); + } + else if( g_dtmModeType == RF_PHY_DTM_MODE_TX_BURST + || g_dtmModeType == RF_PHY_DTM_MODE_TX_CTMOD + || g_dtmModeType == RF_PHY_DTM_MODE_TX_SINGLE ) + { + //====== tp cal + if(g_dtmTpCalEnable) + { + rf_phy_ana_cfg(); + //rf_tpCal_cfg(rfChn); + rf_tpCal_cfg_avg(rfChn,4); + } + + //====== rf initial + rf_phy_ini(); + rf_phy_set_txPower(g_dtmTxPower); + ll_hw_set_timing(g_rfPhyPktFmt); + + //add some tx_foff + if(g_rfPhyFreqOffSet>=0) + PHY_REG_WT(0x400300b4,rfChn+(g_rfPhyFreqOffSet<<8)); + else + PHY_REG_WT(0x400300b4,rfChn-1+((255+g_rfPhyFreqOffSet)<<8)); + + if(!(g_rfPhyPktFmt==PKT_FMT_ZIGBEE)) + { + PHY_REG_WT(0x40030048,RF_PHY_DTM_CRC_WT ); + PHY_REG_WT(0x4003004c,g_dtmAccessCode ); + PHY_REG_WT(0x40030040,0x00030010); + } + + //---------------------------------- + //PRBS SEED should be configed before tx_mod en + PHY_REG_WT(0x40030044,RF_PHY_DTM_PRBS9_SEED ); + + if(g_dtmModeType == RF_PHY_DTM_MODE_TX_SINGLE) + { + PHY_REG_WT(0x400300a4,0x00000100); //tp_mod en and pa_ramp_en + } + else + { + PHY_REG_WT(0x400300a4,0x00000140); //tp_mod en and pa_ramp_en + } + + //PHY_REG_WT(0x40030040,0x000300f0);//need to extend the preamble length + + if(g_dtmModeType == RF_PHY_DTM_MODE_TX_BURST) + { + //DCDC_CONFIG_SETTING(0x08); + if(!(g_rfPhyPktFmt==PKT_FMT_ZIGBEE)) + { + #if 0 + + //[15:8] payload Len [7:5] preamble len, [4] tx mode, [3:0] payload type + //PHY_REG_WT(0x40030040,(0x00030010|(g_dtmLength<<8)|(preambleLen<<5)|(0x0f & g_dtmPKT)) ); + if((g_rfPhyPktFmt == PKT_FMT_BLR125K || g_rfPhyPktFmt == PKT_FMT_BLR500K) + && g_dtmPKT == 0x03 ) + { + //for PKT_FMT all ones 11111111 + //PHY_REG_WT(0x40030040,(0x00030010|((g_dtmLength+2)<<8)|(preambleLen<<5)|0x04) ); + PHY_REG_WT(0x40030040,(0x00030010|((g_dtmLength)<<8)|(preambleLen<<5)|0x04) ); + } + else + { + //PHY_REG_WT(0x40030040,(0x00030010|((g_dtmLength+2)<<8)|(preambleLen<<5)|(0x0f & g_dtmPKT)) ); + PHY_REG_WT(0x40030040,(0x00030010|((g_dtmLength)<<8)|(preambleLen<<5)|(0x0f & g_dtmPKT)) ); + } + + #else + ll_hw_rst_tfifo(); + extern void rf_phy_dtm_ble_pkt_gen(void); + rf_phy_dtm_ble_pkt_gen(); + #endif + } + else + { + ll_hw_rst_tfifo(); + rf_phy_dtm_zigbee_pkt_gen(); + } + } + else + { + if(!(g_rfPhyPktFmt==PKT_FMT_ZIGBEE)) + { + //[15:8] payload Len [7:5] preamble len, [4] tx mode, [3:0] payload type + PHY_REG_WT(0x40030040,0x00030010|(preambleLen<<5)); + } + else + { + //[15:8] payload Len [7:5] preamble len, [4] tx mode, [3:0] payload type + PHY_REG_WT(0x40030040,0x000b0013|(preambleLen<<5)); + PHY_REG_WT(0x40030000,0x78068002); + } + } + + //close ll hw irg + ll_hw_set_irq(0); + ll_hw_set_stx(); + ll_hw_clr_irq(); + + if(g_dtmModeType == RF_PHY_DTM_MODE_TX_BURST) + { + if(!(g_rfPhyPktFmt==PKT_FMT_ZIGBEE)) + { + //PHY_REG_WT( 0x400300a0,0x0000000e); // clr pll_auto override + //PHY_REG_WT( 0x400300a4,0x00000154); // clr tx_auto + ll_hw_trigger(); + } + else + { + ll_hw_trigger(); + //PHY_REG_WT( 0x400300a0,0x0000000e); // clr pll_auto override + //PHY_REG_WT( 0x400300a4,0x00000154); // clr tx_auto + } + + g_dtmTick = read_current_fine_time(); + } + else + { + ll_hw_trigger(); + } + } + else if( g_dtmModeType == RF_PHY_DTM_MODE_RX_PER + || g_dtmModeType == RF_PHY_DTM_MODE_GET_PER_AUTO ) + { + rf_phy_ana_cfg(); + rf_rxDcoc_cfg(/*rfChn*/2,/*bwSet*/1,&g_rfPhyRxDcIQ); //set the rfChn as 2402 for BW=1MHz + //====== rf initial + rf_phy_ini(); + ll_hw_set_timing(g_rfPhyPktFmt); + PHY_REG_WT(0x40031024,g_dtmPktIntv-100);//timeout set + PHY_REG_WT(0x40031028,g_dtmPktIntv-100);//timeout set + + if((rfChn&0x0f)==0) + { + PHY_REG_WT(0x400300b4,rfChn);//freqOffset = 0 + subWriteReg(0x4003011c,11,8,3);//enable spur notch filter setting + } + else + { + subWriteReg(0x4003011c,11,8,0);//disable spur notch filter setting + + if(g_rfPhyFreqOffSet>=0) + PHY_REG_WT(0x400300b4,rfChn+(g_rfPhyFreqOffSet<<16)); + else + PHY_REG_WT(0x400300b4,rfChn-1+((255+g_rfPhyFreqOffSet)<<16)); + } + + if(!(g_rfPhyPktFmt==PKT_FMT_ZIGBEE)) + { + PHY_REG_WT(0x40030044,RF_PHY_DTM_PRBS9_SEED ); + PHY_REG_WT(0x40030048,RF_PHY_DTM_CRC_WT ); + PHY_REG_WT(0x4003004c,g_dtmAccessCode ); + } + + //set rx no timeout[31:16] + max packet len + //PHY_REG_WT(0x4003000c,(g_dtmLength+3)>255 ? 255: g_dtmLength+3 ); + PHY_REG_WT(0x4003000c,(g_dtmLength+3)>255 ? 255:( g_dtmLength<40 ? 40 : g_dtmLength+3) ); + //close ll hw irg + ll_hw_set_irq(0); + ll_hw_set_srx(); + ll_hw_clr_irq(); + ll_hw_trigger(); + } +} +void gen_pn_prbs9(uint16_t seed, int length,uint8_t* pnOut) +{ + uint8_t bitOut[8] = {0}; + uint8_t reg[9]; + uint8_t i = 0; + uint8_t j = 0; + uint8_t feedback = 0; + + for (i = 0; i < 9; i++) + { + reg[i] = (seed >> i) & 0x01; + } + + for (i = 0; i < length; i++) + { + for (j = 0; j < 8; j++) + { + feedback = reg[5] ^ reg[0]; + bitOut[j] = reg[0]; + reg[0] = reg[1]; + reg[1] = reg[2]; + reg[2] = reg[3]; + reg[3] = reg[4]; + reg[4] = reg[5]; + reg[5] = reg[6]; + reg[6] = reg[7]; + reg[7] = reg[8]; + reg[8] = feedback; + } + + bit_to_byte(bitOut, pnOut + i); + } +} +void rf_phy_dtm_ble_pkt_gen(void) +{ + uint8_t tmp[256]; + tmp[1] = g_dtmLength; + tmp[0] = g_dtmPKT; + uint8_t pld=0x00; + + if(g_dtmPKT==1) + { + pld = 0x0f; + } + else if(g_dtmPKT==2) + { + pld=0x55; + } + else if(g_dtmPKT==3) + { + pld=0xff; + tmp[0]=4; + } + + if(g_dtmPKT==0) + { + gen_pn_prbs9(0x01ff,g_dtmLength,&(tmp[2])); + } + else + { + for(uint8_t i=0; i>1) ) ^ 0x61); + } + + zigbee_crc16_gen(tmp+1,g_dtmLength-2,seed,crcCode); + tmp[g_dtmLength-1] = crcCode[0]; + tmp[g_dtmLength ] = crcCode[1]; + ll_hw_write_tfifo(tmp,g_dtmLength+1);//include the crc16 +} +#endif +//------------------------------------------------------------------------------------- + + + +/************************************************************************************** + @fn rf_phy_get_pktFoot + + @brief This function process to get pkt foot + + input parameters + + @param none + + output parameters + + @param rssi : recv signal strength indicator(-dBm) + foff : estimated freq offset by rx BB ,foff-512-->[-512 511]KHz + carrSens: sync qualitiy indicator, estimated by rx BB. + + @return none +*/ +void rf_phy_get_pktFoot(uint8* rssi, uint16* foff,uint8* carrSens) +{ + uint32_t pktFoot0; + uint32_t pktFoot1; + uint16_t tmpFoff; + pktFoot0 = (*(volatile uint32_t*) 0x400300e4); + pktFoot1 = (*(volatile uint32_t*) 0x400300e8); + tmpFoff = pktFoot0 & 0x3ff; + *foff = (tmpFoff>512) ? tmpFoff-512 : tmpFoff+512; + *rssi = (pktFoot1>>24) ; + *carrSens = (pktFoot0>>24) ; +} +void rf_phy_get_pktFoot_fromPkt(uint32 pktFoot0, uint32 pktFoot1, + uint8* rssi, uint16* foff,uint8* carrSens) +{ + uint16_t tmpFoff; +// pktFoot0 = (*(volatile uint32_t *) 0x400300e4); +// pktFoot1 = (*(volatile uint32_t *) 0x400300e8); + tmpFoff = pktFoot0 & 0x3ff; + *foff = (tmpFoff>512) ? tmpFoff-512 : tmpFoff+512; + *rssi = (pktFoot1>>24) ; + *carrSens = (pktFoot0>>24) ; +} +/************************************************************************************** + @fn rf_phy_set_txPower + + @brief This function process for rf phy tx power config + + input parameters + + @param txPower : tx pa power setting (0~0x1f) + + output parameters + + @param none + + @return none +*/ +void rf_phy_set_txPower (uint8 txPower) +{ + if(RF_PHY_TX_POWER_EXTRA_MAX==txPower) + { + DCDC_CONFIG_SETTING(0x08);//set dcdc to highest + RF_PHY_LO_LDO_SETTING(0); + RF_PHY_LNA_LDO_SETTING(0); + RF_PHY_PA_VTRIM_SETTING(1); + } + else + { + DCDC_CONFIG_SETTING(0x0a); + RF_PHY_LO_LDO_SETTING(2); + RF_PHY_LNA_LDO_SETTING(1); + RF_PHY_PA_VTRIM_SETTING(0); + } + + PHY_REG_WT(0x400300b8,(PHY_REG_RD(0x400300b8)&0x0fff) | ((txPower&0x1f)<<12)); +} + + + +/******************************************************************************* + @fn rc32k calibration + + @brief RF calibration function + + + + input parameters + @param None. + + + output parameters + + @param None. + + @return rcCalCode + +*/ +uint8 rc32k_calibration(void) +{ + uint8 delay = 10; + uint32_t temp=0; + *(volatile uint32_t*) 0x4000f05c &= 0xfffffffe; // disable RC32K calibration + WaitRTCCount(6); + // calibrate RC32K clock + *(volatile uint32_t*) 0x4000f018 |= 0x80; // set capbank controlled by calibration + *(volatile uint32_t*) 0x4000f05c |= 0x01; // enable RC32K calibration + + while (!(*(volatile uint32_t*) 0x4000f068 & 0x200) // check RC32K calibration OK flag, normally need >200us + && delay -- > 0) + { + WaitRTCCount(8);//30.125*8 us each loop + } + + if (delay > 0) + { + temp = (*(volatile uint32_t*) 0x4000f060 & 0x3f0000) >> 15; // read 6bit calibration result + *(volatile uint32_t*)0x4000f018 = (*(volatile uint32_t*) 0x4000f018 & 0xffffff81) | temp; // write the result + } + + *(volatile uint32_t*) 0x4000f018 &= 0xffffff7f; // set capbank controlled by AON + return (uint8)(0x7f&(temp>>1)); +} +/******************************************************************************* + @fn rf_calibrate API + + @brief RF calibration function + + + + input parameters + @param None. + + + output parameters + + @param None. + + @return None + +*/ +void rf_calibrate1(void) +{ + /* rf_phy_ana_cfg will overwrite txpower setting configed in rf_phy_ini. + in ble_main, rf_calibration is called after rf_phy_ini,so comment the rf_phy_ana_cfg + */ + //rf_phy_ana_cfg(); + //========== do rf tp cal for tx and rx dcoffset cal + rf_tpCal_gen_cap_arrary(); //generate the tpCal cap arrary + //rf_tpCal_cfg(/*rfChn*/2); + rf_rxDcoc_cfg(/*rfChn*/88,/*bwSet*/1,&g_rfPhyRxDcIQ); //set the rfChn as 2488 for BW=1MHz + g_rc32kCalRes = rc32k_calibration(); +} + + +static void rf_phy_dtm_init(void) +{ + //*(volatile int *) 0xe000e100 |= 0x800; + *(volatile int*) 0xe000e100 = 0x800; //only use uart irq + *(volatile unsigned int*) 0x40004004 |= 0x01; //ENABLE_ERBFI; + //set timer3 free run + //AP_TIM3->ControlReg = 0x05; + //24bit count down mode no IRQ + set_timer(AP_TIM3, RF_PHY_TIME_BASE); + NVIC_DisableIRQ(TIM3_IRQn); +} + + +static void rf_phy_dtm_stop(void) +{ + //====================================================================== + //stop RF_PHY_DTM_MODE + //PHY_REG_WT( 0x400300a4,0x00000100); // clr tx_auto + //PHY_REG_WT( 0x400300a0,0x0000000e); // pll_auto override + subWriteReg(AP_PCR_BASE+0x0c,10,10,0);//reset bbll + PHY_REG_WT( 0x400300a4,0x00000140); // clr tx_auto + PHY_REG_WT( 0x400300a0,0x0000000e); // clr pll_auto override + PHY_REG_WT( 0x400300a0,0x00000000); // clr pll_auto override + subWriteReg(AP_PCR_BASE+0x0c,10,10,1);//release bbll reset +} + +/************************************************************************************** + @fn rf_phy_dtm_ext_tx_singleTone + + @brief This function process for rf phy direct test, test mode interup + + input parameters + + @param txPower : rf tx power + rfChnIdx : rf channel = 2402+(rfChnIdx<<1) + rfFoff : rf freq offset = rfFoff*4KHz + testTimeUs : test loop active time(ms) + + output parameters + + @param none + + @return none +*/ +void rf_phy_dtm_ext_tx_singleTone(uint8_t txPower, uint8_t rfChnIdx,uint8_t xtal_cap,int8_t rfFoff,uint32 testTimeUs) +{ + rf_phy_dtm_init(); + //====================================================================== + //rest RF_PHY_DTM_MODE + g_dtmModeType = RF_PHY_DTM_MODE_RESET; + rf_phy_dtm_trigged(); + //====================================================================== + //config dtm mode + g_dtmModeType = RF_PHY_DTM_MODE_TX_SINGLE; + g_dtmTxPower = txPower; + g_dtmFreq = rfChnIdx; + g_rfPhyPktFmt = PKT_FMT_BLE1M; + g_rfPhyFreqOffSet = rfFoff; + XTAL16M_CAP_SETTING(xtal_cap); + rf_phy_dtm_trigged(); + WaitUs(testTimeUs); + //====================================================================== + //stop RF_PHY_DTM_MODE + rf_phy_dtm_stop(); +} + + +/************************************************************************************** + @fn rf_phy_dtm_ext_tx_modulation + + @brief This function process for rf phy direct test, test mode interup + + input parameters + + @param txPower : rf tx power + rfChnIdx : rf channel = 2402+(rfChnIdx<<1) + rfFoff : rf freq offset = rfFoff*4KHz + pktType : modulaiton data type, 0: prbs9, 1: 1111000: 2 10101010 + testTimeUs : test loop active time(ms) + + output parameters + + @param none + + @return none +*/ +void rf_phy_dtm_ext_tx_modulation(uint8_t txPower, uint8_t rfChnIdx,uint8_t xtal_cap,int8_t rfFoff,uint8_t pktType,uint32 testTimeUs) +{ + rf_phy_dtm_init(); + //====================================================================== + //rest RF_PHY_DTM_MODE + g_dtmModeType = RF_PHY_DTM_MODE_RESET; + rf_phy_dtm_trigged(); + //====================================================================== + //config dtm mode + g_dtmModeType = RF_PHY_DTM_MODE_TX_CTMOD; + g_dtmTxPower = txPower; + g_dtmFreq = rfChnIdx; + g_rfPhyPktFmt = PKT_FMT_BLE1M; + g_dtmPKT = pktType; + g_rfPhyFreqOffSet = rfFoff; + XTAL16M_CAP_SETTING(xtal_cap); + rf_phy_dtm_trigged(); + WaitUs(testTimeUs); + //====================================================================== + //stop RF_PHY_DTM_MODE + rf_phy_dtm_stop(); +} + +/************************************************************************************** + @fn rf_phy_dtm_ext_tx_mt_burst + + @brief This function process for rf phy direct test, test mode interup + + input parameters + + @param txPower : rf tx power + rfChnIdx : rf channel = 2402+(rfChnIdx<<1) + rfFoff : rf freq offset = rfFoff*4KHz + pktType : modulaiton data type, 0: prbs9, 1: 1111000: 2 10101010 + pktLength : pkt length(Byte) + + txPktNum : burst pkt tx number + txPktIntv : txPkt intv,0 txPkt intv is pkt interval = ceil((L+249)/625) * 625 + + output parameters + + @param none + + @return none +*/ +void rf_phy_dtm_ext_tx_mod_burst(uint8_t txPower, uint8_t rfChnIdx,uint8_t xtal_cap,int8_t rfFoff, + uint8_t pktType, uint8_t pktLength,uint32 txPktNum,uint32 txPktIntv) +{ + rf_phy_dtm_init(); + //====================================================================== + //rest RF_PHY_DTM_MODE + g_dtmModeType = RF_PHY_DTM_MODE_RESET; + rf_phy_dtm_trigged(); + //====================================================================== + //config dtm mode + g_dtmModeType = RF_PHY_DTM_MODE_TX_BURST; + g_dtmTxPower = txPower; + g_dtmFreq = rfChnIdx; + g_rfPhyPktFmt = PKT_FMT_BLE1M; + g_dtmPKT = pktType; + g_dtmLength = pktLength; + g_rfPhyFreqOffSet = rfFoff; + XTAL16M_CAP_SETTING(xtal_cap); + rf_phy_dtm_trigged(); + uint32_t currTick=0; + uint32_t deltTick=0; + uint32_t tIntv = 0; + + if(txPktIntv==0) + tIntv = g_dtmPktIntv; + else + tIntv = txPktIntv; + + while(txPktNum>0) + { + ll_hw_set_trx_settle (100, 8, 90); //TxBB,RxAFE,PLL + //subWriteReg(0x400300d4,7,4,0x0f); //boost vco current[7:4] to 0xf to reduce dcdc spur + currTick = read_current_fine_time(); + deltTick = RF_PHY_TIME_DELTA(currTick,g_dtmTick); + + if(deltTick>=tIntv) + { + ll_hw_rst_tfifo(); + ll_hw_trigger(); + txPktNum--; + g_dtmTick = g_dtmTick+tIntv; + + if(g_dtmTick>RF_PHY_TIME_BASE) + g_dtmTick = g_dtmTick-RF_PHY_TIME_BASE; + } + } + + //====================================================================== + //stop RF_PHY_DTM_MODE + rf_phy_dtm_stop(); +} + + +/************************************************************************************** + @fn rf_phy_dtm_ext_rx_demod_burst + + @brief This function process for rf phy direct test, test mode interup + + input parameters + + @param rfChnIdx : rf channel = 2402+(rfChnIdx<<1) + rfFoff : rf freq offset = rfFoff*4KHz + pktLength : pkt length(Byte) + rxWindow : rx demod window length(us) + rxTimeOut : rx on time (ms) + + output parameters + + @param rxEstFoff : rx demod estimated frequency offset + rxEstRssi : rx demod estimated rssi + rxEstCarrSens : rx demod estimated carrier sense + rxPktNum : rx demod received pkt number + + @return none +*/ +void rf_phy_dtm_ext_rx_demod_burst(uint8_t rfChnIdx,int8_t rfFoff,uint8_t xtal_cap,uint8_t pktLength,uint32 rxTimeOut,uint32 rxWindow, + uint16_t* rxEstFoff,uint8_t* rxEstRssi,uint8_t* rxEstCarrSens,uint16_t* rxPktNum) +{ + rf_phy_dtm_init(); + //====================================================================== + //rest RF_PHY_DTM_MODE + g_dtmModeType = RF_PHY_DTM_MODE_RESET; + rf_phy_dtm_trigged(); + //====================================================================== + //config dtm mode + g_dtmModeType = RF_PHY_DTM_MODE_RX_PER; + g_dtmFreq = rfChnIdx; + g_rfPhyPktFmt = PKT_FMT_BLE1M; + g_dtmLength = pktLength; + g_rfPhyFreqOffSet = rfFoff; + rf_phy_dtm_trigged(); + g_dtmPktCount = 0; + uint8_t rssi; + uint16_t foff; + uint8_t carrSens; + uint32 t0 = hal_systick(); + XTAL16M_CAP_SETTING(xtal_cap); + + while(hal_ms_intv(t0)0) + { + PHY_REG_WT(0x40031024,0xffff&rxWindow); + PHY_REG_WT(0x40031028,0xffff&rxWindow); + } + + if(ll_hw_get_irq_status()&LIRQ_MD) + { + if(ll_hw_get_irq_status()&LIRQ_COK) + { + g_dtmPktCount++; + rf_phy_get_pktFoot(&rssi,&foff,&carrSens); + } + else if(ll_hw_get_irq_status()&LIRQ_CERR) + { + g_dtmRxCrcNum++; + } + else if(ll_hw_get_irq_status()&LIRQ_RTO) + { + g_dtmRxTONum++; + } + else + { + //wrap the pktCount + g_dtmPktCount= (g_dtmPktCount==65535) ? 0 : g_dtmPktCount; + } + + ll_hw_clr_irq(); + ll_hw_trigger(); + + if(g_dtmPktCount>0) + { + g_dtmRssi = (g_dtmPktCount==1) ? rssi :((g_dtmRssi+rssi) >>1); + g_dtmFoff = (g_dtmPktCount==1) ? foff :((g_dtmFoff+foff) >>1); + g_dtmCarrSens = (g_dtmPktCount==1) ? carrSens :((g_dtmCarrSens+carrSens) >>1); + } + } + } + + *rxEstFoff = g_dtmFoff; + *rxEstRssi = g_dtmRssi; + *rxPktNum = g_dtmPktCount; + *rxEstCarrSens = g_dtmCarrSens; + //====================================================================== + //stop RF_PHY_DTM_MODE + rf_phy_dtm_stop(); +} + +/************************************************************************************** + @fn rf_phy_dtm_ext_acc_code_set + + @brief config the acc_code in rf phy dtm + + input parameters + + @param acc_code : sync word + + output parameters + @return none +*/ +void rf_phy_dtm_ext_acc_code_set(uint32 accCode) +{ + g_dtmAccessCode = accCode; +} + + + + + + diff --git a/arch/arm/src/phy62xx/rom_sym_def.h b/arch/arm/src/phy62xx/rom_sym_def.h new file mode 100644 index 00000000000..9059de0386c --- /dev/null +++ b/arch/arm/src/phy62xx/rom_sym_def.h @@ -0,0 +1,957 @@ + + +#ifndef __ROM_SYM_H__ +#define __ROM_SYM_H__ +#ifdef USE_ROMSYM_ALIAS + + //#define x _symrom_ + //#define x _symrom_ + #define gpio_write _symrom_gpio_write + #define ll_processExtInitIRQ _symrom_ll_processExtInitIRQ + #define ll_processExtScanIRQ _symrom_ll_processExtScanIRQ + #define ll_processExtAdvIRQ _symrom_ll_processExtAdvIRQ + #define LL_SetDataLengh0 _symrom_LL_SetDataLengh0 + #define LL_SetScanParam0 _symrom_LL_SetScanParam0 + #define LL_SetAdvParam0 _symrom_LL_SetAdvParam0 + #define LL_CreateConn0 _symrom_LL_CreateConn0 + #define isPeerRpaStore _symrom_isPeerRpaStore + #define storeRpaListIndex _symrom_storeRpaListIndex + #define currentPeerRpa _symrom_currentPeerRpa + + #define isPeerRpaStore _symrom_isPeerRpaStore + #define LL_ENC_AES128_Encrypt0 _symrom_LL_ENC_AES128_Encrypt0 + #define llProcessTxData0 _symrom_llProcessTxData0 + #define sleep_tick _symrom_sleep_tick + #define g_currentPeerAddrType _symrom_g_currentPeerAddrType + + #define g_rfPhyTxPower _symrom_g_rfPhyTxPower + #define ble_main _symrom_ble_main + + + #define HCI_LE_Write_Rf_Path_CompensationCmd _symrom_HCI_LE_Write_Rf_Path_CompensationCmd + #define HCI_LE_ReadPeerResolvableAddressCmd _symrom_HCI_LE_ReadPeerResolvableAddressCmd + #define HCI_LE_AddDevToPeriodicAdvListCmd _symrom_HCI_LE_AddDevToPeriodicAdvListCmd + #define HCI_LE_RemovePeriodicAdvListCmd _symrom_HCI_LE_RemovePeriodicAdvListCmd + #define HCI_LE_ClearPeriodicAdvListCmd _symrom_HCI_LE_ClearPeriodicAdvListCmd + #define HCI_LE_ReadPeriodicAdvListSizeCmd _symrom_HCI_LE_ReadPeriodicAdvListSizeCmd + #define HCI_LE_Read_Transmit_PowerCmd _symrom_HCI_LE_Read_Transmit_PowerCmd + #define HCI_LE_Read_Rf_Path_CompensationCmd _symrom_HCI_LE_Read_Rf_Path_CompensationCmd + #define HCI_LE_Set_Privacy_ModeCmd _symrom_HCI_LE_Set_Privacy_ModeCmd + + + + + #define ll_readPeerIRK _symrom_ll_readPeerIRK + #define ownRandomAddr _symrom_ownRandomAddr + #define g_currentLocalRpa _symrom_g_currentLocalRpa + #define g_currentPeerRpa _symrom_g_currentPeerRpa + #define llProcessSlaveControlProcedures0 _symrom_llProcessSlaveControlProcedures0 + #define g_rfTxPathCompensation _symrom_g_rfTxPathCompensation + #define ll_isLegacyAdv _symrom_ll_isLegacyAdv + #define g_llScanMode _symrom_g_llScanMode + #define rf_phy_change_cfg _symrom_rf_phy_change_cfg + #define llProcessMasterControlProcedures0 _symrom_llProcessMasterControlProcedures0 + + + + + #define spif_config _symrom_spif_config + #define m_in_critical_region _symrom_m_in_critical_region + #define _spif_read_status_reg _symrom__spif_read_status_reg + #define _spif_wait_nobusy _symrom__spif_wait_nobusy + #define adv_param _symrom_adv_param + #define app_sleep_process _symrom_app_sleep_process + #define app_wakeup_process _symrom_app_wakeup_process + #define ate_fun_test _symrom_ate_fun_test + #define ate_sleep_process _symrom_ate_sleep_process + #define ate_wakeup_process _symrom_ate_wakeup_process + #define baseTaskID _symrom_baseTaskID + #define bit_to_byte _symrom_bit_to_byte + #define ble_crc24_gen _symrom_ble_crc24_gen + #define bleEvtMask _symrom_bleEvtMask + #define boot_init _symrom_boot_init + #define boot_init0 _symrom_boot_init0 + #define boot_m0 _symrom_boot_m0 + #define bx_to_application _symrom_bx_to_application + #define byte_to_bit _symrom_byte_to_bit + #define cachedTRNGdata _symrom_cachedTRNGdata + #define calculate_whiten_seed _symrom_calculate_whiten_seed + #define cbTimers _symrom_cbTimers + #define chanMapUpdate _symrom_chanMapUpdate + #define clear_timer _symrom_clear_timer + #define clear_timer_int _symrom_clear_timer_int + #define clk_get_pclk _symrom_clk_get_pclk + #define clk_init _symrom_clk_init + #define clk_set_pclk_div _symrom_clk_set_pclk_div + #define clk_spif_ref_clk _symrom_clk_spif_ref_clk + #define config_RTC _symrom_config_RTC + #define conn_param _symrom_conn_param + #define connUpdateTimer _symrom_connUpdateTimer + #define counter_tracking _symrom_counter_tracking + #define rom_crc16 _symrom_crc16 + #define ctrlToHostEnable _symrom_ctrlToHostEnable + #define dataPkt _symrom_dataPkt + #define debug_print _symrom_debug_print + #define deviceFeatureSet _symrom_deviceFeatureSet + #define disableSleep _symrom_disableSleep + #define drv_disable_irq _symrom_drv_disable_irq + #define drv_enable_irq _symrom_drv_enable_irq + #define drv_irq_init _symrom_drv_irq_init + #define dwc_connect _symrom_dwc_connect + #define dwc_data_process _symrom_dwc_data_process + #define dwc_loop _symrom_dwc_loop + #define efuse_read _symrom_efuse_read + #define enableSleep _symrom_enableSleep + #define enter_sleep_off_mode _symrom_enter_sleep_off_mode + #define enterSleepProcess _symrom_enterSleepProcess + #define ext_adv_hdr _symrom_ext_adv_hdr + #define extInitInfo _symrom_extInitInfo + #define extScanInfo _symrom_extScanInfo + #define fastTxRespTime _symrom_fastTxRespTime + #define forever_write _symrom_forever_write + #define g_adv_taskEvent _symrom_g_adv_taskEvent + #define g_adv_taskID _symrom_g_adv_taskID + #define g_advPerSlotTick _symrom_g_advPerSlotTick + #define g_advSetMaximumLen _symrom_g_advSetMaximumLen + #define g_advSlotPeriodic _symrom_g_advSlotPeriodic + #define g_blePktVersion _symrom_g_blePktVersion + #define g_conn_taskEvent _symrom_g_conn_taskEvent + #define g_conn_taskID _symrom_g_conn_taskID + #define g_counter_traking_avg _symrom_g_counter_traking_avg + #define g_counter_traking_cnt _symrom_g_counter_traking_cnt + #define g_currentAdvTimer _symrom_g_currentAdvTimer + #define g_currentExtAdv _symrom_g_currentExtAdv + #define g_currentExtAdv_periodic _symrom_g_currentExtAdv_periodic + #define g_currentTimerTask _symrom_g_currentTimerTask + #define g_dle_taskEvent _symrom_g_dle_taskEvent + #define g_dle_taskID _symrom_g_dle_taskID + #define g_dtmAccessCode _symrom_g_dtmAccessCode + #define g_dtmCarrSens _symrom_g_dtmCarrSens + #define g_dtmCmd _symrom_g_dtmCmd + #define g_dtmCtrl _symrom_g_dtmCtrl + #define g_dtmEvt _symrom_g_dtmEvt + #define g_dtmExtLen _symrom_g_dtmExtLen + #define g_dtmFoff _symrom_g_dtmFoff + #define g_dtmFreq _symrom_g_dtmFreq + #define g_dtmLength _symrom_g_dtmLength + #define g_dtmModeType _symrom_g_dtmModeType + #define g_dtmPara _symrom_g_dtmPara + #define g_dtmPerAutoIntv _symrom_g_dtmPerAutoIntv + #define g_dtmPKT _symrom_g_dtmPKT + #define g_dtmPktCount _symrom_g_dtmPktCount + #define g_dtmPktIntv _symrom_g_dtmPktIntv + #define g_dtmRsp _symrom_g_dtmRsp + #define g_dtmRssi _symrom_g_dtmRssi + #define g_dtmRxCrcNum _symrom_g_dtmRxCrcNum + #define g_dtmRxTONum _symrom_g_dtmRxTONum + #define g_dtmStatus _symrom_g_dtmStatus + #define g_dtmTick _symrom_g_dtmTick + #define g_dtmTpCalEnable _symrom_g_dtmTpCalEnable + #define g_dtmTxPower _symrom_g_dtmTxPower + #define g_extAdvNumber _symrom_g_extAdvNumber + #define g_getPn23_cnt _symrom_g_getPn23_cnt + #define g_getPn23_seed _symrom_g_getPn23_seed + #define g_hclk _symrom_g_hclk + #define g_interAuxPduDuration _symrom_g_interAuxPduDuration + #define g_ll_conn_ctx _symrom_g_ll_conn_ctx + #define g_llHdcDirAdvTime _symrom_g_llHdcDirAdvTime + #define g_llPduLen _symrom_g_llPduLen + #define g_llPeriodAdvSyncInfo _symrom_g_llPeriodAdvSyncInfo + #define g_llResolvinglist _symrom_g_llResolvinglist + #define g_llRlDeviceNum _symrom_g_llRlDeviceNum + #define g_llRlEnable _symrom_g_llRlEnable + #define g_llRlTimeout _symrom_g_llRlTimeout + #define g_llSleepContext _symrom_g_llSleepContext + #define g_llWhitelist _symrom_g_llWhitelist + #define g_llWlDeviceNum _symrom_g_llWlDeviceNum + #define g_maxConnNum _symrom_g_maxConnNum + #define g_maxPktPerEventRx _symrom_g_maxPktPerEventRx + #define g_maxPktPerEventTx _symrom_g_maxPktPerEventTx + #define g_new_master_delta _symrom_g_new_master_delta + #define g_osal_tick_trim _symrom_g_osal_tick_trim + #define g_osalTickTrim_mod _symrom_g_osalTickTrim_mod + #define g_pAdvSchInfo _symrom_g_pAdvSchInfo + #define g_pAdvSchInfo_periodic _symrom_g_pAdvSchInfo_periodic + #define g_perioAdvNumber _symrom_g_perioAdvNumber + #define g_pExtendedAdvInfo _symrom_g_pExtendedAdvInfo + #define g_phyChg_taskEvent _symrom_g_phyChg_taskEvent + #define g_phyChg_taskID _symrom_g_phyChg_taskID + #define g_pLLcteISample _symrom_g_pLLcteISample + #define g_pLLcteQSample _symrom_g_pLLcteQSample + #define g_pmCounters _symrom_g_pmCounters + #define g_pPeriodicAdvInfo _symrom_g_pPeriodicAdvInfo + #define ll_isIrkAllZero _symrom_ll_isIrkAllZero + #define g_currentLocalAddrType _symrom_g_currentLocalAddrType + #define g_rfPhyClkSel _symrom_g_rfPhyClkSel + #define g_rfPhyDtmCmd _symrom_g_rfPhyDtmCmd + #define g_rfPhyDtmEvt _symrom_g_rfPhyDtmEvt + #define g_llAdvMode _symrom_g_llAdvMode + #define g_rfPhyFreqOffSet _symrom_g_rfPhyFreqOffSet + #define g_rfPhyPktFmt _symrom_g_rfPhyPktFmt + #define g_rfPhyRxDcIQ _symrom_g_rfPhyRxDcIQ + #define g_rfPhyTpCal0 _symrom_g_rfPhyTpCal0 + #define g_rfPhyTpCal0_2Mbps _symrom_g_rfPhyTpCal0_2Mbps + #define g_rfPhyTpCal1 _symrom_g_rfPhyTpCal1 + #define g_rfPhyTpCal1_2Mbps _symrom_g_rfPhyTpCal1_2Mbps + //#define g_rfPhyTxPower _symrom_g_rfPhyTxPower + #define g_rx_adv_buf _symrom_g_rx_adv_buf + #define g_rxAdcClkSel _symrom_g_rxAdcClkSel + #define g_same_rf_channel_flag _symrom_g_same_rf_channel_flag + #define g_schExtAdvNum _symrom_g_schExtAdvNum + #define g_schExtAdvNum_periodic _symrom_g_schExtAdvNum_periodic + #define g_smartWindowActive _symrom_g_smartWindowActive + #define g_smartWindowActiveCnt _symrom_g_smartWindowActiveCnt + #define g_smartWindowLater _symrom_g_smartWindowLater + #define g_smartWindowPreAnchPoint _symrom_g_smartWindowPreAnchPoint + #define g_smartWindowRTOCnt _symrom_g_smartWindowRTOCnt + #define g_smartWindowSize _symrom_g_smartWindowSize + #define g_smartWindowSizeNew _symrom_g_smartWindowSizeNew + #define g_system_clk _symrom_g_system_clk + #define g_TIM2_IRQ_PendingTick _symrom_g_TIM2_IRQ_PendingTick + #define g_TIM2_IRQ_TIM3_CurrCount _symrom_g_TIM2_IRQ_TIM3_CurrCount + #define g_TIM2_IRQ_to_Sleep_DeltTick _symrom_g_TIM2_IRQ_to_Sleep_DeltTick + #define g_TIM2_wakeup_delay _symrom_g_TIM2_wakeup_delay + #define g_timerExpiryTick _symrom_g_timerExpiryTick + #define g_tx_adv_buf _symrom_g_tx_adv_buf + #define g_tx_ext_adv_buf _symrom_g_tx_ext_adv_buf + #define g_wakeup_rtc_tick _symrom_g_wakeup_rtc_tick + #define get_rx_read_ptr _symrom_get_rx_read_ptr + #define get_rx_write_ptr _symrom_get_rx_write_ptr + #define get_sleep_flag _symrom_get_sleep_flag + #define get_timer_count _symrom_get_timer_count + #define get_timer_int _symrom_get_timer_int + #define get_tx_read_ptr _symrom_get_tx_read_ptr + #define get_tx_write_ptr _symrom_get_tx_write_ptr + #define getMcuPrecisionCount _symrom_getMcuPrecisionCount + #define getPN23RandNumber _symrom_getPN23RandNumber + #define getRxBufferFree _symrom_getRxBufferFree + #define getRxBufferSize _symrom_getRxBufferSize + #define getSleepMode _symrom_getSleepMode + #define getTxBufferFree _symrom_getTxBufferFree + #define getTxBufferSize _symrom_getTxBufferSize + #define gpio_cfg_analog_io _symrom_gpio_cfg_analog_io + #define gpio_dir _symrom_gpio_dir + #define gpio_fmux_control _symrom_gpio_fmux_control + #define gpio_fmux_set _symrom_gpio_fmux_set + #define gpio_in_trigger _symrom_gpio_in_trigger + #define gpio_init _symrom_gpio_init + #define gpio_interrupt_set _symrom_gpio_interrupt_set + #define GPIO_IRQHandler _symrom_GPIO_IRQHandler + #define gpio_pull_set _symrom_gpio_pull_set + #define gpio_read _symrom_gpio_read + #define gpio_wakeup_set _symrom_gpio_wakeup_set + #define gpio_write _symrom_gpio_write + #define HardFault_Handler _symrom_HardFault_Handler + #define HardFault_IRQHandler _symrom_HardFault_IRQHandler + #define HCI_bm_alloc _symrom_HCI_bm_alloc + #define HCI_CommandCompleteEvent _symrom_HCI_CommandCompleteEvent + #define HCI_CommandStatusEvent _symrom_HCI_CommandStatusEvent + #define HCI_DataBufferOverflowEvent _symrom_HCI_DataBufferOverflowEvent + #define HCI_DisconnectCmd _symrom_HCI_DisconnectCmd + #define HCI_ExtTaskRegister _symrom_HCI_ExtTaskRegister + #define HCI_GAPTaskRegister _symrom_HCI_GAPTaskRegister + #define HCI_HardwareErrorEvent _symrom_HCI_HardwareErrorEvent + #define HCI_HostBufferSizeCmd _symrom_HCI_HostBufferSizeCmd + #define HCI_HostNumCompletedPktCmd _symrom_HCI_HostNumCompletedPktCmd + #define HCI_Init _symrom_HCI_Init + #define HCI_L2CAPTaskRegister _symrom_HCI_L2CAPTaskRegister + #define HCI_LE_AddDevToResolvingListCmd _symrom_HCI_LE_AddDevToResolvingListCmd + #define HCI_LE_AddWhiteListCmd _symrom_HCI_LE_AddWhiteListCmd + #define HCI_LE_ClearAdvSetsCmd _symrom_HCI_LE_ClearAdvSetsCmd + #define HCI_LE_ClearResolvingListCmd _symrom_HCI_LE_ClearResolvingListCmd + #define HCI_LE_ClearWhiteListCmd _symrom_HCI_LE_ClearWhiteListCmd + #define HCI_LE_Connection_CTE_Request_EnableCmd _symrom_HCI_LE_Connection_CTE_Request_EnableCmd + #define HCI_LE_Connection_CTE_Response_EnableCmd _symrom_HCI_LE_Connection_CTE_Response_EnableCmd + #define HCI_LE_ConnectionlessCTE_TransmitEnableCmd _symrom_HCI_LE_ConnectionlessCTE_TransmitEnableCmd + #define HCI_LE_ConnectionlessCTE_TransmitParamCmd _symrom_HCI_LE_ConnectionlessCTE_TransmitParamCmd + #define HCI_LE_ConnectionlessIQ_SampleEnableCmd _symrom_HCI_LE_ConnectionlessIQ_SampleEnableCmd + #define HCI_LE_ConnUpdateCmd _symrom_HCI_LE_ConnUpdateCmd + #define HCI_LE_CreateConnCancelCmd _symrom_HCI_LE_CreateConnCancelCmd + #define HCI_LE_CreateConnCmd _symrom_HCI_LE_CreateConnCmd + #define HCI_LE_EncryptCmd _symrom_HCI_LE_EncryptCmd + #define HCI_LE_ExtendedCreateConnectionCmd _symrom_HCI_LE_ExtendedCreateConnectionCmd + #define HCI_LE_LtkReqNegReplyCmd _symrom_HCI_LE_LtkReqNegReplyCmd + #define HCI_LE_LtkReqReplyCmd _symrom_HCI_LE_LtkReqReplyCmd + #define HCI_LE_PeriodicAdvertisingCreateSyncCancelCmd _symrom_HCI_LE_PeriodicAdvertisingCreateSyncCancelCmd + #define HCI_LE_PeriodicAdvertisingCreateSyncCmd _symrom_HCI_LE_PeriodicAdvertisingCreateSyncCmd + #define HCI_LE_PeriodicAdvertisingTerminateSyncCmd _symrom_HCI_LE_PeriodicAdvertisingTerminateSyncCmd + #define HCI_LE_RandCmd _symrom_HCI_LE_RandCmd + #define HCI_LE_READ_Anatenna_InfoCmd _symrom_HCI_LE_READ_Anatenna_InfoCmd + #define HCI_LE_ReadAdvChanTxPowerCmd _symrom_HCI_LE_ReadAdvChanTxPowerCmd + #define HCI_LE_ReadBufSizeCmd _symrom_HCI_LE_ReadBufSizeCmd + #define HCI_LE_ReadChannelMapCmd _symrom_HCI_LE_ReadChannelMapCmd + #define HCI_LE_ReadLocalSupportedFeaturesCmd _symrom_HCI_LE_ReadLocalSupportedFeaturesCmd + #define HCI_LE_ReadMaxDataLengthCmd _symrom_HCI_LE_ReadMaxDataLengthCmd + #define HCI_LE_ReadMaximumAdvDataLengthCmd _symrom_HCI_LE_ReadMaximumAdvDataLengthCmd + #define HCI_LE_ReadNumberOfSupportAdvSetCmd _symrom_HCI_LE_ReadNumberOfSupportAdvSetCmd + #define HCI_LE_ReadPhyMode _symrom_HCI_LE_ReadPhyMode + #define HCI_LE_ReadRemoteUsedFeaturesCmd _symrom_HCI_LE_ReadRemoteUsedFeaturesCmd + #define HCI_LE_ReadResolvingListSizeCmd _symrom_HCI_LE_ReadResolvingListSizeCmd + #define HCI_LE_ReadSuggestedDefaultDataLengthCmd _symrom_HCI_LE_ReadSuggestedDefaultDataLengthCmd + #define HCI_LE_ReadSupportedStatesCmd _symrom_HCI_LE_ReadSupportedStatesCmd + #define HCI_LE_ReadWhiteListSizeCmd _symrom_HCI_LE_ReadWhiteListSizeCmd + #define HCI_LE_ReceiverTestCmd _symrom_HCI_LE_ReceiverTestCmd + #define HCI_LE_RemoveAdvSetCmd _symrom_HCI_LE_RemoveAdvSetCmd + #define HCI_LE_RemoveResolvingListCmd _symrom_HCI_LE_RemoveResolvingListCmd + #define HCI_LE_RemoveWhiteListCmd _symrom_HCI_LE_RemoveWhiteListCmd + #define HCI_LE_Set_ConnectionCTE_ReceiveParamCmd _symrom_HCI_LE_Set_ConnectionCTE_ReceiveParamCmd + #define HCI_LE_Set_ConnectionCTE_TransmitParamCmd _symrom_HCI_LE_Set_ConnectionCTE_TransmitParamCmd + #define HCI_LE_SetAddressResolutionEnableCmd _symrom_HCI_LE_SetAddressResolutionEnableCmd + #define HCI_LE_SetAdvDataCmd _symrom_HCI_LE_SetAdvDataCmd + #define HCI_LE_SetAdvEnableCmd _symrom_HCI_LE_SetAdvEnableCmd + #define HCI_LE_SetAdvParamCmd _symrom_HCI_LE_SetAdvParamCmd + #define HCI_LE_SetDataLengthCmd _symrom_HCI_LE_SetDataLengthCmd + #define HCI_LE_SetDefaultPhyMode _symrom_HCI_LE_SetDefaultPhyMode + #define HCI_LE_SetEventMaskCmd _symrom_HCI_LE_SetEventMaskCmd + #define HCI_LE_SetExtAdvDataCmd _symrom_HCI_LE_SetExtAdvDataCmd + #define HCI_LE_SetExtAdvEnableCmd _symrom_HCI_LE_SetExtAdvEnableCmd + #define HCI_LE_SetExtAdvParamCmd _symrom_HCI_LE_SetExtAdvParamCmd + #define HCI_LE_SetExtAdvSetRandomAddressCmd _symrom_HCI_LE_SetExtAdvSetRandomAddressCmd + #define HCI_LE_SetExtendedScanEnableCmd _symrom_HCI_LE_SetExtendedScanEnableCmd + #define HCI_LE_SetExtendedScanParametersCmd _symrom_HCI_LE_SetExtendedScanParametersCmd + #define HCI_LE_SetExtScanRspDataCmd _symrom_HCI_LE_SetExtScanRspDataCmd + #define HCI_LE_SetHostChanClassificationCmd _symrom_HCI_LE_SetHostChanClassificationCmd + #define HCI_LE_SetPeriodicAdvDataCmd _symrom_HCI_LE_SetPeriodicAdvDataCmd + #define HCI_LE_SetPeriodicAdvEnableCmd _symrom_HCI_LE_SetPeriodicAdvEnableCmd + #define HCI_LE_SetPeriodicAdvParameterCmd _symrom_HCI_LE_SetPeriodicAdvParameterCmd + #define HCI_LE_SetPhyMode _symrom_HCI_LE_SetPhyMode + #define HCI_LE_SetRandomAddressCmd _symrom_HCI_LE_SetRandomAddressCmd + #define HCI_LE_SetResolvablePrivateAddressTimeoutCmd _symrom_HCI_LE_SetResolvablePrivateAddressTimeoutCmd + #define HCI_LE_SetScanEnableCmd _symrom_HCI_LE_SetScanEnableCmd + #define HCI_LE_SetScanParamCmd _symrom_HCI_LE_SetScanParamCmd + #define HCI_LE_SetScanRspDataCmd _symrom_HCI_LE_SetScanRspDataCmd + #define HCI_LE_StartEncyptCmd _symrom_HCI_LE_StartEncyptCmd + #define HCI_LE_TestEndCmd _symrom_HCI_LE_TestEndCmd + #define HCI_LE_TransmitterTestCmd _symrom_HCI_LE_TransmitterTestCmd + #define HCI_LE_WriteSuggestedDefaultDataLengthCmd _symrom_HCI_LE_WriteSuggestedDefaultDataLengthCmd + #define HCI_NumOfCompletedPacketsEvent _symrom_HCI_NumOfCompletedPacketsEvent + #define HCI_ProcessEvent _symrom_HCI_ProcessEvent + #define HCI_ReadBDADDRCmd _symrom_HCI_ReadBDADDRCmd + #define HCI_ReadLocalSupportedCommandsCmd _symrom_HCI_ReadLocalSupportedCommandsCmd + #define HCI_ReadLocalSupportedFeaturesCmd _symrom_HCI_ReadLocalSupportedFeaturesCmd + #define HCI_ReadLocalVersionInfoCmd _symrom_HCI_ReadLocalVersionInfoCmd + #define HCI_ReadRemoteVersionInfoCmd _symrom_HCI_ReadRemoteVersionInfoCmd + #define HCI_ReadRssiCmd _symrom_HCI_ReadRssiCmd + #define HCI_ReadTransmitPowerLevelCmd _symrom_HCI_ReadTransmitPowerLevelCmd + #define HCI_ResetCmd _symrom_HCI_ResetCmd + #define HCI_ReverseBytes _symrom_HCI_ReverseBytes + #define HCI_SendCommandCompleteEvent _symrom_HCI_SendCommandCompleteEvent + #define HCI_SendCommandStatusEvent _symrom_HCI_SendCommandStatusEvent + #define HCI_SendControllerToHostEvent _symrom_HCI_SendControllerToHostEvent + #define HCI_SendDataPkt _symrom_HCI_SendDataPkt + #define HCI_SetControllerToHostFlowCtrlCmd _symrom_HCI_SetControllerToHostFlowCtrlCmd + #define HCI_SetEventMaskCmd _symrom_HCI_SetEventMaskCmd + #define HCI_SMPTaskRegister _symrom_HCI_SMPTaskRegister + #define HCI_TestAppTaskRegister _symrom_HCI_TestAppTaskRegister + #define HCI_ValidConnTimeParams _symrom_HCI_ValidConnTimeParams + #define HCI_VendorSpecifcCommandCompleteEvent _symrom_HCI_VendorSpecifcCommandCompleteEvent + //#define hciCmdTable _symrom_hciCmdTable + #define hciCtrlCmdToken _symrom_hciCtrlCmdToken + #define hciExtTaskID _symrom_hciExtTaskID + #define hciGapTaskID _symrom_hciGapTaskID + #define hciInitEventMasks _symrom_hciInitEventMasks + #define hciL2capTaskID _symrom_hciL2capTaskID + #define hciPTMenabled _symrom_hciPTMenabled + #define hciSmpTaskID _symrom_hciSmpTaskID + #define hciTaskID _symrom_hciTaskID + #define hciTestTaskID _symrom_hciTestTaskID + #define hclk_per_us _symrom_hclk_per_us + #define hclk_per_us_shift _symrom_hclk_per_us_shift + #define initInfo _symrom_initInfo + #define ISR_entry_time _symrom_ISR_entry_time + #define isSleepAllow _symrom_isSleepAllow + #define isTimer1Running _symrom_isTimer1Running + #define isTimer4Running _symrom_isTimer4Running + #define jump_area_init _symrom_jump_area_init + #define ll_add_adv_task _symrom_ll_add_adv_task + #define ll_add_adv_task_periodic _symrom_ll_add_adv_task_periodic + #define LL_AddResolvingListLDevice _symrom_LL_AddResolvingListLDevice + #define ll_addTask _symrom_ll_addTask + #define LL_AddWhiteListDevice _symrom_LL_AddWhiteListDevice + #define ll_adptive_adj_next_time _symrom_ll_adptive_adj_next_time + #define ll_adptive_smart_window _symrom_ll_adptive_smart_window + #define ll_adv_scheduler _symrom_ll_adv_scheduler + #define ll_adv_scheduler_periodic _symrom_ll_adv_scheduler_periodic + #define LL_AdvReportCback _symrom_LL_AdvReportCback + #define ll_allocAuxAdvTimeSlot _symrom_ll_allocAuxAdvTimeSlot + #define ll_allocAuxAdvTimeSlot_prd _symrom_ll_allocAuxAdvTimeSlot_prd + #define ll_CalcRandomAddr _symrom_ll_CalcRandomAddr + #define LL_ChanMapUpdate _symrom_LL_ChanMapUpdate + #define LL_ClearAdvSets _symrom_LL_ClearAdvSets + #define LL_ClearResolvingList _symrom_LL_ClearResolvingList + #define LL_ClearWhiteList _symrom_LL_ClearWhiteList + #define LL_ConnActive _symrom_LL_ConnActive + #define LL_Connection_CTE_Request_Enable _symrom_LL_Connection_CTE_Request_Enable + #define LL_Connection_CTE_Response_Enable _symrom_LL_Connection_CTE_Response_Enable + #define LL_ConnectionCompleteCback _symrom_LL_ConnectionCompleteCback + #define LL_ConnectionIQReportCback _symrom_LL_ConnectionIQReportCback + #define LL_ConnectionlessCTE_TransmitEnable _symrom_LL_ConnectionlessCTE_TransmitEnable + #define LL_ConnectionlessCTE_TransmitParam _symrom_LL_ConnectionlessCTE_TransmitParam + #define LL_ConnectionlessIQ_SampleEnable _symrom_LL_ConnectionlessIQ_SampleEnable + #define LL_ConnectionlessIQReportCback _symrom_LL_ConnectionlessIQReportCback + #define LL_ConnParamUpdateCback _symrom_LL_ConnParamUpdateCback + #define LL_ConnUpdate _symrom_LL_ConnUpdate + #define LL_CreateConn _symrom_LL_CreateConn + #define LL_CreateConnCancel _symrom_LL_CreateConnCancel + #define LL_CTE_Report_FailedCback _symrom_LL_CTE_Report_FailedCback + #define LL_CtrlToHostFlowControl _symrom_LL_CtrlToHostFlowControl + #define LL_DataLengthChangeCback _symrom_LL_DataLengthChangeCback + #define ll_debug_output _symrom_ll_debug_output + #define ll_delete_adv_task _symrom_ll_delete_adv_task + #define ll_delete_adv_task_periodic _symrom_ll_delete_adv_task_periodic + #define ll_deleteTask _symrom_ll_deleteTask + #define LL_DirectTestEnd _symrom_LL_DirectTestEnd + #define LL_DirectTestTxTest _symrom_LL_DirectTestTxTest + #define LL_Disconnect _symrom_LL_Disconnect + #define LL_DisconnectCback _symrom_LL_DisconnectCback + #define LL_ENC_AES128_Encrypt _symrom_LL_ENC_AES128_Encrypt + #define LL_ENC_Decrypt _symrom_LL_ENC_Decrypt + #define LL_ENC_Encrypt _symrom_LL_ENC_Encrypt + #define LL_ENC_GenDeviceIV _symrom_LL_ENC_GenDeviceIV + #define LL_ENC_GenDeviceSKD _symrom_LL_ENC_GenDeviceSKD + #define LL_ENC_GenerateNonce _symrom_LL_ENC_GenerateNonce + #define LL_ENC_GeneratePseudoRandNum _symrom_LL_ENC_GeneratePseudoRandNum + #define LL_ENC_GenerateTrueRandNum _symrom_LL_ENC_GenerateTrueRandNum + #define LL_ENC_LoadKey _symrom_LL_ENC_LoadKey + #define LL_ENC_ReverseBytes _symrom_LL_ENC_ReverseBytes + #define LL_ENC_sm_ah _symrom_LL_ENC_sm_ah + #define LL_EncChangeCback _symrom_LL_EncChangeCback + #define LL_EncKeyRefreshCback _symrom_LL_EncKeyRefreshCback + #define LL_EncLtkNegReply _symrom_LL_EncLtkNegReply + #define LL_EncLtkReply _symrom_LL_EncLtkReply + #define LL_EncLtkReqCback _symrom_LL_EncLtkReqCback + #define LL_Encrypt _symrom_LL_Encrypt + #define LL_evt_schedule _symrom_LL_evt_schedule + #define ll_ext_adv_schedule_next_event _symrom_ll_ext_adv_schedule_next_event + #define LL_EXT_AdvEventNotice _symrom_LL_EXT_AdvEventNotice + #define LL_EXT_BuildRevision _symrom_LL_EXT_BuildRevision + #define LL_EXT_ClkDivOnHalt _symrom_LL_EXT_ClkDivOnHalt + #define LL_EXT_ConnEventNotice _symrom_LL_EXT_ConnEventNotice + #define LL_EXT_DeclareNvUsage _symrom_LL_EXT_DeclareNvUsage + #define LL_EXT_Decrypt _symrom_LL_EXT_Decrypt + #define LL_EXT_DelaySleep _symrom_LL_EXT_DelaySleep + #define LL_EXT_DisconnectImmed _symrom_LL_EXT_DisconnectImmed + #define LL_EXT_EndModemTest _symrom_LL_EXT_EndModemTest + #define LL_EXT_HaltDuringRf _symrom_LL_EXT_HaltDuringRf + #define LL_EXT_Init_IQ_pBuff _symrom_LL_EXT_Init_IQ_pBuff + #define ll_ext_init_schedule_next_event _symrom_ll_ext_init_schedule_next_event + #define LL_EXT_MapPmIoPort _symrom_LL_EXT_MapPmIoPort + #define LL_EXT_ModemHopTestTx _symrom_LL_EXT_ModemHopTestTx + #define LL_EXT_ModemTestRx _symrom_LL_EXT_ModemTestRx + #define LL_EXT_ModemTestTx _symrom_LL_EXT_ModemTestTx + #define LL_EXT_NumComplPktsLimit _symrom_LL_EXT_NumComplPktsLimit + #define LL_EXT_OnePacketPerEvent _symrom_LL_EXT_OnePacketPerEvent + #define LL_EXT_OverlappedProcessing _symrom_LL_EXT_OverlappedProcessing + #define LL_EXT_PacketErrorRate _symrom_LL_EXT_PacketErrorRate + #define LL_EXT_PERbyChan _symrom_LL_EXT_PERbyChan + #define LL_EXT_ResetSystem _symrom_LL_EXT_ResetSystem + #define LL_EXT_SaveFreqTune _symrom_LL_EXT_SaveFreqTune + #define ll_ext_scan_schedule_next_event _symrom_ll_ext_scan_schedule_next_event + #define LL_EXT_SetBDADDR _symrom_LL_EXT_SetBDADDR + #define LL_EXT_SetFastTxResponseTime _symrom_LL_EXT_SetFastTxResponseTime + #define LL_EXT_SetFreqTune _symrom_LL_EXT_SetFreqTune + #define LL_EXT_SetLocalSupportedFeatures _symrom_LL_EXT_SetLocalSupportedFeatures + #define LL_EXT_SetMaxDtmTxPower _symrom_LL_EXT_SetMaxDtmTxPower + #define LL_EXT_SetRxGain _symrom_LL_EXT_SetRxGain + #define LL_EXT_SetSCA _symrom_LL_EXT_SetSCA + #define LL_EXT_SetSlaveLatencyOverride _symrom_LL_EXT_SetSlaveLatencyOverride + #define LL_EXT_SetTxPower _symrom_LL_EXT_SetTxPower + #define LL_ExtAdvReportCback _symrom_LL_ExtAdvReportCback + #define LL_extAdvTimerExpProcess _symrom_LL_extAdvTimerExpProcess + #define LL_ExtendedCreateConnection _symrom_LL_ExtendedCreateConnection + #define LL_extInitTimerExpProcess _symrom_LL_extInitTimerExpProcess + #define LL_extScanTimerExpProcess _symrom_LL_extScanTimerExpProcess + #define ll_generateExtAdvDid _symrom_ll_generateExtAdvDid + #define ll_generateTxBuffer _symrom_ll_generateTxBuffer + #define ll_get_next_active_conn _symrom_ll_get_next_active_conn + #define ll_get_next_timer _symrom_ll_get_next_timer + #define ll_getFirstAdvChn _symrom_ll_getFirstAdvChn + #define ll_getRPAListEntry _symrom_ll_getRPAListEntry + #define ll_hw_clr_irq _symrom_ll_hw_clr_irq + #define ll_hw_config _symrom_ll_hw_config + #define ll_hw_get_anchor _symrom_ll_hw_get_anchor + #define ll_hw_get_fsm_status _symrom_ll_hw_get_fsm_status + #define ll_hw_get_iq_RawSample _symrom_ll_hw_get_iq_RawSample + #define ll_hw_get_irq_status _symrom_ll_hw_get_irq_status + #define ll_hw_get_last_ack _symrom_ll_hw_get_last_ack + #define ll_hw_get_loop_cycle _symrom_ll_hw_get_loop_cycle + #define ll_hw_get_loop_time _symrom_ll_hw_get_loop_time + #define ll_hw_get_nAck _symrom_ll_hw_get_nAck + #define ll_hw_get_rfifo_depth _symrom_ll_hw_get_rfifo_depth + #define ll_hw_get_rfifo_info _symrom_ll_hw_get_rfifo_info + #define ll_hw_get_rxPkt_CrcErr_num _symrom_ll_hw_get_rxPkt_CrcErr_num + #define ll_hw_get_rxPkt_CrcOk_num _symrom_ll_hw_get_rxPkt_CrcOk_num + #define ll_hw_get_rxPkt_num _symrom_ll_hw_get_rxPkt_num + #define ll_hw_get_rxPkt_stats _symrom_ll_hw_get_rxPkt_stats + #define ll_hw_get_rxPkt_Total_num _symrom_ll_hw_get_rxPkt_Total_num + #define ll_hw_get_snNesn _symrom_ll_hw_get_snNesn + #define ll_hw_get_tfifo_info _symrom_ll_hw_get_tfifo_info + #define ll_hw_get_tfifo_wrptr _symrom_ll_hw_get_tfifo_wrptr + #define ll_hw_get_tr_mode _symrom_ll_hw_get_tr_mode + #define ll_hw_get_txAck _symrom_ll_hw_get_txAck + #define ll_hw_go _symrom_ll_hw_go + #define ll_hw_ign_rfifo _symrom_ll_hw_ign_rfifo + #define ll_hw_process_RTO _symrom_ll_hw_process_RTO + #define ll_hw_read_rfifo _symrom_ll_hw_read_rfifo + #define ll_hw_read_rfifo_pplus _symrom_ll_hw_read_rfifo_pplus + #define ll_hw_read_rfifo_zb _symrom_ll_hw_read_rfifo_zb + #define ll_hw_read_tfifo_packet _symrom_ll_hw_read_tfifo_packet + #define ll_hw_read_tfifo_rtlp _symrom_ll_hw_read_tfifo_rtlp + #define ll_hw_rst_rfifo _symrom_ll_hw_rst_rfifo + #define ll_hw_rst_tfifo _symrom_ll_hw_rst_tfifo + #define ll_hw_set_ant_pattern _symrom_ll_hw_set_ant_pattern + #define ll_hw_set_ant_switch_mode _symrom_ll_hw_set_ant_switch_mode + #define ll_hw_set_ant_switch_timing _symrom_ll_hw_set_ant_switch_timing + #define ll_hw_set_crc_fmt _symrom_ll_hw_set_crc_fmt + #define ll_hw_set_cte_rxSupp _symrom_ll_hw_set_cte_rxSupp + #define ll_hw_set_cte_txSupp _symrom_ll_hw_set_cte_txSupp + #define ll_hw_set_empty_head _symrom_ll_hw_set_empty_head + #define ll_hw_set_irq _symrom_ll_hw_set_irq + #define ll_hw_set_loop_nack_num _symrom_ll_hw_set_loop_nack_num + #define ll_hw_set_loop_timeout _symrom_ll_hw_set_loop_timeout + #define ll_hw_set_pplus_pktfmt _symrom_ll_hw_set_pplus_pktfmt + #define ll_hw_set_rtlp _symrom_ll_hw_set_rtlp + #define ll_hw_set_rtlp_1st _symrom_ll_hw_set_rtlp_1st + #define ll_hw_set_rtx _symrom_ll_hw_set_rtx + #define ll_hw_set_rx_timeout _symrom_ll_hw_set_rx_timeout + #define ll_hw_set_rx_timeout_1st _symrom_ll_hw_set_rx_timeout_1st + #define ll_hw_set_rx_tx_interval _symrom_ll_hw_set_rx_tx_interval + #define ll_hw_set_srx _symrom_ll_hw_set_srx + #define ll_hw_set_stx _symrom_ll_hw_set_stx + #define ll_hw_set_tfifo_space _symrom_ll_hw_set_tfifo_space + #define ll_hw_set_timing _symrom_ll_hw_set_timing + #define ll_hw_set_trlp _symrom_ll_hw_set_trlp + #define ll_hw_set_trx _symrom_ll_hw_set_trx + #define ll_hw_set_trx_settle _symrom_ll_hw_set_trx_settle + #define ll_hw_set_tx_rx_interval _symrom_ll_hw_set_tx_rx_interval + #define ll_hw_set_tx_rx_release _symrom_ll_hw_set_tx_rx_release + #define ll_hw_trigger _symrom_ll_hw_trigger + #define ll_hw_trx_settle_config _symrom_ll_hw_trx_settle_config + #define ll_hw_tx2rx_timing_config _symrom_ll_hw_tx2rx_timing_config + #define ll_hw_update _symrom_ll_hw_update + #define ll_hw_update_rtlp_mode _symrom_ll_hw_update_rtlp_mode + #define ll_hw_update_trlp_mode _symrom_ll_hw_update_trlp_mode + #define ll_hw_write_tfifo _symrom_ll_hw_write_tfifo + #define LL_Init _symrom_LL_Init + #define LL_InitConnectContext _symrom_LL_InitConnectContext + #define LL_InitExtendedAdv _symrom_LL_InitExtendedAdv + #define LL_InitExtendedScan _symrom_LL_InitExtendedScan + #define LL_InitPeriodicAdv _symrom_LL_InitPeriodicAdv + #define LL_IRQHandler _symrom_LL_IRQHandler + #define ll_isAddrInWhiteList _symrom_ll_isAddrInWhiteList + #define ll_isFirstAdvChn _symrom_ll_isFirstAdvChn + #define LL_master_conn_event _symrom_LL_master_conn_event + #define LL_NumEmptyWlEntries _symrom_LL_NumEmptyWlEntries + #define ll_parseExtHeader _symrom_ll_parseExtHeader + #define LL_PeriodicAdvertisingCreateSync _symrom_LL_PeriodicAdvertisingCreateSync + #define LL_PeriodicAdvertisingCreateSyncCancel _symrom_LL_PeriodicAdvertisingCreateSyncCancel + #define LL_PeriodicAdvertisingTerminateSync _symrom_LL_PeriodicAdvertisingTerminateSync + #define LL_PhyUpdate _symrom_LL_PhyUpdate + #define LL_PhyUpdateCompleteCback _symrom_LL_PhyUpdateCompleteCback + #define LL_PLUS_AdvDataFilterCBack _symrom_LL_PLUS_AdvDataFilterCBack + #define LL_PLUS_DisableSlaveLatency _symrom_LL_PLUS_DisableSlaveLatency + #define LL_PLUS_EnableSlaveLatency _symrom_LL_PLUS_EnableSlaveLatency + #define LL_PLUS_GetAdvDataExtendData _symrom_LL_PLUS_GetAdvDataExtendData + #define LL_PLUS_GetScanerAddr _symrom_LL_PLUS_GetScanerAddr + #define LL_PLUS_GetScanRequestExtendData _symrom_LL_PLUS_GetScanRequestExtendData + #define LL_PLUS_PerStasReadByChn _symrom_LL_PLUS_PerStasReadByChn + #define LL_PLUS_PerStats_Init _symrom_LL_PLUS_PerStats_Init + #define LL_PLUS_PerStatsReset _symrom_LL_PLUS_PerStatsReset + #define LL_PLUS_ScanRequestFilterCBack _symrom_LL_PLUS_ScanRequestFilterCBack + #define LL_PLUS_SetAdvDataFilterCB _symrom_LL_PLUS_SetAdvDataFilterCB + #define LL_PLUS_SetScanRequestData _symrom_LL_PLUS_SetScanRequestData + #define LL_PLUS_SetScanRequestFilterCB _symrom_LL_PLUS_SetScanRequestFilterCB + #define LL_PLUS_SetScanRsqData _symrom_LL_PLUS_SetScanRsqData + #define LL_PLUS_SetScanRsqDataByIndex _symrom_LL_PLUS_SetScanRsqDataByIndex + #define ll_prd_adv_schedule_next_event _symrom_ll_prd_adv_schedule_next_event + #define ll_prd_scan_schedule_next_event _symrom_ll_prd_scan_schedule_next_event + #define LL_PrdAdvReportCback _symrom_LL_PrdAdvReportCback + #define LL_PrdAdvSyncEstablishedCback _symrom_LL_PrdAdvSyncEstablishedCback + #define LL_PrdAdvSyncLostCback _symrom_LL_PrdAdvSyncLostCback + #define LL_prdAdvTimerExpProcess _symrom_LL_prdAdvTimerExpProcess + #define LL_prdScanTimerExpProcess _symrom_LL_prdScanTimerExpProcess + #define ll_processBasicIRQ _symrom_ll_processBasicIRQ + #define LL_ProcessEvent _symrom_LL_ProcessEvent + //#define ll_processExtAdvIRQ _symrom_ll_processExtAdvIRQ + //#define ll_processExtInitIRQ _symrom_ll_processExtInitIRQ + //#define ll_processExtScanIRQ _symrom_ll_processExtScanIRQ + #define ll_processMissMasterEvt _symrom_ll_processMissMasterEvt + #define ll_processMissSlaveEvt _symrom_ll_processMissSlaveEvt + #define ll_processPrdAdvIRQ _symrom_ll_processPrdAdvIRQ + #define ll_processPrdScanIRQ _symrom_ll_processPrdScanIRQ + #define LL_PseudoRand _symrom_LL_PseudoRand + #define LL_Rand _symrom_LL_Rand + #define LL_RandCback _symrom_LL_RandCback + #define LL_READ_Anatenna_Info _symrom_LL_READ_Anatenna_Info + #define ll_read_rxfifo _symrom_ll_read_rxfifo + #define LL_ReadAdvChanTxPower _symrom_LL_ReadAdvChanTxPower + #define LL_ReadBDADDR _symrom_LL_ReadBDADDR + #define LL_ReadCarrSens _symrom_LL_ReadCarrSens + #define LL_ReadChanMap _symrom_LL_ReadChanMap + #define LL_ReadFoff _symrom_LL_ReadFoff + #define ll_readLocalIRK _symrom_ll_readLocalIRK + #define LL_ReadLocalSupportedFeatures _symrom_LL_ReadLocalSupportedFeatures + #define LL_ReadLocalVersionInfo _symrom_LL_ReadLocalVersionInfo + #define LL_ReadMaximumAdvDataLength _symrom_LL_ReadMaximumAdvDataLength + #define LL_ReadNumberOfSupportAdvSet _symrom_LL_ReadNumberOfSupportAdvSet + #define LL_ReadRemoteUsedFeatures _symrom_LL_ReadRemoteUsedFeatures + #define LL_ReadRemoteUsedFeaturesCompleteCback _symrom_LL_ReadRemoteUsedFeaturesCompleteCback + #define LL_ReadRemoteVersionInfo _symrom_LL_ReadRemoteVersionInfo + #define LL_ReadRemoteVersionInfoCback _symrom_LL_ReadRemoteVersionInfoCback + #define LL_ReadResolvingListSize _symrom_LL_ReadResolvingListSize + #define LL_ReadRssi _symrom_LL_ReadRssi + #define LL_ReadSupportedStates _symrom_LL_ReadSupportedStates + #define LL_ReadTxPowerLevel _symrom_LL_ReadTxPowerLevel + #define LL_ReadWlSize _symrom_LL_ReadWlSize + #define ll_remain_time _symrom_ll_remain_time + #define LL_RemoveAdvSet _symrom_LL_RemoveAdvSet + #define LL_RemoveResolvingListDevice _symrom_LL_RemoveResolvingListDevice + #define LL_RemoveWhiteListDevice _symrom_LL_RemoveWhiteListDevice + #define LL_Reset _symrom_LL_Reset + #define ll_ResolveRandomAddrs _symrom_ll_ResolveRandomAddrs + #define LL_RX_bm_alloc _symrom_LL_RX_bm_alloc + #define LL_RxDataCompleteCback _symrom_LL_RxDataCompleteCback + #define ll_schedule_next_event _symrom_ll_schedule_next_event + #define ll_scheduler _symrom_ll_scheduler + #define LL_Set_ConnectionCTE_ReceiveParam _symrom_LL_Set_ConnectionCTE_ReceiveParam + #define LL_Set_ConnectionCTE_TransmitParam _symrom_LL_Set_ConnectionCTE_TransmitParam + #define LL_set_default_conn_params _symrom_LL_set_default_conn_params + #define LL_SetAddressResolutionEnable _symrom_LL_SetAddressResolutionEnable + #define LL_SetAdvControl _symrom_LL_SetAdvControl + #define LL_SetAdvData _symrom_LL_SetAdvData + #define LL_SetAdvParam _symrom_LL_SetAdvParam + #define LL_SetDataLengh _symrom_LL_SetDataLengh + #define LL_SetDefaultPhyMode _symrom_LL_SetDefaultPhyMode + //#define LL_SetExtAdvData _symrom_LL_SetExtAdvData + //#define LL_SetExtAdvEnable _symrom_LL_SetExtAdvEnable + //#define LL_SetExtAdvParam _symrom_LL_SetExtAdvParam + #define LL_SetExtAdvSetRandomAddress _symrom_LL_SetExtAdvSetRandomAddress + #define LL_SetExtendedScanEnable _symrom_LL_SetExtendedScanEnable + #define LL_SetExtendedScanParameters _symrom_LL_SetExtendedScanParameters + #define LL_SetExtScanRspData _symrom_LL_SetExtScanRspData + #define LL_SetPeriodicAdvData _symrom_LL_SetPeriodicAdvData + #define LL_SetPeriodicAdvEnable _symrom_LL_SetPeriodicAdvEnable + #define LL_SetPeriodicAdvParameter _symrom_LL_SetPeriodicAdvParameter + #define LL_SetPhyMode _symrom_LL_SetPhyMode + #define LL_SetRandomAddress _symrom_LL_SetRandomAddress + #define LL_SetResolvablePrivateAddressTimeout _symrom_LL_SetResolvablePrivateAddressTimeout + #define LL_SetScanControl _symrom_LL_SetScanControl + #define LL_SetScanParam _symrom_LL_SetScanParam + #define LL_SetScanRspData _symrom_LL_SetScanRspData + #define LL_SetTxPowerLevel _symrom_LL_SetTxPowerLevel + #define LL_slave_conn_event _symrom_LL_slave_conn_event + #define LL_StartEncrypt _symrom_LL_StartEncrypt + #define LL_TaskID _symrom_LL_TaskID + #define LL_TX_bm_alloc _symrom_LL_TX_bm_alloc + #define LL_TxData _symrom_LL_TxData + #define ll_updateAuxAdvTimeSlot _symrom_ll_updateAuxAdvTimeSlot + #define ll_updateExtAdvRemainderTime _symrom_ll_updateExtAdvRemainderTime + #define LL_WriteSuggestedDefaultDataLength _symrom_LL_WriteSuggestedDefaultDataLength + #define ll24BitTimeCompare _symrom_ll24BitTimeCompare + #define llAdjSlaveLatencyValue _symrom_llAdjSlaveLatencyValue + #define llAllocateSyncHandle _symrom_llAllocateSyncHandle + #define llAllocConnId _symrom_llAllocConnId + #define llAtLeastTwoChans _symrom_llAtLeastTwoChans + #define llCalcMaxScanTime _symrom_llCalcMaxScanTime + #define llCalcScaFactor _symrom_llCalcScaFactor + #define llCalcTimerDrift _symrom_llCalcTimerDrift + #define llCheckForLstoDuringSL _symrom_llCheckForLstoDuringSL + #define llCheckWhiteListUsage _symrom_llCheckWhiteListUsage + #define llConnCleanup _symrom_llConnCleanup + #define llConnTerminate _symrom_llConnTerminate + #define llConnTerminate0 _symrom_llConnTerminate0 + #define llConvertCtrlProcTimeoutToEvent _symrom_llConvertCtrlProcTimeoutToEvent + #define llConvertLstoToEvent _symrom_llConvertLstoToEvent + #define llCurrentScanChn _symrom_llCurrentScanChn + #define llDeleteSyncHandle _symrom_llDeleteSyncHandle + #define llDequeueCtrlPkt _symrom_llDequeueCtrlPkt + #define llDequeueDataQ _symrom_llDequeueDataQ + #define llEnqueueCtrlPkt _symrom_llEnqueueCtrlPkt + #define llEnqueueDataQ _symrom_llEnqueueDataQ + #define llEqAlreadyValidAddr _symrom_llEqAlreadyValidAddr + #define llEqSynchWord _symrom_llEqSynchWord + #define llEqualBytes _symrom_llEqualBytes + #define llEventDelta _symrom_llEventDelta + #define llEventInRange _symrom_llEventInRange + #define llGenerateCRC _symrom_llGenerateCRC + #define llGenerateValidAccessAddr _symrom_llGenerateValidAccessAddr + #define llGetNextAdvChn _symrom_llGetNextAdvChn + #define llGetNextAuxAdvChn _symrom_llGetNextAuxAdvChn + #define llGetNextDataChan _symrom_llGetNextDataChan + #define llGetNextDataChanCSA2 _symrom_llGetNextDataChanCSA2 + #define llGtSixConsecZerosOrOnes _symrom_llGtSixConsecZerosOrOnes + #define llGtTwentyFourTransitions _symrom_llGtTwentyFourTransitions + #define llInitFeatureSet _symrom_llInitFeatureSet + #define llInitFeatureSet2MPHY _symrom_llInitFeatureSet2MPHY + #define llInitFeatureSetCodedPHY _symrom_llInitFeatureSetCodedPHY + #define llInitFeatureSetDLE _symrom_llInitFeatureSetDLE + #define llLtTwoChangesInLastSixBits _symrom_llLtTwoChangesInLastSixBits + #define llMasterEvt_TaskEndOk _symrom_llMasterEvt_TaskEndOk + #define llMemCopyDst _symrom_llMemCopyDst + #define llMemCopySrc _symrom_llMemCopySrc + #define llOneBitSynchWordDiffer _symrom_llOneBitSynchWordDiffer + #define llPduLengthManagmentReset _symrom_llPduLengthManagmentReset + #define llPduLengthUpdate _symrom_llPduLengthUpdate + #define llPendingUpdateParam _symrom_llPendingUpdateParam + #define llPhyModeCtrlReset _symrom_llPhyModeCtrlReset + #define llPhyModeCtrlUpdateNotify _symrom_llPhyModeCtrlUpdateNotify + #define llProcessChanMap _symrom_llProcessChanMap + #define llProcessMasterControlPacket _symrom_llProcessMasterControlPacket + #define llProcessMasterControlProcedures _symrom_llProcessMasterControlProcedures + #define llProcessRxData _symrom_llProcessRxData + #define llProcessSlaveControlPacket _symrom_llProcessSlaveControlPacket + #define llProcessSlaveControlProcedures _symrom_llProcessSlaveControlProcedures + #define llProcessTxData _symrom_llProcessTxData + #define llReleaseAllConnId _symrom_llReleaseAllConnId + #define llReleaseConnId _symrom_llReleaseConnId + #define llReplaceCtrlPkt _symrom_llReplaceCtrlPkt + #define llResetConnId _symrom_llResetConnId + #define llResetRfCounters _symrom_llResetRfCounters + #define llScanT1 _symrom_llScanT1 + #define llScanTime _symrom_llScanTime + #define llSecAdvAllow _symrom_llSecAdvAllow + #define llSecondaryState _symrom_llSecondaryState + #define llSetNextDataChan _symrom_llSetNextDataChan + #define llSetNextPhyMode _symrom_llSetNextPhyMode + #define llSetupAdv _symrom_llSetupAdv + #define llSetupAdvExtIndPDU _symrom_llSetupAdvExtIndPDU + #define llSetupAuxAdvIndPDU _symrom_llSetupAuxAdvIndPDU + #define llSetupAuxChainIndPDU _symrom_llSetupAuxChainIndPDU + #define llSetupAuxConnectReqPDU _symrom_llSetupAuxConnectReqPDU + #define llSetupAuxConnectRspPDU _symrom_llSetupAuxConnectRspPDU + #define llSetupAuxScanRspPDU _symrom_llSetupAuxScanRspPDU + #define llSetupAuxSyncIndPDU _symrom_llSetupAuxSyncIndPDU + #define llSetupConn _symrom_llSetupConn + #define llSetupCTEReq _symrom_llSetupCTEReq + #define llSetupCTERsp _symrom_llSetupCTERsp + #define llSetupDataLenghtReq _symrom_llSetupDataLenghtReq + #define llSetupDataLenghtRsp _symrom_llSetupDataLenghtRsp + #define llSetupDirectedAdvEvt _symrom_llSetupDirectedAdvEvt + #define llSetupEncReq _symrom_llSetupEncReq + #define llSetupEncRsp _symrom_llSetupEncRsp + #define llSetupExtAdvEvent _symrom_llSetupExtAdvEvent + //#define llSetupExtInit _symrom_llSetupExtInit + //#define llSetupExtScan _symrom_llSetupExtScan + #define llSetupFeatureSetReq _symrom_llSetupFeatureSetReq + #define llSetupFeatureSetRsp _symrom_llSetupFeatureSetRsp + #define llSetupInit _symrom_llSetupInit + #define llSetupNextMasterEvent _symrom_llSetupNextMasterEvent + #define llSetupNextSlaveEvent _symrom_llSetupNextSlaveEvent + #define llSetupNonConnectableAdvEvt _symrom_llSetupNonConnectableAdvEvt + #define llSetupPauseEncReq _symrom_llSetupPauseEncReq + #define llSetupPauseEncRsp _symrom_llSetupPauseEncRsp + #define llSetupPhyReq _symrom_llSetupPhyReq + #define llSetupPhyRsp _symrom_llSetupPhyRsp + #define llSetupPhyUpdateInd _symrom_llSetupPhyUpdateInd + #define llSetupPrdAdvEvent _symrom_llSetupPrdAdvEvent + //#define llSetupPrdScan _symrom_llSetupPrdScan + #define llSetupRejectExtInd _symrom_llSetupRejectExtInd + #define llSetupRejectInd _symrom_llSetupRejectInd + #define llSetupScan _symrom_llSetupScan + #define llSetupScanInit _symrom_llSetupScanInit + #define llSetupScannableAdvEvt _symrom_llSetupScannableAdvEvt + #define llSetupSecAdvEvt _symrom_llSetupSecAdvEvt + #define llSetupSecConnectableAdvEvt _symrom_llSetupSecConnectableAdvEvt + #define llSetupSecInit _symrom_llSetupSecInit + #define llSetupSecNonConnectableAdvEvt _symrom_llSetupSecNonConnectableAdvEvt + #define llSetupSecScan _symrom_llSetupSecScan + #define llSetupSecScannableAdvEvt _symrom_llSetupSecScannableAdvEvt + #define llSetupStartEncReq _symrom_llSetupStartEncReq + #define llSetupStartEncRsp _symrom_llSetupStartEncRsp + #define llSetupSyncInfo _symrom_llSetupSyncInfo + #define llSetupTermInd _symrom_llSetupTermInd + #define llSetupUndirectedAdvEvt _symrom_llSetupUndirectedAdvEvt + #define llSetupUnknownRsp _symrom_llSetupUnknownRsp + #define llSetupUpdateChanReq _symrom_llSetupUpdateChanReq + #define llSetupUpdateParamReq _symrom_llSetupUpdateParamReq + #define llSetupVersionIndReq _symrom_llSetupVersionIndReq + #define llSlaveEvt_TaskAbort _symrom_llSlaveEvt_TaskAbort + #define llSlaveEvt_TaskEndOk _symrom_llSlaveEvt_TaskEndOk + #define llState _symrom_llState + #define llTaskState _symrom_llTaskState + #define llTrxNumAdaptiveConfig _symrom_llTrxNumAdaptiveConfig + #define llValidAccessAddr _symrom_llValidAccessAddr + #define llWaitingIrq _symrom_llWaitingIrq + #define llWaitUs _symrom_llWaitUs + #define llWriteTxData _symrom_llWriteTxData + #define log_clr_putc _symrom_log_clr_putc + #define log_debug_level _symrom_log_debug_level + #define log_get_debug_level _symrom_log_get_debug_level + #define log_printf _symrom_log_printf + #define log_set_putc _symrom_log_set_putc + #define log_vsprintf _symrom_log_vsprintf + #define move_to_master_function _symrom_move_to_master_function + #define move_to_slave_function _symrom_move_to_slave_function + #define NMI_Handler _symrom_NMI_Handler + #define numComplPkts _symrom_numComplPkts + #define numComplPktsLimit _symrom_numComplPktsLimit + #define numHostBufs _symrom_numHostBufs + #define osal_bm_adjust_header _symrom_osal_bm_adjust_header + #define osal_bm_adjust_tail _symrom_osal_bm_adjust_tail + #define osal_bm_alloc _symrom_osal_bm_alloc + #define osal_bm_free _symrom_osal_bm_free + #define osal_buffer_uint24 _symrom_osal_buffer_uint24 + #define osal_buffer_uint32 _symrom_osal_buffer_uint32 + #define osal_build_uint16 _symrom_osal_build_uint16 + #define osal_build_uint32 _symrom_osal_build_uint32 + #define osal_CbTimerInit _symrom_osal_CbTimerInit + #define osal_CbTimerProcessEvent _symrom_osal_CbTimerProcessEvent + #define osal_CbTimerStart _symrom_osal_CbTimerStart + #define osal_CbTimerStop _symrom_osal_CbTimerStop + #define osal_CbTimerUpdate _symrom_osal_CbTimerUpdate + #define osal_clear_event _symrom_osal_clear_event + #define osal_ConvertUTCSecs _symrom_osal_ConvertUTCSecs + #define osal_ConvertUTCTime _symrom_osal_ConvertUTCTime + #define osal_get_timeoutEx _symrom_osal_get_timeoutEx + #define osal_getClock _symrom_osal_getClock + #define osal_GetSystemClock _symrom_osal_GetSystemClock + #define osal_init_system _symrom_osal_init_system + #define osal_isbufset _symrom_osal_isbufset + #define osal_mem_alloc _symrom_osal_mem_alloc + #define osal_mem_free _symrom_osal_mem_free + #define osal_mem_init _symrom_osal_mem_init + #define osal_mem_kick _symrom_osal_mem_kick + #define osal_mem_set_heap _symrom_osal_mem_set_heap + #define osal_memcmp _symrom_osal_memcmp + #define osal_memcpy _symrom_osal_memcpy + #define osal_memdup _symrom_osal_memdup + #define osal_memset _symrom_osal_memset + #define osal_msg_allocate _symrom_osal_msg_allocate + #define osal_msg_deallocate _symrom_osal_msg_deallocate + #define osal_msg_dequeue _symrom_osal_msg_dequeue + #define osal_msg_enqueue _symrom_osal_msg_enqueue + #define osal_msg_enqueue_max _symrom_osal_msg_enqueue_max + #define osal_msg_extract _symrom_osal_msg_extract + #define osal_msg_find _symrom_osal_msg_find + #define osal_msg_push _symrom_osal_msg_push + #define osal_msg_push_front _symrom_osal_msg_push_front + #define osal_msg_receive _symrom_osal_msg_receive + #define osal_msg_send _symrom_osal_msg_send + #define osal_next_timeout _symrom_osal_next_timeout + #define osal_pwrmgr_device _symrom_osal_pwrmgr_device + #define osal_pwrmgr_init _symrom_osal_pwrmgr_init + #define osal_pwrmgr_powerconserve _symrom_osal_pwrmgr_powerconserve + #define osal_pwrmgr_task_state _symrom_osal_pwrmgr_task_state + #define osal_qHead _symrom_osal_qHead + #define osal_rand _symrom_osal_rand + #define osal_revmemcpy _symrom_osal_revmemcpy + #define osal_run_system _symrom_osal_run_system + #define osal_self _symrom_osal_self + #define osal_set_event _symrom_osal_set_event + #define osal_setClock _symrom_osal_setClock + #define osal_start_reload_timer _symrom_osal_start_reload_timer + #define osal_start_system _symrom_osal_start_system + #define osal_start_timerEx _symrom_osal_start_timerEx + #define osal_stop_timerEx _symrom_osal_stop_timerEx + #define osal_strlen _symrom_osal_strlen + #define osal_sys_tick _symrom_osal_sys_tick + #define osal_timer_num_active _symrom_osal_timer_num_active + #define OSAL_timeSeconds _symrom_OSAL_timeSeconds + #define osalAddTimer _symrom_osalAddTimer + #define osalDeleteTimer _symrom_osalDeleteTimer + #define osalFindTimer _symrom_osalFindTimer + #define osalTimerInit _symrom_osalTimerInit + #define osalTimerUpdate _symrom_osalTimerUpdate + #define osalTimeUpdate _symrom_osalTimeUpdate + #define osalTimeUpdate1 _symrom_osalTimeUpdate1 + #define ownPublicAddr _symrom_ownPublicAddr + #define p_perStatsByChan _symrom_p_perStatsByChan + #define peerInfo _symrom_peerInfo + #define PendSV_Handler _symrom_PendSV_Handler + #define pHciEvtMask _symrom_pHciEvtMask + #define phy_sec_app_key _symrom_phy_sec_app_key + #define phy_sec_decrypt _symrom_phy_sec_decrypt + #define phy_sec_efuse_lock _symrom_phy_sec_efuse_lock + #define phy_sec_encrypt _symrom_phy_sec_encrypt + #define phy_sec_init _symrom_phy_sec_init + #define phy_sec_key_valid _symrom_phy_sec_key_valid + #define prog_process_data _symrom_prog_process_data + #define prog_uart_command _symrom_prog_uart_command + #define prog_uart_fct_command _symrom_prog_uart_fct_command + #define prog_uart_handle _symrom_prog_uart_handle + #define pwrmgr_attribute _symrom_pwrmgr_attribute + #define read_current_fine_time _symrom_read_current_fine_time + #define read_ll_adv_remainder_time _symrom_read_ll_adv_remainder_time + #define read_LL_remainder_time _symrom_read_LL_remainder_time + #define receive_timeout_flag _symrom_receive_timeout_flag + #define reset_conn_buf _symrom_reset_conn_buf + //#define rf_calibrate _symrom_rf_calibrate + //#define rf_init _symrom_rf_init + //#define rf_phy_ana_cfg _symrom_rf_phy_ana_cfg + //#define rf_phy_bb_cfg _symrom_rf_phy_bb_cfg + //#define rf_phy_change_cfg _symrom_rf_phy_change_cfg + //#define rf_phy_direct_test_ate _symrom_rf_phy_direct_test_ate + //#define rf_phy_get_pktFoot _symrom_rf_phy_get_pktFoot + //#define rf_phy_ini _symrom_rf_phy_ini + //#define rf_phy_set_txPower _symrom_rf_phy_set_txPower + //#define rf_rxDcoc_cfg _symrom_rf_rxDcoc_cfg + //#define rf_tp_cal _symrom_rf_tp_cal + //#define rf_tpCal_cfg _symrom_rf_tpCal_cfg + //#define rf_tpCal_cfg_avg _symrom_rf_tpCal_cfg_avg + //#define rf_tpCal_gen_cap_arrary _symrom_rf_tpCal_gen_cap_arrary + #define rfCounters _symrom_rfCounters + #define rom_board_init _symrom_rom_board_init + #define rtc_clear _symrom_rtc_clear + #define rtc_config_prescale _symrom_rtc_config_prescale + #define rtc_get_counter _symrom_rtc_get_counter + #define rtc_mod_value _symrom_rtc_mod_value + #define rtc_start _symrom_rtc_start + #define rtc_stop _symrom_rtc_stop + #define rxFifoFlowCtrl _symrom_rxFifoFlowCtrl + #define s_prog_time_save _symrom_s_prog_time_save + #define s_prog_timeout _symrom_s_prog_timeout + #define s_rom_debug_level _symrom_s_rom_debug_level + #define s_spif_ctx _symrom_s_spif_ctx + #define SCA _symrom_SCA + #define scanInfo _symrom_scanInfo + #define scanSyncInfo _symrom_scanSyncInfo + #define set_access_address _symrom_set_access_address + #define set_channel _symrom_set_channel + #define set_crc_seed _symrom_set_crc_seed + #define set_gpio_pull_down_ate _symrom_set_gpio_pull_down_ate + #define set_gpio_pull_up_ate _symrom_set_gpio_pull_up_ate + #define set_int _symrom_set_int + #define set_max_length _symrom_set_max_length + #define set_sleep_flag _symrom_set_sleep_flag + #define set_timer _symrom_set_timer + #define set_whiten_seed _symrom_set_whiten_seed + #define setSleepMode _symrom_setSleepMode + #define slave_conn_event_recv_delay _symrom_slave_conn_event_recv_delay + #define sleep_flag _symrom_sleep_flag + #define spif_cmd _symrom_spif_cmd + #define spif_erase_all _symrom_spif_erase_all + #define spif_erase_block64 _symrom_spif_erase_block64 + #define spif_erase_chip _symrom_spif_erase_chip + #define spif_erase_sector _symrom_spif_erase_sector + #define spif_flash_size _symrom_spif_flash_size + #define spif_flash_status_reg_0 _symrom_spif_flash_status_reg_0 + #define spif_flash_status_reg_1 _symrom_spif_flash_status_reg_1 + #define spif_init _symrom_spif_init + #define spif_rddata _symrom_spif_rddata + #define spif_read _symrom_spif_read + #define spif_release_deep_sleep _symrom_spif_release_deep_sleep + #define spif_set_deep_sleep _symrom_spif_set_deep_sleep + #define spif_wrdata _symrom_spif_wrdata + #define spif_write _symrom_spif_write + #define spif_write_protect _symrom_spif_write_protect + #define sram_ret_patch _symrom_sram_ret_patch + #define supportedCmdsTable _symrom_supportedCmdsTable + #define syncInfo _symrom_syncInfo + #define timerHead _symrom_timerHead + #define tx_scanRsp_desc _symrom_tx_scanRsp_desc + #define update_rx_read_ptr _symrom_update_rx_read_ptr + #define update_rx_write_ptr _symrom_update_rx_write_ptr + #define update_tx_read_ptr _symrom_update_tx_read_ptr + #define update_tx_write_ptr _symrom_update_tx_write_ptr + #define verInfo _symrom_verInfo + #define WaitRTCCount _symrom_WaitRTCCount + #define wakeup_init _symrom_wakeup_init + #define wakeup_init0 _symrom_wakeup_init0 + #define wakeupProcess _symrom_wakeupProcess + #define whiten_seed _symrom_whiten_seed + #define zigbee_crc16_gen _symrom_zigbee_crc16_gen + #define WaitUs _symrom_WaitUs + +#endif +#endif + diff --git a/arch/arm/src/phy62xx/start.c b/arch/arm/src/phy62xx/start.c new file mode 100644 index 00000000000..8428f67211f --- /dev/null +++ b/arch/arm/src/phy62xx/start.c @@ -0,0 +1,191 @@ +/**************************************************************************** + * arch/arm/src/stm32f0l0g0/stm32_start.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "arm_arch.h" +#include "arm_internal.h" + +#include "start.h" +#include "clock.h" +#include "flash.h" +#include "log.h" +#include "jump_function.h" +#include "rf_phy_driver.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +extern const uint32_t _sramscttexts; +extern const uint32_t _sramscttext; +extern const uint32_t _eramscttext; + +extern const uint32_t _sjtblss; +extern const uint32_t _sjtbls; +extern const uint32_t _ejtbls; + + +#define IDLE_STACK ((uint32_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE) +const uintptr_t g_idle_topstack = IDLE_STACK; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + + + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: showprogress + * + * Description: + * Print a character on the CONSOLE USART to show boot status. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_FEATURES +# define showprogress(c) up_putc(c) +#else +# define showprogress(c) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This is the reset entry point. + * + ****************************************************************************/ + +extern uint32_t* jump_table_base[]; + +extern volatile sysclk_t g_system_clk; +void c_start(void) +{ + const uint32_t *src; + uint32_t *dest; + /* Configure the uart so that we can get debug output as soon as possible */ + + //set stack to main stack point + spif_config(SYS_CLK_DLL_64M, 1, 0x801003B, 0, 0); + + HAL_CRITICAL_SECTION_INIT(); + + g_system_clk = SYS_CLK_DLL_48M; + clk_init(SYS_CLK_DLL_48M); + //clk_init(SYS_CLK_XTAL_16M); +#if 1 + //stm32_clockconfig(); + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sbss; dest < &_ebss; ) + { + *dest++ = 0; + } + + //showprogress('B'); + + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + for (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + + //showprogress('C'); +/* + for (src = &_sramscttexts, dest = &_sramscttext; dest < &_eramscttext; ) + { + *dest++ = *src++; + } +*/ + for (src = &_sjtblss, dest = &_sjtbls; dest < &_ejtbls; ) + { + *dest++ = *src++; + } + + //showprogress('J'); + + /* Perform early serial initialization */ + hal_gpio_init(); + LOG_INIT(); + showprogress('A'); +#ifdef USE_EARLYSERIALINIT + arm_earlyserialinit(); +#endif + showprogress('D'); + + /* For the case of the separate user-/kernel-space build, perform whatever + * platform specific initialization of the user memory is required. + * Normally this just means initializing the user space .data and .bss + * segments. + */ + +#ifdef CONFIG_BUILD_PROTECTED + //stm32_userspace(); + showprogress('E'); +#endif + + /* Initialize onboard resources */ + + //stm32_boardinitialize(); + showprogress('F'); + + /* Then start NuttX */ + + showprogress('\r'); + showprogress('\n'); +#endif + +#ifdef CONFIG_PHY6222_BLE + phy62xx_ble_init(); +#endif + jump_table_base[0] = 0; + nx_start(); + + /* Shouldn't get here */ + + for (; ; ); +} diff --git a/arch/arm/src/phy62xx/start.h b/arch/arm/src/phy62xx/start.h new file mode 100644 index 00000000000..d84600f3652 --- /dev/null +++ b/arch/arm/src/phy62xx/start.h @@ -0,0 +1,62 @@ +/**************************************************************************** + * arch/arm/src/stm32f0l0g0/stm32_start.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F0L0G0_STM32_START_H +#define __ARCH_ARM_SRC_STM32F0L0G0_STM32_START_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +extern "C" +{ +#endif + +/**************************************************************************** + * Public Functions Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_boardinitialize + * + * Description: + * All STM32 architectures must provide the following entry point. This + * entry point is called early in the initialization -- after all memory + * has been configured and mapped but before any devices have been + * initialized. + * + ****************************************************************************/ + +void stm32_boardinitialize(void); + +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_STM32F0L0G0_STM32_START_H */ diff --git a/arch/arm/src/phy62xx/systick.c b/arch/arm/src/phy62xx/systick.c new file mode 100644 index 00000000000..b3cb73300dd --- /dev/null +++ b/arch/arm/src/phy62xx/systick.c @@ -0,0 +1,30 @@ + +#include "rom_sym_def.h" +#include "timer.h" +#include "error.h" +#include "clock.h" +#include "pwrmgr.h" +#include "nvic.h" +#include "arm_arch.h" +#include "jump_function.h" +#include + +static int systic_timerisr(int irq, uint32_t *regs, FAR void *arg) +{ + /* Process timer interrupt */ + + nxsched_process_timer(); + return 0; +} +void up_timer_initialize(void) +{ + + irq_attach(PHY62XX_IRQ_SYSTICK, (xcpt_t)systic_timerisr, NULL); + + putreg32((sysclk_get_clk()/100-1), ARMV6M_SYSTICK_RVR);//10ms tick + putreg32((SYSTICK_CSR_TICKINT | SYSTICK_CSR_ENABLE | SYSTICK_CSR_CLKSOURCE), ARMV6M_SYSTICK_CSR); + + /* And enable the timer interrupt */ + + up_enable_irq(PHY62XX_IRQ_SYSTICK); +} diff --git a/arch/arm/src/phy62xx/timer.c b/arch/arm/src/phy62xx/timer.c new file mode 100644 index 00000000000..65bbd622c9e --- /dev/null +++ b/arch/arm/src/phy62xx/timer.c @@ -0,0 +1,211 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ +#include "rom_sym_def.h" +#include "timer.h" +#include "error.h" +#include "clock.h" +#include "pwrmgr.h" +#include "nvic.h" +#include "arm_arch.h" +#include "jump_function.h" +#include + +AP_TIM_TypeDef* const TimerIndex[FREE_TIMER_NUMBER]= {AP_TIM5,AP_TIM6}; +static ap_tm_hdl_t s_ap_callback = NULL; + +static int hal_timer_clear_int(AP_TIM_TypeDef* TIMx) +{ + return TIMx->EOI; +} + +static void hal_timer_stop_counter(AP_TIM_TypeDef* TIMx) +{ + TIMx->ControlReg = 0; + TIMx->LoadCount = 0; //0x0 + TIMx->CurrentCount = 0;//0x4 +} + +static void hal_timer_set_loadtimer(AP_TIM_TypeDef* TIMx, int time) +{ + if(time>0) + { + TIMx->ControlReg = 0x0; + TIMx->ControlReg = 0x2; + TIMx->LoadCount = 4*time;// 4MHz system timer, * 4 to convert to 1MHz timer + TIMx->ControlReg = 0x3; + } + else + { + TIMx->ControlReg = 0x0; + } +} + +void __attribute__((used)) hal_TIMER5_IRQHandler(void) +{ + if(AP_TIM5->status & 0x1) + { + hal_timer_clear_int(AP_TIM5); + + if(s_ap_callback) + s_ap_callback(HAL_EVT_TIMER_5); + } +} + +void __attribute__((used)) hal_TIMER6_IRQHandler(void) +{ + if(AP_TIM6->status & 0x1) + { + hal_timer_clear_int(AP_TIM6); + + if(s_ap_callback) + s_ap_callback(HAL_EVT_TIMER_6); + } +} + +static void hal_timer_wakeup_handler(void) +{ + if(s_ap_callback) + s_ap_callback(HAL_EVT_WAKEUP); +} + +void hal_timer_sleep_handler(void) +{ + if(s_ap_callback) + s_ap_callback(HAL_EVT_SLEEP); +} + +int hal_timer_mask_int(User_Timer_e timeId, bool en) +{ + volatile AP_TIM_TypeDef* TIMx; + TIMx = TimerIndex[timeId-AP_TIMER_ID_5]; + + if(en) + TIMx->ControlReg |= (1 << 2); + else + TIMx->ControlReg &= ~(1 << 2); + + return PPlus_SUCCESS; +} + +int hal_timer_set(User_Timer_e timeId, uint32_t us) +{ + uint32_t time = us; + + switch(timeId) + { + case AP_TIMER_ID_5: + JUMP_FUNCTION(TIM5_IRQ_HANDLER) = (uint32_t)&hal_TIMER5_IRQHandler; + NVIC_EnableIRQ((IRQn_Type)TIM5_IRQn); + NVIC_SetPriority((IRQn_Type)TIM5_IRQn, IRQ_PRIO_HAL); + hal_timer_set_loadtimer(AP_TIM5, time); + hal_clk_gate_enable(MOD_TIMER5); + break; + + case AP_TIMER_ID_6: + JUMP_FUNCTION(TIM6_IRQ_HANDLER) = (uint32_t)&hal_TIMER6_IRQHandler; + NVIC_EnableIRQ((IRQn_Type)TIM6_IRQn); + NVIC_SetPriority((IRQn_Type)TIM6_IRQn, IRQ_PRIO_HAL); + hal_timer_set_loadtimer(AP_TIM6, time); + hal_clk_gate_enable(MOD_TIMER6); + break; + + default: + return PPlus_ERR_INVALID_PARAM; + } + + return PPlus_SUCCESS; +} + +int hal_timer_stop(User_Timer_e timeId) +{ + switch(timeId) + { + case AP_TIMER_ID_5: + JUMP_FUNCTION(TIM5_IRQ_HANDLER) = 0; + hal_timer_stop_counter(AP_TIM5); + NVIC_DisableIRQ((IRQn_Type)TIM5_IRQn); + hal_clk_gate_disable(MOD_TIMER5); + break; + + case AP_TIMER_ID_6: + JUMP_FUNCTION(TIM6_IRQ_HANDLER) = 0; + hal_timer_stop_counter(AP_TIM6); + NVIC_DisableIRQ((IRQn_Type)TIM6_IRQn); + hal_clk_gate_disable(MOD_TIMER6); + break; + + default: + return PPlus_ERR_INVALID_PARAM; + } + + return PPlus_SUCCESS; +} + +int hal_timer_init(ap_tm_hdl_t callback) +{ + s_ap_callback = callback; + hal_timer_stop(AP_TIMER_ID_5); + hal_timer_stop(AP_TIMER_ID_6); + return hal_pwrmgr_register(MOD_TIMER, hal_timer_sleep_handler, hal_timer_wakeup_handler); +} + +int hal_timer_deinit(void) +{ + s_ap_callback = NULL; + return hal_pwrmgr_unregister(MOD_TIMER); +} + +static int systic_timerisr(int irq, uint32_t *regs, FAR void *arg) +{ + /* Process timer interrupt */ + + nxsched_process_timer(); + return 0; +} +void up_timer_initialize(void) +{ + + irq_attach(PHY62XX_IRQ_SYSTICK, (xcpt_t)systic_timerisr, NULL); + + putreg32((sysclk_get_clk()/100-1), ARMV6M_SYSTICK_RVR);//10ms tick + putreg32((SYSTICK_CSR_TICKINT | SYSTICK_CSR_ENABLE | SYSTICK_CSR_CLKSOURCE), ARMV6M_SYSTICK_CSR); + + /* And enable the timer interrupt */ + + up_enable_irq(PHY62XX_IRQ_SYSTICK); + + + + //set_timer(AP_TIM3, 2000); + NVIC_EnableIRQ((IRQn_Type)TIM3_IRQn); // +} + diff --git a/arch/arm/src/phy62xx/timer.h b/arch/arm/src/phy62xx/timer.h new file mode 100644 index 00000000000..f7582d714b4 --- /dev/null +++ b/arch/arm/src/phy62xx/timer.h @@ -0,0 +1,88 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ +#ifndef __TIMER_H__ +#define __TIMER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "types.h" +#include "bus_dev.h" + +#define FREE_TIMER_NUMBER 2 + +typedef enum +{ + AP_TIMER_ID_5 = 5, + AP_TIMER_ID_6 = 6, + +} User_Timer_e; + +enum +{ + HAL_EVT_TIMER_5 = AP_TIMER_ID_5, + HAL_EVT_TIMER_6 = AP_TIMER_ID_6, + HAL_EVT_WAKEUP = 0x10, + HAL_EVT_SLEEP +}; + +typedef void(*ap_tm_hdl_t)(uint8_t evt); + +int hal_timer_init(ap_tm_hdl_t callback); + +int hal_timer_deinit(void); + +int hal_timer_set(User_Timer_e timeId, uint32_t us); + +int hal_timer_mask_int(User_Timer_e timeId, bool en); + +int hal_timer_stop(User_Timer_e timeId); + +void __attribute__((used)) hal_TIMER5_IRQHandler(void); +void __attribute__((used)) hal_TIMER6_IRQHandler(void); + +extern void set_timer(AP_TIM_TypeDef* TIMx, int time); + +extern uint32_t read_current_fine_time(void); + +extern uint32 read_LL_remainder_time(void); + +#ifndef BASE_TIME_UINTS +#define BASE_TIME_UNITS (0x3fffff) +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/arch/arm/src/phy62xx/types.h b/arch/arm/src/phy62xx/types.h new file mode 100644 index 00000000000..86fe0d303c0 --- /dev/null +++ b/arch/arm/src/phy62xx/types.h @@ -0,0 +1,184 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +#ifndef _TYPES_H_ +#define _TYPES_H_ + +#include +#include +typedef signed char int8; //!< Signed 8 bit integer +typedef unsigned char uint8; //!< Unsigned 8 bit integer + +typedef signed short int16; //!< Signed 16 bit integer +typedef unsigned short uint16; //!< Unsigned 16 bit integer + +typedef signed long int32; //!< Signed 32 bit integer +typedef unsigned long uint32; //!< Unsigned 32 bit integer + +typedef uint8 halDataAlign_t; //!< Used for byte alignment + +#define ALIGN4_U8 __align(4) uint8 +#define ALIGN4_U16 __align(4) uint16 +#define ALIGN4_INT8 __align(4) int8 +#define ALIGN4_INT16 __align(4) int16 + +#define BIT(n) (1ul << (n)) + +#define write_reg(addr,data) (*(volatile unsigned int *)(addr)=(unsigned int)(data)) +#define read_reg(addr) (*(volatile unsigned int *)(addr)) + +//bit operations +#define BM_SET(addr,bit) ( *(addr) |= (bit) ) //bit set +#define BM_CLR(addr,bit) ( *(addr) &= ~(bit) ) //bit clear +#define BM_IS_SET(addr,bit) ( *(addr) & (bit) ) //judge bit is set + + + +#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 + + +/* takes a byte out of a uint32 : var - uint32, ByteNum - byte to take out (0 - 3) */ +#define BREAK_UINT32( var, ByteNum ) \ + (uint8)((uint32)(((var) >>((ByteNum) * 8)) & 0x00FF)) + +#define BUILD_UINT32(Byte0, Byte1, Byte2, Byte3) \ + ((uint32)((uint32)((Byte0) & 0x00FF) \ + + ((uint32)((Byte1) & 0x00FF) << 8) \ + + ((uint32)((Byte2) & 0x00FF) << 16) \ + + ((uint32)((Byte3) & 0x00FF) << 24))) + +#define BUILD_UINT16(loByte, hiByte) \ + ((uint16)(((loByte) & 0x00FF) + (((hiByte) & 0x00FF) << 8))) + +#define HI_UINT16(a) (((a) >> 8) & 0xFF) +#define LO_UINT16(a) ((a) & 0xFF) + +#define BUILD_UINT8(hiByte, loByte) \ + ((uint8)(((loByte) & 0x0F) + (((hiByte) & 0x0F) << 4))) + + +// Write the 32bit value of 'val' in little endian format to the buffer pointed +// to by pBuf, and increment pBuf by 4 +#define UINT32_TO_BUF_LITTLE_ENDIAN(pBuf,val) \ + do { \ + *(pBuf)++ = (((val) >> 0) & 0xFF); \ + *(pBuf)++ = (((val) >> 8) & 0xFF); \ + *(pBuf)++ = (((val) >> 16) & 0xFF); \ + *(pBuf)++ = (((val) >> 24) & 0xFF); \ + } while (0) + +// Return the 32bit little-endian formatted value pointed to by pBuf, and increment pBuf by 4 +#define BUF_TO_UINT32_LITTLE_ENDIAN(pBuf) (((pBuf) += 4), BUILD_UINT32((pBuf)[-4], (pBuf)[-3], (pBuf)[-2], (pBuf)[-1])) + +#ifndef GET_BIT + #define GET_BIT(DISCS, IDX) (((DISCS)[((IDX) / 8)] & BV((IDX) % 8)) ? TRUE : FALSE) +#endif +#ifndef SET_BIT + #define SET_BIT(DISCS, IDX) (((DISCS)[((IDX) / 8)] |= BV((IDX) % 8))) +#endif +#ifndef CLR_BIT + #define CLR_BIT(DISCS, IDX) (((DISCS)[((IDX) / 8)] &= (BV((IDX) % 8) ^ 0xFF))) +#endif + + +/* ------------------------------------------------------------------------------------------------ + Standard Defines + ------------------------------------------------------------------------------------------------ +*/ +#ifndef TRUE + #define TRUE 1 +#endif + +#ifndef FALSE + #define FALSE 0 +#endif + +#ifndef NULL + #define NULL 0 +#endif + +#define HAL_WAIT_CONDITION(condition) {while(!(condition)){}} + + +#define HAL_WAIT_CONDITION_TIMEOUT(condition, timeout) {\ + volatile int val = 0;\ + while(!(condition)){\ + if(val ++ > timeout)\ + return PPlus_ERR_TIMEOUT;\ + }\ + } + +#define HAL_WAIT_CONDITION_TIMEOUT_WO_RETURN(condition, timeout) {\ + volatile int val = 0;\ + while(!(condition)){\ + if(val ++ > timeout)\ + break;\ + }\ + } + + +typedef struct _comm_evt_t +{ + unsigned int type; + unsigned char* data; + unsigned int len; +} comm_evt_t; + +typedef void (*comm_cb_t)(comm_evt_t* pev); + +#define __RAMRUN //__attribute__((section(".ramscttext"))) + + +#define __ATTR_SECTION_SRAM__ // __attribute__((section("_section_sram_code_"))) +#define __ATTR_SECTION_XIP__ //__attribute__((section("_section_xip_code_"))) + + +#endif + diff --git a/arch/arm/src/phy62xx/uart.c b/arch/arm/src/phy62xx/uart.c new file mode 100644 index 00000000000..718590d0a0a --- /dev/null +++ b/arch/arm/src/phy62xx/uart.c @@ -0,0 +1,1145 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/******************************************************************************* + @file uart.c + @brief Contains all functions support for uart driver + @version 0.0 + @date 19. Oct. 2017 + @author qing.han + + +*******************************************************************************/ +#include "rom_sym_def.h" +#include +#include "bus_dev.h" +#include "mcu.h" +#include "gpio.h" +#include "clock.h" +#include "uart.h" +#include "pwrmgr.h" +#include "error.h" +#include "jump_function.h" + +#include +#include +#include +#include + +#define UART_TX_BUFFER_SIZE 256 + +typedef struct _uart_Context +{ + bool enable; + bool rx_available; /* rx byte available */ + + UART_INDEX_e ID; + AP_UART_TypeDef* reg; + + uint8_t irq; + + uint8_t tx_state; + uart_Tx_Buf_t tx_buf; + uart_Cfg_t cfg; +} uart_Ctx_t; + +static uart_Ctx_t m_uartCtx[2] = +{ + { + .ID = UART0, + .reg = (AP_UART_TypeDef*) AP_UART0_BASE, + .irq = PHY62XX_IRQ_UART0_IRQn, + .enable = FALSE, + }, + { + .ID = UART1, + .reg = (AP_UART_TypeDef*) AP_UART1_BASE, + .irq = PHY62XX_IRQ_UART1_IRQn, + .enable = FALSE, + }, +}; + +static int txmit_buf_use_tx_buf(UART_INDEX_e uart_index,uint8_t* buf,uint16_t len) +{ + uart_Tx_Buf_t* p_txbuf = &(m_uartCtx[uart_index].tx_buf); + uint8_t* p_data; + AP_UART_TypeDef* cur_uart = (AP_UART_TypeDef*) AP_UART0_BASE; + + if(len == 0 || buf == NULL) + return PPlus_ERR_INVALID_PARAM; + + if(p_txbuf->tx_state == TX_STATE_UNINIT) + return PPlus_ERR_NO_MEM; + + if(p_txbuf->tx_buf_size < len) + return PPlus_ERR_NO_MEM; + + if(p_txbuf->tx_state != TX_STATE_IDLE) + { + if(p_txbuf->tx_data_size + len > p_txbuf->tx_buf_size) + return PPlus_ERR_NO_MEM; + + _HAL_CS_ALLOC_(); + HAL_ENTER_CRITICAL_SECTION(); + memcpy(p_txbuf->tx_buf + p_txbuf->tx_data_size, buf, len); + p_txbuf->tx_data_size += len; + HAL_EXIT_CRITICAL_SECTION(); + return PPlus_SUCCESS; + } + + memcpy(p_txbuf->tx_buf, buf, len); + p_txbuf->tx_data_size = len; + p_txbuf->tx_data_offset = 0; + p_txbuf->tx_state = TX_STATE_TX; + p_data = p_txbuf->tx_buf; +// len = p_txbuf->tx_data_size; + len = len > UART_TX_FIFO_SIZE ? UART_TX_FIFO_SIZE : len; + + if(uart_index == UART1) + cur_uart = (AP_UART_TypeDef*) AP_UART1_BASE; + + cur_uart->IER &= ~(IER_ETBEI); + + while(len--) + { + cur_uart->THR = p_data[p_txbuf->tx_data_offset++]; + } + + if(uart_index == UART0) + hal_pwrmgr_lock(MOD_UART0); + else + hal_pwrmgr_lock(MOD_UART1); + + cur_uart->IER |= IER_ETBEI; + return PPlus_SUCCESS; +} + +static int txmit_buf_polling(UART_INDEX_e uart_index,uint8_t* buf,uint16_t len) +{ + //volatile int timeout = 0; + AP_UART_TypeDef* cur_uart = (AP_UART_TypeDef*) AP_UART0_BASE; + + if(uart_index == UART1) + cur_uart = (AP_UART_TypeDef*) AP_UART1_BASE; + + HAL_WAIT_CONDITION_TIMEOUT(!(cur_uart->USR & USR_BUSY), 100000); + + while(len--) + { + HAL_WAIT_CONDITION_TIMEOUT((cur_uart->LSR & LSR_THRE), 100000); + cur_uart->THR = *buf++; + //timeout=0; + } + + //wait shift register empty + HAL_WAIT_CONDITION_TIMEOUT((cur_uart->LSR & LSR_TEMT), 100000); + return PPlus_SUCCESS;; +} + +static void irq_rx_handler(UART_INDEX_e uart_index,uint8_t flg) +{ + int i; + uint8_t data[UART_RX_FIFO_SIZE]; + uint8_t len; + AP_UART_TypeDef* cur_uart = (AP_UART_TypeDef*)AP_UART0_BASE; + + if(uart_index == UART1) + { + cur_uart = (AP_UART_TypeDef*) AP_UART1_BASE; + } + + if(m_uartCtx[uart_index].cfg.use_fifo) + { + len = cur_uart->RFL; + + for(i = 0; i< len; i++) + data[i] = (uint8_t)(cur_uart->RBR & 0xff); + } + else + { + len = 1; + cur_uart->LSR; //clear interrupt + data[0] = (uint8_t)(cur_uart->RBR & 0xff); + } + + if(m_uartCtx[uart_index].cfg.evt_handler) + { + uart_Evt_t evt; + evt.type = flg; + evt.data = data; + evt.len = len; + m_uartCtx[uart_index].cfg.evt_handler(&evt); + } +} + +static void irq_tx_empty_handler(UART_INDEX_e uart_index) +{ + uart_Tx_Buf_t* p_txbuf = &(m_uartCtx[uart_index].tx_buf); + uint8_t* p_data; + uint16_t len; + AP_UART_TypeDef* cur_uart = (AP_UART_TypeDef*)AP_UART0_BASE; + + if(m_uartCtx[uart_index].enable == FALSE) + return; + + if(m_uartCtx[uart_index].cfg.use_fifo == FALSE) + return; + + if(m_uartCtx[uart_index].cfg.use_tx_buf == FALSE) + return; + + if(p_txbuf->tx_state != TX_STATE_TX) + return; + + p_data = p_txbuf->tx_buf; + len = p_txbuf->tx_data_size - p_txbuf->tx_data_offset; + len = len > UART_TX_FIFO_SIZE ? UART_TX_FIFO_SIZE : len; + + if(len == 0) + { + p_txbuf->tx_state = TX_STATE_IDLE; + p_txbuf->tx_data_offset = 0; + p_txbuf->tx_data_size = 0; + + if(m_uartCtx[uart_index].cfg.evt_handler) + { + uart_Evt_t evt = + { + .type = UART_EVT_TYPE_TX_COMPLETED, + .data = NULL, + .len = 0, + }; + m_uartCtx[uart_index].cfg.evt_handler(&evt); + } + + if(UART0 == uart_index) + hal_pwrmgr_unlock(MOD_UART0); + else + hal_pwrmgr_unlock(MOD_UART1); + + return; + } + + if(uart_index == UART1) + cur_uart = (AP_UART_TypeDef*) AP_UART1_BASE; + + while(len--) + { + cur_uart->THR = p_data[p_txbuf->tx_data_offset++]; + } +} + +static int uart_hw_deinit(UART_INDEX_e uart_index) +{ + MODULE_e mod = MOD_UART0; + IRQn_Type irq_type = PHY62XX_IRQ_UART0_IRQn; + AP_UART_TypeDef* cur_uart = AP_UART0; + + if(uart_index== UART1) + { + mod = MOD_UART1; + irq_type = PHY62XX_IRQ_UART1_IRQn; + cur_uart = AP_UART1; + } + + NVIC_DisableIRQ(irq_type); + hal_gpio_fmux(m_uartCtx[uart_index].cfg.tx_pin,Bit_DISABLE); + hal_gpio_fmux(m_uartCtx[uart_index].cfg.rx_pin,Bit_DISABLE); + cur_uart->LCR=0x80; + cur_uart->DLM=0; + cur_uart->DLL=0; + cur_uart->LCR =0; + cur_uart->FCR=0; + cur_uart->IER = 0; + //hal_clk_gate_enable(mod); + hal_clk_reset(mod); + hal_clk_gate_disable(mod); + + return PPlus_SUCCESS; +} + +int hal_uart_rxint_en(UART_INDEX_e uart_index, bool en){ + AP_UART_TypeDef* cur_uart = AP_UART0; + if(uart_index== UART1){ + cur_uart = AP_UART1; + } + + if(en) + { + cur_uart->IER |= IER_ERBFI; + } + else + { + cur_uart->IER &= ~IER_ERBFI; + } + +} + +int hal_uart_txint_en(UART_INDEX_e uart_index, bool en){ + AP_UART_TypeDef* cur_uart = AP_UART0; + if(uart_index== UART1){ + cur_uart = AP_UART1; + } + + if(en) + { + cur_uart->IER |= IER_ETBEI; + } + else + { + cur_uart->IER &= ~IER_ETBEI; + } + +} + + +int uart_hw_init(UART_INDEX_e uart_index) +{ + uart_Cfg_t* pcfg; + int pclk = sysclk_get_clk(); + uint32_t dll; + AP_UART_TypeDef* cur_uart = AP_UART0; + MODULE_e mod = MOD_UART0; + IRQn_Type irq_type = PHY62XX_IRQ_UART0_IRQn; + gpio_fmux_e fmux_tx = FMUX_UART0_TX, fmux_rx = FMUX_UART0_RX; + uart_hw_deinit(uart_index); + + if(uart_index== UART1) + { + cur_uart = AP_UART1; + mod = MOD_UART1; + irq_type = PHY62XX_IRQ_UART1_IRQn; + fmux_tx = FMUX_UART1_TX; + fmux_rx = FMUX_UART1_RX; + } + + if((m_uartCtx[uart_index].cfg.tx_pin == GPIO_DUMMY) && (m_uartCtx[uart_index].cfg.rx_pin == GPIO_DUMMY)) + return PPlus_ERR_INVALID_PARAM; + + pcfg = &(m_uartCtx[uart_index].cfg); + hal_clk_gate_enable(mod); + hal_clk_reset(mod); +// if(m_uartCtx[uart_index].enable == FALSE){ +// hal_gpio_fmux(P9, Bit_DISABLE); +// hal_gpio_fmux(P10, Bit_DISABLE); +// } + hal_gpio_pull_set(pcfg->tx_pin, GPIO_PULL_UP); + hal_gpio_pull_set(pcfg->rx_pin, GPIO_PULL_UP); + hal_gpio_fmux_set(pcfg->tx_pin, fmux_tx); + hal_gpio_fmux_set(pcfg->rx_pin, fmux_rx); + cur_uart->LCR =0; + dll = ((pclk>>4)+(pcfg->baudrate>>1))/pcfg->baudrate; + cur_uart->MCR=0x0; + cur_uart->LCR=0x80; + cur_uart->DLM=(dll & 0xFF00) >> 8; + cur_uart->DLL=(dll & 0xFF); + + if(pcfg->parity) + cur_uart->LCR = 0x1b; //8bit, 1 stop even parity + else + cur_uart->LCR = 0x3; //8bit, 1 stop no parity + + if(pcfg->use_fifo)//set fifo, enable tx FIFO mode(empty trigger), rx FIFO mode(1/2 trigger) + cur_uart->FCR= FCR_TX_FIFO_RESET|FCR_RX_FIFO_RESET|FCR_FIFO_ENABLE|UART_FIFO_RX_TRIGGER|UART_FIFO_TX_TRIGGER; + else + cur_uart->FCR=0; + + //enable Received Data Available Interrupt + cur_uart->IER = IER_ERBFI; + + if(pcfg->use_fifo) + cur_uart->IER |= IER_PTIME; + + + + NVIC_SetPriority(irq_type, IRQ_PRIO_HAL); + NVIC_EnableIRQ(irq_type); + return PPlus_SUCCESS; +} +/************************************************************************************** + @fn hal_UART0_IRQHandler + + @brief This function process for uart interrupt + + input parameters + + @param None. + + output parameters + + @param None. + + @return None. + **************************************************************************************/ +void __ATTR_SECTION_SRAM__ hal_UART0_IRQHandler(void) +{ + uint8_t IRQ_ID= (AP_UART0->IIR & 0x0f); + + //if(m_uartCtx[UART0].enable == FALSE) + // return; + + switch(IRQ_ID) + { + case TIMEOUT_IRQ: + irq_rx_handler(UART0,UART_EVT_TYPE_RX_DATA_TO); + break; + + case RDA_IRQ: + irq_rx_handler(UART0,UART_EVT_TYPE_RX_DATA); + break; + + case THR_EMPTY: + irq_tx_empty_handler(UART0); + break; + + case RLS_IRQ: + break; + + case BUSY_IRQ: + (void)AP_UART0->USR; + break; + + default: + break; + } +} + +void __attribute__((used)) hal_UART1_IRQHandler(void) +{ + uint8_t IRQ_ID= (AP_UART1->IIR & 0x0f); + + //if(m_uartCtx[UART1].enable == FALSE) + // return; + + switch(IRQ_ID) + { + case TIMEOUT_IRQ: + irq_rx_handler(UART1,UART_EVT_TYPE_RX_DATA_TO); + break; + + case RDA_IRQ: + irq_rx_handler(UART1,UART_EVT_TYPE_RX_DATA); + break; + + case THR_EMPTY: + irq_tx_empty_handler(UART1); + break; + + case RLS_IRQ: + break; + + case BUSY_IRQ: + (void)AP_UART1->USR; + break; + + default: + break; + } +} + + +static void uart_wakeup_process_0(void) +{ + uart_hw_init(UART0); +} + +static void uart_wakeup_process_1(void) +{ + uart_hw_init(UART1); +} + +int hal_uart_init(uart_Cfg_t cfg,UART_INDEX_e uart_index) +{ + if(m_uartCtx[uart_index].enable) + return PPlus_ERR_BUSY; + + //if(cfg.hw_fwctrl || cfg.parity) + // return PPlus_ERR_NOT_SUPPORTED; + if(cfg.hw_fwctrl) + return PPlus_ERR_NOT_SUPPORTED; + + //memset(&(m_uartCtx[uart_index]), 0, sizeof(uart_Ctx_t)); + memcpy(&(m_uartCtx[uart_index].cfg), &cfg, sizeof(uart_Cfg_t)); + uart_hw_init(uart_index); + m_uartCtx[uart_index].enable = TRUE; + + if(uart_index == UART0) + hal_pwrmgr_register(MOD_UART0, NULL, uart_wakeup_process_0); + else + hal_pwrmgr_register(MOD_UART1, NULL, uart_wakeup_process_1); + + return PPlus_SUCCESS; +} + +int hal_uart_deinit(UART_INDEX_e uart_index) +{ + uart_hw_deinit(uart_index); + m_uartCtx[uart_index].enable = FALSE; + + if(uart_index == UART0) + hal_pwrmgr_unregister(MOD_UART0); + else + hal_pwrmgr_unregister(MOD_UART1); + + return PPlus_SUCCESS; +} + +int hal_uart_set_tx_buf(UART_INDEX_e uart_index,uint8_t* buf, uint16_t size) +{ + uart_Tx_Buf_t* p_txbuf = &(m_uartCtx[uart_index].tx_buf); + + if(m_uartCtx[uart_index].enable == FALSE) + return PPlus_ERR_INVALID_STATE; + + if(m_uartCtx[uart_index].cfg.use_tx_buf == FALSE) + return PPlus_ERR_NOT_SUPPORTED; + + if(p_txbuf->tx_state != TX_STATE_UNINIT) + return PPlus_ERR_INVALID_STATE; + + _HAL_CS_ALLOC_(); + HAL_ENTER_CRITICAL_SECTION(); + p_txbuf->tx_buf = buf; + p_txbuf->tx_buf_size = size; + p_txbuf->tx_data_offset = 0; + p_txbuf->tx_data_size= 0; + p_txbuf->tx_state = TX_STATE_IDLE; + HAL_EXIT_CRITICAL_SECTION(); + return PPlus_SUCCESS; +} + +int hal_uart_get_tx_ready(UART_INDEX_e uart_index) +{ + if(m_uartCtx[uart_index].cfg.use_tx_buf == FALSE) + return PPlus_SUCCESS; + + if(m_uartCtx[uart_index].tx_buf.tx_state == TX_STATE_IDLE) + return PPlus_SUCCESS; + + return PPlus_ERR_BUSY; +} + +int hal_uart_send_buff(UART_INDEX_e uart_index,uint8_t* buff,uint16_t len) +{ + if(m_uartCtx[uart_index].cfg.use_tx_buf) + { + return txmit_buf_use_tx_buf(uart_index,buff,len); + } + + return txmit_buf_polling(uart_index,buff,len); +} + +int hal_uart_send_byte(UART_INDEX_e uart_index,unsigned char data) +{ + AP_UART_TypeDef* cur_uart = (AP_UART_TypeDef*) AP_UART0_BASE; + + if(uart_index == UART1) + cur_uart = (AP_UART_TypeDef*) AP_UART1_BASE; + + HAL_WAIT_CONDITION_TIMEOUT((cur_uart->LSR & LSR_THRE), 10000); + cur_uart->THR=data; + HAL_WAIT_CONDITION_TIMEOUT((cur_uart->LSR & LSR_TEMT), 10000); + return PPlus_SUCCESS; +} + +static int pplus_uart_interrupt(int irq, void *context, FAR void *arg); + +static int pplus_uart_setup(struct uart_dev_s *dev) +{ + uart_Ctx_t *priv = (uart_Ctx_t *)dev->priv; + uart_Cfg_t cfg = { + .tx_pin = P9, + .rx_pin = P10, + .rts_pin = GPIO_DUMMY, + .cts_pin = GPIO_DUMMY, + .baudrate = 115200, + .use_fifo = FALSE, + .hw_fwctrl = FALSE, + .use_tx_buf = FALSE, + .parity = FALSE, + .evt_handler = NULL, + }; + hal_uart_init(cfg, priv->ID); + + /* TODO: configure UART if not selected as console */ + + return OK; +} + +/**************************************************************************** + * Name: pplus_uart_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void pplus_uart_shutdown(struct uart_dev_s *dev) +{ + uart_Ctx_t *priv = (uart_Ctx_t *)dev->priv; + + /* Disable interrupts */ + + /* Reset hardware and disable Rx and Tx */ + + hal_uart_deinit(priv->ID); +} + +/**************************************************************************** + * Name: pplus_uart_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method + * is called when the serial port is opened. Normally, this is just after + * the the setup() method is called, however, the serial console may + * operate in a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless + * the hardware supports multiple levels of interrupt enabling). + * The RX and TX interrupts are not enabled until the txint() and rxint() + * methods are called. + * + ****************************************************************************/ + +static int pplus_uart_attach(struct uart_dev_s *dev) +{ + uart_Ctx_t *priv = (uart_Ctx_t *)dev->priv; + int ret; + + /* Attach and enable the IRQ(s). The interrupts are (probably) still + * disabled in the C2 register. + */ + + ret = irq_attach(priv->irq, pplus_uart_interrupt, dev); + if (ret == OK) + { + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: pplus_uart_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. + * The exception is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void pplus_uart_detach(struct uart_dev_s *dev) +{ + uart_Ctx_t *priv = (uart_Ctx_t *)dev->priv; + + /* Disable interrupts */ + + priv->reg->IER = 0; + up_disable_irq(priv->irq); + + /* Detach from the interrupt(s) */ + + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: pplus_uart_interrupt + * + * Description: + * This is the UART status interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * appropriate uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int pplus_uart_interrupt(int irq, void *context, FAR void *arg) +{ + struct uart_dev_s *dev = (struct uart_dev_s *)arg; + uart_Ctx_t *priv = (uart_Ctx_t *)(dev->priv); + + uint8_t IRQ_ID= (priv->reg->IIR & 0x0f); + + switch(IRQ_ID) + { + case TIMEOUT_IRQ: + case RDA_IRQ: + priv->rx_available = true; + priv->reg->LSR; //clear interrupt + uart_recvchars(dev); + break; + + case THR_EMPTY: + case RLS_IRQ: + break; + + case BUSY_IRQ: + (void)priv->reg->USR; + break; + + default: + break; + } + + + + + return OK; +} + +static int pplus_uart_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#ifdef CONFIG_SERIAL_TERMIOS + struct inode *inode = filep->f_inode; + struct uart_dev_s *dev = inode->i_private; + uart_Ctx_t *priv = (uart_Ctx_t *)dev->priv; + struct uart_config_s *config = &priv->config; +#endif + int ret = OK; + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TERMIOS + case TCGETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + termiosp->c_cflag = ((config->parity != 0) ? PARENB : 0) + | ((config->parity == 1) ? PARODD : 0) + | ((config->stopbits2) ? CSTOPB : 0) | +#ifdef CONFIG_SERIAL_OFLOWCONTROL + ((config->oflow) ? CCTS_OFLOW : 0) | +#endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + ((config->iflow) ? CRTS_IFLOW : 0) | +#endif + CS8; + + cfsetispeed(termiosp, config->baud); + + break; + } + + case TCSETS: + { + struct termios *termiosp = (struct termios *)arg; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + /* Perform some sanity checks before accepting any changes */ + + if ((termiosp->c_cflag & CSIZE) != CS8) + { + ret = -EINVAL; + break; + } + +#ifndef HAVE_UART_STOPBITS + if ((termiosp->c_cflag & CSTOPB) != 0) + { + ret = -EINVAL; + break; + } +#endif + + if (termiosp->c_cflag & PARODD) + { + ret = -EINVAL; + break; + } + + /* TODO: CCTS_OFLOW and CRTS_IFLOW */ + + /* Parity */ + + if (termiosp->c_cflag & PARENB) + { + config->parity = (termiosp->c_cflag & PARODD) ? 1 : 2; + } + else + { + config->parity = 0; + } + +#ifdef HAVE_UART_STOPBITS + /* Stop bits */ + + config->stopbits2 = (termiosp->c_cflag & CSTOPB) != 0; +#endif + + /* Note that only cfgetispeed is used because we have knowledge + * that only one speed is supported. + */ + + config->baud = cfgetispeed(termiosp); + + /* Effect the changes */ + + pplus_uart_set_format(dev); + + break; + } +#endif + + default: + { + ret = -ENOTTY; + break; + } + } + + return ret; +} + +/**************************************************************************** + * Name: pplus_uart_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int pplus_uart_receive(struct uart_dev_s *dev, unsigned int *status) +{ + uart_Ctx_t *priv = (uart_Ctx_t *)dev->priv; + uint32_t data; + + /* Get input data along with receiver control information */ + + data = (uint32_t)(priv->reg->RBR & 0xff); + priv->rx_available = false; + + /* Return receiver control information */ + + if (status) + { + *status = 0x00; + } + + /* Then return the actual received data. */ + + return data; +} + +/**************************************************************************** + * Name: pplus_uart_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void pplus_uart_rxint(struct uart_dev_s *dev, bool enable) +{ + uart_Ctx_t *priv = (uart_Ctx_t *)dev->priv; + + hal_uart_rxint_en(priv->ID, enable); +} + +/**************************************************************************** + * Name: pplus_uart_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +static bool pplus_uart_rxavailable(struct uart_dev_s *dev) +{ + uart_Ctx_t *priv = (uart_Ctx_t *)dev->priv; + + /* Return true if the receive buffer/fifo is not "empty." */ + + return priv->rx_available; +} + +/**************************************************************************** + * Name: pplus_uart_send + * + * Description: + * This method will send one byte on the UART. + * + ****************************************************************************/ + +static void pplus_uart_send(struct uart_dev_s *dev, int ch) +{ + uart_Ctx_t *priv = (uart_Ctx_t *)dev->priv; + + hal_uart_send_byte(priv->ID, (uint8_t)ch); +} + +/**************************************************************************** + * Name: pplus_uart_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void pplus_uart_txint(struct uart_dev_s *dev, bool enable) +{ + /* uart_Ctx_t *priv = (uart_Ctx_t *)dev->priv; */ + if(enable){ + irqstate_t flags = enter_critical_section(); + uart_xmitchars(dev); + leave_critical_section(flags); + + + } + +} + +/**************************************************************************** + * Name: pplus_uart_txready + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +static bool pplus_uart_txready(struct uart_dev_s *dev) +{ + /* uart_Ctx_t *priv = (uart_Ctx_t *)dev->priv; */ + + /* Return true if the transmit FIFO is "not full." */ + + return true; +} + +/**************************************************************************** + * Name: pplus_uart_txempty + * + * Description: + * Return true if the transmit data register is empty + * + ****************************************************************************/ + +static bool pplus_uart_txempty(struct uart_dev_s *dev) +{ + /* uart_Ctx_t *priv = (uart_Ctx_t *)dev->priv; */ + + /* Return true if the transmit FIFO is "empty." */ + + return true; +} +#define CONFIG_UART0_RXBUFSIZE 256 +#define CONFIG_UART0_TXBUFSIZE 256 + +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; + +static const struct uart_ops_s g_pplus_uart_ops = +{ + .setup = pplus_uart_setup, + .shutdown = pplus_uart_shutdown, + .attach = pplus_uart_attach, + .detach = pplus_uart_detach, + .ioctl = pplus_uart_ioctl, + .receive = pplus_uart_receive, + .rxint = pplus_uart_rxint, + .rxavailable = pplus_uart_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = pplus_uart_send, + .txint = pplus_uart_txint, + .txready = pplus_uart_txready, + .txempty = pplus_uart_txempty, +}; + +static uart_dev_t g_uart0port = +{ + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_pplus_uart_ops, + .priv = &m_uartCtx[0], +}; + +void arm_earlyserialinit(void) +{ +} + +/**************************************************************************** + * Name: stm32serial_getregit + * + * Description: + * Register serial console and serial ports. This assumes + * that arm_earlyserialinit was called previously. + * + ****************************************************************************/ +# define CONSOLE_DEV g_uart0port /* UART0 is console */ +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ + +void arm_serialinit(void) +{ +//#ifdef HAVE_UART_CONSOLE + /* Register the serial console */ + + uart_register("/dev/console", &CONSOLE_DEV); +//#endif + + uart_register("/dev/ttyS0", &TTYS0_DEV); +} + + + + + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ + hal_uart_send_byte(UART0, (char)ch); + return ch; +} + + +struct h4uart_param_s{ + struct circbuf_s *pcirc_h2c; + sem_t *psem_h2c ; + struct circbuf_s *pcirc_c2h; + sem_t *psem_c2h ; +}; + + +void h4uart_rx_irq(void* arg) +{ + AP_UART_TypeDef *preg = AP_UART1; + uint8_t buf[UART_RX_FIFO_SIZE]; + int i, len = preg->RFL; + struct h4uart_param_s* param = (struct h4uart_param_s*)arg; + if(len){ + for(i = 0; i< len; i++) + buf[i] = (uint8_t)(preg->RBR & 0xff); + circbuf_write(param->pcirc_h2c, buf, len); + sem_post(param->psem_h2c); + } +} + +void h4uart_tx_irq(void* arg) +{ + AP_UART_TypeDef *preg = AP_UART1; + uint8_t buf[UART_TX_FIFO_SIZE]; + int i, len; + struct h4uart_param_s* param = (struct h4uart_param_s*)arg; + + len = circbuf_read(param->pcirc_c2h, buf, UART_TX_FIFO_SIZE); + if(circbuf_used(param->pcirc_c2h) == 0) + hal_uart_txint_en(UART1, false); + + if(len){ + for(i = 0; i< len; i++){ + while(preg->TFL >= UART_TX_FIFO_SIZE){;} + preg->THR = buf[i]; + } + } + +} + +static int h4uart_interrupt(int irq, void *context, FAR void *arg) +{ + AP_UART_TypeDef *preg = AP_UART1; + + uint8_t IRQ_ID= preg->IIR & 0x0f; + + switch(IRQ_ID) + { + case TIMEOUT_IRQ: + case RDA_IRQ: + h4uart_rx_irq(arg); + break; + case THR_EMPTY: + h4uart_tx_irq(arg); + break; + case RLS_IRQ: + case BUSY_IRQ: + (void)preg->USR; + break; + + default: + break; + } + return OK; +} + + +h4uart_init(void* param) +{ + uart_Cfg_t pcfg1 = { + .tx_pin = P32, + .rx_pin = P31, + .rts_pin = GPIO_DUMMY, + .cts_pin = GPIO_DUMMY, + .baudrate = 115200, + .use_fifo = TRUE, + .hw_fwctrl = FALSE, + .use_tx_buf = FALSE, + .parity = FALSE, + .evt_handler = NULL, + }; + irq_attach(PHY62XX_IRQ_UART1_IRQn, h4uart_interrupt, param); + hal_uart_init(pcfg1, UART1); + hal_uart_txint_en(UART1, true); + hal_uart_rxint_en(UART1, true); + +} + + diff --git a/arch/arm/src/phy62xx/uart.h b/arch/arm/src/phy62xx/uart.h new file mode 100644 index 00000000000..1623df06793 --- /dev/null +++ b/arch/arm/src/phy62xx/uart.h @@ -0,0 +1,189 @@ +/************************************************************************************************** + + Phyplus Microelectronics Limited confidential and proprietary. + All rights reserved. + + IMPORTANT: All rights of this software belong to Phyplus Microelectronics + Limited ("Phyplus"). Your use of this Software is limited to those + specific rights granted under the terms of the business contract, the + confidential agreement, the non-disclosure agreement and any other forms + of agreements as a customer or a partner of Phyplus. You may not use this + Software unless you agree to abide by the terms of these agreements. + You acknowledge that the Software may not be modified, copied, + distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy + (BLE) integrated circuit, either as a product or is integrated into your + products. Other than for the aforementioned purposes, you may not use, + reproduce, copy, prepare derivative works of, modify, distribute, perform, + display or sell this Software and/or its documentation for any purposes. + + YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE + PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, + INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, + NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL + PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT, + NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER + LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES + INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE + OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT + OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES + (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. + +**************************************************************************************************/ + +/******************************************************************************* + @file uart.h + @brief Contains all functions support for uart driver + @version 0.0 + @date 19. Oct. 2017 + @author qing.han + + + +*******************************************************************************/ +#ifndef __UART_H__ +#define __UART_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "types.h" +#include "gpio.h" + +#define UART_TX_FIFO_SIZE 16 +#define UART_RX_FIFO_SIZE 16 + +#define TX_FIFO_MODE 1 +#define RX_FIFO_MODE 2 +#define TX_RX_FIFO_MODE 3 + +#define FIFO_MODE 0//TX_RX_FIFO_MODE //0 + +#define FCR_RX_TRIGGER_00 0x00 +#define FCR_RX_TRIGGER_01 0x40 +#define FCR_RX_TRIGGER_10 0x80 +#define FCR_RX_TRIGGER_11 0xc0 +#define FCR_TX_TRIGGER_00 0x00 +#define FCR_TX_TRIGGER_01 0x10 +#define FCR_TX_TRIGGER_10 0x20 +#define FCR_TX_TRIGGER_11 0x30 +#define FCR_TX_FIFO_RESET 0x04 +#define FCR_RX_FIFO_RESET 0x02 +#define FCR_FIFO_ENABLE 0x01 + + +#define IER_PTIME 0x80 +#define IER_EDSSI 0x08 +#define IER_ELSI 0x04 +#define IER_ETBEI 0x02 +#define IER_ERBFI 0x01 + +/*LSR 0x14*/ +#define LSR_RFE 0x80 +#define LSR_TEMT 0x40 +#define LSR_THRE 0x20 +#define LSR_BI 0x10 +#define LSR_FE 0x08 +#define LSR_PE 0x04 +#define LSR_OE 0x02 +#define LSR_DR 0x01 + +/*USR 0x7c*/ +#define USR_RFF 0x10 +#define USR_RFNE 0x08 +#define USR_TFE 0x04 +#define USR_TFNF 0x02 +#define USR_BUSY 0x01 + +#define UART_FIFO_RX_TRIGGER FCR_RX_TRIGGER_10//FCR_RX_TRIGGER_10//FCR_RX_TRIGGER_11 +#define UART_FIFO_TX_TRIGGER FCR_TX_TRIGGER_00//FCR_TX_TRIGGER_00//FCR_TX_TRIGGER_01 + +typedef enum +{ + UART0=0, //use uart 0 + UART1=1, //use uart 1 +} UART_INDEX_e; + +enum UARTIRQID +{ + NONE_IRQ = 0, + NO_IRQ_PENDING_IRQ = 1, + THR_EMPTY = 2, + RDA_IRQ = 4, + RLS_IRQ = 6, + BUSY_IRQ = 7, + TIMEOUT_IRQ = 12, +}; + +enum +{ + TX_STATE_UNINIT = 0, + TX_STATE_IDLE, + TX_STATE_TX, + TX_STATE_ERR +}; + +typedef struct _uart_Evt_t +{ + uint8_t type; + uint8_t* data; + uint8_t len; +} uart_Evt_t; + + +typedef enum +{ + UART_EVT_TYPE_RX_DATA = 1, + UART_EVT_TYPE_RX_DATA_TO, //case rx data of uart RX timeout + UART_EVT_TYPE_TX_COMPLETED, +} uart_Evt_Type_t; + +typedef void (*uart_Hdl_t)(uart_Evt_t* pev); + +typedef struct _uart_Cfg_t +{ + gpio_pin_e tx_pin; + gpio_pin_e rx_pin; + gpio_pin_e rts_pin; + gpio_pin_e cts_pin; + uint32_t baudrate; + bool use_fifo; + bool hw_fwctrl; + bool use_tx_buf; + bool parity; + uart_Hdl_t evt_handler; +} uart_Cfg_t; + +typedef struct _uart_spi_t +{ + UART_INDEX_e uart_index; +} uart_t; + + +typedef struct _uart_Tx_Buf_t +{ + uint8_t tx_state; + uint16_t tx_data_offset; + uint16_t tx_data_size; + uint16_t tx_buf_size; + uint8_t* tx_buf; +} uart_Tx_Buf_t; + +int hal_uart_txint_en(UART_INDEX_e uart_index, bool en); +int hal_uart_rxint_en(UART_INDEX_e uart_index, bool en); +int hal_uart_init(uart_Cfg_t cfg,UART_INDEX_e uart_index); +int hal_uart_deinit(UART_INDEX_e uart_index); +int hal_uart_set_tx_buf(UART_INDEX_e uart_index,uint8_t* buf, uint16_t size); +int hal_uart_get_tx_ready(UART_INDEX_e uart_index); +int hal_uart_send_buff(UART_INDEX_e uart_index,uint8_t* buff,uint16_t len); +#define logx(...) {char tmp_str[128]; sprintf(tmp_str, __VA_ARGS__); hal_uart_send_buff(0, tmp_str , strlen(tmp_str)+1);} +int hal_uart_send_byte(UART_INDEX_e uart_index,unsigned char data); +void __attribute__((weak)) hal_UART0_IRQHandler(void); +void __attribute__((weak)) hal_UART1_IRQHandler(void); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/arch/arm/src/phy62xx/version.h b/arch/arm/src/phy62xx/version.h new file mode 100644 index 00000000000..3f41dbad21a --- /dev/null +++ b/arch/arm/src/phy62xx/version.h @@ -0,0 +1,41 @@ +/**************************************************************************** + * arch/arm/src/phy62xx/version.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Prototypes + ****************************************************************************/ + +#ifndef __SDK_VER_H__ +#define __SDK_VER_H__ + +#define __DEF_CHIP_QFN32__ (0x0001) +#define __DEF_CHIP_TSOP16__ (0x0002) +#define SDK_VER_MAJOR 3 +#define SDK_VER_MINOR 0 +#define SDK_VER_REVISION 7 +#define SDK_VER_RELEASE_ID ((SDK_VER_MAJOR<<16)|(SDK_VER_MINOR<<8)|(SDK_VER_REVISION)) +#define SDK_VER_CHIP __DEF_CHIP_QFN32__ +/* #define SDK_VER_TEST_BUILD "" */ +#endif + diff --git a/boards/arm/phy62xx/phy6222/Kconfig b/boards/arm/phy62xx/phy6222/Kconfig new file mode 100644 index 00000000000..206eefe306a --- /dev/null +++ b/boards/arm/phy62xx/phy6222/Kconfig @@ -0,0 +1,8 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_BOARD_PHY6222 + +endif diff --git a/boards/arm/phy62xx/phy6222/README.txt b/boards/arm/phy62xx/phy6222/README.txt new file mode 100644 index 00000000000..243dee33768 --- /dev/null +++ b/boards/arm/phy62xx/phy6222/README.txt @@ -0,0 +1,17 @@ +STATUS +====== + +05/17: The basic NSH configuration is functional and shows that there is + 3-4KB of free heap space. However, attempts to extend this have + failed. I suspect that 8KB of SRAM is insufficient to do much + with the existing NSH configuration. Perhaps some fine tuning + can improve this situation but at this point, I think this board + is only useful for the initial STM32 F0 bring-up, perhaps for + embedded solutions that do not use NSH and for general + experimentation. + + There is also support for the Nucleo boards with the STM32 F072 + and F092 MCUs. Those ports do not suffer from these problems and + seem to work well in fairly complex configurations. Apparently 8KB + is SRAM is not usable but the parts with larger 16KB and 32KB SRAMs + are better matches. diff --git a/boards/arm/phy62xx/phy6222/configs/ble/defconfig b/boards/arm/phy62xx/phy6222/configs/ble/defconfig new file mode 100644 index 00000000000..dd7eb065110 --- /dev/null +++ b/boards/arm/phy62xx/phy6222/configs/ble/defconfig @@ -0,0 +1,55 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DISABLE_ENVIRON is not set +# CONFIG_DISABLE_POSIX_TIMERS is not set +# CONFIG_NSH_DISABLEBG is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXIT is not set +# CONFIG_NSH_DISABLE_HEXDUMP is not set +# CONFIG_NSH_DISABLE_PS is not set +# CONFIG_NSH_DISABLE_XD is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="phy6222" +CONFIG_ARCH_BOARD_PHY6222=y +CONFIG_ARCH_CHIP="phy62xx" +CONFIG_ARCH_CHIP_PHY6222=y +CONFIG_ARCH_CHIP_PHY62XX=y +CONFIG_ARCH_INTERRUPTSTACK=1536 +CONFIG_BOARD_LATE_INITIALIZE=y +CONFIG_BTSAK=y +CONFIG_DEBUG_ASSERTIONS=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEFAULT_SMALL=y +CONFIG_DISABLE_MOUNTPOINT=y +CONFIG_DRIVERS_BLUETOOTH=y +CONFIG_DRIVERS_WIRELESS=y +CONFIG_IOB_NBUFFERS=8 +CONFIG_IOB_NCHAINS=0 +CONFIG_MAX_TASKS=8 +CONFIG_MM_SMALL=y +CONFIG_NAME_MAX=48 +CONFIG_NET=y +CONFIG_NET_BLUETOOTH=y +CONFIG_NET_SOCKOPTS=y +CONFIG_NET_TCP=y +CONFIG_NSH_ARCHINIT=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_PTHREAD_MUTEX_TYPES=y +CONFIG_RAM_SIZE=59392 +CONFIG_RAM_START=0x1fff1c00 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_SIG_DEFAULT=y +CONFIG_SPINLOCK=y +CONFIG_SYSTEM_NSH=y +CONFIG_USER_ENTRYPOINT="nsh_main" +CONFIG_WIRELESS=y +CONFIG_WIRELESS_BLUETOOTH=y diff --git a/boards/arm/phy62xx/phy6222/configs/h4/defconfig b/boards/arm/phy62xx/phy6222/configs/h4/defconfig new file mode 100644 index 00000000000..ab7c799c9ea --- /dev/null +++ b/boards/arm/phy62xx/phy6222/configs/h4/defconfig @@ -0,0 +1,86 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DISABLE_ENVIRON is not set +# CONFIG_DISABLE_POSIX_TIMERS is not set +# CONFIG_NSH_DISABLEBG is not set +# CONFIG_NSH_DISABLESCRIPT is not set +# CONFIG_NSH_DISABLE_BASENAME is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXIT is not set +# CONFIG_NSH_DISABLE_HEXDUMP is not set +# CONFIG_NSH_DISABLE_SEMICOLON is not set +# CONFIG_NSH_DISABLE_XD is not set +# CONFIG_SIG_SIGPIPE_ACTION is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="phy6222" +CONFIG_ARCH_BOARD_PHY6222=y +CONFIG_ARCH_CHIP="phy62xx" +CONFIG_ARCH_CHIP_PHY6222=y +CONFIG_ARCH_CHIP_PHY62XX=y +CONFIG_ARCH_INTERRUPTSTACK=1536 +CONFIG_BOARD_LATE_INITIALIZE=y +CONFIG_BUILTIN=y +CONFIG_DEBUG_ASSERTIONS=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEFAULT_SMALL=y +CONFIG_DEV_GPIO=y +CONFIG_DEV_ZERO=y +CONFIG_DISABLE_MQUEUE=y +CONFIG_DRIVERS_BLUETOOTH=y +CONFIG_DRIVERS_WIRELESS=y +CONFIG_EOL_IS_BOTH_CRLF=y +CONFIG_EXAMPLES_GPIO=y +CONFIG_EXAMPLES_TIMER=y +CONFIG_EXAMPLES_UART_H4=y +CONFIG_EXAMPLES_UART_H4_PRIORITY=101 +CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_EXCLUDE_MEMINFO=y +CONFIG_FS_ROMFS=y +CONFIG_LIBC_EXECFUNCS=y +CONFIG_LIBM=y +CONFIG_MM_IOB=y +CONFIG_MM_SMALL=y +CONFIG_NAME_MAX=48 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_ARCHROMFS=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFCONFIG=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_FILE_APPS=y +CONFIG_NSH_QUOTE=y +CONFIG_NSH_ROMFSETC=y +CONFIG_PHY6222_BLE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_PTHREAD_MUTEX_TYPES=y +CONFIG_RAM_SIZE=58368 +CONFIG_RAM_START=0x1fff1c00 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKSTACKSIZE=1024 +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_LPWORKSTACKSIZE=1024 +CONFIG_SCHED_WAITPID=y +CONFIG_SIG_DEFAULT=y +CONFIG_SPINLOCK=y +CONFIG_SYSTEM_NSH=y +CONFIG_TINYCRYPT=y +CONFIG_TINYCRYPT_AES=y +CONFIG_TINYCRYPT_AES_CCM=y +CONFIG_TINYCRYPT_AES_CMAC=y +CONFIG_TINYCRYPT_ECC_DH=y +CONFIG_TINYCRYPT_SHA256=y +CONFIG_TINYCRYPT_SHA256_HMAC=y +CONFIG_TINYCRYPT_SHA256_HMAC_PRNG=y +CONFIG_UART_BTH4=y +CONFIG_USER_ENTRYPOINT="nsh_main" +CONFIG_WIRELESS=y +CONFIG_PHYPLUS_STUB=y +CONFIG_PHYPLUS_DOWNLOAD=y diff --git a/boards/arm/phy62xx/phy6222/configs/nsh/defconfig b/boards/arm/phy62xx/phy6222/configs/nsh/defconfig new file mode 100644 index 00000000000..049e7f73ebb --- /dev/null +++ b/boards/arm/phy62xx/phy6222/configs/nsh/defconfig @@ -0,0 +1,51 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DISABLE_ENVIRON is not set +# CONFIG_NSH_DISABLEBG is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXIT is not set +# CONFIG_NSH_DISABLE_HEXDUMP is not set +# CONFIG_NSH_DISABLE_PS is not set +# CONFIG_NSH_DISABLE_XD is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="phy6222" +CONFIG_ARCH_BOARD_PHY6222=y +CONFIG_ARCH_CHIP="phy62xx" +CONFIG_ARCH_CHIP_PHY6222=y +CONFIG_ARCH_CHIP_PHY62XX=y +CONFIG_BOARD_LATE_INITIALIZE=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEFAULT_SMALL=y +CONFIG_DISABLE_MQUEUE=y +CONFIG_FS_LITTLEFS=y +CONFIG_MM_SMALL=y +CONFIG_MTD=y +CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6 +CONFIG_NSH_DISABLE_MOUNT=y +CONFIG_NSH_DISABLE_UMOUNT=y +CONFIG_NSH_FILEIOSIZE=64 +CONFIG_NUNGET_CHARS=0 +CONFIG_PREALLOC_TIMERS=0 +CONFIG_PTHREAD_STACK_DEFAULT=1536 +CONFIG_RAM_SIZE=59392 +CONFIG_RAM_START=0x1fff1c00 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_SDCLONE_DISABLE=y +CONFIG_START_DAY=19 +CONFIG_START_MONTH=5 +CONFIG_START_YEAR=2013 +CONFIG_STDIO_DISABLE_BUFFERING=y +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=0 +CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=1536 +CONFIG_TLS_NELEM=0 +CONFIG_USERMAIN_STACKSIZE=1536 +CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/boards/arm/phy62xx/phy6222/configs/zblue/defconfig b/boards/arm/phy62xx/phy6222/configs/zblue/defconfig new file mode 100644 index 00000000000..a36a9eac76b --- /dev/null +++ b/boards/arm/phy62xx/phy6222/configs/zblue/defconfig @@ -0,0 +1,95 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_BT_HCI_ACL_FLOW_CONTROL is not set +# CONFIG_DISABLE_ENVIRON is not set +# CONFIG_DISABLE_POSIX_TIMERS is not set +# CONFIG_NSH_DISABLEBG is not set +# CONFIG_NSH_DISABLE_BASENAME is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXIT is not set +# CONFIG_NSH_DISABLE_HEXDUMP is not set +# CONFIG_NSH_DISABLE_SEMICOLON is not set +# CONFIG_NSH_DISABLE_XD is not set +# CONFIG_SIG_SIGPIPE_ACTION is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="phy6222" +CONFIG_ARCH_BOARD_PHY6222=y +CONFIG_ARCH_CHIP="phy62xx" +CONFIG_ARCH_CHIP_PHY6222=y +CONFIG_ARCH_CHIP_PHY62XX=y +CONFIG_ARCH_INTERRUPTSTACK=1536 +CONFIG_BOARD_LATE_INITIALIZE=y +CONFIG_BT=y +CONFIG_BT_BAS=y +CONFIG_BT_CENTRAL=y +CONFIG_BT_DIS=y +CONFIG_BT_H4=y +CONFIG_BT_HCI_ECC_STACK_SIZE=1280 +CONFIG_BT_HCI_MESH_EXT=y +CONFIG_BT_HCI_RAW_H4=y +CONFIG_BT_HCI_RAW_H4_ENABLE=y +CONFIG_BT_HCI_TX_STACK_SIZE=3072 +CONFIG_BT_HCI_TX_STACK_SIZE_WITH_PROMPT=y +CONFIG_BT_HOST_CCM=y +CONFIG_BT_HRS=y +CONFIG_BT_L2CAP_TX_BUF_COUNT=3 +CONFIG_BT_L2CAP_TX_FRAG_COUNT=2 +CONFIG_BT_MAX_PAIRED=0 +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_REMOTE_VERSION=y +CONFIG_BT_RX_BUF_COUNT=10 +CONFIG_BT_RX_STACK_SIZE=3072 +CONFIG_BT_SAMPLE=y +CONFIG_BT_SAMPLE_PERIPHERAL=y +CONFIG_BT_SMP=y +CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY=y +CONFIG_BT_UART_ON_DEV_NAME="/dev/ttyBLE" +CONFIG_BUILTIN=y +CONFIG_DEBUG_ASSERTIONS=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEFAULT_SMALL=y +CONFIG_DISABLE_MQUEUE=y +CONFIG_DRIVERS_BLUETOOTH=y +CONFIG_DRIVERS_WIRELESS=y +CONFIG_EOL_IS_BOTH_CRLF=y +CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_EXCLUDE_MEMINFO=y +CONFIG_LIBC_EXECFUNCS=y +CONFIG_LIBM=y +CONFIG_MM_IOB=y +CONFIG_MM_SMALL=y +CONFIG_NAME_MAX=48 +CONFIG_NET_BUF_RX_COUNT=8 +CONFIG_NET_BUF_TX_COUNT=8 +CONFIG_NET_L2_BT=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFCONFIG=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_FILE_APPS=y +CONFIG_NSH_QUOTE=y +CONFIG_PHY6222_BLE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_PTHREAD_MUTEX_TYPES=y +CONFIG_RAM_SIZE=58368 +CONFIG_RAM_START=0x1fff1c00 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_SIG_DEFAULT=y +CONFIG_SPINLOCK=y +CONFIG_SYSTEM_NSH=y +CONFIG_TINYCRYPT_AES_CCM=y +CONFIG_TINYCRYPT_ECC_DH=y +CONFIG_UART_BTH4=y +CONFIG_USER_ENTRYPOINT="nsh_main" +CONFIG_WIRELESS=y diff --git a/boards/arm/phy62xx/phy6222/include/board.h b/boards/arm/phy62xx/phy6222/include/board.h new file mode 100644 index 00000000000..bc11a30c5a7 --- /dev/null +++ b/boards/arm/phy62xx/phy6222/include/board.h @@ -0,0 +1,38 @@ +/**************************************************************************** + * boards/arm/phy62xx/phy6222/include/board.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_ARM_PHY62xx_PHY6222_INCLUDE_BOARD_H +#define __BOARDS_ARM_PHY62xx_PHY6222_INCLUDE_BOARD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + + +#define HCLK_FREQUENCY 32000000ul /* HSI48 for USB, only some STM32F0xx */ + + +#endif /* phy62xx */ diff --git a/boards/arm/phy62xx/phy6222/include/nsh_romfsimg.h b/boards/arm/phy62xx/phy6222/include/nsh_romfsimg.h new file mode 100644 index 00000000000..44f31a0bcbc --- /dev/null +++ b/boards/arm/phy62xx/phy6222/include/nsh_romfsimg.h @@ -0,0 +1,89 @@ +unsigned char romfs_img[] = { + 0x2d, 0x72, 0x6f, 0x6d, 0x31, 0x66, 0x73, 0x2d, 0x00, 0x00, 0x00, 0xf0, + 0x4f, 0x15, 0x26, 0x7d, 0x76, 0x6f, 0x6c, 0x5f, 0x69, 0x6e, 0x69, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xff, 0xff, 0x97, + 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0xd1, 0xd1, 0xff, 0x80, 0x2e, 0x2e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x2d, 0x96, 0x03, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x64, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, + 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xff, 0xff, 0x00, + 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0xd1, 0xd1, 0xff, 0x20, 0x2e, 0x2e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, + 0x8d, 0x9c, 0xac, 0xf9, 0x72, 0x63, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x34, 0x20, 0x26, + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; +unsigned int romfs_img_len = 1024; diff --git a/boards/arm/phy62xx/phy6222/scripts/Make.defs b/boards/arm/phy62xx/phy6222/scripts/Make.defs new file mode 100644 index 00000000000..948157db327 --- /dev/null +++ b/boards/arm/phy62xx/phy6222/scripts/Make.defs @@ -0,0 +1,65 @@ +############################################################################ +# boards/arm/stm32f0l0g0/stm32f051-discovery/scripts/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(TOPDIR)/.config +include $(TOPDIR)/tools/Config.mk +include $(TOPDIR)/arch/arm/src/armv6-m/Toolchain.defs + +LDSCRIPT = flash.ld + +ifeq ($(CONFIG_CYGWIN_WINTOOL),y) + ARCHSCRIPT = -T "${shell cygpath -w $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)}" +else + ARCHSCRIPT = -T$(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT) +endif + +ifeq ($(CONFIG_DEBUG_SYMBOLS),y) + ARCHOPTIMIZATION = -g +endif + +ifneq ($(CONFIG_DEBUG_NOOPT),y) + ARCHOPTIMIZATION += $(MAXOPTIMIZATION) -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer +endif + +ARCHCFLAGS = -fno-builtin +ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new -fno-rtti +ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef +ARCHWARNINGSXX = -Wall -Wshadow -Wundef +ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10 + +CFLAGS := $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS) +CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS) +CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +AFLAGS := $(CFLAGS) -D__ASSEMBLY__ + +NXFLATLDFLAGS1 = -r -Wl,-d -Wl,-warn-common +NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -Wl,-no-check-sections +LDNXFLATFLAGS = -e main -s 2048 + +ifneq ($(CROSSDEV),arm-nuttx-elf-) + LDFLAGS += -nostartfiles -nodefaultlibs +endif +ifeq ($(CONFIG_DEBUG_SYMBOLS),y) + LDFLAGS += -g +endif + + diff --git a/boards/arm/phy62xx/phy6222/scripts/flash.ld b/boards/arm/phy62xx/phy6222/scripts/flash.ld new file mode 100644 index 00000000000..f281102b525 --- /dev/null +++ b/boards/arm/phy62xx/phy6222/scripts/flash.ld @@ -0,0 +1,185 @@ + + +MEMORY +{ + jumptbl (rwx) : ORIGIN = 0x1fff0000, LENGTH = 1K + gcfgtbl (rwx) : ORIGIN = 0x1fff0400, LENGTH = 1K + flash (rx) : ORIGIN = 0x1100e000, LENGTH = 256K + sram (rwx) : ORIGIN = 0x1fff1c00, LENGTH = 58K +} + +OUTPUT_ARCH(arm) +EXTERN(_vectors) +ENTRY(_stext) + +SECTIONS +{ + + .textentry : { + _stext = ABSOLUTE(.); + *(.vectors) + *phy62xx_start.o(.text) + } > flash + + .init_section : { + _sinit = ABSOLUTE(.); + *(.init_array .init_array.*) + _einit = ABSOLUTE(.); + } > flash + + .ARM.extab : { + *(.ARM.extab*) + } > flash + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > flash + __exidx_end = ABSOLUTE(.); + + + ._sjtblsstore : { + _sjtblss = ABSOLUTE(.); + } > flash + + .jumptbls : { + _sjtbls = ABSOLUTE(.); + *jump_table*(.jumptbls) + _ejtbls = ABSOLUTE(.); + } > jumptbl AT >flash + + .gcfgtbls : { + _sgtbls = ABSOLUTE(.); + *jump_table*(.gcfgtbls) + _egtbls = ABSOLUTE(.); + } > gcfgtbl + + + ._eronlystore : { + _eronly = ABSOLUTE(.); + } > flash + + .data : { + _sdata = ABSOLUTE(.); + _stextram = ABSOLUTE(.); + *flash.o(.text .text.*) + *libarch.a:phy62xx_exception.o(.text .text.*) + *libarch.a:irq.o(.text.arm_ack_irq) + *phy62xx_ble_patch.o(.text .text.*) + //*libarch.a:phy62xx_ble_patch.o(.text.ll_hw_go1) + //*libarch.a:phy62xx_ble_patch.o(.text.TIM1_IRQHandler1) + //*libarch.a:phy62xx_ble_patch.o(.text.LL_IRQHandler1) + //*libarch.a:phy62xx_ble_patch.o(.text.rf_phy_change_cfg0) + //*libarch.a:phy62xx_ble_patch.o(.text.rf_calibrate1) + //*libarch.a:phy62xx_ble_patch.o(.text.l2capPocessFragmentTxData) + //*libarch.a:phy62xx_ble_patch.o(.text.LL_SetDataLengh1) + //*libarch.a:phy62xx_ble_patch.o(.text.llProcessTxData1) + //*libarch.a:phy62xx_ble_patch.o(.text.ll_generateTxBuffer1) + //*libarch.a:phy62xx_ble_patch.o(.text.ll_adptive_adj_next_time1) + //*libarch.a:phy62xx_ble_patch.o(.text.llSecAdvAllow1) + //*libarch.a:phy62xx_ble_patch.o(.text.ll_scheduler1) + //*libarch.a:phy62xx_ble_patch.o(.text.osal_set_event1) + //*libarch.a:phy62xx_ble_patch.o(.text.ll_processBasicIRQ_SRX) + //*libarch.a:phy62xx_ble_patch.o(.text.ll_processBasicIRQ_secondaryAdvTRX) + //*libarch.a:phy62xx_ble_patch.o(.text.ll_processBasicIRQ_ScanTRX) + //*libarch.a:phy62xx_ble_patch.o(.text.llSlaveEvt_TaskEndOk1) + //*libarch.a:phy62xx_ble_patch.o(.text.ll_processBasicIRQ_secondaryAdvTRX0) + //*libarch.a:phy62xx_ble_patch.o(.text.ll_processBasicIRQ_ScanTRX0) + //*libarch.a:phy62xx_ble_patch.o(.text.ll_processBasicIRQ_SRX0) + //*libarch.a:phy62xx_ble_patch.o(.text.ll_hw_read_rfifo1) + + *rf_phy_driver.o(.text.rf_phy_get_pktFoot) + *rf_phy_driver.o(.text.rf_phy_change_cfg0 ) + + *libarch.a:phy62xx_ble_hcitl.o(.text.phy62xx_ble_init) + *libarch.a:phy62xx_ble_hcitl.o(.text.HCI_ProcessEvent1) + *libarch.a:up_idle.o(.text .text.*) + *libarch.a:up_idle.o(.text.up_block_task) + *libarch.a:arm_switchcontext.o(.text .text.*) + *libarch.a:arm_fullcontextrestore.o(.text .text.*) + *libarch.a:arm_fullcontextrestore.o(.text .text.*) + *libarch.a:timer.o(.text.systic_timerisr) + *libarch.a:phy62xx_ble.o(.text.pplus_ble_recv_cb_h4 .text.pplus_ble_recv_cb_acl) + *libarch.a:phy62xx_ble.o(.text.pplus_ble_recv_msg ) + *libarch.a:arm_doirq.o(.text.arm_doirq ) + *libarch.a:arm_hardfault.o(.text.arm_hardfault ) + *libarch.a:irq_dispatch.o(.text.irq_dispatch ) + + *libsched.a:clock_initialize.o(.text.clock_timer) + *libsched.a:sched_processtimer.o(.text.nxsched_process_timer) + *libsched.a:sem_wait.o(.text .text.*) + *libsched.a:sem_holder.o(.text .text.*) + *libsched.a:sched_yield.o(.text .text.*) + *libsched.a:sched_lock.o(.text .text.*) + *libsched.a:sched_unlock.o(.text .text.*) + + *libdrivers.a:uart_bth4.o(.text.uart_bth4_pollnotify) + *libdrivers.a:uart_bth4.o(.text.uart_bth4_post) + *libdrivers.a:uart_bth4.o(.text.uart_bth4_receive) + + *libarch.a:uart.o(.text .text.*) + + *libmm.a:circbuf.o(.text .text.*) + + *libc.a:lib_skipspace.o(.text .text.*) + *libc.a:lib_sprintf.o(.text .text.*) + *libc.a:lib_strlen.o(.text .text.*) + *libc.a:lib_memcmp.o(.text .text.*) + *libc.a:lib_memcpy.o(.text .text.*) + *libc.a:lib_memset.o(.text .text.*) + *libc.a:lib_memmove.o(.text .text.*) + + *libapps.a:zblue.o(.text.k_yield .text.k_sleep .text.z_tick_get) + + _etextram = ABSOLUTE(.); + + + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + . = ALIGN(4); + _edata = ABSOLUTE(.); + } > sram AT > flash + + + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + .common_text : { + *(.text .text.*) + *(.rodata .rodata.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > flash + + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} + diff --git a/boards/arm/phy62xx/phy6222/scripts/gnu-elf.ld b/boards/arm/phy62xx/phy6222/scripts/gnu-elf.ld new file mode 100644 index 00000000000..b7371d8265f --- /dev/null +++ b/boards/arm/phy62xx/phy6222/scripts/gnu-elf.ld @@ -0,0 +1,116 @@ +/**************************************************************************** + * boards/arm/stm32f0l0g0/stm32f051-discovery/scripts/gnu-elf.ld + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +SECTIONS +{ + .text 0x00000000 : + { + _stext = . ; + *(.text) + *(.text.*) + *(.gnu.warning) + *(.stub) + *(.glue_7) + *(.glue_7t) + *(.jcr) + + /* C++ support: The .init and .fini sections contain specific logic + * to manage static constructors and destructors. + */ + + *(.gnu.linkonce.t.*) + *(.init) /* Old ABI */ + *(.fini) /* Old ABI */ + _etext = . ; + } + + .rodata : + { + _srodata = . ; + *(.rodata) + *(.rodata1) + *(.rodata.*) + *(.gnu.linkonce.r*) + _erodata = . ; + } + + .data : + { + _sdata = . ; + *(.data) + *(.data1) + *(.data.*) + *(.gnu.linkonce.d*) + . = ALIGN(4); + _edata = . ; + } + + /* C++ support. For each global and static local C++ object, + * GCC creates a small subroutine to construct the object. Pointers + * to these routines (not the routines themselves) are stored as + * simple, linear arrays in the .ctors section of the object file. + * Similarly, pointers to global/static destructor routines are + * stored in .dtors. + */ + + .ctors : + { + _sctors = . ; + *(.ctors) /* Old ABI: Unallocated */ + *(.init_array) /* New ABI: Allocated */ + _edtors = . ; + } + + .dtors : + { + _sdtors = . ; + *(.dtors) /* Old ABI: Unallocated */ + *(.fini_array) /* New ABI: Allocated */ + _edtors = . ; + } + + .bss : + { + _sbss = . ; + *(.bss) + *(.bss.*) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.b*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + } + + /* Stabs debugging sections. */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/arm/phy62xx/phy6222/src/Makefile b/boards/arm/phy62xx/phy6222/src/Makefile new file mode 100644 index 00000000000..adcfce911ed --- /dev/null +++ b/boards/arm/phy62xx/phy6222/src/Makefile @@ -0,0 +1,33 @@ +############################################################################ +# boards/arm/stm32f0l0g0/stm32f051-discovery/src/Makefile +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(TOPDIR)/Make.defs +#ROMSYMTABLE = bb_rom_sym_m0.gdbsym +#LDFLAGS += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(ROMSYMTABLE) +CSRCS = boot.c bringup.c + +CSRCS += userleds.c + +CSRCS += buttons.c + + +CSRCS += appinit.c + +include $(TOPDIR)/boards/Board.mk diff --git a/boards/arm/phy62xx/phy6222/src/appinit.c b/boards/arm/phy62xx/phy6222/src/appinit.c new file mode 100644 index 00000000000..817b8fbb5ed --- /dev/null +++ b/boards/arm/phy62xx/phy6222/src/appinit.c @@ -0,0 +1,71 @@ +/**************************************************************************** + * boards/arm/stm32f0l0g0/stm32f051-discovery/src/stm32_appinit.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "phy6222.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_app_initialize + * + * Description: + * Perform application specific initialization. This function is never + * called directly from application code, but only indirectly via the + * (non-standard) boardctl() interface using the command BOARDIOC_INIT. + * + * Input Parameters: + * arg - The boardctl() argument is passed to the board_app_initialize() + * implementation without modification. The argument has no + * meaning to NuttX; the meaning of the argument is a contract + * between the board-specific initialization logic and the + * matching application logic. The value could be such things as a + * mode enumeration value, a set of DIP switch switch settings, a + * pointer to configuration data read from a file or serial FLASH, + * or whatever you would like to do with it. Every implementation + * should accept zero/NULL as a default configuration. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure to indicate the nature of the failure. + * + ****************************************************************************/ + +int board_app_initialize(uintptr_t arg) +{ + /* Did we already initialize via board_late_initialize()? */ + +#ifndef CONFIG_BOARD_LATE_INITIALIZE + return phy62xx_bringup(); +#else + return 0; +#endif +} diff --git a/boards/arm/phy62xx/phy6222/src/boot.c b/boards/arm/phy62xx/phy6222/src/boot.c new file mode 100644 index 00000000000..d85ffde904c --- /dev/null +++ b/boards/arm/phy62xx/phy6222/src/boot.c @@ -0,0 +1,79 @@ +/**************************************************************************** + * boards/arm/stm32f0l0g0/stm32f051-discovery/src/stm32_boot.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "arm_arch.h" +#include "phy6222.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_boardinitialize + * + * Description: + * All STM32 architectures must provide the following entry point. + * This entry point is called early in the initialization -- after all + * memory has been configured and mapped but before any devices have been + * initialized. + * + ****************************************************************************/ + +void phy62xx_boardinitialize(void) +{ +#ifdef CONFIG_ARCH_LEDS + /* Configure on-board LEDs if LED support has been selected. */ + + board_autoled_initialize(); +#endif +} + +/**************************************************************************** + * Name: board_late_initialize + * + * Description: + * If CONFIG_BOARD_LATE_INITIALIZE is selected, then an additional + * initialization call will be performed in the boot-up sequence to a + * function called board_late_initialize(). board_late_initialize() will be + * called immediately after up_initialize() is called and just before the + * initial application is started. This additional initialization phase + * may be used, for example, to initialize board-specific device drivers. + * + ****************************************************************************/ + +#ifdef CONFIG_BOARD_LATE_INITIALIZE +void board_late_initialize(void) +{ + /* Perform board-specific initialization here if so configured */ + + phy62xx_bringup(); +} +#endif diff --git a/boards/arm/phy62xx/phy6222/src/bringup.c b/boards/arm/phy62xx/phy6222/src/bringup.c new file mode 100644 index 00000000000..45d9337e1a6 --- /dev/null +++ b/boards/arm/phy62xx/phy6222/src/bringup.c @@ -0,0 +1,151 @@ +/**************************************************************************** + * boards/arm/stm32f0l0g0/stm32f051-discovery/src/stm32_bringup.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include + +#include + +#include + +#include "phy6222.h" +#include "pplus_mtd_flash.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_bringup + * + * Description: + * Perform architecture-specific initialization + * + * CONFIG_BOARD_LATE_INITIALIZE=y : + * Called from board_late_initialize(). + * + * CONFIG_BOARD_LATE_INITIALIZE=n && CONFIG_LIB_BOARDCTL=y : + * Called from the NSH library + * + ****************************************************************************/ +#define PPLUS_MTD_START_OFFSET 0x40000 //start from 256k offset +#define PPLUS_MTD_SIZE 0x40000 //mtd size is 256k bytes + +int phy62xx_bringup(void) +{ + int ret; + +#ifdef CONFIG_FS_PROCFS + /* Mount the procfs file system */ + + ret = nx_mount(NULL, "/proc", "procfs", 0, NULL); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to mount procfs at /proc: %d\n", ret); + return ret; + } +#endif + +#ifdef CONFIG_FS_NXFFS + + struct mtd_dev_s* mtd_temp = pplus_fls_initialize(PPLUS_MTD_START_OFFSET, PPLUS_MTD_SIZE); + if (!mtd_temp) + { + syslog(LOG_ERR, "ERROR: pplus_initialize failed\n"); + return ret; + } + + /* Initialize to provide NXFFS on the N25QXXX MTD interface */ + + ret = nxffs_initialize(mtd_temp); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: NXFFS initialization failed: %d\n", ret); + } + + /* Mount the file system at /mnt/nxffs */ + + ret = nx_mount(NULL, "/mnt/nxffs", "nxffs", 0, NULL); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to mount the NXFFS volume: %d\n", ret); + return ret; + } + +#endif +#ifdef CONFIG_FS_LITTLEFS + + struct mtd_dev_s* mtd = pplus_fls_initialize(PPLUS_MTD_START_OFFSET, PPLUS_MTD_SIZE); + if (!mtd) + { + syslog(LOG_ERR, "ERROR: pplus_initialize failed\n"); + return ret; + } + + + /* Erase the RAM MTD */ + + ret = mtd->ioctl(mtd, MTDIOC_BULKERASE, 0); + + ret = register_mtddriver("/dev/mtd", mtd, 0755, NULL); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to register MTD driver: %d\n", + ret); + } + + /* Mount the LittleFS file system */ + + ret = nx_mount("/dev/mtd", "/mnt/lfs", "littlefs", 0, + "forceformat"); + if (ret < 0) + { + syslog(LOG_ERR, + "ERROR: Failed to mount LittleFS at /mnt/lfs: %d\n", + ret); + } + + + +#endif + +#ifdef CONFIG_PHY6222_BLE + + ret = pplus_ble_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, + "ERROR: Failed to init ble device\n", + ret); + } +#endif + + UNUSED(ret); + return OK; +} diff --git a/boards/arm/phy62xx/phy6222/src/buttons.c b/boards/arm/phy62xx/phy6222/src/buttons.c new file mode 100644 index 00000000000..80bc7ada929 --- /dev/null +++ b/boards/arm/phy62xx/phy6222/src/buttons.c @@ -0,0 +1,110 @@ +/**************************************************************************** + * boards/arm/stm32f0l0g0/stm32f051-discovery/src/stm32_buttons.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + + +#ifdef CONFIG_ARCH_BUTTONS + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Pin configuration for each STM32F3Discovery button. This array is indexed + * by the BUTTON_* definitions in board.h + */ + +static const uint32_t g_buttons[NUM_BUTTONS] = +{ + 1 +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_button_initialize + * + * Description: + * board_button_initialize() must be called to initialize button resources. + * After that, board_buttons() may be called to collect the current state + * of all buttons or board_button_irq() may be called to register button + * interrupt handlers. + * + ****************************************************************************/ + +uint32_t board_button_initialize(void) +{ + + return 1; +} + +/**************************************************************************** + * Name: board_buttons + ****************************************************************************/ + +uint8_t board_buttons(void) +{ + + return 0; +} + +/**************************************************************************** + * Button support. + * + * Description: + * board_button_initialize() must be called to initialize button resources. + * After that, board_buttons() may be called to collect the current state + * of all buttons or board_button_irq() may be called to register button + * interrupt handlers. + * + * After board_button_initialize() has been called, board_buttons() may be + * called to collect the state of all buttons. board_buttons() returns an + * 8-bit bit set with each bit associated with a button. See the + * BUTTON_*_BIT definitions in board.h for the meaning of each bit. + * + * board_button_irq() may be called to register an interrupt handler that + * will be called when a button is depressed or released. The ID value is a + * button enumeration value that uniquely identifies a button resource. See + * the BUTTON_* definitions in board.h for the meaning of enumeration + * value. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQBUTTONS +int board_button_irq(int id, xcpt_t irqhandler, FAR void *arg) +{ + + return 0; +} +#endif +#endif /* CONFIG_ARCH_BUTTONS */ diff --git a/boards/arm/phy62xx/phy6222/src/phy6222.h b/boards/arm/phy62xx/phy6222/src/phy6222.h new file mode 100644 index 00000000000..8031f5b0c7d --- /dev/null +++ b/boards/arm/phy62xx/phy6222/src/phy6222.h @@ -0,0 +1,121 @@ +/**************************************************************************** + * boards/arm/stm32f0l0g0/stm32f051-discovery/src/stm32f051-discovery.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_ARM_PHY6222_H +#define __BOARDS_ARM_PHY6222_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* How many SPI modules does this chip support? */ + + + +/* STM32F0Discovery GPIOs ***************************************************/ + +/* The STM32F0Discovery board has four LEDs. + * Two of these are controlled by logic on the board and + * are not available for software control: + * + * LD1 COM: LD2 default status is red. LD2 turns to green to indicate + * that communications are in progress between the PC and + * the ST-LINK/V2. + * LD2 PWR: Red LED indicates that the board is powered. + * + * And two LEDs can be controlled by software: + * + * User LD3: + * Green LED is a user LED connected to the I/O PB7 of the STM32L152 MCU. + * User LD4: + * Blue LED is a user LED connected to the I/O PB6 of the STM32L152 MCU. + * + * The other side of the LED connects to ground so high value will illuminate + * the LED. + */ + +#define GPIO_LED1 (GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SPEED_MEDIUM | \ + GPIO_OUTPUT_CLEAR | GPIO_PORTC | GPIO_PIN9) +#define GPIO_LED2 (GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SPEED_MEDIUM | \ + GPIO_OUTPUT_CLEAR | GPIO_PORTC | GPIO_PIN8) + +/* Button definitions *******************************************************/ + +/* The STM32F0Discovery supports two buttons; only one button is controllable + * by software: + * + * B1 USER: + * user and wake-up button connected to the I/O PA0 of the STM32F303VCT6. + * B2 RESET: + * pushbutton connected to NRST is used to RESET the STM32F303VCT6. + * + * NOTE that EXTI interrupts are configured + */ + +#define MIN_IRQBUTTON BUTTON_USER +#define MAX_IRQBUTTON BUTTON_USER +#define NUM_IRQBUTTONS 1 + +#define GPIO_BTN_USER (GPIO_INPUT | GPIO_FLOAT | GPIO_EXTI | GPIO_PORTA | GPIO_PIN0) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Functions Definitions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_bringup + * + * Description: + * Perform architecture-specific initialization + * + * CONFIG_BOARD_LATE_INITIALIZE=y : + * Called from board_late_initialize(). + * + * CONFIG_BOARD_LATE_INITIALIZE=n && CONFIG_LIB_BOARDCTL=y : + * Called from the NSH library + * + ****************************************************************************/ + +int phy62xx_bringup(void); + +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_ARM_PHY6222_H */ diff --git a/boards/arm/phy62xx/phy6222/src/userleds.c b/boards/arm/phy62xx/phy6222/src/userleds.c new file mode 100644 index 00000000000..a0096e253e3 --- /dev/null +++ b/boards/arm/phy62xx/phy6222/src/userleds.c @@ -0,0 +1,69 @@ +/**************************************************************************** + * boards/arm/stm32f0l0g0/stm32f051-discovery/src/stm32_userleds.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + + + +#ifndef CONFIG_ARCH_LEDS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_userled_initialize + ****************************************************************************/ + +uint32_t board_userled_initialize(void) +{ + /* Configure LED1-2 GPIOs for output */ + + return 0; +} + +/**************************************************************************** + * Name: board_userled + ****************************************************************************/ + +void board_userled(int led, bool ledon) +{ + +} + +/**************************************************************************** + * Name: board_userled_all + ****************************************************************************/ + +void board_userled_all(uint32_t ledset) +{ + } + +#endif /* !CONFIG_ARCH_LEDS */