initial commit

This commit is contained in:
vance 2022-10-23 23:45:43 -07:00
commit e190fa5193
6450 changed files with 8626944 additions and 0 deletions

40
.cargo/config.toml Normal file
View File

@ -0,0 +1,40 @@
[target.thumbv7em-none-eabihf]
runner = "./tools/svl-wrapper.sh"
# runner = "probe-run --chip AMA3B1KK-KBR"
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
# uncomment ONE of these three option to make `cargo run` start a GDB session
# which option to pick depends on your system
# runner = "arm-none-eabi-gdb -q -x openocd.gdb"
# runner = "gdb-multiarch -q -x openocd.gdb"
# runner = "gdb -q -x openocd.gdb"
rustflags = [
# This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x
# See https://github.com/rust-embedded/cortex-m-quickstart/pull/95
"-C", "link-arg=--nmagic",
# LLD (shipped with the Rust toolchain) is used as the default linker
"-C", "link-arg=-Tlink.x",
# if you run into problems with LLD switch to the GNU linker by commenting out
# this line
# "-C", "linker=arm-none-eabi-ld",
# if you need to link to pre-compiled C libraries provided by a C toolchain
# use GCC as the linker by commenting out both lines above and then
# uncommenting the three lines below
# "-C", "linker=arm-none-eabi-gcc",
# "-C", "link-arg=-Wl,-Tmemory.x",
# "-C", "link-arg=-nostartfiles",
]
[build]
# Pick ONE of these compilation targets
# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
#target = "thumbv7m-none-eabi" # Cortex-M3
# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU)
target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)
# target = "thumbv8m.base-none-eabi" # Cortex-M23
# target = "thumbv8m.main-none-eabi" # Cortex-M33 (no FPU)
# target = "thumbv8m.main-none-eabihf" # Cortex-M33 (with FPU)

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/target
/.idea
Cargo.lock

28
Cargo.toml Normal file
View File

@ -0,0 +1,28 @@
[package]
name = "vos"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
cortex-m = "0.7.6"
cortex-m-rt = "0.7.1"
embedded-hal = { version = "0.2.7", features = [ "unproven" ] }
nb = "1.0.0"
paste = "1.0.9"
rtt-target = { version = "0.3.1", features = ["cortex-m"] }
alloc-cortex-m = "0.4.2"
ufmt = "0.2.0"
rtcc = "0.3.0"
chrono = { version = "0.4.22", default-features = false }
num-complex = { version = "0.4.2", default-features = false }
[dependencies.ambiq-hal-sys]
path = "./ambiq-hal-sys"
version = "0.1.0"
features = ["sparkfun-artemis-thing-plus"]
[dependencies.ambiq-apollo3-pac2]
path = "./apollo3-pac"
version = "0.2.0"

2
README.md Normal file
View File

@ -0,0 +1,2 @@
# VOS
a simple hardware abstraction layer and serial frontend project for Ambiq Apollo3 devices

View File

@ -0,0 +1,41 @@
[target.thumbv7em-none-eabi]
# uncomment this to make `cargo run` execute programs on QEMU
# runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel"
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
# uncomment ONE of these three option to make `cargo run` start a GDB session
# which option to pick depends on your system
# runner = "arm-none-eabi-gdb -q -x openocd.gdb"
# runner = "gdb-multiarch -q -x openocd.gdb"
# runner = "gdb -q -x openocd.gdb"
rustflags = [
# This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x
# See https://github.com/rust-embedded/cortex-m-quickstart/pull/95
"-C", "link-arg=--nmagic",
# LLD (shipped with the Rust toolchain) is used as the default linker
#"-C", "link-arg=-Tlink.x",
# if you run into problems with LLD switch to the GNU linker by commenting out
# this line
#"-C", "linker=arm-none-eabi-ld",
# if you need to link to pre-compiled C libraries provided by a C toolchain
# use GCC as the linker by commenting out both lines above and then
# uncommenting the three lines below
"-C", "linker=arm-none-eabi-gcc",
"-C", "link-arg=-Wl,-Tlink.x",
"-C", "link-arg=-nostartfiles",
]
[build]
# Pick ONE of these compilation targets
# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
# target = "thumbv7m-none-eabi" # Cortex-M3
# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU)
target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)
# target = "thumbv8m.base-none-eabi" # Cortex-M23
# target = "thumbv8m.main-none-eabi" # Cortex-M33 (no FPU)
# target = "thumbv8m.main-none-eabihf" # Cortex-M33 (with FPU)

View File

@ -0,0 +1,14 @@
Copyright (c) 2020, Ambiq Micro
All rights reserved.
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 of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
Third party software included in this distribution is subject to the additional license terms as defined in the /docs/licenses directory.
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 HOLDER 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.

36
ambiq-hal-sys/Cargo.toml Normal file
View File

@ -0,0 +1,36 @@
[package]
name = "ambiq-hal-sys"
authors = ["Gaute Hope <eg@gaute.vetsj.com>"]
version = "0.1.0"
edition = "2021"
description = "Bindings to the Ambiq SDK"
license-file = "AM-BSD-EULA.txt"
repository = "https://github.com/gauteh/ambiq-rs"
exclude = [
"ambiq-sparkfun-sdk/boards",
"ambiq-sparkfun-sdk/pack",
"ambiq-sparkfun-sdk/docs",
"ambiq-sparkfun-sdk/boards_sfe/common/tools_sfe",
"**/*.axf",
"**/*.out",
"**/*.log",
"**/*.txt",
"**/*.lib",
"**/*.a",
"**/bin/*",
]
[dependencies]
[build-dependencies]
bindgen = "0.60.1"
cc = "1.0.73"
glob = "0.3.0"
fs_extra = "1.2.0"
[features]
utils = []
sparkfun-redboard = []
sparkfun-redboard-nano = []
sparkfun-artemis-thing-plus = []
default = [ "utils" ]

8
ambiq-hal-sys/README.md Normal file
View File

@ -0,0 +1,8 @@
# Ambiq Artemis SDK (for Sparkfun Redboard Artemis board)
This is an autogenerated wrapper for the Ambiq Artemis SDK as forked by
Sparkfun for use on the Sparkfun Artemis boards.
# Building
1. git submodule update --init --recursive --depth 1

View File

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

View File

@ -0,0 +1,17 @@
# Build Artifacts
*.o
*.d
*.a
*.axf
*.lst
*.bin
*.map
# Python
__pycache__
# MacOSX
*.DS_Store
# VSCode
.vscode

View File

@ -0,0 +1,3 @@
[submodule "boards_sfe"]
path = boards_sfe
url = https://github.com/sparkfun/SparkFun_Apollo3_AmbiqSuite_BSPs

View File

@ -0,0 +1,14 @@
Copyright (c) 2020, Ambiq Micro
All rights reserved.
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 of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
Third party software included in this distribution is subject to the additional license terms as defined in the /docs/licenses directory.
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 HOLDER 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.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,894 @@
/**************************************************************************//**
* @file cmsis_armcc.h
* @brief CMSIS compiler ARMCC (Arm Compiler 5) header file
* @version V5.1.0
* @date 08. May 2019
******************************************************************************/
/*
* Copyright (c) 2009-2019 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed 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
*
* 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 __CMSIS_ARMCC_H
#define __CMSIS_ARMCC_H
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
#error "Please use Arm Compiler Toolchain V4.0.677 or later!"
#endif
/* CMSIS compiler control architecture macros */
#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \
(defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) )
#define __ARM_ARCH_6M__ 1
#endif
#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1))
#define __ARM_ARCH_7M__ 1
#endif
#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1))
#define __ARM_ARCH_7EM__ 1
#endif
/* __ARM_ARCH_8M_BASE__ not applicable */
/* __ARM_ARCH_8M_MAIN__ not applicable */
/* CMSIS compiler control DSP macros */
#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
#define __ARM_FEATURE_DSP 1
#endif
/* CMSIS compiler specific defines */
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE __inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static __inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE static __forceinline
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __declspec(noreturn)
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT __packed struct
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION __packed union
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
#define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x)))
#endif
#ifndef __UNALIGNED_UINT16_WRITE
#define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
#define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr)))
#endif
#ifndef __UNALIGNED_UINT32_WRITE
#define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
#define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr)))
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
#ifndef __RESTRICT
#define __RESTRICT __restrict
#endif
#ifndef __COMPILER_BARRIER
#define __COMPILER_BARRIER() __memory_changed()
#endif
/* ######################### Startup and Lowlevel Init ######################## */
#ifndef __PROGRAM_START
#define __PROGRAM_START __main
#endif
#ifndef __INITIAL_SP
#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit
#endif
#ifndef __STACK_LIMIT
#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base
#endif
#ifndef __VECTOR_TABLE
#define __VECTOR_TABLE __Vectors
#endif
#ifndef __VECTOR_TABLE_ATTRIBUTE
#define __VECTOR_TABLE_ATTRIBUTE __attribute((used, section("RESET")))
#endif
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
/**
\brief Enable IRQ Interrupts
\details Enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
/* intrinsic void __enable_irq(); */
/**
\brief Disable IRQ Interrupts
\details Disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
/* intrinsic void __disable_irq(); */
/**
\brief Get Control Register
\details Returns the content of the Control Register.
\return Control Register value
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/**
\brief Set Control Register
\details Writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
/**
\brief Get IPSR Register
\details Returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/**
\brief Get APSR Register
\details Returns the content of the APSR Register.
\return APSR Register value
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/**
\brief Get xPSR Register
\details Returns the content of the xPSR Register.
\return xPSR Register value
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/**
\brief Get Process Stack Pointer
\details Returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/**
\brief Set Process Stack Pointer
\details Assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/**
\brief Get Main Stack Pointer
\details Returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/**
\brief Set Main Stack Pointer
\details Assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/**
\brief Get Priority Mask
\details Returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/**
\brief Set Priority Mask
\details Assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
/**
\brief Enable FIQ
\details Enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/**
\brief Disable FIQ
\details Disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/**
\brief Get Base Priority
\details Returns the current value of the Base Priority register.
\return Base Priority register value
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/**
\brief Set Base Priority
\details Assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xFFU);
}
/**
\brief Set Base Priority with condition
\details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
or the new value increases the BASEPRI priority level.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
{
register uint32_t __regBasePriMax __ASM("basepri_max");
__regBasePriMax = (basePri & 0xFFU);
}
/**
\brief Get Fault Mask
\details Returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/**
\brief Set Fault Mask
\details Assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1U);
}
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/**
\brief Get FPSCR
\details Returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0U);
#endif
}
/**
\brief Set FPSCR
\details Assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#else
(void)fpscr;
#endif
}
/*@} end of CMSIS_Core_RegAccFunctions */
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
/**
\brief No Operation
\details No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/**
\brief Wait For Interrupt
\details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
*/
#define __WFI __wfi
/**
\brief Wait For Event
\details Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/**
\brief Send Event
\details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/**
\brief Instruction Synchronization Barrier
\details Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or memory,
after the instruction has been completed.
*/
#define __ISB() do {\
__schedule_barrier();\
__isb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Data Synchronization Barrier
\details Acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() do {\
__schedule_barrier();\
__dsb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Data Memory Barrier
\details Ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() do {\
__schedule_barrier();\
__dmb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Reverse byte order (32 bit)
\details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/**
\brief Reverse byte order (16 bit)
\details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif
/**
\brief Reverse byte order (16 bit)
\details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value)
{
revsh r0, r0
bx lr
}
#endif
/**
\brief Rotate Right in unsigned value (32 bit)
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] op1 Value to rotate
\param [in] op2 Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
/**
\brief Breakpoint
\details Causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __breakpoint(value)
/**
\brief Reverse bit order of value
\details Reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
#define __RBIT __rbit
#else
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */
result = value; /* r will be reversed bits of v; first get LSB of v */
for (value >>= 1U; value != 0U; value >>= 1U)
{
result <<= 1U;
result |= value & 1U;
s--;
}
result <<= s; /* shift when v's highest bits are zero */
return result;
}
#endif
/**
\brief Count leading zeros
\details Counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
/**
\brief LDR Exclusive (8 bit)
\details Executes a exclusive LDR instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
#else
#define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (16 bit)
\details Executes a exclusive LDR instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
#else
#define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (32 bit)
\details Executes a exclusive LDR instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
#else
#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief STR Exclusive (8 bit)
\details Executes a exclusive STR instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXB(value, ptr) __strex(value, ptr)
#else
#define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (16 bit)
\details Executes a exclusive STR instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXH(value, ptr) __strex(value, ptr)
#else
#define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (32 bit)
\details Executes a exclusive STR instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXW(value, ptr) __strex(value, ptr)
#else
#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief Remove the exclusive lock
\details Removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/**
\brief Signed Saturate
\details Saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/**
\brief Unsigned Saturate
\details Saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/**
\brief Rotate Right with Extend (32 bit)
\details Moves each bit of a bitstring right by one bit.
The carry input is shifted in at the left end of the bitstring.
\param [in] value Value to rotate
\return Rotated value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
{
rrx r0, r0
bx lr
}
#endif
/**
\brief LDRT Unprivileged (8 bit)
\details Executes a Unprivileged LDRT instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
/**
\brief LDRT Unprivileged (16 bit)
\details Executes a Unprivileged LDRT instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
/**
\brief LDRT Unprivileged (32 bit)
\details Executes a Unprivileged LDRT instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
/**
\brief STRT Unprivileged (8 bit)
\details Executes a Unprivileged STRT instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRBT(value, ptr) __strt(value, ptr)
/**
\brief STRT Unprivileged (16 bit)
\details Executes a Unprivileged STRT instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRHT(value, ptr) __strt(value, ptr)
/**
\brief STRT Unprivileged (32 bit)
\details Executes a Unprivileged STRT instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRT(value, ptr) __strt(value, ptr)
#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/**
\brief Signed Saturate
\details Saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat)
{
if ((sat >= 1U) && (sat <= 32U))
{
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
const int32_t min = -1 - max ;
if (val > max)
{
return max;
}
else if (val < min)
{
return min;
}
}
return val;
}
/**
\brief Unsigned Saturate
\details Saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat)
{
if (sat <= 31U)
{
const uint32_t max = ((1U << sat) - 1U);
if (val > (int32_t)max)
{
return max;
}
else if (val < 0)
{
return 0U;
}
}
return (uint32_t)val;
}
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/
#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
#define __SADD8 __sadd8
#define __QADD8 __qadd8
#define __SHADD8 __shadd8
#define __UADD8 __uadd8
#define __UQADD8 __uqadd8
#define __UHADD8 __uhadd8
#define __SSUB8 __ssub8
#define __QSUB8 __qsub8
#define __SHSUB8 __shsub8
#define __USUB8 __usub8
#define __UQSUB8 __uqsub8
#define __UHSUB8 __uhsub8
#define __SADD16 __sadd16
#define __QADD16 __qadd16
#define __SHADD16 __shadd16
#define __UADD16 __uadd16
#define __UQADD16 __uqadd16
#define __UHADD16 __uhadd16
#define __SSUB16 __ssub16
#define __QSUB16 __qsub16
#define __SHSUB16 __shsub16
#define __USUB16 __usub16
#define __UQSUB16 __uqsub16
#define __UHSUB16 __uhsub16
#define __SASX __sasx
#define __QASX __qasx
#define __SHASX __shasx
#define __UASX __uasx
#define __UQASX __uqasx
#define __UHASX __uhasx
#define __SSAX __ssax
#define __QSAX __qsax
#define __SHSAX __shsax
#define __USAX __usax
#define __UQSAX __uqsax
#define __UHSAX __uhsax
#define __USAD8 __usad8
#define __USADA8 __usada8
#define __SSAT16 __ssat16
#define __USAT16 __usat16
#define __UXTB16 __uxtb16
#define __UXTAB16 __uxtab16
#define __SXTB16 __sxtb16
#define __SXTAB16 __sxtab16
#define __SMUAD __smuad
#define __SMUADX __smuadx
#define __SMLAD __smlad
#define __SMLADX __smladx
#define __SMLALD __smlald
#define __SMLALDX __smlaldx
#define __SMUSD __smusd
#define __SMUSDX __smusdx
#define __SMLSD __smlsd
#define __SMLSDX __smlsdx
#define __SMLSLD __smlsld
#define __SMLSLDX __smlsldx
#define __SEL __sel
#define __QADD __qadd
#define __QSUB __qsub
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
((int64_t)(ARG3) << 32U) ) >> 32U))
#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/*@} end of group CMSIS_SIMD_intrinsics */
#endif /* __CMSIS_ARMCC_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,283 @@
/**************************************************************************//**
* @file cmsis_compiler.h
* @brief CMSIS compiler generic header file
* @version V5.1.0
* @date 09. October 2018
******************************************************************************/
/*
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed 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
*
* 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 __CMSIS_COMPILER_H
#define __CMSIS_COMPILER_H
#include <stdint.h>
/*
* Arm Compiler 4/5
*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*
* Arm Compiler 6.6 LTM (armclang)
*/
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100)
#include "cmsis_armclang_ltm.h"
/*
* Arm Compiler above 6.10.1 (armclang)
*/
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100)
#include "cmsis_armclang.h"
/*
* GNU Compiler
*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*
* IAR Compiler
*/
#elif defined ( __ICCARM__ )
#include <cmsis_iccarm.h>
/*
* TI Arm Compiler
*/
#elif defined ( __TI_ARM__ )
#include <cmsis_ccs.h>
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __attribute__((packed))
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION union __attribute__((packed))
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
struct __attribute__((packed)) T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
#ifndef __RESTRICT
#define __RESTRICT __restrict
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
/*
* TASKING Compiler
*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __packed__
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __packed__
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION union __packed__
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
struct __packed__ T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __align(x)
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
/*
* COSMIC Compiler
*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#ifndef __ASM
#define __ASM _asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __STATIC_INLINE
#endif
#ifndef __NO_RETURN
// NO RETURN is automatically detected hence no warning here
#define __NO_RETURN
#endif
#ifndef __USED
#warning No compiler specific solution for __USED. __USED is ignored.
#define __USED
#endif
#ifndef __WEAK
#define __WEAK __weak
#endif
#ifndef __PACKED
#define __PACKED @packed
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT @packed struct
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION @packed union
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
@packed struct T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
#define __ALIGNED(x)
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
#ifndef __COMPILER_BARRIER
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
#define __COMPILER_BARRIER() (void)0
#endif
#else
#error Unknown compiler.
#endif
#endif /* __CMSIS_COMPILER_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,964 @@
/**************************************************************************//**
* @file cmsis_iccarm.h
* @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file
* @version V5.1.0
* @date 08. May 2019
******************************************************************************/
//------------------------------------------------------------------------------
//
// Copyright (c) 2017-2019 IAR Systems
// Copyright (c) 2017-2019 Arm Limited. All rights reserved.
//
// Licensed 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 __CMSIS_ICCARM_H__
#define __CMSIS_ICCARM_H__
#ifndef __ICCARM__
#error This file should only be compiled by ICCARM
#endif
#pragma system_include
#define __IAR_FT _Pragma("inline=forced") __intrinsic
#if (__VER__ >= 8000000)
#define __ICCARM_V8 1
#else
#define __ICCARM_V8 0
#endif
#ifndef __ALIGNED
#if __ICCARM_V8
#define __ALIGNED(x) __attribute__((aligned(x)))
#elif (__VER__ >= 7080000)
/* Needs IAR language extensions */
#define __ALIGNED(x) __attribute__((aligned(x)))
#else
#warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored.
#define __ALIGNED(x)
#endif
#endif
/* Define compiler macros for CPU architecture, used in CMSIS 5.
*/
#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__
/* Macros already defined */
#else
#if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__)
#define __ARM_ARCH_8M_MAIN__ 1
#elif defined(__ARM8M_BASELINE__)
#define __ARM_ARCH_8M_BASE__ 1
#elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M'
#if __ARM_ARCH == 6
#define __ARM_ARCH_6M__ 1
#elif __ARM_ARCH == 7
#if __ARM_FEATURE_DSP
#define __ARM_ARCH_7EM__ 1
#else
#define __ARM_ARCH_7M__ 1
#endif
#endif /* __ARM_ARCH */
#endif /* __ARM_ARCH_PROFILE == 'M' */
#endif
/* Alternativ core deduction for older ICCARM's */
#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \
!defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__)
#if defined(__ARM6M__) && (__CORE__ == __ARM6M__)
#define __ARM_ARCH_6M__ 1
#elif defined(__ARM7M__) && (__CORE__ == __ARM7M__)
#define __ARM_ARCH_7M__ 1
#elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__)
#define __ARM_ARCH_7EM__ 1
#elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__)
#define __ARM_ARCH_8M_BASE__ 1
#elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__)
#define __ARM_ARCH_8M_MAIN__ 1
#elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__)
#define __ARM_ARCH_8M_MAIN__ 1
#else
#error "Unknown target."
#endif
#endif
#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1
#define __IAR_M0_FAMILY 1
#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1
#define __IAR_M0_FAMILY 1
#else
#define __IAR_M0_FAMILY 0
#endif
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __COMPILER_BARRIER
#define __COMPILER_BARRIER() __ASM volatile("":::"memory")
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __NO_RETURN
#if __ICCARM_V8
#define __NO_RETURN __attribute__((__noreturn__))
#else
#define __NO_RETURN _Pragma("object_attribute=__noreturn")
#endif
#endif
#ifndef __PACKED
#if __ICCARM_V8
#define __PACKED __attribute__((packed, aligned(1)))
#else
/* Needs IAR language extensions */
#define __PACKED __packed
#endif
#endif
#ifndef __PACKED_STRUCT
#if __ICCARM_V8
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
#else
/* Needs IAR language extensions */
#define __PACKED_STRUCT __packed struct
#endif
#endif
#ifndef __PACKED_UNION
#if __ICCARM_V8
#define __PACKED_UNION union __attribute__((packed, aligned(1)))
#else
/* Needs IAR language extensions */
#define __PACKED_UNION __packed union
#endif
#endif
#ifndef __RESTRICT
#if __ICCARM_V8
#define __RESTRICT __restrict
#else
/* Needs IAR language extensions */
#define __RESTRICT restrict
#endif
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __FORCEINLINE
#define __FORCEINLINE _Pragma("inline=forced")
#endif
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE
#endif
#ifndef __UNALIGNED_UINT16_READ
#pragma language=save
#pragma language=extended
__IAR_FT uint16_t __iar_uint16_read(void const *ptr)
{
return *(__packed uint16_t*)(ptr);
}
#pragma language=restore
#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
#pragma language=save
#pragma language=extended
__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val)
{
*(__packed uint16_t*)(ptr) = val;;
}
#pragma language=restore
#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL)
#endif
#ifndef __UNALIGNED_UINT32_READ
#pragma language=save
#pragma language=extended
__IAR_FT uint32_t __iar_uint32_read(void const *ptr)
{
return *(__packed uint32_t*)(ptr);
}
#pragma language=restore
#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
#pragma language=save
#pragma language=extended
__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val)
{
*(__packed uint32_t*)(ptr) = val;;
}
#pragma language=restore
#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL)
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
#pragma language=save
#pragma language=extended
__packed struct __iar_u32 { uint32_t v; };
#pragma language=restore
#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v)
#endif
#ifndef __USED
#if __ICCARM_V8
#define __USED __attribute__((used))
#else
#define __USED _Pragma("__root")
#endif
#endif
#ifndef __WEAK
#if __ICCARM_V8
#define __WEAK __attribute__((weak))
#else
#define __WEAK _Pragma("__weak")
#endif
#endif
#ifndef __PROGRAM_START
#define __PROGRAM_START __iar_program_start
#endif
#ifndef __INITIAL_SP
#define __INITIAL_SP CSTACK$$Limit
#endif
#ifndef __STACK_LIMIT
#define __STACK_LIMIT CSTACK$$Base
#endif
#ifndef __VECTOR_TABLE
#define __VECTOR_TABLE __vector_table
#endif
#ifndef __VECTOR_TABLE_ATTRIBUTE
#define __VECTOR_TABLE_ATTRIBUTE @".intvec"
#endif
#ifndef __ICCARM_INTRINSICS_VERSION__
#define __ICCARM_INTRINSICS_VERSION__ 0
#endif
#if __ICCARM_INTRINSICS_VERSION__ == 2
#if defined(__CLZ)
#undef __CLZ
#endif
#if defined(__REVSH)
#undef __REVSH
#endif
#if defined(__RBIT)
#undef __RBIT
#endif
#if defined(__SSAT)
#undef __SSAT
#endif
#if defined(__USAT)
#undef __USAT
#endif
#include "iccarm_builtin.h"
#define __disable_fault_irq __iar_builtin_disable_fiq
#define __disable_irq __iar_builtin_disable_interrupt
#define __enable_fault_irq __iar_builtin_enable_fiq
#define __enable_irq __iar_builtin_enable_interrupt
#define __arm_rsr __iar_builtin_rsr
#define __arm_wsr __iar_builtin_wsr
#define __get_APSR() (__arm_rsr("APSR"))
#define __get_BASEPRI() (__arm_rsr("BASEPRI"))
#define __get_CONTROL() (__arm_rsr("CONTROL"))
#define __get_FAULTMASK() (__arm_rsr("FAULTMASK"))
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
#define __get_FPSCR() (__arm_rsr("FPSCR"))
#define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE)))
#else
#define __get_FPSCR() ( 0 )
#define __set_FPSCR(VALUE) ((void)VALUE)
#endif
#define __get_IPSR() (__arm_rsr("IPSR"))
#define __get_MSP() (__arm_rsr("MSP"))
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure MSPLIM is RAZ/WI
#define __get_MSPLIM() (0U)
#else
#define __get_MSPLIM() (__arm_rsr("MSPLIM"))
#endif
#define __get_PRIMASK() (__arm_rsr("PRIMASK"))
#define __get_PSP() (__arm_rsr("PSP"))
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
#define __get_PSPLIM() (0U)
#else
#define __get_PSPLIM() (__arm_rsr("PSPLIM"))
#endif
#define __get_xPSR() (__arm_rsr("xPSR"))
#define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE)))
#define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE)))
#define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE)))
#define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE)))
#define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE)))
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure MSPLIM is RAZ/WI
#define __set_MSPLIM(VALUE) ((void)(VALUE))
#else
#define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE)))
#endif
#define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE)))
#define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE)))
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
#define __set_PSPLIM(VALUE) ((void)(VALUE))
#else
#define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE)))
#endif
#define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS"))
#define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE)))
#define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS"))
#define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE)))
#define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS"))
#define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE)))
#define __TZ_get_SP_NS() (__arm_rsr("SP_NS"))
#define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE)))
#define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS"))
#define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE)))
#define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS"))
#define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE)))
#define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS"))
#define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE)))
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
#define __TZ_get_PSPLIM_NS() (0U)
#define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE))
#else
#define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS"))
#define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE)))
#endif
#define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS"))
#define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE)))
#define __NOP __iar_builtin_no_operation
#define __CLZ __iar_builtin_CLZ
#define __CLREX __iar_builtin_CLREX
#define __DMB __iar_builtin_DMB
#define __DSB __iar_builtin_DSB
#define __ISB __iar_builtin_ISB
#define __LDREXB __iar_builtin_LDREXB
#define __LDREXH __iar_builtin_LDREXH
#define __LDREXW __iar_builtin_LDREX
#define __RBIT __iar_builtin_RBIT
#define __REV __iar_builtin_REV
#define __REV16 __iar_builtin_REV16
__IAR_FT int16_t __REVSH(int16_t val)
{
return (int16_t) __iar_builtin_REVSH(val);
}
#define __ROR __iar_builtin_ROR
#define __RRX __iar_builtin_RRX
#define __SEV __iar_builtin_SEV
#if !__IAR_M0_FAMILY
#define __SSAT __iar_builtin_SSAT
#endif
#define __STREXB __iar_builtin_STREXB
#define __STREXH __iar_builtin_STREXH
#define __STREXW __iar_builtin_STREX
#if !__IAR_M0_FAMILY
#define __USAT __iar_builtin_USAT
#endif
#define __WFE __iar_builtin_WFE
#define __WFI __iar_builtin_WFI
#if __ARM_MEDIA__
#define __SADD8 __iar_builtin_SADD8
#define __QADD8 __iar_builtin_QADD8
#define __SHADD8 __iar_builtin_SHADD8
#define __UADD8 __iar_builtin_UADD8
#define __UQADD8 __iar_builtin_UQADD8
#define __UHADD8 __iar_builtin_UHADD8
#define __SSUB8 __iar_builtin_SSUB8
#define __QSUB8 __iar_builtin_QSUB8
#define __SHSUB8 __iar_builtin_SHSUB8
#define __USUB8 __iar_builtin_USUB8
#define __UQSUB8 __iar_builtin_UQSUB8
#define __UHSUB8 __iar_builtin_UHSUB8
#define __SADD16 __iar_builtin_SADD16
#define __QADD16 __iar_builtin_QADD16
#define __SHADD16 __iar_builtin_SHADD16
#define __UADD16 __iar_builtin_UADD16
#define __UQADD16 __iar_builtin_UQADD16
#define __UHADD16 __iar_builtin_UHADD16
#define __SSUB16 __iar_builtin_SSUB16
#define __QSUB16 __iar_builtin_QSUB16
#define __SHSUB16 __iar_builtin_SHSUB16
#define __USUB16 __iar_builtin_USUB16
#define __UQSUB16 __iar_builtin_UQSUB16
#define __UHSUB16 __iar_builtin_UHSUB16
#define __SASX __iar_builtin_SASX
#define __QASX __iar_builtin_QASX
#define __SHASX __iar_builtin_SHASX
#define __UASX __iar_builtin_UASX
#define __UQASX __iar_builtin_UQASX
#define __UHASX __iar_builtin_UHASX
#define __SSAX __iar_builtin_SSAX
#define __QSAX __iar_builtin_QSAX
#define __SHSAX __iar_builtin_SHSAX
#define __USAX __iar_builtin_USAX
#define __UQSAX __iar_builtin_UQSAX
#define __UHSAX __iar_builtin_UHSAX
#define __USAD8 __iar_builtin_USAD8
#define __USADA8 __iar_builtin_USADA8
#define __SSAT16 __iar_builtin_SSAT16
#define __USAT16 __iar_builtin_USAT16
#define __UXTB16 __iar_builtin_UXTB16
#define __UXTAB16 __iar_builtin_UXTAB16
#define __SXTB16 __iar_builtin_SXTB16
#define __SXTAB16 __iar_builtin_SXTAB16
#define __SMUAD __iar_builtin_SMUAD
#define __SMUADX __iar_builtin_SMUADX
#define __SMMLA __iar_builtin_SMMLA
#define __SMLAD __iar_builtin_SMLAD
#define __SMLADX __iar_builtin_SMLADX
#define __SMLALD __iar_builtin_SMLALD
#define __SMLALDX __iar_builtin_SMLALDX
#define __SMUSD __iar_builtin_SMUSD
#define __SMUSDX __iar_builtin_SMUSDX
#define __SMLSD __iar_builtin_SMLSD
#define __SMLSDX __iar_builtin_SMLSDX
#define __SMLSLD __iar_builtin_SMLSLD
#define __SMLSLDX __iar_builtin_SMLSLDX
#define __SEL __iar_builtin_SEL
#define __QADD __iar_builtin_QADD
#define __QSUB __iar_builtin_QSUB
#define __PKHBT __iar_builtin_PKHBT
#define __PKHTB __iar_builtin_PKHTB
#endif
#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */
#if __IAR_M0_FAMILY
/* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */
#define __CLZ __cmsis_iar_clz_not_active
#define __SSAT __cmsis_iar_ssat_not_active
#define __USAT __cmsis_iar_usat_not_active
#define __RBIT __cmsis_iar_rbit_not_active
#define __get_APSR __cmsis_iar_get_APSR_not_active
#endif
#if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) ))
#define __get_FPSCR __cmsis_iar_get_FPSR_not_active
#define __set_FPSCR __cmsis_iar_set_FPSR_not_active
#endif
#ifdef __INTRINSICS_INCLUDED
#error intrinsics.h is already included previously!
#endif
#include <intrinsics.h>
#if __IAR_M0_FAMILY
/* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */
#undef __CLZ
#undef __SSAT
#undef __USAT
#undef __RBIT
#undef __get_APSR
__STATIC_INLINE uint8_t __CLZ(uint32_t data)
{
if (data == 0U) { return 32U; }
uint32_t count = 0U;
uint32_t mask = 0x80000000U;
while ((data & mask) == 0U)
{
count += 1U;
mask = mask >> 1U;
}
return count;
}
__STATIC_INLINE uint32_t __RBIT(uint32_t v)
{
uint8_t sc = 31U;
uint32_t r = v;
for (v >>= 1U; v; v >>= 1U)
{
r <<= 1U;
r |= v & 1U;
sc--;
}
return (r << sc);
}
__STATIC_INLINE uint32_t __get_APSR(void)
{
uint32_t res;
__asm("MRS %0,APSR" : "=r" (res));
return res;
}
#endif
#if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) ))
#undef __get_FPSCR
#undef __set_FPSCR
#define __get_FPSCR() (0)
#define __set_FPSCR(VALUE) ((void)VALUE)
#endif
#pragma diag_suppress=Pe940
#pragma diag_suppress=Pe177
#define __enable_irq __enable_interrupt
#define __disable_irq __disable_interrupt
#define __NOP __no_operation
#define __get_xPSR __get_PSR
#if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0)
__IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr)
{
return __LDREX((unsigned long *)ptr);
}
__IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr)
{
return __STREX(value, (unsigned long *)ptr);
}
#endif
/* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */
#if (__CORTEX_M >= 0x03)
__IAR_FT uint32_t __RRX(uint32_t value)
{
uint32_t result;
__ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc");
return(result);
}
__IAR_FT void __set_BASEPRI_MAX(uint32_t value)
{
__asm volatile("MSR BASEPRI_MAX,%0"::"r" (value));
}
#define __enable_fault_irq __enable_fiq
#define __disable_fault_irq __disable_fiq
#endif /* (__CORTEX_M >= 0x03) */
__IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2)
{
return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2));
}
#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
__IAR_FT uint32_t __get_MSPLIM(void)
{
uint32_t res;
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure MSPLIM is RAZ/WI
res = 0U;
#else
__asm volatile("MRS %0,MSPLIM" : "=r" (res));
#endif
return res;
}
__IAR_FT void __set_MSPLIM(uint32_t value)
{
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure MSPLIM is RAZ/WI
(void)value;
#else
__asm volatile("MSR MSPLIM,%0" :: "r" (value));
#endif
}
__IAR_FT uint32_t __get_PSPLIM(void)
{
uint32_t res;
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
res = 0U;
#else
__asm volatile("MRS %0,PSPLIM" : "=r" (res));
#endif
return res;
}
__IAR_FT void __set_PSPLIM(uint32_t value)
{
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
(void)value;
#else
__asm volatile("MSR PSPLIM,%0" :: "r" (value));
#endif
}
__IAR_FT uint32_t __TZ_get_CONTROL_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,CONTROL_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_CONTROL_NS(uint32_t value)
{
__asm volatile("MSR CONTROL_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_PSP_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,PSP_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_PSP_NS(uint32_t value)
{
__asm volatile("MSR PSP_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_MSP_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,MSP_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_MSP_NS(uint32_t value)
{
__asm volatile("MSR MSP_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_SP_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,SP_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_SP_NS(uint32_t value)
{
__asm volatile("MSR SP_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_PRIMASK_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,PRIMASK_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value)
{
__asm volatile("MSR PRIMASK_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_BASEPRI_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,BASEPRI_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value)
{
__asm volatile("MSR BASEPRI_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value)
{
__asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value));
}
__IAR_FT uint32_t __TZ_get_PSPLIM_NS(void)
{
uint32_t res;
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
res = 0U;
#else
__asm volatile("MRS %0,PSPLIM_NS" : "=r" (res));
#endif
return res;
}
__IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value)
{
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
// without main extensions, the non-secure PSPLIM is RAZ/WI
(void)value;
#else
__asm volatile("MSR PSPLIM_NS,%0" :: "r" (value));
#endif
}
__IAR_FT uint32_t __TZ_get_MSPLIM_NS(void)
{
uint32_t res;
__asm volatile("MRS %0,MSPLIM_NS" : "=r" (res));
return res;
}
__IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value)
{
__asm volatile("MSR MSPLIM_NS,%0" :: "r" (value));
}
#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */
#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */
#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value))
#if __IAR_M0_FAMILY
__STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat)
{
if ((sat >= 1U) && (sat <= 32U))
{
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
const int32_t min = -1 - max ;
if (val > max)
{
return max;
}
else if (val < min)
{
return min;
}
}
return val;
}
__STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat)
{
if (sat <= 31U)
{
const uint32_t max = ((1U << sat) - 1U);
if (val > (int32_t)max)
{
return max;
}
else if (val < 0)
{
return 0U;
}
}
return (uint32_t)val;
}
#endif
#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */
__IAR_FT uint8_t __LDRBT(volatile uint8_t *addr)
{
uint32_t res;
__ASM("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
return ((uint8_t)res);
}
__IAR_FT uint16_t __LDRHT(volatile uint16_t *addr)
{
uint32_t res;
__ASM("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
return ((uint16_t)res);
}
__IAR_FT uint32_t __LDRT(volatile uint32_t *addr)
{
uint32_t res;
__ASM("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
return res;
}
__IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr)
{
__ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory");
}
__IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr)
{
__ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory");
}
__IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr)
{
__ASM("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory");
}
#endif /* (__CORTEX_M >= 0x03) */
#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
__IAR_FT uint8_t __LDAB(volatile uint8_t *ptr)
{
uint32_t res;
__ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
return ((uint8_t)res);
}
__IAR_FT uint16_t __LDAH(volatile uint16_t *ptr)
{
uint32_t res;
__ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
return ((uint16_t)res);
}
__IAR_FT uint32_t __LDA(volatile uint32_t *ptr)
{
uint32_t res;
__ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
return res;
}
__IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr)
{
__ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory");
}
__IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr)
{
__ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory");
}
__IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr)
{
__ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory");
}
__IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr)
{
uint32_t res;
__ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
return ((uint8_t)res);
}
__IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr)
{
uint32_t res;
__ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
return ((uint16_t)res);
}
__IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr)
{
uint32_t res;
__ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
return res;
}
__IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr)
{
uint32_t res;
__ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory");
return res;
}
__IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr)
{
uint32_t res;
__ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory");
return res;
}
__IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr)
{
uint32_t res;
__ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory");
return res;
}
#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */
#undef __IAR_FT
#undef __IAR_M0_FAMILY
#undef __ICCARM_V8
#pragma diag_default=Pe940
#pragma diag_default=Pe177
#endif /* __CMSIS_ICCARM_H__ */

View File

@ -0,0 +1,39 @@
/**************************************************************************//**
* @file cmsis_version.h
* @brief CMSIS Core(M) Version definitions
* @version V5.0.3
* @date 24. June 2019
******************************************************************************/
/*
* Copyright (c) 2009-2019 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed 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
*
* 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.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CMSIS_VERSION_H
#define __CMSIS_VERSION_H
/* CMSIS Version definitions */
#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */
#define __CM_CMSIS_VERSION_SUB ( 3U) /*!< [15:0] CMSIS Core(M) sub version */
#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \
__CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,272 @@
/******************************************************************************
* @file mpu_armv7.h
* @brief CMSIS MPU API for Armv7-M MPU
* @version V5.1.0
* @date 08. March 2019
******************************************************************************/
/*
* Copyright (c) 2017-2019 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed 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
*
* 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.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__clang__)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef ARM_MPU_ARMV7_H
#define ARM_MPU_ARMV7_H
#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes
#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes
#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes
#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes
#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes
#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte
#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes
#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes
#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes
#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes
#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes
#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes
#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes
#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes
#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes
#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte
#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes
#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes
#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes
#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes
#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes
#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes
#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes
#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes
#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes
#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte
#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes
#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes
#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access
#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only
#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only
#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access
#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only
#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access
/** MPU Region Base Address Register Value
*
* \param Region The region to be configured, number 0 to 15.
* \param BaseAddress The base address for the region.
*/
#define ARM_MPU_RBAR(Region, BaseAddress) \
(((BaseAddress) & MPU_RBAR_ADDR_Msk) | \
((Region) & MPU_RBAR_REGION_Msk) | \
(MPU_RBAR_VALID_Msk))
/**
* MPU Memory Access Attributes
*
* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
* \param IsShareable Region is shareable between multiple bus masters.
* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache.
* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy.
*/
#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \
((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \
(((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \
(((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \
(((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk))
/**
* MPU Region Attribute and Size Register Value
*
* \param DisableExec Instruction access disable bit, 1= disable instruction fetches.
* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode.
* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_.
* \param SubRegionDisable Sub-region disable field.
* \param Size Region size of the region to be configured, for example 4K, 8K.
*/
#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \
((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \
(((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \
(((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \
(((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \
(((Size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \
(((MPU_RASR_ENABLE_Msk))))
/**
* MPU Region Attribute and Size Register Value
*
* \param DisableExec Instruction access disable bit, 1= disable instruction fetches.
* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode.
* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
* \param IsShareable Region is shareable between multiple bus masters.
* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache.
* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy.
* \param SubRegionDisable Sub-region disable field.
* \param Size Region size of the region to be configured, for example 4K, 8K.
*/
#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \
ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size)
/**
* MPU Memory Access Attribute for strongly ordered memory.
* - TEX: 000b
* - Shareable
* - Non-cacheable
* - Non-bufferable
*/
#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U)
/**
* MPU Memory Access Attribute for device memory.
* - TEX: 000b (if shareable) or 010b (if non-shareable)
* - Shareable or non-shareable
* - Non-cacheable
* - Bufferable (if shareable) or non-bufferable (if non-shareable)
*
* \param IsShareable Configures the device memory as shareable or non-shareable.
*/
#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U))
/**
* MPU Memory Access Attribute for normal memory.
* - TEX: 1BBb (reflecting outer cacheability rules)
* - Shareable or non-shareable
* - Cacheable or non-cacheable (reflecting inner cacheability rules)
* - Bufferable or non-bufferable (reflecting inner cacheability rules)
*
* \param OuterCp Configures the outer cache policy.
* \param InnerCp Configures the inner cache policy.
* \param IsShareable Configures the memory as shareable or non-shareable.
*/
#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) & 2U), ((InnerCp) & 1U))
/**
* MPU Memory Access Attribute non-cacheable policy.
*/
#define ARM_MPU_CACHEP_NOCACHE 0U
/**
* MPU Memory Access Attribute write-back, write and read allocate policy.
*/
#define ARM_MPU_CACHEP_WB_WRA 1U
/**
* MPU Memory Access Attribute write-through, no write allocate policy.
*/
#define ARM_MPU_CACHEP_WT_NWA 2U
/**
* MPU Memory Access Attribute write-back, no write allocate policy.
*/
#define ARM_MPU_CACHEP_WB_NWA 3U
/**
* Struct for a single MPU Region
*/
typedef struct {
uint32_t RBAR; //!< The region base address register value (RBAR)
uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR
} ARM_MPU_Region_t;
/** Enable the MPU.
* \param MPU_Control Default access permissions for unconfigured regions.
*/
__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control)
{
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
#endif
__DSB();
__ISB();
}
/** Disable the MPU.
*/
__STATIC_INLINE void ARM_MPU_Disable(void)
{
__DMB();
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
#endif
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
}
/** Clear and disable the given MPU region.
* \param rnr Region number to be cleared.
*/
__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr)
{
MPU->RNR = rnr;
MPU->RASR = 0U;
}
/** Configure an MPU region.
* \param rbar Value for RBAR register.
* \param rsar Value for RSAR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr)
{
MPU->RBAR = rbar;
MPU->RASR = rasr;
}
/** Configure the given MPU region.
* \param rnr Region number to be configured.
* \param rbar Value for RBAR register.
* \param rsar Value for RSAR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr)
{
MPU->RNR = rnr;
MPU->RBAR = rbar;
MPU->RASR = rasr;
}
/** Memcopy with strictly ordered memory access, e.g. for register targets.
* \param dst Destination data is copied to.
* \param src Source data is copied from.
* \param len Amount of data words to be copied.
*/
__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len)
{
uint32_t i;
for (i = 0U; i < len; ++i)
{
dst[i] = src[i];
}
}
/** Load the given number of MPU regions from a table.
* \param table Pointer to the MPU configuration table.
* \param cnt Amount of regions to be configured.
*/
__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt)
{
const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U;
while (cnt > MPU_TYPE_RALIASES) {
ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize);
table += MPU_TYPE_RALIASES;
cnt -= MPU_TYPE_RALIASES;
}
ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize);
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,69 @@
//*****************************************************************************
//
//! @file system_apollo1.h
//!
//! @brief Ambiq Micro Apollo1 MCU specific functions.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
//*****************************************************************************
#ifndef SYSTEM_APOLLO1_H
#define SYSTEM_APOLLO1_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
extern uint32_t SystemCoreClock; // System Clock Frequency (Core Clock)
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern void SystemInit (void);
extern void SystemCoreClockUpdate (void);
#ifdef __cplusplus
}
#endif
#endif // SYSTEM_APOLLO1_H

View File

@ -0,0 +1,69 @@
//*****************************************************************************
//
//! @file system_apollo2.h
//!
//! @brief Ambiq Micro Apollo2 MCU specific functions.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
//*****************************************************************************
#ifndef SYSTEM_APOLLO2_H
#define SYSTEM_APOLLO2_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
extern uint32_t SystemCoreClock; // System Clock Frequency (Core Clock)
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern void SystemInit (void);
extern void SystemCoreClockUpdate (void);
#ifdef __cplusplus
}
#endif
#endif // SYSTEM_APOLLO2_H

View File

@ -0,0 +1,69 @@
//*****************************************************************************
//
//! @file system_Apollo3.h
//!
//! @brief Ambiq Micro Apollo3 MCU specific functions.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
//*****************************************************************************
#ifndef SYSTEM_APOLLO3_H
#define SYSTEM_APOLLO3_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
extern uint32_t SystemCoreClock; // System Clock Frequency (Core Clock)
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern void SystemInit (void);
extern void SystemCoreClockUpdate (void);
#ifdef __cplusplus
}
#endif
#endif // SYSTEM_APOLLO3_H

View File

@ -0,0 +1,69 @@
//*****************************************************************************
//
//! @file system_apollo3p.h
//!
//! @brief Ambiq Micro Apollo3p MCU specific functions.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
//*****************************************************************************
#ifndef SYSTEM_APOLLO3P_H
#define SYSTEM_APOLLO3P_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
extern uint32_t SystemCoreClock; // System Clock Frequency (Core Clock)
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern void SystemInit (void);
extern void SystemCoreClockUpdate (void);
#ifdef __cplusplus
}
#endif
#endif // SYSTEM_APOLLO3P_H

View File

@ -0,0 +1,288 @@
;******************************************************************************
;
;! @file startup_apollo1.s
;!
;! @brief Definitions for Apollo1 interrupt handlers, the vector table, and the stack.
;
;******************************************************************************
;******************************************************************************
;
; Copyright (c) 2020, Ambiq Micro
; All rights reserved.
;
; 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 of the copyright holder nor the names of its
; contributors may be used to endorse or promote products derived from this
; software without specific prior written permission.
;
; Third party software included in this distribution is subject to the
; additional license terms as defined in the /docs/licenses directory.
;
; 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 HOLDER 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.
;
; This is part of revision 2.4.2 of the AmbiqSuite Development Package.
;
;******************************************************************************
;******************************************************************************
;
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
;************************************************************************
Stack EQU 0x00000400
;******************************************************************************
;
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
;
;******************************************************************************
Heap EQU 0x00000000
;******************************************************************************
;
; Allocate space for the stack.
;
;******************************************************************************
AREA STACK, NOINIT, READWRITE, ALIGN=3
StackMem
SPACE Stack
__initial_sp
;******************************************************************************
;
; Allocate space for the heap.
;
;******************************************************************************
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
HeapMem
SPACE Heap
__heap_limit
;******************************************************************************
;
; Indicate that the code in this file preserves 8-byte alignment of the stack.
;
;******************************************************************************
PRESERVE8
;******************************************************************************
;
; Place code into the reset code section.
;
;******************************************************************************
AREA RESET, CODE, READONLY
THUMB
;******************************************************************************
;
; The vector table.
;
;******************************************************************************
;
; Note: Aliasing and weakly exporting am_mpufault_isr, am_busfault_isr, and
; am_usagefault_isr does not work if am_fault_isr is defined externally.
; Therefore, we'll explicitly use am_fault_isr in the table for those vectors.
;
EXPORT __Vectors
__Vectors
DCD StackMem + Stack ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD am_nmi_isr ; NMI Handler
DCD am_fault_isr ; Hard Fault Handler
DCD am_fault_isr ; The MPU fault handler
DCD am_fault_isr ; The bus fault handler
DCD am_fault_isr ; The usage fault handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD am_svcall_isr ; SVCall handler
DCD am_debugmon_isr ; Debug monitor handler
DCD 0 ; Reserved
DCD am_pendsv_isr ; The PendSV handler
DCD am_systick_isr ; The SysTick handler
;
; Peripheral Interrupts
;
DCD am_brownout_isr ; 0: Reserved
DCD am_watchdog_isr ; 1: Reserved
DCD am_clkgen_isr ; 2: CLKGEN
DCD am_vcomp_isr ; 3: Voltage Comparator
DCD am_ioslave_ios_isr ; 4: I/O Slave general
DCD am_ioslave_acc_isr ; 5: I/O Slave access
DCD am_iomaster0_isr ; 6: I/O Master 0
DCD am_iomaster1_isr ; 7: I/O Master 1
DCD am_adc_isr ; 8: Reserved
DCD am_gpio_isr ; 9: GPIO
DCD am_ctimer_isr ; 10: CTIMER
DCD am_uart_isr ; 11: UART
__Vectors_End
__Vectors_Size EQU __Vectors_End - __Vectors
;******************************************************************************
;
; This is the code that gets called when the processor first starts execution
; following a reset event.
;
;******************************************************************************
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
;
; Enable the FPU.
;
MOVW R0, #0xED88
MOVT R0, #0xE000
LDR R1, [R0]
ORR R1, #0x00F00000
STR R1, [R0]
DSB
ISB
;
; Branch to main.
;
LDR R0, =__main
BX R0
ENDP
;******************************************************************************
;
; Weak Exception Handlers.
;
;******************************************************************************
am_nmi_isr PROC
EXPORT am_nmi_isr [WEAK]
B .
ENDP
am_fault_isr\
PROC
EXPORT am_fault_isr [WEAK]
B .
ENDP
am_memmanage_isr\
PROC
EXPORT am_memmanage_isr [WEAK]
B .
ENDP
am_default_isr\
PROC
EXPORT am_svcall_isr [WEAK]
EXPORT am_debugmon_isr [WEAK]
EXPORT am_pendsv_isr [WEAK]
EXPORT am_systick_isr [WEAK]
EXPORT am_brownout_isr [WEAK]
EXPORT am_adc_isr [WEAK]
EXPORT am_watchdog_isr [WEAK]
EXPORT am_clkgen_isr [WEAK]
EXPORT am_vcomp_isr [WEAK]
EXPORT am_ioslave_ios_isr [WEAK]
EXPORT am_ioslave_acc_isr [WEAK]
EXPORT am_iomaster0_isr [WEAK]
EXPORT am_iomaster1_isr [WEAK]
EXPORT am_gpio_isr [WEAK]
EXPORT am_ctimer_isr [WEAK]
EXPORT am_uart_isr [WEAK]
am_svcall_isr
am_debugmon_isr
am_pendsv_isr
am_systick_isr
am_brownout_isr
am_adc_isr
am_watchdog_isr
am_clkgen_isr
am_vcomp_isr
am_ioslave_ios_isr
am_ioslave_acc_isr
am_iomaster0_isr
am_iomaster1_isr
am_gpio_isr
am_ctimer_isr
am_uart_isr
; all device interrupts go here unless the weak label is over
; ridden in the linker hard spin so the debugger will know it
; was an unhandled interrupt request a come-from-buffer or
; instruction trace hardware would sure be nice if you get here
B .
ENDP
;******************************************************************************
;
; Align the end of the section.
;
;******************************************************************************
ALIGN
;******************************************************************************
;
; Initialization of the heap and stack.
;
;******************************************************************************
AREA |.text|, CODE, READONLY
;******************************************************************************
;
; User Initial Stack & Heap.
;
;******************************************************************************
IF :DEF: __MICROLIB
EXPORT __initial_sp
EXPORT __heap_base
EXPORT __heap_limit
ELSE
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap PROC
LDR R0, =HeapMem
LDR R1, =(StackMem + Stack)
LDR R2, =(HeapMem + Heap)
LDR R3, =StackMem
BX LR
ENDP
ENDIF
;******************************************************************************
;
; Align the end of the section.
;
;******************************************************************************
ALIGN
;******************************************************************************
;
; All Done
;
;******************************************************************************
END

View File

@ -0,0 +1,350 @@
;******************************************************************************
;
;! @file startup_apollo2.s
;!
;! @brief Definitions for Apollo2 interrupt handlers, the vector table, and the stack.
;
;******************************************************************************
;******************************************************************************
;
; Copyright (c) 2020, Ambiq Micro
; All rights reserved.
;
; 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 of the copyright holder nor the names of its
; contributors may be used to endorse or promote products derived from this
; software without specific prior written permission.
;
; Third party software included in this distribution is subject to the
; additional license terms as defined in the /docs/licenses directory.
;
; 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 HOLDER 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.
;
; This is part of revision 2.4.2 of the AmbiqSuite Development Package.
;
;******************************************************************************
;******************************************************************************
;
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
;************************************************************************
Stack EQU 0x00000400
;******************************************************************************
;
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
;
;******************************************************************************
Heap EQU 0x00000000
;******************************************************************************
;
; Allocate space for the stack.
;
;******************************************************************************
AREA STACK, NOINIT, READWRITE, ALIGN=3
StackMem
SPACE Stack
__initial_sp
;******************************************************************************
;
; Allocate space for the heap.
;
;******************************************************************************
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
HeapMem
SPACE Heap
__heap_limit
;******************************************************************************
;
; Indicate that the code in this file preserves 8-byte alignment of the stack.
;
;******************************************************************************
PRESERVE8
;******************************************************************************
;
; Place code into the reset code section.
;
;******************************************************************************
AREA RESET, CODE, READONLY
THUMB
;******************************************************************************
;
; The vector table.
;
;******************************************************************************
;
; Note: Aliasing and weakly exporting am_mpufault_isr, am_busfault_isr, and
; am_usagefault_isr does not work if am_fault_isr is defined externally.
; Therefore, we'll explicitly use am_fault_isr in the table for those vectors.
;
EXPORT __Vectors
__Vectors
DCD StackMem + Stack ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD am_nmi_isr ; NMI Handler
DCD am_fault_isr ; Hard Fault Handler
DCD am_fault_isr ; The MPU fault handler
DCD am_fault_isr ; The bus fault handler
DCD am_fault_isr ; The usage fault handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD am_svcall_isr ; SVCall handler
DCD am_debugmon_isr ; Debug monitor handler
DCD 0 ; Reserved
DCD am_pendsv_isr ; The PendSV handler
DCD am_systick_isr ; The SysTick handler
;
; Peripheral Interrupts
;
DCD am_brownout_isr ; 0: Reserved
DCD am_watchdog_isr ; 1: Reserved
DCD am_clkgen_isr ; 2: CLKGEN
DCD am_vcomp_isr ; 3: Voltage Comparator
DCD am_ioslave_ios_isr ; 4: I/O Slave general
DCD am_ioslave_acc_isr ; 5: I/O Slave access
DCD am_iomaster0_isr ; 6: I/O Master 0
DCD am_iomaster1_isr ; 7: I/O Master 1
DCD am_iomaster2_isr ; 8: I/O Master 2
DCD am_iomaster3_isr ; 9: I/O Master 3
DCD am_iomaster4_isr ; 10: I/O Master 4
DCD am_iomaster5_isr ; 11: I/O Master 5
DCD am_gpio_isr ; 12: GPIO
DCD am_ctimer_isr ; 13: CTIMER
DCD am_uart_isr ; 14: UART0
DCD am_uart1_isr ; 15: UART1
DCD am_adc_isr ; 16: ADC
DCD am_pdm0_isr ; 17: PDM
DCD am_stimer_isr ; 18: SYSTEM TIMER
DCD am_stimer_cmpr0_isr ; 19: SYSTEM TIMER COMPARE0
DCD am_stimer_cmpr1_isr ; 20: SYSTEM TIMER COMPARE1
DCD am_stimer_cmpr2_isr ; 21: SYSTEM TIMER COMPARE2
DCD am_stimer_cmpr3_isr ; 22: SYSTEM TIMER COMPARE3
DCD am_stimer_cmpr4_isr ; 23: SYSTEM TIMER COMPARE4
DCD am_stimer_cmpr5_isr ; 24: SYSTEM TIMER COMPARE5
DCD am_stimer_cmpr6_isr ; 25: SYSTEM TIMER COMPARE6
DCD am_stimer_cmpr7_isr ; 26: SYSTEM TIMER COMPARE7
DCD am_flash_isr ; 27: FLASH
DCD am_software0_isr ; 28: SOFTWARE0
DCD am_software1_isr ; 29: SOFTWARE1
DCD am_software2_isr ; 30: SOFTWARE2
DCD am_software3_isr ; 31: SOFTWARE3
__Vectors_End
__Vectors_Size EQU __Vectors_End - __Vectors
;******************************************************************************
;
; This is the code that gets called when the processor first starts execution
; following a reset event.
;
;******************************************************************************
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
;
; Enable the FPU.
;
MOVW R0, #0xED88
MOVT R0, #0xE000
LDR R1, [R0]
ORR R1, #0x00F00000
STR R1, [R0]
DSB
ISB
;
; Branch to main.
;
LDR R0, =__main
BX R0
ENDP
;******************************************************************************
;
; Weak Exception Handlers.
;
;******************************************************************************
am_nmi_isr PROC
EXPORT am_nmi_isr [WEAK]
B .
ENDP
am_fault_isr\
PROC
EXPORT am_fault_isr [WEAK]
B .
ENDP
am_memmanage_isr\
PROC
EXPORT am_memmanage_isr [WEAK]
B .
ENDP
am_default_isr\
PROC
EXPORT am_svcall_isr [WEAK]
EXPORT am_debugmon_isr [WEAK]
EXPORT am_pendsv_isr [WEAK]
EXPORT am_systick_isr [WEAK]
EXPORT am_brownout_isr [WEAK]
EXPORT am_adc_isr [WEAK]
EXPORT am_watchdog_isr [WEAK]
EXPORT am_clkgen_isr [WEAK]
EXPORT am_vcomp_isr [WEAK]
EXPORT am_ioslave_ios_isr [WEAK]
EXPORT am_ioslave_acc_isr [WEAK]
EXPORT am_iomaster0_isr [WEAK]
EXPORT am_iomaster1_isr [WEAK]
EXPORT am_iomaster2_isr [WEAK]
EXPORT am_iomaster3_isr [WEAK]
EXPORT am_iomaster4_isr [WEAK]
EXPORT am_iomaster5_isr [WEAK]
EXPORT am_gpio_isr [WEAK]
EXPORT am_ctimer_isr [WEAK]
EXPORT am_uart_isr [WEAK]
EXPORT am_uart0_isr [WEAK]
EXPORT am_uart1_isr [WEAK]
EXPORT am_pdm0_isr [WEAK]
EXPORT am_stimer_isr [WEAK]
EXPORT am_stimer_cmpr0_isr [WEAK]
EXPORT am_stimer_cmpr1_isr [WEAK]
EXPORT am_stimer_cmpr2_isr [WEAK]
EXPORT am_stimer_cmpr3_isr [WEAK]
EXPORT am_stimer_cmpr4_isr [WEAK]
EXPORT am_stimer_cmpr5_isr [WEAK]
EXPORT am_stimer_cmpr6_isr [WEAK]
EXPORT am_stimer_cmpr7_isr [WEAK]
EXPORT am_flash_isr [WEAK]
EXPORT am_software0_isr [WEAK]
EXPORT am_software1_isr [WEAK]
EXPORT am_software2_isr [WEAK]
EXPORT am_software3_isr [WEAK]
am_svcall_isr
am_debugmon_isr
am_pendsv_isr
am_systick_isr
am_brownout_isr
am_adc_isr
am_watchdog_isr
am_clkgen_isr
am_vcomp_isr
am_ioslave_ios_isr
am_ioslave_acc_isr
am_iomaster0_isr
am_iomaster1_isr
am_iomaster2_isr
am_iomaster3_isr
am_iomaster4_isr
am_iomaster5_isr
am_gpio_isr
am_ctimer_isr
am_uart_isr
am_uart0_isr
am_uart1_isr
am_pdm0_isr
am_stimer_isr
am_stimer_cmpr0_isr
am_stimer_cmpr1_isr
am_stimer_cmpr2_isr
am_stimer_cmpr3_isr
am_stimer_cmpr4_isr
am_stimer_cmpr5_isr
am_stimer_cmpr6_isr
am_stimer_cmpr7_isr
am_flash_isr
am_software0_isr
am_software1_isr
am_software2_isr
am_software3_isr
; all device interrupts go here unless the weak label is over
; ridden in the linker hard spin so the debugger will know it
; was an unhandled interrupt request a come-from-buffer or
; instruction trace hardware would sure be nice if you get here
B .
ENDP
;******************************************************************************
;
; Align the end of the section.
;
;******************************************************************************
ALIGN
;******************************************************************************
;
; Initialization of the heap and stack.
;
;******************************************************************************
AREA |.text|, CODE, READONLY
;******************************************************************************
;
; User Initial Stack & Heap.
;
;******************************************************************************
IF :DEF: __MICROLIB
EXPORT __initial_sp
EXPORT __heap_base
EXPORT __heap_limit
ELSE
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap PROC
LDR R0, =HeapMem
LDR R1, =(StackMem + Stack)
LDR R2, =(HeapMem + Heap)
LDR R3, =StackMem
BX LR
ENDP
ENDIF
;******************************************************************************
;
; Align the end of the section.
;
;******************************************************************************
ALIGN
;******************************************************************************
;
; All Done
;
;******************************************************************************
END

View File

@ -0,0 +1,408 @@
;******************************************************************************
;
;! @file startup_apollo3.s
;!
;! @brief Definitions for Apollo3 interrupt handlers, the vector table, and the stack.
;
;******************************************************************************
;******************************************************************************
;
; Copyright (c) 2020, Ambiq Micro
; All rights reserved.
;
; 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 of the copyright holder nor the names of its
; contributors may be used to endorse or promote products derived from this
; software without specific prior written permission.
;
; Third party software included in this distribution is subject to the
; additional license terms as defined in the /docs/licenses directory.
;
; 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 HOLDER 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.
;
; This is part of revision 2.4.2 of the AmbiqSuite Development Package.
;
;******************************************************************************
;******************************************************************************
;
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
;************************************************************************
Stack EQU 0x00001000
;******************************************************************************
;
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
;
;******************************************************************************
Heap EQU 0x00000000
;******************************************************************************
;
; Allocate space for the stack.
;
;******************************************************************************
AREA STACK, NOINIT, READWRITE, ALIGN=3
StackMem
SPACE Stack
__initial_sp
;******************************************************************************
;
; Allocate space for the heap.
;
;******************************************************************************
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
HeapMem
SPACE Heap
__heap_limit
;******************************************************************************
;
; Indicate that the code in this file preserves 8-byte alignment of the stack.
;
;******************************************************************************
PRESERVE8
;******************************************************************************
;
; Place code into the reset code section.
;
;******************************************************************************
AREA RESET, CODE, READONLY
THUMB
;******************************************************************************
;
; The vector table.
;
;******************************************************************************
;
; Note: Aliasing and weakly exporting am_mpufault_isr, am_busfault_isr, and
; am_usagefault_isr does not work if am_fault_isr is defined externally.
; Therefore, we'll explicitly use am_fault_isr in the table for those vectors.
;
EXPORT __Vectors
__Vectors
DCD StackMem + Stack ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; The MPU fault handler
DCD BusFault_Handler ; The bus fault handler
DCD UsageFault_Handler ; The usage fault handler
DCD SecureFault_Handler ; Secure fault handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall handler
DCD DebugMon_Handler ; Debug monitor handler
DCD 0 ; Reserved
DCD PendSV_Handler ; The PendSV handler
DCD SysTick_Handler ; The SysTick handler
;
; Peripheral Interrupts
;
DCD am_brownout_isr ; 0: Reserved
DCD am_watchdog_isr ; 1: Reserved
DCD am_rtc_isr ; 2: RTC
DCD am_vcomp_isr ; 3: Voltage Comparator
DCD am_ioslave_ios_isr ; 4: I/O Slave general
DCD am_ioslave_acc_isr ; 5: I/O Slave access
DCD am_iomaster0_isr ; 6: I/O Master 0
DCD am_iomaster1_isr ; 7: I/O Master 1
DCD am_iomaster2_isr ; 8: I/O Master 2
DCD am_iomaster3_isr ; 9: I/O Master 3
DCD am_iomaster4_isr ; 10: I/O Master 4
DCD am_iomaster5_isr ; 11: I/O Master 5
DCD am_ble_isr ; 12: BLEIF
DCD am_gpio_isr ; 13: GPIO
DCD am_ctimer_isr ; 14: CTIMER
DCD am_uart_isr ; 15: UART0
DCD am_uart1_isr ; 16: UART1
DCD am_scard_isr ; 17: SCARD
DCD am_adc_isr ; 18: ADC
DCD am_pdm0_isr ; 19: PDM
DCD am_mspi0_isr ; 20: MSPI0
DCD am_software0_isr ; 21: SOFTWARE0
DCD am_stimer_isr ; 22: SYSTEM TIMER
DCD am_stimer_cmpr0_isr ; 23: SYSTEM TIMER COMPARE0
DCD am_stimer_cmpr1_isr ; 24: SYSTEM TIMER COMPARE1
DCD am_stimer_cmpr2_isr ; 25: SYSTEM TIMER COMPARE2
DCD am_stimer_cmpr3_isr ; 26: SYSTEM TIMER COMPARE3
DCD am_stimer_cmpr4_isr ; 27: SYSTEM TIMER COMPARE4
DCD am_stimer_cmpr5_isr ; 28: SYSTEM TIMER COMPARE5
DCD am_stimer_cmpr6_isr ; 29: SYSTEM TIMER COMPARE6
DCD am_stimer_cmpr7_isr ; 30: SYSTEM TIMER COMPARE7
DCD am_clkgen_isr ; 31: CLKGEN
__Vectors_End
__Vectors_Size EQU __Vectors_End - __Vectors
;******************************************************************************
;
; Place code immediately following vector table.
;
;******************************************************************************
;******************************************************************************
;
; The Patch table.
;
; The patch table should pad the vector table size to a total of 64 entries
; (16 core + 48 periph) such that code begins at offset 0x100.
;
;******************************************************************************
EXPORT __Patchable
__Patchable
DCD 0 ; 32
DCD 0 ; 33
DCD 0 ; 34
DCD 0 ; 35
DCD 0 ; 36
DCD 0 ; 37
DCD 0 ; 38
DCD 0 ; 39
DCD 0 ; 40
DCD 0 ; 41
DCD 0 ; 42
DCD 0 ; 43
DCD 0 ; 44
DCD 0 ; 45
DCD 0 ; 46
DCD 0 ; 47
;******************************************************************************
;
; This is the code that gets called when the processor first starts execution
; following a reset event.
;
;******************************************************************************
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
;
; Enable the FPU.
;
MOVW R0, #0xED88
MOVT R0, #0xE000
LDR R1, [R0]
ORR R1, #0x00F00000
STR R1, [R0]
DSB
ISB
;
; Branch to main.
;
LDR R0, =__main
BX R0
ENDP
;******************************************************************************
;
; Weak Exception Handlers.
;
;******************************************************************************
HardFault_Handler\
PROC
EXPORT HardFault_Handler [WEAK]
B .
ENDP
NMI_Handler PROC
EXPORT NMI_Handler [WEAK]
B .
ENDP
MemManage_Handler\
PROC
EXPORT MemManage_Handler [WEAK]
B .
ENDP
BusFault_Handler\
PROC
EXPORT BusFault_Handler [WEAK]
B .
ENDP
UsageFault_Handler\
PROC
EXPORT UsageFault_Handler [WEAK]
B .
ENDP
SecureFault_Handler\
PROC
EXPORT SecureFault_Handler [WEAK]
B .
ENDP
SVC_Handler PROC
EXPORT SVC_Handler [WEAK]
B .
ENDP
DebugMon_Handler PROC
EXPORT DebugMon_Handler [WEAK]
B .
ENDP
PendSV_Handler PROC
EXPORT PendSV_Handler [WEAK]
B .
ENDP
SysTick_Handler PROC
EXPORT SysTick_Handler [WEAK]
B .
ENDP
am_default_isr\
PROC
EXPORT am_brownout_isr [WEAK]
EXPORT am_watchdog_isr [WEAK]
EXPORT am_rtc_isr [WEAK]
EXPORT am_vcomp_isr [WEAK]
EXPORT am_ioslave_ios_isr [WEAK]
EXPORT am_ioslave_acc_isr [WEAK]
EXPORT am_iomaster0_isr [WEAK]
EXPORT am_iomaster1_isr [WEAK]
EXPORT am_iomaster2_isr [WEAK]
EXPORT am_iomaster3_isr [WEAK]
EXPORT am_iomaster4_isr [WEAK]
EXPORT am_iomaster5_isr [WEAK]
EXPORT am_ble_isr [WEAK]
EXPORT am_gpio_isr [WEAK]
EXPORT am_ctimer_isr [WEAK]
EXPORT am_uart_isr [WEAK]
EXPORT am_uart0_isr [WEAK]
EXPORT am_uart1_isr [WEAK]
EXPORT am_scard_isr [WEAK]
EXPORT am_adc_isr [WEAK]
EXPORT am_pdm0_isr [WEAK]
EXPORT am_mspi0_isr [WEAK]
EXPORT am_software0_isr [WEAK]
EXPORT am_stimer_isr [WEAK]
EXPORT am_stimer_cmpr0_isr [WEAK]
EXPORT am_stimer_cmpr1_isr [WEAK]
EXPORT am_stimer_cmpr2_isr [WEAK]
EXPORT am_stimer_cmpr3_isr [WEAK]
EXPORT am_stimer_cmpr4_isr [WEAK]
EXPORT am_stimer_cmpr5_isr [WEAK]
EXPORT am_stimer_cmpr6_isr [WEAK]
EXPORT am_stimer_cmpr7_isr [WEAK]
EXPORT am_clkgen_isr [WEAK]
am_brownout_isr
am_watchdog_isr
am_rtc_isr
am_vcomp_isr
am_ioslave_ios_isr
am_ioslave_acc_isr
am_iomaster0_isr
am_iomaster1_isr
am_iomaster2_isr
am_iomaster3_isr
am_iomaster4_isr
am_iomaster5_isr
am_ble_isr
am_gpio_isr
am_ctimer_isr
am_uart_isr
am_uart0_isr
am_uart1_isr
am_scard_isr
am_adc_isr
am_pdm0_isr
am_mspi0_isr
am_software0_isr
am_stimer_isr
am_stimer_cmpr0_isr
am_stimer_cmpr1_isr
am_stimer_cmpr2_isr
am_stimer_cmpr3_isr
am_stimer_cmpr4_isr
am_stimer_cmpr5_isr
am_stimer_cmpr6_isr
am_stimer_cmpr7_isr
am_clkgen_isr
; all device interrupts go here unless the weak label is over
; ridden in the linker hard spin so the debugger will know it
; was an unhandled interrupt request a come-from-buffer or
; instruction trace hardware would sure be nice if you get here
B .
ENDP
;******************************************************************************
;
; Align the end of the section.
;
;******************************************************************************
ALIGN
;******************************************************************************
;
; Initialization of the heap and stack.
;
;******************************************************************************
AREA |.text|, CODE, READONLY
;******************************************************************************
;
; User Initial Stack & Heap.
;
;******************************************************************************
IF :DEF: __MICROLIB
EXPORT __initial_sp
EXPORT __heap_base
EXPORT __heap_limit
ELSE
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap PROC
LDR R0, =HeapMem
LDR R1, =(StackMem + Stack)
LDR R2, =(HeapMem + Heap)
LDR R3, =StackMem
BX LR
ENDP
ENDIF
;******************************************************************************
;
; Align the end of the section.
;
;******************************************************************************
ALIGN
;******************************************************************************
;
; All Done
;
;******************************************************************************
END

View File

@ -0,0 +1,412 @@
;******************************************************************************
;
;! @file startup_apollo3.s
;!
;! @brief Definitions for Apollo3 interrupt handlers, the vector table, and the stack.
;
;******************************************************************************
;******************************************************************************
;
; Copyright (c) 2020, Ambiq Micro
; All rights reserved.
;
; 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 of the copyright holder nor the names of its
; contributors may be used to endorse or promote products derived from this
; software without specific prior written permission.
;
; Third party software included in this distribution is subject to the
; additional license terms as defined in the /docs/licenses directory.
;
; 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 HOLDER 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.
;
; This is part of revision 2.4.2 of the AmbiqSuite Development Package.
;
;******************************************************************************
;******************************************************************************
;
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
;************************************************************************
Stack EQU 0x00001000
;******************************************************************************
;
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
;
;******************************************************************************
Heap EQU 0x00000000
;******************************************************************************
;
; Allocate space for the stack.
;
;******************************************************************************
AREA STACK, NOINIT, READWRITE, ALIGN=3
StackMem
SPACE Stack
__initial_sp
;******************************************************************************
;
; Allocate space for the heap.
;
;******************************************************************************
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
HeapMem
SPACE Heap
__heap_limit
;******************************************************************************
;
; Indicate that the code in this file preserves 8-byte alignment of the stack.
;
;******************************************************************************
PRESERVE8
;******************************************************************************
;
; Place code into the reset code section.
;
;******************************************************************************
AREA RESET, CODE, READONLY
THUMB
;******************************************************************************
;
; The vector table.
;
;******************************************************************************
;
; Note: Aliasing and weakly exporting am_mpufault_isr, am_busfault_isr, and
; am_usagefault_isr does not work if am_fault_isr is defined externally.
; Therefore, we'll explicitly use am_fault_isr in the table for those vectors.
;
EXPORT __Vectors
__Vectors
DCD StackMem + Stack ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; The MPU fault handler
DCD BusFault_Handler ; The bus fault handler
DCD UsageFault_Handler ; The usage fault handler
DCD SecureFault_Handler ; Secure fault handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall handler
DCD DebugMon_Handler ; Debug monitor handler
DCD 0 ; Reserved
DCD PendSV_Handler ; The PendSV handler
DCD SysTick_Handler ; The SysTick handler
;
; Peripheral Interrupts
;
DCD am_brownout_isr ; 0: Reserved
DCD am_watchdog_isr ; 1: Reserved
DCD am_rtc_isr ; 2: RTC
DCD am_vcomp_isr ; 3: Voltage Comparator
DCD am_ioslave_ios_isr ; 4: I/O Slave general
DCD am_ioslave_acc_isr ; 5: I/O Slave access
DCD am_iomaster0_isr ; 6: I/O Master 0
DCD am_iomaster1_isr ; 7: I/O Master 1
DCD am_iomaster2_isr ; 8: I/O Master 2
DCD am_iomaster3_isr ; 9: I/O Master 3
DCD am_iomaster4_isr ; 10: I/O Master 4
DCD am_iomaster5_isr ; 11: I/O Master 5
DCD am_ble_isr ; 12: BLEIF
DCD am_gpio_isr ; 13: GPIO
DCD am_ctimer_isr ; 14: CTIMER
DCD am_uart_isr ; 15: UART0
DCD am_uart1_isr ; 16: UART1
DCD am_scard_isr ; 17: SCARD
DCD am_adc_isr ; 18: ADC
DCD am_pdm0_isr ; 19: PDM
DCD am_mspi0_isr ; 20: MSPI0
DCD am_software0_isr ; 21: SOFTWARE0
DCD am_stimer_isr ; 22: SYSTEM TIMER
DCD am_stimer_cmpr0_isr ; 23: SYSTEM TIMER COMPARE0
DCD am_stimer_cmpr1_isr ; 24: SYSTEM TIMER COMPARE1
DCD am_stimer_cmpr2_isr ; 25: SYSTEM TIMER COMPARE2
DCD am_stimer_cmpr3_isr ; 26: SYSTEM TIMER COMPARE3
DCD am_stimer_cmpr4_isr ; 27: SYSTEM TIMER COMPARE4
DCD am_stimer_cmpr5_isr ; 28: SYSTEM TIMER COMPARE5
DCD am_stimer_cmpr6_isr ; 29: SYSTEM TIMER COMPARE6
DCD am_stimer_cmpr7_isr ; 30: SYSTEM TIMER COMPARE7
DCD am_clkgen_isr ; 31: CLKGEN
DCD am_mspi1_isr ; 32: MSPI1
DCD am_mspi2_isr ; 33: MSPI2
__Vectors_End
__Vectors_Size EQU __Vectors_End - __Vectors
;******************************************************************************
;
; Place code immediately following vector table.
;
;******************************************************************************
;******************************************************************************
;
; The Patch table.
;
; The patch table should pad the vector table size to a total of 64 entries
; (16 core + 48 periph) such that code begins at offset 0x100.
;
;******************************************************************************
EXPORT __Patchable
__Patchable
DCD 0 ; 34
DCD 0 ; 35
DCD 0 ; 36
DCD 0 ; 37
DCD 0 ; 38
DCD 0 ; 39
DCD 0 ; 40
DCD 0 ; 41
DCD 0 ; 42
DCD 0 ; 43
DCD 0 ; 44
DCD 0 ; 45
DCD 0 ; 46
DCD 0 ; 47
;******************************************************************************
;
; This is the code that gets called when the processor first starts execution
; following a reset event.
;
;******************************************************************************
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
;
; Enable the FPU.
;
MOVW R0, #0xED88
MOVT R0, #0xE000
LDR R1, [R0]
ORR R1, #0x00F00000
STR R1, [R0]
DSB
ISB
;
; Branch to main.
;
LDR R0, =__main
BX R0
ENDP
;******************************************************************************
;
; Weak Exception Handlers.
;
;******************************************************************************
HardFault_Handler\
PROC
EXPORT HardFault_Handler [WEAK]
B .
ENDP
NMI_Handler PROC
EXPORT NMI_Handler [WEAK]
B .
ENDP
MemManage_Handler\
PROC
EXPORT MemManage_Handler [WEAK]
B .
ENDP
BusFault_Handler\
PROC
EXPORT BusFault_Handler [WEAK]
B .
ENDP
UsageFault_Handler\
PROC
EXPORT UsageFault_Handler [WEAK]
B .
ENDP
SecureFault_Handler\
PROC
EXPORT SecureFault_Handler [WEAK]
B .
ENDP
SVC_Handler PROC
EXPORT SVC_Handler [WEAK]
B .
ENDP
DebugMon_Handler PROC
EXPORT DebugMon_Handler [WEAK]
B .
ENDP
PendSV_Handler PROC
EXPORT PendSV_Handler [WEAK]
B .
ENDP
SysTick_Handler PROC
EXPORT SysTick_Handler [WEAK]
B .
ENDP
am_default_isr\
PROC
EXPORT am_brownout_isr [WEAK]
EXPORT am_watchdog_isr [WEAK]
EXPORT am_rtc_isr [WEAK]
EXPORT am_vcomp_isr [WEAK]
EXPORT am_ioslave_ios_isr [WEAK]
EXPORT am_ioslave_acc_isr [WEAK]
EXPORT am_iomaster0_isr [WEAK]
EXPORT am_iomaster1_isr [WEAK]
EXPORT am_iomaster2_isr [WEAK]
EXPORT am_iomaster3_isr [WEAK]
EXPORT am_iomaster4_isr [WEAK]
EXPORT am_iomaster5_isr [WEAK]
EXPORT am_ble_isr [WEAK]
EXPORT am_gpio_isr [WEAK]
EXPORT am_ctimer_isr [WEAK]
EXPORT am_uart_isr [WEAK]
EXPORT am_uart0_isr [WEAK]
EXPORT am_uart1_isr [WEAK]
EXPORT am_scard_isr [WEAK]
EXPORT am_adc_isr [WEAK]
EXPORT am_pdm0_isr [WEAK]
EXPORT am_mspi0_isr [WEAK]
EXPORT am_software0_isr [WEAK]
EXPORT am_stimer_isr [WEAK]
EXPORT am_stimer_cmpr0_isr [WEAK]
EXPORT am_stimer_cmpr1_isr [WEAK]
EXPORT am_stimer_cmpr2_isr [WEAK]
EXPORT am_stimer_cmpr3_isr [WEAK]
EXPORT am_stimer_cmpr4_isr [WEAK]
EXPORT am_stimer_cmpr5_isr [WEAK]
EXPORT am_stimer_cmpr6_isr [WEAK]
EXPORT am_stimer_cmpr7_isr [WEAK]
EXPORT am_clkgen_isr [WEAK]
EXPORT am_mspi1_isr [WEAK]
EXPORT am_mspi2_isr [WEAK]
am_brownout_isr
am_watchdog_isr
am_rtc_isr
am_vcomp_isr
am_ioslave_ios_isr
am_ioslave_acc_isr
am_iomaster0_isr
am_iomaster1_isr
am_iomaster2_isr
am_iomaster3_isr
am_iomaster4_isr
am_iomaster5_isr
am_ble_isr
am_gpio_isr
am_ctimer_isr
am_uart_isr
am_uart0_isr
am_uart1_isr
am_scard_isr
am_adc_isr
am_pdm0_isr
am_mspi0_isr
am_software0_isr
am_stimer_isr
am_stimer_cmpr0_isr
am_stimer_cmpr1_isr
am_stimer_cmpr2_isr
am_stimer_cmpr3_isr
am_stimer_cmpr4_isr
am_stimer_cmpr5_isr
am_stimer_cmpr6_isr
am_stimer_cmpr7_isr
am_clkgen_isr
am_mspi1_isr
am_mspi2_isr
; all device interrupts go here unless the weak label is over
; ridden in the linker hard spin so the debugger will know it
; was an unhandled interrupt request a come-from-buffer or
; instruction trace hardware would sure be nice if you get here
B .
ENDP
;******************************************************************************
;
; Align the end of the section.
;
;******************************************************************************
ALIGN
;******************************************************************************
;
; Initialization of the heap and stack.
;
;******************************************************************************
AREA |.text|, CODE, READONLY
;******************************************************************************
;
; User Initial Stack & Heap.
;
;******************************************************************************
IF :DEF: __MICROLIB
EXPORT __initial_sp
EXPORT __heap_base
EXPORT __heap_limit
ELSE
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap PROC
LDR R0, =HeapMem
LDR R1, =(StackMem + Stack)
LDR R2, =(HeapMem + Heap)
LDR R3, =StackMem
BX LR
ENDP
ENDIF
;******************************************************************************
;
; Align the end of the section.
;
;******************************************************************************
ALIGN
;******************************************************************************
;
; All Done
;
;******************************************************************************
END

View File

@ -0,0 +1,113 @@
//*****************************************************************************
//
//! @file system_apollo1.c
//!
//! @brief Ambiq Micro Apollo1 MCU specific functions.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
//*****************************************************************************
#include <stdint.h>
#include "system_apollo1.h"
#include "apollo1.h"
//*****************************************************************************
//
// Defines
//
//*****************************************************************************
//
// Clocks
//
#define __HSI (6000000UL)
#define __XTAL (32768UL) // Crystal Oscillator frequency
#define __SYS_OSC_CLK (24000000) // Main oscillator frequency
#define __SYSTEM_CLOCK (1*__SYS_OSC_CLK)
//
// Initialize SystemCoreClock with the system core clock frequency value
// achieved after system intitialization.
// This means system core clock frequency after call to SystemInit()
//
uint32_t SystemCoreClock = __SYSTEM_CLOCK; // System Clock Frequency (Core Clock)
//*****************************************************************************
//
//! @brief Set the global clock frequncy.
//!
//! This function sets the global clock frequency.
//!
//! @return None.
//
//*****************************************************************************
void
SystemCoreClockUpdate(void)
{
//
// Calculate the system frequency based upon the current register settings.
// This function can be used to retrieve the system core clock frequeny
// after user changed register sittings.
//
SystemCoreClock = __SYS_OSC_CLK / (CLKGEN->CCTRL_b.CORESEL + 1);
}
//*****************************************************************************
//
//! @brief Initialize the system.
//!
//! This function sets up the microcontroller system.
//!
//! @return None.
//
//*****************************************************************************
void
SystemInit(void)
{
//
// Initialize the system
// Do not use global variables because this function is called before
// reaching pre-main. RW section maybe overwritten afterwards.
//
SystemCoreClock = __SYSTEM_CLOCK;
CLKGEN->CLKKEY = 0x47; // Enable write to CCTRL
CLKGEN->CCTRL_b.CORESEL = 0; // Div by 1 for 24MHz
CLKGEN->CLKKEY = 0; // Disable write to CCTRL
}

View File

@ -0,0 +1,113 @@
//*****************************************************************************
//
//! @file system_apollo2.c
//!
//! @brief Ambiq Micro Apollo2 MCU specific functions.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
//*****************************************************************************
#include <stdint.h>
#include "system_apollo2.h"
#include "apollo2.h"
//*****************************************************************************
//
// Defines
//
//*****************************************************************************
//
// Clocks
//
#define __HSI (6000000UL)
#define __XTAL (32768UL) // Crystal Oscillator frequency
#define __SYS_OSC_CLK (48000000) // Main oscillator frequency
#define __SYSTEM_CLOCK (1*__SYS_OSC_CLK)
//
// Initialize SystemCoreClock with the system core clock frequency value
// achieved after system intitialization.
// This means system core clock frequency after call to SystemInit()
//
uint32_t SystemCoreClock = __SYSTEM_CLOCK; // System Clock Frequency (Core Clock)
//*****************************************************************************
//
//! @brief Set the global clock frequncy.
//!
//! This function sets the global clock frequency.
//!
//! @return None.
//
//*****************************************************************************
void
SystemCoreClockUpdate(void)
{
//
// Calculate the system frequency based upon the current register settings.
// This function can be used to retrieve the system core clock frequeny
// after user changed register sittings.
//
SystemCoreClock = __SYS_OSC_CLK / (CLKGEN->CCTRL_b.CORESEL + 1);
}
//*****************************************************************************
//
//! @brief Initialize the system.
//!
//! This function sets up the microcontroller system.
//!
//! @return None.
//
//*****************************************************************************
void
SystemInit(void)
{
//
// Initialize the system
// Do not use global variables because this function is called before
// reaching pre-main. RW section maybe overwritten afterwards.
//
SystemCoreClock = __SYSTEM_CLOCK;
CLKGEN->CLKKEY = 0x47; // Enable write to CCTRL
CLKGEN->CCTRL_b.CORESEL = 0; // Div by 1 for 48MHz
CLKGEN->CLKKEY = 0; // Disable write to CCTRL
}

View File

@ -0,0 +1,113 @@
//*****************************************************************************
//
//! @file system_apollo3.c
//!
//! @brief Ambiq Micro Apollo3 MCU specific functions.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
//*****************************************************************************
#include <stdint.h>
#include "system_apollo3.h"
#include "apollo3.h"
//*****************************************************************************
//
// Defines
//
//*****************************************************************************
//
// Clocks
//
#define __HSI (6000000UL)
#define __XTAL (32768UL) // Crystal Oscillator frequency
#define __SYS_OSC_CLK (48000000) // Main oscillator frequency
#define __SYSTEM_CLOCK (1*__SYS_OSC_CLK)
//
// Initialize SystemCoreClock with the system core clock frequency value
// achieved after system intitialization.
// This means system core clock frequency after call to SystemInit()
//
uint32_t SystemCoreClock = __SYSTEM_CLOCK; // System Clock Frequency (Core Clock)
//*****************************************************************************
//
//! @brief Set the global clock frequncy.
//!
//! This function sets the global clock frequency.
//!
//! @return None.
//
//*****************************************************************************
void
SystemCoreClockUpdate(void)
{
//
// Calculate the system frequency based upon the current register settings.
// This function can be used to retrieve the system core clock frequeny
// after user changed register sittings.
//
SystemCoreClock = __SYS_OSC_CLK / (CLKGEN->CCTRL_b.CORESEL + 1);
}
//*****************************************************************************
//
//! @brief Initialize the system.
//!
//! This function sets up the microcontroller system.
//!
//! @return None.
//
//*****************************************************************************
void
SystemInit(void)
{
//
// Initialize the system
// Do not use global variables because this function is called before
// reaching pre-main. RW section maybe overwritten afterwards.
//
SystemCoreClock = __SYSTEM_CLOCK;
CLKGEN->CLKKEY = 0x47; // Enable write to CCTRL
CLKGEN->CCTRL_b.CORESEL = 0; // Div by 1 for 48MHz
CLKGEN->CLKKEY = 0; // Disable write to CCTRL
}

View File

@ -0,0 +1,113 @@
//*****************************************************************************
//
//! @file system_apollo3p.c
//!
//! @brief Ambiq Micro Apollo3 Blue Plus MCU specific functions.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
//*****************************************************************************
#include <stdint.h>
#include "system_apollo3.h"
#include "apollo3.h"
//*****************************************************************************
//
// Defines
//
//*****************************************************************************
//
// Clocks
//
#define __HSI (6000000UL)
#define __XTAL (32768UL) // Crystal Oscillator frequency
#define __SYS_OSC_CLK (48000000) // Main oscillator frequency
#define __SYSTEM_CLOCK (1*__SYS_OSC_CLK)
//
// Initialize SystemCoreClock with the system core clock frequency value
// achieved after system intitialization.
// This means system core clock frequency after call to SystemInit()
//
uint32_t SystemCoreClock = __SYSTEM_CLOCK; // System Clock Frequency (Core Clock)
//*****************************************************************************
//
//! @brief Set the global clock frequncy.
//!
//! This function sets the global clock frequency.
//!
//! @return None.
//
//*****************************************************************************
void
SystemCoreClockUpdate(void)
{
//
// Calculate the system frequency based upon the current register settings.
// This function can be used to retrieve the system core clock frequeny
// after user changed register sittings.
//
SystemCoreClock = __SYS_OSC_CLK / (CLKGEN->CCTRL_b.CORESEL + 1);
}
//*****************************************************************************
//
//! @brief Initialize the system.
//!
//! This function sets up the microcontroller system.
//!
//! @return None.
//
//*****************************************************************************
void
SystemInit(void)
{
//
// Initialize the system
// Do not use global variables because this function is called before
// reaching pre-main. RW section maybe overwritten afterwards.
//
SystemCoreClock = __SYSTEM_CLOCK;
CLKGEN->CLKKEY = 0x47; // Enable write to CCTRL
CLKGEN->CCTRL_b.CORESEL = 0; // Div by 1 for 48MHz
CLKGEN->CLKKEY = 0; // Disable write to CCTRL
}

View File

@ -0,0 +1,24 @@
Last updated: August 15, 2019
This file contains origination information about the various
CMSIS header and library files located in this folder.
ARM/Include/:
AmbiqSuite SDK file: Pack Origination:
cmsis*.h CMSIS/5.6.0/CMSIS/Core/Include/
core_cm4.h CMSIS/5.6.0/CMSIS/Core/Include/
mpu_armv7.h CMSIS/5.6.0/CMSIS/Core/Include/
arm_math.h CMSIS/5.6.0/CMSIS/Include/
ARM/Lib/ARM/:
AmbiqSuite SDK file: Pack Origination:
arm_cortexM4lf_math.lib CMSIS/5.6.0/CMSIS/DSP/Lib/ARM/
arm_cortexM4l_math.lib CMSIS/5.6.0/CMSIS/DSP/Lib/ARM/
libarm_cortexM4lf_math.a CMSIS/5.6.0/CMSIS/DSP/Lib/GCC/
libarm_cortexM4l_math.a CMSIS/5.6.0/CMSIS/DSP/Lib/GCC/
iar_cortexM4lf_math.a CMSIS/5.6.0/CMSIS/DSP/Lib/IAR/
iar_cortexM4l_math.a CMSIS/5.6.0/CMSIS/DSP/Lib/IAR/

View File

@ -0,0 +1,127 @@
#******************************************************************************
#
# Makefile - Rules for building the libraries, examples and docs.
#
# Copyright (c) 2020, Ambiq Micro
# All rights reserved.
#
# 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 of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# Third party software included in this distribution is subject to the
# additional license terms as defined in the /docs/licenses directory.
#
# 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 HOLDER 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.
#
# This is part of revision 2.4.2 of the AmbiqSuite Development Package.
#
#******************************************************************************
#******************************************************************************
#
# Target directories.
#
#******************************************************************************
SUBDIRS := $(filter-out tools/ third_party/,$(dir $(wildcard */Makefile)))
HAL := $(dir $(wildcard mcu/*/hal/Makefile))
BSP := $(dir $(wildcard boards/*/bsp/Makefile))
EXAMDIRS := $(dir $(wildcard boards/[!c]*/examples/Makefile))
#******************************************************************************
#
# Build everything.
#
#******************************************************************************
# Use Foreach for job control load average limits to work.
all subdirs: projects
$(foreach subdir,$(SUBDIRS),$(MAKE) -C $(subdir);)
clean: $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $@ $(MAKECMDGOALS)
#******************************************************************************
#
# Build projects for all boards.
#
#******************************************************************************
boards:
$(MAKE) -C boards
#******************************************************************************
#
# Build examples (fast with job control).
#
#******************************************************************************
examdirs: $(EXAMDIRS)
examples:
@$(MAKE) examdirs
$(EXAMDIRS):
$(MAKE) -C $@
#******************************************************************************
#
# Build all BSP libraries.
#
#******************************************************************************
bsp: hal $(BSP)
$(BSP):
$(MAKE) -C $@
#******************************************************************************
#
# Build the HAL.
#
#******************************************************************************
hal: $(HAL)
$(HAL):
$(MAKE) -C $@
#******************************************************************************
#
# Build the doxygen documentation.
#
#******************************************************************************
doxygen doxy:
$(MAKE) -C doxygen quick
doxy-clean:
$(MAKE) -C doxygen clean
#******************************************************************************
#
# Remove build output files.
#
#******************************************************************************
clean: $(SUBDIRS)
.PHONY: all subdirs clean boards
.PHONY: doxygen doxy doxy-clean
.PHONY: svd svd-clean
.PHONY: hal bsp
.PHONY: examples examdirs
.PHONY: ext-build checkout style-check lib-brd-dox failed-build-check
.PHONY: $(SUBDIRS) $(HAL) $(BSP) $(EXAMDIRS)

View File

@ -0,0 +1,62 @@
# AmbiqSuiteSDK
A copy of the AmbiqSuite SDK available on GitHub. Can be used to include AmbiqSuite as a submodule. Can be used to track issues with the SDK, however it is not maintained by AmbiqMicro so the issues may not be resolved upstream.
# Current Version
2.4.2
# Getting Started
First make sure that the necessary tools are available at your command line. They are:
- Git
- ```git```
- Make
- ```make```
- ARM GCC
- ```arm-none-eabi-xxx``` (preferably [8-2018-q4-major](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads#panel2a) - there is a known problem with 8-2019-q3-update for example)
- Python3
- ```python3```
Then follow these steps
```
git clone --recursive https://github.com/sparkfun/AmbiqSuiteSDK
cd AmbiqSuiteSDK
cd boards_sfe/common/examples/{example}/gcc
YOUR_BOARD=redboard_artemis_atp # choose the bsp directory name of the board you want to use
make BOARD=$YOUR_BOARD # build project
make BOARD=$YOUR_BOARD bootload # equivalent to 'bootload_svl'
make BOARD=$YOUR_BOARD bootload_svl # bootloads using the SparkFun Variable Loader
make BOARD=$YOUR_BOARD bootload_asb # bootloads using the Ambiq Secure Bootloader - overwrites SparkFun Variable Loader
```
# Advanced Usage
All the convenient functionality that we've added to the AmbiqSuiteSDK comes from our [SparkFun AmbiqSuite Apollo3 BSPs](https://github.com/sparkfun/SparkFun_Apollo3_AmbiqSuite_BSPs). That repo contains more [detailed documentation for advanced usage](https://github.com/sparkfun/SparkFun_Apollo3_AmbiqSuite_BSPs#advanced-usage).
# Repository Structure
In addition to including the [SparkFun BSPs](https://github.com/sparkfun/SparkFun_Apollo3_AmbiqSuite_BSPs)This repo catalogs information about the AmbiqSuite SDK. Various branches serve different purposes:
### Branch Purposes
Pattern | Use | Addtl. info
---|---|---
master | contains the most up-to-date version of the SDK along with all patches |
mirror | mirrors latest SDK available from AmbiqMicro |
\*-archive | provides an archive of the SDK as released by AmbiqMicro at each version |
\*-patch-\*description| provides a version of the SDK patched beyond AmbiqMicro release
# Submodules
Git submodules can be used to reuse code between repositories. Some special precautions can be necessary when working with them -- most notably the need to clone the contents of submodules explicitly. Here's how to do that:
- If you've already cloned a repo
- ```git submodule update --init --recursive```
- If you are about to clone the repo
- ```git clone --recursive <project url>```
Maintainers of this repo may also need to keep submodules updated.
Here are some more documents about submodules.
- [Working with Submodules by GitHub](https://github.blog/2016-02-01-working-with-submodules/)
- [Git Submodules by gitaarik](https://gist.github.com/gitaarik/8735255)
This repo includes the following git submodules:
- [SparkFun_Apollo3_AmbiqSuite_BSPs](https://github.com/sparkfun/SparkFun_Apollo3_AmbiqSuite_BSPs) : provides board definitions and examples for SparkFun Apollo3 boards

View File

@ -0,0 +1 @@
2.4.2

View File

@ -0,0 +1,113 @@
// ****************************************************************************
//
// amdtp_api.h
//! @file
//!
//! @brief Ambiq Micro's demonstration of AMDTP client.
//!
//! @{
//
// ****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AMDTP_API_H
#define AMDTP_API_H
#include "wsf_os.h"
#ifdef __cplusplus
extern "C" {
#endif
/**************************************************************************************************
Function Declarations
**************************************************************************************************/
/*************************************************************************************************/
/*!
* \fn AmdtpcStart
*
* \brief Start the application.
*
* \return None.
*/
/*************************************************************************************************/
void AmdtpcStart(void);
/*************************************************************************************************/
/*!
* \fn AmdtpcHandlerInit
*
* \brief Application handler init function called during system initialization.
*
* \param handlerID WSF handler ID for App.
*
* \return None.
*/
/*************************************************************************************************/
void AmdtpcHandlerInit(wsfHandlerId_t handlerId);
/*************************************************************************************************/
/*!
* \fn AmdtpcHandler
*
* \brief WSF event handler for the application.
*
* \param event WSF event mask.
* \param pMsg WSF message.
*
* \return None.
*/
/*************************************************************************************************/
void AmdtpcHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg);
void AmdtpcScanStart(void);
void AmdtpcScanStop(void);
void AmdtpcConnOpen(uint8_t idx);
void AmdtpcSendTestData(void);
void AmdtpcSendTestDataStop(void);
void AmdtpcRequestServerSend(void);
void AmdtpcRequestServerSendStop(void);
#ifdef __cplusplus
};
#endif
#endif /* AMDTP_API_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,113 @@
// ****************************************************************************
//
// amdtp_api.h
//! @file
//!
//! @brief Ambiq Micro's demonstration of AMDTP service.
//!
//! @{
//
// ****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AMDTP_API_H
#define AMDTP_API_H
#include "wsf_os.h"
#ifdef __cplusplus
extern "C" {
#endif
/**************************************************************************************************
Macros
**************************************************************************************************/
#ifndef AMDTP_CONN_MAX
#define AMDTP_CONN_MAX 1
#endif
/**************************************************************************************************
Function Declarations
**************************************************************************************************/
/*************************************************************************************************/
/*!
* \fn AmdtpStart
*
* \brief Start the application.
*
* \return None.
*/
/*************************************************************************************************/
void AmdtpStart(void);
/*************************************************************************************************/
/*!
* \fn AmdtpHandlerInit
*
* \brief Application handler init function called during system initialization.
*
* \param handlerID WSF handler ID for App.
*
* \return None.
*/
/*************************************************************************************************/
void AmdtpHandlerInit(wsfHandlerId_t handlerId);
/*************************************************************************************************/
/*!
* \fn AmdtpHandler
*
* \brief WSF event handler for the application.
*
* \param event WSF event mask.
* \param pMsg WSF message.
*
* \return None.
*/
/*************************************************************************************************/
void AmdtpHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg);
#ifdef __cplusplus
};
#endif
#endif /* AMDTP_API_H */

View File

@ -0,0 +1,845 @@
// ****************************************************************************
//
// amdtp_main.c
//! @file
//!
//! @brief Ambiq Micro's demonstration of AMDTP service.
//!
//! @{
//
// ****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <string.h>
#include "wsf_types.h"
#include "bstream.h"
#include "wsf_msg.h"
#include "wsf_trace.h"
#include "hci_api.h"
#include "dm_api.h"
#include "att_api.h"
#include "smp_api.h"
#include "app_api.h"
#include "app_db.h"
#include "app_ui.h"
#include "app_hw.h"
#include "svc_ch.h"
#include "svc_core.h"
#include "svc_dis.h"
#include "amdtp_api.h"
#include "amdtps_api.h"
#include "svc_amdtp.h"
#include "am_util.h"
#include "gatt_api.h"
/**************************************************************************************************
Macros
**************************************************************************************************/
#define MEASURE_THROUGHPUT
/*! WSF message event starting value */
#define AMDTP_MSG_START 0xA0
/*! WSF message event enumeration */
enum
{
AMDTP_TIMER_IND = AMDTP_MSG_START, /*! AMDTP tx timeout timer expired */
#ifdef MEASURE_THROUGHPUT
AMDTP_MEAS_TP_TIMER_IND,
#endif
};
/**************************************************************************************************
Data Types
**************************************************************************************************/
/*! Application message type */
typedef union
{
wsfMsgHdr_t hdr;
dmEvt_t dm;
attsCccEvt_t ccc;
attEvt_t att;
} amdtpMsg_t;
static void amdtpClose(amdtpMsg_t *pMsg);
/**************************************************************************************************
Configurable Parameters
**************************************************************************************************/
/*! configurable parameters for advertising */
static const appAdvCfg_t amdtpAdvCfg =
{
{60000, 0, 0}, /*! Advertising durations in ms */
{ 800, 800, 0} /*! Advertising intervals in 0.625 ms units */
};
/*! configurable parameters for slave */
static const appSlaveCfg_t amdtpSlaveCfg =
{
AMDTP_CONN_MAX, /*! Maximum connections */
};
/*! configurable parameters for security */
static const appSecCfg_t amdtpSecCfg =
{
DM_AUTH_BOND_FLAG | DM_AUTH_SC_FLAG, /*! Authentication and bonding flags */
0, /*! Initiator key distribution flags */
DM_KEY_DIST_LTK, /*! Responder key distribution flags */
FALSE, /*! TRUE if Out-of-band pairing data is present */
FALSE /*! TRUE to initiate security upon connection */
};
/*! configurable parameters for AMDTP connection parameter update */
static const appUpdateCfg_t amdtpUpdateCfg =
{
3000, /*! Connection idle period in ms before attempting
connection parameter update; set to zero to disable */
/* W/A: Apollo2-Blue has issues with interval 7.5ms */
#if defined(AM_PART_APOLLO3) || defined(AM_PART_APOLLO3P)
6, /*! 7.5ms */
15, /*! 18.75ms */
#else
8,
18,
#endif
0, /*! Connection latency */
600, /*! Supervision timeout in 10ms units */
5 /*! Number of update attempts before giving up */
};
/*! SMP security parameter configuration */
static const smpCfg_t amdtpSmpCfg =
{
3000, /*! 'Repeated attempts' timeout in msec */
SMP_IO_NO_IN_NO_OUT, /*! I/O Capability */
7, /*! Minimum encryption key length */
16, /*! Maximum encryption key length */
3, /*! Attempts to trigger 'repeated attempts' timeout */
0, /*! Device authentication requirements */
};
/*! AMDTPS configuration */
static const AmdtpsCfg_t amdtpAmdtpsCfg =
{
0
};
/**************************************************************************************************
Advertising Data
**************************************************************************************************/
/*! advertising data, discoverable mode */
static const uint8_t amdtpAdvDataDisc[] =
{
/*! flags */
2, /*! length */
DM_ADV_TYPE_FLAGS, /*! AD type */
DM_FLAG_LE_GENERAL_DISC | /*! flags */
DM_FLAG_LE_BREDR_NOT_SUP,
/*! tx power */
2, /*! length */
DM_ADV_TYPE_TX_POWER, /*! AD type */
0, /*! tx power */
/*! service UUID list */
3, /*! length */
DM_ADV_TYPE_16_UUID, /*! AD type */
UINT16_TO_BYTES(ATT_UUID_DEVICE_INFO_SERVICE),
17, /*! length */
DM_ADV_TYPE_128_UUID, /*! AD type */
ATT_UUID_AMDTP_SERVICE
};
/*! scan data, discoverable mode */
static const uint8_t amdtpScanDataDisc[] =
{
/*! device name */
6, /*! length */
DM_ADV_TYPE_LOCAL_NAME, /*! AD type */
'A',
'm',
'd',
't',
'p'
};
/**************************************************************************************************
Client Characteristic Configuration Descriptors
**************************************************************************************************/
/*! enumeration of client characteristic configuration descriptors */
enum
{
AMDTP_GATT_SC_CCC_IDX, /*! GATT service, service changed characteristic */
AMDTP_AMDTPS_TX_CCC_IDX, /*! AMDTP service, tx characteristic */
AMDTP_AMDTPS_RX_ACK_CCC_IDX, /*! AMDTP service, rx ack characteristic */
AMDTP_NUM_CCC_IDX
};
/*! client characteristic configuration descriptors settings, indexed by above enumeration */
static const attsCccSet_t amdtpCccSet[AMDTP_NUM_CCC_IDX] =
{
/* cccd handle value range security level */
{GATT_SC_CH_CCC_HDL, ATT_CLIENT_CFG_INDICATE, DM_SEC_LEVEL_NONE}, /* AMDTP_GATT_SC_CCC_IDX */
{AMDTPS_TX_CH_CCC_HDL, ATT_CLIENT_CFG_NOTIFY, DM_SEC_LEVEL_NONE}, /* AMDTP_AMDTPS_TX_CCC_IDX */
{AMDTPS_ACK_CH_CCC_HDL, ATT_CLIENT_CFG_NOTIFY, DM_SEC_LEVEL_NONE} /* AMDTP_AMDTPS_RX_ACK_CCC_IDX */
};
/**************************************************************************************************
Global Variables
**************************************************************************************************/
/*! WSF handler ID */
wsfHandlerId_t amdtpHandlerId;
#ifdef MEASURE_THROUGHPUT
wsfTimer_t measTpTimer;
int gTotalDataBytesRecev = 0;
#endif
/*************************************************************************************************/
/*!
* \fn amdtpDmCback
*
* \brief Application DM callback.
*
* \param pDmEvt DM callback event
*
* \return None.
*/
/*************************************************************************************************/
static void amdtpDmCback(dmEvt_t *pDmEvt)
{
dmEvt_t *pMsg;
uint16_t len;
len = DmSizeOfEvt(pDmEvt);
if ((pMsg = WsfMsgAlloc(len)) != NULL)
{
memcpy(pMsg, pDmEvt, len);
WsfMsgSend(amdtpHandlerId, pMsg);
}
}
/*************************************************************************************************/
/*!
* \fn amdtpAttCback
*
* \brief Application ATT callback.
*
* \param pEvt ATT callback event
*
* \return None.
*/
/*************************************************************************************************/
static void amdtpAttCback(attEvt_t *pEvt)
{
attEvt_t *pMsg;
if ((pMsg = WsfMsgAlloc(sizeof(attEvt_t) + pEvt->valueLen)) != NULL)
{
memcpy(pMsg, pEvt, sizeof(attEvt_t));
pMsg->pValue = (uint8_t *) (pMsg + 1);
memcpy(pMsg->pValue, pEvt->pValue, pEvt->valueLen);
WsfMsgSend(amdtpHandlerId, pMsg);
}
}
/*************************************************************************************************/
/*!
* \fn amdtpCccCback
*
* \brief Application ATTS client characteristic configuration callback.
*
* \param pDmEvt DM callback event
*
* \return None.
*/
/*************************************************************************************************/
static void amdtpCccCback(attsCccEvt_t *pEvt)
{
attsCccEvt_t *pMsg;
appDbHdl_t dbHdl;
/* if CCC not set from initialization and there's a device record */
if ((pEvt->handle != ATT_HANDLE_NONE) &&
((dbHdl = AppDbGetHdl((dmConnId_t) pEvt->hdr.param)) != APP_DB_HDL_NONE))
{
/* store value in device database */
AppDbSetCccTblValue(dbHdl, pEvt->idx, pEvt->value);
}
if ((pMsg = WsfMsgAlloc(sizeof(attsCccEvt_t))) != NULL)
{
memcpy(pMsg, pEvt, sizeof(attsCccEvt_t));
WsfMsgSend(amdtpHandlerId, pMsg);
}
}
static bool sendDataContinuously = false;
static uint32_t counter = 0;
static void AmdtpsSendTestData(void)
{
uint8_t data[1024] = {0};
eAmdtpStatus_t status;
sendDataContinuously = true;
*((uint32_t*)&(data[0])) = counter;
// status = AmdtpsSendPacket(AMDTP_PKT_TYPE_DATA, false, true, data, sizeof(data));
status = AmdtpsSendPacket(AMDTP_PKT_TYPE_DATA, false, false, data, AttGetMtu(1) - 11); //fixme
if (status != AMDTP_STATUS_SUCCESS)
{
APP_TRACE_INFO1("AmdtpsSendTestData() failed, status = %d\n", status);
}
else
{
counter++;
}
}
/*************************************************************************************************/
/*!
* \fn amdtpProcCccState
*
* \brief Process CCC state change.
*
* \param pMsg Pointer to message.
*
* \return None.
*/
/*************************************************************************************************/
bool bPairingCompleted = false;
static void amdtpProcCccState(amdtpMsg_t *pMsg)
{
APP_TRACE_INFO3("ccc state ind value:%d handle:%d idx:%d", pMsg->ccc.value, pMsg->ccc.handle, pMsg->ccc.idx);
/* AMDTPS TX CCC */
if (pMsg->ccc.idx == AMDTP_AMDTPS_TX_CCC_IDX)
{
if (pMsg->ccc.value == ATT_CLIENT_CFG_NOTIFY)
{
// notify enabled
amdtps_start((dmConnId_t)pMsg->ccc.hdr.param, AMDTP_TIMER_IND, AMDTP_AMDTPS_TX_CCC_IDX);
// AppSlaveSecurityeq(1);
// if(bPairingCompleted == true)
{
#if defined(AMDTPS_TXTEST)
counter = 0;
AmdtpsSendTestData(); //fixme
#endif
}
}
else
{
// notify disabled
amdtpClose(pMsg);
amdtps_stop((dmConnId_t)pMsg->ccc.hdr.param);
}
return;
}
}
/*************************************************************************************************/
/*!
* \fn amdtpClose
*
* \brief Perform UI actions on connection close.
*
* \param pMsg Pointer to message.
*
* \return None.
*/
/*************************************************************************************************/
static void amdtpClose(amdtpMsg_t *pMsg)
{
}
/*************************************************************************************************/
/*!
* \fn amdtpSetup
*
* \brief Set up advertising and other procedures that need to be performed after
* device reset.
*
* \param pMsg Pointer to message.
*
* \return None.
*/
/*************************************************************************************************/
static void amdtpSetup(amdtpMsg_t *pMsg)
{
/* set advertising and scan response data for discoverable mode */
AppAdvSetData(APP_ADV_DATA_DISCOVERABLE, sizeof(amdtpAdvDataDisc), (uint8_t *) amdtpAdvDataDisc);
AppAdvSetData(APP_SCAN_DATA_DISCOVERABLE, sizeof(amdtpScanDataDisc), (uint8_t *) amdtpScanDataDisc);
/* set advertising and scan response data for connectable mode */
AppAdvSetData(APP_ADV_DATA_CONNECTABLE, sizeof(amdtpAdvDataDisc), (uint8_t *) amdtpAdvDataDisc);
AppAdvSetData(APP_SCAN_DATA_CONNECTABLE, sizeof(amdtpScanDataDisc), (uint8_t *) amdtpScanDataDisc);
/* start advertising; automatically set connectable/discoverable mode and bondable mode */
AppAdvStart(APP_MODE_AUTO_INIT);
}
/*************************************************************************************************/
/*!
* \fn amdtpBtnCback
*
* \brief Button press callback.
*
* \param btn Button press.
*
* \return None.
*/
/*************************************************************************************************/
static void amdtpBtnCback(uint8_t btn)
{
dmConnId_t connId;
/* button actions when connected */
if ((connId = AppConnIsOpen()) != DM_CONN_ID_NONE)
{
switch (btn)
{
case APP_UI_BTN_1_SHORT:
break;
case APP_UI_BTN_1_MED:
break;
case APP_UI_BTN_1_LONG:
AppConnClose(connId);
break;
case APP_UI_BTN_2_SHORT:
break;
default:
break;
}
}
/* button actions when not connected */
else
{
switch (btn)
{
case APP_UI_BTN_1_SHORT:
/* start or restart advertising */
AppAdvStart(APP_MODE_AUTO_INIT);
break;
case APP_UI_BTN_1_MED:
/* enter discoverable and bondable mode mode */
AppSetBondable(TRUE);
AppAdvStart(APP_MODE_DISCOVERABLE);
break;
case APP_UI_BTN_1_LONG:
/* clear bonded device info and restart advertising */
AppDbDeleteAllRecords();
AppAdvStart(APP_MODE_AUTO_INIT);
break;
default:
break;
}
}
}
#ifdef MEASURE_THROUGHPUT
static void showThroughput(void)
{
APP_TRACE_INFO1("throughput : %d Bytes/s\n", gTotalDataBytesRecev);
gTotalDataBytesRecev = 0;
WsfTimerStartSec(&measTpTimer, 1);
}
#endif
/*************************************************************************************************/
/*!
* \fn amdtpProcMsg
*
* \brief Process messages from the event handler.
*
* \param pMsg Pointer to message.
*
* \return None.
*/
/*************************************************************************************************/
static void amdtpProcMsg(amdtpMsg_t *pMsg)
{
uint8_t uiEvent = APP_UI_NONE;
switch(pMsg->hdr.event)
{
case AMDTP_TIMER_IND:
amdtps_proc_msg(&pMsg->hdr);
break;
#ifdef MEASURE_THROUGHPUT
case AMDTP_MEAS_TP_TIMER_IND:
showThroughput();
break;
#endif
case ATTS_HANDLE_VALUE_CNF:
//APP_TRACE_INFO1("ATTS_HANDLE_VALUE_CNF, status = %d", pMsg->att.hdr.status);
amdtps_proc_msg(&pMsg->hdr);
break;
case ATTS_CCC_STATE_IND:
amdtpProcCccState(pMsg);
break;
case ATT_MTU_UPDATE_IND:
APP_TRACE_INFO1("Negotiated MTU %d", ((attEvt_t *)pMsg)->mtu);
break;
case DM_CONN_DATA_LEN_CHANGE_IND:
APP_TRACE_INFO2("DM_CONN_DATA_LEN_CHANGE_IND, Tx=%d, Rx=%d", ((hciLeDataLenChangeEvt_t*)pMsg)->maxTxOctets, ((hciLeDataLenChangeEvt_t*)pMsg)->maxRxOctets);
//AttcMtuReq((dmConnId_t)(pMsg->hdr.param), 480);//ATT_MAX_MTU);//83); //fixme
break;
case DM_RESET_CMPL_IND:
AttsCalculateDbHash();
DmSecGenerateEccKeyReq();
amdtpSetup(pMsg);
uiEvent = APP_UI_RESET_CMPL;
break;
case DM_ADV_START_IND:
uiEvent = APP_UI_ADV_START;
break;
case DM_ADV_STOP_IND:
uiEvent = APP_UI_ADV_STOP;
break;
case DM_CONN_OPEN_IND:
amdtps_proc_msg(&pMsg->hdr);
// AttcMtuReq((dmConnId_t)(pMsg->hdr.param), ATT_MAX_MTU);//83); //fixme
// hciConnSpec_t connSpec;
// connSpec.connIntervalMin = (7.5/1.25);
// connSpec.connIntervalMax = (15/1.25);
// connSpec.connLatency = 0;
// connSpec.supTimeout = 200;
// connSpec.minCeLen = 4;//0;
// connSpec.maxCeLen = 8;//0xffff; //fixme
// DmConnUpdate(1, &connSpec);
// PDU length, TX interval (0x148 ~ 0x848)
//DmConnSetDataLen(1, 27, 0x148);
DmConnSetDataLen(1, 251, 0x848);
// AppSlaveSecurityReq(1);
uiEvent = APP_UI_CONN_OPEN;
break;
case DM_CONN_CLOSE_IND:
amdtpClose(pMsg);
amdtps_proc_msg(&pMsg->hdr);
APP_TRACE_INFO1("DM_CONN_CLOSE_IND, reason = 0x%x", pMsg->dm.connClose.reason);
uiEvent = APP_UI_CONN_CLOSE;
break;
case DM_CONN_UPDATE_IND:
amdtps_proc_msg(&pMsg->hdr);
break;
case DM_SEC_PAIR_CMPL_IND:
DmSecGenerateEccKeyReq();
uiEvent = APP_UI_SEC_PAIR_CMPL;
bPairingCompleted = true;
break;
case DM_SEC_PAIR_FAIL_IND:
DmSecGenerateEccKeyReq();
APP_TRACE_INFO1("DM_SEC_PAIR_FAIL_IND, status = 0x%x", pMsg->dm.pairCmpl.hdr.status);
bPairingCompleted = false;
uiEvent = APP_UI_SEC_PAIR_FAIL;
break;
case DM_SEC_ENCRYPT_IND:
uiEvent = APP_UI_SEC_ENCRYPT;
break;
case DM_SEC_ENCRYPT_FAIL_IND:
uiEvent = APP_UI_SEC_ENCRYPT_FAIL;
break;
case DM_SEC_AUTH_REQ_IND:
AppHandlePasskey(&pMsg->dm.authReq);
break;
case DM_SEC_ECC_KEY_IND:
DmSecSetEccKey(&pMsg->dm.eccMsg.data.key);
break;
case DM_SEC_COMPARE_IND:
AppHandleNumericComparison(&pMsg->dm.cnfInd);
break;
case DM_HW_ERROR_IND:
uiEvent = APP_UI_HW_ERROR;
break;
case DM_VENDOR_SPEC_CMD_CMPL_IND:
{
#if defined(AM_PART_APOLLO) || defined(AM_PART_APOLLO2)
uint8_t *param_ptr = &pMsg->dm.vendorSpecCmdCmpl.param[0];
switch (pMsg->dm.vendorSpecCmdCmpl.opcode)
{
case 0xFC20: //read at address
{
uint32_t read_value;
BSTREAM_TO_UINT32(read_value, param_ptr);
APP_TRACE_INFO3("VSC 0x%0x complete status %x param %x",
pMsg->dm.vendorSpecCmdCmpl.opcode,
pMsg->hdr.status,
read_value);
}
break;
default:
APP_TRACE_INFO2("VSC 0x%0x complete status %x",
pMsg->dm.vendorSpecCmdCmpl.opcode,
pMsg->hdr.status);
break;
}
#endif
}
break;
default:
break;
}
if (uiEvent != APP_UI_NONE)
{
AppUiAction(uiEvent);
}
}
//
//static void AmdtpsSendTestData(void)
//{
// static uint8_t counter = 0;
// uint8_t data[236] = {0};
// eAmdtpStatus_t status;
//
// sendDataContinuously = true;
// data[1] = counter;
// status = AmdtpsSendPacket(AMDTP_PKT_TYPE_DATA, false, true, data, sizeof(data));
// if (status != AMDTP_STATUS_SUCCESS)
// {
// APP_TRACE_INFO1("AmdtpsSendTestData() failed, status = %d\n", status);
// }
// else
// {
// counter++;
// }
//}
void amdtpDtpRecvCback(uint8_t * buf, uint16_t len)
{
#ifdef MEASURE_THROUGHPUT
static bool measTpStarted = false;
#endif
#if 0
// reception callback
// print the received data
APP_TRACE_INFO0("-----------AMDTP Received data--------------\n");
APP_TRACE_INFO3("len = %d, buf[0] = %d, buf[1] = %d\n", len, buf[0], buf[1]);
#endif
if (buf[0] == 1)
{
APP_TRACE_INFO0("send test data\n");
AmdtpsSendTestData();
}
else if (buf[0] == 2)
{
APP_TRACE_INFO0("send test data stop\n");
sendDataContinuously = false;
}
#ifdef MEASURE_THROUGHPUT
gTotalDataBytesRecev += len;
if (!measTpStarted)
{
measTpStarted = true;
WsfTimerStartSec(&measTpTimer, 1);
}
#endif
}
void amdtpDtpTransCback(eAmdtpStatus_t status)
{
// APP_TRACE_INFO1("amdtpDtpTransCback status = %d\n", status);
if (status == AMDTP_STATUS_SUCCESS && sendDataContinuously)
{
AmdtpsSendTestData();
}
}
/*************************************************************************************************/
/*!
* \fn AmdtpHandlerInit
*
* \brief Application handler init function called during system initialization.
*
* \param handlerID WSF handler ID.
*
* \return None.
*/
/*************************************************************************************************/
void AmdtpHandlerInit(wsfHandlerId_t handlerId)
{
APP_TRACE_INFO0("AmdtpHandlerInit");
/* store handler ID */
amdtpHandlerId = handlerId;
/* Set configuration pointers */
pAppAdvCfg = (appAdvCfg_t *) &amdtpAdvCfg;
pAppSlaveCfg = (appSlaveCfg_t *) &amdtpSlaveCfg;
pAppSecCfg = (appSecCfg_t *) &amdtpSecCfg;
pAppUpdateCfg = (appUpdateCfg_t *) &amdtpUpdateCfg;
/* Initialize application framework */
AppSlaveInit();
AppServerInit();
/* Set stack configuration pointers */
pSmpCfg = (smpCfg_t *) &amdtpSmpCfg;
/* initialize amdtp service server */
amdtps_init(handlerId, (AmdtpsCfg_t *) &amdtpAmdtpsCfg, amdtpDtpRecvCback, amdtpDtpTransCback);
#ifdef MEASURE_THROUGHPUT
measTpTimer.handlerId = handlerId;
measTpTimer.msg.event = AMDTP_MEAS_TP_TIMER_IND;
#endif
}
/*************************************************************************************************/
/*!
* \fn AmdtpHandler
*
* \brief WSF event handler for application.
*
* \param event WSF event mask.
* \param pMsg WSF message.
*
* \return None.
*/
/*************************************************************************************************/
void AmdtpHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg)
{
if (pMsg != NULL)
{
// APP_TRACE_INFO1("Amdtp got evt %d", pMsg->event);
/* process ATT messages */
if (pMsg->event >= ATT_CBACK_START && pMsg->event <= ATT_CBACK_END)
{
/* process server-related ATT messages */
AppServerProcAttMsg(pMsg);
}
/* process DM messages */
else if (pMsg->event >= DM_CBACK_START && pMsg->event <= DM_CBACK_END)
{
/* process advertising and connection-related messages */
AppSlaveProcDmMsg((dmEvt_t *) pMsg);
/* process security-related messages */
AppSlaveSecProcDmMsg((dmEvt_t *) pMsg);
}
/* perform profile and user interface-related operations */
amdtpProcMsg((amdtpMsg_t *) pMsg);
}
}
/*************************************************************************************************/
/*!
* \fn AmdtpStart
*
* \brief Start the application.
*
* \return None.
*/
/*************************************************************************************************/
void AmdtpStart(void)
{
/* Register for stack callbacks */
DmRegister(amdtpDmCback);
DmConnRegister(DM_CLIENT_ID_APP, amdtpDmCback);
AttRegister(amdtpAttCback);
AttConnRegister(AppServerConnCback);
AttsCccRegister(AMDTP_NUM_CCC_IDX, (attsCccSet_t *) amdtpCccSet, amdtpCccCback);
/* Register for app framework callbacks */
AppUiBtnRegister(amdtpBtnCback);
/* Initialize attribute server database */
SvcCoreGattCbackRegister(GattReadCback, GattWriteCback);
SvcCoreAddGroup();
SvcDisAddGroup();
SvcAmdtpsCbackRegister(NULL, amdtps_write_cback);
SvcAmdtpsAddGroup();
/* Set Service Changed CCCD index. */
GattSetSvcChangedIdx(AMDTP_GATT_SC_CCC_IDX);
/* Reset the device */
DmDevReset();
}

View File

@ -0,0 +1,113 @@
// ****************************************************************************
//
// amota_api.h
//! @file
//!
//! @brief Ambiq Micro's demonstration of AMOTA service.
//!
//! @{
//
// ****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AMOTA_API_H
#define AMOTA_API_H
#include "wsf_os.h"
#ifdef __cplusplus
extern "C" {
#endif
/**************************************************************************************************
Macros
**************************************************************************************************/
#ifndef AMOTA_CONN_MAX
#define AMOTA_CONN_MAX 1
#endif
/**************************************************************************************************
Function Declarations
**************************************************************************************************/
/*************************************************************************************************/
/*!
* \fn AmotaStart
*
* \brief Start the application.
*
* \return None.
*/
/*************************************************************************************************/
void AmotaStart(void);
/*************************************************************************************************/
/*!
* \fn AmotaHandlerInit
*
* \brief Application handler init function called during system initialization.
*
* \param handlerID WSF handler ID for App.
*
* \return None.
*/
/*************************************************************************************************/
void AmotaHandlerInit(wsfHandlerId_t handlerId);
/*************************************************************************************************/
/*!
* \fn AmotaHandler
*
* \brief WSF event handler for the application.
*
* \param event WSF event mask.
* \param pMsg WSF message.
*
* \return None.
*/
/*************************************************************************************************/
void AmotaHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg);
#ifdef __cplusplus
};
#endif
#endif /* AMOTA_API_H */

View File

@ -0,0 +1,693 @@
// ****************************************************************************
//
// amota_main.c
//! @file
//!
//! @brief Ambiq Micro's demonstration of AMOTA service.
//!
//! @{
//
// ****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <string.h>
#include "wsf_types.h"
#include "bstream.h"
#include "wsf_msg.h"
#include "wsf_trace.h"
#include "hci_api.h"
#include "dm_api.h"
#include "att_api.h"
#include "app_api.h"
#include "app_db.h"
#include "app_ui.h"
#include "app_hw.h"
#include "svc_ch.h"
#include "svc_core.h"
#include "svc_dis.h"
#include "amota_api.h"
#include "amotas_api.h"
#include "svc_amotas.h"
#include "gatt_api.h"
/**************************************************************************************************
Macros
**************************************************************************************************/
/*! WSF message event starting value */
#define AMOTA_MSG_START 0xA0
/*! WSF message event enumeration */
enum
{
AMOTA_RESET_TIMER_IND = AMOTA_MSG_START, /*! AMOTA reset timer expired */
AMOTA_DISCONNECT_TIMER_IND, /*! AMOTA disconnect timer expired */
};
/**************************************************************************************************
Data Types
**************************************************************************************************/
/*! Application message type */
typedef union
{
wsfMsgHdr_t hdr;
dmEvt_t dm;
attsCccEvt_t ccc;
attEvt_t att;
} amotaMsg_t;
/**************************************************************************************************
Configurable Parameters
**************************************************************************************************/
/*! configurable parameters for advertising */
static const appAdvCfg_t amotaAdvCfg =
{
{ 0, 0, 0}, /*! Advertising durations in ms */
{ 800, 800, 0} /*! Advertising intervals in 0.625 ms units */
};
/*! configurable parameters for slave */
static const appSlaveCfg_t amotaSlaveCfg =
{
AMOTA_CONN_MAX, /*! Maximum connections */
};
/*! configurable parameters for security */
static const appSecCfg_t amotaSecCfg =
{
DM_AUTH_BOND_FLAG, /*! Authentication and bonding flags */
0, /*! Initiator key distribution flags */
DM_KEY_DIST_LTK, /*! Responder key distribution flags */
FALSE, /*! TRUE if Out-of-band pairing data is present */
FALSE /*! TRUE to initiate security upon connection */
};
/*! configurable parameters for AMOTA connection parameter update */
static appUpdateCfg_t otaUpdateCfg =
{
0, /*! Connection idle period in ms before attempting
connection parameter update; set to zero to disable */
(15 / 1.25), /*! 15 ms */
(30 / 1.25), /*! 30 ms */
0, /*! Connection latency */
(6000 / 10), /*! Supervision timeout in 10ms units */
5 /*! Number of update attempts before giving up */
};
/*! AMOTAS configuration */
static const AmotasCfg_t amotasCfg =
{
0
};
/**************************************************************************************************
Advertising Data
**************************************************************************************************/
/*! advertising data, discoverable mode */
static const uint8_t amotaAdvDataDisc[] =
{
/*! flags */
2, /*! length */
DM_ADV_TYPE_FLAGS, /*! AD type */
DM_FLAG_LE_GENERAL_DISC | /*! flags */
DM_FLAG_LE_BREDR_NOT_SUP,
/*! tx power */
2, /*! length */
DM_ADV_TYPE_TX_POWER, /*! AD type */
0, /*! tx power */
/*! service UUID list */
3, /*! length */
DM_ADV_TYPE_16_UUID, /*! AD type */
UINT16_TO_BYTES(ATT_UUID_DEVICE_INFO_SERVICE)
};
/*! scan data, discoverable mode */
static const uint8_t amotaScanDataDisc[] =
{
/*! device name */
15, /*! length */
DM_ADV_TYPE_LOCAL_NAME, /*! AD type */
'a',
'm',
'b',
'i',
'q',
'm',
'i',
'c',
'r',
'o',
' ',
'o',
't',
'a'
};
/**************************************************************************************************
Client Characteristic Configuration Descriptors
**************************************************************************************************/
/*! enumeration of client characteristic configuration descriptors */
enum
{
AMOTA_GATT_SC_CCC_IDX, /*! GATT service, service changed characteristic */
AMOTA_AMOTAS_TX_CCC_IDX, /*! AMOTA service, tx characteristic */
AMOTA_NUM_CCC_IDX
};
/*! client characteristic configuration descriptors settings, indexed by above enumeration */
static const attsCccSet_t amotaCccSet[AMOTA_NUM_CCC_IDX] =
{
/* cccd handle value range security level */
{GATT_SC_CH_CCC_HDL, ATT_CLIENT_CFG_INDICATE, DM_SEC_LEVEL_NONE}, /* AMOTA_GATT_SC_CCC_IDX */
{AMOTAS_TX_CH_CCC_HDL, ATT_CLIENT_CFG_NOTIFY, DM_SEC_LEVEL_NONE} /* AMOTA_AMOTAS_TX_CCC_IDX */
};
/**************************************************************************************************
Global Variables
**************************************************************************************************/
/*! WSF handler ID */
wsfHandlerId_t amotaHandlerId;
/*************************************************************************************************/
/*!
* \fn amotaDmCback
*
* \brief Application DM callback.
*
* \param pDmEvt DM callback event
*
* \return None.
*/
/*************************************************************************************************/
static void amotaDmCback(dmEvt_t *pDmEvt)
{
dmEvt_t *pMsg;
if ((pMsg = WsfMsgAlloc(sizeof(dmEvt_t))) != NULL)
{
memcpy(pMsg, pDmEvt, sizeof(dmEvt_t));
WsfMsgSend(amotaHandlerId, pMsg);
}
}
/*************************************************************************************************/
/*!
* \fn amotaAttCback
*
* \brief Application ATT callback.
*
* \param pEvt ATT callback event
*
* \return None.
*/
/*************************************************************************************************/
static void amotaAttCback(attEvt_t *pEvt)
{
attEvt_t *pMsg;
if ((pMsg = WsfMsgAlloc(sizeof(attEvt_t) + pEvt->valueLen)) != NULL)
{
memcpy(pMsg, pEvt, sizeof(attEvt_t));
pMsg->pValue = (uint8_t *) (pMsg + 1);
memcpy(pMsg->pValue, pEvt->pValue, pEvt->valueLen);
WsfMsgSend(amotaHandlerId, pMsg);
}
}
/*************************************************************************************************/
/*!
* \fn amotaCccCback
*
* \brief Application ATTS client characteristic configuration callback.
*
* \param pDmEvt DM callback event
*
* \return None.
*/
/*************************************************************************************************/
static void amotaCccCback(attsCccEvt_t *pEvt)
{
attsCccEvt_t *pMsg;
appDbHdl_t dbHdl;
/* if CCC not set from initialization and there's a device record */
if ((pEvt->handle != ATT_HANDLE_NONE) &&
((dbHdl = AppDbGetHdl((dmConnId_t) pEvt->hdr.param)) != APP_DB_HDL_NONE))
{
/* store value in device database */
AppDbSetCccTblValue(dbHdl, pEvt->idx, pEvt->value);
}
if ((pMsg = WsfMsgAlloc(sizeof(attsCccEvt_t))) != NULL)
{
memcpy(pMsg, pEvt, sizeof(attsCccEvt_t));
WsfMsgSend(amotaHandlerId, pMsg);
}
}
/*************************************************************************************************/
/*!
* \fn amotaProcCccState
*
* \brief Process CCC state change.
*
* \param pMsg Pointer to message.
*
* \return None.
*/
/*************************************************************************************************/
static void amotaProcCccState(amotaMsg_t *pMsg)
{
APP_TRACE_INFO3("ccc state ind value:%d handle:%d idx:%d", pMsg->ccc.value, pMsg->ccc.handle, pMsg->ccc.idx);
/* handle heart rate measurement CCC */
/* AMOTAS TX CCC */
if (pMsg->ccc.idx == AMOTA_AMOTAS_TX_CCC_IDX)
{
if (pMsg->ccc.value == ATT_CLIENT_CFG_NOTIFY)
{
// notify enabled
amotas_start((dmConnId_t) pMsg->ccc.hdr.param,
AMOTA_RESET_TIMER_IND, AMOTA_DISCONNECT_TIMER_IND,
AMOTA_AMOTAS_TX_CCC_IDX);
}
else
{
// notify disabled
amotas_stop((dmConnId_t) pMsg->ccc.hdr.param);
}
return;
}
}
/*************************************************************************************************/
/*!
* \fn amotaClose
*
* \brief Perform UI actions on connection close.
*
* \param pMsg Pointer to message.
*
* \return None.
*/
/*************************************************************************************************/
static void amotaClose(amotaMsg_t *pMsg)
{
/* stop amotas */
amotas_conn_close((dmConnId_t) pMsg->hdr.param);
}
/*************************************************************************************************/
/*!
* \fn amotaSetup
*
* \brief Set up advertising and other procedures that need to be performed after
* device reset.
*
* \param pMsg Pointer to message.
*
* \return None.
*/
/*************************************************************************************************/
static void amotaSetup(amotaMsg_t *pMsg)
{
/* set advertising and scan response data for discoverable mode */
AppAdvSetData(APP_ADV_DATA_DISCOVERABLE, sizeof(amotaAdvDataDisc), (uint8_t *) amotaAdvDataDisc);
AppAdvSetData(APP_SCAN_DATA_DISCOVERABLE, sizeof(amotaScanDataDisc), (uint8_t *) amotaScanDataDisc);
/* set advertising and scan response data for connectable mode */
AppAdvSetData(APP_ADV_DATA_CONNECTABLE, 0, NULL);
AppAdvSetData(APP_SCAN_DATA_CONNECTABLE, 0, NULL);
/* start advertising; automatically set connectable/discoverable mode and bondable mode */
AppAdvStart(APP_MODE_AUTO_INIT);
}
/*************************************************************************************************/
/*!
* \fn amotaBtnCback
*
* \brief Button press callback.
*
* \param btn Button press.
*
* \return None.
*/
/*************************************************************************************************/
static void amotaBtnCback(uint8_t btn)
{
dmConnId_t connId;
/* button actions when connected */
if ((connId = AppConnIsOpen()) != DM_CONN_ID_NONE)
{
switch (btn)
{
case APP_UI_BTN_1_SHORT:
break;
case APP_UI_BTN_1_MED:
break;
case APP_UI_BTN_1_LONG:
AppConnClose(connId);
break;
case APP_UI_BTN_2_SHORT:
break;
default:
break;
}
}
/* button actions when not connected */
else
{
switch (btn)
{
case APP_UI_BTN_1_SHORT:
/* start or restart advertising */
AppAdvStart(APP_MODE_AUTO_INIT);
break;
case APP_UI_BTN_1_MED:
/* enter discoverable and bondable mode mode */
AppSetBondable(TRUE);
AppAdvStart(APP_MODE_DISCOVERABLE);
break;
case APP_UI_BTN_1_LONG:
/* clear bonded device info and restart advertising */
AppDbDeleteAllRecords();
AppAdvStart(APP_MODE_AUTO_INIT);
break;
default:
break;
}
}
}
/*************************************************************************************************/
/*!
* \fn amotaProcMsg
*
* \brief Process messages from the event handler.
*
* \param pMsg Pointer to message.
*
* \return None.
*/
/*************************************************************************************************/
static void amotaProcMsg(amotaMsg_t *pMsg)
{
uint8_t uiEvent = APP_UI_NONE;
switch(pMsg->hdr.event)
{
case AMOTA_RESET_TIMER_IND:
case AMOTA_DISCONNECT_TIMER_IND:
amotas_proc_msg(&pMsg->hdr);
break;
case ATTS_HANDLE_VALUE_CNF:
break;
case ATTS_CCC_STATE_IND:
amotaProcCccState(pMsg);
break;
case ATT_MTU_UPDATE_IND:
APP_TRACE_INFO1("Negotiated MTU %d", ((attEvt_t *)pMsg)->mtu);
break;
case DM_RESET_CMPL_IND:
AttsCalculateDbHash();
DmSecGenerateEccKeyReq();
amotaSetup(pMsg);
uiEvent = APP_UI_RESET_CMPL;
break;
case DM_ADV_SET_START_IND:
uiEvent = APP_UI_ADV_SET_START_IND;
break;
case DM_ADV_SET_STOP_IND:
uiEvent = APP_UI_ADV_SET_STOP_IND;
break;
case DM_ADV_START_IND:
uiEvent = APP_UI_ADV_START;
break;
case DM_ADV_STOP_IND:
uiEvent = APP_UI_ADV_STOP;
break;
case DM_CONN_OPEN_IND:
amotas_proc_msg(&pMsg->hdr);
uiEvent = APP_UI_CONN_OPEN;
break;
case DM_CONN_CLOSE_IND:
{
hciDisconnectCmplEvt_t *evt = (hciDisconnectCmplEvt_t*) pMsg;
// uiEvent = APP_UI_CONN_CLOSE;
APP_TRACE_INFO1(">>> Connection closed reason 0x%x <<<",
evt->reason);
amotaClose(pMsg);
}
break;
case DM_CONN_UPDATE_IND:
amotas_proc_msg(&pMsg->hdr);
break;
case DM_SEC_PAIR_CMPL_IND:
DmSecGenerateEccKeyReq();
uiEvent = APP_UI_SEC_PAIR_CMPL;
break;
case DM_SEC_PAIR_FAIL_IND:
DmSecGenerateEccKeyReq();
uiEvent = APP_UI_SEC_PAIR_FAIL;
break;
case DM_SEC_ENCRYPT_IND:
uiEvent = APP_UI_SEC_ENCRYPT;
break;
case DM_SEC_ENCRYPT_FAIL_IND:
uiEvent = APP_UI_SEC_ENCRYPT_FAIL;
break;
case DM_SEC_AUTH_REQ_IND:
AppHandlePasskey(&pMsg->dm.authReq);
break;
case DM_SEC_ECC_KEY_IND:
DmSecSetEccKey(&pMsg->dm.eccMsg.data.key);
break;
case DM_SEC_COMPARE_IND:
AppHandleNumericComparison(&pMsg->dm.cnfInd);
break;
case DM_PRIV_CLEAR_RES_LIST_IND:
APP_TRACE_INFO1("Clear resolving list status 0x%02x", pMsg->hdr.status);
break;
case DM_HW_ERROR_IND:
uiEvent = APP_UI_HW_ERROR;
break;
case DM_VENDOR_SPEC_CMD_CMPL_IND:
{
#if defined(AM_PART_APOLLO) || defined(AM_PART_APOLLO2)
uint8_t *param_ptr = &pMsg->dm.vendorSpecCmdCmpl.param[0];
switch (pMsg->dm.vendorSpecCmdCmpl.opcode)
{
case 0xFC20: //read at address
{
uint32_t read_value;
BSTREAM_TO_UINT32(read_value, param_ptr);
APP_TRACE_INFO3("VSC 0x%0x complete status %x param %x",
pMsg->dm.vendorSpecCmdCmpl.opcode,
pMsg->hdr.status,
read_value);
}
break;
default:
APP_TRACE_INFO2("VSC 0x%0x complete status %x",
pMsg->dm.vendorSpecCmdCmpl.opcode,
pMsg->hdr.status);
break;
}
#endif
}
break;
default:
break;
}
if (uiEvent != APP_UI_NONE)
{
AppUiAction(uiEvent);
}
}
/*************************************************************************************************/
/*!
* \fn AmotaHandlerInit
*
* \brief Application handler init function called during system initialization.
*
* \param handlerID WSF handler ID.
*
* \return None.
*/
/*************************************************************************************************/
void AmotaHandlerInit(wsfHandlerId_t handlerId)
{
APP_TRACE_INFO0("AmotaHandlerInit");
/* store handler ID */
amotaHandlerId = handlerId;
/* Set configuration pointers */
pAppAdvCfg = (appAdvCfg_t *) &amotaAdvCfg;
pAppSlaveCfg = (appSlaveCfg_t *) &amotaSlaveCfg;
pAppSecCfg = (appSecCfg_t *) &amotaSecCfg;
pAppUpdateCfg = (appUpdateCfg_t *) &otaUpdateCfg;
/* Initialize application framework */
AppSlaveInit();
AppServerInit();
/* initialize amota service server */
amotas_init(handlerId, (AmotasCfg_t *) &amotasCfg);
}
/*************************************************************************************************/
/*!
* \fn AmotaHandler
*
* \brief WSF event handler for application.
*
* \param event WSF event mask.
* \param pMsg WSF message.
*
* \return None.
*/
/*************************************************************************************************/
void AmotaHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg)
{
if (pMsg != NULL)
{
// APP_TRACE_INFO1("Amota got evt %d", pMsg->event);
/* process ATT messages */
if (pMsg->event >= ATT_CBACK_START && pMsg->event <= ATT_CBACK_END)
{
/* process server-related ATT messages */
AppServerProcAttMsg(pMsg);
}
/* process DM messages */
else if (pMsg->event >= DM_CBACK_START && pMsg->event <= DM_CBACK_END)
{
/* process advertising and connection-related messages */
AppSlaveProcDmMsg((dmEvt_t *) pMsg);
/* process security-related messages */
AppSlaveSecProcDmMsg((dmEvt_t *) pMsg);
}
/* perform profile and user interface-related operations */
amotaProcMsg((amotaMsg_t *) pMsg);
}
}
/*************************************************************************************************/
/*!
* \fn AmotaStart
*
* \brief Start the application.
*
* \return None.
*/
/*************************************************************************************************/
void AmotaStart(void)
{
/* Register for stack callbacks */
DmRegister(amotaDmCback);
DmConnRegister(DM_CLIENT_ID_APP, amotaDmCback);
AttRegister(amotaAttCback);
AttConnRegister(AppServerConnCback);
AttsCccRegister(AMOTA_NUM_CCC_IDX, (attsCccSet_t *) amotaCccSet, amotaCccCback);
/* Register for app framework callbacks */
AppUiBtnRegister(amotaBtnCback);
/* Initialize attribute server database */
SvcCoreGattCbackRegister(GattReadCback, GattWriteCback);
SvcCoreAddGroup();
SvcDisAddGroup();
SvcAmotasCbackRegister(NULL, amotas_write_cback);
SvcAmotasAddGroup();
/* Set Service Changed CCCD index. */
GattSetSvcChangedIdx(AMOTA_GATT_SC_CCC_IDX);
/* Reset the device */
DmDevReset();
}

View File

@ -0,0 +1,112 @@
// ****************************************************************************
//
// ancs_api.h
//! @file
//!
//! @brief Ambiq Micro's demonstration of ANCSC.
//!
//! @{
//
// ****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef ANCS_API_H
#define ANCS_API_H
#include "wsf_os.h"
#ifdef __cplusplus
extern "C" {
#endif
/**************************************************************************************************
Macros
**************************************************************************************************/
#ifndef ANCS_CONN_MAX
#define ANCS_CONN_MAX 1
#endif
/**************************************************************************************************
Function Declarations
**************************************************************************************************/
/*************************************************************************************************/
/*!
* \fn AncsStart
*
* \brief Start the application.
*
* \return None.
*/
/*************************************************************************************************/
void AncsStart(void);
/*************************************************************************************************/
/*!
* \fn AncsHandlerInit
*
* \brief Application handler init function called during system initialization.
*
* \param handlerID WSF handler ID for App.
*
* \return None.
*/
/*************************************************************************************************/
void AncsHandlerInit(wsfHandlerId_t handlerId);
/*************************************************************************************************/
/*!
* \fn AncsHandler
*
* \brief WSF event handler for the application.
*
* \param event WSF event mask.
* \param pMsg WSF message.
*
* \return None.
*/
/*************************************************************************************************/
void AncsHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg);
#ifdef __cplusplus
};
#endif
#endif /* ANCS_API_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,106 @@
// ****************************************************************************
//
// beaconscanner_api.h
//! @file
//!
//! @brief Beacon Scanner sample application interface
//!
//! @{
//
// ****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef BEACONSCANNER_API_H
#define BEACONSCANNER_API_H
#include "wsf_os.h"
#ifdef __cplusplus
extern "C" {
#endif
/**************************************************************************************************
Function Declarations
**************************************************************************************************/
/*************************************************************************************************/
/*!
* \fn BeaconScannerStart
*
* \brief Start Beacon Scan application.
*
* \return None.
*/
/*************************************************************************************************/
void BeaconScannerStart(void);
/*************************************************************************************************/
/*!
* \fn BeaconScannerHandlerInit
*
* \brief Beacon Scan handler init function called during system initialization.
*
* \param handlerID WSF handler ID for App.
*
* \return None.
*/
/*************************************************************************************************/
void BeaconScannerHandlerInit(wsfHandlerId_t handlerId);
/*************************************************************************************************/
/*!
* \fn BeaconScannerHandler
*
* \brief WSF event handler for Beacon Scan application.
*
* \param event WSF event mask.
* \param pMsg WSF message.
*
* \return None.
*/
/*************************************************************************************************/
void BeaconScannerHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg);
#ifdef __cplusplus
};
#endif
#endif /* BEACONSCANNER_API_H */

View File

@ -0,0 +1,109 @@
// ****************************************************************************
//
// ibeacon_api.h
//! @file
//!
//! @brief Ambiq Micro iBeacon example
//!
//! @{
//
// ****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef IBEACON_API_H
#define IBEACON_API_H
#include "wsf_os.h"
#ifdef __cplusplus
extern "C" {
#endif
/**************************************************************************************************
Macros
**************************************************************************************************/
/**************************************************************************************************
Function Declarations
**************************************************************************************************/
/*************************************************************************************************/
/*!
* \fn iBeaconStart
*
* \brief Start the application.
*
* \return None.
*/
/*************************************************************************************************/
void iBeaconStart(void);
/*************************************************************************************************/
/*!
* \fn iBeaconHandlerInit
*
* \brief Application handler init function called during system initialization.
*
* \param handlerID WSF handler ID for App.
*
* \return None.
*/
/*************************************************************************************************/
void iBeaconHandlerInit(wsfHandlerId_t handlerId);
/*************************************************************************************************/
/*!
* \fn iBeaconHandler
*
* \brief WSF event handler for the application.
*
* \param event WSF event mask.
* \param pMsg WSF message.
*
* \return None.
*/
/*************************************************************************************************/
void iBeaconHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg);
#ifdef __cplusplus
};
#endif
#endif /* IBEACON_API_H */

View File

@ -0,0 +1,331 @@
// ****************************************************************************
//
// ibeacon_main.c
//! @file
//!
//! @brief Ambiq Micro's demonstration of iBeacon.
//!
//! @{
//
// ****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <string.h>
#include "wsf_types.h"
#include "bstream.h"
#include "wsf_msg.h"
#include "wsf_trace.h"
#include "hci_api.h"
#include "dm_api.h"
#include "att_api.h"
#include "app_api.h"
#include "app_db.h"
#include "app_ui.h"
#include "app_hw.h"
#include "svc_ch.h"
#include "svc_core.h"
#include "svc_dis.h"
#include "ibeacon_api.h"
#include "gatt_api.h"
/**************************************************************************************************
Macros
**************************************************************************************************/
/*! WSF message event starting value */
#define IBEACON_MSG_START 0xA0
/*! WSF message event enumeration */
enum
{
IBEACON_TIMER_IND = IBEACON_MSG_START, /*! iBeacon reset timer expired */
};
/**************************************************************************************************
Data Types
**************************************************************************************************/
/*! Application message type */
typedef union
{
wsfMsgHdr_t hdr;
dmEvt_t dm;
} ibeaconMsg_t;
/**************************************************************************************************
Configurable Parameters
**************************************************************************************************/
/*! configurable parameters for advertising */
static const appAdvCfg_t ibeaconAdvCfg =
{
{60000, 0, 0}, /*! Advertising durations in ms */
{ 800, 800, 0} /*! Advertising intervals in 0.625 ms units */
};
/*! configurable parameters for slave */
static const appSlaveCfg_t ibeaconSlaveCfg =
{
1, /*! Maximum connections */
};
/*! configurable parameters for security */
static const appSecCfg_t ibeaconSecCfg =
{
DM_AUTH_BOND_FLAG, /*! Authentication and bonding flags */
0, /*! Initiator key distribution flags */
DM_KEY_DIST_LTK, /*! Responder key distribution flags */
FALSE, /*! TRUE if Out-of-band pairing data is present */
FALSE /*! TRUE to initiate security upon connection */
};
/**************************************************************************************************
Advertising Data
**************************************************************************************************/
/*! advertising data, discoverable mode */
static const uint8_t ibeaconAdvDataDisc[] =
{
/*! flags */
2, /*! length */
DM_ADV_TYPE_FLAGS, /*! AD type */
DM_FLAG_LE_GENERAL_DISC | /*! flags */
DM_FLAG_LE_BREDR_NOT_SUP,
/*! Manufacturer specific data AD type */
0x1A, /*! length */
DM_ADV_TYPE_MANUFACTURER, /*! AD type */
0x4C, /*! Company ID[0] */
0x00, /*! Company ID[1] */
0x02, /*! Device type, this has to be 0x02*/
0x15, /*! Length of vendor advertising data. */
/*! Proximity UUID 16 bytes */
0xe2, 0xc5, 0x6d, 0xb5,
0xdf, 0xfb, 0x48, 0xd2,
0xb0, 0x60, 0xd0, 0xf5,
0xa7, 0x10, 0x96, 0xe0,
/*! Major 0xnnnn */
0x00, 0x00,
/*! Minor 0xnnnn */
0x00, 0x00,
/*! Measured Power */
0xc5
};
/**************************************************************************************************
Global Variables
**************************************************************************************************/
/*! WSF handler ID */
wsfHandlerId_t iBeaconHandlerId;
/*************************************************************************************************/
/*!
* \fn iBeaconDmCback
*
* \brief Application DM callback.
*
* \param pDmEvt DM callback event
*
* \return None.
*/
/*************************************************************************************************/
static void iBeaconDmCback(dmEvt_t *pDmEvt)
{
dmEvt_t *pMsg;
if ((pMsg = WsfMsgAlloc(sizeof(dmEvt_t))) != NULL)
{
memcpy(pMsg, pDmEvt, sizeof(dmEvt_t));
WsfMsgSend(iBeaconHandlerId, pMsg);
}
}
/*************************************************************************************************/
/*!
* \fn iBeacon Setup
*
* \brief Set up advertising and other procedures that need to be performed after
* device reset.
*
* \param pMsg Pointer to message.
*
* \return None.
*/
/*************************************************************************************************/
static void iBeaconSetup(ibeaconMsg_t *pMsg)
{
/* set advertising and scan response data for discoverable mode */
AppAdvSetData(APP_ADV_DATA_DISCOVERABLE, sizeof(ibeaconAdvDataDisc), (uint8_t *) ibeaconAdvDataDisc);
/* set advertising and scan response data for connectable mode */
AppAdvSetData(APP_ADV_DATA_CONNECTABLE, 0, NULL);
// non-connectable advertising
AppSetAdvType(DM_ADV_NONCONN_UNDIRECT);
/* start advertising; automatically set connectable/discoverable mode and bondable mode */
AppAdvStart(APP_MODE_DISCOVERABLE);
}
/*************************************************************************************************/
/*!
* \fn iBeaconProcMsg
*
* \brief Process messages from the event handler.
*
* \param pMsg Pointer to message.
*
* \return None.
*/
/*************************************************************************************************/
static void iBeaconProcMsg(ibeaconMsg_t *pMsg)
{
uint8_t uiEvent = APP_UI_NONE;
switch(pMsg->hdr.event)
{
case DM_RESET_CMPL_IND:
AttsCalculateDbHash();
DmSecGenerateEccKeyReq();
iBeaconSetup(pMsg);
uiEvent = APP_UI_RESET_CMPL;
break;
case DM_ADV_START_IND:
uiEvent = APP_UI_ADV_START;
break;
case DM_ADV_STOP_IND:
uiEvent = APP_UI_ADV_STOP;
break;
default:
break;
}
if (uiEvent != APP_UI_NONE)
{
AppUiAction(uiEvent);
}
}
/*************************************************************************************************/
/*!
* \fn iBeaconHandlerInit
*
* \brief Application handler init function called during system initialization.
*
* \param handlerID WSF handler ID.
*
* \return None.
*/
/*************************************************************************************************/
void iBeaconHandlerInit(wsfHandlerId_t handlerId)
{
APP_TRACE_INFO0("iBeaconHandlerInit");
/* store handler ID */
iBeaconHandlerId = handlerId;
/* Set configuration pointers */
pAppAdvCfg = (appAdvCfg_t *) &ibeaconAdvCfg;
pAppSlaveCfg = (appSlaveCfg_t *) &ibeaconSlaveCfg;
pAppSecCfg = (appSecCfg_t *) &ibeaconSecCfg;
/* Initialize application framework */
AppSlaveInit();
}
/*************************************************************************************************/
/*!
* \fn iBeaconHandler
*
* \brief WSF event handler for application.
*
* \param event WSF event mask.
* \param pMsg WSF message.
*
* \return None.
*/
/*************************************************************************************************/
void iBeaconHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg)
{
if (pMsg != NULL)
{
APP_TRACE_INFO1("iBeacon got evt %d", pMsg->event);
if (pMsg->event >= DM_CBACK_START && pMsg->event <= DM_CBACK_END)
{
/* process advertising and connection-related messages */
AppSlaveProcDmMsg((dmEvt_t *) pMsg);
/* process security-related messages */
AppSlaveSecProcDmMsg((dmEvt_t *) pMsg);
}
/* perform profile and user interface-related operations */
iBeaconProcMsg((ibeaconMsg_t *) pMsg);
}
}
/*************************************************************************************************/
/*!
* \fn iBeaconStart
*
* \brief Start the application.
*
* \return None.
*/
/*************************************************************************************************/
void iBeaconStart(void)
{
/* Register for stack callbacks */
DmRegister(iBeaconDmCback);
DmConnRegister(DM_CLIENT_ID_APP, iBeaconDmCback);
/* Reset the device */
DmDevReset();
}

View File

@ -0,0 +1,127 @@
// ****************************************************************************
//
// prodtest_datc_api.h
//! @file
//!
//! @brief Proprietary data transfer client sample application.
//!
//! @{
//
// ****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/*************************************************************************************************/
/*!
* \file prodtest_datc_api.h
*
* \brief Proprietary data transfer client sample application.
*
* $Date: 2016-12-28 16:12:14 -0600 (Wed, 28 Dec 2016) $
* $Revision: 10805 $
*
* Copyright (c) 2012-2017 ARM Ltd., all rights reserved.
* ARM Ltd. confidential and proprietary.
*
* IMPORTANT. Your use of this file is governed by a Software License Agreement
* ("Agreement") that must be accepted in order to download or otherwise receive a
* copy of this file. You may not use or copy this file for any purpose other than
* as described in the Agreement. If you do not agree to all of the terms of the
* Agreement do not use this file and delete all copies in your possession or control;
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
* to any use, copying or further distribution of this software.
*/
/*************************************************************************************************/
#ifndef DATC_API_H
#define DATC_API_H
#include "wsf_os.h"
#ifdef __cplusplus
extern "C" {
#endif
/**************************************************************************************************
Function Declarations
**************************************************************************************************/
/*************************************************************************************************/
/*!
* \fn DatcStart
*
* \brief Start the application.
*
* \return None.
*/
/*************************************************************************************************/
void DatcStart(void);
/*************************************************************************************************/
/*!
* \fn DatcHandlerInit
*
* \brief Application handler init function called during system initialization.
*
* \param handlerID WSF handler ID for App.
*
* \return None.
*/
/*************************************************************************************************/
void DatcHandlerInit(wsfHandlerId_t handlerId);
/*************************************************************************************************/
/*!
* \fn DatcHandler
*
* \brief WSF event handler for the application.
*
* \param event WSF event mask.
* \param pMsg WSF message.
*
* \return None.
*/
/*************************************************************************************************/
void DatcHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg);
#ifdef __cplusplus
};
#endif
#endif /* DATC_API_H */

View File

@ -0,0 +1,130 @@
// ****************************************************************************
//
// prodtest_dats_api.h
//! @file
//!
//! @brief Proprietary data transfer server sample application.
//!
//! @{
//
// ****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/*************************************************************************************************/
/*!
* file prodtest_dats_api.h
*
* brief Proprietary data transfer server sample application.
*
* $Date: 2016-12-28 16:12:14 -0600 (Wed, 28 Dec 2016) $
* $Revision: 10805 $
*
* Copyright (c) 2012-2017 ARM Ltd., all rights reserved.
* ARM Ltd. confidential and proprietary.
*
* IMPORTANT. Your use of this file is governed by a Software License Agreement
* ("Agreement") that must be accepted in order to download or otherwise receive a
* copy of this file. You may not use or copy this file for any purpose other than
* as described in the Agreement. If you do not agree to all of the terms of the
* Agreement do not use this file and delete all copies in your possession or control;
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
* to any use, copying or further distribution of this software.
*/
/*************************************************************************************************/
#ifndef DATS_API_H
#define DATS_API_H
#include "wsf_os.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef WDXS_INCLUDED
#define WDXS_INCLUDED FALSE
#endif
/**************************************************************************************************
Function Declarations
**************************************************************************************************/
/*************************************************************************************************/
/*!
* \fn DatsStart
*
* \brief Start the application.
*
* \return None.
*/
/*************************************************************************************************/
void DatsStart(void);
/*************************************************************************************************/
/*!
* \fn DatsHandlerInit
*
* \brief Application handler init function called during system initialization.
*
* \param handlerID WSF handler ID for App.
*
* \return None.
*/
/*************************************************************************************************/
void DatsHandlerInit(wsfHandlerId_t handlerId);
/*************************************************************************************************/
/*!
* \fn DatsHandler
*
* \brief WSF event handler for the application.
*
* \param event WSF event mask.
* \param pMsg WSF message.
*
* \return None.
*/
/*************************************************************************************************/
void DatsHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg);
#ifdef __cplusplus
};
#endif
#endif /* DATS_API_H */

View File

@ -0,0 +1,802 @@
// ****************************************************************************
//
// prodtest_dats_main.c
//! @file
//!
//! @brief Data transmitter sample application.
//!
//! @{
//
// ****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/*************************************************************************************************/
/*!
* file dats_main.c
*
* brief Data transmitter sample application.
*
* $Date: 2017-03-09 12:18:38 -0600 (Thu, 09 Mar 2017) $
* $Revision: 11460 $
*
* Copyright (c) 2012-2017 ARM Ltd., all rights reserved.
* ARM Ltd. confidential and proprietary.
*
* IMPORTANT. Your use of this file is governed by a Software License Agreement
* ("Agreement") that must be accepted in order to download or otherwise receive a
* copy of this file. You may not use or copy this file for any purpose other than
* as described in the Agreement. If you do not agree to all of the terms of the
* Agreement do not use this file and delete all copies in your possession or control;
* if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
* to any use, copying or further distribution of this software.
*/
/*************************************************************************************************/
#include <string.h>
#include "wsf_types.h"
#include "bstream.h"
#include "wsf_msg.h"
#include "wsf_trace.h"
#include "wsf_buf.h"
#include "hci_api.h"
#include "sec_api.h"
#include "dm_api.h"
#include "smp_api.h"
#include "att_api.h"
#include "app_api.h"
#include "app_db.h"
#include "app_ui.h"
#include "svc_ch.h"
#include "svc_core.h"
#include "svc_wp.h"
#include "calc128.h"
#include "prodtest_dats_api.h"
#if WDXS_INCLUDED == TRUE
#include "wsf_efs.h"
#include "svc_wdxs.h"
#include "wdxs_api.h"
#include "wdxs_main.h"
#include "wdxs_stream.h"
#endif
#include "hci_apollo_config.h"
#include "hci_drv_em9304.h"
#include "gatt_api.h"
/**************************************************************************************************
Macros
**************************************************************************************************/
#if CS50_INCLUDED == TRUE
/* PHY Test Modes */
#define DATS_PHY_1M 1
#define DATS_PHY_2M 2
#define DATS_PHY_CODED 3
#endif /* CS50_INCLUDED */
/*! Enumeration of client characteristic configuration descriptors */
enum
{
#if WDXS_INCLUDED == TRUE
WDXS_DC_CH_CCC_IDX, /*! WDXS DC service, service changed characteristic */
WDXS_FTC_CH_CCC_IDX, /*! WDXS FTC service, service changed characteristic */
WDXS_FTD_CH_CCC_IDX, /*! WDXS FTD service, service changed characteristic */
WDXS_AU_CH_CCC_IDX, /*! WDXS AU service, service changed characteristic */
#endif /* WDXS_INCLUDED */
DATS_GATT_SC_CCC_IDX, /*! GATT service, service changed characteristic */
DATS_WP_DAT_CCC_IDX, /*! ARM Ltd. proprietary service, data transfer characteristic */
DATS_NUM_CCC_IDX
};
/**************************************************************************************************
Configurable Parameters
**************************************************************************************************/
/*! configurable parameters for advertising */
static const appAdvCfg_t datsAdvCfg =
{
{30000, 0, 0}, /*! Advertising durations in ms */
{ 32, 32, 0} /*! Advertising intervals in 0.625 ms units */
};
/*! configurable parameters for slave */
static const appSlaveCfg_t datsSlaveCfg =
{
1, /*! Maximum connections */
};
/*! configurable parameters for security */
static const appSecCfg_t datsSecCfg =
{
0, /*! Authentication and bonding flags */
DM_KEY_DIST_IRK, /*! Initiator key distribution flags */
DM_KEY_DIST_LTK | DM_KEY_DIST_IRK, /*! Responder key distribution flags */
FALSE, /*! TRUE if Out-of-band pairing data is present */
FALSE /*! TRUE to initiate security upon connection */
};
/*! SMP security parameter configuration */
static const smpCfg_t datsSmpCfg =
{
3000, /*! 'Repeated attempts' timeout in msec */
SMP_IO_NO_IN_NO_OUT, /*! I/O Capability */
7, /*! Minimum encryption key length */
16, /*! Maximum encryption key length */
1, /*! Attempts to trigger 'repeated attempts' timeout */
0, /*! Device authentication requirements */
64000, /*! Maximum repeated attempts timeout in msec */
64000, /*! Time msec before attemptExp decreases */
2 /*! Repeated attempts multiplier exponent */
};
/*! configurable parameters for connection parameter update */
static const appUpdateCfg_t datsUpdateCfg =
{
0, /*! Connection idle period in ms before attempting
connection parameter update; set to zero to disable */
640, /*! Minimum connection interval in 1.25ms units */
800, /*! Maximum connection interval in 1.25ms units */
3, /*! Connection latency */
600, /*! Supervision timeout in 10ms units */
5 /*! Number of update attempts before giving up */
};
/*! ATT configurable parameters (increase MTU) */
static const attCfg_t datsAttCfg =
{
15, /* ATT server service discovery connection idle timeout in seconds */
241, /* desired ATT MTU */
ATT_MAX_TRANS_TIMEOUT, /* transcation timeout in seconds */
4 /* number of queued prepare writes supported by server */
};
/*! local IRK */
static uint8_t localIrk[] =
{
0x95, 0xC8, 0xEE, 0x6F, 0xC5, 0x0D, 0xEF, 0x93, 0x35, 0x4E, 0x7C, 0x57, 0x08, 0xE2, 0xA3, 0x85
};
/**************************************************************************************************
Advertising Data
**************************************************************************************************/
/*! advertising data, discoverable mode */
static const uint8_t datsAdvDataDisc[] =
{
/*! flags */
2, /*! length */
DM_ADV_TYPE_FLAGS, /*! AD type */
DM_FLAG_LE_GENERAL_DISC | /*! flags */
DM_FLAG_LE_BREDR_NOT_SUP,
/*! manufacturer specific data */
3, /*! length */
DM_ADV_TYPE_MANUFACTURER, /*! AD type */
UINT16_TO_BYTES(HCI_ID_ARM) /*! company ID */
};
/*! scan data, discoverable mode */
static const uint8_t datsScanDataDisc[] =
{
/*! device name */
8, /*! length */
DM_ADV_TYPE_LOCAL_NAME, /*! AD type */
'D',
'a',
't',
'a',
' ',
'T',
'X'
};
/**************************************************************************************************
Client Characteristic Configuration Descriptors
**************************************************************************************************/
/*! client characteristic configuration descriptors settings, indexed by above enumeration */
static const attsCccSet_t datsCccSet[DATS_NUM_CCC_IDX] =
{
/* cccd handle value range security level */
#if WDXS_INCLUDED == TRUE
{WDXS_DC_CH_CCC_HDL, ATT_CLIENT_CFG_NOTIFY, DM_SEC_LEVEL_NONE}, /* WDXS_DC_CH_CCC_IDX */
{WDXS_FTC_CH_CCC_HDL, ATT_CLIENT_CFG_NOTIFY, DM_SEC_LEVEL_NONE}, /* WDXS_FTC_CH_CCC_IDX */
{WDXS_FTD_CH_CCC_HDL, ATT_CLIENT_CFG_NOTIFY, DM_SEC_LEVEL_NONE}, /* WDXS_FTD_CH_CCC_IDX */
{WDXS_AU_CH_CCC_HDL, ATT_CLIENT_CFG_NOTIFY, DM_SEC_LEVEL_NONE}, /* WDXS_AU_CH_CCC_IDX */
#endif /* WDXS_INCLUDED */
{GATT_SC_CH_CCC_HDL, ATT_CLIENT_CFG_INDICATE, DM_SEC_LEVEL_NONE}, /* DATS_GATT_SC_CCC_IDX */
{WP_DAT_CH_CCC_HDL, ATT_CLIENT_CFG_NOTIFY, DM_SEC_LEVEL_NONE} /* DATS_WP_DAT_CCC_IDX */
};
/**************************************************************************************************
Local Variables
**************************************************************************************************/
/*! application control block */
static struct
{
wsfHandlerId_t handlerId; /* WSF handler ID */
#if CS50_INCLUDED == TRUE
uint8_t phyMode; /*! PHY Test Mode */
#endif /* CS50_INCLUDED */
} datsCb;
/* LESC OOB configuration */
static dmSecLescOobCfg_t *datsOobCfg;
/*************************************************************************************************/
/*!
* \fn datsSendData
*
* \brief Send notification containing data.
*
* \param connId DM connection ID.
*
* \return None.
*/
/*************************************************************************************************/
static void datsSendData(dmConnId_t connId)
{
uint8_t str[] = "hello.....from dats";
if (AttsCccEnabled(connId, DATS_WP_DAT_CCC_IDX))
{
/* send notification */
AttsHandleValueNtf(connId, WP_DAT_HDL, sizeof(str), str);
AttsHandleValueNtf(connId, WP_DAT_HDL, sizeof(str), str);
AttsHandleValueNtf(connId, WP_DAT_HDL, sizeof(str), str);
AttsHandleValueNtf(connId, WP_DAT_HDL, sizeof(str), str);
AttsHandleValueNtf(connId, WP_DAT_HDL, sizeof(str), str);
}
}
static void datsSetup(dmEvt_t *pMsg);
/*************************************************************************************************/
/*!
* \fn datsDmCback
*
* \brief Application DM callback.
*
* \param pDmEvt DM callback event
*
* \return None.
*/
/*************************************************************************************************/
static void datsDmCback(dmEvt_t *pDmEvt)
{
dmEvt_t *pMsg;
uint16_t len;
if (pDmEvt->hdr.event == DM_SEC_ECC_KEY_IND)
{
DmSecSetEccKey(&pDmEvt->eccMsg.data.key);
/* If the local device sends OOB data. */
if (datsSecCfg.oob)
{
uint8_t oobLocalRandom[SMP_RAND_LEN];
SecRand(oobLocalRandom, SMP_RAND_LEN);
DmSecCalcOobReq(oobLocalRandom, pDmEvt->eccMsg.data.key.pubKey_x);
}
}
else if (pDmEvt->hdr.event == DM_SEC_CALC_OOB_IND)
{
if (datsOobCfg == NULL)
{
datsOobCfg = WsfBufAlloc(sizeof(dmSecLescOobCfg_t));
}
if (datsOobCfg)
{
Calc128Cpy(datsOobCfg->localConfirm, pDmEvt->oobCalcInd.confirm);
Calc128Cpy(datsOobCfg->localRandom, pDmEvt->oobCalcInd.random);
}
}
else
{
len = DmSizeOfEvt(pDmEvt);
if ((pMsg = WsfMsgAlloc(len)) != NULL)
{
memcpy(pMsg, pDmEvt, len);
WsfMsgSend(datsCb.handlerId, pMsg);
}
}
}
/*************************************************************************************************/
/*!
* \fn datsAttCback
*
* \brief Application ATT callback.
*
* \param pEvt ATT callback event
*
* \return None.
*/
/*************************************************************************************************/
static void datsAttCback(attEvt_t *pEvt)
{
#if WDXS_INCLUDED == TRUE
WdxsAttCback(pEvt);
#endif /* WDXS_INCLUDED */
}
/*************************************************************************************************/
/*!
* \fn datsCccCback
*
* \brief Application ATTS client characteristic configuration callback.
*
* \param pDmEvt DM callback event
*
* \return None.
*/
/*************************************************************************************************/
static void datsCccCback(attsCccEvt_t *pEvt)
{
appDbHdl_t dbHdl;
/* If CCC not set from initialization and there's a device record and currently bonded */
if ((pEvt->handle != ATT_HANDLE_NONE) &&
((dbHdl = AppDbGetHdl((dmConnId_t) pEvt->hdr.param)) != APP_DB_HDL_NONE) &&
AppCheckBonded((dmConnId_t)pEvt->hdr.param))
{
/* Store value in device database. */
AppDbSetCccTblValue(dbHdl, pEvt->idx, pEvt->value);
}
}
/*************************************************************************************************/
/*!
* \fn datsWpWriteCback
*
* \brief ATTS write callback for proprietary data service.
*
* \return ATT status.
*/
/*************************************************************************************************/
uint8_t datsWpWriteCback(dmConnId_t connId, uint16_t handle, uint8_t operation,
uint16_t offset, uint16_t len, uint8_t *pValue, attsAttr_t *pAttr)
{
/* print received data */
APP_TRACE_INFO0((const char*) pValue);
/* send back some data */
datsSendData(connId);
return ATT_SUCCESS;
}
/*************************************************************************************************/
/*!
* \fn datsSetup
*
* \brief Set up advertising and other procedures that need to be performed after
* device reset.
*
* \param pMsg Pointer to message.
*
* \return None.
*/
/*************************************************************************************************/
static void datsSetup(dmEvt_t *pMsg)
{
/* set advertising and scan response data for discoverable mode */
AppAdvSetData(APP_ADV_DATA_DISCOVERABLE, sizeof(datsAdvDataDisc), (uint8_t *) datsAdvDataDisc);
AppAdvSetData(APP_SCAN_DATA_DISCOVERABLE, sizeof(datsScanDataDisc), (uint8_t *) datsScanDataDisc);
/* set advertising and scan response data for connectable mode */
AppAdvSetData(APP_ADV_DATA_CONNECTABLE, sizeof(datsAdvDataDisc), (uint8_t *) datsAdvDataDisc);
AppAdvSetData(APP_SCAN_DATA_CONNECTABLE, sizeof(datsScanDataDisc), (uint8_t *) datsScanDataDisc);
/* start advertising; automatically set connectable/discoverable mode and bondable mode */
AppAdvStart(APP_MODE_AUTO_INIT);
}
/*************************************************************************************************/
/*!
* \fn datsProcMsg
*
* \brief Process messages from the event handler.
*
* \param pMsg Pointer to message.
*
* \return None.
*/
/*************************************************************************************************/
static void datsProcMsg(dmEvt_t *pMsg)
{
uint8_t uiEvent = APP_UI_NONE;
switch(pMsg->hdr.event)
{
case ATT_MTU_UPDATE_IND:
APP_TRACE_INFO1("Negotiated MTU %d", ((attEvt_t *)pMsg)->mtu);
break;
case DM_RESET_CMPL_IND:
AttsCalculateDbHash();
DmSecGenerateEccKeyReq();
datsSetup(NULL);
uiEvent = APP_UI_RESET_CMPL;
HciVsEM_SetRfPowerLevelEx(TX_POWER_LEVEL_PLUS_0P4_dBm);
break;
case DM_ADV_SET_START_IND:
uiEvent = APP_UI_ADV_SET_START_IND;
break;
case DM_ADV_SET_STOP_IND:
uiEvent = APP_UI_ADV_SET_STOP_IND;
break;
case DM_ADV_START_IND:
uiEvent = APP_UI_ADV_START;
break;
case DM_ADV_STOP_IND:
uiEvent = APP_UI_ADV_STOP;
break;
case DM_CONN_OPEN_IND:
uiEvent = APP_UI_CONN_OPEN;
#if CS50_INCLUDED == TRUE
datsCb.phyMode = DATS_PHY_1M;
#endif /* CS50_INCLUDED */
break;
case DM_CONN_CLOSE_IND:
uiEvent = APP_UI_CONN_CLOSE;
break;
case DM_SEC_PAIR_CMPL_IND:
DmSecGenerateEccKeyReq();
uiEvent = APP_UI_SEC_PAIR_CMPL;
break;
case DM_SEC_PAIR_FAIL_IND:
DmSecGenerateEccKeyReq();
uiEvent = APP_UI_SEC_PAIR_FAIL;
break;
case DM_SEC_ENCRYPT_IND:
uiEvent = APP_UI_SEC_ENCRYPT;
break;
case DM_SEC_ENCRYPT_FAIL_IND:
uiEvent = APP_UI_SEC_ENCRYPT_FAIL;
break;
case DM_SEC_AUTH_REQ_IND:
if (pMsg->authReq.oob)
{
dmConnId_t connId = (dmConnId_t) pMsg->hdr.param;
/* TODO: Perform OOB Exchange with the peer. */
/* TODO: Fill datsOobCfg peerConfirm and peerRandom with value passed out of band */
if (datsOobCfg != NULL)
{
DmSecSetOob(connId, datsOobCfg);
}
DmSecAuthRsp(connId, 0, NULL);
}
else
{
AppHandlePasskey(&pMsg->authReq);
}
break;
case DM_SEC_ECC_KEY_IND:
DmSecSetEccKey(&pMsg->eccMsg.data.key);
break;
case DM_SEC_COMPARE_IND:
AppHandleNumericComparison(&pMsg->cnfInd);
break;
case DM_PRIV_CLEAR_RES_LIST_IND:
APP_TRACE_INFO1("Clear resolving list status 0x%02x", pMsg->hdr.status);
break;
case DM_HW_ERROR_IND:
uiEvent = APP_UI_HW_ERROR;
break;
case DM_VENDOR_SPEC_CMD_CMPL_IND:
{
#if defined(AM_PART_APOLLO) || defined(AM_PART_APOLLO2)
uint8_t *param_ptr = &pMsg->vendorSpecCmdCmpl.param[0];
switch (pMsg->vendorSpecCmdCmpl.opcode)
{
case 0xFC20: //read at address
{
uint32_t read_value;
BSTREAM_TO_UINT32(read_value, param_ptr);
APP_TRACE_INFO3("VSC 0x%0x complete status %x param %x",
pMsg->vendorSpecCmdCmpl.opcode,
pMsg->hdr.status,
read_value);
}
break;
default:
APP_TRACE_INFO2("VSC 0x%0x complete status %x",
pMsg->vendorSpecCmdCmpl.opcode,
pMsg->hdr.status);
break;
}
#endif
}
break;
default:
break;
}
if (uiEvent != APP_UI_NONE)
{
AppUiAction(uiEvent);
}
}
/*************************************************************************************************/
/*!
* \fn DatsHandlerInit
*
* \brief Application handler init function called during system initialization.
*
* \param handlerID WSF handler ID.
*
* \return None.
*/
/*************************************************************************************************/
void DatsHandlerInit(wsfHandlerId_t handlerId)
{
APP_TRACE_INFO0("DatsHandlerInit");
/* store handler ID */
datsCb.handlerId = handlerId;
/* Set configuration pointers */
pAppSlaveCfg = (appSlaveCfg_t *) &datsSlaveCfg;
pAppAdvCfg = (appAdvCfg_t *) &datsAdvCfg;
pAppSecCfg = (appSecCfg_t *) &datsSecCfg;
pAppUpdateCfg = (appUpdateCfg_t *) &datsUpdateCfg;
pSmpCfg = (smpCfg_t *) &datsSmpCfg;
/* Initialize application framework */
AppSlaveInit();
/* Set IRK for the local device */
DmSecSetLocalIrk(localIrk);
}
/*************************************************************************************************/
/*!
* \fn datsBtnCback
*
* \brief Button press callback.
*
* \param btn Button press.
*
* \return None.
*/
/*************************************************************************************************/
static void datsBtnCback(uint8_t btn)
{
#if WDXS_INCLUDED == TRUE
static uint8_t waveform = WDXS_STREAM_WAVEFORM_SINE;
#endif /* WDXS_INCLUDED */
#if CS50_INCLUDED == TRUE
dmConnId_t connId;
if ((connId = AppConnIsOpen()) != DM_CONN_ID_NONE)
#else
if (AppConnIsOpen() != DM_CONN_ID_NONE)
#endif /* CS50_INCLUDED */
{
switch (btn)
{
#if CS50_INCLUDED == TRUE
case APP_UI_BTN_2_SHORT:
/* Toggle PHY Test Mode */
if (datsCb.phyMode == DATS_PHY_1M)
{
APP_TRACE_INFO0("2 MBit TX and RX PHY Requested");
DmSetPhy(connId, HCI_ALL_PHY_ALL_PREFERENCES, HCI_PHY_LE_2M_BIT, HCI_PHY_LE_2M_BIT, HCI_PHY_OPTIONS_NONE);
}
else if (datsCb.phyMode == DATS_PHY_2M)
{
APP_TRACE_INFO0("LE Coded TX and RX PHY Requested");
DmSetPhy(connId, HCI_ALL_PHY_ALL_PREFERENCES, HCI_PHY_LE_CODED_BIT, HCI_PHY_LE_CODED_BIT, HCI_PHY_OPTIONS_NONE);
}
else
{
APP_TRACE_INFO0("1 MBit TX and RX PHY Requested");
DmSetPhy(connId, HCI_ALL_PHY_ALL_PREFERENCES, HCI_PHY_LE_1M_BIT, HCI_PHY_LE_1M_BIT, HCI_PHY_OPTIONS_NONE);
}
break;
#endif /* CS50_INCLUDED */
#if WDXS_INCLUDED == TRUE
case APP_UI_BTN_1_SHORT:
/* Change stream waveform */
waveform++;
if ( waveform > WDXS_STREAM_WAVEFORM_SAWTOOTH )
{
waveform = WDXS_STREAM_WAVEFORM_SINE;
}
wdxsSetStreamWaveform(waveform);
break;
#endif /* WDXS_INCLUDED */
default:
break;
}
}
}
/*************************************************************************************************/
/*!
* \fn datsWsfBufDiagnostics
*
* \brief Callback for WSF buffer diagnostic messages.
*
* \param pInfo Diagnostics message
*
* \return None.
*/
/*************************************************************************************************/
static void datsWsfBufDiagnostics(WsfBufDiag_t *pInfo)
{
if (pInfo->type == WSF_BUF_ALLOC_FAILED)
{
APP_TRACE_INFO2("Dats got WSF Buffer Allocation Failure - Task: %d Len: %d",
pInfo->param.alloc.taskId, pInfo->param.alloc.len);
}
}
/*************************************************************************************************/
/*!
* \fn DatsHandler
*
* \brief WSF event handler for application.
*
* \param event WSF event mask.
* \param pMsg WSF message.
*
* \return None.
*/
/*************************************************************************************************/
void DatsHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg)
{
if (pMsg != NULL)
{
APP_TRACE_INFO1("Dats got evt %d", pMsg->event);
/* process ATT messages */
if (pMsg->event >= ATT_CBACK_START && pMsg->event <= ATT_CBACK_END)
{
/* process server-related ATT messages */
AppServerProcAttMsg(pMsg);
}
/* process DM messages */
else if (pMsg->event >= DM_CBACK_START && pMsg->event <= DM_CBACK_END)
{
/* process advertising and connection-related messages */
AppSlaveProcDmMsg((dmEvt_t *) pMsg);
/* process security-related messages */
AppSlaveSecProcDmMsg((dmEvt_t *) pMsg);
#if WDXS_INCLUDED == TRUE
/* process WDXS-related messages */
WdxsProcDmMsg((dmEvt_t*) pMsg);
#endif /* WDXS_INCLUDED */
}
/* perform profile and user interface-related operations */
datsProcMsg((dmEvt_t *) pMsg);
}
}
/*************************************************************************************************/
/*!
* \fn DatsStart
*
* \brief Start the application.
*
* \return None.
*/
/*************************************************************************************************/
void DatsStart(void)
{
/* Register for stack callbacks */
DmRegister(datsDmCback);
DmConnRegister(DM_CLIENT_ID_APP, datsDmCback);
AttRegister(datsAttCback);
AttConnRegister(AppServerConnCback);
AttsCccRegister(DATS_NUM_CCC_IDX, (attsCccSet_t *) datsCccSet, datsCccCback);
/* Initialize attribute server database */
SvcCoreGattCbackRegister(GattReadCback, GattWriteCback);
SvcCoreAddGroup();
SvcWpCbackRegister(NULL, datsWpWriteCback);
SvcWpAddGroup();
/* Register for app framework button callbacks */
AppUiBtnRegister(datsBtnCback);
#if WDXS_INCLUDED == TRUE
/* Initialize the OTA File Media */
WdxsOtaMediaInit();
/* Initialize the WDXS Stream */
wdxsStreamInit();
/* Set the WDXS CCC Identifiers */
WdxsSetCccIdx(WDXS_DC_CH_CCC_IDX, WDXS_AU_CH_CCC_IDX, WDXS_FTC_CH_CCC_IDX, WDXS_FTD_CH_CCC_IDX);
#endif /* WDXS_INCLUDED */
WsfBufDiagRegister(datsWsfBufDiagnostics);
/* Set Service Changed CCCD index. */
GattSetSvcChangedIdx(DATS_GATT_SC_CCC_IDX);
/* Reset the device */
DmDevReset();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,126 @@
// ****************************************************************************
//
// vole_api.h
//! @file
//!
//! @brief Ambiq Micro's demonstration of AMDTP service.
//!
//! @{
//
// ****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2018, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 1.2.12 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef VOLE_API_H
#define VOLE_API_H
#include "wsf_os.h"
#ifdef __cplusplus
extern "C" {
#endif
/**************************************************************************************************
Macros
**************************************************************************************************/
#ifndef VOLE_CONN_MAX
#define VOLE_CONN_MAX 1
#endif
/*! WSF message event starting value */
#define VOLE_MSG_START 0xA0
/*! WSF message event enumeration */
enum
{
AMOTA_TIMER_IND = VOLE_MSG_START,
};
extern dmConnId_t g_AmaConnId;
/**************************************************************************************************
Function Declarations
**************************************************************************************************/
/*************************************************************************************************/
/*!
* \fn AmvosStart
*
* \brief Start the application.
*
* \return None.
*/
/*************************************************************************************************/
void VoleStart(void);
/*************************************************************************************************/
/*!
* \fn VoleHandlerInit
*
* \brief Application handler init function called during system initialization.
*
* \param handlerID WSF handler ID for App.
*
* \return None.
*/
/*************************************************************************************************/
void VoleHandlerInit(wsfHandlerId_t handlerId);
/*************************************************************************************************/
/*!
* \fn VoleHandler
*
* \brief WSF event handler for the application.
*
* \param event WSF event mask.
* \param pMsg WSF message.
*
* \return None.
*/
/*************************************************************************************************/
void VoleHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg);
void VoleBleSend(uint8_t * buf, uint32_t len);
#ifdef __cplusplus
};
#endif
#endif /* VOLE_API_H */

View File

@ -0,0 +1,867 @@
// ****************************************************************************
//
// vole_main.c
//! @file
//!
//! @brief Ambiq Micro's demonstration of Voice Over LE service.
//!
//! @{
//
// ****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include "usr_include.h"
#include <string.h>
#include "wsf_types.h"
#include "bstream.h"
#include "wsf_msg.h"
#include "wsf_trace.h"
#include "hci_api.h"
#include "dm_api.h"
#include "att_api.h"
#include "smp_api.h"
#include "app_api.h"
#include "app_db.h"
#include "app_ui.h"
#include "app_hw.h"
#include "svc_ch.h"
#include "svc_core.h"
#include "svc_dis.h"
#include "vole_api.h"
#include "svc_amvole.h"
#include "vole_common.h"
#include "vole_board_config.h"
#include "am_util.h"
#include "crc32.h"
#include "am_app_KWD_AMA.h"
#include "FreeRTOS.h"
#include "task.h"
#include "voles_api.h"
#include "gatt_api.h"
/**************************************************************************************************
Macros
**************************************************************************************************/
/**************************************************************************************************
Data Types
**************************************************************************************************/
/*! Application message type */
typedef union
{
wsfMsgHdr_t hdr;
dmEvt_t dm;
attsCccEvt_t ccc;
attEvt_t att;
} amvoleMsg_t;
/**************************************************************************************************
Configurable Parameters
**************************************************************************************************/
/*! configurable parameters for advertising */
static const appAdvCfg_t amvoleAdvCfg =
{
{60000, 0, 0}, /*! Advertising durations in ms */
{ 800, 800, 0} /*! Advertising intervals in 0.625 ms units */
};
/*! configurable parameters for slave */
static const appSlaveCfg_t amvoleSlaveCfg =
{
VOLE_CONN_MAX, /*! Maximum connections */
};
/*! configurable parameters for security */
static const appSecCfg_t amvoleSecCfg =
{
DM_AUTH_BOND_FLAG | DM_AUTH_SC_FLAG, /*! Authentication and bonding flags */
0, /*! Initiator key distribution flags */
DM_KEY_DIST_LTK, /*! Responder key distribution flags */
FALSE, /*! TRUE if Out-of-band pairing data is present */
FALSE /*! TRUE to initiate security upon connection */
};
static const appUpdateCfg_t amvoleUpdateCfg =
{
1000, //3000, /*! Connection idle period in ms before attempting
//connection parameter update; set to zero to disable */
6, //6, /*! 7.5ms */
12, //15, /*! 30ms */
0, /*! Connection latency */
400, //2000, //600, /*! Supervision timeout in 10ms units */
5 /*! Number of update attempts before giving up */
};
/*! SMP security parameter configuration */
static const smpCfg_t amvoleSmpCfg =
{
3000, /*! 'Repeated attempts' timeout in msec */
SMP_IO_NO_IN_NO_OUT, /*! I/O Capability */
7, /*! Minimum encryption key length */
16, /*! Maximum encryption key length */
3, /*! Attempts to trigger 'repeated attempts' timeout */
0, /*! Device authentication requirements */
};
/**************************************************************************************************
Advertising Data
**************************************************************************************************/
// RAM buffers to be used
uint8_t amvoleAdvDataDisc[31];
uint8_t amvoleScanDataDisc[31];
/*! advertising data, discoverable mode */
static const uint8_t amvoleAdvDataDiscDefault[] =
{
/*! flags */
2, /*! length */
DM_ADV_TYPE_FLAGS, /*! AD type */
DM_FLAG_LE_GENERAL_DISC | /*! flags */
DM_FLAG_LE_BREDR_NOT_SUP,
/*! tx power */
2, /*! length */
DM_ADV_TYPE_TX_POWER, /*! AD type */
0, /*! tx power */
/*! service UUID list */
17, /*! length */
DM_ADV_TYPE_128_UUID, /*! AD type */
ATT_UUID_VOLES_SERVICE
};
/*! scan data, discoverable mode */
static const uint8_t amvoleScanDataDiscDefault[] =
{
/*! device name */
5, /*! length */
DM_ADV_TYPE_LOCAL_NAME, /*! AD type */
'V',
'o',
'L',
'E'
};
dmConnId_t g_AmaConnId = DM_CONN_ID_NONE;
bool_t g_start_voice_send = FALSE;
extern bool am_app_KWD_AMA_tx_ver_exchange_send(void);
// index is the starting point of the local name, local name only in advData
static bool amvoleSetLocalName(uint8_t* pAdvData, uint8_t* pLocalName, uint8_t len, uint8_t index)
{
if (index + len + 1 > 31)
{
// max adv data is 31 byte long
return false;
}
// set parameter length
pAdvData[index] = len + 1;
// set parameter type
pAdvData[index + 1] = DM_ADV_TYPE_LOCAL_NAME;
// set local name
for ( uint8_t i = 0; i < len; i++ )
{
pAdvData[i + 2 + index] = pLocalName[i];
}
return true;
}
void amvoleKwdSetDemoName(void)
{
uint8_t test_bdaddress[6];
uint8_t ble_device_name[20] = "VOLES-"; //local name = device name
uint8_t *pBda;
uint8_t index = 6;
//fixme: read bd address and print out
pBda = HciGetBdAddr();
BdaCpy(test_bdaddress, pBda);
pBda = (uint8_t*)Bda2Str(test_bdaddress);
APP_TRACE_INFO0("Local Device BD Address: ");
APP_TRACE_INFO0(Bda2Str(test_bdaddress));
APP_TRACE_INFO0("\n");
// build demo name here
// 1st letter is board variant
#if USE_MAYA
ble_device_name[index++] = 'M';
#elif USE_APOLLO2_QT
ble_device_name[index++] = 'Q';
#else
ble_device_name[index++] = 'E';
#endif
// 3rd letter is wake-on-sound variant
#if USE_WAKE_ON_SOUND
ble_device_name[index++] = 'W';
#else
ble_device_name[index++] = 'A'; // A for always listening...
#endif
ble_device_name[index++] = '-';
ble_device_name[index++] = 'A';
ble_device_name[index++] = 'M';
ble_device_name[index++] = 'A';
// a hyphen...
ble_device_name[index++] = '-';
// take the last 4 hex digit
ble_device_name[index++] = pBda[8];
ble_device_name[index++] = pBda[9];
ble_device_name[index++] = pBda[10];
ble_device_name[index++] = pBda[11];
// set local name here:
amvoleSetLocalName(amvoleScanDataDisc, ble_device_name, index, 0);
//SvcCoreSetDevName(ble_device_name, index);
}
/**************************************************************************************************
Client Characteristic Configuration Descriptors
**************************************************************************************************/
/*! enumeration of client characteristic configuration descriptors */
enum
{
VOLES_GATT_SC_CCC_IDX, /*! GATT service, service changed characteristic */
VOLES_TX_CCC_IDX, /*! AMDTP service, tx characteristic */
VOLES_NUM_CCC_IDX
};
/*! client characteristic configuration descriptors settings, indexed by above enumeration */
static const attsCccSet_t amvoleCccSet[VOLES_NUM_CCC_IDX] =
{
/* cccd handle value range security level */
{GATT_SC_CH_CCC_HDL, ATT_CLIENT_CFG_INDICATE, DM_SEC_LEVEL_NONE}, /* VOLES_GATT_SC_CCC_IDX */
{VOLES_TX_CH_CCC_HDL, ATT_CLIENT_CFG_NOTIFY, DM_SEC_LEVEL_NONE}, /* VOLES_TX_CCC_IDX */
};
/**************************************************************************************************
Global Variables
**************************************************************************************************/
/*! WSF handler ID */
wsfHandlerId_t amvoleHandlerId;
/*************************************************************************************************/
/*!
* \fn amvoleDmCback
*
* \brief Application DM callback.
*
* \param pDmEvt DM callback event
*
* \return None.
*/
/*************************************************************************************************/
static void amvoleDmCback(dmEvt_t *pDmEvt)
{
dmEvt_t *pMsg;
uint16_t len;
len = DmSizeOfEvt(pDmEvt);
if ((pMsg = WsfMsgAlloc(len)) != NULL)
{
memcpy(pMsg, pDmEvt, len);
WsfMsgSend(amvoleHandlerId, pMsg);
}
}
bool amvoleTxChannelIsAvailable(void)
{
return(DM_CONN_ID_NONE != AppConnIsOpen());
}
void VoleBleSend(uint8_t * buf, uint32_t len)
{
if (amvoleTxChannelIsAvailable())
{
// simply tries to send notification
AttsHandleValueNtf(g_AmaConnId, VOLES_TX_HDL, len, buf); // connId always group 0 since support only 1 connection.
}
}
/*************************************************************************************************/
/*!
* \fn amvoleAttCback
*
* \brief Application ATT callback.
*
* \param pEvt ATT callback event
*
* \return None.
*/
/*************************************************************************************************/
static void amvoleAttCback(attEvt_t *pEvt)
{
attEvt_t *pMsg;
if ((pMsg = WsfMsgAlloc(sizeof(attEvt_t) + pEvt->valueLen)) != NULL)
{
memcpy(pMsg, pEvt, sizeof(attEvt_t));
pMsg->pValue = (uint8_t *) (pMsg + 1);
memcpy(pMsg->pValue, pEvt->pValue, pEvt->valueLen);
WsfMsgSend(amvoleHandlerId, pMsg);
}
}
/*************************************************************************************************/
/*!
* \fn amvoleCccCback
*
* \brief Application ATTS client characteristic configuration callback.
*
* \param pDmEvt DM callback event
*
* \return None.
*/
/*************************************************************************************************/
static void amvoleCccCback(attsCccEvt_t *pEvt)
{
attsCccEvt_t *pMsg;
appDbHdl_t dbHdl;
/* if CCC not set from initialization and there's a device record */
if ((pEvt->handle != ATT_HANDLE_NONE) &&
((dbHdl = AppDbGetHdl((dmConnId_t) pEvt->hdr.param)) != APP_DB_HDL_NONE))
{
/* store value in device database */
AppDbSetCccTblValue(dbHdl, pEvt->idx, pEvt->value);
}
if ((pMsg = WsfMsgAlloc(sizeof(attsCccEvt_t))) != NULL)
{
memcpy(pMsg, pEvt, sizeof(attsCccEvt_t));
WsfMsgSend(amvoleHandlerId, pMsg);
}
}
/*************************************************************************************************/
/*!
* \fn amvoleProcCccState
*
* \brief Process CCC state change.
*
* \param pMsg Pointer to message.
*
* \return None.
*/
/*************************************************************************************************/
static void amvoleProcCccState(amvoleMsg_t *pMsg)
{
APP_TRACE_INFO3("ccc state ind value:%d handle:%d idx:%d\n", pMsg->ccc.value, pMsg->ccc.handle, pMsg->ccc.idx);
/* VOLES TX CCC */
if (pMsg->ccc.idx == VOLES_TX_CCC_IDX)
{
if (pMsg->ccc.value == ATT_CLIENT_CFG_NOTIFY)
{
// notify enabled
g_AmaConnId = (dmConnId_t) pMsg->ccc.hdr.param;
APP_TRACE_INFO1("connId : %d\r\n", pMsg->ccc.hdr.param);
}
else
{
g_AmaConnId = DM_CONN_ID_NONE;
}
return;
}
}
/*************************************************************************************************/
/*!
* \fn amvoleClose
*
* \brief Perform UI actions on connection close.
*
* \param pMsg Pointer to message.
*
* \return None.
*/
/*************************************************************************************************/
static void amvoleClose(amvoleMsg_t *pMsg)
{
}
/*************************************************************************************************/
/*!
* \fn amvoleSetup
*
* \brief Set up advertising and other procedures that need to be performed after
* device reset.
*
* \param pMsg Pointer to message.
*
* \return None.
*/
/*************************************************************************************************/
static void amvoleSetup(amvoleMsg_t *pMsg)
{
/* set advertising and scan response data for discoverable mode */
AppAdvSetData(APP_ADV_DATA_DISCOVERABLE, sizeof(amvoleAdvDataDisc), (uint8_t *) amvoleAdvDataDisc);
AppAdvSetData(APP_SCAN_DATA_DISCOVERABLE, sizeof(amvoleScanDataDisc), (uint8_t *) amvoleScanDataDisc);
/* set advertising and scan response data for connectable mode */
AppAdvSetData(APP_ADV_DATA_CONNECTABLE, sizeof(amvoleAdvDataDisc), (uint8_t *) amvoleAdvDataDisc);
AppAdvSetData(APP_SCAN_DATA_CONNECTABLE, sizeof(amvoleScanDataDisc), (uint8_t *) amvoleScanDataDisc);
AppSetBondable(TRUE);
/* start advertising; automatically set connectable/discoverable mode and bondable mode */
AppAdvStart(APP_MODE_AUTO_INIT);
}
//*****************************************************************************
//
// LED task to indicate external events, such as heart beat and key word detected.
//
//*****************************************************************************
void am_app_led_on(void)
{
#if defined(AM_PART_APOLLO2)
am_hal_gpio_out_bit_toggle(LED_D6);
am_hal_gpio_out_bit_toggle(LED_D7);
am_hal_gpio_out_bit_toggle(LED_D8);
#endif // #if defined(AM_PART_APOLLO2)
#if defined(AM_PART_APOLLO3) || defined(AM_PART_APOLLO3P)
#if USE_APOLLO3_BLUE_EVB
am_hal_gpio_state_write(LED_D5, AM_HAL_GPIO_OUTPUT_TOGGLE);
am_hal_gpio_state_write(LED_D6, AM_HAL_GPIO_OUTPUT_TOGGLE);
am_hal_gpio_state_write(LED_D7, AM_HAL_GPIO_OUTPUT_TOGGLE);
am_hal_gpio_state_write(LED_D8, AM_HAL_GPIO_OUTPUT_TOGGLE);
#endif // #if USE_APOLLO3_BLUE_EVB
#endif //#if defined(AM_PART_APOLLO3)
}
void am_app_led_off(void)
{
#if defined(AM_PART_APOLLO2)
am_hal_gpio_out_bit_clear(LED_D6);
am_hal_gpio_out_bit_clear(LED_D7);
am_hal_gpio_out_bit_clear(LED_D8);
#endif
#if defined(AM_PART_APOLLO3) || defined(AM_PART_APOLLO3P)
#if USE_APOLLO3_BLUE_EVB
am_hal_gpio_state_write(LED_D5, AM_HAL_GPIO_OUTPUT_CLEAR);
am_hal_gpio_state_write(LED_D6, AM_HAL_GPIO_OUTPUT_CLEAR);
am_hal_gpio_state_write(LED_D7, AM_HAL_GPIO_OUTPUT_CLEAR);
am_hal_gpio_state_write(LED_D8, AM_HAL_GPIO_OUTPUT_CLEAR);
#endif
#endif
}
/*************************************************************************************************/
/*!
* \fn amvoleBtnCback
*
* \brief Button press callback.
*
* \param btn Button press.
*
* \return None.
*/
/*************************************************************************************************/
static void amvoleBtnCback(uint8_t btn)
{
dmConnId_t connId = AppConnIsOpen();
APP_TRACE_INFO2("button %d pressed, connection open:%d", btn, connId);
/* button actions when connected */
if (connId != DM_CONN_ID_NONE)
{
APP_TRACE_INFO1("btn:%d", btn);
switch (btn)
{
// transmit voice data using mSBC encode
case APP_UI_BTN_1_SHORT:
APP_TRACE_INFO0("start speech data send...");
voles_set_codec_type(MSBC_CODEC_IN_USE);
voles_init(amvoleHandlerId, MSBC_CODEC_IN_USE);
am_app_KWD_AMA_start_speech_send();
break;
case APP_UI_BTN_2_SHORT:
voles_set_codec_type(OPUS_CODEC_IN_USE);
voles_init(amvoleHandlerId, OPUS_CODEC_IN_USE);
am_app_KWD_AMA_start_speech_send();
break;
default:
break;
}
}
}
uint8_t
amvole_write_cback(dmConnId_t connId, uint16_t handle, uint8_t operation,
uint16_t offset, uint16_t len, uint8_t *pValue, attsAttr_t *pAttr)
{
if (handle == VOLES_RX_HDL)
{
am_app_KWD_AMA_rx_handler(pValue, len);
}
return ATT_SUCCESS;
}
/*************************************************************************************************/
/*!
* \fn amvoleProcMsg
*
* \brief Process messages from the event handler.
*
* \param pMsg Pointer to message.
*
* \return None.
*/
/*************************************************************************************************/
static void amvoleProcMsg(amvoleMsg_t *pMsg)
{
uint8_t uiEvent = APP_UI_NONE;
static uint8_t retry_cnt = 0;
switch(pMsg->hdr.event)
{
case ATTS_HANDLE_VALUE_CNF:
voles_proc_msg(&pMsg->hdr);
break;
case ATTS_CCC_STATE_IND:
amvoleProcCccState(pMsg);
if (pMsg->ccc.handle == VOLES_TX_CH_CCC_HDL)
{
am_app_KWD_AMA_tx_ver_exchange_send();
}
break;
case DM_RESET_CMPL_IND:
AttsCalculateDbHash();
DmSecGenerateEccKeyReq();
amvoleSetup(pMsg);
#if USE_BLE_TX_POWER_SET
HciVsEM_SetRfPowerLevelEx(TX_POWER_LEVEL_PLUS_6P2_dBm);
#endif
uiEvent = APP_UI_RESET_CMPL;
break;
case DM_ADV_SET_START_IND:
uiEvent = APP_UI_ADV_SET_START_IND;
break;
case DM_ADV_SET_STOP_IND:
uiEvent = APP_UI_ADV_SET_STOP_IND;
break;
case DM_ADV_START_IND:
uiEvent = APP_UI_ADV_START;
break;
case DM_ADV_STOP_IND:
uiEvent = APP_UI_ADV_STOP;
break;
case DM_CONN_OPEN_IND:
voles_proc_msg(&pMsg->hdr);
DmConnSetDataLen(1, 251, 0x848);
uiEvent = APP_UI_CONN_OPEN;
retry_cnt = 0;
break;
case ATT_MTU_UPDATE_IND:
if ( AttGetMtu(1) < BLE_MSBC_DATA_BUFFER_SIZE )
{
if (retry_cnt < 5)
{
retry_cnt++;
AttcMtuReq(1, 247);
}
}
APP_TRACE_INFO2("ATT_MTU_UPDATE_IND AttGetMtu(), return = %d pMsg->att.mtu = %d\n", AttGetMtu(1), pMsg->att.mtu);
break;
case DM_CONN_DATA_LEN_CHANGE_IND:
am_util_debug_printf("DM_CONN_DATA_LEN_CHANGE_IND: status = %d, max RX len = %d, max TX len = %d \n", pMsg->dm.dataLenChange.hdr.status, pMsg->dm.dataLenChange.maxRxOctets, pMsg->dm.dataLenChange.maxTxOctets);
break;
case DM_CONN_CLOSE_IND:
APP_TRACE_INFO1("DM_CONN_CLOSE_IND reason = 0x%02x\n", pMsg->dm.connClose.reason);
amvoleClose(pMsg);
uiEvent = APP_UI_CONN_CLOSE;
// AppAdvStart(APP_MODE_DISCOVERABLE);
g_AmaConnId = DM_CONN_ID_NONE;
//g_eAmaStatus = VOS_AMA_INIT;
break;
case DM_CONN_UPDATE_IND:
voles_proc_msg(&pMsg->hdr);
break;
case DM_SEC_PAIR_CMPL_IND:
DmSecGenerateEccKeyReq();
uiEvent = APP_UI_SEC_PAIR_CMPL;
break;
case DM_SEC_PAIR_FAIL_IND:
DmSecGenerateEccKeyReq();
uiEvent = APP_UI_SEC_PAIR_FAIL;
break;
case DM_SEC_ENCRYPT_IND:
uiEvent = APP_UI_SEC_ENCRYPT;
break;
case DM_SEC_ENCRYPT_FAIL_IND:
uiEvent = APP_UI_SEC_ENCRYPT_FAIL;
break;
case DM_SEC_AUTH_REQ_IND:
AppHandlePasskey(&pMsg->dm.authReq);
break;
case DM_SEC_ECC_KEY_IND:
DmSecSetEccKey(&pMsg->dm.eccMsg.data.key);
break;
case DM_SEC_COMPARE_IND:
AppHandleNumericComparison(&pMsg->dm.cnfInd);
break;
case DM_PRIV_CLEAR_RES_LIST_IND:
APP_TRACE_INFO1("Clear resolving list status 0x%02x", pMsg->hdr.status);
break;
case DM_HW_ERROR_IND:
uiEvent = APP_UI_HW_ERROR;
break;
case DM_VENDOR_SPEC_CMD_CMPL_IND:
{
#if defined(AM_PART_APOLLO) || defined(AM_PART_APOLLO2)
uint8_t *param_ptr = &pMsg->dm.vendorSpecCmdCmpl.param[0];
switch (pMsg->dm.vendorSpecCmdCmpl.opcode)
{
case 0xFC20: //read at address
{
uint32_t read_value;
BSTREAM_TO_UINT32(read_value, param_ptr);
APP_TRACE_INFO3("VSC 0x%0x complete status %x param %x",
pMsg->dm.vendorSpecCmdCmpl.opcode,
pMsg->hdr.status,
read_value);
}
break;
default:
APP_TRACE_INFO2("VSC 0x%0x complete status %x",
pMsg->dm.vendorSpecCmdCmpl.opcode,
pMsg->hdr.status);
break;
}
#endif
}
break;
default:
break;
}
if (uiEvent != APP_UI_NONE)
{
AppUiAction(uiEvent);
}
}
void amvoleStartSendVoiceData()
{
g_start_voice_send = TRUE;
am_app_led_on();
voles_transmit_voice_data();
}
/*************************************************************************************************/
/*!
* \fn VoleHandlerInit
*
* \brief Application handler init function called during system initialization.
*
* \param handlerID WSF handler ID.
*
* \return None.
*/
/*************************************************************************************************/
void VoleHandlerInit(wsfHandlerId_t handlerId)
{
APP_TRACE_INFO0("VoleHandlerInit");
/* store handler ID */
amvoleHandlerId = handlerId;
/* Set configuration pointers */
pAppAdvCfg = (appAdvCfg_t *) &amvoleAdvCfg;
pAppSlaveCfg = (appSlaveCfg_t *) &amvoleSlaveCfg;
pAppSecCfg = (appSecCfg_t *) &amvoleSecCfg;
pAppUpdateCfg = (appUpdateCfg_t *) &amvoleUpdateCfg;
/* Initialize application framework */
AppSlaveInit();
AppServerInit();
/* Set stack configuration pointers */
pSmpCfg = (smpCfg_t *) &amvoleSmpCfg;
//voles_init(handlerId);
}
/*************************************************************************************************/
/*!
* \fn VoleHandler
*
* \brief WSF event handler for application.
*
* \param event WSF event mask.
* \param pMsg WSF message.
*
* \return None.
*/
/*************************************************************************************************/
void VoleHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg)
{
if (pMsg != NULL)
{
APP_TRACE_INFO1("vole got evt 0x%x", pMsg->event);
/* process ATT messages */
if (pMsg->event >= ATT_CBACK_START && pMsg->event <= ATT_CBACK_END)
{
/* process server-related ATT messages */
AppServerProcAttMsg(pMsg);
}
/* process DM messages */
else if (pMsg->event >= DM_CBACK_START && pMsg->event <= DM_CBACK_END)
{
/* process advertising and connection-related messages */
AppSlaveProcDmMsg((dmEvt_t *) pMsg);
/* process security-related messages */
AppSlaveSecProcDmMsg((dmEvt_t *) pMsg);
}
/* perform profile and user interface-related operations */
amvoleProcMsg((amvoleMsg_t *) pMsg);
}
}
/*************************************************************************************************/
/*!
* \fn VoleStart
*
* \brief Start the application.
*
* \return None.
*/
/*************************************************************************************************/
void VoleStart(void)
{
/* Register for stack callbacks */
DmRegister(amvoleDmCback);
DmConnRegister(DM_CLIENT_ID_APP, amvoleDmCback);
AttRegister(amvoleAttCback);
AttConnRegister(AppServerConnCback);
AttsCccRegister(VOLES_NUM_CCC_IDX, (attsCccSet_t *) amvoleCccSet, amvoleCccCback);
/* Register for app framework callbacks */
AppUiBtnRegister(amvoleBtnCback);
// set up adv data
memcpy(amvoleAdvDataDisc, amvoleAdvDataDiscDefault, sizeof(amvoleAdvDataDiscDefault));
memcpy(amvoleScanDataDisc, amvoleScanDataDiscDefault, sizeof(amvoleScanDataDiscDefault));
/* Initialize attribute server database */
SvcCoreGattCbackRegister(GattReadCback, GattWriteCback);
SvcCoreAddGroup();
SvcDisAddGroup();
SvcVolesCbackRegister(NULL, amvole_write_cback);
SvcVolesAddGroup();
/* Set Service Changed CCCD index. */
GattSetSvcChangedIdx(VOLES_GATT_SC_CCC_IDX);
/* Reset the device */
DmDevReset();
}

View File

@ -0,0 +1,824 @@
//*****************************************************************************
//
//! @file hci_drv.c
//!
//! @brief HCI driver interface.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "am_mcu_apollo.h"
#include "am_util.h"
#include "am_devices_em9304.h"
#include "em9304_init.h"
#include "em9304_patches.h"
#include "hci_apollo_config.h"
#define INVALIDATE_UNKNOWN_PATCHES
#define ENABLE_32K_CLK_FROM_APOLLO
#define SLEEP_CLK_PATCH_CONTAINER_ID (0x16)
// if a product is designed with step-up DCDC mode for EM9304
// and was programmed HCI v6 patch on OTP, it's required
// to define INVALIDATE_HCI_V6_PATCH_ON_OTP to do a special
// handling to invalidate the v6 patch on OTP and program
// v8 or later HCI patch.
#define INVALIDATE_HCI_V6_PATCH_ON_OTP
#ifdef INVALIDATE_HCI_V6_PATCH_ON_OTP
#define HCI_V6_PATCH_CONTAINER_ID 53
#endif
// This should be defined as the currently included HCI code patch
// e.g. currently v8 is latest, which has container ID 77.
#define HCI_CURRENT_CODE_PATCH_CONTAINER_ID 77
// Define the HCI Command Type locally.
#define HCI_CMD_TYPE 1
// EM_PatchQuery field offsets
#define PATCH_INDEX_OFFSET 3
// EM_PatchQuery response field offsets
#define CONTAINER_COUNT_INDEX 7
#define CONTAINER_ADDR_INDEX 15
#define CONTAINER_SIZE_INDEX 19
#define BUILD_NUMBER_INDEX 27
#define USER_BUILD_NUMBER_INDEX 29
#define CONTAINER_VERSION_INDEX 32
#define CONTAINER_TYPE_INDEX 33
#define CONTAINER_ID_INDEX 34
// EM_PatchQuery response values
#define CONTAINER_TYPE_CONFIG_DATA_WORD 1
#define CONTAINER_TYPE_RANDOM_DATA_WORD 2
#define CONTAINER_TYPE_RANDOM_DATA_BYTE 3
#define CONTAINER_TYPE_CONFIG_DATA_BYTE 11
// EM_PatchWrite and EM_PatchContine field offsets
#define PATCH_LENGTH_OFFSET 2
// EM_PatchWrite destination memory field offsets
#define PATCH_DEST_MEMORY_OFFSET 3
// EM_PatchWrite and EM_PatchContinue response field offsets
#define HCI_STATUS_OFFSET 6
#define EM_PATCH_STATUS_OFFSET 7
// EM_PatchWrite and EM_PatchContinue Patch Status values
#define EM_PATCH_APPLIED 1
#define EM_PATCH_CONTINUE 2
// Maximum number of attempts to wait for a response from EM9304.
#define EM9304_MAX_ATTEMPTS 100
#define EM9304_ATTEMPT_DELAY_MS 1
#define EM9304_IRAM1_START_ADDRESS 0x20000
// Initialization function error return status.
enum
{
EM9304_INIT_STATUS_SUCCESS,
EM9304_INIT_STATUS_ERROR
} e_em9304_init_status;
//*****************************************************************************
//
// HCI Commands for EM9304
//
//*****************************************************************************
uint8_t g_pui8EM_SleepDisable[] = {0x2D, 0xFC, 0x01, 0x00};
uint8_t g_pui8EM_SetOTPOn[] = {0x2B, 0xFC, 0x01, 0x01};
uint8_t g_pui8EM_SetOTPOff[] = {0x2B, 0xFC, 0x01, 0x00};
uint8_t g_pui8EM_SetIRAMOn[] = {0x2B, 0xFC, 0x01, 0x07};
uint8_t g_pui8EM_PatchQuery[] = {0x34, 0xFC, 0x02, 0x00, 0x00};
uint8_t g_pui8EM_SleepEnable[] = {0x2D, 0xFC, 0x01, 0x01};
uint8_t g_pui8EM_CpuReset[] = {0x32, 0xFC, 0x00};
uint32_t
applyEM9304Patches(uint32_t target_memory, uint32_t containerID);
//*****************************************************************************
//
// HCI RX packet buffer for EM9304 Driver.
//
//*****************************************************************************
static uint32_t g_pui32HCIRXBuffer[64];
//*****************************************************************************
//
// Static record of the EM9304 patch errors
//
//*****************************************************************************
uint32_t g_EMPatchErrors = 0;
//*****************************************************************************
//
//! @brief Patch Response helper functions for the EM9304 patches. This
//! routine blocks on a response from the EM9304 and filters the
//! vendor specific events.
//!
//! @return none.
//
//*****************************************************************************
uint32_t
waitEM9304Response(void)
{
uint32_t numBytesRx;
// HCI Respone should return in 1-2 messages at most, but driver returns
// 0 bytes when nothing is available, so wait up to 10msec.
for (uint32_t attempts = 0; attempts < EM9304_MAX_ATTEMPTS; attempts++)
{
numBytesRx = am_devices_em9304_block_read(&g_sEm9304, g_pui32HCIRXBuffer, 0);
// Look for "no message" return while filtering out the EM9304 vendor specific events.
if ((numBytesRx != 0) && (!((numBytesRx == 4) && (0x0000FF04 == (g_pui32HCIRXBuffer[0] & 0x0000FFFF)))))
{
return EM9304_INIT_STATUS_SUCCESS;
}
am_util_delay_ms(EM9304_ATTEMPT_DELAY_MS);
}
return EM9304_INIT_STATUS_ERROR;
}
//*****************************************************************************
//
//! @brief Function to check for valid patches in the em9304_patches.* files.
//! Invalid patches means that the scripts to generate the patch files
//! were run without valid *.emp files as input.
//!
//! @return bool (TRUE = patches are valid).
//
//*****************************************************************************
bool validEM9304Patches(void)
{
//
// Check to see if we have valid patches.
// NULL patch has a specific signature.
//
if ((1 == EM9304_PATCHES_NUM_PATCHES) &&
(0xFFFF == g_pEm9304Patches[0].buildNumber) &&
(0xFFFF == g_pEm9304Patches[0].userBuildNumber) &&
(0xFF == g_pEm9304Patches[0].containerVersion) &&
(0xFF == g_pEm9304Patches[0].containerType) &&
(0xFF == g_pEm9304Patches[0].containerID) &&
(0x00 == g_pEm9304Patches[0].applyPatch) &&
(0x00 == g_pEm9304Patches[0].startingPatch) &&
(0x00 == g_pEm9304Patches[0].endingPatch))
{
am_util_debug_printf("em9304_patches.c contains NULL patch only\n");
return false;
}
else
{
am_util_debug_printf("Valid em9304_patches.c file found\n");
return true;
}
}
//*****************************************************************************
//
//! @brief Function to invalidate a patch at a given address. The size field
//! is changed to corrupt the patch in OTP.
//!
//! @return status.
//
//*****************************************************************************
#ifdef INVALIDATE_UNKNOWN_PATCHES
static uint32_t invalidateEM9304Patch(uint32_t addr, uint32_t size)
{
uint8_t *bytePtr = (uint8_t *)&g_pui32HCIRXBuffer;
uint8_t payload[] =
{
0x22, 0xFC, //WriteAtAddr command
0x0C, //HCI param length
0, 0, 0, 0, // container address placeholder
0x33, 0x39, 0x6D, 0x65, //signature
0, 0, 0, 0 //size placeholder
};
payload[3] = (uint8_t)(addr & 0xFF);
payload[4] = (uint8_t)((addr & 0xFF00) >> 8);
payload[5] = (uint8_t)((addr & 0xFF0000) >> 16);
payload[6] = (uint8_t)((addr & 0xFF000000) >> 24);
size |= 0x36000000; // mask the size to change the patch (invalidate it).
payload[11] = (uint8_t)(size & 0xFF);
payload[12] = (uint8_t)((size & 0xFF00) >> 8);
payload[13] = (uint8_t)((size & 0xFF0000) >> 16);
payload[14] = (uint8_t)((size & 0xFF000000) >> 24);
am_devices_em9304_block_write(&g_sEm9304, HCI_CMD_TYPE, payload, sizeof(payload));
if ((EM9304_INIT_STATUS_SUCCESS != waitEM9304Response()) || (bytePtr[HCI_STATUS_OFFSET] != 0))
{
am_util_debug_printf("Invalidating patch at %x status %d\n", addr, bytePtr[HCI_STATUS_OFFSET]);
return EM9304_INIT_STATUS_ERROR;
}
am_util_debug_printf("Invalidating patch at %x status OK\n", addr);
return EM9304_INIT_STATUS_SUCCESS;
}
#endif
//*****************************************************************************
//
//! @brief Query the EM9304 patches. This routine uses the EM_PatchQuery HCI
//! command to interogate the connected EM9304 about its current patch
//! state and then update the patch Container Info data structure.
//!
//! @return status.
//
//*****************************************************************************
uint32_t
queryEM9304Patches(void)
{
uint32_t containerCount;
uint32_t buildNumber, userBuildNumber, containerVersion, containerType, containerID;
#ifdef INVALIDATE_UNKNOWN_PATCHES
uint32_t containerAddr, containerSize;
bool invalidatePatch = false;
#endif
uint8_t *pBuf = (uint8_t *)g_pui32HCIRXBuffer;
// Initialize the container info patch status
for (uint32_t patch = 0; patch < EM9304_PATCHES_NUM_PATCHES; patch++)
{
// Check patch for enabling 32Khz clck from Apollo MCU
if ((g_pEm9304Patches[patch].userBuildNumber == 2) && (g_pEm9304Patches[patch].containerID == SLEEP_CLK_PATCH_CONTAINER_ID))
{
uint32_t ui32PN;
//
// Device identification
//
ui32PN = AM_REG(MCUCTRL, CHIP_INFO) &
AM_UTIL_MCUCTRL_CHIP_INFO_PARTNUM_PN_M;
#ifdef ENABLE_32K_CLK_FROM_APOLLO
// Currently only enable this for Apollo2-Blue
if (ui32PN == AM_UTIL_MCUCTRL_CHIP_INFO_PARTNUM_APOLLOBL)
{
g_pEm9304Patches[patch].applyPatch = true;
// GPIO 24 in Apollo2-blue connected to LFCLK in EM9304
am_hal_gpio_pin_config(24, AM_HAL_PIN_24_CLKOUT);
am_hal_clkgen_osc_start(AM_HAL_CLKGEN_OSC_XT);
am_util_delay_ms(500);
am_hal_clkgen_clkout_enable(AM_HAL_CLKGEN_CLKOUT_CKSEL_XT);
}
#endif
}
else
{
g_pEm9304Patches[patch].applyPatch = true;
}
}
// Send the EM_SetSleepOptions command to disable sleep and check the response.
am_devices_em9304_block_write(&g_sEm9304, HCI_CMD_TYPE, g_pui8EM_SleepDisable, sizeof(g_pui8EM_SleepDisable));
if (EM9304_INIT_STATUS_SUCCESS != waitEM9304Response())
{
am_util_debug_printf("No Response to EM9304 Sleep Disable\n");
return EM9304_INIT_STATUS_ERROR;
}
// Check that the response is to the Sleep Disable.
if ((0x01040E04 != g_pui32HCIRXBuffer[0]) || (0x0000FC2D != (g_pui32HCIRXBuffer[1] & 0x0000FFFF)))
{
am_util_debug_printf("Invalid Response to EM9304 Sleep Disable\n");
return EM9304_INIT_STATUS_ERROR;
}
// Send the EM_SetMemoryMode command to turn on OTP and check the response.
am_devices_em9304_block_write(&g_sEm9304, HCI_CMD_TYPE, g_pui8EM_SetOTPOn, sizeof(g_pui8EM_SetOTPOn));
if (EM9304_INIT_STATUS_SUCCESS != waitEM9304Response())
{
am_util_debug_printf("No Response to EM9304 OTP Enable\n");
return EM9304_INIT_STATUS_ERROR;
}
// Check that the response is to the OTP enable.
if ((0x01040E04 != g_pui32HCIRXBuffer[0]) || (0x0000FC2B != (g_pui32HCIRXBuffer[1] & 0x0000FFFF)))
{
am_util_debug_printf("Invalid Response to EM9304 OTP Enable\n");
return EM9304_INIT_STATUS_ERROR;
}
// Query the EM9304 with the EM_PatchQuery and Patch Index = 0. This will return the Container Count.
am_devices_em9304_block_write(&g_sEm9304, HCI_CMD_TYPE, g_pui8EM_PatchQuery, sizeof(g_pui8EM_PatchQuery));
if (EM9304_INIT_STATUS_SUCCESS != waitEM9304Response())
{
am_util_debug_printf("No Response to EM9304 Patch Query\n");
return EM9304_INIT_STATUS_ERROR;
}
// Check that the response is to the Patch Query.
if ((0x01200E04 != g_pui32HCIRXBuffer[0]) || (0x0000FC34 != (g_pui32HCIRXBuffer[1] & 0x0000FFFF)))
{
am_util_debug_printf("Invalid Response to EM9304 Patch Query\n");
return EM9304_INIT_STATUS_ERROR;
}
// Extract the container information from the query response.
containerCount = (uint32_t)pBuf[CONTAINER_COUNT_INDEX] +
((uint32_t)pBuf[CONTAINER_COUNT_INDEX + 1] << 8);
// Assume the first patch is the manufacturing trim patch.
// This is the only patch that never should be invalidated.
am_util_debug_printf("Number of patch containers on EM9304 excluding Patch#0: %d\n", containerCount - 1);
#ifdef INVALIDATE_UNKNOWN_PATCHES
#ifdef INVALIDATE_HCI_V6_PATCH_ON_OTP
bool old_patch_invalidated = false;
bool hci_v6_patch_present_on_otp = false;
// For each container in Container Count to see if HCI meta patch v6 patch
// is present
for (uint32_t container = 1; container < containerCount; container++)
{
// Send the EM_PatchQuery for the Container.
g_pui8EM_PatchQuery[PATCH_INDEX_OFFSET] = container;
am_devices_em9304_block_write(&g_sEm9304, HCI_CMD_TYPE, g_pui8EM_PatchQuery, sizeof(g_pui8EM_PatchQuery));
if (EM9304_INIT_STATUS_SUCCESS != waitEM9304Response())
{
am_util_debug_printf("No Response to EM9304 Patch Query\n");
return EM9304_INIT_STATUS_ERROR;
}
containerID = pBuf[CONTAINER_ID_INDEX];
// v6 patch's container ID is 53 in decimal.
if (containerID == HCI_V6_PATCH_CONTAINER_ID)
{
hci_v6_patch_present_on_otp = true;
am_util_debug_printf("HCI v6 patch found in OTP\n");
break;
}
}
if (hci_v6_patch_present_on_otp)
{
// here we have to do code-reset to EM9304
am_hal_gpio_pin_config(HCI_APOLLO_RESET_PIN, AM_HAL_GPIO_OUTPUT);
am_hal_gpio_out_bit_clear(HCI_APOLLO_RESET_PIN);
am_util_delay_ms(10);
am_hal_gpio_out_bit_set(HCI_APOLLO_RESET_PIN);
am_util_delay_ms(20);
// Apply the latest code patch into IRAM in order to invalidate v6 patch in otp
// properly.
applyEM9304Patches(DEST_MEMORY_IRAM, HCI_CURRENT_CODE_PATCH_CONTAINER_ID);
// Send EM_CpuReset HCI command.
am_devices_em9304_block_write(&g_sEm9304, HCI_CMD_TYPE, g_pui8EM_CpuReset, sizeof(g_pui8EM_CpuReset));
// HCI Respone should return in 1-2 messages at most, but driver returns
// 0 bytes when nothing is available, so wait up to 10msec.
for (uint32_t attempts = 0; attempts < EM9304_MAX_ATTEMPTS; attempts++)
{
uint32_t numBytesRx;
numBytesRx = am_devices_em9304_block_read(&g_sEm9304, g_pui32HCIRXBuffer, 0);
if ((numBytesRx == 7) && (0x0000FC32 == (g_pui32HCIRXBuffer[1] & 0x0000FFFF)))
{
am_util_debug_printf("EM9304 CPU Reset Successfully\n");
break;
}
am_util_delay_ms(EM9304_ATTEMPT_DELAY_MS);
}
// Send the EM_SetSleepOptions command to disable sleep and check the response.
am_devices_em9304_block_write(&g_sEm9304, HCI_CMD_TYPE, g_pui8EM_SleepDisable, sizeof(g_pui8EM_SleepDisable));
if (EM9304_INIT_STATUS_SUCCESS != waitEM9304Response())
{
am_util_debug_printf("No Response to EM9304 Sleep Disable\n");
return EM9304_INIT_STATUS_ERROR;
}
// Check that the response is to the Sleep Disable.
if ((0x01040E04 != g_pui32HCIRXBuffer[0]) || (0x0000FC2D != (g_pui32HCIRXBuffer[1] & 0x0000FFFF)))
{
am_util_debug_printf("Invalid Response to EM9304 Sleep Disable\n");
return EM9304_INIT_STATUS_ERROR;
}
// Send the EM_SetMemoryMode command to turn on OTP and check the response.
am_devices_em9304_block_write(&g_sEm9304, HCI_CMD_TYPE, g_pui8EM_SetOTPOn, sizeof(g_pui8EM_SetOTPOn));
if (EM9304_INIT_STATUS_SUCCESS != waitEM9304Response())
{
am_util_debug_printf("No Response to EM9304 OTP Enable\n");
return EM9304_INIT_STATUS_ERROR;
}
// Check that the response is to the OTP enable.
if ((0x01040E04 != g_pui32HCIRXBuffer[0]) || (0x0000FC2B != (g_pui32HCIRXBuffer[1] & 0x0000FFFF)))
{
am_util_debug_printf("Invalid Response to EM9304 OTP Enable\n");
return EM9304_INIT_STATUS_ERROR;
}
// Query the EM9304 with the EM_PatchQuery and Patch Index = 0. This will return the Container Count.
am_devices_em9304_block_write(&g_sEm9304, HCI_CMD_TYPE, g_pui8EM_PatchQuery, sizeof(g_pui8EM_PatchQuery));
if (EM9304_INIT_STATUS_SUCCESS != waitEM9304Response())
{
am_util_debug_printf("No Response to EM9304 Patch Query\n");
return EM9304_INIT_STATUS_ERROR;
}
// Check that the response is to the Patch Query.
if ((0x01200E04 != g_pui32HCIRXBuffer[0]) || (0x0000FC34 != (g_pui32HCIRXBuffer[1] & 0x0000FFFF)))
{
am_util_debug_printf("Invalid Response to EM9304 Patch Query\n");
return EM9304_INIT_STATUS_ERROR;
}
// Extract the container information from the query response.
containerCount = (uint32_t)pBuf[CONTAINER_COUNT_INDEX] +
((uint32_t)pBuf[CONTAINER_COUNT_INDEX + 1] << 8);
// Assume the first patch is the manufacturing trim patch.
// This is the only patch that never should be invalidated.
am_util_debug_printf("Number of patch containers on EM9304 excluding Patch#0: %d\n", containerCount - 1);
}
#endif
#endif
// For each container in Container Count
for (uint32_t container = 1; container < containerCount; container++)
{
// Send the EM_PatchQuery for the Container.
g_pui8EM_PatchQuery[PATCH_INDEX_OFFSET] = container;
am_devices_em9304_block_write(&g_sEm9304, HCI_CMD_TYPE, g_pui8EM_PatchQuery, sizeof(g_pui8EM_PatchQuery));
if (EM9304_INIT_STATUS_SUCCESS != waitEM9304Response())
{
am_util_debug_printf("No Response to EM9304 Patch Query\n");
return EM9304_INIT_STATUS_ERROR;
}
// Extract the container information from the query response.
containerCount = (uint32_t)pBuf[CONTAINER_COUNT_INDEX] +
((uint32_t)pBuf[CONTAINER_COUNT_INDEX + 1] << 8);
buildNumber = (uint32_t)pBuf[BUILD_NUMBER_INDEX] +
((uint32_t)(pBuf[BUILD_NUMBER_INDEX + 1] << 8));
userBuildNumber = (uint32_t)pBuf[USER_BUILD_NUMBER_INDEX] +
((uint32_t)(pBuf[USER_BUILD_NUMBER_INDEX + 1] << 8));
containerVersion = pBuf[CONTAINER_VERSION_INDEX];
containerType = pBuf[CONTAINER_TYPE_INDEX];
containerID = pBuf[CONTAINER_ID_INDEX];
#ifdef INVALIDATE_UNKNOWN_PATCHES
containerAddr = (uint32_t)((pBuf[CONTAINER_ADDR_INDEX + 3] << 24) +
(pBuf[CONTAINER_ADDR_INDEX + 2] << 16) +
(pBuf[CONTAINER_ADDR_INDEX + 1] << 8) +
pBuf[CONTAINER_ADDR_INDEX]);
containerSize = (uint32_t)((pBuf[CONTAINER_SIZE_INDEX + 3] << 24) +
(pBuf[CONTAINER_SIZE_INDEX + 2] << 16) +
(pBuf[CONTAINER_SIZE_INDEX + 1] << 8) +
pBuf[CONTAINER_SIZE_INDEX]);
am_util_debug_printf("Patch #%d: Container Address = %8.8X Container Size = %4.4d Container Type=%d Container ID=%d Container Version=%d Build Number=%d User Build Number=%d\n",
container, containerAddr, containerSize, containerType, containerID, containerVersion, buildNumber, userBuildNumber);
// if patch is on IRAM, we wont' do anything to it.
if (containerAddr & EM9304_IRAM1_START_ADDRESS)
{
continue;
}
// Check for patches that are likely not configuration managed by the customer.
// Avoid invalidating these patches.
if (((CONTAINER_TYPE_CONFIG_DATA_WORD == containerType) ||
(CONTAINER_TYPE_RANDOM_DATA_WORD == containerType) ||
(CONTAINER_TYPE_CONFIG_DATA_BYTE == containerType) ||
(CONTAINER_TYPE_RANDOM_DATA_BYTE == containerType)) &&
((0 == buildNumber) || (3089 == buildNumber)) &&
(0 == userBuildNumber))
{
invalidatePatch = false;
}
else
{
// Initialize the invalidate flag.
invalidatePatch = true;
}
#endif
// For each local patch, compare the Container Version, Container Type, and Container ID to the container info.
for (uint32_t patch = 0; patch < EM9304_PATCHES_NUM_PATCHES; patch++)
{
if ((g_pEm9304Patches[patch].buildNumber == buildNumber) &&
(g_pEm9304Patches[patch].userBuildNumber == userBuildNumber) &&
(g_pEm9304Patches[patch].containerVersion == containerVersion) &&
(g_pEm9304Patches[patch].containerType == containerType) &&
(g_pEm9304Patches[patch].containerID == containerID))
{
g_pEm9304Patches[patch].applyPatch = false; // Patch is already installed, so don't apply.
#ifdef INVALIDATE_UNKNOWN_PATCHES
// Note that we will "re-enable" patches here even if they met the criteria above (which can happen!)
invalidatePatch = false;
#endif
break;
}
}
#ifdef INVALIDATE_UNKNOWN_PATCHES
// Check to see if we need to invalidate the patch.
if (invalidatePatch)
{
invalidateEM9304Patch(containerAddr, containerSize);
// if any old patch on OTP got invalidated, we need to hard-reset em9304
// for the patch not to take effect so that subsequent patch applying can
// work reliably.
old_patch_invalidated = true;
}
#endif
}
#ifdef INVALIDATE_UNKNOWN_PATCHES
#ifdef INVALIDATE_HCI_V6_PATCH_ON_OTP
if (hci_v6_patch_present_on_otp || old_patch_invalidated)
{
// If we has invalidate v6 or other unknown patch on OTP
// we should do a cold reset to em9304 in order to clean
// the previously programmed patch in IRAM.
// here we have to do code-reset to EM9304
am_hal_gpio_pin_config(HCI_APOLLO_RESET_PIN, AM_HAL_GPIO_OUTPUT);
am_hal_gpio_out_bit_clear(HCI_APOLLO_RESET_PIN);
am_util_delay_ms(10);
am_hal_gpio_out_bit_set(HCI_APOLLO_RESET_PIN);
am_util_delay_ms(20);
}
#endif
#endif
// if (DEST_MEMORY_IRAM == EM9304_PATCHES_DEST_MEMORY)
// {
// // Send the EM_SetMemoryMode command to turn off OTP and check the response.
// am_devices_em9304_block_write(&g_sEm9304, HCI_CMD_TYPE, g_pui8EM_SetOTPOff, sizeof(g_pui8EM_SetOTPOff) );
// if (EM9304_INIT_STATUS_SUCCESS != waitEM9304Response())
// {
// am_util_debug_printf("No Response to EM9304 OTP Disable\n");
// return EM9304_INIT_STATUS_ERROR;
// }
// // Check that the response is to the OTP Disable.
// if ((0x01040E04 != g_pui32HCIRXBuffer[0]) || (0x0000FC2B != (g_pui32HCIRXBuffer[1] & 0x0000FFFF)))
// {
// am_util_debug_printf("Invalid Response to EM9304 OTP Disable\n");
// return EM9304_INIT_STATUS_ERROR;
// }
// }
// Send the EM_SetSleepOptions command to disable sleep and check the response.
am_devices_em9304_block_write(&g_sEm9304, HCI_CMD_TYPE, g_pui8EM_SleepEnable, sizeof(g_pui8EM_SleepEnable));
if (EM9304_INIT_STATUS_SUCCESS != waitEM9304Response())
{
am_util_debug_printf("No Response to EM9304 Sleep Enable\n");
return EM9304_INIT_STATUS_ERROR;
}
// Check that the response is to the Sleep Enable.
if ((0x01040E04 != g_pui32HCIRXBuffer[0]) || (0x0000FC2D != (g_pui32HCIRXBuffer[1] & 0x0000FFFF)))
{
am_util_debug_printf("Invalid Response to EM9304 Sleep Enable\n");
return EM9304_INIT_STATUS_ERROR;
}
return EM9304_INIT_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Apply the EM9304 patches. This routine uses the EM_PatchQuery HCI
//! command to interogate the connected EM9304 about its current patch
//! state and then update the patch Container Info data structure.
//!
//!
//! @return Returns the status of the patch application (< 0 is an error).
//
//*****************************************************************************
uint32_t
applyEM9304Patches(uint32_t target_memory, uint32_t containerID)
{
uint8_t *bytePtr = (uint8_t *)&g_pui32HCIRXBuffer;
uint32_t ui32PN;
g_EMPatchErrors = 0;
//
// Device identification
//
ui32PN = AM_REG(MCUCTRL, CHIP_INFO) &
AM_UTIL_MCUCTRL_CHIP_INFO_PARTNUM_PN_M;
// only enable clock for Apollo2-blue (maybe later Apollo3 as well)
if (ui32PN == AM_UTIL_MCUCTRL_CHIP_INFO_PARTNUM_APOLLOBL)
{
}
if (DEST_MEMORY_IRAM == target_memory)
{
// Send the EM_SetMemoryMode command to turn on IRAM and check the response.
am_devices_em9304_block_write(&g_sEm9304, HCI_CMD_TYPE, g_pui8EM_SetIRAMOn, sizeof(g_pui8EM_SetIRAMOn));
if (EM9304_INIT_STATUS_SUCCESS != waitEM9304Response())
{
am_util_debug_printf("No Response to EM9304 IRAM Enable\n");
return EM9304_INIT_STATUS_ERROR;
}
// Check that the response is to the IRAM enable.
if ((0x01040E04 != g_pui32HCIRXBuffer[0]) || (0x0000FC2B != (g_pui32HCIRXBuffer[1] & 0x0000FFFF)))
{
am_util_debug_printf("Invalid Response to EM9304 IRAM Enable\n");
return EM9304_INIT_STATUS_ERROR;
}
}
// Loop through the patches and apply those that are not already there.
// For each local patch, compare the Container Version, Container Type, and Container ID to the container info.
for (uint32_t patch = 0; patch < EM9304_PATCHES_NUM_PATCHES; patch++)
{
if ((containerID != 0) && (containerID != (uint32_t)g_pEm9304Patches[patch].containerID))
{
continue;
}
if (g_pEm9304Patches[patch].applyPatch)
{
am_util_debug_printf("Applying Patch #%d: Container Type=%d Container ID=%d Container Version=%d Build Number=%d User Build Number=%d\n",
patch, g_pEm9304Patches[patch].containerType, g_pEm9304Patches[patch].containerID, g_pEm9304Patches[patch].containerVersion,
g_pEm9304Patches[patch].buildNumber, g_pEm9304Patches[patch].userBuildNumber);
for (uint32_t index = g_pEm9304Patches[patch].startingPatch; index < g_pEm9304Patches[patch].endingPatch; index++)
{
if ((index == g_pEm9304Patches[patch].startingPatch) &&
(target_memory != g_pEm9304PatchesHCICmd[index][PATCH_DEST_MEMORY_OFFSET]))
{
// max payload is 64 bytes for patch writing
uint8_t g_pEm9304PatchesHCICmd_temp[80];
memcpy(g_pEm9304PatchesHCICmd_temp, g_pEm9304PatchesHCICmd[index],
g_pEm9304PatchesHCICmd[index][PATCH_LENGTH_OFFSET] + 3);
// change destination memory type
g_pEm9304PatchesHCICmd_temp[PATCH_DEST_MEMORY_OFFSET] = target_memory;
am_devices_em9304_block_write(&g_sEm9304, HCI_CMD_TYPE, (uint8_t *)g_pEm9304PatchesHCICmd_temp,
g_pEm9304PatchesHCICmd_temp[PATCH_LENGTH_OFFSET] + 3);
}
else
{
am_devices_em9304_block_write(&g_sEm9304, HCI_CMD_TYPE, (uint8_t *)g_pEm9304PatchesHCICmd[index],
g_pEm9304PatchesHCICmd[index][PATCH_LENGTH_OFFSET] + 3);
}
if (EM9304_INIT_STATUS_SUCCESS != waitEM9304Response())
{
am_util_debug_printf("No Response to EM9304 Patch Write\n");
return EM9304_INIT_STATUS_ERROR;
}
if ((g_pEm9304PatchesHCICmd[index][0] == 0x27) &&
((bytePtr[EM_PATCH_STATUS_OFFSET] != EM_PATCH_CONTINUE) &&
(bytePtr[EM_PATCH_STATUS_OFFSET] != EM_PATCH_APPLIED)))
{
am_util_debug_printf("Error Response (%d)to EM9304 Patch Write\n", bytePtr[EM_PATCH_STATUS_OFFSET]);
return EM9304_INIT_STATUS_ERROR;
}
else if (g_pEm9304PatchesHCICmd[index][0] == 0x28)
{
if (((index + 1) == g_pEm9304Patches[patch].endingPatch) && (bytePtr[EM_PATCH_STATUS_OFFSET] != EM_PATCH_APPLIED))
{
am_util_debug_printf("Error Response to EM9304 Patch Continue (next to last patch segment)\n");
return EM9304_INIT_STATUS_ERROR;
}
else if (((index + 1) < g_pEm9304Patches[patch].endingPatch) && (bytePtr[EM_PATCH_STATUS_OFFSET] != EM_PATCH_CONTINUE))
{
am_util_debug_printf("Error Response to EM9304 Patch Continue (last patch segment)\n");
return EM9304_INIT_STATUS_ERROR;
}
}
}
}
}
return EM9304_INIT_STATUS_SUCCESS;
}
//*****************************************************************************
//
// Configure the necessary pins and start the EM9304 radio.
//
//*****************************************************************************
uint32_t
initEM9304(void)
{
if (validEM9304Patches())
{
//
// Query the EM9304 for patches
//
if (EM9304_INIT_STATUS_SUCCESS == queryEM9304Patches())
{
//
// Apply the patches not already in the EM9304
//
if (EM9304_INIT_STATUS_SUCCESS != applyEM9304Patches(EM9304_PATCHES_DEST_MEMORY, 0))
{
am_util_debug_printf("EM9304 Patch Application Failed\n");
}
}
else
{
am_util_debug_printf("EM9304 Patching Query Failed. Patch update not applied\n");
}
}
// Send EM_CpuReset HCI command.
am_devices_em9304_block_write(&g_sEm9304, HCI_CMD_TYPE, g_pui8EM_CpuReset, sizeof(g_pui8EM_CpuReset));
// HCI Respone should return in 1-2 messages at most, but driver returns
// 0 bytes when nothing is available, so wait up to 10msec.
for (uint32_t attempts = 0; attempts < EM9304_MAX_ATTEMPTS; attempts++)
{
uint32_t numBytesRx;
numBytesRx = am_devices_em9304_block_read(&g_sEm9304, g_pui32HCIRXBuffer, 0);
if ((numBytesRx == 7) && (0x0000FC32 == (g_pui32HCIRXBuffer[1] & 0x0000FFFF)))
{
am_util_debug_printf("EM9304 CPU Reset Successfully\n");
break;
}
am_util_delay_ms(EM9304_ATTEMPT_DELAY_MS);
}
return EM9304_PATCHES_DEST_MEMORY;
}

View File

@ -0,0 +1,51 @@
//*****************************************************************************
//
//! @file em9304_init.h
//!
//! @brief Initialization functions for the EM Micro EM9304 BLE radio.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef EM9304_INIT_H
#define EM9304_INIT_H
uint32_t initEM9304(void);
#endif // EM9304_INIT_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,95 @@
//*****************************************************************************
//
//! @file em9304_patches.h
//!
//! @brief This is a generated file.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#ifndef EM9304_PATCHES_H
#define EM9304_PATCHES_H
//*****************************************************************************
//
// Length of the binary array in bytes.
//
//*****************************************************************************
#define EM9304_PATCHES_NUM_PATCHES 8
// EM patch destination memory:
// 1 means EM patch will be programmed into OTP if emp file
// was not programmed before.
// 0 means EM patch will be programmed into IRAM each time when
// EM9304 is cold boot.
#define DEST_MEMORY_IRAM 0
#define DEST_MEMORY_OTP 1
#define EM9304_PATCHES_DEST_MEMORY 0
//*****************************************************************************
//
// EM9304 Container Info type
//
//*****************************************************************************
typedef struct
{
uint16_t buildNumber; // Firmware Build Number
uint16_t userBuildNumber; // User defined Build Number (determines patch precedence)
uint8_t containerVersion; // Container Version
uint8_t containerType; // Container Type
uint8_t containerID; // Container ID
bool applyPatch; // Flag to apply this patch.
uint8_t startingPatch; // Starting patch index.
uint8_t endingPatch; // Ending patch index + 1.
} em9304_container_info_t;
//*****************************************************************************
//
// Extracted binary array.
//
//*****************************************************************************
extern em9304_container_info_t g_pEm9304Patches[8];
extern const uint8_t g_pEm9304PatchesHCICmd[131][68];
#endif // EM9304_PATCHES_H

View File

@ -0,0 +1,321 @@
// ****************************************************************************
//
// ble_menu.c
//! @file
//!
//! @brief Functions for BLE control menu.
//!
//! @{
//
// ****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include "ble_menu.h"
#include "wsf_types.h"
#include "amdtp_api.h"
#include "app_api.h"
char menuRxData[20];
uint32_t menuRxDataLen = 0;
sBleMenuCb bleMenuCb;
char mainMenuContent[BLE_MENU_ID_MAX][32] = {
"1. BLE_MENU_ID_GAP",
"2. BLE_MENU_ID_GATT",
"3. BLE_MENU_ID_AMDTP",
};
char gapMenuContent[GAP_MENU_ID_MAX][32] = {
"1. Start Scan",
"2. Stop Scan",
"3. Show Scan Results",
"4. Create Connection"
};
char gattMenuContent[GATT_MENU_ID_MAX][32] = {
"1. TBD",
};
char amdtpMenuContent[AMDTP_MENU_ID_MAX][64] = {
"1. Send test data continuously",
"2. Stop sending test data",
"3. Request Server to send",
"4. Request Server to stop sending"
};
static void BleMenuShowMenu(void);
//*****************************************************************************
//
// Transmit delay waits for busy bit to clear to allow
// for a transmission to fully complete before proceeding.
//
//*****************************************************************************
void
uart_transmit_delay(uint32_t ui32Module)
{
//
// Wait until busy bit clears to make sure UART fully transmitted last byte
//
//while ( am_hal_uart_flags_get(ui32Module) & AM_HAL_UART_FR_BUSY );
}
static bool isSelectionHome(void)
{
if (menuRxData[0] == 'h')
{
bleMenuCb.menuId = BLE_MENU_ID_MAIN;
bleMenuCb.prevMenuId = BLE_MENU_ID_MAIN;
bleMenuCb.gapMenuSelected = GAP_MENU_ID_NONE;
return true;
}
return false;
}
static void showScanResults(void)
{
appDevInfo_t *devInfo;
uint8_t num = AppScanGetNumResults();
am_menu_printf("--------------------Scan Results--------------------\r\n");
for (int i = 0; i < num; i++)
{
devInfo = AppScanGetResult(i);
if (devInfo)
{
am_menu_printf("%d : %d %02x%02x%02x%02x%02x%02x \r\n", i, devInfo->addrType,
devInfo->addr[0], devInfo->addr[1], devInfo->addr[2], devInfo->addr[3], devInfo->addr[4], devInfo->addr[5]);
}
}
am_menu_printf("-----------------------------------------------------\r\n");
}
static void handleGAPSlection(void)
{
eGapMenuId id;
if (bleMenuCb.gapMenuSelected == GAP_MENU_ID_NONE)
{
id = (eGapMenuId)(menuRxData[0] - '0');
}
else
{
id = bleMenuCb.gapMenuSelected;
}
switch (id)
{
case GAP_MENU_ID_SCAN_START:
am_menu_printf("scan start\r\n");
AmdtpcScanStart();
break;
case GAP_MENU_ID_SCAN_STOP:
AmdtpcScanStop();
break;
case GAP_MENU_ID_SCAN_RESULTS:
showScanResults();
break;
case GAP_MENU_ID_CONNECT:
if (bleMenuCb.gapMenuSelected == GAP_MENU_ID_NONE)
{
am_menu_printf("choose an idx from scan results to connect:\r\n");
showScanResults();
bleMenuCb.gapMenuSelected = GAP_MENU_ID_CONNECT;
}
else
{
uint8_t idx = menuRxData[0] - '0';
bleMenuCb.gapMenuSelected = GAP_MENU_ID_NONE;
AmdtpcConnOpen(idx);
}
break;
default:
break;
}
}
static void handleAMDTPSlection(void)
{
eAmdtpMenuId id;
id = (eAmdtpMenuId)(menuRxData[0] - '0');
switch (id)
{
case AMDTP_MENU_ID_SEND:
am_menu_printf("send data to server\r\n");
AmdtpcSendTestData();
break;
case AMDTP_MENU_ID_SEND_STOP:
am_menu_printf("send data to server stop\r\n");
AmdtpcSendTestDataStop();
break;
case AMDTP_MENU_ID_SERVER_SEND:
am_menu_printf("request server to send\r\n");
AmdtpcRequestServerSend();
break;
case AMDTP_MENU_ID_SERVER_SEND_STOP:
am_menu_printf("request server to stop\r\n");
AmdtpcRequestServerSendStop();
break;
default:
break;
}
}
static void handleSelection(void)
{
if (isSelectionHome())
{
BleMenuShowMenu();
return;
}
switch (bleMenuCb.menuId)
{
case BLE_MENU_ID_MAIN:
bleMenuCb.menuId = (eBleMenuId)(menuRxData[0] - '0');
BleMenuShowMenu();
break;
case BLE_MENU_ID_GAP:
handleGAPSlection();
break;
case BLE_MENU_ID_GATT:
break;
case BLE_MENU_ID_AMDTP:
handleAMDTPSlection();
break;
default:
am_util_debug_printf("handleSelection() unknown input\n");
break;
}
}
void
BleMenuRx(void)
{
if (menuRxDataLen == 0)
{
return;
}
menuRxData[menuRxDataLen] = '\0';
am_util_debug_printf("BleMenuRx data = %s\n", menuRxData);
handleSelection();
// clear UART rx buffer
memset(menuRxData, 0, sizeof(menuRxData));
menuRxDataLen = 0;
}
static void
BLEMenuShowMainMenu(void)
{
am_menu_printf("--------------------BLE main menu--------------------\r\n");
for (int i = 0; i < BLE_MENU_ID_MAX; i++)
{
am_menu_printf("%s\r\n", mainMenuContent[i]);
uart_transmit_delay(AM_BSP_UART_PRINT_INST);
}
am_menu_printf("hint: use 'h' to do main menu\r\n");
am_menu_printf("-----------------------------------------------------\r\n");
}
static void
BLEMenuShowGAPMenu(void)
{
for (int i = 0; i < GAP_MENU_ID_MAX; i++)
{
am_menu_printf("%s\r\n", gapMenuContent[i]);
uart_transmit_delay(AM_BSP_UART_PRINT_INST);
}
}
static void
BLEMenuShowGATTMenu(void)
{
for (int i = 0; i < GATT_MENU_ID_MAX; i++)
{
am_menu_printf("%s\r\n", gattMenuContent[i]);
uart_transmit_delay(AM_BSP_UART_PRINT_INST);
}
}
static void
BLEMenuShowAMDTPMenu(void)
{
for (int i = 0; i < AMDTP_MENU_ID_MAX; i++)
{
am_menu_printf("%s\r\n", amdtpMenuContent[i]);
uart_transmit_delay(AM_BSP_UART_PRINT_INST);
}
}
static void
BleMenuShowMenu(void)
{
switch (bleMenuCb.menuId)
{
case BLE_MENU_ID_MAIN:
BLEMenuShowMainMenu();
break;
case BLE_MENU_ID_GAP:
BLEMenuShowGAPMenu();
break;
case BLE_MENU_ID_GATT:
BLEMenuShowGATTMenu();
break;
case BLE_MENU_ID_AMDTP:
BLEMenuShowAMDTPMenu();
break;
default:
break;
}
}
void
BleMenuInit(void)
{
bleMenuCb.prevMenuId = BLE_MENU_ID_MAIN;
bleMenuCb.menuId = BLE_MENU_ID_MAIN;
bleMenuCb.gapMenuSelected = GAP_MENU_ID_NONE;
bleMenuCb.gattMenuSelected = GATT_MENU_ID_NONE;
BleMenuShowMenu();
}

View File

@ -0,0 +1,125 @@
// ****************************************************************************
//
// ble_menu.h
//! @file
//!
//! @brief Functions for BLE control menu.
//!
//! @{
//
// ****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef BLE_MENU_H
#define BLE_MENU_H
#include "am_util.h"
#include "am_util_stdio.h"
#include "am_bsp.h"
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdarg.h>
#ifdef __cplusplus
extern "C"
{
#endif
typedef enum
{
BLE_MENU_ID_MAIN = 0,
BLE_MENU_ID_GAP,
BLE_MENU_ID_GATT,
BLE_MENU_ID_AMDTP,
BLE_MENU_ID_MAX
}eBleMenuId;
typedef enum
{
GAP_MENU_ID_NONE = 0,
GAP_MENU_ID_SCAN_START,
GAP_MENU_ID_SCAN_STOP,
GAP_MENU_ID_SCAN_RESULTS,
GAP_MENU_ID_CONNECT,
GAP_MENU_ID_MAX
}eGapMenuId;
typedef enum
{
GATT_MENU_ID_NONE = 0,
GATT_MENU_ID_TBD,
GATT_MENU_ID_MAX
}eGattMenuId;
typedef enum
{
AMDTP_MENU_ID_NONE = 0,
AMDTP_MENU_ID_SEND,
AMDTP_MENU_ID_SEND_STOP,
AMDTP_MENU_ID_SERVER_SEND,
AMDTP_MENU_ID_SERVER_SEND_STOP,
AMDTP_MENU_ID_MAX
}eAmdtpMenuId;
typedef struct
{
eBleMenuId prevMenuId;
eBleMenuId menuId;
eGapMenuId gapMenuSelected;
eGattMenuId gattMenuSelected;
}sBleMenuCb;
extern char menuRxData[20];
extern uint32_t menuRxDataLen;
extern uint32_t am_menu_printf(const char *pcFmt, ...);
void
BleMenuRx(void);
void
BleMenuInit(void);
#ifdef __cplusplus
}
#endif
#endif // BLE_MENU_H

View File

@ -0,0 +1,423 @@
//*****************************************************************************
//
//! @file amdtp_common.c
//!
//! @brief This file provides the shared functions for the AMDTP service.
//!
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include "amdtp_common.h"
#include "amota_crc32.h"
#include "am_util.h"
extern void amdtps_timeout_timer_expired(void *data, UINT16 datalen);
void
resetPkt(amdtpPacket_t *pkt)
{
pkt->offset = 0;
pkt->header.pktType = AMDTP_PKT_TYPE_UNKNOWN;
pkt->len = 0;
}
eAmdtpStatus_t
AmdtpReceivePkt(amdtpCb_t *amdtpCb, amdtpPacket_t *pkt, uint16_t len, uint8_t *pValue)
{
uint8_t dataIdx = 0;
uint32_t calDataCrc = 0;
uint16_t header = 0;
if (pkt->offset == 0 && len < AMDTP_PREFIX_SIZE_IN_PKT)
{
AMDTP_TRC("Invalid packet!!!\n");
AmdtpSendReply(amdtpCb, AMDTP_STATUS_INVALID_PKT_LENGTH, NULL, 0);
return AMDTP_STATUS_INVALID_PKT_LENGTH;
}
// new packet
if (pkt->offset == 0)
{
BT_UNPACK_LE_2_BYTE(&pkt->len, pValue);
BT_UNPACK_LE_2_BYTE(&header, &pValue[2]);
pkt->header.pktType = (header & PACKET_TYPE_BIT_MASK) >> PACKET_TYPE_BIT_OFFSET;
pkt->header.pktSn = (header & PACKET_SN_BIT_MASK) >> PACKET_SN_BIT_OFFSET;
pkt->header.encrypted = (header & PACKET_ENCRYPTION_BIT_MASK) >> PACKET_ENCRYPTION_BIT_OFFSET;
pkt->header.ackEnabled = (header & PACKET_ACK_BIT_MASK) >> PACKET_ACK_BIT_OFFSET;
dataIdx = AMDTP_PREFIX_SIZE_IN_PKT;
if (pkt->header.pktType == AMDTP_PKT_TYPE_DATA)
{
amdtpCb->rxState = AMDTP_STATE_GETTING_DATA;
}
#ifdef AMDTP_DEBUG_ON
AMDTP_TRC("pkt len = 0x%x\n", pkt->len);
AMDTP_TRC("pkt header = 0x%x\n", header);
#endif
AMDTP_TRC("type = %d, sn = %d\n", pkt->header.pktType, pkt->header.pktSn);
AMDTP_TRC("enc = %d, ackEnabled = %d\n", pkt->header.encrypted, pkt->header.ackEnabled);
}
// make sure we have enough space for new data
if (pkt->offset + len - dataIdx > AMDTP_PACKET_SIZE)
{
AMDTP_TRC("not enough buffer size!!!\n");
if (pkt->header.pktType == AMDTP_PKT_TYPE_DATA)
{
amdtpCb->rxState = AMDTP_STATE_RX_IDLE;
}
// reset pkt
resetPkt(pkt);
AmdtpSendReply(amdtpCb, AMDTP_STATUS_INSUFFICIENT_BUFFER, NULL, 0);
return AMDTP_STATUS_INSUFFICIENT_BUFFER;
}
// copy new data into buffer and also save crc into it if it's the last frame in a packet
// 4 bytes crc is included in pkt length
memcpy(pkt->data + pkt->offset, pValue + dataIdx, len - dataIdx);
pkt->offset += (len - dataIdx);
// whole packet received
if (pkt->offset >= pkt->len)
{
uint32_t peerCrc = 0;
//
// check CRC
//
BT_UNPACK_LE_4_BYTE(&peerCrc, pkt->data + pkt->len - AMDTP_CRC_SIZE_IN_PKT);
calDataCrc = AmotaCrc32(0xFFFFFFFFU, pkt->len - AMDTP_CRC_SIZE_IN_PKT, pkt->data);
#ifdef AMDTP_DEBUG_ON
AMDTP_TRC("calDataCrc = 0x%x\n", calDataCrc);
AMDTP_TRC("peerCrc = 0x%x\n", peerCrc);
AMDTP_TRC("len: %d\n", pkt->len);
#endif
if (peerCrc != calDataCrc)
{
AMDTP_TRC("crc error\n");
if (pkt->header.pktType == AMDTP_PKT_TYPE_DATA)
{
amdtpCb->rxState = AMDTP_STATE_RX_IDLE;
}
// reset pkt
resetPkt(pkt);
AmdtpSendReply(amdtpCb, AMDTP_STATUS_CRC_ERROR, NULL, 0);
return AMDTP_STATUS_CRC_ERROR;
}
return AMDTP_STATUS_RECEIVE_DONE;
}
return AMDTP_STATUS_RECEIVE_CONTINUE;
}
//*****************************************************************************
//
// AMDTP packet handler
//
//*****************************************************************************
void
AmdtpPacketHandler(amdtpCb_t *amdtpCb, eAmdtpPktType_t type, uint16_t len, uint8_t *buf)
{
#ifdef AMDTP_DEBUG_ON
AMDTP_TRC("received packet type = %d, len = %d\n", type, len);
#endif
switch(type)
{
case AMDTP_PKT_TYPE_DATA:
//
// data package recevied
//
// record packet serial number
amdtpCb->lastRxPktSn = amdtpCb->rxPkt.header.pktSn;
AmdtpSendReply(amdtpCb, AMDTP_STATUS_SUCCESS, NULL, 0);
if (amdtpCb->recvCback)
{
amdtpCb->recvCback(buf, len);
}
amdtpCb->rxState = AMDTP_STATE_RX_IDLE;
resetPkt(&amdtpCb->rxPkt);
break;
case AMDTP_PKT_TYPE_ACK:
{
eAmdtpStatus_t status = (eAmdtpStatus_t)buf[0];
// stop tx timeout timer
if (BT_TIMER_HANDLE_INIT_VAL != amdtpCb->timeoutTimer)
{
#ifdef AMDTP_DEBUG_ON
API_RESULT retval = API_SUCCESS;
retval = BT_stop_timer (amdtpCb->timeoutTimer);
AMDTP_TRC (
"[AMDTP]: Stopping Timer with result 0x%04X, timer handle %p\n",
retval, amdtpCb->timeoutTimer);
#else
BT_stop_timer (amdtpCb->timeoutTimer);
#endif
amdtpCb->timeoutTimer = BT_TIMER_HANDLE_INIT_VAL;
}
if (amdtpCb->txState != AMDTP_STATE_TX_IDLE)
{
#ifdef AMDTP_DEBUG_ON
AMDTP_TRC("set txState back to idle, state = %d\n", amdtpCb->txState);
#endif
amdtpCb->txState = AMDTP_STATE_TX_IDLE;
}
if (status == AMDTP_STATUS_CRC_ERROR || status == AMDTP_STATUS_RESEND_REPLY)
{
// resend packet
AmdtpSendPacketHandler(amdtpCb);
}
else
{
// increase packet serial number if send successfully
if (status == AMDTP_STATUS_SUCCESS)
{
amdtpCb->txPktSn++;
if (amdtpCb->txPktSn == 16)
{
amdtpCb->txPktSn = 0;
}
}
// packet transfer successful or other error
// reset packet
resetPkt(&amdtpCb->txPkt);
// notify application layer
if (amdtpCb->transCback)
{
amdtpCb->transCback(status);
}
}
resetPkt(&amdtpCb->ackPkt);
}
break;
case AMDTP_PKT_TYPE_CONTROL:
{
eAmdtpControl_t control = (eAmdtpControl_t)buf[0];
uint8_t resendPktSn = buf[1];
if (control == AMDTP_CONTROL_RESEND_REQ)
{
AMDTP_TRC("resendPktSn = %d, lastRxPktSn = %d\n", resendPktSn, amdtpCb->lastRxPktSn);
amdtpCb->rxState = AMDTP_STATE_RX_IDLE;
resetPkt(&amdtpCb->rxPkt);
if (resendPktSn > amdtpCb->lastRxPktSn)
{
AmdtpSendReply(amdtpCb, AMDTP_STATUS_RESEND_REPLY, NULL, 0);
}
else if (resendPktSn == amdtpCb->lastRxPktSn)
{
AmdtpSendReply(amdtpCb, AMDTP_STATUS_SUCCESS, NULL, 0);
}
else
{
AMDTP_ERR("resendPktSn = %d, lastRxPktSn = %d\n", resendPktSn, amdtpCb->lastRxPktSn);
}
}
else
{
AMDTP_TRC("unexpected contrl = %d\n", control);
}
resetPkt(&amdtpCb->ackPkt);
}
break;
default:
break;
}
}
void
AmdtpBuildPkt(amdtpCb_t *amdtpCb, eAmdtpPktType_t type, BOOLEAN encrypted, BOOLEAN enableACK, uint8_t *buf, uint16_t len)
{
uint16_t header = 0;
uint32_t calDataCrc;
amdtpPacket_t *pkt;
if (type == AMDTP_PKT_TYPE_DATA)
{
pkt = &amdtpCb->txPkt;
header = amdtpCb->txPktSn << PACKET_SN_BIT_OFFSET;
}
else
{
pkt = &amdtpCb->ackPkt;
}
//
// Prepare header frame to be sent first
//
// length
pkt->len = len + AMDTP_PREFIX_SIZE_IN_PKT + AMDTP_CRC_SIZE_IN_PKT;
pkt->data[0] = (len + AMDTP_CRC_SIZE_IN_PKT) & 0xff;
pkt->data[1] = ((len + AMDTP_CRC_SIZE_IN_PKT) >> 8) & 0xff;
// header
header = header | (type << PACKET_TYPE_BIT_OFFSET);
if (encrypted)
{
header = header | (1 << PACKET_ENCRYPTION_BIT_OFFSET);
}
if (enableACK)
{
header = header | (1 << PACKET_ACK_BIT_OFFSET);
}
pkt->data[2] = (header & 0xff);
pkt->data[3] = (header >> 8);
// copy data
memcpy(&(pkt->data[AMDTP_PREFIX_SIZE_IN_PKT]), buf, len);
calDataCrc = AmotaCrc32(0xFFFFFFFFU, len, buf);
// add checksum
pkt->data[AMDTP_PREFIX_SIZE_IN_PKT + len] = (calDataCrc & 0xff);
pkt->data[AMDTP_PREFIX_SIZE_IN_PKT + len + 1] = ((calDataCrc >> 8) & 0xff);
pkt->data[AMDTP_PREFIX_SIZE_IN_PKT + len + 2] = ((calDataCrc >> 16) & 0xff);
pkt->data[AMDTP_PREFIX_SIZE_IN_PKT + len + 3] = ((calDataCrc >> 24) & 0xff);
}
//*****************************************************************************
//
// Send Reply to Sender
//
//*****************************************************************************
void
AmdtpSendReply(amdtpCb_t *amdtpCb, eAmdtpStatus_t status, uint8_t *data, uint16_t len)
{
uint8_t buf[ATT_DEFAULT_PAYLOAD_LEN] = {0};
eAmdtpStatus_t st;
buf[0] = status;
if (len > 0)
{
memcpy(buf + 1, data, len);
}
st = amdtpCb->ack_sender_func(AMDTP_PKT_TYPE_ACK, false, false, buf, len + 1);
if (st != AMDTP_STATUS_SUCCESS)
{
AMDTP_ERR("AmdtpSendReply status = %d\n", status);
}
}
//*****************************************************************************
//
// Send control message to Receiver
//
//*****************************************************************************
void
AmdtpSendControl(amdtpCb_t *amdtpCb, eAmdtpControl_t control, uint8_t *data, uint16_t len)
{
uint8_t buf[ATT_DEFAULT_PAYLOAD_LEN] = {0};
eAmdtpStatus_t st;
buf[0] = control;
if (len > 0)
{
memcpy(buf + 1, data, len);
}
st = amdtpCb->ack_sender_func(AMDTP_PKT_TYPE_CONTROL, false, false, buf, len + 1);
if (st != AMDTP_STATUS_SUCCESS)
{
AMDTP_ERR("AmdtpSendControl status = %d\n", st);
}
}
void
AmdtpSendPacketHandler(amdtpCb_t *amdtpCb)
{
uint16_t transferSize = 0;
uint16_t remainingBytes = 0;
amdtpPacket_t *txPkt = &amdtpCb->txPkt;
API_RESULT retval = API_SUCCESS;
if ( amdtpCb->txState == AMDTP_STATE_TX_IDLE )
{
txPkt->offset = 0;
amdtpCb->txState = AMDTP_STATE_SENDING;
}
if ( txPkt->offset >= txPkt->len )
{
// done sent packet
amdtpCb->txState = AMDTP_STATE_WAITING_ACK;
// start tx timeout timer
if (BT_TIMER_HANDLE_INIT_VAL != amdtpCb->timeoutTimer)
{
retval = BT_stop_timer (amdtpCb->timeoutTimer);
AMDTP_TRC (
"[AMDTP]: Stopping Timer with result 0x%04X, timer handle %p\n",
retval, amdtpCb->timeoutTimer);
amdtpCb->timeoutTimer = BT_TIMER_HANDLE_INIT_VAL;
}
retval = BT_start_timer
(
&amdtpCb->timeoutTimer,
amdtpCb->txTimeout,
amdtps_timeout_timer_expired,
NULL,
0
);
}
else
{
remainingBytes = txPkt->len - txPkt->offset;
transferSize = ((amdtpCb->attMtuSize - 3) > remainingBytes)
? remainingBytes
: (amdtpCb->attMtuSize - 3);
// send packet
amdtpCb->data_sender_func(&txPkt->data[txPkt->offset], transferSize);
txPkt->offset += transferSize;
}
}

View File

@ -0,0 +1,217 @@
//*****************************************************************************
//
//! @file amdtp_common.h
//!
//! @brief This file provides the shared functions for the AMDTP service.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AMDTP_COMMON_H
#define AMDTP_COMMON_H
#include "BT_api.h"
//*****************************************************************************
//
// Macro definitions
//
//*****************************************************************************
#define BT_MODULE_BIT_MASK_AMDTPS 0x00020000
#define BT_MODULE_ID_AMDTPS (BT_MODULE_PAGE_2 | BT_MODULE_BIT_MASK_AMDTPS)
#define AMDTP_ERR(...) BT_debug_error(BT_MODULE_ID_AMDTPS, __VA_ARGS__)
#define AMDTP_TRC(...) BT_debug_trace(BT_MODULE_ID_AMDTPS, __VA_ARGS__)
#define AMDTP_MAX_PAYLOAD_SIZE 2048 //512
#define AMDTP_PACKET_SIZE (AMDTP_MAX_PAYLOAD_SIZE + AMDTP_PREFIX_SIZE_IN_PKT + AMDTP_CRC_SIZE_IN_PKT) // Bytes
#define AMDTP_LENGTH_SIZE_IN_PKT 2
#define AMDTP_HEADER_SIZE_IN_PKT 2
#define AMDTP_CRC_SIZE_IN_PKT 4
#define AMDTP_PREFIX_SIZE_IN_PKT AMDTP_LENGTH_SIZE_IN_PKT + AMDTP_HEADER_SIZE_IN_PKT
#define PACKET_TYPE_BIT_OFFSET 12
#define PACKET_TYPE_BIT_MASK (0xf << PACKET_TYPE_BIT_OFFSET)
#define PACKET_SN_BIT_OFFSET 8
#define PACKET_SN_BIT_MASK (0xf << PACKET_SN_BIT_OFFSET)
#define PACKET_ENCRYPTION_BIT_OFFSET 7
#define PACKET_ENCRYPTION_BIT_MASK (0x1 << PACKET_ENCRYPTION_BIT_OFFSET)
#define PACKET_ACK_BIT_OFFSET 6
#define PACKET_ACK_BIT_MASK (0x1 << PACKET_ACK_BIT_OFFSET)
#define TX_TIMEOUT_DEFAULT 1 // 1 second
#define ATT_DEFAULT_PAYLOAD_LEN 20
//
// amdtp states
//
typedef enum eAmdtpState
{
AMDTP_STATE_INIT,
AMDTP_STATE_TX_IDLE,
AMDTP_STATE_RX_IDLE,
AMDTP_STATE_SENDING,
AMDTP_STATE_GETTING_DATA,
AMDTP_STATE_WAITING_ACK,
AMDTP_STATE_MAX
}eAmdtpState_t;
//
// amdtp packet type
//
typedef enum eAmdtpPktType
{
AMDTP_PKT_TYPE_UNKNOWN,
AMDTP_PKT_TYPE_DATA,
AMDTP_PKT_TYPE_ACK,
AMDTP_PKT_TYPE_CONTROL,
AMDTP_PKT_TYPE_MAX
}eAmdtpPktType_t;
typedef enum eAmdtpControl
{
AMDTP_CONTROL_RESEND_REQ,
AMDTP_CONTROL_MAX
}eAmdtpControl_t;
//
// amdtp status
//
typedef enum eAmdtpStatus
{
AMDTP_STATUS_SUCCESS,
AMDTP_STATUS_CRC_ERROR,
AMDTP_STATUS_INVALID_METADATA_INFO,
AMDTP_STATUS_INVALID_PKT_LENGTH,
AMDTP_STATUS_INSUFFICIENT_BUFFER,
AMDTP_STATUS_UNKNOWN_ERROR,
AMDTP_STATUS_BUSY,
AMDTP_STATUS_TX_NOT_READY, // no connection or tx busy
AMDTP_STATUS_RESEND_REPLY,
AMDTP_STATUS_RECEIVE_CONTINUE,
AMDTP_STATUS_RECEIVE_DONE,
AMDTP_STATUS_MAX
}eAmdtpStatus_t;
//
// packet prefix structure
//
typedef struct
{
uint8_t pktType : 4;
uint8_t pktSn : 4;
uint8_t encrypted : 1;
uint32_t ackEnabled : 1;
uint32_t reserved : 6; // Reserved for future usage
}
amdtpPktHeader_t;
//
// packet
//
typedef struct
{
uint16_t offset;
uint16_t len; // data plus checksum
amdtpPktHeader_t header;
uint8_t *data;
}
amdtpPacket_t;
/*! Application data reception callback */
typedef void (*amdtpRecvCback_t)(uint8_t *buf, uint16_t len);
/*! Application data transmission result callback */
typedef void (*amdtpTransCback_t)(eAmdtpStatus_t status);
typedef void (*amdtp_reply_func_t)(eAmdtpStatus_t status, uint8_t *data, uint16_t len);
typedef void (*amdtp_packet_handler_func_t)(eAmdtpPktType_t type, uint16_t len, uint8_t *buf);
typedef eAmdtpStatus_t (*amdtp_ack_sender_func_t)(eAmdtpPktType_t type, BOOLEAN encrypted, BOOLEAN enableACK, uint8_t *buf, uint16_t len);
typedef void (*amdtp_data_sender_func_t)(uint8_t *buf, uint16_t len);
typedef struct
{
eAmdtpState_t txState;
eAmdtpState_t rxState;
amdtpPacket_t rxPkt;
amdtpPacket_t txPkt;
amdtpPacket_t ackPkt;
uint8_t txPktSn; // data packet serial number for Tx
uint8_t lastRxPktSn; // last received data packet serial number
uint16_t attMtuSize;
BT_timer_handle timeoutTimer; // timeout timer after DTP update done
uint8_t txTimeout; // timeout in second unit
amdtpRecvCback_t recvCback; // application callback for data reception
amdtpTransCback_t transCback; // application callback for tx complete status
amdtp_data_sender_func_t data_sender_func;
amdtp_ack_sender_func_t ack_sender_func;
}
amdtpCb_t;
//*****************************************************************************
//
// function definitions
//
//*****************************************************************************
void
AmdtpBuildPkt(amdtpCb_t *amdtpCb, eAmdtpPktType_t type, BOOLEAN encrypted, BOOLEAN enableACK, uint8_t *buf, uint16_t len);
eAmdtpStatus_t
AmdtpReceivePkt(amdtpCb_t *amdtpCb, amdtpPacket_t *pkt, uint16_t len, uint8_t *pValue);
void
AmdtpSendReply(amdtpCb_t *amdtpCb, eAmdtpStatus_t status, uint8_t *data, uint16_t len);
void
AmdtpSendControl(amdtpCb_t *amdtpCb, eAmdtpControl_t control, uint8_t *data, uint16_t len);
void
AmdtpSendPacketHandler(amdtpCb_t *amdtpCb);
void
AmdtpPacketHandler(amdtpCb_t *amdtpCb, eAmdtpPktType_t type, uint16_t len, uint8_t *buf);
void
resetPkt(amdtpPacket_t *pkt);
#endif // AMDTP_COMMON_H

View File

@ -0,0 +1,554 @@
//*****************************************************************************
//
// appl_amdtps.c
//! @file
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/**
* \file appl_amdtps.c
*
* This file contains the AMDTP application.
* Sample applications detailed below:
* a. The Sensor, as defined by the Sepcification plays the GAP Peripheral
* role.
* b. The Sensor application has following sevice records:
* - GAP
* - GATT
* - Battery
* - Device Information and
* - AMDTP
* [NOTE]: Please see gatt_db.c for more details of the record.
* c. appl_manage_transfer routine takes care of handling peer
* configuration. This handling would be needed:
* - When Peer Configures Measurement Transfer by writting to the
* Characteristic Client Configuration of AMOTA Tx.
* - Subsequent reconnection with bonded device that had already
* configured the device for transfer. Please note it is mandatory
* for GATT Servers to remember the configurations of bonded GATT
* clients.
* In order to ensure the above mentioned configurations are correctly
* handled, the routine, appl_manage_transfer, is therefore called from:
* - gatt_db_amotas_handler and
* - appl_amdtps_connect
* [NOTE]: If link does not have the needed secruity for the service,
* transfer will not be initiated.
*/
/* --------------------------------------------- Header File Inclusion */
#include "appl.h"
#include "am_mcu_apollo.h"
#include "am_bsp.h"
#include "am_util.h"
#ifdef AMDTPS
//*****************************************************************************
//
// Global variables
//
//*****************************************************************************
uint8_t rxPktBuf[AMDTP_PACKET_SIZE];
uint8_t txPktBuf[AMDTP_PACKET_SIZE];
uint8_t ackPktBuf[20];
#if defined(AMDTPS_RXONLY) || defined(AMDTPS_RX2TX)
static int totalLen = 0;
#endif
//*****************************************************************************
//
// Macro definitions
//
//*****************************************************************************
/* Control block */
static struct
{
BOOLEAN txReady; // TRUE if ready to send notifications
AmdtpsCfg_t cfg; // configurable parameters
amdtpCb_t core;
}
amdtpsCb;
/* --------------------------------------------- Static Global Variables */
static GATT_DB_HANDLE appl_amdtps_handle;
static ATT_ATTR_HANDLE appl_tx_hndl;
static ATT_ATTR_HANDLE appl_ack_hndl;
/* --------------------------------------------- Functions */
static bool sendDataContinuously = false;
static uint32_t counter = 0;
static void AmdtpsSendTestData(void)
{
uint8_t data[236] = {0};
eAmdtpStatus_t status;
sendDataContinuously = true;
*((uint32_t*)&(data[0])) = counter;
status = AmdtpsSendPacket(AMDTP_PKT_TYPE_DATA, false, true, data, sizeof(data));
if (status != AMDTP_STATUS_SUCCESS)
{
AMDTP_TRC("[AMDTP]: AmdtpsSendTestData() failed, status = %d\n", status);
}
else
{
counter++;
}
}
void amdtpsDtpRecvCback(uint8_t * buf, uint16_t len)
{
if (buf[0] == 1)
{
AMDTP_TRC("[AMDTP]: send test data\n");
AmdtpsSendTestData();
}
else if (buf[0] == 2)
{
AMDTP_TRC("[AMDTP]: send test data stop\n");
sendDataContinuously = false;
}
}
void amdtpsDtpTransCback(eAmdtpStatus_t status)
{
#ifdef AMDTP_DEBUG_ON
AMDTP_TRC("[AMDTP]: amdtpDtpTransCback =%d\n", status);
#endif
if (status == AMDTP_STATUS_SUCCESS && sendDataContinuously)
{
AmdtpsSendTestData();
}
}
void appl_amdtps_init(void)
{
appl_amdtp_server_reinitialize();
}
void appl_amdtps_connect(APPL_HANDLE * appl_handle)
{
ATT_VALUE value;
UINT16 cli_cnfg;
cli_cnfg = 0;
appl_amdtps_handle.device_id = APPL_GET_DEVICE_HANDLE((*appl_handle));
appl_amdtps_handle.char_id = GATT_CHAR_AMDTP_TX;
appl_amdtps_handle.service_id = GATT_SER_AMDTP_INST;
BT_gatt_db_get_char_val_hndl(&appl_amdtps_handle, &appl_tx_hndl);
BT_gatt_db_get_char_cli_cnfg(&appl_amdtps_handle, &value);
BT_UNPACK_LE_2_BYTE (&cli_cnfg, value.val);
appl_amdtps_handle.char_id = GATT_CHAR_AMDTP_ACK;
BT_gatt_db_get_char_val_hndl(&appl_amdtps_handle, &appl_ack_hndl);
BT_gatt_db_get_char_cli_cnfg(&appl_amdtps_handle, &value);
BT_UNPACK_LE_2_BYTE (&cli_cnfg, value.val);
AMDTP_TRC (
"[APPL]: Fetched Client Configuration (0x%04X) for Device (0x%02X)\n",
cli_cnfg, APPL_GET_DEVICE_HANDLE((*appl_handle)));
appl_manage_trasnfer(appl_amdtps_handle, cli_cnfg);
}
void appl_manage_trasnfer(GATT_DB_HANDLE handle, UINT16 config)
{
APPL_HANDLE appl_handle;
API_RESULT retval;
UCHAR security, ekey_size;
AMDTP_TRC("[AMDTP]: appl_manage_trasnfer+ \n");
/* Get required security for service */
/* Get required security level */
BT_gatt_db_get_service_security (&handle, &security);
/* Get required encryption key size */
BT_gatt_db_get_service_enc_key_size (&handle, &ekey_size);
/* Verify if security requirements are available with the link */
retval = appl_smp_assert_security
(
&handle.device_id,
security,
ekey_size
);
/* Security requirements satisfied? */
if (API_SUCCESS != retval)
{
/* No. Return */
return;
}
/* Security requirements satisfied, go ahead with data transfer */
retval = appl_get_handle_from_device_handle(handle.device_id, &appl_handle);
if (API_SUCCESS != retval)
{
return;
}
if (GATT_CLI_CNFG_NOTIFICATION == config)
{
amdtpsCb.txReady = true;
amdtpsCb.core.txState = AMDTP_STATE_TX_IDLE;
AMDTP_TRC("[AMDTP]: notify registered \n");
#if defined(AMDTPS_TXTEST)
counter = 0;
AmdtpsSendTestData(); //fixme
#endif
}
else if (GATT_CLI_CNFG_DEFAULT == config)
{
amdtpsCb.txReady = false;
AMDTP_TRC("[AMDTP]: notify unregistered \n");
}
else
{
/* Incorrect Configuration */
}
}
//*****************************************************************************
//
// Send Notification to Client
//
//*****************************************************************************
static void amdtpsSendData(uint8_t *buf, uint16_t len)
{
ATT_HANDLE_VALUE_PAIR hndl_val_param;
API_RESULT retval;
APPL_HANDLE appl_handle;
#ifdef AMDTP_DEBUG_ON
AMDTP_TRC("Sending Tx On Handle 0x%04X\n", appl_tx_hndl);
#endif
appl_get_handle_from_device_handle (appl_amdtps_handle.device_id, &appl_handle);
hndl_val_param.handle = appl_tx_hndl;
hndl_val_param.value.val = buf;
hndl_val_param.value.len = len;
retval = BT_att_send_hndl_val_ntf
(
&APPL_GET_ATT_INSTANCE(appl_handle),
&hndl_val_param
);
if (API_SUCCESS != retval)
{
AMDTP_ERR( "[** ERR **]: Failed to send, reason 0x%04X", retval);
}
}
static eAmdtpStatus_t
amdtpsSendAck(eAmdtpPktType_t type, BOOLEAN encrypted, BOOLEAN enableACK, uint8_t *buf, uint16_t len)
{
ATT_HANDLE_VALUE_PAIR hndl_val_param;
API_RESULT retval;
APPL_HANDLE appl_handle;
AmdtpBuildPkt(&amdtpsCb.core, type, encrypted, enableACK, buf, len);
#ifdef AMDTP_DEBUG_ON
AMDTP_TRC("Sending Ack On Handle 0x%04X\n", appl_ack_hndl);
#endif
/* send notification */
appl_get_handle_from_device_handle (appl_amdtps_handle.device_id, &appl_handle);
hndl_val_param.handle = appl_ack_hndl;
hndl_val_param.value.val = amdtpsCb.core.ackPkt.data;
hndl_val_param.value.len = amdtpsCb.core.ackPkt.len;
retval = BT_att_send_hndl_val_ntf
(
&APPL_GET_ATT_INSTANCE(appl_handle),
&hndl_val_param
);
if (API_SUCCESS != retval)
{
AMDTP_ERR( "[** ERR **]: Failed to send measurement, reason 0x%04X", retval);
return AMDTP_STATUS_TX_NOT_READY;
}
return AMDTP_STATUS_SUCCESS;
}
//*****************************************************************************
//
// Timer Expiration handler
//
//*****************************************************************************
void amdtps_timeout_timer_expired(void *data, UINT16 datalen)
{
API_RESULT retval = API_SUCCESS;
uint8_t ack[1];
ack[0] = amdtpsCb.core.txPktSn;
AMDTP_TRC("amdtps tx timeout, txPktSn = %d\n", amdtpsCb.core.txPktSn);
AmdtpSendControl(&amdtpsCb.core, AMDTP_CONTROL_RESEND_REQ, ack, 1);
// fire a timer for receiving an AMDTP_STATUS_RESEND_REPLY ACK
if (BT_TIMER_HANDLE_INIT_VAL != amdtpsCb.core.timeoutTimer)
{
retval = BT_stop_timer (amdtpsCb.core.timeoutTimer);
AMDTP_TRC (
"[AMDTP]: Stopping Timer with result 0x%04X, timer handle %p\n",
retval, amdtpsCb.core.timeoutTimer);
amdtpsCb.core.timeoutTimer = BT_TIMER_HANDLE_INIT_VAL;
}
retval = BT_start_timer
(
&amdtpsCb.core.timeoutTimer,
amdtpsCb.core.txTimeout,
amdtps_timeout_timer_expired,
NULL,
0
);
AMDTP_TRC (
"[AMDTP]: Started Timer with result 0x%04X, timer handle %p\n",
retval, amdtpsCb.core.timeoutTimer);
}
void amdtpsHandleValueCnf(
APPL_HANDLE * appl_handle,
UCHAR * event_data,
UINT16 event_datalen
)
{
ATT_ATTR_HANDLE attr_handle;
BT_UNPACK_LE_2_BYTE(&attr_handle, event_data);
#ifdef AMDTP_DEBUG_ON
AMDTP_TRC("appl_handle 0x%x attr_handle = 0x%x\n", *appl_handle, attr_handle);
#endif
#if !defined(AMDTPS_RXONLY) && !defined(AMDTPS_RX2TX)
if ( attr_handle == appl_tx_hndl )
{
amdtpsCb.txReady = true;
// process next data
AmdtpSendPacketHandler(&amdtpsCb.core);
#ifdef AMDTPS_TXTEST
// fixme when last packet, continue to send next one.
if (amdtpsCb.core.txState == AMDTP_STATE_WAITING_ACK)
{
uint8_t temp[3];
temp[0] = AMDTP_STATUS_SUCCESS;
AmdtpPacketHandler(&amdtpsCb.core, AMDTP_PKT_TYPE_ACK, 3, temp);
}
#endif
}
#endif
}
void amdtps_mtu_update(APPL_HANDLE * appl_handle, UINT16 t_mtu)
{
UINT16 mtu = 0;
BT_att_access_mtu(&APPL_GET_ATT_INSTANCE(*appl_handle),
&mtu);
AMDTP_TRC("appl_handle 0x%x t_mtu = %d %d\n", *appl_handle, t_mtu, mtu);
}
void appl_amdtp_server_reinitialize(void)
{
API_RESULT retval = API_SUCCESS;
memset(&amdtpsCb, 0, sizeof(amdtpsCb));
amdtpsCb.txReady = false;
amdtpsCb.core.txState = AMDTP_STATE_INIT;
amdtpsCb.core.rxState = AMDTP_STATE_RX_IDLE;
amdtpsCb.core.lastRxPktSn = 0;
amdtpsCb.core.txPktSn = 0;
resetPkt(&amdtpsCb.core.rxPkt);
amdtpsCb.core.rxPkt.data = rxPktBuf;
resetPkt(&amdtpsCb.core.txPkt);
amdtpsCb.core.txPkt.data = txPktBuf;
resetPkt(&amdtpsCb.core.ackPkt);
amdtpsCb.core.ackPkt.data = ackPktBuf;
amdtpsCb.core.recvCback = amdtpsDtpRecvCback;
amdtpsCb.core.transCback = amdtpsDtpTransCback;
amdtpsCb.core.data_sender_func = amdtpsSendData;
amdtpsCb.core.ack_sender_func = amdtpsSendAck;
amdtpsCb.core.txTimeout = TX_TIMEOUT_DEFAULT;
if (BT_TIMER_HANDLE_INIT_VAL != amdtpsCb.core.timeoutTimer)
{
retval = BT_stop_timer (amdtpsCb.core.timeoutTimer);
AMDTP_TRC (
"[AMDTP]: Stopping Timer with result 0x%04X, timer handle %p\n",
retval, amdtpsCb.core.timeoutTimer);
amdtpsCb.core.timeoutTimer = BT_TIMER_HANDLE_INIT_VAL;
}
#if defined(AMDTPS_RXONLY) || defined(AMDTPS_RX2TX)
AMDTP_TRC("*** RECEIVED TOTAL %d ***\n", totalLen);
totalLen = 0;
#endif
}
API_RESULT appl_amdtps_write_cback
(
GATT_DB_HANDLE * handle,
ATT_VALUE * value
)
{
API_RESULT retval = API_SUCCESS;
eAmdtpStatus_t status = AMDTP_STATUS_UNKNOWN_ERROR;
amdtpPacket_t *pkt = NULL;
#if 0
uint16_t i = 0;
AMDTP_TRC("============= data arrived start ===============\n");
for (i = 0; i < value->len; i++)
{
AMDTP_TRC("%x\t", value->val[i]);
}
AMDTP_TRC("============= data arrived end ===============\n");
#endif
if (GATT_CHAR_AMDTP_RX == handle->char_id)
{
#if defined(AMDTPS_RX2TX)
amdtpsSendData(value->val, value->len);
#endif
#if defined(AMDTPS_RXONLY) || defined(AMDTPS_RX2TX)
totalLen += value->len;
AMDTP_TRC("received data len %d, total %d\n", value->len, totalLen);
return API_SUCCESS;
#else /* RXONLY && RX2TX */
status = AmdtpReceivePkt(&amdtpsCb.core, &amdtpsCb.core.rxPkt, value->len, value->val);
#endif
}
else if (GATT_CHAR_AMDTP_ACK == handle->char_id)
{
status = AmdtpReceivePkt(&amdtpsCb.core, &amdtpsCb.core.ackPkt, value->len, value->val);
}
if (status == AMDTP_STATUS_RECEIVE_DONE)
{
if (GATT_CHAR_AMDTP_RX == handle->char_id)
{
pkt = &amdtpsCb.core.rxPkt;
}
else if (GATT_CHAR_AMDTP_ACK == handle->char_id)
{
pkt = &amdtpsCb.core.ackPkt;
}
AmdtpPacketHandler(&amdtpsCb.core, (eAmdtpPktType_t)pkt->header.pktType, pkt->len - AMDTP_CRC_SIZE_IN_PKT, pkt->data);
}
return retval;
}
//*****************************************************************************
//
//! @brief Send data to Client via notification
//!
//! @param type - packet type
//! @param encrypted - is packet encrypted
//! @param enableACK - does client need to response
//! @param buf - data
//! @param len - data length
//!
//! @return status
//
//*****************************************************************************
eAmdtpStatus_t
AmdtpsSendPacket(eAmdtpPktType_t type, BOOLEAN encrypted, BOOLEAN enableACK, uint8_t *buf, uint16_t len)
{
//
// Check if ready to send notification
//
if ( !amdtpsCb.txReady )
{
//set in callback amdtpsHandleValueCnf
AMDTP_TRC("data sending failed, not ready for notification.\n", NULL);
return AMDTP_STATUS_TX_NOT_READY;
}
//
// Check if the service is idle to send
//
if ( amdtpsCb.core.txState != AMDTP_STATE_TX_IDLE )
{
AMDTP_TRC("data sending failed, tx state = %d\n", amdtpsCb.core.txState);
return AMDTP_STATUS_BUSY;
}
//
// Check if data length is valid
//
if ( len > AMDTP_MAX_PAYLOAD_SIZE )
{
AMDTP_TRC("data sending failed, exceed maximum payload, len = %d.\n", len);
return AMDTP_STATUS_INVALID_PKT_LENGTH;
}
AmdtpBuildPkt(&amdtpsCb.core, type, encrypted, enableACK, buf, len);
// send packet
AmdtpSendPacketHandler(&amdtpsCb.core);
return AMDTP_STATUS_SUCCESS;
}
#endif /* AMDTPS */

View File

@ -0,0 +1,102 @@
//*****************************************************************************
//
// appl_amdtps.h
//! @file
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/**
* \file appl_amdtps.h
*
* Application Header File for AMDTPS.
*/
#ifndef _H_APPL_AMDTPS_
#define _H_APPL_AMDTPS_
/* ----------------------------------------- Header File Inclusion */
#include "BT_api.h"
#include "BT_gatt_db_api.h"
#include "gatt_db.h"
#include "appl.h"
#include "amdtp_common.h"
//*****************************************************************************
//
// Macro definitions
//
//*****************************************************************************
/*! Configurable parameters */
typedef struct
{
//! Short description of each member should go here.
uint32_t reserved;
}
AmdtpsCfg_t;
/* --------------------------------------------- Functions */
void appl_amdtps_init(void);
void appl_manage_trasnfer(GATT_DB_HANDLE handle, UINT16 config);
void appl_amdtps_connect(DEVICE_HANDLE * dq_handle);
void appl_amdtp_server_reinitialize(void);
API_RESULT appl_amdtps_write_cback(GATT_DB_HANDLE *handle, ATT_VALUE *value);
eAmdtpStatus_t AmdtpsSendPacket(eAmdtpPktType_t type, BOOLEAN encrypted, BOOLEAN enableACK, uint8_t *buf, uint16_t len);
void amdtpsHandleValueCnf( APPL_HANDLE * appl_handle, UCHAR * event_data, UINT16 event_datalen);
void amdtps_mtu_update(APPL_HANDLE * appl_handle, UINT16 t_mtu);
/* Profile handling */
#define APPL_PROFILE_INIT(...) appl_amdtps_init()
#define APPL_PROFILE_CONNECT(x) appl_amdtps_connect(x)
#define APPL_SEND_MEASUREMENT(x)
#define APPL_PROFILE_DISCONNECT_HANDLER(x) appl_amdtp_server_reinitialize()
#define GATT_DB_PROFILE_HANDLER gatt_db_amdtps_handler
#define APPL_PROFILE_HVN_NTF_COMPLETE_HANDLER(x, y, z) amdtpsHandleValueCnf(x, y, z)
#define APPL_PROFILE_HVN_IND_COMPLETE_HANDLER(x, y, z) amdtpsHandleValueCnf(x, y, z)
#define APPL_PROFILE_MTU_UPDT_COMPLETE_HANDLER(x, y) amdtps_mtu_update(x, y)
#define APPL_USE_IDLE_TIMER
#define APPL_IDLE_TIMEOUT 30
#endif /* _H_APPL_AMDTPS_ */

View File

@ -0,0 +1,221 @@
//*****************************************************************************
//
// appl_gap_config_params.c
//! @file
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/**
* \file appl_gap_config_params.c
*
* This file contains GAP Configuration Parameters used by the application.
*/
/* --------------------------------------------- Header File Inclusion */
#include "appl_gap.h"
#ifdef AMDTPS
/* --------------------------------------------- External Global Variables */
/* --------------------------------------------- Exported Global Variables */
/* --------------------------------------------- Static Global Variables */
#if ((defined APPL_GAP_BROADCASTER_SUPPORT) || (defined APPL_GAP_PERIPHERAL_SUPPORT))
/** Advertisement Data Options */
const APPL_GAP_ADV_DATA appl_gap_adv_data[APPL_GAP_MAX_ADV_DATA_OPTIONS] =
{
/* GAP Advertisement Parameters */
{
{
/**
* Flags:
* 0x01: LE Limited Discoverable Mode
* 0x02: LE General Discoverable Mode
* 0x04: BR/EDR Not Supported
* 0x08: Simultaneous LE and BR/EDR to Same Device
* Capable (Controller)
* 0x10: Simultaneous LE and BR/EDR to Same Device
* Capable (Host)
*/
0x02, 0x01,
(BT_AD_FLAGS_LE_GENERAL_DISC_MODE | BT_AD_FLAGS_LE_BR_EDR_SUPPORT),
/**
* Service UUID List:
* Battery Service (0x180F)
* DeviceInformation Service (0x180A)
* Heart Rate Service (0x180D)
*/
0x07, 0x03, 0x0F, 0x18, 0x0A, 0x18, 0x0D, 0x18,
/**
* Shortened Device Name: Mindtree
*/
0x09, 0x08, 0x4D, 0x69, 0x6E, 0x64, 0x74, 0x72, 0x65, 0x65
},
21
}
};
/* Advertisement parameters options */
const APPL_GAP_ADV_PARAM appl_gap_adv_param[APPL_GAP_MAX_ADV_PARAM_OPTIONS] =
{
/* 0 - Normal Advertising Params */
{
32,
32,
7,
0
},
/* 1 - Fast Connection Advertising Params */
{
32,
48,
7,
0
},
/* 2 - Low Power Advertising Params */
{
1600,
4000,
7,
0
}
};
/* Advertisement Table */
APPL_GAP_ADV_INFO appl_gap_adv_table =
{
appl_gap_adv_data,
appl_gap_adv_param,
APPL_GAP_ADV_IDLE
};
#endif /* APPL_GAP_BROADCASTER || APPL_GAP_PERIPHERAL_SUPPORT */
#if ((defined APPL_GAP_OBSERVER_SUPPORT) || (defined APPL_GAP_CENTRAL_SUPPORT))
/* Scan Parameters Option */
const APPL_GAP_SCAN_PARAM appl_gap_scan_param[APPL_GAP_MAX_SCAN_PARAM_OPTIONS] =
{
/* Normal Scan Params */
{
32,
7,
0
},
/* Fast Connection Scan Params */
{
48,
7,
0
},
/* Low Power Scan Params */
{
4000,
7,
0
}
};
/* Scan Table */
APPL_GAP_SCAN_INFO appl_gap_scan_table =
{
appl_gap_scan_param,
APPL_GAP_SCAN_IDLE
};
#endif /* APPL_GAP_OBSERVER_SUPPORT || APPL_GAP_CENTRAL_SUPPORT */
#ifdef APPL_GAP_CENTRAL_SUPPORT
/* Connection Parameters Options */
const APPL_GAP_CONN_PARAM appl_gap_conn_param[APPL_GAP_MAX_CONN_PARAM_OPTIONS] =
{
{
4,
4,
0,
40,
56,
0,
955,
32,
32
}
};
/* GAP Connection Table */
APPL_GAP_CONN_INFO appl_gap_conn_table =
{
appl_gap_conn_param,
APPL_GAP_CONN_IDLE
};
#endif /* APPL_GAP_CENTRAL_SUPPORT */
#endif /* AMDTPS */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,161 @@
//*****************************************************************************
//
// gatt_db.h
//! @file
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/**
* \file gatt_db.h
*/
#ifndef _H_GATT_DB_
#define _H_GATT_DB_
/**
* addgroup gatt_db_module
*/
/**
* defgroup gatt_db_tuneable_param Tuneable Parameters
* {
* This section defines the Tuneable Constants of Data Base Module.
*/
/** Number of Characteristics in the data base */
#define GATT_CHARACTERISTIC_COUNT 16
/** Number of Services in the data base */
#define GATT_SERVICE_COUNT 5
/** Number of Characteristics that are configurable by the client */
#define GATT_DB_MAX_CONFIGUREABLE_CHAR 4
/** Maximum Length of any Characteristic Value/Descriptor */
#define GATT_DB_MAX_VAL_LENGTH 32
#define GATT_VALUE_ARRAY_SIZE 1
#define GATT_CONST_VALUE_ARRAY_SIZE 245
#define GATT_DB_PEER_VALUE_ARRAY_SIZE 8
#define GATT_DB_MAX_ATTRIBUTES 43
#define GATT_UUID_ARRAY_SIZE 118
#define GATT_DB_MAX_TYPE_COUNT 25
#define GATT_DB_MAX_PEER_CONFIGURATION \
(GATT_DB_PEER_VALUE_ARRAY_SIZE * BT_MAX_DEVICE_QUEUE_SIZE)
/** \} */
/** Service Instance Reference */
/** GAP Service */
#define GATT_SER_GAP_INST 0
/** GATT Service */
#define GATT_SER_GATT_INST 1
/** Battery Service */
#define GATT_SER_BATTERY_INST 2
/** DeviceInformation Service */
#define GATT_SER_DEV_INFO_INST 3
/** AMDTP Service */
#define GATT_SER_AMDTP_INST 4
/** Characteristic Instance Reference */
/** DeviceName */
#define GATT_CHAR_DEV_NAME_INST 0
/** Appearance */
#define GATT_CHAR_APPEARANCE_INST 1
/** Service Changed */
#define GATT_CHAR_SER_CHNGD_INST 2
/** BatteryLevel */
#define GATT_CHAR_BATTERY_LVL_INST 3
/** ManufacturerName */
#define GATT_CHAR_MAN_NAME_INST 4
/** ModelNumber */
#define GATT_CHAR_MODEL_NO_INST 5
/** SerialNumber */
#define GATT_CHAR_SL_NO_INST 6
/** FirmwareRevision */
#define GATT_CHAR_FW_REV_INST 7
/** HardwareRevision */
#define GATT_CHAR_HW_REV_INST 8
/** SoftwareRevision */
#define GATT_CHAR_SW_REV_INST 9
/** SystemId */
#define GATT_CHAR_SYS_ID_INST 10
/** RegCertDataList */
#define GATT_CHAR_REG_CERT_DATA_INST 11
/** PnPID */
#define GATT_CHAR_PNP_ID_INST 12
/** AMDTP Rx */
#define GATT_CHAR_AMDTP_RX 13
/** AMDTP Tx */
#define GATT_CHAR_AMDTP_TX 14
/** AMDTP Ack */
#define GATT_CHAR_AMDTP_ACK 15
#endif /* _H_GATT_DB_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,113 @@
//*****************************************************************************
//
// appl_amota.h
//! @file
//!
//! @brief Application Header File for AMOTA.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/**
* \file appl_amota.h
*
* Application Header File for AMOTA.
*/
#ifndef _H_APPL_AMOTA_
#define _H_APPL_AMOTA_
/* ----------------------------------------- Header File Inclusion */
#include "BT_api.h"
#include "BT_gatt_db_api.h"
#include "gatt_db.h"
#include "appl.h"
// enable debug print for AMOTA profile
// #define AMOTA_DEBUG_ON
/* --------------------------------------------- Global Definitions */
#define AMOTA_PACKET_SIZE (512 + 16) // Bytes
#define AMOTA_LENGTH_SIZE_IN_PKT 2
#define AMOTA_CMD_SIZE_IN_PKT 1
#define AMOTA_CRC_SIZE_IN_PKT 4
#define AMOTA_HEADER_SIZE_IN_PKT AMOTA_LENGTH_SIZE_IN_PKT + AMOTA_CMD_SIZE_IN_PKT
#define AMOTA_FW_HEADER_SIZE 44
#define AMOTA_FW_STORAGE_INTERNAL 0
#define AMOTA_FW_STORAGE_EXTERNAL 1
/* ----------------------------------------- Data Types/ Structures */
/*! Configurable parameters */
typedef struct
{
//! Short description of each member should go here.
uint32_t reserved;
}
AmotasCfg_t;
/* --------------------------------------------- Functions */
void appl_amotas_init(void);
void appl_manage_trasnfer(GATT_DB_HANDLE handle, UINT16 config);
void appl_amotas_connect(DEVICE_HANDLE * dq_handle);
void appl_amotas_send_data(UCHAR *data, UINT16 len);
void appl_amotas_disconnect(void);
API_RESULT appl_amotas_write_cback(GATT_DB_HANDLE *handle, ATT_VALUE *value);
void amota_mtu_update(APPL_HANDLE * appl_handle, UINT16 t_mtu);
/* Profile handling */
#define APPL_PROFILE_INIT(...) appl_amotas_init()
#define APPL_PROFILE_CONNECT(x) appl_amotas_connect(x)
#define APPL_SEND_MEASUREMENT(x) //appl_send_amotas_measurement(x)
#define APPL_PROFILE_DISCONNECT_HANDLER(x) appl_amotas_disconnect()
#define GATT_DB_PROFILE_HANDLER gatt_db_amotas_handler
#define APPL_PROFILE_HVN_NTF_COMPLETE_HANDLER(x, y, z)
#define APPL_PROFILE_HVN_IND_COMPLETE_HANDLER(x, y, z)
#define APPL_PROFILE_MTU_UPDT_COMPLETE_HANDLER(x, y) amota_mtu_update(x, y)
#define APPL_USE_IDLE_TIMER
#define APPL_IDLE_TIMEOUT 30
#endif /* _H_APPL_AMOTA_ */

View File

@ -0,0 +1,223 @@
//*****************************************************************************
//
// appl_gap_config_params.c
//! @file
//!
//! @brief This file contains GAP Configuration Parameters used by the application.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/**
* \file appl_gap_config_params.c
*
* This file contains GAP Configuration Parameters used by the application.
*/
/* --------------------------------------------- Header File Inclusion */
#include "appl_gap.h"
#ifdef AMOTAS
/* --------------------------------------------- External Global Variables */
/* --------------------------------------------- Exported Global Variables */
/* --------------------------------------------- Static Global Variables */
#if ((defined APPL_GAP_BROADCASTER_SUPPORT) || (defined APPL_GAP_PERIPHERAL_SUPPORT))
/** Advertisement Data Options */
const APPL_GAP_ADV_DATA appl_gap_adv_data[APPL_GAP_MAX_ADV_DATA_OPTIONS] =
{
/* GAP Advertisement Parameters */
{
{
/**
* Flags:
* 0x01: LE Limited Discoverable Mode
* 0x02: LE General Discoverable Mode
* 0x04: BR/EDR Not Supported
* 0x08: Simultaneous LE and BR/EDR to Same Device
* Capable (Controller)
* 0x10: Simultaneous LE and BR/EDR to Same Device
* Capable (Host)
*/
0x02, 0x01,
(BT_AD_FLAGS_LE_GENERAL_DISC_MODE | BT_AD_FLAGS_LE_BR_EDR_SUPPORT),
/**
* Service UUID List:
* Battery Service (0x180F)
* DeviceInformation Service (0x180A)
* Heart Rate Service (0x180D)
*/
0x07, 0x03, 0x0F, 0x18, 0x0A, 0x18, 0x0D, 0x18,
/**
* Shortened Device Name: Mindtree
*/
0x09, 0x08, 0x4D, 0x69, 0x6E, 0x64, 0x74, 0x72, 0x65, 0x65
},
21
}
};
/* Advertisement parameters options */
const APPL_GAP_ADV_PARAM appl_gap_adv_param[APPL_GAP_MAX_ADV_PARAM_OPTIONS] =
{
/* 0 - Normal Advertising Params */
{
32,
32,
7,
0
},
/* 1 - Fast Connection Advertising Params */
{
32,
48,
7,
0
},
/* 2 - Low Power Advertising Params */
{
32,
32,
7,
0
}
};
/* Advertisement Table */
APPL_GAP_ADV_INFO appl_gap_adv_table =
{
appl_gap_adv_data,
appl_gap_adv_param,
APPL_GAP_ADV_IDLE
};
#endif /* APPL_GAP_BROADCASTER || APPL_GAP_PERIPHERAL_SUPPORT */
#if ((defined APPL_GAP_OBSERVER_SUPPORT) || (defined APPL_GAP_CENTRAL_SUPPORT))
/* Scan Parameters Option */
const APPL_GAP_SCAN_PARAM appl_gap_scan_param[APPL_GAP_MAX_SCAN_PARAM_OPTIONS] =
{
/* Normal Scan Params */
{
32,
7,
0
},
/* Fast Connection Scan Params */
{
48,
7,
0
},
/* Low Power Scan Params */
{
4000,
7,
0
}
};
/* Scan Table */
APPL_GAP_SCAN_INFO appl_gap_scan_table =
{
appl_gap_scan_param,
APPL_GAP_SCAN_IDLE
};
#endif /* APPL_GAP_OBSERVER_SUPPORT || APPL_GAP_CENTRAL_SUPPORT */
#ifdef APPL_GAP_CENTRAL_SUPPORT
/* Connection Parameters Options */
const APPL_GAP_CONN_PARAM appl_gap_conn_param[APPL_GAP_MAX_CONN_PARAM_OPTIONS] =
{
{
4,
4,
0,
40,
56,
0,
955,
32,
32
}
};
/* GAP Connection Table */
APPL_GAP_CONN_INFO appl_gap_conn_table =
{
appl_gap_conn_param,
APPL_GAP_CONN_IDLE
};
#endif /* APPL_GAP_CENTRAL_SUPPORT */
#endif /* AMOTAS */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,161 @@
//*****************************************************************************
//
// gatt_db.h
//! @file
//!
//! @brief This section defines the Tuneable Constants of Data Base Module.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/**
* \file gatt_db.h
*/
#ifndef _H_GATT_DB_
#define _H_GATT_DB_
/**
* addgroup gatt_db_module
*/
/**
* defgroup gatt_db_tuneable_param Tuneable Parameters
* {
* This section defines the Tuneable Constants of Data Base Module.
*/
/** Number of Characteristics in the data base */
#define GATT_CHARACTERISTIC_COUNT 15
/** Number of Services in the data base */
#define GATT_SERVICE_COUNT 5
/** Number of Characteristics that are configurable by the client */
#define GATT_DB_MAX_CONFIGUREABLE_CHAR 3
/** Maximum Length of any Characteristic Value/Descriptor */
#define GATT_DB_MAX_VAL_LENGTH 32
#define GATT_VALUE_ARRAY_SIZE 1
#define GATT_CONST_VALUE_ARRAY_SIZE 226
#define GATT_DB_PEER_VALUE_ARRAY_SIZE 6
#define GATT_DB_MAX_ATTRIBUTES 40
#define GATT_UUID_ARRAY_SIZE 102
#define GATT_DB_MAX_TYPE_COUNT 24
#define GATT_DB_MAX_PEER_CONFIGURATION \
(GATT_DB_PEER_VALUE_ARRAY_SIZE * BT_MAX_DEVICE_QUEUE_SIZE)
/** \} */
/** Service Instance Reference */
/** GAP Service */
#define GATT_SER_GAP_INST 0
/** GATT Service */
#define GATT_SER_GATT_INST 1
/** Battery Service */
#define GATT_SER_BATTERY_INST 2
/** DeviceInformation Service */
#define GATT_SER_DEV_INFO_INST 3
/** AMOTA Service */
#define GATT_SER_AMOTA_INST 4
/** Characteristic Instance Reference */
/** DeviceName */
#define GATT_CHAR_DEV_NAME_INST 0
/** Appearance */
#define GATT_CHAR_APPEARANCE_INST 1
/** Service Changed */
#define GATT_CHAR_SER_CHNGD_INST 2
/** BatteryLevel */
#define GATT_CHAR_BATTERY_LVL_INST 3
/** ManufacturerName */
#define GATT_CHAR_MAN_NAME_INST 4
/** ModelNumber */
#define GATT_CHAR_MODEL_NO_INST 5
/** SerialNumber */
#define GATT_CHAR_SL_NO_INST 6
/** FirmwareRevision */
#define GATT_CHAR_FW_REV_INST 7
/** HardwareRevision */
#define GATT_CHAR_HW_REV_INST 8
/** SoftwareRevision */
#define GATT_CHAR_SW_REV_INST 9
/** SystemId */
#define GATT_CHAR_SYS_ID_INST 10
/** RegCertDataList */
#define GATT_CHAR_REG_CERT_DATA_INST 11
/** PnPID */
#define GATT_CHAR_PNP_ID_INST 12
/** AMOTA Rx */
#define GATT_CHAR_AMOTA_RX 13
/** AMOTA Tx */
#define GATT_CHAR_AMOTA_TX 14
#endif /* _H_GATT_DB_ */

View File

@ -0,0 +1,604 @@
//*****************************************************************************
//
//! @file appl_ams.c
//!
//! @brief Provides functions for the AMS service.
//!
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/**
* \file appl_ams.c
*
*/
/* --------------------------------------------- Header File Inclusion */
#ifdef AMS
#include "appl.h"
#include "BT_common.h"
#include "BT_hci_api.h"
#include "BT_att_api.h"
#include "BT_smp_api.h"
#include "smp_pl.h"
#include "l2cap.h"
#include "fsm_defines.h"
#include "task.h"
/* ----------------------------------------- Configuration Defines */
extern uint32_t am_util_stdio_printf(const char *pcFmt, ...);
#undef APPL_TRC
#undef APPL_ERR
#define APPL_TRC am_util_stdio_printf
#define APPL_ERR am_util_stdio_printf
/* ----------------------------------------- Macro Defines */
/**@brief Entity IDs */
typedef enum
{
AMS_ENTITY_ID_PLAYER, /** The currently active media app. Attributes for this entity include values such as its name, playback state, and playback volume. */
AMS_ENTITY_ID_QUEUE, /** The currently loaded playback queue. Attributes for this entity include values such as its size and its shuffle and repeat modes. */
AMS_ENTITY_ID_TRACK, /** The currently loaded track. Attributes for this entity include values such as its artist, title, and duration. */
} ams_entity_id_values_t;
/**@brief Player AttributeID */
typedef enum
{
AMS_PLAYER_ATTRID_NAME, /** A string containing the localized name of the app */
AMS_PLAYER_ATTRID_PLAYBACKINFO, /** PlaybackState, PlaybackRate, ElapsedTime */
AMS_PLAYER_ATTRID_VOLUME, /** A string that represents the floating point value of the volume, ranging from 0 (silent) to 1 (full volume). */
} ams_player_attribute_id_values_t;
/**@brief Queue AttributeID */
typedef enum
{
AMS_QUEUE_ATTRID_INDEX, /** A string containing the integer value of the queue index, zero-based. */
AMS_QUEUE_ATTRID_COUNT, /** A string containing the integer value of the total number of items in the queue. */
AMS_QUEUE_ATTRID_SHUFFLE, /** A string containing the integer value of the shuffle mode. */
AMS_QUEUE_ATTRID_REPEAT, /** A string containing the integer value value of the repeat mode. */
} ams_queue_attribute_id_values_t;
/**@brief Track AttributeID */
typedef enum
{
AMS_TRACK_ATTRID_ARTIST, /** A string containing the name of the artist. */
AMS_TRACK_ATTRID_ALBUM, /** A string containing the name of the album. */
AMS_TRACK_ATTRID_TITLE, /** A string containing the title of the track. */
AMS_TRACK_ATTRID_DURATION, /** A string containing the floating point value of the total duration of the track in seconds. */
} ams_track_attribute_id_values_t;
typedef enum
{
AMS_DISCONNECTED,
AMS_CONNECTED,
AMS_BONDED,
AMS_DISCOVERED,
} ams_appl_state_t;
/* ----------------------------------------- External Global Variables */
void appl_profile_operations (void);
void appl_bond_with_peer(void);
void appl_discover_AMS(void);
extern BT_DEVICE_ADDR g_bd_addr;
/* ----------------------------------------- Exported Global Variables */
/* ----------------------------------------- Static Global Variables */
DECL_STATIC UCHAR write_response = 0;
DECL_STATIC API_RESULT gResult = 0;
DECL_STATIC ams_appl_state_t appl_ams_state = AMS_DISCONNECTED;
DECL_STATIC ATT_UUID ams_service_uuid128 = {.uuid_128.value = {0xDC, 0xF8, 0x55, 0xAD, 0x02, 0xC5, 0xF4, 0x8E, 0x3A, 0x43, 0x36, 0x0F, 0x2B, 0x50, 0xD3, 0x89}};
DECL_STATIC ATT_UUID AMS_RemoteCommand_UUID = {.uuid_128.value = {0xC2, 0x51, 0xCA, 0xF7, 0x56, 0x0E, 0xDF, 0xB8, 0x8A, 0x4A, 0xB1, 0x57, 0xD8, 0x81, 0x3C, 0x9B}};
DECL_STATIC ATT_UUID AMS_EntityUpdate_UUID = {.uuid_128.value = {0x02, 0xC1, 0x96, 0xBA, 0x92, 0xBB, 0x0C, 0x9A, 0x1F, 0x41, 0x8D, 0x80, 0xCE, 0xAB, 0x7C, 0x2F}};
DECL_STATIC ATT_UUID AMS_EntityAttribute_UUID = {.uuid_128.value = {0xD7, 0xD5, 0xBB, 0x70, 0xA8, 0xA3, 0xAB, 0xA6, 0xD8, 0x46, 0xAB, 0x23, 0x8C, 0xF3, 0xB2, 0xC6}};
/* BLE Connection Handle */
//DECL_STATIC UINT16 appl_ble_connection_handle;
/** AMS Characteristic related information */
typedef struct
{
/* AMS Service */
/* Remote Command */
ATT_ATTR_HANDLE ams_remote_command_hdl;
/* Remote Command - CCC */
ATT_ATTR_HANDLE ams_remote_command_ccc_hdl;
/* Entity Update */
ATT_ATTR_HANDLE ams_entity_update_hdl;
/* Entity Update - CCC */
ATT_ATTR_HANDLE ams_entity_update_ccc_hdl;
/* Entity Attribute */
ATT_ATTR_HANDLE ams_entity_attribute_hdl;
} AMS_CHAR_INFO;
#define APPL_CLI_CNFG_VAL_LENGTH 2
DECL_STATIC AMS_CHAR_INFO ams_char_info;
#ifdef APPL_MENU_OPS
BT_DEVICE_ADDR g_peer_bd_addr;
static UCHAR ams_client_menu[] =
"\n\
\r\n\
1. Bond with peer \r\n\
\r\n\
2. Discover AMS \r\n\
\r\n\
3. Subscribe to Entity Update \r\n\
\r\n\
4. Write to Entity Update \r\n\
\r\n\
5. Write to Remote Command \r\n\
\r\n\
6. Write to Entity Attribute \r\n\
\r\n\
7. Read Entity Attribute \r\n\
\r\n\
Your Option? \0";
#endif /* APPL_MENU_OPS */
/* --------------------------------------------- Constants */
/* --------------------------------------------- Static Global Variables */
/* --------------------------------------------- Functions */
void appl_bond_with_peer(void)
{
API_RESULT retval;
/* If connection is successful, initiate bonding [Step 2(c)] */
SMP_AUTH_INFO auth;
SMP_BD_ADDR smp_peer_bd_addr;
SMP_BD_HANDLE smp_bd_handle;
APPL_TRC("\n<<appl_bond_with_peer>>\n");
auth.param = 1;
auth.bonding = 1;
auth.ekey_size = 12;
auth.security = SMP_SEC_LEVEL_1;
BT_COPY_BD_ADDR(smp_peer_bd_addr.addr, g_bd_addr.addr);
BT_COPY_TYPE(smp_peer_bd_addr.type, g_bd_addr.type);
retval = BT_smp_get_bd_handle
(
&smp_peer_bd_addr,
&smp_bd_handle
);
if (API_SUCCESS == retval)
{
retval = BT_smp_authenticate (&smp_bd_handle, &auth);
}
if (API_SUCCESS != retval)
{
APPL_TRC (
"Initiation of Authentication Failed. Reason 0x%04X\n",
retval);
}
/**
* Application will receive authentication complete event,
* in SMP Callback.
*
* Look for 'SMP_AUTHENTICATION_COMPLETE' event handling in
* 'appl_smp_callback'.
*/
}
void appl_ams_init(void)
{
appl_ams_state = AMS_DISCONNECTED;
APPL_TRC("\n\n<<appl_ams_init>>\n\n");
}
void appl_ams_connect(APPL_HANDLE * appl_handle)
{
APPL_STATE_T state = GET_APPL_STATE(*appl_handle);
if ( state == SL_0_TRANSPORT_OPERATING && appl_ams_state == AMS_DISCONNECTED )
{
appl_ams_state = AMS_CONNECTED;
APPL_TRC("\n\n<<CONNECTED>>\n\n");
}
else if ( state == SL_0_TRANSPORT_OPERATING && appl_ams_state == AMS_DISCOVERED)
{
appl_ams_state = AMS_BONDED;
APPL_TRC("\n\n<<BONDED>>\n\n");
}
else
{
appl_ams_state = AMS_DISCONNECTED;
APPL_TRC("\n\n<<DISCONNECTED>>\n\n");
}
}
void appl_search_complete(void)
{
appl_ams_state = AMS_DISCOVERED;
APPL_TRC("\n\n<<DISCOVERED>>\n\n");
}
void appl_recvice_att_event(UCHAR att_event, API_RESULT event_result)
{
if ( att_event == ATT_WRITE_RSP )
{
write_response = 1;
gResult = 0;
}
else if ( att_event == ATT_ERROR_RSP )
{
gResult = event_result;
}
}
void appl_manage_trasnfer (GATT_DB_HANDLE handle, UINT16 config)
{
APPL_TRC("\n\n<<appl_manage_trasnfer>>\n\n");
}
void appl_send_ams_measurement (APPL_HANDLE * handle)
{
APPL_TRC("\n\n<<appl_send_ams_measurement>>\n\n");
}
void appl_timer_expiry_handler (void *data, UINT16 datalen)
{
APPL_TRC("\n\n<<appl_timer_expiry_handler>>\n\n");
}
void appl_ams_server_reinitialize (void)
{
appl_ams_state = AMS_DISCONNECTED;
APPL_TRC("\n\n<<appl_ams_server_reinitialize>>\n\n");
}
void ams_mtu_update(APPL_HANDLE * appl_handle, UINT16 t_mtu)
{
UINT16 mtu = 0;
BT_att_access_mtu(&APPL_GET_ATT_INSTANCE(*appl_handle),
&mtu);
APPL_TRC("appl_handle 0x%x t_mtu = %d %d\n", *appl_handle, t_mtu, mtu);
}
/* ------------------------------- ATT related Functions */
void appl_rcv_service_desc (UINT16 config, ATT_UUID uuid, UINT16 value_handle)
{
/* Populate Needed CCCDs here */
if (GATT_CLIENT_CONFIG == config)
{
if ( memcmp(&uuid, &AMS_RemoteCommand_UUID, ATT_128_BIT_UUID_SIZE) == 0 )
{
ams_char_info.ams_remote_command_ccc_hdl = value_handle;
}
else if ( memcmp(&uuid, &AMS_EntityUpdate_UUID, ATT_128_BIT_UUID_SIZE) == 0 )
{
ams_char_info.ams_entity_update_ccc_hdl = value_handle;
}
}
}
void appl_rcv_service_char (ATT_UUID uuid, UINT16 value_handle)
{
if ( memcmp(&uuid, &AMS_RemoteCommand_UUID, ATT_128_BIT_UUID_SIZE) == 0 )
{
ams_char_info.ams_remote_command_hdl = value_handle;
}
else if ( memcmp(&uuid, &AMS_EntityUpdate_UUID, ATT_128_BIT_UUID_SIZE) == 0 )
{
ams_char_info.ams_entity_update_hdl = value_handle;
}
else if ( memcmp(&uuid, &AMS_EntityAttribute_UUID, ATT_128_BIT_UUID_SIZE) == 0 )
{
ams_char_info.ams_entity_attribute_hdl = value_handle;
}
}
void Wait4WrtRsp(void)
{
const TickType_t xDelay = 10 / portTICK_PERIOD_MS;
UCHAR i = 0;
while ( !write_response )
{
vTaskDelay( xDelay );
if (i++ > 10 )
{
break;
}
}
write_response = 0;
}
void appl_discover_AMS(void)
{
APPL_TRC("\n<<appl discover AMS>>\n");
appl_discover_service
(
ams_service_uuid128,
ATT_128_BIT_UUID_FORMAT
);
return;
}
void AmsWrite2EnityUpdate(uint8_t entityID)
{
ATT_VALUE att_value;
uint8_t buf[5];
APPL_TRC("\n++<<AmsWrite2EnityUpdate %d>>\n", entityID);
if ( entityID == AMS_ENTITY_ID_PLAYER )
{
buf[0] = AMS_ENTITY_ID_PLAYER;
buf[1] = AMS_PLAYER_ATTRID_NAME;
buf[2] = AMS_PLAYER_ATTRID_PLAYBACKINFO;
buf[3] = AMS_PLAYER_ATTRID_VOLUME;
att_value.len = 4;
}
else if ( entityID == AMS_ENTITY_ID_QUEUE )
{
buf[0] = AMS_ENTITY_ID_QUEUE;
buf[1] = AMS_QUEUE_ATTRID_INDEX;
buf[2] = AMS_QUEUE_ATTRID_COUNT;
buf[3] = AMS_QUEUE_ATTRID_SHUFFLE;
buf[4] = AMS_QUEUE_ATTRID_REPEAT;
att_value.len = 5;
}
else if ( entityID == AMS_ENTITY_ID_TRACK )
{
buf[0] = AMS_ENTITY_ID_TRACK;
buf[1] = AMS_TRACK_ATTRID_ARTIST;
buf[2] = AMS_TRACK_ATTRID_ALBUM;
buf[3] = AMS_TRACK_ATTRID_TITLE;
buf[4] = AMS_TRACK_ATTRID_DURATION;
att_value.len = 5;
}
else
{
return;
}
att_value.val = buf;
appl_write_req (ams_char_info.ams_entity_update_hdl, &att_value);
Wait4WrtRsp();
APPL_TRC("\n--<<AmsWrite2EnityUpdate %d>>\n", entityID);
}
void AmsWrite2RemoteCommand(uint8_t cmd)
{
ATT_VALUE att_value;
uint8_t buf[1]; // retrieve the complete attribute list
buf[0] = cmd;
att_value.len = 1;
att_value.val = buf;
appl_write_req (ams_char_info.ams_remote_command_hdl, &att_value);
}
void AmsWrite2EntityAttribute(uint8_t entityID, uint8_t attrID)
{
ATT_VALUE att_value;
uint8_t buf[2]; // retrieve the complete attribute list
buf[0] = entityID;
buf[1] = attrID;
att_value.len = 2;
att_value.val = buf;
appl_write_req (ams_char_info.ams_entity_attribute_hdl, &att_value);
}
void AmsSubscribe2EnityUpdate(void)
{
ATT_VALUE att_value;
UINT16 cli_cfg;
UCHAR cfg_val[APPL_CLI_CNFG_VAL_LENGTH];
APPL_TRC("\n++<<AmsSubscribe2EnityUpdate>>\n");
cli_cfg = GATT_CLI_CNFG_NOTIFICATION;
BT_PACK_LE_2_BYTE(cfg_val, &cli_cfg);
att_value.len = APPL_CLI_CNFG_VAL_LENGTH;
att_value.val = cfg_val;
appl_write_req (ams_char_info.ams_entity_update_ccc_hdl, &att_value);
Wait4WrtRsp();
APPL_TRC("\n--<<AmsSubscribe2EnityUpdate(0x%04X)>>\n", gResult);
}
void appl_profile_operations (void)
{
const TickType_t xDelay = 100 / portTICK_PERIOD_MS;
write_response = 0;
fsm_post_event
(
APPL_FSM_ID,
ev_appl_device_init_req,
NULL
);
while ( appl_ams_state != AMS_CONNECTED )
{
vTaskDelay( xDelay );
}
appl_discover_AMS();
while ( appl_ams_state != AMS_DISCOVERED )
{
vTaskDelay( xDelay );
}
AmsSubscribe2EnityUpdate();
if (gResult == 0x0305 /* insufficient authentication */ ||
gResult == 0x030F /* insufficient Encryption */ )
{
appl_bond_with_peer();
while ( appl_ams_state != AMS_BONDED )
{
vTaskDelay( xDelay );
}
AmsSubscribe2EnityUpdate();
}
else
{
appl_ams_state = AMS_BONDED;
}
AmsWrite2EnityUpdate(AMS_ENTITY_ID_PLAYER);
AmsWrite2EnityUpdate(AMS_ENTITY_ID_QUEUE);
AmsWrite2EnityUpdate(AMS_ENTITY_ID_TRACK);
while ( appl_ams_state != AMS_DISCONNECTED )
{
vTaskDelay( xDelay );
}
}
void AmsDumpBytes (UCHAR *buffer, UINT16 length)
{
char hex_stream[49];
char char_stream[17];
UINT32 i;
UINT16 offset, count;
UCHAR c;
APPL_TRC("\n");
APPL_TRC (
"-------------------------------------------------------------------\n");
count = 0;
offset = 0;
for (i = 0; i < length; i ++ )
{
c = buffer[i];
sprintf(hex_stream + offset, "%02X ", c);
if ( (c >= 0x20) && (c <= 0x7E) )
{
char_stream[count] = c;
}
else
{
char_stream[count] = '.';
}
count ++;
offset += 3;
if ( 16 == count )
{
char_stream[count] = '\0';
count = 0;
offset = 0;
APPL_TRC ("%s %s\n",
hex_stream, char_stream);
BT_mem_set(hex_stream, 0, 49);
BT_mem_set(char_stream, 0, 17);
}
}
if ( offset != 0 )
{
char_stream[count] = '\0';
/* Maintain the alignment */
APPL_TRC ("%-48s %s\n",
hex_stream, char_stream);
}
APPL_TRC (
"-------------------------------------------------------------------\n");
APPL_TRC ("\n");
return;
}
void AmsNotificationCb(UCHAR *event_data, UINT16 event_datalen)
{
AmsDumpBytes(event_data + 2, (event_datalen - 2));
}
void AmsReadRSPCb(UCHAR *event_data, UINT16 event_datalen)
{
ATT_ATTR_HANDLE attr_handle;
BT_UNPACK_LE_2_BYTE(&attr_handle, event_data);
AmsDumpBytes(event_data + 2, (event_datalen - 2));
}
#endif /* AMS */

View File

@ -0,0 +1,117 @@
//*****************************************************************************
//
//! @file appl_ams.c
//!
//! @brief Application Header File for AMS.
//!
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/**
* \file appl_ams.h
*
* Application Header File for AMS.
*/
#ifndef _H_APPL_AMS_
#define _H_APPL_AMS_
/* ----------------------------------------- Header File Inclusion */
#include "BT_api.h"
#include "BT_gatt_db_api.h"
#include "gatt_db.h"
#include "appl.h"
#include "appl_ams_att_server.h"
/* ----------------------------------------- Data Types/ Structures */
typedef struct
{
UCHAR index;
UCHAR length;
}APPL_HRS_OBS_DATA_INFO;
/* --------------------------------------------- Global Definitions */
/** LSB of error code has to be spec defined */
#define APPL_HR_CNTRL_PNT_NOT_SUPPORTED (APPL_ERR_ID | 0x80)
/* --------------------------------------------- Functions */
void appl_ams_init(void);
void appl_manage_trasnfer (GATT_DB_HANDLE handle, UINT16 config);
void appl_timer_expiry_handler (void *data, UINT16 datalen);
void appl_ams_connect(DEVICE_HANDLE * dq_handle);
void appl_send_ams_measurement (APPL_HANDLE * handle);
void appl_ams_server_reinitialize (void);
void appl_rcv_service_desc (UINT16 config, ATT_UUID uuid, UINT16 value_handle);
void appl_rcv_service_char (ATT_UUID uuid, UINT16 value_handle);
API_RESULT appl_hr_control_point_handler
(
GATT_DB_HANDLE * handle,
ATT_VALUE * value
);
API_RESULT appl_att_callback
(
ATT_HANDLE * handle,
UCHAR event_type,
API_RESULT event_result,
UCHAR * event_data,
UINT16 event_datalen
);
void ams_mtu_update(APPL_HANDLE * appl_handle, UINT16 t_mtu);
/* Profile handling */
#define APPL_PROFILE_INIT(...) appl_ams_init()
#define APPL_PROFILE_CONNECT(x) appl_ams_connect(x)
#define APPL_SEND_MEASUREMENT(x)appl_send_ams_measurement(x)
#define APPL_PROFILE_DISCONNECT_HANDLER(x) appl_ams_server_reinitialize()
#define GATT_DB_PROFILE_HANDLER gatt_db_ams_handler
#define APPL_PROFILE_HVN_NTF_COMPLETE_HANDLER(x, y, z)
#define APPL_PROFILE_HVN_IND_COMPLETE_HANDLER(x, y, z)
#define APPL_PROFILE_MTU_UPDT_COMPLETE_HANDLER(x, y) ams_mtu_update(x, y)
#define APPL_USE_IDLE_TIMER
#define APPL_IDLE_TIMEOUT 30
#endif /* _H_APPL_AMS_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,158 @@
//*****************************************************************************
//
//! @file appl_ams_att_server.h
//!
//! @brief ATT Server Application Header File
//!
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/**
* \file appl_ams_att_server.h
*
* ATT Server Application Header File
*/
/*
* Copyright (C) 2013. Mindtree Ltd.
* All rights reserved.
*/
#ifndef _H_APPL_AMS_ATT_SERVER_
#define _H_APPL_AMS_ATT_SERVER_
/* ----------------------------------------- Header File Inclusion */
#include "BT_api.h"
#include "BT_gatt_db_api.h"
#define APPL_ATT_WRITE_QUEUE_SIZE 10
#define APPL_ATT_MAX_WRITE_BUFFER_SIZE 256 /* 255 */
#define APPL_ATT_MTU ATT_MAX_MTU
#define APPL_SERVER_BUFFER_SIZE 256 /* 256 */
#define APPL_MAX_GROUP_TYPE_QUERIED 5
#define APPL_MAX_HNDL_UUID_LIST_SIZE 5
#define APPL_MAX_HNDL_LIST_SIZE 11
#define APPL_MAX_HNDL_VALUE_SIZE 5
/* ATT PDU Request Length */
#define APPL_ATT_XCNHG_MTU_REQ_LEN 2
#define APPL_ATT_XCNHG_MTU_RSP_LEN 2
#define APPL_ATT_FIND_INFO_REQ_LEN 4
#define APPL_ATT_FIND_INFO_RSP_LEN_1 5
#define APPL_ATT_FIND_INFO_RSP_LEN_2 22
#define ATT_FIND_BY_TYPE_VAL_RSP_LEN1 4
#define ATT_FIND_BY_TYPE_VAL_RSP_LEN2 21
#define APPL_ATT_READ_BY_TYPE_REQ_LEN_1 6
#define APPL_ATT_READ_BY_TYPE_REQ_LEN_2 20
#define ATT_READ_BY_TYPE_RSP_LEN_1 3
#define ATT_READ_BY_TYPE_RSP_LEN_2 22
#define APPL_ATT_READ_REQ_LEN 2
#define APPL_ATT_READ_RSP_LEN_1 0
#define APPL_ATT_READ_RSP_LEN_2 22
#define APPL_ATT_READ_BLOB_REQ_LEN 4
#define APPL_ATT_READ_BLOB_RSP_LEN_1 0
#define APPL_ATT_READ_BLOB_RSP_LEN_2 22
#define APPL_ATT_READ_BY_GROUP_REQ_LEN_1 6
#define APPL_ATT_READ_BY_GROUP_REQ_LEN_2 20
#define APPL_ATT_READ_BY_GROUP_RSP_LEN_1 5
#define APPL_ATT_READ_BY_GROUP_RSP_LEN_2 22
#define APPL_ATT_EXECUTE_WRITE_REQ_LEN 1
#define APPL_ATT_INVALID_LEN 0xFF
#define APPL_MAX_VALID_ATT_PDU_LEN_CHK 7
/** Application Defined error */
#define APPL_ATT_INVALID_OFFSET 0xFFFF
#define ATT_INVALID_ATTR_HANDLE_VAL 0x0000
#define APPL_MAX_MULTIPLE_READ_COUNT 11
#define APPL_CHECK_IF_ATT_REQUEST(type)\
((((((type) > 0x13) && ((type) < 0x16)) ||\
(((type) > 0x1E) && (((type) != ATT_SIGNED_WRITE_CMD) &&\
((type) != ATT_WRITE_CMD)))) || (0x01 == ((type) & 0x01)))? BT_FALSE : BT_TRUE)
#define APPL_ATT_PREPARE_QUEUE_INIT(i)\
appl_att_write_queue[(i)].handle_value.handle = 0;\
appl_att_write_queue[(i)].offset = 0xFFFF;\
appl_att_write_queue[(i)].handle_value.value.len = 0;\
appl_att_write_queue[(i)].handle_value.value.val = NULL;
API_RESULT appl_discover_service
(
/* IN */ ATT_UUID uuid,
/* IN */ UCHAR uuid_frmt
);
API_RESULT appl_write_req
(
/* IN */ ATT_ATTR_HANDLE handle,
/* IN */ ATT_VALUE * value
);
API_RESULT appl_read_req
(
/* IN */ ATT_ATTR_HANDLE handle
);
API_RESULT appl_att_server_init(void);
API_RESULT appl_handle_unsupported_op_code (ATT_HANDLE *handle, UCHAR op_code);
API_RESULT appl_validate_att_pdu_req_len
(
UCHAR att_event,
UINT16 event_datalen
);
#ifdef SMP_DATA_SIGNING
void appl_gatt_signing_complete (API_RESULT status, UCHAR * data, UINT16 datalen);
void appl_gatt_signing_verification_complete
(
API_RESULT status,
UCHAR * data,
UINT16 datalen
);
#endif /* SMP_DATA_SIGNING */
#endif /* _H_APPL_AMS_ATT_SERVER_ */

View File

@ -0,0 +1,227 @@
//*****************************************************************************
//
//! @file appl_gap_config_params.c
//!
//! @brief This file contains GAP Configuration Parameters used by the application.
//!
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/**
* \file appl_gap_config_params.c
*
* This file contains GAP Configuration Parameters used by the application.
*/
/* --------------------------------------------- Header File Inclusion */
#include "appl_gap.h"
#ifdef AMS
/* --------------------------------------------- External Global Variables */
/* --------------------------------------------- Exported Global Variables */
/* --------------------------------------------- Static Global Variables */
#if ((defined APPL_GAP_BROADCASTER_SUPPORT) || (defined APPL_GAP_PERIPHERAL_SUPPORT))
/** Advertisement Data Options */
const APPL_GAP_ADV_DATA appl_gap_adv_data[APPL_GAP_MAX_ADV_DATA_OPTIONS] =
{
/* GAP Advertisement Parameters */
{
{
/**
* Flags:
* 0x01: LE Limited Discoverable Mode
* 0x02: LE General Discoverable Mode
* 0x04: BR/EDR Not Supported
* 0x08: Simultaneous LE and BR/EDR to Same Device
* Capable (Controller)
* 0x10: Simultaneous LE and BR/EDR to Same Device
* Capable (Host)
*/
0x02, 0x01,
(BT_AD_FLAGS_LE_GENERAL_DISC_MODE | BT_AD_FLAGS_LE_BR_EDR_SUPPORT),
/**
* Service UUID List:
* Battery Service (0x180F)
* DeviceInformation Service (0x180A)
*/
0x05, 0x03, 0x0F, 0x18, 0x0A, 0x18,
/**
* Shortened Device Name: AM
*/
0x03, 0x08, 0x41, 0x4d,
/**
* List of 16-bit Service Solicitation UUIDs(AMS UUID)
*/
0x11, 0x15, 0xDC, 0xF8, 0x55, 0xAD, 0x02, 0xC5, 0xF4, 0x8E, 0x3A, 0x43, 0x36, 0x0F, 0x2B, 0x50, 0xD3, 0x89
},
31
}
};
/* Advertisement parameters options */
const APPL_GAP_ADV_PARAM appl_gap_adv_param[APPL_GAP_MAX_ADV_PARAM_OPTIONS] =
{
/* 0 - Normal Advertising Params */
{
32,
32,
7,
0
},
/* 1 - Fast Connection Advertising Params */
{
32,
48,
7,
0
},
/* 2 - Low Power Advertising Params */
{
1600,
4000,
7,
0
}
};
/* Advertisement Table */
APPL_GAP_ADV_INFO appl_gap_adv_table =
{
appl_gap_adv_data,
appl_gap_adv_param,
APPL_GAP_ADV_IDLE
};
#endif /* APPL_GAP_BROADCASTER || APPL_GAP_PERIPHERAL_SUPPORT */
#if ((defined APPL_GAP_OBSERVER_SUPPORT) || (defined APPL_GAP_CENTRAL_SUPPORT))
/* Scan Parameters Option */
const APPL_GAP_SCAN_PARAM appl_gap_scan_param[APPL_GAP_MAX_SCAN_PARAM_OPTIONS] =
{
/* Normal Scan Params */
{
32,
7,
0
},
/* Fast Connection Scan Params */
{
48,
7,
0
},
/* Low Power Scan Params */
{
4000,
7,
0
}
};
/* Scan Table */
APPL_GAP_SCAN_INFO appl_gap_scan_table =
{
appl_gap_scan_param,
APPL_GAP_SCAN_IDLE
};
#endif /* APPL_GAP_OBSERVER_SUPPORT || APPL_GAP_CENTRAL_SUPPORT */
#ifdef APPL_GAP_CENTRAL_SUPPORT
/* Connection Parameters Options */
const APPL_GAP_CONN_PARAM appl_gap_conn_param[APPL_GAP_MAX_CONN_PARAM_OPTIONS] =
{
{
4,
4,
0,
40,
56,
0,
955,
32,
32
}
};
/* GAP Connection Table */
APPL_GAP_CONN_INFO appl_gap_conn_table =
{
appl_gap_conn_param,
APPL_GAP_CONN_IDLE
};
#endif /* APPL_GAP_CENTRAL_SUPPORT */
#endif /* AMS */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,157 @@
//*****************************************************************************
//
//! @file gatt_db.h
//!
//! @brief GATT Databse.
//!
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/**
* \file gatt_db.h
*/
/*
* Copyright (C) 2013. Mindtree Ltd.
* All rights reserved.
*/
#ifndef _H_GATT_DB_
#define _H_GATT_DB_
/**
* addgroup gatt_db_module
*/
/**
* defgroup gatt_db_tuneable_param Tuneable Parameters
* {
* This section defines the Tuneable Constants of Data Base Module.
*/
/** Number of Characteristics in the data base */
#define GATT_CHARACTERISTIC_COUNT 13
/** Number of Services in the data base */
#define GATT_SERVICE_COUNT 4
/** Number of Characteristics that are configurable by the client */
#define GATT_DB_MAX_CONFIGUREABLE_CHAR 3
/** Maximum Length of any Characteristic Value/Descriptor */
#define GATT_DB_MAX_VAL_LENGTH 32
#define GATT_VALUE_ARRAY_SIZE 1
#define GATT_CONST_VALUE_ARRAY_SIZE 180
#define GATT_DB_PEER_VALUE_ARRAY_SIZE 4
#define GATT_DB_MAX_ATTRIBUTES 34
#define GATT_UUID_ARRAY_SIZE 54
#define GATT_DB_MAX_TYPE_COUNT 21
#define GATT_DB_MAX_PEER_CONFIGURATION \
(GATT_DB_PEER_VALUE_ARRAY_SIZE * BT_MAX_DEVICE_QUEUE_SIZE)
/** \} */
/** Service Instance Reference */
/** GAP Service */
#define GATT_SER_GAP_INST 0
/** GATT Service */
#define GATT_SER_GATT_INST 1
/** Battery Service */
#define GATT_SER_BATTERY_INST 2
/** DeviceInformation Service */
#define GATT_SER_DEV_INFO_INST 3
/** Characteristic Instance Reference */
/** DeviceName */
#define GATT_CHAR_DEV_NAME_INST 0
/** Appearance */
#define GATT_CHAR_APPEARANCE_INST 1
/** Service Changed */
#define GATT_CHAR_SER_CHNGD_INST 2
/** BatteryLevel */
#define GATT_CHAR_BATTERY_LVL_INST 3
/** ManufacturerName */
#define GATT_CHAR_MAN_NAME_INST 4
/** ModelNumber */
#define GATT_CHAR_MODEL_NO_INST 5
/** SerialNumber */
#define GATT_CHAR_SL_NO_INST 6
/** FirmwareRevision */
#define GATT_CHAR_FW_REV_INST 7
/** HardwareRevision */
#define GATT_CHAR_HW_REV_INST 8
/** SoftwareRevision */
#define GATT_CHAR_SW_REV_INST 9
/** SystemId */
#define GATT_CHAR_SYS_ID_INST 10
/** RegCertDataList */
#define GATT_CHAR_REG_CERT_DATA_INST 11
/** PnPID */
#define GATT_CHAR_PNP_ID_INST 12
#endif /* _H_GATT_DB_ */

View File

@ -0,0 +1,666 @@
//*****************************************************************************
//
//! @file appl_ancs.c
//!
//! @brief ANCS service.
//!
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/**
* \file appl_ancs.c
*
*/
/* --------------------------------------------- Header File Inclusion */
#ifdef ANCS
#include "appl.h"
#include "BT_common.h"
#include "BT_hci_api.h"
#include "BT_att_api.h"
#include "BT_smp_api.h"
#include "smp_pl.h"
#include "l2cap.h"
#include "fsm_defines.h"
#include "task.h"
#include "queue.h"
/* ----------------------------------------- Configuration Defines */
extern uint32_t am_util_stdio_printf(const char *pcFmt, ...);
#undef APPL_TRC
#undef APPL_ERR
#define APPL_TRC am_util_stdio_printf
#define APPL_ERR am_util_stdio_printf
/* ----------------------------------------- Macro Defines */
/**@brief Category IDs for iOS notifications. */
typedef enum
{
BLE_ANCS_CATEGORY_ID_OTHER, /**< The iOS notification belongs to the "other" category. */
BLE_ANCS_CATEGORY_ID_INCOMING_CALL, /**< The iOS notification belongs to the "Incoming Call" category. */
BLE_ANCS_CATEGORY_ID_MISSED_CALL, /**< The iOS notification belongs to the "Missed Call" category. */
BLE_ANCS_CATEGORY_ID_VOICE_MAIL, /**< The iOS notification belongs to the "Voice Mail" category. */
BLE_ANCS_CATEGORY_ID_SOCIAL, /**< The iOS notification belongs to the "Social" category. */
BLE_ANCS_CATEGORY_ID_SCHEDULE, /**< The iOS notification belongs to the "Schedule" category. */
BLE_ANCS_CATEGORY_ID_EMAIL, /**< The iOS notification belongs to the "E-mail" category. */
BLE_ANCS_CATEGORY_ID_NEWS, /**< The iOS notification belongs to the "News" category. */
BLE_ANCS_CATEGORY_ID_HEALTH_AND_FITNESS, /**< The iOS notification belongs to the "Health and Fitness" category. */
BLE_ANCS_CATEGORY_ID_BUSINESS_AND_FINANCE, /**< The iOS notification belongs to the "Buisness and Finance" category. */
BLE_ANCS_CATEGORY_ID_LOCATION, /**< The iOS notification belongs to the "Location" category. */
BLE_ANCS_CATEGORY_ID_ENTERTAINMENT /**< The iOS notification belongs to the "Entertainment" category. */
} ancc_category_id_values_t;
/**@brief Event IDs for iOS notifications. */
typedef enum
{
BLE_ANCS_EVENT_ID_NOTIFICATION_ADDED, /**< The iOS notification was added. */
BLE_ANCS_EVENT_ID_NOTIFICATION_MODIFIED, /**< The iOS notification was modified. */
BLE_ANCS_EVENT_ID_NOTIFICATION_REMOVED /**< The iOS notification was removed. */
} ancc_evt_id_values_t;
/**@brief Control point command IDs that the Notification Consumer can send to the Notification Provider. */
typedef enum
{
BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES, /**< Requests attributes to be sent from the NP to the NC for a given notification. */
BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES, /**< Requests attributes to be sent from the NP to the NC for a given iOS App. */
BLE_ANCS_COMMAND_ID_GET_PERFORM_NOTIF_ACTION, /**< Requests an action to be performed on a given notification, for example dismiss an alarm. */
} ancc_command_id_values_t;
/**@brief IDs for iOS notification attributes. */
typedef enum
{
BLE_ANCS_NOTIF_ATTR_ID_APP_IDENTIFIER, /**< Identifies that the attribute data is of an "App Identifier" type. */
BLE_ANCS_NOTIF_ATTR_ID_TITLE, /**< Identifies that the attribute data is a "Title". Needs to be followed by a 2-bytes max length parameter*/
BLE_ANCS_NOTIF_ATTR_ID_SUBTITLE, /**< Identifies that the attribute data is a "Subtitle". Needs to be followed by a 2-bytes max length parameter*/
BLE_ANCS_NOTIF_ATTR_ID_MESSAGE, /**< Identifies that the attribute data is a "Message". Needs to be followed by a 2-bytes max length parameter*/
BLE_ANCS_NOTIF_ATTR_ID_MESSAGE_SIZE, /**< Identifies that the attribute data is a "Message Size". */
BLE_ANCS_NOTIF_ATTR_ID_DATE, /**< Identifies that the attribute data is a "Date". */
BLE_ANCS_NOTIF_ATTR_ID_POSITIVE_ACTION_LABEL, /**< The notification has a "Positive action" that can be executed associated with it. */
BLE_ANCS_NOTIF_ATTR_ID_NEGATIVE_ACTION_LABEL, /**< The notification has a "Negative action" that can be executed associated with it. */
} ancc_notif_attr_id_values_t;
/**@brief Typedef for iOS notifications. */
typedef struct
{
uint8_t event_id; /**< This field informs the accessory whether the given iOS notification was added, modified, or removed. The enumerated values for this field are defined in EventID Values.. */
uint8_t event_flags; /**< A bitmask whose set bits inform an NC of specificities with the iOS notification. */
uint8_t category_id; /**< A numerical value providing a category in which the iOS notification can be classified. */
uint8_t category_count; /**< The current number of active iOS notifications in the given category. */
uint32_t notification_uid; /**< A 32-bit numerical value that is the unique identifier (UID) for the iOS notification. */
} ancc_notif_t;
typedef enum
{
ANCS_DISCONNECTED,
ANCS_CONNECTED,
ANCS_BONDED,
ANCS_DISCOVERED,
} ancs_appl_state_t;
/* ----------------------------------------- External Global Variables */
void appl_profile_operations (void);
void AncsGetNotificationAttribute(uint32_t notiUid);
extern BT_DEVICE_ADDR g_bd_addr;
/* ----------------------------------------- Exported Global Variables */
QueueHandle_t xNtfUIDQueue;
/* ----------------------------------------- Static Global Variables */
DECL_STATIC UCHAR write_response = 0;
DECL_STATIC API_RESULT gResult = 0;
DECL_STATIC ancs_appl_state_t appl_ancs_state = ANCS_DISCONNECTED;
DECL_STATIC ATT_UUID ancs_service_uuid128 = {.uuid_128.value = {0xD0, 0x00, 0x2D, 0x12, 0x1E, 0x4B, 0x0F, 0xA4, 0x99, 0x4E, 0xCE, 0xB5, 0x31, 0xF4, 0x05, 0x79}};
DECL_STATIC ATT_UUID ANCS_ControlPoint_UUID = {.uuid_128.value = {0xD9, 0xD9, 0xAA, 0xFD, 0xBD, 0x9B, 0x21, 0x98, 0xA8, 0x49, 0xE1, 0x45, 0xF3, 0xD8, 0xD1, 0x69}};
DECL_STATIC ATT_UUID ANCS_NotificationSource_UUID = {.uuid_128.value = {0xBD, 0x1D, 0xA2, 0x99, 0xE6, 0x25, 0x58, 0x8C, 0xD9, 0x42, 0x01, 0x63, 0x0D, 0x12, 0xBF, 0x9F}};
DECL_STATIC ATT_UUID ANCS_DataSource_UUID = {.uuid_128.value = {0xFB, 0x7B, 0x7C, 0xCE, 0x6A, 0xB3, 0x44, 0xBE, 0xB5, 0x4B, 0xD6, 0x24, 0xE9, 0xC6, 0xEA, 0x22}};
/* BLE Connection Handle */
//DECL_STATIC UINT16 appl_ble_connection_handle;
/** ANCS Characteristic related information */
typedef struct
{
/* ANCS Service */
/* Notification Source */
ATT_ATTR_HANDLE ancs_notification_source_hdl;
/* Notification Source - CCC */
ATT_ATTR_HANDLE ancs_notification_source_ccc_hdl;
/* Control Point */
ATT_ATTR_HANDLE ancs_control_point_hdl;
/* Data Source */
ATT_ATTR_HANDLE ancs_data_source_hdl;
/* Data Source - CCC */
ATT_ATTR_HANDLE ancs_data_source_ccc_hdl;
} ANCS_CHAR_INFO;
#define APPL_CLI_CNFG_VAL_LENGTH 2
DECL_STATIC ANCS_CHAR_INFO ancs_char_info;
#ifdef APPL_MENU_OPS
BT_DEVICE_ADDR g_peer_bd_addr;
static UCHAR ancs_client_menu[] =
"\n\
\r\n\
1. Bond with peer \r\n\
\r\n\
2. Discover ANCS \r\n\
\r\n\
3. Set Data Source CCCD \r\n\
\r\n\
4. Set Notification Source CCCD \r\n\
\r\n\
5. Get Notification Attribute by UID \r\n\
\r\n\
Your Option? \0";
#endif /* APPL_MENU_OPS */
/* --------------------------------------------- Constants */
/* --------------------------------------------- Static Global Variables */
/* --------------------------------------------- Functions */
void appl_bond_with_peer(void)
{
API_RESULT retval;
/* If connection is successful, initiate bonding [Step 2(c)] */
SMP_AUTH_INFO auth;
SMP_BD_ADDR smp_peer_bd_addr;
SMP_BD_HANDLE smp_bd_handle;
APPL_TRC("\n<<appl_bond_with_peer>>\n");
auth.param = 1;
auth.bonding = 1;
auth.ekey_size = 12;
auth.security = SMP_SEC_LEVEL_1;
BT_COPY_BD_ADDR(smp_peer_bd_addr.addr, g_bd_addr.addr);
BT_COPY_TYPE(smp_peer_bd_addr.type, g_bd_addr.type);
retval = BT_smp_get_bd_handle
(
&smp_peer_bd_addr,
&smp_bd_handle
);
if (API_SUCCESS == retval)
{
retval = BT_smp_authenticate (&smp_bd_handle, &auth);
}
if (API_SUCCESS != retval)
{
APPL_TRC (
"Initiation of Authentication Failed. Reason 0x%04X\n",
retval);
}
/**
* Application will receive authentication complete event,
* in SMP Callback.
*
* Look for 'SMP_AUTHENTICATION_COMPLETE' event handling in
* 'appl_smp_callback'.
*/
}
void appl_ancs_init(void)
{
appl_ancs_state = ANCS_DISCONNECTED;
APPL_TRC("\n\n<<appl_ancs_init>>\n\n");
}
void appl_ancs_connect(APPL_HANDLE * appl_handle)
{
APPL_STATE_T state = GET_APPL_STATE(*appl_handle);
if ( state == SL_0_TRANSPORT_OPERATING && appl_ancs_state == ANCS_DISCONNECTED )
{
appl_ancs_state = ANCS_CONNECTED;
APPL_TRC("\n\n<<CONNECTED>>\n\n");
}
else if ( state == SL_0_TRANSPORT_OPERATING && appl_ancs_state == ANCS_DISCOVERED )
{
appl_ancs_state = ANCS_BONDED;
APPL_TRC("\n\n<<BONDED>>\n\n");
}
else
{
appl_ancs_state = ANCS_DISCONNECTED;
APPL_TRC("\n\n<<DISCONNECTED>>\n\n");
}
}
void appl_search_complete(void)
{
appl_ancs_state = ANCS_DISCOVERED;
APPL_TRC("\n\n<<DISCOVERED>>\n\n");
}
void appl_recvice_att_event(UCHAR att_event, API_RESULT event_result)
{
if ( att_event == ATT_WRITE_RSP )
{
write_response = 1;
gResult = 0;
}
else if ( att_event == ATT_ERROR_RSP )
{
gResult = event_result;
}
}
void appl_manage_trasnfer (GATT_DB_HANDLE handle, UINT16 config)
{
APPL_TRC("\n\n<<appl_manage_trasnfer>>\n\n");
}
void appl_send_ancs_measurement (APPL_HANDLE * handle)
{
APPL_TRC("\n\n<<appl_send_ancs_measurement>>\n\n");
}
void appl_timer_expiry_handler (void *data, UINT16 datalen)
{
APPL_TRC("\n\n<<appl_timer_expiry_handler>>\n\n");
}
void appl_ancs_server_reinitialize (void)
{
appl_ancs_state = ANCS_DISCONNECTED;
APPL_TRC("\n\n<<appl_ancs_server_reinitialize>>\n\n");
}
void ancs_mtu_update(APPL_HANDLE * appl_handle, UINT16 t_mtu)
{
UINT16 mtu = 0;
BT_att_access_mtu(&APPL_GET_ATT_INSTANCE(*appl_handle),
&mtu);
APPL_TRC("appl_handle 0x%x t_mtu = %d %d\n", *appl_handle, t_mtu, mtu);
}
/* ------------------------------- ATT related Functions */
void appl_rcv_service_desc (UINT16 config, ATT_UUID uuid, UINT16 value_handle)
{
/* Populate Needed CCCDs here */
if (GATT_CLIENT_CONFIG == config)
{
if ( memcmp(&uuid, &ANCS_NotificationSource_UUID, ATT_128_BIT_UUID_SIZE) == 0 )
{
ancs_char_info.ancs_notification_source_ccc_hdl = value_handle;
}
else if ( memcmp(&uuid, &ANCS_DataSource_UUID, ATT_128_BIT_UUID_SIZE) == 0 )
{
ancs_char_info.ancs_data_source_ccc_hdl = value_handle;
}
}
}
void appl_rcv_service_char (ATT_UUID uuid, UINT16 value_handle)
{
if ( memcmp(&uuid, &ANCS_NotificationSource_UUID, ATT_128_BIT_UUID_SIZE) == 0 )
{
ancs_char_info.ancs_notification_source_hdl = value_handle;
}
else if ( memcmp(&uuid, &ANCS_ControlPoint_UUID, ATT_128_BIT_UUID_SIZE) == 0 )
{
ancs_char_info.ancs_control_point_hdl = value_handle;
}
else if ( memcmp(&uuid, &ANCS_DataSource_UUID, ATT_128_BIT_UUID_SIZE) == 0 )
{
ancs_char_info.ancs_data_source_hdl = value_handle;
}
}
void Wait4WrtRsp(void)
{
const TickType_t xDelay = 10 / portTICK_PERIOD_MS;
UCHAR i = 0;
while ( !write_response )
{
vTaskDelay( xDelay );
if (i++ > 10 )
{
break;
}
}
write_response = 0;
}
void appl_discover_ANCS(void)
{
APPL_TRC("\n<<appl_discover_ANCS>>\n");
appl_discover_service
(
ancs_service_uuid128,
ATT_128_BIT_UUID_FORMAT
);
return;
}
void AncsSubscribeNotifications(void)
{
ATT_VALUE att_value;
UINT16 cli_cfg;
UCHAR cfg_val[APPL_CLI_CNFG_VAL_LENGTH];
APPL_TRC("\n++<<AncsSubscribeNotifications>>\n");
cli_cfg = GATT_CLI_CNFG_NOTIFICATION;
BT_PACK_LE_2_BYTE(cfg_val, &cli_cfg);
att_value.len = APPL_CLI_CNFG_VAL_LENGTH;
att_value.val = cfg_val;
appl_write_req(ancs_char_info.ancs_data_source_ccc_hdl, &att_value);
Wait4WrtRsp();
cli_cfg = GATT_CLI_CNFG_NOTIFICATION;
BT_PACK_LE_2_BYTE(cfg_val, &cli_cfg);
att_value.len = APPL_CLI_CNFG_VAL_LENGTH;
att_value.val = cfg_val;
appl_write_req(ancs_char_info.ancs_notification_source_ccc_hdl, &att_value);
Wait4WrtRsp();
APPL_TRC("\n--<<AncsSubscribeNotifications(0x%04X)>>\n", gResult);
}
void appl_profile_operations (void)
{
const TickType_t xDelay = 100 / portTICK_PERIOD_MS;
UINT32 NtfUID;
write_response = 0;
xNtfUIDQueue = 0;
xNtfUIDQueue = xQueueCreate( 10, sizeof(UINT32) );
fsm_post_event
(
APPL_FSM_ID,
ev_appl_device_init_req,
NULL
);
while ( appl_ancs_state != ANCS_CONNECTED)
{
vTaskDelay( xDelay );
}
appl_discover_ANCS();
while ( appl_ancs_state != ANCS_DISCOVERED )
{
vTaskDelay( xDelay );
}
AncsSubscribeNotifications();
if ( gResult == 0x0305 /* insufficient authentication */ ||
gResult == 0x030F /* insufficient Encryption */ )
{
appl_bond_with_peer();
while ( appl_ancs_state != ANCS_BONDED )
{
vTaskDelay( xDelay );
}
AncsSubscribeNotifications();
}
else
{
appl_ancs_state = ANCS_BONDED;
}
while ( appl_ancs_state != ANCS_DISCONNECTED )
{
if ( xQueueReceive( xNtfUIDQueue, &( NtfUID ), ( TickType_t ) 10 ) )
{
AncsGetNotificationAttribute(NtfUID);
}
}
if ( xNtfUIDQueue != 0 )
{
vQueueDelete( xNtfUIDQueue);
}
}
void AncsDumpBytes (UCHAR *buffer, UINT16 length)
{
char hex_stream[49];
char char_stream[17];
UINT32 i;
UINT16 offset, count;
UCHAR c;
APPL_TRC (
"-------------------------------------------------------------------\n");
count = 0;
offset = 0;
for ( i = 0; i < length; i++ )
{
c = buffer[i];
sprintf(hex_stream + offset, "%02X ", c);
if ( (c >= 0x20) && (c <= 0x7E) )
{
char_stream[count] = c;
}
else
{
char_stream[count] = '.';
}
count ++;
offset += 3;
if ( 16 == count )
{
char_stream[count] = '\0';
count = 0;
offset = 0;
APPL_TRC ("%s %s\n",
hex_stream, char_stream);
BT_mem_set(hex_stream, 0, 49);
BT_mem_set(char_stream, 0, 17);
}
}
if ( offset != 0 )
{
char_stream[count] = '\0';
/* Maintain the alignment */
APPL_TRC ("%-48s %s\n",
hex_stream, char_stream);
}
APPL_TRC (
"-------------------------------------------------------------------\n\n");
return;
}
void AncsGetNotificationAttribute(uint32_t notiUid)
{
API_RESULT retval;
ATT_VALUE att_value;
// An example to get notification attributes
uint16_t max_len = 256;
uint8_t buf[19]; // retrieve the complete attribute list
APPL_TRC("++<<GetNtfUID:%X>>\n", notiUid);
buf[0] = BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES; // put command
uint8_t *p = &buf[1];
BT_UNPACK_LE_4_BYTE(p, (uint8_t*)(&notiUid)); // encode notification uid
// encode attribute IDs
buf[5] = BLE_ANCS_NOTIF_ATTR_ID_APP_IDENTIFIER;
buf[6] = BLE_ANCS_NOTIF_ATTR_ID_TITLE;
// 2 byte length
buf[7] = max_len;
buf[8] = max_len >> 8;
buf[9] = BLE_ANCS_NOTIF_ATTR_ID_SUBTITLE;
buf[10] = max_len;
buf[11] = max_len >> 8;
buf[12] = BLE_ANCS_NOTIF_ATTR_ID_MESSAGE;
buf[13] = max_len;
buf[14] = max_len >> 8;
buf[15] = BLE_ANCS_NOTIF_ATTR_ID_MESSAGE_SIZE;
buf[16] = BLE_ANCS_NOTIF_ATTR_ID_DATE;
buf[17] = BLE_ANCS_NOTIF_ATTR_ID_POSITIVE_ACTION_LABEL;
buf[18] = BLE_ANCS_NOTIF_ATTR_ID_NEGATIVE_ACTION_LABEL;
att_value.len = 19;
att_value.val = buf;
retval = appl_write_req(ancs_char_info.ancs_control_point_hdl, &att_value);
//APPL_TRC ("retval 0x%04X\n", retval);
if ( retval == API_SUCCESS )
{
Wait4WrtRsp();
}
APPL_TRC("--<<GetNtfUID:%X>>\n", notiUid);
}
void AncsNotificationCb(UCHAR *event_data, UINT16 event_datalen)
{
ATT_ATTR_HANDLE attr_handle;
ancc_notif_t *NotificationSource;
BT_UNPACK_LE_2_BYTE(&attr_handle, event_data);
if ( attr_handle == ancs_char_info.ancs_notification_source_hdl )
{
NotificationSource = (ancc_notif_t *)(event_data + 2);
switch(NotificationSource->category_id)
{
case(BLE_ANCS_CATEGORY_ID_OTHER):
APPL_TRC("OTHER(%X)\n", NotificationSource->notification_uid);
break;
case(BLE_ANCS_CATEGORY_ID_INCOMING_CALL):
APPL_TRC("INCOMING_CALL(%X)\n", NotificationSource->notification_uid);
break;
case(BLE_ANCS_CATEGORY_ID_MISSED_CALL):
APPL_TRC("MISSED_CALL(%X)\n", NotificationSource->notification_uid);
break;
case(BLE_ANCS_CATEGORY_ID_VOICE_MAIL):
APPL_TRC("VOICE_MAIL(%X)\n", NotificationSource->notification_uid);
break;
case(BLE_ANCS_CATEGORY_ID_SOCIAL):
APPL_TRC("SOCIAL(%X)\n", NotificationSource->notification_uid);
break;
case(BLE_ANCS_CATEGORY_ID_SCHEDULE):
APPL_TRC("SCHEDULE(%X)\n", NotificationSource->notification_uid);
break;
case(BLE_ANCS_CATEGORY_ID_EMAIL):
APPL_TRC("EMAIL(%X)\n", NotificationSource->notification_uid);
break;
case(BLE_ANCS_CATEGORY_ID_NEWS):
APPL_TRC("NEWS(%X)\n", NotificationSource->notification_uid);
break;
case(BLE_ANCS_CATEGORY_ID_HEALTH_AND_FITNESS):
APPL_TRC("HEALTH_AND_FITNESS(%X)\n", NotificationSource->notification_uid);
break;
case(BLE_ANCS_CATEGORY_ID_BUSINESS_AND_FINANCE):
APPL_TRC("BUSINESS_AND_FINANCE(%X)\n", NotificationSource->notification_uid);
break;
case(BLE_ANCS_CATEGORY_ID_LOCATION):
APPL_TRC("LOCATION(%X)\n", NotificationSource->notification_uid);
break;
case(BLE_ANCS_CATEGORY_ID_ENTERTAINMENT):
APPL_TRC("ENTERTAINMENT(%X)\n", NotificationSource->notification_uid);
break;
default:
break;
}
//APPL_TRC("Spaces %d\n", uxQueueSpacesAvailable(xNtfUIDQueue));
xQueueSend( xNtfUIDQueue, ( void * ) &(NotificationSource->notification_uid), ( TickType_t ) 0 );
}
#if 0
else if ( attr_handle == ancs_char_info.ancs_data_source_hdl )
{
APPL_TRC("data source\n");
}
#endif
AncsDumpBytes(event_data + 2, (event_datalen-2));
}
#endif /* ANCS */

View File

@ -0,0 +1,122 @@
//*****************************************************************************
//
//! @file appl_ancs.h
//!
//! @brief Application Header File for ANCS.
//!
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/**
* \file appl_ancs.h
*
* Application Header File for ANCS.
*/
/*
* Copyright (C) 2013. Mindtree Ltd.
* All rights reserved.
*/
#ifndef _H_APPL_ANCS_
#define _H_APPL_ANCS_
/* ----------------------------------------- Header File Inclusion */
#include "BT_api.h"
#include "BT_gatt_db_api.h"
#include "gatt_db.h"
#include "appl.h"
#include "appl_ancs_att_server.h"
/* ----------------------------------------- Data Types/ Structures */
typedef struct
{
UCHAR index;
UCHAR length;
}APPL_HRS_OBS_DATA_INFO;
/* --------------------------------------------- Global Definitions */
/** LSB of error code has to be spec defined */
#define APPL_HR_CNTRL_PNT_NOT_SUPPORTED (APPL_ERR_ID | 0x80)
/* --------------------------------------------- Functions */
void appl_ancs_init(void);
void appl_manage_trasnfer (GATT_DB_HANDLE handle, UINT16 config);
void appl_timer_expiry_handler (void *data, UINT16 datalen);
void appl_ancs_connect(DEVICE_HANDLE * dq_handle);
void appl_send_ancs_measurement (APPL_HANDLE * handle);
void appl_ancs_server_reinitialize (void);
void appl_rcv_service_desc (UINT16 config, ATT_UUID uuid, UINT16 value_handle);
void appl_rcv_service_char (ATT_UUID uuid, UINT16 value_handle);
API_RESULT appl_hr_control_point_handler
(
GATT_DB_HANDLE * handle,
ATT_VALUE * value
);
API_RESULT appl_att_callback
(
ATT_HANDLE * handle,
UCHAR event_type,
API_RESULT event_result,
UCHAR * event_data,
UINT16 event_datalen
);
void ancs_mtu_update(APPL_HANDLE * appl_handle, UINT16 t_mtu);
/* Profile handling */
#define APPL_PROFILE_INIT(...) appl_ancs_init()
#define APPL_PROFILE_CONNECT(x) appl_ancs_connect(x)
#define APPL_SEND_MEASUREMENT(x)appl_send_ancs_measurement(x)
#define APPL_PROFILE_DISCONNECT_HANDLER(x) appl_ancs_server_reinitialize()
#define GATT_DB_PROFILE_HANDLER gatt_db_ancs_handler
#define APPL_PROFILE_HVN_NTF_COMPLETE_HANDLER(x, y, z)
#define APPL_PROFILE_HVN_IND_COMPLETE_HANDLER(x, y, z)
#define APPL_PROFILE_MTU_UPDT_COMPLETE_HANDLER(x, y) ancs_mtu_update(x, y)
#define APPL_USE_IDLE_TIMER
#define APPL_IDLE_TIMEOUT 30
#endif /* _H_APPL_ANCS_ */

View File

@ -0,0 +1,158 @@
//*****************************************************************************
//
//! @file appl_ancs_att_server.h
//!
//! @brief ATT Server Application Header File
//!
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/**
* \file appl_ancs_att_server.h
*
* ATT Server Application Header File
*/
/*
* Copyright (C) 2013. Mindtree Ltd.
* All rights reserved.
*/
#ifndef _H_APPL_ANCS_ATT_SERVER_
#define _H_APPL_ANCS_ATT_SERVER_
/* ----------------------------------------- Header File Inclusion */
#include "BT_api.h"
#include "BT_gatt_db_api.h"
#define APPL_ATT_WRITE_QUEUE_SIZE 10
#define APPL_ATT_MAX_WRITE_BUFFER_SIZE 256 /* 255 */
#define APPL_ATT_MTU ATT_MAX_MTU
#define APPL_SERVER_BUFFER_SIZE 256 /* 256 */
#define APPL_MAX_GROUP_TYPE_QUERIED 5
#define APPL_MAX_HNDL_UUID_LIST_SIZE 5
#define APPL_MAX_HNDL_LIST_SIZE 11
#define APPL_MAX_HNDL_VALUE_SIZE 5
/* ATT PDU Request Length */
#define APPL_ATT_XCNHG_MTU_REQ_LEN 2
#define APPL_ATT_XCNHG_MTU_RSP_LEN 2
#define APPL_ATT_FIND_INFO_REQ_LEN 4
#define APPL_ATT_FIND_INFO_RSP_LEN_1 5
#define APPL_ATT_FIND_INFO_RSP_LEN_2 22
#define ATT_FIND_BY_TYPE_VAL_RSP_LEN1 4
#define ATT_FIND_BY_TYPE_VAL_RSP_LEN2 21
#define APPL_ATT_READ_BY_TYPE_REQ_LEN_1 6
#define APPL_ATT_READ_BY_TYPE_REQ_LEN_2 20
#define ATT_READ_BY_TYPE_RSP_LEN_1 3
#define ATT_READ_BY_TYPE_RSP_LEN_2 22
#define APPL_ATT_READ_REQ_LEN 2
#define APPL_ATT_READ_RSP_LEN_1 0
#define APPL_ATT_READ_RSP_LEN_2 22
#define APPL_ATT_READ_BLOB_REQ_LEN 4
#define APPL_ATT_READ_BLOB_RSP_LEN_1 0
#define APPL_ATT_READ_BLOB_RSP_LEN_2 22
#define APPL_ATT_READ_BY_GROUP_REQ_LEN_1 6
#define APPL_ATT_READ_BY_GROUP_REQ_LEN_2 20
#define APPL_ATT_READ_BY_GROUP_RSP_LEN_1 5
#define APPL_ATT_READ_BY_GROUP_RSP_LEN_2 22
#define APPL_ATT_EXECUTE_WRITE_REQ_LEN 1
#define APPL_ATT_INVALID_LEN 0xFF
#define APPL_MAX_VALID_ATT_PDU_LEN_CHK 7
/** Application Defined error */
#define APPL_ATT_INVALID_OFFSET 0xFFFF
#define ATT_INVALID_ATTR_HANDLE_VAL 0x0000
#define APPL_MAX_MULTIPLE_READ_COUNT 11
#define APPL_CHECK_IF_ATT_REQUEST(type)\
((((((type) > 0x13) && ((type) < 0x16)) ||\
(((type) > 0x1E) && (((type) != ATT_SIGNED_WRITE_CMD) &&\
((type) != ATT_WRITE_CMD)))) || (0x01 == ((type) & 0x01)))? BT_FALSE : BT_TRUE)
#define APPL_ATT_PREPARE_QUEUE_INIT(i)\
appl_att_write_queue[(i)].handle_value.handle = 0;\
appl_att_write_queue[(i)].offset = 0xFFFF;\
appl_att_write_queue[(i)].handle_value.value.len = 0;\
appl_att_write_queue[(i)].handle_value.value.val = NULL;
API_RESULT appl_discover_service
(
/* IN */ ATT_UUID uuid,
/* IN */ UCHAR uuid_frmt
);
API_RESULT appl_write_req
(
/* IN */ ATT_ATTR_HANDLE handle,
/* IN */ ATT_VALUE * value
);
API_RESULT appl_read_req
(
/* IN */ ATT_ATTR_HANDLE handle
);
API_RESULT appl_att_server_init(void);
API_RESULT appl_handle_unsupported_op_code (ATT_HANDLE *handle, UCHAR op_code);
API_RESULT appl_validate_att_pdu_req_len
(
UCHAR att_event,
UINT16 event_datalen
);
#ifdef SMP_DATA_SIGNING
void appl_gatt_signing_complete (API_RESULT status, UCHAR * data, UINT16 datalen);
void appl_gatt_signing_verification_complete
(
API_RESULT status,
UCHAR * data,
UINT16 datalen
);
#endif /* SMP_DATA_SIGNING */
#endif /* _H_APPL_ANCS_ATT_SERVER_ */

View File

@ -0,0 +1,231 @@
//*****************************************************************************
//
//! @file appl_gap_config_params.c
//!
//! @brief This file contains GAP Configuration Parameters used by the application.
//!
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/**
* \file appl_gap_config_params.c
*
* This file contains GAP Configuration Parameters used by the application.
*/
/*
* Copyright (C) 2013. Mindtree Ltd.
* All rights reserved.
*/
/* --------------------------------------------- Header File Inclusion */
#include "appl_gap.h"
#ifdef ANCS
/* --------------------------------------------- External Global Variables */
/* --------------------------------------------- Exported Global Variables */
/* --------------------------------------------- Static Global Variables */
#if ((defined APPL_GAP_BROADCASTER_SUPPORT) || (defined APPL_GAP_PERIPHERAL_SUPPORT))
/** Advertisement Data Options */
const APPL_GAP_ADV_DATA appl_gap_adv_data[APPL_GAP_MAX_ADV_DATA_OPTIONS] =
{
/* GAP Advertisement Parameters */
{
{
/**
* Flags:
* 0x01: LE Limited Discoverable Mode
* 0x02: LE General Discoverable Mode
* 0x04: BR/EDR Not Supported
* 0x08: Simultaneous LE and BR/EDR to Same Device
* Capable (Controller)
* 0x10: Simultaneous LE and BR/EDR to Same Device
* Capable (Host)
*/
0x02, 0x01,
(BT_AD_FLAGS_LE_GENERAL_DISC_MODE | BT_AD_FLAGS_LE_BR_EDR_SUPPORT),
/**
* Service UUID List:
* Battery Service (0x180F)
* DeviceInformation Service (0x180A)
*/
0x05, 0x03, 0x0F, 0x18, 0x0A, 0x18,
/**
* Shortened Device Name: AM
*/
0x03, 0x08, 0x41, 0x4d,
/**
* List of 16-bit Service Solicitation UUIDs(ANCS UUID)
*/
0x11, 0x15, 0xD0, 0x00, 0x2D, 0x12, 0x1E, 0x4B, 0x0F, 0xA4, 0x99, 0x4E, 0xCE, 0xB5, 0x31, 0xF4, 0x05, 0x79
},
31
}
};
/* Advertisement parameters options */
const APPL_GAP_ADV_PARAM appl_gap_adv_param[APPL_GAP_MAX_ADV_PARAM_OPTIONS] =
{
/* 0 - Normal Advertising Params */
{
32,
32,
7,
0
},
/* 1 - Fast Connection Advertising Params */
{
32,
48,
7,
0
},
/* 2 - Low Power Advertising Params */
{
1600,
4000,
7,
0
}
};
/* Advertisement Table */
APPL_GAP_ADV_INFO appl_gap_adv_table =
{
appl_gap_adv_data,
appl_gap_adv_param,
APPL_GAP_ADV_IDLE
};
#endif /* APPL_GAP_BROADCASTER || APPL_GAP_PERIPHERAL_SUPPORT */
#if ((defined APPL_GAP_OBSERVER_SUPPORT) || (defined APPL_GAP_CENTRAL_SUPPORT))
/* Scan Parameters Option */
const APPL_GAP_SCAN_PARAM appl_gap_scan_param[APPL_GAP_MAX_SCAN_PARAM_OPTIONS] =
{
/* Normal Scan Params */
{
32,
7,
0
},
/* Fast Connection Scan Params */
{
48,
7,
0
},
/* Low Power Scan Params */
{
4000,
7,
0
}
};
/* Scan Table */
APPL_GAP_SCAN_INFO appl_gap_scan_table =
{
appl_gap_scan_param,
APPL_GAP_SCAN_IDLE
};
#endif /* APPL_GAP_OBSERVER_SUPPORT || APPL_GAP_CENTRAL_SUPPORT */
#ifdef APPL_GAP_CENTRAL_SUPPORT
/* Connection Parameters Options */
const APPL_GAP_CONN_PARAM appl_gap_conn_param[APPL_GAP_MAX_CONN_PARAM_OPTIONS] =
{
{
4,
4,
0,
40,
56,
0,
955,
32,
32
}
};
/* GAP Connection Table */
APPL_GAP_CONN_INFO appl_gap_conn_table =
{
appl_gap_conn_param,
APPL_GAP_CONN_IDLE
};
#endif /* APPL_GAP_CENTRAL_SUPPORT */
#endif /* ANCS */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,157 @@
//*****************************************************************************
//
//! @file gatt_db.h
//!
//! @brief GATT Databse.
//!
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/**
* \file gatt_db.h
*/
/*
* Copyright (C) 2013. Mindtree Ltd.
* All rights reserved.
*/
#ifndef _H_GATT_DB_
#define _H_GATT_DB_
/**
* addgroup gatt_db_module
*/
/**
* defgroup gatt_db_tuneable_param Tuneable Parameters
* {
* This section defines the Tuneable Constants of Data Base Module.
*/
/** Number of Characteristics in the data base */
#define GATT_CHARACTERISTIC_COUNT 13
/** Number of Services in the data base */
#define GATT_SERVICE_COUNT 4
/** Number of Characteristics that are configurable by the client */
#define GATT_DB_MAX_CONFIGUREABLE_CHAR 3
/** Maximum Length of any Characteristic Value/Descriptor */
#define GATT_DB_MAX_VAL_LENGTH 32
#define GATT_VALUE_ARRAY_SIZE 1
#define GATT_CONST_VALUE_ARRAY_SIZE 182
#define GATT_DB_PEER_VALUE_ARRAY_SIZE 4
#define GATT_DB_MAX_ATTRIBUTES 34
#define GATT_UUID_ARRAY_SIZE 54
#define GATT_DB_MAX_TYPE_COUNT 21
#define GATT_DB_MAX_PEER_CONFIGURATION \
(GATT_DB_PEER_VALUE_ARRAY_SIZE * BT_MAX_DEVICE_QUEUE_SIZE)
/** \} */
/** Service Instance Reference */
/** GAP Service */
#define GATT_SER_GAP_INST 0
/** GATT Service */
#define GATT_SER_GATT_INST 1
/** Battery Service */
#define GATT_SER_BATTERY_INST 2
/** DeviceInformation Service */
#define GATT_SER_DEV_INFO_INST 3
/** Characteristic Instance Reference */
/** DeviceName */
#define GATT_CHAR_DEV_NAME_INST 0
/** Appearance */
#define GATT_CHAR_APPEARANCE_INST 1
/** Service Changed */
#define GATT_CHAR_SER_CHNGD_INST 2
/** BatteryLevel */
#define GATT_CHAR_BATTERY_LVL_INST 3
/** ManufacturerName */
#define GATT_CHAR_MAN_NAME_INST 4
/** ModelNumber */
#define GATT_CHAR_MODEL_NO_INST 5
/** SerialNumber */
#define GATT_CHAR_SL_NO_INST 6
/** FirmwareRevision */
#define GATT_CHAR_FW_REV_INST 7
/** HardwareRevision */
#define GATT_CHAR_HW_REV_INST 8
/** SoftwareRevision */
#define GATT_CHAR_SW_REV_INST 9
/** SystemId */
#define GATT_CHAR_SYS_ID_INST 10
/** RegCertDataList */
#define GATT_CHAR_REG_CERT_DATA_INST 11
/** PnPID */
#define GATT_CHAR_PNP_ID_INST 12
#endif /* _H_GATT_DB_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,234 @@
//*****************************************************************************
//
//! @file appl_gap_config_params.c
//!
//! @brief This file contains GAP Configuration Parameters used by the application.
//!
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/**
* \file appl_gap_config_params.c
*
* This file contains GAP Configuration Parameters used by the application.
*/
/*
* Copyright (C) 2013. Mindtree Ltd.
* All rights reserved.
*/
/* --------------------------------------------- Header File Inclusion */
#include "appl_gap.h"
/* --------------------------------------------- External Global Variables */
/* --------------------------------------------- Exported Global Variables */
/* --------------------------------------------- Static Global Variables */
#if ((defined APPL_GAP_BROADCASTER_SUPPORT) || (defined APPL_GAP_PERIPHERAL_SUPPORT))
/** Advertisement Data Options */
const APPL_GAP_ADV_DATA appl_gap_adv_data[APPL_GAP_MAX_ADV_DATA_OPTIONS] =
{
/* GAP Advertisement Parameters */
{
{
/**
* Flags:
* 0x01: LE Limited Discoverable Mode
* 0x02: LE General Discoverable Mode
* 0x04: BR/EDR Not Supported
* 0x08: Simultaneous LE and BR/EDR to Same Device
* Capable (Controller)
* 0x10: Simultaneous LE and BR/EDR to Same Device
* Capable (Host)
*/
0x02, 0x01,
(BT_AD_FLAGS_LE_GENERAL_DISC_MODE | BT_AD_FLAGS_LE_BR_EDR_SUPPORT),
/*! Manufacturer specific data AD type */
0x1A, /*! length */
HCI_AD_TYPE_MANUFACTURER_SPECIFIC_DATA, /*! AD type */
0x4C, /*! Company ID[0] */
0x00, /*! Company ID[1] */
0x02, /*! Device type, this has to be 0x02*/
0x15, /*! Length of vendor advertising data. */
/*! Proximity UUID 16 bytes */
0xe2, 0xc5, 0x6d, 0xb5,
0xdf, 0xfb, 0x48, 0xd2,
0xb0, 0x60, 0xd0, 0xf5,
0xa7, 0x10, 0x96, 0xe0,
/*! Major 0xnnnn */
0x00, 0x00,
/*! Minor 0xnnnn */
0x00, 0x00,
/*! Measured Power */
0xc5
},
30
}
};
/* Advertisement parameters options */
const APPL_GAP_ADV_PARAM appl_gap_adv_param[APPL_GAP_MAX_ADV_PARAM_OPTIONS] =
{
/* 0 - Normal Advertising Params */
{
32,
32,
7,
0
},
/* 1 - Fast Connection Advertising Params */
{
32,
48,
7,
0
},
/* 2 - Low Power Advertising Params */
{
1600,
4000,
7,
0
}
};
/* Advertisement Table */
APPL_GAP_ADV_INFO appl_gap_adv_table =
{
appl_gap_adv_data,
appl_gap_adv_param,
APPL_GAP_ADV_IDLE
};
#endif /* APPL_GAP_BROADCASTER || APPL_GAP_PERIPHERAL_SUPPORT */
#if ((defined APPL_GAP_OBSERVER_SUPPORT) || (defined APPL_GAP_CENTRAL_SUPPORT))
/* Scan Parameters Option */
const APPL_GAP_SCAN_PARAM appl_gap_scan_param[APPL_GAP_MAX_SCAN_PARAM_OPTIONS] =
{
/* Normal Scan Params */
{
32,
7,
0
},
/* Fast Connection Scan Params */
{
48,
7,
0
},
/* Low Power Scan Params */
{
4000,
7,
0
}
};
/* Scan Table */
APPL_GAP_SCAN_INFO appl_gap_scan_table =
{
appl_gap_scan_param,
APPL_GAP_SCAN_IDLE
};
#endif /* APPL_GAP_OBSERVER_SUPPORT || APPL_GAP_CENTRAL_SUPPORT */
#ifdef APPL_GAP_CENTRAL_SUPPORT
/* Connection Parameters Options */
const APPL_GAP_CONN_PARAM appl_gap_conn_param[APPL_GAP_MAX_CONN_PARAM_OPTIONS] =
{
{
4,
4,
0,
40,
56,
0,
955,
32,
32
}
};
/* GAP Connection Table */
APPL_GAP_CONN_INFO appl_gap_conn_table =
{
appl_gap_conn_param,
APPL_GAP_CONN_IDLE
};
#endif /* APPL_GAP_CENTRAL_SUPPORT */

View File

@ -0,0 +1,25 @@
/**
* \file appl_ibeacon.c
*
* This file contains ibeacon example
*
* Copyright (C) 2013. Mindtree Ltd.
* All rights reserved.
*/
/* --------------------------------------------- Header File Inclusion */
#include "appl.h"
/* --------------------------------------------- Constants */
/* --------------------------------------------- Static Global Variables */
/* --------------------------------------------- Functions */
void appl_ibeacon_init(void)
{
}

View File

@ -0,0 +1,87 @@
//*****************************************************************************
//
//! @file appl_ibeacon.h
//!
//! @brief Application Header File for iBeacon example.
//!
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// 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 of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// 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 HOLDER 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.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
/**
* \file appl_ibeacon.h
*
* Application Header File for iBeacon example.
*/
/*
* Copyright (C) 2013. Mindtree Ltd.
* All rights reserved.
*/
#ifndef _H_APPL_HRS_
#define _H_APPL_HRS_
/* ----------------------------------------- Header File Inclusion */
#include "BT_api.h"
#include "BT_gatt_db_api.h"
#include "gatt_db.h"
#include "appl.h"
/* ----------------------------------------- Data Types/ Structures */
/* --------------------------------------------- Functions */
void appl_ibeacon_init(void);
/* Profile handling */
#define APPL_PROFILE_INIT(...) appl_ibeacon_init()
#define APPL_PROFILE_CONNECT(x)
#define APPL_SEND_MEASUREMENT(x)
#define APPL_PROFILE_DISCONNECT_HANDLER(x)
#define GATT_DB_PROFILE_HANDLER
#define APPL_PROFILE_HVN_NTF_COMPLETE_HANDLER(x, y, z)
#define APPL_PROFILE_HVN_IND_COMPLETE_HANDLER(x, y, z)
#define APPL_PROFILE_MTU_UPDT_COMPLETE_HANDLER(x, y)
#define APPL_USE_IDLE_TIMER
#define APPL_IDLE_TIMEOUT 30
#endif /* _H_APPL_HRS_ */

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More