Initial project setup
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
# BridgeTek FT9xx MCU
|
||||
|
||||
**BridgeTek** provides a hardware abstraction library with software source code for the SDKs for FT9xx software family.
|
||||
|
||||
Whole SDK repository is installed as part of the FT9xx Toolchain and can be downloaded from BridgeTek web page `https://www.brtchip.com`.
|
||||
|
||||
Registers definition files, and included peripheral register definition files have licenses that allow for redistribution.
|
||||
@@ -0,0 +1,286 @@
|
||||
.equ SYS_REGMSC0CFG_B3 , 0x1001b
|
||||
.equ SYS_REGIRQCTL_B3 , 0x100e3
|
||||
.equ MAILBOX_MEMORY , 0x13000
|
||||
|
||||
.equ IS_IMG_SDBL_PRESENT, 0
|
||||
.equ IS_IMG_D2XX_PRESENT, 0
|
||||
.equ IS_IMG_DLOG_PRESENT, 0
|
||||
|
||||
.section .crt0
|
||||
.global _start
|
||||
|
||||
_start:
|
||||
# START Interrupt Vector Table [[
|
||||
jmp __PMSIZE-4 # RESET Vector
|
||||
jmp interrupt_33 # Watchdog reset vector
|
||||
jmp interrupt_0
|
||||
jmp interrupt_1
|
||||
jmp interrupt_2
|
||||
jmp interrupt_3
|
||||
jmp interrupt_4
|
||||
jmp interrupt_5
|
||||
jmp interrupt_6
|
||||
jmp interrupt_7
|
||||
jmp interrupt_8
|
||||
jmp interrupt_9
|
||||
jmp interrupt_10
|
||||
jmp interrupt_11
|
||||
jmp interrupt_12
|
||||
jmp interrupt_13
|
||||
jmp interrupt_14
|
||||
jmp interrupt_15
|
||||
jmp interrupt_16
|
||||
jmp interrupt_17
|
||||
jmp interrupt_18
|
||||
jmp interrupt_19
|
||||
jmp interrupt_20
|
||||
jmp interrupt_21
|
||||
jmp interrupt_22
|
||||
jmp interrupt_23
|
||||
jmp interrupt_24
|
||||
jmp interrupt_25
|
||||
jmp interrupt_26
|
||||
jmp interrupt_27
|
||||
jmp interrupt_28
|
||||
jmp interrupt_29
|
||||
jmp interrupt_30
|
||||
jmp interrupt_31
|
||||
jmp __PMSIZE-8 #Interrupt vector 32 (NMI)
|
||||
# ]] END Interrupt Vector Table
|
||||
|
||||
codestart:
|
||||
jmp init
|
||||
|
||||
.global _exithook
|
||||
_exithook: # Debugger uses '_exithook' at 0x90 to catch program exit
|
||||
return
|
||||
|
||||
init:
|
||||
# Disable all interrupts
|
||||
ldk $r0,0x80
|
||||
.ifdef __FT930__
|
||||
sta.b 0x10123, $r0
|
||||
.else
|
||||
sta.b 0x100e3,$r0
|
||||
.endif
|
||||
|
||||
# Reset all peripherals
|
||||
# lda.l $r0, 0x10018
|
||||
# bins.l $r0, $r0, 0x23F # Set bit 31
|
||||
# sta.l 0x10018, $r0
|
||||
|
||||
# Initialize DATA by copying from program memory
|
||||
ldk.l $r0,__data_load_start
|
||||
ldk.l $r1,__data_load_end
|
||||
ldk.l $r2,0 # Will use __data after binutils patch
|
||||
|
||||
jmp .dscopy
|
||||
.dsloop:
|
||||
# Copy PM[$r0] to RAM $r2
|
||||
lpmi.l $r3,$r0,0
|
||||
sti.l $r2,0,$r3
|
||||
add.l $r0,$r0,4
|
||||
add.l $r2,$r2,4
|
||||
.dscopy:
|
||||
cmp.l $r0,$r1
|
||||
jmpc lt,.dsloop
|
||||
|
||||
# Zero BSS
|
||||
ldk.l $r0,_bss_start
|
||||
ldk.l $r2,_end
|
||||
sub.l $r2,$r2,$r0
|
||||
ldk.l $r1,0
|
||||
ldk $r3,32764
|
||||
1:
|
||||
cmp $r2,$r3
|
||||
jmpc lt,2f
|
||||
memset $r0,$r1,$r3
|
||||
add $r0,$r0,$r3
|
||||
sub $r2,$r2,$r3
|
||||
jmp 1b
|
||||
2:
|
||||
memset $r0,$r1,$r2
|
||||
.ifdef __FT930__
|
||||
/*##############################################################*/
|
||||
# copy UserConfig DATA from flash to mailbox memory
|
||||
/*##############################################################*/
|
||||
ldk.l $r0,D2XX_Struct_start /*start of d2xx config in PM memory */
|
||||
ldk.l $r1,D2XX_Struct_end /*end of d2xx config in PM memory */
|
||||
ldk.l $r2,D2XXTEST_UserD2xxConfig /* RAM cache where the d2xx config from PM to be copied*/
|
||||
jmp .configcopy
|
||||
|
||||
.configloop:
|
||||
# Copy PM[$r0] to RAM[$r2]
|
||||
lpmi.l $r3,$r0,0
|
||||
sti.l $r2,0,$r3
|
||||
# Increment
|
||||
add.l $r0,$r0,4
|
||||
add.l $r2,$r2,4
|
||||
.configcopy:
|
||||
cmp.l $r0,$r1
|
||||
jmpc lt,.configloop
|
||||
|
||||
ldk.l $r1,D2XX_Struct_start
|
||||
ldk.l $r2,D2XX_Struct_end
|
||||
#compute size
|
||||
sub.l $r2,$r2,$r1
|
||||
ldk.l $r1,D2XXTEST_UserD2xxConfig
|
||||
ldk.l $r0,MAILBOX_MEMORY /* D2xx config from RAM cache to be copied to Mailbox memory */
|
||||
# Copy RAM[$r1] to Mailbox $r0, for $r2 bytes
|
||||
streamouti.b $r0,$r1,$r2
|
||||
/*############################################################*/
|
||||
.endif
|
||||
sub.l $sp,$sp,24 # Space for the caller argument frame
|
||||
call main
|
||||
|
||||
.equ EXITEXIT , 0x1fffc
|
||||
|
||||
.global _exit
|
||||
_exit:
|
||||
sta.l EXITEXIT,$r0 # simulator end of test
|
||||
jmp _exithook
|
||||
|
||||
#_watchdog_isr:
|
||||
# ldk $sp,__RAMSIZE
|
||||
# jmp __PMSIZE-4
|
||||
|
||||
# Macro to construct the interrupt stub code.
|
||||
# it just saves r0, loads r0 with the int vector
|
||||
# and branches to interrupt_common.
|
||||
|
||||
.macro inth i=0
|
||||
interrupt_\i:
|
||||
push $r0 # {
|
||||
lda $r0,(vector_table + 4 * \i)
|
||||
jmp interrupt_common
|
||||
.endm
|
||||
|
||||
inth 0
|
||||
inth 1
|
||||
inth 2
|
||||
inth 3
|
||||
inth 4
|
||||
inth 5
|
||||
inth 6
|
||||
inth 7
|
||||
inth 8
|
||||
inth 9
|
||||
inth 10
|
||||
inth 11
|
||||
inth 12
|
||||
inth 13
|
||||
inth 14
|
||||
inth 15
|
||||
inth 16
|
||||
inth 17
|
||||
inth 18
|
||||
inth 19
|
||||
inth 20
|
||||
inth 21
|
||||
inth 22
|
||||
inth 23
|
||||
inth 24
|
||||
inth 25
|
||||
inth 26
|
||||
inth 27
|
||||
inth 28
|
||||
inth 29
|
||||
inth 30
|
||||
inth 31
|
||||
inth 32
|
||||
inth 33
|
||||
|
||||
# On entry: r0, already saved, holds the handler function
|
||||
interrupt_common:
|
||||
push $r1 # {
|
||||
push $r2 # {
|
||||
push $r3 # {
|
||||
push $r4 # {
|
||||
push $r5 # {
|
||||
push $r6 # {
|
||||
push $r7 # {
|
||||
push $r8 # {
|
||||
push $r9 # {
|
||||
push $r10 # {
|
||||
push $r11 # {
|
||||
push $r12 # {
|
||||
push $cc # {
|
||||
|
||||
calli $r0
|
||||
|
||||
pop $cc # }
|
||||
pop $r12 # }
|
||||
pop $r11 # }
|
||||
pop $r10 # }
|
||||
pop $r9 # }
|
||||
pop $r8 # }
|
||||
pop $r7 # }
|
||||
pop $r6 # }
|
||||
pop $r5 # }
|
||||
pop $r4 # }
|
||||
pop $r3 # }
|
||||
pop $r2 # }
|
||||
pop $r1 # }
|
||||
pop $r0 # } matching push in interrupt_0-31 above
|
||||
reti
|
||||
|
||||
# Null function for unassigned interrupt to point at
|
||||
.global nullvector
|
||||
nullvector:
|
||||
return
|
||||
|
||||
.section .data
|
||||
.global vector_table
|
||||
.align (4) # assembler alignment is in the power of 2 (in this case 2^4)
|
||||
vector_table:
|
||||
.rept 34
|
||||
.long nullvector
|
||||
.endr
|
||||
|
||||
|
||||
.section .text
|
||||
.global __gxx_personality_sj0
|
||||
__gxx_personality_sj0:
|
||||
|
||||
|
||||
.section ._flash_d2xx_config
|
||||
.global __pD2XXDefaultConfiguration
|
||||
.align (10)
|
||||
|
||||
D2XX_partition_start = .
|
||||
|
||||
.if IS_IMG_D2XX_PRESENT
|
||||
.ifdef __FT930__
|
||||
.include "ft930_d2xx_default_config.inc"
|
||||
.else
|
||||
.include "ft900_d2xx_default_config.inc"
|
||||
.endif
|
||||
.endif
|
||||
|
||||
D2XX_partition_end = .
|
||||
|
||||
.section ._flash_dlog_partition
|
||||
.align (10)
|
||||
.global __dlog_partition
|
||||
__dlog_partition:
|
||||
dlog_partition_start = .
|
||||
.if IS_IMG_DLOG_PRESENT
|
||||
.long 0xF7D1D106
|
||||
.rept (0x1000-4)
|
||||
.byte 0xFF
|
||||
.endr
|
||||
.endif
|
||||
dlog_partition_end = .
|
||||
|
||||
.section ._pm
|
||||
.global __sdbl_partition_sizeof
|
||||
.global __D2XX_partition_sizeof
|
||||
.global __dlog_partition_sizeof
|
||||
.if IS_IMG_SDBL_PRESENT
|
||||
__sdbl_partition_sizeof = 0x2000
|
||||
.else
|
||||
__sdbl_partition_sizeof = 0
|
||||
.endif
|
||||
|
||||
__D2XX_partition_sizeof = D2XX_partition_end - D2XX_partition_start
|
||||
__dlog_partition_sizeof = dlog_partition_end - dlog_partition_start
|
||||
@@ -0,0 +1,95 @@
|
||||
/* Default linker script, for normal executables */
|
||||
OUTPUT_FORMAT("elf32-ft32")
|
||||
OUTPUT_ARCH(ft32)
|
||||
SEARCH_DIR("/data/win8/ft32/ft32-elf/lib");
|
||||
/* Allow the command line to override the memory region sizes. */
|
||||
__PMSIZE = DEFINED(__PMSIZE) ? __PMSIZE : 256K;
|
||||
__RAMSIZE = DEFINED(__RAMSIZE) ? __RAMSIZE : 64K;
|
||||
MEMORY
|
||||
{
|
||||
flash (rx) : ORIGIN = 0, LENGTH = __PMSIZE
|
||||
ram (rw!x) : ORIGIN = 0x800000, LENGTH = __RAMSIZE
|
||||
ehci_mmap (rw!x) : ORIGIN = 0x811000, LENGTH = 2K
|
||||
}
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
*(.text*)
|
||||
*(.strings)
|
||||
*(._pm*)
|
||||
*(.init)
|
||||
*(.fini)
|
||||
_etext = . ;
|
||||
. = ALIGN(4);
|
||||
} > flash
|
||||
.tors :
|
||||
{
|
||||
___ctors = . ;
|
||||
*(.ctors)
|
||||
___ctors_end = . ;
|
||||
___dtors = . ;
|
||||
*(.dtors)
|
||||
___dtors_end = . ;
|
||||
. = ALIGN(4);
|
||||
} > ram
|
||||
.data : AT (ADDR (.text) + SIZEOF (.text))
|
||||
{
|
||||
*(.data)
|
||||
*(.data*)
|
||||
*(.rodata)
|
||||
*(.rodata*)
|
||||
_edata = . ;
|
||||
. = ALIGN(4);
|
||||
} > ram
|
||||
.bss SIZEOF(.data) + ADDR(.data) :
|
||||
{
|
||||
_bss_start = . ;
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
_end = . ;
|
||||
. = ALIGN(4);
|
||||
} > ram
|
||||
__data_load_start = LOADADDR(.data);
|
||||
__data_load_end = __data_load_start + SIZEOF(.data);
|
||||
.stab 0 (NOLOAD) :
|
||||
{
|
||||
*(.stab)
|
||||
}
|
||||
.stabstr 0 (NOLOAD) :
|
||||
{
|
||||
*(.stabstr)
|
||||
}
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* DWARF 3 */
|
||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
/* DWARF Extension. */
|
||||
.debug_macro 0 : { *(.debug_macro) }
|
||||
.debug_addr 0 : { *(.debug_addr) }
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# Dialog DA1469x MCU
|
||||
|
||||
**Dialog Semiconductors** provides SDKs for DA146x MCU family.
|
||||
Most of the files there can't be redistributed.
|
||||
Registers definition file `DA1469xAB.h` and some **ARM** originated headers are have licenses that allow
|
||||
for redistribution.
|
||||
Whole SDK repository can be downloaded from Dialog Semiconductor web page `https://www.dialog.com`
|
||||
@@ -0,0 +1,26 @@
|
||||
/* Copyright (c) 2009 - 2013 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- 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.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND 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
@@ -0,0 +1,270 @@
|
||||
/**************************************************************************//**
|
||||
* @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
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
|
||||
#else
|
||||
#error Unknown compiler.
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __CMSIS_COMPILER_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,39 @@
|
||||
/**************************************************************************//**
|
||||
* @file cmsis_version.h
|
||||
* @brief CMSIS Core(M) Version definitions
|
||||
* @version V5.0.2
|
||||
* @date 19. April 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 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 ( 1U) /*!< [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
|
||||
@@ -0,0 +1,950 @@
|
||||
/**************************************************************************//**
|
||||
* @file core_cm0.h
|
||||
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
|
||||
* @version V5.0.6
|
||||
* @date 13. March 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.
|
||||
*/
|
||||
/* Copyright (c) 2019 Modified by Dialog Semiconductor */
|
||||
|
||||
#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 __CORE_CM0_H_GENERIC
|
||||
#define __CORE_CM0_H_GENERIC
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
\page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
|
||||
CMSIS violates the following MISRA-C:2004 rules:
|
||||
|
||||
\li Required Rule 8.5, object/function definition in header file.<br>
|
||||
Function definitions in header files are used to allow 'inlining'.
|
||||
|
||||
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
|
||||
Unions are used for effective representation of core registers.
|
||||
|
||||
\li Advisory Rule 19.7, Function-like macro defined.<br>
|
||||
Function-like macros are used to allow more efficient code.
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* CMSIS definitions
|
||||
******************************************************************************/
|
||||
/**
|
||||
\ingroup Cortex_M0
|
||||
@{
|
||||
*/
|
||||
|
||||
#include "cmsis_version.h"
|
||||
|
||||
/* CMSIS CM0 definitions */
|
||||
#define __CM0_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
|
||||
#define __CM0_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
|
||||
#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__CM0_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_M (0U) /*!< Cortex-M Core */
|
||||
|
||||
/** __FPU_USED indicates whether an FPU is used or not.
|
||||
This core does not support an FPU at all
|
||||
*/
|
||||
#define __FPU_USED 0U
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
#if defined __TARGET_FPU_VFP
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
#if defined __ARM_FP
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
#if defined __ARMVFP__
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __TI_ARM__ )
|
||||
#if defined __TI_VFP_SUPPORT__
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __TASKING__ )
|
||||
#if defined __FPU_VFP__
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __CSMC__ )
|
||||
#if ( __CSMC__ & 0x400U)
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include "cmsis_compiler.h" /* CMSIS compiler specific defines */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CORE_CM0_H_GENERIC */
|
||||
|
||||
#ifndef __CMSIS_GENERIC
|
||||
|
||||
#ifndef __CORE_CM0_H_DEPENDANT
|
||||
#define __CORE_CM0_H_DEPENDANT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* check device defines and use defaults */
|
||||
#if defined __CHECK_DEVICE_DEFINES
|
||||
#ifndef __CM0_REV
|
||||
#define __CM0_REV 0x0000U
|
||||
#warning "__CM0_REV not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __NVIC_PRIO_BITS
|
||||
#define __NVIC_PRIO_BITS 2U
|
||||
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __Vendor_SysTickConfig
|
||||
#define __Vendor_SysTickConfig 0U
|
||||
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* IO definitions (access restrictions to peripheral registers) */
|
||||
/**
|
||||
\defgroup CMSIS_glob_defs CMSIS Global Defines
|
||||
|
||||
<strong>IO Type Qualifiers</strong> are used
|
||||
\li to specify the access to peripheral variables.
|
||||
\li for automatic generation of peripheral register debug information.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
#define __I volatile /*!< Defines 'read only' permissions */
|
||||
#else
|
||||
#define __I volatile const /*!< Defines 'read only' permissions */
|
||||
#endif
|
||||
#define __O volatile /*!< Defines 'write only' permissions */
|
||||
#define __IO volatile /*!< Defines 'read / write' permissions */
|
||||
|
||||
/* following defines should be used for structure members */
|
||||
#define __IM volatile const /*! Defines 'read only' structure member permissions */
|
||||
#define __OM volatile /*! Defines 'write only' structure member permissions */
|
||||
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
|
||||
|
||||
/*@} end of group Cortex_M0 */
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Register Abstraction
|
||||
Core Register contain:
|
||||
- Core Register
|
||||
- Core NVIC Register
|
||||
- Core SCB Register
|
||||
- Core SysTick Register
|
||||
******************************************************************************/
|
||||
/**
|
||||
\defgroup CMSIS_core_register Defines and Type Definitions
|
||||
\brief Type definitions and defines for Cortex-M processor based devices.
|
||||
*/
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_CORE Status and Control Registers
|
||||
\brief Core Register type definitions.
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Union type to access the Application Program Status Register (APSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
|
||||
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} APSR_Type;
|
||||
|
||||
/* APSR Register Definitions */
|
||||
#define APSR_N_Pos 31U /*!< APSR: N Position */
|
||||
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
|
||||
|
||||
#define APSR_Z_Pos 30U /*!< APSR: Z Position */
|
||||
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
|
||||
|
||||
#define APSR_C_Pos 29U /*!< APSR: C Position */
|
||||
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
|
||||
|
||||
#define APSR_V_Pos 28U /*!< APSR: V Position */
|
||||
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
|
||||
|
||||
|
||||
/**
|
||||
\brief Union type to access the Interrupt Program Status Register (IPSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} IPSR_Type;
|
||||
|
||||
/* IPSR Register Definitions */
|
||||
#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
|
||||
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
|
||||
|
||||
|
||||
/**
|
||||
\brief Union type to access the Special-Purpose Program Status Registers (xPSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
|
||||
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
|
||||
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
|
||||
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} xPSR_Type;
|
||||
|
||||
/* xPSR Register Definitions */
|
||||
#define xPSR_N_Pos 31U /*!< xPSR: N Position */
|
||||
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
|
||||
|
||||
#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
|
||||
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
|
||||
|
||||
#define xPSR_C_Pos 29U /*!< xPSR: C Position */
|
||||
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
|
||||
|
||||
#define xPSR_V_Pos 28U /*!< xPSR: V Position */
|
||||
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
|
||||
|
||||
#define xPSR_T_Pos 24U /*!< xPSR: T Position */
|
||||
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
|
||||
|
||||
#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
|
||||
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
|
||||
|
||||
|
||||
/**
|
||||
\brief Union type to access the Control Registers (CONTROL).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t _reserved0:1; /*!< bit: 0 Reserved */
|
||||
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
|
||||
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} CONTROL_Type;
|
||||
|
||||
/* CONTROL Register Definitions */
|
||||
#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
|
||||
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
|
||||
|
||||
/*@} end of group CMSIS_CORE */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
|
||||
\brief Type definitions for the NVIC Registers
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
|
||||
uint32_t RESERVED0[31U];
|
||||
__IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
|
||||
uint32_t RESERVED1[31U];
|
||||
__IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
|
||||
uint32_t RESERVED2[31U];
|
||||
__IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
|
||||
uint32_t RESERVED3[31U];
|
||||
uint32_t RESERVED4[64U];
|
||||
__IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
|
||||
} NVIC_Type;
|
||||
|
||||
/*@} end of group CMSIS_NVIC */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_SCB System Control Block (SCB)
|
||||
\brief Type definitions for the System Control Block Registers
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Structure type to access the System Control Block (SCB).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
|
||||
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
|
||||
uint32_t RESERVED0;
|
||||
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
|
||||
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
|
||||
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
|
||||
uint32_t RESERVED1;
|
||||
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
|
||||
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
|
||||
} SCB_Type;
|
||||
|
||||
/* SCB CPUID Register Definitions */
|
||||
#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
|
||||
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
|
||||
|
||||
#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
|
||||
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
|
||||
|
||||
#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
|
||||
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
|
||||
|
||||
#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
|
||||
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
|
||||
|
||||
#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
|
||||
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
|
||||
|
||||
/* SCB Interrupt Control State Register Definitions */
|
||||
#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
|
||||
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
|
||||
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
|
||||
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
|
||||
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
|
||||
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
|
||||
|
||||
#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
|
||||
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
|
||||
|
||||
#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
|
||||
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
|
||||
|
||||
#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
|
||||
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
|
||||
|
||||
#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
|
||||
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
|
||||
|
||||
/* SCB Application Interrupt and Reset Control Register Definitions */
|
||||
#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
|
||||
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
|
||||
|
||||
#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
|
||||
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
|
||||
|
||||
#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
|
||||
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
|
||||
|
||||
#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
|
||||
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
|
||||
|
||||
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
|
||||
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
|
||||
|
||||
/* SCB System Control Register Definitions */
|
||||
#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
|
||||
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
|
||||
|
||||
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
|
||||
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
|
||||
|
||||
#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
|
||||
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
|
||||
|
||||
/* SCB Configuration Control Register Definitions */
|
||||
#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
|
||||
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
|
||||
|
||||
#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
|
||||
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
|
||||
|
||||
/* SCB System Handler Control and State Register Definitions */
|
||||
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
|
||||
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
|
||||
|
||||
/*@} end of group CMSIS_SCB */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
|
||||
\brief Type definitions for the System Timer Registers.
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Structure type to access the System Timer (SysTick).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
|
||||
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
|
||||
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
|
||||
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
|
||||
} SysTick_Type;
|
||||
|
||||
/* SysTick Control / Status Register Definitions */
|
||||
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
|
||||
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
|
||||
|
||||
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
|
||||
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
|
||||
|
||||
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
|
||||
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
|
||||
|
||||
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
|
||||
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
|
||||
|
||||
/* SysTick Reload Register Definitions */
|
||||
#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
|
||||
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
|
||||
|
||||
/* SysTick Current Register Definitions */
|
||||
#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
|
||||
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
|
||||
|
||||
/* SysTick Calibration Register Definitions */
|
||||
#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
|
||||
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
|
||||
|
||||
#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
|
||||
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
|
||||
|
||||
#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
|
||||
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
|
||||
|
||||
/*@} end of group CMSIS_SysTick */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
|
||||
\brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
|
||||
Therefore they are not covered by the Cortex-M0 header file.
|
||||
@{
|
||||
*/
|
||||
/*@} end of group CMSIS_CoreDebug */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_core_bitfield Core register bit field macros
|
||||
\brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Mask and shift a bit field value for use in a register bit range.
|
||||
\param[in] field Name of the register bit field.
|
||||
\param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type.
|
||||
\return Masked and shifted value.
|
||||
*/
|
||||
#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk)
|
||||
|
||||
/**
|
||||
\brief Mask and shift a register value to extract a bit filed value.
|
||||
\param[in] field Name of the register bit field.
|
||||
\param[in] value Value of register. This parameter is interpreted as an uint32_t type.
|
||||
\return Masked and shifted bit field value.
|
||||
*/
|
||||
#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos)
|
||||
|
||||
/*@} end of group CMSIS_core_bitfield */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_core_base Core Definitions
|
||||
\brief Definitions for base addresses, unions, and structures.
|
||||
@{
|
||||
*/
|
||||
|
||||
/* Memory mapping of Core Hardware */
|
||||
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
|
||||
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
|
||||
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
|
||||
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
|
||||
|
||||
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
|
||||
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
|
||||
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
|
||||
|
||||
|
||||
/*@} */
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer
|
||||
Core Function Interface contains:
|
||||
- Core NVIC Functions
|
||||
- Core SysTick Functions
|
||||
- Core Register Access Functions
|
||||
******************************************************************************/
|
||||
/**
|
||||
\defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* ########################## NVIC functions #################################### */
|
||||
/**
|
||||
\ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
|
||||
\brief Functions that manage interrupts and exceptions via the NVIC.
|
||||
@{
|
||||
*/
|
||||
|
||||
#ifdef CMSIS_NVIC_VIRTUAL
|
||||
#ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE
|
||||
#define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h"
|
||||
#endif
|
||||
#include CMSIS_NVIC_VIRTUAL_HEADER_FILE
|
||||
#else
|
||||
#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping
|
||||
#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping
|
||||
#define NVIC_EnableIRQ __NVIC_EnableIRQ
|
||||
#define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ
|
||||
#define NVIC_DisableIRQ __NVIC_DisableIRQ
|
||||
#define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ
|
||||
#define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ
|
||||
#define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ
|
||||
/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0 */
|
||||
#define NVIC_SetPriority __NVIC_SetPriority
|
||||
#define NVIC_GetPriority __NVIC_GetPriority
|
||||
#define NVIC_SystemReset __NVIC_SystemReset
|
||||
#endif /* CMSIS_NVIC_VIRTUAL */
|
||||
|
||||
#ifdef CMSIS_VECTAB_VIRTUAL
|
||||
#ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE
|
||||
#define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h"
|
||||
#endif
|
||||
#include CMSIS_VECTAB_VIRTUAL_HEADER_FILE
|
||||
#else
|
||||
#define NVIC_SetVector __NVIC_SetVector
|
||||
#define NVIC_GetVector __NVIC_GetVector
|
||||
#endif /* (CMSIS_VECTAB_VIRTUAL) */
|
||||
|
||||
#define NVIC_USER_IRQ_OFFSET 16
|
||||
|
||||
|
||||
/* The following EXC_RETURN values are saved the LR on exception entry */
|
||||
#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */
|
||||
#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */
|
||||
#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */
|
||||
|
||||
|
||||
/* Interrupt Priorities are WORD accessible only under Armv6-M */
|
||||
/* The following MACROS handle generation of the register offset and byte masks */
|
||||
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
|
||||
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
|
||||
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
|
||||
|
||||
#define __NVIC_SetPriorityGrouping(X) (void)(X)
|
||||
#define __NVIC_GetPriorityGrouping() (0U)
|
||||
|
||||
/**
|
||||
\brief Enable Interrupt
|
||||
\details Enables a device specific interrupt in the NVIC interrupt controller.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Interrupt Enable status
|
||||
\details Returns a device specific interrupt enable status from the NVIC interrupt controller.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\return 0 Interrupt is not enabled.
|
||||
\return 1 Interrupt is enabled.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0U);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Disable Interrupt
|
||||
\details Disables a device specific interrupt in the NVIC interrupt controller.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Pending Interrupt
|
||||
\details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\return 0 Interrupt status is not pending.
|
||||
\return 1 Interrupt status is pending.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0U);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Pending Interrupt
|
||||
\details Sets the pending bit of a device specific interrupt in the NVIC pending register.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Clear Pending Interrupt
|
||||
\details Clears the pending bit of a device specific interrupt in the NVIC pending register.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Interrupt Priority
|
||||
\details Sets the priority of a device specific interrupt or a processor exception.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
\param [in] IRQn Interrupt number.
|
||||
\param [in] priority Priority to set.
|
||||
\note The priority cannot be set for every processor exception.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||
}
|
||||
else
|
||||
{
|
||||
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Interrupt Priority
|
||||
\details Reads the priority of a device specific interrupt or a processor exception.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
\param [in] IRQn Interrupt number.
|
||||
\return Interrupt Priority.
|
||||
Value is aligned automatically to the implemented priority bits of the microcontroller.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn)
|
||||
{
|
||||
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Encode Priority
|
||||
\details Encodes the priority for an interrupt with the given priority group,
|
||||
preemptive priority value, and subpriority value.
|
||||
In case of a conflict between priority grouping and available
|
||||
priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
|
||||
\param [in] PriorityGroup Used priority group.
|
||||
\param [in] PreemptPriority Preemptive priority value (starting from 0).
|
||||
\param [in] SubPriority Subpriority value (starting from 0).
|
||||
\return Encoded priority. Value can be used in the function \ref __NVIC_SetPriority().
|
||||
*/
|
||||
__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
|
||||
{
|
||||
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
|
||||
uint32_t PreemptPriorityBits;
|
||||
uint32_t SubPriorityBits;
|
||||
|
||||
PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
|
||||
SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
|
||||
|
||||
return (
|
||||
((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
|
||||
((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL)))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Decode Priority
|
||||
\details Decodes an interrupt priority value with a given priority group to
|
||||
preemptive priority value and subpriority value.
|
||||
In case of a conflict between priority grouping and available
|
||||
priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
|
||||
\param [in] Priority Priority value, which can be retrieved with the function \ref __NVIC_GetPriority().
|
||||
\param [in] PriorityGroup Used priority group.
|
||||
\param [out] pPreemptPriority Preemptive priority value (starting from 0).
|
||||
\param [out] pSubPriority Subpriority value (starting from 0).
|
||||
*/
|
||||
__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
|
||||
{
|
||||
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
|
||||
uint32_t PreemptPriorityBits;
|
||||
uint32_t SubPriorityBits;
|
||||
|
||||
PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
|
||||
SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
|
||||
|
||||
*pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
|
||||
*pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Interrupt Vector
|
||||
\details Sets an interrupt vector in SRAM based interrupt vector table.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
Address 0 must be mapped to SRAM.
|
||||
\param [in] IRQn Interrupt number
|
||||
\param [in] vector Address of interrupt handler function
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
|
||||
{
|
||||
uint32_t vectors = 0x0U;
|
||||
(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Interrupt Vector
|
||||
\details Reads an interrupt vector from interrupt vector table.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
\param [in] IRQn Interrupt number.
|
||||
\return Address of interrupt handler function
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn)
|
||||
{
|
||||
uint32_t vectors = 0x0U;
|
||||
return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief System Reset
|
||||
\details Initiates a system reset request to reset the MCU.
|
||||
*/
|
||||
__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void)
|
||||
{
|
||||
__DSB(); /* Ensure all outstanding memory accesses included
|
||||
buffered write are completed before reset */
|
||||
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
|
||||
SCB_AIRCR_SYSRESETREQ_Msk);
|
||||
__DSB(); /* Ensure completion of memory access */
|
||||
|
||||
for(;;) /* wait until reset */
|
||||
{
|
||||
__NOP();
|
||||
}
|
||||
}
|
||||
|
||||
/*@} end of CMSIS_Core_NVICFunctions */
|
||||
|
||||
|
||||
/* ########################## FPU functions #################################### */
|
||||
/**
|
||||
\ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_FpuFunctions FPU Functions
|
||||
\brief Function that provides FPU type.
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief get FPU type
|
||||
\details returns the FPU type
|
||||
\returns
|
||||
- \b 0: No FPU
|
||||
- \b 1: Single precision FPU
|
||||
- \b 2: Double + Single precision FPU
|
||||
*/
|
||||
__STATIC_INLINE uint32_t SCB_GetFPUType(void)
|
||||
{
|
||||
return 0U; /* No FPU */
|
||||
}
|
||||
|
||||
|
||||
/*@} end of CMSIS_Core_FpuFunctions */
|
||||
|
||||
|
||||
|
||||
/* ################################## SysTick function ############################################ */
|
||||
/**
|
||||
\ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
|
||||
\brief Functions that configure the System.
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U)
|
||||
|
||||
/**
|
||||
\brief System Tick Configuration
|
||||
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
|
||||
Counter is in free running mode to generate periodic interrupts.
|
||||
\param [in] ticks Number of ticks between two interrupts.
|
||||
\return 0 Function succeeded.
|
||||
\return 1 Function failed.
|
||||
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
|
||||
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
|
||||
must contain a vendor-specific implementation of this function.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
|
||||
{
|
||||
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
|
||||
{
|
||||
return (1UL); /* Reload value impossible */
|
||||
}
|
||||
|
||||
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
|
||||
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
|
||||
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
|
||||
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
|
||||
SysTick_CTRL_TICKINT_Msk |
|
||||
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
|
||||
return (0UL); /* Function successful */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*@} end of CMSIS_Core_SysTickFunctions */
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CORE_CM0_H_DEPENDANT */
|
||||
|
||||
#endif /* __CMSIS_GENERIC */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,346 @@
|
||||
/******************************************************************************
|
||||
* @file mpu_armv8.h
|
||||
* @brief CMSIS MPU API for Armv8-M and Armv8.1-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.
|
||||
*/
|
||||
/* Copyright (c) 2019 Modified by Dialog Semiconductor */
|
||||
|
||||
#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_ARMV8_H
|
||||
#define ARM_MPU_ARMV8_H
|
||||
|
||||
/** \brief Attribute for device memory (outer only) */
|
||||
#define ARM_MPU_ATTR_DEVICE ( 0U )
|
||||
|
||||
/** \brief Attribute for non-cacheable, normal memory */
|
||||
#define ARM_MPU_ATTR_NON_CACHEABLE ( 4U )
|
||||
|
||||
/** \brief Attribute for normal memory (outer and inner)
|
||||
* \param NT Non-Transient: Set to 1 for non-transient data.
|
||||
* \param WB Write-Back: Set to 1 to use write-back update policy.
|
||||
* \param RA Read Allocation: Set to 1 to use cache allocation on read miss.
|
||||
* \param WA Write Allocation: Set to 1 to use cache allocation on write miss.
|
||||
*/
|
||||
#define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \
|
||||
(((NT & 1U) << 3U) | ((WB & 1U) << 2U) | ((RA & 1U) << 1U) | (WA & 1U))
|
||||
|
||||
/** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */
|
||||
#define ARM_MPU_ATTR_DEVICE_nGnRnE (0U)
|
||||
|
||||
/** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */
|
||||
#define ARM_MPU_ATTR_DEVICE_nGnRE (1U)
|
||||
|
||||
/** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */
|
||||
#define ARM_MPU_ATTR_DEVICE_nGRE (2U)
|
||||
|
||||
/** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */
|
||||
#define ARM_MPU_ATTR_DEVICE_GRE (3U)
|
||||
|
||||
/** \brief Memory Attribute
|
||||
* \param O Outer memory attributes
|
||||
* \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes
|
||||
*/
|
||||
#define ARM_MPU_ATTR(O, I) (((O & 0xFU) << 4U) | (((O & 0xFU) != 0U) ? (I & 0xFU) : ((I & 0x3U) << 2U)))
|
||||
|
||||
/** \brief Normal memory non-shareable */
|
||||
#define ARM_MPU_SH_NON (0U)
|
||||
|
||||
/** \brief Normal memory outer shareable */
|
||||
#define ARM_MPU_SH_OUTER (2U)
|
||||
|
||||
/** \brief Normal memory inner shareable */
|
||||
#define ARM_MPU_SH_INNER (3U)
|
||||
|
||||
/** \brief Memory access permissions
|
||||
* \param RO Read-Only: Set to 1 for read-only memory.
|
||||
* \param NP Non-Privileged: Set to 1 for non-privileged memory.
|
||||
*/
|
||||
#define ARM_MPU_AP_(RO, NP) (((RO & 1U) << 1U) | (NP & 1U))
|
||||
|
||||
/** \brief Region Base Address Register value
|
||||
* \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned.
|
||||
* \param SH Defines the Shareability domain for this memory region.
|
||||
* \param RO Read-Only: Set to 1 for a read-only memory region.
|
||||
* \param NP Non-Privileged: Set to 1 for a non-privileged memory region.
|
||||
* \param XN eXecute Never: Set to 1 for a non-executable memory region.
|
||||
*/
|
||||
#define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \
|
||||
((BASE & MPU_RBAR_BASE_Msk) | \
|
||||
((SH << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \
|
||||
((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \
|
||||
((XN << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk))
|
||||
|
||||
/** \brief Region Limit Address Register value
|
||||
* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended.
|
||||
* \param IDX The attribute index to be associated with this memory region.
|
||||
*/
|
||||
#define ARM_MPU_RLAR(LIMIT, IDX) \
|
||||
((LIMIT & MPU_RLAR_LIMIT_Msk) | \
|
||||
((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \
|
||||
(MPU_RLAR_EN_Msk))
|
||||
|
||||
#if defined(MPU_RLAR_PXN_Pos)
|
||||
|
||||
/** \brief Region Limit Address Register with PXN value
|
||||
* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended.
|
||||
* \param PXN Privileged execute never. Defines whether code can be executed from this privileged region.
|
||||
* \param IDX The attribute index to be associated with this memory region.
|
||||
*/
|
||||
#define ARM_MPU_RLAR_PXN(LIMIT, PXN, IDX) \
|
||||
((LIMIT & MPU_RLAR_LIMIT_Msk) | \
|
||||
((PXN << MPU_RLAR_PXN_Pos) & MPU_RLAR_PXN_Msk) | \
|
||||
((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \
|
||||
(MPU_RLAR_EN_Msk))
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Struct for a single MPU Region
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t RBAR; /*!< Region Base Address Register value */
|
||||
uint32_t RLAR; /*!< Region Limit Address Register value */
|
||||
} 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;
|
||||
}
|
||||
|
||||
#ifdef MPU_NS
|
||||
/** Enable the Non-secure MPU.
|
||||
* \param MPU_Control Default access permissions for unconfigured regions.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control)
|
||||
{
|
||||
MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
|
||||
/** Disable the Non-secure MPU.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Disable_NS(void)
|
||||
{
|
||||
__DMB();
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Set the memory attribute encoding to the given MPU.
|
||||
* \param mpu Pointer to the MPU to be configured.
|
||||
* \param idx The attribute index to be set [0-7]
|
||||
* \param attr The attribute value to be set.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr)
|
||||
{
|
||||
const uint8_t reg = idx / 4U;
|
||||
const uint32_t pos = ((idx % 4U) * 8U);
|
||||
const uint32_t mask = 0xFFU << pos;
|
||||
|
||||
if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) {
|
||||
return; // invalid index
|
||||
}
|
||||
|
||||
mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask));
|
||||
}
|
||||
|
||||
/** Set the memory attribute encoding.
|
||||
* \param idx The attribute index to be set [0-7]
|
||||
* \param attr The attribute value to be set.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr)
|
||||
{
|
||||
ARM_MPU_SetMemAttrEx(MPU, idx, attr);
|
||||
}
|
||||
|
||||
#ifdef MPU_NS
|
||||
/** Set the memory attribute encoding to the Non-secure MPU.
|
||||
* \param idx The attribute index to be set [0-7]
|
||||
* \param attr The attribute value to be set.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr)
|
||||
{
|
||||
ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Clear and disable the given MPU region of the given MPU.
|
||||
* \param mpu Pointer to MPU to be used.
|
||||
* \param rnr Region number to be cleared.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr)
|
||||
{
|
||||
mpu->RNR = rnr;
|
||||
mpu->RLAR = 0U;
|
||||
}
|
||||
|
||||
/** Clear and disable the given MPU region.
|
||||
* \param rnr Region number to be cleared.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr)
|
||||
{
|
||||
ARM_MPU_ClrRegionEx(MPU, rnr);
|
||||
}
|
||||
|
||||
#ifdef MPU_NS
|
||||
/** Clear and disable the given Non-secure MPU region.
|
||||
* \param rnr Region number to be cleared.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr)
|
||||
{
|
||||
ARM_MPU_ClrRegionEx(MPU_NS, rnr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Configure the given MPU region of the given MPU.
|
||||
* \param mpu Pointer to MPU to be used.
|
||||
* \param rnr Region number to be configured.
|
||||
* \param rbar Value for RBAR register.
|
||||
* \param rlar Value for RLAR register.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar)
|
||||
{
|
||||
mpu->RNR = rnr;
|
||||
mpu->RBAR = rbar;
|
||||
mpu->RLAR = rlar;
|
||||
}
|
||||
|
||||
/** Configure the given MPU region.
|
||||
* \param rnr Region number to be configured.
|
||||
* \param rbar Value for RBAR register.
|
||||
* \param rlar Value for RLAR register.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar)
|
||||
{
|
||||
ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar);
|
||||
}
|
||||
|
||||
#ifdef MPU_NS
|
||||
/** Configure the given Non-secure MPU region.
|
||||
* \param rnr Region number to be configured.
|
||||
* \param rbar Value for RBAR register.
|
||||
* \param rlar Value for RLAR register.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar)
|
||||
{
|
||||
ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** 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 to the given MPU.
|
||||
* \param mpu Pointer to the MPU registers to be used.
|
||||
* \param rnr First region number to be configured.
|
||||
* \param table Pointer to the MPU configuration table.
|
||||
* \param cnt Amount of regions to be configured.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
|
||||
{
|
||||
const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U;
|
||||
if (cnt == 1U) {
|
||||
mpu->RNR = rnr;
|
||||
ARM_MPU_OrderedMemcpy(&(mpu->RBAR), &(table->RBAR), rowWordSize);
|
||||
} else {
|
||||
uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U);
|
||||
uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES;
|
||||
|
||||
mpu->RNR = rnrBase;
|
||||
while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) {
|
||||
uint32_t c = MPU_TYPE_RALIASES - rnrOffset;
|
||||
ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize);
|
||||
table += c;
|
||||
cnt -= c;
|
||||
rnrOffset = 0U;
|
||||
rnrBase += MPU_TYPE_RALIASES;
|
||||
mpu->RNR = rnrBase;
|
||||
}
|
||||
|
||||
ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize);
|
||||
}
|
||||
}
|
||||
|
||||
/** Load the given number of MPU regions from a table.
|
||||
* \param rnr First region number to be configured.
|
||||
* \param table Pointer to the MPU configuration table.
|
||||
* \param cnt Amount of regions to be configured.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
|
||||
{
|
||||
ARM_MPU_LoadEx(MPU, rnr, table, cnt);
|
||||
}
|
||||
|
||||
#ifdef MPU_NS
|
||||
/** Load the given number of MPU regions from a table to the Non-secure MPU.
|
||||
* \param rnr First region number to be configured.
|
||||
* \param table Pointer to the MPU configuration table.
|
||||
* \param cnt Amount of regions to be configured.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
|
||||
{
|
||||
ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
/**************************************************************************//**
|
||||
* @file system_ARMCM0.h
|
||||
* @brief CMSIS Device System Header File for
|
||||
* ARMCM0 Device
|
||||
* @version V5.3.1
|
||||
* @date 09. July 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 SYSTEM_ARMCM0_H
|
||||
#define SYSTEM_ARMCM0_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
|
||||
|
||||
|
||||
/**
|
||||
\brief Setup the microcontroller system.
|
||||
|
||||
Initialize the System and update the SystemCoreClock variable.
|
||||
*/
|
||||
extern void SystemInit (void);
|
||||
|
||||
|
||||
/**
|
||||
\brief Update SystemCoreClock variable.
|
||||
|
||||
Updates the SystemCoreClock with current core Clock retrieved from cpu registers.
|
||||
*/
|
||||
extern void SystemCoreClockUpdate (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SYSTEM_ARMCM0_H */
|
||||
@@ -0,0 +1,72 @@
|
||||
/**************************************************************************//**
|
||||
* @file system_DA1469x.h
|
||||
* @brief CMSIS Device System Header File for DA1469x Device
|
||||
* @version V5.3.1
|
||||
* @date 17. May 2019
|
||||
******************************************************************************/
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/* Copyright (c) 2017 Modified by Dialog Semiconductor */
|
||||
|
||||
|
||||
#ifndef SYSTEM_DA1469x_H
|
||||
#define SYSTEM_DA1469x_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
|
||||
|
||||
|
||||
/**
|
||||
\brief Setup the microcontroller system.
|
||||
|
||||
Initialize the System and update the SystemCoreClock variable.
|
||||
*/
|
||||
extern void SystemInit (void);
|
||||
|
||||
|
||||
/**
|
||||
\brief Update SystemCoreClock variable.
|
||||
Updates the SystemCoreClock with current core Clock retrieved from cpu registers.
|
||||
*/
|
||||
extern void SystemCoreClockUpdate (void);
|
||||
|
||||
/**
|
||||
* \brief Convert a CPU address to a physical address
|
||||
*
|
||||
* To calculate the physical address, the current remapping (SYS_CTRL_REG.REMAP_ADR0)
|
||||
* is used.
|
||||
*
|
||||
* \param [in] addr address seen by CPU
|
||||
*
|
||||
* \return physical address (for DMA, AES/HASH etc.) -- can be same or different as addr
|
||||
*
|
||||
*/
|
||||
extern uint32_t black_orca_phy_addr(uint32_t addr);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SYSTEM_DA1469x_H */
|
||||
@@ -0,0 +1,227 @@
|
||||
/* Linker script for Dialog DA1469x devices
|
||||
*
|
||||
* Version: Sourcery G++ 4.5-1
|
||||
* Support: https://support.codesourcery.com/GNUToolchain/
|
||||
*
|
||||
* Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc.
|
||||
*
|
||||
* The authors hereby grant permission to use, copy, modify, distribute,
|
||||
* and license this software and its documentation for any purpose, provided
|
||||
* that existing copyright notices are retained in all copies and that this
|
||||
* notice is included verbatim in any distributions. No written agreement,
|
||||
* license, or royalty fee is required for any of the authorized uses.
|
||||
* Modifications to this software may be copyrighted by their authors
|
||||
* and need not follow the licensing terms described here, provided that
|
||||
* the new terms are clearly indicated on the first page of each file where
|
||||
* they apply.
|
||||
*/
|
||||
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
||||
|
||||
/* Linker script to place sections and symbol values. Should be used together
|
||||
* with other linker script that defines memory regions FLASH and RAM.
|
||||
* It references following symbols, which must be defined in code:
|
||||
* Reset_Handler : Entry of reset handler
|
||||
*
|
||||
* It defines following symbols, which code can use without definition:
|
||||
* __exidx_start
|
||||
* __exidx_end
|
||||
* __etext
|
||||
* __data_start__
|
||||
* __preinit_array_start
|
||||
* __preinit_array_end
|
||||
* __init_array_start
|
||||
* __init_array_end
|
||||
* __fini_array_start
|
||||
* __fini_array_end
|
||||
* __data_end__
|
||||
* __bss_start__
|
||||
* __bss_end__
|
||||
* __HeapBase
|
||||
* __HeapLimit
|
||||
* __StackLimit
|
||||
* __StackTop
|
||||
* __stack
|
||||
* __bssnz_start__
|
||||
* __bssnz_end__
|
||||
*/
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.imghdr (NOLOAD):
|
||||
{
|
||||
. = . + _imghdr_size;
|
||||
} > FLASH
|
||||
|
||||
__text = .;
|
||||
|
||||
.text :
|
||||
{
|
||||
__isr_vector_start = .;
|
||||
KEEP(*(.isr_vector))
|
||||
/* ISR vector shall have exactly 512 bytes */
|
||||
. = __isr_vector_start + 0x200;
|
||||
__isr_vector_end = .;
|
||||
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.fini))
|
||||
|
||||
/* .ctors */
|
||||
*crtbegin.o(.ctors)
|
||||
*crtbegin?.o(.ctors)
|
||||
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
|
||||
*(SORT(.ctors.*))
|
||||
*(.ctors)
|
||||
|
||||
/* .dtors */
|
||||
*crtbegin.o(.dtors)
|
||||
*crtbegin?.o(.dtors)
|
||||
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
|
||||
*(SORT(.dtors.*))
|
||||
*(.dtors)
|
||||
|
||||
*(.rodata*)
|
||||
|
||||
*(.eh_frame*)
|
||||
. = ALIGN(4);
|
||||
} > FLASH
|
||||
|
||||
.ARM.extab :
|
||||
{
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
. = ALIGN(4);
|
||||
} > FLASH
|
||||
|
||||
__exidx_start = .;
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
. = ALIGN(4);
|
||||
} > FLASH
|
||||
__exidx_end = .;
|
||||
|
||||
.intvect :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__intvect_start__ = .;
|
||||
. = . + (__isr_vector_end - __isr_vector_start);
|
||||
. = ALIGN(4);
|
||||
} > RAM
|
||||
|
||||
.sleep_state (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(sleep_state)
|
||||
} > RAM
|
||||
|
||||
/* This section will be zeroed by RTT package init */
|
||||
.rtt (NOLOAD):
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.rtt)
|
||||
. = ALIGN(4);
|
||||
} > RAM
|
||||
|
||||
__text_ram_addr = LOADADDR(.text_ram);
|
||||
|
||||
.text_ram :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__text_ram_start__ = .;
|
||||
*(.text_ram*)
|
||||
. = ALIGN(4);
|
||||
__text_ram_end__ = .;
|
||||
} > RAM AT > FLASH
|
||||
|
||||
__etext = LOADADDR(.data);
|
||||
|
||||
.data :
|
||||
{
|
||||
__data_start__ = .;
|
||||
*(vtable)
|
||||
*(.data*)
|
||||
|
||||
. = ALIGN(4);
|
||||
/* preinit data */
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
*(.preinit_array)
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
/* init data */
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
*(SORT(.init_array.*))
|
||||
*(.init_array)
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
|
||||
|
||||
. = ALIGN(4);
|
||||
/* finit data */
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
*(SORT(.fini_array.*))
|
||||
*(.fini_array)
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
|
||||
*(.jcr)
|
||||
. = ALIGN(4);
|
||||
/* All data end */
|
||||
__data_end__ = .;
|
||||
} > RAM AT > FLASH
|
||||
|
||||
.bssnz :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bssnz_start__ = .;
|
||||
*(.bss.core.nz*)
|
||||
. = ALIGN(4);
|
||||
__bssnz_end__ = .;
|
||||
} > RAM
|
||||
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start__ = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end__ = .;
|
||||
} > RAM
|
||||
|
||||
.cmac (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(0x400);
|
||||
*(.libcmac.ram)
|
||||
} > RAM
|
||||
|
||||
/* Heap starts after BSS */
|
||||
. = ALIGN(8);
|
||||
__HeapBase = .;
|
||||
|
||||
/* .stack_dummy section doesn't contains any symbols. It is only
|
||||
* used for linker to calculate size of stack sections, and assign
|
||||
* values to stack symbols later */
|
||||
.stack_dummy (COPY):
|
||||
{
|
||||
*(.stack*)
|
||||
} > RAM
|
||||
|
||||
_ram_start = ORIGIN(RAM);
|
||||
|
||||
/* Set stack top to end of RAM, and stack limit move down by
|
||||
* size of stack_dummy section */
|
||||
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
|
||||
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
|
||||
PROVIDE(__stack = __StackTop);
|
||||
|
||||
/* Top of head is the bottom of the stack */
|
||||
__HeapLimit = __StackLimit;
|
||||
|
||||
/* Check if data + heap + stack exceeds RAM limit */
|
||||
ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack")
|
||||
|
||||
/* Check that intvect is at the beginning of RAM */
|
||||
ASSERT(__intvect_start__ == ORIGIN(RAM), "intvect is not at beginning of RAM")
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @addtogroup HAL
|
||||
* @{
|
||||
* @defgroup HALGpio HAL GPIO
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef H_HAL_GPIO_
|
||||
#define H_HAL_GPIO_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The "mode" of the gpio. The gpio is either an input, output, or it is
|
||||
* "not connected" (the pin specified is not functioning as a gpio)
|
||||
*/
|
||||
enum hal_gpio_mode_e {
|
||||
/** Not connected */
|
||||
HAL_GPIO_MODE_NC = -1,
|
||||
/** Input */
|
||||
HAL_GPIO_MODE_IN = 0,
|
||||
/** Output */
|
||||
HAL_GPIO_MODE_OUT = 1
|
||||
};
|
||||
typedef enum hal_gpio_mode_e hal_gpio_mode_t;
|
||||
|
||||
/*
|
||||
* The "pull" of the gpio. This is either an input or an output.
|
||||
*/
|
||||
enum hal_gpio_pull {
|
||||
/** Pull-up/down not enabled */
|
||||
HAL_GPIO_PULL_NONE = 0,
|
||||
/** Pull-up enabled */
|
||||
HAL_GPIO_PULL_UP = 1,
|
||||
/** Pull-down enabled */
|
||||
HAL_GPIO_PULL_DOWN = 2
|
||||
};
|
||||
typedef enum hal_gpio_pull hal_gpio_pull_t;
|
||||
|
||||
/*
|
||||
* IRQ trigger type.
|
||||
*/
|
||||
enum hal_gpio_irq_trigger {
|
||||
HAL_GPIO_TRIG_NONE = 0,
|
||||
/** IRQ occurs on rising edge */
|
||||
HAL_GPIO_TRIG_RISING = 1,
|
||||
/** IRQ occurs on falling edge */
|
||||
HAL_GPIO_TRIG_FALLING = 2,
|
||||
/** IRQ occurs on either edge */
|
||||
HAL_GPIO_TRIG_BOTH = 3,
|
||||
/** IRQ occurs when line is low */
|
||||
HAL_GPIO_TRIG_LOW = 4,
|
||||
/** IRQ occurs when line is high */
|
||||
HAL_GPIO_TRIG_HIGH = 5
|
||||
};
|
||||
typedef enum hal_gpio_irq_trigger hal_gpio_irq_trig_t;
|
||||
|
||||
/* Function proto for GPIO irq handler functions */
|
||||
typedef void (*hal_gpio_irq_handler_t)(void *arg);
|
||||
|
||||
/**
|
||||
* Initializes the specified pin as an input
|
||||
*
|
||||
* @param pin Pin number to set as input
|
||||
* @param pull pull type
|
||||
*
|
||||
* @return int 0: no error; -1 otherwise.
|
||||
*/
|
||||
int hal_gpio_init_in(int pin, hal_gpio_pull_t pull);
|
||||
|
||||
/**
|
||||
* Initialize the specified pin as an output, setting the pin to the specified
|
||||
* value.
|
||||
*
|
||||
* @param pin Pin number to set as output
|
||||
* @param val Value to set pin
|
||||
*
|
||||
* @return int 0: no error; -1 otherwise.
|
||||
*/
|
||||
int hal_gpio_init_out(int pin, int val);
|
||||
|
||||
/**
|
||||
* Deinitialize the specified pin to revert the previous initialization
|
||||
*
|
||||
* @param pin Pin number to unset
|
||||
*
|
||||
* @return int 0: no error; -1 otherwise.
|
||||
*/
|
||||
int hal_gpio_deinit(int pin);
|
||||
|
||||
/**
|
||||
* Write a value (either high or low) to the specified pin.
|
||||
*
|
||||
* @param pin Pin to set
|
||||
* @param val Value to set pin (0:low 1:high)
|
||||
*/
|
||||
void hal_gpio_write(int pin, int val);
|
||||
|
||||
/**
|
||||
* Reads the specified pin.
|
||||
*
|
||||
* @param pin Pin number to read
|
||||
*
|
||||
* @return int 0: low, 1: high
|
||||
*/
|
||||
int hal_gpio_read(int pin);
|
||||
|
||||
/**
|
||||
* Toggles the specified pin
|
||||
*
|
||||
* @param pin Pin number to toggle
|
||||
*
|
||||
* @return current gpio state int 0: low, 1: high
|
||||
*/
|
||||
int hal_gpio_toggle(int pin);
|
||||
|
||||
/**
|
||||
* Initialize a given pin to trigger a GPIO IRQ callback.
|
||||
*
|
||||
* @param pin The pin to trigger GPIO interrupt on
|
||||
* @param handler The handler function to call
|
||||
* @param arg The argument to provide to the IRQ handler
|
||||
* @param trig The trigger mode (e.g. rising, falling)
|
||||
* @param pull The mode of the pin (e.g. pullup, pulldown)
|
||||
*
|
||||
* @return 0 on success, non-zero error code on failure.
|
||||
*/
|
||||
int hal_gpio_irq_init(int pin, hal_gpio_irq_handler_t handler, void *arg,
|
||||
hal_gpio_irq_trig_t trig, hal_gpio_pull_t pull);
|
||||
|
||||
/**
|
||||
* Release a pin from being configured to trigger IRQ on state change.
|
||||
*
|
||||
* @param pin The pin to release
|
||||
*/
|
||||
void hal_gpio_irq_release(int pin);
|
||||
|
||||
/**
|
||||
* Enable IRQs on the passed pin
|
||||
*
|
||||
* @param pin The pin to enable IRQs on
|
||||
*/
|
||||
void hal_gpio_irq_enable(int pin);
|
||||
|
||||
/**
|
||||
* Disable IRQs on the passed pin
|
||||
*
|
||||
* @param pin The pin to disable IRQs on
|
||||
*/
|
||||
void hal_gpio_irq_disable(int pin);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* H_HAL_GPIO_ */
|
||||
|
||||
/**
|
||||
* @} HALGpio
|
||||
* @} HAL
|
||||
*/
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef __MCU_DA1469X_CLOCK_H_
|
||||
#define __MCU_DA1469X_CLOCK_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "mcu/da1469x_hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initialize XTAL32M
|
||||
*/
|
||||
void da1469x_clock_sys_xtal32m_init(void);
|
||||
|
||||
/**
|
||||
* Enable XTAL32M
|
||||
*/
|
||||
void da1469x_clock_sys_xtal32m_enable(void);
|
||||
|
||||
/**
|
||||
* Wait for XTAL32M to settle
|
||||
*/
|
||||
void da1469x_clock_sys_xtal32m_wait_to_settle(void);
|
||||
|
||||
/**
|
||||
* Switch sys_clk to XTAL32M
|
||||
*
|
||||
* Caller shall ensure that XTAL32M is already settled.
|
||||
*/
|
||||
void da1469x_clock_sys_xtal32m_switch(void);
|
||||
|
||||
/**
|
||||
* Switch sys_clk to XTAL32M
|
||||
*
|
||||
* Waits for XTAL32M to settle before switching.
|
||||
*/
|
||||
void da1469x_clock_sys_xtal32m_switch_safe(void);
|
||||
|
||||
/**
|
||||
* Disable RC32M
|
||||
*/
|
||||
void da1469x_clock_sys_rc32m_disable(void);
|
||||
|
||||
/**
|
||||
* Enable AMBA clock(s)
|
||||
*
|
||||
* @param mask
|
||||
*/
|
||||
static inline void
|
||||
da1469x_clock_amba_enable(uint32_t mask)
|
||||
{
|
||||
uint32_t primask;
|
||||
|
||||
__HAL_DISABLE_INTERRUPTS(primask);
|
||||
CRG_TOP->CLK_AMBA_REG |= mask;
|
||||
__HAL_ENABLE_INTERRUPTS(primask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable AMBA clock(s)
|
||||
*
|
||||
* @param uint32_t mask
|
||||
*/
|
||||
static inline void
|
||||
da1469x_clock_amba_disable(uint32_t mask)
|
||||
{
|
||||
uint32_t primask;
|
||||
|
||||
__HAL_DISABLE_INTERRUPTS(primask);
|
||||
CRG_TOP->CLK_AMBA_REG &= ~mask;
|
||||
__HAL_ENABLE_INTERRUPTS(primask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable PLL96
|
||||
*/
|
||||
static inline void
|
||||
da1469x_clock_sys_pll_enable(void)
|
||||
{
|
||||
CRG_XTAL->PLL_SYS_CTRL1_REG |= CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_EN_Msk |
|
||||
CRG_XTAL_PLL_SYS_CTRL1_REG_LDO_PLL_ENABLE_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable PLL96
|
||||
*
|
||||
* If PLL was used as SYS_CLOCK switches to XTAL32M.
|
||||
*/
|
||||
void da1469x_clock_sys_pll_disable(void);
|
||||
|
||||
/**
|
||||
* Checks whether PLL96 is locked and can be use as system clock or USB clock
|
||||
*
|
||||
* @return 0 if PLL is off, non-0 it its running
|
||||
*/
|
||||
static inline int
|
||||
da1469x_clock_is_pll_locked(void)
|
||||
{
|
||||
return 0 != (CRG_XTAL->PLL_SYS_STATUS_REG & CRG_XTAL_PLL_SYS_STATUS_REG_PLL_LOCK_FINE_Msk);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for PLL96 to lock.
|
||||
*/
|
||||
void da1469x_clock_pll_wait_to_lock(void);
|
||||
|
||||
/**
|
||||
* Switches system clock to PLL96
|
||||
*
|
||||
* Caller shall ensure that PLL is already locked.
|
||||
*/
|
||||
void da1469x_clock_sys_pll_switch(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MCU_DA1469X_CLOCK_H_ */
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef __MCU_DA1469X_HAL_H_
|
||||
#define __MCU_DA1469X_HAL_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include "mcu/mcu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Helper functions to enable/disable interrupts. */
|
||||
#define __HAL_DISABLE_INTERRUPTS(x) \
|
||||
do { \
|
||||
x = __get_PRIMASK(); \
|
||||
__disable_irq(); \
|
||||
} while (0)
|
||||
|
||||
#define __HAL_ENABLE_INTERRUPTS(x) \
|
||||
do { \
|
||||
if (!x) { \
|
||||
__enable_irq(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define __HAL_ASSERT_CRITICAL() \
|
||||
do { \
|
||||
assert(__get_PRIMASK() & 1); \
|
||||
} while (0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MCU_DA1469X_HAL_H_ */
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef __MCU_MCU_H_
|
||||
#define __MCU_MCU_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "DA1469xAB.h"
|
||||
|
||||
#define sec_text_ram_core __attribute__((section(".text_ram"))) __attribute__((noinline))
|
||||
|
||||
#define MCU_SYSVIEW_INTERRUPTS \
|
||||
"I#1=Reset,I#2=MNI,I#3=HardFault,I#4=MemoryMgmt,I#5=BusFault,I#6=UsageFault," \
|
||||
"I#7=SecureFault,I#11=SVCall,I#12=DebugMonitor,I#14=PendSV,I#15=SysTick," \
|
||||
"I#16=SENSOR_NODE,I#17=DMA,I#18=CHARGER_STATE,I#19=CHARGER_ERROR," \
|
||||
"I#20=CMAC2SYS,I#21=UART,I#22=UART2,I#23=UART3,I#24=I2C,I#25=I2C2,I#26=SPI," \
|
||||
"I#27=SPI2,I#28=PCM,I#29=SRC_IN,I#30=SRC_OUT,I#31=USB,I#32=TIMER," \
|
||||
"I#33=TIMER2,I#34=RTC,I#35=KEY_WKUP_GPIO,I#36=PDC,I#37=VBUS,I#38=MRM," \
|
||||
"I#39=MOTOR_CONTROLLER,I#40=TRNG,I#41=DCDC,I#42=XTAL32M_RDY,I#43=ADC," \
|
||||
"I#44=ADC2,I#45=CRYPTO,I#46=CAPTIMER1,I#47=RFDIAG,I#48=LCD_CONTROLLER," \
|
||||
"I#49=PLL_LOCK,I#50=TIMER3,I#51=TIMER4,I#52=LRA,I#53=RTC_EVENT," \
|
||||
"I#54=GPIO_P0,I#55=GPIO_P1"
|
||||
|
||||
/**
|
||||
* \brief GPIO function
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
MCU_GPIO_FUNC_GPIO = 0, /**< GPIO */
|
||||
MCU_GPIO_FUNC_UART_RX = 1, /**< GPIO as UART RX */
|
||||
MCU_GPIO_FUNC_UART_TX = 2, /**< GPIO as UART TX */
|
||||
MCU_GPIO_FUNC_UART2_RX = 3, /**< GPIO as UART2 RX */
|
||||
MCU_GPIO_FUNC_UART2_TX = 4, /**< GPIO as UART2 TX */
|
||||
MCU_GPIO_FUNC_UART2_CTSN = 5, /**< GPIO as UART2 CTSN */
|
||||
MCU_GPIO_FUNC_UART2_RTSN = 6, /**< GPIO as UART2 RTSN */
|
||||
MCU_GPIO_FUNC_UART3_RX = 7, /**< GPIO as UART3 RX */
|
||||
MCU_GPIO_FUNC_UART3_TX = 8, /**< GPIO as UART3 TX */
|
||||
MCU_GPIO_FUNC_UART3_CTSN = 9, /**< GPIO as UART3 CTSN */
|
||||
MCU_GPIO_FUNC_UART3_RTSN = 10, /**< GPIO as UART3 RTSN */
|
||||
MCU_GPIO_FUNC_ISO_CLK = 11, /**< GPIO as ISO CLK */
|
||||
MCU_GPIO_FUNC_ISO_DATA = 12, /**< GPIO as ISO DATA */
|
||||
MCU_GPIO_FUNC_SPI_DI = 13, /**< GPIO as SPI DI */
|
||||
MCU_GPIO_FUNC_SPI_DO = 14, /**< GPIO as SPI DO */
|
||||
MCU_GPIO_FUNC_SPI_CLK = 15, /**< GPIO as SPI CLK */
|
||||
MCU_GPIO_FUNC_SPI_EN = 16, /**< GPIO as SPI EN */
|
||||
MCU_GPIO_FUNC_SPI2_DI = 17, /**< GPIO as SPI2 DI */
|
||||
MCU_GPIO_FUNC_SPI2_DO = 18, /**< GPIO as SPI2 DO */
|
||||
MCU_GPIO_FUNC_SPI2_CLK = 19, /**< GPIO as SPI2 CLK */
|
||||
MCU_GPIO_FUNC_SPI2_EN = 20, /**< GPIO as SPI2 EN */
|
||||
MCU_GPIO_FUNC_I2C_SCL = 21, /**< GPIO as I2C SCL */
|
||||
MCU_GPIO_FUNC_I2C_SDA = 22, /**< GPIO as I2C SDA */
|
||||
MCU_GPIO_FUNC_I2C2_SCL = 23, /**< GPIO as I2C2 SCL */
|
||||
MCU_GPIO_FUNC_I2C2_SDA = 24, /**< GPIO as I2C2 SDA */
|
||||
MCU_GPIO_FUNC_USB_SOF = 25, /**< GPIO as USB SOF */
|
||||
MCU_GPIO_FUNC_ADC = 26, /**< GPIO as ADC (dedicated pin) */
|
||||
MCU_GPIO_FUNC_USB = 27, /**< GPIO as USB */
|
||||
MCU_GPIO_FUNC_PCM_DI = 28, /**< GPIO as PCM DI */
|
||||
MCU_GPIO_FUNC_PCM_DO = 29, /**< GPIO as PCM DO */
|
||||
MCU_GPIO_FUNC_PCM_FSC = 30, /**< GPIO as PCM FSC */
|
||||
MCU_GPIO_FUNC_PCM_CLK = 31, /**< GPIO as PCM CLK */
|
||||
MCU_GPIO_FUNC_PDM_DATA = 32, /**< GPIO as PDM DATA */
|
||||
MCU_GPIO_FUNC_PDM_CLK = 33, /**< GPIO as PDM CLK */
|
||||
MCU_GPIO_FUNC_COEX_EXT_ACT = 34, /**< GPIO as COEX EXT ACT0 */
|
||||
MCU_GPIO_FUNC_COEX_SMART_ACT = 35, /**< GPIO as COEX SMART ACT */
|
||||
MCU_GPIO_FUNC_COEX_SMART_PRI = 36, /**< GPIO as COEX SMART PRI */
|
||||
MCU_GPIO_FUNC_PORT0_DCF = 37, /**< GPIO as PORT0 DCF */
|
||||
MCU_GPIO_FUNC_PORT1_DCF = 38, /**< GPIO as PORT1 DCF */
|
||||
MCU_GPIO_FUNC_PORT2_DCF = 39, /**< GPIO as PORT2 DCF */
|
||||
MCU_GPIO_FUNC_PORT3_DCF = 40, /**< GPIO as PORT3 DCF */
|
||||
MCU_GPIO_FUNC_PORT4_DCF = 41, /**< GPIO as PORT4 DCF */
|
||||
MCU_GPIO_FUNC_CLOCK = 42, /**< GPIO as CLOCK */
|
||||
MCU_GPIO_FUNC_PG = 43, /**< GPIO as PG */
|
||||
MCU_GPIO_FUNC_LCD = 44, /**< GPIO as LCD */
|
||||
MCU_GPIO_FUNC_LCD_SPI_DC = 45, /**< GPIO as LCD SPI DC */
|
||||
MCU_GPIO_FUNC_LCD_SPI_DO = 46, /**< GPIO as LCD SPI DO */
|
||||
MCU_GPIO_FUNC_LCD_SPI_CLK = 47, /**< GPIO as LCD SPI CLK */
|
||||
MCU_GPIO_FUNC_LCD_SPI_EN = 48, /**< GPIO as LCD SPI EN */
|
||||
MCU_GPIO_FUNC_TIM_PWM = 49, /**< GPIO as TIM PWM */
|
||||
MCU_GPIO_FUNC_TIM2_PWM = 50, /**< GPIO as TIM2 PWM */
|
||||
MCU_GPIO_FUNC_TIM_1SHOT = 51, /**< GPIO as TIM 1SHOT */
|
||||
MCU_GPIO_FUNC_TIM2_1SHOT = 52, /**< GPIO as TIM2 1SHOT */
|
||||
MCU_GPIO_FUNC_TIM3_PWM = 53, /**< GPIO as TIM3 PWM */
|
||||
MCU_GPIO_FUNC_TIM4_PWM = 54, /**< GPIO as TIM4 PWM */
|
||||
MCU_GPIO_FUNC_AGC_EXT = 55, /**< GPIO as AGC EXT */
|
||||
MCU_GPIO_FUNC_CMAC_DIAG0 = 56, /**< GPIO as CMAC DIAG0 */
|
||||
MCU_GPIO_FUNC_CMAC_DIAG1 = 57, /**< GPIO as CMAC DIAG1 */
|
||||
MCU_GPIO_FUNC_CMAC_DIAG2 = 58, /**< GPIO as CMAC DIAG2 */
|
||||
MCU_GPIO_FUNC_CMAC_DIAGX = 59, /**< GPIO as CMAC DIAGX */
|
||||
MCU_GPIO_FUNC_LAST,
|
||||
} mcu_gpio_func;
|
||||
|
||||
#define MCU_GPIO_MODE_INPUT 0x000 /**< GPIO as an input */
|
||||
#define MCU_GPIO_MODE_INPUT_PULLUP 0x100 /**< GPIO as an input with pull-up */
|
||||
#define MCU_GPIO_MODE_INPUT_PULLDOWN 0x200 /**< GPIO as an input with pull-down */
|
||||
#define MCU_GPIO_MODE_OUTPUT 0x300 /**< GPIO as an output */
|
||||
#define MCU_GPIO_MODE_OUTPUT_OPEN_DRAIN 0x700 /**< GPIO as an open-drain output */
|
||||
|
||||
#define MCU_GPIO_PORT0_PIN_COUNT 32
|
||||
#define MCU_GPIO_PORT0(pin) ((0 * 32) + (pin))
|
||||
#define MCU_GPIO_PORT1(pin) ((1 * 32) + (pin))
|
||||
#define MCU_DMA_CHAN_MAX 8
|
||||
|
||||
#define MCU_PIN_GPADC_SEL0 MCU_GPIO_PORT1(9)
|
||||
#define MCU_PIN_GPADC_SEL1 MCU_GPIO_PORT0(25)
|
||||
#define MCU_PIN_GPADC_SEL2 MCU_GPIO_PORT0(8)
|
||||
#define MCU_PIN_GPADC_SEL3 MCU_GPIO_PORT0(9)
|
||||
#define MCU_PIN_GPADC_SEL16 MCU_GPIO_PORT1(13)
|
||||
#define MCU_PIN_GPADC_SEL17 MCU_GPIO_PORT1(12)
|
||||
#define MCU_PIN_GPADC_SEL18 MCU_GPIO_PORT1(18)
|
||||
#define MCU_PIN_GPADC_SEL19 MCU_GPIO_PORT1(19)
|
||||
#define MCU_PIN_GPADC_DIFF0_P0 MCU_GPIO_PORT1(9)
|
||||
#define MCU_PIN_GPADC_DIFF0_P1 MCU_GPIO_PORT0(25)
|
||||
#define MCU_PIN_GPADC_DIFF1_P0 MCU_GPIO_PORT0(8)
|
||||
#define MCU_PIN_GPADC_DIFF1_P1 MCU_GPIO_PORT0(9)
|
||||
|
||||
#define MCU_PIN_SDADC0 MCU_GPIO_PORT1(9)
|
||||
#define MCU_PIN_SDADC1 MCU_GPIO_PORT0(25)
|
||||
#define MCU_PIN_SDADC2 MCU_GPIO_PORT0(8)
|
||||
#define MCU_PIN_SDADC3 MCU_GPIO_PORT0(9)
|
||||
#define MCU_PIN_SDADC4 MCU_GPIO_PORT1(14)
|
||||
#define MCU_PIN_SDADC5 MCU_GPIO_PORT1(20)
|
||||
#define MCU_PIN_SDADC6 MCU_GPIO_PORT1(21)
|
||||
#define MCU_PIN_SDADC7 MCU_GPIO_PORT1(22)
|
||||
|
||||
void mcu_gpio_set_pin_function(int pin, int mode, mcu_gpio_func func);
|
||||
void mcu_gpio_enter_sleep(void);
|
||||
void mcu_gpio_exit_sleep(void);
|
||||
|
||||
#define MCU_MEM_QSPIF_M_END_REMAP_ADDRESS (0x800000)
|
||||
#define MCU_MEM_QSPIF_M_START_ADDRESS (0x16000000)
|
||||
#define MCU_MEM_QSPIF_M_END_ADDRESS (0x18000000)
|
||||
#define MCU_MEM_SYSRAM_START_ADDRESS (0x20000000)
|
||||
#define MCU_MEM_SYSRAM_END_ADDRESS (0x20080000)
|
||||
|
||||
#define MCU_OTPM_BASE 0x30080000UL
|
||||
#define MCU_OTPM_SIZE 4096
|
||||
|
||||
/* Largest group id seen on a DA14699 was 18 so far */
|
||||
#define MCU_TRIMV_GROUP_ID_MAX (18)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MCU_MCU_H_ */
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "syscfg/syscfg.h"
|
||||
#include "mcu/da1469x_hal.h"
|
||||
#include "mcu/da1469x_clock.h"
|
||||
|
||||
static inline bool
|
||||
da1469x_clock_is_xtal32m_settled(void)
|
||||
{
|
||||
return ((*(uint32_t *)0x5001001c & 0xff00) == 0) &&
|
||||
((*(uint32_t *)0x50010054 & 0x000f) != 0xb);
|
||||
}
|
||||
|
||||
void
|
||||
da1469x_clock_sys_xtal32m_init(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
int xtalrdy_cnt;
|
||||
|
||||
/* Number of lp_clk cycles (~30.5us) */
|
||||
xtalrdy_cnt = MYNEWT_VAL(MCU_CLOCK_XTAL32M_SETTLE_TIME_US) * 10 / 305;
|
||||
|
||||
reg = CRG_XTAL->XTALRDY_CTRL_REG;
|
||||
reg &= ~(CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CLK_SEL_Msk |
|
||||
CRG_XTAL_XTALRDY_CTRL_REG_XTALRDY_CNT_Msk);
|
||||
reg |= xtalrdy_cnt;
|
||||
CRG_XTAL->XTALRDY_CTRL_REG = reg;
|
||||
}
|
||||
|
||||
void
|
||||
da1469x_clock_sys_xtal32m_enable(void)
|
||||
{
|
||||
PDC->PDC_CTRL0_REG = (2 << PDC_PDC_CTRL0_REG_TRIG_SELECT_Pos) |
|
||||
(15 << PDC_PDC_CTRL0_REG_TRIG_ID_Pos) |
|
||||
(1 << PDC_PDC_CTRL0_REG_PDC_MASTER_Pos) |
|
||||
(1 << PDC_PDC_CTRL0_REG_EN_XTAL_Pos);
|
||||
|
||||
PDC->PDC_SET_PENDING_REG = 0;
|
||||
PDC->PDC_ACKNOWLEDGE_REG = 0;
|
||||
}
|
||||
|
||||
void
|
||||
da1469x_clock_sys_xtal32m_switch(void)
|
||||
{
|
||||
if (CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_RC32M_Msk) {
|
||||
CRG_TOP->CLK_SWITCH2XTAL_REG = CRG_TOP_CLK_SWITCH2XTAL_REG_SWITCH2XTAL_Msk;
|
||||
} else {
|
||||
CRG_TOP->CLK_CTRL_REG &= ~CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Msk;
|
||||
}
|
||||
|
||||
while (!(CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_XTAL32M_Msk));
|
||||
}
|
||||
|
||||
void
|
||||
da1469x_clock_sys_xtal32m_wait_to_settle(void)
|
||||
{
|
||||
uint32_t primask;
|
||||
|
||||
__HAL_DISABLE_INTERRUPTS(primask);
|
||||
|
||||
NVIC_ClearPendingIRQ(XTAL32M_RDY_IRQn);
|
||||
|
||||
if (!da1469x_clock_is_xtal32m_settled()) {
|
||||
NVIC_EnableIRQ(XTAL32M_RDY_IRQn);
|
||||
while (!NVIC_GetPendingIRQ(XTAL32M_RDY_IRQn)) {
|
||||
__WFI();
|
||||
}
|
||||
NVIC_DisableIRQ(XTAL32M_RDY_IRQn);
|
||||
}
|
||||
|
||||
__HAL_ENABLE_INTERRUPTS(primask);
|
||||
}
|
||||
|
||||
void
|
||||
da1469x_clock_sys_xtal32m_switch_safe(void)
|
||||
{
|
||||
da1469x_clock_sys_xtal32m_wait_to_settle();
|
||||
|
||||
da1469x_clock_sys_xtal32m_switch();
|
||||
}
|
||||
|
||||
void
|
||||
da1469x_clock_sys_rc32m_disable(void)
|
||||
{
|
||||
CRG_TOP->CLK_RC32M_REG &= ~CRG_TOP_CLK_RC32M_REG_RC32M_ENABLE_Msk;
|
||||
}
|
||||
|
||||
void
|
||||
da1469x_clock_lp_xtal32k_enable(void)
|
||||
{
|
||||
CRG_TOP->CLK_XTAL32K_REG |= CRG_TOP_CLK_XTAL32K_REG_XTAL32K_ENABLE_Msk;
|
||||
}
|
||||
|
||||
void
|
||||
da1469x_clock_lp_xtal32k_switch(void)
|
||||
{
|
||||
CRG_TOP->CLK_CTRL_REG = (CRG_TOP->CLK_CTRL_REG &
|
||||
~CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk) |
|
||||
(2 << CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos);
|
||||
}
|
||||
|
||||
void
|
||||
da1469x_clock_pll_disable(void)
|
||||
{
|
||||
while (CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_PLL96M_Msk) {
|
||||
CRG_TOP->CLK_SWITCH2XTAL_REG = CRG_TOP_CLK_SWITCH2XTAL_REG_SWITCH2XTAL_Msk;
|
||||
}
|
||||
|
||||
CRG_XTAL->PLL_SYS_CTRL1_REG &= ~CRG_XTAL_PLL_SYS_CTRL1_REG_PLL_EN_Msk;
|
||||
}
|
||||
|
||||
void
|
||||
da1469x_clock_pll_wait_to_lock(void)
|
||||
{
|
||||
uint32_t primask;
|
||||
|
||||
__HAL_DISABLE_INTERRUPTS(primask);
|
||||
|
||||
NVIC_ClearPendingIRQ(PLL_LOCK_IRQn);
|
||||
|
||||
if (!da1469x_clock_is_pll_locked()) {
|
||||
NVIC_EnableIRQ(PLL_LOCK_IRQn);
|
||||
while (!NVIC_GetPendingIRQ(PLL_LOCK_IRQn)) {
|
||||
__WFI();
|
||||
}
|
||||
NVIC_DisableIRQ(PLL_LOCK_IRQn);
|
||||
}
|
||||
|
||||
__HAL_ENABLE_INTERRUPTS(primask);
|
||||
}
|
||||
|
||||
void
|
||||
da1469x_clock_sys_pll_switch(void)
|
||||
{
|
||||
/* CLK_SEL_Msk == 3 means PLL */
|
||||
CRG_TOP->CLK_CTRL_REG |= CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Msk;
|
||||
|
||||
while (!(CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_PLL96M_Msk));
|
||||
}
|
||||
@@ -0,0 +1,478 @@
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include "syscfg/syscfg.h"
|
||||
#include "mcu/da1469x_hal.h"
|
||||
#include <mcu/mcu.h>
|
||||
#include "hal/hal_gpio.h"
|
||||
|
||||
/* GPIO interrupts */
|
||||
#define HAL_GPIO_MAX_IRQ MYNEWT_VAL(MCU_GPIO_MAX_IRQ)
|
||||
|
||||
#define GPIO_REG(name) ((__IO uint32_t *)(GPIO_BASE + offsetof(GPIO_Type, name)))
|
||||
#define WAKEUP_REG(name) ((__IO uint32_t *)(WAKEUP_BASE + offsetof(WAKEUP_Type, name)))
|
||||
#define CRG_TOP_REG(name) ((__IO uint32_t *)(CRG_TOP_BASE + offsetof(CRG_TOP_Type, name)))
|
||||
|
||||
#ifndef MCU_GPIO_PORT0_PIN_COUNT
|
||||
#define MCU_GPIO_PORT0_PIN_COUNT 32
|
||||
#endif
|
||||
|
||||
#if (MCU_GPIO_PORT0_PIN_COUNT) == 32
|
||||
#define GPIO_PORT(pin) (((unsigned)(pin)) >> 5U)
|
||||
#define GPIO_PORT_PIN(pin) (((unsigned)(pin)) & 31U)
|
||||
#else
|
||||
#define GPIO_PORT(pin) (((unsigned)(pin)) < MCU_GPIO_PORT0_PIN_COUNT ? 0 : 1)
|
||||
#define GPIO_PORT_PIN(pin) ((unsigned)(pin) < MCU_GPIO_PORT0_PIN_COUNT ? \
|
||||
(pin) : (pin) - MCU_GPIO_PORT0_PIN_COUNT)
|
||||
#endif
|
||||
|
||||
#define GPIO_PIN_BIT(pin) (1 << GPIO_PORT_PIN(pin))
|
||||
|
||||
#define GPIO_PIN_DATA_REG_ADDR(pin) (GPIO_REG(P0_DATA_REG) + GPIO_PORT(pin))
|
||||
#define GPIO_PIN_DATA_REG(pin) *GPIO_PIN_DATA_REG_ADDR(pin)
|
||||
#define GPIO_PIN_SET_DATA_REG_ADDR(pin) (GPIO_REG(P0_SET_DATA_REG) + GPIO_PORT(pin))
|
||||
#define GPIO_PIN_SET_DATA_REG(pin) *GPIO_PIN_SET_DATA_REG_ADDR(pin)
|
||||
#define GPIO_PIN_RESET_DATA_REG_ADDR(pin) (GPIO_REG(P0_RESET_DATA_REG) + GPIO_PORT(pin))
|
||||
#define GPIO_PIN_RESET_DATA_REG(pin) *GPIO_PIN_RESET_DATA_REG_ADDR(pin)
|
||||
#define GPIO_PIN_MODE_REG_ADDR(pin) (GPIO_REG(P0_00_MODE_REG) + (pin))
|
||||
#define GPIO_PIN_MODE_REG(pin) *GPIO_PIN_MODE_REG_ADDR(pin)
|
||||
#define GPIO_PIN_PADPWR_CTRL_REG_ADDR(pin) (GPIO_REG(P0_PADPWR_CTRL_REG) + GPIO_PORT(pin))
|
||||
#define GPIO_PIN_PADPWR_CTRL_REG(pin) *GPIO_PIN_PADPWR_CTRL_REG_ADDR(pin)
|
||||
#define GPIO_PIN_UNLATCH_ADDR(pin) (CRG_TOP_REG(P0_SET_PAD_LATCH_REG) + GPIO_PORT(pin) * 3)
|
||||
#define GPIO_PIN_LATCH_ADDR(pin) (CRG_TOP_REG(P0_RESET_PAD_LATCH_REG) + GPIO_PORT(pin) * 3)
|
||||
|
||||
#define WKUP_CTRL_REG_ADDR (WAKEUP_REG(WKUP_CTRL_REG))
|
||||
#define WKUP_RESET_IRQ_REG_ADDR (WAKEUP_REG(WKUP_RESET_IRQ_REG))
|
||||
#define WKUP_SELECT_PX_REG_ADDR(pin) (WAKEUP_REG(WKUP_SELECT_P0_REG) + GPIO_PORT(pin))
|
||||
#define WKUP_SELECT_PX_REG(pin) *(WKUP_SELECT_PX_REG_ADDR(pin))
|
||||
#define WKUP_POL_PX_REG_ADDR(pin) (WAKEUP_REG(WKUP_POL_P0_REG) + GPIO_PORT(pin))
|
||||
#define WKUP_POL_PX_SET_FALLING(pin) do { *(WKUP_POL_PX_REG_ADDR(pin)) |= GPIO_PIN_BIT(pin); } while (0)
|
||||
#define WKUP_POL_PX_SET_RISING(pin) do { *(WKUP_POL_PX_REG_ADDR(pin)) &= ~GPIO_PIN_BIT(pin); } while (0)
|
||||
#define WKUP_STAT_PX_REG_ADDR(pin) (WAKEUP_REG(WKUP_STATUS_P0_REG) + GPIO_PORT(pin))
|
||||
#define WKUP_STAT(pin) ((*(WKUP_STAT_PX_REG_ADDR(pin)) >> GPIO_PORT_PIN(pin)) & 1)
|
||||
#define WKUP_CLEAR_PX_REG_ADDR(pin) (WAKEUP_REG(WKUP_CLEAR_P0_REG) + GPIO_PORT(pin))
|
||||
#define WKUP_CLEAR_PX(pin) do { (*(WKUP_CLEAR_PX_REG_ADDR(pin)) = GPIO_PIN_BIT(pin)); } while (0)
|
||||
#define WKUP_SEL_GPIO_PX_REG_ADDR(pin) (WAKEUP_REG(WKUP_SEL_GPIO_P0_REG) + GPIO_PORT(pin))
|
||||
#define WKUP_SEL_GPIO_PX_REG(pin) *(WKUP_SEL_GPIO_PX_REG_ADDR(pin))
|
||||
|
||||
/* Storage for GPIO callbacks. */
|
||||
struct hal_gpio_irq {
|
||||
int pin;
|
||||
hal_gpio_irq_handler_t func;
|
||||
void *arg;
|
||||
};
|
||||
|
||||
static struct hal_gpio_irq hal_gpio_irqs[HAL_GPIO_MAX_IRQ];
|
||||
|
||||
#if MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM) >= 0
|
||||
static uint32_t g_mcu_gpio_latch_state[2];
|
||||
static uint8_t g_mcu_gpio_retained_num;
|
||||
static struct da1469x_retreg g_mcu_gpio_retained[MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM)];
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We assume that any latched pin has default configuration, i.e. was either
|
||||
* not configured or was deinited. Any unlatched pin is considered to be used
|
||||
* by someone.
|
||||
*
|
||||
* By default, all pins are assumed to have default configuration and are
|
||||
* latched. This allows PD_COM to be disabled (if no other peripheral needs
|
||||
* it) since we do not need GPIO mux to be active.
|
||||
*
|
||||
* Configuration of any pin shall be done as follows, with interrupts disabled:
|
||||
* 1. call mcu_gpio_unlatch_prepare() to enable PD_COM if needed
|
||||
* 2. configure pin
|
||||
* 3. call mcu_gpio_unlatch() to actually unlatch pin
|
||||
*
|
||||
* Once pin is restored to default configuration it shall be latched again by
|
||||
* calling mcu_gpio_latch().
|
||||
*/
|
||||
|
||||
#if MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM) >= 0
|
||||
static void
|
||||
mcu_gpio_retained_add_port(uint32_t latch_val, volatile uint32_t *base_reg)
|
||||
{
|
||||
struct da1469x_retreg *retreg;
|
||||
int pin;
|
||||
|
||||
retreg = &g_mcu_gpio_retained[g_mcu_gpio_retained_num];
|
||||
|
||||
while (latch_val) {
|
||||
assert(g_mcu_gpio_retained_num < MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM));
|
||||
|
||||
pin = __builtin_ctz(latch_val);
|
||||
latch_val &= ~(1 << pin);
|
||||
|
||||
da1469x_retreg_assign(retreg, &base_reg[pin]);
|
||||
|
||||
g_mcu_gpio_retained_num++;
|
||||
retreg++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
mcu_gpio_retained_refresh(void)
|
||||
{
|
||||
#if MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM) >= 0
|
||||
g_mcu_gpio_retained_num = 0;
|
||||
|
||||
mcu_gpio_retained_add_port(CRG_TOP->P0_PAD_LATCH_REG, &GPIO->P0_00_MODE_REG);
|
||||
mcu_gpio_retained_add_port(CRG_TOP->P1_PAD_LATCH_REG, &GPIO->P1_00_MODE_REG);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
mcu_gpio_unlatch_prepare(int pin)
|
||||
{
|
||||
__HAL_ASSERT_CRITICAL();
|
||||
(void)pin;
|
||||
|
||||
/* Acquire PD_COM if first pin will be unlatched */
|
||||
// if ((CRG_TOP->P0_PAD_LATCH_REG | CRG_TOP->P1_PAD_LATCH_REG) == 0) {
|
||||
// da1469x_pd_acquire(MCU_PD_DOMAIN_COM);
|
||||
// }
|
||||
}
|
||||
|
||||
static inline void
|
||||
mcu_gpio_unlatch(int pin)
|
||||
{
|
||||
__HAL_ASSERT_CRITICAL();
|
||||
|
||||
*GPIO_PIN_UNLATCH_ADDR(pin) = GPIO_PIN_BIT(pin);
|
||||
mcu_gpio_retained_refresh();
|
||||
}
|
||||
|
||||
static inline void
|
||||
mcu_gpio_latch(int pin)
|
||||
{
|
||||
(void)pin;
|
||||
// uint32_t primask;
|
||||
// uint32_t latch_pre;
|
||||
// uint32_t latch_post;
|
||||
//
|
||||
// __HAL_DISABLE_INTERRUPTS(primask);
|
||||
//
|
||||
// latch_pre = CRG_TOP->P0_PAD_LATCH_REG | CRG_TOP->P1_PAD_LATCH_REG;
|
||||
//
|
||||
// *GPIO_PIN_LATCH_ADDR(pin) = GPIO_PIN_BIT(pin);
|
||||
// mcu_gpio_retained_refresh();
|
||||
//
|
||||
// latch_post = CRG_TOP->P0_PAD_LATCH_REG | CRG_TOP->P1_PAD_LATCH_REG;
|
||||
//
|
||||
// /* Release PD_COM if last pin was latched */
|
||||
// if (latch_pre && !latch_post) {
|
||||
// da1469x_pd_release(MCU_PD_DOMAIN_COM);
|
||||
// }
|
||||
//
|
||||
// __HAL_ENABLE_INTERRUPTS(primask);
|
||||
}
|
||||
|
||||
int
|
||||
hal_gpio_init_in(int pin, hal_gpio_pull_t pull)
|
||||
{
|
||||
volatile uint32_t *px_xx_mod_reg = GPIO_PIN_MODE_REG_ADDR(pin);
|
||||
uint32_t regval;
|
||||
uint32_t primask;
|
||||
|
||||
switch (pull) {
|
||||
case HAL_GPIO_PULL_UP:
|
||||
regval = MCU_GPIO_FUNC_GPIO | MCU_GPIO_MODE_INPUT_PULLUP;
|
||||
break;
|
||||
case HAL_GPIO_PULL_DOWN:
|
||||
regval = MCU_GPIO_FUNC_GPIO | MCU_GPIO_MODE_INPUT_PULLDOWN;
|
||||
break;
|
||||
case HAL_GPIO_PULL_NONE:
|
||||
regval = MCU_GPIO_FUNC_GPIO | MCU_GPIO_MODE_INPUT;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
__HAL_DISABLE_INTERRUPTS(primask);
|
||||
|
||||
mcu_gpio_unlatch_prepare(pin);
|
||||
|
||||
*px_xx_mod_reg = regval;
|
||||
|
||||
mcu_gpio_unlatch(pin);
|
||||
|
||||
__HAL_ENABLE_INTERRUPTS(primask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hal_gpio_init_out(int pin, int val)
|
||||
{
|
||||
uint32_t primask;
|
||||
|
||||
__HAL_DISABLE_INTERRUPTS(primask);
|
||||
|
||||
mcu_gpio_unlatch_prepare(pin);
|
||||
|
||||
GPIO_PIN_MODE_REG(pin) = MCU_GPIO_MODE_OUTPUT;
|
||||
|
||||
if (val) {
|
||||
GPIO_PIN_SET_DATA_REG(pin) = GPIO_PIN_BIT(pin);
|
||||
} else {
|
||||
GPIO_PIN_RESET_DATA_REG(pin) = GPIO_PIN_BIT(pin);
|
||||
}
|
||||
|
||||
mcu_gpio_unlatch(pin);
|
||||
|
||||
__HAL_ENABLE_INTERRUPTS(primask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hal_gpio_deinit(int pin)
|
||||
{
|
||||
/* Reset mode to default value and latch pin */
|
||||
GPIO_PIN_MODE_REG(pin) = 0x200;
|
||||
GPIO_PIN_RESET_DATA_REG(pin) = GPIO_PIN_BIT(pin);
|
||||
|
||||
mcu_gpio_latch(pin);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
hal_gpio_write(int pin, int val)
|
||||
{
|
||||
if (val) {
|
||||
GPIO_PIN_SET_DATA_REG(pin) = GPIO_PIN_BIT(pin);
|
||||
} else {
|
||||
GPIO_PIN_RESET_DATA_REG(pin) = GPIO_PIN_BIT(pin);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
hal_gpio_read(int pin)
|
||||
{
|
||||
return (GPIO_PIN_DATA_REG(pin) >> GPIO_PORT_PIN(pin)) & 1;
|
||||
}
|
||||
|
||||
int
|
||||
hal_gpio_toggle(int pin)
|
||||
{
|
||||
int new_value = hal_gpio_read(pin) == 0;
|
||||
|
||||
hal_gpio_write(pin, new_value);
|
||||
|
||||
return new_value;
|
||||
}
|
||||
|
||||
static void
|
||||
hal_gpio_irq_handler(void)
|
||||
{
|
||||
struct hal_gpio_irq *irq;
|
||||
uint32_t stat;
|
||||
int i;
|
||||
|
||||
*WKUP_RESET_IRQ_REG_ADDR = 1;
|
||||
NVIC_ClearPendingIRQ(KEY_WKUP_GPIO_IRQn);
|
||||
|
||||
for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) {
|
||||
irq = &hal_gpio_irqs[i];
|
||||
|
||||
/* Read latched status value from relevant GPIO port */
|
||||
stat = WKUP_STAT(irq->pin);
|
||||
|
||||
if (irq->func && stat) {
|
||||
irq->func(irq->arg);
|
||||
}
|
||||
|
||||
WKUP_CLEAR_PX(irq->pin);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
hal_gpio_irq_setup(void)
|
||||
{
|
||||
static uint8_t irq_setup;
|
||||
int sr;
|
||||
|
||||
if (!irq_setup) {
|
||||
__HAL_DISABLE_INTERRUPTS(sr);
|
||||
|
||||
irq_setup = 1;
|
||||
|
||||
NVIC_ClearPendingIRQ(GPIO_P0_IRQn);
|
||||
NVIC_ClearPendingIRQ(GPIO_P1_IRQn);
|
||||
NVIC_SetVector(GPIO_P0_IRQn, (uint32_t)hal_gpio_irq_handler);
|
||||
NVIC_SetVector(GPIO_P1_IRQn, (uint32_t)hal_gpio_irq_handler);
|
||||
WAKEUP->WKUP_CTRL_REG = 0;
|
||||
WAKEUP->WKUP_CLEAR_P0_REG = 0xFFFFFFFF;
|
||||
WAKEUP->WKUP_CLEAR_P1_REG = 0x007FFFFF;
|
||||
WAKEUP->WKUP_SELECT_P0_REG = 0;
|
||||
WAKEUP->WKUP_SELECT_P1_REG = 0;
|
||||
WAKEUP->WKUP_SEL_GPIO_P0_REG = 0;
|
||||
WAKEUP->WKUP_SEL_GPIO_P1_REG = 0;
|
||||
WAKEUP->WKUP_RESET_IRQ_REG = 0;
|
||||
|
||||
CRG_TOP->CLK_TMR_REG |= CRG_TOP_CLK_TMR_REG_WAKEUPCT_ENABLE_Msk;
|
||||
|
||||
__HAL_ENABLE_INTERRUPTS(sr);
|
||||
NVIC_EnableIRQ(GPIO_P0_IRQn);
|
||||
NVIC_EnableIRQ(GPIO_P1_IRQn);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
hal_gpio_find_empty_slot(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) {
|
||||
if (hal_gpio_irqs[i].func == NULL) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
hal_gpio_irq_init(int pin, hal_gpio_irq_handler_t handler, void *arg,
|
||||
hal_gpio_irq_trig_t trig, hal_gpio_pull_t pull)
|
||||
{
|
||||
int i;
|
||||
|
||||
hal_gpio_irq_setup();
|
||||
|
||||
i = hal_gpio_find_empty_slot();
|
||||
/* If assert failed increase syscfg value MCU_GPIO_MAX_IRQ */
|
||||
assert(i >= 0);
|
||||
if (i < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
hal_gpio_init_in(pin, pull);
|
||||
|
||||
switch (trig) {
|
||||
case HAL_GPIO_TRIG_RISING:
|
||||
WKUP_POL_PX_SET_RISING(pin);
|
||||
break;
|
||||
case HAL_GPIO_TRIG_FALLING:
|
||||
WKUP_POL_PX_SET_FALLING(pin);
|
||||
break;
|
||||
case HAL_GPIO_TRIG_BOTH:
|
||||
/* Not supported */
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
hal_gpio_irqs[i].pin = pin;
|
||||
hal_gpio_irqs[i].func = handler;
|
||||
hal_gpio_irqs[i].arg = arg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
hal_gpio_irq_release(int pin)
|
||||
{
|
||||
int i;
|
||||
|
||||
hal_gpio_irq_disable(pin);
|
||||
|
||||
for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) {
|
||||
if (hal_gpio_irqs[i].pin == pin && hal_gpio_irqs[i].func) {
|
||||
hal_gpio_irqs[i].pin = -1;
|
||||
hal_gpio_irqs[i].arg = NULL;
|
||||
hal_gpio_irqs[i].func = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
hal_gpio_irq_enable(int pin)
|
||||
{
|
||||
WKUP_SEL_GPIO_PX_REG(pin) |= GPIO_PIN_BIT(pin);
|
||||
}
|
||||
|
||||
void
|
||||
hal_gpio_irq_disable(int pin)
|
||||
{
|
||||
WKUP_SEL_GPIO_PX_REG(pin) &= ~GPIO_PIN_BIT(pin);
|
||||
WKUP_CLEAR_PX(pin);
|
||||
}
|
||||
|
||||
void
|
||||
mcu_gpio_set_pin_function(int pin, int mode, mcu_gpio_func func)
|
||||
{
|
||||
uint32_t primask;
|
||||
|
||||
__HAL_DISABLE_INTERRUPTS(primask);
|
||||
|
||||
mcu_gpio_unlatch_prepare(pin);
|
||||
|
||||
GPIO_PIN_MODE_REG(pin) = (func & GPIO_P0_00_MODE_REG_PID_Msk) |
|
||||
(mode & (GPIO_P0_00_MODE_REG_PUPD_Msk | GPIO_P0_00_MODE_REG_PPOD_Msk));
|
||||
|
||||
mcu_gpio_unlatch(pin);
|
||||
|
||||
__HAL_ENABLE_INTERRUPTS(primask);
|
||||
}
|
||||
|
||||
void
|
||||
mcu_gpio_enter_sleep(void)
|
||||
{
|
||||
#if MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM) >= 0
|
||||
if (g_mcu_gpio_retained_num == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_mcu_gpio_latch_state[0] = CRG_TOP->P0_PAD_LATCH_REG;
|
||||
g_mcu_gpio_latch_state[1] = CRG_TOP->P1_PAD_LATCH_REG;
|
||||
|
||||
da1469x_retreg_update(g_mcu_gpio_retained, g_mcu_gpio_retained_num);
|
||||
|
||||
CRG_TOP->P0_RESET_PAD_LATCH_REG = CRG_TOP_P0_PAD_LATCH_REG_P0_LATCH_EN_Msk;
|
||||
CRG_TOP->P1_RESET_PAD_LATCH_REG = CRG_TOP_P1_PAD_LATCH_REG_P1_LATCH_EN_Msk;
|
||||
|
||||
da1469x_pd_release(MCU_PD_DOMAIN_COM);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
mcu_gpio_exit_sleep(void)
|
||||
{
|
||||
#if MYNEWT_VAL(MCU_GPIO_RETAINABLE_NUM) >= 0
|
||||
if (g_mcu_gpio_retained_num == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
da1469x_pd_acquire(MCU_PD_DOMAIN_COM);
|
||||
|
||||
da1469x_retreg_restore(g_mcu_gpio_retained, g_mcu_gpio_retained_num);
|
||||
|
||||
/* Set pins states to their latched values */
|
||||
GPIO->P0_DATA_REG = GPIO->P0_DATA_REG;
|
||||
GPIO->P1_DATA_REG = GPIO->P1_DATA_REG;
|
||||
|
||||
CRG_TOP->P0_PAD_LATCH_REG = g_mcu_gpio_latch_state[0];
|
||||
CRG_TOP->P1_PAD_LATCH_REG = g_mcu_gpio_latch_state[1];
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "syscfg/syscfg.h"
|
||||
#include "mcu/da1469x_clock.h"
|
||||
#include "mcu/da1469x_lpclk.h"
|
||||
#include "mcu/da1469x_pd.h"
|
||||
#include "mcu/da1469x_pdc.h"
|
||||
#include "mcu/da1469x_prail.h"
|
||||
#include "hal/hal_system.h"
|
||||
#include "os/os_cputime.h"
|
||||
|
||||
#if !MYNEWT_VAL(BOOT_LOADER)
|
||||
static enum hal_reset_reason g_hal_reset_reason;
|
||||
#endif
|
||||
|
||||
void
|
||||
hal_system_init(void)
|
||||
{
|
||||
#if MYNEWT_VAL(MCU_DCDC_ENABLE)
|
||||
da1469x_prail_dcdc_enable();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* RESET_STAT_REG has to be cleared to allow HW set bits during next reset
|
||||
* so we should read it now and keep result for application to check at any
|
||||
* time. This does not happen for bootloader since reading reset reason in
|
||||
* bootloader would prevent application from reading it.
|
||||
*/
|
||||
|
||||
#if !MYNEWT_VAL(BOOT_LOADER)
|
||||
uint32_t reg;
|
||||
|
||||
reg = CRG_TOP->RESET_STAT_REG;
|
||||
CRG_TOP->RESET_STAT_REG = 0;
|
||||
|
||||
if (reg & CRG_TOP_RESET_STAT_REG_PORESET_STAT_Msk) {
|
||||
g_hal_reset_reason = HAL_RESET_POR;
|
||||
} else if (reg & CRG_TOP_RESET_STAT_REG_WDOGRESET_STAT_Msk) {
|
||||
g_hal_reset_reason = HAL_RESET_WATCHDOG;
|
||||
} else if (reg & CRG_TOP_RESET_STAT_REG_SWRESET_STAT_Msk) {
|
||||
g_hal_reset_reason = HAL_RESET_SOFT;
|
||||
} else if (reg & CRG_TOP_RESET_STAT_REG_HWRESET_STAT_Msk) {
|
||||
g_hal_reset_reason = HAL_RESET_PIN;
|
||||
} else {
|
||||
g_hal_reset_reason = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
hal_system_reset(void)
|
||||
{
|
||||
|
||||
#if MYNEWT_VAL(HAL_SYSTEM_RESET_CB)
|
||||
hal_system_reset_cb();
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
HAL_DEBUG_BREAK();
|
||||
CRG_TOP->SYS_CTRL_REG = 0x20;
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
hal_debugger_connected(void)
|
||||
{
|
||||
return CRG_TOP->SYS_STAT_REG & CRG_TOP_SYS_STAT_REG_DBG_IS_ACTIVE_Msk;
|
||||
}
|
||||
|
||||
void
|
||||
hal_system_clock_start(void)
|
||||
{
|
||||
/* Reset clock dividers to 0 */
|
||||
CRG_TOP->CLK_AMBA_REG &= ~(CRG_TOP_CLK_AMBA_REG_HCLK_DIV_Msk | CRG_TOP_CLK_AMBA_REG_PCLK_DIV_Msk);
|
||||
|
||||
/* PD_TIM is already started in SystemInit */
|
||||
|
||||
da1469x_clock_sys_xtal32m_init();
|
||||
da1469x_clock_sys_xtal32m_enable();
|
||||
#if MYNEWT_VAL(MCU_PLL_ENABLE)
|
||||
da1469x_clock_sys_pll_enable();
|
||||
#endif
|
||||
#if MYNEWT_VAL_CHOICE(MCU_SYSCLK_SOURCE, PLL96)
|
||||
da1469x_clock_pll_wait_to_lock();
|
||||
da1469x_clock_sys_pll_switch();
|
||||
#endif
|
||||
#if MYNEWT_VAL_CHOICE(MCU_SYSCLK_SOURCE, XTAL32M)
|
||||
/* Switch to XTAL32M and disable RC32M */
|
||||
da1469x_clock_sys_xtal32m_switch_safe();
|
||||
#endif
|
||||
da1469x_clock_sys_rc32m_disable();
|
||||
|
||||
#if MYNEWT_VAL_CHOICE(MCU_LPCLK_SOURCE, RCX)
|
||||
/* Switch to RCX and calibrate it */
|
||||
da1469x_clock_lp_rcx_enable();
|
||||
da1469x_clock_lp_rcx_switch();
|
||||
da1469x_clock_lp_rcx_calibrate();
|
||||
da1469x_lpclk_enabled();
|
||||
#else
|
||||
/*
|
||||
* We cannot switch lp_clk to XTAL32K here since it needs some time to
|
||||
* settle, so we just disable RCX (we don't need it) and then we'll handle
|
||||
* switch to XTAL32K from sysinit since we need os_cputime for this.
|
||||
*/
|
||||
da1469x_clock_lp_rcx_disable();
|
||||
#endif
|
||||
}
|
||||
|
||||
enum hal_reset_reason
|
||||
hal_reset_cause(void)
|
||||
{
|
||||
#if MYNEWT_VAL(BOOT_LOADER)
|
||||
return 0;
|
||||
#else
|
||||
return g_hal_reset_reason;
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include "mcu/mcu.h"
|
||||
#include "mcu/da1469x_hal.h"
|
||||
#include <flash_map/flash_map.h>
|
||||
#include <mcu/da1469x_clock.h>
|
||||
#if MCUBOOT_MYNEWT
|
||||
#include "bootutil/bootutil.h"
|
||||
#include "bootutil/image.h"
|
||||
#include "bootutil/bootutil_log.h"
|
||||
#include "mcu/da1469x_dma.h"
|
||||
#include "mcu/da1469x_otp.h"
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BOOT_CUSTOM_START) && MCUBOOT_MYNEWT
|
||||
sec_text_ram_core
|
||||
#endif
|
||||
void __attribute__((naked))
|
||||
hal_system_start(void *img_start)
|
||||
{
|
||||
uint32_t img_data_addr;
|
||||
uint32_t *img_data;
|
||||
|
||||
img_data_addr = MCU_MEM_QSPIF_M_START_ADDRESS + (uint32_t)img_start;
|
||||
|
||||
assert(img_data_addr < MCU_MEM_QSPIF_M_END_ADDRESS);
|
||||
|
||||
img_data = (uint32_t *)img_data_addr;
|
||||
|
||||
asm volatile (".syntax unified \n"
|
||||
/* 1st word is stack pointer */
|
||||
" msr msp, %0 \n"
|
||||
/* 2nd word is a reset handler (image entry) */
|
||||
" bx %1 \n"
|
||||
: /* no output */
|
||||
: "r" (img_data[0]), "r" (img_data[1]));
|
||||
}
|
||||
|
||||
void
|
||||
hal_system_restart(void *img_start)
|
||||
{
|
||||
uint32_t primask __attribute__((unused));
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Disable interrupts, and leave them disabled.
|
||||
* They get re-enabled when system starts coming back again.
|
||||
*/
|
||||
__HAL_DISABLE_INTERRUPTS(primask);
|
||||
|
||||
for (i = 0; i < sizeof(NVIC->ICER) / sizeof(NVIC->ICER[0]); i++) {
|
||||
NVIC->ICER[i] = 0xffffffff;
|
||||
}
|
||||
|
||||
hal_system_start(img_start);
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BOOT_CUSTOM_START) && MCUBOOT_MYNEWT
|
||||
#define IMAGE_TLV_AES_NONCE 0x50
|
||||
#define IMAGE_TLV_SECRET_ID 0x60
|
||||
|
||||
sec_text_ram_core void
|
||||
boot_custom_start(uintptr_t flash_base, struct boot_rsp *rsp)
|
||||
{
|
||||
int rc;
|
||||
struct image_tlv_iter it;
|
||||
const struct flash_area *fap;
|
||||
uint32_t off;
|
||||
uint16_t len;
|
||||
uint16_t type;
|
||||
uint8_t buf[8];
|
||||
uint8_t key;
|
||||
uint32_t nonce[2];
|
||||
bool has_aes_nonce;
|
||||
bool has_secret_id;
|
||||
DMA_Type *dma_regs = DMA;
|
||||
uint32_t jump_offset = rsp->br_image_off + rsp->br_hdr->ih_hdr_size;
|
||||
|
||||
BOOT_LOG_INF("Custom initialization");
|
||||
|
||||
/* skip to booting if we are running nonsecure mode */
|
||||
if (!(CRG_TOP->SECURE_BOOT_REG & 0x1)) {
|
||||
hal_system_start((void *)(flash_base + jump_offset));
|
||||
}
|
||||
|
||||
rc = flash_area_open(flash_area_id_from_image_slot(0), &fap);
|
||||
assert(rc == 0);
|
||||
|
||||
rc = bootutil_tlv_iter_begin(&it, rsp->br_hdr, fap, IMAGE_TLV_ANY, true);
|
||||
assert(rc == 0);
|
||||
|
||||
has_aes_nonce = has_secret_id = false;
|
||||
while (true) {
|
||||
rc = bootutil_tlv_iter_next(&it, &off, &len, &type);
|
||||
assert(rc >= 0);
|
||||
|
||||
if (rc > 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (type == IMAGE_TLV_AES_NONCE) {
|
||||
assert(len == 8);
|
||||
|
||||
rc = flash_area_read(fap, off, buf, len);
|
||||
assert(rc == 0);
|
||||
|
||||
nonce[0] = __builtin_bswap32(*(uint32_t *)buf);
|
||||
nonce[1] = __builtin_bswap32(*(uint32_t *)(buf + 4));
|
||||
has_aes_nonce = true;
|
||||
} else if (type == IMAGE_TLV_SECRET_ID) {
|
||||
assert(len == 4);
|
||||
|
||||
rc = flash_area_read(fap, off, buf, len);
|
||||
assert(rc == 0);
|
||||
|
||||
key = buf[0];
|
||||
has_secret_id = true;
|
||||
}
|
||||
}
|
||||
|
||||
assert(has_aes_nonce && has_secret_id && key <= 7);
|
||||
|
||||
/* enable OTP clock and set in read mode */
|
||||
da1469x_clock_amba_enable(CRG_TOP_CLK_AMBA_REG_OTP_ENABLE_Msk);
|
||||
da1469x_otp_set_mode(OTPC_MODE_READ);
|
||||
|
||||
/* disable decrypt on the fly and program start and end addresses */
|
||||
QSPIC->QSPIC_CTR_CTRL_REG = 0;
|
||||
QSPIC->QSPIC_CTR_SADDR_REG = jump_offset;
|
||||
QSPIC->QSPIC_CTR_EADDR_REG = QSPIC->QSPIC_CTR_SADDR_REG +
|
||||
rsp->br_hdr->ih_img_size - 1;
|
||||
|
||||
/* securely DMA hardware key from secret storage to QSPI decrypt engine */
|
||||
dma_regs->DMA_REQ_MUX_REG |= 0xf000;
|
||||
dma_regs->DMA7_LEN_REG = 8;
|
||||
dma_regs->DMA7_A_START_REG = MCU_OTPM_BASE + OTP_SEGMENT_QSPI_FW_KEYS +
|
||||
(32 * key);
|
||||
dma_regs->DMA7_B_START_REG = (uint32_t)&QSPIC->QSPIC_CTR_KEY_0_3_REG;
|
||||
dma_regs->DMA7_CTRL_REG = DMA_DMA7_CTRL_REG_AINC_Msk |
|
||||
DMA_DMA7_CTRL_REG_BINC_Msk |
|
||||
(MCU_DMA_BUS_WIDTH_4B << DMA_DMA7_CTRL_REG_BW_Pos) |
|
||||
DMA_DMA7_CTRL_REG_DMA_ON_Msk;
|
||||
while (dma_regs->DMA7_IDX_REG != 8);
|
||||
|
||||
/* program NONCE */
|
||||
QSPIC->QSPIC_CTR_NONCE_0_3_REG = nonce[0];
|
||||
QSPIC->QSPIC_CTR_NONCE_4_7_REG = nonce[1];
|
||||
|
||||
/* turn back on decrypt on the fly */
|
||||
QSPIC->QSPIC_CTR_CTRL_REG = 1;
|
||||
|
||||
/* set OTP to standby and turn off clock */
|
||||
da1469x_otp_set_mode(OTPC_MODE_STBY);
|
||||
da1469x_clock_amba_disable(CRG_TOP_CLK_AMBA_REG_OTP_ENABLE_Msk);
|
||||
|
||||
hal_system_start((void *)(flash_base + jump_offset));
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include "mcu/mcu.h"
|
||||
#include <mcu/da1469x_clock.h>
|
||||
|
||||
extern uint8_t __StackLimit;
|
||||
|
||||
uint32_t SystemCoreClock = 32000000;
|
||||
|
||||
void
|
||||
SystemInit(void)
|
||||
{
|
||||
/* Enable FPU when using hard-float */
|
||||
#if (__FPU_USED == 1)
|
||||
SCB->CPACR |= (3UL << 20) | (3UL << 22);
|
||||
__DSB();
|
||||
__ISB();
|
||||
#endif
|
||||
|
||||
/* Freeze watchdog */
|
||||
GPREG->SET_FREEZE_REG |= GPREG_SET_FREEZE_REG_FRZ_SYS_WDOG_Msk;
|
||||
/* Initialize power domains (disable radio only) */
|
||||
CRG_TOP->PMU_CTRL_REG = CRG_TOP_PMU_CTRL_REG_RADIO_SLEEP_Msk;
|
||||
|
||||
CRG_TOP->P0_SET_PAD_LATCH_REG = CRG_TOP_P0_PAD_LATCH_REG_P0_LATCH_EN_Msk;
|
||||
CRG_TOP->P1_SET_PAD_LATCH_REG = CRG_TOP_P1_PAD_LATCH_REG_P1_LATCH_EN_Msk;
|
||||
|
||||
/* Reset clock dividers to 0 */
|
||||
CRG_TOP->CLK_AMBA_REG &= ~(CRG_TOP_CLK_AMBA_REG_HCLK_DIV_Msk | CRG_TOP_CLK_AMBA_REG_PCLK_DIV_Msk);
|
||||
|
||||
/* PD_TIM is already started in SystemInit */
|
||||
|
||||
da1469x_clock_sys_xtal32m_init();
|
||||
da1469x_clock_sys_xtal32m_enable();
|
||||
da1469x_clock_sys_pll_enable();
|
||||
da1469x_clock_pll_wait_to_lock();
|
||||
/* Switch to XTAL32M and disable RC32M */
|
||||
da1469x_clock_sys_xtal32m_switch_safe();
|
||||
da1469x_clock_sys_rc32m_disable();
|
||||
}
|
||||
|
||||
void _init(void)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,685 @@
|
||||
/*
|
||||
* Copyright (c) 2012 - 2018, Nordic Semiconductor ASA
|
||||
* 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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 Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup BLE_COMMON BLE SoftDevice Common
|
||||
@{
|
||||
@defgroup ble_api Events, type definitions and API calls
|
||||
@{
|
||||
|
||||
@brief Module independent events, type definitions and API calls for the BLE SoftDevice.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef BLE_H__
|
||||
#define BLE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "nrf_svc.h"
|
||||
#include "nrf_error.h"
|
||||
#include "ble_err.h"
|
||||
#include "ble_gap.h"
|
||||
#include "ble_l2cap.h"
|
||||
#include "ble_gatt.h"
|
||||
#include "ble_gattc.h"
|
||||
#include "ble_gatts.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup BLE_COMMON_ENUMERATIONS Enumerations
|
||||
* @{ */
|
||||
|
||||
/**
|
||||
* @brief Common API SVC numbers.
|
||||
*/
|
||||
enum BLE_COMMON_SVCS
|
||||
{
|
||||
SD_BLE_ENABLE = BLE_SVC_BASE, /**< Enable and initialize the BLE stack */
|
||||
SD_BLE_EVT_GET, /**< Get an event from the pending events queue. */
|
||||
SD_BLE_UUID_VS_ADD, /**< Add a Vendor Specific base UUID. */
|
||||
SD_BLE_UUID_DECODE, /**< Decode UUID bytes. */
|
||||
SD_BLE_UUID_ENCODE, /**< Encode UUID bytes. */
|
||||
SD_BLE_VERSION_GET, /**< Get the local version information (company ID, Link Layer Version, Link Layer Subversion). */
|
||||
SD_BLE_USER_MEM_REPLY, /**< User Memory Reply. */
|
||||
SD_BLE_OPT_SET, /**< Set a BLE option. */
|
||||
SD_BLE_OPT_GET, /**< Get a BLE option. */
|
||||
SD_BLE_CFG_SET, /**< Add a configuration to the BLE stack. */
|
||||
SD_BLE_UUID_VS_REMOVE, /**< Remove a Vendor Specific base UUID. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief BLE Module Independent Event IDs.
|
||||
*/
|
||||
enum BLE_COMMON_EVTS
|
||||
{
|
||||
BLE_EVT_USER_MEM_REQUEST = BLE_EVT_BASE + 0, /**< User Memory request. @ref ble_evt_user_mem_request_t */
|
||||
BLE_EVT_USER_MEM_RELEASE = BLE_EVT_BASE + 1, /**< User Memory release. @ref ble_evt_user_mem_release_t */
|
||||
};
|
||||
|
||||
/**@brief BLE Connection Configuration IDs.
|
||||
*
|
||||
* IDs that uniquely identify a connection configuration.
|
||||
*/
|
||||
enum BLE_CONN_CFGS
|
||||
{
|
||||
BLE_CONN_CFG_GAP = BLE_CONN_CFG_BASE + 0, /**< BLE GAP specific connection configuration. */
|
||||
BLE_CONN_CFG_GATTC = BLE_CONN_CFG_BASE + 1, /**< BLE GATTC specific connection configuration. */
|
||||
BLE_CONN_CFG_GATTS = BLE_CONN_CFG_BASE + 2, /**< BLE GATTS specific connection configuration. */
|
||||
BLE_CONN_CFG_GATT = BLE_CONN_CFG_BASE + 3, /**< BLE GATT specific connection configuration. */
|
||||
BLE_CONN_CFG_L2CAP = BLE_CONN_CFG_BASE + 4, /**< BLE L2CAP specific connection configuration. */
|
||||
};
|
||||
|
||||
/**@brief BLE Common Configuration IDs.
|
||||
*
|
||||
* IDs that uniquely identify a common configuration.
|
||||
*/
|
||||
enum BLE_COMMON_CFGS
|
||||
{
|
||||
BLE_COMMON_CFG_VS_UUID = BLE_CFG_BASE, /**< Vendor specific base UUID configuration */
|
||||
};
|
||||
|
||||
/**@brief Common Option IDs.
|
||||
* IDs that uniquely identify a common option.
|
||||
*/
|
||||
enum BLE_COMMON_OPTS
|
||||
{
|
||||
BLE_COMMON_OPT_PA_LNA = BLE_OPT_BASE + 0, /**< PA and LNA options */
|
||||
BLE_COMMON_OPT_CONN_EVT_EXT = BLE_OPT_BASE + 1, /**< Extended connection events option */
|
||||
BLE_COMMON_OPT_EXTENDED_RC_CAL = BLE_OPT_BASE + 2, /**< Extended RC calibration option */
|
||||
BLE_COMMON_OPT_ADV_SCHED_CFG = BLE_OPT_BASE + 3, /**< Advertiser role scheduling configuration option */
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup BLE_COMMON_DEFINES Defines
|
||||
* @{ */
|
||||
|
||||
/** @brief Required pointer alignment for BLE Events.
|
||||
*/
|
||||
#define BLE_EVT_PTR_ALIGNMENT 4
|
||||
|
||||
/** @brief Leaves the maximum of the two arguments.
|
||||
*/
|
||||
#define BLE_MAX(a, b) ((a) < (b) ? (b) : (a))
|
||||
|
||||
/** @brief Maximum possible length for BLE Events.
|
||||
* @note The highest value used for @ref ble_gatt_conn_cfg_t::att_mtu in any connection configuration shall be used as a parameter.
|
||||
* If that value has not been configured for any connections then @ref BLE_GATT_ATT_MTU_DEFAULT must be used instead.
|
||||
*/
|
||||
#define BLE_EVT_LEN_MAX(ATT_MTU) ( \
|
||||
offsetof(ble_evt_t, evt.gattc_evt.params.prim_srvc_disc_rsp.services) + ((ATT_MTU) - 1) / 4 * sizeof(ble_gattc_service_t) \
|
||||
)
|
||||
|
||||
/** @defgroup ADV_SCHED_CFG Advertiser Role Scheduling Configuration
|
||||
* @{ */
|
||||
#define ADV_SCHED_CFG_DEFAULT 0 /**< Default advertiser role scheduling configuration. */
|
||||
#define ADV_SCHED_CFG_IMPROVED 1 /**< Improved advertiser role scheduling configuration in which the housekeeping time is reduced. */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup BLE_USER_MEM_TYPES User Memory Types
|
||||
* @{ */
|
||||
#define BLE_USER_MEM_TYPE_INVALID 0x00 /**< Invalid User Memory Types. */
|
||||
#define BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES 0x01 /**< User Memory for GATTS queued writes. */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup BLE_UUID_VS_COUNTS Vendor Specific base UUID counts
|
||||
* @{
|
||||
*/
|
||||
#define BLE_UUID_VS_COUNT_DEFAULT 10 /**< Default VS UUID count. */
|
||||
#define BLE_UUID_VS_COUNT_MAX 254 /**< Maximum VS UUID count. */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup BLE_COMMON_CFG_DEFAULTS Configuration defaults.
|
||||
* @{
|
||||
*/
|
||||
#define BLE_CONN_CFG_TAG_DEFAULT 0 /**< Default configuration tag, SoftDevice default connection configuration. */
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup BLE_COMMON_STRUCTURES Structures
|
||||
* @{ */
|
||||
|
||||
/**@brief User Memory Block. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *p_mem; /**< Pointer to the start of the user memory block. */
|
||||
uint16_t len; /**< Length in bytes of the user memory block. */
|
||||
} ble_user_mem_block_t;
|
||||
|
||||
/**@brief Event structure for @ref BLE_EVT_USER_MEM_REQUEST. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */
|
||||
} ble_evt_user_mem_request_t;
|
||||
|
||||
/**@brief Event structure for @ref BLE_EVT_USER_MEM_RELEASE. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */
|
||||
ble_user_mem_block_t mem_block; /**< User memory block */
|
||||
} ble_evt_user_mem_release_t;
|
||||
|
||||
/**@brief Event structure for events not associated with a specific function module. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t conn_handle; /**< Connection Handle on which this event occurred. */
|
||||
union
|
||||
{
|
||||
ble_evt_user_mem_request_t user_mem_request; /**< User Memory Request Event Parameters. */
|
||||
ble_evt_user_mem_release_t user_mem_release; /**< User Memory Release Event Parameters. */
|
||||
} params; /**< Event parameter union. */
|
||||
} ble_common_evt_t;
|
||||
|
||||
/**@brief BLE Event header. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t evt_id; /**< Value from a BLE_<module>_EVT series. */
|
||||
uint16_t evt_len; /**< Length in octets including this header. */
|
||||
} ble_evt_hdr_t;
|
||||
|
||||
/**@brief Common BLE Event type, wrapping the module specific event reports. */
|
||||
typedef struct
|
||||
{
|
||||
ble_evt_hdr_t header; /**< Event header. */
|
||||
union
|
||||
{
|
||||
ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */
|
||||
ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */
|
||||
ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */
|
||||
ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */
|
||||
ble_l2cap_evt_t l2cap_evt; /**< L2CAP originated event, evt_id in BLE_L2CAP_EVT* series. */
|
||||
} evt; /**< Event union. */
|
||||
} ble_evt_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Version Information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t version_number; /**< Link Layer Version number. See https://www.bluetooth.org/en-us/specification/assigned-numbers/link-layer for assigned values. */
|
||||
uint16_t company_id; /**< Company ID, Nordic Semiconductor's company ID is 89 (0x0059) (https://www.bluetooth.org/apps/content/Default.aspx?doc_id=49708). */
|
||||
uint16_t subversion_number; /**< Link Layer Sub Version number, corresponds to the SoftDevice Config ID or Firmware ID (FWID). */
|
||||
} ble_version_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration parameters for the PA and LNA.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t enable :1; /**< Enable toggling for this amplifier */
|
||||
uint8_t active_high :1; /**< Set the pin to be active high */
|
||||
uint8_t gpio_pin :6; /**< The GPIO pin to toggle for this amplifier */
|
||||
} ble_pa_lna_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief PA & LNA GPIO toggle configuration
|
||||
*
|
||||
* This option configures the SoftDevice to toggle pins when the radio is active for use with a power amplifier and/or
|
||||
* a low noise amplifier.
|
||||
*
|
||||
* Toggling the pins is achieved by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided
|
||||
* by the application and should be regarded as reserved as long as any PA/LNA toggling is enabled.
|
||||
*
|
||||
* @note @ref sd_ble_opt_get is not supported for this option.
|
||||
* @note Setting this option while the radio is in use (i.e. any of the roles are active) may have undefined consequences
|
||||
* and must be avoided by the application.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ble_pa_lna_cfg_t pa_cfg; /**< Power Amplifier configuration */
|
||||
ble_pa_lna_cfg_t lna_cfg; /**< Low Noise Amplifier configuration */
|
||||
|
||||
uint8_t ppi_ch_id_set; /**< PPI channel used for radio pin setting */
|
||||
uint8_t ppi_ch_id_clr; /**< PPI channel used for radio pin clearing */
|
||||
uint8_t gpiote_ch_id; /**< GPIOTE channel used for radio pin toggling */
|
||||
} ble_common_opt_pa_lna_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration of extended BLE connection events.
|
||||
*
|
||||
* When enabled the SoftDevice will dynamically extend the connection event when possible.
|
||||
*
|
||||
* The connection event length is controlled by the connection configuration as set by @ref ble_gap_conn_cfg_t::event_length.
|
||||
* The connection event can be extended if there is time to send another packet pair before the start of the next connection interval,
|
||||
* and if there are no conflicts with other BLE roles requesting radio time.
|
||||
*
|
||||
* @note @ref sd_ble_opt_get is not supported for this option.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t enable : 1; /**< Enable extended BLE connection events, disabled by default. */
|
||||
} ble_common_opt_conn_evt_ext_t;
|
||||
|
||||
/**
|
||||
* @brief Enable/disable extended RC calibration.
|
||||
*
|
||||
* If extended RC calibration is enabled and the internal RC oscillator (@ref NRF_CLOCK_LF_SRC_RC) is used as the SoftDevice
|
||||
* LFCLK source, the SoftDevice as a peripheral will by default try to increase the receive window if two consecutive packets
|
||||
* are not received. If it turns out that the packets were not received due to clock drift, the RC calibration is started.
|
||||
* This calibration comes in addition to the periodic calibration that is configured by @ref sd_softdevice_enable(). When
|
||||
* using only peripheral connections, the periodic calibration can therefore be configured with a much longer interval as the
|
||||
* peripheral will be able to detect and adjust automatically to clock drift, and calibrate on demand.
|
||||
*
|
||||
* If extended RC calibration is disabled and the internal RC oscillator is used as the SoftDevice LFCLK source, the
|
||||
* RC oscillator is calibrated periodically as configured by @ref sd_softdevice_enable().
|
||||
*
|
||||
* @note @ref sd_ble_opt_get is not supported for this option.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t enable : 1; /**< Enable extended RC calibration, enabled by default. */
|
||||
} ble_common_opt_extended_rc_cal_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration of BLE advertiser role scheduling.
|
||||
*
|
||||
* @note @ref sd_ble_opt_get is not supported for this option.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t sched_cfg; /**< See @ref ADV_SCHED_CFG. */
|
||||
} ble_common_opt_adv_sched_cfg_t;
|
||||
|
||||
/**@brief Option structure for common options. */
|
||||
typedef union
|
||||
{
|
||||
ble_common_opt_pa_lna_t pa_lna; /**< Parameters for controlling PA and LNA pin toggling. */
|
||||
ble_common_opt_conn_evt_ext_t conn_evt_ext; /**< Parameters for enabling extended connection events. */
|
||||
ble_common_opt_extended_rc_cal_t extended_rc_cal; /**< Parameters for enabling extended RC calibration. */
|
||||
ble_common_opt_adv_sched_cfg_t adv_sched_cfg; /**< Parameters for configuring advertiser role scheduling. */
|
||||
} ble_common_opt_t;
|
||||
|
||||
/**@brief Common BLE Option type, wrapping the module specific options. */
|
||||
typedef union
|
||||
{
|
||||
ble_common_opt_t common_opt; /**< COMMON options, opt_id in @ref BLE_COMMON_OPTS series. */
|
||||
ble_gap_opt_t gap_opt; /**< GAP option, opt_id in @ref BLE_GAP_OPTS series. */
|
||||
} ble_opt_t;
|
||||
|
||||
/**@brief BLE connection configuration type, wrapping the module specific configurations, set with
|
||||
* @ref sd_ble_cfg_set.
|
||||
*
|
||||
* @note Connection configurations don't have to be set.
|
||||
* In the case that no configurations has been set, or fewer connection configurations has been set than enabled connections,
|
||||
* the default connection configuration will be automatically added for the remaining connections.
|
||||
* When creating connections with the default configuration, @ref BLE_CONN_CFG_TAG_DEFAULT should be used in
|
||||
* place of @ref ble_conn_cfg_t::conn_cfg_tag.
|
||||
*
|
||||
* @sa sd_ble_gap_adv_start()
|
||||
* @sa sd_ble_gap_connect()
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_CONN_CFG}
|
||||
* @endmscs
|
||||
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t conn_cfg_tag; /**< The application chosen tag it can use with the
|
||||
@ref sd_ble_gap_adv_start() and @ref sd_ble_gap_connect() calls
|
||||
to select this configuration when creating a connection.
|
||||
Must be different for all connection configurations added and not @ref BLE_CONN_CFG_TAG_DEFAULT. */
|
||||
union {
|
||||
ble_gap_conn_cfg_t gap_conn_cfg; /**< GAP connection configuration, cfg_id is @ref BLE_CONN_CFG_GAP. */
|
||||
ble_gattc_conn_cfg_t gattc_conn_cfg; /**< GATTC connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTC. */
|
||||
ble_gatts_conn_cfg_t gatts_conn_cfg; /**< GATTS connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTS. */
|
||||
ble_gatt_conn_cfg_t gatt_conn_cfg; /**< GATT connection configuration, cfg_id is @ref BLE_CONN_CFG_GATT. */
|
||||
ble_l2cap_conn_cfg_t l2cap_conn_cfg; /**< L2CAP connection configuration, cfg_id is @ref BLE_CONN_CFG_L2CAP. */
|
||||
} params; /**< Connection configuration union. */
|
||||
} ble_conn_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration of Vendor Specific base UUIDs, set with @ref sd_ble_cfg_set.
|
||||
*
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Too many UUIDs configured.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t vs_uuid_count; /**< Number of 128-bit Vendor Specific base UUID bases to allocate memory for.
|
||||
Default value is @ref BLE_UUID_VS_COUNT_DEFAULT. Maximum value is
|
||||
@ref BLE_UUID_VS_COUNT_MAX. */
|
||||
} ble_common_cfg_vs_uuid_t;
|
||||
|
||||
/**@brief Common BLE Configuration type, wrapping the common configurations. */
|
||||
typedef union
|
||||
{
|
||||
ble_common_cfg_vs_uuid_t vs_uuid_cfg; /**< Vendor Specific base UUID configuration, cfg_id is @ref BLE_COMMON_CFG_VS_UUID. */
|
||||
} ble_common_cfg_t;
|
||||
|
||||
/**@brief BLE Configuration type, wrapping the module specific configurations. */
|
||||
typedef union
|
||||
{
|
||||
ble_conn_cfg_t conn_cfg; /**< Connection specific configurations, cfg_id in @ref BLE_CONN_CFGS series. */
|
||||
ble_common_cfg_t common_cfg; /**< Global common configurations, cfg_id in @ref BLE_COMMON_CFGS series. */
|
||||
ble_gap_cfg_t gap_cfg; /**< Global GAP configurations, cfg_id in @ref BLE_GAP_CFGS series. */
|
||||
ble_gatts_cfg_t gatts_cfg; /**< Global GATTS configuration, cfg_id in @ref BLE_GATTS_CFGS series. */
|
||||
} ble_cfg_t;
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup BLE_COMMON_FUNCTIONS Functions
|
||||
* @{ */
|
||||
|
||||
/**@brief Enable the BLE stack
|
||||
*
|
||||
* @param[in, out] p_app_ram_base Pointer to a variable containing the start address of the
|
||||
* application RAM region (APP_RAM_BASE). On return, this will
|
||||
* contain the minimum start address of the application RAM region
|
||||
* required by the SoftDevice for this configuration.
|
||||
*
|
||||
* @note The memory requirement for a specific configuration will not increase between SoftDevices
|
||||
* with the same major version number.
|
||||
*
|
||||
* @note At runtime the IC's RAM is split into 2 regions: The SoftDevice RAM region is located
|
||||
* between 0x20000000 and APP_RAM_BASE-1 and the application's RAM region is located between
|
||||
* APP_RAM_BASE and the start of the call stack.
|
||||
*
|
||||
* @details This call initializes the BLE stack, no BLE related function other than @ref
|
||||
* sd_ble_cfg_set can be called before this one.
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_COMMON_ENABLE}
|
||||
* @endmscs
|
||||
*
|
||||
* @retval ::NRF_SUCCESS The BLE stack has been initialized successfully.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized and cannot be reinitialized.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied.
|
||||
* @retval ::NRF_ERROR_NO_MEM One or more of the following is true:
|
||||
* - The amount of memory assigned to the SoftDevice by *p_app_ram_base is not
|
||||
* large enough to fit this configuration's memory requirement. Check *p_app_ram_base
|
||||
* and set the start address of the application RAM region accordingly.
|
||||
* - Dynamic part of the SoftDevice RAM region is larger then 64 kB which
|
||||
* is currently not supported.
|
||||
* @retval ::NRF_ERROR_RESOURCES The total number of L2CAP Channels configured using @ref sd_ble_cfg_set is too large.
|
||||
*/
|
||||
SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(uint32_t * p_app_ram_base));
|
||||
|
||||
/**@brief Add configurations for the BLE stack
|
||||
*
|
||||
* @param[in] cfg_id Config ID, see @ref BLE_CONN_CFGS, @ref BLE_COMMON_CFGS, @ref
|
||||
* BLE_GAP_CFGS or @ref BLE_GATTS_CFGS.
|
||||
* @param[in] p_cfg Pointer to a ble_cfg_t structure containing the configuration value.
|
||||
* @param[in] app_ram_base The start address of the application RAM region (APP_RAM_BASE).
|
||||
* See @ref sd_ble_enable for details about APP_RAM_BASE.
|
||||
*
|
||||
* @note The memory requirement for a specific configuration will not increase between SoftDevices
|
||||
* with the same major version number.
|
||||
*
|
||||
* @note If a configuration is set more than once, the last one set is the one that takes effect on
|
||||
* @ref sd_ble_enable.
|
||||
*
|
||||
* @note Any part of the BLE stack that is NOT configured with @ref sd_ble_cfg_set will have default
|
||||
* configuration.
|
||||
*
|
||||
* @note @ref sd_ble_cfg_set may be called at any time when the SoftDevice is enabled (see @ref
|
||||
* sd_softdevice_enable) while the BLE part of the SoftDevice is not enabled (see @ref
|
||||
* sd_ble_enable).
|
||||
*
|
||||
* @note Error codes for the configurations are described in the configuration structs.
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_COMMON_ENABLE}
|
||||
* @endmscs
|
||||
*
|
||||
* @retval ::NRF_SUCCESS The configuration has been added successfully.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid cfg_id supplied.
|
||||
* @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by app_ram_base is not
|
||||
* large enough to fit this configuration's memory requirement.
|
||||
*/
|
||||
SVCALL(SD_BLE_CFG_SET, uint32_t, sd_ble_cfg_set(uint32_t cfg_id, ble_cfg_t const * p_cfg, uint32_t app_ram_base));
|
||||
|
||||
/**@brief Get an event from the pending events queue.
|
||||
*
|
||||
* @param[out] p_dest Pointer to buffer to be filled in with an event, or NULL to retrieve the event length.
|
||||
* This buffer <b>must be aligned to the extend defined by @ref BLE_EVT_PTR_ALIGNMENT</b>.
|
||||
* The buffer should be interpreted as a @ref ble_evt_t struct.
|
||||
* @param[in, out] p_len Pointer the length of the buffer, on return it is filled with the event length.
|
||||
*
|
||||
* @details This call allows the application to pull a BLE event from the BLE stack. The application is signaled that
|
||||
* an event is available from the BLE stack by the triggering of the SD_EVT_IRQn interrupt.
|
||||
* The application is free to choose whether to call this function from thread mode (main context) or directly from the
|
||||
* Interrupt Service Routine that maps to SD_EVT_IRQn. In any case however, and because the BLE stack runs at a higher
|
||||
* priority than the application, this function should be called in a loop (until @ref NRF_ERROR_NOT_FOUND is returned)
|
||||
* every time SD_EVT_IRQn is raised to ensure that all available events are pulled from the BLE stack. Failure to do so
|
||||
* could potentially leave events in the internal queue without the application being aware of this fact.
|
||||
*
|
||||
* Sizing the p_dest buffer is equally important, since the application needs to provide all the memory necessary for the event to
|
||||
* be copied into application memory. If the buffer provided is not large enough to fit the entire contents of the event,
|
||||
* @ref NRF_ERROR_DATA_SIZE will be returned and the application can then call again with a larger buffer size.
|
||||
* The maximum possible event length is defined by @ref BLE_EVT_LEN_MAX. The application may also "peek" the event length
|
||||
* by providing p_dest as a NULL pointer and inspecting the value of *p_len upon return:
|
||||
*
|
||||
* \code
|
||||
* uint16_t len;
|
||||
* errcode = sd_ble_evt_get(NULL, &len);
|
||||
* \endcode
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_COMMON_IRQ_EVT_MSC}
|
||||
* @mmsc{@ref BLE_COMMON_THREAD_EVT_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Event pulled and stored into the supplied buffer.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied.
|
||||
* @retval ::NRF_ERROR_NOT_FOUND No events ready to be pulled.
|
||||
* @retval ::NRF_ERROR_DATA_SIZE Event ready but could not fit into the supplied buffer.
|
||||
*/
|
||||
SVCALL(SD_BLE_EVT_GET, uint32_t, sd_ble_evt_get(uint8_t *p_dest, uint16_t *p_len));
|
||||
|
||||
|
||||
/**@brief Add a Vendor Specific base UUID.
|
||||
*
|
||||
* @details This call enables the application to add a Vendor Specific base UUID to the BLE stack's table, for later
|
||||
* use with all other modules and APIs. This then allows the application to use the shorter, 24-bit @ref ble_uuid_t
|
||||
* format when dealing with both 16-bit and 128-bit UUIDs without having to check for lengths and having split code
|
||||
* paths. This is accomplished by extending the grouping mechanism that the Bluetooth SIG standard base UUID uses
|
||||
* for all other 128-bit UUIDs. The type field in the @ref ble_uuid_t structure is an index (relative to
|
||||
* @ref BLE_UUID_TYPE_VENDOR_BEGIN) to the table populated by multiple calls to this function, and the UUID field
|
||||
* in the same structure contains the 2 bytes at indexes 12 and 13. The number of possible 128-bit UUIDs available to
|
||||
* the application is therefore the number of Vendor Specific UUIDs added with the help of this function times 65536,
|
||||
* although restricted to modifying bytes 12 and 13 for each of the entries in the supplied array.
|
||||
*
|
||||
* @note Bytes 12 and 13 of the provided UUID will not be used internally, since those are always replaced by
|
||||
* the 16-bit uuid field in @ref ble_uuid_t.
|
||||
*
|
||||
* @note If a UUID is already present in the BLE stack's internal table, the corresponding index will be returned in
|
||||
* p_uuid_type along with an @ref NRF_SUCCESS error code.
|
||||
*
|
||||
* @param[in] p_vs_uuid Pointer to a 16-octet (128-bit) little endian Vendor Specific base UUID disregarding
|
||||
* bytes 12 and 13.
|
||||
* @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponding to this UUID will be stored.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully added the Vendor Specific base UUID.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR If p_vs_uuid or p_uuid_type is NULL or invalid.
|
||||
* @retval ::NRF_ERROR_NO_MEM If there are no more free slots for VS UUIDs.
|
||||
*/
|
||||
SVCALL(SD_BLE_UUID_VS_ADD, uint32_t, sd_ble_uuid_vs_add(ble_uuid128_t const *p_vs_uuid, uint8_t *p_uuid_type));
|
||||
|
||||
|
||||
/**@brief Remove a Vendor Specific base UUID.
|
||||
*
|
||||
* @details This call removes a Vendor Specific base UUID that has been added with @ref sd_ble_uuid_vs_add. This function allows
|
||||
* the application to reuse memory allocated for Vendor Specific base UUIDs.
|
||||
*
|
||||
* @note Currently this function can only be called with a p_uuid_type set to @ref BLE_UUID_TYPE_UNKNOWN or the last added UUID type.
|
||||
*
|
||||
* @param[in] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t::type corresponds to the UUID type that
|
||||
* shall be removed. If the type is set to @ref BLE_UUID_TYPE_UNKNOWN, or the pointer is NULL, the last
|
||||
* Vendor Specific base UUID will be removed.
|
||||
* @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponds to the UUID type that was
|
||||
* removed. If function returns with a failure, it contains the last type that is in use by the ATT Server.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully removed the Vendor Specific base UUID.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR If p_uuid_type is invalid.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM If p_uuid_type points to a non-valid UUID type.
|
||||
* @retval ::NRF_ERROR_FORBIDDEN If the Vendor Specific base UUID is in use by the ATT Server.
|
||||
*/
|
||||
|
||||
SVCALL(SD_BLE_UUID_VS_REMOVE, uint32_t, sd_ble_uuid_vs_remove(uint8_t *p_uuid_type));
|
||||
|
||||
|
||||
/** @brief Decode little endian raw UUID bytes (16-bit or 128-bit) into a 24 bit @ref ble_uuid_t structure.
|
||||
*
|
||||
* @details The raw UUID bytes excluding bytes 12 and 13 (i.e. bytes 0-11 and 14-15) of p_uuid_le are compared
|
||||
* to the corresponding ones in each entry of the table of Vendor Specific base UUIDs populated with @ref sd_ble_uuid_vs_add
|
||||
* to look for a match. If there is such a match, bytes 12 and 13 are returned as p_uuid->uuid and the index
|
||||
* relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN as p_uuid->type.
|
||||
*
|
||||
* @note If the UUID length supplied is 2, then the type set by this call will always be @ref BLE_UUID_TYPE_BLE.
|
||||
*
|
||||
* @param[in] uuid_le_len Length in bytes of the buffer pointed to by p_uuid_le (must be 2 or 16 bytes).
|
||||
* @param[in] p_uuid_le Pointer pointing to little endian raw UUID bytes.
|
||||
* @param[out] p_uuid Pointer to a @ref ble_uuid_t structure to be filled in.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully decoded into the @ref ble_uuid_t structure.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_INVALID_LENGTH Invalid UUID length.
|
||||
* @retval ::NRF_ERROR_NOT_FOUND For a 128-bit UUID, no match in the populated table of UUIDs.
|
||||
*/
|
||||
SVCALL(SD_BLE_UUID_DECODE, uint32_t, sd_ble_uuid_decode(uint8_t uuid_le_len, uint8_t const *p_uuid_le, ble_uuid_t *p_uuid));
|
||||
|
||||
|
||||
/** @brief Encode a @ref ble_uuid_t structure into little endian raw UUID bytes (16-bit or 128-bit).
|
||||
*
|
||||
* @note The pointer to the destination buffer p_uuid_le may be NULL, in which case only the validity and size of p_uuid is computed.
|
||||
*
|
||||
* @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes.
|
||||
* @param[out] p_uuid_le_len Pointer to a uint8_t that will be filled with the encoded length (2 or 16 bytes).
|
||||
* @param[out] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes (2 or 16) will be stored.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully encoded into the buffer.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid UUID type.
|
||||
*/
|
||||
SVCALL(SD_BLE_UUID_ENCODE, uint32_t, sd_ble_uuid_encode(ble_uuid_t const *p_uuid, uint8_t *p_uuid_le_len, uint8_t *p_uuid_le));
|
||||
|
||||
|
||||
/**@brief Get Version Information.
|
||||
*
|
||||
* @details This call allows the application to get the BLE stack version information.
|
||||
*
|
||||
* @param[out] p_version Pointer to a ble_version_t structure to be filled in.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Version information stored successfully.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_BUSY The BLE stack is busy (typically doing a locally-initiated disconnection procedure).
|
||||
*/
|
||||
SVCALL(SD_BLE_VERSION_GET, uint32_t, sd_ble_version_get(ble_version_t *p_version));
|
||||
|
||||
|
||||
/**@brief Provide a user memory block.
|
||||
*
|
||||
* @note This call can only be used as a response to a @ref BLE_EVT_USER_MEM_REQUEST event issued to the application.
|
||||
*
|
||||
* @param[in] conn_handle Connection handle.
|
||||
* @param[in] p_block Pointer to a user memory block structure or NULL if memory is managed by the application.
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC}
|
||||
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC}
|
||||
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC}
|
||||
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC}
|
||||
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_NOAUTH_MSC}
|
||||
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully queued a response to the peer.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_LENGTH Invalid user memory block length supplied.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no user memory request pending.
|
||||
*/
|
||||
SVCALL(SD_BLE_USER_MEM_REPLY, uint32_t, sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block));
|
||||
|
||||
/**@brief Set a BLE option.
|
||||
*
|
||||
* @details This call allows the application to set the value of an option.
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS.
|
||||
* @param[in] p_opt Pointer to a ble_opt_t structure containing the option value.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Option set successfully.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Unable to set the parameter at this time.
|
||||
* @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed.
|
||||
*/
|
||||
SVCALL(SD_BLE_OPT_SET, uint32_t, sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt));
|
||||
|
||||
|
||||
/**@brief Get a BLE option.
|
||||
*
|
||||
* @details This call allows the application to retrieve the value of an option.
|
||||
*
|
||||
* @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS.
|
||||
* @param[out] p_opt Pointer to a ble_opt_t structure to be filled in.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Option retrieved successfully.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Unable to retrieve the parameter at this time.
|
||||
* @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed.
|
||||
* @retval ::NRF_ERROR_NOT_SUPPORTED This option is not supported.
|
||||
*
|
||||
*/
|
||||
SVCALL(SD_BLE_OPT_GET, uint32_t, sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt));
|
||||
|
||||
/** @} */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* BLE_H__ */
|
||||
|
||||
/**
|
||||
@}
|
||||
@}
|
||||
*/
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2012 - 2018, Nordic Semiconductor ASA
|
||||
* 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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 Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup BLE_COMMON
|
||||
@{
|
||||
@addtogroup nrf_error
|
||||
@{
|
||||
@ingroup BLE_COMMON
|
||||
@}
|
||||
|
||||
@defgroup ble_err General error codes
|
||||
@{
|
||||
|
||||
@brief General error code definitions for the BLE API.
|
||||
|
||||
@ingroup BLE_COMMON
|
||||
*/
|
||||
#ifndef NRF_BLE_ERR_H__
|
||||
#define NRF_BLE_ERR_H__
|
||||
|
||||
#include "nrf_error.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* @defgroup BLE_ERRORS Error Codes
|
||||
* @{ */
|
||||
#define BLE_ERROR_NOT_ENABLED (NRF_ERROR_STK_BASE_NUM+0x001) /**< @ref sd_ble_enable has not been called. */
|
||||
#define BLE_ERROR_INVALID_CONN_HANDLE (NRF_ERROR_STK_BASE_NUM+0x002) /**< Invalid connection handle. */
|
||||
#define BLE_ERROR_INVALID_ATTR_HANDLE (NRF_ERROR_STK_BASE_NUM+0x003) /**< Invalid attribute handle. */
|
||||
#define BLE_ERROR_INVALID_ADV_HANDLE (NRF_ERROR_STK_BASE_NUM+0x004) /**< Invalid advertising handle. */
|
||||
#define BLE_ERROR_INVALID_ROLE (NRF_ERROR_STK_BASE_NUM+0x005) /**< Invalid role. */
|
||||
#define BLE_ERROR_BLOCKED_BY_OTHER_LINKS (NRF_ERROR_STK_BASE_NUM+0x006) /**< The attempt to change link settings failed due to the scheduling of other links. */
|
||||
/** @} */
|
||||
|
||||
|
||||
/** @defgroup BLE_ERROR_SUBRANGES Module specific error code subranges
|
||||
* @brief Assignment of subranges for module specific error codes.
|
||||
* @note For specific error codes, see ble_<module>.h or ble_error_<module>.h.
|
||||
* @{ */
|
||||
#define NRF_L2CAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x100) /**< L2CAP specific errors. */
|
||||
#define NRF_GAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x200) /**< GAP specific errors. */
|
||||
#define NRF_GATTC_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x300) /**< GATT client specific errors. */
|
||||
#define NRF_GATTS_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x400) /**< GATT server specific errors. */
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
@}
|
||||
@}
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
|
||||
* 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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 Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup BLE_GATT Generic Attribute Profile (GATT) Common
|
||||
@{
|
||||
@brief Common definitions and prototypes for the GATT interfaces.
|
||||
*/
|
||||
|
||||
#ifndef BLE_GATT_H__
|
||||
#define BLE_GATT_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "nrf_svc.h"
|
||||
#include "nrf_error.h"
|
||||
#include "ble_hci.h"
|
||||
#include "ble_ranges.h"
|
||||
#include "ble_types.h"
|
||||
#include "ble_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup BLE_GATT_DEFINES Defines
|
||||
* @{ */
|
||||
|
||||
/** @brief Default ATT MTU, in bytes. */
|
||||
#define BLE_GATT_ATT_MTU_DEFAULT 23
|
||||
|
||||
/**@brief Invalid Attribute Handle. */
|
||||
#define BLE_GATT_HANDLE_INVALID 0x0000
|
||||
|
||||
/**@brief First Attribute Handle. */
|
||||
#define BLE_GATT_HANDLE_START 0x0001
|
||||
|
||||
/**@brief Last Attribute Handle. */
|
||||
#define BLE_GATT_HANDLE_END 0xFFFF
|
||||
|
||||
/** @defgroup BLE_GATT_TIMEOUT_SOURCES GATT Timeout sources
|
||||
* @{ */
|
||||
#define BLE_GATT_TIMEOUT_SRC_PROTOCOL 0x00 /**< ATT Protocol timeout. */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup BLE_GATT_WRITE_OPS GATT Write operations
|
||||
* @{ */
|
||||
#define BLE_GATT_OP_INVALID 0x00 /**< Invalid Operation. */
|
||||
#define BLE_GATT_OP_WRITE_REQ 0x01 /**< Write Request. */
|
||||
#define BLE_GATT_OP_WRITE_CMD 0x02 /**< Write Command. */
|
||||
#define BLE_GATT_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */
|
||||
#define BLE_GATT_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */
|
||||
#define BLE_GATT_OP_EXEC_WRITE_REQ 0x05 /**< Execute Write Request. */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup BLE_GATT_EXEC_WRITE_FLAGS GATT Execute Write flags
|
||||
* @{ */
|
||||
#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL 0x00 /**< Cancel prepared write. */
|
||||
#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE 0x01 /**< Execute prepared write. */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup BLE_GATT_HVX_TYPES GATT Handle Value operations
|
||||
* @{ */
|
||||
#define BLE_GATT_HVX_INVALID 0x00 /**< Invalid Operation. */
|
||||
#define BLE_GATT_HVX_NOTIFICATION 0x01 /**< Handle Value Notification. */
|
||||
#define BLE_GATT_HVX_INDICATION 0x02 /**< Handle Value Indication. */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup BLE_GATT_STATUS_CODES GATT Status Codes
|
||||
* @{ */
|
||||
#define BLE_GATT_STATUS_SUCCESS 0x0000 /**< Success. */
|
||||
#define BLE_GATT_STATUS_UNKNOWN 0x0001 /**< Unknown or not applicable status. */
|
||||
#define BLE_GATT_STATUS_ATTERR_INVALID 0x0100 /**< ATT Error: Invalid Error Code. */
|
||||
#define BLE_GATT_STATUS_ATTERR_INVALID_HANDLE 0x0101 /**< ATT Error: Invalid Attribute Handle. */
|
||||
#define BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED 0x0102 /**< ATT Error: Read not permitted. */
|
||||
#define BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED 0x0103 /**< ATT Error: Write not permitted. */
|
||||
#define BLE_GATT_STATUS_ATTERR_INVALID_PDU 0x0104 /**< ATT Error: Used in ATT as Invalid PDU. */
|
||||
#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION 0x0105 /**< ATT Error: Authenticated link required. */
|
||||
#define BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED 0x0106 /**< ATT Error: Used in ATT as Request Not Supported. */
|
||||
#define BLE_GATT_STATUS_ATTERR_INVALID_OFFSET 0x0107 /**< ATT Error: Offset specified was past the end of the attribute. */
|
||||
#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION 0x0108 /**< ATT Error: Used in ATT as Insufficient Authorization. */
|
||||
#define BLE_GATT_STATUS_ATTERR_PREPARE_QUEUE_FULL 0x0109 /**< ATT Error: Used in ATT as Prepare Queue Full. */
|
||||
#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND 0x010A /**< ATT Error: Used in ATT as Attribute not found. */
|
||||
#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_LONG 0x010B /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */
|
||||
#define BLE_GATT_STATUS_ATTERR_INSUF_ENC_KEY_SIZE 0x010C /**< ATT Error: Encryption key size used is insufficient. */
|
||||
#define BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH 0x010D /**< ATT Error: Invalid value size. */
|
||||
#define BLE_GATT_STATUS_ATTERR_UNLIKELY_ERROR 0x010E /**< ATT Error: Very unlikely error. */
|
||||
#define BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION 0x010F /**< ATT Error: Encrypted link required. */
|
||||
#define BLE_GATT_STATUS_ATTERR_UNSUPPORTED_GROUP_TYPE 0x0110 /**< ATT Error: Attribute type is not a supported grouping attribute. */
|
||||
#define BLE_GATT_STATUS_ATTERR_INSUF_RESOURCES 0x0111 /**< ATT Error: Encrypted link required. */
|
||||
#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_BEGIN 0x0112 /**< ATT Error: Reserved for Future Use range #1 begin. */
|
||||
#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_END 0x017F /**< ATT Error: Reserved for Future Use range #1 end. */
|
||||
#define BLE_GATT_STATUS_ATTERR_APP_BEGIN 0x0180 /**< ATT Error: Application range begin. */
|
||||
#define BLE_GATT_STATUS_ATTERR_APP_END 0x019F /**< ATT Error: Application range end. */
|
||||
#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_BEGIN 0x01A0 /**< ATT Error: Reserved for Future Use range #2 begin. */
|
||||
#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_END 0x01DF /**< ATT Error: Reserved for Future Use range #2 end. */
|
||||
#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_BEGIN 0x01E0 /**< ATT Error: Reserved for Future Use range #3 begin. */
|
||||
#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_END 0x01FC /**< ATT Error: Reserved for Future Use range #3 end. */
|
||||
#define BLE_GATT_STATUS_ATTERR_CPS_WRITE_REQ_REJECTED 0x01FC /**< ATT Common Profile and Service Error: Write request rejected. */
|
||||
#define BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR 0x01FD /**< ATT Common Profile and Service Error: Client Characteristic Configuration Descriptor improperly configured. */
|
||||
#define BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG 0x01FE /**< ATT Common Profile and Service Error: Procedure Already in Progress. */
|
||||
#define BLE_GATT_STATUS_ATTERR_CPS_OUT_OF_RANGE 0x01FF /**< ATT Common Profile and Service Error: Out Of Range. */
|
||||
/** @} */
|
||||
|
||||
|
||||
/** @defgroup BLE_GATT_CPF_FORMATS Characteristic Presentation Formats
|
||||
* @note Found at http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml
|
||||
* @{ */
|
||||
#define BLE_GATT_CPF_FORMAT_RFU 0x00 /**< Reserved For Future Use. */
|
||||
#define BLE_GATT_CPF_FORMAT_BOOLEAN 0x01 /**< Boolean. */
|
||||
#define BLE_GATT_CPF_FORMAT_2BIT 0x02 /**< Unsigned 2-bit integer. */
|
||||
#define BLE_GATT_CPF_FORMAT_NIBBLE 0x03 /**< Unsigned 4-bit integer. */
|
||||
#define BLE_GATT_CPF_FORMAT_UINT8 0x04 /**< Unsigned 8-bit integer. */
|
||||
#define BLE_GATT_CPF_FORMAT_UINT12 0x05 /**< Unsigned 12-bit integer. */
|
||||
#define BLE_GATT_CPF_FORMAT_UINT16 0x06 /**< Unsigned 16-bit integer. */
|
||||
#define BLE_GATT_CPF_FORMAT_UINT24 0x07 /**< Unsigned 24-bit integer. */
|
||||
#define BLE_GATT_CPF_FORMAT_UINT32 0x08 /**< Unsigned 32-bit integer. */
|
||||
#define BLE_GATT_CPF_FORMAT_UINT48 0x09 /**< Unsigned 48-bit integer. */
|
||||
#define BLE_GATT_CPF_FORMAT_UINT64 0x0A /**< Unsigned 64-bit integer. */
|
||||
#define BLE_GATT_CPF_FORMAT_UINT128 0x0B /**< Unsigned 128-bit integer. */
|
||||
#define BLE_GATT_CPF_FORMAT_SINT8 0x0C /**< Signed 2-bit integer. */
|
||||
#define BLE_GATT_CPF_FORMAT_SINT12 0x0D /**< Signed 12-bit integer. */
|
||||
#define BLE_GATT_CPF_FORMAT_SINT16 0x0E /**< Signed 16-bit integer. */
|
||||
#define BLE_GATT_CPF_FORMAT_SINT24 0x0F /**< Signed 24-bit integer. */
|
||||
#define BLE_GATT_CPF_FORMAT_SINT32 0x10 /**< Signed 32-bit integer. */
|
||||
#define BLE_GATT_CPF_FORMAT_SINT48 0x11 /**< Signed 48-bit integer. */
|
||||
#define BLE_GATT_CPF_FORMAT_SINT64 0x12 /**< Signed 64-bit integer. */
|
||||
#define BLE_GATT_CPF_FORMAT_SINT128 0x13 /**< Signed 128-bit integer. */
|
||||
#define BLE_GATT_CPF_FORMAT_FLOAT32 0x14 /**< IEEE-754 32-bit floating point. */
|
||||
#define BLE_GATT_CPF_FORMAT_FLOAT64 0x15 /**< IEEE-754 64-bit floating point. */
|
||||
#define BLE_GATT_CPF_FORMAT_SFLOAT 0x16 /**< IEEE-11073 16-bit SFLOAT. */
|
||||
#define BLE_GATT_CPF_FORMAT_FLOAT 0x17 /**< IEEE-11073 32-bit FLOAT. */
|
||||
#define BLE_GATT_CPF_FORMAT_DUINT16 0x18 /**< IEEE-20601 format. */
|
||||
#define BLE_GATT_CPF_FORMAT_UTF8S 0x19 /**< UTF-8 string. */
|
||||
#define BLE_GATT_CPF_FORMAT_UTF16S 0x1A /**< UTF-16 string. */
|
||||
#define BLE_GATT_CPF_FORMAT_STRUCT 0x1B /**< Opaque Structure. */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup BLE_GATT_CPF_NAMESPACES GATT Bluetooth Namespaces
|
||||
* @{
|
||||
*/
|
||||
#define BLE_GATT_CPF_NAMESPACE_BTSIG 0x01 /**< Bluetooth SIG defined Namespace. */
|
||||
#define BLE_GATT_CPF_NAMESPACE_DESCRIPTION_UNKNOWN 0x0000 /**< Namespace Description Unknown. */
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup BLE_GATT_STRUCTURES Structures
|
||||
* @{ */
|
||||
|
||||
/**
|
||||
* @brief BLE GATT connection configuration parameters, set with @ref sd_ble_cfg_set.
|
||||
*
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM att_mtu is smaller than @ref BLE_GATT_ATT_MTU_DEFAULT.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t att_mtu; /**< Maximum size of ATT packet the SoftDevice can send or receive.
|
||||
The default and minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT.
|
||||
@mscs
|
||||
@mmsc{@ref BLE_GATTC_MTU_EXCHANGE}
|
||||
@mmsc{@ref BLE_GATTS_MTU_EXCHANGE}
|
||||
@endmscs
|
||||
*/
|
||||
} ble_gatt_conn_cfg_t;
|
||||
|
||||
/**@brief GATT Characteristic Properties. */
|
||||
typedef struct
|
||||
{
|
||||
/* Standard properties */
|
||||
uint8_t broadcast :1; /**< Broadcasting of the value permitted. */
|
||||
uint8_t read :1; /**< Reading the value permitted. */
|
||||
uint8_t write_wo_resp :1; /**< Writing the value with Write Command permitted. */
|
||||
uint8_t write :1; /**< Writing the value with Write Request permitted. */
|
||||
uint8_t notify :1; /**< Notification of the value permitted. */
|
||||
uint8_t indicate :1; /**< Indications of the value permitted. */
|
||||
uint8_t auth_signed_wr :1; /**< Writing the value with Signed Write Command permitted. */
|
||||
} ble_gatt_char_props_t;
|
||||
|
||||
/**@brief GATT Characteristic Extended Properties. */
|
||||
typedef struct
|
||||
{
|
||||
/* Extended properties */
|
||||
uint8_t reliable_wr :1; /**< Writing the value with Queued Write operations permitted. */
|
||||
uint8_t wr_aux :1; /**< Writing the Characteristic User Description descriptor permitted. */
|
||||
} ble_gatt_char_ext_props_t;
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // BLE_GATT_H__
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,715 @@
|
||||
/*
|
||||
* Copyright (c) 2011 - 2017, Nordic Semiconductor ASA
|
||||
* 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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 Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup BLE_GATTC Generic Attribute Profile (GATT) Client
|
||||
@{
|
||||
@brief Definitions and prototypes for the GATT Client interface.
|
||||
*/
|
||||
|
||||
#ifndef BLE_GATTC_H__
|
||||
#define BLE_GATTC_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "nrf.h"
|
||||
#include "nrf_svc.h"
|
||||
#include "nrf_error.h"
|
||||
#include "ble_ranges.h"
|
||||
#include "ble_types.h"
|
||||
#include "ble_err.h"
|
||||
#include "ble_gatt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup BLE_GATTC_ENUMERATIONS Enumerations
|
||||
* @{ */
|
||||
|
||||
/**@brief GATTC API SVC numbers. */
|
||||
enum BLE_GATTC_SVCS
|
||||
{
|
||||
SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER = BLE_GATTC_SVC_BASE, /**< Primary Service Discovery. */
|
||||
SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, /**< Relationship Discovery. */
|
||||
SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, /**< Characteristic Discovery. */
|
||||
SD_BLE_GATTC_DESCRIPTORS_DISCOVER, /**< Characteristic Descriptor Discovery. */
|
||||
SD_BLE_GATTC_ATTR_INFO_DISCOVER, /**< Attribute Information Discovery. */
|
||||
SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, /**< Read Characteristic Value by UUID. */
|
||||
SD_BLE_GATTC_READ, /**< Generic read. */
|
||||
SD_BLE_GATTC_CHAR_VALUES_READ, /**< Read multiple Characteristic Values. */
|
||||
SD_BLE_GATTC_WRITE, /**< Generic write. */
|
||||
SD_BLE_GATTC_HV_CONFIRM, /**< Handle Value Confirmation. */
|
||||
SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief GATT Client Event IDs.
|
||||
*/
|
||||
enum BLE_GATTC_EVTS
|
||||
{
|
||||
BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP = BLE_GATTC_EVT_BASE, /**< Primary Service Discovery Response event. \n See @ref ble_gattc_evt_prim_srvc_disc_rsp_t. */
|
||||
BLE_GATTC_EVT_REL_DISC_RSP, /**< Relationship Discovery Response event. \n See @ref ble_gattc_evt_rel_disc_rsp_t. */
|
||||
BLE_GATTC_EVT_CHAR_DISC_RSP, /**< Characteristic Discovery Response event. \n See @ref ble_gattc_evt_char_disc_rsp_t. */
|
||||
BLE_GATTC_EVT_DESC_DISC_RSP, /**< Descriptor Discovery Response event. \n See @ref ble_gattc_evt_desc_disc_rsp_t. */
|
||||
BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, /**< Attribute Information Response event. \n See @ref ble_gattc_evt_attr_info_disc_rsp_t. */
|
||||
BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, /**< Read By UUID Response event. \n See @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t. */
|
||||
BLE_GATTC_EVT_READ_RSP, /**< Read Response event. \n See @ref ble_gattc_evt_read_rsp_t. */
|
||||
BLE_GATTC_EVT_CHAR_VALS_READ_RSP, /**< Read multiple Response event. \n See @ref ble_gattc_evt_char_vals_read_rsp_t. */
|
||||
BLE_GATTC_EVT_WRITE_RSP, /**< Write Response event. \n See @ref ble_gattc_evt_write_rsp_t. */
|
||||
BLE_GATTC_EVT_HVX, /**< Handle Value Notification or Indication event. \n Confirm indication with @ref sd_ble_gattc_hv_confirm. \n See @ref ble_gattc_evt_hvx_t. */
|
||||
BLE_GATTC_EVT_EXCHANGE_MTU_RSP, /**< Exchange MTU Response event. \n See @ref ble_gattc_evt_exchange_mtu_rsp_t. */
|
||||
BLE_GATTC_EVT_TIMEOUT, /**< Timeout event. \n See @ref ble_gattc_evt_timeout_t. */
|
||||
BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE /**< Write without Response transmission complete. \n See @ref ble_gattc_evt_write_cmd_tx_complete_t. */
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup BLE_GATTC_DEFINES Defines
|
||||
* @{ */
|
||||
|
||||
/** @defgroup BLE_ERRORS_GATTC SVC return values specific to GATTC
|
||||
* @{ */
|
||||
#define BLE_ERROR_GATTC_PROC_NOT_PERMITTED (NRF_GATTC_ERR_BASE + 0x000) /**< Procedure not Permitted. */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup BLE_GATTC_ATTR_INFO_FORMAT Attribute Information Formats
|
||||
* @{ */
|
||||
#define BLE_GATTC_ATTR_INFO_FORMAT_16BIT 1 /**< 16-bit Attribute Information Format. */
|
||||
#define BLE_GATTC_ATTR_INFO_FORMAT_128BIT 2 /**< 128-bit Attribute Information Format. */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup BLE_GATTC_DEFAULTS GATT Client defaults
|
||||
* @{ */
|
||||
#define BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Write without Response that can be queued for transmission. */
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup BLE_GATTC_STRUCTURES Structures
|
||||
* @{ */
|
||||
|
||||
/**
|
||||
* @brief BLE GATTC connection configuration parameters, set with @ref sd_ble_cfg_set.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t write_cmd_tx_queue_size; /**< The guaranteed minimum number of Write without Response that can be queued for transmission.
|
||||
The default value is @ref BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT */
|
||||
} ble_gattc_conn_cfg_t;
|
||||
|
||||
/**@brief Operation Handle Range. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t start_handle; /**< Start Handle. */
|
||||
uint16_t end_handle; /**< End Handle. */
|
||||
} ble_gattc_handle_range_t;
|
||||
|
||||
|
||||
/**@brief GATT service. */
|
||||
typedef struct
|
||||
{
|
||||
ble_uuid_t uuid; /**< Service UUID. */
|
||||
ble_gattc_handle_range_t handle_range; /**< Service Handle Range. */
|
||||
} ble_gattc_service_t;
|
||||
|
||||
|
||||
/**@brief GATT include. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t handle; /**< Include Handle. */
|
||||
ble_gattc_service_t included_srvc; /**< Handle of the included service. */
|
||||
} ble_gattc_include_t;
|
||||
|
||||
|
||||
/**@brief GATT characteristic. */
|
||||
typedef struct
|
||||
{
|
||||
ble_uuid_t uuid; /**< Characteristic UUID. */
|
||||
ble_gatt_char_props_t char_props; /**< Characteristic Properties. */
|
||||
uint8_t char_ext_props : 1; /**< Extended properties present. */
|
||||
uint16_t handle_decl; /**< Handle of the Characteristic Declaration. */
|
||||
uint16_t handle_value; /**< Handle of the Characteristic Value. */
|
||||
} ble_gattc_char_t;
|
||||
|
||||
|
||||
/**@brief GATT descriptor. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t handle; /**< Descriptor Handle. */
|
||||
ble_uuid_t uuid; /**< Descriptor UUID. */
|
||||
} ble_gattc_desc_t;
|
||||
|
||||
|
||||
/**@brief Write Parameters. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t write_op; /**< Write Operation to be performed, see @ref BLE_GATT_WRITE_OPS. */
|
||||
uint8_t flags; /**< Flags, see @ref BLE_GATT_EXEC_WRITE_FLAGS. */
|
||||
uint16_t handle; /**< Handle to the attribute to be written. */
|
||||
uint16_t offset; /**< Offset in bytes. @note For WRITE_CMD and WRITE_REQ, offset must be 0. */
|
||||
uint16_t len; /**< Length of data in bytes. */
|
||||
uint8_t const *p_value; /**< Pointer to the value data. */
|
||||
} ble_gattc_write_params_t;
|
||||
|
||||
/**@brief Attribute Information for 16-bit Attribute UUID. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t handle; /**< Attribute handle. */
|
||||
ble_uuid_t uuid; /**< 16-bit Attribute UUID. */
|
||||
} ble_gattc_attr_info16_t;
|
||||
|
||||
/**@brief Attribute Information for 128-bit Attribute UUID. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t handle; /**< Attribute handle. */
|
||||
ble_uuid128_t uuid; /**< 128-bit Attribute UUID. */
|
||||
} ble_gattc_attr_info128_t;
|
||||
|
||||
/**@brief Event structure for @ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t count; /**< Service count. */
|
||||
ble_gattc_service_t services[1]; /**< Service data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
|
||||
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
|
||||
} ble_gattc_evt_prim_srvc_disc_rsp_t;
|
||||
|
||||
/**@brief Event structure for @ref BLE_GATTC_EVT_REL_DISC_RSP. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t count; /**< Include count. */
|
||||
ble_gattc_include_t includes[1]; /**< Include data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
|
||||
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
|
||||
} ble_gattc_evt_rel_disc_rsp_t;
|
||||
|
||||
/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_DISC_RSP. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t count; /**< Characteristic count. */
|
||||
ble_gattc_char_t chars[1]; /**< Characteristic data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
|
||||
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
|
||||
} ble_gattc_evt_char_disc_rsp_t;
|
||||
|
||||
/**@brief Event structure for @ref BLE_GATTC_EVT_DESC_DISC_RSP. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t count; /**< Descriptor count. */
|
||||
ble_gattc_desc_t descs[1]; /**< Descriptor data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
|
||||
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
|
||||
} ble_gattc_evt_desc_disc_rsp_t;
|
||||
|
||||
/**@brief Event structure for @ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t count; /**< Attribute count. */
|
||||
uint8_t format; /**< Attribute information format, see @ref BLE_GATTC_ATTR_INFO_FORMAT. */
|
||||
union {
|
||||
ble_gattc_attr_info16_t attr_info16[1]; /**< Attribute information for 16-bit Attribute UUID.
|
||||
@note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
|
||||
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
|
||||
ble_gattc_attr_info128_t attr_info128[1]; /**< Attribute information for 128-bit Attribute UUID.
|
||||
@note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
|
||||
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
|
||||
} info; /**< Attribute information union. */
|
||||
} ble_gattc_evt_attr_info_disc_rsp_t;
|
||||
|
||||
/**@brief GATT read by UUID handle value pair. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t handle; /**< Attribute Handle. */
|
||||
uint8_t *p_value; /**< Pointer to the Attribute Value, length is available in @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t::value_len. */
|
||||
} ble_gattc_handle_value_t;
|
||||
|
||||
/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t count; /**< Handle-Value Pair Count. */
|
||||
uint16_t value_len; /**< Length of the value in Handle-Value(s) list. */
|
||||
uint8_t handle_value[1]; /**< Handle-Value(s) list. To iterate through the list use @ref sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter.
|
||||
@note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
|
||||
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
|
||||
} ble_gattc_evt_char_val_by_uuid_read_rsp_t;
|
||||
|
||||
/**@brief Event structure for @ref BLE_GATTC_EVT_READ_RSP. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t handle; /**< Attribute Handle. */
|
||||
uint16_t offset; /**< Offset of the attribute data. */
|
||||
uint16_t len; /**< Attribute data length. */
|
||||
uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
|
||||
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
|
||||
} ble_gattc_evt_read_rsp_t;
|
||||
|
||||
/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t len; /**< Concatenated Attribute values length. */
|
||||
uint8_t values[1]; /**< Attribute values. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
|
||||
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
|
||||
} ble_gattc_evt_char_vals_read_rsp_t;
|
||||
|
||||
/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_RSP. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t handle; /**< Attribute Handle. */
|
||||
uint8_t write_op; /**< Type of write operation, see @ref BLE_GATT_WRITE_OPS. */
|
||||
uint16_t offset; /**< Data offset. */
|
||||
uint16_t len; /**< Data length. */
|
||||
uint8_t data[1]; /**< Data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
|
||||
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
|
||||
} ble_gattc_evt_write_rsp_t;
|
||||
|
||||
/**@brief Event structure for @ref BLE_GATTC_EVT_HVX. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t handle; /**< Handle to which the HVx operation applies. */
|
||||
uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */
|
||||
uint16_t len; /**< Attribute data length. */
|
||||
uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
|
||||
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
|
||||
} ble_gattc_evt_hvx_t;
|
||||
|
||||
/**@brief Event structure for @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t server_rx_mtu; /**< Server RX MTU size. */
|
||||
} ble_gattc_evt_exchange_mtu_rsp_t;
|
||||
|
||||
/**@brief Event structure for @ref BLE_GATTC_EVT_TIMEOUT. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */
|
||||
} ble_gattc_evt_timeout_t;
|
||||
|
||||
/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t count; /**< Number of write without response transmissions completed. */
|
||||
} ble_gattc_evt_write_cmd_tx_complete_t;
|
||||
|
||||
/**@brief GATTC event structure. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t conn_handle; /**< Connection Handle on which event occurred. */
|
||||
uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */
|
||||
uint16_t error_handle; /**< In case of error: The handle causing the error. In all other cases @ref BLE_GATT_HANDLE_INVALID. */
|
||||
union
|
||||
{
|
||||
ble_gattc_evt_prim_srvc_disc_rsp_t prim_srvc_disc_rsp; /**< Primary Service Discovery Response Event Parameters. */
|
||||
ble_gattc_evt_rel_disc_rsp_t rel_disc_rsp; /**< Relationship Discovery Response Event Parameters. */
|
||||
ble_gattc_evt_char_disc_rsp_t char_disc_rsp; /**< Characteristic Discovery Response Event Parameters. */
|
||||
ble_gattc_evt_desc_disc_rsp_t desc_disc_rsp; /**< Descriptor Discovery Response Event Parameters. */
|
||||
ble_gattc_evt_char_val_by_uuid_read_rsp_t char_val_by_uuid_read_rsp; /**< Characteristic Value Read by UUID Response Event Parameters. */
|
||||
ble_gattc_evt_read_rsp_t read_rsp; /**< Read Response Event Parameters. */
|
||||
ble_gattc_evt_char_vals_read_rsp_t char_vals_read_rsp; /**< Characteristic Values Read Response Event Parameters. */
|
||||
ble_gattc_evt_write_rsp_t write_rsp; /**< Write Response Event Parameters. */
|
||||
ble_gattc_evt_hvx_t hvx; /**< Handle Value Notification/Indication Event Parameters. */
|
||||
ble_gattc_evt_exchange_mtu_rsp_t exchange_mtu_rsp; /**< Exchange MTU Response Event Parameters. */
|
||||
ble_gattc_evt_timeout_t timeout; /**< Timeout Event Parameters. */
|
||||
ble_gattc_evt_attr_info_disc_rsp_t attr_info_disc_rsp; /**< Attribute Information Discovery Event Parameters. */
|
||||
ble_gattc_evt_write_cmd_tx_complete_t write_cmd_tx_complete; /**< Write without Response transmission complete Event Parameters. */
|
||||
} params; /**< Event Parameters. @note Only valid if @ref gatt_status == @ref BLE_GATT_STATUS_SUCCESS. */
|
||||
} ble_gattc_evt_t;
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup BLE_GATTC_FUNCTIONS Functions
|
||||
* @{ */
|
||||
|
||||
/**@brief Initiate or continue a GATT Primary Service Discovery procedure.
|
||||
*
|
||||
* @details This function initiates or resumes a Primary Service discovery procedure, starting from the supplied handle.
|
||||
* If the last service has not been reached, this function must be called again with an updated start handle value to continue the search.
|
||||
*
|
||||
* @note If any of the discovered services have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with
|
||||
* type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event.
|
||||
*
|
||||
* @events
|
||||
* @event{@ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP}
|
||||
* @endevents
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTC_PRIM_SRVC_DISC_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
|
||||
* @param[in] start_handle Handle to start searching from.
|
||||
* @param[in] p_srvc_uuid Pointer to the service UUID to be found. If it is NULL, all primary services will be returned.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully started or resumed the Primary Service Discovery procedure.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
|
||||
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
|
||||
* @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, uint32_t, sd_ble_gattc_primary_services_discover(uint16_t conn_handle, uint16_t start_handle, ble_uuid_t const *p_srvc_uuid));
|
||||
|
||||
|
||||
/**@brief Initiate or continue a GATT Relationship Discovery procedure.
|
||||
*
|
||||
* @details This function initiates or resumes the Find Included Services sub-procedure. If the last included service has not been reached,
|
||||
* this must be called again with an updated handle range to continue the search.
|
||||
*
|
||||
* @events
|
||||
* @event{@ref BLE_GATTC_EVT_REL_DISC_RSP}
|
||||
* @endevents
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTC_REL_DISC_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
|
||||
* @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully started or resumed the Relationship Discovery procedure.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
|
||||
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
|
||||
* @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, uint32_t, sd_ble_gattc_relationships_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
|
||||
|
||||
|
||||
/**@brief Initiate or continue a GATT Characteristic Discovery procedure.
|
||||
*
|
||||
* @details This function initiates or resumes a Characteristic discovery procedure. If the last Characteristic has not been reached,
|
||||
* this must be called again with an updated handle range to continue the discovery.
|
||||
*
|
||||
* @note If any of the discovered characteristics have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with
|
||||
* type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event.
|
||||
*
|
||||
* @events
|
||||
* @event{@ref BLE_GATTC_EVT_CHAR_DISC_RSP}
|
||||
* @endevents
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTC_CHAR_DISC_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
|
||||
* @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully started or resumed the Characteristic Discovery procedure.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
|
||||
* @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, uint32_t, sd_ble_gattc_characteristics_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
|
||||
|
||||
|
||||
/**@brief Initiate or continue a GATT Characteristic Descriptor Discovery procedure.
|
||||
*
|
||||
* @details This function initiates or resumes a Characteristic Descriptor discovery procedure. If the last Descriptor has not been reached,
|
||||
* this must be called again with an updated handle range to continue the discovery.
|
||||
*
|
||||
* @events
|
||||
* @event{@ref BLE_GATTC_EVT_DESC_DISC_RSP}
|
||||
* @endevents
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTC_DESC_DISC_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
|
||||
* @param[in] p_handle_range A pointer to the range of handles of the Characteristic to perform this procedure on.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully started or resumed the Descriptor Discovery procedure.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
|
||||
* @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, uint32_t, sd_ble_gattc_descriptors_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
|
||||
|
||||
|
||||
/**@brief Initiate or continue a GATT Read using Characteristic UUID procedure.
|
||||
*
|
||||
* @details This function initiates or resumes a Read using Characteristic UUID procedure. If the last Characteristic has not been reached,
|
||||
* this must be called again with an updated handle range to continue the discovery.
|
||||
*
|
||||
* @events
|
||||
* @event{@ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP}
|
||||
* @endevents
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTC_READ_UUID_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
|
||||
* @param[in] p_uuid Pointer to a Characteristic value UUID to read.
|
||||
* @param[in] p_handle_range A pointer to the range of handles to perform this procedure on.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully started or resumed the Read using Characteristic UUID procedure.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
|
||||
* @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, uint32_t, sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, ble_uuid_t const *p_uuid, ble_gattc_handle_range_t const *p_handle_range));
|
||||
|
||||
|
||||
/**@brief Initiate or continue a GATT Read (Long) Characteristic or Descriptor procedure.
|
||||
*
|
||||
* @details This function initiates or resumes a GATT Read (Long) Characteristic or Descriptor procedure. If the Characteristic or Descriptor
|
||||
* to be read is longer than ATT_MTU - 1, this function must be called multiple times with appropriate offset to read the
|
||||
* complete value.
|
||||
*
|
||||
* @events
|
||||
* @event{@ref BLE_GATTC_EVT_READ_RSP}
|
||||
* @endevents
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTC_VALUE_READ_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
|
||||
* @param[in] handle The handle of the attribute to be read.
|
||||
* @param[in] offset Offset into the attribute value to be read.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
|
||||
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
|
||||
* @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset));
|
||||
|
||||
|
||||
/**@brief Initiate a GATT Read Multiple Characteristic Values procedure.
|
||||
*
|
||||
* @details This function initiates a GATT Read Multiple Characteristic Values procedure.
|
||||
*
|
||||
* @events
|
||||
* @event{@ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP}
|
||||
* @endevents
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTC_READ_MULT_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
|
||||
* @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read.
|
||||
* @param[in] handle_count The number of handles in p_handles.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully started the Read Multiple Characteristic Values procedure.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
|
||||
* @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTC_CHAR_VALUES_READ, uint32_t, sd_ble_gattc_char_values_read(uint16_t conn_handle, uint16_t const *p_handles, uint16_t handle_count));
|
||||
|
||||
|
||||
/**@brief Perform a Write (Characteristic Value or Descriptor, with or without response, signed or not, long or reliable) procedure.
|
||||
*
|
||||
* @details This function can perform all write procedures described in GATT.
|
||||
*
|
||||
* @note Only one write with response procedure can be ongoing per connection at a time.
|
||||
* If the application tries to write with response while another write with response procedure is ongoing,
|
||||
* the function call will return @ref NRF_ERROR_BUSY.
|
||||
* A @ref BLE_GATTC_EVT_WRITE_RSP event will be issued as soon as the write response arrives from the peer.
|
||||
*
|
||||
* @note The number of Write without Response that can be queued is configured by @ref ble_gattc_conn_cfg_t::write_cmd_tx_queue_size
|
||||
* When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES.
|
||||
* A @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event will be issued as soon as the transmission of the write without response is complete.
|
||||
*
|
||||
* @note The application can keep track of the available queue element count for writes without responses by following the procedure below:
|
||||
* - Store initial queue element count in a variable.
|
||||
* - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS.
|
||||
* - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event.
|
||||
*
|
||||
* @events
|
||||
* @event{@ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE, Write without response transmission complete.}
|
||||
* @event{@ref BLE_GATTC_EVT_WRITE_RSP, Write response received from the peer.}
|
||||
* @endevents
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTC_VALUE_WRITE_WITHOUT_RESP_MSC}
|
||||
* @mmsc{@ref BLE_GATTC_VALUE_WRITE_MSC}
|
||||
* @mmsc{@ref BLE_GATTC_VALUE_LONG_WRITE_MSC}
|
||||
* @mmsc{@ref BLE_GATTC_VALUE_RELIABLE_WRITE_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
|
||||
* @param[in] p_write_params A pointer to a write parameters structure.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully started the Write procedure.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
|
||||
* @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
|
||||
* @retval ::NRF_ERROR_BUSY For write with response, procedure already in progress. Wait for a @ref BLE_GATTC_EVT_WRITE_RSP event and retry.
|
||||
* @retval ::NRF_ERROR_RESOURCES Too many writes without responses queued.
|
||||
* Wait for a @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event and retry.
|
||||
* @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const *p_write_params));
|
||||
|
||||
|
||||
/**@brief Send a Handle Value Confirmation to the GATT Server.
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTC_HVI_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
|
||||
* @param[in] handle The handle of the attribute in the indication.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully queued the Handle Value Confirmation for transmission.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no Indication pending to be confirmed.
|
||||
* @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle.
|
||||
* @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTC_HV_CONFIRM, uint32_t, sd_ble_gattc_hv_confirm(uint16_t conn_handle, uint16_t handle));
|
||||
|
||||
/**@brief Discovers information about a range of attributes on a GATT server.
|
||||
*
|
||||
* @events
|
||||
* @event{@ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, Generated when information about a range of attributes has been received.}
|
||||
* @endevents
|
||||
*
|
||||
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
|
||||
* @param[in] p_handle_range The range of handles to request information about.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully started an attribute information discovery procedure.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid connection state
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
|
||||
* @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTC_ATTR_INFO_DISCOVER, uint32_t, sd_ble_gattc_attr_info_discover(uint16_t conn_handle, ble_gattc_handle_range_t const * p_handle_range));
|
||||
|
||||
/**@brief Start an ATT_MTU exchange by sending an Exchange MTU Request to the server.
|
||||
*
|
||||
* @details The SoftDevice sets ATT_MTU to the minimum of:
|
||||
* - The Client RX MTU value, and
|
||||
* - The Server RX MTU value from @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP.
|
||||
*
|
||||
* However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT.
|
||||
*
|
||||
* @events
|
||||
* @event{@ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP}
|
||||
* @endevents
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTC_MTU_EXCHANGE}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
|
||||
* @param[in] client_rx_mtu Client RX MTU size.
|
||||
* - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT.
|
||||
* - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration
|
||||
used for this connection.
|
||||
* - The value must be equal to Server RX MTU size given in @ref sd_ble_gatts_exchange_mtu_reply
|
||||
* if an ATT_MTU exchange has already been performed in the other direction.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully sent request to the server.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid connection state or an ATT_MTU exchange was already requested once.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid Client RX MTU size supplied.
|
||||
* @retval ::NRF_ERROR_BUSY Client procedure already in progress.
|
||||
* @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, uint32_t, sd_ble_gattc_exchange_mtu_request(uint16_t conn_handle, uint16_t client_rx_mtu));
|
||||
|
||||
/**@brief Iterate through Handle-Value(s) list in @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event.
|
||||
*
|
||||
* @param[in] p_gattc_evt Pointer to event buffer containing @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event.
|
||||
* @note If the buffer contains different event, behavior is undefined.
|
||||
* @param[in,out] p_iter Iterator, points to @ref ble_gattc_handle_value_t structure that will be filled in with
|
||||
* the next Handle-Value pair in each iteration. If the function returns other than
|
||||
* @ref NRF_SUCCESS, it will not be changed.
|
||||
* - To start iteration, initialize the structure to zero.
|
||||
* - To continue, pass the value from previous iteration.
|
||||
*
|
||||
* \code
|
||||
* ble_gattc_handle_value_t iter;
|
||||
* memset(&iter, 0, sizeof(ble_gattc_handle_value_t));
|
||||
* while (sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(&ble_evt.evt.gattc_evt, &iter) == NRF_SUCCESS)
|
||||
* {
|
||||
* app_handle = iter.handle;
|
||||
* memcpy(app_value, iter.p_value, ble_evt.evt.gattc_evt.params.char_val_by_uuid_read_rsp.value_len);
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully retrieved the next Handle-Value pair.
|
||||
* @retval ::NRF_ERROR_NOT_FOUND No more Handle-Value pairs available in the list.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
|
||||
|
||||
__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter)
|
||||
{
|
||||
uint32_t value_len = p_gattc_evt->params.char_val_by_uuid_read_rsp.value_len;
|
||||
uint8_t *p_first = p_gattc_evt->params.char_val_by_uuid_read_rsp.handle_value;
|
||||
uint8_t *p_next = p_iter->p_value ? p_iter->p_value + value_len : p_first;
|
||||
|
||||
if ((p_next - p_first) / (sizeof(uint16_t) + value_len) < p_gattc_evt->params.char_val_by_uuid_read_rsp.count)
|
||||
{
|
||||
p_iter->handle = (uint16_t)p_next[1] << 8 | p_next[0];
|
||||
p_iter->p_value = p_next + sizeof(uint16_t);
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_ERROR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* BLE_GATTC_H__ */
|
||||
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
@@ -0,0 +1,845 @@
|
||||
/*
|
||||
* Copyright (c) 2011 - 2018, Nordic Semiconductor ASA
|
||||
* 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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 Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup BLE_GATTS Generic Attribute Profile (GATT) Server
|
||||
@{
|
||||
@brief Definitions and prototypes for the GATTS interface.
|
||||
*/
|
||||
|
||||
#ifndef BLE_GATTS_H__
|
||||
#define BLE_GATTS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "nrf_svc.h"
|
||||
#include "nrf_error.h"
|
||||
#include "ble_hci.h"
|
||||
#include "ble_ranges.h"
|
||||
#include "ble_types.h"
|
||||
#include "ble_err.h"
|
||||
#include "ble_gatt.h"
|
||||
#include "ble_gap.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup BLE_GATTS_ENUMERATIONS Enumerations
|
||||
* @{ */
|
||||
|
||||
/**
|
||||
* @brief GATTS API SVC numbers.
|
||||
*/
|
||||
enum BLE_GATTS_SVCS
|
||||
{
|
||||
SD_BLE_GATTS_SERVICE_ADD = BLE_GATTS_SVC_BASE, /**< Add a service. */
|
||||
SD_BLE_GATTS_INCLUDE_ADD, /**< Add an included service. */
|
||||
SD_BLE_GATTS_CHARACTERISTIC_ADD, /**< Add a characteristic. */
|
||||
SD_BLE_GATTS_DESCRIPTOR_ADD, /**< Add a generic attribute. */
|
||||
SD_BLE_GATTS_VALUE_SET, /**< Set an attribute value. */
|
||||
SD_BLE_GATTS_VALUE_GET, /**< Get an attribute value. */
|
||||
SD_BLE_GATTS_HVX, /**< Handle Value Notification or Indication. */
|
||||
SD_BLE_GATTS_SERVICE_CHANGED, /**< Perform a Service Changed Indication to one or more peers. */
|
||||
SD_BLE_GATTS_RW_AUTHORIZE_REPLY, /**< Reply to an authorization request for a read or write operation on one or more attributes. */
|
||||
SD_BLE_GATTS_SYS_ATTR_SET, /**< Set the persistent system attributes for a connection. */
|
||||
SD_BLE_GATTS_SYS_ATTR_GET, /**< Retrieve the persistent system attributes. */
|
||||
SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, /**< Retrieve the first valid user handle. */
|
||||
SD_BLE_GATTS_ATTR_GET, /**< Retrieve the UUID and/or metadata of an attribute. */
|
||||
SD_BLE_GATTS_EXCHANGE_MTU_REPLY /**< Reply to Exchange MTU Request. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief GATT Server Event IDs.
|
||||
*/
|
||||
enum BLE_GATTS_EVTS
|
||||
{
|
||||
BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE, /**< Write operation performed. \n See @ref ble_gatts_evt_write_t. */
|
||||
BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, /**< Read/Write Authorization request. \n Reply with @ref sd_ble_gatts_rw_authorize_reply. \n See @ref ble_gatts_evt_rw_authorize_request_t. */
|
||||
BLE_GATTS_EVT_SYS_ATTR_MISSING, /**< A persistent system attribute access is pending. \n Respond with @ref sd_ble_gatts_sys_attr_set. \n See @ref ble_gatts_evt_sys_attr_missing_t. */
|
||||
BLE_GATTS_EVT_HVC, /**< Handle Value Confirmation. \n See @ref ble_gatts_evt_hvc_t. */
|
||||
BLE_GATTS_EVT_SC_CONFIRM, /**< Service Changed Confirmation. \n No additional event structure applies. */
|
||||
BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. \n Reply with @ref sd_ble_gatts_exchange_mtu_reply. \n See @ref ble_gatts_evt_exchange_mtu_request_t. */
|
||||
BLE_GATTS_EVT_TIMEOUT, /**< Peer failed to respond to an ATT request in time. \n See @ref ble_gatts_evt_timeout_t. */
|
||||
BLE_GATTS_EVT_HVN_TX_COMPLETE /**< Handle Value Notification transmission complete. \n See @ref ble_gatts_evt_hvn_tx_complete_t. */
|
||||
};
|
||||
|
||||
/**@brief GATTS Configuration IDs.
|
||||
*
|
||||
* IDs that uniquely identify a GATTS configuration.
|
||||
*/
|
||||
enum BLE_GATTS_CFGS
|
||||
{
|
||||
BLE_GATTS_CFG_SERVICE_CHANGED = BLE_GATTS_CFG_BASE, /**< Service changed configuration. */
|
||||
BLE_GATTS_CFG_ATTR_TAB_SIZE, /**< Attribute table size configuration. */
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup BLE_GATTS_DEFINES Defines
|
||||
* @{ */
|
||||
|
||||
/** @defgroup BLE_ERRORS_GATTS SVC return values specific to GATTS
|
||||
* @{ */
|
||||
#define BLE_ERROR_GATTS_INVALID_ATTR_TYPE (NRF_GATTS_ERR_BASE + 0x000) /**< Invalid attribute type. */
|
||||
#define BLE_ERROR_GATTS_SYS_ATTR_MISSING (NRF_GATTS_ERR_BASE + 0x001) /**< System Attributes missing. */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup BLE_GATTS_ATTR_LENS_MAX Maximum attribute lengths
|
||||
* @{ */
|
||||
#define BLE_GATTS_FIX_ATTR_LEN_MAX (510) /**< Maximum length for fixed length Attribute Values. */
|
||||
#define BLE_GATTS_VAR_ATTR_LEN_MAX (512) /**< Maximum length for variable length Attribute Values. */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup BLE_GATTS_SRVC_TYPES GATT Server Service Types
|
||||
* @{ */
|
||||
#define BLE_GATTS_SRVC_TYPE_INVALID 0x00 /**< Invalid Service Type. */
|
||||
#define BLE_GATTS_SRVC_TYPE_PRIMARY 0x01 /**< Primary Service. */
|
||||
#define BLE_GATTS_SRVC_TYPE_SECONDARY 0x02 /**< Secondary Type. */
|
||||
/** @} */
|
||||
|
||||
|
||||
/** @defgroup BLE_GATTS_ATTR_TYPES GATT Server Attribute Types
|
||||
* @{ */
|
||||
#define BLE_GATTS_ATTR_TYPE_INVALID 0x00 /**< Invalid Attribute Type. */
|
||||
#define BLE_GATTS_ATTR_TYPE_PRIM_SRVC_DECL 0x01 /**< Primary Service Declaration. */
|
||||
#define BLE_GATTS_ATTR_TYPE_SEC_SRVC_DECL 0x02 /**< Secondary Service Declaration. */
|
||||
#define BLE_GATTS_ATTR_TYPE_INC_DECL 0x03 /**< Include Declaration. */
|
||||
#define BLE_GATTS_ATTR_TYPE_CHAR_DECL 0x04 /**< Characteristic Declaration. */
|
||||
#define BLE_GATTS_ATTR_TYPE_CHAR_VAL 0x05 /**< Characteristic Value. */
|
||||
#define BLE_GATTS_ATTR_TYPE_DESC 0x06 /**< Descriptor. */
|
||||
#define BLE_GATTS_ATTR_TYPE_OTHER 0x07 /**< Other, non-GATT specific type. */
|
||||
/** @} */
|
||||
|
||||
|
||||
/** @defgroup BLE_GATTS_OPS GATT Server Operations
|
||||
* @{ */
|
||||
#define BLE_GATTS_OP_INVALID 0x00 /**< Invalid Operation. */
|
||||
#define BLE_GATTS_OP_WRITE_REQ 0x01 /**< Write Request. */
|
||||
#define BLE_GATTS_OP_WRITE_CMD 0x02 /**< Write Command. */
|
||||
#define BLE_GATTS_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */
|
||||
#define BLE_GATTS_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */
|
||||
#define BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL 0x05 /**< Execute Write Request: Cancel all prepared writes. */
|
||||
#define BLE_GATTS_OP_EXEC_WRITE_REQ_NOW 0x06 /**< Execute Write Request: Immediately execute all prepared writes. */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup BLE_GATTS_VLOCS GATT Value Locations
|
||||
* @{ */
|
||||
#define BLE_GATTS_VLOC_INVALID 0x00 /**< Invalid Location. */
|
||||
#define BLE_GATTS_VLOC_STACK 0x01 /**< Attribute Value is located in stack memory, no user memory is required. */
|
||||
#define BLE_GATTS_VLOC_USER 0x02 /**< Attribute Value is located in user memory. This requires the user to maintain a valid buffer through the lifetime of the attribute, since the stack
|
||||
will read and write directly to the memory using the pointer provided in the APIs. There are no alignment requirements for the buffer. */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup BLE_GATTS_AUTHORIZE_TYPES GATT Server Authorization Types
|
||||
* @{ */
|
||||
#define BLE_GATTS_AUTHORIZE_TYPE_INVALID 0x00 /**< Invalid Type. */
|
||||
#define BLE_GATTS_AUTHORIZE_TYPE_READ 0x01 /**< Authorize a Read Operation. */
|
||||
#define BLE_GATTS_AUTHORIZE_TYPE_WRITE 0x02 /**< Authorize a Write Request Operation. */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup BLE_GATTS_SYS_ATTR_FLAGS System Attribute Flags
|
||||
* @{ */
|
||||
#define BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS (1 << 0) /**< Restrict system attributes to system services only. */
|
||||
#define BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS (1 << 1) /**< Restrict system attributes to user services only. */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup BLE_GATTS_SERVICE_CHANGED Service Changed Inclusion Values
|
||||
* @{
|
||||
*/
|
||||
#define BLE_GATTS_SERVICE_CHANGED_DEFAULT (1) /**< Default is to include the Service Changed characteristic in the Attribute Table. */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup BLE_GATTS_ATTR_TAB_SIZE Attribute Table size
|
||||
* @{
|
||||
*/
|
||||
#define BLE_GATTS_ATTR_TAB_SIZE_MIN (248) /**< Minimum Attribute Table size */
|
||||
#define BLE_GATTS_ATTR_TAB_SIZE_DEFAULT (1408) /**< Default Attribute Table size. */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup BLE_GATTS_DEFAULTS GATT Server defaults
|
||||
* @{
|
||||
*/
|
||||
#define BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Handle Value Notifications that can be queued for transmission. */
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup BLE_GATTS_STRUCTURES Structures
|
||||
* @{ */
|
||||
|
||||
/**
|
||||
* @brief BLE GATTS connection configuration parameters, set with @ref sd_ble_cfg_set.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t hvn_tx_queue_size; /**< Minimum guaranteed number of Handle Value Notifications that can be queued for transmission.
|
||||
The default value is @ref BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT */
|
||||
} ble_gatts_conn_cfg_t;
|
||||
|
||||
/**@brief Attribute metadata. */
|
||||
typedef struct
|
||||
{
|
||||
ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */
|
||||
ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */
|
||||
uint8_t vlen :1; /**< Variable length attribute. */
|
||||
uint8_t vloc :2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/
|
||||
uint8_t rd_auth :1; /**< Read authorization and value will be requested from the application on every read operation. */
|
||||
uint8_t wr_auth :1; /**< Write authorization will be requested from the application on every Write Request operation (but not Write Command). */
|
||||
} ble_gatts_attr_md_t;
|
||||
|
||||
|
||||
/**@brief GATT Attribute. */
|
||||
typedef struct
|
||||
{
|
||||
ble_uuid_t const *p_uuid; /**< Pointer to the attribute UUID. */
|
||||
ble_gatts_attr_md_t const *p_attr_md; /**< Pointer to the attribute metadata structure. */
|
||||
uint16_t init_len; /**< Initial attribute value length in bytes. */
|
||||
uint16_t init_offs; /**< Initial attribute value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */
|
||||
uint16_t max_len; /**< Maximum attribute value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */
|
||||
uint8_t *p_value; /**< Pointer to the attribute data. Please note that if the @ref BLE_GATTS_VLOC_USER value location is selected in the attribute metadata, this will have to point to a buffer
|
||||
that remains valid through the lifetime of the attribute. This excludes usage of automatic variables that may go out of scope or any other temporary location.
|
||||
The stack may access that memory directly without the application's knowledge. For writable characteristics, this value must not be a location in flash memory.*/
|
||||
} ble_gatts_attr_t;
|
||||
|
||||
/**@brief GATT Attribute Value. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t len; /**< Length in bytes to be written or read. Length in bytes written or read after successful return.*/
|
||||
uint16_t offset; /**< Attribute value offset. */
|
||||
uint8_t *p_value; /**< Pointer to where value is stored or will be stored.
|
||||
If value is stored in user memory, only the attribute length is updated when p_value == NULL.
|
||||
Set to NULL when reading to obtain the complete length of the attribute value */
|
||||
} ble_gatts_value_t;
|
||||
|
||||
|
||||
/**@brief GATT Characteristic Presentation Format. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t format; /**< Format of the value, see @ref BLE_GATT_CPF_FORMATS. */
|
||||
int8_t exponent; /**< Exponent for integer data types. */
|
||||
uint16_t unit; /**< Unit from Bluetooth Assigned Numbers. */
|
||||
uint8_t name_space; /**< Namespace from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */
|
||||
uint16_t desc; /**< Namespace description from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */
|
||||
} ble_gatts_char_pf_t;
|
||||
|
||||
|
||||
/**@brief GATT Characteristic metadata. */
|
||||
typedef struct
|
||||
{
|
||||
ble_gatt_char_props_t char_props; /**< Characteristic Properties. */
|
||||
ble_gatt_char_ext_props_t char_ext_props; /**< Characteristic Extended Properties. */
|
||||
uint8_t const *p_char_user_desc; /**< Pointer to a UTF-8 encoded string (non-NULL terminated), NULL if the descriptor is not required. */
|
||||
uint16_t char_user_desc_max_size; /**< The maximum size in bytes of the user description descriptor. */
|
||||
uint16_t char_user_desc_size; /**< The size of the user description, must be smaller or equal to char_user_desc_max_size. */
|
||||
ble_gatts_char_pf_t const *p_char_pf; /**< Pointer to a presentation format structure or NULL if the CPF descriptor is not required. */
|
||||
ble_gatts_attr_md_t const *p_user_desc_md; /**< Attribute metadata for the User Description descriptor, or NULL for default values. */
|
||||
ble_gatts_attr_md_t const *p_cccd_md; /**< Attribute metadata for the Client Characteristic Configuration Descriptor, or NULL for default values. */
|
||||
ble_gatts_attr_md_t const *p_sccd_md; /**< Attribute metadata for the Server Characteristic Configuration Descriptor, or NULL for default values. */
|
||||
} ble_gatts_char_md_t;
|
||||
|
||||
|
||||
/**@brief GATT Characteristic Definition Handles. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t value_handle; /**< Handle to the characteristic value. */
|
||||
uint16_t user_desc_handle; /**< Handle to the User Description descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
|
||||
uint16_t cccd_handle; /**< Handle to the Client Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
|
||||
uint16_t sccd_handle; /**< Handle to the Server Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
|
||||
} ble_gatts_char_handles_t;
|
||||
|
||||
|
||||
/**@brief GATT HVx parameters. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t handle; /**< Characteristic Value Handle. */
|
||||
uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */
|
||||
uint16_t offset; /**< Offset within the attribute value. */
|
||||
uint16_t *p_len; /**< Length in bytes to be written, length in bytes written after return. */
|
||||
uint8_t const *p_data; /**< Actual data content, use NULL to use the current attribute value. */
|
||||
} ble_gatts_hvx_params_t;
|
||||
|
||||
/**@brief GATT Authorization parameters. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */
|
||||
uint8_t update : 1; /**< If set, data supplied in p_data will be used to update the attribute value.
|
||||
Please note that for @ref BLE_GATTS_AUTHORIZE_TYPE_WRITE operations this bit must always be set,
|
||||
as the data to be written needs to be stored and later provided by the application. */
|
||||
uint16_t offset; /**< Offset of the attribute value being updated. */
|
||||
uint16_t len; /**< Length in bytes of the value in p_data pointer, see @ref BLE_GATTS_ATTR_LENS_MAX. */
|
||||
uint8_t const *p_data; /**< Pointer to new value used to update the attribute value. */
|
||||
} ble_gatts_authorize_params_t;
|
||||
|
||||
/**@brief GATT Read or Write Authorize Reply parameters. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */
|
||||
union {
|
||||
ble_gatts_authorize_params_t read; /**< Read authorization parameters. */
|
||||
ble_gatts_authorize_params_t write; /**< Write authorization parameters. */
|
||||
} params; /**< Reply Parameters. */
|
||||
} ble_gatts_rw_authorize_reply_params_t;
|
||||
|
||||
/**@brief Service Changed Inclusion configuration parameters, set with @ref sd_ble_cfg_set. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t service_changed : 1; /**< If 1, include the Service Changed characteristic in the Attribute Table. Default is @ref BLE_GATTS_SERVICE_CHANGED_DEFAULT. */
|
||||
} ble_gatts_cfg_service_changed_t;
|
||||
|
||||
/**@brief Attribute table size configuration parameters, set with @ref sd_ble_cfg_set.
|
||||
*
|
||||
* @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true:
|
||||
* - The specified Attribute Table size is too small.
|
||||
* The minimum acceptable size is defined by @ref BLE_GATTS_ATTR_TAB_SIZE_MIN.
|
||||
* - The specified Attribute Table size is not a multiple of 4.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t attr_tab_size; /**< Attribute table size. Default is @ref BLE_GATTS_ATTR_TAB_SIZE_DEFAULT, minimum is @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. */
|
||||
} ble_gatts_cfg_attr_tab_size_t;
|
||||
|
||||
/**@brief Config structure for GATTS configurations. */
|
||||
typedef union
|
||||
{
|
||||
ble_gatts_cfg_service_changed_t service_changed; /**< Include service changed characteristic, cfg_id is @ref BLE_GATTS_CFG_SERVICE_CHANGED. */
|
||||
ble_gatts_cfg_attr_tab_size_t attr_tab_size; /**< Attribute table size, cfg_id is @ref BLE_GATTS_CFG_ATTR_TAB_SIZE. */
|
||||
} ble_gatts_cfg_t;
|
||||
|
||||
|
||||
/**@brief Event structure for @ref BLE_GATTS_EVT_WRITE. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t handle; /**< Attribute Handle. */
|
||||
ble_uuid_t uuid; /**< Attribute UUID. */
|
||||
uint8_t op; /**< Type of write operation, see @ref BLE_GATTS_OPS. */
|
||||
uint8_t auth_required; /**< Writing operation deferred due to authorization requirement. Application may use @ref sd_ble_gatts_value_set to finalize the writing operation. */
|
||||
uint16_t offset; /**< Offset for the write operation. */
|
||||
uint16_t len; /**< Length of the received data. */
|
||||
uint8_t data[1]; /**< Received data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
|
||||
See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
|
||||
} ble_gatts_evt_write_t;
|
||||
|
||||
/**@brief Event substructure for authorized read requests, see @ref ble_gatts_evt_rw_authorize_request_t. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t handle; /**< Attribute Handle. */
|
||||
ble_uuid_t uuid; /**< Attribute UUID. */
|
||||
uint16_t offset; /**< Offset for the read operation. */
|
||||
} ble_gatts_evt_read_t;
|
||||
|
||||
/**@brief Event structure for @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */
|
||||
union {
|
||||
ble_gatts_evt_read_t read; /**< Attribute Read Parameters. */
|
||||
ble_gatts_evt_write_t write; /**< Attribute Write Parameters. */
|
||||
} request; /**< Request Parameters. */
|
||||
} ble_gatts_evt_rw_authorize_request_t;
|
||||
|
||||
/**@brief Event structure for @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t hint; /**< Hint (currently unused). */
|
||||
} ble_gatts_evt_sys_attr_missing_t;
|
||||
|
||||
|
||||
/**@brief Event structure for @ref BLE_GATTS_EVT_HVC. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t handle; /**< Attribute Handle. */
|
||||
} ble_gatts_evt_hvc_t;
|
||||
|
||||
/**@brief Event structure for @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t client_rx_mtu; /**< Client RX MTU size. */
|
||||
} ble_gatts_evt_exchange_mtu_request_t;
|
||||
|
||||
/**@brief Event structure for @ref BLE_GATTS_EVT_TIMEOUT. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */
|
||||
} ble_gatts_evt_timeout_t;
|
||||
|
||||
/**@brief Event structure for @ref BLE_GATTS_EVT_HVN_TX_COMPLETE. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t count; /**< Number of notification transmissions completed. */
|
||||
} ble_gatts_evt_hvn_tx_complete_t;
|
||||
|
||||
/**@brief GATTS event structure. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t conn_handle; /**< Connection Handle on which the event occurred. */
|
||||
union
|
||||
{
|
||||
ble_gatts_evt_write_t write; /**< Write Event Parameters. */
|
||||
ble_gatts_evt_rw_authorize_request_t authorize_request; /**< Read or Write Authorize Request Parameters. */
|
||||
ble_gatts_evt_sys_attr_missing_t sys_attr_missing; /**< System attributes missing. */
|
||||
ble_gatts_evt_hvc_t hvc; /**< Handle Value Confirmation Event Parameters. */
|
||||
ble_gatts_evt_exchange_mtu_request_t exchange_mtu_request; /**< Exchange MTU Request Event Parameters. */
|
||||
ble_gatts_evt_timeout_t timeout; /**< Timeout Event. */
|
||||
ble_gatts_evt_hvn_tx_complete_t hvn_tx_complete; /**< Handle Value Notification transmission complete Event Parameters. */
|
||||
} params; /**< Event Parameters. */
|
||||
} ble_gatts_evt_t;
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup BLE_GATTS_FUNCTIONS Functions
|
||||
* @{ */
|
||||
|
||||
/**@brief Add a service declaration to the Attribute Table.
|
||||
*
|
||||
* @note Secondary Services are only relevant in the context of the entity that references them, it is therefore forbidden to
|
||||
* add a secondary service declaration that is not referenced by another service later in the Attribute Table.
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] type Toggles between primary and secondary services, see @ref BLE_GATTS_SRVC_TYPES.
|
||||
* @param[in] p_uuid Pointer to service UUID.
|
||||
* @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully added a service declaration.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, Vendor Specific UUIDs need to be present in the table.
|
||||
* @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
|
||||
* @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type, ble_uuid_t const *p_uuid, uint16_t *p_handle));
|
||||
|
||||
|
||||
/**@brief Add an include declaration to the Attribute Table.
|
||||
*
|
||||
* @note It is currently only possible to add an include declaration to the last added service (i.e. only sequential population is supported at this time).
|
||||
*
|
||||
* @note The included service must already be present in the Attribute Table prior to this call.
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] service_handle Handle of the service where the included service is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
|
||||
* @param[in] inc_srvc_handle Handle of the included service.
|
||||
* @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully added an include declaration.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, handle values need to match previously added services.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required.
|
||||
* @retval ::NRF_ERROR_NOT_SUPPORTED Feature is not supported, service_handle must be that of the last added service.
|
||||
* @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, self inclusions are not allowed.
|
||||
* @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
|
||||
* @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTS_INCLUDE_ADD, uint32_t, sd_ble_gatts_include_add(uint16_t service_handle, uint16_t inc_srvc_handle, uint16_t *p_include_handle));
|
||||
|
||||
|
||||
/**@brief Add a characteristic declaration, a characteristic value declaration and optional characteristic descriptor declarations to the Attribute Table.
|
||||
*
|
||||
* @note It is currently only possible to add a characteristic to the last added service (i.e. only sequential population is supported at this time).
|
||||
*
|
||||
* @note Several restrictions apply to the parameters, such as matching permissions between the user description descriptor and the writable auxiliaries bits,
|
||||
* readable (no security) and writable (selectable) CCCDs and SCCDs and valid presentation format values.
|
||||
*
|
||||
* @note If no metadata is provided for the optional descriptors, their permissions will be derived from the characteristic permissions.
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] service_handle Handle of the service where the characteristic is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
|
||||
* @param[in] p_char_md Characteristic metadata.
|
||||
* @param[in] p_attr_char_value Pointer to the attribute structure corresponding to the characteristic value.
|
||||
* @param[out] p_handles Pointer to the structure where the assigned handles will be stored.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully added a characteristic.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, service handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required.
|
||||
* @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
|
||||
* @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
|
||||
* @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTS_CHARACTERISTIC_ADD, uint32_t, sd_ble_gatts_characteristic_add(uint16_t service_handle, ble_gatts_char_md_t const *p_char_md, ble_gatts_attr_t const *p_attr_char_value, ble_gatts_char_handles_t *p_handles));
|
||||
|
||||
|
||||
/**@brief Add a descriptor to the Attribute Table.
|
||||
*
|
||||
* @note It is currently only possible to add a descriptor to the last added characteristic (i.e. only sequential population is supported at this time).
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] char_handle Handle of the characteristic where the descriptor is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
|
||||
* @param[in] p_attr Pointer to the attribute structure.
|
||||
* @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully added a descriptor.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, characteristic handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a characteristic context is required.
|
||||
* @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
|
||||
* @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
|
||||
* @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTS_DESCRIPTOR_ADD, uint32_t, sd_ble_gatts_descriptor_add(uint16_t char_handle, ble_gatts_attr_t const *p_attr, uint16_t *p_handle));
|
||||
|
||||
/**@brief Set the value of a given attribute.
|
||||
*
|
||||
* @note Values other than system attributes can be set at any time, regardless of whether any active connections exist.
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC}
|
||||
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute.
|
||||
* @param[in] handle Attribute handle.
|
||||
* @param[in,out] p_value Attribute value information.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully set the value of the attribute.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
|
||||
* @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
|
||||
* @retval ::NRF_ERROR_FORBIDDEN Forbidden handle supplied, certain attributes are not modifiable by the application.
|
||||
* @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTS_VALUE_SET, uint32_t, sd_ble_gatts_value_set(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value));
|
||||
|
||||
/**@brief Get the value of a given attribute.
|
||||
*
|
||||
* @note If the attribute value is longer than the size of the supplied buffer,
|
||||
* @ref ble_gatts_value_t::len will return the total attribute value length (excluding offset),
|
||||
* and not the number of bytes actually returned in @ref ble_gatts_value_t::p_value.
|
||||
* The application may use this information to allocate a suitable buffer size.
|
||||
*
|
||||
* @note When retrieving system attribute values with this function, the connection handle
|
||||
* may refer to an already disconnected connection. Refer to the documentation of
|
||||
* @ref sd_ble_gatts_sys_attr_get for further information.
|
||||
*
|
||||
* @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute.
|
||||
* @param[in] handle Attribute handle.
|
||||
* @param[in,out] p_value Attribute value information.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully retrieved the value of the attribute.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid attribute offset supplied.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute.
|
||||
* @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value));
|
||||
|
||||
/**@brief Notify or Indicate an attribute value.
|
||||
*
|
||||
* @details This function checks for the relevant Client Characteristic Configuration descriptor value to verify that the relevant operation
|
||||
* (notification or indication) has been enabled by the client. It is also able to update the attribute value before issuing the PDU, so that
|
||||
* the application can atomically perform a value update and a server initiated transaction with a single API call.
|
||||
*
|
||||
* @note The local attribute value may be updated even if an outgoing packet is not sent to the peer due to an error during execution.
|
||||
* The Attribute Table has been updated if one of the following error codes is returned: @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY,
|
||||
* @ref NRF_ERROR_FORBIDDEN, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and @ref NRF_ERROR_RESOURCES.
|
||||
* The caller can check whether the value has been updated by looking at the contents of *(@ref ble_gatts_hvx_params_t::p_len).
|
||||
*
|
||||
* @note Only one indication procedure can be ongoing per connection at a time.
|
||||
* If the application tries to indicate an attribute value while another indication procedure is ongoing,
|
||||
* the function call will return @ref NRF_ERROR_BUSY.
|
||||
* A @ref BLE_GATTS_EVT_HVC event will be issued as soon as the confirmation arrives from the peer.
|
||||
*
|
||||
* @note The number of Handle Value Notifications that can be queued is configured by @ref ble_gatts_conn_cfg_t::hvn_tx_queue_size
|
||||
* When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES.
|
||||
* A @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event will be issued as soon as the transmission of the notification is complete.
|
||||
*
|
||||
* @note The application can keep track of the available queue element count for notifications by following the procedure below:
|
||||
* - Store initial queue element count in a variable.
|
||||
* - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS.
|
||||
* - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event.
|
||||
*
|
||||
* @events
|
||||
* @event{@ref BLE_GATTS_EVT_HVN_TX_COMPLETE, Notification transmission complete.}
|
||||
* @event{@ref BLE_GATTS_EVT_HVC, Confirmation received from the peer.}
|
||||
* @endevents
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC}
|
||||
* @mmsc{@ref BLE_GATTS_HVN_MSC}
|
||||
* @mmsc{@ref BLE_GATTS_HVI_MSC}
|
||||
* @mmsc{@ref BLE_GATTS_HVX_DISABLED_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle Connection handle.
|
||||
* @param[in,out] p_hvx_params Pointer to an HVx parameters structure. If @ref ble_gatts_hvx_params_t::p_data
|
||||
* contains a non-NULL pointer the attribute value will be updated with the contents
|
||||
* pointed by it before sending the notification or indication. If the attribute value
|
||||
* is updated, @ref ble_gatts_hvx_params_t::p_len is updated by the SoftDevice to
|
||||
* contain the number of actual bytes written, else it will be set to 0.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully queued a notification or indication for transmission, and optionally updated the attribute value.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true:
|
||||
* - Invalid Connection State
|
||||
* - Notifications and/or indications not enabled in the CCCD
|
||||
* - An ATT_MTU exchange is ongoing
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
|
||||
* @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied. Only attributes added directly by the application are available to notify and indicate.
|
||||
* @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE Invalid attribute type(s) supplied, only characteristic values may be notified and indicated.
|
||||
* @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
|
||||
* @retval ::NRF_ERROR_FORBIDDEN The connection's current security level is lower than the one required by the write permissions of the CCCD associated with this characteristic.
|
||||
* @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
|
||||
* @retval ::NRF_ERROR_BUSY For @ref BLE_GATT_HVX_INDICATION Procedure already in progress. Wait for a @ref BLE_GATTS_EVT_HVC event and retry.
|
||||
* @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
|
||||
* @retval ::NRF_ERROR_RESOURCES Too many notifications queued.
|
||||
* Wait for a @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event and retry.
|
||||
* @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params));
|
||||
|
||||
/**@brief Indicate the Service Changed attribute value.
|
||||
*
|
||||
* @details This call will send a Handle Value Indication to one or more peers connected to inform them that the Attribute
|
||||
* Table layout has changed. As soon as the peer has confirmed the indication, a @ref BLE_GATTS_EVT_SC_CONFIRM event will
|
||||
* be issued.
|
||||
*
|
||||
* @note Some of the restrictions and limitations that apply to @ref sd_ble_gatts_hvx also apply here.
|
||||
*
|
||||
* @events
|
||||
* @event{@ref BLE_GATTS_EVT_SC_CONFIRM, Confirmation of attribute table change received from peer.}
|
||||
* @endevents
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTS_SC_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle Connection handle.
|
||||
* @param[in] start_handle Start of affected attribute handle range.
|
||||
* @param[in] end_handle End of affected attribute handle range.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully queued the Service Changed indication for transmission.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_NOT_SUPPORTED Service Changed not enabled at initialization. See @ref
|
||||
* sd_ble_cfg_set and @ref ble_gatts_cfg_service_changed_t.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true:
|
||||
* - Invalid Connection State
|
||||
* - Notifications and/or indications not enabled in the CCCD
|
||||
* - An ATT_MTU exchange is ongoing
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
|
||||
* @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied, handles must be in the range populated by the application.
|
||||
* @retval ::NRF_ERROR_BUSY Procedure already in progress.
|
||||
* @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
|
||||
* @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTS_SERVICE_CHANGED, uint32_t, sd_ble_gatts_service_changed(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle));
|
||||
|
||||
/**@brief Respond to a Read/Write authorization request.
|
||||
*
|
||||
* @note This call should only be used as a response to a @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event issued to the application.
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC}
|
||||
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC}
|
||||
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC}
|
||||
* @mmsc{@ref BLE_GATTS_READ_REQ_AUTH_MSC}
|
||||
* @mmsc{@ref BLE_GATTS_WRITE_REQ_AUTH_MSC}
|
||||
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC}
|
||||
* @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle Connection handle.
|
||||
* @param[in] p_rw_authorize_reply_params Pointer to a structure with the attribute provided by the application.
|
||||
*
|
||||
* @note @ref ble_gatts_authorize_params_t::p_data is ignored when this function is used to respond
|
||||
* to a @ref BLE_GATTS_AUTHORIZE_TYPE_READ event if @ref ble_gatts_authorize_params_t::update
|
||||
* is set to 0.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully queued a response to the peer, and in the case of a write operation, Attribute Table updated.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no authorization request pending.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Authorization op invalid,
|
||||
* handle supplied does not match requested handle,
|
||||
* or invalid data to be written provided by the application.
|
||||
* @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_reply(uint16_t conn_handle, ble_gatts_rw_authorize_reply_params_t const *p_rw_authorize_reply_params));
|
||||
|
||||
|
||||
/**@brief Update persistent system attribute information.
|
||||
*
|
||||
* @details Supply information about persistent system attributes to the stack,
|
||||
* previously obtained using @ref sd_ble_gatts_sys_attr_get.
|
||||
* This call is only allowed for active connections, and is usually
|
||||
* made immediately after a connection is established with an known bonded device,
|
||||
* often as a response to a @ref BLE_GATTS_EVT_SYS_ATTR_MISSING.
|
||||
*
|
||||
* p_sysattrs may point directly to the application's stored copy of the system attributes
|
||||
* obtained using @ref sd_ble_gatts_sys_attr_get.
|
||||
* If the pointer is NULL, the system attribute info is initialized, assuming that
|
||||
* the application does not have any previously saved system attribute data for this device.
|
||||
*
|
||||
* @note The state of persistent system attributes is reset upon connection establishment and then remembered for its duration.
|
||||
*
|
||||
* @note If this call returns with an error code different from @ref NRF_SUCCESS, the storage of persistent system attributes may have been completed only partially.
|
||||
* This means that the state of the attribute table is undefined, and the application should either provide a new set of attributes using this same call or
|
||||
* reset the SoftDevice to return to a known state.
|
||||
*
|
||||
* @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be modified.
|
||||
* @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be modified.
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC}
|
||||
* @mmsc{@ref BLE_GATTS_SYS_ATTRS_UNK_PEER_MSC}
|
||||
* @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle Connection handle.
|
||||
* @param[in] p_sys_attr_data Pointer to a saved copy of system attributes supplied to the stack, or NULL.
|
||||
* @param[in] len Size of data pointed by p_sys_attr_data, in octets.
|
||||
* @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully set the system attribute information.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied.
|
||||
* @retval ::NRF_ERROR_INVALID_DATA Invalid data supplied, the data should be exactly the same as retrieved with @ref sd_ble_gatts_sys_attr_get.
|
||||
* @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTS_SYS_ATTR_SET, uint32_t, sd_ble_gatts_sys_attr_set(uint16_t conn_handle, uint8_t const *p_sys_attr_data, uint16_t len, uint32_t flags));
|
||||
|
||||
|
||||
/**@brief Retrieve persistent system attribute information from the stack.
|
||||
*
|
||||
* @details This call is used to retrieve information about values to be stored persistently by the application
|
||||
* during the lifetime of a connection or after it has been terminated. When a new connection is established with the same bonded device,
|
||||
* the system attribute information retrieved with this function should be restored using using @ref sd_ble_gatts_sys_attr_set.
|
||||
* If retrieved after disconnection, the data should be read before a new connection established. The connection handle for
|
||||
* the previous, now disconnected, connection will remain valid until a new one is created to allow this API call to refer to it.
|
||||
* Connection handles belonging to active connections can be used as well, but care should be taken since the system attributes
|
||||
* may be written to at any time by the peer during a connection's lifetime.
|
||||
*
|
||||
* @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be returned.
|
||||
* @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be returned.
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle Connection handle of the recently terminated connection.
|
||||
* @param[out] p_sys_attr_data Pointer to a buffer where updated information about system attributes will be filled in. The format of the data is described
|
||||
* in @ref BLE_GATTS_SYS_ATTRS_FORMAT. NULL can be provided to obtain the length of the data.
|
||||
* @param[in,out] p_len Size of application buffer if p_sys_attr_data is not NULL. Unconditionally updated to actual length of system attribute data.
|
||||
* @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully retrieved the system attribute information.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied.
|
||||
* @retval ::NRF_ERROR_DATA_SIZE The system attribute information did not fit into the provided buffer.
|
||||
* @retval ::NRF_ERROR_NOT_FOUND No system attributes found.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTS_SYS_ATTR_GET, uint32_t, sd_ble_gatts_sys_attr_get(uint16_t conn_handle, uint8_t *p_sys_attr_data, uint16_t *p_len, uint32_t flags));
|
||||
|
||||
|
||||
/**@brief Retrieve the first valid user attribute handle.
|
||||
*
|
||||
* @param[out] p_handle Pointer to an integer where the handle will be stored.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully retrieved the handle.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, uint32_t, sd_ble_gatts_initial_user_handle_get(uint16_t *p_handle));
|
||||
|
||||
/**@brief Retrieve the attribute UUID and/or metadata.
|
||||
*
|
||||
* @param[in] handle Attribute handle
|
||||
* @param[out] p_uuid UUID of the attribute. Use NULL to omit this field.
|
||||
* @param[out] p_md Metadata of the attribute. Use NULL to omit this field.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully retrieved the attribute metadata,
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. Returned when both @c p_uuid and @c p_md are NULL.
|
||||
* @retval ::NRF_ERROR_NOT_FOUND Attribute was not found.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTS_ATTR_GET, uint32_t, sd_ble_gatts_attr_get(uint16_t handle, ble_uuid_t * p_uuid, ble_gatts_attr_md_t * p_md));
|
||||
|
||||
/**@brief Reply to an ATT_MTU exchange request by sending an Exchange MTU Response to the client.
|
||||
*
|
||||
* @details This function is only used to reply to a @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event.
|
||||
*
|
||||
* @details The SoftDevice sets ATT_MTU to the minimum of:
|
||||
* - The Client RX MTU value from @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, and
|
||||
* - The Server RX MTU value.
|
||||
*
|
||||
* However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT.
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_GATTS_MTU_EXCHANGE}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
|
||||
* @param[in] server_rx_mtu Server RX MTU size.
|
||||
* - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT.
|
||||
* - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration
|
||||
* used for this connection.
|
||||
* - The value must be equal to Client RX MTU size given in @ref sd_ble_gattc_exchange_mtu_request
|
||||
* if an ATT_MTU exchange has already been performed in the other direction.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully sent response to the client.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no ATT_MTU exchange request pending.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid Server RX MTU size supplied.
|
||||
* @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
|
||||
*/
|
||||
SVCALL(SD_BLE_GATTS_EXCHANGE_MTU_REPLY, uint32_t, sd_ble_gatts_exchange_mtu_reply(uint16_t conn_handle, uint16_t server_rx_mtu));
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // BLE_GATTS_H__
|
||||
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 2012 - 2017, Nordic Semiconductor ASA
|
||||
* 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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 Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup BLE_COMMON
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BLE_HCI_H__
|
||||
#define BLE_HCI_H__
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @defgroup BLE_HCI_STATUS_CODES Bluetooth status codes
|
||||
* @{ */
|
||||
|
||||
#define BLE_HCI_STATUS_CODE_SUCCESS 0x00 /**< Success. */
|
||||
#define BLE_HCI_STATUS_CODE_UNKNOWN_BTLE_COMMAND 0x01 /**< Unknown BLE Command. */
|
||||
#define BLE_HCI_STATUS_CODE_UNKNOWN_CONNECTION_IDENTIFIER 0x02 /**< Unknown Connection Identifier. */
|
||||
/*0x03 Hardware Failure
|
||||
0x04 Page Timeout
|
||||
*/
|
||||
#define BLE_HCI_AUTHENTICATION_FAILURE 0x05 /**< Authentication Failure. */
|
||||
#define BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING 0x06 /**< Pin or Key missing. */
|
||||
#define BLE_HCI_MEMORY_CAPACITY_EXCEEDED 0x07 /**< Memory Capacity Exceeded. */
|
||||
#define BLE_HCI_CONNECTION_TIMEOUT 0x08 /**< Connection Timeout. */
|
||||
/*0x09 Connection Limit Exceeded
|
||||
0x0A Synchronous Connection Limit To A Device Exceeded
|
||||
0x0B ACL Connection Already Exists*/
|
||||
#define BLE_HCI_STATUS_CODE_COMMAND_DISALLOWED 0x0C /**< Command Disallowed. */
|
||||
/*0x0D Connection Rejected due to Limited Resources
|
||||
0x0E Connection Rejected Due To Security Reasons
|
||||
0x0F Connection Rejected due to Unacceptable BD_ADDR
|
||||
0x10 Connection Accept Timeout Exceeded
|
||||
0x11 Unsupported Feature or Parameter Value*/
|
||||
#define BLE_HCI_STATUS_CODE_INVALID_BTLE_COMMAND_PARAMETERS 0x12 /**< Invalid BLE Command Parameters. */
|
||||
#define BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION 0x13 /**< Remote User Terminated Connection. */
|
||||
#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES 0x14 /**< Remote Device Terminated Connection due to low resources.*/
|
||||
#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF 0x15 /**< Remote Device Terminated Connection due to power off. */
|
||||
#define BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION 0x16 /**< Local Host Terminated Connection. */
|
||||
/*
|
||||
0x17 Repeated Attempts
|
||||
0x18 Pairing Not Allowed
|
||||
0x19 Unknown LMP PDU
|
||||
*/
|
||||
#define BLE_HCI_UNSUPPORTED_REMOTE_FEATURE 0x1A /**< Unsupported Remote Feature. */
|
||||
/*
|
||||
0x1B SCO Offset Rejected
|
||||
0x1C SCO Interval Rejected
|
||||
0x1D SCO Air Mode Rejected*/
|
||||
#define BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS 0x1E /**< Invalid LMP Parameters. */
|
||||
#define BLE_HCI_STATUS_CODE_UNSPECIFIED_ERROR 0x1F /**< Unspecified Error. */
|
||||
/*0x20 Unsupported LMP Parameter Value
|
||||
0x21 Role Change Not Allowed
|
||||
*/
|
||||
#define BLE_HCI_STATUS_CODE_LMP_RESPONSE_TIMEOUT 0x22 /**< LMP Response Timeout. */
|
||||
#define BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION 0x23 /**< LMP Error Transaction Collision/LL Procedure Collision. */
|
||||
#define BLE_HCI_STATUS_CODE_LMP_PDU_NOT_ALLOWED 0x24 /**< LMP PDU Not Allowed. */
|
||||
/*0x25 Encryption Mode Not Acceptable
|
||||
0x26 Link Key Can Not be Changed
|
||||
0x27 Requested QoS Not Supported
|
||||
*/
|
||||
#define BLE_HCI_INSTANT_PASSED 0x28 /**< Instant Passed. */
|
||||
#define BLE_HCI_PAIRING_WITH_UNIT_KEY_UNSUPPORTED 0x29 /**< Pairing with Unit Key Unsupported. */
|
||||
#define BLE_HCI_DIFFERENT_TRANSACTION_COLLISION 0x2A /**< Different Transaction Collision. */
|
||||
/*
|
||||
0x2B Reserved
|
||||
0x2C QoS Unacceptable Parameter
|
||||
0x2D QoS Rejected
|
||||
0x2E Channel Classification Not Supported
|
||||
0x2F Insufficient Security
|
||||
*/
|
||||
#define BLE_HCI_PARAMETER_OUT_OF_MANDATORY_RANGE 0x30 /**< Parameter Out Of Mandatory Range. */
|
||||
/*
|
||||
0x31 Reserved
|
||||
0x32 Role Switch Pending
|
||||
0x33 Reserved
|
||||
0x34 Reserved Slot Violation
|
||||
0x35 Role Switch Failed
|
||||
0x36 Extended Inquiry Response Too Large
|
||||
0x37 Secure Simple Pairing Not Supported By Host.
|
||||
0x38 Host Busy - Pairing
|
||||
0x39 Connection Rejected due to No Suitable Channel Found*/
|
||||
#define BLE_HCI_CONTROLLER_BUSY 0x3A /**< Controller Busy. */
|
||||
#define BLE_HCI_CONN_INTERVAL_UNACCEPTABLE 0x3B /**< Connection Interval Unacceptable. */
|
||||
#define BLE_HCI_DIRECTED_ADVERTISER_TIMEOUT 0x3C /**< Directed Advertisement Timeout. */
|
||||
#define BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE 0x3D /**< Connection Terminated due to MIC Failure. */
|
||||
#define BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED 0x3E /**< Connection Failed to be Established. */
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // BLE_HCI_H__
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,506 @@
|
||||
/*
|
||||
* Copyright (c) 2011 - 2018, Nordic Semiconductor ASA
|
||||
* 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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 Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup BLE_L2CAP Logical Link Control and Adaptation Protocol (L2CAP)
|
||||
@{
|
||||
@brief Definitions and prototypes for the L2CAP interface.
|
||||
*/
|
||||
|
||||
#ifndef BLE_L2CAP_H__
|
||||
#define BLE_L2CAP_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "nrf_svc.h"
|
||||
#include "nrf_error.h"
|
||||
#include "ble_ranges.h"
|
||||
#include "ble_types.h"
|
||||
#include "ble_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**@addtogroup BLE_L2CAP_TERMINOLOGY Terminology
|
||||
* @{
|
||||
* @details
|
||||
*
|
||||
* L2CAP SDU
|
||||
* - A data unit that the application can send/receive to/from a peer.
|
||||
*
|
||||
* L2CAP PDU
|
||||
* - A data unit that is exchanged between local and remote L2CAP entities.
|
||||
* It consists of L2CAP protocol control information and payload fields.
|
||||
* The payload field can contain an L2CAP SDU or a part of an L2CAP SDU.
|
||||
*
|
||||
* L2CAP MTU
|
||||
* - The maximum length of an L2CAP SDU.
|
||||
*
|
||||
* L2CAP MPS
|
||||
* - The maximum length of an L2CAP PDU payload field.
|
||||
*
|
||||
* Credits
|
||||
* - A value indicating the number of L2CAP PDUs that the receiver of the credit can send to the peer.
|
||||
* @} */
|
||||
|
||||
/**@addtogroup BLE_L2CAP_ENUMERATIONS Enumerations
|
||||
* @{ */
|
||||
|
||||
/**@brief L2CAP API SVC numbers. */
|
||||
enum BLE_L2CAP_SVCS
|
||||
{
|
||||
SD_BLE_L2CAP_CH_SETUP = BLE_L2CAP_SVC_BASE + 0, /**< Set up an L2CAP channel. */
|
||||
SD_BLE_L2CAP_CH_RELEASE = BLE_L2CAP_SVC_BASE + 1, /**< Release an L2CAP channel. */
|
||||
SD_BLE_L2CAP_CH_RX = BLE_L2CAP_SVC_BASE + 2, /**< Receive an SDU on an L2CAP channel. */
|
||||
SD_BLE_L2CAP_CH_TX = BLE_L2CAP_SVC_BASE + 3, /**< Transmit an SDU on an L2CAP channel. */
|
||||
SD_BLE_L2CAP_CH_FLOW_CONTROL = BLE_L2CAP_SVC_BASE + 4, /**< Advanced SDU reception flow control. */
|
||||
};
|
||||
|
||||
/**@brief L2CAP Event IDs. */
|
||||
enum BLE_L2CAP_EVTS
|
||||
{
|
||||
BLE_L2CAP_EVT_CH_SETUP_REQUEST = BLE_L2CAP_EVT_BASE + 0, /**< L2CAP Channel Setup Request event.
|
||||
\n See @ref ble_l2cap_evt_ch_setup_request_t. */
|
||||
BLE_L2CAP_EVT_CH_SETUP_REFUSED = BLE_L2CAP_EVT_BASE + 1, /**< L2CAP Channel Setup Refused event.
|
||||
\n See @ref ble_l2cap_evt_ch_setup_refused_t. */
|
||||
BLE_L2CAP_EVT_CH_SETUP = BLE_L2CAP_EVT_BASE + 2, /**< L2CAP Channel Setup Completed event.
|
||||
\n See @ref ble_l2cap_evt_ch_setup_t. */
|
||||
BLE_L2CAP_EVT_CH_RELEASED = BLE_L2CAP_EVT_BASE + 3, /**< L2CAP Channel Released event.
|
||||
\n No additional event structure applies. */
|
||||
BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED = BLE_L2CAP_EVT_BASE + 4, /**< L2CAP Channel SDU data buffer released event.
|
||||
\n See @ref ble_l2cap_evt_ch_sdu_buf_released_t. */
|
||||
BLE_L2CAP_EVT_CH_CREDIT = BLE_L2CAP_EVT_BASE + 5, /**< L2CAP Channel Credit received.
|
||||
\n See @ref ble_l2cap_evt_ch_credit_t. */
|
||||
BLE_L2CAP_EVT_CH_RX = BLE_L2CAP_EVT_BASE + 6, /**< L2CAP Channel SDU received.
|
||||
\n See @ref ble_l2cap_evt_ch_rx_t. */
|
||||
BLE_L2CAP_EVT_CH_TX = BLE_L2CAP_EVT_BASE + 7, /**< L2CAP Channel SDU transmitted.
|
||||
\n See @ref ble_l2cap_evt_ch_tx_t. */
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
/**@addtogroup BLE_L2CAP_DEFINES Defines
|
||||
* @{ */
|
||||
|
||||
/**@brief Maximum number of L2CAP channels per connection. */
|
||||
#define BLE_L2CAP_CH_COUNT_MAX (64)
|
||||
|
||||
/**@brief Minimum L2CAP MTU, in bytes. */
|
||||
#define BLE_L2CAP_MTU_MIN (23)
|
||||
|
||||
/**@brief Minimum L2CAP MPS, in bytes. */
|
||||
#define BLE_L2CAP_MPS_MIN (23)
|
||||
|
||||
/**@brief Invalid CID. */
|
||||
#define BLE_L2CAP_CID_INVALID (0x0000)
|
||||
|
||||
/**@brief Default number of credits for @ref sd_ble_l2cap_ch_flow_control. */
|
||||
#define BLE_L2CAP_CREDITS_DEFAULT (1)
|
||||
|
||||
/**@defgroup BLE_L2CAP_CH_SETUP_REFUSED_SRCS L2CAP channel setup refused sources
|
||||
* @{ */
|
||||
#define BLE_L2CAP_CH_SETUP_REFUSED_SRC_LOCAL (0x01) /**< Local. */
|
||||
#define BLE_L2CAP_CH_SETUP_REFUSED_SRC_REMOTE (0x02) /**< Remote. */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup BLE_L2CAP_CH_STATUS_CODES L2CAP channel status codes
|
||||
* @{ */
|
||||
#define BLE_L2CAP_CH_STATUS_CODE_SUCCESS (0x0000) /**< Success. */
|
||||
#define BLE_L2CAP_CH_STATUS_CODE_LE_PSM_NOT_SUPPORTED (0x0002) /**< LE_PSM not supported. */
|
||||
#define BLE_L2CAP_CH_STATUS_CODE_NO_RESOURCES (0x0004) /**< No resources available. */
|
||||
#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_AUTHENTICATION (0x0005) /**< Insufficient authentication. */
|
||||
#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_AUTHORIZATION (0x0006) /**< Insufficient authorization. */
|
||||
#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_ENC_KEY_SIZE (0x0007) /**< Insufficient encryption key size. */
|
||||
#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_ENC (0x0008) /**< Insufficient encryption. */
|
||||
#define BLE_L2CAP_CH_STATUS_CODE_INVALID_SCID (0x0009) /**< Invalid Source CID. */
|
||||
#define BLE_L2CAP_CH_STATUS_CODE_SCID_ALLOCATED (0x000A) /**< Source CID already allocated. */
|
||||
#define BLE_L2CAP_CH_STATUS_CODE_UNACCEPTABLE_PARAMS (0x000B) /**< Unacceptable parameters. */
|
||||
#define BLE_L2CAP_CH_STATUS_CODE_NOT_UNDERSTOOD (0x8000) /**< Command Reject received instead of LE Credit Based Connection Response. */
|
||||
#define BLE_L2CAP_CH_STATUS_CODE_TIMEOUT (0xC000) /**< Operation timed out. */
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
||||
|
||||
/**@addtogroup BLE_L2CAP_STRUCTURES Structures
|
||||
* @{ */
|
||||
|
||||
/**
|
||||
* @brief BLE L2CAP connection configuration parameters, set with @ref sd_ble_cfg_set.
|
||||
*
|
||||
* @note These parameters are set per connection, so all L2CAP channels created on this connection
|
||||
* will have the same parameters.
|
||||
*
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true:
|
||||
* - rx_mps is smaller than @ref BLE_L2CAP_MPS_MIN.
|
||||
* - tx_mps is smaller than @ref BLE_L2CAP_MPS_MIN.
|
||||
* - ch_count is greater than @ref BLE_L2CAP_CH_COUNT_MAX.
|
||||
* @retval ::NRF_ERROR_NO_MEM rx_mps or tx_mps is set too high.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t rx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall
|
||||
be able to receive on L2CAP channels on connections with this
|
||||
configuration. The minimum value is @ref BLE_L2CAP_MPS_MIN. */
|
||||
uint16_t tx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall
|
||||
be able to transmit on L2CAP channels on connections with this
|
||||
configuration. The minimum value is @ref BLE_L2CAP_MPS_MIN. */
|
||||
uint8_t rx_queue_size; /**< Number of SDU data buffers that can be queued for reception per
|
||||
L2CAP channel. The minimum value is one. */
|
||||
uint8_t tx_queue_size; /**< Number of SDU data buffers that can be queued for transmission
|
||||
per L2CAP channel. The minimum value is one. */
|
||||
uint8_t ch_count; /**< Number of L2CAP channels the application can create per connection
|
||||
with this configuration. The default value is zero, the maximum
|
||||
value is @ref BLE_L2CAP_CH_COUNT_MAX.
|
||||
@note if this parameter is set to zero, all other parameters in
|
||||
@ref ble_l2cap_conn_cfg_t are ignored. */
|
||||
} ble_l2cap_conn_cfg_t;
|
||||
|
||||
/**@brief L2CAP channel RX parameters. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t rx_mtu; /**< The maximum L2CAP SDU size, in bytes, that L2CAP shall be able to
|
||||
receive on this L2CAP channel.
|
||||
- Must be equal to or greater than @ref BLE_L2CAP_MTU_MIN. */
|
||||
uint16_t rx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall be
|
||||
able to receive on this L2CAP channel.
|
||||
- Must be equal to or greater than @ref BLE_L2CAP_MPS_MIN.
|
||||
- Must be equal to or less than @ref ble_l2cap_conn_cfg_t::rx_mps. */
|
||||
ble_data_t sdu_buf; /**< SDU data buffer for reception.
|
||||
- If @ref ble_data_t::p_data is non-NULL, initial credits are
|
||||
issued to the peer.
|
||||
- If @ref ble_data_t::p_data is NULL, no initial credits are
|
||||
issued to the peer. */
|
||||
} ble_l2cap_ch_rx_params_t;
|
||||
|
||||
/**@brief L2CAP channel setup parameters. */
|
||||
typedef struct
|
||||
{
|
||||
ble_l2cap_ch_rx_params_t rx_params; /**< L2CAP channel RX parameters. */
|
||||
uint16_t le_psm; /**< LE Protocol/Service Multiplexer. Used when requesting
|
||||
setup of an L2CAP channel, ignored otherwise. */
|
||||
uint16_t status; /**< Status code, see @ref BLE_L2CAP_CH_STATUS_CODES.
|
||||
Used when replying to a setup request of an L2CAP
|
||||
channel, ignored otherwise. */
|
||||
} ble_l2cap_ch_setup_params_t;
|
||||
|
||||
/**@brief L2CAP channel TX parameters. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t tx_mtu; /**< The maximum L2CAP SDU size, in bytes, that L2CAP is able to
|
||||
transmit on this L2CAP channel. */
|
||||
uint16_t peer_mps; /**< The maximum L2CAP PDU payload size, in bytes, that the peer is
|
||||
able to receive on this L2CAP channel. */
|
||||
uint16_t tx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP is able
|
||||
to transmit on this L2CAP channel. This is effective tx_mps,
|
||||
selected by the SoftDevice as
|
||||
MIN( @ref ble_l2cap_ch_tx_params_t::peer_mps, @ref ble_l2cap_conn_cfg_t::tx_mps ) */
|
||||
uint16_t credits; /**< Initial credits given by the peer. */
|
||||
} ble_l2cap_ch_tx_params_t;
|
||||
|
||||
/**@brief L2CAP Channel Setup Request event. */
|
||||
typedef struct
|
||||
{
|
||||
ble_l2cap_ch_tx_params_t tx_params; /**< L2CAP channel TX parameters. */
|
||||
uint16_t le_psm; /**< LE Protocol/Service Multiplexer. */
|
||||
} ble_l2cap_evt_ch_setup_request_t;
|
||||
|
||||
/**@brief L2CAP Channel Setup Refused event. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t source; /**< Source, see @ref BLE_L2CAP_CH_SETUP_REFUSED_SRCS */
|
||||
uint16_t status; /**< Status code, see @ref BLE_L2CAP_CH_STATUS_CODES */
|
||||
} ble_l2cap_evt_ch_setup_refused_t;
|
||||
|
||||
/**@brief L2CAP Channel Setup Completed event. */
|
||||
typedef struct
|
||||
{
|
||||
ble_l2cap_ch_tx_params_t tx_params; /**< L2CAP channel TX parameters. */
|
||||
} ble_l2cap_evt_ch_setup_t;
|
||||
|
||||
/**@brief L2CAP Channel SDU Data Buffer Released event. */
|
||||
typedef struct
|
||||
{
|
||||
ble_data_t sdu_buf; /**< Returned reception or transmission SDU data buffer. The SoftDevice
|
||||
returns SDU data buffers supplied by the application, which have
|
||||
not yet been returned previously via a @ref BLE_L2CAP_EVT_CH_RX or
|
||||
@ref BLE_L2CAP_EVT_CH_TX event. */
|
||||
} ble_l2cap_evt_ch_sdu_buf_released_t;
|
||||
|
||||
/**@brief L2CAP Channel Credit received event. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t credits; /**< Additional credits given by the peer. */
|
||||
} ble_l2cap_evt_ch_credit_t;
|
||||
|
||||
/**@brief L2CAP Channel received SDU event. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t sdu_len; /**< Total SDU length, in bytes. */
|
||||
ble_data_t sdu_buf; /**< SDU data buffer.
|
||||
@note If there is not enough space in the buffer
|
||||
(sdu_buf.len < sdu_len) then the rest of the SDU will be
|
||||
silently discarded by the SoftDevice. */
|
||||
} ble_l2cap_evt_ch_rx_t;
|
||||
|
||||
/**@brief L2CAP Channel transmitted SDU event. */
|
||||
typedef struct
|
||||
{
|
||||
ble_data_t sdu_buf; /**< SDU data buffer. */
|
||||
} ble_l2cap_evt_ch_tx_t;
|
||||
|
||||
/**@brief L2CAP event structure. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t conn_handle; /**< Connection Handle on which the event occurred. */
|
||||
uint16_t local_cid; /**< Local Channel ID of the L2CAP channel, or
|
||||
@ref BLE_L2CAP_CID_INVALID if not present. */
|
||||
union
|
||||
{
|
||||
ble_l2cap_evt_ch_setup_request_t ch_setup_request; /**< L2CAP Channel Setup Request Event Parameters. */
|
||||
ble_l2cap_evt_ch_setup_refused_t ch_setup_refused; /**< L2CAP Channel Setup Refused Event Parameters. */
|
||||
ble_l2cap_evt_ch_setup_t ch_setup; /**< L2CAP Channel Setup Completed Event Parameters. */
|
||||
ble_l2cap_evt_ch_sdu_buf_released_t ch_sdu_buf_released;/**< L2CAP Channel SDU Data Buffer Released Event Parameters. */
|
||||
ble_l2cap_evt_ch_credit_t credit; /**< L2CAP Channel Credit Received Event Parameters. */
|
||||
ble_l2cap_evt_ch_rx_t rx; /**< L2CAP Channel SDU Received Event Parameters. */
|
||||
ble_l2cap_evt_ch_tx_t tx; /**< L2CAP Channel SDU Transmitted Event Parameters. */
|
||||
} params; /**< Event Parameters. */
|
||||
} ble_l2cap_evt_t;
|
||||
|
||||
/** @} */
|
||||
|
||||
/**@addtogroup BLE_L2CAP_FUNCTIONS Functions
|
||||
* @{ */
|
||||
|
||||
/**@brief Set up an L2CAP channel.
|
||||
*
|
||||
* @details This function is used to:
|
||||
* - Request setup of an L2CAP channel: sends an LE Credit Based Connection Request packet to a peer.
|
||||
* - Reply to a setup request of an L2CAP channel (if called in response to a
|
||||
* @ref BLE_L2CAP_EVT_CH_SETUP_REQUEST event): sends an LE Credit Based Connection
|
||||
* Response packet to a peer.
|
||||
*
|
||||
* @note A call to this function will require the application to keep the SDU data buffer alive
|
||||
* until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_RX or
|
||||
* @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event.
|
||||
*
|
||||
* @events
|
||||
* @event{@ref BLE_L2CAP_EVT_CH_SETUP, Setup successful.}
|
||||
* @event{@ref BLE_L2CAP_EVT_CH_SETUP_REFUSED, Setup failed.}
|
||||
* @endevents
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_L2CAP_CH_SETUP_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle Connection Handle.
|
||||
* @param[in,out] p_local_cid Pointer to a uint16_t containing Local Channel ID of the L2CAP channel:
|
||||
* - As input: @ref BLE_L2CAP_CID_INVALID when requesting setup of an L2CAP
|
||||
* channel or local_cid provided in the @ref BLE_L2CAP_EVT_CH_SETUP_REQUEST
|
||||
* event when replying to a setup request of an L2CAP channel.
|
||||
* - As output: local_cid for this channel.
|
||||
* @param[in] p_params L2CAP channel parameters.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully queued request or response for transmission.
|
||||
* @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
|
||||
* @retval ::NRF_ERROR_INVALID_LENGTH Supplied higher rx_mps than has been configured on this link.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (L2CAP channel already set up).
|
||||
* @retval ::NRF_ERROR_NOT_FOUND CID not found.
|
||||
* @retval ::NRF_ERROR_RESOURCES The limit has been reached for available L2CAP channels,
|
||||
* see @ref ble_l2cap_conn_cfg_t::ch_count.
|
||||
*/
|
||||
SVCALL(SD_BLE_L2CAP_CH_SETUP, uint32_t, sd_ble_l2cap_ch_setup(uint16_t conn_handle, uint16_t *p_local_cid, ble_l2cap_ch_setup_params_t const *p_params));
|
||||
|
||||
/**@brief Release an L2CAP channel.
|
||||
*
|
||||
* @details This sends a Disconnection Request packet to a peer.
|
||||
*
|
||||
* @events
|
||||
* @event{@ref BLE_L2CAP_EVT_CH_RELEASED, Release complete.}
|
||||
* @endevents
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_L2CAP_CH_RELEASE_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle Connection Handle.
|
||||
* @param[in] local_cid Local Channel ID of the L2CAP channel.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully queued request for transmission.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is
|
||||
* in progress for the L2CAP channel).
|
||||
* @retval ::NRF_ERROR_NOT_FOUND CID not found.
|
||||
*/
|
||||
SVCALL(SD_BLE_L2CAP_CH_RELEASE, uint32_t, sd_ble_l2cap_ch_release(uint16_t conn_handle, uint16_t local_cid));
|
||||
|
||||
/**@brief Receive an SDU on an L2CAP channel.
|
||||
*
|
||||
* @details This may issue additional credits to the peer using an LE Flow Control Credit packet.
|
||||
*
|
||||
* @note A call to this function will require the application to keep the memory pointed by
|
||||
* @ref ble_data_t::p_data alive until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_RX
|
||||
* or @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event.
|
||||
*
|
||||
* @note The SoftDevice can queue up to @ref ble_l2cap_conn_cfg_t::rx_queue_size SDU data buffers
|
||||
* for reception per L2CAP channel.
|
||||
*
|
||||
* @events
|
||||
* @event{@ref BLE_L2CAP_EVT_CH_RX, The SDU is received.}
|
||||
* @endevents
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_L2CAP_CH_RX_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle Connection Handle.
|
||||
* @param[in] local_cid Local Channel ID of the L2CAP channel.
|
||||
* @param[in] p_sdu_buf Pointer to the SDU data buffer.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Buffer accepted.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is
|
||||
* in progress for an L2CAP channel).
|
||||
* @retval ::NRF_ERROR_NOT_FOUND CID not found.
|
||||
* @retval ::NRF_ERROR_RESOURCES Too many SDU data buffers supplied. Wait for a
|
||||
* @ref BLE_L2CAP_EVT_CH_RX event and retry.
|
||||
*/
|
||||
SVCALL(SD_BLE_L2CAP_CH_RX, uint32_t, sd_ble_l2cap_ch_rx(uint16_t conn_handle, uint16_t local_cid, ble_data_t const *p_sdu_buf));
|
||||
|
||||
/**@brief Transmit an SDU on an L2CAP channel.
|
||||
*
|
||||
* @note A call to this function will require the application to keep the memory pointed by
|
||||
* @ref ble_data_t::p_data alive until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_TX
|
||||
* or @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event.
|
||||
*
|
||||
* @note The SoftDevice can queue up to @ref ble_l2cap_conn_cfg_t::tx_queue_size SDUs for
|
||||
* transmission per L2CAP channel.
|
||||
*
|
||||
* @note The application can keep track of the available credits for transmission by following
|
||||
* the procedure below:
|
||||
* - Store initial credits given by the peer in a variable.
|
||||
* (Initial credits are provided in a @ref BLE_L2CAP_EVT_CH_SETUP event.)
|
||||
* - Decrement the variable, which stores the currently available credits, by
|
||||
* ceiling((@ref ble_data_t::len + 2) / tx_mps) when a call to this function returns
|
||||
* @ref NRF_SUCCESS. (tx_mps is provided in a @ref BLE_L2CAP_EVT_CH_SETUP event.)
|
||||
* - Increment the variable, which stores the currently available credits, by additional
|
||||
* credits given by the peer in a @ref BLE_L2CAP_EVT_CH_CREDIT event.
|
||||
*
|
||||
* @events
|
||||
* @event{@ref BLE_L2CAP_EVT_CH_TX, The SDU is transmitted.}
|
||||
* @endevents
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_L2CAP_CH_TX_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle Connection Handle.
|
||||
* @param[in] local_cid Local Channel ID of the L2CAP channel.
|
||||
* @param[in] p_sdu_buf Pointer to the SDU data buffer.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Successfully queued L2CAP SDU for transmission.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is
|
||||
* in progress for the L2CAP channel).
|
||||
* @retval ::NRF_ERROR_NOT_FOUND CID not found.
|
||||
* @retval ::NRF_ERROR_DATA_SIZE Invalid SDU length supplied, must not be more than
|
||||
* @ref ble_l2cap_ch_tx_params_t::tx_mtu provided in
|
||||
* @ref BLE_L2CAP_EVT_CH_SETUP event.
|
||||
* @retval ::NRF_ERROR_RESOURCES Too many SDUs queued for transmission. Wait for a
|
||||
* @ref BLE_L2CAP_EVT_CH_TX event and retry.
|
||||
*/
|
||||
SVCALL(SD_BLE_L2CAP_CH_TX, uint32_t, sd_ble_l2cap_ch_tx(uint16_t conn_handle, uint16_t local_cid, ble_data_t const *p_sdu_buf));
|
||||
|
||||
/**@brief Advanced SDU reception flow control.
|
||||
*
|
||||
* @details Adjust the way the SoftDevice issues credits to the peer.
|
||||
* This may issue additional credits to the peer using an LE Flow Control Credit packet.
|
||||
*
|
||||
* @mscs
|
||||
* @mmsc{@ref BLE_L2CAP_CH_FLOW_CONTROL_MSC}
|
||||
* @endmscs
|
||||
*
|
||||
* @param[in] conn_handle Connection Handle.
|
||||
* @param[in] local_cid Local Channel ID of the L2CAP channel or @ref BLE_L2CAP_CID_INVALID to set
|
||||
* the value that will be used for newly created channels.
|
||||
* @param[in] credits Number of credits that the SoftDevice will make sure the peer has every
|
||||
* time it starts using a new reception buffer.
|
||||
* - @ref BLE_L2CAP_CREDITS_DEFAULT is the default value the SoftDevice will
|
||||
* use if this function is not called.
|
||||
* - If set to zero, the SoftDevice will stop issuing credits for new reception
|
||||
* buffers the application provides or has provided. SDU reception that is
|
||||
* currently ongoing will be allowed to complete.
|
||||
* @param[out] p_credits NULL or pointer to a uint16_t. If a valid pointer is provided, it will be
|
||||
* written by the SoftDevice with the number of credits that is or will be
|
||||
* available to the peer. If the value written by the SoftDevice is 0 when
|
||||
* credits parameter was set to 0, the peer will not be able to send more
|
||||
* data until more credits are provided by calling this function again with
|
||||
* credits > 0. This parameter is ignored when local_cid is set to
|
||||
* @ref BLE_L2CAP_CID_INVALID.
|
||||
*
|
||||
* @note Application should take care when setting number of credits higher than default value. In
|
||||
* this case the application must make sure that the SoftDevice always has reception buffers
|
||||
* available (see @ref sd_ble_l2cap_ch_rx) for that channel. If the SoftDevice does not have
|
||||
* such buffers available, packets may be NACKed on the Link Layer and all Bluetooth traffic
|
||||
* on the connection handle may be stalled until the SoftDevice again has an available
|
||||
* reception buffer. This applies even if the application has used this call to set the
|
||||
* credits back to default, or zero.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS Flow control parameters accepted.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
|
||||
* @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is
|
||||
* in progress for an L2CAP channel).
|
||||
* @retval ::NRF_ERROR_NOT_FOUND CID not found.
|
||||
*/
|
||||
SVCALL(SD_BLE_L2CAP_CH_FLOW_CONTROL, uint32_t, sd_ble_l2cap_ch_flow_control(uint16_t conn_handle, uint16_t local_cid, uint16_t credits, uint16_t *p_credits));
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // BLE_L2CAP_H__
|
||||
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) 2012 - 2018, Nordic Semiconductor ASA
|
||||
* 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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 Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup BLE_COMMON
|
||||
@{
|
||||
@defgroup ble_ranges Module specific SVC, event and option number subranges
|
||||
@{
|
||||
|
||||
@brief Definition of SVC, event and option number subranges for each API module.
|
||||
|
||||
@note
|
||||
SVCs, event and option numbers are split into subranges for each API module.
|
||||
Each module receives its entire allocated range of SVC calls, whether implemented or not,
|
||||
but return BLE_ERROR_NOT_SUPPORTED for unimplemented or undefined calls in its range.
|
||||
|
||||
Note that the symbols BLE_<module>_SVC_LAST is the end of the allocated SVC range,
|
||||
rather than the last SVC function call actually defined and implemented.
|
||||
|
||||
Specific SVC, event and option values are defined in each module's ble_<module>.h file,
|
||||
which defines names of each individual SVC code based on the range start value.
|
||||
*/
|
||||
|
||||
#ifndef BLE_RANGES_H__
|
||||
#define BLE_RANGES_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BLE_SVC_BASE 0x60 /**< Common BLE SVC base. */
|
||||
#define BLE_SVC_LAST 0x6B /**< Common BLE SVC last. */
|
||||
|
||||
#define BLE_GAP_SVC_BASE 0x6C /**< GAP BLE SVC base. */
|
||||
#define BLE_GAP_SVC_LAST 0x9A /**< GAP BLE SVC last. */
|
||||
|
||||
#define BLE_GATTC_SVC_BASE 0x9B /**< GATTC BLE SVC base. */
|
||||
#define BLE_GATTC_SVC_LAST 0xA7 /**< GATTC BLE SVC last. */
|
||||
|
||||
#define BLE_GATTS_SVC_BASE 0xA8 /**< GATTS BLE SVC base. */
|
||||
#define BLE_GATTS_SVC_LAST 0xB7 /**< GATTS BLE SVC last. */
|
||||
|
||||
#define BLE_L2CAP_SVC_BASE 0xB8 /**< L2CAP BLE SVC base. */
|
||||
#define BLE_L2CAP_SVC_LAST 0xBF /**< L2CAP BLE SVC last. */
|
||||
|
||||
|
||||
#define BLE_EVT_INVALID 0x00 /**< Invalid BLE Event. */
|
||||
|
||||
#define BLE_EVT_BASE 0x01 /**< Common BLE Event base. */
|
||||
#define BLE_EVT_LAST 0x0F /**< Common BLE Event last. */
|
||||
|
||||
#define BLE_GAP_EVT_BASE 0x10 /**< GAP BLE Event base. */
|
||||
#define BLE_GAP_EVT_LAST 0x2F /**< GAP BLE Event last. */
|
||||
|
||||
#define BLE_GATTC_EVT_BASE 0x30 /**< GATTC BLE Event base. */
|
||||
#define BLE_GATTC_EVT_LAST 0x4F /**< GATTC BLE Event last. */
|
||||
|
||||
#define BLE_GATTS_EVT_BASE 0x50 /**< GATTS BLE Event base. */
|
||||
#define BLE_GATTS_EVT_LAST 0x6F /**< GATTS BLE Event last. */
|
||||
|
||||
#define BLE_L2CAP_EVT_BASE 0x70 /**< L2CAP BLE Event base. */
|
||||
#define BLE_L2CAP_EVT_LAST 0x8F /**< L2CAP BLE Event last. */
|
||||
|
||||
|
||||
#define BLE_OPT_INVALID 0x00 /**< Invalid BLE Option. */
|
||||
|
||||
#define BLE_OPT_BASE 0x01 /**< Common BLE Option base. */
|
||||
#define BLE_OPT_LAST 0x1F /**< Common BLE Option last. */
|
||||
|
||||
#define BLE_GAP_OPT_BASE 0x20 /**< GAP BLE Option base. */
|
||||
#define BLE_GAP_OPT_LAST 0x3F /**< GAP BLE Option last. */
|
||||
|
||||
#define BLE_GATT_OPT_BASE 0x40 /**< GATT BLE Option base. */
|
||||
#define BLE_GATT_OPT_LAST 0x5F /**< GATT BLE Option last. */
|
||||
|
||||
#define BLE_GATTC_OPT_BASE 0x60 /**< GATTC BLE Option base. */
|
||||
#define BLE_GATTC_OPT_LAST 0x7F /**< GATTC BLE Option last. */
|
||||
|
||||
#define BLE_GATTS_OPT_BASE 0x80 /**< GATTS BLE Option base. */
|
||||
#define BLE_GATTS_OPT_LAST 0x9F /**< GATTS BLE Option last. */
|
||||
|
||||
#define BLE_L2CAP_OPT_BASE 0xA0 /**< L2CAP BLE Option base. */
|
||||
#define BLE_L2CAP_OPT_LAST 0xBF /**< L2CAP BLE Option last. */
|
||||
|
||||
|
||||
#define BLE_CFG_INVALID 0x00 /**< Invalid BLE configuration. */
|
||||
|
||||
#define BLE_CFG_BASE 0x01 /**< Common BLE configuration base. */
|
||||
#define BLE_CFG_LAST 0x1F /**< Common BLE configuration last. */
|
||||
|
||||
#define BLE_CONN_CFG_BASE 0x20 /**< BLE connection configuration base. */
|
||||
#define BLE_CONN_CFG_LAST 0x3F /**< BLE connection configuration last. */
|
||||
|
||||
#define BLE_GAP_CFG_BASE 0x40 /**< GAP BLE configuration base. */
|
||||
#define BLE_GAP_CFG_LAST 0x5F /**< GAP BLE configuration last. */
|
||||
|
||||
#define BLE_GATT_CFG_BASE 0x60 /**< GATT BLE configuration base. */
|
||||
#define BLE_GATT_CFG_LAST 0x7F /**< GATT BLE configuration last. */
|
||||
|
||||
#define BLE_GATTC_CFG_BASE 0x80 /**< GATTC BLE configuration base. */
|
||||
#define BLE_GATTC_CFG_LAST 0x9F /**< GATTC BLE configuration last. */
|
||||
|
||||
#define BLE_GATTS_CFG_BASE 0xA0 /**< GATTS BLE configuration base. */
|
||||
#define BLE_GATTS_CFG_LAST 0xBF /**< GATTS BLE configuration last. */
|
||||
|
||||
#define BLE_L2CAP_CFG_BASE 0xC0 /**< L2CAP BLE configuration base. */
|
||||
#define BLE_L2CAP_CFG_LAST 0xDF /**< L2CAP BLE configuration last. */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* BLE_RANGES_H__ */
|
||||
|
||||
/**
|
||||
@}
|
||||
@}
|
||||
*/
|
||||
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (c) 2012 - 2017, Nordic Semiconductor ASA
|
||||
* 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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 Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup BLE_COMMON
|
||||
@{
|
||||
@defgroup ble_types Common types and macro definitions
|
||||
@{
|
||||
|
||||
@brief Common types and macro definitions for the BLE SoftDevice.
|
||||
*/
|
||||
|
||||
#ifndef BLE_TYPES_H__
|
||||
#define BLE_TYPES_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup BLE_TYPES_DEFINES Defines
|
||||
* @{ */
|
||||
|
||||
/** @defgroup BLE_CONN_HANDLES BLE Connection Handles
|
||||
* @{ */
|
||||
#define BLE_CONN_HANDLE_INVALID 0xFFFF /**< Invalid Connection Handle. */
|
||||
#define BLE_CONN_HANDLE_ALL 0xFFFE /**< Applies to all Connection Handles. */
|
||||
/** @} */
|
||||
|
||||
|
||||
/** @defgroup BLE_UUID_VALUES Assigned Values for BLE UUIDs
|
||||
* @{ */
|
||||
/* Generic UUIDs, applicable to all services */
|
||||
#define BLE_UUID_UNKNOWN 0x0000 /**< Reserved UUID. */
|
||||
#define BLE_UUID_SERVICE_PRIMARY 0x2800 /**< Primary Service. */
|
||||
#define BLE_UUID_SERVICE_SECONDARY 0x2801 /**< Secondary Service. */
|
||||
#define BLE_UUID_SERVICE_INCLUDE 0x2802 /**< Include. */
|
||||
#define BLE_UUID_CHARACTERISTIC 0x2803 /**< Characteristic. */
|
||||
#define BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP 0x2900 /**< Characteristic Extended Properties Descriptor. */
|
||||
#define BLE_UUID_DESCRIPTOR_CHAR_USER_DESC 0x2901 /**< Characteristic User Description Descriptor. */
|
||||
#define BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG 0x2902 /**< Client Characteristic Configuration Descriptor. */
|
||||
#define BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG 0x2903 /**< Server Characteristic Configuration Descriptor. */
|
||||
#define BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT 0x2904 /**< Characteristic Presentation Format Descriptor. */
|
||||
#define BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT 0x2905 /**< Characteristic Aggregate Format Descriptor. */
|
||||
/* GATT specific UUIDs */
|
||||
#define BLE_UUID_GATT 0x1801 /**< Generic Attribute Profile. */
|
||||
#define BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED 0x2A05 /**< Service Changed Characteristic. */
|
||||
/* GAP specific UUIDs */
|
||||
#define BLE_UUID_GAP 0x1800 /**< Generic Access Profile. */
|
||||
#define BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME 0x2A00 /**< Device Name Characteristic. */
|
||||
#define BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE 0x2A01 /**< Appearance Characteristic. */
|
||||
#define BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR 0x2A03 /**< Reconnection Address Characteristic. */
|
||||
#define BLE_UUID_GAP_CHARACTERISTIC_PPCP 0x2A04 /**< Peripheral Preferred Connection Parameters Characteristic. */
|
||||
#define BLE_UUID_GAP_CHARACTERISTIC_CAR 0x2AA6 /**< Central Address Resolution Characteristic. */
|
||||
#define BLE_UUID_GAP_CHARACTERISTIC_RPA_ONLY 0x2AC9 /**< Resolvable Private Address Only Characteristic. */
|
||||
/** @} */
|
||||
|
||||
|
||||
/** @defgroup BLE_UUID_TYPES Types of UUID
|
||||
* @{ */
|
||||
#define BLE_UUID_TYPE_UNKNOWN 0x00 /**< Invalid UUID type. */
|
||||
#define BLE_UUID_TYPE_BLE 0x01 /**< Bluetooth SIG UUID (16-bit). */
|
||||
#define BLE_UUID_TYPE_VENDOR_BEGIN 0x02 /**< Vendor UUID types start at this index (128-bit). */
|
||||
/** @} */
|
||||
|
||||
|
||||
/** @defgroup BLE_APPEARANCES Bluetooth Appearance values
|
||||
* @note Retrieved from http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml
|
||||
* @{ */
|
||||
#define BLE_APPEARANCE_UNKNOWN 0 /**< Unknown. */
|
||||
#define BLE_APPEARANCE_GENERIC_PHONE 64 /**< Generic Phone. */
|
||||
#define BLE_APPEARANCE_GENERIC_COMPUTER 128 /**< Generic Computer. */
|
||||
#define BLE_APPEARANCE_GENERIC_WATCH 192 /**< Generic Watch. */
|
||||
#define BLE_APPEARANCE_WATCH_SPORTS_WATCH 193 /**< Watch: Sports Watch. */
|
||||
#define BLE_APPEARANCE_GENERIC_CLOCK 256 /**< Generic Clock. */
|
||||
#define BLE_APPEARANCE_GENERIC_DISPLAY 320 /**< Generic Display. */
|
||||
#define BLE_APPEARANCE_GENERIC_REMOTE_CONTROL 384 /**< Generic Remote Control. */
|
||||
#define BLE_APPEARANCE_GENERIC_EYE_GLASSES 448 /**< Generic Eye-glasses. */
|
||||
#define BLE_APPEARANCE_GENERIC_TAG 512 /**< Generic Tag. */
|
||||
#define BLE_APPEARANCE_GENERIC_KEYRING 576 /**< Generic Keyring. */
|
||||
#define BLE_APPEARANCE_GENERIC_MEDIA_PLAYER 640 /**< Generic Media Player. */
|
||||
#define BLE_APPEARANCE_GENERIC_BARCODE_SCANNER 704 /**< Generic Barcode Scanner. */
|
||||
#define BLE_APPEARANCE_GENERIC_THERMOMETER 768 /**< Generic Thermometer. */
|
||||
#define BLE_APPEARANCE_THERMOMETER_EAR 769 /**< Thermometer: Ear. */
|
||||
#define BLE_APPEARANCE_GENERIC_HEART_RATE_SENSOR 832 /**< Generic Heart rate Sensor. */
|
||||
#define BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT 833 /**< Heart Rate Sensor: Heart Rate Belt. */
|
||||
#define BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE 896 /**< Generic Blood Pressure. */
|
||||
#define BLE_APPEARANCE_BLOOD_PRESSURE_ARM 897 /**< Blood Pressure: Arm. */
|
||||
#define BLE_APPEARANCE_BLOOD_PRESSURE_WRIST 898 /**< Blood Pressure: Wrist. */
|
||||
#define BLE_APPEARANCE_GENERIC_HID 960 /**< Human Interface Device (HID). */
|
||||
#define BLE_APPEARANCE_HID_KEYBOARD 961 /**< Keyboard (HID Subtype). */
|
||||
#define BLE_APPEARANCE_HID_MOUSE 962 /**< Mouse (HID Subtype). */
|
||||
#define BLE_APPEARANCE_HID_JOYSTICK 963 /**< Joystick (HID Subtype). */
|
||||
#define BLE_APPEARANCE_HID_GAMEPAD 964 /**< Gamepad (HID Subtype). */
|
||||
#define BLE_APPEARANCE_HID_DIGITIZERSUBTYPE 965 /**< Digitizer Tablet (HID Subtype). */
|
||||
#define BLE_APPEARANCE_HID_CARD_READER 966 /**< Card Reader (HID Subtype). */
|
||||
#define BLE_APPEARANCE_HID_DIGITAL_PEN 967 /**< Digital Pen (HID Subtype). */
|
||||
#define BLE_APPEARANCE_HID_BARCODE 968 /**< Barcode Scanner (HID Subtype). */
|
||||
#define BLE_APPEARANCE_GENERIC_GLUCOSE_METER 1024 /**< Generic Glucose Meter. */
|
||||
#define BLE_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR 1088 /**< Generic Running Walking Sensor. */
|
||||
#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE 1089 /**< Running Walking Sensor: In-Shoe. */
|
||||
#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE 1090 /**< Running Walking Sensor: On-Shoe. */
|
||||
#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP 1091 /**< Running Walking Sensor: On-Hip. */
|
||||
#define BLE_APPEARANCE_GENERIC_CYCLING 1152 /**< Generic Cycling. */
|
||||
#define BLE_APPEARANCE_CYCLING_CYCLING_COMPUTER 1153 /**< Cycling: Cycling Computer. */
|
||||
#define BLE_APPEARANCE_CYCLING_SPEED_SENSOR 1154 /**< Cycling: Speed Sensor. */
|
||||
#define BLE_APPEARANCE_CYCLING_CADENCE_SENSOR 1155 /**< Cycling: Cadence Sensor. */
|
||||
#define BLE_APPEARANCE_CYCLING_POWER_SENSOR 1156 /**< Cycling: Power Sensor. */
|
||||
#define BLE_APPEARANCE_CYCLING_SPEED_CADENCE_SENSOR 1157 /**< Cycling: Speed and Cadence Sensor. */
|
||||
#define BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 3136 /**< Generic Pulse Oximeter. */
|
||||
#define BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 3137 /**< Fingertip (Pulse Oximeter subtype). */
|
||||
#define BLE_APPEARANCE_PULSE_OXIMETER_WRIST_WORN 3138 /**< Wrist Worn(Pulse Oximeter subtype). */
|
||||
#define BLE_APPEARANCE_GENERIC_WEIGHT_SCALE 3200 /**< Generic Weight Scale. */
|
||||
#define BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACT 5184 /**< Generic Outdoor Sports Activity. */
|
||||
#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_DISP 5185 /**< Location Display Device (Outdoor Sports Activity subtype). */
|
||||
#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_DISP 5186 /**< Location and Navigation Display Device (Outdoor Sports Activity subtype). */
|
||||
#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_POD 5187 /**< Location Pod (Outdoor Sports Activity subtype). */
|
||||
#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_POD 5188 /**< Location and Navigation Pod (Outdoor Sports Activity subtype). */
|
||||
/** @} */
|
||||
|
||||
/** @brief Set .type and .uuid fields of ble_uuid_struct to specified UUID value. */
|
||||
#define BLE_UUID_BLE_ASSIGN(instance, value) do {\
|
||||
instance.type = BLE_UUID_TYPE_BLE; \
|
||||
instance.uuid = value;} while(0)
|
||||
|
||||
/** @brief Copy type and uuid members from src to dst ble_uuid_t pointer. Both pointers must be valid/non-null. */
|
||||
#define BLE_UUID_COPY_PTR(dst, src) do {\
|
||||
(dst)->type = (src)->type; \
|
||||
(dst)->uuid = (src)->uuid;} while(0)
|
||||
|
||||
/** @brief Copy type and uuid members from src to dst ble_uuid_t struct. */
|
||||
#define BLE_UUID_COPY_INST(dst, src) do {\
|
||||
(dst).type = (src).type; \
|
||||
(dst).uuid = (src).uuid;} while(0)
|
||||
|
||||
/** @brief Compare for equality both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */
|
||||
#define BLE_UUID_EQ(p_uuid1, p_uuid2) \
|
||||
(((p_uuid1)->type == (p_uuid2)->type) && ((p_uuid1)->uuid == (p_uuid2)->uuid))
|
||||
|
||||
/** @brief Compare for difference both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */
|
||||
#define BLE_UUID_NEQ(p_uuid1, p_uuid2) \
|
||||
(((p_uuid1)->type != (p_uuid2)->type) || ((p_uuid1)->uuid != (p_uuid2)->uuid))
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup BLE_TYPES_STRUCTURES Structures
|
||||
* @{ */
|
||||
|
||||
/** @brief 128 bit UUID values. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t uuid128[16]; /**< Little-Endian UUID bytes. */
|
||||
} ble_uuid128_t;
|
||||
|
||||
/** @brief Bluetooth Low Energy UUID type, encapsulates both 16-bit and 128-bit UUIDs. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t uuid; /**< 16-bit UUID value or octets 12-13 of 128-bit UUID. */
|
||||
uint8_t type; /**< UUID type, see @ref BLE_UUID_TYPES. If type is @ref BLE_UUID_TYPE_UNKNOWN, the value of uuid is undefined. */
|
||||
} ble_uuid_t;
|
||||
|
||||
/**@brief Data structure. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *p_data; /**< Pointer to the data buffer provided to/from the application. */
|
||||
uint16_t len; /**< Length of the data buffer, in bytes. */
|
||||
} ble_data_t;
|
||||
|
||||
/** @} */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BLE_TYPES_H__ */
|
||||
|
||||
/**
|
||||
@}
|
||||
@}
|
||||
*/
|
||||
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* Copyright (c) 2014 - 2017, Nordic Semiconductor ASA
|
||||
* 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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 Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup nrf_mbr_api Master Boot Record API
|
||||
@{
|
||||
|
||||
@brief APIs for updating SoftDevice and BootLoader
|
||||
|
||||
*/
|
||||
|
||||
#ifndef NRF_MBR_H__
|
||||
#define NRF_MBR_H__
|
||||
|
||||
#include "nrf_svc.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup NRF_MBR_DEFINES Defines
|
||||
* @{ */
|
||||
|
||||
/**@brief MBR SVC Base number. */
|
||||
#define MBR_SVC_BASE (0x18)
|
||||
|
||||
/**@brief Page size in words. */
|
||||
#define MBR_PAGE_SIZE_IN_WORDS (1024)
|
||||
|
||||
/** @brief The size that must be reserved for the MBR when a SoftDevice is written to flash.
|
||||
This is the offset where the first byte of the SoftDevice hex file is written. */
|
||||
#define MBR_SIZE (0x1000)
|
||||
|
||||
/** @brief Location (in the flash memory) of the bootloader address. */
|
||||
#define MBR_BOOTLOADER_ADDR (0xFF8)
|
||||
|
||||
/** @brief Location (in UICR) of the bootloader address. */
|
||||
#define MBR_UICR_BOOTLOADER_ADDR (&(NRF_UICR->NRFFW[0]))
|
||||
|
||||
/** @brief Location (in the flash memory) of the address of the MBR parameter page. */
|
||||
#define MBR_PARAM_PAGE_ADDR (0xFFC)
|
||||
|
||||
/** @brief Location (in UICR) of the address of the MBR parameter page. */
|
||||
#define MBR_UICR_PARAM_PAGE_ADDR (&(NRF_UICR->NRFFW[1]))
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup NRF_MBR_ENUMS Enumerations
|
||||
* @{ */
|
||||
|
||||
/**@brief nRF Master Boot Record API SVC numbers. */
|
||||
enum NRF_MBR_SVCS
|
||||
{
|
||||
SD_MBR_COMMAND = MBR_SVC_BASE, /**< ::sd_mbr_command */
|
||||
};
|
||||
|
||||
/**@brief Possible values for ::sd_mbr_command_t.command */
|
||||
enum NRF_MBR_COMMANDS
|
||||
{
|
||||
SD_MBR_COMMAND_COPY_BL, /**< Copy a new BootLoader. @see ::sd_mbr_command_copy_bl_t*/
|
||||
SD_MBR_COMMAND_COPY_SD, /**< Copy a new SoftDevice. @see ::sd_mbr_command_copy_sd_t*/
|
||||
SD_MBR_COMMAND_INIT_SD, /**< Initialize forwarding interrupts to SD, and run reset function in SD. Does not require any parameters in ::sd_mbr_command_t params.*/
|
||||
SD_MBR_COMMAND_COMPARE, /**< This command works like memcmp. @see ::sd_mbr_command_compare_t*/
|
||||
SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Change the address the MBR starts after a reset. @see ::sd_mbr_command_vector_table_base_set_t*/
|
||||
SD_MBR_COMMAND_RESERVED,
|
||||
SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET, /**< Start forwarding all interrupts to this address. @see ::sd_mbr_command_irq_forward_address_set_t*/
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup NRF_MBR_TYPES Types
|
||||
* @{ */
|
||||
|
||||
/**@brief This command copies part of a new SoftDevice
|
||||
*
|
||||
* The destination area is erased before copying.
|
||||
* If dst is in the middle of a flash page, that whole flash page will be erased.
|
||||
* If (dst+len) is in the middle of a flash page, that whole flash page will be erased.
|
||||
*
|
||||
* The user of this function is responsible for setting the BPROT registers.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly.
|
||||
* @retval ::NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t *src; /**< Pointer to the source of data to be copied.*/
|
||||
uint32_t *dst; /**< Pointer to the destination where the content is to be copied.*/
|
||||
uint32_t len; /**< Number of 32 bit words to copy. Must be a multiple of @ref MBR_PAGE_SIZE_IN_WORDS words.*/
|
||||
} sd_mbr_command_copy_sd_t;
|
||||
|
||||
|
||||
/**@brief This command works like memcmp, but takes the length in words.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS indicates that the contents of both memory blocks are equal.
|
||||
* @retval ::NRF_ERROR_NULL indicates that the contents of the memory blocks are not equal.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t *ptr1; /**< Pointer to block of memory. */
|
||||
uint32_t *ptr2; /**< Pointer to block of memory. */
|
||||
uint32_t len; /**< Number of 32 bit words to compare.*/
|
||||
} sd_mbr_command_compare_t;
|
||||
|
||||
|
||||
/**@brief This command copies a new BootLoader.
|
||||
*
|
||||
* The MBR assumes that either @ref MBR_BOOTLOADER_ADDR or @ref MBR_UICR_BOOTLOADER_ADDR is set to
|
||||
* the address where the bootloader will be copied. If both addresses are set, the MBR will prioritize
|
||||
* @ref MBR_BOOTLOADER_ADDR.
|
||||
*
|
||||
* The bootloader destination is erased by this function.
|
||||
* If (destination+bl_len) is in the middle of a flash page, that whole flash page will be erased.
|
||||
*
|
||||
* This command requires that @ref MBR_PARAM_PAGE_ADDR or @ref MBR_UICR_PARAM_PAGE_ADDR is set,
|
||||
* see @ref sd_mbr_command.
|
||||
*
|
||||
* This command will use the flash protect peripheral (BPROT or ACL) to protect the flash that is
|
||||
* not intended to be written.
|
||||
*
|
||||
* On success, this function will not return. It will start the new bootloader from reset-vector as normal.
|
||||
*
|
||||
* @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen.
|
||||
* @retval ::NRF_ERROR_FORBIDDEN if the bootloader address is not set.
|
||||
* @retval ::NRF_ERROR_INVALID_LENGTH if parameters attempts to read or write outside flash area.
|
||||
* @retval ::NRF_ERROR_NO_MEM No MBR parameter page is provided. See @ref sd_mbr_command.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t *bl_src; /**< Pointer to the source of the bootloader to be be copied.*/
|
||||
uint32_t bl_len; /**< Number of 32 bit words to copy for BootLoader. */
|
||||
} sd_mbr_command_copy_bl_t;
|
||||
|
||||
/**@brief Change the address the MBR starts after a reset
|
||||
*
|
||||
* Once this function has been called, this address is where the MBR will start to forward
|
||||
* interrupts to after a reset.
|
||||
*
|
||||
* To restore default forwarding, this function should be called with @ref address set to 0. If a
|
||||
* bootloader is present, interrupts will be forwarded to the bootloader. If not, interrupts will
|
||||
* be forwarded to the SoftDevice.
|
||||
*
|
||||
* The location of a bootloader can be specified in @ref MBR_BOOTLOADER_ADDR or
|
||||
* @ref MBR_UICR_BOOTLOADER_ADDR. If both addresses are set, the MBR will prioritize
|
||||
* @ref MBR_BOOTLOADER_ADDR.
|
||||
*
|
||||
* This command requires that @ref MBR_PARAM_PAGE_ADDR or @ref MBR_UICR_PARAM_PAGE_ADDR is set,
|
||||
* see @ref sd_mbr_command.
|
||||
*
|
||||
* On success, this function will not return. It will reset the device.
|
||||
*
|
||||
* @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen.
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR if parameter address is outside of the flash size.
|
||||
* @retval ::NRF_ERROR_NO_MEM No MBR parameter page is provided. See @ref sd_mbr_command.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/
|
||||
} sd_mbr_command_vector_table_base_set_t;
|
||||
|
||||
/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the MBR
|
||||
*
|
||||
* Unlike sd_mbr_command_vector_table_base_set_t, this function does not reset, and it does not
|
||||
* change where the MBR starts after reset.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/
|
||||
} sd_mbr_command_irq_forward_address_set_t;
|
||||
|
||||
/**@brief Input structure containing data used when calling ::sd_mbr_command
|
||||
*
|
||||
* Depending on what command value that is set, the corresponding params value type must also be
|
||||
* set. See @ref NRF_MBR_COMMANDS for command types and corresponding params value type. If command
|
||||
* @ref SD_MBR_COMMAND_INIT_SD is set, it is not necessary to set any values under params.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t command; /**< Type of command to be issued. See @ref NRF_MBR_COMMANDS. */
|
||||
union
|
||||
{
|
||||
sd_mbr_command_copy_sd_t copy_sd; /**< Parameters for copy SoftDevice.*/
|
||||
sd_mbr_command_compare_t compare; /**< Parameters for verify.*/
|
||||
sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy BootLoader. Requires parameter page. */
|
||||
sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set. Requires parameter page.*/
|
||||
sd_mbr_command_irq_forward_address_set_t irq_forward_address_set; /**< Parameters for irq forward address set*/
|
||||
} params; /**< Command parameters. */
|
||||
} sd_mbr_command_t;
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup NRF_MBR_FUNCTIONS Functions
|
||||
* @{ */
|
||||
|
||||
/**@brief Issue Master Boot Record commands
|
||||
*
|
||||
* Commands used when updating a SoftDevice and bootloader.
|
||||
*
|
||||
* The @ref SD_MBR_COMMAND_COPY_BL and @ref SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET requires
|
||||
* parameters to be retained by the MBR when resetting the IC. This is done in a separate flash
|
||||
* page. The location of the flash page should be provided by the application in either
|
||||
* @ref MBR_PARAM_PAGE_ADDR or @ref MBR_UICR_PARAM_PAGE_ADDR. If both addresses are set, the MBR
|
||||
* will prioritize @ref MBR_PARAM_PAGE_ADDR. This page will be cleared by the MBR and is used to
|
||||
* store the command before reset. When an address is specified, the page it refers to must not be
|
||||
* used by the application. If no address is provided by the application, i.e. both
|
||||
* @ref MBR_PARAM_PAGE_ADDR and @ref MBR_UICR_PARAM_PAGE_ADDR is 0xFFFFFFFF, MBR commands which use
|
||||
* flash will be unavailable and return @ref NRF_ERROR_NO_MEM.
|
||||
*
|
||||
* @param[in] param Pointer to a struct describing the command.
|
||||
*
|
||||
* @note For a complete set of return values, see ::sd_mbr_command_copy_sd_t,
|
||||
* ::sd_mbr_command_copy_bl_t, ::sd_mbr_command_compare_t,
|
||||
* ::sd_mbr_command_vector_table_base_set_t, ::sd_mbr_command_irq_forward_address_set_t
|
||||
*
|
||||
* @retval ::NRF_ERROR_NO_MEM No MBR parameter page provided
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM if an invalid command is given.
|
||||
*/
|
||||
SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t* param));
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // NRF_MBR_H__
|
||||
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2014 - 2017, Nordic Semiconductor ASA
|
||||
* 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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 Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup nrf_error SoftDevice Global Error Codes
|
||||
@{
|
||||
|
||||
@brief Global Error definitions
|
||||
*/
|
||||
|
||||
/* Header guard */
|
||||
#ifndef NRF_ERROR_H__
|
||||
#define NRF_ERROR_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions
|
||||
* @{ */
|
||||
#define NRF_ERROR_BASE_NUM (0x0) ///< Global error base
|
||||
#define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base
|
||||
#define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base
|
||||
#define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base
|
||||
/** @} */
|
||||
|
||||
#define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command
|
||||
#define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing
|
||||
#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled
|
||||
#define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error
|
||||
#define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation
|
||||
#define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found
|
||||
#define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported
|
||||
#define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter
|
||||
#define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state
|
||||
#define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length
|
||||
#define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags
|
||||
#define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data
|
||||
#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Invalid Data size
|
||||
#define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out
|
||||
#define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer
|
||||
#define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation
|
||||
#define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address
|
||||
#define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy
|
||||
#define NRF_ERROR_CONN_COUNT (NRF_ERROR_BASE_NUM + 18) ///< Maximum connection count exceeded.
|
||||
#define NRF_ERROR_RESOURCES (NRF_ERROR_BASE_NUM + 19) ///< Not enough resources for operation
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // NRF_ERROR_H__
|
||||
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2012 - 2017, Nordic Semiconductor ASA
|
||||
* 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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 Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup nrf_sdm_api
|
||||
@{
|
||||
@defgroup nrf_sdm_error SoftDevice Manager Error Codes
|
||||
@{
|
||||
|
||||
@brief Error definitions for the SDM API
|
||||
*/
|
||||
|
||||
/* Header guard */
|
||||
#ifndef NRF_ERROR_SDM_H__
|
||||
#define NRF_ERROR_SDM_H__
|
||||
|
||||
#include "nrf_error.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN (NRF_ERROR_SDM_BASE_NUM + 0) ///< Unknown LFCLK source.
|
||||
#define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1) ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts).
|
||||
#define NRF_ERROR_SDM_INCORRECT_CLENR0 (NRF_ERROR_SDM_BASE_NUM + 2) ///< Incorrect CLENR0 (can be caused by erroneous SoftDevice flashing).
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // NRF_ERROR_SDM_H__
|
||||
|
||||
/**
|
||||
@}
|
||||
@}
|
||||
*/
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2012 - 2017, Nordic Semiconductor ASA
|
||||
* 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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 Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@addtogroup nrf_soc_api
|
||||
@{
|
||||
@defgroup nrf_soc_error SoC Library Error Codes
|
||||
@{
|
||||
|
||||
@brief Error definitions for the SoC library
|
||||
|
||||
*/
|
||||
|
||||
/* Header guard */
|
||||
#ifndef NRF_ERROR_SOC_H__
|
||||
#define NRF_ERROR_SOC_H__
|
||||
|
||||
#include "nrf_error.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Mutex Errors */
|
||||
#define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN (NRF_ERROR_SOC_BASE_NUM + 0) ///< Mutex already taken
|
||||
|
||||
/* NVIC errors */
|
||||
#define NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE (NRF_ERROR_SOC_BASE_NUM + 1) ///< NVIC interrupt not available
|
||||
#define NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED (NRF_ERROR_SOC_BASE_NUM + 2) ///< NVIC interrupt priority not allowed
|
||||
#define NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 3) ///< NVIC should not return
|
||||
|
||||
/* Power errors */
|
||||
#define NRF_ERROR_SOC_POWER_MODE_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 4) ///< Power mode unknown
|
||||
#define NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 5) ///< Power POF threshold unknown
|
||||
#define NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 6) ///< Power off should not return
|
||||
|
||||
/* Rand errors */
|
||||
#define NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES (NRF_ERROR_SOC_BASE_NUM + 7) ///< RAND not enough values
|
||||
|
||||
/* PPI errors */
|
||||
#define NRF_ERROR_SOC_PPI_INVALID_CHANNEL (NRF_ERROR_SOC_BASE_NUM + 8) ///< Invalid PPI Channel
|
||||
#define NRF_ERROR_SOC_PPI_INVALID_GROUP (NRF_ERROR_SOC_BASE_NUM + 9) ///< Invalid PPI Group
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // NRF_ERROR_SOC_H__
|
||||
/**
|
||||
@}
|
||||
@}
|
||||
*/
|
||||
@@ -0,0 +1,491 @@
|
||||
/*
|
||||
* Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
|
||||
* 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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 Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup nrf_nvic_api SoftDevice NVIC API
|
||||
* @{
|
||||
*
|
||||
* @note In order to use this module, the following code has to be added to a .c file:
|
||||
* \code
|
||||
* nrf_nvic_state_t nrf_nvic_state = {0};
|
||||
* \endcode
|
||||
*
|
||||
* @note Definitions and declarations starting with __ (double underscore) in this header file are
|
||||
* not intended for direct use by the application.
|
||||
*
|
||||
* @brief APIs for the accessing NVIC when using a SoftDevice.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NRF_NVIC_H__
|
||||
#define NRF_NVIC_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "nrf.h"
|
||||
#include "nrf_svc.h"
|
||||
#include "nrf_error.h"
|
||||
#include "nrf_error_soc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**@addtogroup NRF_NVIC_DEFINES Defines
|
||||
* @{ */
|
||||
|
||||
/**@defgroup NRF_NVIC_ISER_DEFINES SoftDevice NVIC internal definitions
|
||||
* @{ */
|
||||
|
||||
#define __NRF_NVIC_NVMC_IRQn (30) /**< The peripheral ID of the NVMC. IRQ numbers are used to identify peripherals, but the NVMC doesn't have an IRQ number in the MDK. */
|
||||
|
||||
#define __NRF_NVIC_ISER_COUNT (2) /**< The number of ISER/ICER registers in the NVIC that are used. */
|
||||
|
||||
/**@brief Interrupt priority levels used by the SoftDevice. */
|
||||
#define __NRF_NVIC_SD_IRQ_PRIOS ((uint8_t)( \
|
||||
(1U << 0) /**< Priority level high .*/ \
|
||||
| (1U << 1) /**< Priority level medium. */ \
|
||||
| (1U << 4) /**< Priority level low. */ \
|
||||
))
|
||||
|
||||
/**@brief Interrupt priority levels available to the application. */
|
||||
#define __NRF_NVIC_APP_IRQ_PRIOS ((uint8_t)~__NRF_NVIC_SD_IRQ_PRIOS)
|
||||
|
||||
/**@brief Interrupts used by the SoftDevice, with IRQn in the range 0-31. */
|
||||
#define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \
|
||||
(1U << POWER_CLOCK_IRQn) \
|
||||
| (1U << RADIO_IRQn) \
|
||||
| (1U << RTC0_IRQn) \
|
||||
| (1U << TIMER0_IRQn) \
|
||||
| (1U << RNG_IRQn) \
|
||||
| (1U << ECB_IRQn) \
|
||||
| (1U << CCM_AAR_IRQn) \
|
||||
| (1U << TEMP_IRQn) \
|
||||
| (1U << __NRF_NVIC_NVMC_IRQn) \
|
||||
| (1U << (uint32_t)SWI5_IRQn) \
|
||||
))
|
||||
|
||||
/**@brief Interrupts used by the SoftDevice, with IRQn in the range 32-63. */
|
||||
#define __NRF_NVIC_SD_IRQS_1 ((uint32_t)0)
|
||||
|
||||
/**@brief Interrupts available for to application, with IRQn in the range 0-31. */
|
||||
#define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0)
|
||||
|
||||
/**@brief Interrupts available for to application, with IRQn in the range 32-63. */
|
||||
#define __NRF_NVIC_APP_IRQS_1 (~__NRF_NVIC_SD_IRQS_1)
|
||||
|
||||
/**@} */
|
||||
|
||||
/**@} */
|
||||
|
||||
/**@addtogroup NRF_NVIC_VARIABLES Variables
|
||||
* @{ */
|
||||
|
||||
/**@brief Type representing the state struct for the SoftDevice NVIC module. */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t volatile __irq_masks[__NRF_NVIC_ISER_COUNT]; /**< IRQs enabled by the application in the NVIC. */
|
||||
uint32_t volatile __cr_flag; /**< Non-zero if already in a critical region */
|
||||
} nrf_nvic_state_t;
|
||||
|
||||
/**@brief Variable keeping the state for the SoftDevice NVIC module. This must be declared in an
|
||||
* application source file. */
|
||||
extern nrf_nvic_state_t nrf_nvic_state;
|
||||
|
||||
/**@} */
|
||||
|
||||
/**@addtogroup NRF_NVIC_INTERNAL_FUNCTIONS SoftDevice NVIC internal functions
|
||||
* @{ */
|
||||
|
||||
/**@brief Disables IRQ interrupts globally, including the SoftDevice's interrupts.
|
||||
*
|
||||
* @retval The value of PRIMASK prior to disabling the interrupts.
|
||||
*/
|
||||
__STATIC_INLINE int __sd_nvic_irq_disable(void);
|
||||
|
||||
/**@brief Enables IRQ interrupts globally, including the SoftDevice's interrupts.
|
||||
*/
|
||||
__STATIC_INLINE void __sd_nvic_irq_enable(void);
|
||||
|
||||
/**@brief Checks if IRQn is available to application
|
||||
* @param[in] IRQn IRQ to check
|
||||
*
|
||||
* @retval 1 (true) if the IRQ to check is available to the application
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn);
|
||||
|
||||
/**@brief Checks if priority is available to application
|
||||
* @param[in] priority priority to check
|
||||
*
|
||||
* @retval 1 (true) if the priority to check is available to the application
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __sd_nvic_is_app_accessible_priority(uint32_t priority);
|
||||
|
||||
/**@} */
|
||||
|
||||
/**@addtogroup NRF_NVIC_FUNCTIONS SoftDevice NVIC public functions
|
||||
* @{ */
|
||||
|
||||
/**@brief Enable External Interrupt.
|
||||
* @note Corresponds to NVIC_EnableIRQ in CMSIS.
|
||||
*
|
||||
* @pre IRQn is valid and not reserved by the stack.
|
||||
*
|
||||
* @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS The interrupt was enabled.
|
||||
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application.
|
||||
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn);
|
||||
|
||||
/**@brief Disable External Interrupt.
|
||||
* @note Corresponds to NVIC_DisableIRQ in CMSIS.
|
||||
*
|
||||
* @pre IRQn is valid and not reserved by the stack.
|
||||
*
|
||||
* @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS The interrupt was disabled.
|
||||
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn);
|
||||
|
||||
/**@brief Get Pending Interrupt.
|
||||
* @note Corresponds to NVIC_GetPendingIRQ in CMSIS.
|
||||
*
|
||||
* @pre IRQn is valid and not reserved by the stack.
|
||||
*
|
||||
* @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS.
|
||||
* @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS The interrupt is available for the application.
|
||||
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq);
|
||||
|
||||
/**@brief Set Pending Interrupt.
|
||||
* @note Corresponds to NVIC_SetPendingIRQ in CMSIS.
|
||||
*
|
||||
* @pre IRQn is valid and not reserved by the stack.
|
||||
*
|
||||
* @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS The interrupt is set pending.
|
||||
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn);
|
||||
|
||||
/**@brief Clear Pending Interrupt.
|
||||
* @note Corresponds to NVIC_ClearPendingIRQ in CMSIS.
|
||||
*
|
||||
* @pre IRQn is valid and not reserved by the stack.
|
||||
*
|
||||
* @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS The interrupt pending flag is cleared.
|
||||
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn);
|
||||
|
||||
/**@brief Set Interrupt Priority.
|
||||
* @note Corresponds to NVIC_SetPriority in CMSIS.
|
||||
*
|
||||
* @pre IRQn is valid and not reserved by the stack.
|
||||
* @pre Priority is valid and not reserved by the stack.
|
||||
*
|
||||
* @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS.
|
||||
* @param[in] priority A valid IRQ priority for use by the application.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS The interrupt and priority level is available for the application.
|
||||
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
|
||||
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority);
|
||||
|
||||
/**@brief Get Interrupt Priority.
|
||||
* @note Corresponds to NVIC_GetPriority in CMSIS.
|
||||
*
|
||||
* @pre IRQn is valid and not reserved by the stack.
|
||||
*
|
||||
* @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS.
|
||||
* @param[out] p_priority Return value from NVIC_GetPriority.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority.
|
||||
* @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority);
|
||||
|
||||
/**@brief System Reset.
|
||||
* @note Corresponds to NVIC_SystemReset in CMSIS.
|
||||
*
|
||||
* @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN
|
||||
*/
|
||||
__STATIC_INLINE uint32_t sd_nvic_SystemReset(void);
|
||||
|
||||
/**@brief Enter critical region.
|
||||
*
|
||||
* @post Application interrupts will be disabled.
|
||||
* @note sd_nvic_critical_region_enter() and ::sd_nvic_critical_region_exit() must be called in matching pairs inside each
|
||||
* execution context
|
||||
* @sa sd_nvic_critical_region_exit
|
||||
*
|
||||
* @param[out] p_is_nested_critical_region If 1, the application is now in a nested critical region.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS
|
||||
*/
|
||||
__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region);
|
||||
|
||||
/**@brief Exit critical region.
|
||||
*
|
||||
* @pre Application has entered a critical region using ::sd_nvic_critical_region_enter.
|
||||
* @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called.
|
||||
*
|
||||
* @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS
|
||||
*/
|
||||
__STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region);
|
||||
|
||||
/**@} */
|
||||
|
||||
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
|
||||
|
||||
__STATIC_INLINE int __sd_nvic_irq_disable(void)
|
||||
{
|
||||
int pm = __get_PRIMASK();
|
||||
__disable_irq();
|
||||
return pm;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void __sd_nvic_irq_enable(void)
|
||||
{
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn)
|
||||
{
|
||||
if (IRQn < 32)
|
||||
{
|
||||
return ((1UL<<IRQn) & __NRF_NVIC_APP_IRQS_0) != 0;
|
||||
}
|
||||
else if (IRQn < 64)
|
||||
{
|
||||
return ((1UL<<(IRQn-32)) & __NRF_NVIC_APP_IRQS_1) != 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t __sd_nvic_is_app_accessible_priority(uint32_t priority)
|
||||
{
|
||||
if( (priority >= (1 << __NVIC_PRIO_BITS))
|
||||
|| (((1 << priority) & __NRF_NVIC_APP_IRQ_PRIOS) == 0)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
__STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if (!__sd_nvic_app_accessible_irq(IRQn))
|
||||
{
|
||||
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
|
||||
}
|
||||
if (!__sd_nvic_is_app_accessible_priority(NVIC_GetPriority(IRQn)))
|
||||
{
|
||||
return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED;
|
||||
}
|
||||
|
||||
if (nrf_nvic_state.__cr_flag)
|
||||
{
|
||||
nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] |= (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F));
|
||||
}
|
||||
else
|
||||
{
|
||||
NVIC_EnableIRQ(IRQn);
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if (!__sd_nvic_app_accessible_irq(IRQn))
|
||||
{
|
||||
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (nrf_nvic_state.__cr_flag)
|
||||
{
|
||||
nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] &= ~(1UL << ((uint32_t)(IRQn) & 0x1F));
|
||||
}
|
||||
else
|
||||
{
|
||||
NVIC_DisableIRQ(IRQn);
|
||||
}
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq)
|
||||
{
|
||||
if (__sd_nvic_app_accessible_irq(IRQn))
|
||||
{
|
||||
*p_pending_irq = NVIC_GetPendingIRQ(IRQn);
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if (__sd_nvic_app_accessible_irq(IRQn))
|
||||
{
|
||||
NVIC_SetPendingIRQ(IRQn);
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if (__sd_nvic_app_accessible_irq(IRQn))
|
||||
{
|
||||
NVIC_ClearPendingIRQ(IRQn);
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority)
|
||||
{
|
||||
if (!__sd_nvic_app_accessible_irq(IRQn))
|
||||
{
|
||||
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (!__sd_nvic_is_app_accessible_priority(priority))
|
||||
{
|
||||
return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED;
|
||||
}
|
||||
|
||||
NVIC_SetPriority(IRQn, (uint32_t)priority);
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority)
|
||||
{
|
||||
if (__sd_nvic_app_accessible_irq(IRQn))
|
||||
{
|
||||
*p_priority = (NVIC_GetPriority(IRQn) & 0xFF);
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t sd_nvic_SystemReset(void)
|
||||
{
|
||||
NVIC_SystemReset();
|
||||
return NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region)
|
||||
{
|
||||
int was_masked = __sd_nvic_irq_disable();
|
||||
if (!nrf_nvic_state.__cr_flag)
|
||||
{
|
||||
nrf_nvic_state.__cr_flag = 1;
|
||||
nrf_nvic_state.__irq_masks[0] = ( NVIC->ICER[0] & __NRF_NVIC_APP_IRQS_0 );
|
||||
NVIC->ICER[0] = __NRF_NVIC_APP_IRQS_0;
|
||||
nrf_nvic_state.__irq_masks[1] = ( NVIC->ICER[1] & __NRF_NVIC_APP_IRQS_1 );
|
||||
NVIC->ICER[1] = __NRF_NVIC_APP_IRQS_1;
|
||||
*p_is_nested_critical_region = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*p_is_nested_critical_region = 1;
|
||||
}
|
||||
if (!was_masked)
|
||||
{
|
||||
__sd_nvic_irq_enable();
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region)
|
||||
{
|
||||
if (nrf_nvic_state.__cr_flag && (is_nested_critical_region == 0))
|
||||
{
|
||||
int was_masked = __sd_nvic_irq_disable();
|
||||
NVIC->ISER[0] = nrf_nvic_state.__irq_masks[0];
|
||||
NVIC->ISER[1] = nrf_nvic_state.__irq_masks[1];
|
||||
nrf_nvic_state.__cr_flag = 0;
|
||||
if (!was_masked)
|
||||
{
|
||||
__sd_nvic_irq_enable();
|
||||
}
|
||||
}
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NRF_NVIC_H__
|
||||
|
||||
/**@} */
|
||||
@@ -0,0 +1,367 @@
|
||||
/*
|
||||
* Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
|
||||
* 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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 Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@defgroup nrf_sdm_api SoftDevice Manager API
|
||||
@{
|
||||
|
||||
@brief APIs for SoftDevice management.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef NRF_SDM_H__
|
||||
#define NRF_SDM_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "nrf.h"
|
||||
#include "nrf_svc.h"
|
||||
#include "nrf_error.h"
|
||||
#include "nrf_error_sdm.h"
|
||||
#include "nrf_soc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup NRF_SDM_DEFINES Defines
|
||||
* @{ */
|
||||
#ifdef NRFSOC_DOXYGEN
|
||||
/// Declared in nrf_mbr.h
|
||||
#define MBR_SIZE 0
|
||||
#warning test
|
||||
#endif
|
||||
|
||||
/** @brief The major version for the SoftDevice binary distributed with this header file. */
|
||||
#define SD_MAJOR_VERSION (6)
|
||||
|
||||
/** @brief The minor version for the SoftDevice binary distributed with this header file. */
|
||||
#define SD_MINOR_VERSION (1)
|
||||
|
||||
/** @brief The bugfix version for the SoftDevice binary distributed with this header file. */
|
||||
#define SD_BUGFIX_VERSION (1)
|
||||
|
||||
/** @brief The SoftDevice variant of this firmware. */
|
||||
#define SD_VARIANT_ID 140
|
||||
|
||||
/** @brief The full version number for the SoftDevice binary this header file was distributed
|
||||
* with, as a decimal number in the form Mmmmbbb, where:
|
||||
* - M is major version (one or more digits)
|
||||
* - mmm is minor version (three digits)
|
||||
* - bbb is bugfix version (three digits). */
|
||||
#define SD_VERSION (SD_MAJOR_VERSION * 1000000 + SD_MINOR_VERSION * 1000 + SD_BUGFIX_VERSION)
|
||||
|
||||
/** @brief SoftDevice Manager SVC Base number. */
|
||||
#define SDM_SVC_BASE 0x10
|
||||
|
||||
/** @brief SoftDevice unique string size in bytes. */
|
||||
#define SD_UNIQUE_STR_SIZE 20
|
||||
|
||||
/** @brief Invalid info field. Returned when an info field does not exist. */
|
||||
#define SDM_INFO_FIELD_INVALID (0)
|
||||
|
||||
/** @brief Defines the SoftDevice Information Structure location (address) as an offset from
|
||||
the start of the SoftDevice (without MBR)*/
|
||||
#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000)
|
||||
|
||||
/** @brief Defines the absolute SoftDevice Information Structure location (address) when the
|
||||
* SoftDevice is installed just above the MBR (the usual case). */
|
||||
#define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE)
|
||||
|
||||
/** @brief Defines the offset for the SoftDevice Information Structure size value relative to the
|
||||
* SoftDevice base address. The size value is of type uint8_t. */
|
||||
#define SD_INFO_STRUCT_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET)
|
||||
|
||||
/** @brief Defines the offset for the SoftDevice size value relative to the SoftDevice base address.
|
||||
* The size value is of type uint32_t. */
|
||||
#define SD_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08)
|
||||
|
||||
/** @brief Defines the offset for FWID value relative to the SoftDevice base address. The FWID value
|
||||
* is of type uint16_t. */
|
||||
#define SD_FWID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C)
|
||||
|
||||
/** @brief Defines the offset for the SoftDevice ID relative to the SoftDevice base address. The ID
|
||||
* is of type uint32_t. */
|
||||
#define SD_ID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x10)
|
||||
|
||||
/** @brief Defines the offset for the SoftDevice version relative to the SoftDevice base address in
|
||||
* the same format as @ref SD_VERSION, stored as an uint32_t. */
|
||||
#define SD_VERSION_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x14)
|
||||
|
||||
/** @brief Defines the offset for the SoftDevice unique string relative to the SoftDevice base address.
|
||||
* The SD_UNIQUE_STR is stored as an array of uint8_t. The size of array is @ref SD_UNIQUE_STR_SIZE.
|
||||
*/
|
||||
#define SD_UNIQUE_STR_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x18)
|
||||
|
||||
/** @brief Defines a macro for retrieving the actual SoftDevice Information Structure size value
|
||||
* from a given base address. Use @ref MBR_SIZE as the argument when the SoftDevice is
|
||||
* installed just above the MBR (the usual case). */
|
||||
#define SD_INFO_STRUCT_SIZE_GET(baseaddr) (*((uint8_t *) ((baseaddr) + SD_INFO_STRUCT_SIZE_OFFSET)))
|
||||
|
||||
/** @brief Defines a macro for retrieving the actual SoftDevice size value from a given base
|
||||
* address. Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above
|
||||
* the MBR (the usual case). */
|
||||
#define SD_SIZE_GET(baseaddr) (*((uint32_t *) ((baseaddr) + SD_SIZE_OFFSET)))
|
||||
|
||||
/** @brief Defines the amount of flash that is used by the SoftDevice.
|
||||
* Add @ref MBR_SIZE to find the first available flash address when the SoftDevice is installed
|
||||
* just above the MBR (the usual case).
|
||||
*/
|
||||
#define SD_FLASH_SIZE 0x25000
|
||||
|
||||
/** @brief Defines a macro for retrieving the actual FWID value from a given base address. Use
|
||||
* @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the usual
|
||||
* case). */
|
||||
#define SD_FWID_GET(baseaddr) (*((uint16_t *) ((baseaddr) + SD_FWID_OFFSET)))
|
||||
|
||||
/** @brief Defines a macro for retrieving the actual SoftDevice ID from a given base address. Use
|
||||
* @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the
|
||||
* usual case). */
|
||||
#define SD_ID_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_ID_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \
|
||||
? (*((uint32_t *) ((baseaddr) + SD_ID_OFFSET))) : SDM_INFO_FIELD_INVALID)
|
||||
|
||||
/** @brief Defines a macro for retrieving the actual SoftDevice version from a given base address.
|
||||
* Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR
|
||||
* (the usual case). */
|
||||
#define SD_VERSION_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_VERSION_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \
|
||||
? (*((uint32_t *) ((baseaddr) + SD_VERSION_OFFSET))) : SDM_INFO_FIELD_INVALID)
|
||||
|
||||
/** @brief Defines a macro for retrieving the address of SoftDevice unique str based on a given base address.
|
||||
* Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR
|
||||
* (the usual case). */
|
||||
#define SD_UNIQUE_STR_ADDR_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_UNIQUE_STR_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \
|
||||
? (((uint8_t *) ((baseaddr) + SD_UNIQUE_STR_OFFSET))) : SDM_INFO_FIELD_INVALID)
|
||||
|
||||
/**@defgroup NRF_FAULT_ID_RANGES Fault ID ranges
|
||||
* @{ */
|
||||
#define NRF_FAULT_ID_SD_RANGE_START 0x00000000 /**< SoftDevice ID range start. */
|
||||
#define NRF_FAULT_ID_APP_RANGE_START 0x00001000 /**< Application ID range start. */
|
||||
/**@} */
|
||||
|
||||
/**@defgroup NRF_FAULT_IDS Fault ID types
|
||||
* @{ */
|
||||
#define NRF_FAULT_ID_SD_ASSERT (NRF_FAULT_ID_SD_RANGE_START + 1) /**< SoftDevice assertion. The info parameter is reserved for future used. */
|
||||
#define NRF_FAULT_ID_APP_MEMACC (NRF_FAULT_ID_APP_RANGE_START + 1) /**< Application invalid memory access. The info parameter will contain 0x00000000,
|
||||
in case of SoftDevice RAM access violation. In case of SoftDevice peripheral
|
||||
register violation the info parameter will contain the sub-region number of
|
||||
PREGION[0], on whose address range the disallowed write access caused the
|
||||
memory access fault. */
|
||||
/**@} */
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup NRF_SDM_ENUMS Enumerations
|
||||
* @{ */
|
||||
|
||||
/**@brief nRF SoftDevice Manager API SVC numbers. */
|
||||
enum NRF_SD_SVCS
|
||||
{
|
||||
SD_SOFTDEVICE_ENABLE = SDM_SVC_BASE, /**< ::sd_softdevice_enable */
|
||||
SD_SOFTDEVICE_DISABLE, /**< ::sd_softdevice_disable */
|
||||
SD_SOFTDEVICE_IS_ENABLED, /**< ::sd_softdevice_is_enabled */
|
||||
SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, /**< ::sd_softdevice_vector_table_base_set */
|
||||
SVC_SDM_LAST /**< Placeholder for last SDM SVC */
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup NRF_SDM_DEFINES Defines
|
||||
* @{ */
|
||||
|
||||
/**@defgroup NRF_CLOCK_LF_ACCURACY Clock accuracy
|
||||
* @{ */
|
||||
|
||||
#define NRF_CLOCK_LF_ACCURACY_250_PPM (0) /**< Default: 250 ppm */
|
||||
#define NRF_CLOCK_LF_ACCURACY_500_PPM (1) /**< 500 ppm */
|
||||
#define NRF_CLOCK_LF_ACCURACY_150_PPM (2) /**< 150 ppm */
|
||||
#define NRF_CLOCK_LF_ACCURACY_100_PPM (3) /**< 100 ppm */
|
||||
#define NRF_CLOCK_LF_ACCURACY_75_PPM (4) /**< 75 ppm */
|
||||
#define NRF_CLOCK_LF_ACCURACY_50_PPM (5) /**< 50 ppm */
|
||||
#define NRF_CLOCK_LF_ACCURACY_30_PPM (6) /**< 30 ppm */
|
||||
#define NRF_CLOCK_LF_ACCURACY_20_PPM (7) /**< 20 ppm */
|
||||
#define NRF_CLOCK_LF_ACCURACY_10_PPM (8) /**< 10 ppm */
|
||||
#define NRF_CLOCK_LF_ACCURACY_5_PPM (9) /**< 5 ppm */
|
||||
#define NRF_CLOCK_LF_ACCURACY_2_PPM (10) /**< 2 ppm */
|
||||
#define NRF_CLOCK_LF_ACCURACY_1_PPM (11) /**< 1 ppm */
|
||||
|
||||
/** @} */
|
||||
|
||||
/**@defgroup NRF_CLOCK_LF_SRC Possible LFCLK oscillator sources
|
||||
* @{ */
|
||||
|
||||
#define NRF_CLOCK_LF_SRC_RC (0) /**< LFCLK RC oscillator. */
|
||||
#define NRF_CLOCK_LF_SRC_XTAL (1) /**< LFCLK crystal oscillator. */
|
||||
#define NRF_CLOCK_LF_SRC_SYNTH (2) /**< LFCLK Synthesized from HFCLK. */
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup NRF_SDM_TYPES Types
|
||||
* @{ */
|
||||
|
||||
/**@brief Type representing LFCLK oscillator source. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t source; /**< LF oscillator clock source, see @ref NRF_CLOCK_LF_SRC. */
|
||||
uint8_t rc_ctiv; /**< Only for ::NRF_CLOCK_LF_SRC_RC: Calibration timer interval in 1/4 second
|
||||
units (nRF52: 1-32).
|
||||
@note To avoid excessive clock drift, 0.5 degrees Celsius is the
|
||||
maximum temperature change allowed in one calibration timer
|
||||
interval. The interval should be selected to ensure this.
|
||||
|
||||
@note Must be 0 if source is not ::NRF_CLOCK_LF_SRC_RC. */
|
||||
uint8_t rc_temp_ctiv; /**< Only for ::NRF_CLOCK_LF_SRC_RC: How often (in number of calibration
|
||||
intervals) the RC oscillator shall be calibrated if the temperature
|
||||
hasn't changed.
|
||||
0: Always calibrate even if the temperature hasn't changed.
|
||||
1: Only calibrate if the temperature has changed (legacy - nRF51 only).
|
||||
2-33: Check the temperature and only calibrate if it has changed,
|
||||
however calibration will take place every rc_temp_ctiv
|
||||
intervals in any case.
|
||||
|
||||
@note Must be 0 if source is not ::NRF_CLOCK_LF_SRC_RC.
|
||||
|
||||
@note For nRF52, the application must ensure calibration at least once
|
||||
every 8 seconds to ensure +/-500 ppm clock stability. The
|
||||
recommended configuration for ::NRF_CLOCK_LF_SRC_RC on nRF52 is
|
||||
rc_ctiv=16 and rc_temp_ctiv=2. This will ensure calibration at
|
||||
least once every 8 seconds and for temperature changes of 0.5
|
||||
degrees Celsius every 4 seconds. See the Product Specification
|
||||
for the nRF52 device being used for more information.*/
|
||||
uint8_t accuracy; /**< External clock accuracy used in the LL to compute timing
|
||||
windows, see @ref NRF_CLOCK_LF_ACCURACY.*/
|
||||
} nrf_clock_lf_cfg_t;
|
||||
|
||||
/**@brief Fault Handler type.
|
||||
*
|
||||
* When certain unrecoverable errors occur within the application or SoftDevice the fault handler will be called back.
|
||||
* The protocol stack will be in an undefined state when this happens and the only way to recover will be to
|
||||
* perform a reset, using e.g. CMSIS NVIC_SystemReset().
|
||||
* If the application returns from the fault handler the SoftDevice will call NVIC_SystemReset().
|
||||
*
|
||||
* @note This callback is executed in HardFault context, thus SVC functions cannot be called from the fault callback.
|
||||
*
|
||||
* @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
|
||||
* @param[in] pc The program counter of the instruction that triggered the fault.
|
||||
* @param[in] info Optional additional information regarding the fault. Refer to each Fault identifier for details.
|
||||
*
|
||||
* @note When id is set to @ref NRF_FAULT_ID_APP_MEMACC, pc will contain the address of the instruction being executed at the time when
|
||||
* the fault is detected by the CPU. The CPU program counter may have advanced up to 2 instructions (no branching) after the one that triggered the fault.
|
||||
*/
|
||||
typedef void (*nrf_fault_handler_t)(uint32_t id, uint32_t pc, uint32_t info);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @addtogroup NRF_SDM_FUNCTIONS Functions
|
||||
* @{ */
|
||||
|
||||
/**@brief Enables the SoftDevice and by extension the protocol stack.
|
||||
*
|
||||
* @note Some care must be taken if a low frequency clock source is already running when calling this function:
|
||||
* If the LF clock has a different source then the one currently running, it will be stopped. Then, the new
|
||||
* clock source will be started.
|
||||
*
|
||||
* @note This function has no effect when returning with an error.
|
||||
*
|
||||
* @post If return code is ::NRF_SUCCESS
|
||||
* - SoC library and protocol stack APIs are made available.
|
||||
* - A portion of RAM will be unavailable (see relevant SDS documentation).
|
||||
* - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation).
|
||||
* - Interrupts will not arrive from protected peripherals or interrupts.
|
||||
* - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the SoftDevice.
|
||||
* - Interrupt latency may be affected by the SoftDevice (see relevant SDS documentation).
|
||||
* - Chosen low frequency clock source will be running.
|
||||
*
|
||||
* @param p_clock_lf_cfg Low frequency clock source and accuracy.
|
||||
If NULL the clock will be configured as an RC source with rc_ctiv = 16 and .rc_temp_ctiv = 2
|
||||
In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock.
|
||||
* @param fault_handler Callback to be invoked in case of fault, cannot be NULL.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS
|
||||
* @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied.
|
||||
* @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and fault handler cannot be updated.
|
||||
* @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDevice interrupt is already enabled, or an enabled interrupt has an illegal priority level.
|
||||
* @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected.
|
||||
* @retval ::NRF_ERROR_INVALID_PARAM Invalid clock source configuration supplied in p_clock_lf_cfg.
|
||||
*/
|
||||
SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler));
|
||||
|
||||
|
||||
/**@brief Disables the SoftDevice and by extension the protocol stack.
|
||||
*
|
||||
* Idempotent function to disable the SoftDevice.
|
||||
*
|
||||
* @post SoC library and protocol stack APIs are made unavailable.
|
||||
* @post All interrupts that was protected by the SoftDevice will be disabled and initialized to priority 0 (highest).
|
||||
* @post All peripherals used by the SoftDevice will be reset to default values.
|
||||
* @post All of RAM become available.
|
||||
* @post All interrupts are forwarded to the application.
|
||||
* @post LFCLK source chosen in ::sd_softdevice_enable will be left running.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS
|
||||
*/
|
||||
SVCALL(SD_SOFTDEVICE_DISABLE, uint32_t, sd_softdevice_disable(void));
|
||||
|
||||
/**@brief Check if the SoftDevice is enabled.
|
||||
*
|
||||
* @param[out] p_softdevice_enabled If the SoftDevice is enabled: 1 else 0.
|
||||
*
|
||||
* @retval ::NRF_SUCCESS
|
||||
*/
|
||||
SVCALL(SD_SOFTDEVICE_IS_ENABLED, uint32_t, sd_softdevice_is_enabled(uint8_t * p_softdevice_enabled));
|
||||
|
||||
/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the SoftDevice
|
||||
*
|
||||
* This function is only intended to be called when a bootloader is enabled.
|
||||
*
|
||||
* @param[in] address The base address of the interrupt vector table for forwarded interrupts.
|
||||
|
||||
* @retval ::NRF_SUCCESS
|
||||
*/
|
||||
SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address));
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // NRF_SDM_H__
|
||||
|
||||
/**
|
||||
@}
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2012 - 2017, Nordic Semiconductor ASA
|
||||
* 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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 Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_SVC__
|
||||
#define NRF_SVC__
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef SVCALL_AS_NORMAL_FUNCTION
|
||||
#define SVCALL(number, return_type, signature) return_type signature
|
||||
#else
|
||||
|
||||
#ifndef SVCALL
|
||||
#if defined (__CC_ARM)
|
||||
#define SVCALL(number, return_type, signature) return_type __svc(number) signature
|
||||
#elif defined (__GNUC__)
|
||||
#ifdef __cplusplus
|
||||
#define GCC_CAST_CPP (uint16_t)
|
||||
#else
|
||||
#define GCC_CAST_CPP
|
||||
#endif
|
||||
#define SVCALL(number, return_type, signature) \
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \
|
||||
__attribute__((naked)) \
|
||||
__attribute__((unused)) \
|
||||
static return_type signature \
|
||||
{ \
|
||||
__asm( \
|
||||
"svc %0\n" \
|
||||
"bx r14" : : "I" (GCC_CAST_CPP number) : "r0" \
|
||||
); \
|
||||
} \
|
||||
_Pragma("GCC diagnostic pop")
|
||||
|
||||
#elif defined (__ICCARM__)
|
||||
#define PRAGMA(x) _Pragma(#x)
|
||||
#define SVCALL(number, return_type, signature) \
|
||||
PRAGMA(swi_number = (number)) \
|
||||
__swi return_type signature;
|
||||
#else
|
||||
#define SVCALL(number, return_type, signature) return_type signature
|
||||
#endif
|
||||
#endif // SVCALL
|
||||
|
||||
#endif // SVCALL_AS_NORMAL_FUNCTION
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // NRF_SVC__
|
||||
2
managed_components/espressif__tinyusb/hw/mcu/sony/cxd56/mkspk/.gitignore
vendored
Normal file
2
managed_components/espressif__tinyusb/hw/mcu/sony/cxd56/mkspk/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/mkspk
|
||||
/mkspk.exe
|
||||
@@ -0,0 +1,51 @@
|
||||
############################################################################
|
||||
# tools/mkspk/Makefile
|
||||
#
|
||||
# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# 3. Neither the name NuttX nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
all: mkspk
|
||||
default: mkspk
|
||||
.PHONY: clean
|
||||
|
||||
# Add CFLAGS=-g on the make command line to build debug versions
|
||||
|
||||
CFLAGS = -O2 -Wall -I.
|
||||
|
||||
# mkspk - Convert nuttx.hex image to nuttx.spk image
|
||||
|
||||
mkspk:
|
||||
@gcc $(CFLAGS) -o mkspk mkspk.c clefia.c
|
||||
|
||||
clean:
|
||||
@rm -f *.o *.a *.dSYM *~ .*.swp
|
||||
@rm -f mkspk mkspk.exe
|
||||
@@ -0,0 +1,517 @@
|
||||
/****************************************************************************
|
||||
* tools/cxd56/clefia.c
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Sony Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "clefia.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define clefiamul4(_x) (clefiamul2(clefiamul2((_x))))
|
||||
#define clefiamul6(_x) (clefiamul2((_x)) ^ clefiamul4((_x)))
|
||||
#define clefiamul8(_x) (clefiamul2(clefiamul4((_x))))
|
||||
#define clefiamula(_x) (clefiamul2((_x)) ^ clefiamul8((_x)))
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* S0 (8-bit S-box based on four 4-bit S-boxes) */
|
||||
|
||||
static const unsigned char clefia_s0[256] =
|
||||
{
|
||||
0x57u, 0x49u, 0xd1u, 0xc6u, 0x2fu, 0x33u, 0x74u, 0xfbu,
|
||||
0x95u, 0x6du, 0x82u, 0xeau, 0x0eu, 0xb0u, 0xa8u, 0x1cu,
|
||||
0x28u, 0xd0u, 0x4bu, 0x92u, 0x5cu, 0xeeu, 0x85u, 0xb1u,
|
||||
0xc4u, 0x0au, 0x76u, 0x3du, 0x63u, 0xf9u, 0x17u, 0xafu,
|
||||
0xbfu, 0xa1u, 0x19u, 0x65u, 0xf7u, 0x7au, 0x32u, 0x20u,
|
||||
0x06u, 0xceu, 0xe4u, 0x83u, 0x9du, 0x5bu, 0x4cu, 0xd8u,
|
||||
0x42u, 0x5du, 0x2eu, 0xe8u, 0xd4u, 0x9bu, 0x0fu, 0x13u,
|
||||
0x3cu, 0x89u, 0x67u, 0xc0u, 0x71u, 0xaau, 0xb6u, 0xf5u,
|
||||
0xa4u, 0xbeu, 0xfdu, 0x8cu, 0x12u, 0x00u, 0x97u, 0xdau,
|
||||
0x78u, 0xe1u, 0xcfu, 0x6bu, 0x39u, 0x43u, 0x55u, 0x26u,
|
||||
0x30u, 0x98u, 0xccu, 0xddu, 0xebu, 0x54u, 0xb3u, 0x8fu,
|
||||
0x4eu, 0x16u, 0xfau, 0x22u, 0xa5u, 0x77u, 0x09u, 0x61u,
|
||||
0xd6u, 0x2au, 0x53u, 0x37u, 0x45u, 0xc1u, 0x6cu, 0xaeu,
|
||||
0xefu, 0x70u, 0x08u, 0x99u, 0x8bu, 0x1du, 0xf2u, 0xb4u,
|
||||
0xe9u, 0xc7u, 0x9fu, 0x4au, 0x31u, 0x25u, 0xfeu, 0x7cu,
|
||||
0xd3u, 0xa2u, 0xbdu, 0x56u, 0x14u, 0x88u, 0x60u, 0x0bu,
|
||||
0xcdu, 0xe2u, 0x34u, 0x50u, 0x9eu, 0xdcu, 0x11u, 0x05u,
|
||||
0x2bu, 0xb7u, 0xa9u, 0x48u, 0xffu, 0x66u, 0x8au, 0x73u,
|
||||
0x03u, 0x75u, 0x86u, 0xf1u, 0x6au, 0xa7u, 0x40u, 0xc2u,
|
||||
0xb9u, 0x2cu, 0xdbu, 0x1fu, 0x58u, 0x94u, 0x3eu, 0xedu,
|
||||
0xfcu, 0x1bu, 0xa0u, 0x04u, 0xb8u, 0x8du, 0xe6u, 0x59u,
|
||||
0x62u, 0x93u, 0x35u, 0x7eu, 0xcau, 0x21u, 0xdfu, 0x47u,
|
||||
0x15u, 0xf3u, 0xbau, 0x7fu, 0xa6u, 0x69u, 0xc8u, 0x4du,
|
||||
0x87u, 0x3bu, 0x9cu, 0x01u, 0xe0u, 0xdeu, 0x24u, 0x52u,
|
||||
0x7bu, 0x0cu, 0x68u, 0x1eu, 0x80u, 0xb2u, 0x5au, 0xe7u,
|
||||
0xadu, 0xd5u, 0x23u, 0xf4u, 0x46u, 0x3fu, 0x91u, 0xc9u,
|
||||
0x6eu, 0x84u, 0x72u, 0xbbu, 0x0du, 0x18u, 0xd9u, 0x96u,
|
||||
0xf0u, 0x5fu, 0x41u, 0xacu, 0x27u, 0xc5u, 0xe3u, 0x3au,
|
||||
0x81u, 0x6fu, 0x07u, 0xa3u, 0x79u, 0xf6u, 0x2du, 0x38u,
|
||||
0x1au, 0x44u, 0x5eu, 0xb5u, 0xd2u, 0xecu, 0xcbu, 0x90u,
|
||||
0x9au, 0x36u, 0xe5u, 0x29u, 0xc3u, 0x4fu, 0xabu, 0x64u,
|
||||
0x51u, 0xf8u, 0x10u, 0xd7u, 0xbcu, 0x02u, 0x7du, 0x8eu
|
||||
};
|
||||
|
||||
/* S1 (8-bit S-box based on inverse function) */
|
||||
|
||||
static const unsigned char clefia_s1[256] =
|
||||
{
|
||||
0x6cu, 0xdau, 0xc3u, 0xe9u, 0x4eu, 0x9du, 0x0au, 0x3du,
|
||||
0xb8u, 0x36u, 0xb4u, 0x38u, 0x13u, 0x34u, 0x0cu, 0xd9u,
|
||||
0xbfu, 0x74u, 0x94u, 0x8fu, 0xb7u, 0x9cu, 0xe5u, 0xdcu,
|
||||
0x9eu, 0x07u, 0x49u, 0x4fu, 0x98u, 0x2cu, 0xb0u, 0x93u,
|
||||
0x12u, 0xebu, 0xcdu, 0xb3u, 0x92u, 0xe7u, 0x41u, 0x60u,
|
||||
0xe3u, 0x21u, 0x27u, 0x3bu, 0xe6u, 0x19u, 0xd2u, 0x0eu,
|
||||
0x91u, 0x11u, 0xc7u, 0x3fu, 0x2au, 0x8eu, 0xa1u, 0xbcu,
|
||||
0x2bu, 0xc8u, 0xc5u, 0x0fu, 0x5bu, 0xf3u, 0x87u, 0x8bu,
|
||||
0xfbu, 0xf5u, 0xdeu, 0x20u, 0xc6u, 0xa7u, 0x84u, 0xceu,
|
||||
0xd8u, 0x65u, 0x51u, 0xc9u, 0xa4u, 0xefu, 0x43u, 0x53u,
|
||||
0x25u, 0x5du, 0x9bu, 0x31u, 0xe8u, 0x3eu, 0x0du, 0xd7u,
|
||||
0x80u, 0xffu, 0x69u, 0x8au, 0xbau, 0x0bu, 0x73u, 0x5cu,
|
||||
0x6eu, 0x54u, 0x15u, 0x62u, 0xf6u, 0x35u, 0x30u, 0x52u,
|
||||
0xa3u, 0x16u, 0xd3u, 0x28u, 0x32u, 0xfau, 0xaau, 0x5eu,
|
||||
0xcfu, 0xeau, 0xedu, 0x78u, 0x33u, 0x58u, 0x09u, 0x7bu,
|
||||
0x63u, 0xc0u, 0xc1u, 0x46u, 0x1eu, 0xdfu, 0xa9u, 0x99u,
|
||||
0x55u, 0x04u, 0xc4u, 0x86u, 0x39u, 0x77u, 0x82u, 0xecu,
|
||||
0x40u, 0x18u, 0x90u, 0x97u, 0x59u, 0xddu, 0x83u, 0x1fu,
|
||||
0x9au, 0x37u, 0x06u, 0x24u, 0x64u, 0x7cu, 0xa5u, 0x56u,
|
||||
0x48u, 0x08u, 0x85u, 0xd0u, 0x61u, 0x26u, 0xcau, 0x6fu,
|
||||
0x7eu, 0x6au, 0xb6u, 0x71u, 0xa0u, 0x70u, 0x05u, 0xd1u,
|
||||
0x45u, 0x8cu, 0x23u, 0x1cu, 0xf0u, 0xeeu, 0x89u, 0xadu,
|
||||
0x7au, 0x4bu, 0xc2u, 0x2fu, 0xdbu, 0x5au, 0x4du, 0x76u,
|
||||
0x67u, 0x17u, 0x2du, 0xf4u, 0xcbu, 0xb1u, 0x4au, 0xa8u,
|
||||
0xb5u, 0x22u, 0x47u, 0x3au, 0xd5u, 0x10u, 0x4cu, 0x72u,
|
||||
0xccu, 0x00u, 0xf9u, 0xe0u, 0xfdu, 0xe2u, 0xfeu, 0xaeu,
|
||||
0xf8u, 0x5fu, 0xabu, 0xf1u, 0x1bu, 0x42u, 0x81u, 0xd6u,
|
||||
0xbeu, 0x44u, 0x29u, 0xa6u, 0x57u, 0xb9u, 0xafu, 0xf2u,
|
||||
0xd4u, 0x75u, 0x66u, 0xbbu, 0x68u, 0x9fu, 0x50u, 0x02u,
|
||||
0x01u, 0x3cu, 0x7fu, 0x8du, 0x1au, 0x88u, 0xbdu, 0xacu,
|
||||
0xf7u, 0xe4u, 0x79u, 0x96u, 0xa2u, 0xfcu, 0x6du, 0xb2u,
|
||||
0x6bu, 0x03u, 0xe1u, 0x2eu, 0x7du, 0x14u, 0x95u, 0x1du
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void bytecpy(unsigned char *dst, const unsigned char *src, int bytelen)
|
||||
{
|
||||
while (bytelen-- > 0)
|
||||
{
|
||||
*dst++ = *src++;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char clefiamul2(unsigned char x)
|
||||
{
|
||||
/* multiplication over GF(2^8) (p(x) = '11d') */
|
||||
|
||||
if (x & 0x80u)
|
||||
{
|
||||
x ^= 0x0eu;
|
||||
}
|
||||
|
||||
return ((x << 1) | (x >> 7));
|
||||
}
|
||||
|
||||
static void clefiaf0xor(unsigned char *dst, const unsigned char *src,
|
||||
const unsigned char *rk)
|
||||
{
|
||||
unsigned char x[4];
|
||||
unsigned char y[4];
|
||||
unsigned char z[4];
|
||||
|
||||
/* F0 */
|
||||
|
||||
/* Key addition */
|
||||
|
||||
bytexor(x, src, rk, 4);
|
||||
|
||||
/* Substitution layer */
|
||||
|
||||
z[0] = clefia_s0[x[0]];
|
||||
z[1] = clefia_s1[x[1]];
|
||||
z[2] = clefia_s0[x[2]];
|
||||
z[3] = clefia_s1[x[3]];
|
||||
|
||||
/* Diffusion layer (M0) */
|
||||
|
||||
y[0] = z[0] ^ clefiamul2(z[1]) ^ clefiamul4(z[2]) ^ clefiamul6(z[3]);
|
||||
y[1] = clefiamul2(z[0]) ^ z[1] ^ clefiamul6(z[2]) ^ clefiamul4(z[3]);
|
||||
y[2] = clefiamul4(z[0]) ^ clefiamul6(z[1]) ^ z[2] ^ clefiamul2(z[3]);
|
||||
y[3] = clefiamul6(z[0]) ^ clefiamul4(z[1]) ^ clefiamul2(z[2]) ^ z[3];
|
||||
|
||||
/* Xoring after F0 */
|
||||
|
||||
bytecpy(dst + 0, src + 0, 4);
|
||||
bytexor(dst + 4, src + 4, y, 4);
|
||||
}
|
||||
|
||||
static void clefiaf1xor(unsigned char *dst, const unsigned char *src,
|
||||
const unsigned char *rk)
|
||||
{
|
||||
unsigned char x[4];
|
||||
unsigned char y[4];
|
||||
unsigned char z[4];
|
||||
|
||||
/* F1 */
|
||||
|
||||
/* Key addition */
|
||||
|
||||
bytexor(x, src, rk, 4);
|
||||
|
||||
/* Substitution layer */
|
||||
|
||||
z[0] = clefia_s1[x[0]];
|
||||
z[1] = clefia_s0[x[1]];
|
||||
z[2] = clefia_s1[x[2]];
|
||||
z[3] = clefia_s0[x[3]];
|
||||
|
||||
/* Diffusion layer (M1) */
|
||||
|
||||
y[0] = z[0] ^ clefiamul8(z[1]) ^ clefiamul2(z[2]) ^ clefiamula(z[3]);
|
||||
y[1] = clefiamul8(z[0]) ^ z[1] ^ clefiamula(z[2]) ^ clefiamul2(z[3]);
|
||||
y[2] = clefiamul2(z[0]) ^ clefiamula(z[1]) ^ z[2] ^ clefiamul8(z[3]);
|
||||
y[3] = clefiamula(z[0]) ^ clefiamul2(z[1]) ^ clefiamul8(z[2]) ^ z[3];
|
||||
|
||||
/* Xoring after F1 */
|
||||
|
||||
bytecpy(dst + 0, src + 0, 4);
|
||||
bytexor(dst + 4, src + 4, y, 4);
|
||||
}
|
||||
|
||||
static void clefiagfn4(unsigned char *y, const unsigned char *x,
|
||||
const unsigned char *rk, int r)
|
||||
{
|
||||
unsigned char fin[16];
|
||||
unsigned char fout[16];
|
||||
|
||||
bytecpy(fin, x, 16);
|
||||
while (r-- > 0)
|
||||
{
|
||||
clefiaf0xor(fout + 0, fin + 0, rk + 0);
|
||||
clefiaf1xor(fout + 8, fin + 8, rk + 4);
|
||||
rk += 8;
|
||||
if (r)
|
||||
{
|
||||
/* swapping for encryption */
|
||||
|
||||
bytecpy(fin + 0, fout + 4, 12);
|
||||
bytecpy(fin + 12, fout + 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
bytecpy(y, fout, 16);
|
||||
}
|
||||
|
||||
#if 0 /* Not used */
|
||||
static void clefiagfn8(unsigned char *y, const unsigned char *x,
|
||||
const unsigned char *rk, int r)
|
||||
{
|
||||
unsigned char fin[32];
|
||||
unsigned char fout[32];
|
||||
|
||||
bytecpy(fin, x, 32);
|
||||
while (r-- > 0)
|
||||
{
|
||||
clefiaf0xor(fout + 0, fin + 0, rk + 0);
|
||||
clefiaf1xor(fout + 8, fin + 8, rk + 4);
|
||||
clefiaf0xor(fout + 16, fin + 16, rk + 8);
|
||||
clefiaf1xor(fout + 24, fin + 24, rk + 12);
|
||||
rk += 16;
|
||||
if (r)
|
||||
{
|
||||
/* swapping for encryption */
|
||||
|
||||
bytecpy(fin + 0, fout + 4, 28);
|
||||
bytecpy(fin + 28, fout + 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
bytecpy(y, fout, 32);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0 /* Not used */
|
||||
static void clefiagfn4inv(unsigned char *y, const unsigned char *x,
|
||||
const unsigned char *rk, int r)
|
||||
{
|
||||
unsigned char fin[16];
|
||||
unsigned char fout[16];
|
||||
|
||||
rk += (r - 1) * 8;
|
||||
bytecpy(fin, x, 16);
|
||||
while (r-- > 0)
|
||||
{
|
||||
clefiaf0xor(fout + 0, fin + 0, rk + 0);
|
||||
clefiaf1xor(fout + 8, fin + 8, rk + 4);
|
||||
rk -= 8;
|
||||
if (r)
|
||||
{
|
||||
/* swapping for decryption */
|
||||
|
||||
bytecpy(fin + 0, fout + 12, 4);
|
||||
bytecpy(fin + 4, fout + 0, 12);
|
||||
}
|
||||
}
|
||||
|
||||
bytecpy(y, fout, 16);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void clefiadoubleswap(unsigned char *lk)
|
||||
{
|
||||
unsigned char t[16];
|
||||
|
||||
t[0] = (lk[0] << 7) | (lk[1] >> 1);
|
||||
t[1] = (lk[1] << 7) | (lk[2] >> 1);
|
||||
t[2] = (lk[2] << 7) | (lk[3] >> 1);
|
||||
t[3] = (lk[3] << 7) | (lk[4] >> 1);
|
||||
t[4] = (lk[4] << 7) | (lk[5] >> 1);
|
||||
t[5] = (lk[5] << 7) | (lk[6] >> 1);
|
||||
t[6] = (lk[6] << 7) | (lk[7] >> 1);
|
||||
t[7] = (lk[7] << 7) | (lk[15] & 0x7fu);
|
||||
|
||||
t[8] = (lk[8] >> 7) | (lk[0] & 0xfeu);
|
||||
t[9] = (lk[9] >> 7) | (lk[8] << 1);
|
||||
t[10] = (lk[10] >> 7) | (lk[9] << 1);
|
||||
t[11] = (lk[11] >> 7) | (lk[10] << 1);
|
||||
t[12] = (lk[12] >> 7) | (lk[11] << 1);
|
||||
t[13] = (lk[13] >> 7) | (lk[12] << 1);
|
||||
t[14] = (lk[14] >> 7) | (lk[13] << 1);
|
||||
t[15] = (lk[15] >> 7) | (lk[14] << 1);
|
||||
|
||||
bytecpy(lk, t, 16);
|
||||
}
|
||||
|
||||
static void clefiaconset(unsigned char *con, const unsigned char *iv, int lk)
|
||||
{
|
||||
unsigned char t[2];
|
||||
unsigned char tmp;
|
||||
|
||||
bytecpy(t, iv, 2);
|
||||
while (lk-- > 0)
|
||||
{
|
||||
con[0] = t[0] ^ 0xb7u; /* P_16 = 0xb7e1 (natural logarithm) */
|
||||
con[1] = t[1] ^ 0xe1u;
|
||||
con[2] = ~((t[0] << 1) | (t[1] >> 7));
|
||||
con[3] = ~((t[1] << 1) | (t[0] >> 7));
|
||||
con[4] = ~t[0] ^ 0x24u; /* Q_16 = 0x243f (circle ratio) */
|
||||
con[5] = ~t[1] ^ 0x3fu;
|
||||
con[6] = t[1];
|
||||
con[7] = t[0];
|
||||
con += 8;
|
||||
|
||||
/* updating T */
|
||||
|
||||
if (t[1] & 0x01u)
|
||||
{
|
||||
t[0] ^= 0xa8u;
|
||||
t[1] ^= 0x30u;
|
||||
}
|
||||
|
||||
tmp = t[0] << 7;
|
||||
t[0] = (t[0] >> 1) | (t[1] << 7);
|
||||
t[1] = (t[1] >> 1) | tmp;
|
||||
}
|
||||
}
|
||||
|
||||
static void left_shift_one(uint8_t * in, uint8_t * out)
|
||||
{
|
||||
int i;
|
||||
int overflow;
|
||||
|
||||
overflow = 0;
|
||||
for (i = 15; i >= 0; i--)
|
||||
{
|
||||
out[i] = in[i] << 1;
|
||||
out[i] |= overflow;
|
||||
overflow = (in[i] >> 7) & 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void gen_subkey(struct cipher *c)
|
||||
{
|
||||
uint8_t L[16];
|
||||
|
||||
memset(L, 0, 16);
|
||||
clefiaencrypt(L, L, c->rk, c->round);
|
||||
|
||||
left_shift_one(L, c->k1);
|
||||
if (L[0] & 0x80)
|
||||
{
|
||||
c->k1[15] = c->k1[15] ^ 0x87;
|
||||
}
|
||||
|
||||
left_shift_one(c->k1, c->k2);
|
||||
if (c->k1[0] & 0x80)
|
||||
{
|
||||
c->k2[15] = c->k2[15] ^ 0x87;
|
||||
}
|
||||
|
||||
memset(L, 0, 16);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
struct cipher *cipher_init(uint8_t * key, uint8_t * iv)
|
||||
{
|
||||
struct cipher *c;
|
||||
|
||||
c = (struct cipher *)malloc(sizeof(*c));
|
||||
if (!c)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
c->round = clefiakeyset(c->rk, key);
|
||||
|
||||
gen_subkey(c);
|
||||
memset(c->vector, 0, 16);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void cipher_deinit(struct cipher *c)
|
||||
{
|
||||
memset(c, 0, sizeof(*c));
|
||||
free(c);
|
||||
}
|
||||
|
||||
int cipher_calc_cmac(struct cipher *c, void *data, int size, void *cmac)
|
||||
{
|
||||
uint8_t m[16];
|
||||
uint8_t *p;
|
||||
|
||||
if (size & 0xf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = (uint8_t *) data;
|
||||
while (size)
|
||||
{
|
||||
bytexor(m, c->vector, p, 16);
|
||||
clefiaencrypt(c->vector, m, c->rk, c->round);
|
||||
size -= 16;
|
||||
p += 16;
|
||||
}
|
||||
|
||||
bytexor(cmac, m, c->k1, 16);
|
||||
clefiaencrypt(cmac, cmac, c->rk, c->round);
|
||||
memset(m, 0, 16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bytexor(unsigned char *dst, const unsigned char *a,
|
||||
const unsigned char *b, int bytelen)
|
||||
{
|
||||
while (bytelen-- > 0)
|
||||
{
|
||||
*dst++ = *a++ ^ *b++;
|
||||
}
|
||||
}
|
||||
|
||||
int clefiakeyset(unsigned char *rk, const unsigned char *skey)
|
||||
{
|
||||
const unsigned char iv[2] =
|
||||
{
|
||||
0x42u, 0x8au /* cubic root of 2 */
|
||||
};
|
||||
|
||||
unsigned char lk[16];
|
||||
unsigned char con128[4 * 60];
|
||||
int i;
|
||||
|
||||
/* generating CONi^(128) (0 <= i < 60, lk = 30) */
|
||||
|
||||
clefiaconset(con128, iv, 30);
|
||||
|
||||
/* GFN_{4,12} (generating L from K) */
|
||||
|
||||
clefiagfn4(lk, skey, con128, 12);
|
||||
|
||||
bytecpy(rk, skey, 8); /* initial whitening key (WK0, WK1) */
|
||||
rk += 8;
|
||||
for (i = 0; i < 9; i++)
|
||||
{
|
||||
/* round key (RKi (0 <= i < 36)) */
|
||||
|
||||
bytexor(rk, lk, con128 + i * 16 + (4 * 24), 16);
|
||||
if (i % 2)
|
||||
{
|
||||
bytexor(rk, rk, skey, 16); /* Xoring K */
|
||||
}
|
||||
|
||||
clefiadoubleswap(lk); /* Updating L (DoubleSwap function) */
|
||||
rk += 16;
|
||||
}
|
||||
|
||||
bytecpy(rk, skey + 8, 8); /* final whitening key (WK2, WK3) */
|
||||
|
||||
return 18;
|
||||
}
|
||||
|
||||
void clefiaencrypt(unsigned char *ct, const unsigned char *pt,
|
||||
const unsigned char *rk, const int r)
|
||||
{
|
||||
unsigned char rin[16];
|
||||
unsigned char rout[16];
|
||||
|
||||
bytecpy(rin, pt, 16);
|
||||
|
||||
bytexor(rin + 4, rin + 4, rk + 0, 4); /* initial key whitening */
|
||||
bytexor(rin + 12, rin + 12, rk + 4, 4);
|
||||
rk += 8;
|
||||
|
||||
clefiagfn4(rout, rin, rk, r); /* GFN_{4,r} */
|
||||
|
||||
bytecpy(ct, rout, 16);
|
||||
bytexor(ct + 4, ct + 4, rk + r * 8 + 0, 4); /* final key whitening */
|
||||
bytexor(ct + 12, ct + 12, rk + r * 8 + 4, 4);
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/****************************************************************************
|
||||
* tools/cxd56/clefia.h
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Sony Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _TOOLS_CXD56_CLEFIA_H_
|
||||
#define _TOOLS_CXD56_CLEFIA_H_
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
struct cipher
|
||||
{
|
||||
int mode;
|
||||
int dir;
|
||||
uint8_t rk[8 * 26 + 16];
|
||||
uint8_t vector[16];
|
||||
int round;
|
||||
uint8_t k1[16];
|
||||
uint8_t k2[16];
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
struct cipher *cipher_init(uint8_t * key, uint8_t * iv);
|
||||
void cipher_deinit(struct cipher *c);
|
||||
int cipher_calc_cmac(struct cipher *c, void *data, int size, void *cmac);
|
||||
void bytexor(unsigned char *dst, const unsigned char *a,
|
||||
const unsigned char *b, int bytelen);
|
||||
int clefiakeyset(unsigned char *rk, const unsigned char *skey);
|
||||
void clefiaencrypt(unsigned char *ct, const unsigned char *pt,
|
||||
const unsigned char *rk, const int r);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,175 @@
|
||||
/****************************************************************************
|
||||
* include/elf32.h
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Reference: System V Application Binary Interface, Edition 4.1, March 18,
|
||||
* 1997, The Santa Cruz Operation, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_ELF32_H
|
||||
#define __INCLUDE_ELF32_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define EI_NIDENT 16 /* Size of e_ident[] */
|
||||
|
||||
#define ELF32_ST_BIND(i) ((i) >> 4)
|
||||
#define ELF32_ST_TYPE(i) ((i) & 0xf)
|
||||
#define ELF32_ST_INFO(b,t) (((b) << 4) | ((t) & 0xf))
|
||||
|
||||
/* Definitions for Elf32_Rel*::r_info */
|
||||
|
||||
#define ELF32_R_SYM(i) ((i) >> 8)
|
||||
#define ELF32_R_TYPE(i) ((i) & 0xff)
|
||||
#define ELF32_R_INFO(s,t) (((s)<< 8) | ((t) & 0xff))
|
||||
|
||||
#define ELF_R_SYM(i) ELF32_R_SYM(i)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Figure 4.2: 32-Bit Data Types */
|
||||
|
||||
typedef uint32_t Elf32_Addr; /* Unsigned program address */
|
||||
typedef uint16_t Elf32_Half; /* Unsigned medium integer */
|
||||
typedef uint32_t Elf32_Off; /* Unsigned file offset */
|
||||
typedef int32_t Elf32_Sword; /* Signed large integer */
|
||||
typedef uint32_t Elf32_Word; /* Unsigned large integer */
|
||||
|
||||
/* Figure 4-3: ELF Header */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
Elf32_Half e_type;
|
||||
Elf32_Half e_machine;
|
||||
Elf32_Word e_version;
|
||||
Elf32_Addr e_entry;
|
||||
Elf32_Off e_phoff;
|
||||
Elf32_Off e_shoff;
|
||||
Elf32_Word e_flags;
|
||||
Elf32_Half e_ehsize;
|
||||
Elf32_Half e_phentsize;
|
||||
Elf32_Half e_phnum;
|
||||
Elf32_Half e_shentsize;
|
||||
Elf32_Half e_shnum;
|
||||
Elf32_Half e_shstrndx;
|
||||
} Elf32_Ehdr;
|
||||
|
||||
/* Figure 4-8: Section Header */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Word sh_name;
|
||||
Elf32_Word sh_type;
|
||||
Elf32_Word sh_flags;
|
||||
Elf32_Addr sh_addr;
|
||||
Elf32_Off sh_offset;
|
||||
Elf32_Word sh_size;
|
||||
Elf32_Word sh_link;
|
||||
Elf32_Word sh_info;
|
||||
Elf32_Word sh_addralign;
|
||||
Elf32_Word sh_entsize;
|
||||
} Elf32_Shdr;
|
||||
|
||||
/* Figure 4-15: Symbol Table Entry */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Word st_name;
|
||||
Elf32_Addr st_value;
|
||||
Elf32_Word st_size;
|
||||
unsigned char st_info;
|
||||
unsigned char st_other;
|
||||
Elf32_Half st_shndx;
|
||||
} Elf32_Sym;
|
||||
|
||||
/* Figure 4-19: Relocation Entries */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Addr r_offset;
|
||||
Elf32_Word r_info;
|
||||
} Elf32_Rel;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Addr r_offset;
|
||||
Elf32_Word r_info;
|
||||
Elf32_Sword r_addend;
|
||||
} Elf32_Rela;
|
||||
|
||||
/* Figure 5-1: Program Header */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Word p_type;
|
||||
Elf32_Off p_offset;
|
||||
Elf32_Addr p_vaddr;
|
||||
Elf32_Addr p_paddr;
|
||||
Elf32_Word p_filesz;
|
||||
Elf32_Word p_memsz;
|
||||
Elf32_Word p_flags;
|
||||
Elf32_Word p_align;
|
||||
} Elf32_Phdr;
|
||||
|
||||
/* Figure 5-9: Dynamic Structure */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Sword d_tag;
|
||||
union
|
||||
{
|
||||
Elf32_Word d_val;
|
||||
Elf32_Addr d_ptr;
|
||||
} d_un;
|
||||
} Elf32_Dyn;
|
||||
|
||||
typedef Elf32_Addr Elf_Addr;
|
||||
typedef Elf32_Ehdr Elf_Ehdr;
|
||||
typedef Elf32_Rel Elf_Rel;
|
||||
typedef Elf32_Rela Elf_Rela;
|
||||
typedef Elf32_Sym Elf_Sym;
|
||||
typedef Elf32_Shdr Elf_Shdr;
|
||||
typedef Elf32_Word Elf_Word;
|
||||
|
||||
#endif /* __INCLUDE_ELF32_H */
|
||||
@@ -0,0 +1,392 @@
|
||||
/****************************************************************************
|
||||
* tools/cxd56/mkspk.c
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Sony Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "mkspk.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct args
|
||||
{
|
||||
int core;
|
||||
char *elffile;
|
||||
char *savename;
|
||||
char *outputfile;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static uint8_t vmk[16] =
|
||||
"\x27\xc0\xaf\x1b\x5d\xcb\xc6\xc5\x58\x22\x1c\xdd\xaf\xf3\x20\x21";
|
||||
|
||||
static struct args g_options =
|
||||
{
|
||||
0
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static struct args *parse_args(int argc, char **argv)
|
||||
{
|
||||
int opt;
|
||||
int show_help;
|
||||
struct args *args = &g_options;
|
||||
char *endp;
|
||||
|
||||
show_help = 0;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
show_help = 1;
|
||||
}
|
||||
|
||||
memset(args, 0, sizeof(*args));
|
||||
args->core = -1;
|
||||
|
||||
while ((opt = getopt(argc, argv, "h:c:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'c':
|
||||
args->core = strtol(optarg, &endp, 0);
|
||||
if (*endp)
|
||||
{
|
||||
fprintf(stderr, "Invalid core number \"%s\"\n", optarg);
|
||||
show_help = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
default:
|
||||
show_help = 1;
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
args->elffile = argv[0];
|
||||
args->savename = argv[1];
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
|
||||
if (argc > 0)
|
||||
{
|
||||
args->outputfile = strdup(argv[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
show_help = 1;
|
||||
}
|
||||
|
||||
/* Sanity checks for options */
|
||||
|
||||
if (show_help == 1)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"mkspk [-c <number>] <filename> <save name> [<output file>]\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (args->core < 0)
|
||||
{
|
||||
fprintf(stderr, "Core number is not set. Please use -c option.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (strlen(args->savename) > 63)
|
||||
{
|
||||
fprintf(stderr, "savename too long.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
static struct elf_file *load_elf(const char *filename)
|
||||
{
|
||||
size_t fsize;
|
||||
int pos;
|
||||
char *buf;
|
||||
FILE *fp;
|
||||
struct elf_file *ef;
|
||||
Elf32_Shdr *sh;
|
||||
uint16_t i;
|
||||
int ret;
|
||||
|
||||
fp = fopen(filename, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ef = (struct elf_file *)malloc(sizeof(*ef));
|
||||
if (!ef)
|
||||
{
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pos = fseek(fp, 0, SEEK_END);
|
||||
fsize = (size_t) ftell(fp);
|
||||
fseek(fp, pos, SEEK_SET);
|
||||
|
||||
buf = (char *)malloc(fsize);
|
||||
if (!buf)
|
||||
{
|
||||
free(ef);
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = fread(buf, fsize, 1, fp);
|
||||
fclose(fp);
|
||||
if (ret != 1)
|
||||
{
|
||||
free(ef);
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ef->data = buf;
|
||||
|
||||
ef->ehdr = (Elf32_Ehdr *) buf;
|
||||
|
||||
Elf32_Ehdr *h = (Elf32_Ehdr *) buf;
|
||||
|
||||
if (!(h->e_ident[EI_MAG0] == 0x7f &&
|
||||
h->e_ident[EI_MAG1] == 'E' &&
|
||||
h->e_ident[EI_MAG2] == 'L' && h->e_ident[EI_MAG3] == 'F'))
|
||||
{
|
||||
free(ef);
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ef->phdr = (Elf32_Phdr *) (buf + ef->ehdr->e_phoff);
|
||||
ef->shdr = (Elf32_Shdr *) (buf + ef->ehdr->e_shoff);
|
||||
ef->shstring = buf + ef->shdr[ef->ehdr->e_shstrndx].sh_offset;
|
||||
|
||||
for (i = 0, sh = ef->shdr; i < ef->ehdr->e_shnum; i++, sh++)
|
||||
{
|
||||
if (sh->sh_type == SHT_SYMTAB)
|
||||
{
|
||||
ef->symtab = (Elf32_Sym *) (buf + sh->sh_offset);
|
||||
ef->nsyms = sh->sh_size / sh->sh_entsize;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sh->sh_type == SHT_STRTAB)
|
||||
{
|
||||
if (!strcmp(".strtab", ef->shstring + sh->sh_name))
|
||||
{
|
||||
ef->string = buf + sh->sh_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ef;
|
||||
}
|
||||
|
||||
static void *create_image(struct elf_file *elf, int core, char *savename,
|
||||
int *image_size)
|
||||
{
|
||||
char *img;
|
||||
struct spk_header *header;
|
||||
struct spk_prog_info *pi;
|
||||
Elf32_Phdr *ph;
|
||||
Elf32_Sym *sym;
|
||||
char *name;
|
||||
int snlen;
|
||||
int nphs, psize, imgsize;
|
||||
int i;
|
||||
int j;
|
||||
uint32_t offset;
|
||||
uint32_t sp;
|
||||
|
||||
snlen = alignup(strlen(savename) + 1, 16);
|
||||
|
||||
nphs = 0;
|
||||
psize = 0;
|
||||
for (i = 0, ph = elf->phdr; i < elf->ehdr->e_phnum; i++, ph++)
|
||||
{
|
||||
if (ph->p_type != PT_LOAD || ph->p_filesz == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
nphs++;
|
||||
psize += alignup(ph->p_filesz, 16);
|
||||
}
|
||||
|
||||
imgsize = sizeof(*header) + snlen + (nphs * 16) + psize;
|
||||
|
||||
img = (char *)malloc(imgsize + 32);
|
||||
if (!img)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*image_size = imgsize;
|
||||
sym = elf->symtab;
|
||||
name = elf->string;
|
||||
sp = 0;
|
||||
|
||||
for (j = 0; j < elf->nsyms; j++, sym++)
|
||||
{
|
||||
if (!strcmp("__stack", name + sym->st_name))
|
||||
{
|
||||
sp = sym->st_value;
|
||||
}
|
||||
}
|
||||
|
||||
memset(img, 0, imgsize);
|
||||
|
||||
header = (struct spk_header *)img;
|
||||
header->magic[0] = 0xef;
|
||||
header->magic[1] = 'M';
|
||||
header->magic[2] = 'O';
|
||||
header->magic[3] = 'D';
|
||||
header->cpu = core;
|
||||
|
||||
header->entry = elf->ehdr->e_entry;
|
||||
header->stack = sp;
|
||||
header->core = core;
|
||||
|
||||
header->binaries = nphs;
|
||||
header->phoffs = sizeof(*header) + snlen;
|
||||
header->mode = 0777;
|
||||
|
||||
strncpy(img + sizeof(*header), savename, 63);
|
||||
|
||||
ph = elf->phdr;
|
||||
pi = (struct spk_prog_info *)(img + header->phoffs);
|
||||
offset = ((char *)pi - img) + (nphs * sizeof(*pi));
|
||||
for (i = 0; i < elf->ehdr->e_phnum; i++, ph++)
|
||||
{
|
||||
if (ph->p_type != PT_LOAD || ph->p_filesz == 0)
|
||||
continue;
|
||||
pi->load_address = ph->p_paddr;
|
||||
pi->offset = offset;
|
||||
pi->size = alignup(ph->p_filesz, 16); /* need 16 bytes align for
|
||||
* decryption */
|
||||
pi->memsize = ph->p_memsz;
|
||||
|
||||
memcpy(img + pi->offset, elf->data + ph->p_offset, ph->p_filesz);
|
||||
|
||||
offset += alignup(ph->p_filesz, 16);
|
||||
pi++;
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct args *args;
|
||||
struct elf_file *elf;
|
||||
struct cipher *c;
|
||||
uint8_t *spkimage;
|
||||
int size = 0;
|
||||
FILE *fp;
|
||||
char footer[16];
|
||||
|
||||
args = parse_args(argc, argv);
|
||||
|
||||
elf = load_elf(args->elffile);
|
||||
if (!elf)
|
||||
{
|
||||
fprintf(stderr, "Loading ELF %s failure.\n", args->elffile);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
spkimage = create_image(elf, args->core, args->savename, &size);
|
||||
if(elf->data) {
|
||||
free(elf->data);
|
||||
}
|
||||
free(elf);
|
||||
|
||||
|
||||
c = cipher_init(vmk, NULL);
|
||||
cipher_calc_cmac(c, spkimage, size, (uint8_t *) spkimage + size);
|
||||
cipher_deinit(c);
|
||||
|
||||
size += 16; /* Extend CMAC size */
|
||||
|
||||
snprintf(footer, 16, "MKSPK_BN_HOOTER");
|
||||
footer[15] = '\0';
|
||||
|
||||
fp = fopen(args->outputfile, "wb");
|
||||
if (!fp)
|
||||
{
|
||||
fprintf(stderr, "Output file open error.\n");
|
||||
free(spkimage);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fwrite(spkimage, size, 1, fp);
|
||||
fwrite(footer, 16, 1, fp);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
printf("File %s is successfully created.\n", args->outputfile);
|
||||
free(args->outputfile);
|
||||
|
||||
memset(spkimage, 0, size);
|
||||
free(spkimage);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/****************************************************************************
|
||||
* tools/cxd56/mkspk.h
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Sony Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "clefia.h"
|
||||
#include "elf32.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define EI_MAG0 0 /* File identification */
|
||||
#define EI_MAG1 1
|
||||
#define EI_MAG2 2
|
||||
#define EI_MAG3 3
|
||||
|
||||
#define SHT_SYMTAB 2
|
||||
#define SHT_STRTAB 3
|
||||
|
||||
#define PT_LOAD 1
|
||||
|
||||
#define alignup(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
|
||||
#define swap(a, b) { (a) ^= (b); (b) ^= (a); (a) ^= (b); }
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
struct spk_header
|
||||
{
|
||||
uint8_t magic[4];
|
||||
uint8_t cpu;
|
||||
uint8_t reserved[11];
|
||||
uint32_t entry;
|
||||
uint32_t stack;
|
||||
uint16_t core;
|
||||
uint16_t binaries;
|
||||
uint16_t phoffs;
|
||||
uint16_t mode;
|
||||
};
|
||||
|
||||
struct spk_prog_info
|
||||
{
|
||||
uint32_t load_address;
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
uint32_t memsize;
|
||||
};
|
||||
|
||||
struct elf_file
|
||||
{
|
||||
Elf32_Ehdr *ehdr;
|
||||
Elf32_Phdr *phdr;
|
||||
Elf32_Shdr *shdr;
|
||||
Elf32_Sym *symtab;
|
||||
int nsyms;
|
||||
char *shstring;
|
||||
char *string;
|
||||
char *data;
|
||||
};
|
||||
@@ -0,0 +1,580 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright (C) 2018 Sony Semiconductor Solutions Corp.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# 3. Neither the name NuttX nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
import time
|
||||
import sys
|
||||
import os
|
||||
import struct
|
||||
import glob
|
||||
import fnmatch
|
||||
import errno
|
||||
import telnetlib
|
||||
import argparse
|
||||
import shutil
|
||||
import subprocess
|
||||
import re
|
||||
import xmodem
|
||||
|
||||
import_serial_module = True
|
||||
|
||||
# When SDK release, please set SDK_RELEASE as True.
|
||||
SDK_RELEASE = False
|
||||
|
||||
if SDK_RELEASE :
|
||||
PRINT_RAW_COMMAND = False
|
||||
REBOOT_AT_END = True
|
||||
else :
|
||||
PRINT_RAW_COMMAND = True
|
||||
REBOOT_AT_END = True
|
||||
|
||||
try:
|
||||
import serial
|
||||
except:
|
||||
import_serial_module = False
|
||||
|
||||
# supported environment various
|
||||
# CXD56_PORT
|
||||
# CXD56_TELNETSRV_PORT
|
||||
# CXD56_TELNETSRV_IP
|
||||
|
||||
PROTOCOL_SERIAL = 0
|
||||
PROTOCOL_TELNET = 1
|
||||
|
||||
MAX_DOT_COUNT = 70
|
||||
|
||||
# configure parameters and default value
|
||||
class ConfigArgs:
|
||||
PROTOCOL_TYPE = None
|
||||
SERIAL_PORT = "COM1"
|
||||
SERVER_PORT = 4569
|
||||
SERVER_IP = "localhost"
|
||||
EOL = bytes([10])
|
||||
WAIT_RESET = True
|
||||
AUTO_RESET = False
|
||||
DTR_RESET = False
|
||||
XMODEM_BAUD = 0
|
||||
NO_SET_BOOTABLE = False
|
||||
PACKAGE_NAME = []
|
||||
FILE_NAME = []
|
||||
ERASE_NAME = []
|
||||
PKGSYS_NAME = []
|
||||
PKGAPP_NAME = []
|
||||
PKGUPD_NAME = []
|
||||
|
||||
ROM_MSG = [b"Welcome to nash"]
|
||||
XMDM_MSG = "Waiting for XMODEM (CRC or 1K) transfer. Ctrl-X to cancel."
|
||||
|
||||
class ConfigArgsLoader():
|
||||
def __init__(self):
|
||||
self.parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
|
||||
self.parser.add_argument("package_name", help="the name of the package to install", nargs='*')
|
||||
self.parser.add_argument("-f", "--file", dest="file_name", help="save file", action='append')
|
||||
self.parser.add_argument("-e", "--erase", dest="erase_name", help="erase file", action='append')
|
||||
|
||||
self.parser.add_argument("-S", "--sys", dest="pkgsys_name", help="the name of the system package to install", action='append')
|
||||
self.parser.add_argument("-A", "--app", dest="pkgapp_name", help="the name of the application package to install", action='append')
|
||||
self.parser.add_argument("-U", "--upd", dest="pkgupd_name", help="the name of the updater package to install", action='append')
|
||||
|
||||
self.parser.add_argument("-a", "--auto-reset", dest="auto_reset",
|
||||
action="store_true", default=None,
|
||||
help="try to auto reset develop board if possible")
|
||||
self.parser.add_argument("-d", "--dtr-reset", dest="dtr_reset",
|
||||
action="store_true", default=None,
|
||||
help="try to auto reset develop board if possible")
|
||||
self.parser.add_argument("-n", "--no-set-bootable", dest="no_set_bootable",
|
||||
action="store_true", default=None,
|
||||
help="not to set bootable")
|
||||
|
||||
group = self.parser.add_argument_group()
|
||||
group.add_argument("-i", "--server-ip", dest="server_ip",
|
||||
help="the ip address connected to the telnet server")
|
||||
group.add_argument("-p", "--server-port", dest="server_port", type=int,
|
||||
help="the port connected to the telnet server")
|
||||
|
||||
group = self.parser.add_argument_group()
|
||||
group.add_argument("-c", "--serial-port", dest="serial_port", help="the serial port")
|
||||
group.add_argument("-b", "--xmodem-baudrate", dest="xmodem_baud", help="Use the faster baudrate in xmodem")
|
||||
|
||||
mutually_group = self.parser.add_mutually_exclusive_group()
|
||||
mutually_group.add_argument("-t", "--telnet-protocol", dest="telnet_protocol",
|
||||
action="store_true", default=None,
|
||||
help="use the telnet protocol for binary transmission")
|
||||
mutually_group.add_argument("-s", "--serial-protocol", dest="serial_protocol",
|
||||
action="store_true", default=None,
|
||||
help="use the serial port for binary transmission, default options")
|
||||
|
||||
mutually_group2 = self.parser.add_mutually_exclusive_group()
|
||||
mutually_group2.add_argument("-F", "--force-wait-reset", dest="wait_reset",
|
||||
action="store_true", default=None,
|
||||
help="force wait for pressing RESET button")
|
||||
mutually_group2.add_argument("-N", "--no-wait-reset", dest="wait_reset",
|
||||
action="store_false", default=None,
|
||||
help="if possible, skip to wait for pressing RESET button")
|
||||
|
||||
def update_config(self):
|
||||
args = self.parser.parse_args()
|
||||
|
||||
ConfigArgs.PACKAGE_NAME = args.package_name
|
||||
ConfigArgs.FILE_NAME = args.file_name
|
||||
ConfigArgs.ERASE_NAME = args.erase_name
|
||||
ConfigArgs.PKGSYS_NAME = args.pkgsys_name
|
||||
ConfigArgs.PKGAPP_NAME = args.pkgapp_name
|
||||
ConfigArgs.PKGUPD_NAME = args.pkgupd_name
|
||||
|
||||
# Get serial port or telnet server ip etc
|
||||
if args.serial_protocol == True:
|
||||
ConfigArgs.PROTOCOL_TYPE = PROTOCOL_SERIAL
|
||||
elif args.telnet_protocol == True:
|
||||
ConfigArgs.PROTOCOL_TYPE = PROTOCOL_TELNET
|
||||
|
||||
if ConfigArgs.PROTOCOL_TYPE == None:
|
||||
proto = os.environ.get("CXD56_PROTOCOL")
|
||||
if proto is not None:
|
||||
if 's' in proto:
|
||||
ConfigArgs.PROTOCOL_TYPE = PROTOCOL_SERIAL
|
||||
elif 't' in proto:
|
||||
ConfigArgs.PROTOCOL_TYPE = PROTOCOL_TELNET
|
||||
|
||||
if ConfigArgs.PROTOCOL_TYPE == None:
|
||||
ConfigArgs.PROTOCOL_TYPE = PROTOCOL_SERIAL
|
||||
|
||||
if ConfigArgs.PROTOCOL_TYPE == PROTOCOL_SERIAL:
|
||||
if args.serial_port is not None:
|
||||
ConfigArgs.SERIAL_PORT = args.serial_port
|
||||
else:
|
||||
# Get serial port from the environment
|
||||
port = os.environ.get("CXD56_PORT")
|
||||
if port is not None:
|
||||
ConfigArgs.SERIAL_PORT = port
|
||||
else:
|
||||
print("CXD56_PORT is not set, Use " + ConfigArgs.SERIAL_PORT + ".")
|
||||
else:
|
||||
ConfigArgs.PROTOCOL_TYPE = PROTOCOL_TELNET
|
||||
if args.server_port is not None:
|
||||
ConfigArgs.SERVER_PORT = args.server_port
|
||||
else:
|
||||
port = os.environ.get("CXD56_TELNETSRV_PORT")
|
||||
if port is not None:
|
||||
ConfigArgs.SERVER_PORT = port
|
||||
else:
|
||||
print("CXD56_TELNETSRV_PORT is not set, Use " + str(ConfigArgs.SERVER_PORT) + ".")
|
||||
if args.server_ip is not None:
|
||||
ConfigArgs.SERVER_IP = args.server_ip
|
||||
else:
|
||||
ip = os.environ.get("CXD56_TELNETSRV_IP")
|
||||
if ip is not None:
|
||||
ConfigArgs.SERVER_IP = ip
|
||||
else:
|
||||
print("CXD56_TELNETSRV_IP is not set, Use " + ConfigArgs.SERVER_IP + ".")
|
||||
|
||||
if args.xmodem_baud is not None:
|
||||
ConfigArgs.XMODEM_BAUD = args.xmodem_baud
|
||||
|
||||
if args.auto_reset is not None:
|
||||
ConfigArgs.AUTO_RESET = args.auto_reset
|
||||
|
||||
if args.dtr_reset is not None:
|
||||
ConfigArgs.DTR_RESET = args.dtr_reset
|
||||
|
||||
if args.no_set_bootable is not None:
|
||||
ConfigArgs.NO_SET_BOOTABLE = args.no_set_bootable
|
||||
|
||||
if args.wait_reset is not None:
|
||||
ConfigArgs.WAIT_RESET = args.wait_reset
|
||||
|
||||
class TelnetDev:
|
||||
def __init__(self):
|
||||
srv_ipaddr = ConfigArgs.SERVER_IP
|
||||
srv_port = ConfigArgs.SERVER_PORT
|
||||
self.recvbuf = b'';
|
||||
try:
|
||||
self.telnet = telnetlib.Telnet(host=srv_ipaddr, port=srv_port, timeout=10)
|
||||
# There is a ack to be sent after connecting to the telnet server.
|
||||
self.telnet.write(b"\xff")
|
||||
except Exception as e:
|
||||
print("Cannot connect to the server %s:%d" % (srv_ipaddr, srv_port))
|
||||
sys.exit(e.args[0])
|
||||
|
||||
def readline(self, size=None):
|
||||
res = b''
|
||||
ch = b''
|
||||
while ch != ConfigArgs.EOL:
|
||||
ch = self.getc_raw(1, timeout=0.1)
|
||||
if ch == b'':
|
||||
return res
|
||||
res += ch
|
||||
return res
|
||||
|
||||
def getc_raw(self, size, timeout=1):
|
||||
res = b''
|
||||
tm = time.monotonic()
|
||||
while size > 0:
|
||||
while self.recvbuf == b'':
|
||||
self.recvbuf = self.telnet.read_eager()
|
||||
if self.recvbuf == b'':
|
||||
if (time.monotonic() - tm) > timeout:
|
||||
return res
|
||||
time.sleep(0.1)
|
||||
res += self.recvbuf[0:1]
|
||||
self.recvbuf = self.recvbuf[1:]
|
||||
size -= 1
|
||||
return res
|
||||
|
||||
def write(self, buffer):
|
||||
self.telnet.write(buffer)
|
||||
|
||||
def discard_inputs(self, timeout=1.0):
|
||||
while True:
|
||||
ch = self.getc_raw(1, timeout=timeout)
|
||||
if ch == b'':
|
||||
break
|
||||
|
||||
def getc(self, size, timeout=1):
|
||||
c = self.getc_raw(size, timeout)
|
||||
return c
|
||||
|
||||
def putc(self, buffer, timeout=1):
|
||||
self.telnet.write(buffer)
|
||||
self.show_progress(len(buffer))
|
||||
|
||||
def reboot(self):
|
||||
# no-op
|
||||
pass
|
||||
|
||||
def set_file_size(self, filesize):
|
||||
self.bytes_transfered = 0
|
||||
self.filesize = filesize
|
||||
self.count = 0
|
||||
|
||||
def show_progress(self, sendsize):
|
||||
if PRINT_RAW_COMMAND:
|
||||
if self.count < MAX_DOT_COUNT:
|
||||
self.bytes_transfered = self.bytes_transfered + sendsize
|
||||
cur_count = int(self.bytes_transfered * MAX_DOT_COUNT / self.filesize)
|
||||
if MAX_DOT_COUNT < cur_count:
|
||||
cur_count = MAX_DOT_COUNT
|
||||
for idx in range(cur_count - self.count):
|
||||
print('#',end='')
|
||||
sys.stdout.flush()
|
||||
self.count = cur_count
|
||||
if self.count == MAX_DOT_COUNT:
|
||||
print("\n")
|
||||
|
||||
class SerialDev:
|
||||
def __init__(self):
|
||||
if import_serial_module is False:
|
||||
print("Cannot import serial module, maybe it's not install yet.")
|
||||
print("\n", end="")
|
||||
print("Please install python-setuptool by Cygwin installer.")
|
||||
print("After that use easy_intall command to install serial module")
|
||||
print(" $ cd tool/")
|
||||
print(" $ python3 -m easy_install pyserial-2.7.tar.gz")
|
||||
quit()
|
||||
else:
|
||||
port = ConfigArgs.SERIAL_PORT
|
||||
try:
|
||||
self.serial = serial.Serial(port, baudrate=115200,
|
||||
parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE,
|
||||
bytesize=serial.EIGHTBITS, timeout=0.1)
|
||||
except Exception as e:
|
||||
print("Cannot open port : " + port)
|
||||
sys.exit(e.args[0])
|
||||
|
||||
def readline(self, size=None):
|
||||
return self.serial.readline(size)
|
||||
|
||||
def write(self, buffer):
|
||||
self.serial.write(buffer)
|
||||
self.serial.flush()
|
||||
|
||||
def discard_inputs(self, timeout=1.0):
|
||||
time.sleep(timeout)
|
||||
self.serial.flushInput()
|
||||
|
||||
def getc(self, size, timeout=1):
|
||||
self.serial.timeout = timeout
|
||||
c = self.serial.read(size)
|
||||
self.serial.timeout = 0.1
|
||||
return c
|
||||
|
||||
def putc(self, buffer, timeout=1):
|
||||
self.serial.timeout = timeout
|
||||
self.serial.write(buffer)
|
||||
self.serial.flush()
|
||||
self.serial.timeout = 0.1
|
||||
self.show_progress(len(buffer))
|
||||
|
||||
# Note: windows platform dependent code
|
||||
def putc_win(self, buffer, timeout=1):
|
||||
self.serial.write(buffer)
|
||||
self.show_progress(len(buffer))
|
||||
while True:
|
||||
if self.serial.out_waiting == 0:
|
||||
break
|
||||
|
||||
def setBaudrate(self, baudrate):
|
||||
# self.serial.setBaudrate(baudrate)
|
||||
self.serial.baudrate = baudrate
|
||||
|
||||
def reboot(self):
|
||||
# Target Reset by DTR
|
||||
self.serial.setDTR(False)
|
||||
self.serial.setDTR(True)
|
||||
self.serial.setDTR(False)
|
||||
|
||||
def set_file_size(self, filesize):
|
||||
self.bytes_transfered = 0
|
||||
self.filesize = filesize
|
||||
self.count = 0
|
||||
|
||||
def show_progress(self, sendsize):
|
||||
if PRINT_RAW_COMMAND:
|
||||
if self.count < MAX_DOT_COUNT:
|
||||
self.bytes_transfered = self.bytes_transfered + sendsize
|
||||
cur_count = int(self.bytes_transfered * MAX_DOT_COUNT / self.filesize)
|
||||
if MAX_DOT_COUNT < cur_count:
|
||||
cur_count = MAX_DOT_COUNT
|
||||
for idx in range(cur_count - self.count):
|
||||
print('#',end='')
|
||||
sys.stdout.flush()
|
||||
self.count = cur_count
|
||||
if self.count == MAX_DOT_COUNT:
|
||||
print("\n")
|
||||
|
||||
class FlashWriter:
|
||||
def __init__(self, protocol_sel=PROTOCOL_SERIAL):
|
||||
if protocol_sel == PROTOCOL_TELNET:
|
||||
self.serial = TelnetDev()
|
||||
else:
|
||||
self.serial = SerialDev()
|
||||
|
||||
def cancel_autoboot(self) :
|
||||
boot_msg = ''
|
||||
self.serial.reboot() # Target reboot before send 'r'
|
||||
while boot_msg == '' :
|
||||
rx = self.serial.readline().strip()
|
||||
self.serial.write(b"r") # Send "r" key to avoid auto boot
|
||||
for msg in ROM_MSG :
|
||||
if msg in rx :
|
||||
boot_msg = msg
|
||||
break
|
||||
while True :
|
||||
rx = self.serial.readline().decode(errors="replace").strip()
|
||||
if "updater" in rx :
|
||||
# Workaround : Sometime first character is dropped.
|
||||
# Send line feed as air shot before actual command.
|
||||
self.serial.write(b"\n") # Send line feed
|
||||
self.serial.discard_inputs()# Clear input buffer to sync
|
||||
return boot_msg.decode(errors="ignore")
|
||||
|
||||
def recv(self):
|
||||
rx = self.serial.readline()
|
||||
if PRINT_RAW_COMMAND :
|
||||
serial_line = rx.decode(errors="replace")
|
||||
if serial_line.strip() != "" and not serial_line.startswith(XMDM_MSG):
|
||||
print(serial_line, end="")
|
||||
return rx
|
||||
|
||||
def wait(self, string):
|
||||
while True:
|
||||
rx = self.recv()
|
||||
if string.encode() in rx:
|
||||
time.sleep(0.1)
|
||||
break
|
||||
|
||||
def wait_for_prompt(self):
|
||||
prompt_pat = re.compile(b"updater")
|
||||
while True:
|
||||
rx = self.recv()
|
||||
if prompt_pat.search(rx):
|
||||
time.sleep(0.1)
|
||||
break
|
||||
|
||||
def send(self, string):
|
||||
self.serial.write(str(string).encode() + b"\n")
|
||||
rx = self.serial.readline()
|
||||
if PRINT_RAW_COMMAND :
|
||||
print(rx.decode(errors="replace"), end="")
|
||||
|
||||
def read_output(self, prompt_text) :
|
||||
output = []
|
||||
while True :
|
||||
rx = self.serial.readline()
|
||||
if prompt_text.encode() in rx :
|
||||
time.sleep(0.1)
|
||||
break
|
||||
if rx != "" :
|
||||
output.append(rx.decode(errors="ignore").rstrip())
|
||||
return output
|
||||
|
||||
def install_files(self, files, command) :
|
||||
if ConfigArgs.XMODEM_BAUD:
|
||||
command += " -b " + ConfigArgs.XMODEM_BAUD
|
||||
if os.name == 'nt':
|
||||
modem = xmodem.XMODEM(self.serial.getc, self.serial.putc_win, 'xmodem1k')
|
||||
else:
|
||||
modem = xmodem.XMODEM(self.serial.getc, self.serial.putc, 'xmodem1k')
|
||||
for file in files:
|
||||
with open(file, "rb") as bin :
|
||||
self.send(command)
|
||||
print("Install " + file)
|
||||
self.wait(XMDM_MSG)
|
||||
print("|0%" +
|
||||
"-" * (int(MAX_DOT_COUNT / 2) - 6) +
|
||||
"50%" +
|
||||
"-" * (MAX_DOT_COUNT - int(MAX_DOT_COUNT / 2) - 5) +
|
||||
"100%|")
|
||||
if ConfigArgs.XMODEM_BAUD:
|
||||
self.serial.setBaudrate(ConfigArgs.XMODEM_BAUD)
|
||||
self.serial.discard_inputs() # Clear input buffer to sync
|
||||
self.serial.set_file_size(os.path.getsize(file))
|
||||
modem.send(bin)
|
||||
if ConfigArgs.XMODEM_BAUD:
|
||||
self.serial.setBaudrate(115200)
|
||||
self.wait_for_prompt()
|
||||
|
||||
def save_files(self, files) :
|
||||
if ConfigArgs.XMODEM_BAUD:
|
||||
command = "save_file -b " + ConfigArgs.XMODEM_BAUD + " -x "
|
||||
else:
|
||||
command = "save_file -x "
|
||||
if os.name == 'nt':
|
||||
modem = xmodem.XMODEM(self.serial.getc, self.serial.putc_win, 'xmodem1k')
|
||||
else:
|
||||
modem = xmodem.XMODEM(self.serial.getc, self.serial.putc, 'xmodem1k')
|
||||
for file in files:
|
||||
with open(file, "rb") as bin :
|
||||
self.send(command + os.path.basename(file))
|
||||
print("Save " + file)
|
||||
self.wait(XMDM_MSG)
|
||||
if ConfigArgs.XMODEM_BAUD:
|
||||
self.serial.setBaudrate(ConfigArgs.XMODEM_BAUD)
|
||||
self.serial.discard_inputs() # Clear input buffer to sync
|
||||
self.serial.set_file_size(os.path.getsize(file))
|
||||
modem.send(bin)
|
||||
if ConfigArgs.XMODEM_BAUD:
|
||||
self.serial.setBaudrate(115200)
|
||||
self.wait_for_prompt()
|
||||
self.send("chmod d+rw " + os.path.basename(file))
|
||||
self.wait_for_prompt()
|
||||
|
||||
def delete_files(self, files) :
|
||||
for file in files :
|
||||
self.delete_binary(file)
|
||||
|
||||
def delete_binary(self, bin_name) :
|
||||
self.send("rm " + bin_name)
|
||||
self.wait_for_prompt()
|
||||
|
||||
def main():
|
||||
try:
|
||||
config_loader = ConfigArgsLoader()
|
||||
config_loader.update_config()
|
||||
except:
|
||||
return errno.EINVAL
|
||||
|
||||
# Wait to reset the board
|
||||
writer = FlashWriter(ConfigArgs.PROTOCOL_TYPE)
|
||||
|
||||
do_wait_reset = True
|
||||
if ConfigArgs.AUTO_RESET:
|
||||
if subprocess.call("cd " + sys.path[0] + "; ./reset_board.sh", shell=True) == 0:
|
||||
print("auto reset board success!!")
|
||||
do_wait_reset = False
|
||||
bootrom_msg = writer.cancel_autoboot()
|
||||
|
||||
if ConfigArgs.DTR_RESET:
|
||||
do_wait_reset = False
|
||||
bootrom_msg = writer.cancel_autoboot()
|
||||
|
||||
if ConfigArgs.WAIT_RESET == False and do_wait_reset == True:
|
||||
rx = writer.recv()
|
||||
time.sleep(1)
|
||||
for i in range(3):
|
||||
writer.send("")
|
||||
rx = writer.recv()
|
||||
if "updater".encode() in rx:
|
||||
# No need to wait for reset
|
||||
do_wait_reset = False
|
||||
break
|
||||
time.sleep(1)
|
||||
|
||||
if do_wait_reset:
|
||||
# Wait to reset the board
|
||||
print('Please press RESET button on target board')
|
||||
sys.stdout.flush()
|
||||
bootrom_msg = writer.cancel_autoboot()
|
||||
|
||||
# Remove files
|
||||
if ConfigArgs.ERASE_NAME :
|
||||
print(">>> Remove existing files ...")
|
||||
writer.delete_files(ConfigArgs.ERASE_NAME)
|
||||
|
||||
# Install files
|
||||
if ConfigArgs.PACKAGE_NAME or ConfigArgs.PKGSYS_NAME or ConfigArgs.PKGAPP_NAME or ConfigArgs.PKGUPD_NAME:
|
||||
print(">>> Install files ...")
|
||||
if ConfigArgs.PACKAGE_NAME :
|
||||
writer.install_files(ConfigArgs.PACKAGE_NAME, "install")
|
||||
if ConfigArgs.PKGSYS_NAME :
|
||||
writer.install_files(ConfigArgs.PKGSYS_NAME, "install")
|
||||
if ConfigArgs.PKGAPP_NAME :
|
||||
writer.install_files(ConfigArgs.PKGAPP_NAME, "install")
|
||||
if ConfigArgs.PKGUPD_NAME :
|
||||
writer.install_files(ConfigArgs.PKGUPD_NAME, "install -k updater.key")
|
||||
|
||||
# Save files
|
||||
if ConfigArgs.FILE_NAME :
|
||||
print(">>> Save files ...")
|
||||
writer.save_files(ConfigArgs.FILE_NAME)
|
||||
|
||||
# Set auto boot
|
||||
if not ConfigArgs.NO_SET_BOOTABLE:
|
||||
print(">>> Save Configuration to FlashROM ...")
|
||||
writer.send("set bootable M0P")
|
||||
writer.wait_for_prompt()
|
||||
|
||||
# Sync all cached data to flash
|
||||
writer.send("sync")
|
||||
writer.wait_for_prompt()
|
||||
|
||||
if REBOOT_AT_END :
|
||||
print("Restarting the board ...")
|
||||
writer.send("reboot")
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
sys.exit(main())
|
||||
except KeyboardInterrupt:
|
||||
print("Canceled by keyboard interrupt.")
|
||||
pass
|
||||
@@ -0,0 +1,591 @@
|
||||
#!/usr/bin/env python3
|
||||
'''
|
||||
===============================
|
||||
XMODEM file transfer protocol
|
||||
===============================
|
||||
|
||||
.. $Id$
|
||||
|
||||
This is a literal implementation of XMODEM.TXT_, XMODEM1K.TXT_ and
|
||||
XMODMCRC.TXT_, support for YMODEM and ZMODEM is pending. YMODEM should
|
||||
be fairly easy to implement as it is a hack on top of the XMODEM
|
||||
protocol using sequence bytes ``0x00`` for sending file names (and some
|
||||
meta data).
|
||||
|
||||
.. _XMODEM.TXT: doc/XMODEM.TXT
|
||||
.. _XMODEM1K.TXT: doc/XMODEM1K.TXT
|
||||
.. _XMODMCRC.TXT: doc/XMODMCRC.TXT
|
||||
|
||||
Data flow example including error recovery
|
||||
==========================================
|
||||
|
||||
Here is a sample of the data flow, sending a 3-block message.
|
||||
It includes the two most common line hits - a garbaged block,
|
||||
and an ``ACK`` reply getting garbaged. ``CRC`` or ``CSUM`` represents
|
||||
the checksum bytes.
|
||||
|
||||
XMODEM 128 byte blocks
|
||||
----------------------
|
||||
|
||||
::
|
||||
|
||||
SENDER RECEIVER
|
||||
|
||||
<-- NAK
|
||||
SOH 01 FE Data[128] CSUM -->
|
||||
<-- ACK
|
||||
SOH 02 FD Data[128] CSUM -->
|
||||
<-- ACK
|
||||
SOH 03 FC Data[128] CSUM -->
|
||||
<-- ACK
|
||||
SOH 04 FB Data[128] CSUM -->
|
||||
<-- ACK
|
||||
SOH 05 FA Data[100] CPMEOF[28] CSUM -->
|
||||
<-- ACK
|
||||
EOT -->
|
||||
<-- ACK
|
||||
|
||||
XMODEM-1k blocks, CRC mode
|
||||
--------------------------
|
||||
|
||||
::
|
||||
|
||||
SENDER RECEIVER
|
||||
|
||||
<-- C
|
||||
STX 01 FE Data[1024] CRC CRC -->
|
||||
<-- ACK
|
||||
STX 02 FD Data[1024] CRC CRC -->
|
||||
<-- ACK
|
||||
STX 03 FC Data[1000] CPMEOF[24] CRC CRC -->
|
||||
<-- ACK
|
||||
EOT -->
|
||||
<-- ACK
|
||||
|
||||
Mixed 1024 and 128 byte Blocks
|
||||
------------------------------
|
||||
|
||||
::
|
||||
|
||||
SENDER RECEIVER
|
||||
|
||||
<-- C
|
||||
STX 01 FE Data[1024] CRC CRC -->
|
||||
<-- ACK
|
||||
STX 02 FD Data[1024] CRC CRC -->
|
||||
<-- ACK
|
||||
SOH 03 FC Data[128] CRC CRC -->
|
||||
<-- ACK
|
||||
SOH 04 FB Data[100] CPMEOF[28] CRC CRC -->
|
||||
<-- ACK
|
||||
EOT -->
|
||||
<-- ACK
|
||||
|
||||
YMODEM Batch Transmission Session (1 file)
|
||||
------------------------------------------
|
||||
|
||||
::
|
||||
|
||||
SENDER RECEIVER
|
||||
<-- C (command:rb)
|
||||
SOH 00 FF foo.c NUL[123] CRC CRC -->
|
||||
<-- ACK
|
||||
<-- C
|
||||
SOH 01 FE Data[128] CRC CRC -->
|
||||
<-- ACK
|
||||
SOH 02 FC Data[128] CRC CRC -->
|
||||
<-- ACK
|
||||
SOH 03 FB Data[100] CPMEOF[28] CRC CRC -->
|
||||
<-- ACK
|
||||
EOT -->
|
||||
<-- NAK
|
||||
EOT -->
|
||||
<-- ACK
|
||||
<-- C
|
||||
SOH 00 FF NUL[128] CRC CRC -->
|
||||
<-- ACK
|
||||
|
||||
|
||||
'''
|
||||
|
||||
__author__ = 'Wijnand Modderman <maze@pyth0n.org>'
|
||||
__copyright__ = ['Copyright (c) 2010 Wijnand Modderman',
|
||||
'Copyright (c) 1981 Chuck Forsberg']
|
||||
__license__ = 'MIT'
|
||||
__version__ = '0.3.2'
|
||||
|
||||
import logging
|
||||
import time
|
||||
import sys
|
||||
from functools import partial
|
||||
import collections
|
||||
|
||||
# Loggerr
|
||||
log = logging.getLogger('xmodem')
|
||||
|
||||
# Protocol bytes
|
||||
SOH = bytes([0x01])
|
||||
STX = bytes([0x02])
|
||||
EOT = bytes([0x04])
|
||||
ACK = bytes([0x06])
|
||||
DLE = bytes([0x10])
|
||||
NAK = bytes([0x15])
|
||||
CAN = bytes([0x18])
|
||||
CRC = bytes([0x43]) # C
|
||||
|
||||
|
||||
class XMODEM(object):
|
||||
'''
|
||||
XMODEM Protocol handler, expects an object to read from and an object to
|
||||
write to.
|
||||
|
||||
>>> def getc(size, timeout=1):
|
||||
... return data or None
|
||||
...
|
||||
>>> def putc(data, timeout=1):
|
||||
... return size or None
|
||||
...
|
||||
>>> modem = XMODEM(getc, putc)
|
||||
|
||||
|
||||
:param getc: Function to retrieve bytes from a stream
|
||||
:type getc: callable
|
||||
:param putc: Function to transmit bytes to a stream
|
||||
:type putc: callable
|
||||
:param mode: XMODEM protocol mode
|
||||
:type mode: string
|
||||
:param pad: Padding character to make the packets match the packet size
|
||||
:type pad: char
|
||||
|
||||
'''
|
||||
|
||||
# crctab calculated by Mark G. Mendel, Network Systems Corporation
|
||||
crctable = [
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
|
||||
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
|
||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
|
||||
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
|
||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
|
||||
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
|
||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
|
||||
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
|
||||
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
|
||||
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
|
||||
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
|
||||
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
|
||||
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
|
||||
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
|
||||
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
|
||||
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
|
||||
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
|
||||
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
|
||||
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
|
||||
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
|
||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
|
||||
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
|
||||
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
|
||||
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
|
||||
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
|
||||
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
|
||||
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
|
||||
]
|
||||
|
||||
def __init__(self, getc, putc, mode='xmodem', pad=b'\x1a'):
|
||||
self.getc = getc
|
||||
self.putc = putc
|
||||
self.mode = mode
|
||||
self.pad = pad
|
||||
|
||||
def abort(self, count=2, timeout=60):
|
||||
'''
|
||||
Send an abort sequence using CAN bytes.
|
||||
'''
|
||||
for counter in range(0, count):
|
||||
self.putc(CAN, timeout)
|
||||
|
||||
def send(self, stream, retry=32, timeout=360, quiet=0, callback=None):
|
||||
'''
|
||||
Send a stream via the XMODEM protocol.
|
||||
|
||||
>>> stream = file('/etc/issue', 'rb')
|
||||
>>> print modem.send(stream)
|
||||
True
|
||||
|
||||
Returns ``True`` upon successful transmission or ``False`` in case of
|
||||
failure.
|
||||
|
||||
:param stream: The stream object to send data from.
|
||||
:type stream: stream (file, etc.)
|
||||
:param retry: The maximum number of times to try to resend a failed
|
||||
packet before failing.
|
||||
:type retry: int
|
||||
:param timeout: The number of seconds to wait for a response before
|
||||
timing out.
|
||||
:type timeout: int
|
||||
:param quiet: If 0, it prints info to stderr. If 1, it does not print any info.
|
||||
:type quiet: int
|
||||
:param callback: Reference to a callback function that has the
|
||||
following signature. This is useful for
|
||||
getting status updates while a xmodem
|
||||
transfer is underway.
|
||||
Expected callback signature:
|
||||
def callback(total_packets, success_count, error_count)
|
||||
:type callback: callable
|
||||
'''
|
||||
|
||||
# initialize protocol
|
||||
try:
|
||||
packet_size = dict(
|
||||
xmodem = 128,
|
||||
xmodem1k = 1024,
|
||||
)[self.mode]
|
||||
except AttributeError:
|
||||
raise ValueError("An invalid mode was supplied")
|
||||
|
||||
error_count = 0
|
||||
crc_mode = 0
|
||||
cancel = 0
|
||||
while True:
|
||||
char = self.getc(1)
|
||||
if char:
|
||||
if char == NAK:
|
||||
crc_mode = 0
|
||||
break
|
||||
elif char == CRC:
|
||||
crc_mode = 1
|
||||
break
|
||||
elif char == CAN:
|
||||
if not quiet:
|
||||
print('received CAN', file=sys.stderr)
|
||||
if cancel:
|
||||
return False
|
||||
else:
|
||||
cancel = 1
|
||||
else:
|
||||
log.error('send ERROR expected NAK/CRC, got %s' % \
|
||||
(ord(char),))
|
||||
|
||||
error_count += 1
|
||||
if error_count >= retry:
|
||||
self.abort(timeout=timeout)
|
||||
return False
|
||||
|
||||
# send data
|
||||
error_count = 0
|
||||
success_count = 0
|
||||
total_packets = 0
|
||||
sequence = 1
|
||||
while True:
|
||||
data = stream.read(packet_size)
|
||||
if not data:
|
||||
log.info('sending EOT')
|
||||
# end of stream
|
||||
break
|
||||
total_packets += 1
|
||||
data = data.ljust(packet_size, self.pad)
|
||||
if crc_mode:
|
||||
crc = self.calc_crc(data)
|
||||
else:
|
||||
crc = self.calc_checksum(data)
|
||||
|
||||
# emit packet
|
||||
while True:
|
||||
if packet_size == 128:
|
||||
self.putc(SOH)
|
||||
else: # packet_size == 1024
|
||||
self.putc(STX)
|
||||
self.putc(bytes([sequence]))
|
||||
self.putc(bytes([0xff - sequence]))
|
||||
self.putc(data)
|
||||
if crc_mode:
|
||||
self.putc(bytes([crc >> 8]))
|
||||
self.putc(bytes([crc & 0xff]))
|
||||
else:
|
||||
self.putc(bytes([crc]))
|
||||
|
||||
char = self.getc(1, timeout)
|
||||
if char == ACK:
|
||||
success_count += 1
|
||||
if isinstance(callback, collections.Callable):
|
||||
callback(total_packets, success_count, error_count)
|
||||
break
|
||||
if char == NAK:
|
||||
error_count += 1
|
||||
if isinstance(callback, collections.Callable):
|
||||
callback(total_packets, success_count, error_count)
|
||||
if error_count >= retry:
|
||||
# excessive amounts of retransmissions requested,
|
||||
# abort transfer
|
||||
self.abort(timeout=timeout)
|
||||
log.warning('excessive NAKs, transfer aborted')
|
||||
return False
|
||||
|
||||
# return to loop and resend
|
||||
continue
|
||||
else:
|
||||
log.error('Not ACK, Not NAK')
|
||||
error_count += 1
|
||||
if isinstance(callback, collections.Callable):
|
||||
callback(total_packets, success_count, error_count)
|
||||
if error_count >= retry:
|
||||
# excessive amounts of retransmissions requested,
|
||||
# abort transfer
|
||||
self.abort(timeout=timeout)
|
||||
log.warning('excessive protocol errors, transfer aborted')
|
||||
return False
|
||||
|
||||
# return to loop and resend
|
||||
continue
|
||||
|
||||
# protocol error
|
||||
self.abort(timeout=timeout)
|
||||
log.error('protocol error')
|
||||
return False
|
||||
|
||||
# keep track of sequence
|
||||
sequence = (sequence + 1) % 0x100
|
||||
|
||||
while True:
|
||||
# end of transmission
|
||||
self.putc(EOT)
|
||||
|
||||
#An ACK should be returned
|
||||
char = self.getc(1, timeout)
|
||||
if char == ACK:
|
||||
break
|
||||
else:
|
||||
error_count += 1
|
||||
if error_count >= retry:
|
||||
self.abort(timeout=timeout)
|
||||
log.warning('EOT was not ACKd, transfer aborted')
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def recv(self, stream, crc_mode=1, retry=16, timeout=60, delay=1, quiet=0):
|
||||
'''
|
||||
Receive a stream via the XMODEM protocol.
|
||||
|
||||
>>> stream = file('/etc/issue', 'wb')
|
||||
>>> print modem.recv(stream)
|
||||
2342
|
||||
|
||||
Returns the number of bytes received on success or ``None`` in case of
|
||||
failure.
|
||||
'''
|
||||
|
||||
# initiate protocol
|
||||
error_count = 0
|
||||
char = 0
|
||||
cancel = 0
|
||||
while True:
|
||||
# first try CRC mode, if this fails,
|
||||
# fall back to checksum mode
|
||||
if error_count >= retry:
|
||||
self.abort(timeout=timeout)
|
||||
return None
|
||||
elif crc_mode and error_count < (retry / 2):
|
||||
if not self.putc(CRC):
|
||||
time.sleep(delay)
|
||||
error_count += 1
|
||||
else:
|
||||
crc_mode = 0
|
||||
if not self.putc(NAK):
|
||||
time.sleep(delay)
|
||||
error_count += 1
|
||||
|
||||
char = self.getc(1, timeout)
|
||||
if not char:
|
||||
error_count += 1
|
||||
continue
|
||||
elif char == SOH:
|
||||
#crc_mode = 0
|
||||
break
|
||||
elif char == STX:
|
||||
break
|
||||
elif char == CAN:
|
||||
if cancel:
|
||||
return None
|
||||
else:
|
||||
cancel = 1
|
||||
else:
|
||||
error_count += 1
|
||||
|
||||
# read data
|
||||
error_count = 0
|
||||
income_size = 0
|
||||
packet_size = 128
|
||||
sequence = 1
|
||||
cancel = 0
|
||||
while True:
|
||||
while True:
|
||||
if char == SOH:
|
||||
packet_size = 128
|
||||
break
|
||||
elif char == STX:
|
||||
packet_size = 1024
|
||||
break
|
||||
elif char == EOT:
|
||||
# We received an EOT, so send an ACK and return the received
|
||||
# data length
|
||||
self.putc(ACK)
|
||||
return income_size
|
||||
elif char == CAN:
|
||||
# cancel at two consecutive cancels
|
||||
if cancel:
|
||||
return None
|
||||
else:
|
||||
cancel = 1
|
||||
else:
|
||||
if not quiet:
|
||||
print('recv ERROR expected SOH/EOT, got', ord(char), file=sys.stderr)
|
||||
error_count += 1
|
||||
if error_count >= retry:
|
||||
self.abort()
|
||||
return None
|
||||
# read sequence
|
||||
error_count = 0
|
||||
cancel = 0
|
||||
seq1 = ord(self.getc(1))
|
||||
seq2 = 0xff - ord(self.getc(1))
|
||||
if seq1 == sequence and seq2 == sequence:
|
||||
# sequence is ok, read packet
|
||||
# packet_size + checksum
|
||||
data = self.getc(packet_size + 1 + crc_mode, timeout)
|
||||
if crc_mode:
|
||||
csum = (ord(data[-2]) << 8) + ord(data[-1])
|
||||
data = data[:-2]
|
||||
log.debug('CRC (%04x <> %04x)' % \
|
||||
(csum, self.calc_crc(data)))
|
||||
valid = csum == self.calc_crc(data)
|
||||
else:
|
||||
csum = data[-1]
|
||||
data = data[:-1]
|
||||
log.debug('checksum (checksum(%02x <> %02x)' % \
|
||||
(ord(csum), self.calc_checksum(data)))
|
||||
valid = ord(csum) == self.calc_checksum(data)
|
||||
|
||||
# valid data, append chunk
|
||||
if valid:
|
||||
income_size += len(data)
|
||||
stream.write(data)
|
||||
self.putc(ACK)
|
||||
sequence = (sequence + 1) % 0x100
|
||||
char = self.getc(1, timeout)
|
||||
continue
|
||||
else:
|
||||
# consume data
|
||||
self.getc(packet_size + 1 + crc_mode)
|
||||
self.debug('expecting sequence %d, got %d/%d' % \
|
||||
(sequence, seq1, seq2))
|
||||
|
||||
# something went wrong, request retransmission
|
||||
self.putc(NAK)
|
||||
|
||||
def calc_checksum(self, data, checksum=0):
|
||||
'''
|
||||
Calculate the checksum for a given block of data, can also be used to
|
||||
update a checksum.
|
||||
|
||||
>>> csum = modem.calc_checksum('hello')
|
||||
>>> csum = modem.calc_checksum('world', csum)
|
||||
>>> hex(csum)
|
||||
'0x3c'
|
||||
|
||||
'''
|
||||
return (sum(map(ord, data)) + checksum) % 256
|
||||
|
||||
def calc_crc(self, data, crc=0):
|
||||
'''
|
||||
Calculate the Cyclic Redundancy Check for a given block of data, can
|
||||
also be used to update a CRC.
|
||||
|
||||
>>> crc = modem.calc_crc('hello')
|
||||
>>> crc = modem.calc_crc('world', crc)
|
||||
>>> hex(crc)
|
||||
'0xd5e3'
|
||||
|
||||
'''
|
||||
for char in data:
|
||||
crc = (crc << 8) ^ self.crctable[((crc >> 8) ^ int(char)) & 0xff]
|
||||
return crc & 0xffff
|
||||
|
||||
|
||||
XMODEM1k = partial(XMODEM, mode='xmodem1k')
|
||||
|
||||
|
||||
def run():
|
||||
import optparse
|
||||
import subprocess
|
||||
|
||||
parser = optparse.OptionParser(usage='%prog [<options>] <send|recv> filename filename')
|
||||
parser.add_option('-m', '--mode', default='xmodem',
|
||||
help='XMODEM mode (xmodem, xmodem1k)')
|
||||
|
||||
options, args = parser.parse_args()
|
||||
if len(args) != 3:
|
||||
parser.error('invalid arguments')
|
||||
return 1
|
||||
|
||||
elif args[0] not in ('send', 'recv'):
|
||||
parser.error('invalid mode')
|
||||
return 1
|
||||
|
||||
def _func(so, si):
|
||||
import select
|
||||
import subprocess
|
||||
|
||||
print('si', si)
|
||||
print('so', so)
|
||||
|
||||
def getc(size, timeout=3):
|
||||
w,t,f = select.select([so], [], [], timeout)
|
||||
if w:
|
||||
data = so.read(size)
|
||||
else:
|
||||
data = None
|
||||
|
||||
print('getc(', repr(data), ')')
|
||||
return data
|
||||
|
||||
def putc(data, timeout=3):
|
||||
w,t,f = select.select([], [si], [], timeout)
|
||||
if t:
|
||||
si.write(data)
|
||||
si.flush()
|
||||
size = len(data)
|
||||
else:
|
||||
size = None
|
||||
|
||||
print('putc(', repr(data), repr(size), ')')
|
||||
return size
|
||||
|
||||
return getc, putc
|
||||
|
||||
def _pipe(*command):
|
||||
pipe = subprocess.Popen(command,
|
||||
stdout=subprocess.PIPE, stdin=subprocess.PIPE)
|
||||
return pipe.stdout, pipe.stdin
|
||||
|
||||
if args[0] == 'recv':
|
||||
import io
|
||||
getc, putc = _func(*_pipe('sz', '--xmodem', args[2]))
|
||||
stream = open(args[1], 'wb')
|
||||
xmodem = XMODEM(getc, putc, mode=options.mode)
|
||||
status = xmodem.recv(stream, retry=8)
|
||||
stream.close()
|
||||
|
||||
elif args[0] == 'send':
|
||||
getc, putc = _func(*_pipe('rz', '--xmodem', args[2]))
|
||||
stream = open(args[1], 'rb')
|
||||
xmodem = XMODEM(getc, putc, mode=options.mode)
|
||||
status = xmodem.send(stream, retry=8)
|
||||
stream.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(run())
|
||||
Reference in New Issue
Block a user