diff --git a/BUILD.gn b/BUILD.gn new file mode 100755 index 0000000..35d6257 --- /dev/null +++ b/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +if (ohos_kernel_type == "liteos_m") { + import("//kernel/liteos_m/liteos.gni") + module_name = get_path_info(rebase_path("."), "name") + module_group(module_name) { + modules = [ "b91" ] + } +} diff --git a/Kconfig.liteos_m.defconfig b/Kconfig.liteos_m.defconfig new file mode 100755 index 0000000..c165a00 --- /dev/null +++ b/Kconfig.liteos_m.defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +rsource "*/Kconfig.liteos_m.defconfig.series" diff --git a/Kconfig.liteos_m.series b/Kconfig.liteos_m.series new file mode 100755 index 0000000..9b89cbc --- /dev/null +++ b/Kconfig.liteos_m.series @@ -0,0 +1,16 @@ +# Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +rsource "*/Kconfig.liteos_m.series" diff --git a/Kconfig.liteos_m.soc b/Kconfig.liteos_m.soc new file mode 100755 index 0000000..3e63370 --- /dev/null +++ b/Kconfig.liteos_m.soc @@ -0,0 +1,24 @@ +# Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +config SOC_COMPANY_TELINK + bool + +if SOC_COMPANY_TELINK +config SOC_COMPANY + default "telink" + +rsource "*/Kconfig.liteos_m.soc" +endif # SOC_COMPANY_TELINK diff --git a/b91/BUILD.gn b/b91/BUILD.gn new file mode 100755 index 0000000..742bb81 --- /dev/null +++ b/b91/BUILD.gn @@ -0,0 +1,52 @@ +# Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//build/lite/config/subsystem/lite_subsystem.gni") +import("//kernel/liteos_m/liteos.gni") +import("//drivers/adapter/khdf/liteos_m/hdf.gni") + +driver_sdk_path = "b91m_ble_sdk" + +config("B91_config") { + defines = [ + "__PROJECT_B91_EXTERNAL=1" + ] + + include_dirs = [ + "liteos_m/inc", + "$driver_sdk_path", + "$driver_sdk_path/common", + "$driver_sdk_path/drivers", + "$driver_sdk_path/drivers/B91", + "$driver_sdk_path/vendor/common", + ] + + configs = [ + "//drivers/adapter/khdf/liteos_m:hdf_config", + ] +} + +module_name = get_path_info(rebase_path("."), "name") + +module_group(module_name) { + deps = [ + driver_sdk_path, + "hdf", + ] + modules = [ + "liteos_m", + ] +} diff --git a/b91/Kconfig.liteos_m.defconfig.b91 b/b91/Kconfig.liteos_m.defconfig.b91 new file mode 100755 index 0000000..53aa679 --- /dev/null +++ b/b91/Kconfig.liteos_m.defconfig.b91 @@ -0,0 +1,19 @@ +# Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +config SOC + string + default "B91" + depends on SOC_B91 diff --git a/b91/Kconfig.liteos_m.defconfig.series b/b91/Kconfig.liteos_m.defconfig.series new file mode 100755 index 0000000..6762aa5 --- /dev/null +++ b/b91/Kconfig.liteos_m.defconfig.series @@ -0,0 +1,25 @@ +# Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +if SOC_SERIES_B91 + +rsource "Kconfig.liteos_m.defconfig.b91" + +config SOC_SERIES + string + default "B91" + +endif + diff --git a/b91/Kconfig.liteos_m.series b/b91/Kconfig.liteos_m.series new file mode 100755 index 0000000..82fa0d9 --- /dev/null +++ b/b91/Kconfig.liteos_m.series @@ -0,0 +1,23 @@ +# Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +config SOC_SERIES_B91 + bool "Telink B91 Series" + select RISC-V + select SOC_COMPANY_TELINK + select CPU_RISCV32 + help + Enable support for telink b91 series + diff --git a/b91/Kconfig.liteos_m.soc b/b91/Kconfig.liteos_m.soc new file mode 100755 index 0000000..3de9f12 --- /dev/null +++ b/b91/Kconfig.liteos_m.soc @@ -0,0 +1,23 @@ +# Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +choice + prompt "Telink B91 Series SoC" + depends on SOC_SERIES_B91 + +config SOC_B91 + bool "SoC B91" +endchoice + diff --git a/b91/adapter/hals/utils/file/BUILD.gn b/b91/adapter/hals/utils/file/BUILD.gn new file mode 100755 index 0000000..3dd5d3c --- /dev/null +++ b/b91/adapter/hals/utils/file/BUILD.gn @@ -0,0 +1,27 @@ +# Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") + +static_library("hal_file_static") { + sources = [ "src/hal_file.c" ] + + include_dirs = [ + "//utils/native/lite/hals/file", + "//utils/native/lite/include", + ] + + deps = [] +} diff --git a/b91/adapter/hals/utils/file/src/hal_file.c b/b91/adapter/hals/utils/file/src/hal_file.c new file mode 100755 index 0000000..3f0dc6f --- /dev/null +++ b/b91/adapter/hals/utils/file/src/hal_file.c @@ -0,0 +1,253 @@ +/****************************************************************************** + * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils_file.h" +#include "hal_file.h" + +#define RD_WR_FIELD_MASK 0x000f +#define CREAT_EXCL_FIELD_MASK 0x00f0 +#define TRUNC_FILED_MASK 0x0f00 + +#define ADDITIONAL_LEN 2 +#define MAX_PATH_LEN 40 +#define MAX_OPEN_FILE_NUM 32 +#define ROOT_PATH "/data" +#define DIR_SEPARATOR "/" + +#define SLOT_AVAILABLE -1 + +#define HAL_ERROR -1 + +static int FileHandlerArray[MAX_OPEN_FILE_NUM] = +{ + SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, + SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, + SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, + SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, SLOT_AVAILABLE, +}; + +static int GetAvailableFileHandlerIndex(void) +{ + int i = MAX_OPEN_FILE_NUM; + + for (; i > 0; i--) { + if (FileHandlerArray[i - 1] == SLOT_AVAILABLE) + break; + } + + return i; +} +static int ConvertFlags(int oflag) +{ + int ret = 0; + int buffer = 0; + + buffer = (oflag & RD_WR_FIELD_MASK); + if (buffer == O_RDONLY_FS) { + ret = O_RDONLY; + } else if (buffer == O_WRONLY_FS) { + ret = O_WRONLY; + } else if (buffer == O_RDWR_FS) { + ret = O_RDWR; + } + + buffer = (oflag & CREAT_EXCL_FIELD_MASK); + if ((buffer & O_CREAT_FS) != 0) { + ret |= O_CREAT; + } + + if ((buffer & O_EXCL_FS) != 0) { + ret |= O_EXCL; + } + + buffer = (oflag & TRUNC_FILED_MASK); + if ((buffer & O_TRUNC_FS) != 0) { + ret |= O_TRUNC; + } + + if ((buffer & O_APPEND_FS) != 0) { + ret |= O_APPEND; + } + + return ret; +} + +static char *GetActualFilePath(const char *path) +{ + int len; + char *file_path = NULL; + + len = strnlen(path, MAX_PATH_LEN); + if (len >= MAX_PATH_LEN) { + printf("path is too long!\r\n"); + return NULL; + } + + len += (strlen(ROOT_PATH) + ADDITIONAL_LEN); + file_path = (char *)malloc(len); + if (file_path == NULL) { + printf("malloc failed!\r\n"); + return NULL; + } + + strcpy(file_path, ROOT_PATH); + strcat(file_path, DIR_SEPARATOR); + strcat(file_path, path); +} + +int HalFileOpen(const char *path, int oflag, int mode) +{ + int index; + int fd; + char *file_path; + + index = GetAvailableFileHandlerIndex(); + if (index == 0) { + printf("no space available!\r\n"); + return HAL_ERROR; + } + + file_path = GetActualFilePath(path); + if (file_path == NULL) { + return HAL_ERROR; + } + + fd = open(file_path, ConvertFlags(oflag)); + if (fd < 0) { + printf("failed to open file '%s': %d\r\n", file_path, errno); + free(file_path); + return HAL_ERROR; + } + + FileHandlerArray[index - 1] = fd; + free(file_path); + + return index; +} + +int HalFileClose(int fd) +{ + int ret; + + /* make sure fd is within the allowed range, which is 1 to MAX_OPEN_FILE_NUM */ + if ((fd > MAX_OPEN_FILE_NUM) || (fd <= 0)) { + return HAL_ERROR; + } + + ret = close(FileHandlerArray[fd - 1]); + if (ret != 0) { + return HAL_ERROR; + } + + FileHandlerArray[fd - 1] = SLOT_AVAILABLE; + + return ret; +} + +int HalFileRead(int fd, char *buf, unsigned int len) +{ + /* make sure fd is within the allowed range, which is 1 to MAX_OPEN_FILE_NUM */ + if ((fd > MAX_OPEN_FILE_NUM) || (fd <= 0)) { + return HAL_ERROR; + } + + return read(FileHandlerArray[fd - 1], buf, len); +} + +int HalFileWrite(int fd, const char *buf, unsigned int len) +{ + /* make sure fd is within the allowed range, which is 1 to MAX_OPEN_FILE_NUM */ + if ((fd > MAX_OPEN_FILE_NUM) || (fd <= 0)) { + return HAL_ERROR; + } + + return write(FileHandlerArray[fd - 1], buf, len); +} + +int HalFileDelete(const char *path) +{ + char *file_path; + int ret; + + file_path = GetActualFilePath(path); + if (file_path == NULL) { + return HAL_ERROR; + } + + ret = unlink(file_path); + free(file_path); + + return ret; +} + +int HalFileStat(const char *path, unsigned int *fileSize) +{ + char *file_path; + struct stat f_info; + int ret; + + file_path = GetActualFilePath(path); + if (file_path == NULL) { + return HAL_ERROR; + } + + ret = stat(file_path, &f_info); + *fileSize = f_info.st_size; + free(file_path); + + return ret; +} + +int HalFileSeek(int fd, int offset, unsigned int whence) +{ + int ret = 0; + struct stat f_info; + + /* make sure fd is within the allowed range, which is 1 to MAX_OPEN_FILE_NUM */ + if ((fd > MAX_OPEN_FILE_NUM) || (fd <= 0)) { + return HAL_ERROR; + } + + ret = fstat(FileHandlerArray[fd - 1], &f_info); + if (ret != 0) { + return HAL_ERROR; + } + + if (whence == SEEK_SET_FS) { + if (offset > f_info.st_size) { + ret = HAL_ERROR; + } + } + + ret = lseek(FileHandlerArray[fd - 1], offset, whence); + if ((ret > f_info.st_size) || (ret < 0)) { + return HAL_ERROR; + } + + return ret; +} diff --git a/b91/b91m_ble_sdk/.cproject b/b91/b91m_ble_sdk/.cproject new file mode 100755 index 0000000..17df9b6 --- /dev/null +++ b/b91/b91m_ble_sdk/.cproject @@ -0,0 +1,1242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/b91/b91m_ble_sdk/.project b/b91/b91m_ble_sdk/.project new file mode 100755 index 0000000..54fa58d --- /dev/null +++ b/b91/b91m_ble_sdk/.project @@ -0,0 +1,82 @@ + + + B91_ble_multi_conn_sdk + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + all + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + make + + + org.eclipse.cdt.make.core.buildLocation + ${workspace_loc:/Eagle_Driver_Demo}/9518_UART_DEMO + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + all + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + false + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/b91/b91m_ble_sdk/BUILD.gn b/b91/b91m_ble_sdk/BUILD.gn new file mode 100755 index 0000000..643ddc6 --- /dev/null +++ b/b91/b91m_ble_sdk/BUILD.gn @@ -0,0 +1,44 @@ +# Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") +import("//build/lite/config/subsystem/lite_subsystem.gni") + +static_library("b91m_ble_sdk") { + sources = [ + "common/utility.c", + "drivers/B91/aes.c", + "drivers/B91/analog.c", + "drivers/B91/clock.c", + "drivers/B91/stimer.c", + "drivers/B91/gpio.c", + "drivers/B91/uart.c", + "drivers/B91/flash.c", + + "drivers/B91/ext_driver/software_pa.c", + ] + + sources += [ + "application/keyboard/keyboard.c", + "vendor/common/simple_sdp.c", + "vendor/common/blt_common.c", + "vendor/common/custom_pair.c", + "vendor/common/device_manage.c", + ] + + libs = ["proj_lib/liblt_9518.a"] + + configs += ["..:B91_config"] +} diff --git a/b91/b91m_ble_sdk/algorithm/aes_ccm/aes_ccm.h b/b91/b91m_ble_sdk/algorithm/aes_ccm/aes_ccm.h new file mode 100755 index 0000000..426bb2a --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/aes_ccm/aes_ccm.h @@ -0,0 +1,154 @@ +/******************************************************************************************************** + * @file aes_ccm.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "stack/ble/ble_format.h" + +#define AES_BLOCK_SIZE 16 + + +//#define SUCCESS 0 +enum { + AES_SUCC = SUCCESS, + AES_NO_BUF, + AES_FAIL, +}; + + +typedef struct { + u32 pkt; + u8 dir; + u8 iv[8]; +} ble_cyrpt_nonce_t; + + +typedef struct { + u64 enc_pno; + u64 dec_pno; + u8 sk[16]; //session key + ble_cyrpt_nonce_t nonce; + u8 st; + u8 enable; //1: slave enable; 2: master enable + u8 mic_fail; +} ble_crypt_para_t; + + +struct CCM_FLAGS_TAG { + union { + struct { + u8 L : 3; + u8 M : 3; + u8 aData :1; + u8 reserved :1; + } bf; + u8 val; + }; +}; + +typedef struct CCM_FLAGS_TAG ccm_flags_t; + + +typedef struct { + union { + u8 A[AES_BLOCK_SIZE]; + u8 B[AES_BLOCK_SIZE]; + } bf; + + u8 tmpResult[AES_BLOCK_SIZE]; + u8 newAstr[AES_BLOCK_SIZE]; +} aes_enc_t; + + +enum{ + CRYPT_NONCE_TYPE_ACL = 0, + CRYPT_NONCE_TYPE_CIS = 1, + CRYPT_NONCE_TYPE_BIS = 2, +}; + + +/** + * @brief this function is used to encrypt the plaintext + * @param[in] *key - aes key: 128 bit key for the encryption of the data, little--endian. + * @param[in] *plaintext - 128 bit data block that is requested to be encrypted, little--endian. + * @param[out] *result - 128 bit encrypted data block, little--endian. + * @return none. + * @Note Input data requires strict Word alignment + */ +void aes_ll_encryption(u8* key, u8* plaintext, u8 *encrypted_data); + + +/** + * @brief this function is used to initialize the aes_ccm initial value + * @param[in] ltk - encryption key, LTK + * @param[in] skdm - + * @param[in] skds - + * @param[in] ivm - + * @param[in] ivs - + * @param[in] pd - Reference structure ble_crypt_para_t + * @return none + */ +void aes_ll_ccm_encryption_init (u8 *ltk, u8 *skdm, u8 *skds, u8 *ivm, u8 *ivs, ble_crypt_para_t *pd); + + +/** + * @brief this function is used to encrypt the aes_ccm value + * @param[in] pkt - plaint_text + * @param[in] master - ll_ccm_enc: Master role must use 1, Slave role must use 0; + ll_ccm_dec: Master role must use 0, Slave role must use 1; + * @param[in] pd - Reference structure ble_crypt_para_t + * @return none + */ +//void aes_ll_ccm_encryption(u8 *pkt, int master, ble_crypt_para_t *pd); + + +/** + * @brief this function is used to encrypt the aes_ccm value, version2 + * @param[in] pd - Reference structure leCryptCtrl_t + * @return none + */ +void aes_ll_ccm_encryption(llPhysChnPdu_t *pllPhysChnPdu, u8 role, u8 ll_type, ble_crypt_para_t *pd); + + +/** + * @brief this function is used to decrypt the aes_ccm value + * @param[in] pkt - plaint_text + * @param[in] master - ll_ccm_enc: Master role must use 1, Slave role must use 0; + ll_ccm_dec: Master role must use 0, Slave role must use 1; + * @param[in] pd - Reference structure ble_crypt_para_t + * @return 0: decryption succeeded; 1: decryption failed + */ +//int aes_ll_ccm_decryption(u8 *pkt, int master, ble_crypt_para_t *pd); + + +/** + * @brief this function is used to decrypt the aes_ccm value, version2 + * @param[in] pd - Reference structure leCryptCtrl_t + * @return 0: decryption succeeded; 1: decryption failed + */ +int aes_ll_ccm_decryption(llPhysChnPdu_t *pllPhysChnPdu, u8 role, u8 ll_type, ble_crypt_para_t *pd); + + + + + + diff --git a/b91/b91m_ble_sdk/algorithm/algorithm.h b/b91/b91m_ble_sdk/algorithm/algorithm.h new file mode 100755 index 0000000..71c9c83 --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/algorithm.h @@ -0,0 +1,37 @@ +/******************************************************************************************************** + * @file algorithm.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2021.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#ifndef ALGORITHM_H_ +#define ALGORITHM_H_ + +#include "algorithm/aes_ccm/aes_ccm.h" +#include "algorithm/crypto/crypto_alg.h" + + +#include "algorithm/ecc/ecc_ll.h" +#include "algorithm/ecc/hw_ecc.h" + +#include "algorithm/lc3/inc/lc3_enc.h" +#include "algorithm/lc3/inc/lc3_dec.h" + +#endif /* ALGORITHM_H_ */ diff --git a/b91/b91m_ble_sdk/algorithm/crypto/crypto_alg.h b/b91/b91m_ble_sdk/algorithm/crypto/crypto_alg.h new file mode 100755 index 0000000..fca51f1 --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/crypto/crypto_alg.h @@ -0,0 +1,166 @@ +/******************************************************************************************************** + * @file crypto_alg.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef CRYPTO_ALG_H_ +#define CRYPTO_ALG_H_ + + + + +/* + * @brief This function is used to generate the prand + * @param[out] prand - The out are stored in little endian format + * @return none + * */ +void blt_crypto_alg_prand(unsigned char prand[3]); + +/* + * @brief Resolvable Private Address Generation and Resolution + * @param[in] irk - The IRKs are stored in little endian format + * @param[in] r - The r are stored in little endian format + * @param[out] out - The out are stored in little endian format + * @return none + * */ +void blt_crypto_alg_ah(const unsigned char irk[16], unsigned char r[3], unsigned char out[3]); + +/** + * @brief This function is used to generate the confirm values + * @param[out] c1: the confirm value, little--endian. + * @param[in] key: aes key, little--endian. + * @param[in] r: the plaintext, little--endian. + * @param[in] pres: packet buffer2, little--endian. + * @param[in] preq: packet buffer2, little--endian. + * @param[in] iat: initiate address type + * @param[in] ia: initiate address, little--endian. + * @param[in] rat: response address type + * @param[in] ra: response address, little--endian. + * @return none. + * @Note Input data requires strict Word alignment + */ +void blt_crypto_alg_c1(unsigned char *c1, unsigned char key[16], unsigned char r[16], unsigned char pres[7], unsigned char preq[7], unsigned char iat, unsigned char ia[6], unsigned char rat, unsigned char ra[6]); + +/** + * @brief This function is used to generate the STK during the LE legacy pairing process. + * @param[out] *STK - the result of encrypt, little--endian. + * @param[in] *key - aes key, little--endian. + * @param[in] *r1 - the plaintext1, little--endian. + * @param[in] *r2 - the plaintext2, little--endian. + * @return none. + * @Note Input data requires strict Word alignment + */ +void blt_crypto_alg_s1(unsigned char *stk, unsigned char key[16], unsigned char r1[16], unsigned char r2[16]); + +/** + * @brief This function is used to compute confirm value by function f4 + * --- Ca: f4(U, V, X, Z) = AES-CMACX (U || V || Z) --- + * @param[out] r: the output of the confirm:128-bits, big--endian. + * @param[in] u: is the 256-bits, big--endian. + * @param[in] v: is the 256-bits, big--endian. + * @param[in] x: is the 128-bits, big--endian. + * @param[in] z: is the 8-bits + * @return none. + */ +void blt_crypto_alg_f4 (unsigned char *r, unsigned char u[32], unsigned char v[32], unsigned char x[16], unsigned char z); + +/** + * @brief This function is used to generate the numeric comparison values during authentication + * stage 1 of the LE Secure Connections pairing process by function g2 + * @param[in] u: is the 256-bits, big--endian. + * @param[in] v: is the 256-bits, big--endian. + * @param[in] x: is the 128-bits, big--endian. + * @param[in] y: is the 128-bits, big--endian. + * @return pincode value: 32-bits. + */ +unsigned int blt_crypto_alg_g2 (unsigned char u[32], unsigned char v[32], unsigned char x[16], unsigned char y[16]); + +/** + * @brief This function is used to generate derived keying material in order to create the LTK + * and keys for the commitment function f6 by function f5 + * @param[out] mac: the output of the MAC value:128-bits, big--endian. + * @param[out] ltk: the output of the LTK value:128-bits, big--endian. + * @param[in] w: is the 256-bits, big--endian. + * @param[in] n1: is the 128-bits, big--endian. + * @param[in] n2: is the 128-bits, big--endian. + * @param[in] a1: is the 56-bits, big--endian. + * @param[in] a2: is the 56-bits, big--endian. + * @return none. + */ +void blt_crypto_alg_f5 (unsigned char *mac, unsigned char *ltk, unsigned char w[32], unsigned char n1[16], unsigned char n2[16], + unsigned char a1[7], unsigned char a2[7]); + +/** + * @brief This function is used to generate check values during authentication stage 2 of the + * LE Secure Connections pairing process by function f6 + * @param[out] *e: the output of Ea or Eb:128-bits, big--endian. + * @param[in] w: is the 256-bits, big--endian. + * @param[in] n1: is the 128-bits, big--endian. + * @param[in] n2: is the 128-bits, big--endian. + * @param[in] a1: is the 56-bits, big--endian. + * @param[in] a2: is the 56-bits, big--endian. + * @return none. + */ +void blt_crypto_alg_f6 (unsigned char *e, unsigned char w[16], unsigned char n1[16], unsigned char n2[16], + unsigned char r[16], unsigned char iocap[3], unsigned char a1[7], unsigned char a2[7]); + +/** + * @brief This function is used to convert keys of a given size from one key type to another + * key type with equivalent strength + * @param[out] r: the output of h6:128-bits, big--endian. + * @param[in] w: is the 128-bits, big--endian. + * @param[in] keyid: is the 32-bits, big--endian. + * @return none. + */ +void blt_crypto_alg_h6 (unsigned char *r, unsigned char w[16], unsigned char keyid[4]); + + +/** + * @brief This function is used to convert keys of a given size from one key type to another + * key type with equivalent strength + * --- h7(SALT, W) = AES-CMACsalt(W) --- + * @param[out] r: the output of h7:128-bits, big--endian. + * @param[in] salt: is the 128-bits, big--endian. + * @param[in] w: is the 128-bits, big--endian. + * @return none. + */ +void blt_crypto_alg_h7 (unsigned char *r, unsigned char salt[16], unsigned char w[16]); + + +/** + * @brief This function is used to generate the Group Session Key (GSK) for encrypting or + * decrypting payloads of an encrypted BIS. + * --- h8(K, S, keyID) = AES-CMACik(keyID) --- + * @param[out] r: the output of h8:128-bits, big--endian. + * @param[in] k: is the 128-bits, big--endian. + * @param[in] s: is the 128-bits, big--endian. + * @param[in] keyid: is the 32-bits, big--endian. + * @return none. + */ +void blt_crypto_alg_h8 (unsigned char *r, unsigned char k[16], unsigned char s[16], unsigned char keyId[4]); + + + + +#endif /* CRYPTO_ALG_H_ */ + + + + diff --git a/b91/b91m_ble_sdk/algorithm/ecc/.gitignore b/b91/b91m_ble_sdk/algorithm/ecc/.gitignore new file mode 100755 index 0000000..cd812eb --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/ecc/.gitignore @@ -0,0 +1,8 @@ +__build__/ +__pycache__ +*.pyc +*.pyo +*.pyd +*.pyz +*.egg-info/ +.DS_Store \ No newline at end of file diff --git a/b91/b91m_ble_sdk/algorithm/ecc/ecc_curve.h b/b91/b91m_ble_sdk/algorithm/ecc/ecc_curve.h new file mode 100755 index 0000000..7bdc355 --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/ecc/ecc_curve.h @@ -0,0 +1,40 @@ +/******************************************************************************************************** + * @file ecc_ll.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#ifndef ECC_CURVE_H_ +#define ECC_CURVE_H_ + +/* Curve selection options */ +typedef enum{ +// ECC_use_secp160r1, + ECC_use_secp192r1, + ECC_use_secp224r1, + ECC_use_secp256r1, +// ECC_use_secp256k1, +}ecc_curve_t; + + + + + +#endif /* ECC_CURVE_H_ */ diff --git a/b91/b91m_ble_sdk/algorithm/ecc/ecc_ll.h b/b91/b91m_ble_sdk/algorithm/ecc/ecc_ll.h new file mode 100755 index 0000000..9272f8e --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/ecc/ecc_ll.h @@ -0,0 +1,69 @@ +/******************************************************************************************************** + * @file ecc_ll.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef ECC_LL_H_ +#define ECC_LL_H_ + +#include "algorithm/ecc/ecc_curve.h" + +extern const u8 blt_ecc_dbg_priv_key192[24]; +extern const u8 blt_ecc_dbg_pub_key192[48]; + +extern const u8 blt_ecc_dbg_priv_key256[32]; +extern const u8 blt_ecc_dbg_pub_key256[64]; + + +/** +* @brief This function is used to register the random number function needed for ECC calculation +* @param none +* @return none +*/ +void blt_ecc_init(void); + +/** +* @brief This function is used to generate an ECDH public-private key pairs +* @param[out] pub[64]: output ecdh public key +* @param[out] priv[64]: output ecdh private key +* @param[in] use_dbg_key: 0: Non-debug key , others: debug key +* @return 1: success +* 0: failure +*/ +int blt_ecc_gen_key_pair(unsigned char *pub, unsigned char *priv, ecc_curve_t curve, bool use_dbg_key); + +/** +* @brief This function is used to calculate DHKEY based on the peer public key and own private key +* @param[in] peer_pub_key[64]: peer public key +* @param[in] own_priv_key[32]: own private key +* @param[out] out_dhkey[32]: dhkey key +* @return 1: success +* 0: failure +*/ +int blt_ecc_gen_dhkey(const unsigned char *peer_pub, const unsigned char *own_priv, unsigned char *out_dhkey, ecc_curve_t curve); + + + + +#endif /* ECC_LL_H_ */ + + + + diff --git a/b91/b91m_ble_sdk/algorithm/ecc/hw_ecc.h b/b91/b91m_ble_sdk/algorithm/ecc/hw_ecc.h new file mode 100755 index 0000000..7a02597 --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/ecc/hw_ecc.h @@ -0,0 +1,77 @@ +/******************************************************************************************************** + * @file hw_ecc.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef HW_ECC_H_ +#define HW_ECC_H_ + +#include "algorithm/ecc/hw_ecc.h" +#include "algorithm/ecc/ecc_curve.h" + +#if ( (MCU_CORE_TYPE == MCU_CORE_827x) || (MCU_CORE_TYPE == MCU_CORE_9518) ) + +/* hECC_RNG_Function type +The RNG function should fill 'size' random bytes into 'dest'. It should return 1 if +'dest' was filled with random data, or 0 if the random data could not be generated. +The filled-in values should be either truly random, or from a cryptographically-secure PRNG. +A correctly functioning RNG function must be set (using hECC_set_rng()) before calling +hECC_make_key(). */ + +typedef int (*hECC_rng_func)(unsigned char *dest, unsigned size); + + +/** + * @brief The function that will be used to generate random bytes. + * @param[in] resister predefined TRNG function + * @return none + */ +void hwECC_set_rng(hECC_rng_func rng_func); + + +/** + * @brief get ECCP key pair(the key pair could be used in ECDH). + * @param[out] public_key - public key, big--endian. + * @param[out] private_key - private key, big--endian. + * @param[in] curve_sel - ecc_curve select, e.g.: p-256r1. + * @return 1(success), 0(error). + */ +unsigned char hwECC_make_key(unsigned char *public_key, unsigned char *private_key, ecc_curve_t curve_sel); + + +/** + * @brief ECDH compute key. + * @param[in] local_prikey - local private key, big--endian. + * @param[in] public_key - peer public key, big--endian. + * @param[out] dhkey - output dhkey, big--endian. + * @param[in] curve_sel - ecc_curve select, e.g.: p-256r1. + * @Return 1(success); 0(error). + */ +unsigned char hwECC_shared_secret(const unsigned char *public_key, const unsigned char *private_key, + unsigned char *secret, ecc_curve_t curve_sel); + + + + +#endif /* HW_ECC_H_ */ + +#endif /* The end of #if((MCU_CORE_TYPE == MCU_CORE_827x) || (MCU_CORE_TYPE == MCU_CORE_9518)) */ + + diff --git a/b91/b91m_ble_sdk/algorithm/lc3/inc/config.h b/b91/b91m_ble_sdk/algorithm/lc3/inc/config.h new file mode 100755 index 0000000..4728a46 --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/inc/config.h @@ -0,0 +1,33 @@ +#ifndef _CONFIG_H +#define _CONFIG_H + +#if (LE_AUDIO_ENABLE) +#define ALG_LC3_ENABLE 1 +#define ANDES_INTRINSIC +#endif + +#if (ALG_LC3_ENABLE) +#define FIXED_POINT 32 +#define DISABLE_LTPF 0 +//#define LC3_16K_ONLY +//#define DUMP_IMTERMEDIATE +//#define USE_SPREAD_FFT +//#define ANDES_PROFILE +//#define ANDES_INTRINSIC +//#define EN_SPEC_INTERMEDIATE + +#ifdef ANDES_INTRINSIC +#undef DUMP_IMTERMEDIATE +#define ANDES_DSPLIB_MAX +#define ANDES_DSPLIB_DPROD +#endif +#define Errata_ID_15041 +//#define KNOWN_ISSUE +//#define KNOWN_ISSUE_NC +//#define OLD_HEADER + + +#endif + +#endif // !CONFIG_H + diff --git a/b91/b91m_ble_sdk/algorithm/lc3/inc/lc3_common.h b/b91/b91m_ble_sdk/algorithm/lc3/inc/lc3_common.h new file mode 100755 index 0000000..cef589f --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/inc/lc3_common.h @@ -0,0 +1,55 @@ +#ifndef _LC3_COMMON_H +#define _LC3_COMMON_H + +#include "config.h" + +#if (ALG_LC3_ENABLE) + +#define LC3_MODE_10MS (0) +#define LC3_MODE_75MS (1) + +#define LC3_MAX_CHANNELS (2) +#define LC3_MAX_SAMPLES (480) +#define LC3_MAX_FRAME_SIZE (870) + +#ifdef LC3_16K_ONLY +#define LC3_MAX_NF (160) +#define LC3_MAX_NE (160) +#else +#define LC3_MAX_NF (480) +#define LC3_MAX_NE (400) +#endif + +#if LC3_MAX_NF==480 +#define LC3_MAX_INPUT_DELAY 60 +#elif LC3_MAX_NF==320 +#define LC3_MAX_INPUT_DELAY 40 +#elif LC3_MAX_NF==240 +#define LC3_MAX_INPUT_DELAY 30 +#elif LC3_MAX_NF==160 +#define LC3_MAX_INPUT_DELAY 20 +#else +#define LC3_MAX_INPUT_DELAY 10 +#endif // LC3_MAX_NF==480 + + +#define L_NUM_MAX (11) +#define L_DEN_MAX (13) +#define P_INT_MAX (228) +#define LTPF_MEM_MAX (P_INT_MAX * LC3_MAX_NF / 128 + (L_DEN_MAX + 1) / 2) + +typedef enum { + LC3_PARA_FRAMESIZE = 0, + LC3_PARA_OUTSIZE, + LC3_PARA_CHANNELS, + LC3_PARA_SAMPLERATE, + LC3_PARA_BITRATE, + LC3_PARA_SAMPLES, + LC3_PARA_DELAY, + LC3_PARA_END +} LC3_PARAMETER; + + +#endif + +#endif diff --git a/b91/b91m_ble_sdk/algorithm/lc3/inc/lc3_dec.h b/b91/b91m_ble_sdk/algorithm/lc3/inc/lc3_dec.h new file mode 100755 index 0000000..f2c0990 --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/inc/lc3_dec.h @@ -0,0 +1,107 @@ +#ifndef _LC3_DEC_H +#define _LC3_DEC_H + +#include "lc3_types.h" +#include "lc3_common.h" +#include "config.h" + +#if (ALG_LC3_ENABLE) + +#include "../src/fft_lib/_kiss_fft_guts.h" // FIXME +#include "../src/fft_lib/kiss_fft_custom/kiss_fft_custom.h" +/*! LC3 decoder error codes. */ +typedef enum +{ + LC3DEC_OK = 0, + LC3DEC_ERROR_GETPARA = 1, + LC3DEC_ERROR_INIT, + LC3DEC_ERROR_SHAPE, + LC3DEC_ERROR_SETPARA, + LC3DEC_ERROR_BITSTREAM, + LC3DEC_ERROR_ARITHMATIC, +} LC3DEC_Error; + +typedef struct LC3_DEC +{ + Word32 nSamplerate; + Word32 nBitrate; + Word32 nChannels; + Word16 NF; + Word16 NE; + Word16 Nb; + Word16 Nms; // 20 ->10ms,15->7.5ms + Word16 Nms_mode; // 0->10ms,1->7.5ms + Word16 Z; + /* Bandwidth detector */ + Word16 nBitsBw; + Word16 nFsIdx; + /* side infor */ + Word16 nPbw; + Word16 lastnz; + Word16 lsbMode; + Word16 gg_ind; // used in global_gain + Word16 num_tns_filters; // used in tns decoder + Word16 rc_order[2]; // tns + Word16 rc_i[8][2]; // tns + Word16 ind_LF; // sns + Word16 ind_HF; // sns + Word16 shape_j; // sns + Word16 gain_i; // sns + Word32 idxA; // sns + Word32 idxB; // sns + Word16 LS_indA; // sns + Word16 LS_indB; // sns + Word16 pitch_present; // ltpf + Word16 ltpf_active; // ltpf + Word16 pitch_index; // ltpf + Word16 p_int; // ltpf + Word16 p_fr; // ltpf + Word16 mem_ltpf_active; // ltpf + Word16 mem_p_int; // ltpf + Word16 mem_p_fr; // ltpf + Word16 F_NF; + /* bitstream pointer */ + Word16 bp_side; + Word16 mask_side; + /* noise filling */ + Word16 zeroFrameFlag; + Word32 nf_seed; + /* imdct */ + // kiss_fft_cfg kiss_fft_state; + kiss_fft_state16_ptr kiss_fft_state; + Word16* mdct_twiddle; + Word16* mdct_sin_twiddle; + Word16 sin_step; + const Word16* W_MDCT; + Word16 W_size; + /* plc */ + Word32 plc_seed; +#ifdef FIXED_POINT + Word32* mem_imdct; + Word32* mem_plc_buf; + Word32* mem_x; + Word32* mem_x_ltpf; + Word16* mem_c_num; + Word16* mem_c_den; +#else + double* mem_imdct; + double* mem_plc_buf; + double* mem_x; + double* mem_x_ltpf; + double* mem_c_num; + double* mem_c_den; +#endif + /* plc */ + Word16 bec_detect; +} LC3_DEC_STRU; + +LC3DEC_Error lc3dec_init(LC3_DEC_STRU* dec, Word32 samplerate, Word32 bitrate, Word16 channels, Word16 Nms_mode); +LC3DEC_Error lc3dec_decode_frame(LC3_DEC_STRU* dec, UWord8* inbuf, UWord32 inlen, Word16* outbuf); +LC3DEC_Error lc3dec_get_parameter(LC3_DEC_STRU* dec, LC3_PARAMETER para, Word32* val); +LC3DEC_Error lc3dec_set_parameter(LC3_DEC_STRU* dec, LC3_PARAMETER para, Word32* val); +LC3DEC_Error lc3dec_free(LC3_DEC_STRU* dec); + + +#endif + +#endif diff --git a/b91/b91m_ble_sdk/algorithm/lc3/inc/lc3_enc.h b/b91/b91m_ble_sdk/algorithm/lc3/inc/lc3_enc.h new file mode 100755 index 0000000..664c0bd --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/inc/lc3_enc.h @@ -0,0 +1,141 @@ +#ifndef _LC3_ENC_H +#define _LC3_ENC_H + +#include "lc3_types.h" +#include "lc3_common.h" +#include "config.h" + +#if (ALG_LC3_ENABLE) + +#include "../src/fft_lib/_kiss_fft_guts.h" +#include "../src/fft_lib/kiss_fft_custom/kiss_fft_custom.h" +#ifdef ANDES_INTRINSIC +#include "nds_filtering_math.h" +#endif // DEBUG + + +//#define EN_SPEC_INTERMEDIATE +/*! LC3 encoder error codes. */ +typedef enum +{ + LC3ENC_OK = 0, + LC3ENC_ERROR_INIT = 1, + LC3ENC_ERROR_GETPARA, + LC3ENC_ERROR_SETPARA +} LC3ENC_Error; + + +typedef struct LC3_ENC +{ +#ifndef FIXED_POINT + // Spectral quantization + double nbits_offset_old; + Word32 nbits_spec_old; + Word32 nbits_est_old; + Word32 reset_offset_old; + // LTPF + double stage1; + double stage2; + Word32 len_12k8; + Word32 D_LTPF; + double* x_12k8_HP_last; // input data of last frame + double* x_12k8_HP_D_last; // + double* x_i_fr_last; + double* x_6k4_last; + Word16 T_prev; // pirch_lag estimated in previous frame + Word16 mem_ltpf_active; + double mem_nc; + double mem_mem_nc; + Word16 mem_pitch; + // att + double A_att_last; + double E_att_last; + Word32 P_att_last; + double* x_att_last; + // BW + Word16 nbits_bw; + // mdct + double* W_MDCT; + Word16 W_size; + Word16 Nb; // number of bands +#else + + /* mdct */ + //kiss_fft_cfg kiss_fft_state; + kiss_fft_state16_ptr kiss_fft_state; + const Word16* mdct_twiddle; + const Word16* mdct_sin_twiddle; + Word16 sin_step; + const Word16* W_MDCT; + Word16 W_size; + Word16 Nb; // number of bands + + /* bw detector */ + Word16 nbits_bw; + + /* attack detector */ + Word16 M_F; + Word16 m_stop; + Word16 att_scaling; + Word16 x_att_last[2]; + Word32 A_att_last; + Word32 E_att_last; + Word32 P_att_last; + /* tns */ + Word32 nn_idx; + /* ltpf */ +#if 0 + nds_bq_df1_q15_t ltpf_highpass_q15; +#endif // ANDES_INTRINSIC + Word16 ltpf_enable; + Word32 len_12k8; + Word32 D_LTPF; + Word32 stage1; + Word32 stage2; + Word16 x_12k8_last[128]; // x_12k8 of last frame + Word16 x_12k8_D_buf[232+130]; //x_12k8_D_buf[232] is x_12k8_D[0] + Word16 x_12k8_D_last_exp; + Word16 x_12k8_D_last_3[3]; + Word16 x_6k4_last[114+64]; + Word16 x_6k4_last_exp; + Word32 T_prev; // pirch_lag estimated in previous frame + Word16 mem_ltpf_active; + Word16 mem_nc; + Word16 mem_mem_nc; + Word16 mem_pitch; + + /* Spectral quantization */ + Word32 nbits_offset_old; + Word16 nbits_spec_old; + Word16 nbits_est_old; + Word32 reset_offset_old; + Word16 gg_off; + Word16 nbits_ari; +#endif // !FIXED_POINT + /* overall */ + Word32 frame_counter; + Word32 fs; // sample rate + Word16 fs_ind; // index of fs + Word16 channelNum; //channal number + Word32 bitrate; // bit rate + Word16 NF; // sample number of one frame + Word16 NE; // frequency number of one frame + Word16 Nms_mode;// 0->10ms,1->7.5ms + Word16 Nms; // 20 ->10ms,15->7.5ms + Word16 nbytes; // bytes of one frame + Word32 nbits; // bits of one frame + Word16 input_last[LC3_MAX_NF]; // input data of last frame + +} LC3_ENC_STRU; + +LC3ENC_Error lc3enc_init(LC3_ENC_STRU* enc, Word32 nSamplerate, Word16 nChannels, Word32 nBitrate,int nMs_mode); +LC3ENC_Error lc3enc_encode_frame(LC3_ENC_STRU* enc, Word16* input, UWord8* output); +LC3ENC_Error lc3enc_get_parameter(LC3_ENC_STRU* enc, LC3_PARAMETER para, Word32* val); +LC3ENC_Error lc3enc_set_parameter(LC3_ENC_STRU* enc, LC3_PARAMETER para, Word32* val); +LC3ENC_Error lc3enc_change_bitrate(LC3_ENC_STRU* enc, Word32 bitrate); +LC3ENC_Error lc3enc_free(LC3_ENC_STRU* enc); + + +#endif + +#endif diff --git a/b91/b91m_ble_sdk/algorithm/lc3/inc/lc3_types.h b/b91/b91m_ble_sdk/algorithm/lc3/inc/lc3_types.h new file mode 100755 index 0000000..8a57a76 --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/inc/lc3_types.h @@ -0,0 +1,68 @@ +#ifndef _LC3_TYPES_H +#define _LC3_TYPES_H + +#include "config.h" + +#ifndef ANDES_INTRINSIC +typedef char Word8; +typedef short Word16; +typedef int Word32; +typedef long long Word64; + +typedef unsigned char UWord8; +typedef unsigned short UWord16; +typedef unsigned int UWord32; +#else +#include +typedef int8_t Word8; +typedef int16_t Word16; +typedef int32_t Word32; +typedef int64_t Word64; + +typedef uint8_t UWord8; +typedef uint16_t UWord16; +typedef uint32_t UWord32; +#endif +typedef struct { + Word16 r; + Word16 i; +}lc3_cpx; + +typedef struct { + Word32 r; + Word32 i; +}kiss_fft_cpx; + +struct kiss_fft_state { + int nfft; + int inverse; + int factors[2 * 32]; // 32->MAXFACTORS + kiss_fft_cpx twiddles[1]; +}; + +typedef struct kiss_fft_state* kiss_fft_cfg; +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX_32 +#define MAX_32 (0x7fffffffL) +#endif // !MAX_32 + +#ifndef MIN_32 +#define MIN_32 (0x80000000L) +#endif // !MIN_32 + +#ifndef MAX_16 +#define MAX_16 (32767) +#endif + +#ifndef MIN_16 +#define MIN_16 (-32768) +#endif + +#endif diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/arithmatic_decoder.h b/b91/b91m_ble_sdk/algorithm/lc3/src/arithmatic_decoder.h new file mode 100755 index 0000000..80b97d4 --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/arithmatic_decoder.h @@ -0,0 +1,21 @@ +#ifndef _ARITHMATIC_DECODER_H +#define _ARITHMATIC_DECODER_H + +#include "../inc/lc3_dec.h" +#include "constant.h" + +#if (ALG_LC3_ENABLE) + + +typedef struct { + Word32 low; + Word32 range; +} ST_STRU; + +LC3DEC_Error dec_arithmatic(LC3_DEC_STRU* dec, UWord8* inbuf, UWord32 inlen, + Word16* X_q, Word16* resBits, Word16* pBitsResidual); + + +#endif //#if (ALG_LC3_ENABLE) + +#endif diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/basic_op.h b/b91/b91m_ble_sdk/algorithm/lc3/src/basic_op.h new file mode 100755 index 0000000..a4d774c --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/basic_op.h @@ -0,0 +1,223 @@ +#ifndef BASIC_OP_H +#define BASIC_OP_H + +#include "../inc/lc3_types.h" +#include "constant.h" + +#if (ALG_LC3_ENABLE) + +/* short logical shift */ +//Word16 lshr(Word16 var1, Word16 var2); +/* int shift*/ +//Word32 L_shl(Word32 L_var1, Word16 var2); +//Word32 L_shr(Word32 L_var1, Word16 var2); +/* short shift*/ +Word16 shr(Word16 var1, Word16 var2); +Word16 shl(Word16 var1, Word16 var2); +/* short shift and rounding*/ +Word16 shr_r(Word16 var1, Word16 var2); + +/* if x==0 return 0 */ +Word16 getScaleFactor16(Word16* x, Word16 len); +/* if x==0 return 16 */ +Word16 getScaleFactor16_0(Word16* x, Word16 len); +Word16 getScaleWord32(Word32* x, Word16 len); +/* if x==0 return 32 */ +Word16 getScaleFactor32_0(Word32* x, Word16 len); +Word32 Norm32Norm(const Word32* x, Word16 shift, const Word16 length, Word16* result_e); + +/* log2 */ +inline Word16 BASOP_Util_Log2_16(Word32 x, Word16 x_e) +{ + Word16 shift, tmp1, tmp2; + Word16 outInt, outFrac, out; + + if (x == 0) + { + return (MIN_16); + } + + /* Scale Input */ + shift = clrs32(x); + + x = L_shl(x, (shift - 10)); + + /* Integer part */ + outInt = ((x_e - shift - 1) << 9); + + /* Fractional part */ + + tmp1 = mac_r(x, -33, 16384); + tmp2 = lshr((Word16)(x) , 6); + outFrac = mac_r(Log2_16_table1[tmp1], Log2_16_table2[tmp1], tmp2); + + /* Output */ + out = (outInt + outFrac); + + return out; +} + +inline Word32 BASOP_Util_Log2(Word32 x) +{ + Word32 exp; + Word16 exp_e; + Word16 nIn; + Word16 accuSqr; + Word32 accuRes; + + /* x never == 0 + if (x == 0) + { + return ((Word32)MIN_32); + } + */ + /* normalize input, calculate integer part */ + exp_e = clrs32(x); + x = L_shl(x, exp_e); + exp =(Word32) (exp_e); + + /* calculate (1-normalized_input) */ + nIn = ((MAX_32 - x))>>16; + + /* approximate ln() for fractional part (nIn *c0 + nIn^2*c1 + nIn^3*c2 + ... + nIn^8 *c7) */ + + /* iteration 1, no need for accumulation */ + accuRes = L_mult(nIn, ldCoeff[0]); /* nIn^i * coeff[0] */ + accuSqr = mult_16(nIn, nIn); /* nIn^2, nIn^3 .... */ + + /* iteration 2 */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff[1]); /* nIn^i * coeff[1] */ + accuSqr = mult_16(accuSqr, nIn); /* nIn^2, nIn^3 .... */ + + /* iteration 3 */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff[2]); /* nIn^i * coeff[2] */ + accuSqr = mult_16(accuSqr, nIn); /* nIn^2, nIn^3 .... */ + + /* iteration 4 */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff[3]); /* nIn^i * coeff[3] */ + accuSqr = mult_16(accuSqr, nIn); /* nIn^2, nIn^3 .... */ + + /* iteration 5 */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff[4]); /* nIn^i * coeff[4] */ + accuSqr = mult_16(accuSqr, nIn); /* nIn^2, nIn^3 .... */ + + /* iteration 6 */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff[5]); /* nIn^i * coeff[5] */ + accuSqr = mult_16(accuSqr, nIn); /* nIn^2, nIn^3 .... */ + + /* iteration 7, no need to calculate accuSqr any more */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff[6]); /* nIn^i * coeff[6] */ + + /* ld(fractional part) = ln(fractional part)/ln(2), 1/ln(2) = (1 + 0.44269504) */ + accuRes = (L_shr(accuRes, 1) + mult_16_16_32( (accuRes)>>16, 14506)); + + accuRes = L_shr(accuRes, 6 - 1); /* fractional part/LD_DATA_SCALE =6 */ + exp = L_shl(exp, (31 - 6)); /* integer part/LD_DATA_SCALE */ + accuRes = (accuRes - exp); /* result = integer part + fractional part */ + + return (accuRes); +} + +Word32 BASOP_Util_InvLog2(Word32 x); +Word16 Inv16(Word16 mantissa, Word16* exponent); +Word16 BASOP_Util_Divide3216_Scale(Word32 x,Word16 y,Word16* s); +Word16 BASOP_Util_Divide1616_Scale(Word16 x, Word16 y, Word16* s); + +void Mpy_32_16_ss(Word32 L_var1, Word16 var2, Word32* L_varout_h, UWord16* varout_l); + +Word32 Mpy_32_16(Word32 x, Word16 y); +Word16 div_s(Word16 var1, Word16 var2); + +#ifdef USE_SPREAD_FFT + + +void Mpy_32_32_ss(Word32 L_var1, Word32 L_var2, Word32* L_varout_h, UWord32* L_varout_l); +Word32 Mpy_32_32(Word32 x, Word32 y); + +#define SHC(x) ((Word16)x) +#define shr_pos shr +#define shl_pos shl +#define L_shr_pos L_shr +#define L_shl_pos L_shl +#define SCALEFACTORN2 (3) +#define SCALEFACTOR5 (4) +#define SCALEFACTOR6 (4) +#define SCALEFACTOR8 (4) +#define SCALEFACTOR10 (5) +#define SCALEFACTOR15 (5) +#define SCALEFACTOR30_1 (5) +#define SCALEFACTOR30_2 (1) +#define Mpy_32_xx mult_32_Q15_32 +#define SCALEFACTOR20 (5) + +#define WORD32_BITS 32 +#define WORD16_BITS 16 + +#define WORD322WORD16(val) \ + ((((((val) >> (WORD32_BITS - WORD16_BITS - 1)) + 1) > (((long)1 << WORD16_BITS) - 1)) && ((long)(val) > 0)) \ + ? (Word16)(short)(((long)1 << (WORD16_BITS - 1)) - 1) \ + : (Word16)(short)((((val) >> (WORD32_BITS - WORD16_BITS - 1)) + 1) >> 1)) + +#define FFTC(x) WORD322WORD16((Word32)x) + +#define C31 (FFTC(0x91261468)) /* FL2WORD32( -0.86602540) -sqrt(3)/2 */ +#define C31_32 0x91261468 +#define C51 (FFTC(0x79bc3854)) /* FL2WORD32( 0.95105652) */ +#define C52 (FFTC(0x9d839db0)) /* FL2WORD32(-1.53884180/2) */ +#define C53 (FFTC(0xd18053ce)) /* FL2WORD32(-0.36327126) */ +#define C54 (FFTC(0x478dde64)) /* FL2WORD32( 0.55901699) */ +#define C55 (FFTC(0xb0000001)) /* FL2WORD32(-1.25/2) */ +#define C81 (FFTC(0x5a82799a)) /* FL2WORD32( 7.071067811865475e-1) */ +#define C82 (FFTC(0xa57d8666)) /* FL2WORD32(-7.071067811865475e-1) */ +#define C51_32 (0x79bc3854) /* FL2WORD32( 0.95105652) */ +#define C52_32 (0x9d839db0) /* FL2WORD32(-1.53884180/2) */ +#define C53_32 (0xd18053ce) /* FL2WORD32(-0.36327126) */ +#define C54_32 (0x478dde64) /* FL2WORD32( 0.55901699) */ +#define C55_32 (0xb0000001) /* FL2WORD32(-1.25/2) */ +#define C81_32 (0x5a82799a) /* FL2WORD32( 7.071067811865475e-1) */ +#define C82_32 (0xa57d8666) /* FL2WORD32(-7.071067811865475e-1) */ + +#define cplxMpy4_8_0(re, im, a, b, c, d) \ + do \ + { \ + re = L_shr(L_sub(Mpy_32_xx(a, c), Mpy_32_xx(b, d)), 1); \ + im = L_shr(L_add(Mpy_32_xx(a, d), Mpy_32_xx(b, c)), 1); \ + } while (0) + + +#define cplxMpy4_8_1(re, im, a, b) \ + do \ + { \ + re = L_shr(a, 1); \ + im = L_shr(b, 1); \ + } while (0) + + +#define cplxMpy4_8_2(re, im, a, b, c, d) \ + do \ + { \ + re = L_shr(L_add(Mpy_32_32(a, c), Mpy_32_32(b, d)), 1); \ + im = L_shr(L_sub(Mpy_32_32(b, c), Mpy_32_32(a, d)), 1); \ + } while (0) + + +#define cplxMpy4_12_0(re, im, a, b, c, d) \ + do \ + { \ + re = L_sub(Mpy_32_xx(a, c), Mpy_32_xx(b, d)); \ + im = L_add(Mpy_32_xx(a, d), Mpy_32_xx(b, c)); \ + } while (0) + +#define cplxMpy4_12_1(re, im, a, b) \ + do \ + { \ + re = a; \ + im = b; \ + } while (0) +#endif + +#endif //#if (ALG_LC3_ENABLE) + +#endif // !BASIC_OP_H + +#pragma once diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/bitstream_decoder.h b/b91/b91m_ble_sdk/algorithm/lc3/src/bitstream_decoder.h new file mode 100755 index 0000000..989fa6a --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/bitstream_decoder.h @@ -0,0 +1,12 @@ +#ifndef _BITSTREAM_DECODER_H +#define _BITSTREAM_DECODER_H + +#include "../inc/lc3_dec.h" + +#if (ALG_LC3_ENABLE) + +LC3DEC_Error dec_bitstream(LC3_DEC_STRU* dec, UWord8* inbuf, UWord32 inlen); + +#endif + +#endif diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/common_func.h b/b91/b91m_ble_sdk/algorithm/lc3/src/common_func.h new file mode 100755 index 0000000..ebdaf28 --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/common_func.h @@ -0,0 +1,44 @@ +#ifndef _COMMON_FUNC_H +#define _COMMON_FUNC_H + +#include "../inc/lc3_dec.h" + +#if (ALG_LC3_ENABLE) + +#ifdef ANDES_INTRINSIC +#include "nds_basic_math.h" +#include "nds_utils_math.h" +#include "nds_filtering_math.h" +#include "nds_statistics_math.h" +#endif +#ifdef FIXED_POINT +void idct_fix(const Word16* in, Word16* out); +void dct_fix(const Word16* in, Word16* out); +Word16 pow2_16(Word16 x, Word16* y_e); +Word32 Isqrt(Word32 x, /* mantissa */ + Word16* x_e /* pointer to exponent */ +); +#else +void dct( + double* x, // i: input + double* y // o: dct output +); + +void idct( + double* x, // i:input + double* y // o:idct output +); + +#endif + +void duplicate_q15(Word16* src, Word16* dst, Word32 size); +void duplicate_q31(Word32* src, Word32* dst, Word32 size); +void shift_q15(Word16 x[], /* i/o: signal to scale Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ +); +void set_q31(Word32 val, Word32* dst, Word32 size); + +#endif //#if (ALG_LC3_ENABLE) + +#endif diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/constant.h b/b91/b91m_ble_sdk/algorithm/lc3/src/constant.h new file mode 100755 index 0000000..c88f145 --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/constant.h @@ -0,0 +1,369 @@ +#ifndef _CONSTANT_H +#define _CONSTANT_H + +#include "../inc/lc3_types.h" +#include "../inc/config.h" + +#if (ALG_LC3_ENABLE) + +#define PI 3.1415926 + +extern int Nms[2]; +/* mdct */ +#ifndef FIXED_POINT +/* W_10ms_NF for MDCT*/ +extern double w_0_N80[130]; +extern double w_0_N160[260]; +extern double w_0_N240[390]; +extern double w_0_N320[520]; +extern double w_0_N480[780]; +/* W_7.5ms_NF for MDCT*/ +extern double w_1_N60[106]; +extern double w_1_N120[212]; +extern double w_1_N180[318]; +extern double w_1_N240[424]; +extern double w_1_N360[636]; +extern double * w_Nms_NF_all[2][5]; +#else +#ifdef USE_SPREAD_FFT +extern Word32 RotVector_40_32[2 * 28]; +#ifndef LC3_16K_ONLY +extern Word16 RotVector_240[2 * (240 - 30)]; +extern Word16 RotVector_150[150]; +#endif +extern Word16 RotVector_160[2 * (160 - 20)]; +//extern Word16 RotVector_120[2 * (120 - 20)]; +//extern Word16 RotVector_100[100]; +extern Word16 RotVector_330[330]; +//extern Word16 RotVector_220[220]; +#endif +/* W_10ms_NF for MDCT*/ +extern Word16 w_0_N80[130]; +extern Word16 w_0_N160[260]; +#ifndef LC3_16K_ONLY +extern Word16 w_0_N240[390]; +extern Word16 w_0_N320[520]; +extern Word16 w_0_N480[780]; +#endif +/* W_7.5ms_NF for MDCT*/ +extern Word16 w_1_N60[106]; +extern Word16 w_1_N120[212]; +#ifndef LC3_16K_ONLY +extern Word16 w_1_N180[318]; +extern Word16 w_1_N240[424]; +extern Word16 w_1_N360[636]; +#endif +#ifndef LC3_16K_ONLY +extern Word16* w_Nms_NF_all[2][5]; +#else +extern Word16* w_Nms_NF_all[2][2]; +#endif +/* 0x5a82799a*/ +#define TWIDDLE (0x5a82) + +/* twiddle for dct_IV */ +extern Word16 mdct_twiddle_0_N80[80]; +extern Word16 mdct_twiddle_0_N160[160]; +#ifndef LC3_16K_ONLY +extern Word16 mdct_twiddle_0_N240[240]; +extern Word16 mdct_twiddle_0_N320[320]; +extern Word16 mdct_twiddle_0_N480[480]; +#endif +extern Word16 mdct_twiddle_1_N60[60]; +extern Word16 mdct_twiddle_1_N120[120]; +#ifndef LC3_16K_ONLY +extern Word16 mdct_twiddle_1_N180[180]; +extern Word16 mdct_twiddle_1_N240[240]; +extern Word16 mdct_twiddle_1_N360[360]; +#endif +#ifndef LC3_16K_ONLY +extern Word16* mdct_twiddle_all[2][5]; +#else +extern Word16* mdct_twiddle_all[2][2]; +#endif +/* sin_twiddle for dct_IV*/ +extern Word16 mdct_sin_twiddle_161[]; +extern Word16 mdct_sin_twiddle_181[]; +extern Word16 mdct_sin_twiddle_241[]; + +/* sin_step for dct_IV */ +extern Word16 mdct_sin_step_all[5]; + +extern Word16 InvIntTable[32]; +#endif // !FIXED_PONIT +extern Word32 I_8000[65]; +extern Word32 I_16000[65]; +#ifndef LC3_16K_ONLY +extern Word32 I_24000[65]; +extern Word32 I_32000[65]; +extern Word32 I_48000[65]; +#endif +extern Word32 I_8000_7_5ms[61]; +extern Word32 I_16000_7_5ms[65]; +#ifndef LC3_16K_ONLY +extern Word32 I_24000_7_5ms[65]; +extern Word32 I_32000_7_5ms[65]; +extern Word32 I_48000_7_5ms[65]; +#endif +#ifndef LC3_16K_ONLY +extern Word32 * I_FS[2][5]; +#else +extern Word32* I_FS[2][2]; +#endif +extern Word16 bands_nrg_scale[32]; + +/* bw detector */ +extern Word32 Ibw_start_16000_10ms[4]; +extern Word32 Ibw_start_24000_10ms[4] ; +extern Word32 Ibw_start_32000_10ms[4] ; +extern Word32 Ibw_start_48000_10ms[4] ; +extern Word32 Ibw_start_16000_7_5ms[4] ; +extern Word32 Ibw_start_24000_7_5ms[4] ; +extern Word32 Ibw_start_32000_7_5ms[4] ; +extern Word32 Ibw_start_48000_7_5ms[4] ; +extern Word32* Ibw_start_all_10ms[4] ; +extern Word32* Ibw_start_all_7_5ms[4]; + +extern Word32 Ibw_stop_16000_10ms[4] ; +extern Word32 Ibw_stop_24000_10ms[4] ; +extern Word32 Ibw_stop_32000_10ms[4] ; +extern Word32 Ibw_stop_48000_10ms[4]; +extern Word32 Ibw_stop_16000_7_5ms[4] ; +extern Word32 Ibw_stop_24000_7_5ms[4]; +extern Word32 Ibw_stop_32000_7_5ms[4] ; +extern Word32 Ibw_stop_48000_7_5ms[4] ; +extern Word32* Ibw_stop_all_10ms[4] ; +extern Word32* Ibw_stop_all_7_5ms[4] ; + +extern Word32 L_10ms[4]; +extern Word32 L_7_5ms[4]; +extern Word16 bw_nbits_tab[5]; +extern Word32 BW_thresh_quiet[4] ; +extern Word16 BW_thresh_quiet_exp ; + +/* sns */ +extern Word16 g_tilt_8000[64]; +extern Word16 g_tilt_8000_e[64]; +extern Word16 g_tilt_16000[64]; +extern Word16 g_tilt_16000_e[64]; +#ifndef LC3_16K_ONLY +extern Word16 g_tilt_24000[64]; +extern Word16 g_tilt_24000_e[64]; +extern Word16 g_tilt_32000[64]; +extern Word16 g_tilt_32000_e[64]; +extern Word16 g_tilt_48000[64]; +extern Word16 g_tilt_48000_e[64]; +#endif +#ifndef LC3_16K_ONLY +extern Word16* g_tilt_all[5]; +extern Word16* g_tilt_all_e[5]; +#else +extern Word16* g_tilt_all[2]; +extern Word16* g_tilt_all_e[2]; +#endif +extern Word16 isqrt_Q16tab[1 + 64]; +extern Word32 ISqrtTable[32]; +extern Word16 ISqrtDiffTable[32]; +#ifdef FIXED_POINT +extern Word16 LFCB_fix[256]; +extern Word16 HFCB_fix[256]; +#else +extern double LFCB[256]; +extern double HFCB[256]; +#endif + +#ifdef FIXED_POINT +extern Word16 sns_vq_reg_adj_gains_fix[2]; +extern Word16 sns_vq_reg_lf_adj_gains_fix[4]; +extern Word16 sns_vq_near_adj_gains_fix[4]; +extern Word16 sns_vq_far_adj_gains_fix[8]; +extern Word16* sns_vq_adj_gains_fix[4]; +#else +extern double sns_vq_reg_adj_gains[2] ; +extern double sns_vq_reg_lf_adj_gains[4] ; +extern double sns_vq_near_adj_gains[4] ; +extern double sns_vq_far_adj_gains[8] ; +extern double* sns_vq_adj_gains[4]; +#endif + +extern Word32 sns_gainMSBbits[4] ; +extern Word32 sns_gainLSBbits[4] ; + +extern UWord32 MPVQ_offsets[16][11] ; +#ifndef FIXED_POINT +extern double D[256]; +#endif // !FIXED_POINT + + + +/* TNS */ +extern Word16 tns_sub_start_freq_NB_10ms[6]; +extern Word16 tns_sub_start_freq_WB_10ms[6]; +extern Word16 tns_sub_start_freq_SSWB_10ms[6]; +extern Word16 tns_sub_start_freq_SWB_10ms[6]; +extern Word16 tns_sub_start_freq_FB_10ms[6]; +extern Word16 tns_sub_start_freq_NB_7_5ms[6]; +extern Word16 tns_sub_start_freq_WB_7_5ms[6]; +extern Word16 tns_sub_start_freq_SSWB_7_5ms[6]; +extern Word16 tns_sub_start_freq_SWB_7_5ms[6]; +extern Word16 tns_sub_start_freq_FB_7_5ms[6]; +extern Word16 tns_sub_stop_freq_NB_10ms[6]; +extern Word16 tns_sub_stop_freq_WB_10ms[6]; +extern Word16 tns_sub_stop_freq_SSWB_10ms[6]; +extern Word16 tns_sub_stop_freq_SWB_10ms[6]; +extern Word16 tns_sub_stop_freq_FB_10ms[6]; + +extern Word16 tns_sub_stop_freq_NB_7_5ms[6]; +extern Word16 tns_sub_stop_freq_WB_7_5ms[6]; +extern Word16 tns_sub_stop_freq_SSWB_7_5ms[6]; +extern Word16 tns_sub_stop_freq_SWB_7_5ms[6]; +extern Word16 tns_sub_stop_freq_FB_7_5ms[6]; + +extern Word16* tns_sub_start_freq_all[2][5]; +extern Word16* tns_sub_stop_freq_all[2][5]; + +extern Word16 ac_tns_order_bits[2][8] ; +extern Word16 ac_tns_order_freq[2][8]; +extern Word16 ac_tns_order_cumfreq[2][8]; +extern Word16 ac_tns_coef_bits[8][17] ; +extern Word16 ac_tns_coef_freq[8][17] ; +extern Word16 ac_tns_coef_cumfreq[8][17] ; +extern Word32 tnsAcfWindow[8]; +extern Word16 tnsQuantThr[16]; +extern Word16 tnsQuantPts[17]; +/* Long Term Postfiltering*/ +extern Word16 resamp_params[5][4]; +#ifdef FIXED_POINT +/*extern Word16 tab_resamp_filter_8k_16k[239];// Q_16k = 15,Q_8k =14 +extern Word16 tab_resamp_filter_24k[239];//Q_24 = 15 +extern Word16 tab_resamp_filter_32k[239];//Q_32 = 15 +extern Word16 tab_resamp_filter_48k[239];//Q_48 = 15 +extern Word16* tab_resamp_filter_all[5];*/ +extern Word16 resamp_filt_8k[240]; +extern Word16 resamp_filt_16k[240]; +#ifndef LC3_16K_ONLY +extern Word16 resamp_filt_24k[240]; +extern Word16 resamp_filt_32k[240]; +extern Word16 resamp_filt_48k[240]; +#endif +#ifndef LC3_16K_ONLY +extern Word16* resamp_filts[5]; +#else +extern Word16* resamp_filts[2]; +#endif +extern Word16 ltpf_ac_interp_filt[7][9]; +extern Word16 inter_filter[5][4][12]; +#ifdef ANDES_INTRINSIC +extern Word16 inter_filter_i[3] ; +extern Word16 inter_filter_fr[5][4][4]; +#endif +extern Word16 inter_filter_shift[5]; +extern Word16 inter_filter_len[5]; +extern Word32 isqrt_table[128 + 2]; +extern Word16 highpass50_num[3]; +extern Word16 highpass50_den[2]; +#ifdef ANDES_INTRINSIC +extern Word16 highpass50[6]; +#endif // ANDES_INTRINSIC +extern Word16 DownSamp_h2[5]; //Q15 +extern Word16 R_6k4_corr_weighting[98]; +extern Word16 tab_ltpf_interp_R[31]; +#else +extern double tab_resamp_filter[239]; +extern double tab_ltpf_interp_R[31]; + +extern double h12k8_coef_4[240]; +extern double h12k8_coef_3[240]; +extern double h12k8_coef_2[240]; +extern double h12k8_coef_1[240]; +extern double h12k8_coef_0[240]; +extern double* h12k8_coef_all[5]; +extern double highpass50_num[3]; +extern double highpass50_den[2]; +extern double DownSamp_h2[5]; +extern double R_6k4_corr_weighting[98]; + +extern double tab_ltpf_interp_x12k8[15]; +#endif // FIXED_POINT + + +#define LTPF_K_MAX 114 +#define LTPF_K_MIN 17 +#ifdef FIXED_POINT +extern Word16 tab_ltpf_num_8000_fix[4 * 3]; +extern Word16 tab_ltpf_num_16000_fix[4 * 3]; +#ifndef LC3_16K_ONLY +extern Word16 tab_ltpf_num_24000_fix[4 * 5]; +extern Word16 tab_ltpf_num_32000_fix[4 * 7]; +extern Word16 tab_ltpf_num_48000_fix[4 * 11]; +#endif +#ifndef LC3_16K_ONLY +extern Word16* tab_ltpf_num_fix[5]; +#else +extern Word16* tab_ltpf_num_fix[2]; +#endif +extern Word16 tab_ltpf_den_8000_fix[4 * 5]; +extern Word16 tab_ltpf_den_16000_fix[4 * 5]; +#ifndef LC3_16K_ONLY +extern Word16 tab_ltpf_den_24000_fix[4 * 7]; +extern Word16 tab_ltpf_den_32000_fix[4 * 9]; +extern Word16 tab_ltpf_den_48000_fix[4 * 13]; +#endif +#ifndef LC3_16K_ONLY +extern Word16* tab_ltpf_den_fix[5]; +#else +extern Word16* tab_ltpf_den_fix[2]; +#endif +#else +extern double tab_ltpf_num_8000[4*3]; +extern double tab_ltpf_num_16000[4*3]; +extern double tab_ltpf_num_24000[4*5]; +extern double tab_ltpf_num_32000[4*7]; +extern double tab_ltpf_num_48000[4*11]; +extern double* tab_ltpf_num[5]; +extern double tab_ltpf_den_8000[4*5]; +extern double tab_ltpf_den_16000[4*5]; +extern double tab_ltpf_den_24000[4*7]; +extern double tab_ltpf_den_32000[4*9]; +extern double tab_ltpf_den_48000[4*13]; +extern double* tab_ltpf_den[5]; +#endif +extern Word16 tab_ltpf_num_len[5]; +extern Word16 tab_ltpf_den_len[5]; + +/* spectral data */ +#define NBITS_SNS 38 +#define NBITS_GAIN 8 +#define NBITS_NF 3 +extern UWord8 ac_spec_lookup[4096]; +extern Word16 ac_spec_cumfreq[64][17]; +extern Word16 ac_spec_freq[64][17]; +extern Word16 ac_spec_bits[64][17]; +extern Word16 Tab_esc_nb[4]; +extern Word32 global_gain_tab[28]; +extern Word16 global_gain_t1[5]; +extern Word16 global_gain_t2[5]; +extern Word16 global_gain_t3[5]; +extern Word16 global_gain_t4[5]; +extern Word16 global_gain_t5[5]; +/* noise estimation */ +extern Word16 bw_stop_10ms[5]; +extern Word16 bw_stop_7_5ms[5]; + +/* basic op */ +extern Word32 Log2_16_table1[16]; + +extern Word16 Log2_16_table2[16] ; +extern Word16 ldCoeff[7]; +/* table for 2^x */ +extern UWord32 exp2x_tab_long[32] ; +extern UWord32 exp2_tab_long[32] ; +extern UWord32 exp2w_tab_long[32]; +/* 1/x tables */ +extern Word32 InvTable[32]; +extern Word16 InvDiffTable[32]; + +#endif //#if (ALG_LC3_ENABLE) + +#endif // CONSTANT_H + diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/dump.h b/b91/b91m_ble_sdk/algorithm/lc3/src/dump.h new file mode 100755 index 0000000..4c3fe82 --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/dump.h @@ -0,0 +1,120 @@ + +#ifndef __DUMP_H__ +#define __DUMP_H__ + +#define DUMP_INPUT 0x1 +#define DUMP_MDCT 0x2; + +/* encoder part */ +#define FILE_MDCT "enc_mdct.txt" +#define FILE_ENERGY "enc_energy.txt" +#define FILE_BW_D "enc_bw_detector.txt" +#define FILE_SNS "enc_sns.txt" +#define FILE_SNS_SCF "enc_sns_scf.txt" +#define FILE_TNS_X_F "enc_tns_X_F_f.txt" + +/* decoder part */ +#define FILE_DEC_ARI "dec_arithmatic.txt" +#define FILE_DEC_RES "dec_residual.txt" +#define FILE_DEC_NF "dec_noisefilling.txt" +#define FILE_DEC_GG "dec_globalgain.txt" +#define FILE_DEC_TNS "dec_tns.txt" +#define FILE_DEC_SNS "dec_sns.txt" +#define FILE_DEC_IMDCT "dec_imdct.txt" +#define FILE_DEC_LTPF "dec_ltpf.txt" +#define FILE_DEC_SNS_SCF "dec_sns_scf.txt" +#define FILE_DEC_SNS_G_SNS "dec_sns_g_sns.txt" +#define FILE_LTPF_X_12k8_D "ltpf_x12k8_D.txt" + + +#define DUMP_FLAG (DUMP_MDCT) + +#define FILE_OPEN(fp, name) \ + fp = fopen(name, "w"); \ + if (fp == NULL) { \ + printf("failed to open %s\n", name); \ + return -1; \ + } + +int dump_open(); +void dump_close(); + +void dump_dec_arithmatic(short* in, int len); +void dump_dec_residual(int* in, short exponent, int len); +void dump_dec_residual_f(double* in, int len); +void dump_dec_noisefilling(int* in, short exponent, int len); +void dump_dec_noisefilling_f(double* in, int len); +void dump_dec_global_gain(int* in, short exponent, int len); +void dump_dec_global_gain_f(double* in, int len); +void dump_dec_tns(int* in, short exponent, int len); +void dump_dec_tns_f(double* in, int len); +void dump_dec_sns(int* in, short exponent, int len); +void dump_dec_sns_f(double* in, int len); +void dump_dec_sns_scf(short* inbuf, short exponent, short len); +void dump_dec_sns_scf_f(double* inbuf, short len); +void dump_dec_sns_g_sns(short* inbuf, short* exponent, short len); +void dump_dec_sns_g_sns_f(double* inbuf, short len); +void dump_dec_imdct1(int* inbuf, short exponent, short len); +void dump_dec_imdct(short* inbuf, short exponent, short len); +void dump_dec_imdct_f(double* inbuf, short len); +void dump_dec_ltpf(short* inbuf, short exponent, short len); +void dump_dec_ltpf1(int* inbuf, short exponent, short len); +void dump_dec_ltpf_f(double* inbuf, short len, short ltpf_active); +void dump_mdct(int* inbuf, short exponent, short len); +void dump_mdct_f(double* inbuf, short len); +void dump_energy(int* inbuf, short exponent, short len); +void dump_energy_f(double* inbuf, short len); +void dump_bw_detector(int bw_idx); +void dump_sns(int* inbuf, short exponent, short len); +void dump_sns_f(double* inbuf, short len); +void dump_sns_scf(short* inbuf, short exponent, short len); +void dump_sns_scf_f(double* inbuf, short len); +void dump_sns_index(int index_LF, int index_HF); +void dump_tns_X_F(int* inbuf, short exponent, short len); +void dump_tns_X_F_f(double* inbuf, short len); +void dump_sq_X_q_f(short* X_q, short len); +void dump_ltpf_x_tilde_12k8D_f(double* inbuf, short len); +void dump_ltpf_x_tilde_12k8D(short* input, short exponent, short len); +void dump_bw0(int bw0); +void dump_sns_shape_index(int shape_j); +void dump_sns_y(short* y0, short* y1, short* y2, short* y3); +void dump_sns_t2_rot(short* t2_rot, short len); +void dump_sns_t2_rot_f(double* t2_rot, short len); +void dump_sns_E_P(int* input, short* exponent, short len); +void dump_sns_E_4_f(double* E_4, short len); +void dump_sns_E_4(int* input, short* exponent, short len); +void dump_sns_r1_f(double* input, short len); +void dump_sns_r1(short* input, short len); +void dump_sns_scf_q(short* input, short exponent, short len); +void dump_sns_scf_q_f(double* input, short len); +void dump_sns_scf_q_int(short* input, short exponent, short len); +void dump_sns_scf_q_int_f(double* input, short len); +void dump_tns_nbits_tns(short input); +void dump_tns_tns_lpc_weighting(short input); +void dump_tns_rc_order(short* input, short len); +void dump_tns_rc_int(short* input, short len); +void dump_ltpf_active(short input); +void dump_ltpf_pitch_index(int input); +void dump_x_6k4(short* input, short exponent); +void dump_x_12k8_HP(short* input, short exponent, int len); +void dump_x_12k8_HP_f(double* input); +void dump_ltpf_nc_T_f(double input); +void dump_ltpf_nc_T(short input, short exponent); +void dump_side_information(char* input, int len); +void dump_mdct_input(int* input, short exponent, int len); +void dump_tda_x_hp(short* input, int len); +void dump_F_att(short input); +void dump_short_data(short input); +void dump_short_matric(short* input, int len); +void dump_int_data(int input); +void dump_int_matric(int* input, int len); +void dump_sq_X_q(short* input, int len); +void dump_res_bits(char* input, int len); +void dump_F_NF(short input); +void dump_output(char* input, int len); +void dump_pitch_present(int input); +void dump_ltpf_bits(int input); +void dump_ltpf_x6k4(short* input, int len); +void dump_mdct_output(int* input, short exponent, int len); +#endif + diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/encoder_function.h b/b91/b91m_ble_sdk/algorithm/lc3/src/encoder_function.h new file mode 100755 index 0000000..c6212e5 --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/encoder_function.h @@ -0,0 +1,116 @@ +#ifndef _ENCODER_FUNCTION_H +#define _ENCODER_FUNCIION_H +#include"../inc/lc3_enc.h" +#if (ALG_LC3_ENABLE) +#include +//#include +#include "fft_lib/_kiss_fft_guts.h" +#include"constant.h" +#include"../inc/config.h" +#include"intrinsic.h" +#include"dump.h" +#include"basic_op.h" +#include"common_func.h" +#ifndef FIXED_POINT + +void ld_mdct(LC3_ENC_STRU*enc,Word16 *input,double *X,double *E_B); + +void bw_detector(LC3_ENC_STRU* enc, double* E_B, Word16* Pbw); + +void tda_detector(LC3_ENC_STRU* enc, Word16* input, Word32* Fatt); + +void sns( + LC3_ENC_STRU* enc, // i + Word32 F_att, // i: attack flag + double* X, // i: frequancy data + double* E_B, // i: frequancy bands energy + double* X_S, // o: frequanct data after SNS + Word16* ind_LF, // o: codebook index for LF vector + Word16* ind_HF, // o: codebook index for HF vector + Word16* shape_j, // o: shape index for pyramid vector + Word32* PVQ_PARA // o: PVQ parameter +); + +void tns(LC3_ENC_STRU* enc, Word32 Pbw, double* X_S, Word16 num_tns_filter, Word16* rc_int, + Word16* rc_order, double* X_F, double* max_abs_X_F, Word16* nbits_TNS, Word16* tns_lpc_weighting); + + +void ltpf(LC3_ENC_STRU* enc, Word16* input, Word32* pitch_present, Word32* ltpf_active, Word32* pitch_index, Word16* nbits_LTPF); + +void spectral_quantization(LC3_ENC_STRU* enc, Word32 nbits_bw, Word32 nbits_TNS, Word32 nbits_LTPF, double* X_F, + double max_abs_X_F, Word16* X_q, Word32* nbits_spec, Word32* nbits_trunc, double* gg, Word16* gg_ind, Word16* lsbMode, Word16* lastnz_trunc, Word16* rateFlag); + +void residual_coding_encoder(LC3_ENC_STRU* enc, Word32 nbits_residual_max, Word16* X_q, + double* X_F, double gg, Word16* res_bits, Word32* nbits_residual); + +void noise_estimation_encoder(LC3_ENC_STRU* enc, Word16* X_q, Word32 Pbw, double* X_f, double gg, Word16* F_NF); + +void bitstream_encoder( + LC3_ENC_STRU* enc, // i + Word16 nbits_bw, Word16 P_bw, // i: bw_detector + Word16 ind_LF, Word16 ind_HF, Word16 shape_j, Word32* SNS_VQ_ORDER, // i: sns + Word16 num_tns_filters, Word16* rc_order, Word16 tns_lpc_weighting, Word16* rc_i, Word16* X_q, // i: tns + Word16 pitch_present, Word16 ltpf_active, Word16 pitch_index, // i: ltpf + Word16 lastnz_trunc, Word16 lsbMode, Word16 gg_ind, Word16 rateFlag, // i: spectral quantization + Word32 nbits_residual, Word16* res_bits, // i: residual coding + Word16 F_NF, // i: noise level estimation + UWord8* bytes // o: bitstream +); +#else + void dct_IV(Word32 nMs_mode, Word16 fs_ind, Word32* dct_input, kiss_fft_state16_ptr kiss_fft_state, Word16 NF, Word16* data_exp); + void ld_mdct(LC3_ENC_STRU* enc, Word16* input, Word32* X, Word32* E_B,Word16* data_exp, Word16* E_B_exp); + void bw_detector( + LC3_ENC_STRU* enc, // i + Word32* E_B, // i:from ld_mdct + Word16 E_B_exp, + Word16* Pbw // o:P_bw + ); + void tda_detector( + LC3_ENC_STRU* enc, // i + Word16* input, // i:input data + Word16* F_att // o:attack Flag + ); + void sns( + LC3_ENC_STRU* enc, // i + Word16 F_att, // i: attack flag + Word32* X, // i: frequancy data + Word32* E_B, // i: frequancy bands energy + Word16* E_B_exp, // i: exp of E_B + Word32* X_S, // o: frequanct data after SNS + Word16* ind_LF, // o: codebook index for LF vector + Word16* ind_HF, // o: codebook index for HF vector + Word16* shape_j, // o: shape index for pyramid vector + Word32* PVQ_PARA // o: PVQ parameter + ); + void tns(LC3_ENC_STRU* enc, Word32 Pbw, Word32* X_S, Word16 num_tns_filter,Word32 near_nyquist_flag, Word16* rc_int, Word16* rc_order, Word32* X_F, Word16* nbits_TNS, Word16* tns_lpc_weighting); + + void ltpf(LC3_ENC_STRU* enc, Word16* input, Word32* pitch_present, Word32* ltpf_active, Word32* pitch_index, Word16* nbits_LTPF, Word16 ltpf_enable); + + + void spectral_quantization( + LC3_ENC_STRU* enc, Word16 nbits_bw, Word16 nbits_TNS, Word16 nbits_LTPF, Word32* X_F, Word16 X_exp, + Word16* X_q, Word16* nbits_spec, Word16* nbits_trunc, Word16* gg, Word16* gg_e, + Word16* gg_ind, Word16* lsbMode, Word16* lastnz_trunc, Word16* rateFlag, Word16* codingdata); + + + void residual_coding_encoder(LC3_ENC_STRU* enc, Word16 nbits_residual_max, Word16* X_q, + Word32* X_F, Word16 X_exp, Word16 gg, Word16 gg_e, Word8* res_bits, Word16* nbits_residual); + + void noise_estimation_encoder(LC3_ENC_STRU* enc, Word16* X_q, Word32 Pbw, + Word32* X_f, Word16 X_exp, Word16 gg, Word16 gg_e, Word16* F_NF); + + void bitstream_encoder( + LC3_ENC_STRU* enc, // i + Word16 nbits_bw, Word16 P_bw, // i: bw_detector + Word16 ind_LF, Word16 ind_HF, Word16 shape_j, Word32* PVQ_PARA, // i: sns + Word16 num_tns_filters, Word16* rc_order, Word16 tns_lpc_weighting, Word16* rc_i, Word16* X_q, // i: tns + Word16 pitch_present, Word16 ltpf_active, Word16 pitch_index, // i: ltpf + Word16 lastnz_trunc, Word16 lsbMode, Word16 gg_ind, Word16 rateFlag, Word16* codingdata, // i: spectral quantization + Word32 nbits_residual, Word8* res_bits, // i: residual coding + Word16 F_NF, // i: noise level estimation + UWord8* bytes // o: bitstream + ); +#endif // FIXED_POINT +#endif //#if (ALG_LC3_ENABLE) +#endif + diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/_kiss_fft_guts.h b/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/_kiss_fft_guts.h new file mode 100755 index 0000000..82aee0c --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/_kiss_fft_guts.h @@ -0,0 +1,190 @@ +/* +Copyright (c) 2003-2010, Mark Borgerding + +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 author nor the names of any 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 __KISS_FFT_GUTS_H__ +#define __KISS_FFT_GUTS_H__ +#ifndef USE_SPREAD_FFT +#include "../../inc/lc3_types.h" + +#if (ALG_LC3_ENABLE) + +/* kiss_fft.h + defines kiss_fft_scalar as either short or a float type + and defines + typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */ +#include "kiss_fft.h" +//#include +#include "../../inc/config.h" +#include "../intrinsic.h" +#define MAXFACTORS 32 +/* e.g. an fft of length 128 has 4 factors + as far as kissfft is concerned + 4*4*4*2 + + +struct kiss_fft_state{ + int nfft; + int inverse; + int factors[2*MAXFACTORS]; + kiss_fft_cpx twiddles[1]; +}; +*/ +/* + Explanation of macros dealing with complex math: + + C_MUL(m,a,b) : m = a*b + C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise + C_SUB( res, a,b) : res = a - b + C_SUBFROM( res , a) : res -= a + C_ADDTO( res , a) : res += a + * */ +#ifdef FIXED_POINT +#if (FIXED_POINT==32) +# define FRACBITS 31 +# define SAMPPROD Word64 +#define SAMP_MAX 2147483647 +#else +# define FRACBITS 15 +# define SAMPPROD Word32 +#define SAMP_MAX 32767 +#endif + +#define SAMP_MIN -SAMP_MAX + +#if defined(CHECK_OVERFLOW) +# define CHECK_OVERFLOW_OP(a,op,b) \ + if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \ + fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) ); } +#endif + + +# define smul(a,b) ( (SAMPPROD)(a)*(b) ) +# define sround( x ) (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS ) + +#if 0 +# define S_MUL(a,b) sround( smul(a,b) ) +# define C_MUL(m,a,b) \ + do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \ + (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0) +# define DIVSCALAR(x,k) \ + (x) = sround( smul( x, SAMP_MAX/k ) ) +# define C_MULBYSCALAR( c, s ) \ + do{ (c).r = sround( smul( (c).r , s ) ) ;\ + (c).i = sround( smul( (c).i , s ) ) ; }while(0) +#else +# define S_MUL(a,b) ( mult_r_32_Q31_32(a,b) ) +# define C_MUL(m,a,b) \ + do{ (m).r = ( mult_r_32_Q31_32((a).r,(b).r) - mult_r_32_Q31_32((a).i,(b).i) ); \ + (m).i = ( mult_r_32_Q31_32((a).r,(b).i) + mult_r_32_Q31_32((a).i,(b).r) ); }while(0) +# define DIVSCALAR(x,k) \ + (x) = ( mult_r_32_Q31_32( x, SAMP_MAX/k ) ) +# define C_MULBYSCALAR( c, s ) \ + do{ (c).r = ( mult_r_32_Q31_32( (c).r , s ) ) ;\ + (c).i = ( mult_r_32_Q31_32( (c).i , s ) ) ; }while(0) +#endif + + + +# define C_FIXDIV(c,div) \ + do { DIVSCALAR( (c).r , div); \ + DIVSCALAR( (c).i , div); }while (0) + + + +#else /* not FIXED_POINT*/ + +# define S_MUL(a,b) ( (a)*(b) ) +#define C_MUL(m,a,b) \ + do{ (m).r = (a).r*(b).r - (a).i*(b).i;\ + (m).i = (a).r*(b).i + (a).i*(b).r; }while(0) +# define C_FIXDIV(c,div) /* NOOP */ +# define C_MULBYSCALAR( c, s ) \ + do{ (c).r *= (s);\ + (c).i *= (s); }while(0) +#endif + +#ifndef CHECK_OVERFLOW_OP +# define CHECK_OVERFLOW_OP(a,op,b) /* noop */ +#endif + +#define C_ADD( res, a,b)\ + do { \ + CHECK_OVERFLOW_OP((a).r,+,(b).r)\ + CHECK_OVERFLOW_OP((a).i,+,(b).i)\ + (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ + }while(0) +#define C_SUB( res, a,b)\ + do { \ + CHECK_OVERFLOW_OP((a).r,-,(b).r)\ + CHECK_OVERFLOW_OP((a).i,-,(b).i)\ + (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ + }while(0) +#define C_ADDTO( res , a)\ + do { \ + CHECK_OVERFLOW_OP((res).r,+,(a).r)\ + CHECK_OVERFLOW_OP((res).i,+,(a).i)\ + (res).r += (a).r; (res).i += (a).i;\ + }while(0) + +#define C_SUBFROM( res , a)\ + do {\ + CHECK_OVERFLOW_OP((res).r,-,(a).r)\ + CHECK_OVERFLOW_OP((res).i,-,(a).i)\ + (res).r -= (a).r; (res).i -= (a).i; \ + }while(0) + + +#ifdef FIXED_POINT +# define KISS_FFT_COS(phase) floor(.5+SAMP_MAX * cos (phase)) +# define KISS_FFT_SIN(phase) floor(.5+SAMP_MAX * sin (phase)) +# define HALF_OF(x) ((x)>>1) +#elif defined(USE_SIMD) +# define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) ) +# define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) ) +# define HALF_OF(x) ((x)*_mm_set1_ps(.5)) +#else +# define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase) +# define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase) +# define HALF_OF(x) ((x)*.5) +#endif + +#define kf_cexp(x,phase) \ + do{ \ + (x)->r = KISS_FFT_COS(phase);\ + (x)->i = KISS_FFT_SIN(phase);\ + }while(0) + + +/* a debugging function */ +#define pcpx(c)\ + fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) ) + + +#ifdef KISS_FFT_USE_ALLOCA +// define this to allow use of alloca instead of malloc for temporary buffers +// Temporary buffers are used in two case: +// 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5 +// 2. "in-place" FFTs. Notice the quotes, since kissfft does not really do an in-place transform. +#include +#define KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes) +#define KISS_FFT_TMP_FREE(ptr) +#else +#define KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes) +#define KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr) +#endif + +#endif //#if (ALG_LC3_ENABLE) + +#endif +#endif diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/kiss_fft.h b/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/kiss_fft.h new file mode 100755 index 0000000..f5a26f6 --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/kiss_fft.h @@ -0,0 +1,128 @@ +#ifndef KISS_FFT_H +#define KISS_FFT_H +#include "../../inc/config.h" +#ifndef USE_SPREAD_FFT + + +#include "../../inc/lc3_types.h" +#include "../../inc/config.h" +#if (ALG_LC3_ENABLE) +#ifdef __cplusplus +extern "C" { +#endif + +/* + ATTENTION! + If you would like a : + -- a utility that will handle the caching of fft objects + -- real-only (no imaginary time component ) FFT + -- a multi-dimensional FFT + -- a command-line utility to perform ffts + -- a command-line utility to perform fast-convolution filtering + + Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c + in the tools/ directory. +*/ + +#ifdef USE_SIMD +# include +# define kiss_fft_scalar __m128 +#define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes,16) +#define KISS_FFT_FREE _mm_free +#else +#define KISS_FFT_MALLOC malloc +#define KISS_FFT_FREE free +#endif + + +#ifdef FIXED_POINT +//#include +# if (FIXED_POINT == 32) +# define kiss_fft_scalar Word32 +# else +# define kiss_fft_scalar Word16 +# endif +#else +# ifndef kiss_fft_scalar +/* default is float */ +# define kiss_fft_scalar float +# endif +#endif +/* +typedef struct { + kiss_fft_scalar r; + kiss_fft_scalar i; +}kiss_fft_cpx; + +typedef struct kiss_fft_state* kiss_fft_cfg; +*/ +/* + * kiss_fft_alloc + * + * Initialize a FFT (or IFFT) algorithm's cfg/state buffer. + * + * typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL); + * + * The return value from fft_alloc is a cfg buffer used internally + * by the fft routine or NULL. + * + * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc. + * The returned value should be free()d when done to avoid memory leaks. + * + * The state can be placed in a user supplied buffer 'mem': + * If lenmem is not NULL and mem is not NULL and *lenmem is large enough, + * then the function places the cfg in mem and the size used in *lenmem + * and returns mem. + * + * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough), + * then the function returns NULL and places the minimum cfg + * buffer size in *lenmem. + * */ + +kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,unsigned int * lenmem); + +/* + * kiss_fft(cfg,in_out_buf) + * + * Perform an FFT on a complex input buffer. + * for a forward FFT, + * fin should be f[0] , f[1] , ... ,f[nfft-1] + * fout will be F[0] , F[1] , ... ,F[nfft-1] + * Note that each element is complex and can be accessed like + f[k].r and f[k].i + * */ +void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); + +/* + A more generic version of the above function. It reads its input from every Nth sample. + * */ +void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride); + +/* If kiss_fft_alloc allocated a buffer, it is one contiguous + buffer and can be simply free()d when no longer needed*/ +#define kiss_fft_free free + +/* + Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up + your compiler output to call this before you exit. +*/ +void kiss_fft_cleanup(void); + + +/* + * Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5) + */ +int kiss_fft_next_fast_size(int n); + +/* for real ffts, we need an even size */ +#define kiss_fftr_next_fast_size_real(n) \ + (kiss_fft_next_fast_size( ((n)+1)>>1)<<1) + +#ifdef __cplusplus +} +#endif + +#endif //#if (ALG_LC3_ENABLE) + +#endif +#endif // !1 diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/kiss_fft_custom/kiss_fft_custom.h b/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/kiss_fft_custom/kiss_fft_custom.h new file mode 100755 index 0000000..90e34e2 --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/kiss_fft_custom/kiss_fft_custom.h @@ -0,0 +1,13 @@ +#ifndef KISS_FFT_CUSTOM_H +#define KISS_FFT_CUSTOM_H + +#include "../../../inc/config.h" +#if (ALG_LC3_ENABLE) + +#include "kiss_fft_type.h" +void kiss_fft_32_16(kiss_fft_state16_ptr cfg, const kiss_fft_cpx_data_32* fin, kiss_fft_cpx_data_32* fout); +kiss_fft_state16_ptr kiss_fft_init_32_16(int nfft, int inverse_fft); + +#endif //#if (ALG_LC3_ENABLE) + +#endif diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/kiss_fft_custom/kiss_fft_fixed_op.h b/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/kiss_fft_custom/kiss_fft_fixed_op.h new file mode 100755 index 0000000..8ee078d --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/kiss_fft_custom/kiss_fft_fixed_op.h @@ -0,0 +1,189 @@ +#ifndef FIXED_OP_H +#define FIXED_OP_H + +#include "../../../inc/config.h" +#if (ALG_LC3_ENABLE) + +#if __riscv +#include +#endif +#define QCONST16(x,bits) ((short)(.5+(x)*(((int)1)<<(bits)))) +#define QCONST32(x,bits) ((int)(.5+(x)*(((int)1)<<(bits)))) + +#define NEG16(x) (-(x)) +#define NEG32(x) (-(x)) +#define EXTRACT16(x) ((short)(x)) +#define EXTEND32(x) ((int)(x)) +#define SHR16(a,shift) ((a) >> (shift)) +#define SHL16(a,shift) ((a) << (shift)) +#define SHR32(a,shift) ((a) >> (shift)) +#define SHL32(a,shift) ((a) << (shift)) +#define PSHR16(a,shift) (SHR16((a)+((1<<((shift))>>1)),shift)) +#define PSHR32(a,shift) (SHR32((a)+((EXTEND32(1)<<((shift))>>1)),shift)) +#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift))) +#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) +#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) + +#define SHR(a,shift) ((a) >> (shift)) +#define SHL(a,shift) ((int)(a) << (shift)) +#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift)) +#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) + + +#define ADD16(a,b) ((short)((short)(a)+(short)(b))) +#define SUB16(a,b) ((short)(a)-(short)(b)) +#define ADD32(a,b) ((int)(a)+(int)(b)) +#define SUB32(a,b) ((int)(a)-(int)(b)) + + +/* result fits in 16 bits */ +#define MULT16_16_16(a,b) ((((short)(a))*((short)(b)))) + +/* (int)(short) gives TI compiler a hint that it's 16x16->32 multiply */ +#define MULT16_16(a,b) (((int)(short)(a))*((int)(short)(b))) + +#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b)))) +#define MULT16_32_Q12(a,b) ADD32(MULT16_16((a),SHR((b),12)), SHR(MULT16_16((a),((b)&0x00000fff)),12)) +#define MULT16_32_Q13(a,b) ADD32(MULT16_16((a),SHR((b),13)), SHR(MULT16_16((a),((b)&0x00001fff)),13)) +#define MULT16_32_Q14(a,b) ADD32(MULT16_16((a),SHR((b),14)), SHR(MULT16_16((a),((b)&0x00003fff)),14)) + +#define MULT16_32_Q11(a,b) ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11)) +#define MAC16_32_Q11(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11))) + +#define MULT16_32_P15(a,b) ADD32(MULT16_16((a),SHR((b),15)), PSHR(MULT16_16((a),((b)&0x00007fff)),15)) +#define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)) +#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))) + + +#define MAC16_16_Q11(c,a,b) (ADD32((c),SHR(MULT16_16((a),(b)),11))) +#define MAC16_16_Q13(c,a,b) (ADD32((c),SHR(MULT16_16((a),(b)),13))) +#define MAC16_16_P13(c,a,b) (ADD32((c),SHR(ADD32(4096,MULT16_16((a),(b))),13))) + +#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11)) +#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13)) +#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14)) +#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15)) + +#define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13)) +#define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14)) +#define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15)) + +#define MUL_16_32_R15(a,bh,bl) ADD32(MULT16_16((a),(bh)), SHR(MULT16_16((a),(bl)),15)) + +#define MULT32_16_Q15(a,b) ((long long int)a*(long long int)b>>15) +#define MULT32_16_P15(a,b) (((long long int)a*(long long int)b+(1<<14))>>15) + +#define DIV32_16(a,b) ((short)(((int)(a))/((short)(b)))) +#define PDIV32_16(a,b) ((short)(((int)(a)+((short)(b)>>1))/((short)(b)))) +#define DIV32(a,b) (((int)(a))/((int)(b))) +#define PDIV32(a,b) (((int)(a)+((short)(b)>>1))/((int)(b))) + +# define smul(a,b) ( (int)(a)*(b) ) +# define sround( x ) (short)( ( (x) + (1<<(15-1)) ) >> 15 ) + +# define smul32(a,b) ( (long long int)(a)*(b) ) +# define sround32( x ) (int)( ( (x) + (1<<(15-1)) ) >> 15 ) + +# define S_MUL(a,b) sround( smul(a,b) ) +#if __riscv +# define S_MUL32(a,b) ( __nds__kmmwb2_u(a,b) ) +#else +# define S_MUL32(a,b) sround32( smul32(a,b) ) +#endif +# define C_MUL_16_16(m,a,b) \ + do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \ + (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0) +#if __riscv +/* +# define C_MUL_32_16(m,a,b) \ + do{ (m).r = ( __nds__kmmwb2_u((a).r,(b).r) - __nds__kmmwb2_u((a).i,(b).i) ); \ + (m).i = __nds__kmmawb2_u( __nds__kmmwb2_u((a).r,(b).i) , (a).i,(b).r ); }while(0) +*/ +# define C_MUL_32_16(m,a,b) \ + do{ (m).r = ( __nds__kmmwb2_u((a).r,(b).r) - __nds__kmmwb2_u((a).i,(b).i) ); \ + (m).i = ( __nds__kmmwb2_u((a).r,(b).i) + __nds__kmmwb2_u((a).i,(b).r) ); }while(0) + +#else +# define C_MUL_32_16(m,a,b) \ + do{ (m).r = (sround32 (smul32((a).r,(b).r)) - sround32 (smul32((a).i,(b).i)) ); \ + (m).i = (sround32 (smul32((a).r,(b).i)) + sround32(smul32((a).i,(b).r)) ); }while(0) +#endif + +// C_MUL4 ½á¹ûÓÒÒÆ17λ +# define C_MUL4(m,a,b) \ + do{ (m).r = PSHR32( smul((a).r,(b).r) - smul((a).i,(b).i),17 ); \ + (m).i = PSHR32( smul((a).r,(b).i) + smul((a).i,(b).r),17 ); }while(0) + +# define DIVSCALAR(x,k) \ + (x) = sround( smul( x, 32767/k ) ) + +# define C_FIXDIV(c,div) \ + do { DIVSCALAR( (c).r , div); \ + DIVSCALAR( (c).i , div); }while (0) + +# define C_MULBYSCALAR( c, s ) \ + do{ (c).r = sround( smul( (c).r , s ) ) ;\ + (c).i = sround( smul( (c).i , s ) ) ; }while(0) +#if __riscv +# define C_MULBYSCALAR_32( c, s ) \ + do{ (c).r = ( __nds__kmmwb2_u( (c).r , s ) ) ;\ + (c).i = ( __nds__kmmwb2_u( (c).i , s ) ) ; }while(0) +#else +# define C_MULBYSCALAR_32( c, s ) \ + do{ (c).r = sround32( smul32( (c).r , s ) ) ;\ + (c).i = sround32( smul32( (c).i , s ) ) ; }while(0) +#endif +#define C_ADD( res, a,b)\ + do { \ + (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ + }while(0) +#define C_SUB( res, a,b)\ + do { \ + (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ + }while(0) +#if __riscv +#define C_ADD_HALF( res, a,b)\ + do { \ + (res).r=__nds__raddw((a).r,(b).r); (res).i=__nds__raddw((a).i,(b).i); \ + }while(0) +#define C_SUB_HALF( res, a,b)\ + do { \ + (res).r=__nds__rsubw((a).r,(b).r); (res).i=__nds__rsubw((a).i,(b).i); \ + }while(0) +#else +#define C_ADD_HALF( res, a,b)\ + do { \ + (res).r=((long long int)(a).r+(b).r)>>1; (res).i=((long long int)(a).i+(b).i)>>1; \ + }while(0) +#define C_SUB_HALF( res, a,b)\ + do { \ + (res).r=((long long int)(a).r-(b).r)>>1; (res).i=((long long int)(a).i-(b).i)>>1; \ + }while(0) +#endif +#define C_ADDTO( res , a)\ + do { \ + (res).r += (a).r; (res).i += (a).i;\ + }while(0) + +#define C_SUBFROM( res , a)\ + do {\ + (res).r -= (a).r; (res).i -= (a).i; \ + }while(0) + +# define HALF_OF(x) ((x)>>1) +/* +#ifdef FIXED_POINT +# define KISS_FFT_COS(phase) floor(MIN(32767,MAX(-32767,.5+32768 * cos (phase)))) +# define KISS_FFT_SIN(phase) floor(MIN(32767,MAX(-32767,.5+32768 * sin (phase)))) +# define HALF_OF(x) ((x)>>1) + +#else +# define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase) +# define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase) +# define HALF_OF(x) ((x)*.5) +#endif +*/ + +#endif //#if (ALG_LC3_ENABLE) + +#endif diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/kiss_fft_custom/kiss_fft_function.h b/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/kiss_fft_custom/kiss_fft_function.h new file mode 100755 index 0000000..01ec7c3 --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/kiss_fft_custom/kiss_fft_function.h @@ -0,0 +1,264 @@ +#ifndef KISS_FFT_FUNCTION_H +#define KISS_FFT_FUNCTION_H + + +#include "../../../inc/config.h" +#if (ALG_LC3_ENABLE) +#include "kiss_fft_fixed_op.h" + + +static inline short spx_ilog2(unsigned int x) +{ + int r = 0; + if (x >= (int)65536) + { + x >>= 16; + r += 16; + } + if (x >= 256) + { + x >>= 8; + r += 8; + } + if (x >= 16) + { + x >>= 4; + r += 4; + } + if (x >= 4) + { + x >>= 2; + r += 2; + } + if (x >= 2) + { + r += 1; + } + return r; +} + +static inline short spx_ilog4(unsigned int x) +{ + int r = 0; + if (x >= (int)65536) + { + x >>= 16; + r += 8; + } + if (x >= 256) + { + x >>= 8; + r += 4; + } + if (x >= 16) + { + x >>= 4; + r += 2; + } + if (x >= 4) + { + r += 1; + } + return r; +} + + +/** Generate a pseudo-random number */ +static inline short speex_rand(short std, int* seed) +{ + int res; + *seed = 1664525 * *seed + 1013904223; + res = MULT16_16(EXTRACT16(SHR32(*seed, 16)), std); + return EXTRACT16(PSHR32(SUB32(res, SHR32(res, 3)), 14)); +} + +/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25723*x^3 (for .25 < x < 1) */ +/*#define C0 3634 +#define C1 21173 +#define C2 -12627 +#define C3 4215*/ + +/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25659*x^3 (for .25 < x < 1) */ +#define C0 3634 +#define C1 21173 +#define C2 -12627 +#define C3 4204 + +static inline short spx_sqrt(int x) +{ + int k; + int rt; + k = spx_ilog4(x) - 6; + x = VSHR32(x, (k << 1)); + rt = ADD16(C0, MULT16_16_Q14(x, ADD16(C1, MULT16_16_Q14(x, ADD16(C2, MULT16_16_Q14(x, (C3))))))); + rt = VSHR32(rt, 7 - k); + return rt; +} + +/* log(x) ~= -2.18151 + 4.20592*x - 2.88938*x^2 + 0.86535*x^3 (for .5 < x < 1) */ + + +#define A1 16469 +#define A2 2242 +#define A3 1486 + +static inline short spx_acos(short x) +{ + int s = 0; + short ret; + short sq; + if (x < 0) + { + s = 1; + x = NEG16(x); + } + x = SUB16(16384, x); + + x = x >> 1; + sq = MULT16_16_Q13(x, ADD16(A1, MULT16_16_Q13(x, ADD16(A2, MULT16_16_Q13(x, (A3)))))); + ret = spx_sqrt(SHL32(EXTEND32(sq), 13)); + + /*ret = spx_sqrt(67108864*(-1.6129e-04 + 2.0104e+00*f + 2.7373e-01*f*f + 1.8136e-01*f*f*f));*/ + if (s) + ret = SUB16(25736, ret); + return ret; +} + + +#define K1 8192 +#define K2 -4096 +#define K3 340 +#define K4 -10 + +static inline short spx_cos(short x) +{ + short x2; + + if (x < 12868) + { + x2 = MULT16_16_P13(x, x); + return ADD32(K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2)))))); + } + else { + x = SUB16(25736, x); + x2 = MULT16_16_P13(x, x); + return SUB32(-K1, MULT16_16_P13(x2, ADD32(K2, MULT16_16_P13(x2, ADD32(K3, MULT16_16_P13(K4, x2)))))); + } +} + +#define L1 32767 +#define L2 -7651 +#define L3 8277 +#define L4 -626 + +static inline short _spx_cos_pi_2(short x) +{ + short x2; + + x2 = MULT16_16_P15(x, x); + return ADD16(1, MIN16(32766, ADD32(SUB16(L1, x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2)))))))); +} + +static inline short spx_cos_norm(int x) +{ + x = x & 0x0001ffff; + if (x > SHL32(EXTEND32(1), 16)) + x = SUB32(SHL32(EXTEND32(1), 17), x); + if (x & 0x00007fff) + { + if (x < SHL32(EXTEND32(1), 15)) + { + return _spx_cos_pi_2(EXTRACT16(x)); + } + else { + return NEG32(_spx_cos_pi_2(EXTRACT16(65536 - x))); + } + } + else { + if (x & 0x0000ffff) + return 0; + else if (x & 0x0001ffff) + return -32767; + else + return 32767; + } +} + +/* + K0 = 1 + K1 = log(2) + K2 = 3-4*log(2) + K3 = 3*log(2) - 2 +*/ +#define D0 16384 +#define D1 11356 +#define D2 3726 +#define D3 1301 +/* Input in Q11 format, output in Q16 */ +static inline int spx_exp2(short x) +{ + int integer; + short frac; + integer = SHR16(x, 11); + if (integer > 14) + return 0x7fffffff; + else if (integer < -15) + return 0; + frac = SHL16(x - SHL16(integer, 11), 3); + frac = ADD16(D0, MULT16_16_Q14(frac, ADD16(D1, MULT16_16_Q14(frac, ADD16(D2, MULT16_16_Q14(D3, frac)))))); + return VSHR32(EXTEND32(frac), -integer - 2); +} + +/* Input in Q11 format, output in Q16 */ +static inline int spx_exp(short x) +{ + if (x > 21290) + return 0x7fffffff; + else if (x < -21290) + return 0; + else + return spx_exp2(MULT16_16_P14(23637, x)); +} +#define M1 32767 +#define M2 -21 +#define M3 -11943 +#define M4 4936 + +static inline short spx_atan01(short x) +{ + return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x))))))); +} + +#undef M1 +#undef M2 +#undef M3 +#undef M4 + +/* Input in Q15, output in Q14 */ +static inline short spx_atan(int x) +{ + if (x <= 32767) + { + return SHR16(spx_atan01(x), 1); + } + else { + int e = spx_ilog2(x); + if (e >= 29) + return 25736; + x = DIV32_16(SHL32(EXTEND32(32767), 29 - e), EXTRACT16(SHR32(x, e - 14))); + return SUB16(25736, SHR16(spx_atan01(x), 1)); + } +} + + + +#define kf_cexp2(x,phase) \ + do{ \ + (x)->r = spx_cos_norm((phase));\ + (x)->i = spx_cos_norm((phase)-32768);\ +}while(0) + + +#endif //#if (ALG_LC3_ENABLE) + +#endif // KISS_FFT_FUNCTION_H diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/kiss_fft_custom/kiss_fft_type.h b/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/kiss_fft_custom/kiss_fft_type.h new file mode 100755 index 0000000..d1adf7c --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/kiss_fft_custom/kiss_fft_type.h @@ -0,0 +1,51 @@ +#ifndef KISS_FFT_TYPE_H +#define KISS_FFT_TYPE_H + +#include "../../../inc/config.h" +#if (ALG_LC3_ENABLE) + +//#define FIXED_POINT +#define ABS(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute integer value. */ +#define ABS16(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 16-bit value. */ +#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 16-bit value. */ +#define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */ +#define ABS32(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 32-bit value. */ +#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 32-bit value. */ +#define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */ + +typedef struct { + short r; + short i; +}kiss_fft_cpx_twiddle; + +typedef struct { + short r; + short i; +}kiss_fft_cpx_data_16; + +typedef struct { + short r; + short i; +}kiss_fft_cpx_twiddle_16; + +typedef struct { + int r; + int i; +}kiss_fft_cpx_data_32; + +#define MAX_STAGE 32 +#define NFFT 240 + +struct kiss_fft_state16 { + int nfft; + int inverse; + int factors[2 * MAX_STAGE]; + int Q_shift; + kiss_fft_cpx_twiddle_16 twiddles[NFFT]; +}; +typedef struct kiss_fft_state16* kiss_fft_state16_ptr; + +#endif //#if (ALG_LC3_ENABLE) + +#endif // !KISS_FFT_H + diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/spread_fft.h b/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/spread_fft.h new file mode 100755 index 0000000..b9c5f5b --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/fft_lib/spread_fft.h @@ -0,0 +1,8 @@ +#ifndef SPREAD_FFT +#define SPREAD_FFT + +#include "../../inc/lc3_types.h" +#if (ALG_LC3_ENABLE) +void BASOP_cfft(Word32* re, Word32* im, Word16 sizeOfFft, Word16 s, Word16* scale, Word32* x); +#endif //#if (ALG_LC3_ENABLE) +#endif diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/func_asm.h b/b91/b91m_ble_sdk/algorithm/lc3/src/func_asm.h new file mode 100755 index 0000000..4ec2017 --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/func_asm.h @@ -0,0 +1,6 @@ +#ifndef _FUNC_ASM_H +#define _FUNC_ASM_H + +Word32 dprod_q15(Word16 *src1, Word16 *src2, Word32 size); + +#endif diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/global_gain.h b/b91/b91m_ble_sdk/algorithm/lc3/src/global_gain.h new file mode 100755 index 0000000..168537e --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/global_gain.h @@ -0,0 +1,14 @@ +#ifndef _GLOBAL_GAIN_H +#define _GLOBAL_GAIN_H + +#include "../inc/lc3_dec.h" + +#if (ALG_LC3_ENABLE) +#ifdef FIXED_POINT +void global_gain_fix(LC3_DEC_STRU* dec, Word32* Xq_residual, Word16 nBits, Word16* exp); +#else +void global_gain(LC3_DEC_STRU* dec, double* Xq_residual, Word16 nBits); +#endif +#endif + +#endif diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/intrinsic.h b/b91/b91m_ble_sdk/algorithm/lc3/src/intrinsic.h new file mode 100755 index 0000000..48f4d8d --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/intrinsic.h @@ -0,0 +1,727 @@ +#ifndef _INTRINSIC_H +#define _INTRINSIC_H + +#include "../inc/lc3_types.h" + +#if (ALG_LC3_ENABLE) +#ifdef ANDES_INTRINSIC +#include +#include +#endif + +#ifdef ANDES_INTRINSIC +/* 16-bit Count Leading Redundant Sign */ +inline Word16 clrs16(Word16 a) +{ + return __nds__clrs16(a); +} +/* 32-bit count leading zero */ +inline UWord32 clz32(UWord32 a) { + return __nds__clz32(a); +} + +/* vin1 : Q15, vin2: Q15 ---> vout: Q15 */ +inline Word16 mult_16(Word16 vin1, Word16 vin2) +{ + Word16 vout; + vout = __nds__khmbb(vin1, vin2); + return vout; +} +inline Word32 mult_16_16_32(Word16 vin1, Word16 vin2) +{ + return __nds__smul16(vin1, vin2); +} +/* vin1 : Q15, vin2: Q15 ---> vout: Q15 */ +inline Word16 mult_r_16(Word16 vin1, Word16 vin2) +{ + return __nds__sra_u(__nds__smul16(vin1, vin2),15); +} +inline Word32 mult_32(Word32 vin1, Word32 vin2) +{ + return __nds__smmul(vin1, vin2); +} + +/* 32-bit count leading redundant sign */ +inline UWord32 clrs32(UWord32 a){ + return __nds__clrs32(a); +} + +/* 32-bit shift right arithmetic */ +inline UWord32 sra32(UWord32 a, UWord32 b) { + return __nds__sra32(a, b); +} + +inline Word32 mult_32_16_32(Word32 vin1, Word16 vin2) +{ + return __nds__smmwb(vin1, (UWord32)vin2); +} + +inline Word32 mult_r_32_16_32(Word32 vin1, Word16 vin2) +{ + return __nds__smmwb_u(vin1, (UWord32)vin2); +} + +inline Word32 mult_32_Q31_32(Word32 vin1, Word32 vin2) +{ + return __nds__kwmmul(vin1, vin2); +} + +inline Word32 mult_r_32_Q31_32(Word32 vin1, Word32 vin2) +{ + return __nds__kwmmul_u(vin1, vin2); +} + +inline Word32 mult_32_Q15_32(Word32 vin1, Word16 vin2) +{ + return __nds__kmmwb2(vin1, vin2); +} + +inline Word32 mult_r_32_Q15_32(Word32 vin1, Word16 vin2) +{ + return __nds__kmmwb2_u(vin1, vin2); +} + +inline Word32 mac_r_32_Q15_32(Word32 acc, Word32 vin1, Word16 vin2) +{ + return __nds__kmmawb2_u(acc, vin1, vin2); +} + +inline Word32 mac_r_32_16_32(Word32 acc, Word32 vin1, Word16 vin2) +{ + return __nds__kmmawb_u(acc, vin1, vin2); +} + +inline Word32 mac_16_16_32(Word32 vin, Word16 vin1, Word16 vin2) +{ + return __nds__kmabb(vin, vin1, vin2); +} + +inline Word32 L_shl(Word32 L_var1, Word16 var2) +{ + return __nds__kslraw(L_var1, var2); +} + +inline Word32 L_shr(Word32 L_var1, Word16 var2) +{ + return __nds__kslraw(L_var1, -var2); +} +/* +inline Word16 lshr(Word16 var1, Word16 var2) +{ + //printf("\ninput=%d %d",var1,var2); + //printf("\noutput=%d",__nds__srl16(var1, var2)); + return (Word16)__nds__srl16(var1, var2); + +}*/ +inline Word32 L_add(Word32 L_var1, Word32 L_var2) +{ + return __nds__kaddw(L_var1, L_var2); +} + +inline Word32 L_sub(Word32 L_var1, Word32 L_var2) +{ + return __nds__ksubw(L_var1, L_var2); +} +inline Word32 L_add_half(Word32 L_var1, Word32 L_var2) +{ + return __nds__raddw(L_var1, L_var2); +} + +inline Word32 L_sub_half(Word32 L_var1, Word32 L_var2) +{ + return __nds__rsubw(L_var1, L_var2); +} +inline Word16 abs16(Word16 x) +{ + return __nds__kabs16(x); +} +inline Word32 abs32(Word32 x) +{ + return __nds__kabsw(x); +} +inline Word16 convert_q31_q15_u(Word32 x) +{ + return __nds__sra_u(x, 16); +} +inline Word32 L_mult(Word16 var1, Word16 var2) +{ + return __nds__kdmbb(var1, var2); +} +inline Word32 L_mac(Word32 L_var3, Word16 var1, Word16 var2) +{ + return __nds__kaddw(L_var3, __nds__kdmbb(var1, var2)); +} +inline Word32 L_msu(Word32 L_var3, Word16 var1, Word16 var2) +{ + return __nds__ksubw(L_var3, __nds__kdmbb(var1, var2)); +} +/* Multiply var1 by var2 and shift the result left by 1. Add the 32 bit + result to L_var3 with saturation. Round the LS 16 bits of the result + into the MS 16 bits with saturation and shift the result right by 16. */ +inline Word16 mac_r(Word32 L_var3, Word16 var1, Word16 var2) +{ + return __nds__sra_u(__nds__kaddw(L_var3, __nds__kdmbb(var1, var2)), 16); +} +inline Word16 msu_r(Word32 L_var3, Word16 var1, Word16 var2) +{ + return __nds__sra_u(__nds__ksubw(L_var3, __nds__kdmbb(var1, var2)), 16); +} +#else + +inline UWord32 clz32(UWord32 a) { + int i; + for (i = 32; i >= 0; i--) { + if (a == 0) + break; + a = a >> 1; + } + return i; +} + +/* vin1 : Q15, vin2: Q15 ---> vout: Q15 */ +inline Word16 mult_16(Word16 vin1, Word16 vin2) +{ + Word32 tmp; + Word16 vout; + tmp = (Word32)vin1 * (Word32)vin2; + if (tmp == 0x40000000) { + tmp = 0x3fffffff; + } + vout = (Word16)(tmp >> 15); + return vout; +} +inline Word32 mult_16_16_32(Word16 vin1, Word16 vin2) +{ + Word32 vout = (Word32)vin1 * (Word32)vin2; + return vout; +} +/* vin1 : Q15, vin2: Q15 ---> vout: Q15 */ +inline Word16 mult_r_16(Word16 vin1, Word16 vin2) +{ + Word32 tmp; + Word16 vout; + tmp = mult_16_16_32(vin1, vin2); + tmp += 0x4000; + vout = (Word16)(tmp >> 15); + return vout; +} +inline Word32 mult_32(Word32 vin1, Word32 vin2) +{ + Word64 tmp; + Word32 vout; + tmp = (Word64)vin1 * (Word64)vin2; + vout = (Word32)(tmp >> 32); + return vout; +} +inline Word16 clrs16(Word16 a) +{ + int i; + UWord32 cnt = 0; + for (i = 14; i >= 0; i--) + { + + if (((a >> i) & 1) == ((a >> 15) & 1)) + { + cnt++; + } + else + { + break; + } + } + return cnt; +} +inline UWord32 clrs32(UWord32 a) { + int i; + UWord32 cnt=0; + for ( i = 30; i >= 0; i--) + { + + if ( ((a>>i)&1) == ((a>>31)&1) ) + { + cnt++; + } + else + { + break; + } + } + return cnt; +} + +inline UWord32 sra32(Word32 a, UWord32 b) +{ + return a >> b; +} + +inline Word32 mult_32_16_32(Word32 vin1, Word16 vin2) +{ + return (Word32)(((Word64)vin1 * (Word64)vin2) >> 16); +} + +inline Word32 mult_r_32_16_32(Word32 vin1, Word16 vin2) +{ + Word64 round_factor = 1 << 15; + return (Word32)(((Word64)vin1 * (Word64)vin2 + round_factor) >> 16); +} + +inline Word32 mult_32_Q31_32(Word32 vin1, Word32 vin2) +{ + return (Word32)(((Word64)vin1 * (Word64)vin2) >> 31); +} + +inline Word32 mult_r_32_Q31_32(Word32 vin1, Word32 vin2) +{ + Word64 round_factor = 1 << 30; + return (Word32)(((Word64)vin1 * (Word64)vin2 + round_factor) >> 31); +} + +inline Word32 mult_32_Q15_32(Word32 vin1, Word16 vin2) +{ + Word64 tmp = ((Word64)vin1 * (Word64)vin2); + return (Word32)(tmp >> 15); +} + +inline Word32 mult_r_32_Q15_32(Word32 vin1, Word16 vin2) +{ + Word64 round_factor = 1 << 14; + Word64 tmp = ((Word64)vin1 * (Word64)vin2); + return (Word32)((tmp + round_factor) >> 15); +} + +inline Word32 mac_r_32_Q15_32(Word32 acc, Word32 vin1, Word16 vin2) +{ + Word64 round_factor = 1 << 14; + Word64 tmp = ((Word64)vin1 * (Word64)vin2); + return (Word32)(acc + ((tmp + round_factor) >> 15)); +} + +inline Word32 mac_r_32_16_32(Word32 acc, Word32 vin1, Word16 vin2) +{ + Word64 round_factor = 1 << 15; + Word64 tmp = ((Word64)vin1 * (Word64)vin2); + return (Word32)(acc + ((tmp + round_factor) >> 16)); +} + +inline Word32 mac_16_16_32(Word32 vin, Word16 vin1, Word16 vin2) +{ + Word32 vout = vin + (Word32)vin1 * (Word32)vin2; + return vout; +} +/* 32-bit logical left shift or arithmetic right shift*/ +inline Word32 L_shl(Word32 L_var1, Word16 var2) +{ + + Word32 L_var_out = 0L; + //int Overflow = 0; + + if (var2 <= 0) + { + if (var2 < -32) + var2 = -32; + var2 = -var2; + //L_var_out = L_shr(L_var1, var2); + if (var2 >= 31) + { + L_var_out = (L_var1 < 0L) ? -1 : 0; + } + else + { + if (L_var1 < 0) + { + L_var_out = ~((~L_var1) >> var2); + } + else + { + L_var_out = L_var1 >> var2; + } + } + } + else + { + for (; var2 > 0; var2--) + { + if (L_var1 > (Word32)0X3fffffffL) + { + //Overflow = 1; + L_var_out = MAX_32; + break; + } + else + { + if (L_var1 < (Word32)0xc0000000L) + { + //Overflow = 1; + L_var_out = MIN_32; + break; + } + } + L_var1 *= 2; + L_var_out = L_var1; + } + } + + return (L_var_out); +} + +inline Word32 L_shr(Word32 L_var1, Word16 var2) +{ + Word32 L_var_out; + + if (var2 < 0) + { + if (var2 < -32) + var2 = -32; + var2 = -var2; + L_var_out = L_shl(L_var1, var2); + } + else + { + if (var2 >= 31) + { + L_var_out = (L_var1 < 0L) ? -1 : 0; + } + else + { + if (L_var1 < 0) + { + L_var_out = ~((~L_var1) >> var2); + } + else + { + L_var_out = L_var1 >> var2; + } + } + } + + return (L_var_out); +} + + +inline Word32 L_add(Word32 L_var1, Word32 L_var2) +{ + Word32 L_var_out; + int Overflow = 0; + + L_var_out = L_var1 + L_var2; + + if (((L_var1 ^ L_var2) & 0x80000000L) == 0) + { + if ((L_var_out ^ L_var1) & 0x80000000L) + { + L_var_out = (L_var1 < 0) ? 0x80000000L : 0x7fffffffL; + Overflow = 1; + } + } + if (Overflow == 1) + { + //printf("LaddÒç³ö\n"); + } + return (L_var_out); +} + +inline Word32 L_sub(Word32 L_var1, Word32 L_var2) +{ + Word32 L_var_out; + + L_var_out = L_var1 - L_var2; + + if (((L_var1 ^ L_var2) & MIN_32) != 0) + { + if ((L_var_out ^ L_var1) & MIN_32) + { + L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32; + //printf("LsubÒç³ö\n"); + } + } + return (L_var_out); +} + +inline Word32 L_add_half(Word32 L_var1, Word32 L_var2) +{ + return (L_add(L_var1, L_var2)) >> 1; +} + +inline Word32 L_sub_half(Word32 L_var1, Word32 L_var2) +{ + return (L_sub(L_var1, L_var2)) >> 1; +} + +inline Word16 abs16(Word16 x) +{ + if (x < 0) + { + if (x == MIN_16) + { + return MAX_16; + } + else + { + return -x; + } + + } + else + { + return x; + } +} +inline Word32 abs32(Word32 x) +{ + if (x < 0) + { + if (x == MIN_32) + { + return MAX_32; + } + else + { + return -x; + } + + } + else + { + return x; + } +} +inline Word16 convert_q31_q15_u(Word32 x) +{ + return (x + 0x8000) >> 16; +} +inline Word32 L_mult(Word16 var1, Word16 var2) +{ + Word32 L_var_out; + L_var_out = (Word32)var1 * (Word32)var2; + + if (L_var_out != (Word32)0x40000000L) + { + L_var_out *= 2; + } + else + { + L_var_out = 0x7fffffffL; + } + + return (L_var_out); +} +inline Word32 L_mac(Word32 L_var3, Word16 var1, Word16 var2) +{ + Word32 L_var_out; + Word32 L_product; + + L_product = L_mult(var1, var2); + L_var_out = L_add(L_var3, L_product); + + return (L_var_out); +} +inline Word32 L_msu(Word32 L_var3, Word16 var1, Word16 var2) +{ + Word32 L_var_out; + Word32 L_product; + + L_product = L_mult(var1, var2); + L_var_out = (L_var3 - L_product); + + return (L_var_out); +} +/* Multiply var1 by var2 and shift the result left by 1. Add the 32 bit + result to L_var3 with saturation. Round the LS 16 bits of the result + into the MS 16 bits with saturation and shift the result right by 16. */ +inline Word16 mac_r(Word32 L_var3, Word16 var1, Word16 var2) +{ + Word16 var_out; + + L_var3 = L_mac(L_var3, var1, var2); + L_var3 = L_add(L_var3, (Word32)0x00008000L); + var_out = (L_var3) >> 16; + + return (var_out); +} +inline Word16 msu_r(Word32 L_var3, Word16 var1, Word16 var2) +{ + Word16 var_out; + + L_var3 = L_msu(L_var3, var1, var2); + L_var3 = L_add(L_var3, (Word32)0x00008000L); + var_out = (L_var3) >> 16; + + return (var_out); +} +#endif + + + +/* below functions needs to be further optimized */ +inline Word32 L_negate(Word32 L_var1) +{ + Word32 L_var_out; + + L_var_out = (L_var1 == MIN_32) ? MAX_32 : -L_var1; + + return (L_var_out); +} + +inline UWord32 sll32(UWord32 a, UWord32 b) +{ + return a << b; +} + +inline Word16 saturate(Word32 vin) +{ + Word16 vout; + + if (vin > MAX_16) { + vout = MAX_16; + } + else if (vin < MIN_16) { + vout = MIN_16; + } + else { + vout = (Word16)vin; + } + + return vout; +} + +inline Word16 add_s_16(Word16 vin1, Word16 vin2) +{ + Word16 vout; + Word32 tmp; + + tmp = (Word32)vin1 + (Word32)vin2; + vout = saturate(tmp); + + return (vout); +} + +inline Word16 sub_s_16(Word16 vin1, Word16 vin2) +{ + Word16 vout; + Word32 tmp; + + tmp = (Word32)vin1 - (Word32)vin2; + vout = saturate(tmp); + + return (vout); +} + +inline Word16 mult_16_shift(Word16 vin1, Word16 vin2, Word32 shift) +{ + Word32 tmp; + Word16 vout; + + tmp = (Word32)vin1 * (Word32)vin2 >> shift; + + vout = saturate(tmp); + return vout; +} + +inline Word16 mult_r_16_shift(Word16 vin1, Word16 vin2, Word32 shift) +{ + Word32 tmp; + Word32 round_factor; + Word16 vout; + + round_factor = 1 << (shift - 1); + + tmp = (Word32)vin1 * (Word32)vin2; + tmp = (tmp + round_factor) >> shift; + + vout = saturate(tmp); + return vout; +} + +inline Word32 mult_32_shift(Word32 vin1, Word32 vin2, Word32 shift) +{ + Word64 tmp; + Word32 vout; + + tmp = (Word64)vin1 * (Word64)vin2; + vout = (Word32)(tmp >> shift); + return vout; +} + +inline Word16 asr_r_16(Word16 vin, Word32 shift) +{ + Word16 vout; + Word32 round_factor = 1 << (shift - 1); + + vout = (vin + round_factor) >> shift; + return vout; +} + +inline Word32 asr_r_32(Word32 vin, Word32 shift) +{ + Word32 vout; + Word32 round_factor = 1 << (shift - 1); + + vout = (vin + round_factor) >> shift; + return vout; +} +inline Word16 norm32_l(Word32 x) +{ + if (x==0) + { + return 0; + } + else + { + return (Word16)clrs32(x); + } + +} + +inline Word64 mac_32_32_64(Word32 vin1, Word32 vin2, Word64 vout) +{ + vout = vout + (Word64)vin1 * (Word64)vin1; + if (vout >= 0x80000000) + { + vout = 0x7FFFFFF; + } + return vout; +} + + +inline Word16 norm16_l(Word16 x) +{ + if (x == 0) + { + return 0; + } + else + { + return clrs16(x); + } +} + +inline Word16 negate(Word16 var1) +{ + Word16 var_out; + + var_out = (var1 == MIN_16) ? MAX_16 : -var1; + + return (var_out); +} + +inline Word16 lshr(Word16 var1, Word16 var2) { + Word16 var_out; + + + var_out = var1 >> 1; + var_out = var_out & 0x7fff; + var_out = var_out >> (var2 - 1); + + //printf("\noutput=%d %d\n", (Word16)__nds__srl16(var1, var2), var_out); + return (var_out); +} +#define cplxMult32_16_32(r, i, a, b, c, d) \ + do \ + { \ + r =(( ( (mult_32_16_32(a, c)) ) - ( (mult_32_16_32(b, d)) ) )); \ + i =(( ( (mult_32_16_32(a, d)) ) + ( (mult_32_16_32(b, c)) ) )); \ + } while (0) + +#endif //#if (ALG_LC3_ENABLE) + +#endif diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/ltpf_decoder.h b/b91/b91m_ble_sdk/algorithm/lc3/src/ltpf_decoder.h new file mode 100755 index 0000000..f101594 --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/ltpf_decoder.h @@ -0,0 +1,16 @@ +#ifndef _LTPF_DECODER_H +#define _LTPF_DECODER_H + +#include "../inc/lc3_dec.h" + +#if (ALG_LC3_ENABLE) + +#ifdef FIXED_POINT +LC3DEC_Error dec_ltpf_fix(LC3_DEC_STRU* dec, Word32* x, Word32 nbits, Word32* x_ltpf); +#else +LC3DEC_Error dec_ltpf(LC3_DEC_STRU* dec, double* x, Word32 nbits, double* x_ltpf); +#endif + +#endif //#if (ALG_LC3_ENABLE) + +#endif diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/mdct_decoder.h b/b91/b91m_ble_sdk/algorithm/lc3/src/mdct_decoder.h new file mode 100755 index 0000000..bcf0ed7 --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/mdct_decoder.h @@ -0,0 +1,16 @@ +#ifndef _MDCT_DECODER_H +#define _MDCT_DECODER_H + +#include "../inc/lc3_dec.h" + +#if (ALG_LC3_ENABLE) + +#ifdef FIXED_POINT +LC3DEC_Error dec_imdct_fix(LC3_DEC_STRU* dec, Word32* in, Word32* out, Word16* exp); +#else +LC3DEC_Error dec_imdct(LC3_DEC_STRU* dec, double* in, double* out); +#endif + +#endif + +#endif diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/noise_filling.h b/b91/b91m_ble_sdk/algorithm/lc3/src/noise_filling.h new file mode 100755 index 0000000..93a541d --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/noise_filling.h @@ -0,0 +1,18 @@ +#ifndef _NOISE_FILLING_H +#define _NOISE_FILLING_H + +#include "../inc/lc3_dec.h" + +#if (ALG_LC3_ENABLE) + +#ifdef FIXED_POINT +#define NOISEFILLING_Q (15) +LC3DEC_Error dec_noisefilling_fix(LC3_DEC_STRU* dec, Word32* Xq); + +#else +LC3DEC_Error dec_noisefilling(LC3_DEC_STRU* dec, double* Xq); +#endif + +#endif //#if (ALG_LC3_ENABLE) + +#endif diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/residual_decoder.h b/b91/b91m_ble_sdk/algorithm/lc3/src/residual_decoder.h new file mode 100755 index 0000000..b0ed68c --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/residual_decoder.h @@ -0,0 +1,18 @@ +#ifndef _RESIDUAL_DECODER_H +#define _RESIDUAL_DECODER_H + +#include "../inc/lc3_dec.h" + +#if (ALG_LC3_ENABLE) + +#define RESIDUAL_Q (15) +#define RESIDUAL_A (3 << (RESIDUAL_Q - 4)) // 0.1875 +#define RESIDUAL_B (5 << (RESIDUAL_Q - 4)) // 0.3125 + +LC3DEC_Error dec_residual_fix(Word16* X_q, Word16 N_E, Word16* resBits, Word16* nResBits, Word32* X_q_residual); + +LC3DEC_Error dec_residual(Word16* X_q, Word16 N_E, Word16* resBits, Word16* nResBits, double* X_q_residual); + +#endif //#if (ALG_LC3_ENABLE) + +#endif diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/sns_decoder.h b/b91/b91m_ble_sdk/algorithm/lc3/src/sns_decoder.h new file mode 100755 index 0000000..d283ced --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/sns_decoder.h @@ -0,0 +1,15 @@ +#ifndef _SNS_DECODER_H +#define _SNS_DECODER_H + +#include "../inc/lc3_dec.h" +#if (ALG_LC3_ENABLE) + +#ifdef FIXED_POINT +LC3DEC_Error dec_sns_fix(LC3_DEC_STRU* dec, Word32* X_s, Word32* X); +#else +LC3DEC_Error dec_sns(LC3_DEC_STRU* dec, double* X_s, double* X); +#endif + +#endif //#if (ALG_LC3_ENABLE) + +#endif diff --git a/b91/b91m_ble_sdk/algorithm/lc3/src/tns_decoder.h b/b91/b91m_ble_sdk/algorithm/lc3/src/tns_decoder.h new file mode 100755 index 0000000..357d33b --- /dev/null +++ b/b91/b91m_ble_sdk/algorithm/lc3/src/tns_decoder.h @@ -0,0 +1,15 @@ +#ifndef _TNS_DECODER_H +#define _TNS_DECODER_H + +#include "../inc/lc3_dec.h" +#if (ALG_LC3_ENABLE) + +#ifdef FIXED_POINT +LC3DEC_Error dec_tns_fix(LC3_DEC_STRU* dec, Word32* Xq); +#else +LC3DEC_Error dec_tns(LC3_DEC_STRU* dec, double* Xq); +#endif + +#endif //#if (ALG_LC3_ENABLE) + +#endif diff --git a/b91/b91m_ble_sdk/application/app/usbaud.c b/b91/b91m_ble_sdk/application/app/usbaud.c new file mode 100755 index 0000000..25397e0 --- /dev/null +++ b/b91/b91m_ble_sdk/application/app/usbaud.c @@ -0,0 +1,284 @@ +/******************************************************************************************************** + * @file usbaud.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "drivers.h" +#include "usbaud.h" +#include "application/usbstd/usb.h" +#include "application/usbstd/AudioClassCommon.h" +#include "application/rf_frame.h" + +/************************************************* + * g_audio_hid_chg: + * 0x00: no event + * 0x01: speaker volume change + * 0x02: speaker mute change + * 0x11: microphone volume change + * 0x12: microphone mute change + *************************************************/ + +static speaker_setting_t speaker_setting; +static mic_setting_t mic_setting; +void usbaud_set_audio_mode(int iso_en, int mono_en) { + SET_FLD(reg_usb_ep_ctrl(USB_EDP_MIC), FLD_USB_EP_EOF_ISO | FLD_USB_EP_MONO); +} + +#if 0 +void usbaud_hid_report(char format, char volume) { + unsigned char sAudioHidReport[] = { 0x01,/* report ID */ + format,/*[0]:play/pause, + [1]:scan next track, + [2]:scan previous track, + [3]:stop, + [4]:play, + [5]:pause, + [6]:fast forward, + [7]:rewind, + */ + volume /*[0]:volume up + [1]:volume down + [2]:mute + [3:7] 0; + */ + }; + WriteEndPoint(EDP_ID_AUDIO_HID, sAudioHidReport, sizeof(sAudioHidReport)); +} +#endif + + +#if(USB_SPEAKER_ENABLE || USB_MIC_ENABLE) // use for volumn control, mute, next, prev track, move to mouse hid +int usbaud_hid_report(u8 cmd, u8 vol){ + if (usbhw_is_ep_busy(USB_EDP_AUDIO_IN)) + return 0; + reg_usb_ep_ptr(USB_EDP_AUDIO_IN) = 0; + + // please refer to keyboard_report_desc + reg_usb_ep_dat(USB_EDP_AUDIO_IN) = USB_HID_AUDIO; + reg_usb_ep_dat(USB_EDP_AUDIO_IN) = cmd; + reg_usb_ep_dat(USB_EDP_AUDIO_IN) = vol; + + reg_usb_ep_ctrl(USB_EDP_AUDIO_IN) = FLD_EP_DAT_ACK; // ACK + return 1; +} +#endif + +#if 0 +u8 usbaud_handle_report(u8 c) { + if (USB_REPORT_NO_EVENT == c) { + return USB_REPORT_NO_EVENT; + } + if(reg_usb_ep_ctrl(USB_EDP_AUDIO) & FLD_USB_EP_BUSY) + return c; + + if(USB_REPORT_RELEASE == c){ + usbaud_hid_report(0, 0); + return USB_REPORT_NO_EVENT; + }else{ + usbaud_hid_report((c < 0x10) ? (1 << c) : 0 + ,(c < 0x10) ? 0 : (1 << (c & 0x0f))); + return USB_REPORT_RELEASE; + } +} +#endif + +static u16 usbaud_cal_speaker_step(s16 vol){ + if(vol < SPEAKER_VOL_MIN) + return 0; + return (vol - SPEAKER_VOL_MIN) / SPEAKER_VOL_RES; +} + +static u16 usbaud_cal_mic_step(s16 vol){ + if(vol < MIC_VOL_MIN) + return 0; + return (vol - MIC_VOL_MIN) / MIC_VOL_RES; +} + +void usbaud_set_speaker_vol(s16 vol){ + speaker_setting.vol_cur = vol; + speaker_setting.vol_step = usbaud_cal_speaker_step(vol); +} + +void usbaud_set_mic_vol(s16 vol){ + mic_setting.vol_cur = vol; + mic_setting.vol_step = usbaud_cal_mic_step(vol); +} + +usb_audio_status_t g_usb_audio_status; + +u8 usbaud_speaker_vol_get(void){ + //return ((g_usb_audio_status.speaker_mute << 7) | g_usb_audio_status.speaker_vol); + return (speaker_setting.mute << 7) | (speaker_setting.vol_step & 0x7f); +} + +u8 usbaud_mic_vol_get(void){ + //return ((g_usb_audio_status.speaker_mute << 7) | g_usb_audio_status.speaker_vol); + return (mic_setting.mute << 7) | (mic_setting.vol_step & 0x7f); +} + +void usbaud_mic_en(int en) { + mic_setting.mute = en; +} + +volatile int aaa_audio_intf_set = 0; +int usb_audio_class_out_intf_proc(u8 type, u8 feature_id){ + int ret = 0; + usb_audio_status_t *p_aud = &g_usb_audio_status; + + aaa_audio_intf_set = 0; + aaa_audio_intf_set = (type << 8); + aaa_audio_intf_set |= feature_id; + switch (type) { + // mute control and sample + case 0x01: + switch (feature_id) { + case 0x00://set sample frequency + break; + case AUDIO_FEATURE_ID_SPEAKER:// Feature ID 0x02, Speaker + p_aud->speaker_mute = usbhw_read_ctrl_ep_data(); + p_aud->change |= 0x1; + break; + case AUDIO_FEATURE_ID_MIC:// Feature ID 0x05, MIC + p_aud->mic_mute = usbhw_read_ctrl_ep_data(); + p_aud->change |= 0x2; + break; + default: + ret = 1; + break; + } + break; + + // volume control + case 0x02: + switch (feature_id) { + case AUDIO_FEATURE_ID_SPEAKER: // Feature ID 0x02, Speaker + p_aud->speaker_vol = usbhw_read_ctrl_ep_data() + (usbhw_read_ctrl_ep_data() << 8); + p_aud->speaker_vol = ((p_aud->speaker_vol - (short)SPEAKER_VOL_MIN + SPEAKER_VOL_STEP) * (10 - 1)) >> 12; + if (p_aud->speaker_vol < 0){ + p_aud->speaker_vol = 0; + } + p_aud->change |= 0x4; + break; + + case AUDIO_FEATURE_ID_MIC: // Feature ID 0x05, MIC + p_aud->mic_vol = usbhw_read_ctrl_ep_data() + (usbhw_read_ctrl_ep_data() << 8); + p_aud->change |= 0x8; + break; + + default: + ret = 1; + break; + } + + default: + break; + } + return ret; +} + +// return -1 on fail, 0 on success +int usbaud_handle_set_speaker_cmd(int type) { + if(type == AUDIO_FEATURE_MUTE){ + speaker_setting.mute = usbhw_read_ctrl_ep_data(); + }else if(type == AUDIO_FEATURE_VOLUME){ + u16 val = usbhw_read_ctrl_ep_u16(); + usbaud_set_speaker_vol(val); + }else{ + return -1; + } + return 0; +} +// return -1 on fail, 0 on success +int usbaud_handle_set_mic_cmd(int type) { + if(type == AUDIO_FEATURE_MUTE){ + mic_setting.mute = usbhw_read_ctrl_ep_data(); + }else if(type == AUDIO_FEATURE_VOLUME){ + u16 val = usbhw_read_ctrl_ep_u16(); + usbaud_set_mic_vol(val); + }else{ + } + return 0; +} + +// return -1 on fail, 0 on success +int usbaud_handle_get_speaker_cmd(int req, int type) { + if(type == AUDIO_FEATURE_MUTE){ + usbhw_write_ctrl_ep_data(speaker_setting.mute); + }else if(type == AUDIO_FEATURE_VOLUME){ + switch (req) { + case AUDIO_REQ_GetCurrent: + usbhw_write_ctrl_ep_u16(speaker_setting.vol_cur); + break; + case AUDIO_REQ_GetMinimum: + usbhw_write_ctrl_ep_u16(SPEAKER_VOL_MIN); + break; + case AUDIO_REQ_GetMaximum: + usbhw_write_ctrl_ep_u16(SPEAKER_VOL_MAX); + break; + case AUDIO_REQ_GetResolution: + usbhw_write_ctrl_ep_u16(SPEAKER_VOL_RES); + break; + default: + return -1; + } + }else{ + return -1; + } + return 0; +} + +// return -1 on fail, 0 on success +int usbaud_handle_get_mic_cmd(int req, int type) { + if(type == AUDIO_FEATURE_MUTE){ + usbhw_write_ctrl_ep_data(mic_setting.mute); + }else if(type == AUDIO_FEATURE_VOLUME){ + switch (req) { + case AUDIO_REQ_GetCurrent: + usbhw_write_ctrl_ep_u16(mic_setting.vol_cur); + break; + case AUDIO_REQ_GetMinimum: + usbhw_write_ctrl_ep_u16(MIC_VOL_MIN); + break; + case AUDIO_REQ_GetMaximum: + usbhw_write_ctrl_ep_u16(MIC_VOL_MAX); + break; + case AUDIO_REQ_GetResolution: + usbhw_write_ctrl_ep_u16(MIC_VOL_RES); + break; + default: + return -1; + } + }else{ + return -1; + } + return 0; +} +void usbaud_init(void) { + if (USB_MIC_ENABLE && 1 == MIC_CHANNEL_COUNT) { + usbaud_set_audio_mode(1, 1); + } +#if (USB_SPEAKER_ENABLE) + usbaud_set_speaker_vol(SPEAKER_VOL_MAX); +#endif +#if (USB_MIC_ENABLE) + mic_setting.vol_cur = MIC_VOL_DEF; +#endif +} + diff --git a/b91/b91m_ble_sdk/application/app/usbaud.h b/b91/b91m_ble_sdk/application/app/usbaud.h new file mode 100755 index 0000000..21b2a29 --- /dev/null +++ b/b91/b91m_ble_sdk/application/app/usbaud.h @@ -0,0 +1,100 @@ +/******************************************************************************************************** + * @file usbaud.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include +#include +#include "tl_common.h" + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +extern "C" { +#endif + +// telink usb report ctrl command. used mixed with USB_REPORT_NO_EVENT +enum { + USB_AUD_PLAY_PAUSE = 0, + USB_AUD_NEXT_TRACK = 1, + USB_AUD_PREV_TRACK = 2, + USB_AUD_STOP = 3, + USB_AUD_PLAY = 4, + USB_AUD_PAUSE = 5, + USB_AUD_FAST_FWD = 6, + USB_AUD_REWIND = 7, + USB_AUD_VOL_INC = 0x10, + USB_AUD_VOL_DEC = 0x11, + USB_AUD_VOL_MUTE = 0x12, +}; + +#define AUDIO_FEATURE_ID_SPEAKER 0x02 +#define AUDIO_FEATURE_ID_MIC 0x05 + +typedef struct{ + s16 speaker_vol; + s16 mic_vol; + s8 speaker_mute; + s8 mic_mute; + s8 change; +}usb_audio_status_t; + + +typedef struct { + u16 vol_cur; + u16 vol_step; + u8 mute; +}speaker_setting_t; + + +typedef struct { + u16 vol_cur; + u16 vol_step; + u8 mute; +}mic_setting_t; + +#define AUDIO_VOLUME_STEP_MAX 11 + +#define MIC_VOL_MIN ((s16) 0x0000) /* Volume Minimum Value */ +#define MIC_VOL_MAX ((s16) 0x1e00) /* Volume Maximum Value */ +#define MIC_VOL_RES 0x0180 /* Volume Resolution */ +#define MIC_VOL_DEF 0x1800 /* Volume default */ +#define MIC_MAX_STEP (MIC_VOL_MAX / MIC_VOL_RES) + +#define SPEAKER_VOL_MIN ((s16) 0xa000) /* Volume Minimum Value */ +#define SPEAKER_VOL_MAX ((s16) 0x0300) /* Volume Maximum Value */ +#define SPEAKER_VOL_RES 0x0180 /* Volume Resolution */ +#define SPEAKER_VOL_DEF 0x8000 /* Volume default */ +#define SPEAKER_VOL_STEP 400 + +int usbaud_handle_set_speaker_cmd(int type); +int usbaud_handle_set_mic_cmd(int type); +int usbaud_handle_get_speaker_cmd(int req, int type); +int usbaud_handle_get_mic_cmd(int req, int type); +void usbaud_init(void); +u8 usbaud_speaker_vol_get(void); +u8 usbaud_mic_vol_get(void); +void usbaud_mic_en(int en); +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +} +#endif + diff --git a/b91/b91m_ble_sdk/application/app/usbaud_i.h b/b91/b91m_ble_sdk/application/app/usbaud_i.h new file mode 100755 index 0000000..6126ab9 --- /dev/null +++ b/b91/b91m_ble_sdk/application/app/usbaud_i.h @@ -0,0 +1,115 @@ +/******************************************************************************************************** + * @file usbaud_i.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + + +#include "drivers.h" +#include "usbaud.h" +#include "application/usbstd/AudioClassCommon.h" +#include "application/usbstd/usb.h" + + +#if 0 +static const USB_Descriptor_HIDReport_Datatype_t usbaud_report_desc[] = { + HID_RI_USAGE_PAGE(8, 0x0c), /* Consumer Page */ + HID_RI_USAGE(8, 0x01) , /* Consumer Controls */ + HID_RI_COLLECTION(8, 0x01) , /* Application */ + + HID_RI_REPORT_ID(8, 0x01) , /*Report ID*/ + + HID_RI_LOGICAL_MINIMUM(8, 0x00) , + HID_RI_LOGICAL_MAXIMUM(8, 0x01), + + HID_RI_USAGE(8, 0xcd), /* Play/Pause (toggle) */ + HID_RI_USAGE(8, 0xb5) , /* Next Track */ + HID_RI_USAGE(8, 0xb6) , /* Previous Track */ + HID_RI_USAGE(8, 0xb7) , /* Stop */ + + HID_RI_REPORT_SIZE(8, 0x01) , + HID_RI_REPORT_COUNT(8, 0x04), + HID_RI_INPUT(8, HID_IOF_VARIABLE), + HID_RI_LOGICAL_MINIMUM(8, 0x00), + HID_RI_LOGICAL_MAXIMUM(8, 0x01), + + HID_RI_USAGE(8, 0xb0), /* Play */ + HID_RI_USAGE(8, 0xb1) , /* Pause */ + HID_RI_USAGE(8, 0xb3) , /* Fast Forward */ + HID_RI_USAGE(8, 0xb4) , /* Rewind */ + + HID_RI_REPORT_SIZE(8, 0x01) , + HID_RI_REPORT_COUNT(8, 0x04), + HID_RI_INPUT(8, HID_IOF_NO_PREFERRED_STATE | HID_IOF_VARIABLE), + HID_RI_LOGICAL_MINIMUM(8, 0x00), + HID_RI_LOGICAL_MAXIMUM(8, 0x01), + HID_RI_USAGE(8, 0xe9), + HID_RI_USAGE(8, 0xea), + HID_RI_USAGE(8, 0xe2), + HID_RI_REPORT_SIZE(8, 0x01), + HID_RI_REPORT_COUNT(8, 0x03), + HID_RI_INPUT(8, HID_IOF_NO_PREFERRED_STATE | HID_IOF_VARIABLE), + HID_RI_REPORT_SIZE(8, 0x05), + HID_RI_REPORT_COUNT(8, 0x01), + HID_RI_INPUT(8, HID_IOF_CONSTANT), + HID_RI_END_COLLECTION(0), + HID_RI_USAGE_PAGE(16, 0xffa0), + HID_RI_USAGE(8, 0x01), + HID_RI_COLLECTION(8, 0x01), /* Application */ + + HID_RI_REPORT_ID(8, 0x02) , /*Report ID*/ + + HID_RI_USAGE(8, 0x01) , + HID_RI_LOGICAL_MINIMUM(8, 0x00), + HID_RI_LOGICAL_MAXIMUM(16, 0x00ff), + HID_RI_REPORT_SIZE(8, 0x08), + HID_RI_REPORT_COUNT(8, 0x02), + HID_RI_OUTPUT(8, HID_IOF_DATA), + HID_RI_USAGE(8, 0x02), /* mouse? */ + + HID_RI_REPORT_SIZE(8, 0x08) , + HID_RI_REPORT_COUNT(8, 0x02), + HID_RI_INPUT(8, HID_IOF_DATA), + HID_RI_END_COLLECTION(0), }; + +#endif + +//Definition of USB HID report descriptor +static const USB_Descriptor_HIDReport_Datatype_t usbaud_report_desc[] = { + 0x05, 0x0c, 0x09, 0x01, 0xa1, 0x01, + 0x85, 0x01, 0x15, 0x00, 0x25, 0x01, 0x09, 0xcd, 0x09, 0xb5, 0x09, 0xb6, + 0x09, 0xb7, 0x75, 0x01, 0x95, 0x04, 0x81, 0x02, 0x15, 0x00, 0x25, 0x01, + 0x09, 0xb0, 0x09, 0xb1, 0x09, 0xb3, 0x09, 0xb4, 0x75, 0x01, 0x95, 0x04, + 0x81, 0x22, 0x15, 0x00, 0x25, 0x01, 0x09, 0xe9, 0x09, 0xea, 0x09, 0xe2, + 0x75, 0x01, 0x95, 0x03, 0x81, 0x22, 0x75, 0x05, 0x95, 0x01, 0x81, 0x01, + 0xc0, 0x06, 0xa0, 0xff, 0x09, 0x01, 0xa1, 0x01, 0x85, 0x02, 0x09, 0x01, + 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x02, 0x91, 0x00, 0x09, + 0x02, 0x75, 0x08, 0x95, 0x02, 0x81, 0x00, 0xc0, }; + +static inline u8* usbaud_get_report_desc(void) { + return (u8*) (usbaud_report_desc); +} + +static inline u16 usbaud_get_report_desc_size(void) { + return sizeof(usbaud_report_desc); +} + + diff --git a/b91/b91m_ble_sdk/application/app/usbcdc.c b/b91/b91m_ble_sdk/application/app/usbcdc.c new file mode 100755 index 0000000..40129f4 --- /dev/null +++ b/b91/b91m_ble_sdk/application/app/usbcdc.c @@ -0,0 +1,321 @@ +/******************************************************************************************************** + * @file usbcdc.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#if(USB_CDC_ENABLE) + +#include "usbcdc.h" +#include "application/usbstd/usb.h" +#include "application/rf_frame.h" + + +void usbcdc_write32(u32 value); +void usbcdc_read32(u32* value); +int usbcdc_recvTimeoutCb(void* arg); + + +typedef struct { + u8 *rxBuf; + u8 *txBuf; + + /* Following variables are used in the RX more than CDC_TXRX_EPSIZE */ + ev_time_event_t timer; + u8 lastIndex; + + + u16 lenToSend; + u16 lastSendIndex; + + cdc_handlerFn_t rxCb; + cdc_handlerFn_t txCb; + +} cdc_ctrl_t; + +#ifdef STATIC_V_INST +cdc_ctrl_t cdc_vs; +#endif +cdc_ctrl_t *cdc_v; + + + + + +USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface = +{ + //.Config = + { + 0, //ControlInterfaceNumber + + CDC_TX_EPNUM, // DataINEndpointNumber + CDC_TXRX_EPSIZE, // DataINEndpointSize + false, // DataINEndpointDoubleBank + + CDC_RX_EPNUM, // DataOUTEndpointNumber + CDC_TXRX_EPSIZE, // DataOUTEndpointSize + false, // DataOUTEndpointDoubleBank + + CDC_NOTIFICATION_EPNUM, // NotificationEndpointNumber + CDC_NOTIFICATION_EPSIZE, // NotificationEndpointSize + false, // NotificationEndpointDoubleBank + }, +}; + +USB_ClassInfo_CDC_Device_t *CDCInterfaceInfo = &VirtualSerial_CDC_Interface; + + + + +void CDC_Device_ProcessControlRequest(u8 bRequest, u16 wValue, u16 wIndex, u16 wLength) +{ + + if (wIndex != CDCInterfaceInfo->Config.ControlInterfaceNumber) + return; + + switch (bRequest) + { + case CDC_REQ_GetLineEncoding: + + usbcdc_write32(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS); + usbhw_write_ctrl_ep_data(CDCInterfaceInfo->State.LineEncoding.CharFormat); + usbhw_write_ctrl_ep_data(CDCInterfaceInfo->State.LineEncoding.ParityType); + usbhw_write_ctrl_ep_data(CDCInterfaceInfo->State.LineEncoding.DataBits); + break; + + case CDC_REQ_SetLineEncoding: + + usbcdc_read32(&CDCInterfaceInfo->State.LineEncoding.BaudRateBPS); + CDCInterfaceInfo->State.LineEncoding.CharFormat = usbhw_read_ctrl_ep_data(); + CDCInterfaceInfo->State.LineEncoding.ParityType = usbhw_read_ctrl_ep_data(); + CDCInterfaceInfo->State.LineEncoding.DataBits = usbhw_read_ctrl_ep_data(); + + //EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo); + break; + + case CDC_REQ_SetControlLineState: + CDCInterfaceInfo->State.ControlLineStates.HostToDevice = wValue; + //EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo); + break; + + case CDC_REQ_SendBreak: + + break; + } +} + +void usbcdc_write32(u32 value) +{ + usbhw_write_ctrl_ep_data(value&0xff); + usbhw_write_ctrl_ep_data((value>>8)&0xff); + usbhw_write_ctrl_ep_data((value>>16)&0xff); + usbhw_write_ctrl_ep_data((value>>24)&0xff); +} + +void usbcdc_read32(u32* value) +{ + u32 temp = 0; + *value = usbhw_read_ctrl_ep_data(); + + temp = usbhw_read_ctrl_ep_data(); + *value = (temp << 8) | (*value); + temp = 0; + + temp = usbhw_read_ctrl_ep_data(); + *value = (temp << 16) | (*value); + temp = 0; + + temp = usbhw_read_ctrl_ep_data(); + *value = (temp << 24) | (*value); + +} + + +void usbcdc_init(void) +{ + /* Init UART parameters */ + CDCInterfaceInfo->State.LineEncoding.BaudRateBPS = 115200; + CDCInterfaceInfo->State.LineEncoding.CharFormat = 0; + CDCInterfaceInfo->State.LineEncoding.ParityType = 0; + CDCInterfaceInfo->State.LineEncoding.DataBits = 8; + + + cdc_v = &cdc_vs; + cdc_v->lastIndex = 0; + cdc_v->timer.cb = usbcdc_recvTimeoutCb; +} + + +void usbcdc_setRxBuf(u8 *buf) +{ + cdc_v->rxBuf = buf; +} + +void usbcdc_setCB(cdc_handlerFn_t rxFunc, cdc_handlerFn_t txCb) +{ + cdc_v->rxCb = rxFunc; + cdc_v->txCb = txCb; +} + +int usbcdc_recvTimeoutCb(void* arg) +{ + u8* p; + + cdc_v->lastIndex = 0; + + /* Clear the buffer */ + p = cdc_v->rxBuf; + cdc_v->rxBuf = NULL; + + /* Callback */ + if (cdc_v->rxCb) { + cdc_v->rxCb(p); + } + + return -1; +} + + +void usbcdc_recvData(void) +{ + u8 i; + u8 *p; + u8 len; + u8 fEnd = 0; + + /* No buffer */ + if (!cdc_v->rxBuf) { + while(1); + } + + if (!is_timer_expired(&cdc_v->timer)) { + ev_unon_timer(&cdc_v->timer); + } + + len = reg_usb_ep_ptr(CDC_RX_EPNUM & 0x07); + fEnd = (len == CDC_TXRX_EPSIZE) ? 0 : 1; + usbhw_reset_ep_ptr(CDC_RX_EPNUM); + + for (i = 0; i < len; i++) { + cdc_v->rxBuf[cdc_v->lastIndex++] = usbhw_read_ep_data(CDC_RX_EPNUM); + } + + if (fEnd) { + cdc_v->lastIndex = 0; + + /* Clear the buffer */ + p = cdc_v->rxBuf; + cdc_v->rxBuf = NULL; + + /* Callback */ + if (cdc_v->rxCb) { + cdc_v->rxCb(p); + } + } else { + ev_on_timer(&cdc_v->timer, 500); + } +} + +u8 T_BUF[60]; +u32 T_CNT; +u8 usbcdc_sendBulkData(void) +{ + u16 len; + + /* Wait until not busy */ + if (usbhw_is_ep_busy(CDC_TX_EPNUM)) { + /* Return to wait IRQ come again */ + return 0; + } + + /* Get the length to send in this bulk transaction */ + len = (cdc_v->lenToSend > CDC_TXRX_EPSIZE) ? CDC_TXRX_EPSIZE : cdc_v->lenToSend; + cdc_v->lenToSend -= len; + + if (len == 0) { + return 0; + } + + + reg_usb_ep_ptr(CDC_TX_EPNUM) = 0; + + /* Write data to USB fifo */ + foreach (i, len) { + T_BUF[i] = cdc_v->txBuf[cdc_v->lastSendIndex]; + reg_usb_ep_dat(CDC_TX_EPNUM) = cdc_v->txBuf[cdc_v->lastSendIndex++]; + } + + /* Write ACK */ + reg_usb_ep_ctrl(CDC_TX_EPNUM) = FLD_EP_DAT_ACK; // ACK + u16 t = 0; + while(usbhw_is_ep_busy(CDC_TX_EPNUM)) { + if (t++ > 10000) { + T_CNT++; + reg_usb_ep_ctrl(CDC_TX_EPNUM) &= 0xfe; // clear bit(0) + } + }; + + /* TX transaction finish */ + if (cdc_v->lenToSend == 0) { + cdc_v->lenToSend = 0; + cdc_v->lastSendIndex = 0; + + if (cdc_v->txCb) { + EV_SCHEDULE_TASK(cdc_v->txCb, cdc_v->txBuf); + } + + cdc_v->txBuf = NULL; + } + + return len; +} + + + + + +usbcdc_sts_t usbcdc_sendData(u8 *buf, u8 len) +{ + if (cdc_v->txBuf) { + return USB_BUSY; + } + + /* Init the bulk transfer */ + cdc_v->lenToSend = len; + cdc_v->txBuf = buf; + cdc_v->lastSendIndex = 0; + + /* Send first bulk */ + usbcdc_sendBulkData(); + + usbhw_data_ep_ack(USB_EDP_CDC_OUT); + + return SUCCESS; + + +} + + +u8 usbcdc_isAvailable(void) +{ + return (cdc_v->txBuf == NULL); +} + + +#endif /* USB_CDC_ENABLE */ diff --git a/b91/b91m_ble_sdk/application/app/usbcdc.h b/b91/b91m_ble_sdk/application/app/usbcdc.h new file mode 100755 index 0000000..1d3a43f --- /dev/null +++ b/b91/b91m_ble_sdk/application/app/usbcdc.h @@ -0,0 +1,70 @@ +/******************************************************************************************************** + * @file usbcdc.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "application/usbstd/CDCClassCommon.h" +#include "application/usbstd/CDCClassDevice.h" +#include "common/types.h" +#include "common/bit.h" +#include "tl_common.h" +#include "drivers.h" + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) + extern "C" { +#endif + + +typedef void ( *cdc_handlerFn_t)( u8* pData); + +typedef struct { + u8 len; + u8 data[1]; +} usbcdc_txBuf_t; + + +typedef enum usbcdc_sts_e { + // success = 0 + USB_BUSY = 1, + USB_MULTIBLOCK, +} usbcdc_sts_t; + + +void CDC_Device_ProcessControlRequest(u8 bRequest, u16 wValue, u16 wIndex, u16 wLength); + +usbcdc_sts_t usbcdc_sendData(u8* buf, u8 len); +u8 usbcdc_sendBulkData(void); + +u8 usbcdc_isAvailable(void); +u8* usbcdc_getData(void); +void usbcdc_init(void); +void usbcdc_setCB(cdc_handlerFn_t rxFunc, cdc_handlerFn_t txCb); +void usbcdc_setRxBuf(u8 *buf); + + + + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) + } +#endif diff --git a/b91/b91m_ble_sdk/application/app/usbcdc_i.h b/b91/b91m_ble_sdk/application/app/usbcdc_i.h new file mode 100755 index 0000000..46f953e --- /dev/null +++ b/b91/b91m_ble_sdk/application/app/usbcdc_i.h @@ -0,0 +1,30 @@ +/******************************************************************************************************** + * @file usbcdc_i.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "usbcdc.h" +#include "drivers.h" +#include "application/usbstd/usb.h" + + + diff --git a/b91/b91m_ble_sdk/application/app/usbkb.c b/b91/b91m_ble_sdk/application/app/usbkb.c new file mode 100755 index 0000000..1a6146a --- /dev/null +++ b/b91/b91m_ble_sdk/application/app/usbkb.c @@ -0,0 +1,366 @@ +/******************************************************************************************************** + * @file usbkb.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "usbkb.h" +#include "usbmouse.h" +#include "application/usbstd/usb.h" +#include "application/usbstd/usbkeycode.h" +#include "application/rf_frame.h" + + +u8 usb_fifo[USB_FIFO_NUM][USB_FIFO_SIZE]; +u8 usb_ff_rptr = 0; +u8 usb_ff_wptr = 0; + +int usbkb_hid_report_normal(u8 ctrl_key, u8 *keycode); + +static u8 vk_sys_map[VK_SYS_CNT] = { + VK_POWER_V, VK_SLEEP_V, VK_WAKEUP_V +}; + +static vk_ext_t vk_media_map[VK_MEDIA_CNT] = { + {VK_W_SRCH_V}, + {VK_HOME_V}, + {VK_W_BACK_V}, + {VK_W_FORWRD_V}, + {VK_W_STOP_V}, + {VK_W_REFRESH_V}, + {VK_W_FAV_V}, + {VK_MEDIA_V}, + {VK_MAIL_V}, + {VK_CAL_V}, + {VK_MY_COMP_V}, + {VK_NEXT_TRK_V}, + {VK_PREV_TRK_V}, + {VK_STOP_V}, + {VK_PLAY_PAUSE_V}, + {VK_W_MUTE_V}, + {VK_VOL_UP_V}, + {VK_VOL_DN_V}, +}; + +enum{ + KB_NORMAL_RELEASE_MASK = BIT(0), + KB_SYS_RELEASE_MASK = BIT(1), + KB_MEDIA_RELEASE_MASK = BIT(2), +}; + + + +#define USBKB_BUFF_DATA_NUM 8 +//static +kb_data_t kb_dat_buff[USBKB_BUFF_DATA_NUM]; + +//static +u8 usbkb_wptr, usbkb_rptr; +static u32 usbkb_not_released; +static u32 usbkb_data_report_time; + +void usbkb_report_frame(void) +{ + if(usbkb_wptr != usbkb_rptr){ + kb_data_t *data = (kb_data_t *)(&kb_dat_buff[usbkb_rptr]); + usbkb_hid_report(data); + BOUND_INC_POW2(usbkb_rptr,USBKB_BUFF_DATA_NUM); + } + return; +} + +static void usbkb_release_normal_key(void){ + if(usbkb_not_released & KB_NORMAL_RELEASE_MASK){ + u8 normal_keycode[KEYBOARD_REPORT_KEY_MAX] = {0}; + if(usbkb_hid_report_normal(0, normal_keycode)){ + BM_CLR(usbkb_not_released, KB_NORMAL_RELEASE_MASK); + } + } +} + +static void usbkb_release_sys_key(void){ + if(usbkb_not_released & KB_SYS_RELEASE_MASK){ + u32 release_data = 0; + if(usbmouse_hid_report(USB_HID_KB_SYS, (u8*)(&release_data), 1)){ + BM_CLR(usbkb_not_released, KB_SYS_RELEASE_MASK); + } + } +} + +static void usbkb_release_media_key(void){ + if(usbkb_not_released & KB_MEDIA_RELEASE_MASK){ + u8 ext_keycode[MOUSE_REPORT_DATA_LEN] = {0}; + if(usbmouse_hid_report(USB_HID_KB_MEDIA, ext_keycode, MEDIA_REPORT_DATA_LEN)){ + BM_CLR(usbkb_not_released, KB_MEDIA_RELEASE_MASK); + } + } +} + +static void usbkb_release_keys(void){ + usbkb_release_sys_key(); + usbkb_release_normal_key(); + usbkb_release_media_key(); +} + +void usbkb_release_check(){ + if(usbkb_not_released && clock_time_exceed(usbkb_data_report_time, USB_KEYBOARD_RELEASE_TIMEOUT)){ + usbkb_release_keys(); // release keys + } + +} + + +int usbkb_separate_key_types(u8 *keycode, u8 cnt, u8 *normal_key, u8 *ext_key){ + + int normal_cnt = 0; + foreach(i, cnt){ + if(keycode[i] >= VK_EXT_START && keycode[i] < VK_EXT_END){ + *ext_key = keycode[i]; + }else{ + normal_key[normal_cnt++] = keycode[i]; + } + } + return normal_cnt; +} + +int usbkb_hid_report_normal(u8 ctrl_key, u8 *keycode){ + + if(usbhw_is_ep_busy(USB_EDP_KEYBOARD_IN)){ + + u8 *pData = (u8 *)&usb_fifo[usb_ff_wptr++ & (USB_FIFO_NUM - 1)]; + pData[0] = DAT_TYPE_KB; + pData[1] = ctrl_key; + memcpy(pData + 2, keycode, 6); + + int fifo_use = (usb_ff_wptr - usb_ff_rptr) & (USB_FIFO_NUM*2-1); + if (fifo_use > USB_FIFO_NUM) { + usb_ff_rptr++; + //fifo overflow, overlap older data + } + + return 0; + } + + reg_usb_ep_ptr(USB_EDP_KEYBOARD_IN) = 0; + + + + +#if USB_SOFTWARE_CRC_CHECK + + unsigned char crc_in[KEYBOARD_REPORT_KEY_MAX+2]; + unsigned short crc; + unsigned int crch; + + crc_in[0] = ctrl_key; + crc_in[1] = 0; + foreach(i, KEYBOARD_REPORT_KEY_MAX){ + crc_in[i+2] = keycode[i]; + } + crc = USB_CRC16 (crc_in, KEYBOARD_REPORT_KEY_MAX+2); + crch = crc >> 8; + + if ((crch==0x06) || (crch==0x04) || (crch == 0x00)) + { + unsigned int tmp = crc_in[2]; + crc_in[2] = crc_in[3]; + crc_in[3] = tmp; + } + // please refer to keyboard_report_desc + foreach(i, (KEYBOARD_REPORT_KEY_MAX+2)){ + reg_usb_ep_dat(USB_EDP_KEYBOARD_IN) = crc_in[i]; + } + +#else + + // please refer to keyboard_report_desc + reg_usb_ep_dat(USB_EDP_KEYBOARD_IN) = ctrl_key; + reg_usb_ep_dat(USB_EDP_KEYBOARD_IN) = 0;//resv + foreach(i, KEYBOARD_REPORT_KEY_MAX){ + reg_usb_ep_dat(USB_EDP_KEYBOARD_IN) = keycode[i]; + } + +#endif +// reg_usb_ep_ctrl(USB_EDP_KEYBOARD_IN) = FLD_EP_DAT_ACK; // ACK + reg_usb_ep_ctrl(USB_EDP_KEYBOARD_IN) = FLD_EP_DAT_ACK | (edp_toggle[USB_EDP_KEYBOARD_IN] ? FLD_USB_EP_DAT1 : FLD_USB_EP_DAT0); // ACK + edp_toggle[USB_EDP_KEYBOARD_IN] ^= 1; + + return 1; +} + +static inline void usbkb_report_normal_key(int ctrl_key, u8 *keycode, int cnt){ + if(cnt > 0 || ctrl_key){ + if(usbkb_hid_report_normal(ctrl_key, keycode)){ + BM_SET(usbkb_not_released, KB_NORMAL_RELEASE_MASK); + } + }else{ + usbkb_release_normal_key(); + } +} + +static inline void usbkb_report_sys_key(u8 ext_key){ + if(ext_key >= VK_SYS_START && ext_key < VK_SYS_END){ + int idx = ext_key - VK_SYS_START; + if(usbmouse_hid_report(USB_HID_KB_SYS, (u8*)(&vk_sys_map[idx]), 1)){ // assert sys key len == 1, check descriptor + BM_SET(usbkb_not_released, KB_SYS_RELEASE_MASK); + } + }else{ + usbkb_release_sys_key(); + } +} + +static inline void usbkb_report_media_key(u8 ext_key){ + if(ext_key >= VK_MEDIA_START && ext_key < VK_MEDIA_END){ + + u8 ext_keycode[MOUSE_REPORT_DATA_LEN] = {0}; + + int idx = ext_key - VK_MEDIA_START; + foreach(i, VK_EXT_LEN){ + ext_keycode[i] = vk_media_map[idx].val[i]; + } + if(usbmouse_hid_report(USB_HID_KB_MEDIA, ext_keycode, MEDIA_REPORT_DATA_LEN)){ + BM_SET(usbkb_not_released, KB_MEDIA_RELEASE_MASK); + } + }else{ + usbkb_release_media_key(); + } +} + + +void usbkb_report_consumer_key(u16 consumer_key) +{ + if(consumer_key){ + + u8 ext_keycode[MOUSE_REPORT_DATA_LEN] = {0}; + + foreach(i, VK_EXT_LEN){ + ext_keycode[i] = consumer_key; + consumer_key >>=8; + } + + if(usbmouse_hid_report(USB_HID_KB_MEDIA, ext_keycode, MEDIA_REPORT_DATA_LEN)){ + BM_SET(usbkb_not_released, KB_MEDIA_RELEASE_MASK); + } + }else{ + usbkb_release_media_key(); + } + + + usbkb_data_report_time = clock_time(); + +} + + +int kb_is_data_same(kb_data_t *a, kb_data_t *b){ + if(!a || !b){ + return 0; + } + if((a->cnt != b->cnt) || (a->ctrl_key != b->ctrl_key)) + return 0; + foreach(i, a->cnt){ + if(a->keycode[i] != b->keycode[i]){ + return 0; + } + } + return 1; +} + +static inline int usbkb_check_repeat_and_save(kb_data_t *data){ + static kb_data_t last_data; + int same = kb_is_data_same(&last_data, data); + if(!same){ + ((u32*) (&last_data))[0] = ((u32*) (data))[0]; + ((u32*) (&last_data))[1] = ((u32*) (data))[1]; + } + return same; +} + + +void usbkb_hid_report(kb_data_t *data){ + u8 ext_key = VK_EXT_END, normal_key_cnt = 0; + u8 normal_keycode[KEYBOARD_REPORT_KEY_MAX] = {0}; + + if(data->cnt > KB_RETURN_KEY_MAX){ // must, in case bad packets + return; + } + + /* http://msdn.microsoft.com/en-us/windows/hardware/gg462991.aspx + It is also important to notice that any re-triggering of events should be done by software timers in the host system and not by hardware timers in the device itself. + For example, if the user keeps pressing the Volume Increment button, the device should only generate one input report with this state information + */ + if((data->cnt > 0 || data->ctrl_key) && usbkb_check_repeat_and_save(data)){ + if(usbkb_not_released){ + usbkb_data_report_time = clock_time(); + return; + } + } + + + if(data->cnt > 0){ + normal_key_cnt = usbkb_separate_key_types(data->keycode, data->cnt, normal_keycode, &ext_key); + } + + usbkb_report_normal_key(data->ctrl_key, normal_keycode, normal_key_cnt); + usbkb_report_sys_key(ext_key); + usbkb_report_media_key(ext_key); + + usbkb_data_report_time = clock_time(); +} + + +int usb_hid_report_fifo_proc(void) +{ + if(usb_ff_rptr == usb_ff_wptr){ + return 0; + } + + u8 *pData = (u8 *)&usb_fifo[usb_ff_rptr & (USB_FIFO_NUM - 1)]; + + if(pData[0] == DAT_TYPE_KB){ + if(usbhw_is_ep_busy(USB_EDP_KEYBOARD_IN)){ + return 0; + } + else{ + + usbkb_hid_report_normal(pData[1], pData + 2); + + usb_ff_rptr ++; + + return 1; + } + } + else if(pData[0] == DAT_TYPE_MOUSE){ + if(usbhw_is_ep_busy(USB_EDP_MOUSE)){ + return 0; + } + else{ + + usbmouse_hid_report(pData[1], pData + 4, pData[2]); + + usb_ff_rptr ++; + + return 1; + } + } + + + return 0; +} + + diff --git a/b91/b91m_ble_sdk/application/app/usbkb.h b/b91/b91m_ble_sdk/application/app/usbkb.h new file mode 100755 index 0000000..0e3da28 --- /dev/null +++ b/b91/b91m_ble_sdk/application/app/usbkb.h @@ -0,0 +1,70 @@ +/******************************************************************************************************** + * @file usbkb.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include +#include +#include "tl_common.h" +#include "drivers.h" + +#include "application/keyboard/keyboard.h" + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +extern "C" { +#endif + + +#define DAT_TYPE_KB 1 +#define DAT_TYPE_MOUSE 2 + +#define USB_FIFO_NUM 4 +#define USB_FIFO_SIZE 8 + +extern u8 usb_fifo[USB_FIFO_NUM][USB_FIFO_SIZE]; +extern u8 usb_ff_rptr; +extern u8 usb_ff_wptr; + + + +#define KEYBOARD_REPORT_KEY_MAX 6 +typedef struct { + u8 Modifier; /**< Keyboard modifier byte, indicating pressed modifier keys (a combination of + * \c HID_KEYBOARD_MODIFER_* masks). + */ + u8 Reserved; /**< Reserved for OEM use, always set to 0. */ + u8 KeyCode[KEYBOARD_REPORT_KEY_MAX]; /**< Key codes of the currently pressed keys. */ +} usbkb_hid_report_t; + + +void usbkb_report_consumer_key(u16 consumer_key); + +void usbkb_hid_report(kb_data_t *data); + +int usb_hid_report_fifo_proc(void); + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +} +#endif + diff --git a/b91/b91m_ble_sdk/application/app/usbkb_i.h b/b91/b91m_ble_sdk/application/app/usbkb_i.h new file mode 100755 index 0000000..44a3eec --- /dev/null +++ b/b91/b91m_ble_sdk/application/app/usbkb_i.h @@ -0,0 +1,130 @@ +/******************************************************************************************************** + * @file usbkb_i.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "usbkb.h" +#include "application/usbstd/usb.h" + +/** HID class report descriptor. This is a special descriptor constructed with values from the + * USBIF HID class specification to describe the reports and capabilities of the HID device. This + * descriptor is parsed by the host and its contents used to determine what data (and in what encoding) + * the device will send, and what it may be sent back from the host. Refer to the HID specification for + * more details on HID report descriptors. + */ +static const USB_Descriptor_HIDReport_Datatype_t keyboard_report_desc[] = { + HID_DESCRIPTOR_KEYBOARD(KEYBOARD_REPORT_KEY_MAX), +}; + +static inline u8* usbkb_get_report_desc(void) { + return (u8*) (keyboard_report_desc); +} + +static inline u16 usbkb_get_report_desc_size(void) { + return sizeof(keyboard_report_desc); +} + +#if (AUDIO_HOGP) +static const USB_Descriptor_HIDReport_Datatype_t audio_hogp_report_desc[] = { + + 0x06, 0x01, 0xFF, // Usage Page (Vendor Defined 0xFF01) + 0x09, 0x02, // Usage (tmp usage) + 0xA1, 0x02, // Collection (Logical) + + 0x85, 0x02, // Report ID (2) + 0x09, 0x14, // Usage (tmp usage) + 0x75, 0x08, // Report Size (8) + 0x95, 0x14, // Report Count (20) + 0x15, 0x80, // Logical Minimum (128) + 0x25, 0x7F, // Logical Maximum (127) + 0x81, 0x22, // Input (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position) + + 0x85, 0x0a, // Report ID (10) + 0x09, 0x14, // Usage (tmp usage) + 0x75, 0x08, // Report Size (8) + 0x95, 0x14, // Report Count (20) + 0x15, 0x80, // Logical Minimum (128) + 0x25, 0x7F, // Logical Maximum (127) + 0x81, 0x22, // Input (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position) + + 0x85, 0x0b, // Report ID (11) + 0x09, 0x14, // Usage (tmp usage) + 0x75, 0x08, // Report Size (8) + 0x95, 0x14, // Report Count (20) + 0x15, 0x80, // Logical Minimum (128) + 0x25, 0x7F, // Logical Maximum (127) + 0x81, 0x22, // Input (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position) + + + 0x85, 0x0c, // Report ID (12) + 0x09, 0x14, // Usage (tmp usage) + 0x75, 0x08, // Report Size (8) + 0x95, 0x14, // Report Count (20) + 0x15, 0x80, // Logical Minimum (128) + 0x25, 0x7F, // Logical Maximum (127) + 0x81, 0x22, // Input (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position) + + 0x85, 0x04, // Report ID (4) + 0x09, 0x04, // Usage (tmp usage) + 0x75, 0x08, // Report Size (8) + 0x95, 0x01, // Report Count (1) + 0x91, 0x02, // Output + + 0xC0, // End Collection +}; +static const USB_Descriptor_HIDReport_Datatype_t vendor_report_desc[] = { + + 0x06, 0x01, 0xFF, // Usage Page (Vendor Defined 0xFF01) + 0x09, 0x02, // Usage (tmp usage) + 0xA1, 0x02, // Collection (Logical) + 0x85, 0x03, // Report ID (3) + 0x09, 0x14, // Usage (tmp usage) + 0x75, 0x08, // Report Size (8) + 0x95, 0x20, // Report Count (20) + 0x15, 0x80, // Logical Minimum (128) + 0x25, 0x7F, // Logical Maximum (127) + 0x81, 0x22, // Input (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position) + + 0x85, 0x04, // Report ID (4) + 0x09, 0x04, // Usage (tmp usage) + 0x75, 0x08, // Report Size (8) + 0x95, 0x20, // Report Count (1) + 0x91, 0x02, // Output + + 0xC0, // End Collection + +}; + +static inline u8* usbaudio_hogp_get_report_desc(void) { + return (u8*) (audio_hogp_report_desc); +} +static inline u16 usbaudio_hogp_get_report_desc_size(void) { + return sizeof(audio_hogp_report_desc); +} + +static inline u8* usb_vendor_get_report_desc(void) { + return (u8*) (vendor_report_desc); +} +static inline u16 usb_vendor_get_report_desc_size(void) { + return sizeof(vendor_report_desc); +} +#endif diff --git a/b91/b91m_ble_sdk/application/app/usbmouse.c b/b91/b91m_ble_sdk/application/app/usbmouse.c new file mode 100755 index 0000000..0786a33 --- /dev/null +++ b/b91/b91m_ble_sdk/application/app/usbmouse.c @@ -0,0 +1,152 @@ +/******************************************************************************************************** + * @file usbmouse.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "tl_common.h" + +#if(USB_MOUSE_ENABLE) + +#include "usbmouse.h" +#include "usbkb.h" +#include "application/usbstd/usb.h" +#include "application/rf_frame.h" + + +#ifndef USB_MOUSE_REPORT_SMOOTH +#define USB_MOUSE_REPORT_SMOOTH 0 +#endif + + +#define USBMOUSE_BUFF_DATA_NUM 8 +static mouse_data_t mouse_dat_buff[USBMOUSE_BUFF_DATA_NUM]; + +static u8 usbmouse_wptr, usbmouse_rptr; +static u32 usbmouse_not_released; +static u32 usbmouse_data_report_time; + + + +void usbmouse_add_frame (rf_packet_mouse_t *packet_mouse){ + + u8 new_data_num = packet_mouse->pno; + for(u8 i=0;idata[i*sizeof(mouse_data_t)]), sizeof(mouse_data_t)); + memcpy((s8*)(&mouse_dat_buff[usbmouse_wptr]), (s8*)(&packet_mouse->data[i*sizeof(mouse_data_t)]), sizeof(mouse_data_t)); + BOUND_INC_POW2(usbmouse_wptr,USBMOUSE_BUFF_DATA_NUM); + if(usbmouse_wptr == usbmouse_rptr) + { + //BOUND_INC_POW2(usbmouse_rptr,USBMOUSE_BUFF_DATA_NUM); + break; + } + } +} + + +void usbmouse_release_check(){ + if(usbmouse_not_released && clock_time_exceed(usbmouse_data_report_time, USB_MOUSE_RELEASE_TIMEOUT)){ + u32 release_data = 0; + + if(usbmouse_hid_report(USB_HID_MOUSE, (u8*)(&release_data), MOUSE_REPORT_DATA_LEN)){ + usbmouse_not_released = 0; + } + } +} + + +void usbmouse_report_frame(){ + +#if USB_MOUSE_REPORT_SMOOTH + static u32 tick = 0; + if(usbhw_is_ep_busy(USB_EDP_MOUSE)) { + tick = clock_time (); + } + + u8 diff = (usbmouse_wptr - usbmouse_rptr) & (USBMOUSE_BUFF_DATA_NUM - 1); + if (diff < 3 && !clock_time_exceed (tick, 5000)) { + return; + } +#endif + + if(usbmouse_wptr != usbmouse_rptr){ + u32 data = *(u32*)(&mouse_dat_buff[usbmouse_rptr]); // that is > 0 + int ret = usbmouse_hid_report(USB_HID_MOUSE,(u8*)(&data), MOUSE_REPORT_DATA_LEN); + if(ret){ + BOUND_INC_POW2(usbmouse_rptr,USBMOUSE_BUFF_DATA_NUM); + } + if(0 == data && ret){ // successfully release the key + usbmouse_not_released = 0; + }else{ + usbmouse_not_released = 1; + usbmouse_data_report_time = clock_time(); + } + } + return; +} + + +int usbmouse_hid_report(u8 report_id, u8 *data, int cnt){ + //unsigned char crc_in[8]; + //unsigned short crc; + //unsigned int crch; + + + if(usbhw_is_ep_busy(USB_EDP_MOUSE)){ + + u8 *pData = (u8 *)&usb_fifo[usb_ff_wptr++ & (USB_FIFO_NUM - 1)]; + pData[0] = DAT_TYPE_MOUSE; + pData[1] = report_id; + pData[2] = cnt; + memcpy(pData + 4, data, cnt); + + int fifo_use = (usb_ff_wptr - usb_ff_rptr) & (USB_FIFO_NUM*2-1); + if (fifo_use > USB_FIFO_NUM) { + usb_ff_rptr++; + //fifo overflow, overlap older data + } + + return 0; + } + reg_usb_ep_ptr(USB_EDP_MOUSE) = 0; + + // please refer to usbmouse_i.h mouse_report_desc + extern u8 usb_mouse_report_proto; + + if (!usb_mouse_report_proto) { + reg_usb_ep_dat(USB_EDP_MOUSE) = data[0]; + reg_usb_ep_dat(USB_EDP_MOUSE) = data[1]; + reg_usb_ep_dat(USB_EDP_MOUSE) = data[2]; + } + else { + reg_usb_ep_dat(USB_EDP_MOUSE) = report_id; + foreach(i, cnt){ + reg_usb_ep_dat(USB_EDP_MOUSE) = data[i]; + } + } +// reg_usb_ep_ctrl(USB_EDP_MOUSE) = FLD_EP_DAT_ACK; // ACK + reg_usb_ep_ctrl(USB_EDP_MOUSE) = FLD_EP_DAT_ACK | (edp_toggle[USB_EDP_MOUSE] ? FLD_USB_EP_DAT1 : FLD_USB_EP_DAT0); // ACK + edp_toggle[USB_EDP_MOUSE] ^= 1; + + return 1; +} + + +#endif diff --git a/b91/b91m_ble_sdk/application/app/usbmouse.h b/b91/b91m_ble_sdk/application/app/usbmouse.h new file mode 100755 index 0000000..0710749 --- /dev/null +++ b/b91/b91m_ble_sdk/application/app/usbmouse.h @@ -0,0 +1,45 @@ +/******************************************************************************************************** + * @file usbmouse.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + + +#include +#include +#include "tl_common.h" +#include "drivers.h" + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) + extern "C" { +#endif + + +#define MOUSE_REPORT_DATA_LEN (sizeof(mouse_data_t)) +#define MEDIA_REPORT_DATA_LEN 4 +int usbmouse_hid_report(u8 report_id, u8 *data, int cnt); + + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) + } +#endif diff --git a/b91/b91m_ble_sdk/application/app/usbmouse_i.h b/b91/b91m_ble_sdk/application/app/usbmouse_i.h new file mode 100755 index 0000000..3124d7d --- /dev/null +++ b/b91/b91m_ble_sdk/application/app/usbmouse_i.h @@ -0,0 +1,255 @@ +/******************************************************************************************************** + * @file usbmouse_i.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "usbmouse.h" +#include "application/usbstd/usb.h" +#include "vendor/common/default_config.h" + + +/** HID class report descriptor. This is a special descriptor constructed with values from the + * USBIF HID class specification to describe the reports and capabilities of the HID device. This + * descriptor is parsed by the host and its contents used to determine what data (and in what encoding) + * the device will send, and what it may be sent back from the host. Refer to the HID specification for + * more details on HID report descriptors. + */ +/* debug note: */ +/* + 0x85, 0x01, //Report ID (1) keyboard + 0x85, 0x02, //report ID 02 mouse + */ +static const USB_Descriptor_HIDReport_Datatype_t mouse_report_desc[] = { +#if 0 + + HID_RPT_USAGE_PAGE(8, 0x01), /* Generic Desktop */ + + HID_RPT_USAGE(8, 0x02) , /* Mouse */ + + HID_RPT_COLLECTION(8, 0x01) , /* Application */ + + HID_RPT_REPORT_ID(8, USB_HID_MOUSE) , /*Report ID*/ + + HID_RPT_USAGE_PAGE(8, 0x09) , /* Button */ + + // 1 is mouse left button,2 is mouse right button,3 is central buuton + HID_RPT_USAGE_MINIMUM(8, 0x01) , + + HID_RPT_USAGE_MAXIMUM(8, 0x05), + + HID_RPT_LOGICAL_MINIMUM(8, 0x00) , + + HID_RPT_LOGICAL_MAXIMUM(8, 0x01), + + HID_RPT_REPORT_SIZE(8, 0x01), + + HID_RPT_REPORT_COUNT(8, 0x05), /* debug note: 3->5*/ + + HID_RPT_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), + + HID_RPT_REPORT_SIZE(8, 0x03), /* debug note: 5->3*/ + + HID_RPT_REPORT_COUNT(8, 0x01), + + HID_RPT_INPUT(8, HID_IOF_CONSTANT), + + HID_RPT_USAGE(8, 0x01), /* Pointer */ + + HID_RPT_COLLECTION(8, 0x00), /* Physical */ + + HID_RPT_USAGE_PAGE(8, 0x01), /* Generic Desktop */ + + HID_RPT_USAGE(8, 0x30), /* Usage X */ + + HID_RPT_USAGE(8, 0x31), /* Usage Y */ + + HID_RPT_LOGICAL_MINIMUM(8, 0x81), // LOGICAL_MINIMUM (-127) + HID_RPT_LOGICAL_MAXIMUM(8, 0x7f), // LOGICAL_MAXIMUM (127) + + HID_RPT_REPORT_SIZE(8, 0x08), + HID_RPT_REPORT_COUNT(8, 0x02), + + HID_RPT_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE), + + HID_RPT_USAGE(8, 0x38), /* Usage Wheel */ + HID_RPT_LOGICAL_MINIMUM(8, 0x81), //LOGICAL_MINIMUM (-127) + HID_RPT_LOGICAL_MAXIMUM(8, 0x7f), //LOGICAL_MAXIMUM (127) + HID_RPT_REPORT_SIZE(8, 0x08), //REPORT_SIZE (8) + HID_RPT_REPORT_COUNT(8, 0x01), //REPORT_COUNT (1) + HID_RPT_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE), + + HID_RPT_END_COLLECTION(0), + HID_RPT_END_COLLECTION(0), + + HID_RPT_USAGE_PAGE(8, 0x0c), //global, usage page (follow 1 bytes) consumer page + HID_RPT_USAGE(8, 0x01), //local, usage ID 01 Consumer Control + HID_RPT_COLLECTION(8, 0x01), //main, collection + HID_RPT_REPORT_ID(8, USB_HID_KB_MEDIA), //Report ID + HID_RPT_REPORT_SIZE(8, 0x10), //global, report size 16 bits + HID_RPT_REPORT_COUNT(8, 0x02), //global, report count 2 + HID_RPT_LOGICAL_MINIMUM(8, 0x01), //global, min 0x01 + HID_RPT_LOGICAL_MAXIMUM(16, 0x02ff), //global, max 0x028c + HID_RPT_USAGE_MINIMUM(8, 0x01), //local, min 0x01 + HID_RPT_USAGE_MAXIMUM(16, 0x02ff), //local, max 0x28c + HID_RPT_INPUT(8, HID_IOF_ABSOLUTE), //main, input data varible, absolute + HID_RPT_END_COLLECTION(0), //main, end collection + + HID_RPT_USAGE_PAGE(8, 0x01), //gobal, USAGE_PAGE 1 (Generic Desktop) + HID_RPT_USAGE(8, 0x80), //local, usage ID 0x80 system control + HID_RPT_COLLECTION(8, 0x01), //main conllection + HID_RPT_REPORT_ID(8, USB_HID_KB_SYS), //Report ID + HID_RPT_REPORT_SIZE(8, 0x01), //global, report size 2 + HID_RPT_REPORT_COUNT(8, 0x03), //report count 1 + HID_RPT_LOGICAL_MINIMUM(8, 0x00), //global min 01 + HID_RPT_LOGICAL_MAXIMUM(8, 0x01), //gobal, max 3 + HID_RPT_USAGE(8, 0x81), //local usage ID 0x81 system power down + HID_RPT_USAGE(8, 0x82), //local usage ID 0x82 system sleep + HID_RPT_USAGE(8, 0x83), //local usage ID 0x83 system wakeup + HID_RPT_INPUT(8, HID_IOF_ABSOLUTE|HID_IOF_NO_PREFERRED_STATE|HID_IOF_NULLSTATE), + HID_RPT_REPORT_SIZE(8, 0x05), //global report size 6 + HID_RPT_REPORT_COUNT(8, 0x01), //report count 1 + HID_RPT_INPUT(8, HID_IOF_CONSTANT|HID_IOF_VARIABLE), + HID_RPT_END_COLLECTION(0), //end of collection + +#else + + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + + 0x09, 0x02, // USAGE (Mouse) + + 0xa1, 0x01, // COLLECTION (Application) + + 0x85, USB_HID_MOUSE, //report ID 01 + + 0x09, 0x01, // USAGE (Pointer) + + 0xa1, 0x00, // COLLECTION (Physical) + + 0x05, 0x09, // USAGE_PAGE (Button) + + // 1 is mouse left button,2 is mouse right button,3 is central buuton + 0x19, 0x01, // USAGE_MINIMUM (Button 1) + + 0x29, 0x05, // USAGE_MAXIMUM (Button 5) + + 0x15, 0x00, // LOGICAL_MINIMUM (0) + + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + + 0x95, 0x05, // REPORT_COUNT (3) + + 0x75, 0x01, // REPORT_SIZE (1) + + 0x81, 0x02, // INPUT (Data,Var,Abs) + + 0x95, 0x01, // REPORT_COUNT (1) + + 0x75, 0x03, // REPORT_SIZE (3) + + 0x81, 0x01, // INPUT (Cnst,Var,Abs) + + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + + 0x09, 0x30, // USAGE (X) + + 0x09, 0x31, // USAGE (Y) + + 0x15, 0x81, // LOGICAL_MINIMUM (-127) + 0x25, 0x7f, // LOGICAL_MAXIMUM (127) + + 0x75, 0x08, // REPORT_SIZE (16) + + 0x95, 0x02, // REPORT_COUNT (2) + + 0x81, 0x06, // INPUT (Data,Var,Rel) + + 0x09, 0x38, // USAGE (Wheel) + 0x15, 0x81, //LOGICAL_MINIMUM (-127) + 0x25, 0x7f, //LOGICAL_MAXIMUM (127) + 0x75, 0x08, //REPORT_SIZE (16) + 0x95, 0x01, //REPORT_COUNT (1) + 0x81, 0x06, //INPUT (Data,Var,Rel) + + 0xc0, // END_COLLECTION + 0xc0, // END_COLLECTION + +#if (ONEKEY_WEB==0) + // begin of media key + 0x05,0x0c, //global, usage page (follow 1 bytes) consumer page + 0x09,0x01, //local, usage ID 01 Consumer Control + 0xA1,0x01, //main, collection + 0x85,USB_HID_KB_MEDIA, //global, report ID 0x03 + 0x75,0x10, //global, report size 16 bits + 0x95,0x02, //global, report count 2 + 0x15,0x01, //global, min 0x01 + 0x26,0x9c,0x02, //global, max 0x29c +#if CHIP_EOP_ERROR + 0x19,0x01, //local, min 0x01 + 0x2a,0xff,0x02, //local, max 0x2ff +#else + 0x19,0x01, //local, min 0x01 + 0x2a,0x8c,0x02, //local, max 0x28c +#endif + 0x81,0x00, //main, input data varible, absolute + 0xc0, //main, end collection + + 0x05,0x01, //gobal, USAGE_PAGE 1 (Generic Desktop) + 0x09,0x80, //local, usage ID 0x80 system control + 0xa1,0x01, //main conllection + 0x85,USB_HID_KB_SYS, //global report ID 0x4 + 0x75,0x02, //global, report size 2 + 0x95,0x01, //report count 1 + 0x15,0x01, //global min 01 + 0x25,0x03, //gobal, max 3 + 0x09,0x82, //local usage ID 0x82 system sleep + 0x09,0x81, //local usage ID 0x81 system power down + 0x09,0x83, //local usage ID 0x83 system wakeup + 0x81,0x60, //main, input data, var, abs, No Prefer, NULL state + 0x75,0x06, //global report size 6 + 0x81,0x03, //main input, constant, array + 0xc0, //end of collection + // end of media key +#endif +#endif + //need Jensen's help: report ID 5 + HID_RPT_USAGE_PAGE(8, 0x01), //global, USAGE_PAGE 1 (Generic Desktop) + 0x09,0x00, //usage undefined + 0xa1,0x01, //main collection + 0x85,0x05, //global report ID 0x5 + 0x06,0x00,0xff, //global usage page + 0x09,0x01, //local, usage ID 01 Consumer Control + 0x15,0x81, //global min 81 + 0x25,0x7f, //global, max 7f + 0x75,0x08, //global, report size 8 + 0x95,0x07, //report count 7 + 0xb1,0x02, //feature (data, var, abs) + HID_RPT_END_COLLECTION(0), //main, end collection +}; + +static inline u8* usbmouse_get_report_desc(void) { + return (u8*) (mouse_report_desc); +} + +static inline u16 usbmouse_get_report_desc_size(void) { + return sizeof(mouse_report_desc); +} + diff --git a/b91/b91m_ble_sdk/application/audio/adpcm.c b/b91/b91m_ble_sdk/application/audio/adpcm.c new file mode 100755 index 0000000..2fcd02c --- /dev/null +++ b/b91/b91m_ble_sdk/application/audio/adpcm.c @@ -0,0 +1,506 @@ +/******************************************************************************************************** + * @file adpcm.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "tl_common.h" +#include "drivers.h" +#include "audio_config.h" +#include "adpcm.h" + +#if (TL_AUDIO_MODE & TL_AUDIO_MASK_ADPCM_MODE) //Adpcm mode + + +static const signed char idxtbl[] = { -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8}; +static const unsigned short steptbl[] = { + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 }; + + +#define NUM_OF_ORIG_SAMPLE 2 + +#if (TL_AUDIO_MODE & RCU_PROJECT) //RCU + +#if (TL_AUDIO_MODE == TL_AUDIO_RCU_ADPCM_GATT_TLEINK) //RCU,GATT TELINK +///////////////////////////////////////////////////////////////////////////////// +// 256-samples split into 2 +///////////////////////////////////////////////////////////////////////////////// +void mic_to_adpcm_split (signed short *ps, int len, signed short *pds, int start) +{ + int i, j; + unsigned short code=0; + unsigned short code16=0; + static int predict_idx = 0; + code = 0; + static signed short *pd; + static int predict; + + //byte2,byte1: predict; byte3: predict_idx; byte4:adpcm data len + if (start) + { + pd = pds; + *pd++ = predict; + * (((signed char *)pds) + 2)= predict_idx; + * (((unsigned char *)pds) + 3)= (ADPCM_PACKET_LEN - 4); + pd++; + } + + //byte5- byte128: 124 byte(62 sample) adpcm data + for (i=0; i=0 ) { + code = 0; + } + else { + diff = -diff; + code = 8; + } + + int diffq = step >> 3; + + for (j=4; j>0; j=j>>1) { + if( diff >= step) { + diff = diff - step; + diffq = diffq + step; + code = code + j; + } + step = step >> 1; + } + + code16 = (code16 >> 4) | (code << 12); + if ( (i&3) == 3) { + *pd++ = code16; + } + + if(code >= 8) { + predict = predict - diffq; + } + else { + predict = predict + diffq; + } + + if (predict > 32767) { + predict = 32767; + } + else if (predict < -32768) { + predict = -32768; + } + + predict_idx = predict_idx + idxtbl[code]; + if(predict_idx < 0) { + predict_idx = 0; + } + else if(predict_idx > 88) { + predict_idx = 88; + } + } +} + +#elif (TL_AUDIO_MODE == TL_AUDIO_RCU_ADPCM_GATT_GOOGLE) //RCU,GATT GOOGLE + +#define ADPCM_ANDROID_ID 0x00 + +static int serial_id = 0; + +unsigned short adpcm_serial_num = 0; + +_attribute_ram_code_ void mic_to_adpcm_split (signed short *ps, int len, signed short *pds, int start) +{ + int i, j; + unsigned short code=0; + unsigned short code16=0; + static signed short *pd; + static int predict_idx = 1; + code = 0; + static int predict; + + //Seq# 2bytes; Id: 1bytes; Prev.pred: 2bytes; index: 1bytes + if (start) + { + pd = pds; + *pd++ = ((adpcm_serial_num>>8)&0x00ff)|((adpcm_serial_num<<8)&0xff00); + *pd++ = (ADPCM_ANDROID_ID)|((predict&0xff00)); + *pd++ = ((predict)&0x00ff)|((predict_idx<<8)&0xff00); + adpcm_serial_num ++; + } + + for(i=0 ; i= 0){ + code = 0; + }else{ + diff = -diff; + code = 8; + } + + int diffq = step >> 3; + + for(j=4; j>0; j=j>>1){ + if(diff >= step){ + diff = diff - step; + diffq = diffq + step; + code = code + j; + } + step = step >> 1; + } + + code16 = (code16 >> 4) | (code << 12); + if((i&3) == 3){ + code16 = ((code16&0x0f)<<4)|((code16&0xf0)>>4) | ((code16&0x0f00)<<4)|((code16&0xf000)>>4); + *pd++ = code16; + } + + if(code >= 8) { + predict = predict - diffq; + }else { + predict = predict + diffq; + } + + if(predict > 32767){ + predict = 32767; + }else if (predict < -32768) { + predict = -32768; + } + + predict_idx = predict_idx + idxtbl[code]; + if(predict_idx < 0) { + predict_idx = 0; + }else if(predict_idx > 88){ + predict_idx = 88; + } + } +} + +#elif (TL_AUDIO_MODE & TL_AUDIO_MASK_HID_SERVICE_CHANNEL) //RCU,HID SERVICE + +int predict = 0; +int predict_idx = 0; +///////////////////////////////////////////////////////////////////////////////// +// 256-samples split into 2 +///////////////////////////////////////////////////////////////////////////////// +_attribute_ram_code_ void mic_to_adpcm_split (signed short *ps, int len, signed short *pds, int start) +{ + int i, j; + unsigned short code=0; + unsigned short code16=0; + static signed short *pd; + pd = pds; + code = 0; + + for (i=0; i=0 ) { + code = 0; + } + else { + diff = -diff; + code = 8; + } + + int diffq = step >> 3; + + for (j=4; j>0; j=j>>1) { + if( diff >= step) { + diff = diff - step; + diffq = diffq + step; + code = code + j; + } + step = step >> 1; + } + + code16 = (code16 >> 4) | (code << 12); + if ( (i&3) == 3) { + code16 = ((code16&0x0f)<<4)|((code16&0xf0)>>4) | ((code16&0x0f00)<<4)|((code16&0xf000)>>4); + *pd++ = code16; + } + + if(code >= 8) { + predict = predict - diffq; + } + else { + predict = predict + diffq; + } + + if (predict > 32767) { + predict = 32767; + } + else if (predict < -32768) { + predict = -32768; + } + + predict_idx = predict_idx + idxtbl[code & 15]; + if(predict_idx < 0) { + predict_idx = 0; + } + else if(predict_idx > 88) { + predict_idx = 88; + } + } +} +#else + +#endif//end RCU_PROJECT pcm to adpcm + +#elif (TL_AUDIO_MODE & DONGLE_PROJECT) //Dongle + +#if (TL_AUDIO_MODE == TL_AUDIO_DONGLE_ADPCM_GATT_TELINK) //Dongle,GATT TELINK + +void adpcm_to_pcm (signed short *ps, signed short *pd, int len) +{ + int i; + + //byte2,byte1: predict; byte3: predict_idx; byte4:adpcm data len + int predict = ps[0]; + int predict_idx = ps[1] & 0xff; +// int adpcm_len = (ps[1]>>8) & 0xff; + + unsigned char *pcode = (unsigned char *) (ps + NUM_OF_ORIG_SAMPLE); + + unsigned char code; + code = *pcode ++; + + //byte5- byte128: 124 byte(62 sample) adpcm data + for (i=0; i> 3; + + if (code & 4) { + diffq = diffq + step; + } + step = step >> 1; + if (code & 2) { + diffq = diffq + step; + } + step = step >> 1; + if (code & 1) { + diffq = diffq + step; + } + + if (code & 8) { + predict = predict - diffq; + } + else { + predict = predict + diffq; + } + + if (predict > 32767) { + predict = 32767; + } + else if (predict < -32768) { + predict = -32768; + } + + predict_idx = predict_idx + idxtbl[code & 15]; + + if(predict_idx < 0) { + predict_idx = 0; + } + else if(predict_idx > 88) { + predict_idx = 88; + } + + if (i&1) { + code = *pcode ++; + } + else { + code = code >> 4; + } + } + + if (0 && i < NUM_OF_ORIG_SAMPLE) { + *pd++ = ps[i]; + } + else { + *pd++ = predict; + } + } +} + + +#elif (TL_AUDIO_MODE == TL_AUDIO_DONGLE_ADPCM_GATT_GOOGLE) //Dongle,GATT GOOGLE + +#define ADPCM_ANDROID_ID 0x00 + +_attribute_ram_code_ void adpcm_to_pcm (signed short *ps, signed short *pd, int len) +{ + int i; + + int predict = (s16)((ps[1]&0xff00) | (ps[2]&0x00ff)); + int predict_idx = (s8)((ps[2]&0xff00)>>8); + unsigned char *pcode = (unsigned char *) (ps + 3); + unsigned char code; + code = *pcode ++; + code = ((code>>4)&0x0f)|((code<<4)&0xf0); + + //google: byte7-byte134: 128 byte(62 sample) adpcm data + //t4h: byte5-byte100: 96 byte(48 sample) adpcm data + for(i=0; i> 3; + + if(code & 4){ + diffq = diffq + step; + } + step = step >> 1; + if(code & 2){ + diffq = diffq + step; + } + step = step >> 1; + if(code & 1){ + diffq = diffq + step; + } + + if(code & 8){ + predict = predict - diffq; + }else{ + predict = predict + diffq; + } + + if(predict > 32767){ + predict = 32767; + }else if(predict < -32768){ + predict = -32768; + } + + predict_idx = predict_idx + idxtbl[code & 15]; + + if(predict_idx < 0){ + predict_idx = 0; + }else if(predict_idx > 88){ + predict_idx = 88; + } + + if(i&1){ + code = *pcode ++; + code = ((code>>4)&0x0f)|((code<<4)&0xf0); //add by qiuwei for android 8 + }else{ + code = code >> 4; + } + + if (0 && i < NUM_OF_ORIG_SAMPLE) { + *pd++ = ps[i]; + } + else { + *pd++ = predict; + } + } +} + +#elif (TL_AUDIO_MODE & TL_AUDIO_MASK_HID_SERVICE_CHANNEL) //Dongle,HID SERVICE + +int predict = 0; +int predict_idx = 0; + +void adpcm_to_pcm (signed short *ps, signed short *pd, int len) +{ + int i; + unsigned char *pcode = (unsigned char *) ps; + unsigned char code; + code = *pcode ++; + code = ((code>>4)&0x0f)|((code<<4) &0xf0); + + for (i=0; i> 3; + + if (code & 4) { + diffq = diffq + step; + } + step = step >> 1; + if (code & 2) { + diffq = diffq + step; + } + step = step >> 1; + if (code & 1) { + diffq = diffq + step; + } + + if (code & 8) { + predict = predict - diffq; + } + else { + predict = predict + diffq; + } + + if (predict > 32767) { + predict = 32767; + } + else if (predict < -32768) { + predict = -32768; + } + + predict_idx = predict_idx + idxtbl[code & 15]; + + if(predict_idx < 0) { + predict_idx = 0; + } + else if(predict_idx > 88) { + predict_idx = 88; + } + + if (i&1) { + code = *pcode ++; + code = ((code>>4)&0x0f)|((code<<4) &0xf0); + } + else { + code = code >> 4; + } + } + + if (0 && i < NUM_OF_ORIG_SAMPLE) { + *pd++ = ps[i]; + } + else { + *pd++ = predict; + } + } +} +#else + +#endif//end DONGLE_PROJECT adpcm to pcm + +#endif//end RCU_PROJECT OR DONGLE_PROJECT + +#endif diff --git a/b91/b91m_ble_sdk/application/audio/adpcm.h b/b91/b91m_ble_sdk/application/audio/adpcm.h new file mode 100755 index 0000000..4a7a790 --- /dev/null +++ b/b91/b91m_ble_sdk/application/audio/adpcm.h @@ -0,0 +1,29 @@ +/******************************************************************************************************** + * @file adpcm.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef ADPCM_H_ +#define ADPCM_H_ + +void mic_to_adpcm_split (signed short *ps, int len, signed short *pds, int start); +void adpcm_to_pcm (signed short *ps, signed short *pd, int len); + +#endif /* ADPCM_H_ */ diff --git a/b91/b91m_ble_sdk/application/audio/audio_common.h b/b91/b91m_ble_sdk/application/audio/audio_common.h new file mode 100755 index 0000000..b7a21bc --- /dev/null +++ b/b91/b91m_ble_sdk/application/audio/audio_common.h @@ -0,0 +1,84 @@ +/******************************************************************************************************** + * @file audio_common.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef AUDIO_COMMON_H_ +#define AUDIO_COMMON_H_ + +#define TL_AUDIO_MASK_SBC_MODE (0x00000001) +#define TL_AUDIO_MASK_MSBC_MODE (0x00000002) +#define TL_AUDIO_MASK_ADPCM_MODE (0x00000004) +#define TL_AUDIO_MASK_OPUS_MODE (0x00000008) + +#define TL_AUDIO_MASK_HID_SERVICE_CHANNEL (0x00000100) +#define TL_AUDIO_MASK_GATT_SERVICE_TELINK_CHANNEL (0x00000200) +#define TL_AUDIO_MASK_GATT_SERVICE_GOOGLE_CHANNEL (0x00000400) +#define TL_AUDIO_MASK_GATT_SERVICE_AMAZON_CHANNEL (0x00000800) + +#define TL_AUDIO_MASK_DONGLE_TO_STB (0x00010000) + +#define RCU_PROJECT (0x01000000) +#define DONGLE_PROJECT (0x02000000) + +#define AUDIO_DISABLE 0 + +//RCU Audio Mode + +#define TL_AUDIO_RCU_ADPCM_GATT_TLEINK (RCU_PROJECT | TL_AUDIO_MASK_ADPCM_MODE | TL_AUDIO_MASK_GATT_SERVICE_TELINK_CHANNEL) + +#define TL_AUDIO_RCU_ADPCM_GATT_GOOGLE (RCU_PROJECT | TL_AUDIO_MASK_ADPCM_MODE | TL_AUDIO_MASK_GATT_SERVICE_GOOGLE_CHANNEL) + +#define TL_AUDIO_RCU_ADPCM_HID (RCU_PROJECT | TL_AUDIO_MASK_ADPCM_MODE | TL_AUDIO_MASK_HID_SERVICE_CHANNEL) + +#define TL_AUDIO_RCU_SBC_HID (RCU_PROJECT | TL_AUDIO_MASK_SBC_MODE | TL_AUDIO_MASK_HID_SERVICE_CHANNEL) + +#define TL_AUDIO_RCU_ADPCM_HID_DONGLE_TO_STB (RCU_PROJECT | TL_AUDIO_MASK_ADPCM_MODE | TL_AUDIO_MASK_HID_SERVICE_CHANNEL | TL_AUDIO_MASK_DONGLE_TO_STB) + +#define TL_AUDIO_RCU_SBC_HID_DONGLE_TO_STB (RCU_PROJECT | TL_AUDIO_MASK_SBC_MODE | TL_AUDIO_MASK_HID_SERVICE_CHANNEL | TL_AUDIO_MASK_DONGLE_TO_STB) + +#define TL_AUDIO_RCU_MSBC_HID (RCU_PROJECT | TL_AUDIO_MASK_MSBC_MODE | TL_AUDIO_MASK_HID_SERVICE_CHANNEL) + +#define TL_AUDIO_RCU_OPUS_GATT_AMAZON (RCU_PROJECT | TL_AUDIO_MASK_OPUS_MODE | TL_AUDIO_MASK_GATT_SERVICE_AMAZON_CHANNEL) + +//Dongle Audio Mode + +#define TL_AUDIO_DONGLE_ADPCM_GATT_TELINK (DONGLE_PROJECT | TL_AUDIO_MASK_ADPCM_MODE | TL_AUDIO_MASK_GATT_SERVICE_TELINK_CHANNEL) + +#define TL_AUDIO_DONGLE_ADPCM_GATT_GOOGLE (DONGLE_PROJECT | TL_AUDIO_MASK_ADPCM_MODE | TL_AUDIO_MASK_GATT_SERVICE_GOOGLE_CHANNEL) + +#define TL_AUDIO_DONGLE_ADPCM_HID (DONGLE_PROJECT | TL_AUDIO_MASK_ADPCM_MODE | TL_AUDIO_MASK_HID_SERVICE_CHANNEL) + +#define TL_AUDIO_DONGLE_SBC_HID (DONGLE_PROJECT | TL_AUDIO_MASK_SBC_MODE | TL_AUDIO_MASK_HID_SERVICE_CHANNEL) + +#define TL_AUDIO_DONGLE_ADPCM_HID_DONGLE_TO_STB (DONGLE_PROJECT | TL_AUDIO_MASK_ADPCM_MODE | TL_AUDIO_MASK_HID_SERVICE_CHANNEL | TL_AUDIO_MASK_DONGLE_TO_STB) + +#define TL_AUDIO_DONGLE_SBC_HID_DONGLE_TO_STB (DONGLE_PROJECT | TL_AUDIO_MASK_SBC_MODE | TL_AUDIO_MASK_HID_SERVICE_CHANNEL | TL_AUDIO_MASK_DONGLE_TO_STB) + +#define TL_AUDIO_DONGLE_MSBC_HID (DONGLE_PROJECT | TL_AUDIO_MASK_MSBC_MODE | TL_AUDIO_MASK_HID_SERVICE_CHANNEL) + +#define TL_AUDIO_DONGLE_OPUS_GATT_AMAZON (DONGLE_PROJECT | TL_AUDIO_MASK_OPUS_MODE | TL_AUDIO_MASK_GATT_SERVICE_AMAZON_CHANNEL) + + + + + + +#endif /* AUDIO_COMMON_H_ */ diff --git a/b91/b91m_ble_sdk/application/audio/audio_config.h b/b91/b91m_ble_sdk/application/audio/audio_config.h new file mode 100755 index 0000000..a27a6e4 --- /dev/null +++ b/b91/b91m_ble_sdk/application/audio/audio_config.h @@ -0,0 +1,47 @@ +/******************************************************************************************************** + * @file audio_config.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#include "application/audio/audio_common.h" +#include "tl_common.h" + + +#ifndef TL_AUDIO_MODE +#define TL_AUDIO_MODE AUDIO_DISABLE +#endif + +#if (TL_AUDIO_MODE & RCU_PROJECT) //RCU + #if (TL_AUDIO_MODE == TL_AUDIO_RCU_ADPCM_GATT_TLEINK) + #define ADPCM_PACKET_LEN 128 + #define TL_MIC_ADPCM_UNIT_SIZE 248 + #define TL_MIC_BUFFER_SIZE 992 + #endif + +#elif (TL_AUDIO_MODE & DONGLE_PROJECT) //Dongle + + #if (TL_AUDIO_MODE == TL_AUDIO_DONGLE_ADPCM_GATT_TELINK) + #define MIC_ADPCM_FRAME_SIZE 128 + #define MIC_SHORT_DEC_SIZE 248 + #endif +#else + +#endif diff --git a/b91/b91m_ble_sdk/application/audio/tl_audio.c b/b91/b91m_ble_sdk/application/audio/tl_audio.c new file mode 100755 index 0000000..f2c32e4 --- /dev/null +++ b/b91/b91m_ble_sdk/application/audio/tl_audio.c @@ -0,0 +1,555 @@ +/******************************************************************************************************** + * @file tl_audio.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "tl_common.h" +#include "drivers.h" +#include "tl_audio.h" +#include "audio_config.h" +#include "adpcm.h" + + + + +#if (TL_AUDIO_MODE & RCU_PROJECT) //RCU + +#if (TL_AUDIO_MODE & (TL_AUDIO_MASK_SBC_MODE | TL_AUDIO_MASK_MSBC_MODE)) + + u8 buffer_mic_enc[(ADPCM_PACKET_LEN+3)*TL_MIC_PACKET_BUFFER_NUM]; + +#else + #define BUFFER_PACKET_SIZE ((ADPCM_PACKET_LEN >> 2) * TL_MIC_PACKET_BUFFER_NUM) + + #if BUFFER_PACKET_SIZE + int buffer_mic_enc[BUFFER_PACKET_SIZE]; + #endif +#endif + +u8 buffer_mic_pkt_wptr; +u8 buffer_mic_pkt_rptr; + + +#if TL_NOISE_SUPRESSION_ENABLE + + int md_long =0; + int md_short =0; + int md_im =0; + int md_noise = 0; + int md_gain = 256; + +#endif + +#if (IIR_FILTER_ENABLE) + +//inner band EQ default parameter. user need to set according to actual situation. +//int filter_1[10] = {16630, -22724, 15507, 22724, -15753}; +//int filter_2[10] = {15380, 0, 14450, 0, -13446}; +//int filter_3[10] = {14961, 14869, 0, -13446, 0}; + +int filter_1[10] = {995*4, 1990*4, 995*4, 849*4, 734*4}; +int filter_2[10] = {3691*4, -5564*4, 2915*4, 5564*4, -2510*4}; +int filter_3[10] = {2534*4, -1482*4, 955*4, 3956*4, -1866*4}; + +u8 filter1_shift = 0; +u8 filter2_shift = 0; +u8 filter3_shift = 0; + +//used for OOB processing. i.e LPF. user need to set according to actual situation +int LPF_FILTER_1[10] = {739,87,739,2419,-1401}; +int LPF_FILTER_2[10] = {4301,5262,4299,889,-3601}; + +u8 lpf_filter1_shift = 0; +u8 lpf_filter2_shift = 0; + + +//voice data out of band need to be processed using 12 bits. +_attribute_ram_code_ void voice_iir_OOB(signed short * ps, signed short *pd, int* coef, int nsample,u8 shift) +{ + int i = 0; + long int s = 0; + for (i=0; i>shift; + s = (*ps * coef[0])>>0; //input 16-bit + s += coef[5] * coef[1]; + s += coef[6] * coef[2]; //coef 0,1,2: 12-bit + s += coef[7] * coef[3]; + s += coef[8] * coef[4]; //coef 4 & 5: 10-bit; coef 7 & 8: 18-bit + //s = s >> 10; //18-bit + //s = s >> 12; //18-bit + + s = ((s + (1 << 11)) >> 12); /////this line code indicate that process sample data with 12 bits + +#if 0 + if (s >= (1<<18)) + s = (1<<18) - 1; + else if (s < -(1<<18)) + s = - (1<<18); +#endif + coef[6] = coef[5]; //16-bit + coef[5] = *ps++; //16-bit + coef[8] = coef[7]; //18-bit + coef[7] = s; + //*pd++ = s >> 3; + //*pd++ = s >> 1; + + //limit + if(s > 32767){ + s = 32767; + } + else if(s < -32767){ + s = -32767; + } + + *pd++ = s >> shift; + } +} + + +_attribute_ram_code_ static inline void audio_getHalfsample_func(s16*ps, u16 len) +{ + for(u16 i = 0;i < (len >> 1);i++) + { + ps[i] = ps[2 * i]; + } +} + +//voice data inner band need to be processed using 14 bits. +_attribute_ram_code_ void voice_iir(signed short * ps, signed short *pd, int* coef, int nsample,u8 shift) +{ + int i = 0; + long int s = 0; + for (i=0; i>shift; + s = (*ps * coef[0])>>0; //input 16-bit + s += coef[5] * coef[1]; + s += coef[6] * coef[2]; //coef 0,1,2: 12-bit + s += coef[7] * coef[3]; + s += coef[8] * coef[4]; //coef 4 & 5: 10-bit; coef 7 & 8: 18-bit + //s = s >> 10; //18-bit + //s = s >> 12; //18-bit + + s = ((s + (1 << 13)) >> 14); /////this line code indicate that process sample data with 14 bits +// s = ((s + (1 << 11)) >> 12); +#if 0 + if (s >= (1<<18)) + s = (1<<18) - 1; + else if (s < -(1<<18)) + s = - (1<<18); +#endif + coef[6] = coef[5]; //16-bit + coef[5] = *ps++; //16-bit + coef[8] = coef[7]; //18-bit + coef[7] = s; + //*pd++ = s >> 3; + //*pd++ = s >> 1; + + //limit + if(s > 32767){ + s = 32767; + } + else if(s < -32767){ + s = -32767; + } + + *pd++ = s >> shift; + } +} + +void Audio_VolumeSet(unsigned char input_output_select,unsigned char volume_set_value) +{ +#if 0 //not support now + #if (BLE_DMIC_ENABLE) + reg_mic_ctrl = MASK_VAL( FLD_AUD_MIC_VOL_CONTROL, (volume_set_value & 0x3f),\ + FLD_AUD_MIC_MONO_EN, 1, \ + FLD_AUD_AMIC_DMIC_SELECT, 1 ); + #else + reg_mic_ctrl = MASK_VAL( FLD_AUD_MIC_VOL_CONTROL, (volume_set_value & 0x3f),\ + FLD_AUD_MIC_MONO_EN, 1, \ + FLD_AUD_AMIC_DMIC_SELECT, 0 ); + #endif +#endif +} +#define IIR_FILTER_ADR 0x71000 +#define CBUFFER_SIZE 20 +u8 filter_step_enable = 0; +u8 vol_gain_tmp = 0xff; +u8 pga_post_gain_tmp = 0xff; +u8 filter_cmp[20]; +/* + FLASH 0x71000 + +----------------0x71000 + | c1(20B) first inner band EQ + +----------------0x71013 + | c2(20B) second inner band EQ + +----------------0x71027 + | c3(20B) three inner band EQ + +----------------0x7103B + | c4(20B) first out of band EQ + +----------------0x7104F + | c5(20B) second out of band EQ + +----------------0x71063 + | f1_sft(1B) | f2_sft(1B) |f3_sft(1B) |f4_sft(1B) | f5_sft(1B) five shift + +----------------0x7109F + + +----------------0x710A0 + | vol_gain(1B)volume gain setting + +----------------0x710A1 + | PGA_POST_GAIN(1B)(0~49): 0x710A1 + +----------------0x710A2 +*/ +#define MANUAL_VOLUMN_SETTINGS 0x1C +void filter_setting() +{ + //get the configuration data in the flash + u32 *pfilter = (u32*)IIR_FILTER_ADR; + u8 *p_start_iir = (u8 *)(pfilter); + + memset(filter_cmp, 0xff,sizeof(filter_cmp)); + + if(memcmp(p_start_iir,filter_cmp,sizeof(filter_cmp)))//step 1 disaptch + { + memcpy((u8 *)filter_1,p_start_iir,CBUFFER_SIZE); + filter_step_enable |= BIT(1); + memset(filter_cmp, 0xff,sizeof(filter_cmp)); + } + if(memcmp(p_start_iir+CBUFFER_SIZE,filter_cmp,sizeof(filter_cmp)))//step 2 disaptch + { + memcpy((u8 *)filter_2,p_start_iir+CBUFFER_SIZE,CBUFFER_SIZE); + filter_step_enable |= BIT(2); + memset(filter_cmp, 0xff,sizeof(filter_cmp)); + } + if(memcmp(p_start_iir+(CBUFFER_SIZE*2),filter_cmp,sizeof(filter_cmp)))//step 3 dispatch + { + memcpy((u8 *)filter_3,p_start_iir+(CBUFFER_SIZE*2),CBUFFER_SIZE); + filter_step_enable |= BIT(3); + memset(filter_cmp, 0xff,sizeof(filter_cmp)); + } + + if(memcmp(p_start_iir+(CBUFFER_SIZE*3),filter_cmp,sizeof(filter_cmp)))//step 4 dispatch + { + memcpy((u8 *)LPF_FILTER_1,p_start_iir+(CBUFFER_SIZE*3),CBUFFER_SIZE); + filter_step_enable |= BIT(4); + memset(filter_cmp, 0xff,sizeof(filter_cmp)); + } + if(memcmp(p_start_iir+(CBUFFER_SIZE*4),filter_cmp,sizeof(filter_cmp)))//step 5 dispatch + { + memcpy((u8 *)LPF_FILTER_2,p_start_iir+(CBUFFER_SIZE*4),CBUFFER_SIZE); + filter_step_enable |= BIT(5); + memset(filter_cmp, 0xff,sizeof(filter_cmp)); + } + + int i; + i = CBUFFER_SIZE*5; + + filter1_shift = (p_start_iir[i] == 0xff) ? 0:p_start_iir[i]; + filter2_shift = (p_start_iir[i+1] == 0xff) ? 0:p_start_iir[i+1]; + filter3_shift = (p_start_iir[i+2] == 0xff) ? 0:p_start_iir[i+2]; + + lpf_filter1_shift = (p_start_iir[i+3] == 0xff)? 0:p_start_iir[i+3]; + lpf_filter2_shift = (p_start_iir[i+4] == 0xff)? 0:p_start_iir[i+4]; + + //volume gain setting .position 0x710A0 + vol_gain_tmp = p_start_iir[0xA0]; + if(vol_gain_tmp!=0xff){ + if(vol_gain_tmp&0x80){ + if(MANUAL_VOLUMN_SETTINGS<(vol_gain_tmp&0x7f)){ + return; + } + Audio_VolumeSet(1,MANUAL_VOLUMN_SETTINGS-(vol_gain_tmp&0x7f)); + }else{ + if(MANUAL_VOLUMN_SETTINGS+vol_gain_tmp>0x3f){ + return; + } + Audio_VolumeSet(1,MANUAL_VOLUMN_SETTINGS+vol_gain_tmp); + } + }else{ + Audio_VolumeSet(1,MANUAL_VOLUMN_SETTINGS); + } + + //PGA_POST_GAIN setting .position 0x710A1 +#if (!BLE_DMIC_ENABLE) + pga_post_gain_tmp = p_start_iir[0xA1]; + if(pga_post_gain_tmp != 0xff){ + if(pga_post_gain_tmp > 0x0f){//0x0f: PGA_GAIN_VOL_0_0DB + return; + } + analog_write_reg8(codec_ana_cfg4,(analog_read(codec_ana_cfg4) & 0x00) | pga_post_gain_tmp); + } +#endif + return ; +} + +#endif + + + +#if (TL_AUDIO_MODE == TL_AUDIO_RCU_ADPCM_GATT_TLEINK) //RCU,GATT Telink +void proc_mic_encoder (void) +{ + static u16 buffer_mic_rptr; + u16 mic_wptr = (audio_get_rx_dma_wptr (DMA2) - (u32)buffer_mic) >> 1; + u16 l = (mic_wptr >= buffer_mic_rptr) ? (mic_wptr - buffer_mic_rptr) : 0xffff; + + if (l >=(TL_MIC_BUFFER_SIZE>>2)) { + + s16 *ps = buffer_mic + buffer_mic_rptr; +#if TL_NOISE_SUPRESSION_ENABLE + // for FIR adc sample data, only half part data are effective + for (int i=0; i>2), lpf_filter1_shift);//12 bits + voice_iir_OOB(ps, ps, LPF_FILTER_2, (TL_MIC_BUFFER_SIZE>>2), lpf_filter2_shift);//12 bits + + //step2: 32K->16K + audio_getHalfsample_func(ps, TL_MIC_BUFFER_SIZE>>2); //496B/2=> 248B + + //step3: inner band voice 14bits EQ filter process + voice_iir(ps,ps,filter_1,(TL_MIC_BUFFER_SIZE>>3),filter1_shift);//14 bits + voice_iir(ps,ps,filter_2,(TL_MIC_BUFFER_SIZE>>3),filter2_shift);//14 bits + voice_iir(ps,ps,filter_3,(TL_MIC_BUFFER_SIZE>>3),filter3_shift);//14 bits + #endif + + #if 0 + //step1: out of band voice 12bits EQ filter process + if((filter_step_enable & 0x30) != 0) + { + if(filter_step_enable & BIT(4)) + { + voice_iir_OOB(ps, ps, LPF_FILTER_1, (TL_MIC_BUFFER_SIZE>>2), lpf_filter1_shift);//12 bits + } + if(filter_step_enable & BIT(5)) + { + voice_iir_OOB(ps, ps, LPF_FILTER_2, (TL_MIC_BUFFER_SIZE>>2), lpf_filter2_shift);//12 bits + } + } + //step2: 32K->16K + audio_getHalfsample_func(ps, TL_MIC_BUFFER_SIZE>>2); //496B/2=> 248B + #endif + + //step3: inner band voice 14bits EQ filter process + if((filter_step_enable & 0x0e) != 0) + { + if(filter_step_enable & BIT(1)) + { + voice_iir(ps,ps,filter_1,(TL_MIC_BUFFER_SIZE>>2),filter1_shift);//14 bits + } + if(filter_step_enable & BIT(2)) + { + voice_iir(ps,ps,filter_2,(TL_MIC_BUFFER_SIZE>>2),filter2_shift);//14 bits + } + if(filter_step_enable & BIT(3)) + { + voice_iir(ps,ps,filter_3,(TL_MIC_BUFFER_SIZE>>2),filter3_shift);//14 bits + } + } + + // step4: Soft HPF, NONE need +#endif + mic_to_adpcm_split ( ps, TL_MIC_ADPCM_UNIT_SIZE, + (s16 *)(buffer_mic_enc + (ADPCM_PACKET_LEN>>2) * + (buffer_mic_pkt_wptr & (TL_MIC_PACKET_BUFFER_NUM - 1))), 1); + + buffer_mic_rptr = buffer_mic_rptr ? 0 : (TL_MIC_BUFFER_SIZE>>2); + buffer_mic_pkt_wptr++; + int pkts = (buffer_mic_pkt_wptr - buffer_mic_pkt_rptr) & (TL_MIC_PACKET_BUFFER_NUM*2-1); + if (pkts > TL_MIC_PACKET_BUFFER_NUM) { + buffer_mic_pkt_rptr++; + } + } +} + +int * mic_encoder_data_buffer () +{ + if (buffer_mic_pkt_rptr == buffer_mic_pkt_wptr) { + return 0; + } + + int *ps = buffer_mic_enc + (ADPCM_PACKET_LEN>>2) * + (buffer_mic_pkt_rptr & (TL_MIC_PACKET_BUFFER_NUM - 1)); + + + return ps; +} + +void mic_encoder_data_read_ok (void) +{ + buffer_mic_pkt_rptr++; +} + + +#endif + +#elif (TL_AUDIO_MODE & DONGLE_PROJECT) //Dongle + +#if (TL_AUDIO_MODE == TL_AUDIO_DONGLE_ADPCM_GATT_TELINK) //Dongle, GATT Telink +u8 abuf_mic_wptr, abuf_dec_wptr; +u16 abuf_dec_rptr; + +#define DEC_BUFFER_SIZE (MIC_SHORT_DEC_SIZE<<2) +#define PACK_POINTER (abuf_dec_rptr/248) | (abuf_dec_wptr<<8) | (abuf_mic_wptr<<16) +#define USB_ISO_IN_SIZE (MIC_SAMPLE_RATE / 1000) + +u8 abuf_mic[MIC_ADPCM_FRAME_SIZE * 4]; +s16 abuf_dec[DEC_BUFFER_SIZE]; + +int abuf_reset = 0; + +void abuf_init () +{ + abuf_mic_wptr = abuf_dec_wptr = 0; + abuf_reset = 16; +} + +void abuf_mic_add (u32 *p) +{ + u32 *pd = (u32 *) (abuf_mic + (abuf_mic_wptr & 3) * MIC_ADPCM_FRAME_SIZE); + for (int i=0; i<(MIC_ADPCM_FRAME_SIZE>>2); i++) + { + *pd ++ = *p++; + } + abuf_mic_wptr ++; +} + +void abuf_mic_dec () +{ + static int start = 1; + static int abuf_reset_no; + if (abuf_reset) + { + abuf_dec_wptr = abuf_mic_wptr; + } + else + { + u8 num_mic = abuf_mic_wptr - abuf_dec_wptr; + u8 num_dec = abuf_dec_wptr - (abuf_dec_rptr/MIC_SHORT_DEC_SIZE); + + if (num_mic > 4) // in case of overflow + { + abuf_dec_wptr ++; + } + + if (num_dec > 4) + { + abuf_reset = 16; + start = 1; + abuf_reset_no++; + } + else if ( ((!start && num_mic>=1) || (start && num_mic>=2)) && (num_dec <= 3) ) + { + adpcm_to_pcm ( + (s16 *) (abuf_mic + (abuf_dec_wptr & 3) * MIC_ADPCM_FRAME_SIZE), + abuf_dec + (abuf_dec_wptr & 3) * MIC_SHORT_DEC_SIZE, + MIC_SHORT_DEC_SIZE ); + + abuf_dec_wptr ++; // 256-byte = 128-s16 + start = 0; + } + } +} + + +_attribute_ram_code_ void abuf_dec_usb () +{ + static u32 tick_usb_iso_in; + static u8 buffer_empty = 1; + static u8 n_usb_iso = 0; + + n_usb_iso++; + + if (clock_time_exceed (tick_usb_iso_in, 4000)) + { + abuf_reset = 16; + } + + tick_usb_iso_in = clock_time (); + if (abuf_reset) + { + abuf_dec_rptr = abuf_dec_wptr*MIC_SHORT_DEC_SIZE; + abuf_reset--; + } + /////////////////// copy data to usb iso in buffer /////////////// + reg_usb_ep7_ptr = 0; + u8 num = abuf_dec_wptr - (abuf_dec_rptr/MIC_SHORT_DEC_SIZE); + if (num) + { + if ( (buffer_empty && num >= 3) || (!buffer_empty && (num >= 1 || (n_usb_iso & 3))) ) + { + buffer_empty = 0; + + u16 offset = abuf_dec_rptr%DEC_BUFFER_SIZE; + s16 *ps = abuf_dec + offset; + + + if(offset == DEC_BUFFER_SIZE - (USB_ISO_IN_SIZE/2)){ + for (int i=0; i<(USB_ISO_IN_SIZE/2); i++) + { + reg_usb_ep7_dat = *ps; + reg_usb_ep7_dat = *ps++ >> 8; + } + ps = abuf_dec; + for (int i=0; i<(USB_ISO_IN_SIZE/2); i++) + { + reg_usb_ep7_dat = *ps; + reg_usb_ep7_dat = *ps++ >> 8; + } + } + else{ + for (int i=0; i> 8; + } + } + + + abuf_dec_rptr += USB_ISO_IN_SIZE; + if(abuf_dec_rptr >= (MIC_SHORT_DEC_SIZE<<8) ){ + abuf_dec_rptr = 0; + } + } + else + { + for (int i=0; i>1] __attribute__((aligned(4))); +#endif + +#if TL_NOISE_SUPRESSION_ENABLE +extern int md_long; +extern int md_short; +extern int md_im; +extern int md_noise; +extern int md_gain; + +static inline int noise_supression (s16 md) { + + static int md_th =384; + //static int md_long =0; + //static int md_short =0; + //static int md_im =0; + //static int md_noise = 0; + //static int md_gain = 256; + md_long = ((md_long * 1023) + abs (md)) >> 10; + md_short = ((md_short * 127) + abs (md)) >> 7; + md_im = ((md_im * 15) + abs (md)) >> 4; + + //md_long = ((md_long * 127) + abs (md)) >> 7; + //md_short = ((md_short * 31) + abs (md)) >> 5; + //md_im = ((md_im * 3) + abs (md)) >> 2; + + if ((md_noise && (md_short > md_th)) || (md_im > (md_th<<1))) { + md_noise = 0; + md_long = md_short << 2; + } + else if (!md_noise && md_long < md_th) { + md_noise = 1; + } + if (md_noise) { + if (md_gain) { md_gain --; } + } + else { + if (md_gain < 256) { md_gain ++;} + } + + return (md * md_gain + 128) >> 8; +} +#endif + +void voice_iir_OOB(signed short * ps, signed short *pd, int* coef, int nsample,u8 shift); +void voice_iir(signed short * ps, signed short *pd, int* coef, int nsample,u8 shift); +void Audio_VolumeSet(unsigned char input_output_select,unsigned char volume_set_value); +void filter_setting(); + +void audio_mic_param_init(void); +void proc_mic_encoder (void); +int * mic_encoder_data_buffer (); +void mic_encoder_data_read_ok (void); + +#elif (TL_AUDIO_MODE & DONGLE_PROJECT) //Dongle + +void abuf_init (); +void abuf_mic_add (u32 *p); +void abuf_mic_dec (); +void abuf_dec_usb (); + +#endif +#endif /* TL_AUDIO_H_ */ diff --git a/b91/b91m_ble_sdk/application/keyboard/keyboard.c b/b91/b91m_ble_sdk/application/keyboard/keyboard.c new file mode 100755 index 0000000..41374b7 --- /dev/null +++ b/b91/b91m_ble_sdk/application/keyboard/keyboard.c @@ -0,0 +1,509 @@ +/******************************************************************************************************** + * @file keyboard.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "tl_common.h" +#include "drivers.h" +#include "keyboard.h" +#include "application/usbstd/usbkeycode.h" + + +#if (defined(KB_DRIVE_PINS) && defined(KB_SCAN_PINS)) + +const u32 drive_pins[] = KB_DRIVE_PINS; +const u32 scan_pins[] = KB_SCAN_PINS; + +#if (STUCK_KEY_PROCESS_ENABLE) +unsigned char stuckKeyPress[ARRAY_SIZE(drive_pins)]; +#endif + +_attribute_data_retention_ kb_data_t kb_event; +_attribute_data_retention_ kb_data_t kb_event_cache; +_attribute_data_retention_ unsigned char deepback_key_state; +_attribute_data_retention_ u32 deepback_key_tick; + +#ifndef SCAN_PIN_50K_PULLUP_ENABLE +#define SCAN_PIN_50K_PULLUP_ENABLE 0 +#endif + +#ifndef KB_MAP_DEFAULT +#define KB_MAP_DEFAULT 1 +#endif + +#ifndef KB_LINE_MODE +#define KB_LINE_MODE 0 +#endif + +#ifndef KB_LINE_HIGH_VALID +#define KB_LINE_HIGH_VALID 1 +#endif + +#ifndef KB_KEY_FLASH_PIN_MULTI_USE +#define KB_KEY_FLASH_PIN_MULTI_USE 0 +#endif + +#ifndef KB_HAS_CTRL_KEYS +#define KB_HAS_CTRL_KEYS 1 +#endif + +#ifndef KB_RM_GHOST_KEY_EN +#define KB_RM_GHOST_KEY_EN 0 +#endif + +#ifndef KB_HAS_FN_KEY +#define KB_HAS_FN_KEY 1 +#endif + +#ifndef KB_DRV_DELAY_TIME +#define KB_DRV_DELAY_TIME 10 +#endif + +#ifndef KB_STANDARD_KEYBOARD +#define KB_STANDARD_KEYBOARD 0 +#endif + + +#if KB_REPEAT_KEY_ENABLE + +#ifndef KB_REPEAT_KEY_INTERVAL_MS +#define KB_REPEAT_KEY_INTERVAL_MS 200 +#endif +#ifndef KB_REPEAT_KEY_NUM +#define KB_REPEAT_KEY_NUM 4 +#endif +static const unsigned char kb_map_repeat[KB_REPEAT_KEY_NUM] = KB_MAP_REPEAT; + +repeatKey_t repeat_key = { + 0, + 0, + 0, + 0, + U32_MAX, +}; + +#endif + +typedef unsigned char kb_k_mp_t[ARRAY_SIZE(drive_pins)]; //typedef unsigned char kb_k_mp_t[8] + +#if KB_MAP_DEFAULT + +#ifndef KB_MAP_NORMAL +static const unsigned char kb_map_normal[ARRAY_SIZE(scan_pins)][ARRAY_SIZE(drive_pins)] = { + {VK_PAUSE, VK_POWER, VK_EURO, VK_SLEEP, VK_RCTRL, VK_WAKEUP, VK_CTRL, VK_F5}, + {VK_Q, VK_TAB, VK_A, VK_ESC, VK_Z, VK_NCHG, VK_TILDE, VK_1}, + {VK_W, VK_CAPITAL, VK_S, VK_K45, VK_X, VK_CHG, VK_F1, VK_2}, + {VK_E, VK_F3, VK_D, VK_F4, VK_C, VK_ROMA, VK_F2, VK_3}, + {VK_R, VK_T, VK_F, VK_G, VK_V, VK_B, VK_5, VK_4}, + {VK_U, VK_Y, VK_J, VK_H, VK_M, VK_N, VK_6, VK_7}, + {VK_I, VK_RBRACE, VK_K, VK_F6, VK_COMMA, VK_K56, VK_EQUAL, VK_8}, + {VK_O, VK_F7, VK_L, VK_RMB, VK_PERIOD, VK_APP, VK_F8, VK_9}, + {VK_P, VK_LBRACE, VK_SEMICOLON, VK_QUOTE, VK_BACKSLASH, VK_SLASH, VK_MINUS, VK_0}, + {VK_SCR_LOCK,VK_C9R1, VK_FN, VK_ALT, VK_MMODE, VK_RALT, VK_C9R6, VK_PRINTSCREEN}, + {VK_K14, VK_BACKSPACE,VK_BACKSLASH, VK_F11, VK_ENTER, VK_F12, VK_F9, VK_F10}, + {VK_HOME, VK_LEFT, VK_END, VK_SPACE, VK_NUM_LOCK, VK_DOWN, VK_DELETE, VK_POWER}, + {VK_UP, VK_NONE, VK_DOWN, VK_INSERT, VKPAD_SLASH, VK_RIGHT, VK_INSERT, VK_SLEEP}, + {VK_PAGE_UP, VK_RIGHT, VK_PAGE_DOWN, VKPAD_PERIOD, VKPAD_ASTERIX,VKPAD_MINUS, VK_PAGE_UP, VK_PAGE_DOWN}, + {VKPAD_PLUS, VK_K107, VKPAD_ENTER, VK_UP, VK_PLAY_PAUSE,VK_LEFT, VK_HOME, VK_END}, + {VK_WAKEUP, VK_SHIFT, VK_RSHIFT, VK_VOL_DN, VK_VOL_UP, VK_NEXT_TRK, VK_PREV_TRK, VK_MEDIA}, + {VK_MAIL, VK_WIN, VK_W_FORWRD, VK_W_STOP, VK_W_BACK, VK_W_REFRESH, VK_W_MUTE, VK_W_SRCH}, + {VK_KCL, VK_W_FAV, VK_RWIN, VK_MY_COMP, VK_STOP, VK_CAL, VK_WEB, VK_KCR}, +}; +#else +static const unsigned char kb_map_normal[ARRAY_SIZE(scan_pins)][ARRAY_SIZE(drive_pins)] = KB_MAP_NORMAL; +#endif + + +#if (KB_STANDARD_KEYBOARD) +#ifndef KB_MAP_NUM +static const unsigned char kb_map_num[ARRAY_SIZE(scan_pins)][ARRAY_SIZE(drive_pins)] = { + {VK_PAUSE, VK_POWER, VK_EURO, VK_SLEEP, VK_RCTRL, VK_WAKEUP, VK_CTRL, VK_F5}, + {VK_Q, VK_TAB, VK_A, VK_ESC, VK_Z, VK_NCHG, VK_TILDE, VK_1}, + {VK_W, VK_CAPITAL, VK_S, VK_K45, VK_X, VK_CHG, VK_F1, VK_2}, + {VK_E, VK_F3, VK_D, VK_F4, VK_C, VK_ROMA, VK_F2, VK_3}, + {VK_R, VK_T, VK_F, VK_G, VK_V, VK_B, VK_5, VK_4}, + {VK_U, VK_Y, VK_J, VK_H, VK_M, VK_N, VK_6, VK_7}, + {VK_I, VK_RBRACE, VK_K, VK_F6, VK_COMMA, VK_K56, VK_EQUAL, VK_8}, + {VK_O, VK_F7, VK_L, VK_RMB, VK_PERIOD, VK_APP, VK_F8, VK_9}, + {VK_P, VK_LBRACE, VK_SEMICOLON, VK_QUOTE, VK_BACKSLASH, VK_SLASH, VK_MINUS, VK_0}, + {VK_SCR_LOCK,VK_C9R1, VK_FN, VK_ALT, VK_MMODE, VK_RALT, VK_C9R6, VK_PRINTSCREEN}, + {VK_K14, VK_BACKSPACE,VK_BACKSLASH, VK_F11, VK_ENTER, VK_F12, VK_F9, VK_F10}, + {VKPAD_7, VKPAD_4, VKPAD_1, VK_SPACE, VK_NUM_LOCK, VK_DOWN, VK_DELETE, VK_POWER}, + {VKPAD_8, VKPAD_5, VKPAD_2, VKPAD_0, VKPAD_SLASH, VK_RIGHT, VK_INSERT, VK_SLEEP}, + {VKPAD_9, VKPAD_6, VKPAD_3, VKPAD_PERIOD, VKPAD_ASTERIX,VKPAD_MINUS, VK_PAGE_UP, VK_PAGE_DOWN}, + {VKPAD_PLUS, VK_K107, VKPAD_ENTER, VK_UP, VK_PLAY_PAUSE,VK_LEFT, VK_HOME, VK_END}, + {VK_WAKEUP, VK_SHIFT, VK_RSHIFT, VK_VOL_DN, VK_VOL_UP, VK_NEXT_TRK, VK_PREV_TRK, VK_MEDIA}, + {VK_MAIL, VK_WIN, VK_W_FORWRD, VK_W_STOP, VK_W_BACK, VK_W_REFRESH, VK_W_MUTE, VK_W_SRCH}, + {VK_KCL, VK_W_FAV, VK_RWIN, VK_MY_COMP, VK_STOP, VK_CAL, VK_WEB, VK_KCR}, +}; +#else +static const unsigned char kb_map_num[ARRAY_SIZE(scan_pins)][ARRAY_SIZE(drive_pins)] = KB_MAP_NUM; +#endif + +#ifndef KB_MAP_FN +static const unsigned char kb_map_fn[ARRAY_SIZE(scan_pins)][ARRAY_SIZE(drive_pins)] = { + {VK_PAUSE, VK_POWER, VK_EURO, VK_SLEEP, VK_RCTRL, VK_WAKEUP, VK_CTRL, VK_F5}, + {VK_Q, VK_TAB, VK_A, VK_ESC, VK_Z, VK_NCHG, VK_TILDE, VK_1}, + {VK_W, VK_CAPITAL, VK_S, VK_K45, VK_X, VK_CHG, VK_F1, VK_2}, + {VK_E, VK_F3, VK_D, VK_F4, VK_C, VK_ROMA, VK_F2, VK_3}, + {VK_R, VK_T, VK_F, VK_G, VK_V, VK_B, VK_5, VK_4}, + {VK_U, VK_Y, VK_J, VK_H, VK_M, VK_N, VK_6, VK_7}, + {VK_I, VK_RBRACE, VK_K, VK_F6, VK_COMMA, VK_K56, VK_EQUAL, VK_8}, + {VK_O, VK_F7, VK_L, VK_RMB, VK_PERIOD, VK_APP, VK_F8, VK_9}, + {VK_P, VK_LBRACE, VK_SEMICOLON, VK_QUOTE, VK_BACKSLASH, VK_SLASH, VK_MINUS, VK_0}, + {VK_SCR_LOCK,VK_C9R1, VK_FN, VK_ALT, VK_MMODE, VK_RALT, VK_C9R6, VK_PRINTSCREEN}, + {VK_K14, VK_BACKSPACE,VK_BACKSLASH, VK_F11, VK_ENTER, VK_F12, VK_F9, VK_F10}, + {VKPAD_7, VKPAD_4, VKPAD_1, VK_SPACE, VK_NUM_LOCK, VK_DOWN, VK_DELETE, VK_POWER}, + {VKPAD_8, VKPAD_5, VKPAD_2, VKPAD_0, VKPAD_SLASH, VK_RIGHT, VK_INSERT, VK_SLEEP}, + {VKPAD_9, VKPAD_6, VKPAD_3, VKPAD_PERIOD, VKPAD_ASTERIX,VKPAD_MINUS, VK_PAGE_UP, VK_PAGE_DOWN}, + {VKPAD_PLUS, VK_K107, VKPAD_ENTER, VK_UP, VK_PLAY_PAUSE,VK_LEFT, VK_HOME, VK_END}, + {VK_WAKEUP, VK_SHIFT, VK_RSHIFT, VK_VOL_DN, VK_VOL_UP, VK_NEXT_TRK, VK_PREV_TRK, VK_MEDIA}, + {VK_MAIL, VK_WIN, VK_W_FORWRD, VK_W_STOP, VK_W_BACK, VK_W_REFRESH, VK_W_MUTE, VK_W_SRCH}, + {VK_KCL, VK_W_FAV, VK_RWIN, VK_MY_COMP, VK_STOP, VK_CAL, VK_WEB, VK_KCR}, + +}; +#else +static const unsigned char kb_map_fn[ARRAY_SIZE(scan_pins)][ARRAY_SIZE(drive_pins)] = KB_MAP_FN; +#endif + +kb_k_mp_t * kb_p_map[4] = { + kb_map_normal, + kb_map_num, + kb_map_fn, + kb_map_fn, +}; +#endif + + +/////////////////////////////////////////////////////////////////////// +//////////// load configuration from flash/OTP //////////////////////// +/////////////////////////////////////////////////////////////////////// +#else //line 62 + +#endif + +_attribute_data_retention_ u32 scan_pin_need; + +static unsigned char kb_is_fn_pressed = 0; + +kb_k_mp_t * kb_k_mp; + +void kb_rmv_ghost_key(u32 * pressed_matrix){ + u32 mix_final = 0; + foreach_arr(i, drive_pins){ + for(int j = (i+1); j < ARRAY_SIZE(drive_pins); ++j){ + u32 mix = (pressed_matrix[i] & pressed_matrix[j]); + //four or three key at "#" is pressed at the same time, should remove ghost key + if( mix && (!BIT_IS_POW2(mix) || (pressed_matrix[i] ^ pressed_matrix[j])) ){ + // remove ghost keys + //pressed_matrix[i] &= ~mix; + //pressed_matrix[j] &= ~mix; + mix_final |= mix; + } + } + pressed_matrix[i] &= ~mix_final; + } +} + +#if (LONG_PRESS_KEY_POWER_OPTIMIZE) +int key_matrix_same_as_last_cnt = 0; //record key matrix no change cnt +#endif + +unsigned int key_debounce_filter( u32 mtrx_cur[], u32 filt_en ){ + u32 kc = 0; +#if (LONG_PRESS_KEY_POWER_OPTIMIZE) + unsigned char matrix_differ = 0; +#endif + static u32 mtrx_pre[ARRAY_SIZE(drive_pins)]; + static u32 mtrx_last[ARRAY_SIZE(drive_pins)]; + foreach_arr(i, drive_pins){ + u32 mtrx_tmp = mtrx_cur[i]; +#if (STUCK_KEY_PROCESS_ENABLE) + stuckKeyPress[i] = mtrx_tmp ? 1 : 0; +#endif + if( filt_en ){ + //mtrx_cur[i] = (mtrx_last[i] ^ mtrx_tmp) ^ (mtrx_last[i] | mtrx_tmp); //key_matrix_pressed is valid when current and last value is the same + mtrx_cur[i] = ( ~mtrx_last[i] & (mtrx_pre[i] & mtrx_tmp) ) | ( mtrx_last[i] & (mtrx_pre[i] | mtrx_tmp) ); + } + if ( mtrx_cur[i] != mtrx_last[i] ) { + kc = 1; + } +#if (LONG_PRESS_KEY_POWER_OPTIMIZE) + if(mtrx_cur[i]^mtrx_pre[i]){ //when same, XOR value is 0 + matrix_differ = 1; + } +#endif + mtrx_pre[i] = mtrx_tmp; + mtrx_last[i] = mtrx_cur[i]; + } + +#if (LONG_PRESS_KEY_POWER_OPTIMIZE) + if(matrix_differ){ + key_matrix_same_as_last_cnt = 0; + } + else{ + key_matrix_same_as_last_cnt++; + } +#endif + + return kc; +} + + +// input: pressed_matrix, +// key_code: output keys array +// key_max: max keys should be returned +static inline void kb_remap_key_row(int drv_ind, u32 m, int key_max, kb_data_t *kb_data){ + foreach_arr(i, scan_pins){ + if(m & 0x01){ + unsigned char kc = kb_k_mp[i][drv_ind]; +#if(KB_HAS_CTRL_KEYS) + + if(kc >= VK_CTRL && kc <= VK_RWIN) + kb_data->ctrl_key |= BIT(kc - VK_CTRL); + //else if(kc == VK_MEDIA_END) + //lock_button_pressed = 1; + else if(VK_ZOOM_IN == kc || VK_ZOOM_OUT == kc){ + kb_data->ctrl_key |= VK_MSK_LCTRL; + kb_data->keycode[kb_data->cnt++] = (VK_ZOOM_IN == kc)? VK_EQUAL : VK_MINUS; + } + else if(kc != VK_FN)//fix fn ghost bug + kb_data->keycode[kb_data->cnt++] = kc; + +#else + kb_data->keycode[kb_data->cnt++] = kc; +#endif + if(kb_data->cnt >= key_max){ + break; + } + } + m = m >> 1; + if(!m){ + break; + } + } +} + +static inline void kb_remap_key_code(u32 * pressed_matrix, int key_max, kb_data_t *kb_data, int numlock_status){ + +#if (KB_STANDARD_KEYBOARD) + kb_k_mp = kb_p_map[(numlock_status&1) | (kb_is_fn_pressed << 1)]; +#else + kb_k_mp = (kb_k_mp_t *)&kb_map_normal[0]; +#endif + foreach_arr(i, drive_pins){ + u32 m = pressed_matrix[i]; + if(!m) continue; + kb_remap_key_row(i, m, key_max, kb_data); + if(kb_data->cnt >= key_max){ + break; + } + } +} + + +u32 kb_scan_row(int drv_ind, unsigned char * gpio){ + /* + * set as gpio mode if using spi flash pin + * */ + u32 sr = irq_disable(); +#if (KB_KEY_FLASH_PIN_MULTI_USE) + MSPI_AS_GPIO; +#endif + +#if(!KB_LINE_MODE) + u32 drv_pin = drive_pins[drv_ind]; + gpio_write(drv_pin, KB_LINE_HIGH_VALID); + gpio_set_output_en(drv_pin, 1); +#endif + + u32 matrix = 0; + foreach_arr(j, scan_pins){ + if(scan_pin_need & BIT(j)){ + int key = !gpio_read_cache (scan_pins[j], gpio); + if(KB_LINE_HIGH_VALID != key) { + if (KB_HAS_FN_KEY && (kb_k_mp[j][drv_ind] == VK_FN)) { + kb_is_fn_pressed = 1; + } + matrix |= (1 << j); + } + } + } + //sleep_us(KB_DRV_DELAY_TIME); + gpio_read_all (gpio); + /* + * set as spi mode if using spi flash pin + * */ +#if (KB_KEY_FLASH_PIN_MULTI_USE) + MSPI_AS_SPI; +#endif + +#if(!KB_LINE_MODE) + //////// float drive pin //////////////////////////// + //sleep_us(KB_SCAN_DELAY_TIME); + gpio_write(drv_pin, 0); + gpio_set_output_en(drv_pin, 0); +#endif + + irq_restore(sr); + return matrix; +} + +u32 matrix_buff[4][ARRAY_SIZE(drive_pins)]; +int matrix_wptr, matrix_rptr; + + +u32 kb_key_pressed(unsigned char * gpio) +{ + foreach_arr(i,drive_pins){ + gpio_write(drive_pins[i], KB_LINE_HIGH_VALID); + gpio_set_output_en(drive_pins[i], 1); + } + sleep_us (20); + gpio_read_all (gpio); + + u32 ret = 0; + static unsigned char release_cnt = 0; + static u32 ret_last = 0; + + foreach_arr(i,scan_pins){ + if(KB_LINE_HIGH_VALID != !gpio_read_cache (scan_pins[i], gpio)){ + ret |= (1 << i); + release_cnt = 6; + ret_last = ret; + } + //ret = ret && gpio_read(scan_pins[i]); + } + if(release_cnt){ + ret = ret_last; + release_cnt--; + } + foreach_arr(i,drive_pins){ + gpio_write(drive_pins[i], 0); + gpio_set_output_en(drive_pins[i], 0); + } + return ret; +} + +u32 kb_scan_key_value (int numlock_status, int read_key,unsigned char * gpio) +{ + kb_event.cnt = 0; + kb_event.ctrl_key = 0; + kb_is_fn_pressed = 0; + + u32 pressed_matrix[ARRAY_SIZE(drive_pins)] = {0}; +#if (KB_STANDARD_KEYBOARD) + kb_k_mp = kb_p_map[0]; +#else + kb_k_mp = (kb_k_mp_t *)&kb_map_normal[0]; +#endif + kb_scan_row (0, gpio); + for (int i=0; i<=ARRAY_SIZE(drive_pins); i++) { + u32 r = kb_scan_row (i < ARRAY_SIZE(drive_pins) ? i : 0, gpio); + if (i) { + pressed_matrix[i - 1] = r; + } + } + +#if(KB_RM_GHOST_KEY_EN) + kb_rmv_ghost_key(&pressed_matrix[0]); +#endif + + u32 key_changed = key_debounce_filter( pressed_matrix, \ + (numlock_status & KB_NUMLOCK_STATUS_POWERON) ? 0 : 1); + +#if (KB_REPEAT_KEY_ENABLE) + if(key_changed){ + repeat_key.key_change_flg = KEY_CHANGE; + repeat_key.key_change_tick = clock_time(); + } + else{ + if(repeat_key.key_change_flg == KEY_CHANGE){ + repeat_key.key_change_flg = KEY_SAME; + } + + if( repeat_key.key_change_flg == KEY_SAME && repeat_key.key_repeat_flg && \ + clock_time_exceed(repeat_key.key_change_tick,(KB_REPEAT_KEY_INTERVAL_MS-5)*1000)){ + repeat_key.key_change_tick = clock_time(); + key_changed = 1; + } + } +#endif + + /////////////////////////////////////////////////////////////////// + // insert buffer here + // key mapping requires NUMLOCK status + /////////////////////////////////////////////////////////////////// + u32 *pd; + if (key_changed) { + + /////////// push to matrix buffer ///////////////////////// + pd = matrix_buff[matrix_wptr&3]; + for (int k=0; k 4 ) { //overwrite older data + matrix_rptr = (matrix_wptr - 4) & 7; + } + } + + if (numlock_status & KB_NUMLOCK_STATUS_INVALID) { + return 1; //return empty key + } + + ////////// read out ////////// + if (matrix_wptr == matrix_rptr || !read_key) { + return 0; //buffer empty, no data + } + pd = matrix_buff[matrix_rptr&3]; + matrix_rptr = (matrix_rptr + 1) & 7; + + /////////////////////////////////////////////////////////////////// + kb_remap_key_code(pd, KB_RETURN_KEY_MAX, &kb_event, numlock_status); + +#if (KB_REPEAT_KEY_ENABLE) + if(repeat_key.key_change_flg == KEY_CHANGE){ + repeat_key.key_repeat_flg = 0; + + if(kb_event.cnt == 1){ //handle one key repeat only + for(int i=0;icnt || p->ctrl_key); +} +static inline void kb_set_key_invalid(kb_data_t *p){ + p->cnt = p->ctrl_key = 0; +} + + +extern unsigned int kb_key_pressed(unsigned char * gpio); +extern unsigned int kb_scan_key_value (int numlock_status, int read_key,unsigned char * gpio); + +extern unsigned int scan_pin_need; + + +static inline unsigned int kb_scan_key (int numlock_status, int read_key) { + unsigned char gpio[8]; + + + scan_pin_need = kb_key_pressed (gpio); + if(scan_pin_need){ + return kb_scan_key_value(numlock_status,read_key,gpio); + } + else{ +#if (KB_REPEAT_KEY_ENABLE) + repeat_key.key_change_flg = KEY_NONE; +#endif + return 0; + } +} diff --git a/b91/b91m_ble_sdk/application/print/printf.c b/b91/b91m_ble_sdk/application/print/printf.c new file mode 100755 index 0000000..e6c2b0f --- /dev/null +++ b/b91/b91m_ble_sdk/application/print/printf.c @@ -0,0 +1,128 @@ +/******************************************************************************************************** + * @file printf.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "tl_common.h" +#include "drivers.h" +#include "tl_common.h" + +#include +#include "printf.h" + + +#if(DEBUG_MODE==1) + +#if (DEBUG_BUS==DEBUG_USB) + +__attribute__((used)) int _write(int fd, const unsigned char *buf, int size) +{ + + + int i; + for (i = 0; i < size; i++) + { + #if(BLOCK_MODE) + while (read_reg8(USBFIFO) & 0x02); + #endif + write_reg8(EDPS_DAT, buf[i]); + + } + + return i; +} + +#elif ((DEBUG_BUS==DEBUG_IO) && (UART_PRINT_DEBUG_ENABLE)) + + +#ifndef BIT_INTERVAL +#define BIT_INTERVAL (16*1000*1000/PRINT_BAUD_RATE) +#endif + + +#define UART_DEBUG_TX_PIN_REG ((0x140303 + ((DEBUG_INFO_TX_PIN>>8)<<3))) +/** + * @brief This function serves to foramt string by GPIO simulate uart. + * @param[in] byte - a byte need to print + * @return none. + */ +_attribute_ram_code_sec_noinline_ void dr_putchar(unsigned char byte){ + unsigned char j = 0; + unsigned int t1 = 0; + unsigned int t2 = 0; + + + unsigned int pcTxReg = UART_DEBUG_TX_PIN_REG; + unsigned char tmp_bit0 = read_reg8(pcTxReg) & (~(DEBUG_INFO_TX_PIN & 0xff)); + unsigned char tmp_bit1 = read_reg8(pcTxReg) | (DEBUG_INFO_TX_PIN & 0xff); + unsigned char bit[10] = {0}; + + bit[0] = tmp_bit0; + bit[1] = (byte & 0x01)? tmp_bit1 : tmp_bit0; + bit[2] = ((byte>>1) & 0x01)? tmp_bit1 : tmp_bit0; + bit[3] = ((byte>>2) & 0x01)? tmp_bit1 : tmp_bit0; + bit[4] = ((byte>>3) & 0x01)? tmp_bit1 : tmp_bit0; + bit[5] = ((byte>>4) & 0x01)? tmp_bit1 : tmp_bit0; + bit[6] = ((byte>>5) & 0x01)? tmp_bit1 : tmp_bit0; + bit[7] = ((byte>>6) & 0x01)? tmp_bit1 : tmp_bit0; + bit[8] = ((byte>>7) & 0x01)? tmp_bit1 : tmp_bit0; + bit[9] = tmp_bit1; + + t1 = clock_time();//eagle stimer register + for(j = 0;j<10;j++) + { + t2=t1; + while(t1 - t2 < BIT_INTERVAL){ + t1 = clock_time(); + } + + write_reg8(pcTxReg,bit[j]); //send bit0 + } +} + +__attribute__((used)) int _write(int fd, const unsigned char *buf, int size) +{ + + + int i; + for (i = 0; i < size; i++){ + dr_putchar(buf[i]); + } + return i; +} + +void array_printf(unsigned char*data, unsigned int len) { + printf("{"); + for(int i = 0; i < len; ++i){ + printf("%X%s", data[i], i<(len)-1? ":":" "); + } + printf("}\n"); +} +#else +//keep safe, if user call printf func, smp will be wrong, if no printf is used, below can be removed. +__attribute__((used)) int _write(int fd, const unsigned char *buf, int size) +{ + return 0; +} +#endif + +#endif + + diff --git a/b91/b91m_ble_sdk/application/print/printf.h b/b91/b91m_ble_sdk/application/print/printf.h new file mode 100755 index 0000000..c9318ff --- /dev/null +++ b/b91/b91m_ble_sdk/application/print/printf.h @@ -0,0 +1,51 @@ +/******************************************************************************************************** + * @file printf.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once +#include "drivers.h" +#include +#define DEBUG_MODE 1 + +#if(DEBUG_MODE==1) + +#define DEBUG_IO 0 +#define DEBUG_USB 1 + +#define DEBUG_BUS DEBUG_IO + + +#if (DEBUG_BUS==DEBUG_USB) + #define EDPS_DAT (0x100818 |0x80000000) + #define USBFIFO (0x10083d |0x80000000) + #define FIFOTHRESHOLD 4 + #define BLOCK_MODE 0 +#else /* DEBUG_IO */ + #if (UART_PRINT_DEBUG_ENABLE) + void array_printf(unsigned char*data, unsigned int len); + #else + #define array_printf + #define printf + #endif +#endif + +#endif + diff --git a/b91/b91m_ble_sdk/application/rf_frame.h b/b91/b91m_ble_sdk/application/rf_frame.h new file mode 100755 index 0000000..a7f92b7 --- /dev/null +++ b/b91/b91m_ble_sdk/application/rf_frame.h @@ -0,0 +1,204 @@ +/******************************************************************************************************** + * @file rf_frame.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef _RF_FRAME_H_ +#define _RF_FRAME_H_ +#include "../drivers.h" +#include "keyboard/keyboard.h" + + + +#define RF_PROTO_BYTE 0x51 +#define PIPE0_CODE 0x55556666 +#define PIPE1_CODE 0xaabbccdd + + + +#define MOUSE_FRAME_DATA_NUM 4 + +typedef struct { + u8 btn; + s8 x; + s8 y; + s8 wheel; +}mouse_data_t; + + +typedef struct{ + u32 dma_len; //won't be a fixed number as previous, should adjust with the mouse package number + + u8 rf_len; + u8 proto; + u8 flow; + u8 type; + +// u32 gid0; //pipe0 code, used as sync code for control pipe in hamster + + u8 rssi; + u8 per; + u8 seq_no; + u8 rsvd; + + u32 did; + +}rf_packet_pairing_t; + +typedef struct { + u32 dma_len; //won't be a fixed number as previous, should adjust with the mouse package number + + u8 rf_len; + u8 proto; + u8 flow; + u8 type; + +// u32 gid; //pipe0 code, used as sync code for control pipe in hamster + + u8 rssi; + u8 per; + u8 seq_no; + u8 pno; + u8 data[MOUSE_FRAME_DATA_NUM*sizeof(mouse_data_t)]; //now the data length is variable, if the previous no ACK, data will send again in next time + +}rf_packet_mouse_t; + +typedef struct { + u32 dma_len; //won't be a fixed number as previous, should adjust with the mouse package number + + u8 rf_len; + u8 proto; + u8 flow; + u8 type; + +// u32 gid; //pipe0 code, used as sync code for control pipe in hamster + + u8 rssi; + u8 per; + u8 seq_no; + u8 pno; + + u32 did; + + u8 data[4*sizeof(kb_data_t)]; //now the data length is variable, if the previous no ACK, data will send again in next time + +}rf_packet_keyboard_t; + +////////////////////////// host side /////////////////////////////// +typedef struct{ + u32 dma_len; + + u8 rf_len; + u8 proto; + u8 flow; + u8 type; + +// u32 gid0; + + u8 rssi; + u8 per; + u16 tick; + + u8 chn; + u8 info0; + u8 info1; + u8 info2; + + u32 gid1; + u32 did; + +}rf_packet_debug_t; + + +typedef struct{ + u32 dma_len; //won't be a fixed number as previous, should adjust with the mouse package number + u8 rf_len; + u8 proto; + u8 flow; + u8 type; + +// u32 gid0; //pipe0 code, used as sync code for control pipe in hamster + + u8 rssi; + u8 per; + u16 tick; + u8 chn; +}rf_ack_empty_t; + + +typedef struct{ + u32 dma_len; //won't be a fixed number as previous, should adjust with the mouse package number + + u8 rf_len; + u8 proto; + u8 flow; + u8 type; + +// u32 gid0; //pipe0 code, used as sync code for control pipe in hamster + + u8 rssi; + u8 per; + u16 tick; + u8 chn; + u8 info0; + u8 info1; + u8 info2; + + u32 gid1; //pipe1 code, used as sync code for data pipe in hamster + u32 did; + +}rf_packet_ack_pairing_t; + +typedef struct{ + u32 dma_len; //won't be a fixed number as previous, should adjust with the mouse package number + + u8 rf_len; + u8 proto; + u8 flow; + u8 type; + +// u32 gid; //pipe0 code, used as sync code for control pipe in hamster + + u8 rssi; + u8 per; + u16 tick; + u8 chn; + + u8 info; +}rf_packet_ack_mouse_t; + +typedef struct{ + u32 dma_len; //won't be a fixed number as previous, should adjust with the mouse package number + + u8 rf_len; + u8 proto; + u8 flow; + u8 type; + +// u32 gid; //pipe0 code, used as sync code for control pipe in hamster + + u8 rssi; + u8 per; + u16 tick; + u8 chn; + u8 status; +}rf_packet_ack_keyboard_t; + +#endif /* LED_RF_FRAME_H_ */ diff --git a/b91/b91m_ble_sdk/application/usbstd/AudioClassCommon.h b/b91/b91m_ble_sdk/application/usbstd/AudioClassCommon.h new file mode 100755 index 0000000..b10060a --- /dev/null +++ b/b91/b91m_ble_sdk/application/usbstd/AudioClassCommon.h @@ -0,0 +1,353 @@ +/******************************************************************************************************** + * @file AudioClassCommon.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +/* Includes: */ +#include "tl_common.h" +#include "StdDescriptors.h" + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +extern "C" { +#endif + +#define AUDIO_CHANNEL_LEFT_FRONT BIT(0) +#define AUDIO_CHANNEL_RIGHT_FRONT BIT(1) +#define AUDIO_CHANNEL_CENTER_FRONT BIT(2) +#define AUDIO_CHANNEL_LOW_FREQ_ENHANCE BIT(3) +#define AUDIO_CHANNEL_LEFT_SURROUND BIT(4) +#define AUDIO_CHANNEL_RIGHT_SURROUND BIT(5) +#define AUDIO_CHANNEL_LEFT_OF_CENTER BIT(6) +#define AUDIO_CHANNEL_RIGHT_OF_CENTER BIT(7) +#define AUDIO_CHANNEL_SURROUND BIT(8) +#define AUDIO_CHANNEL_SIDE_LEFT BIT(9) +#define AUDIO_CHANNEL_SIDE_RIGHT BIT(10) +#define AUDIO_CHANNEL_TOP BIT(11) + +#define AUDIO_FEATURE_MUTE BIT(0) +#define AUDIO_FEATURE_VOLUME BIT(1) +#define AUDIO_FEATURE_BASS BIT(2) +#define AUDIO_FEATURE_MID BIT(3) +#define AUDIO_FEATURE_TREBLE BIT(4) +#define AUDIO_FEATURE_GRAPHIC_EQUALIZER BIT(5) +#define AUDIO_FEATURE_AUTOMATIC_GAIN BIT(6) +#define AUDIO_FEATURE_DELAY BIT(7) +#define AUDIO_FEATURE_BASS_BOOST BIT(8) +#define AUDIO_FEATURE_BASS_LOUDNESS BIT(9) + +#define AUDIO_TERMINAL_UNDEFINED (0x100) +#define AUDIO_TERMINAL_STREAMING (0x101) +#define AUDIO_TERMINAL_VENDOR (0x1FF) +#define AUDIO_TERMINAL_IN_UNDEFINED (0x200) +#define AUDIO_TERMINAL_IN_MIC (0x201) +#define AUDIO_TERMINAL_IN_DESKTOP_MIC (0x202) +#define AUDIO_TERMINAL_IN_PERSONAL_MIC (0x203) +#define AUDIO_TERMINAL_IN_OMNIDIR_MIC (0x204) +#define AUDIO_TERMINAL_IN_MIC_ARRAY (0x205) +#define AUDIO_TERMINAL_IN_PROCESSING_MIC (0x206) +#define AUDIO_TERMINAL_IN_OUT_UNDEFINED (0x300) +#define AUDIO_TERMINAL_OUT_SPEAKER (0x301) +#define AUDIO_TERMINAL_OUT_HEADPHONES (0x302) +#define AUDIO_TERMINAL_OUT_HEAD_MOUNTED (0x303) +#define AUDIO_TERMINAL_OUT_DESKTOP (0x304) +#define AUDIO_TERMINAL_OUT_ROOM (0x305) +#define AUDIO_TERMINAL_OUT_COMMUNICATION (0x306) +#define AUDIO_TERMINAL_OUT_LOWFREQ (0x307) + +#define AUDIO_SAMPLE_FREQ(freq) { \ + .Byte1 = ((u32)freq & 0xFF), \ + .Byte2 = (((u32)freq >> 8) & 0xFF), \ + .Byte3 = (((u32)freq >> 16) & 0xFF) \ + } + + +#define AUDIO_EP_FULL_PACKETS_ONLY BIT(7) +#define AUDIO_EP_ACCEPTS_SMALL_PACKETS (0<<7) +#define AUDIO_EP_SAMPLE_FREQ_CONTROL BIT(0) +#define AUDIO_EP_PITCH_CONTROL BIT(1) + + +enum Audio_Descriptor_ClassSubclassProtocol_t +{ + AUDIO_CSCP_StreamingProtocol = 0, + AUDIO_CSCP_ControlProtocol = 0, + AUDIO_CSCP_AudioClass = 1, + AUDIO_CSCP_ControlSubclass = 1, + AUDIO_CSCP_AudioStreamingSubclass, + AUDIO_CSCP_MIDIStreamingSubclass, +}; + +enum Audio_CSInterface_AC_SubTypes_t +{ + AUDIO_DSUBTYPE_CSInterface_Header = 1, + AUDIO_DSUBTYPE_CSInterface_InputTerminal, + AUDIO_DSUBTYPE_CSInterface_OutputTerminal, + AUDIO_DSUBTYPE_CSInterface_Mixer, + AUDIO_DSUBTYPE_CSInterface_Selector, + AUDIO_DSUBTYPE_CSInterface_Feature, + AUDIO_DSUBTYPE_CSInterface_Processing, + AUDIO_DSUBTYPE_CSInterface_Extension, +}; + +enum Audio_CSInterface_AS_SubTypes_t +{ + AUDIO_DSUBTYPE_CSInterface_General = 1, + AUDIO_DSUBTYPE_CSInterface_FormatType, + AUDIO_DSUBTYPE_CSInterface_FormatSpecific, +}; + +enum Audio_CSEndpoint_SubTypes_t +{ + AUDIO_DSUBTYPE_CSEndpoint_General = 1, +}; + +enum Audio_ClassRequests_t +{ + AUDIO_REQ_SetCurrent = 1, + AUDIO_REQ_SetMinimum, + AUDIO_REQ_SetMaximum, + AUDIO_REQ_SetResolution, + AUDIO_REQ_SetMemory, + AUDIO_REQ_GetCurrent = 0x81, + AUDIO_REQ_GetMinimum, + AUDIO_REQ_GetMaximum, + AUDIO_REQ_GetResolution, + AUDIO_REQ_GetMemory, + AUDIO_REQ_GetStatus = 0xFF, +}; + +enum Audio_EndpointControls_t +{ + AUDIO_EPCONTROL_SamplingFreq = 1, + AUDIO_EPCONTROL_Pitch, +}; + + +typedef struct +{ + USB_Descriptor_Hdr_t Header; + u8 Subtype; + u8 TerminalID; + u16 TerminalType; + u8 AssociatedOutputTerminal; + u8 TotalChannels; + u16 ChannelConfig; + u8 ChannelStrIndex; + u8 TerminalStrIndex; +}USB_Audio_Descriptor_InputTerminal_t; + +typedef struct +{ + u8 Length; + u8 DescriptorType; + u8 DescriptorSubtype; + u8 TerminalID; + u16 TerminalType; + u8 AssocTerminal; + u8 NrChannels; + u16 ChannelConfig; + u8 ChannelNames; + u8 Terminal; +}USB_Audio_StdDescriptor_InputTerminal_t; + +typedef struct +{ + USB_Descriptor_Hdr_t Header; + u8 Subtype; + u8 TerminalID; + u16 TerminalType; + u8 AssociatedInputTerminal; + u8 SourceID; + u8 TerminalStrIndex; +}USB_Audio_Descriptor_OutputTerminal_t; + +typedef struct +{ + u8 Length; + u8 DescriptorType; + u8 DescriptorSubtype; + u8 TerminalID; + u16 TerminalType; + u8 AssocTerminal; + u8 SourceID; + u8 Terminal; +}USB_Audio_StdDescriptor_OutputTerminal_t; + +typedef struct +{ + USB_Descriptor_Hdr_t Header; + u8 Subtype; + u8 ACSpecification[2]; + u8 TotalLength[2]; + u8 InCollection; + u8 InterfaceNumber; +}USB_Audio_Descriptor_Interface_AC_t; + +typedef struct +{ + USB_Descriptor_Hdr_t Header; + u8 Subtype; + u8 ACSpecification[2]; + u8 TotalLength[2]; + u8 InCollection; + u8 InterfaceNumber_speaker; + u8 InterfaceNumber_mic; +}USB_Audio_Descriptor_Interface_AC_TL_t; + +typedef struct +{ + u8 Length; + u8 DescriptorType; + u8 DescriptorSubtype; + u8 BcdADC[2]; + u8 TotalLength[2]; + u8 InCollection; + u8 InterfaceNumbers; +}USB_Audio_StdDescriptor_Interface_AC_t; + +typedef struct +{ + USB_Descriptor_Hdr_t Header; + u8 Subtype; + u8 UnitID; + u8 SourceID; + u8 ControlSize; + u8 ChannelControls[3]; + u8 FeatureUnitStrIndex; +}USB_Audio_Descriptor_FeatureUnit_t; + +typedef struct +{ + USB_Descriptor_Hdr_t Header; + u8 Subtype; + u8 UnitID; + u8 SourceID; + u8 ControlSize; + u8 ChannelControls[2]; + u8 FeatureUnitStrIndex; +}USB_Audio_Descriptor_FeatureUnit_Mic_t; + +typedef struct +{ + u8 Length; + u8 DescriptorType; + u8 DescriptorSubtype; + u8 UnitID; + u8 SourceID; + u8 ControlSize; + u8 MAControls[3]; + u8 Feature; +}USB_Audio_StdDescriptor_FeatureUnit_t; + +typedef struct +{ + USB_Descriptor_Hdr_t Header; + u8 Subtype; + u8 TerminalLink; + u8 FrameDelay; + u8 AudioFormat[2]; +}USB_Audio_Descriptor_Interface_AS_t; + +typedef struct +{ + u8 Length; + u8 DescriptorType; + u8 DescriptorSubtype; + u8 TerminalLink; + u8 Delay; + u16 FormatTag; +}USB_Audio_StdDescriptor_Interface_AS_t; + +typedef struct +{ + USB_Descriptor_Hdr_t Header; + u8 Subtype; + u8 FormatType; + u8 Channels; + u8 SubFrameSize; + u8 BitResolution; + u8 TotalDiscreteSampleRates; +}USB_Audio_Descriptor_Format_t; + +typedef struct +{ + u8 Byte1; + u8 Byte2; + u8 Byte3; +}USB_Audio_SampleFreq_t; + +typedef struct +{ + u8 Length; + u8 DescriptorType; + u8 DescriptorSubtype; + u8 FormatType; + u8 NrChannels; + u8 SubFrameSize; + u8 BitResolution; + u8 SampleFrequencyType; +}USB_Audio_StdDescriptor_Format_t; + +typedef struct +{ + USB_Descriptor_Endpoint_t Endpoint; + u8 Refresh; + u8 SyncEndpointNumber; +}USB_Audio_Descriptor_StreamEndpoint_Std_t; + +typedef struct +{ + u8 Length; + u8 DescriptorType; + u8 EndpointAddress; + u8 MAttributes; + u16 MaxPacketSize; + u8 Interval; + u8 Refresh; + u8 SynchAddress; +}USB_Audio_StdDescriptor_StreamEndpoint_Std_t; + +typedef struct +{ + USB_Descriptor_Hdr_t Header; + u8 Subtype; + u8 Attributes; + u8 LockDelayUnits; + u8 LockDelay[2]; +}USB_Audio_Descriptor_StreamEndpoint_Spc_t; + +typedef struct +{ + u8 Length; + u8 DescriptorType; + u8 DescriptorSubtype; + u8 MAttributes; + u8 LockDelayUnits; + u16 LockDelay; +}USB_Audio_StdDescriptor_StreamEndpoint_Spc_t; + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +} +#endif + diff --git a/b91/b91m_ble_sdk/application/usbstd/CDCClassCommon.h b/b91/b91m_ble_sdk/application/usbstd/CDCClassCommon.h new file mode 100755 index 0000000..c1f8079 --- /dev/null +++ b/b91/b91m_ble_sdk/application/usbstd/CDCClassCommon.h @@ -0,0 +1,178 @@ +/******************************************************************************************************** + * @file CDCClassCommon.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +/* Includes: */ +#include "application/usbstd/stdDescriptors.h" +#include "tl_common.h" + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +extern "C" { +#endif + + + +#define CDC_CONTROL_LINE_OUT_DTR BIT(0) +#define CDC_CONTROL_LINE_OUT_RTS BIT(1) +#define CDC_CONTROL_LINE_IN_DCD BIT(0) +#define CDC_CONTROL_LINE_IN_DSR BIT(1) +#define CDC_CONTROL_LINE_IN_BREAK BIT(2) +#define CDC_CONTROL_LINE_IN_RING BIT(3) +#define CDC_CONTROL_LINE_IN_FRAMEERROR BIT(4) +#define CDC_CONTROL_LINE_IN_PARITYERROR BIT(5) +#define CDC_CONTROL_LINE_IN_OVERRUNERROR BIT(6) + +#define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \ + struct \ + { \ + USB_Descriptor_Hdr_t Header; \ + u8 SubType; \ + u8 Data[DataSize]; \ + } + +enum CDC_Descriptor_ClassSubclass_Protocol_t +{ + CDC_CSCP_NoSpecific_Subclass = 0x00, + CDC_CSCP_NoSpecific_Protocol = 0x00, + CDC_CSCP_NoData_Subclass = 0x00, + CDC_CSCP_NoData_Protocol = 0x00, + CDC_CSCP_ATCmd_Protocol = 0x01, + CDC_CSCP_CDC_Class = 0x02, + CDC_CSCP_ACM_Subclass = 0x02, + CDC_CSCP_CDCData_Class = 0x0A, + CDC_CSCP_VendorSpecific_Protocol = 0xFF, +}; + +enum CDC_Class_Requestions_t +{ + CDC_REQ_SendEncapsulated_Cmd, + CDC_REQ_GetEncapsulated_Rsp, + CDC_REQ_SetLine_Encoding = 0x20, + CDC_REQ_GetLine_Encoding, + CDC_REQ_SetControlLine_State, + CDC_REQ_SendBreak, +}; + +enum CDC_Class_Notifications_t +{ + CDC_NOTIF_Serial_State = 0x20, +}; + + +enum CDC_Descriptor_Subtypes_t +{ + CDC_DSUBTYPE_CSInterface_Header, + CDC_DSUBTYPE_CSInterface_CallManagement, + CDC_DSUBTYPE_CSInterface_ACM, + CDC_DSUBTYPE_CSInterface_DirectLine, + CDC_DSUBTYPE_CSInterface_TelephoneRinger, + CDC_DSUBTYPE_CSInterface_TelephoneCall, + CDC_DSUBTYPE_CSInterface_Union, + CDC_DSUBTYPE_CSInterface_CountrySelection, + CDC_DSUBTYPE_CSInterface_TelephoneOpModes, + CDC_DSUBTYPE_CSInterface_USBTerminal, + CDC_DSUBTYPE_CSInterface_NetworkChannel, + CDC_DSUBTYPE_CSInterface_ProtocolUnit, + CDC_DSUBTYPE_CSInterface_ExtensionUnit, + CDC_DSUBTYPE_CSInterface_MultiChannel, + CDC_DSUBTYPE_CSInterface_CAPI, + CDC_DSUBTYPE_CSInterface_Ethernet, + CDC_DSUBTYPE_CSInterface_ATM, +}; + +enum CDC_LineEncoding_Formats_t +{ + CDC_LINEENCODING_OneStopBit, + CDC_LINEENCODING_OneAndAHalfStopBits, + CDC_LINEENCODING_TwoStopBits, +}; + +enum CDC_LineEncoding_Parity_t +{ + CDC_PARITY_None, + CDC_PARITY_Odd, + CDC_PARITY_Even, + CDC_PARITY_Mark, + CDC_PARITY_Space, +}; + +typedef struct +{ + USB_Descriptor_Hdr_t Header; + u8 Subtype; + u16 CDCSpecification; +} USB_CDC_Descriptor_FunctionalHeader_t; + +typedef struct +{ + u8 bFunctionLength; + u8 bDescriptorType; + u8 bDescriptorSubType; + u16 bcdCDC; +} USB_CDC_StdDescriptor_FunctionalHeader_t; + +typedef struct +{ + USB_Descriptor_Hdr_t Header; + u8 Subtype; + u8 Capabilities; +} USB_CDC_Descriptor_FunctionalACM_t; + +typedef struct +{ + u8 bFunctionLength; + u8 bDescriptorType; + u8 bDescriptorSubType; + u8 bmCapabilities; +} USB_CDC_StdDescriptor_FunctionalACM_t; + +typedef struct +{ + USB_Descriptor_Hdr_t Header; + u8 Subtype; + u8 MasterInterfaceNumber; + u8 SlaveInterfaceNumber; +} USB_CDC_Descriptor_FunctionalUnion_t; + +typedef struct +{ + u8 bFunctionLength; + u8 bDescriptorType; + u8 bDescriptorSubType; + u8 bMasterInterface; + u8 bSlaveInterface0; +} USB_CDC_StdDescriptor_FunctionalUnion_t; + +typedef struct +{ + u32 BaudRateBPS; + u8 CharFormat; + u8 ParityType; + u8 DataBits; +} CDC_LineEncoding_t; + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) + } +#endif diff --git a/b91/b91m_ble_sdk/application/usbstd/CDCClassDevice.h b/b91/b91m_ble_sdk/application/usbstd/CDCClassDevice.h new file mode 100755 index 0000000..f01896a --- /dev/null +++ b/b91/b91m_ble_sdk/application/usbstd/CDCClassDevice.h @@ -0,0 +1,66 @@ +/******************************************************************************************************** + * @file CDCClassDevice.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +/* Includes: */ +#include +#include "../common/types.h" + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) + extern "C" { +#endif + +typedef struct +{ + struct + { + u8 ControlInterfaceNumber; + u8 DataINEndpointNumber; + u16 DataINEndpointSize; + bool DataINEndpointDoubleBank; + u8 DataOUTEndpointNumber; + u16 DataOUTEndpointSize; + bool DataOUTEndpointDoubleBank; + u8 NotificationEndpointNumber; + u16 NotificationEndpointSize; + bool NotificationEndpointDoubleBank; + } Config; + + struct + { + struct + { + u16 HostToDevice; + u16 DeviceToHost; + } ControlLineStates; + + CDC_LineEncoding_t LineEncoding; + } State; +} USB_ClassInfo_CDC_Device_t; + + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) + } +#endif diff --git a/b91/b91m_ble_sdk/application/usbstd/HIDClassCommon.h b/b91/b91m_ble_sdk/application/usbstd/HIDClassCommon.h new file mode 100755 index 0000000..80d00ca --- /dev/null +++ b/b91/b91m_ble_sdk/application/usbstd/HIDClassCommon.h @@ -0,0 +1,449 @@ +/******************************************************************************************************** + * @file HIDClassCommon.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +/* Includes: */ +#include "application/usbstd/stdDescriptors.h" +#include "tl_common.h" + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +extern "C" { +#endif + +#define HID_KEYBOARD_MODIFIER_LEFTCTRL BIT(0) +#define HID_KEYBOARD_MODIFIER_LEFTSHIFT BIT(1) +#define HID_KEYBOARD_MODIFIER_LEFTALT BIT(2) +#define HID_KEYBOARD_MODIFIER_LEFTGUI BIT(3) +#define HID_KEYBOARD_MODIFIER_RIGHTCTRL BIT(4) +#define HID_KEYBOARD_MODIFIER_RIGHTSHIFT BIT(5) +#define HID_KEYBOARD_MODIFIER_RIGHTALT BIT(6) +#define HID_KEYBOARD_MODIFIER_RIGHTGUI BIT(7) +#define HID_KEYBOARD_LED_NUMLOCK BIT(0) +#define HID_KEYBOARD_LED_CAPSLOCK BIT(1) +#define HID_KEYBOARD_LED_SCROLLLOCK BIT(2) +#define HID_KEYBOARD_LED_KATANA BIT(3) + +#define HID_KEYBOARD_SC_ERROR_ROLLOVER 1 +#define HID_KEYBOARD_SC_POST_FAIL 2 +#define HID_KEYBOARD_SC_ERROR_UNDEFINED 3 +#define HID_KEYBOARD_SC_A 4 +#define HID_KEYBOARD_SC_B 5 +#define HID_KEYBOARD_SC_C 6 +#define HID_KEYBOARD_SC_D 7 +#define HID_KEYBOARD_SC_E 8 +#define HID_KEYBOARD_SC_F 9 +#define HID_KEYBOARD_SC_G 10 +#define HID_KEYBOARD_SC_H 11 +#define HID_KEYBOARD_SC_I 12 +#define HID_KEYBOARD_SC_J 13 +#define HID_KEYBOARD_SC_K 14 +#define HID_KEYBOARD_SC_L 15 +#define HID_KEYBOARD_SC_M 16 +#define HID_KEYBOARD_SC_N 17 +#define HID_KEYBOARD_SC_O 18 +#define HID_KEYBOARD_SC_P 19 +#define HID_KEYBOARD_SC_Q 20 +#define HID_KEYBOARD_SC_R 21 +#define HID_KEYBOARD_SC_S 22 +#define HID_KEYBOARD_SC_T 23 +#define HID_KEYBOARD_SC_U 24 +#define HID_KEYBOARD_SC_V 25 +#define HID_KEYBOARD_SC_W 26 +#define HID_KEYBOARD_SC_X 27 +#define HID_KEYBOARD_SC_Y 28 +#define HID_KEYBOARD_SC_Z 29 +#define HID_KEYBOARD_SC_1_AND_EXCLAMATION 30 +#define HID_KEYBOARD_SC_2_AND_AT 31 +#define HID_KEYBOARD_SC_3_AND_HASHMARK 32 +#define HID_KEYBOARD_SC_4_AND_DOLLAR 33 +#define HID_KEYBOARD_SC_5_AND_PERCENTAGE 34 +#define HID_KEYBOARD_SC_6_AND_CARET 35 +#define HID_KEYBOARD_SC_7_AND_AND_AMPERSAND 36 +#define HID_KEYBOARD_SC_8_AND_ASTERISK 37 +#define HID_KEYBOARD_SC_9_AND_OPENING_PARENTHESIS 38 +#define HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS 39 +#define HID_KEYBOARD_SC_ENTER 40 +#define HID_KEYBOARD_SC_ESCAPE 41 +#define HID_KEYBOARD_SC_BACKSPACE 42 +#define HID_KEYBOARD_SC_TAB 43 +#define HID_KEYBOARD_SC_SPACE 44 +#define HID_KEYBOARD_SC_MINUS_AND_UNDERSCORE 45 +#define HID_KEYBOARD_SC_EQUAL_AND_PLUS 46 +#define HID_KEYBOARD_SC_OPENING_BRACKET_AND_OPENING_BRACE 47 +#define HID_KEYBOARD_SC_CLOSING_BRACKET_AND_CLOSING_BRACE 48 +#define HID_KEYBOARD_SC_BACKSLASH_AND_PIPE 49 +#define HID_KEYBOARD_SC_NON_US_HASHMARK_AND_TILDE 50 +#define HID_KEYBOARD_SC_SEMICOLON_AND_COLON 51 +#define HID_KEYBOARD_SC_APOSTROPHE_AND_QUOTE 52 +#define HID_KEYBOARD_SC_GRAVE_ACCENT_AND_TILDE 53 +#define HID_KEYBOARD_SC_COMMA_AND_LESS_THAN_SIGN 54 +#define HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN 55 +#define HID_KEYBOARD_SC_SLASH_AND_QUESTION_MARK 56 +#define HID_KEYBOARD_SC_CAPS_LOCK 57 +#define HID_KEYBOARD_SC_F1 58 +#define HID_KEYBOARD_SC_F2 59 +#define HID_KEYBOARD_SC_F3 60 +#define HID_KEYBOARD_SC_F4 61 +#define HID_KEYBOARD_SC_F5 62 +#define HID_KEYBOARD_SC_F6 63 +#define HID_KEYBOARD_SC_F7 64 +#define HID_KEYBOARD_SC_F8 65 +#define HID_KEYBOARD_SC_F9 66 +#define HID_KEYBOARD_SC_F10 67 +#define HID_KEYBOARD_SC_F11 68 +#define HID_KEYBOARD_SC_F12 69 +#define HID_KEYBOARD_SC_PRINT_SCREEN 70 +#define HID_KEYBOARD_SC_SCROLL_LOCK 71 +#define HID_KEYBOARD_SC_PAUSE 72 +#define HID_KEYBOARD_SC_INSERT 73 +#define HID_KEYBOARD_SC_HOME 74 +#define HID_KEYBOARD_SC_PAGE_UP 75 +#define HID_KEYBOARD_SC_DELETE 76 +#define HID_KEYBOARD_SC_END 77 +#define HID_KEYBOARD_SC_PAGE_DOWN 78 +#define HID_KEYBOARD_SC_RIGHT_ARROW 79 +#define HID_KEYBOARD_SC_LEFT_ARROW 80 +#define HID_KEYBOARD_SC_DOWN_ARROW 81 +#define HID_KEYBOARD_SC_UP_ARROW 82 +#define HID_KEYBOARD_SC_NUM_LOCK 83 +#define HID_KEYBOARD_SC_KEYPAD_SLASH 84 +#define HID_KEYBOARD_SC_KEYPAD_ASTERISK 85 +#define HID_KEYBOARD_SC_KEYPAD_MINUS 86 +#define HID_KEYBOARD_SC_KEYPAD_PLUS 87 +#define HID_KEYBOARD_SC_KEYPAD_ENTER 88 +#define HID_KEYBOARD_SC_KEYPAD_1_AND_END 89 +#define HID_KEYBOARD_SC_KEYPAD_2_AND_DOWN_ARROW 90 +#define HID_KEYBOARD_SC_KEYPAD_3_AND_PAGE_DOWN 91 +#define HID_KEYBOARD_SC_KEYPAD_4_AND_LEFT_ARROW 92 +#define HID_KEYBOARD_SC_KEYPAD_5 93 +#define HID_KEYBOARD_SC_KEYPAD_6_AND_RIGHT_ARROW 94 +#define HID_KEYBOARD_SC_KEYPAD_7_AND_HOME 95 +#define HID_KEYBOARD_SC_KEYPAD_8_AND_UP_ARROW 96 +#define HID_KEYBOARD_SC_KEYPAD_9_AND_PAGE_UP 97 +#define HID_KEYBOARD_SC_KEYPAD_0_AND_INSERT 98 +#define HID_KEYBOARD_SC_KEYPAD_DOT_AND_DELETE 99 +#define HID_KEYBOARD_SC_NON_US_BACKSLASH_AND_PIPE 100 +#define HID_KEYBOARD_SC_POWER 102 +#define HID_KEYBOARD_SC_EQUAL_SIGN 103 +#define HID_KEYBOARD_SC_F13 104 +#define HID_KEYBOARD_SC_F14 105 +#define HID_KEYBOARD_SC_F15 106 +#define HID_KEYBOARD_SC_F16 107 +#define HID_KEYBOARD_SC_F17 108 +#define HID_KEYBOARD_SC_F18 109 +#define HID_KEYBOARD_SC_F19 110 +#define HID_KEYBOARD_SC_F20 111 +#define HID_KEYBOARD_SC_F21 112 +#define HID_KEYBOARD_SC_F22 113 +#define HID_KEYBOARD_SC_F23 114 +#define HID_KEYBOARD_SC_F24 115 +#define HID_KEYBOARD_SC_EXECUTE 116 +#define HID_KEYBOARD_SC_HELP 117 +#define HID_KEYBOARD_SC_MANU 118 +#define HID_KEYBOARD_SC_SELECT 119 +#define HID_KEYBOARD_SC_STOP 120 +#define HID_KEYBOARD_SC_AGAIN 121 +#define HID_KEYBOARD_SC_UNDO 122 +#define HID_KEYBOARD_SC_CUT 123 +#define HID_KEYBOARD_SC_COPY 124 +#define HID_KEYBOARD_SC_PASTE 125 +#define HID_KEYBOARD_SC_FIND 126 +#define HID_KEYBOARD_SC_MUTE 127 +#define HID_KEYBOARD_SC_VOLUME_UP 128 +#define HID_KEYBOARD_SC_VOLUME_DOWN 129 +#define HID_KEYBOARD_SC_LOCKING_CAPS_LOCK 130 +#define HID_KEYBOARD_SC_LOCKING_NUM_LOCK 131 +#define HID_KEYBOARD_SC_LOCKING_SCROLL_LOCK 132 +#define HID_KEYBOARD_SC_KEYPAD_COMMA 133 +#define HID_KEYBOARD_SC_KEYPAD_EQUAL_SIGN 134 +#define HID_KEYBOARD_SC_INTERNATIONAL1 135 +#define HID_KEYBOARD_SC_INTERNATIONAL2 136 +#define HID_KEYBOARD_SC_INTERNATIONAL3 137 +#define HID_KEYBOARD_SC_INTERNATIONAL4 138 +#define HID_KEYBOARD_SC_INTERNATIONAL5 139 +#define HID_KEYBOARD_SC_INTERNATIONAL6 140 +#define HID_KEYBOARD_SC_INTERNATIONAL7 141 +#define HID_KEYBOARD_SC_INTERNATIONAL8 142 +#define HID_KEYBOARD_SC_INTERNATIONAL9 143 +#define HID_KEYBOARD_SC_LANG1 144 +#define HID_KEYBOARD_SC_LANG2 145 +#define HID_KEYBOARD_SC_LANG3 146 +#define HID_KEYBOARD_SC_LANG4 147 +#define HID_KEYBOARD_SC_LANG5 148 +#define HID_KEYBOARD_SC_LANG6 149 +#define HID_KEYBOARD_SC_LANG7 150 +#define HID_KEYBOARD_SC_LANG8 151 +#define HID_KEYBOARD_SC_LANG9 152 +#define HID_KEYBOARD_SC_ALTERNATE_ERASE 153 +#define HID_KEYBOARD_SC_SISREQ 154 +#define HID_KEYBOARD_SC_CANCEL 155 +#define HID_KEYBOARD_SC_CLEAR 156 +#define HID_KEYBOARD_SC_PRIOR 157 +#define HID_KEYBOARD_SC_RETURN 158 +#define HID_KEYBOARD_SC_SEPARATOR 159 +#define HID_KEYBOARD_SC_OUT 160 +#define HID_KEYBOARD_SC_OPER 161 +#define HID_KEYBOARD_SC_CLEAR_AND_AGAIN 162 +#define HID_KEYBOARD_SC_CRSEL_ANDPROPS 163 +#define HID_KEYBOARD_SC_EXSEL 164 +#define HID_KEYBOARD_SC_KEYPAD_00 176 +#define HID_KEYBOARD_SC_KEYPAD_000 177 +#define HID_KEYBOARD_SC_THOUSANDS_SEPARATOR 178 +#define HID_KEYBOARD_SC_DECIMAL_SEPARATOR 179 +#define HID_KEYBOARD_SC_CURRENCY_UNIT 180 +#define HID_KEYBOARD_SC_CURRENCY_SUB_UNIT 181 +#define HID_KEYBOARD_SC_KEYPAD_OPENING_PARENTHESIS 182 +#define HID_KEYBOARD_SC_KEYPAD_CLOSING_PARENTHESIS 183 +#define HID_KEYBOARD_SC_KEYPAD_OPENING_BRACE 184 +#define HID_KEYBOARD_SC_KEYPAD_CLOSING_BRACE 185 +#define HID_KEYBOARD_SC_KEYPAD_TAB 186 +#define HID_KEYBOARD_SC_KEYPAD_BACKSPACE 187 +#define HID_KEYBOARD_SC_KEYPAD_A 188 +#define HID_KEYBOARD_SC_KEYPAD_B 189 +#define HID_KEYBOARD_SC_KEYPAD_C 190 +#define HID_KEYBOARD_SC_KEYPAD_D 191 +#define HID_KEYBOARD_SC_KEYPAD_E 192 +#define HID_KEYBOARD_SC_KEYPAD_F 193 +#define HID_KEYBOARD_SC_KEYPAD_XOR 194 +#define HID_KEYBOARD_SC_KEYPAD_CARET 195 +#define HID_KEYBOARD_SC_KEYPAD_PERCENTAGE 196 +#define HID_KEYBOARD_SC_KEYPAD_LESS_THAN_SIGN 197 +#define HID_KEYBOARD_SC_KEYPAD_GREATER_THAN_SIGN 198 +#define HID_KEYBOARD_SC_KEYPAD_AMP 199 +#define HID_KEYBOARD_SC_KEYPAD_AMP_AMP 200 +#define HID_KEYBOARD_SC_KEYPAD_PIPE 201 +#define HID_KEYBOARD_SC_KEYPAD_PIPE_PIPE 202 +#define HID_KEYBOARD_SC_KEYPAD_COLON 203 +#define HID_KEYBOARD_SC_KEYPAD_HASHMARK 204 +#define HID_KEYBOARD_SC_KEYPAD_SPACE 205 +#define HID_KEYBOARD_SC_KEYPAD_AT 206 +#define HID_KEYBOARD_SC_KEYPAD_EXCLAMATION_SIGN 207 +#define HID_KEYBOARD_SC_KEYPAD_MEMORY_STORE 208 +#define HID_KEYBOARD_SC_KEYPAD_MEMORY_RECALL 209 +#define HID_KEYBOARD_SC_KEYPAD_MEMORY_CLEAR 210 +#define HID_KEYBOARD_SC_KEYPAD_MEMORY_ADD 211 +#define HID_KEYBOARD_SC_KEYPAD_MEMORY_SUBTRACT 212 +#define HID_KEYBOARD_SC_KEYPAD_MEMORY_MULTIPLY 213 +#define HID_KEYBOARD_SC_KEYPAD_MEMORY_DIVIDE 214 +#define HID_KEYBOARD_SC_KEYPAD_PLUS_AND_MINUS 215 +#define HID_KEYBOARD_SC_KEYPAD_CLEAR 216 +#define HID_KEYBOARD_SC_KEYPAD_CLEAR_ENTRY 217 +#define HID_KEYBOARD_SC_KEYPAD_BINARY 218 +#define HID_KEYBOARD_SC_KEYPAD_OCTAL 219 +#define HID_KEYBOARD_SC_KEYPAD_DECIMAL 220 +#define HID_KEYBOARD_SC_KEYPAD_HEXADECIMAL 221 +#define HID_KEYBOARD_SC_LEFT_CONTROL 224 +#define HID_KEYBOARD_SC_LEFT_SHIFT 225 +#define HID_KEYBOARD_SC_LEFT_ALT 226 +#define HID_KEYBOARD_SC_LEFT_GUI 227 +#define HID_KEYBOARD_SC_RIGHT_CONTROL 228 +#define HID_KEYBOARD_SC_RIGHT_SHIFT 229 +#define HID_KEYBOARD_SC_RIGHT_ALT 230 +#define HID_KEYBOARD_SC_RIGHT_GUI 231 + +#define HID_DESCRIPTOR_JOYSTICK(NumAxis, MinAxisVal, MaxAxisVal, MinPhysicalVal, MaxPhysicalVal, Buttons) \ + HID_RPT_USAGE_PAGE (8, 0x01), \ + HID_RPT_USAGE (8, 0x04), \ + HID_RPT_COLLECTION (8, 0x01), \ + HID_RPT_USAGE (8, 0x01), \ + HID_RPT_COLLECTION (8, 0x00), \ + HID_RPT_USAGE_MINIMUM (8, 0x30), \ + HID_RPT_USAGE_MAXIMUM (8, (0x30 + (NumAxis - 1))), \ + HID_RPT_LOGICAL_MINIMUM (16, MinAxisVal), \ + HID_RPT_LOGICAL_MAXIMUM (16, MaxAxisVal), \ + HID_RPT_PHYSICAL_MINIMUM(16, MinPhysicalVal), \ + HID_RPT_PHYSICAL_MAXIMUM(16, MaxPhysicalVal), \ + HID_RPT_REPORT_COUNT (8, NumAxis), \ + HID_RPT_REPORT_SIZE (8, ((((MinAxisVal >= -0xFF) && (MaxAxisVal <= 0xFF)) ? 8 : 16))), \ + HID_RPT_INPUT (8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \ + HID_RPT_END_COLLECTION (0), \ + HID_RPT_USAGE_PAGE (8, 0x09), \ + HID_RPT_USAGE_MINIMUM (8, 0x01), \ + HID_RPT_USAGE_MAXIMUM (8, Buttons), \ + HID_RPT_LOGICAL_MINIMUM (8, 0x00), \ + HID_RPT_LOGICAL_MAXIMUM (8, 0x01), \ + HID_RPT_REPORT_SIZE (8, 0x01), \ + HID_RPT_REPORT_COUNT (8, Buttons), \ + HID_RPT_INPUT (8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \ + HID_RPT_REPORT_SIZE (8, (8 - (Buttons % 8))), \ + HID_RPT_REPORT_COUNT (8, 0x01), \ + HID_RPT_INPUT (8, HID_IOF_CONSTANT), \ + HID_RPT_END_COLLECTION (0) + +#define HID_DESCRIPTOR_KEYBOARD(MaxKeys) \ + HID_RPT_USAGE_PAGE (8, 0x01), \ + HID_RPT_USAGE (8, 0x06), \ + HID_RPT_COLLECTION (8, 0x01), \ + HID_RPT_USAGE_PAGE (8, 0x07), \ + HID_RPT_USAGE_MINIMUM (8, 0xE0), \ + HID_RPT_USAGE_MAXIMUM (8, 0xE7), \ + HID_RPT_LOGICAL_MINIMUM (8, 0x00), \ + HID_RPT_LOGICAL_MAXIMUM (8, 0x01), \ + HID_RPT_REPORT_COUNT (8, 0x08), \ + HID_RPT_REPORT_SIZE (8, 0x01), \ + HID_RPT_INPUT (8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \ + HID_RPT_INPUT (8, HID_IOF_CONSTANT | HID_IOF_VARIABLE), \ + HID_RPT_REPORT_COUNT (8, 0x05), \ + HID_RPT_USAGE_PAGE (8, 0x08), \ + HID_RPT_USAGE_MINIMUM (8, 0x01), \ + HID_RPT_USAGE_MAXIMUM (8, 0x05), \ + HID_RPT_OUTPUT (8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), \ + HID_RPT_REPORT_COUNT (8, 0x01), \ + HID_RPT_REPORT_SIZE (8, 0x03), \ + HID_RPT_OUTPUT (8, HID_IOF_CONSTANT), \ + HID_RPT_REPORT_COUNT (8, 0x06), \ + HID_RPT_REPORT_SIZE (8, 0x08), \ + HID_RPT_LOGICAL_MINIMUM (8, 0x00), \ + 0x26, 0xa4, 0x00, \ + HID_RPT_USAGE_PAGE (8, 0x07), \ + HID_RPT_USAGE_MINIMUM (8, 0x00), \ + 0x2a, 0xa4, 0x00, \ + HID_RPT_INPUT (8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), \ + HID_RPT_END_COLLECTION(0) + +#define HID_DESCRIPTOR_MOUSE(MinAxisVal, MaxAxisVal, MinPhysicalVal, MaxPhysicalVal, Buttons, AbsoluteCoords) \ + HID_RPT_USAGE_PAGE (8, 0x01), \ + HID_RPT_USAGE (8, 0x02), \ + HID_RPT_COLLECTION (8, 0x01), \ + HID_RPT_USAGE (8, 0x01), \ + HID_RPT_COLLECTION (8, 0x00), \ + HID_RPT_USAGE_PAGE (8, 0x09), \ + HID_RPT_USAGE_MINIMUM (8, 0x01), \ + HID_RPT_USAGE_MAXIMUM (8, Buttons), \ + HID_RPT_LOGICAL_MINIMUM (8, 0x00), \ + HID_RPT_LOGICAL_MAXIMUM (8, 0x01), \ + HID_RPT_REPORT_COUNT (8, Buttons), \ + HID_RPT_REPORT_SIZE (8, 0x01), \ + HID_RPT_INPUT (8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \ + HID_RPT_REPORT_COUNT (8, 0x01), \ + HID_RPT_REPORT_SIZE (8, (8 - (Buttons % 8))), \ + HID_RPT_INPUT (8, HID_IOF_CONSTANT), \ + HID_RPT_USAGE_PAGE (8, 0x01), \ + HID_RPT_USAGE (8, 0x30), \ + HID_RPT_USAGE (8, 0x31), \ + HID_RPT_LOGICAL_MINIMUM (16, MinAxisVal), \ + HID_RPT_LOGICAL_MAXIMUM (16, MaxAxisVal), \ + HID_RPT_PHYSICAL_MINIMUM (16, MinPhysicalVal), \ + HID_RPT_PHYSICAL_MAXIMUM (16, MaxPhysicalVal), \ + HID_RPT_REPORT_COUNT (8, 0x02), \ + HID_RPT_REPORT_SIZE (8, ((((MinAxisVal >= -0xFF) && (MaxAxisVal <= 0xFF)) ? 8 : 16))), \ + HID_RPT_INPUT (8, HID_IOF_DATA | HID_IOF_VARIABLE | (AbsoluteCoords ? HID_IOF_ABSOLUTE : HID_IOF_RELATIVE)), \ + HID_RPT_END_COLLECTION (0), \ + HID_RPT_END_COLLECTION(0) + +#define HID_DESCRIPTOR_VENDOR(VendorPageNum, CollectionUsage, DataINUsage, DataOUTUsage, NumBytes) \ + HID_RPT_USAGE_PAGE (16, (0xFF00 | VendorPageNum)), \ + HID_RPT_USAGE (8, CollectionUsage), \ + HID_RPT_COLLECTION (8, 0x01), \ + HID_RPT_USAGE (8, DataINUsage), \ + HID_RPT_LOGICAL_MINIMUM (8, 0x00), \ + HID_RPT_LOGICAL_MAXIMUM (8, 0xFF), \ + HID_RPT_REPORT_SIZE (8, 0x08), \ + HID_RPT_REPORT_COUNT (8, NumBytes), \ + HID_RPT_INPUT (8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \ + HID_RPT_USAGE (8, DataOUTUsage), \ + HID_RPT_LOGICAL_MINIMUM (8, 0x00), \ + HID_RPT_LOGICAL_MAXIMUM (8, 0xFF), \ + HID_RPT_REPORT_SIZE (8, 0x08), \ + HID_RPT_REPORT_COUNT (8, NumBytes), \ + HID_RPT_OUTPUT (8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), \ + HID_RPT_END_COLLECTION (0) + +enum HID_Descriptor_ClassSubclassProtocol_t +{ + HID_CSCP_NonBootSubclass = 0x00, + HID_CSCP_NonBootProtocol = 0x00, + HID_CSCP_BootSubclass = 0x01, + HID_CSCP_KeyboardBootProtocol = 0x01, + HID_CSCP_MouseBootProtocol, + HID_CSCP_HIDClass, +}; + +enum HID_ClassRequests_t +{ + HID_REQ_GetReport = 0x01, + HID_REQ_GetIdle, + HID_REQ_GetProtocol, + HID_REQ_SetReport = 0x09, + HID_REQ_SetIdle, + HID_REQ_SetProtocol, +}; + +enum HID_DescriptorTypes_t +{ + HID_DTYPE_HID = 0x21, + HID_DTYPE_Report, +}; + +enum HID_ReportItemTypes_t +{ + HID_REPORT_ITEM_In, + HID_REPORT_ITEM_Out, + HID_REPORT_ITEM_Feature, + HID_REPORT_CUSTOM, +}; + +typedef struct +{ + USB_Descriptor_Hdr_t Header; + + u16 HIDSpec; + u8 CountryCode; + u8 TotalReportDescriptors; + u8 HIDReportType; + u8 HIDReportLength[2]; +}USB_HID_Descriptor_HID_t; + +typedef struct +{ + u8 Length; + u8 DescriptorType; + u16 BcdHID; + u8 CountryCode; + u8 NumDescriptors; + u8 DescriptorType2; + u8 DescriptorLength[2]; +}USB_HID_StdDescriptor_HID_t; + +typedef struct +{ + u8 Button; + s8 X; + s8 Y; +}USB_MouseReport_Data_t; + +typedef struct +{ + u8 Modifier; + u8 Reserved; + u8 KeyCode[6]; +}USB_KeyboardReport_Data_t; + +typedef u8 USB_Descriptor_HIDReport_Datatype_t; + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +} +#endif + diff --git a/b91/b91m_ble_sdk/application/usbstd/HIDClassDevice.h b/b91/b91m_ble_sdk/application/usbstd/HIDClassDevice.h new file mode 100755 index 0000000..0ac6cc4 --- /dev/null +++ b/b91/b91m_ble_sdk/application/usbstd/HIDClassDevice.h @@ -0,0 +1,58 @@ +/******************************************************************************************************** + * @file HIDClassDevice.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +/* Includes: */ +#include "../common/types.h" + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) + extern "C" { +#endif + +typedef struct +{ + u8 InterfaceNumber; + u8 ReportINEndpointNumber; + u16 ReportINEndpointSize; + bool ReportINEndpointDoubleBank; + void* PrevReportINBuffer; + u8 PrevReportINBufferSize; +} usbhid_config_t; + +typedef struct +{ + bool UsingReportProtocol; + u16 PrevFrameNum; + u16 IdleCount; + u16 IdleMSRemaining; +} usbhid_state_t; + + + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) + } +#endif + + diff --git a/b91/b91m_ble_sdk/application/usbstd/HIDReportData.h b/b91/b91m_ble_sdk/application/usbstd/HIDReportData.h new file mode 100755 index 0000000..7a26753 --- /dev/null +++ b/b91/b91m_ble_sdk/application/usbstd/HIDReportData.h @@ -0,0 +1,110 @@ +/******************************************************************************************************** + * @file HIDReportData.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#define HID_RPT_DATA_SIZE_MASK (0x03) +#define HID_RPT_TYPE_MASK (0x0C) +#define HID_RPT_TAG_MASK (0xF0) + +#define HID_RPT_TYPE_MAIN (0x00) +#define HID_RPT_TYPE_GLOBAL (0x04) +#define HID_RPT_TYPE_LOCAL (0x08) + +#define HID_RPT_DATA_BITS_0 (0x00) +#define HID_RPT_DATA_BITS_8 (0x01) +#define HID_RPT_DATA_BITS_16 (0x02) +#define HID_RPT_DATA_BITS_32 (0x03) +#define HID_RPT_DATA_BITS(Data_bits) HID_RPT_DATA_BITS_##Data_bits + +#define _HID_RPT_DATA_ENCODE_0(Data) +#define _HID_RPT_DATA_ENCODE_8(Data) , (Data & 0xFF) +#define _HID_RPT_DATA_ENCODE_16(Data) _HID_RPT_DATA_ENCODE_8(Data) _HID_RPT_DATA_ENCODE_8(Data>>8) +#define _HID_RPT_DATA_ENCODE_32(Data) _HID_RPT_DATA_ENCODE_16(Data) _HID_RPT_DATA_ENCODE_16(Data>>16) +#define _HID_RPT_DATA_ENCODE(Data_bits, ...) _HID_RPT_DATA_ENCODE_##Data_bits(__VA_ARGS__) + + +#define _HID_RPT_DATA_ENTRY(Type, Tag, Data_bits, ...) \ + (Type | Tag | HID_RPT_DATA_BITS(Data_bits)) _HID_RPT_DATA_ENCODE(Data_bits, (__VA_ARGS__)) + + +#define HID_IOF_CONSTANT BIT(0) +#define HID_IOF_DATA (0<<0) +#define HID_IOF_VARIABLE BIT(1) +#define HID_IOF_ARRAY (0<<1) +#define HID_IOF_RELATIVE BIT(2) +#define HID_IOF_ABSOLUTE (0<<2) +#define HID_IOF_WRAP BIT(3) +#define HID_IOF_NO_WRAP (0<<3) +#define HID_IOF_NON_LINEAR BIT(4) +#define HID_IOF_LINEAR (0<<4) +#define HID_IOF_NO_PREFERRED_STATE BIT(5) +#define HID_IOF_PREFERRED_STATE (0<<5) +#define HID_IOF_NULLSTATE BIT(6) +#define HID_IOF_NO_NULL_POSITION (0<<6) +#define HID_IOF_VOLATILE BIT(7) +#define HID_IOF_NON_VOLATILE (0<<7) +#define HID_IOF_BUFFERED_BYTES BIT(8) +#define HID_IOF_BITFIELD (0<<8) + + +#define HID_RPT_INPUT(Data_bits, ...) _HID_RPT_DATA_ENTRY(HID_RPT_TYPE_MAIN , \ + 0x80, Data_bits, __VA_ARGS__) +#define HID_RPT_OUTPUT(Data_bits, ...) _HID_RPT_DATA_ENTRY(HID_RPT_TYPE_MAIN , \ + 0x90, Data_bits, __VA_ARGS__) +#define HID_RPT_COLLECTION(Data_bits, ...) _HID_RPT_DATA_ENTRY(HID_RPT_TYPE_MAIN , \ + 0xA0, Data_bits, __VA_ARGS__) +#define HID_RPT_FEATURE(Data_bits, ...) _HID_RPT_DATA_ENTRY(HID_RPT_TYPE_MAIN , \ + 0xB0, Data_bits, __VA_ARGS__) +#define HID_RPT_END_COLLECTION(Data_bits, ...) _HID_RPT_DATA_ENTRY(HID_RPT_TYPE_MAIN , \ + 0xC0, Data_bits, __VA_ARGS__) +#define HID_RPT_USAGE_PAGE(Data_bits, ...) _HID_RPT_DATA_ENTRY(HID_RPT_TYPE_GLOBAL, \ + 0x00, Data_bits, __VA_ARGS__) +#define HID_RPT_LOGICAL_MINIMUM(Data_bits, ...) _HID_RPT_DATA_ENTRY(HID_RPT_TYPE_GLOBAL, \ + 0x10, Data_bits, __VA_ARGS__) +#define HID_RPT_LOGICAL_MAXIMUM(Data_bits, ...) _HID_RPT_DATA_ENTRY(HID_RPT_TYPE_GLOBAL, \ + 0x20, Data_bits, __VA_ARGS__) +#define HID_RPT_PHYSICAL_MINIMUM(Data_bits, ...) _HID_RPT_DATA_ENTRY(HID_RPT_TYPE_GLOBAL, \ + 0x30, Data_bits, __VA_ARGS__) +#define HID_RPT_PHYSICAL_MAXIMUM(Data_bits, ...) _HID_RPT_DATA_ENTRY(HID_RPT_TYPE_GLOBAL, \ + 0x40, Data_bits, __VA_ARGS__) +#define HID_RPT_UNIT_EXPONENT(Data_bits, ...) _HID_RPT_DATA_ENTRY(HID_RPT_TYPE_GLOBAL, \ + 0x50, Data_bits, __VA_ARGS__) +#define HID_RPT_UNIT(Data_bits, ...) _HID_RPT_DATA_ENTRY(HID_RPT_TYPE_GLOBAL, \ + 0x60, Data_bits, __VA_ARGS__) +#define HID_RPT_REPORT_SIZE(Data_bits, ...) _HID_RPT_DATA_ENTRY(HID_RPT_TYPE_GLOBAL, \ + 0x70, Data_bits, __VA_ARGS__) +#define HID_RPT_REPORT_ID(Data_bits, ...) _HID_RPT_DATA_ENTRY(HID_RPT_TYPE_GLOBAL, \ + 0x80, Data_bits, __VA_ARGS__) +#define HID_RPT_REPORT_COUNT(Data_bits, ...) _HID_RPT_DATA_ENTRY(HID_RPT_TYPE_GLOBAL, \ + 0x90, Data_bits, __VA_ARGS__) +#define HID_RPT_PUSH(Data_bits, ...) _HID_RPT_DATA_ENTRY(HID_RPT_TYPE_GLOBAL, \ + 0xA0, Data_bits, __VA_ARGS__) +#define HID_RPT_POP(Data_bits, ...) _HID_RPT_DATA_ENTRY(HID_RPT_TYPE_GLOBAL, \ + 0xB0, Data_bits, __VA_ARGS__) +#define HID_RPT_USAGE(Data_bits, ...) _HID_RPT_DATA_ENTRY(HID_RPT_TYPE_LOCAL , \ + 0x00, Data_bits, __VA_ARGS__) +#define HID_RPT_USAGE_MINIMUM(Data_bits, ...) _HID_RPT_DATA_ENTRY(HID_RPT_TYPE_LOCAL , \ + 0x10, Data_bits, __VA_ARGS__) +#define HID_RPT_USAGE_MAXIMUM(Data_bits, ...) _HID_RPT_DATA_ENTRY(HID_RPT_TYPE_LOCAL , \ + 0x20, Data_bits, __VA_ARGS__) + diff --git a/b91/b91m_ble_sdk/application/usbstd/MassStorageClassCommon.h b/b91/b91m_ble_sdk/application/usbstd/MassStorageClassCommon.h new file mode 100755 index 0000000..a478d76 --- /dev/null +++ b/b91/b91m_ble_sdk/application/usbstd/MassStorageClassCommon.h @@ -0,0 +1,178 @@ +/******************************************************************************************************** + * @file MassStorageClassCommon.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +/* Includes: */ +#include +#include "../common/types.h" + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +extern "C" { +#endif + +#pragma pack(1) + +#define MS_CBW_SIGNATURE 0x43425355UL +#define MS_CSW_SIGNATURE 0x53425355UL +#define MS_COMMAND_DIR_DATA_OUT (0<<7) +#define MS_COMMAND_DIR_DATA_IN (1<<7) + +#define MS_SCSI_CMD_INQUIRY 0x12 +#define MS_SCSI_CMD_REQUEST_SENSE 0x03 +#define MS_SCSI_CMD_TEST_UNIT_READY 0x00 +#define MS_SCSI_CMD_READ_CAPACITY_10 0x25 +#define MS_SCSI_CMD_SEND_DIAGNOSTIC 0x1D +#define MS_SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E +#define MS_SCSI_CMD_WRITE_10 0x2A +#define MS_SCSI_CMD_READ_10 0x28 +#define MS_SCSI_CMD_WRITE_6 0x0A +#define MS_SCSI_CMD_READ_6 0x08 +#define MS_SCSI_CMD_VERIFY_10 0x2F +#define MS_SCSI_CMD_MODE_SENSE_6 0x1A +#define MS_SCSI_CMD_MODE_SENSE_10 0x5A + +#define MS_SCSI_SENSE_KEY_GOOD 0x00 +#define MS_SCSI_SENSE_KEY_RECOVERED_ERROR 0x01 +#define MS_SCSI_SENSE_KEY_NOT_READY 0x02 +#define MS_SCSI_SENSE_KEY_MEDIUM_ERROR 0x03 +#define MS_SCSI_SENSE_KEY_HARDWARE_ERROR 0x04 +#define MS_SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05 + +#define MS_SCSI_SENSE_KEY_UNIT_ATTENTION 0x06 +#define MS_SCSI_SENSE_KEY_DATA_PROTECT 0x07 +#define MS_SCSI_SENSE_KEY_BLANK_CHECK 0x08 +#define MS_SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09 +#define MS_SCSI_SENSE_KEY_COPY_ABORTED 0x0A +#define MS_SCSI_SENSE_KEY_ABORTED_COMMAND 0x0B +#define MS_SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0D +#define MS_SCSI_SENSE_KEY_MISCOMPARE 0x0E + +#define MS_SCSI_ASENSE_NO_ADDITIONAL_INFORMATION 0x00 +#define MS_SCSI_ASENSE_LOGICAL_UNIT_NOT_READY 0x04 +#define MS_SCSI_ASENSE_INVALID_FIELD_IN_CDB 0x24 + +#define MS_SCSI_ASENSE_NOT_READY_TO_READY_CHANGE 0x28 +#define MS_SCSI_ASENSE_WRITE_PROTECTED 0x27 +#define MS_SCSI_ASENSE_FORMAT_ERROR 0x31 +#define MS_SCSI_ASENSE_INVALID_COMMAND 0x20 +#define MS_SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21 +#define MS_SCSI_ASENSE_MEDIUM_NOT_PRESENT 0x3A + +#define MS_SCSI_ASENSEQ_NO_QUALIFIER 0x00 +#define MS_SCSI_ASENSEQ_FORMAT_COMMAND_FAILED 0x01 +#define MS_SCSI_ASENSEQ_INITIALIZING_COMMAND_REQUIRED 0x02 +#define MS_SCSI_ASENSEQ_OPERATION_IN_PROGRESS 0x07 + +enum MS_Descriptor_ClassSubclassProtocol_t +{ + MS_CSCP_MassStorageClass = 0x08, + MS_CSCP_SCSITransparentSubclass = 0x06, + MS_CSCP_BulkOnlyTransportProtocol = 0x50, +}; + +enum MS_ClassRequests_t +{ + MS_REQ_GetMaxLUN = 0xFE, + MS_REQ_MassStorageReset, +}; + +enum MS_CommandStatusCodes_t +{ + MS_MS_SCSI_COMMAND_Pass, + MS_MS_SCSI_COMMAND_Fail, + MS_MS_SCSI_COMMAND_PhaseError, +}; + + +typedef struct +{ + u32 Signature; + u32 Tag; + u32 DataTransferLength; + u8 Flags; + u8 LUN; + u8 SCSICommandLength; + u8 SCSICommandData[16]; +} MS_CommandBlockWrapper_t; + +typedef struct +{ + u32 Signature; + u32 Tag; + u32 DataTransferResidue; + u8 Status; +} MS_CommandStatusWrapper_t; + +typedef struct +{ + u8 ResponseCode; + u8 SegmentNumber; + u8 SenseKey : 4; + u8 Reserved : 1; + u8 ILI : 1; + u8 EOM : 1; + u8 FileMark : 1; + u8 Information[4]; + u8 AdditionalLength; + u8 CmdSpecificInformation[4]; + u8 AdditionalSenseCode; + u8 AdditionalSenseQualifier; + u8 FieldReplaceableUnitCode; + u8 SenseKeySpecific[3]; +} MS_SCSI_Request_Sense_Response_t; + + +typedef struct +{ + u8 DeviceType : 5; + u8 PeripheralQualifier : 3; + u8 Reserved : 7; + u8 Removable : 1; + u8 Version; + u8 ResponseDataFormat : 4; + u8 Reserved2 : 1; + u8 NormACA : 1; + u8 TrmTsk : 1; + u8 AERC : 1; + u8 AdditionalLength; + u8 Reserved3[2]; + u8 SoftReset : 1; + u8 CmdQue : 1; + u8 Reserved4 : 1; + u8 Linked : 1; + u8 Sync : 1; + u8 WideBus16Bit : 1; + u8 WideBus32Bit : 1; + u8 RelAddr : 1; + u8 VendorID[8]; + u8 ProductID[16]; + u8 RevisionID[4]; +} MS_SCSI_Inquiry_Response_t; + +#pragma pack() + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +} +#endif diff --git a/b91/b91m_ble_sdk/application/usbstd/PrinterClassCommon.h b/b91/b91m_ble_sdk/application/usbstd/PrinterClassCommon.h new file mode 100755 index 0000000..bba07ec --- /dev/null +++ b/b91/b91m_ble_sdk/application/usbstd/PrinterClassCommon.h @@ -0,0 +1,55 @@ +/******************************************************************************************************** + * @file PrinterClassCommon.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + /* Includes: */ +#include "tl_common.h" + + /* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) + extern "C" { +#endif + + +#define PRNT_PORTSTATUS_NOTERROR BIT(3) +#define PRNT_PORTSTATUS_SELECT BIT(4) +#define PRNT_PORTSTATUS_PAPEREMPTY BIT(5) + +enum PRNT_Descriptor_ClassSubclassProtocol_t +{ + PRNT_CSCP_PrinterClass = 0x07, + PRNT_CSCP_PrinterSubclass = 0x01, + PRNT_CSCP_BidirectionalProtocol = 0x02, +}; + +enum PRNT_ClassRequests_t +{ + PRNT_REQ_GetDeviceID, + PRNT_REQ_GetPortStatus, + PRNT_REQ_SoftReset, +}; + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) + } +#endif + diff --git a/b91/b91m_ble_sdk/application/usbstd/StdRequestType.h b/b91/b91m_ble_sdk/application/usbstd/StdRequestType.h new file mode 100755 index 0000000..401e8e9 --- /dev/null +++ b/b91/b91m_ble_sdk/application/usbstd/StdRequestType.h @@ -0,0 +1,85 @@ +/******************************************************************************************************** + * @file StdRequestType.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once +/* Includes: */ +#include "tl_common.h" + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) + extern "C" { +#endif + + +#define CONTROL_REQTYPE_TYPE 0x60 +#define CONTROL_REQTYPE_DIRECTION 0x80 +#define CONTROL_REQTYPE_RECIPIENT 0x1F +#define REQDIR_HOSTTODEVICE (0<<7) +#define REQDIR_DEVICETOHOST (1<<7) +#define REQTYPE_STANDARD (0<<5) +#define REQTYPE_CLASS (1<<5) +#define REQTYPE_VENDOR (2<<5) +#define REQREC_DEVICE (0<<0) +#define REQREC_INTERFACE (1<<0) +#define REQREC_ENDPOINT (2<<0) +#define REQREC_OTHER (3<<0) +#define FEATURE_SELFPOWERED_ENABLED (1<<0) +#define FEATURE_REMOTE_WAKEUP_ENABLED (1<<1) + +typedef struct +{ + u8 RequestType; + u8 Request; + u16 Value; + u16 Index; + u16 Length; +}USB_Request_Hdr_t; + +enum USB_Control_Request_t +{ + REQ_GetStatus, + REQ_ClearFeature, + REQ_SetFeature = 3, + REQ_SetAddress = 5, + REQ_GetDescriptor, + REQ_SetDescriptor, + REQ_GetConfiguration, + REQ_SetConfiguration, + REQ_GetInterface, + REQ_SetInterface, + REQ_SynchFrame, +}; + + +enum USB_Feature_Selectors_t +{ + FEATURE_SEL_EndpointHalt, + FEATURE_SEL_DeviceRemoteWakeup, + FEATURE_SEL_TestMode, +}; + +#if defined(__cplusplus) + } +#endif + + + diff --git a/b91/b91m_ble_sdk/application/usbstd/USBController.h b/b91/b91m_ble_sdk/application/usbstd/USBController.h new file mode 100755 index 0000000..480ed48 --- /dev/null +++ b/b91/b91m_ble_sdk/application/usbstd/USBController.h @@ -0,0 +1,67 @@ +/******************************************************************************************************** + * @file USBController.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +extern "C" { +#endif + + +/**If Isochronous endpoint, +Bits 3..2 = Synchronisation Type (Iso Mode) +00 = No Synchonisation +01 = Asynchronous +10 = Adaptive +11 = Synchronous +Bits 5..4 = Usage Type (Iso Mode) +00 = Data Endpoint +01 = Feedback Endpoint +10 = Explicit Feedback Data Endpoint +11 = Reserved +*/ +#define EP_SYNC_TYPE_NO_SYNC 0 +#define EP_SYNC_TYPE_ASYN 1 +#define EP_SYNC_TYPE_ADAPTIVE 2 +#define EP_SYNC_TYPE_SYNC 3 + +#define EP_USAGE_TYPE_DATA 0 +#define EP_USAGE_TYPE_FEEDBACK 1 +#define EP_USAGE_TYPE_FEEDBACK_DATA 2 +#define EP_USAGE_TYPE_RSV 3 + + +#define ENDPOINT_DIR_MASK BIT(7) +#define ENDPOINT_DIR_OUT 0 +#define ENDPOINT_DIR_IN BIT(7) +#define EP_TYPE_MASK 3 +#define EP_TYPE_CONTROL 0 +#define EP_TYPE_ISOCHRONOUS 1 +#define EP_TYPE_BULK 2 +#define EP_TYPE_INTERRUPT 3 + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +} +#endif + diff --git a/b91/b91m_ble_sdk/application/usbstd/stdDescriptors.h b/b91/b91m_ble_sdk/application/usbstd/stdDescriptors.h new file mode 100755 index 0000000..17b9220 --- /dev/null +++ b/b91/b91m_ble_sdk/application/usbstd/stdDescriptors.h @@ -0,0 +1,272 @@ +/******************************************************************************************************** + * @file stdDescriptors.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +/* Includes: */ +#include "tl_common.h" +#include "drivers.h" + +//#include "../mcu/compiler.h" + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) + extern "C" { +#endif + +#define NO_DESCRIPTOR (0) +#define USB_CONFIG_POWER_MA(mA) ((mA) >> 1) +#define USB_STRING_LEN(UnicodeChars) (sizeof(USB_Descriptor_Hdr_t) + ((UnicodeChars) << 1)) +#define LANGUAGE_ID_ENG (0x0409) +#define USB_CONFIG_ATTR_REMOTEWAKEUP (0x20) +#define USB_CONFIG_ATTR_SELFPOWERED (0x40) +#define USB_CONFIG_ATTR_RESERVED (0x80) +#define ENDPOINT_ATTR_NO_SYNC (0<<2) +#define ENDPOINT_ATTR_ASYNC (1<<2) +#define ENDPOINT_ATTR_ADAPTIVE (2<<2) +#define ENDPOINT_ATTR_SYNC (3<<2) +#define ENDPOINT_USAGE_DATA (0<<4) +#define ENDPOINT_USAGE_FEEDBACK (1<<4) +#define ENDPOINT_USAGE_IMPLICIT_FEEDBACK (2<<4) + +enum USB_DescriptorTypes_t +{ + DTYPE_Device = 0x01, + DTYPE_Configuration, + DTYPE_String, + DTYPE_Interface, + DTYPE_Endpoint, + DTYPE_DeviceQualifier, + DTYPE_Other, + DTYPE_InterfacePower, + DTYPE_InterfaceAssociation = 0x0B, + DTYPE_CSInterface = 0x24, + DTYPE_CSEndpoint = 0x25, +}; + +enum USB_Descriptor_ClassSubclassProtocol_t +{ + USB_CSCP_NoDeviceClass = 0x00, + USB_CSCP_NoDeviceSubclass = 0x00, + USB_CSCP_NoDeviceProtocol = 0x00, + USB_CSCP_IADDeviceProtocol = 0x01, + USB_CSCP_IADDeviceSubclass = 0x02, + USB_CSCP_IADDeviceClass = 0xEF, + USB_CSCP_VendorSpecificClass = 0xFF, + USB_CSCP_VendorSpecificSubclass = 0xFF, + USB_CSCP_VendorSpecificProtocol = 0xFF, +}; + +typedef struct +{ + u8 Size; + u8 Type; +}USB_Descriptor_Hdr_t; + +typedef struct +{ + u8 Length; + u8 DescriptorType; +}USB_StdDescriptor_Hdr_t; + +typedef struct +{ + USB_Descriptor_Hdr_t Header; + u16 USBSpecification; + u8 Class; + u8 SubClass; + u8 Protocol; + u8 Endpoint0Size; + u16 VendorID; + u16 ProductID; + u16 ReleaseNumber; + u8 ManufacturerStrIndex; + u8 ProductStrIndex; + u8 SerialNumStrIndex; + u8 NumberOfConfigurations; +}USB_Descriptor_Device_t; + +typedef struct +{ + u8 Length; + u8 DescriptorType; + u16 BcdUSB; + u8 DeviceClass; + u8 DeviceSubClass; + u8 DeviceProtocol; + u8 MaxPacketSize0; + u16 IdVendor; + u16 IdProduct; + u16 BcdDevice; + u8 Manufacturer; + u8 Product; + u8 SerialNumber; + u8 NumConfigurations; +}USB_StdDescriptor_Device_t; + +typedef struct +{ + USB_Descriptor_Hdr_t Header; + u16 USBSpecification; + u8 Class; + u8 SubClass; + u8 Protocol; + u8 Endpoint0Size; + u8 NumberOfConfigurations; + u8 Reserved; +}USB_Descriptor_DeviceQualifier_t; + +typedef struct +{ + u8 Length; + u8 DescriptorType; + u16 BcdUSB; + u8 DeviceClass; + u8 DeviceSubClass; + u8 DeviceProtocol; + u8 MaxPacketSize0; + u8 NumConfigurations; + u8 Reserved; +}USB_StdDescriptor_DeviceQualifier_t; + +typedef struct +{ + USB_Descriptor_Hdr_t Header; + u16 TotalConfigurationSize; + u8 TotalInterfaces; + u8 ConfigurationNumber; + u8 ConfigurationStrIndex; + u8 ConfigAttributes; + u8 MaxPowerConsumption; +}USB_Descriptor_Configuration_Hdr_t; + +typedef struct +{ + u8 Length; + u8 DescriptorType; + u16 TotalLength; + u8 NumInterfaces; + u8 ConfigurationValue; + u8 Configuration; + u8 MAttributes; + u8 MaxPower; +}USB_StdDescriptor_Configuration_Hdr_t; + +typedef struct +{ + USB_Descriptor_Hdr_t Header; + u8 InterfaceNumber; + u8 AlternateSetting; + u8 TotalEndpoints; + u8 Class; + u8 SubClass; + u8 Protocol; + u8 InterfaceStrIndex; +}USB_Descriptor_Interface_t; + +typedef struct +{ + u8 Length; + u8 DescriptorType; + u8 InterfaceNum; + u8 AlternateSetting; + u8 NumberEndpoints; + u8 InterfaceClass; + u8 InterfaceSubclass; + u8 InterfaceProtocol; + u8 Interface; +}USB_StdDescriptor_Interface_t; + + +typedef struct +{ + USB_Descriptor_Hdr_t Header; + u8 FirstInterfaceIndex; + u8 TotalInterfaces; + u8 Class; + u8 SubClass; + u8 Protocol; + u8 IADStrIndex; +}USB_Descriptor_Interface_Association_t; + + +typedef struct +{ + u8 Length; + u8 DescriptorType; + u8 FirstInterface; + u8 InterfaceCount; + u8 FunctionClass; + u8 FunctionSubClass; + u8 FunctionProtocol; + u8 Function; +}USB_StdDescriptor_Interface_Association_t; + + +typedef struct +{ + USB_Descriptor_Hdr_t Header; + u8 EndpointAddress; + u8 Attributes; + u16 EndpointSize; + u8 PollingIntervalMS; +}USB_Descriptor_Endpoint_t; + +typedef struct +{ + u8 Length; + u8 DescriptorType; + u8 EndpointAddress; + u8 MAttributes; + u16 MaxPacketSize; + u8 Interval; +}USB_StdDescriptor_Endpoint_t; + + +#ifndef __GNUC__ +#pragma warning(push) +#pragma warning(disable:4200) // none standard zero length array +#endif + +typedef struct +{ + USB_Descriptor_Hdr_t Header; + wchar_t UnicodeString[]; +}USB_Descriptor_String_t; + +typedef struct +{ + u8 Length; + u8 DescriptorType; + wchar_t bString[]; +}USB_StdDescriptor_String_t; + +#ifndef __GNUC__ +#pragma warning(pop) +#endif + + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) + } +#endif + diff --git a/b91/b91m_ble_sdk/application/usbstd/usb.c b/b91/b91m_ble_sdk/application/usbstd/usb.c new file mode 100755 index 0000000..4a77aa6 --- /dev/null +++ b/b91/b91m_ble_sdk/application/usbstd/usb.c @@ -0,0 +1,872 @@ +/******************************************************************************************************** + * @file usb.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "tl_common.h" +#include "drivers.h" + +//#define MODULE_USB_ENABLE 1 +//#define FLOW_NO_OS 0 +//#define USB_MOUSE_ENABLE 1 + +#if(USB_DESCRIPTER_CONFIGURATION_FOR_KM_DONGLE || USB_ID_AND_STRING_CUSTOM) + #include "../../vendor/8267_multi_mode/dongle_usb.h" +#endif + +#ifndef USB_CUSTOM_HID_REPORT_REG_ACCESS +#define USB_CUSTOM_HID_REPORT_REG_ACCESS 1 +#endif + +#if (MODULE_USB_ENABLE) + +#include "usb.h" +#include "usbdesc.h" +#include "application/usbstd/StdRequestType.h" + + +#if (USB_MOUSE_ENABLE) +#include "application/app/usbmouse_i.h" +#endif + +#if (USB_KEYBOARD_ENABLE) +#include "application/app/usbkb_i.h" +#endif + +#if (USB_SOMATIC_ENABLE) +#include "application/app/usbsomatic_i.h" +#include "somatic_sensor.h" +#endif + +#if (USB_SPEAKER_ENABLE || USB_MIC_ENABLE) +#include "application/app/usbaud_i.h" +#endif + +#ifdef WIN32 +#include +#endif + +extern u8 keyboard_interface_number, mouse_interface_number; + +u8 host_keyboard_status; +u8 host_cmd[8]; +u8 host_cmd_pairing_ok = 0; +static USB_Request_Hdr_t control_request; +static u8 * g_response = 0; +static u16 g_response_len = 0; +static int g_stall = 0; +u8 usb_mouse_report_proto = 0; //default 1 for report proto +u8 g_rate = 0; //default 0 for all report + +#if (USB_SPEAKER_ENABLE || USB_MIC_ENABLE) +u8 usb_alt_intf[USB_INTF_MAX]; +#endif + + +void usb_send_response(void) { + u16 n; +#ifdef WIN32 + n = g_response_len; +#else + if (g_response_len < 8) { + n = g_response_len; + } else { + n = 8; + } + g_response_len -= n; +#endif + usbhw_reset_ctrl_ep_ptr(); + while (n-- > 0) { + usbhw_write_ctrl_ep_data(*g_response); + ++g_response; + } +} + + + +void usb_prepare_desc_data(void) { + u8 value_l = (control_request.Value) & 0xff; + u8 value_h = (control_request.Value >> 8) & 0xff; + + g_response = 0; + g_response_len = 0; + + switch (value_h) { + + case DTYPE_Device: +#if(USB_ID_AND_STRING_CUSTOM) + g_response = (u8*) (&device_desc_km); +#else + g_response = usbdesc_get_device(); +#endif + g_response_len = sizeof(USB_Descriptor_Device_t); + break; + + case DTYPE_Configuration: +#if(USB_DESCRIPTER_CONFIGURATION_FOR_KM_DONGLE) + g_response = (u8*) (&configuration_km_desc); + g_response_len = configuration_km_desc[2]; //the third element is the len +#else + g_response = usbdesc_get_configuration(); + g_response_len = sizeof(USB_Descriptor_Configuration_t); +#endif + break; + + case DTYPE_String: +#if(USB_ID_AND_STRING_CUSTOM) + if (USB_STRING_LANGUAGE == value_l) { + g_response = usbdesc_get_language(); + g_response_len = sizeof(LANGUAGE_ID_ENG); + } else if (USB_STRING_VENDOR == value_l) { + g_response = (u8*) (&vendor_desc_km); + g_response_len = vendor_desc_km.Size; + } else if (USB_STRING_PRODUCT == value_l) { + g_response = (u8*) (&prodct_desc_km); + g_response_len = prodct_desc_km.Size; + } else if (USB_STRING_SERIAL == value_l) { + g_response = (u8*) (&serial_desc_km); + g_response_len = serial_desc_km.Size; +#else + if (USB_STRING_LANGUAGE == value_l) { + g_response = usbdesc_get_language(); + g_response_len = sizeof(LANGUAGE_ID_ENG); + } else if (USB_STRING_VENDOR == value_l) { + g_response = usbdesc_get_vendor(); + g_response_len = sizeof(STRING_VENDOR); + } else if (USB_STRING_PRODUCT == value_l) { + g_response = usbdesc_get_product(); + g_response_len = sizeof(STRING_PRODUCT); + } else if (USB_STRING_SERIAL == value_l) { + g_response = usbdesc_get_serial(); + g_response_len = sizeof(STRING_SERIAL); +#endif + +#if (MS_OS_DESCRIPTOR_ENABLE) + } else if (USB_STRING_MS_OS == value_l) { + g_response = usbdesc_get_OS_descriptor(); + g_response_len = sizeof(STRING_MSFT); +#endif + + } else { + g_stall = 1; + } + break; + + default: + g_stall = 1; + break; + + } + + if (control_request.Length < g_response_len) { + g_response_len = control_request.Length; + } + + return; +} + +//standard interface request handle + + + +void usb_handle_std_intf_req() { + u8 value_h = (control_request.Value >> 8) & 0xff; +#if(USB_MIC_ENABLE || USB_SPEAKER_ENABLE || USB_MOUSE_ENABLE || USB_KEYBOARD_ENABLE || USB_SOMATIC_ENABLE) + u8 index_l = (control_request.Index) & 0xff; +#endif + switch (value_h) { + case HID_DTYPE_HID:// HID Descriptor +#if(0) + if (index_l == USB_INTF_AUDIO_HID) { + //audio hid + g_response = usbdesc_get_audio(); + g_response_len = sizeof(USB_HID_Descriptor_HID_Audio_t); + } +#endif +#if(USB_MOUSE_ENABLE) +#if(USB_DESCRIPTER_CONFIGURATION_FOR_KM_DONGLE) + if (index_l == mouse_interface_number) + { + g_response = (u8*) (&configuration_desc_mouse[9]); + g_response_len = USB_HID_DESCRIPTOR_LENGTH; + } +#else + if (index_l == USB_INTF_MOUSE) //index_l is the interface number + { + //mouse + g_response = usbdesc_get_mouse(); + g_response_len = sizeof(USB_HID_Descriptor_HID_Mouse_t); + } +#endif +#endif +#if(USB_KEYBOARD_ENABLE) +#if(USB_DESCRIPTER_CONFIGURATION_FOR_KM_DONGLE) + if (index_l == keyboard_interface_number) + { + g_response = (u8*) (&configuration_desc_keyboard[9]); + g_response_len = USB_HID_DESCRIPTOR_LENGTH; + } +#else + if (index_l == USB_INTF_KEYBOARD) { + //keyboard + g_response = usbdesc_get_keyboard(); + g_response_len = sizeof(USB_HID_Descriptor_HID_Keyboard_t); + } +#endif +#if (AUDIO_HOGP) + if (index_l == USB_INTF_AUDIO_HOGP) { + //keyboard + g_response = usbdesc_get_audio_hogp(); + g_response_len = sizeof(USB_HID_Descriptor_HID_Keyboard_t); + } +// if (index_l == USB_INTF_PRINTER) { +// //keyboard +// g_response = usbdesc_get_vendor_desc(); +// g_response_len = sizeof(USB_HID_Descriptor_HID_Keyboard_t1); +// } +#endif +#endif +#if(USB_SOMATIC_ENABLE ) + if (index_l == USB_INTF_SOMATIC) //index_l is the interface number + { + //SOMATIC + g_response = usbdesc_get_somatic(); + g_response_len = sizeof(USB_HID_Descriptor_HID_Somatic_t); + } +#endif + break; + case HID_DTYPE_Report://Report Descriptor +#if (0) + if (index_l == USB_INTF_AUDIO_HID) { + //audio hid + g_response = usbaud_get_report_desc(); + g_response_len = usbaud_get_report_desc_size(); + } +#endif +#if(USB_KEYBOARD_ENABLE) + if (index_l == (USB_DESCRIPTER_CONFIGURATION_FOR_KM_DONGLE ? keyboard_interface_number : USB_INTF_KEYBOARD)) { + //keyboard + g_response = (u8*) usbkb_get_report_desc(); + g_response_len = usbkb_get_report_desc_size(); + } +#endif +#if(USB_MOUSE_ENABLE) + else if (index_l == (USB_DESCRIPTER_CONFIGURATION_FOR_KM_DONGLE ? mouse_interface_number : USB_INTF_MOUSE)) { + //mouse + g_response = (u8*) usbmouse_get_report_desc(); + g_response_len = usbmouse_get_report_desc_size(); + } +#endif +#if (AUDIO_HOGP) + else if(index_l==USB_INTF_AUDIO_HOGP) + { + g_response = (u8*) usbaudio_hogp_get_report_desc(); + g_response_len = usbaudio_hogp_get_report_desc_size(); + } +// else if(index_l == USB_INTF_PRINTER) +// { +// //cmisc +// g_response = (u8*) usb_vendor_get_report_desc(); +// g_response_len = usb_vendor_get_report_desc_size(); +// } +#endif +#if(USB_SOMATIC_ENABLE) + else if (index_l == USB_INTF_SOMATIC) { + //somatic sensor + g_response = (u8*) usbsomatic_get_report_desc(); + g_response_len = usbsomatic_get_report_desc_size(); + } +#endif +#if (!(USB_MOUSE_ENABLE | USB_KEYBOARD_ENABLE | USB_SOMATIC_ENABLE)) + if (0) { + + } +#endif + else{ + g_stall = 1; + } + break; + case 0x23:// Phisical Descriptor + // TODO + break; + + default:// other condition + break; + } + + if (control_request.Length < g_response_len) { + g_response_len = control_request.Length; + } + + return; +} + +u32 custom_read_dat; +u32 custom_reg_cmd; + + +void usb_handle_out_class_intf_req(int data_request) { + u8 property = control_request.Request; + u8 value_l = (control_request.Value) & 0xff; + u8 value_h = (control_request.Value >> 8) & 0xff; +#if (USB_MIC_ENABLE || USB_SPEAKER_ENABLE) + u8 Entity = (control_request.Index >> 8) & 0xff; +#endif + + switch (property) { + + case HID_REQ_SetReport: + switch (value_h) { + case HID_REPORT_ITEM_In: + break; + case HID_REPORT_ITEM_Out: + // usb_hid_set_report_ouput(); + break; + case HID_REPORT_ITEM_Feature: + if (data_request) { + host_keyboard_status = usbhw_read_ctrl_ep_data(); + } +#if(USB_SET_REPORT_FEATURE_SUPPORT) + { + usb_set_report_t rpt; + rpt.report_id = value_l; + rpt.len = control_request.Index; + ev_emit_event_syn(EV_USB_SET_REPORT, (void*)(&rpt)); // send in report id + } +#endif + break; + case HID_REPORT_CUSTOM: +#if (USB_CUSTOM_HID_REPORT) + { //pairing, EMI-TX, EMI-RX + if (data_request) { + int i=0; + usbhw_reset_ctrl_ep_ptr (); //address + for(i=0;i<8;i++) { + host_cmd[i] = usbhw_read_ctrl_ep_data(); + } +#if (USB_CUSTOM_HID_REPORT_REG_ACCESS) + custom_reg_cmd = (host_cmd[1] & 0xf0) == 0xc0; + if (custom_reg_cmd) { + host_cmd[0] = 0; + int adr = *((u16 *)(host_cmd + 2)); + int len = host_cmd[1] & 3; + if (host_cmd[1] == 0xcc && adr == 0x5af0) { //re-enumerate device + usb_dp_pullup_en (0); //disable device + sleep_us (300000); + reg_ctrl_ep_irq_mode = 0xff; //hardware mode + usb_dp_pullup_en (1); //enable device + } + else { + adr += 0x800000; + } + + if ((host_cmd[1] & 0x0c)==0) { //write core register + if (len == 0) { + for (int k=0; k<4; k++) { + custom_read_dat = (custom_read_dat >> 8) | (read_reg8 (adr++) << 24); + } + } + else if (len == 1) { + write_reg8 (adr, host_cmd[4]); + } + else if (len == 2) { + write_reg16 (adr, *((u16 *)(host_cmd + 4))); + } + else { + write_reg32 (adr, *((u32 *)(host_cmd + 4))); + } + } + else { //read core register + if (len == 0) { + custom_read_dat = analog_read_reg8 (host_cmd[2]); + } + else { + analog_write_reg8 (host_cmd[2], host_cmd[4]); + } + } + } +#endif + } + break; + } +#endif + default: + g_stall = 1; + break; + } + break; + + case HID_REQ_SetIdle: + if (data_request) { + g_rate = usbhw_read_ctrl_ep_data(); + } + g_rate = value_h; + break; + + case HID_REQ_SetProtocol: + if (data_request) { + usb_mouse_report_proto = usbhw_read_ctrl_ep_data(); + } + usb_mouse_report_proto = value_l; + reg_usb_ep_ctrl(USB_EDP_MOUSE) = 0; + break; + + default: + g_stall = 1; + break; + } + +#if (USB_MIC_ENABLE || USB_SPEAKER_ENABLE) + if(0 == g_stall){ // already handled + return; + } + g_stall = 0; + switch(Entity){ + case USB_SPEAKER_FEATURE_UNIT_ID: + usbaud_handle_set_speaker_cmd(value_h); + break; + case USB_MIC_FEATURE_UNIT_ID: + usbaud_handle_set_mic_cmd(value_h); + break; + default: + g_stall = 1; + break; + } +#endif +} + + + +void usb_handle_in_class_intf_req() { + u8 property = control_request.Request; +#if (USB_MIC_ENABLE || USB_SPEAKER_ENABLE) + u8 value_h = (control_request.Value >> 8); + u8 Entity = (control_request.Index >> 8); +#endif + switch (property) { + case 0x00: + usbhw_write_ctrl_ep_data(0x00); + break; + case HID_REQ_GetReport: +#if(USB_SOMATIC_ENABLE) + if(usbsomatic_hid_report_type((control_request.Value & 0xff))){ + } + else +#elif (USB_CUSTOM_HID_REPORT) + if( control_request.Value==0x0305 ) { + if (USB_CUSTOM_HID_REPORT_REG_ACCESS && custom_reg_cmd) { + usbhw_write_ctrl_ep_data (custom_read_dat); + usbhw_write_ctrl_ep_data (custom_read_dat>>8); + usbhw_write_ctrl_ep_data (custom_read_dat>>16); + usbhw_write_ctrl_ep_data (custom_read_dat>>24); + usbhw_write_ctrl_ep_data (0x10); + usbhw_write_ctrl_ep_data (0x20); + usbhw_write_ctrl_ep_data (0x40); + usbhw_write_ctrl_ep_data (0x80); + } + else { + usbhw_write_ctrl_ep_data (0x04); + usbhw_write_ctrl_ep_data (0x58); + usbhw_write_ctrl_ep_data (0x00); + usbhw_write_ctrl_ep_data (host_cmd_pairing_ok ? 0xa1 : 0x00); //For binding OK + usbhw_write_ctrl_ep_data (0x00); + usbhw_write_ctrl_ep_data (0x00); + usbhw_write_ctrl_ep_data (0x08); + usbhw_write_ctrl_ep_data (0x00); + } + } + else +#endif + { // donot know what is this + // usbhw_write_ctrl_ep_data(0x81); + // usbhw_write_ctrl_ep_data(0x02); + // usbhw_write_ctrl_ep_data(0x55); + // usbhw_write_ctrl_ep_data(0x55); + } + break; + case HID_REQ_GetIdle: + usbhw_write_ctrl_ep_data(g_rate); + break; + case HID_REQ_GetProtocol: + usbhw_write_ctrl_ep_data(usb_mouse_report_proto); + break; + default: + g_stall = 1; + break; + } +#if (USB_MIC_ENABLE || USB_SPEAKER_ENABLE) + if(0 == g_stall){ // already handled + return; + } + g_stall = 0; + switch(Entity){ + case USB_SPEAKER_FEATURE_UNIT_ID: + if(usbaud_handle_get_speaker_cmd(property, value_h)){ + g_stall = 1; + } + break; + case USB_MIC_FEATURE_UNIT_ID: + if(usbaud_handle_get_mic_cmd(property, value_h)){ + g_stall = 1; + } + break; + default: + g_stall = 1; + break; + } +#endif + +} + + +void usb_handle_in_class_endp_req() { +#if (USB_MIC_ENABLE || USB_SPEAKER_ENABLE) + u8 property = control_request.Request; + u8 ep_ctrl = control_request.Value >> 8; + //u8 addr = (control_request.Index >> 8); + + if(ep_ctrl == AUDIO_EPCONTROL_SamplingFreq){ + switch(property){ + case AUDIO_REQ_GetCurrent: + usbhw_write_ctrl_ep_data(MIC_SAMPLE_RATE & 0xff); + usbhw_write_ctrl_ep_data(MIC_SAMPLE_RATE >> 8); + usbhw_write_ctrl_ep_data(MIC_SAMPLE_RATE >> 16); + break; + default: + break; + } + } +#endif +} + +void usb_handle_out_class_endp_req(int data_request) { + return; +#if 0 + u8 property = control_request.Request; + u8 ep_ctrl = control_request.Value & 0xff; +#if (USB_MIC_ENABLE || USB_SPEAKER_ENABLE) + u8 addr = (control_request.Index >> 8); +#endif +#endif +} + + +void usb_handle_set_intf() { +#if (USB_SPEAKER_ENABLE || USB_MIC_ENABLE) + u8 value_l = (control_request.Value) & 0xff; + u8 intf_index = (control_request.Index) & 0x07; + usb_alt_intf[intf_index] = value_l; + +#if (USB_MIC_ENABLE) + if(USB_INTF_MIC == intf_index && value_l){ +// usbhw_reset_ep_ptr(USB_EDP_MIC); +// reg_usb_ep_ptr(USB_EDP_MIC) = USB_MIC_CHANNELS_LEN; +// reg_usb_ep_ctrl(USB_EDP_MIC) = (MIC_CHANNEL_COUNT == 2 ? 0x81 : 0xc1); + reg_usb_ep_ptr(USB_EDP_MIC) = 0; + reg_usb_ep_ctrl(USB_EDP_MIC) = BIT(0); //ACK first packet + } +#endif + +#if (USB_SPEAKER_ENABLE) + if(USB_INTF_SPEAKER == intf_index && value_l){ +// usbhw_reset_ep_ptr(USB_EDP_MIC); +// reg_usb_ep_ptr(USB_EDP_MIC) = USB_MIC_CHANNELS_LEN; +// reg_usb_ep_ctrl(USB_EDP_MIC) = (MIC_CHANNEL_COUNT == 2 ? 0x81 : 0xc1); + reg_usb_ep_ptr(USB_EDP_SPEAKER) = 0; + reg_usb_ep_ctrl(USB_EDP_SPEAKER) = BIT(0); //ACK first packet + } +#endif +#endif + return; +} + +#if (USB_SPEAKER_ENABLE || USB_MIC_ENABLE) +void usb_handle_get_intf() { + u8 intf_index = (control_request.Index) & 0x07; + + usbhw_write_ctrl_ep_data(usb_alt_intf[intf_index]); + + return; +} +#endif + + +void usb_handle_request(u8 data_request) { + u8 RequestType = control_request.RequestType; + u8 Request = control_request.Request; + +#ifdef WIN32 + printf("\r\nusb_sim:s:"); +#endif + + usbhw_reset_ctrl_ep_ptr(); + switch (RequestType) { + case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE): + if (REQ_GetDescriptor == Request) { + if (USB_IRQ_SETUP_REQ == data_request) { + usb_prepare_desc_data(); + } + usb_send_response(); + } + break; + + case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE): + if (REQ_GetDescriptor == Request) { + if (USB_IRQ_SETUP_REQ == data_request) { + usb_handle_std_intf_req(); + } + usb_send_response(); + } +#if (USB_SPEAKER_ENABLE || USB_MIC_ENABLE) + else if (REQ_GetInterface == Request) { + usb_handle_get_intf(); + } +#endif + break; +#if (MS_OS_DESCRIPTOR_ENABLE) + case (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_DEVICE): + case (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_INTERFACE): + if ((Request == MS_VENDORCODE)) {//Retrieve an OS Feature Descriptor + u8 index_l = control_request.Index&0xff; + if (USB_IRQ_SETUP_REQ == data_request) { + //usb_indexl==0x04 for Extended compat ID + //usb_indexl==0x05 for Extended properties + if(index_l==0x04 ) + { + g_response = usbdesc_get_compatID(&g_response_len); + } + else if(index_l==0x05) + { + g_response = usbdesc_get_OSFeature(&g_response_len); + } + else + g_stall = 1; + if (control_request.Length < g_response_len) { + g_response_len = control_request.Length; + } + } + + usb_send_response(); + } + break; +#endif + case (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE): + usb_handle_out_class_intf_req(data_request); + break; + case (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT): + usb_handle_out_class_endp_req(data_request); + break; + case (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE): + usb_handle_in_class_intf_req(); + break; + case (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT): + usb_handle_in_class_endp_req(); + break; + + case (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE): + if (REQ_SetInterface == Request) { + usb_handle_set_intf(); + } + break; + + default: + g_stall = 1; + break; + } + + return; +} + + +void usb_handle_ctl_ep_setup() { + usbhw_reset_ctrl_ep_ptr(); + control_request.RequestType = usbhw_read_ctrl_ep_data(); + control_request.Request = usbhw_read_ctrl_ep_data(); + control_request.Value = usbhw_read_ctrl_ep_u16(); + control_request.Index = usbhw_read_ctrl_ep_u16(); + control_request.Length = usbhw_read_ctrl_ep_u16(); + g_stall = 0; + usb_handle_request(USB_IRQ_SETUP_REQ); + if (g_stall) + usbhw_write_ctrl_ep_ctrl(FLD_EP_DAT_STALL); + else + usbhw_write_ctrl_ep_ctrl(FLD_EP_DAT_ACK); +} + + +void usb_handle_ctl_ep_data(void) { + usbhw_reset_ctrl_ep_ptr(); + g_stall = 0; + usb_handle_request(USB_IRQ_DATA_REQ); + if (g_stall) + usbhw_write_ctrl_ep_ctrl(FLD_EP_DAT_STALL); + else + usbhw_write_ctrl_ep_ctrl(FLD_EP_DAT_ACK); +} + + + +void usb_handle_ctl_ep_status() { + if (g_stall) + usbhw_write_ctrl_ep_ctrl(FLD_EP_STA_STALL); + else + usbhw_write_ctrl_ep_ctrl(FLD_EP_STA_ACK); +} + +u8 usb_has_suspend_irq = 0; +u8 usb_just_wakeup_from_suspend = 1; +extern u8 rf_channel; +int usb_suspend_check(void){ + return 0; +} + +#if(0) +void usb_resume_host(void) +{ +#if (MCU_CORE_TYPE == MCU_CORE_3520) +#else + reg_wakeup_en = FLD_WAKEUP_SRC_USB_RESM; + reg_wakeup_en = 0; +#endif + sleep_us(6000); +} +#endif +u8 edp_toggle[8]; + + +void usb_handle_irq(void) +{ + u32 irq = usbhw_get_ctrl_ep_irq(); + if (irq & FLD_CTRL_EP_IRQ_SETUP) { + usbhw_clr_ctrl_ep_irq(FLD_CTRL_EP_IRQ_SETUP); + usb_handle_ctl_ep_setup(); + } + if (irq & FLD_CTRL_EP_IRQ_DATA) { + usbhw_clr_ctrl_ep_irq(FLD_CTRL_EP_IRQ_DATA); + usb_handle_ctl_ep_data(); + } + if (irq & FLD_CTRL_EP_IRQ_STA) { + usbhw_clr_ctrl_ep_irq(FLD_CTRL_EP_IRQ_STA); + usb_handle_ctl_ep_status(); + } + if (reg_usb_irq_mask & FLD_USB_IRQ_RESET_O){ //USB reset + usb_mouse_report_proto = 1; + reg_usb_irq_mask |= FLD_USB_IRQ_RESET_O; //Clear USB reset flag + for (int i=0; i<8; i++) { + reg_usb_ep_ctrl(i) = 0; + edp_toggle[i]=0; + } + } + irq = reg_usb_irq; // data irq +#if(USB_SOMATIC_ENABLE) + if(irq & BIT((USB_EDP_SOMATIC_OUT & 0x07))){ + reg_usb_irq = BIT((USB_EDP_SOMATIC_OUT & 0x07)); // clear ime + usbhw_reset_ep_ptr(USB_EDP_SOMATIC_OUT); + + ev_emit_event_syn(EV_USB_OUT_DATA, (void*)irq); + + usbhw_data_ep_ack(USB_EDP_SOMATIC_OUT); + } +#endif + if(IRQ_USB_PWDN_ENABLE && (reg_irq_src(FLD_IRQ_USB_PWDN_EN) & FLD_IRQ_USB_PWDN_EN)){ + usb_has_suspend_irq = 1; + }else{ + usb_has_suspend_irq = 0; + } +#if (AUDIO_HOGP) +// if(irq & BIT(USB_EDP_KEYBOARD_OUT & 0x07)){ +// reg_usb_irq = BIT((USB_EDP_KEYBOARD_OUT & 0x07)); // clear ime +// +// g_stall = 0; +// u8 rx_from_usbhost_len = reg_usb_ep_ptr(USB_EDP_KEYBOARD_OUT); +// usbhw_reset_ep_ptr(USB_EDP_KEYBOARD_OUT); +// +// if(rx_from_usbhost_len > 0 && rx_from_usbhost_len <= 64){ +// keyboard_outpoint_handle(rx_from_usbhost_len); +// } +// +// if(g_stall) +// { usbhw_data_ep_stall(USB_EDP_KEYBOARD_OUT); } +// else +// { usbhw_data_ep_ack(USB_EDP_KEYBOARD_OUT); } +// } + + if(irq & BIT((USB_EDP_AUDIO_IN & 0x07))) + { + reg_usb_irq = BIT((USB_EDP_AUDIO_IN & 0x07)); // clear ime +// usbhw_reset_ep_ptr(USB_EDP_AUDIO_IN); + } +// if(irq & BIT((USB_EDP_PRINTER_OUT & 0x07))) +// { +// reg_usb_irq = BIT((USB_EDP_PRINTER_OUT & 0x07)); // clear ime +// usbhw_reset_ep_ptr(USB_EDP_PRINTER_OUT); +// } + + if(IRQ_USB_PWDN_ENABLE && (reg_irq_src & FLD_IRQ_USB_PWDN_EN)){ + usb_has_suspend_irq = 1; + }else{ + usb_has_suspend_irq = 0; + } +#endif + +#if (!USB_DESCRIPTER_CONFIGURATION_FOR_KM_DONGLE) + if ((reg_irq_src(FLD_IRQ_USB_PWDN_EN) & FLD_IRQ_USB_PWDN_EN)) + { + return; + } + + #if(USB_MOUSE_ENABLE) + extern void usbmouse_report_frame(void); + extern void usbmouse_release_check(void); + usbmouse_report_frame(); + //usbmouse_release_check(); + #endif + + #if(USB_KEYBOARD_ENABLE) + extern void usbkb_report_frame(void); + extern void usbkb_release_check(void); + //usbkb_report_frame(); + //usbkb_release_check(); + #endif +#endif + + usb_hid_report_fifo_proc(); +} + +void usb_init_interrupt(void) +{ + + usbhw_enable_manual_interrupt(FLD_CTRL_EP_AUTO_STD | FLD_CTRL_EP_AUTO_DESC); + + reg_usb_edp_en = 0xff;//todo by zhangchong + + reg_usb_irq_mask |= BIT(0); //set USB IRQ reset mask +} + +void usb_init(void) +{ + usb_init_interrupt(); +} + + + + + +#endif diff --git a/b91/b91m_ble_sdk/application/usbstd/usb.h b/b91/b91m_ble_sdk/application/usbstd/usb.h new file mode 100755 index 0000000..5198810 --- /dev/null +++ b/b91/b91m_ble_sdk/application/usbstd/usb.h @@ -0,0 +1,80 @@ +/******************************************************************************************************** + * @file usb.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + + +#include "tl_common.h" +#include "drivers.h" +#include "usbdesc.h" + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +extern "C" { +#endif + +enum { + // 3000 ms + USB_TIME_BEFORE_ALLOW_SUSPEND = (3000*1000), +}; + +enum { + USB_IRQ_SETUP_REQ = 0, + USB_IRQ_DATA_REQ, +}; + + +// telink usb report ctrl command. used mixed with USB_AUD_PLAY_PAUSE... +enum{ + USB_REPORT_NO_EVENT = 0xf0, + USB_REPORT_RELEASE = 0xff, +}; + +#if (USB_MIC_ENABLE) +extern u8 usb_alt_intf[USB_INTF_MAX]; +static inline int usb_mic_is_enable(){ + return usb_alt_intf[USB_INTF_MIC]; +} +#endif + +extern u8 usb_just_wakeup_from_suspend; +extern u8 usb_has_suspend_irq; +extern u8 edp_toggle[8]; + +void usb_init(void); + +void usb_handle_irq(void); + +#ifndef USB_SOFTWARE_CRC_CHECK +#define USB_SOFTWARE_CRC_CHECK 0 +#endif + +#define MS_VENDORCODE 'T' //This must match the char after the "MSFT100" +#define STRING_MSFT L"MSFT100T" + +#define MS_OS_DESCRIPTOR_ENABLE 0 + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +} +#endif + diff --git a/b91/b91m_ble_sdk/application/usbstd/usbdesc.c b/b91/b91m_ble_sdk/application/usbstd/usbdesc.c new file mode 100755 index 0000000..a3db907 --- /dev/null +++ b/b91/b91m_ble_sdk/application/usbstd/usbdesc.c @@ -0,0 +1,822 @@ +/******************************************************************************************************** + * @file usbdesc.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include +#include "tl_common.h" +#include "drivers.h" + +#if (USB_MOUSE_ENABLE) +#include +#endif + +#if (USB_KEYBOARD_ENABLE) +#include +#endif + +#if (USB_SOMATIC_ENABLE) +#include "../app/usbsomatic_i.h" +#endif + +#if (USB_SPEAKER_ENABLE || USB_MIC_ENABLE) +#include +#endif + +#if (USB_CDC_ENABLE) +#include +#endif +//#include "usb.h" + +// request parameters +/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests + * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate + * via the language ID table available at USB.org what languages the device supports for its string descriptors. + */ +const USB_Descriptor_String_t language_desc = { { + sizeof(USB_Descriptor_Hdr_t) + 2, DTYPE_String }, + { LANGUAGE_ID_ENG } }; + +/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable + * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device + * Descriptor. + */ +const USB_Descriptor_String_t vendor_desc = { { sizeof(USB_Descriptor_Hdr_t) + + sizeof(STRING_VENDOR) - 2, DTYPE_String }, // Header + STRING_VENDOR }; + +/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, + * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device + * Descriptor. + */ +const USB_Descriptor_String_t product_desc = { { + sizeof(USB_Descriptor_Hdr_t) + sizeof(STRING_PRODUCT) - 2, + DTYPE_String }, // Header + STRING_PRODUCT }; + +/** Serial number string. This is a Unicode string containing the device's unique serial number, expressed as a + * series of uppercase hexadecimal digits. + */ +const USB_Descriptor_String_t serial_desc = { { sizeof(USB_Descriptor_Hdr_t) + + sizeof(STRING_SERIAL) - 2, DTYPE_String }, // Header + STRING_SERIAL }; + + +#if (MS_OS_DESCRIPTOR_ENABLE) +const USB_Descriptor_String_t microsoft_OS_desc = { { + sizeof(USB_Descriptor_Hdr_t) + sizeof(STRING_MSFT) - 2, + DTYPE_String }, // Header + STRING_MSFT }; + + +const unsigned char OSFeatureDescriptor[] ={ + 0x26,0x01, 0x00, 0x00, + 0x00,0x01, + 0x05,0x00, + 0x05,0x00, + + // DeviceIdleEnabled + 0x36,0x00, 0x00, 0x00, + 0x04,0x00, 0x00, 0x00, + 0x24, 0x00, + + 0x44,0x00,0x65,0x00,0x76,0x00,0x69,0x00,0x63,0x00,0x65,0x00,0x49,0x00,0x64,0x00, + 0x6C,0x00,0x65,0x00,0x45,0x00,0x6E,0x00,0x61,0x00,0x62,0x00,0x6C,0x00,0x65,0x00, + 0x64,0x00,0x00,0x00, + + 0x04,0x00,0x00,0x00, + 0x01,0x00,0x00,0x00, + + //DefaultIdleState + 0x34,0x00,0x00,0x00, + 0x04,0x00, 0x00, 0x00, + 0x22,0x00, + + 0x44,0x00, 0x65,0x00, 0x66,0x00, 0x61,0x00, 0x75,0x00, + 0x6C,0x00, 0x74,0x00, 0x49,0x00, 0x64,0x00, 0x6C,0x00, + 0x65,0x00, 0x53,0x00, 0x74,0x00, 0x61,0x00, 0x74,0x00, + 0x65,0x00, 0x00,0x00, + + 0x04,0x00,0x00,0x00, + 0x01,0x00,0x00,0x00, + + + //default timeout value for selective suspend. + 0x38,0x00,0x00,0x00, + 0x04,0x00, 0x00, 0x00, + 0x26,0x00, + + 0x44,0x00,0x65,0x00,0x66,0x00,0x61,0x00, + 0x75,0x00,0x6C,0x00,0x74,0x00,0x49,0x00, + 0x64,0x00,0x6C,0x00,0x65,0x00,0x54,0x00, + 0x69,0x00,0x6D,0x00,0x65,0x00,0x6F,0x00, + 0x75,0x00,0x74,0x00, + 0x00,0x00, + + 0x04,0x00,0x00,0x00, + 0x88,0x13,0x00,0x00, + +// user-enabled selective suspend. + 0x44,0x00,0x00,0x00, + 0x04,0x00, 0x00, 0x00, + 0x32,0x00, + + 0x55,0x00,0x73,0x00, + 0x65,0x00,0x72,0x00, + 0x53,0x00,0x65,0x00, + 0x74,0x00,0x44,0x00, + 0x65,0x00,0x76,0x00, + 0x69,0x00,0x63,0x00, + 0x65,0x00,0x49,0x00, + 0x64,0x00,0x6C,0x00, + 0x65,0x00,0x45,0x00, + 0x6E,0x00,0x61,0x00, + 0x62,0x00,0x6C,0x00, + 0x65,0x00,0x64,0x00, + 0x00,0x00, + + 0x04,0x00,0x00,0x00, + 0x01,0x00,0x00,0x00, + +//user-enabled remote wake setting. + + 0x36,0x00,0x00,0x00, + 0x04,0x00,0x00,0x00, + 0x24,0x00, + 0x53,0x00,0x79,0x00,0x73,0x00,0x74,0x00,0x65,0x00,0x6D,0x00,0x57,0x00,0x61,0x00, + 0x6B,0x00,0x65,0x00,0x45,0x00,0x6E,0x00,0x61,0x00,0x62,0x00,0x6C,0x00,0x65,0x00, + 0x64,0x00,0x00,0x00, + + 0x04,0x00,0x00,0x00, + 0x01,0x00,0x00,0x00 + +}; + + + +const USB_MS_OS_compatID_t OSFeatureDescriptor_compatID = { + { + sizeof(USB_MS_OS_compatID_Header_t) + + USB_KEYBOARD_ENABLE * sizeof(USB_MS_OS_compatID_Function_t) + + USB_MOUSE_ENABLE * sizeof(USB_MS_OS_compatID_Function_t), + + 0x0100, + 0x0004, + USB_KEYBOARD_ENABLE + USB_MOUSE_ENABLE, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00, + }, + { +#if USB_KEYBOARD_ENABLE + { + USB_INTF_KEYBOARD, + 0x01, + 'W', 'I', 'N', 'U' ,'S','B', 0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00, + }, +#endif + +#if USB_MOUSE_ENABLE + { + USB_INTF_MOUSE, + 0x01, + 'W', 'I', 'N', 'U' ,'S','B', 0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00, + }, +#endif + } +}; +#if 0 +const unsigned char OSFeatureDescriptor_compatID[] = { + 0x28,0x00,0x00,0x00, + 0x00,0x01, + 0x04,0x00, + 0x01, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00, + USB_INTF_MOUSE, + 0x01, + 'W', 'I', 'N', 'U' ,'S','B', 0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00, + }; +#endif +#endif + + +#ifndef ID_PRODUCT +#define ID_PRODUCT (ID_PRODUCT_BASE | (USB_PRINTER_ENABLE?(1<<0):0) | (USB_SPEAKER_ENABLE?(1<<1):0) | (USB_MIC_ENABLE?(1<<2):0) \ + | (USB_MOUSE_ENABLE?(1<<3):0) | (USB_KEYBOARD_ENABLE?(1<<4):0) | (USB_SOMATIC_ENABLE?(1<<5):0)) +#endif + +const USB_Descriptor_Device_t device_desc = { { + sizeof(USB_Descriptor_Device_t), DTYPE_Device }, // Header +#if (MS_OS_DESCRIPTOR_ENABLE) + 0x0200, // USBSpecification, USB 2.0 +#else + 0x0110, // USBSpecification, USB 1.1 +#endif +#if (USB_CDC_ENABLE) + CDC_CSCP_CDCClass, // Class + USB_CSCP_NoDeviceSubclass, // SubClass + USB_CSCP_NoDeviceProtocol, // Protocol +#else + USB_CSCP_NoDeviceClass, + USB_CSCP_NoDeviceSubclass, // SubClass + USB_CSCP_NoDeviceProtocol, // Protocol +#endif + 8, // Endpoint0Size, Maximum Packet Size for Zero Endpoint. Valid Sizes are 8, 16, 32, 64 + ID_VENDOR, // VendorID +#if USB_CDC_ENABLE + 0x8846, +#else +#if AUDIO_HOGP + 0xc080,//ID_PRODUCT, // ProductID +#else + ID_PRODUCT, +#endif +#endif + 0x0100, // .ReleaseNumber + USB_STRING_VENDOR, // .ManufacturerStrIndex + USB_STRING_PRODUCT, // .ProductStrIndex + 3, // .SerialNumStrIndex, iSerialNumber + 1 }; + +const USB_Descriptor_Configuration_t + configuration_desc = { { { + sizeof(USB_Descriptor_Configuration_Hdr_t), + DTYPE_Configuration }, // Length, type + sizeof(USB_Descriptor_Configuration_t), // TotalLength: variable + USB_INTF_MAX, // NumInterfaces + 1, // Configuration index + NO_DESCRIPTOR, // Configuration String + //USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_REMOTEWAKEUP, // Attributes + USB_CONFIG_ATTR_RESERVED,//don't support remote wakeup + USB_CONFIG_POWER_MA(250) // MaxPower = 2*250mA + }, +#if AUDIO_HOGP + // HID audio hogp interface + { {sizeof(USB_Descriptor_Interface_t), DTYPE_Interface}, + USB_INTF_AUDIO_HOGP, + 0, // AlternateSetting + 1, // bNumEndpoints + HID_CSCP_HIDClass, HID_CSCP_NonBootSubclass, + HID_CSCP_KeyboardBootProtocol, NO_DESCRIPTOR + }, + { + // hid des + { + {sizeof(USB_HID_Descriptor_HID_t), HID_DTYPE_HID}, 0x0111, // HIDSpec + 0, 1, // TotalReportDescriptors + HID_DTYPE_Report, {sizeof(audio_hogp_report_desc), 0x00}, // HIDReportLength + }, + // audio_hogp_in_endpoint + { + {sizeof(USB_Descriptor_Endpoint_t), DTYPE_Endpoint}, + ENDPOINT_DIR_IN | USB_EDP_AUDIO_IN, + EP_TYPE_INTERRUPT, 0x40, // EndpointSize + 1,//USB_KEYBOARD_POLL_INTERVAL // PollingIntervalMS + }, +// // audio_hogp_out_endpoint +// { +// {sizeof(USB_Descriptor_Endpoint_t), DTYPE_Endpoint}, +// ENDPOINT_DIR_OUT | USB_EDP_KEYBOARD_OUT, +// EP_TYPE_BULK, 0x0010, // EndpointSize +// 1//USB_KEYBOARD_POLL_INTERVAL // PollingIntervalMS +// }, + }, +#endif +#if (USB_CDC_ENABLE) +#if 0 + { + // iad0 + {sizeof(USB_Descriptor_Interface_Association_t), DTYPE_InterfaceAssociation}, // Header + 0, // FirstInterfaceIndex + 2, // TotalInterface + CDC_CSCP_CDCClass, // Class + CDC_CSCP_ACMSubclass, // Subclass + CDC_CSCP_ATCommandProtocol, // protocol + NO_DESCRIPTOR // IADStrIndex + }, +#endif + + + { + // cdc_interface + + {sizeof(USB_Descriptor_Interface_t), DTYPE_Interface}, // Header + USB_INTF_CDC_CCI, // InterfaceNumber + 0, // AlternateSetting + 1, // TotalEndpoints + CDC_CSCP_CDCClass, // Class + CDC_CSCP_ACMSubclass, // SubClass + CDC_CSCP_ATCommandProtocol, // Protocol + NO_DESCRIPTOR //InterfaceStrIndex + }, + + { + + + // cdc_descriptor + //CDC_Functional_Header + { + {sizeof(USB_CDC_Descriptor_FunctionalHeader_t), DTYPE_CSInterface}, // Header + CDC_DSUBTYPE_CSInterface_Header, // Subtype + 0x0110 // CDCSpecification + }, + + // CDC_Functional_ACM = + { + {sizeof(USB_CDC_Descriptor_FunctionalACM_t), DTYPE_CSInterface}, // Header + CDC_DSUBTYPE_CSInterface_ACM, // Subtype + 0x02 // Capabilities + }, + + // CDC_Functional_Union = + { + {sizeof(USB_CDC_Descriptor_FunctionalUnion_t), DTYPE_CSInterface}, // Header + CDC_DSUBTYPE_CSInterface_Union, // Subtype + 0, // MasterInterfaceNumber + 1, // SlaveInterfaceNumber + }, + + + // CDC_CallManagement = + { + {sizeof(USB_CDC_Descriptor_FunctionalUnion_t), DTYPE_CSInterface}, // Header + CDC_DSUBTYPE_CSInterface_CallManagement, // Subtype + 0, // MasterInterfaceNumber + 1, // SlaveInterfaceNumber + }, + + + + // CDC_NotificationEndpoint = + { + {sizeof(USB_Descriptor_Endpoint_t), DTYPE_Endpoint}, // Header + (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM), // EndpointAddress + (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), // Attributes + CDC_NOTIFICATION_EPSIZE, // EndpointSize + 0x40 // PollingIntervalMS + }, + + + // CDC_DCI_Interface = + { + {sizeof(USB_Descriptor_Interface_t), DTYPE_Interface}, // Header + USB_INTF_CDC_DCI, // InterfaceNumber + 0, // AlternateSetting + 2, // TotalEndpoints + CDC_CSCP_CDCDataClass, // Class + CDC_CSCP_NoDataSubclass, // SubClass + CDC_CSCP_NoDataProtocol, // Protocol + NO_DESCRIPTOR // InterfaceStrIndex + }, + + + // CDC_DataOutEndpoint = + { + {sizeof(USB_Descriptor_Endpoint_t), DTYPE_Endpoint}, // Header + (ENDPOINT_DIR_OUT | CDC_RX_EPNUM), // EndpointAddress + (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), // Attributes + CDC_TXRX_EPSIZE, // EndpointSize + 0x00 // PollingIntervalMS + }, + + // CDC_DataInEndpoint = + { + {sizeof(USB_Descriptor_Endpoint_t), DTYPE_Endpoint}, // Header + (ENDPOINT_DIR_IN | CDC_TX_EPNUM), // EndpointAddress + (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), // Attributes + CDC_TXRX_EPSIZE, // EndpointSize + 0x00 // PollingIntervalMS + }, + }, +#endif + + + +#if(USB_PRINTER_ENABLE) + // printer_interface + { { sizeof(USB_Descriptor_Interface_t), DTYPE_Interface }, + USB_INTF_PRINTER, 0, // AlternateSetting + #if(USB_SOMATIC_ENABLE) + 1, // bNumEndpoints + #else + 2, // bNumEndpoints + #endif + PRNT_CSCP_PrinterClass, // bInterfaceclass ->Printer + PRNT_CSCP_PrinterSubclass, // bInterfaceSubClass -> Control + PRNT_CSCP_BidirectionalProtocol,// bInterfaceProtocol + NO_DESCRIPTOR // iInterface, same as iProduct in USB_Descriptor_Device_t, or else not working + }, + // printer_in_endpoint + { { sizeof(USB_Descriptor_Endpoint_t), DTYPE_Endpoint }, // length, bDescriptorType + ENDPOINT_DIR_IN | USB_EDP_PRINTER_IN, // endpoint id + EP_TYPE_BULK, // endpoint type + 0x0040, // wMaxPacketSize + 0 // bInterval + }, +#if(!USB_SOMATIC_ENABLE) + // printer_out_endpoint + { { sizeof(USB_Descriptor_Endpoint_t), DTYPE_Endpoint }, // length, bDescriptorType + USB_EDP_PRINTER_OUT, // endpoint id + EP_TYPE_BULK, // endpoint type + 0x0040, // wMaxPacketSize + 0 // polling bInterval. valid for iso or interrupt type + }, +#endif +#endif +#if (USB_MIC_ENABLE || USB_SPEAKER_ENABLE) + // audio_control_interface + { { sizeof(USB_Descriptor_Interface_t), DTYPE_Interface}, + USB_INTF_AUDIO_CONTROL, 0, // AlternateSetting + 0, // bNumEndpoints + AUDIO_CSCP_AudioClass, // bInterfaceclass ->Printer + AUDIO_CSCP_ControlSubclass, // bInterfaceSubClass -> Control + AUDIO_CSCP_ControlProtocol, // bInterfaceProtocol + NO_DESCRIPTOR // iInterface + }, + // audio_control_interface_ac; + { +#if (USB_MIC_ENABLE && USB_SPEAKER_ENABLE) + { sizeof(USB_Audio_Descriptor_Interface_AC_TL_t),DTYPE_CSInterface}, AUDIO_DSUBTYPE_CSInterface_Header, // Subtype + {0x00, 0x01}, // ACSpecification, version == 1.0 + // debug note: TotalLength must less than 256 + {(sizeof(USB_Audio_Descriptor_Interface_AC_TL_t) + /*10*/ + sizeof(USB_Audio_Descriptor_InputTerminal_t) + /*12*/ + sizeof(USB_Audio_Descriptor_OutputTerminal_t) + /*9*/ + sizeof(USB_Audio_Descriptor_FeatureUnit_Mic_t) + /*9*/ + sizeof(USB_Audio_Descriptor_InputTerminal_t) + /*12*/ + sizeof(USB_Audio_Descriptor_OutputTerminal_t) + /*9*/ + sizeof(USB_Audio_StdDescriptor_FeatureUnit_t)/*10*/), 0}, 2, // InCollection + USB_INTF_SPEAKER, USB_INTF_MIC +#else + {sizeof(USB_Audio_Descriptor_Interface_AC_t), DTYPE_CSInterface}, + AUDIO_DSUBTYPE_CSInterface_Header, // Subtype + {0x00, 0x01}, // ACSpecification, version == 1.0 +#if (USB_MIC_ENABLE) + {(sizeof(USB_Audio_Descriptor_Interface_AC_t) + /*9*/ + sizeof(USB_Audio_Descriptor_InputTerminal_t) + /*12*/ + sizeof(USB_Audio_Descriptor_OutputTerminal_t) + /*9*/ + sizeof(USB_Audio_Descriptor_FeatureUnit_Mic_t) /*9*/),0}, + 1, + USB_INTF_MIC +#else + {(sizeof(USB_Audio_Descriptor_Interface_AC_t) + /*9*/ + sizeof(USB_Audio_Descriptor_InputTerminal_t) + /*12*/ + sizeof(USB_Audio_Descriptor_OutputTerminal_t) + /*9*/ + sizeof(USB_Audio_StdDescriptor_FeatureUnit_t) /*10*/),0}, + + 1, + USB_INTF_SPEAKER +#endif +#endif + }, +#endif +#if (USB_SPEAKER_ENABLE) + // speaker_input_terminal + { { sizeof(USB_Audio_Descriptor_InputTerminal_t), DTYPE_CSInterface}, + AUDIO_DSUBTYPE_CSInterface_InputTerminal, + USB_SPEAKER_INPUT_TERMINAL_ID, AUDIO_TERMINAL_STREAMING, 0, // AssociatedOutputTerminal + 2, // TotalChannels + 0x0003, // ChannelConfig + 0, // ChannelStrIndex + NO_DESCRIPTOR}, + // speaker_feature_unit + { sizeof(USB_Audio_StdDescriptor_FeatureUnit_t), DTYPE_CSInterface, + AUDIO_DSUBTYPE_CSInterface_Feature, + USB_SPEAKER_FEATURE_UNIT_ID, + USB_SPEAKER_FEATURE_UNIT_SOURCE_ID, 1, // bControlSize + { 0x03, 0x00, 0x00}, // bmaControls + NO_DESCRIPTOR}, + // speaker_output_terminal + { { sizeof(USB_Audio_Descriptor_OutputTerminal_t), DTYPE_CSInterface}, + AUDIO_DSUBTYPE_CSInterface_OutputTerminal, + USB_SPEAKER_OUTPUT_TERMINAL_ID, AUDIO_TERMINAL_OUT_SPEAKER, 0, // AssociatedOutputTerminal + USB_SPEAKER_OUTPUT_TERMINAL_SOURCE_ID, NO_DESCRIPTOR}, +#endif +#if (USB_MIC_ENABLE) + // mic_input_terminal + { { sizeof(USB_Audio_Descriptor_InputTerminal_t), DTYPE_CSInterface}, + AUDIO_DSUBTYPE_CSInterface_InputTerminal, + USB_MIC_INPUT_TERMINAL_ID, AUDIO_TERMINAL_IN_MIC, 0, // AssociatedOutputTerminal + 1, // TotalChannels + 0x0001, // ChannelConfig + 0, // ChannelStrIndex + NO_DESCRIPTOR}, + // mic_feature_unit + { + { sizeof(USB_Audio_Descriptor_FeatureUnit_Mic_t), + DTYPE_CSInterface}, + AUDIO_DSUBTYPE_CSInterface_Feature, USB_MIC_FEATURE_UNIT_ID, + USB_MIC_FEATURE_UNIT_SOURCE_ID, 1, // bControlSize + { 0x03, 0x00}, // bmaControls + NO_DESCRIPTOR}, + // mic_output_terminal + { { sizeof(USB_Audio_Descriptor_OutputTerminal_t), DTYPE_CSInterface}, + AUDIO_DSUBTYPE_CSInterface_OutputTerminal, + USB_MIC_OUTPUT_TERMINAL_ID, AUDIO_TERMINAL_STREAMING, 0, // AssociatedOutputTerminal + USB_MIC_OUTPUT_TERMINAL_SOURCE_ID, NO_DESCRIPTOR}, +#endif +#if (USB_SPEAKER_ENABLE) + // speaker_setting0 + { { sizeof(USB_Descriptor_Interface_t), DTYPE_Interface}, + USB_INTF_SPEAKER, + 0, // AlternateSetting + 0, // bNumEndpoints + AUDIO_CSCP_AudioClass, AUDIO_CSCP_AudioStreamingSubclass, + AUDIO_CSCP_StreamingProtocol, NO_DESCRIPTOR}, + // speaker_setting1 + { { sizeof(USB_Descriptor_Interface_t), DTYPE_Interface}, + USB_INTF_SPEAKER, + 1, // AlternateSetting + 1, // bNumEndpoints + AUDIO_CSCP_AudioClass, AUDIO_CSCP_AudioStreamingSubclass, + AUDIO_CSCP_StreamingProtocol, NO_DESCRIPTOR}, + // speaker_audio_stream + { { sizeof(USB_Audio_Descriptor_Interface_AS_t), DTYPE_CSInterface}, + AUDIO_DSUBTYPE_CSInterface_General, 1, // TerminalLink #1 USB Streaming IT + 1, // FrameDelay + { USB_AUDIO_FORMAT_PCM & 0xff, (USB_AUDIO_FORMAT_PCM >> 8) + & 0xff}}, + // speaker_audio_format + { { sizeof(USB_Audio_Descriptor_Format_t) + + sizeof(USB_Audio_SampleFreq_t), DTYPE_CSInterface}, + AUDIO_DSUBTYPE_CSInterface_FormatType, USB_AUDIO_FORMAT_PCM, 2, // Channels + 2, // SubFrameSize + 0x10, // BitsResolution + 1 // TotalDiscreteSampleRates + }, + // speaker_sample_rate AUDIO_SAMPLE_FREQ + { 0x80, 0xbb, 0x00}, + // speaker_stream_endpoint + { { + { sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), DTYPE_Endpoint}, + USB_EDP_SPEAKER, + EP_TYPE_ISOCHRONOUS | (EP_SYNC_TYPE_ADAPTIVE << 2) | (EP_USAGE_TYPE_DATA << 4), // Attributes ENDPOINT_ATTR_ASYNC + 0x00c0, // EndpointSize USB_MIC_CHANNELS_LEN + 1 // PollingIntervalMS + }, 0, // Refresh + 0 // SyncEndpointNumber + }, + // speaker_stream_endpoint_spc + { + { sizeof(USB_Audio_Descriptor_StreamEndpoint_Spc_t), + DTYPE_CSEndpoint}, AUDIO_DSUBTYPE_CSInterface_General, + AUDIO_EP_FULL_PACKETS_ONLY | AUDIO_EP_SAMPLE_FREQ_CONTROL, 0, // LockDelayUnits + { 0, 0} // LockDelay + }, +#if(USB_AUDIO_441K_ENABLE) + NOTE("Add 441k descriptor if USB_AUDIO_441K_ENABLE defined") +#endif +#endif +#if (USB_MIC_ENABLE) + // mic_setting0 + { { sizeof(USB_Descriptor_Interface_t), DTYPE_Interface}, + USB_INTF_MIC, + 0, // AlternateSetting + 0, // bNumEndpoints + AUDIO_CSCP_AudioClass, AUDIO_CSCP_AudioStreamingSubclass, + AUDIO_CSCP_StreamingProtocol, NO_DESCRIPTOR + }, + // mic_setting1 + { { sizeof(USB_Descriptor_Interface_t), DTYPE_Interface}, + USB_INTF_MIC, + 1, // AlternateSetting + 1, // bNumEndpoints + AUDIO_CSCP_AudioClass, AUDIO_CSCP_AudioStreamingSubclass, + AUDIO_CSCP_StreamingProtocol, NO_DESCRIPTOR + }, + // mic_audio_stream + { { sizeof(USB_Audio_Descriptor_Interface_AS_t), DTYPE_CSInterface}, + AUDIO_DSUBTYPE_CSInterface_General, 6, // TerminalLink #6USB USB Streaming OT + 1, // FrameDelay + { USB_AUDIO_FORMAT_PCM & 0xff, (USB_AUDIO_FORMAT_PCM >> 8)& 0xff} + }, + // mic_audio_format + { { sizeof(USB_Audio_Descriptor_Format_t) + + sizeof(USB_Audio_SampleFreq_t), DTYPE_CSInterface}, + AUDIO_DSUBTYPE_CSInterface_FormatType, USB_AUDIO_FORMAT_PCM, // FormatType + MIC_CHANNEL_COUNT, // Channels + 2, // SubFrameSize + MIC_RESOLUTION_BIT, // BitsResolution + 1 // TotalDiscreteSampleRates + }, + // mic_sample_rate + {(MIC_SAMPLE_RATE & 0xff), (MIC_SAMPLE_RATE >> 8), 0x00}, + // mic_stream_endpoint + { { + { sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), DTYPE_Endpoint} + , ENDPOINT_DIR_MASK | USB_EDP_MIC, + EP_TYPE_ISOCHRONOUS | (EP_SYNC_TYPE_SYNC << 2) | (EP_USAGE_TYPE_DATA << 4), // Attributes + USB_MIC_CHANNELS_LEN, 1 // PollingIntervalMS + }, + 0, // Refresh + 0 // SyncEndpointNumber + }, + // mic_stream_endpoint_spc + { + { sizeof(USB_Audio_Descriptor_StreamEndpoint_Spc_t), + DTYPE_CSEndpoint}, AUDIO_DSUBTYPE_CSInterface_General, + AUDIO_EP_SAMPLE_FREQ_CONTROL, 0, // LockDelayUnits + { 0, 0} // LockDelay + }, +#endif +#if(0) + // audio_interface + { + {sizeof(USB_Descriptor_Interface_t), DTYPE_Interface}, + USB_INTF_AUDIO_HID, + 0, // AlternateSetting + 1, // bNumEndpoints + HID_CSCP_HIDClass, HID_CSCP_NonBootSubclass, + HID_CSCP_NonBootProtocol, NO_DESCRIPTOR + }, + { + // audio_hid + { + {sizeof(USB_HID_Descriptor_HID_t), HID_DTYPE_HID}, 0x0111, // HIDSpec + USB_HID_COUNTRY_NONE, 1, // TotalReportDescriptors + HID_DTYPE_Report, {sizeof(usbaud_report_desc), 0x00}, // HIDReportLength sizeof(Report) + }, + // audio_in_endpoint + { + {sizeof(USB_Descriptor_Endpoint_t), DTYPE_Endpoint}, + ENDPOINT_DIR_IN | USB_EDP_AUDIO, + EP_TYPE_INTERRUPT, 0x0010, // EndpointSize + 1 // PollingIntervalMS + } + }, +#endif +#if (USB_KEYBOARD_ENABLE) + // keyboardInterface + { {sizeof(USB_Descriptor_Interface_t), DTYPE_Interface}, + USB_INTF_KEYBOARD, + 0, // AlternateSetting + 1, // bNumEndpoints + HID_CSCP_HIDClass, HID_CSCP_BootSubclass, + HID_CSCP_KeyboardBootProtocol, NO_DESCRIPTOR + }, + { + // keyboard_hid + { + {sizeof(USB_HID_Descriptor_HID_t), HID_DTYPE_HID}, 0x0111, // HIDSpec + USB_HID_COUNTRY_US, 1, // TotalReportDescriptors + HID_DTYPE_Report, {sizeof(keyboard_report_desc), 0x00}, // HIDReportLength + }, + // keyboard_in_endpoint + { + {sizeof(USB_Descriptor_Endpoint_t), DTYPE_Endpoint}, + ENDPOINT_DIR_IN | USB_EDP_KEYBOARD_IN, + EP_TYPE_INTERRUPT, 0x0008, // EndpointSize + USB_KEYBOARD_POLL_INTERVAL // PollingIntervalMS + }, + }, +#endif +#if (USB_MOUSE_ENABLE) + // mouse_interface + { { sizeof(USB_Descriptor_Interface_t), DTYPE_Interface}, + USB_INTF_MOUSE, + 0, // AlternateSetting + 1, // bNumEndpoints + HID_CSCP_HIDClass, HID_CSCP_BootSubclass, + HID_CSCP_MouseBootProtocol, NO_DESCRIPTOR}, { + // mouse_hid + { { sizeof(USB_HID_Descriptor_HID_t), HID_DTYPE_HID}, 0x0111, // HIDSpec + USB_HID_COUNTRY_US, 1, // TotalReportDescriptors + HID_DTYPE_Report, {sizeof(mouse_report_desc), 0x00}, // HIDReportLength + }, + // mouse_in_endpoint + { { sizeof(USB_Descriptor_Endpoint_t), DTYPE_Endpoint}, + ENDPOINT_DIR_IN | USB_EDP_MOUSE, + EP_TYPE_INTERRUPT, 0x0008, // EndpointSize + USB_MOUSE_POLL_INTERVAL // PollingIntervalMS + }}, +#endif +#if (USB_SOMATIC_ENABLE) + // SOMATICInterface + { {sizeof(USB_Descriptor_Interface_t), DTYPE_Interface}, + USB_INTF_SOMATIC, + 0, // AlternateSetting + 1, // bNumEndpoints + HID_CSCP_HIDClass, HID_CSCP_BootSubclass, + HID_CSCP_NonBootProtocol, NO_DESCRIPTOR + }, + { + // SOMATIC_hid + { + {sizeof(USB_HID_Descriptor_HID_t), HID_DTYPE_HID}, 0x0111, // HIDSpec + USB_HID_COUNTRY_US, 1, // TotalReportDescriptors + HID_DTYPE_Report, {sizeof(somatic_report_desc), 0x00}, // HIDReportLength + }, + // SOMATIC_in_endpoint + { + {sizeof(USB_Descriptor_Endpoint_t), DTYPE_Endpoint}, + ENDPOINT_DIR_IN | USB_EDP_SOMATIC_OUT, + EP_TYPE_INTERRUPT, 0x0010, // EndpointSize + USB_SOMATIC_POLL_INTERVAL // PollingIntervalMS + }, + }, +#endif +}; + +u8* usbdesc_get_language(void) { + return (u8*) (&language_desc); +} + +u8* usbdesc_get_vendor(void) { + return (u8*) (&vendor_desc); +} + +u8* usbdesc_get_product(void) { + return (u8*) (&product_desc); +} + +#if (MS_OS_DESCRIPTOR_ENABLE) + +u8* usbdesc_get_OS_descriptor(void) { + return (u8*) (µsoft_OS_desc); +} + +u8* usbdesc_get_OSFeature(int *length) { + *length = sizeof(OSFeatureDescriptor); + return (u8*) (&OSFeatureDescriptor); +} + +u8* usbdesc_get_compatID(int *length) { + *length = OSFeatureDescriptor_compatID.compatID_Header.dwLength; + + return (u8*) (&OSFeatureDescriptor_compatID); +} + +#endif + +u8* usbdesc_get_serial(void) { + return (u8*) (&serial_desc); +} + +u8* usbdesc_get_device(void) { + return (u8*) (&device_desc); +} + +u8* usbdesc_get_configuration(void) { + return (u8*) (&configuration_desc); +} + +#if(0) +u8* usbdesc_get_audio(void) { + return (u8*) (&configuration_desc.audio_descriptor); +} +#endif + +#if (USB_MOUSE_ENABLE) +u8* usbdesc_get_mouse(void) { + return (u8*) (&configuration_desc.mouse_descriptor); +} +#endif + +#if (USB_KEYBOARD_ENABLE) +u8* usbdesc_get_keyboard(void) { + return (u8*) (&configuration_desc.keyboard_descriptor); +} +#endif + +#if (USB_SOMATIC_ENABLE) +u8* usbdesc_get_somatic(void) { + return (u8*) (&configuration_desc.somatic_descriptor); +} +#endif + +#if (USB_CDC_ENABLE) +u8* usbdesc_get_cdc(void) { + return (u8*) (&configuration_desc.cdc_descriptor); +} + +u8* usbdesc_get_cdc_inf(void) { + return (u8*) (&configuration_desc.cdc_interface); +} +#endif + +#if (AUDIO_HOGP) +u8* usbdesc_get_audio_hogp(void) { + return (u8*) (&configuration_desc.audio_hogp_descriptor); +} +#endif diff --git a/b91/b91m_ble_sdk/application/usbstd/usbdesc.h b/b91/b91m_ble_sdk/application/usbstd/usbdesc.h new file mode 100755 index 0000000..e95aaef --- /dev/null +++ b/b91/b91m_ble_sdk/application/usbstd/usbdesc.h @@ -0,0 +1,419 @@ +/******************************************************************************************************** + * @file usbdesc.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include +#include +#include +#include +#include + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +extern "C" { +#endif + +// interface id +typedef enum { + +#if AUDIO_HOGP + USB_INTF_AUDIO_HOGP, //Must place in this position +#endif + +#if USB_CDC_ENABLE + USB_INTF_CDC_CCI, + USB_INTF_CDC_DCI, +#endif + +#if (USB_PRINTER_ENABLE) + USB_INTF_PRINTER, +#endif +#if (USB_SPEAKER_ENABLE || USB_MIC_ENABLE) + USB_INTF_AUDIO_CONTROL, +#endif +#if (USB_SPEAKER_ENABLE) + USB_INTF_SPEAKER, +#endif +#if (USB_MIC_ENABLE) + USB_INTF_MIC, +#endif +#if(0) + USB_INTF_AUDIO_HID, // use for volumn control, mute, next, prev track, move to mouse hid +#endif +#if USB_KEYBOARD_ENABLE + USB_INTF_KEYBOARD, +#endif +#if USB_MOUSE_ENABLE + USB_INTF_MOUSE, +#endif +#if USB_SOMATIC_ENABLE + USB_INTF_SOMATIC, +#endif + USB_INTF_MAX, +} USB_INTF_ID_E; + +enum { + USB_SPEAKER_FEATURE_UNIT = USB_SPEAKER_ENABLE, + USB_MIC_FEATURE_UNIT = USB_MIC_ENABLE, +}; + +enum { + USB_SPEAKER_INPUT_TERMINAL_ID = 1, + USB_SPEAKER_FEATURE_UNIT_ID, + USB_SPEAKER_OUTPUT_TERMINAL_ID, + USB_MIC_INPUT_TERMINAL_ID, + USB_MIC_FEATURE_UNIT_ID, + USB_MIC_OUTPUT_TERMINAL_ID, +}; + +enum { + USB_SPEAKER_FEATURE_UNIT_SOURCE_ID = 1, + USB_SPEAKER_OUTPUT_TERMINAL_SOURCE_ID, + USB_MIC_FEATURE_UNIT_SOURCE_ID = 4, + USB_MIC_OUTPUT_TERMINAL_SOURCE_ID, +}; + +#if(USB_MIC_ENABLE) +#define USB_MIC_CHANNELS_LEN (MIC_CHANNEL_COUNT*(MIC_SAMPLE_RATE*MIC_RESOLUTION_BIT/1000/8)) +#endif + +enum { + USB_AUDIO_FORMAT_UNKNOWN = 0, + USB_AUDIO_FORMAT_PCM, + USB_AUDIO_FORMAT_ADPCM, + USB_AUDIO_FORMAT_IEEE_FLOAT, + USB_AUDIO_FORMAT_IBM_CVSD, + USB_AUDIO_FORMAT_ALAW, + USB_AUDIO_FORMAT_MULAW, + USB_AUDIO_FORMAT_WMAVOICE9, + USB_AUDIO_FORMAT_OKI_ADPCM, + USB_AUDIO_FORMAT_DVI_ADPCM, + USB_AUDIO_FORMAT_IMA_ADPCM, + USB_AUDIO_FORMAT_MEDIASPACE_ADPCM, + USB_AUDIO_FORMAT_SIERRA_ADPCM, + USB_AUDIO_FORMAT_G723_ADPCM, + USB_AUDIO_FORMAT_DIGISTD, + USB_AUDIO_FORMAT_DIGIFIX, + USB_AUDIO_FORMAT_DIALOGIC_OKI_ADPCM, + USB_AUDIO_FORMAT_MEDIAVISION_ADPCM, + USB_AUDIO_FORMAT_YAMAHA_ADPCM, + USB_AUDIO_FORMAT_SONARC, + USB_AUDIO_FORMAT_DSPGROUP_TRUESPEECH, + USB_AUDIO_FORMAT_ECHOSC1, + USB_AUDIO_FORMAT_AUDIOFILE_AF36, + USB_AUDIO_FORMAT_APTX, + USB_AUDIO_FORMAT_AUDIOFILE_AF10, + USB_AUDIO_FORMAT_DOLBY_AC2, + USB_AUDIO_FORMAT_GSM610, + USB_AUDIO_FORMAT_MSNAUDIO, + USB_AUDIO_FORMAT_ANTEX_ADPCME, + USB_AUDIO_FORMAT_CONTROL_RES_VQLPC, + USB_AUDIO_FORMAT_DIGIREAL, + USB_AUDIO_FORMAT_DIGIADPCM, + USB_AUDIO_FORMAT_CONTROL_RES_CR10, + USB_AUDIO_FORMAT_NMS_VBXADPCM, + USB_AUDIO_FORMAT_CS_IMAADPCM, + USB_AUDIO_FORMAT_ECHOSC3, + USB_AUDIO_FORMAT_ROCKWELL_ADPCM, + USB_AUDIO_FORMAT_ROCKWELL_DIGITALK, + USB_AUDIO_FORMAT_XEBEC, + USB_AUDIO_FORMAT_G721_ADPCM, + USB_AUDIO_FORMAT_G728_CELP, + USB_AUDIO_FORMAT_MPEG, + USB_AUDIO_FORMAT_MPEGLAYER3, + USB_AUDIO_FORMAT_CIRRUS, + USB_AUDIO_FORMAT_ESPCM, + USB_AUDIO_FORMAT_VOXWARE, + USB_AUDIO_FORMAT_WAVEFORMAT_CANOPUS_ATRAC, + USB_AUDIO_FORMAT_G726_ADPCM, + USB_AUDIO_FORMAT_G722_ADPCM, + USB_AUDIO_FORMAT_DSAT, + USB_AUDIO_FORMAT_DSAT_DISPLAY, + USB_AUDIO_FORMAT_SOFTSOUND, + USB_AUDIO_FORMAT_RHETOREX_ADPCM, + USB_AUDIO_FORMAT_MSAUDIO1, + USB_AUDIO_FORMAT_WMAUDIO2, + USB_AUDIO_FORMAT_WMAUDIO3, + USB_AUDIO_FORMAT_WMAUDIO_LOSSLESS, + USB_AUDIO_FORMAT_CREATIVE_ADPCM, + USB_AUDIO_FORMAT_CREATIVE_FASTSPEECH8, + USB_AUDIO_FORMAT_CREATIVE_FASTSPEECH10, + USB_AUDIO_FORMAT_QUARTERDECK, + USB_AUDIO_FORMAT_FM_TOWNS_SND, + USB_AUDIO_FORMAT_BTV_DIGITAL, + USB_AUDIO_FORMAT_OLIGSM, + USB_AUDIO_FORMAT_OLIADPCM, + USB_AUDIO_FORMAT_OLICELP, + USB_AUDIO_FORMAT_OLISBC, + USB_AUDIO_FORMAT_OLIOPR, + USB_AUDIO_FORMAT_LH_CODEC, + USB_AUDIO_FORMAT_NORRIS, +}; + +enum { + USB_HID_COUNTRY_NONE = 0, + USB_HID_COUNTRY_ARABIC, + USB_HID_COUNTRY_BELGIAN, + USB_HID_COUNTRY_CANADA_BI, + USB_HID_COUNTRY_CANADA_FR, + USB_HID_COUNTRY_CZECH_REPUBLIC, + USB_HID_COUNTRY_DANISH, + USB_HID_COUNTRY_FINNISH, + USB_HID_COUNTRY_FRENCH, + USB_HID_COUNTRY_GERMAN, + USB_HID_COUNTRY_GREEK, + USB_HID_COUNTRY_HEBREW, + USB_HID_COUNTRY_HUNGARY, + USB_HID_COUNTRY_INTERNATIONAL_ISO, + USB_HID_COUNTRY_ITALIAN, + USB_HID_COUNTRY_JAPAN_KATAKANA, + USB_HID_COUNTRY_KOREAN, + USB_HID_COUNTRY_LATIN_AMERICAN, + USB_HID_COUNTRY_NETHERLANDS, + USB_HID_COUNTRY_NORWEGIAN, + USB_HID_COUNTRY_PERSIAN, + USB_HID_COUNTRY_POLAND, + USB_HID_COUNTRY_PORTUGUESE, + USB_HID_COUNTRY_RUSSIA, + USB_HID_COUNTRY_SLOVAKIA, + USB_HID_COUNTRY_SPANISH, + USB_HID_COUNTRY_SWEDISH, + USB_HID_COUNTRY_SWISS_FRENCH, + USB_HID_COUNTRY_SWISS_GERMAN, + USB_HID_COUNTRY_SWITZERLAND, + USB_HID_COUNTRY_TAIWAN, + USB_HID_COUNTRY_TURKISH_Q, + USB_HID_COUNTRY_UK, + USB_HID_COUNTRY_US, + USB_HID_COUNTRY_YUGOSLAVIA, + USB_HID_COUNTRY_TURKISH_F, +}; + +enum { + USB_STRING_LANGUAGE = 0, + USB_STRING_VENDOR, + USB_STRING_PRODUCT, + USB_STRING_SERIAL, + + USB_STRING_MS_OS =0xee, +}; + +#if (USB_CDC_ENABLE) +/** Endpoint number of the CDC device-to-host notification IN endpoint. */ +#define CDC_NOTIFICATION_EPNUM 2 + +/** Endpoint number of the CDC device-to-host data IN endpoint. */ +#ifndef CDC_TX_EPNUM +#define CDC_TX_EPNUM 4 ///3 +#endif + +/** Endpoint number of the CDC host-to-device data OUT endpoint. */ +#define CDC_RX_EPNUM 5///4 + +/** Size in bytes of the CDC device-to-host notification IN endpoint. */ +#define CDC_NOTIFICATION_EPSIZE 8 + +/** Size in bytes of the CDC data IN and OUT endpoints. */ +#define CDC_TXRX_EPSIZE 64 +#endif /* USB_CDC_ENABLE */ + +typedef struct { + USB_HID_Descriptor_HID_t audio_hid; + USB_Descriptor_Endpoint_t audio_in_endpoint; +} USB_HID_Descriptor_HID_Audio_t; + +typedef struct { + USB_HID_Descriptor_HID_t mouse_hid; + USB_Descriptor_Endpoint_t mouse_in_endpoint; +} USB_HID_Descriptor_HID_Mouse_t; + +typedef struct { + USB_HID_Descriptor_HID_t keyboard_hid; + USB_Descriptor_Endpoint_t keyboard_in_endpoint; +} USB_HID_Descriptor_HID_Keyboard_t; + +typedef struct { + USB_HID_Descriptor_HID_t somatic_hid; + USB_Descriptor_Endpoint_t somatic_in_endpoint; + USB_Descriptor_Endpoint_t somatic_out_endpoint; +} USB_HID_Descriptor_HID_Somatic_t; + +typedef struct { + // CDC Control Interface + USB_CDC_Descriptor_FunctionalHeader_t CDC_Functional_Header; + USB_CDC_Descriptor_FunctionalACM_t CDC_Functional_ACM; + USB_CDC_Descriptor_FunctionalUnion_t CDC_Functional_Union; + USB_CDC_Descriptor_FunctionalUnion_t CDC_Functional_CallManagement; + USB_Descriptor_Endpoint_t CDC_NotificationEndpoint; + + // CDC Data Interface + USB_Descriptor_Interface_t CDC_DCI_Interface; + USB_Descriptor_Endpoint_t CDC_DataOutEndpoint; + USB_Descriptor_Endpoint_t CDC_DataInEndpoint; +} USB_CDC_Descriptor_t; + +typedef struct { + USB_Descriptor_Configuration_Hdr_t Config; + +#if AUDIO_HOGP + USB_Descriptor_Interface_t audio_hogp_interface; + USB_HID_Descriptor_HID_Keyboard_t audio_hogp_descriptor; +#endif + +#if (USB_CDC_ENABLE) +#if 0 + // IAD0 + USB_Descriptor_Interface_Association_t cdc_iad; +#endif + // CDC Interface + USB_Descriptor_Interface_t cdc_interface; + USB_CDC_Descriptor_t cdc_descriptor; +#endif + +#if(USB_PRINTER_ENABLE) + // printer HID Interface + USB_Descriptor_Interface_t printer_interface; + USB_Descriptor_Endpoint_t printer_in_endpoint; +#if(!USB_SOMATIC_ENABLE) + USB_Descriptor_Endpoint_t printer_out_endpoint; +#endif +#endif +#if (USB_MIC_ENABLE || USB_SPEAKER_ENABLE) + USB_Descriptor_Interface_t audio_control_interface; +#if (USB_MIC_ENABLE && USB_SPEAKER_ENABLE) + USB_Audio_Descriptor_Interface_AC_TL_t audio_control_interface_ac; +#else + USB_Audio_Descriptor_Interface_AC_t audio_control_interface_ac; +#endif +#endif +#if (USB_SPEAKER_ENABLE) + USB_Audio_Descriptor_InputTerminal_t speaker_input_terminal; + USB_Audio_StdDescriptor_FeatureUnit_t speaker_feature_unit; + USB_Audio_Descriptor_OutputTerminal_t speaker_output_terminal; +#endif +#if (USB_MIC_ENABLE) + USB_Audio_Descriptor_InputTerminal_t mic_input_terminal; + USB_Audio_Descriptor_FeatureUnit_Mic_t mic_feature_unit; + USB_Audio_Descriptor_OutputTerminal_t mic_output_terminal; +#endif +#if (USB_SPEAKER_ENABLE) + USB_Descriptor_Interface_t speaker_setting0; + USB_Descriptor_Interface_t speaker_setting1; + USB_Audio_Descriptor_Interface_AS_t speaker_audio_stream; + USB_Audio_Descriptor_Format_t speaker_audio_format; + USB_Audio_SampleFreq_t speaker_sample_rate; + USB_Audio_Descriptor_StreamEndpoint_Std_t speaker_stream_endpoint; + USB_Audio_Descriptor_StreamEndpoint_Spc_t speaker_stream_endpoint_spc; +#if(USB_AUDIO_441K_ENABLE) + NOTE("Add 441k descriptor if USB_AUDIO_441K_ENABLE defined") +#endif +#endif +#if (USB_MIC_ENABLE) + USB_Descriptor_Interface_t mic_setting0; + USB_Descriptor_Interface_t mic_setting1; + USB_Audio_Descriptor_Interface_AS_t mic_audio_stream; + USB_Audio_Descriptor_Format_t mic_audio_format; + USB_Audio_SampleFreq_t mic_sample_rate; + USB_Audio_Descriptor_StreamEndpoint_Std_t mic_stream_endpoint; + USB_Audio_Descriptor_StreamEndpoint_Spc_t mic_stream_endpoint_spc; +#endif +#if (0) + // audio HID Interface + USB_Descriptor_Interface_t audio_interface; + USB_HID_Descriptor_HID_Audio_t audio_descriptor; +#endif +#if (USB_KEYBOARD_ENABLE) + // Keyboard HID Interface + USB_Descriptor_Interface_t keyboard_interface; + USB_HID_Descriptor_HID_Keyboard_t keyboard_descriptor; +#endif +#if (USB_MOUSE_ENABLE) + // Mouse HID Interface + USB_Descriptor_Interface_t mouse_interface; + USB_HID_Descriptor_HID_Mouse_t mouse_descriptor; +#endif +#if (USB_SOMATIC_ENABLE) + // SOMATIC HID Interface + USB_Descriptor_Interface_t somatic_interface; + USB_HID_Descriptor_HID_Somatic_t somatic_descriptor; +#endif +} USB_Descriptor_Configuration_t; + +typedef struct { + u32 dwLength; // length, in bytes, of the complete extended compat ID descriptor + u16 bcdVersion; // BCD The descriptors version number, in binary coded decimal (BCD) format + u16 wIndex; // An index that identifies the particular OS feature descriptor + u8 bCount; //The number of custom property sections + u8 RESERVED[7]; //Reserved + +}USB_MS_OS_compatID_Header_t; + +typedef struct { + + u8 bFirstInterfaceNumber; //The interface or function number + u8 RESERVED1; //Reserved + u8 compatibleID[8]; //The functions compatible ID + u8 subCompatibleID[8]; //The functions subcompatible ID + u8 RESERVED2[6]; //Reserved + +}USB_MS_OS_compatID_Function_t; + + +typedef struct { + USB_MS_OS_compatID_Header_t compatID_Header; + USB_MS_OS_compatID_Function_t compatID_Function[]; +}USB_MS_OS_compatID_t; + + +u8* usbdesc_get_language(void); +u8* usbdesc_get_vendor(void); +u8* usbdesc_get_product(void); +u8* usbdesc_get_serial(void); +u8* usbdesc_get_device(void); +u8* usbdesc_get_configuration(void); + +#if(USB_MIC_ENABLE || USB_SPEAKER_ENABLE) +u8* usbdesc_get_audio(void); +#endif + +#if (USB_MOUSE_ENABLE) +u8* usbdesc_get_mouse(void); +#endif + +#if (USB_KEYBOARD_ENABLE) +u8* usbdesc_get_keyboard(void); +#endif + +#if (USB_SOMATIC_ENABLE) +u8* usbdesc_get_somatic(void); +#endif + +#if (USB_CRC_ENABLE) +u8 *usbdesc_get_cdc(void); +#endif + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +} +#endif + diff --git a/b91/b91m_ble_sdk/application/usbstd/usbkeycode.h b/b91/b91m_ble_sdk/application/usbstd/usbkeycode.h new file mode 100755 index 0000000..2d2480e --- /dev/null +++ b/b91/b91m_ble_sdk/application/usbstd/usbkeycode.h @@ -0,0 +1,348 @@ +/******************************************************************************************************** + * @file usbkeycode.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#define VK_NONE 0x00 + +// function key bitmap +#define VK_MSK_CTRL 0x01 +#define VK_MSK_SHIFT 0x02 +#define VK_MSK_ALT 0x04 +#define VK_MSK_WIN 0x08 + +#define VK_MSK_LCTRL 0x01 +#define VK_MSK_LSHIFT 0x02 +#define VK_MSK_LALT 0x04 +#define VK_MSK_LWIN 0x08 + +#define VK_MSK_RCTRL 0x10 +#define VK_MSK_RSHIFT 0x20 +#define VK_MSK_RALT 0x40 +#define VK_MSK_RWIN 0x80 + +// ordinary keys +#define VK_A 0x04 +#define VK_B 0x05 +#define VK_C 0x06 +#define VK_D 0x07 +#define VK_E 0x08 +#define VK_F 0x09 +#define VK_G 0x0a +#define VK_H 0x0b +#define VK_I 0x0c +#define VK_J 0x0d +#define VK_K 0x0e +#define VK_L 0x0f +#define VK_M 0x10 +#define VK_N 0x11 +#define VK_O 0x12 +#define VK_P 0x13 +#define VK_Q 0x14 +#define VK_R 0x15 +#define VK_S 0x16 +#define VK_T 0x17 +#define VK_U 0x18 +#define VK_V 0x19 +#define VK_W 0x1a +#define VK_X 0x1b +#define VK_Y 0x1c +#define VK_Z 0x1d +#define VK_1 0x1e +#define VK_2 0x1f +#define VK_3 0x20 +#define VK_4 0x21 +#define VK_5 0x22 +#define VK_6 0x23 +#define VK_7 0x24 +#define VK_8 0x25 +#define VK_9 0x26 +#define VK_0 0x27 +#define VK_ENTER 0x28 +#define VK_ESC 0x29 +#define VK_BACKSPACE 0x2a +#define VK_TAB 0x2b +#define VK_SPACE 0x2c +#define VK_MINUS 0x2d +#define VK_EQUAL 0x2e +#define VK_LBRACE 0x2f +#define VK_RBRACE 0x30 +#define VK_BACKSLASH 0x31 +#define VK_NUMBER 0x32 +#define VK_SEMICOLON 0x33 +#define VK_QUOTE 0x34 +#define VK_TILDE 0x35 +#define VK_COMMA 0x36 +#define VK_PERIOD 0x37 +#define VK_SLASH 0x38 +#define VK_CAPITAL 0x39 +#define VK_F1 0x3a +#define VK_F2 0x3b +#define VK_F3 0x3c +#define VK_F4 0x3d +#define VK_F5 0x3e +#define VK_F6 0x3f +#define VK_F7 0x40 +#define VK_F8 0x41 +#define VK_F9 0x42 +#define VK_F10 0x43 +#define VK_F11 0x44 +#define VK_F12 0x45 +#define VK_PRINTSCREEN 0x46 +#define VK_SCR_LOCK 0x47 +#define VK_PAUSE 0x48 +#define VK_INSERT 0x49 +#define VK_HOME 0x4a +#define VK_PAGE_UP 0x4b +#define VK_DELETE 0x4c +#define VK_END 0x4d +#define VK_PAGE_DOWN 0x4e +#define VK_RIGHT 0x4f +#define VK_LEFT 0x50 +#define VK_DOWN 0x51 +#define VK_UP 0x52 +#define VK_NUM_LOCK 0x53 +#define VKPAD_SLASH 0x54 +#define VKPAD_ASTERIX 0x55 +#define VKPAD_MINUS 0x56 +#define VKPAD_PLUS 0x57 +#define VKPAD_ENTER 0x58 +#define VKPAD_1 0x59 +#define VKPAD_2 0x5a +#define VKPAD_3 0x5b +#define VKPAD_4 0x5c +#define VKPAD_5 0x5d +#define VKPAD_6 0x5e +#define VKPAD_7 0x5f +#define VKPAD_8 0x60 +#define VKPAD_9 0x61 +#define VKPAD_0 0x62 +#define VKPAD_PERIOD 0x63 +#define VK_K45 0x64 +#define VK_APP 0x65 +// below KEY is for ELAN's application matrix +#define VK_C9R1 0xf0 //C9R1 00 +#define VK_C9R6 0xf1 //C9R6 000 +#define VK_RMB 0xf2 //C7R3 +#define VK_EURO 0xf3 //C0R2 +#define VK_MMODE 0xf4 //C9R4 + +#define VK_K107 0x85 //ok +#define VK_K56 0x87 //ok +#define VK_ROMA 0x88 //ok +#define VK_K14 0x89 //ok +#define VK_CHG 0x8a //ok +#define VK_NCHG 0x8b //ok +#define VK_KCR 0x90 //ok,K151 +#define VK_KCL 0x91 //ok,K150 + +// NOT standard, use these reserved code to distinguish ctrol keys +#ifndef CTRL_SHIFT_E0E7 +#define CTRL_SHIFT_E0E7 1 +#endif + +#if CTRL_SHIFT_E0E7 +#define VK_CTRL 0xe0 +#define VK_SHIFT 0xe1 +#define VK_ALT 0xe2 +#define VK_WIN 0xe3 +#define VK_RCTRL 0xe4 +#define VK_RSHIFT 0xe5 +#define VK_RALT 0xe6 +#define VK_RWIN 0xe7 +#else +#define VK_CTRL 0x90 +#define VK_SHIFT 0x91 +#define VK_ALT 0x92 +#define VK_WIN 0x93 +#define VK_RCTRL 0x94 +#define VK_RSHIFT 0x95 +#define VK_RALT 0x96 +#define VK_RWIN 0x97 +#endif + +enum{ + VK_EXT_START = 0xa0, + + VK_SYS_START = VK_EXT_START, //0xa0 + VK_SLEEP = VK_SYS_START, //0xa0, sleep + VK_POWER, //0xa1, power + VK_WAKEUP, //0xa2, wake-up +// VK_MCE_STR, //0xa3 +// VK_MY_MUSIC, //0xa4 + VK_SYS_END, //0xa3 + VK_SYS_CNT = (VK_SYS_END - VK_SYS_START),//0xa3-0xa0=0x03 + + VK_MEDIA_START = VK_SYS_END, //0xa3 + VK_W_SRCH = VK_MEDIA_START, //0xa3 + VK_WEB, //0xa4 + VK_W_BACK, + VK_W_FORWRD, + VK_W_STOP, + VK_W_REFRESH, + VK_W_FAV, //0xa9 + VK_MEDIA, + VK_MAIL, + VK_CAL, + VK_MY_COMP, + VK_NEXT_TRK, + VK_PREV_TRK, + VK_STOP, //b0 + VK_PLAY_PAUSE, + VK_W_MUTE, + VK_VOL_UP, + VK_VOL_DN, + + + VK_MEDIA_END, + VK_EXT_END = VK_MEDIA_END, + VK_MEDIA_CNT = (VK_MEDIA_END - VK_MEDIA_START),//0xb5-0xa3=0x12 + + VK_ZOOM_IN = (VK_MEDIA_END + 1),//0xb6 + VK_ZOOM_OUT , //0xb7 + + //special key,do it later + VK_CH_UP = 0xf0, + VK_CH_DN = 0xf1, + VK_FAST_FORWARD = 0xf2, + VK_FAST_BACKWARD = 0xf3, + VK_W_SHOPPING = 0xf4, + VK_W_APP_STORE = 0xf5, + VK_MY_FAVORIT = 0xf6, + VK_MENU = 0xf7, + VK_EXIT = 0xf8, + VK_CONFIRM = 0xf9, + VK_RETURN = 0xfa, + VK_VOICE_SEARCH = 0xfb, + VK_PROGRAM = 0xfc, + VK_LOW_BATT = 0xfd, + VK_TV_PLUS = 0xfe, + VK_TV_MINUS = 0xff, + VK_IN_OUTPUT = 0xef, + VK_TV_POWER = 0xee, + VK_STB_POWER = 0xed, + + +}; +#define VK_FN 0xff + +#define VK_EXT_LEN 2 +typedef struct{ + u8 val[VK_EXT_LEN]; +}vk_ext_t; + +// mulit-byte keycode for media keys, cannot used directly in c code..for reference +#define VK_POWER_V 0x01 +#define VK_SLEEP_V 0x02 +#define VK_WAKEUP_V 0x04 + +#define VK_W_SRCH_V {0x21,0x02} +#define VK_HOME_V {0x23,0x02} +#define VK_W_BACK_V {0x24,0x02} +#define VK_W_FORWRD_V {0x25,0x02} +#define VK_W_STOP_V {0x26,0x02} +#define VK_W_REFRESH_V {0x27,0x02} +// favorite +#define VK_W_FAV_V {0x2a,0x02} +#define VK_MEDIA_V {0x83,0x01} +#define VK_MAIL_V {0x8a,0x01} +// calculator +#define VK_CAL_V {0x92,0x01} +#define VK_MY_COMP_V {0x94,0x01} +// next track -- 01(mosue-ep/USB_EDP_MOUSE) 05(len) 03(kb-report-id/USB_HID_KB_MEDIA) +// b5(val) 00 00 00 +#define VK_MENU_V {0x40,0x00} +#define VK_MENU_PICK_V {0x41,0x00} +#define VK_MENU_UP_V {0x42,0x00} +#define VK_MENU_DN_V {0x43,0x00} +#define VK_MENU_LEFT_V {0x44,0x00} +#define VK_MENU_RIGHT_V {0x45,0x00} + +#define VK_CHN_UP_V {0x9c,0x00} +#define VK_CHN_DN_V {0x9d,0x00} + +#define VK_PLAY_V {0xb0,0x00} +#define VK_PAUSE_V {0xb1,0x00} +#define VK_RECORD_V {0xb2,0x00} +#define VK_FAST_FORWARD_V {0xb3,0x00} +#define VK_REWIND_V {0xb4,0x00} +#define VK_NEXT_TRK_V {0xb5,0x00} +#define VK_PREV_TRK_V {0xb6,0x00} +#define VK_STOP_V {0xb7,0x00} +#define VK_PLAY_PAUSE_V {0xcd,0x00} +#define VK_W_MUTE_V {0xe2,0x00} +#define VK_VOL_UP_V {0xe9,0x00} +#define VK_VOL_DN_V {0xea,0x00} + + + +// media key, consumer key +//reference: <> Consumer Page(0x0C) +typedef enum { + MKEY_POWER = 0x0030, + MKEY_RESET = 0x0031, + MKEY_SLEEP = 0x0032, + + MKEY_MENU = 0x0040, + MKEY_MENU_PICK = 0x0041, + MKEY_MENU_UP = 0x0042, + MKEY_MENU_DN = 0x0043, + MKEY_MENU_LEFT = 0x0044, + MKEY_MENU_RIGHT = 0x0045, + + + MKEY_CHN_UP = 0x009c, + MKEY_CHN_DN = 0x009d, + + MKEY_PLAY = 0x00b0, + MKEY_PAUSE = 0x00b1, + MKEY_RECORD = 0x00b2, + MKEY_FAST_FORWARD = 0x00b3, + MKEY_REWIND = 0x00b4, + MKEY_NEXT_TRK = 0x00b5, + MKEY_PREV_TRK = 0x00b6, + MKEY_STOP = 0x00b7, + MKEY_EJECT = 0x00b8, + + MKEY_PLAY_PAUSE = 0x00cd, + MKEY_PLAY_SKIP = 0x00ce, + + MKEY_VOLUME = 0x00e0, + MKEY_BALANCE = 0x00e1, + MKEY_MUTE = 0x00e2, + MKEY_VOL_UP = 0x00e9, + MKEY_VOL_DN = 0x00ea, + + MKEY_AC_SEARCH = 0x0221, + MKEY_AC_GOTO = 0x0222, + MKEY_AC_HOME = 0x0223, + MKEY_AC_BACK = 0x0224, + MKEY_AC_FORWARD = 0x0225, + MKEY_AC_STOP = 0x0226, + MKEY_AC_REFRESH = 0x0227, + MKEY_AC_BOOKMARK = 0x022a, + MKEY_AC_HISTORY = 0x022b, + MKEY_AC_ZOOM_IN = 0x022d, + MKEY_AC_ZOOM_OUT = 0x022e, + MKEY_AC_ZOOM = 0x022f, + +} media_key_t; diff --git a/b91/b91m_ble_sdk/boot.link b/b91/b91m_ble_sdk/boot.link new file mode 100755 index 0000000..f076965 --- /dev/null +++ b/b91/b91m_ble_sdk/boot.link @@ -0,0 +1,100 @@ +/******************************************************************************************************** + * @file boot.link + * + * @brief This is the link file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +ENTRY(_RESET_ENTRY) +SECTIONS +{ + NDS_SAG_LMA_FLASH = 0x20000000 ; + . = 0x20000000; + PROVIDE (BIN_BEGIN = .); + .vectors : { KEEP(*(.vectors )) } + . = 0x00000000; + .retention_reset : AT( ALIGN(LOADADDR (.vectors) + SIZEOF (.vectors),8)) + { KEEP(*(.retention_reset )) } + PROVIDE (_RETENTION_RESET_VMA_START = ADDR(.retention_reset)); + PROVIDE (_RETENTION_RESET_LMA_START = LOADADDR(.retention_reset)); + PROVIDE (_RETENTION_RESET_VMA_END = .); + /* By default,the aes_data section can only be used in the first 64K of IRAM, */ + /* please do not change the position of this section,unless you know the correct way to use */ + . = ALIGN(8); + PROVIDE (_AES_VMA_START = .); + .aes_data (NOLOAD) : { KEEP(*(.aes_data )) } + PROVIDE (_AES_VMA_END = .); + . = ALIGN(8); + .retention_data : AT( ALIGN(LOADADDR (.retention_reset) + SIZEOF (.retention_reset),8)) + { KEEP(*(.retention_data )) } + PROVIDE (_RETENTION_DATA_VMA_START = ADDR(.retention_data)); + PROVIDE (_RETENTION_DATA_LMA_START = LOADADDR(.retention_data)); + PROVIDE (_RETENTION_DATA_VMA_END = .); + + . = ALIGN(8); + .ram_code : AT( ALIGN(LOADADDR (.retention_data) + SIZEOF (.retention_data),8)) + { KEEP(*(.ram_code )) } + PROVIDE (_RAMCODE_VMA_END = .); + PROVIDE (_RAMCODE_VMA_START = ADDR(.ram_code)); + PROVIDE (_RAMCODE_LMA_START = LOADADDR(.ram_code)); + PROVIDE (_RAMCODE_SIZE = SIZEOF (.ram_code)); + + . = ALIGN(LOADADDR (.ram_code) + SIZEOF (.ram_code), 8); + .text : AT(ALIGN(LOADADDR (.ram_code) + SIZEOF (.ram_code), 8)) + { *(.text .stub .text.* .gnu.linkonce.t.* ) KEEP(*(.text.*personality* )) *(.gnu.warning ) } + .rodata : AT(ALIGN(LOADADDR (.text) + SIZEOF (.text), ALIGNOF(.rodata))) + { *(.rodata .rodata.* .gnu.linkonce.r.* ) + *(.srodata.cst16 ) *(.srodata.cst8 ) *(.srodata.cst4 ) *(.srodata.cst2 ) *(.srodata .srodata.* ) + *(.sdata2 .sdata2.* .gnu.linkonce.s.* ) + } + .eh_frame_hdr : AT(ALIGN(LOADADDR (.rodata) + SIZEOF (.rodata), ALIGNOF(.eh_frame_hdr))) + { *(.eh_frame_hdr ) } + . = ALIGN(0x20); + .eh_frame : AT(ALIGN(LOADADDR (.eh_frame_hdr) + SIZEOF (.eh_frame_hdr), 32)) + { KEEP(*(.eh_frame )) } + + .exec.itable : AT(ALIGN(LOADADDR (.eh_frame) + SIZEOF (.eh_frame), ALIGNOF(.exec.itable))) + { KEEP(*(.exec.itable)) } + + . = 0x00080000; + PROVIDE( __global_pointer$ = . + (4K / 2) ); + .data : AT(ALIGN(LOADADDR (.exec.itable) + SIZEOF (.exec.itable), ALIGNOF(.data))) + { *(.data .data.* .gnu.linkonce.d.* ) KEEP(*(.gnu.linkonce.d.*personality* )) SORT(CONSTRUCTORS) + *(.sdata .sdata.* .gnu.linkonce.s.* ) + } + PROVIDE (_DATA_VMA_END = .); + PROVIDE (_DATA_VMA_START = ADDR(.data)); + PROVIDE (_DATA_LMA_START = LOADADDR(.data)); + PROVIDE (BIN_SIZE = LOADADDR(.data) + SIZEOF(.data) - BIN_BEGIN); + + . = ALIGN(8); + PROVIDE (_BSS_VMA_START = .); + .sbss (NOLOAD) : { *(.dynsbss ) *(.sbss .sbss.* .gnu.linkonce.sb.* ) *(.scommon .scommon.* ) } + .bss (NOLOAD) : { *(.dynbss ) *(.bss .bss.* .gnu.linkonce.b.* ) *(COMMON ) . = ALIGN(8); } + PROVIDE (_BSS_VMA_END = .); + + . = ALIGN(8); + /* end is the starting address of the heap, the heap grows upward */ + _end = .; + PROVIDE (end = .); + PROVIDE (_STACK_TOP = 0x00a0000);/*Need to prevent stack overflow*/ + PROVIDE (FLASH_SIZE = 0x0100000); +} + +ASSERT((BIN_SIZE)<= FLASH_SIZE, "BIN FILE OVERFLOW"); diff --git a/b91/b91m_ble_sdk/boot/B91/boot_DLM.link b/b91/b91m_ble_sdk/boot/B91/boot_DLM.link new file mode 100755 index 0000000..35dfe80 --- /dev/null +++ b/b91/b91m_ble_sdk/boot/B91/boot_DLM.link @@ -0,0 +1,107 @@ +/******************************************************************************************************** + * @file boot_DLM.link + * + * @brief This is the link file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +ENTRY(_RESET_ENTRY) +SECTIONS +{ + NDS_SAG_LMA_FLASH = 0x20000000 ; + . = 0x20000000; + PROVIDE (BIN_BEGIN = .); + .vectors : { KEEP(*(.vectors )) } + . = 0x00000000; + .retention_reset : AT( ALIGN(LOADADDR (.vectors) + SIZEOF (.vectors),8)) + { KEEP(*(.retention_reset )) } + PROVIDE (_RETENTION_RESET_VMA_START = ADDR(.retention_reset)); + PROVIDE (_RETENTION_RESET_LMA_START = LOADADDR(.retention_reset)); + PROVIDE (_RETENTION_RESET_VMA_END = .); + /* By default,the aes_data section can only be used in the first 64K of IRAM, */ + /* please do not change the position of this section,unless you know the correct way to use */ + . = ALIGN(8); + PROVIDE (_AES_VMA_START = .); + .aes_data (NOLOAD) : { KEEP(*(.aes_data )) } + PROVIDE (_AES_VMA_END = .); + . = ALIGN(8); + .retention_data : AT( ALIGN(LOADADDR (.retention_reset) + SIZEOF (.retention_reset),8)) + { KEEP(*(.retention_data )) } + PROVIDE (_RETENTION_DATA_VMA_START = ADDR(.retention_data)); + PROVIDE (_RETENTION_DATA_LMA_START = LOADADDR(.retention_data)); + PROVIDE (_RETENTION_DATA_VMA_END = .); + + . = ALIGN(8); + .ram_code : AT( ALIGN(LOADADDR (.retention_data) + SIZEOF (.retention_data),8)) + { KEEP(*(.ram_code )) } + PROVIDE (_RAMCODE_VMA_END = .); + PROVIDE (_RAMCODE_VMA_START = ADDR(.ram_code)); + PROVIDE (_RAMCODE_LMA_START = LOADADDR(.ram_code)); + PROVIDE (_RAMCODE_SIZE = SIZEOF (.ram_code)); + + . = ALIGN(LOADADDR (.ram_code) + SIZEOF (.ram_code), 8); + .text : AT(ALIGN(LOADADDR (.ram_code) + SIZEOF (.ram_code), 8)) + { *(.text .stub .text.* .gnu.linkonce.t.* ) KEEP(*(.text.*personality* )) *(.gnu.warning ) } + .rodata : AT(ALIGN(LOADADDR (.text) + SIZEOF (.text), ALIGNOF(.rodata))) + { *(.rodata .rodata.* .gnu.linkonce.r.* ) + *(.srodata.cst16 ) *(.srodata.cst8 ) *(.srodata.cst4 ) *(.srodata.cst2 ) *(.srodata .srodata.* ) + *(.sdata2 .sdata2.* .gnu.linkonce.s.* ) + } + .eh_frame_hdr : AT(ALIGN(LOADADDR (.rodata) + SIZEOF (.rodata), ALIGNOF(.eh_frame_hdr))) + { *(.eh_frame_hdr ) } + . = ALIGN(0x20); + .eh_frame : AT(ALIGN(LOADADDR (.eh_frame_hdr) + SIZEOF (.eh_frame_hdr), 32)) + { KEEP(*(.eh_frame )) } + + .exec.itable : AT(ALIGN(LOADADDR (.eh_frame) + SIZEOF (.eh_frame), ALIGNOF(.exec.itable))) + { KEEP(*(.exec.itable)) } + + . = 0x00080000; + .dlm_data : AT(ALIGN(LOADADDR (.exec.itable) + SIZEOF (.exec.itable), 8)) + { KEEP(*(.dlm_data )) } + PROVIDE (_DLM_DATA_VMA_START = ADDR(.dlm_data)); + PROVIDE (_DLM_DATA_LMA_START = LOADADDR(.dlm_data)); + PROVIDE (_DLM_DATA_VMA_END = .); + PROVIDE (BIN_SIZE = LOADADDR(.dlm_data) + SIZEOF(.dlm_data) - BIN_BEGIN); + + . = 0x0001c000; + PROVIDE( __global_pointer$ = . + (4K / 2) ); + .data : AT(ALIGN(LOADADDR (.dlm_data) + SIZEOF (.dlm_data), ALIGNOF(.data))) + { *(.data .data.* .gnu.linkonce.d.* ) KEEP(*(.gnu.linkonce.d.*personality* )) SORT(CONSTRUCTORS) + *(.sdata .sdata.* .gnu.linkonce.s.* ) + } + PROVIDE (_DATA_VMA_END = .); + PROVIDE (_DATA_VMA_START = ADDR(.data)); + PROVIDE (_DATA_LMA_START = LOADADDR(.data)); + + . = ALIGN(8); + PROVIDE (_BSS_VMA_START = .); + .sbss (NOLOAD) : { *(.dynsbss ) *(.sbss .sbss.* .gnu.linkonce.sb.* ) *(.scommon .scommon.* ) } + .bss (NOLOAD) : { *(.dynbss ) *(.bss .bss.* .gnu.linkonce.b.* ) *(COMMON ) . = ALIGN(8); } + PROVIDE (_BSS_VMA_END = .); + + . = ALIGN(8); + /* end is the starting address of the heap, the heap grows upward */ + _end = .; + PROVIDE (end = .); + PROVIDE (_STACK_TOP = 0x0020000);/*Need to prevent stack overflow*/ + PROVIDE (FLASH_SIZE = 0x0100000); +} + +ASSERT((BIN_SIZE)<= FLASH_SIZE, "BIN FILE OVERFLOW"); diff --git a/b91/b91m_ble_sdk/boot/B91/boot_general.link b/b91/b91m_ble_sdk/boot/B91/boot_general.link new file mode 100755 index 0000000..1a0d469 --- /dev/null +++ b/b91/b91m_ble_sdk/boot/B91/boot_general.link @@ -0,0 +1,100 @@ +/******************************************************************************************************** + * @file boot_general.link + * + * @brief This is the link file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +ENTRY(_RESET_ENTRY) +SECTIONS +{ + NDS_SAG_LMA_FLASH = 0x20000000 ; + . = 0x20000000; + PROVIDE (BIN_BEGIN = .); + .vectors : { KEEP(*(.vectors )) } + . = 0x00000000; + .retention_reset : AT( ALIGN(LOADADDR (.vectors) + SIZEOF (.vectors),8)) + { KEEP(*(.retention_reset )) } + PROVIDE (_RETENTION_RESET_VMA_START = ADDR(.retention_reset)); + PROVIDE (_RETENTION_RESET_LMA_START = LOADADDR(.retention_reset)); + PROVIDE (_RETENTION_RESET_VMA_END = .); + /* By default,the aes_data section can only be used in the first 64K of IRAM, */ + /* please do not change the position of this section,unless you know the correct way to use */ + . = ALIGN(8); + PROVIDE (_AES_VMA_START = .); + .aes_data (NOLOAD) : { KEEP(*(.aes_data )) } + PROVIDE (_AES_VMA_END = .); + . = ALIGN(8); + .retention_data : AT( ALIGN(LOADADDR (.retention_reset) + SIZEOF (.retention_reset),8)) + { KEEP(*(.retention_data )) } + PROVIDE (_RETENTION_DATA_VMA_START = ADDR(.retention_data)); + PROVIDE (_RETENTION_DATA_LMA_START = LOADADDR(.retention_data)); + PROVIDE (_RETENTION_DATA_VMA_END = .); + + . = ALIGN(8); + .ram_code : AT( ALIGN(LOADADDR (.retention_data) + SIZEOF (.retention_data),8)) + { KEEP(*(.ram_code )) } + PROVIDE (_RAMCODE_VMA_END = .); + PROVIDE (_RAMCODE_VMA_START = ADDR(.ram_code)); + PROVIDE (_RAMCODE_LMA_START = LOADADDR(.ram_code)); + PROVIDE (_RAMCODE_SIZE = SIZEOF (.ram_code)); + + . = ALIGN(LOADADDR (.ram_code) + SIZEOF (.ram_code), 8); + .text : AT(ALIGN(LOADADDR (.ram_code) + SIZEOF (.ram_code), 8)) + { *(.text .stub .text.* .gnu.linkonce.t.* ) KEEP(*(.text.*personality* )) *(.gnu.warning ) } + .rodata : AT(ALIGN(LOADADDR (.text) + SIZEOF (.text), ALIGNOF(.rodata))) + { *(.rodata .rodata.* .gnu.linkonce.r.* ) + *(.srodata.cst16 ) *(.srodata.cst8 ) *(.srodata.cst4 ) *(.srodata.cst2 ) *(.srodata .srodata.* ) + *(.sdata2 .sdata2.* .gnu.linkonce.s.* ) + } + .eh_frame_hdr : AT(ALIGN(LOADADDR (.rodata) + SIZEOF (.rodata), ALIGNOF(.eh_frame_hdr))) + { *(.eh_frame_hdr ) } + . = ALIGN(0x20); + .eh_frame : AT(ALIGN(LOADADDR (.eh_frame_hdr) + SIZEOF (.eh_frame_hdr), 32)) + { KEEP(*(.eh_frame )) } + + .exec.itable : AT(ALIGN(LOADADDR (.eh_frame) + SIZEOF (.eh_frame), ALIGNOF(.exec.itable))) + { KEEP(*(.exec.itable)) } + + . = 0x00080000; + PROVIDE( __global_pointer$ = . + (4K / 2) ); + .data : AT(ALIGN(LOADADDR (.exec.itable) + SIZEOF (.exec.itable), ALIGNOF(.data))) + { *(.data .data.* .gnu.linkonce.d.* ) KEEP(*(.gnu.linkonce.d.*personality* )) SORT(CONSTRUCTORS) + *(.sdata .sdata.* .gnu.linkonce.s.* ) + } + PROVIDE (_DATA_VMA_END = .); + PROVIDE (_DATA_VMA_START = ADDR(.data)); + PROVIDE (_DATA_LMA_START = LOADADDR(.data)); + PROVIDE (BIN_SIZE = LOADADDR(.data) + SIZEOF(.data) - BIN_BEGIN); + + . = ALIGN(8); + PROVIDE (_BSS_VMA_START = .); + .sbss (NOLOAD) : { *(.dynsbss ) *(.sbss .sbss.* .gnu.linkonce.sb.* ) *(.scommon .scommon.* ) } + .bss (NOLOAD) : { *(.dynbss ) *(.bss .bss.* .gnu.linkonce.b.* ) *(COMMON ) . = ALIGN(8); } + PROVIDE (_BSS_VMA_END = .); + + . = ALIGN(8); + /* end is the starting address of the heap, the heap grows upward */ + _end = .; + PROVIDE (end = .); + PROVIDE (_STACK_TOP = 0x00a0000);/*Need to prevent stack overflow*/ + PROVIDE (FLASH_SIZE = 0x0100000); +} + +ASSERT((BIN_SIZE)<= FLASH_SIZE, "BIN FILE OVERFLOW"); diff --git a/b91/b91m_ble_sdk/boot/B91/cstartup_B91.S b/b91/b91m_ble_sdk/boot/B91/cstartup_B91.S new file mode 100755 index 0000000..21f5705 --- /dev/null +++ b/b91/b91m_ble_sdk/boot/B91/cstartup_B91.S @@ -0,0 +1,475 @@ +/******************************************************************************************************** + * @file cstartup_B91.S + * + * @brief This is the boot file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#if 1 /*default is open*/ + .section .vectors, "ax" + + //.org and linker's relaxation (-flto) cannot be used at the same time + //Pop corresponds to push. Before using .option norelax, use push to save the current .option configuration + //and then modify .option. After using norelax, use pop to restore + .option push + .option norelax + .org 0x0 + + + .global _RESET_ENTRY + .type _RESET_ENTRY,@function + + .align 2 +_RESET_ENTRY: + j _START + //free the 6th ~ 7th byte to store the crc type of the bin file + .org 0x18 + .word (BIN_SIZE) + + .org 0x20 + .word ('T'<<24 | 'L'<<16 | 'N'<<8 | 'K') + + .org 0x26 + //.short (0x0003) //READ: cmd:1x, addr:1x, data:1x, dummy:0 + //.short (0x070B) //FREAD: cmd:1x, addr:1x, data:1x, dummy:8 + .short (0x173B) //DREAD: cmd:1x, addr:1x, data:2x, dummy:8 + //.short (0x53BB) //X2READ: cmd:1x, addr:2x, data:2x, dummy:4 + //.short (0x276B) //QREAD: cmd:1x, addr:1x, data:4x, dummy:8 + //.short (0x65EB) //X4READ: cmd:1x, addr:4x, data:4x, dummy:6 + .option pop + .align 2 + +_START: + +#if 0 + // add debug, PB4 output 1 + lui t0,0x80140 //0x8014030a + li t1, 0xef + li t2, 0x10 + sb t1 , 0x30a(t0) //0x8014030a PB oen = 0xef + sb t2 , 0x30b(t0) //0x8014030b PB output = 0x10 +#endif + /* Initialize global pointer */ + .option push + .option norelax + la gp, __global_pointer$ + .option pop + + /* Initialize stack pointer */ + la t0, _STACK_TOP + mv sp, t0 + +#ifdef __nds_execit + /* Initialize EXEC.IT table */ + la t0, _ITB_BASE_ + csrw uitb, t0 +#endif + +#ifdef __riscv_flen + /* Enable FPU */ + li t0, 0x00006000 + csrrs t0, mstatus, t0 + /* Initialize FCSR */ + fscsr zero +#endif + + /* Initial machine trap-vector Base */ + la t0, __vectors + csrw mtvec, t0 + + /* Enable vectored external plic interrupt */ + csrsi mmisc_ctl, 2 +/* +*#if (SUPPORT_PFT_ARCH) +* plic_set_feature(FLD_FEATURE_PREEMPT_PRIORITY_INT_EN | FLD_FEATURE_VECTOR_MODE_EN);//enable vectored in PLIC +* =(0xe4000000))= 0x03 +*#else +* plic_set_feature(FLD_FEATURE_VECTOR_MODE_EN);//enable vectored in PLIC +* =(0xe4000000))= 0x02 +*#endif +*/ + /*vector mode enable bit (VECTORED) of the Feature Enable Register */ + lui t0, 0xe4000 + li t1, 0x03 + sw t1, 0x0(t0) //(*(volatile unsigned long*)(0xe4000000))= 0x02 + + /* Enable I/D-Cache */ + csrr t0, mcache_ctl + ori t0, t0, 1 #/I-Cache + ori t0, t0, 2 #/D-Cache + csrw mcache_ctl, t0 + fence.i + /* Move retention reset from flash to sram */ +_RETENTION_RESET_INIT: + + la t1, _RETENTION_RESET_LMA_START + la t2, _RETENTION_RESET_VMA_START + la t3, _RETENTION_RESET_VMA_END +_RETENTION_RESET_BEGIN: + bleu t3, t2, _RETENTION_DATA_INIT + lw t0, 0(t1) + sw t0, 0(t2) + addi t1, t1, 4 + addi t2, t2, 4 + j _RETENTION_RESET_BEGIN + + /* Move retention from flash to sram */ +_RETENTION_DATA_INIT: + + la t1, _RETENTION_DATA_LMA_START + la t2, _RETENTION_DATA_VMA_START + la t3, _RETENTION_DATA_VMA_END +_RETENTION_DATA_INIT_BEGIN: + bleu t3, t2, _RAMCODE_INIT + lw t0, 0(t1) + sw t0, 0(t2) + addi t1, t1, 4 + addi t2, t2, 4 + j _RETENTION_DATA_INIT_BEGIN + + /* Move ramcode from flash to sram */ +_RAMCODE_INIT: + + la t1, _RAMCODE_LMA_START + la t2, _RAMCODE_VMA_START + la t3, _RAMCODE_VMA_END +_RAMCODE_INIT_BEGIN: + bleu t3, t2, _DATA_INIT + lw t0, 0(t1) + sw t0, 0(t2) + addi t1, t1, 4 + addi t2, t2, 4 + j _RAMCODE_INIT_BEGIN + + + /* Move Data from flash to sram */ +_DATA_INIT: + la t1, _DATA_LMA_START + la t2, _DATA_VMA_START + la t3, _DATA_VMA_END +_DATA_INIT_BEGIN: + bleu t3, t2, _ZERO_BSS + lw t0, 0(t1) + sw t0, 0(t2) + addi t1, t1, 4 + addi t2, t2, 4 + j _DATA_INIT_BEGIN + + + + /* Zero .bss section in sram */ +_ZERO_BSS: + lui t0, 0 + la t2, _BSS_VMA_START + la t3, _BSS_VMA_END +_ZERO_BSS_BEGIN: + bleu t3, t2, _ZERO_AES + sw t0, 0(t2) + addi t2, t2, 4 + j _ZERO_BSS_BEGIN + + /* Zero .aes section in sram */ +_ZERO_AES: + lui t0, 0 + la t2, _AES_VMA_START + la t3, _AES_VMA_END +_ZERO_AES_BEGIN: + bleu t3, t2, _FILL_STK + sw t0, 0(t2) + addi t2, t2, 4 + j _ZERO_AES_BEGIN + + /* Fill the remaining section in sram */ +_FILL_STK: +#if 0 + lui t0, 0x55555 + addi t0, t0, 0x555 + la t2, _BSS_VMA_END + la t3, _STACK_TOP +_FILL_STK_BEGIN: + bleu t3, t2, _MAIN_FUNC + sw t0, 0(t2) + addi t2, t2, 4 + j _FILL_STK_BEGIN +#endif + /* Jump to the main function */ +_MAIN_FUNC: + nop + + la t0, main + jalr t0 + + nop + nop + nop + nop + nop +_END: + j _END + + + .section .retention_reset, "ax" + .option push + .option norelax + .global _IRESET_ENTRY + .type _IRESET_ENTRY,@function + + .align 2 +_IRESET_ENTRY: + /* Decide whether this is an NMI or cold reset */ + j _ISTART + + .org 0x22 +_ISTART: + + +/* GPIO_DEBUG */ +#if 0 + // add debug, PE1 output 1 + lui t0, 0x80140 //0x80140322 + li t1, 0xfd + li t2, 0x02 + sb t1 , 0x322(t0) //0x8014030a Pe oen = 0xfd + sb t2 , 0x323(t0) //0x8014030b Pe output = 0x02 +#endif +#if 0 + // add debug, PD0 output 1 + lui t0,0x80140 //0x8014031a + li t1, 0xfe + li t2, 0x01 + sb t1 , 0x31a(t0) //0x8014031a PD oen = 0xfe + sb t2 , 0x31b(t0) //0x8014031b PD output = 0x01 +#endif + + /* Initialize global pointer */ + + la gp, __global_pointer$ + .option pop + + /* Initialize stack pointer */ + la t0, _STACK_TOP + mv sp, t0 + +#ifdef __nds_execit + /* Initialize EXEC.IT table */ + la t0, _ITB_BASE_ + csrw uitb, t0 +#endif + +#ifdef __riscv_flen + /* Enable FPU */ + li t0, 0x00006000 + csrrs t0, mstatus, t0 + /* Initialize FCSR */ + fscsr zero +#endif + + /* Initial machine trap-vector Base */ + la t0, __vectors + csrw mtvec, t0 + + /* Enable vectored external plic interrupt */ + csrsi mmisc_ctl, 2 + +/* +*#if (SUPPORT_PFT_ARCH) +* plic_set_feature(FLD_FEATURE_PREEMPT_PRIORITY_INT_EN | FLD_FEATURE_VECTOR_MODE_EN);//enable vectored in PLIC +* =(0xe4000000))= 0x03 +*#else +* plic_set_feature(FLD_FEATURE_VECTOR_MODE_EN);//enable vectored in PLIC +* =(0xe4000000))= 0x02 +*#endif +*/ + /*vector mode enable bit (VECTORED) of the Feature Enable Register */ + lui t0, 0xe4000 + li t1, 0x03 + sw t1, 0x0(t0) //(*(volatile unsigned long*)(0xe4000000))= 0x03 + + /* Enable I/D-Cache */ + csrr t0, mcache_ctl + ori t0, t0, 1 #/I-Cache + ori t0, t0, 2 #/D-Cache + csrw mcache_ctl, t0 + fence.i + + +/* flash wakeup */ +_WAKEUP_FLASH: + lui t0 , 0x80140 + li t1 , 0xff + li t2 , 0x0 + li t3 , 0xab + sb t1 , 0x329(t0) //mspi ie enable :0x140329:0x1f + sb t2 , 0x101(t0) //cs_low :0x140101:0x00 + sb t3 , 0x100(t0) //wakeup_cmd :0x140100:0xab +_MSPI_WAIT: + lui t0 , 0x80140 + lb t2 , 0x102(t0) //read reg_mspi_status FLD_MSPI_BUSY(bit0) + li t3 , 0x1 + li t4 , 0x10 + beq t3 , t2 ,_MSPI_WAIT + sb t4 , 0x101(t0) //cs_high :0x140101:0x10 +#if 0 + // add debug, PB4 output 1 + lui t0,0x80140 //0x8014030a + li t1, 0x00 + sb t1 , 0x30b(t0) //0x8014030b PB output = 0x00 +#endif +/*efuse load need delay about 18us */ + li t0 , 0 + li t1 , 226 +_WAIT_EFUSE_LOAD_FINISH: + addi t0 , t0 , 1 + bgeu t1 , t0 , _WAIT_EFUSE_LOAD_FINISH + +#if 0 + // add debug, PB4 output 1 + lui t0,0x80140 //0x8014030a + li t1, 0x10 + sb t1 , 0x30b(t0) //0x8014030b PB output = 0x00 +#endif + + +_MULTI_ADDRESS_BEGIN: + lui t0 , 0x80140 + la t1 , g_pm_multi_addr + lw t2 , 0(t1) + sw t2 , 0x104(t0) //g_pm_multi_addr->0x80140104 + + +#if 0 + /* Move ramcode from flash to sram */ +_IRAMCODE_INIT: + + la t1, _RAMCODE_LMA_START + la t2, _RAMCODE_VMA_START + la t3, _RAMCODE_VMA_END +_IRAMCODE_INIT_BEGIN: + bleu t3, t2, _IDATA_INIT + lw t0, 0(t1) + sw t0, 0(t2) + addi t1, t1, 4 + addi t2, t2, 4 + j _IRAMCODE_INIT_BEGIN +#endif + + /* Move Data from flash to sram */ +_IDATA_INIT: + la t1, _DATA_LMA_START + la t2, _DATA_VMA_START + la t3, _DATA_VMA_END +_IDATA_INIT_BEGIN: + bleu t3, t2, _IZERO_BSS + lw t0, 0(t1) + sw t0, 0(t2) + addi t1, t1, 4 + addi t2, t2, 4 + j _IDATA_INIT_BEGIN + + + + /* Zero .bss section in sram */ +_IZERO_BSS: + lui t0, 0 + la t2, _BSS_VMA_START + la t3, _BSS_VMA_END +_IZERO_BSS_BEGIN: + bleu t3, t2, _IZERO_AES + sw t0, 0(t2) + addi t2, t2, 4 + j _IZERO_BSS_BEGIN + + /* Zero .aes section in sram */ +_IZERO_AES: + lui t0, 0 + la t2, _AES_VMA_START + la t3, _AES_VMA_END +_IZERO_AES_BEGIN: + bleu t3, t2, _IFILL_STK + sw t0, 0(t2) + addi t2, t2, 4 + j _IZERO_AES_BEGIN + + + /* Fill the remaining section in sram */ +_IFILL_STK: +#if 0 + lui t0, 0x55555 + addi t0, t0, 0x555 + la t2, _BSS_VMA_END + la t3, _STACK_TOP +_IFILL_STK_BEGIN: + bleu t3, t2, _IMAIN_FUNC + sw t0, 0(t2) + addi t2, t2, 4 + j _IFILL_STK_BEGIN +#endif + /* Jump to the main function */ +_IMAIN_FUNC: + nop + + la t0, main + jalr t0 + + nop + nop + nop + nop + nop +_IEND: + j _IEND + + +.text + .global default_irq_entry + .align 2 + +default_irq_entry: +1: j 1b + + .weak trap_handler + + trap_handler: +1: j 1b + + .macro INTERRUPT num + .weak entry_irq\num + .set entry_irq\num, default_irq_entry + .long entry_irq\num + .endm + +#define VECTOR_NUMINTRS 63 + + .section .ram_code, "ax" + + .global __vectors + .balign 256 + + +__vectors: + /* Trap vector */ + .long trap_entry + + /* PLIC interrupt vector */ + .altmacro + .set irqno, 1 + .rept VECTOR_NUMINTRS/* .rept .endr */ + INTERRUPT %irqno + .set irqno, irqno+1 + .endr +#endif diff --git a/b91/b91m_ble_sdk/boot/B91/cstartup_B91_DLM.S b/b91/b91m_ble_sdk/boot/B91/cstartup_B91_DLM.S new file mode 100755 index 0000000..4028351 --- /dev/null +++ b/b91/b91m_ble_sdk/boot/B91/cstartup_B91_DLM.S @@ -0,0 +1,485 @@ +/******************************************************************************************************** + * @file cstartup_B91_DLM.S + * + * @brief This is the boot file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#if 0 /*default is close*/ + .section .vectors, "ax" + + //.org and linker's relaxation (-flto) cannot be used at the same time + //Pop corresponds to push. Before using .option norelax, use push to save the current .option configuration + //and then modify .option. After using norelax, use pop to restore + .option push + .option norelax + .org 0x0 + + + .global _RESET_ENTRY + .type _RESET_ENTRY,@function + + .align 2 +_RESET_ENTRY: + j _START + //free the 6th ~ 7th byte to store the crc type of the bin file + .org 0x18 + .word (BIN_SIZE) + + .org 0x20 + .word ('T'<<24 | 'L'<<16 | 'N'<<8 | 'K') + + .org 0x26 + //.short (0x0003) //READ: cmd:1x, addr:1x, data:1x, dummy:0 + //.short (0x070B) //FREAD: cmd:1x, addr:1x, data:1x, dummy:8 + .short (0x173B) //DREAD: cmd:1x, addr:1x, data:2x, dummy:8 + //.short (0x53BB) //X2READ: cmd:1x, addr:2x, data:2x, dummy:4 + //.short (0x276B) //QREAD: cmd:1x, addr:1x, data:4x, dummy:8 + //.short (0x65EB) //X4READ: cmd:1x, addr:4x, data:4x, dummy:6 + .option pop + .align 2 + +_START: + +#if 0 + // add debug, PB4 output 1 + lui t0,0x80140 //0x8014030a + li t1, 0xef + li t2, 0x10 + sb t1 , 0x30a(t0) //0x8014030a PB oen = 0xef + sb t2 , 0x30b(t0) //0x8014030b PB output = 0x10 +#endif + /* Initialize global pointer */ + .option push + .option norelax + la gp, __global_pointer$ + .option pop + + /* Initialize stack pointer */ + la t0, _STACK_TOP + mv sp, t0 + +#ifdef __nds_execit + /* Initialize EXEC.IT table */ + la t0, _ITB_BASE_ + csrw uitb, t0 +#endif + +#ifdef __riscv_flen + /* Enable FPU */ + li t0, 0x00006000 + csrrs t0, mstatus, t0 + /* Initialize FCSR */ + fscsr zero +#endif + + /* Initial machine trap-vector Base */ + la t0, __vectors + csrw mtvec, t0 + + /* Enable vectored external plic interrupt */ + csrsi mmisc_ctl, 2 +/* +*#if (SUPPORT_PFT_ARCH) +* plic_set_feature(FLD_FEATURE_PREEMPT_PRIORITY_INT_EN | FLD_FEATURE_VECTOR_MODE_EN);//enable vectored in PLIC +* =(0xe4000000))= 0x03 +*#else +* plic_set_feature(FLD_FEATURE_VECTOR_MODE_EN);//enable vectored in PLIC +* =(0xe4000000))= 0x02 +*#endif +*/ + /*vector mode enable bit (VECTORED) of the Feature Enable Register */ + lui t0, 0xe4000 + li t1, 0x03 + sw t1, 0x0(t0) //(*(volatile unsigned long*)(0xe4000000))= 0x02 + + /* Enable I/D-Cache */ + csrr t0, mcache_ctl + ori t0, t0, 1 #/I-Cache + ori t0, t0, 2 #/D-Cache + csrw mcache_ctl, t0 + fence.i + /* Move retention reset from flash to sram */ +_RETENTION_RESET_INIT: + + la t1, _RETENTION_RESET_LMA_START + la t2, _RETENTION_RESET_VMA_START + la t3, _RETENTION_RESET_VMA_END +_RETENTION_RESET_BEGIN: + bleu t3, t2, _RETENTION_DATA_INIT + lw t0, 0(t1) + sw t0, 0(t2) + addi t1, t1, 4 + addi t2, t2, 4 + j _RETENTION_RESET_BEGIN + + /* Move retention from flash to sram */ +_RETENTION_DATA_INIT: + + la t1, _RETENTION_DATA_LMA_START + la t2, _RETENTION_DATA_VMA_START + la t3, _RETENTION_DATA_VMA_END +_RETENTION_DATA_INIT_BEGIN: + bleu t3, t2, _RAMCODE_INIT + lw t0, 0(t1) + sw t0, 0(t2) + addi t1, t1, 4 + addi t2, t2, 4 + j _RETENTION_DATA_INIT_BEGIN + + /* Move ramcode from flash to sram */ +_RAMCODE_INIT: + + la t1, _RAMCODE_LMA_START + la t2, _RAMCODE_VMA_START + la t3, _RAMCODE_VMA_END +_RAMCODE_INIT_BEGIN: + bleu t3, t2, _DATA_INIT + lw t0, 0(t1) + sw t0, 0(t2) + addi t1, t1, 4 + addi t2, t2, 4 + j _RAMCODE_INIT_BEGIN + + /* Move DLM_Data from flash to sram */ +_DLM_DATA_INIT: + la t1, _DLM_DATA_LMA_START + la t2, _DLM_DATA_VMA_START + la t3, _DLM_DATA_VMA_END +_DLM_DATA_INIT_BEGIN: + bleu t3, t2, _DATA_INIT + lw t0, 0(t1) + sw t0, 0(t2) + addi t1, t1, 4 + addi t2, t2, 4 + j _DLM_DATA_INIT_BEGIN + + /* Move Data from flash to sram */ +_DATA_INIT: + la t1, _DATA_LMA_START + la t2, _DATA_VMA_START + la t3, _DATA_VMA_END +_DATA_INIT_BEGIN: + bleu t3, t2, _ZERO_BSS + lw t0, 0(t1) + sw t0, 0(t2) + addi t1, t1, 4 + addi t2, t2, 4 + j _DATA_INIT_BEGIN + + + + /* Zero .bss section in sram */ +_ZERO_BSS: + lui t0, 0 + la t2, _BSS_VMA_START + la t3, _BSS_VMA_END +_ZERO_BSS_BEGIN: + bleu t3, t2, _ZERO_AES + sw t0, 0(t2) + addi t2, t2, 4 + j _ZERO_BSS_BEGIN + + /* Zero .aes section in sram */ +_ZERO_AES: + lui t0, 0 + la t2, _AES_VMA_START + la t3, _AES_VMA_END +_ZERO_AES_BEGIN: + bleu t3, t2, _FILL_STK + sw t0, 0(t2) + addi t2, t2, 4 + j _ZERO_AES_BEGIN + + /* Fill the remaining section in sram */ +_FILL_STK: +#if 0 + lui t0, 0x55555 + addi t0, t0, 0x555 + la t2, _BSS_VMA_END + la t3, _STACK_TOP +_FILL_STK_BEGIN: + bleu t3, t2, _MAIN_FUNC + sw t0, 0(t2) + addi t2, t2, 4 + j _FILL_STK_BEGIN +#endif + /* Jump to the main function */ +_MAIN_FUNC: + nop + + la t0, main + jalr t0 + + nop + nop + nop + nop + nop +_END: + j _END + + + .section .retention_reset, "ax" + .option push + .option norelax + .global _IRESET_ENTRY + .type _IRESET_ENTRY,@function + + .align 2 +_IRESET_ENTRY: + /* Decide whether this is an NMI or cold reset */ + j _ISTART + + .org 0x22 +_ISTART: +#if 0 + // add debug, PB4 output 1 + lui t0,0x80140 //0x8014030a + li t1, 0xef + li t2, 0x10 + sb t1 , 0x30a(t0) //0x8014030a PB oen = 0xef + sb t2 , 0x30b(t0) //0x8014030b PB output = 0x10 +#endif + /* Initialize global pointer */ + + la gp, __global_pointer$ + .option pop + + /* Initialize stack pointer */ + la t0, _STACK_TOP + mv sp, t0 + +#ifdef __nds_execit + /* Initialize EXEC.IT table */ + la t0, _ITB_BASE_ + csrw uitb, t0 +#endif + +#ifdef __riscv_flen + /* Enable FPU */ + li t0, 0x00006000 + csrrs t0, mstatus, t0 + /* Initialize FCSR */ + fscsr zero +#endif + + /* Initial machine trap-vector Base */ + la t0, __vectors + csrw mtvec, t0 + + /* Enable vectored external plic interrupt */ + csrsi mmisc_ctl, 2 + +/* +*#if (SUPPORT_PFT_ARCH) +* plic_set_feature(FLD_FEATURE_PREEMPT_PRIORITY_INT_EN | FLD_FEATURE_VECTOR_MODE_EN);//enable vectored in PLIC +* =(0xe4000000))= 0x03 +*#else +* plic_set_feature(FLD_FEATURE_VECTOR_MODE_EN);//enable vectored in PLIC +* =(0xe4000000))= 0x02 +*#endif +*/ + /*vector mode enable bit (VECTORED) of the Feature Enable Register */ + lui t0, 0xe4000 + li t1, 0x03 + sw t1, 0x0(t0) //(*(volatile unsigned long*)(0xe4000000))= 0x03 + + /* Enable I/D-Cache */ + csrr t0, mcache_ctl + ori t0, t0, 1 #/I-Cache + ori t0, t0, 2 #/D-Cache + csrw mcache_ctl, t0 + fence.i + + +/* flash wakeup */ +_WAKEUP_FLASH: + lui t0 , 0x80140 + li t1 , 0xff + li t2 , 0x0 + li t3 , 0xab + sb t1 , 0x329(t0) //mspi ie enable :0x140329:0x1f + sb t2 , 0x101(t0) //cs_low :0x140101:0x00 + sb t3 , 0x100(t0) //wakeup_cmd :0x140100:0xab +_MSPI_WAIT: + lui t0 , 0x80140 + lb t2 , 0x102(t0) //read reg_mspi_status FLD_MSPI_BUSY(bit0) + li t3 , 0x1 + li t4 , 0x10 + beq t3 , t2 ,_MSPI_WAIT + sb t4 , 0x101(t0) //cs_high :0x140101:0x10 +#if 0 + // add debug, PB4 output 1 + lui t0,0x80140 //0x8014030a + li t1, 0x00 + sb t1 , 0x30b(t0) //0x8014030b PB output = 0x00 +#endif +/*efuse load need delay about 18us */ + li t0 , 0 + li t1 , 226 +_WAIT_EFUSE_LOAD_FINISH: + addi t0 , t0 , 1 + bgeu t1 , t0 , _WAIT_EFUSE_LOAD_FINISH + +#if 0 + // add debug, PB4 output 1 + lui t0,0x80140 //0x8014030a + li t1, 0x10 + sb t1 , 0x30b(t0) //0x8014030b PB output = 0x00 +#endif +_MULTI_ADDRESS_BEGIN: + lui t0 , 0x80140 + la t1 , tl_multi_addr + lw t2 , 0(t1) + sw t2 , 0x104(t0) //g_pm_multi_addr->0x80140104 + +#if 0 + /* Move ramcode from flash to sram */ +_IRAMCODE_INIT: + + la t1, _RAMCODE_LMA_START + la t2, _RAMCODE_VMA_START + la t3, _RAMCODE_VMA_END +_IRAMCODE_INIT_BEGIN: + bleu t3, t2, _IDATA_INIT + lw t0, 0(t1) + sw t0, 0(t2) + addi t1, t1, 4 + addi t2, t2, 4 + j _IRAMCODE_INIT_BEGIN +#endif + + /* Move DLM_Data from flash to sram */ +_IDLM_DATA_INIT: + la t1, _DLM_DATA_LMA_START + la t2, _DLM_DATA_VMA_START + la t3, _DLM_DATA_VMA_END +_IDLM_DATA_INIT_BEGIN: + bleu t3, t2, _IDATA_INIT + lw t0, 0(t1) + sw t0, 0(t2) + addi t1, t1, 4 + addi t2, t2, 4 + j _IDLM_DATA_INIT_BEGIN + + /* Move Data from flash to sram */ +_IDATA_INIT: + la t1, _DATA_LMA_START + la t2, _DATA_VMA_START + la t3, _DATA_VMA_END +_IDATA_INIT_BEGIN: + bleu t3, t2, _IZERO_BSS + lw t0, 0(t1) + sw t0, 0(t2) + addi t1, t1, 4 + addi t2, t2, 4 + j _IDATA_INIT_BEGIN + + + + /* Zero .bss section in sram */ +_IZERO_BSS: + lui t0, 0 + la t2, _BSS_VMA_START + la t3, _BSS_VMA_END +_IZERO_BSS_BEGIN: + bleu t3, t2, _IZERO_AES + sw t0, 0(t2) + addi t2, t2, 4 + j _IZERO_BSS_BEGIN + + /* Zero .aes section in sram */ +_IZERO_AES: + lui t0, 0 + la t2, _AES_VMA_START + la t3, _AES_VMA_END +_IZERO_AES_BEGIN: + bleu t3, t2, _IFILL_STK + sw t0, 0(t2) + addi t2, t2, 4 + j _IZERO_AES_BEGIN + + + /* Fill the remaining section in sram */ +_IFILL_STK: +#if 0 + lui t0, 0x55555 + addi t0, t0, 0x555 + la t2, _BSS_VMA_END + la t3, _STACK_TOP +_IFILL_STK_BEGIN: + bleu t3, t2, _IMAIN_FUNC + sw t0, 0(t2) + addi t2, t2, 4 + j _IFILL_STK_BEGIN +#endif + /* Jump to the main function */ +_IMAIN_FUNC: + nop + + la t0, main + jalr t0 + + nop + nop + nop + nop + nop +_IEND: + j _IEND + + +.text + .global default_irq_entry + .align 2 + +default_irq_entry: +1: j 1b + + .weak trap_handler + + trap_handler: +1: j 1b + + .macro INTERRUPT num + .weak entry_irq\num + .set entry_irq\num, default_irq_entry + .long entry_irq\num + .endm + +#define VECTOR_NUMINTRS 63 + + .section .ram_code, "ax" + + .global __vectors + .balign 256 + + +__vectors: + /* Trap vector */ + .long trap_entry + + /* PLIC interrupt vector */ + .altmacro + .set irqno, 1 + .rept VECTOR_NUMINTRS/* .rept .endr */ + INTERRUPT %irqno + .set irqno, irqno+1 + .endr +#endif diff --git a/b91/b91m_ble_sdk/common/assert.h b/b91/b91m_ble_sdk/common/assert.h new file mode 100755 index 0000000..aded3a7 --- /dev/null +++ b/b91/b91m_ble_sdk/common/assert.h @@ -0,0 +1,81 @@ +/******************************************************************************************************** + * @file assert.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "config/user_config.h" // for __DEBUG__ + +/////////////////////////////////////////////////////////////////////////////////// +#if (__DEBUG__) + +#define assert(expression) \ + do{if(!(expression)) __assert (expression, __FILE__, __LINE__)}while(0) + +#define __assert(expression, file, lineno) {printf ("%s:%u: assertion failed!\n", file, lineno);} + +#else +#define assert(ignore) ((void) 0) +#endif + +//////////////////// To do compiler warning ////////////////// +// http://stackoverflow.com/questions/5966594/how-can-i-use-pragma-message-so-that-the-message-points-to-the-filelineno +// http://gcc.gnu.org/ml/gcc-help/2010-10/msg00196.html +// http://stackoverflow.com/questions/3030099/c-c-pragma-in-define-macro + +#define _STRINGIFY(x) #x +#define STRINGIFY(x) _STRINGIFY(x) + +#ifdef __GNUC__ +#define COMPILE_MESSAGE(x) _Pragma (#x) +#endif + +#if (__SHOW_TODO__) +#ifdef __GNUC__ +#define TODO(x) COMPILE_MESSAGE(message ("--TODO-- " #x)) +#else +#define TODO(x) __pragma(message("--TODO-- "_STRINGIFY(x) " ::function: " __FUNCTION__ "@"STRINGIFY(__LINE__))) +#endif +#else +#define TODO(x) +#endif + +#if (__SHOW_WARN__) +#ifdef __GNUC__ +#define WARN(x) COMPILE_MESSAGE(message ("--WARN-- " #x)) +#else +#define WARN(x) __pragma(message("--WARN-- "_STRINGIFY(x) " ::function: " __FUNCTION__ "@"STRINGIFY(__LINE__))) +#endif +#else +#define WARN(x) +#endif + +#if (__SHOW_WARN__) +#ifdef __GNUC__ +#define NOTE(x) COMPILE_MESSAGE(message ("--NOTE-- " #x)) +#else +#define NOTE(x) __pragma(message("--NOTE-- "_STRINGIFY(x) " ::function: " __FUNCTION__ "@"STRINGIFY(__LINE__))) +#endif +#else +#define NOTE(x) +#endif + + diff --git a/b91/b91m_ble_sdk/common/bit.h b/b91/b91m_ble_sdk/common/bit.h new file mode 100755 index 0000000..02c7e2d --- /dev/null +++ b/b91/b91m_ble_sdk/common/bit.h @@ -0,0 +1,241 @@ +/******************************************************************************************************** + * @file bit.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + + +#include "macro_trick.h" + +#define BIT(n) ( 1<<(n) ) + +// BITSx are internal used macro, please use BITS instead +#define BITS1(a) BIT(a) +#define BITS2(a, b) (BIT(a) | BIT(b)) +#define BITS3(a, b, c) (BIT(a) | BIT(b) | BIT(c)) +#define BITS4(a, b, c, d) (BIT(a) | BIT(b) | BIT(c) | BIT(d)) +#define BITS5(a, b, c, d, e) (BIT(a) | BIT(b) | BIT(c) | BIT(d) | BIT(e)) +#define BITS6(a, b, c, d, e, f) (BIT(a) | BIT(b) | BIT(c) | BIT(d) | BIT(e) | BIT(f)) +#define BITS7(a, b, c, d, e, f, g) (BIT(a) | BIT(b) | BIT(c) | BIT(d) | BIT(e) | BIT(f) | BIT(g)) +#define BITS8(a, b, c, d, e, f, g, h) (BIT(a) | BIT(b) | BIT(c) | BIT(d) | BIT(e) | BIT(f) | BIT(g) | BIT(h)) + +#define BITS(...) VARARG(BITS, __VA_ARGS__) + + +// bits range: BITS_RNG(4, 5) 0b000111110000, start from 4, length = 5 +#define BIT_RNG(s, e) (BIT_MASK_LEN((e)-(s)+1) << (s)) + +#define BM_MASK_V(x, mask) ( (x) | (mask) ) +#define BM_CLR_MASK_V(x, mask) ( (x) & ~(mask) ) + +#define BM_SET(x, mask) ( (x) |= (mask) ) +#define BM_CLR(x, mask) ( (x) &= ~(mask) ) +#define BM_IS_SET(x, mask) ( (x) & (mask) ) +#define BM_IS_CLR(x, mask) ( (~x) & (mask) ) +#define BM_FLIP(x, mask) ( (x) ^= (mask) ) + +// !!!! v is already a masked value, no need to shift +#define BM_MASK_VAL(x, mask, v) ( ((x) & ~(mask)) | (v)) +#define BM_SET_MASK_VAL(x, mask, v) ( (x) = BM_MASK_VAL(x, mask, v) ) + + +#define BIT_SET(x, n) ((x) |= BIT(n)) +#define BIT_CLR(x, n) ((x) &= ~ BIT(n)) +#define BIT_IS_SET(x, n) ((x) & BIT(n)) +#define BIT_FLIP(x, n) ((x) ^= BIT(n)) +#define BIT_SET_HIGH(x) ((x) |= BIT((sizeof((x))*8-1))) // set the highest bit +#define BIT_CLR_HIGH(x) ((x) &= ~ BIT((sizeof((x))*8-1))) // clr the highest bit +#define BIT_IS_SET_HIGH(x) ((x) & BIT((sizeof((x))*8-1))) // check the higest bit + +#define BIT_MASK_LEN(len) (BIT(len)-1) +#define BIT_MASK(start, len) (BIT_MASK_LEN(len) << (start) ) + +//! Prepare a bitmask for insertion or combining. +#define BIT_PREP(x, start, len) ((x) & BIT_MASK(start, len)) + +//! Extract a bitfield of length \a len starting at bit \a start from \a y. +#define BIT_GET(x, start, len) (((x) >> (start)) & BIT_MASK_LEN(len)) +#define BIT_GET_LOW(x, len) ((x) & BIT_MASK_LEN(len)) + +//! Insert a new bitfield value \a x into \a y. +#define BIT_MERGE(y, x, start, len) \ + ( y = ((y) &~ BIT_MASK(start, len)) | BIT_PREP(x, start, len) ) + +#define BIT_IS_EVEN(x) (((x)&1)==0) +#define BIT_IS_ODD(x) (!BIT_IS_EVEN((x))) +#define BIT_IS_POW2(x) (!((x) & ((x)-1))) +#define BIT_TURNOFF_1(x) ((x) &= ((x)-1)) +#define BIT_ISOLATE_1(x) ((x) &= (-(x))) +#define BIT_PROPAGATE_1(x) ((x) |= ((x)-1)) +#define BIT_ISOLATE_0(x) ((x) = ~(x) & ((x)+1)) +#define BIT_TURNON_0(x) ((x) |= ((x)+1)) +#define CLAMP_TO_ONE(x) (!!(x)) // compiler defined, not stardard. 0 --> 0, 1 --> 0xffffffff + +#define ONES(x) BIT_MASK_LEN(x) +#define ONES_32 0xffffffff +#define ALL_SET 0xffffffff + + + +// Return the bit index of the lowest 1 in y. ex: 0b00110111000 --> 3 +#define BIT_LOW_BIT(y) (((y) & BIT(0))?0:(((y) & BIT(1))?1:(((y) & BIT(2))?2:(((y) & BIT(3))?3: \ + (((y) & BIT(4))?4:(((y) & BIT(5))?5:(((y) & BIT(6))?6:(((y) & BIT(7))?7: \ + (((y) & BIT(8))?8:(((y) & BIT(9))?9:(((y) & BIT(10))?10:(((y) & BIT(11))?11: \ + (((y) & BIT(12))?12:(((y) & BIT(13))?13:(((y) & BIT(14))?14:(((y) & BIT(15))?15: \ + (((y) & BIT(16))?16:(((y) & BIT(17))?17:(((y) & BIT(18))?18:(((y) & BIT(19))?19: \ + (((y) & BIT(20))?20:(((y) & BIT(21))?21:(((y) & BIT(22))?22:(((y) & BIT(23))?23: \ + (((y) & BIT(24))?24:(((y) & BIT(25))?25:(((y) & BIT(26))?26:(((y) & BIT(27))?27: \ + (((y) & BIT(28))?28:(((y) & BIT(29))?29:(((y) & BIT(30))?30:(((y) & BIT(31))?31:32 \ + )))))))))))))))))))))))))))))))) + +// Return the bit index of the highest 1 in (y). ex: 0b00110111000 --> 8 +#define BIT_HIGH_BIT(y) (((y) & BIT(31))?31:(((y) & BIT(30))?30:(((y) & BIT(29))?29:(((y) & BIT(28))?28: \ + (((y) & BIT(27))?27:(((y) & BIT(26))?26:(((y) & BIT(25))?25:(((y) & BIT(24))?24: \ + (((y) & BIT(23))?23:(((y) & BIT(22))?22:(((y) & BIT(21))?21:(((y) & BIT(20))?20: \ + (((y) & BIT(19))?19:(((y) & BIT(18))?18:(((y) & BIT(17))?17:(((y) & BIT(16))?16: \ + (((y) & BIT(15))?15:(((y) & BIT(14))?14:(((y) & BIT(13))?13:(((y) & BIT(12))?12: \ + (((y) & BIT(11))?11:(((y) & BIT(10))?10:(((y) & BIT(9))?9:(((y) & BIT(8))?8: \ + (((y) & BIT(7))?7:(((y) & BIT(6))?6:(((y) & BIT(5))?5:(((y) & BIT(4))?4: \ + (((y) & BIT(3))?3:(((y) & BIT(2))?2:(((y) & BIT(1))?1:(((y) & BIT(0))?0:32 \ + )))))))))))))))))))))))))))))))) + +#define BM_MASK_FLD(x, mask) (((x) & (mask)) >> BIT_LOW_BIT(mask)) +#define BM_SET_MASK_FLD(x, mask, v) ( (x) = BM_MASK_VAL(x,mask,v) ) + +////////////////////// +#define MV(m, v) (((v) << BIT_LOW_BIT(m)) & (m)) + +// warning MASK_VALn are internal used macro, please use MASK_VAL instead +#define MASK_VAL2(m, v) (MV(m,v)) +#define MASK_VAL4(m1,v1,m2,v2) (MV(m1,v1)|MV(m2,v2)) +#define MASK_VAL6(m1,v1,m2,v2,m3,v3) (MV(m1,v1)|MV(m2,v2)|MV(m3,v3)) +#define MASK_VAL8(m1,v1,m2,v2,m3,v3,m4,v4) (MV(m1,v1)|MV(m2,v2)|MV(m3,v3)|MV(m4,v4)) +#define MASK_VAL10(m1,v1,m2,v2,m3,v3,m4,v4,m5,v5) (MV(m1,v1)|MV(m2,v2)|MV(m3,v3)|MV(m4,v4)|MV(m5,v5)) +#define MASK_VAL12(m1,v1,m2,v2,m3,v3,m4,v4,m5,v5,m6,v6) (MV(m1,v1)|MV(m2,v2)|MV(m3,v3)|MV(m4,v4)|MV(m5,v5)|MV(m6,v6)) +#define MASK_VAL14(m1,v1,m2,v2,m3,v3,m4,v4,m5,v5,m6,v6,m7,v7) (MV(m1,v1)|MV(m2,v2)|MV(m3,v3)|MV(m4,v4)|MV(m5,v5)|MV(m6,v6)|MV(m7,v7)) +#define MASK_VAL16(m1,v1,m2,v2,m3,v3,m4,v4,m5,v5,m6,v6,m7,v7,m8,v8) (MV(m1,v1)|MV(m2,v2)|MV(m3,v3)|MV(m4,v4)|MV(m5,v5)|MV(m6,v6)|MV(m7,v7)|MV(m8,v8)) + +#define MASK_VAL(...) VARARG(MASK_VAL, __VA_ARGS__) + +#define FLD_MASK_VAL(x, mask, v) BM_MASK_VAL(x, mask, MV(mask,v)) + +#define SET_FLD(x, mask) BM_SET(x, mask) +#define CLR_FLD(x, mask) BM_CLR(x, mask) +#define FLIP_FLD(x, mask) BM_FLIP(x, mask) + +#define GET_FLD(x, mask) BM_MASK_FLD(x, mask) + +#define SET_FLD_V(...) VARARG(SET_FLD_V, __VA_ARGS__) + + + +#define SET_FLD_FULL_V3(x, m, v) ((x) = MASK_VAL2(m,v)) +#define SET_FLD_FULL_V5(x, m1, v1, m2, v2) ((x) = MASK_VAL4(m1,v1,m2,v2)) +#define SET_FLD_FULL_V7(x, m1, v1, m2, v2, m3, v3) ((x) = MASK_VAL6(m1,v1,m2,v2,m3,v3)) +#define SET_FLD_FULL_V9(x, m1, v1, m2, v2, m3, v3, m4, v4) ((x) = MASK_VAL8(m1,v1,m2,v2,m3,v3,m4,v4)) +#define SET_FLD_FULL_V11(x, m1, v1, m2, v2, m3, v3, m4, v4, m5, v5) ((x) = MASK_VAL10(m1,v1,m2,v2,m3,v3,m4,v4,m5,v5)) +#define SET_FLD_FULL_V13(x, m1, v1, m2, v2, m3, v3, m4, v4, m5, v5, m6, v6) ((x) = MASK_VAL12(m1,v1,m2,v2,m3,v3,m4,v4,m5,v5,m6,v6)) +#define SET_FLD_FULL_V(...) VARARG(SET_FLD_FULL_V, __VA_ARGS__) + +//////////////////////////////////////////////////////////////////////// +#define BIT8_IFY(y) ( \ + ((y&0x0000000FLU)?1:0) + ((y&0x000000F0LU)? 2:0) + ((y&0x00000F00LU)? 4:0) + \ + ((y&0x0000F000LU)?8:0) + ((y&0x000F0000LU)?16:0) + ((y&0x00F00000LU)?32:0) + \ + ((y&0x0F000000LU)?64:0) + ((y&0xF0000000LU)?128:0) \ + ) + +#define HEX_X(i) (0x##i##LU) + +#define BIT_8(j) ((unsigned char)BIT8_IFY(HEX_X(j))) + +#ifndef WIN32 + // warning SET_FLD_Vn are internal used macro, please use SET_FLD_V instead + #define SET_FLD_V3(x, m, v) \ + BM_SET_MASK_FLD(x,m,MV(m,v)) + + #define SET_FLD_V5(x, m1, v1, m2, v2) \ + BM_SET_MASK_FLD(x, m1|m2, MV(m1,v1)| MV(m2,v2)) + + #define SET_FLD_V7(x, m1, v1, m2, v2, m3, v3) \ + BM_SET_MASK_FLD(x, m1|m2|m3, MV(m1,v1)| MV(m2,v2)| MV(m3,v3)) + + #define SET_FLD_V9(x, m1, v1, m2, v2, m3, v3, m4, v4) \ + BM_SET_MASK_FLD(x, m1|m2|m3|m4, MV(m1,v1)| MV(m2,v2)| MV(m3,v3)| MV(m4,v4)) + + #define SET_FLD_V11(x, m1, v1, m2, v2, m3, v3, m4, v4, m5, v5) \ + BM_SET_MASK_FLD(x, m1|m2|m3|m4|m5, MV(m1,v1)| MV(m2,v2)| MV(m3,v3)| MV(m4,v4)| MV(m5,v5)) + + #define SET_FLD_V13(x, m1, v1, m2, v2, m3, v3, m4, v4, m5, v5, m6, v6) \ + BM_SET_MASK_FLD(x, m1|m2|m3|m4|m5|m6, MV(m1,v1)| MV(m2,v2)| MV(m3,v3)| MV(m4,v4)| MV(m5,v5)| MV(m6,v6)) +#else + #define SET_FLD_V3(x, m, v) \ + __pragma(warning(push)) \ + __pragma(warning(disable:4244)) \ + BM_SET_MASK_FLD(x,m,MV(m,v)) \ + __pragma(warning(pop)) + + #define SET_FLD_V5(x, m1, v1, m2, v2) \ + __pragma(warning(push)) \ + __pragma(warning(disable:4244)) \ + BM_SET_MASK_FLD(x, m1|m2, MV(m1,v1)| MV(m2,v2)) \ + __pragma(warning(pop)) + + #define SET_FLD_V7(x, m1, v1, m2, v2, m3, v3) \ + __pragma(warning(push)) \ + __pragma(warning(disable:4244)) \ + BM_SET_MASK_FLD(x, m1|m2|m3, MV(m1,v1)| MV(m2,v2)| MV(m3,v3)) \ + __pragma(warning(pop)) + + #define SET_FLD_V9(x, m1, v1, m2, v2, m3, v3, m4, v4) \ + __pragma(warning(push)) \ + __pragma(warning(disable:4244)) \ + BM_SET_MASK_FLD(x, m1|m2|m3|m4, MV(m1,v1)| MV(m2,v2)| MV(m3,v3)| MV(m4,v4)) \ + __pragma(warning(pop)) + + #define SET_FLD_V11(x, m1, v1, m2, v2, m3, v3, m4, v4, m5, v5) \ + __pragma(warning(push)) \ + __pragma(warning(disable:4244)) \ + BM_SET_MASK_FLD(x, m1|m2|m3|m4|m5, MV(m1,v1)| MV(m2,v2)| MV(m3,v3)| MV(m4,v4)| MV(m5,v5)) \ + __pragma(warning(pop)) + + #define SET_FLD_V13(x, m1, v1, m2, v2, m3, v3, m4, v4, m5, v5, m6, v6) \ + __pragma(warning(push)) \ + __pragma(warning(disable:4244)) \ + BM_SET_MASK_FLD(x, m1|m2|m3|m4|m5|m6, MV(m1,v1)| MV(m2,v2)| MV(m3,v3)| MV(m4,v4)| MV(m5,v5)| MV(m6,v6)) \ + __pragma(warning(pop)) +#endif + +#if 0 + //! Massage \a x for use in bitfield \a name. + #define BFN_PREP(x, name) ( ((x)<>name##_SHIFT ) + + //! Set bitfield \a name from \a y to \a x: y.name= x. + #define BFN_SET(y, x, name) (y = ((y)&~name##_MASK) | BFN_PREP(x,name) ) + + // Usage: prio get/set like before: + prio= BFN_GET(attr2, ATTR2_PRIO); + BFN_SET(attr2, x, ATTR2_PRIO); +#endif + + diff --git a/b91/b91m_ble_sdk/common/buf_pool0/Readme.txt b/b91/b91m_ble_sdk/common/buf_pool0/Readme.txt new file mode 100755 index 0000000..c1c1fbd --- /dev/null +++ b/b91/b91m_ble_sdk/common/buf_pool0/Readme.txt @@ -0,0 +1 @@ +Packetcraft's dynamic memory allocation \ No newline at end of file diff --git a/b91/b91m_ble_sdk/common/buf_pool0/myBuf.c b/b91/b91m_ble_sdk/common/buf_pool0/myBuf.c new file mode 100755 index 0000000..d509acf --- /dev/null +++ b/b91/b91m_ble_sdk/common/buf_pool0/myBuf.c @@ -0,0 +1,610 @@ +/*************************************************************************************************/ +/*! + * \file my_buf.c + * + * \brief Buffer pool service. + * + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include +#include +#include "types.h" +#include "utility.h" +#include "assert.h" +#include "common\compiler.h" +#include "application\print\printf.h" + + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/*! \brief Critical section nesting level. */ +_attribute_data_retention_ static u8 myCsNesting = 0; + +/*************************************************************************************************/ +/*! + * \brief Enter a critical section. + */ +/*************************************************************************************************/ +void myCsEnter(void) +{ + if (myCsNesting == 0) + { + irq_disable(); + } + myCsNesting++; +} + +/*************************************************************************************************/ +/*! + * \brief Exit a critical section. + */ +/*************************************************************************************************/ +void myCsExit(void) +{ + assert(myCsNesting != 0); + + myCsNesting--; + if (myCsNesting == 0) + { + irq_enable(); + } +} + + + + + + +/************************************************************************************************** + Macros +**************************************************************************************************/ +#define DEBUG_INFO //printf //debug use + +/* Magic number used to check for free buffer. */ +#define MY_BUF_FREE_NUM 0xFAABD00D + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/* Unit of memory storage-- a structure containing a pointer. */ +typedef struct myBufMem_tag +{ + struct myBufMem_tag *pNext; +#if MY_BUF_FREE_CHECK_ASSERT == TRUE + u32 free; +#endif +} myBufMem_t; + +/* Internal buffer pool. */ +typedef struct +{ + myBufPoolDesc_t desc; /* Number of buffers and length. */ + myBufMem_t *pStart; /* Start of pool. */ + myBufMem_t *pFree; /* First free buffer in pool. */ +#if MY_BUF_STATS == TRUE + u8 numAlloc; /* Number of buffers currently allocated from pool. */ + u8 maxAlloc; /* Maximum buffers ever allocated from pool. */ + u16 maxReqLen; /* Maximum request length from pool. */ +#endif +} myBufPool_t; + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/* Number of pools. */ +_attribute_data_retention_ u8 myBufNumPools; + +/* Memory used for pools. */ +_attribute_data_retention_ myBufMem_t *myBufMem = NULL; + +/* Currently use for debugging only. */ +_attribute_data_retention_ u32 myBufMemLen; + +#if MY_BUF_STATS_HIST == TRUE +/* Buffer allocation counter. */ +_attribute_data_retention_ u8 myBufAllocCount[MY_BUF_STATS_MAX_LEN]; + +/* Pool Overflow counter. */ +_attribute_data_retention_ u8 myPoolOverFlowCount[MY_BUF_STATS_MAX_POOL]; +#endif + +#if MY_OS_DIAG == TRUE +/* MY buffer diagnostic callback function. */ +_attribute_data_retention_ static myBufDiagCback_t myBufDiagCback = NULL; +#endif + +/*************************************************************************************************/ +/*! + * \brief Calculate size required by the buffer pool. + * + * \param numPools Number of buffer pools. + * \param pDesc Array of buffer pool descriptors, one for each pool. + * + * \return Amount of pBufMem used. + */ +/*************************************************************************************************/ +u32 myBufCalcSize(u8 numPools, myBufPoolDesc_t *pDesc) +{ + u32 len; + u32 descLen; + myBufPool_t *pPool; + myBufMem_t *pStart; + u8 i; + + myBufMem = (myBufMem_t *)0; + pPool = (myBufPool_t *)myBufMem; + + /* Buffer storage starts after the pool structs. */ + pStart = (myBufMem_t *) (pPool + numPools); + + /* Create each pool; see loop exit condition below. */ + while (TRUE) + { + /* Exit loop after verification check. */ + if (numPools-- == 0) + { + break; + } + + /* Adjust pool lengths for minimum size and alignment. */ + if (pDesc->len < sizeof(myBufMem_t)) + { + descLen = sizeof(myBufMem_t); + } + else if ((pDesc->len % sizeof(myBufMem_t)) != 0) + { + descLen = pDesc->len + sizeof(myBufMem_t) - (pDesc->len % sizeof(myBufMem_t)); + } + else + { + descLen = pDesc->len; + } + + len = descLen / sizeof(myBufMem_t); + for (i = pDesc->num; i > 0; i--) + { + /* Pointer to the next free buffer is stored in the buffer itself. */ + pStart += len; + } + pDesc++; + } + + return (u8 *)pStart - (u8 *)myBufMem; +} + +/*************************************************************************************************/ +/*! + * \brief Initialize the buffer pool service. This function should only be called once + * upon system initialization. + * + * \param numPools Number of buffer pools. + * \param pDesc Array of buffer pool descriptors, one for each pool. + * + * \return Amount of pBufMem used or 0 for failures. + */ +/*************************************************************************************************/ +u32 myBufInit(u8 numPools, myBufPoolDesc_t *pDesc) +{ + myBufPool_t *pPool; + myBufMem_t *pStart; + u16 len; + u8 i; + + myBufMem = (myBufMem_t *) myHeapGetFreeStartAddress();//È¡systemHeapStartAddr + pPool = (myBufPool_t *) myBufMem; + + /* Buffer storage starts after the pool structs. */ + pStart = (myBufMem_t *) (pPool + numPools); //Ú´Í·numPoolspStartÖ¸Ú´0ĵһ(num=0)ʼַ + + myBufNumPools = numPools; + + /* Create each pool; see loop exit condition below. */ + while (TRUE) + { + /* Verify we didn't overrun memory; if we did, abort. */ + if (pStart > &myBufMem[myHeapCountAvailable() / sizeof(myBufMem_t)]) + { + assert(FALSE); + return 0; + } + + /* Exit loop after verification check. */ + if (numPools-- == 0) + { + break; + } + + /* Adjust pool lengths for minimum size and alignment. */ + if (pDesc->len < sizeof(myBufMem_t)) //һڴس < sizeof(myBufMem_t) + { + pPool->desc.len = sizeof(myBufMem_t); + } + else if ((pDesc->len % sizeof(myBufMem_t)) != 0)//È¡sizeof(myBufMem_t)Ö½Ú¶ + { + pPool->desc.len = pDesc->len + sizeof(myBufMem_t) - (pDesc->len % sizeof(myBufMem_t)); + } + else + { + pPool->desc.len = pDesc->len; + } + + pPool->desc.num = pDesc->num; + pDesc++; + + pPool->pStart = pStart; + pPool->pFree = pStart; +#if MY_BUF_STATS == TRUE + pPool->numAlloc = 0; + pPool->maxAlloc = 0; + pPool->maxReqLen = 0; +#endif + + + /* Initialize free list. */ + len = pPool->desc.len / sizeof(myBufMem_t); + for (i = pPool->desc.num; i > 1; i--) + { + /* Verify we didn't overrun memory; if we did, abort. */ + if (pStart > &myBufMem[myHeapCountAvailable() / sizeof(myBufMem_t)]) + { + assert(FALSE); + return 0; + } + /* Pointer to the next free buffer is stored in the buffer itself. */ + pStart->pNext = pStart + len; //Ö¸Ò» + pStart += len;//pStartָǰڴصһʼַ(/ǰڴضӦnum++) + } + + /* Verify we didn't overrun memory; if we did, abort. */ + if (pStart > &myBufMem[myHeapCountAvailable() / sizeof(myBufMem_t)]) + { + assert(FALSE); + return 0; + } + /* Last one in list points to NULL. */ + pStart->pNext = NULL;//ǰڴصһnumӦһʼַΪNULL + pStart += len;//pStartָһڴصĵһʼַ + + /* Next pool. */ + pPool++; //Ö¸Ò»Ú´Í·Ö· + } + + myBufMemLen = (u8 *) pStart - (u8 *) myBufMem; + + return myBufMemLen; //Ú´0Ú´numPools-1ȫʼĵBufferСλByte +} + +/*************************************************************************************************/ +/*! + * \brief Allocate a buffer. + * + * \param len Length of buffer to allocate. + * + * \return Pointer to allocated buffer or NULL if allocation fails. + */ +/*************************************************************************************************/ +void *myBufAlloc(u16 len) +{ + myBufPool_t *pPool; + myBufMem_t *pBuf; + u8 i; + + //MY_CS_INIT(cs); + + assert(len > 0); + + pPool = (myBufPool_t *) myBufMem; + + for (i = myBufNumPools; i > 0; i--, pPool++) + { + /* Check if buffer is big enough. */ + if (len <= pPool->desc.len) + { + /* Enter critical section. */ + myCsEnter(); + + /* Check if buffers are available. */ + if (pPool->pFree != NULL) + { + /* Allocation succeeded. */ + pBuf = pPool->pFree; + + /* Next free buffer is stored inside current free buffer. */ + pPool->pFree = pBuf->pNext; + +#if MY_BUF_FREE_CHECK_ASSERT == TRUE + pBuf->free = 0; +#endif +#if MY_BUF_STATS_HIST == TRUE + /* Increment count for buffers of this length. */ + if (len < MY_BUF_STATS_MAX_LEN) + { + myBufAllocCount[len]++; + } + else + { + myBufAllocCount[0]++; + } +#endif +#if MY_BUF_STATS == TRUE + if (++pPool->numAlloc > pPool->maxAlloc) + { + pPool->maxAlloc = pPool->numAlloc; + } + pPool->maxReqLen = max2(pPool->maxReqLen, len); +#endif + /* Exit critical section. */ + myCsExit();; + + + return pBuf; + } +#if MY_BUF_STATS_HIST == TRUE + else + { + /* Pool overflow: increment count of overflow for current pool. */ + myPoolOverFlowCount[myBufNumPools-i]++; + } +#endif + /* Exit critical section. */ + myCsExit();; + +#if MY_BUF_ALLOC_BEST_FIT_FAIL_ASSERT == TRUE + assert(FALSE); +#endif + } + } + + /* Allocation failed. */ +#if MY_OS_DIAG == TRUE + if (myBufDiagCback != NULL) + { + myBufDiag_t info; + + info.type = MY_BUF_ALLOC_FAILED; + info.param.alloc.taskId = MY_OS_GET_ACTIVE_HANDLER_ID(); + info.param.alloc.len = len; + + myBufDiagCback(&info); + } + else + { + + } +#else + +#endif + +#if MY_BUF_ALLOC_FAIL_ASSERT == TRUE + assert(FALSE); +#endif + + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Free a buffer. + * + * \param pBuf Buffer to free. + */ +/*************************************************************************************************/ +void myBufFree(void *pBuf) +{ + myBufPool_t *pPool; + myBufMem_t *p = pBuf; + + //MY_CS_INIT(cs); + + /* Verify pointer is within range. */ +#if MY_BUF_FREE_CHECK_ASSERT == TRUE + assert(p >= ((myBufPool_t *) myBufMem)->pStart); + assert(p < (myBufMem_t *)(((u8 *) myBufMem) + myBufMemLen)); +#endif + + /* Iterate over pools starting from last pool. */ + pPool = (myBufPool_t *) myBufMem + (myBufNumPools - 1); + while (pPool >= (myBufPool_t *) myBufMem) + { + /* Check if the buffer memory is located inside this pool. */ + if (p >= pPool->pStart) + { + /* Enter critical section. */ + myCsEnter(); + +#if MY_BUF_FREE_CHECK_ASSERT == TRUE + assert(p->free != MY_BUF_FREE_NUM); + p->free = MY_BUF_FREE_NUM; +#endif +#if MY_BUF_STATS == TRUE + pPool->numAlloc--; +#endif + + /* Pool found; put buffer back in free list. */ + p->pNext = pPool->pFree; + pPool->pFree = p; + + /* Exit critical section. */ + myCsExit();; + + return; + } + + /* Next pool. */ + pPool--; + } + + /* Should never get here. */ + assert(FALSE); + + return; +} + +/*************************************************************************************************/ +/*! + * \brief Diagnostic function to get the buffer allocation statistics. + * + * \return Buffer allocation statistics array. + */ +/*************************************************************************************************/ +u8 *myBufGetAllocStats(void) +{ +#if MY_BUF_STATS_HIST == TRUE + return myBufAllocCount; +#else + return NULL; +#endif +} + +/*************************************************************************************************/ +/*! + * \brief Diagnostic function to get the number of overflow times for each pool. + * + * \return Overflow times statistics array + */ +/*************************************************************************************************/ +u8 *myBufGetPoolOverFlowStats(void) +{ +#if MY_BUF_STATS_HIST == TRUE + return myPoolOverFlowCount; +#else + return NULL; +#endif +} + +/*************************************************************************************************/ +/*! + * \brief Get number of pools. + * + * \return Number of pools. + */ +/*************************************************************************************************/ +u8 myBufGetNumPool(void) +{ + return myBufNumPools; +} + +/*************************************************************************************************/ +/*! + * \brief Get statistics for each pool. + * + * \param pBuf Buffer to store the statistics. + * \param poolId Pool ID. + */ +/*************************************************************************************************/ +void myBufGetPoolStats(myBufPoolStat_t *pStat, u8 poolId) +{ + myBufPool_t *pPool; + + if (poolId >= myBufNumPools) + { + pStat->bufSize = 0; + return; + } + + //MY_CS_INIT(cs); + myCsEnter(); + + pPool = (myBufPool_t *) myBufMem; + + pStat->bufSize = pPool[poolId].desc.len; + pStat->numBuf = pPool[poolId].desc.num; +#if MY_BUF_STATS == TRUE + pStat->numAlloc = pPool[poolId].numAlloc; + pStat->maxAlloc = pPool[poolId].maxAlloc; + pStat->maxReqLen = pPool[poolId].maxReqLen; +#else + pStat->numAlloc = 0; + pStat->maxAlloc = 0; + pStat->maxReqLen = 0; +#endif + + /* Exit critical section. */ + myCsExit();; +} + +/*************************************************************************************************/ +/*! + * \brief Called to register the buffer diagnostics callback function. + * + * \param pCallback Pointer to the callback function. + */ +/*************************************************************************************************/ +void myBufDiagRegister(myBufDiagCback_t callback) +{ +#if MY_OS_DIAG == TRUE + myBufDiagCback = callback; +#else + /* Unused parameter */ + (void)callback; +#endif +} + + +#if 0 //demo test + u8* AAA = NULL; + u8* ABB = NULL; + u8* ACC = NULL; + u8* ADD = NULL; + u8* AEE = NULL; + u8* AFF = NULL; + u8* AGG = NULL; + myBufPoolStat_t myBufPoolStatA,myBufPoolStatB,myBufPoolStatC; + void user_init(void) + { + myBufPoolDesc_t poolDesc[] = + { + { 16, 8 }, + { 32, 4 }, + { 64, 8 }, + { 128, 4 }, + { 256, 4 }, + { 512, 2 }, + }; + const u8 numPools = sizeof(poolDesc) / sizeof(poolDesc[0]); + /* Initial buffer configuration. */ + u16 memUsed = myBufInit(numPools, poolDesc); + myHeapAlloc(memUsed); + AAA = myBufAlloc(512); + ABB = myBufAlloc(19); + ACC = myBufAlloc(45); + ADD = myBufAlloc(6); + AEE = myBufAlloc(36); + AFF = myBufAlloc(97); + AGG = myBufAlloc(78); + + myBufFree(AAA); + myBufFree(ABB); + myBufFree(ACC); + myBufFree(ADD); + myBufFree(AEE); + myBufFree(AFF); + myBufFree(AGG); + + + myBufGetPoolStats(&myBufPoolStatA, 1); + myBufGetPoolStats(&myBufPoolStatB, 2); + myBufGetPoolStats(&myBufPoolStatC, 5); + } +#endif + diff --git a/b91/b91m_ble_sdk/common/buf_pool0/myBuf.h b/b91/b91m_ble_sdk/common/buf_pool0/myBuf.h new file mode 100755 index 0000000..2b06573 --- /dev/null +++ b/b91/b91m_ble_sdk/common/buf_pool0/myBuf.h @@ -0,0 +1,236 @@ +/*************************************************************************************************/ +/*! + * \file my_buf.h + * + * \brief Buffer pool service. + * + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ +#ifndef MY_BUF_H +#define MY_BUF_H + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "common/types.h" +#include "common/compiler.h" + + +/*! \addtogroup MY_BUF_API + * \{ */ + +/************************************************************************************************** + Configuration +**************************************************************************************************/ + +/*! \brief Check if trying to free a buffer that is already free */ +#ifndef MY_BUF_FREE_CHECK_ASSERT +#define MY_BUF_FREE_CHECK_ASSERT TRUE +#endif + +/*! \brief Assert on best-fit buffer allocation failure */ +#ifndef MY_BUF_ALLOC_BEST_FIT_FAIL_ASSERT +#define MY_BUF_ALLOC_BEST_FIT_FAIL_ASSERT TRUE//FALSE +#endif + +/*! \brief Assert on buffer allocation failure */ +#ifndef MY_BUF_ALLOC_FAIL_ASSERT +#define MY_BUF_ALLOC_FAIL_ASSERT TRUE +#endif + +/*! \brief Buffer histogram stats */ +#ifndef MY_BUF_STATS_HIST +#define MY_BUF_STATS_HIST FALSE//TRUE// +#endif + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/*! \brief Length of the buffer statistics array */ +#define MY_BUF_STATS_MAX_LEN 128 + +/*! \brief Max number of pools can allocate */ +#define MY_BUF_STATS_MAX_POOL 32 + +/*! \brief Failure Codes */ +#define MY_BUF_ALLOC_FAILED 1 + +#ifndef MY_BUF_STATS +/*! \brief Enable buffer allocation statistics. */ +#define MY_BUF_STATS FALSE//TRUE// +#endif + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief Buffer pool descriptor structure */ +typedef struct +{ + u16 len; /*!< \brief Length of buffers in pool */ + u8 num; /*!< \brief Number of buffers in pool */ +} myBufPoolDesc_t; + +/*! \brief Pool statistics */ +typedef struct +{ + u16 bufSize; /*!< \brief Pool buffer size. */ + u8 numBuf; /*!< \brief Total number of buffers. */ + u8 numAlloc; /*!< \brief Number of outstanding allocations. */ + u8 maxAlloc; /*!< \brief High allocation watermark. */ + u16 maxReqLen; /*!< \brief Maximum requested buffer length. */ +} myBufPoolStat_t; + +/*! \brief MY buffer diagnostics - buffer allocation failure */ +typedef struct +{ + u8 taskId; /*!< \brief Task handler ID where failure occured */ + u16 len; /*!< \brief Length of buffer being allocated */ +} myBufDiagAllocFail_t; + +/*! \brief MY buffer diagnostics message */ +typedef struct +{ + union + { + myBufDiagAllocFail_t alloc; /*!< \brief Buffer allocation failure */ + } param; /*!< \brief Union of diagnostic data types. */ + + u8 type; /*!< \brief Type of error */ +} myBufDiag_t; + +/************************************************************************************************** + Callback Function Datatypes +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Callback providing MY buffer diagnostic messages. + * + * \param pInfo Diagnostics message. + */ +/*************************************************************************************************/ +typedef void (*myBufDiagCback_t)(myBufDiag_t *pInfo); + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Calculate size required by the buffer pool. + * + * \param numPools Number of buffer pools. + * \param pDesc Array of buffer pool descriptors, one for each pool. + * + * \return Amount of pBufMem used. + */ +/*************************************************************************************************/ +u32 myBufCalcSize(u8 numPools, myBufPoolDesc_t *pDesc); + +/*************************************************************************************************/ +/*! + * \brief Initialize the buffer pool service. This function should only be called once + * upon system initialization. + * + * \param numPools Number of buffer pools. + * \param pDesc Array of buffer pool descriptors, one for each pool. + * + * \return Amount of pBufMem used or 0 for failures. + */ +/*************************************************************************************************/ +u32 myBufInit(u8 numPools, myBufPoolDesc_t *pDesc); + +/*************************************************************************************************/ +/*! + * \brief Allocate a buffer. + * + * \param len Length of buffer to allocate. + * + * \return Pointer to allocated buffer or NULL if allocation fails. + */ +/*************************************************************************************************/ +void *myBufAlloc(u16 len); + +/*************************************************************************************************/ +/*! + * \brief Free a buffer. + * + * \param pBuf Buffer to free. + */ +/*************************************************************************************************/ +void myBufFree(void *pBuf); + +/*************************************************************************************************/ +/*! + * \brief Diagnostic function to get the buffer allocation statistics. + * + * \return Buffer allocation statistics array. + */ +/*************************************************************************************************/ +u8 *myBufGetAllocStats(void); + +/*************************************************************************************************/ +/*! + * \brief Diagnostic function to get the number of overflow times for each pool. + * + * \return Overflow times statistics array + */ +/*************************************************************************************************/ +u8 *myBufGetPoolOverFlowStats(void); + +/*************************************************************************************************/ +/*! + * \brief Get number of pools. + * + * \return Number of pools. + */ +/*************************************************************************************************/ +u8 myBufGetNumPool(void); + +/*************************************************************************************************/ +/*! + * \brief Get statistics for each pool. + * + * \param pStat Buffer to store the statistics. + * \param numPool Number of pool elements. + * + * \return Pool statistics. + */ +/*************************************************************************************************/ +void myBufGetPoolStats(myBufPoolStat_t *pStat, u8 numPool); + +/*************************************************************************************************/ +/*! + * \brief Called to register the buffer diagnostics callback function. + * + * \param callback Pointer to the callback function. + */ +/*************************************************************************************************/ +void myBufDiagRegister(myBufDiagCback_t callback); + +/*! \} */ /* MY_BUF_API */ + +#ifdef __cplusplus +}; +#endif + +#endif /* MY_BUF_H */ diff --git a/b91/b91m_ble_sdk/common/buf_pool0/myHeap.c b/b91/b91m_ble_sdk/common/buf_pool0/myHeap.c new file mode 100755 index 0000000..95ae449 --- /dev/null +++ b/b91/b91m_ble_sdk/common/buf_pool0/myHeap.c @@ -0,0 +1,94 @@ +/*************************************************************************************************/ +/*! + * \file my_heap.c + * + * \brief Heap service. + * + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "common\types.h" +#include "common\compiler.h" + +/************************************************************************************************** + Macros +**************************************************************************************************/ +#define HEAP_MEM_SIZE_CFG 3072 //3K Heap + + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/*! Free memory for pool buffers. */ +_attribute_data_retention_ static u8 myBufMem[HEAP_MEM_SIZE_CFG]; + +_attribute_data_retention_ static u8 *SystemHeapStart = myBufMem; +_attribute_data_retention_ static u32 SystemHeapSize = HEAP_MEM_SIZE_CFG; + +/*************************************************************************************************/ +/*! + * \brief Reserve heap memory. + * + * \param size Number of bytes of heap memory used. + */ +/*************************************************************************************************/ +void myHeapAlloc(u32 size) +{ + /* Round up to nearest multiple of 4 for word alignment */ + size = (size + 3) & ~3; + + SystemHeapStart += size; + SystemHeapSize -= size; +} + +/*************************************************************************************************/ +/*! + * \brief Get next available heap memory. + * + * \return Address of the start of heap memory. + */ +/*************************************************************************************************/ +void *myHeapGetFreeStartAddress(void) +{ + return (void *)SystemHeapStart; +} + +/*************************************************************************************************/ +/*! + * \brief Get heap available. + * + * \return Number of bytes of heap memory available. + */ +/*************************************************************************************************/ +u32 myHeapCountAvailable(void) +{ + return SystemHeapSize; +} + +/*************************************************************************************************/ +/*! + * \brief Get heap used. + * + * \return Number of bytes of heap memory used. + */ +/*************************************************************************************************/ +u32 myHeapCountUsed(void) +{ + return HEAP_MEM_SIZE_CFG - SystemHeapSize; +} diff --git a/b91/b91m_ble_sdk/common/buf_pool0/myHeap.h b/b91/b91m_ble_sdk/common/buf_pool0/myHeap.h new file mode 100755 index 0000000..8725399 --- /dev/null +++ b/b91/b91m_ble_sdk/common/buf_pool0/myHeap.h @@ -0,0 +1,84 @@ +/*************************************************************************************************/ +/*! + * \file my_heap.h + * + * \brief Buffer heap service. + * + * Copyright (c) 2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#pragma once + + + + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \addtogroup MY_HEAP_API + * \{ */ + + +#include "common/types.h" +#include "common/compiler.h" + + +/*************************************************************************************************/ +/*! + * \brief Get heap available. + * + * \return Number of bytes of heap memory available. + */ +/*************************************************************************************************/ +u32 myHeapCountAvailable(void); + +/*************************************************************************************************/ +/*! + * \brief Get heap used. + * + * \return Number of bytes of heap memory used. + */ +/*************************************************************************************************/ +u32 myHeapCountUsed(void); + +/*************************************************************************************************/ +/*! + * \brief Reserve heap memory. + * + * \param size Number of bytes of heap memory used. + */ +/*************************************************************************************************/ +void myHeapAlloc(u32 size); + +/*************************************************************************************************/ +/*! + * \brief Get next available heap memory. + * + * \return Address of the start of heap memory. + */ +/*************************************************************************************************/ +void *myHeapGetFreeStartAddress(void); + +/*! \} */ /* MY_HEAP_API */ + +#ifdef __cplusplus +}; +#endif + + diff --git a/b91/b91m_ble_sdk/common/buf_pool1/Readme.txt b/b91/b91m_ble_sdk/common/buf_pool1/Readme.txt new file mode 100755 index 0000000..a61b672 --- /dev/null +++ b/b91/b91m_ble_sdk/common/buf_pool1/Readme.txt @@ -0,0 +1,13 @@ +Telink Zigbee's dynamic memory allocation + +1. for user used + ev_buffer.c + ev_buffer.h + mempool.c + mempool.h + +2. for zigbee stack internal used + zb_buffer.c + zb_buffer.h + + \ No newline at end of file diff --git a/b91/b91m_ble_sdk/common/buf_pool1/ev_buffer.c b/b91/b91m_ble_sdk/common/buf_pool1/ev_buffer.c new file mode 100755 index 0000000..c98dcb8 --- /dev/null +++ b/b91/b91m_ble_sdk/common/buf_pool1/ev_buffer.c @@ -0,0 +1,314 @@ +/******************************************************************************************************** + * @file ev_buffer.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "ev_buffer.h" +#include "user_config.h" +#include "mempool.h" +#include "common/utility.h" +#include "common/assert.h" +#include +#include "drivers/B91/ext_driver/ext_misc.h" + +#ifdef WIN32 +#include +#endif + + +#if (1) + +#define DEFAULT_BUFFER_GROUP_NUM 3 + + +/**************************** Private Variable Definitions *******************/ + +typedef struct { + mem_pool_t *qHead; + u16 size; + u8 availBufNum; + u8 reserved; +} ev_buf_groups_t; + + +typedef struct bufm_vars { + ev_buf_groups_t bufGroups[DEFAULT_BUFFER_GROUP_NUM]; +} ev_buf_vars_t; + + +ev_buf_vars_t ev_buf_vs; +ev_buf_vars_t *ev_buf_v = &ev_buf_vs; + + +MEMPOOL_DECLARE(size_0_pool, size_0_mem, BUFFER_GROUP_0, BUFFER_NUM_IN_GROUP0); +MEMPOOL_DECLARE(size_1_pool, size_1_mem, BUFFER_GROUP_1, BUFFER_NUM_IN_GROUP1); +MEMPOOL_DECLARE(size_2_pool, size_2_mem, BUFFER_GROUP_2, BUFFER_NUM_IN_GROUP2); + +/********************************************************************* + * @fn ev_buf_isExisted + * + * @brief Return whether the buffer is in the available buffer + * + * @param index + * @param block + * + * @return TRUE or FALSE + */ +u8 ev_buf_isExisted(u8 index, mem_block_t *block) +{ + mem_pool_t *pool = (mem_pool_t *)ev_buf_v->bufGroups[index].qHead; + mem_block_t *curBlock = pool->free_list; + + while(curBlock){ + if(block == curBlock){ + return TRUE; + } + curBlock = curBlock->next_block; + } + + return FALSE; +} + +u8 *ev_buf_retriveMempoolHeader(u8 *pd) +{ + return pd - (OFFSETOF(ev_bufItem_t, data) - OFFSETOF(mem_block_t, data)); +} + + +/********************************************************************* + * @fn ev_buf_reset + * + * @brief Reset the EV Buffer module + * + * @param None + * + * @return None + */ +void ev_buf_reset(void) +{ + u16 size[DEFAULT_BUFFER_GROUP_NUM] = {BUFFER_GROUP_0, BUFFER_GROUP_1, BUFFER_GROUP_2}; + mem_pool_t *memPool[DEFAULT_BUFFER_GROUP_NUM] = {&size_0_pool, &size_1_pool, &size_2_pool}; + u8 *mem[DEFAULT_BUFFER_GROUP_NUM] = {size_0_mem, size_1_mem, size_2_mem}; + u8 buffCnt[DEFAULT_BUFFER_GROUP_NUM] = {BUFFER_NUM_IN_GROUP0, BUFFER_NUM_IN_GROUP1, BUFFER_NUM_IN_GROUP2}; + + memset((u8 *)ev_buf_v, 0, sizeof(ev_buf_vars_t)); + + /* reinitialize available buffer */ + for(u8 i = 0; i < DEFAULT_BUFFER_GROUP_NUM; i++){ + ev_buf_v->bufGroups[i].availBufNum = buffCnt[i]; + ev_buf_v->bufGroups[i].qHead = mempool_init(memPool[i], mem[i], size[i], buffCnt[i]); + ev_buf_v->bufGroups[i].size = size[i]; + } +} + +/********************************************************************* + * @fn ev_buf_init + * + * @brief Initialize the EV Buffer module + * + * @param None + * + * @return None + */ +void ev_buf_init(void) +{ + ev_buf_reset(); +} + +/********************************************************************* + * @fn ev_buf_allocate + * + * @brief Allocate an available buffer according to the requested size + * The allocated buffer will have only three kind of size, defined + * in @ref EV_BUFFER_CONSTANT + * + * @param size - requested size + * + * @return Pointer to an allocated buffer. + * NULL means the there is no available buffer. + */ + +#if EV_BUFFER_DEBUG +u8 *my_ev_buf_allocate(u16 size, u16 line) +#else +u8 *ev_buf_allocate(u16 size) +#endif +{ + if((size == 0) || (size > MAX_BUFFER_SIZE)){ + /* the size parameter is wrong */ + return NULL; + } + u32 r = irq_disable(); + u8 index = U8_MAX; + + /* find related the buffer blocks */ + for(u8 i = 0; i < DEFAULT_BUFFER_GROUP_NUM; i++){ + if((size <= ev_buf_v->bufGroups[i].size - OFFSETOF(ev_bufItem_t, data)) && ev_buf_v->bufGroups[i].availBufNum){ + index = i; + break; + } + } + if((index == U8_MAX ) || (!ev_buf_v->bufGroups[index].availBufNum)){ + /* no available buffer */ + irq_restore(r); + return NULL; + } + u8 *temp = (u8 *)mempool_alloc(ev_buf_v->bufGroups[index].qHead); + if(!temp){ + irq_restore(r); + return NULL; + } + ev_buf_v->bufGroups[index].availBufNum--; + + ev_bufItem_t *pNewBuf = (ev_bufItem_t *)(temp - 4); + pNewBuf->groupIndex = index; +#if EV_BUFFER_DEBUG + pNewBuf->line = line; + pNewBuf->flag = 0xfe; +#endif + irq_restore(r); + return pNewBuf->data; +} + + +/********************************************************************* + * @fn ev_buf_free + * + * @brief Free the specified buffer + * + * @param pBuf - the pointer to the specified buffer to free. + * + * @return status + */ +#if EV_BUFFER_DEBUG +volatile u32 T_DBG_evFreeBuf = 0; +volatile u16 T_DBG_evFreeBufLine = 0; +buf_sts_t my_ev_buf_free(u8 *pBuf, u16 line) +#else +buf_sts_t ev_buf_free(u8 *pBuf) +#endif +{ + u32 r = irq_disable(); + + if(!is_ev_buf(pBuf)){ +#if EV_BUFFER_DEBUG + T_DBG_evFreeBuf = (u32)pBuf; + T_DBG_evFreeBufLine = line; +#endif + + //TODO: Throw exceptions to the application layer + } + + ev_bufItem_t *pDelBuf = ev_buf_getHead(pBuf); + + /* check whether the buffer is duplicated release */ + if(ev_buf_isExisted(pDelBuf->groupIndex, (mem_block_t *)pDelBuf)){ + +#if EV_BUFFER_DEBUG + T_DBG_evFreeBuf = (u32)pBuf; + T_DBG_evFreeBufLine = line; +#endif + + //TODO: Throw exceptions to the application layer + + irq_restore(r); + return BUFFER_DUPLICATE_FREE; + } + + mempool_free(ev_buf_v->bufGroups[pDelBuf->groupIndex].qHead, ev_buf_retriveMempoolHeader(pBuf)); + ev_buf_v->bufGroups[pDelBuf->groupIndex].availBufNum++; + +#if EV_BUFFER_DEBUG + pDelBuf->line = line; + pDelBuf->flag = 0xff; +#endif + + irq_restore(r); + return BUFFER_SUCC; +} + + + +/********************************************************************* + * @fn ev_buf_getHead + * + * @brief Get the header pointer of a buffer item + * + * @param pd - the pointer of a data, which is previously allocated + * + * @return Pointer of bufferItem + */ +ev_bufItem_t *ev_buf_getHead(u8 *pd) +{ + return (ev_bufItem_t *)(pd - OFFSETOF(ev_bufItem_t, data)); +} + +/********************************************************************* + * @fn ev_buf_getTail + * + * @brief Get the pointer from a EV BUFFER tail. + * + * @param pd - the pointer of a data, which is previously allocated + * @param offsetToTail - The offset to Tail + * + * @return Pointer of the specified memory + */ +u8 *ev_buf_getTail(u8 *pd, int offsetToTail) +{ + u32 index; + u16 size[DEFAULT_BUFFER_GROUP_NUM] = {BUFFER_GROUP_0, BUFFER_GROUP_1, BUFFER_GROUP_2}; + + memcpy((u8*)&index, pd - 4, 4); + assert((index < 3) && (index >= 0)); + return (u8*)(pd - 8 + size[index] - offsetToTail); +} + + +u8 is_ev_buf(void *arg){ + if( ((u32)arg >= (u32)(size_0_mem) && (u32)arg <= ((u32)(size_0_mem) + sizeof(size_0_mem))) || + ((u32)arg >= (u32)(size_1_mem) && (u32)arg <= ((u32)(size_1_mem) + sizeof(size_1_mem))) || + ((u32)arg >= (u32)(size_2_mem) && (u32)arg <= ((u32)(size_2_mem) + sizeof(size_2_mem))) ){ + return 1; + } + return 0; +} + +u16 ev_buf_getFreeMaxSize(void) +{ + u16 size = 0; + + for(u8 i = 0; i < DEFAULT_BUFFER_GROUP_NUM; i++){ + if(ev_buf_v->bufGroups[i].availBufNum){ + if((ev_buf_v->bufGroups[i].size - OFFSETOF(ev_bufItem_t, data)) > size){ + size = ev_buf_v->bufGroups[i].size - OFFSETOF(ev_bufItem_t, data); + } + } + } + + return size; +} + +#endif /* MODULE_BUFM_ENABLE */ + + + + + + diff --git a/b91/b91m_ble_sdk/common/buf_pool1/ev_buffer.h b/b91/b91m_ble_sdk/common/buf_pool1/ev_buffer.h new file mode 100755 index 0000000..fcb5218 --- /dev/null +++ b/b91/b91m_ble_sdk/common/buf_pool1/ev_buffer.h @@ -0,0 +1,186 @@ +/******************************************************************************************************** + * @file ev_buffer.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "common/types.h" +#include "common/compiler.h" + + +/** @addtogroup TELINK_COMMON_MODULE TELINK Common Module + * @{ + */ + +/** @addtogroup EV_BUFFER EV Buffer + * @{ + */ + +/** @defgroup EV_BUFFER_CONSTANT EV Buffer Constants + * @{ + */ + + +/** @addtogroup ev_buffer_groups EV Buffer Groups + * Definition the length of each buffer group + * @{ + */ +#define BUFFER_GROUP_0 24 +#define BUFFER_GROUP_1 60 +#define BUFFER_GROUP_2 150 +#define MAX_BUFFER_SIZE BUFFER_GROUP_2 + +/** @} end of group ev_buffer_groups */ + +/** + * @brief Default buffer number in each group + */ +#define BUFFER_NUM_IN_GROUP0 8 +#define BUFFER_NUM_IN_GROUP1 20 +#define BUFFER_NUM_IN_GROUP2 5 + +/** @addtogroup ev_buffer_typical_size EV Buffer Typical Application Size + * Definition default buffer size for different typical usage + * @{ + */ +#define SMALL_BUFFER 48 +#define LARGE_BUFFER 142 + +#define EV_BUFFER_DEBUG 0 + +/** @} end of group ev_buffer_typical_size */ + +/** @} end of group EV_BUFFER_CONSTANT */ + + +/** @defgroup EV_BUFFER_TYPE EV Buffer Types + * @{ + */ + +/** + * @brief Definition of a buffer item, it is internal used. + */ +typedef struct ev_bufItem { + struct ev_bufItem *next; +#if EV_BUFFER_DEBUG + u8 groupIndex; + u8 flag; + u16 line; +#else + u32 groupIndex; +#endif + u8 data[1]; +} ev_bufItem_t; + + +/** + * @brief Definiton error code of EV buffer operation + */ +typedef enum buf_sts_e { + // SUCCESS always be ZERO + BUFFER_SUCC, + BUFFER_INVALID_PARAMETER = 1, //!< Invalid parameter passed to the buffer API + BUFFER_DUPLICATE_FREE //!< The same buffer is freed more than once +} buf_sts_t; + +/** @} end of group EV_BUFFER_TYPE */ + + +/** @defgroup EV_BUFFER_FUNCTIONS EV Buffer API + * @brief Function declaration of EV Buffer module + * @{ + */ + + /** + * @brief Reset the EV Buffer module + * + * @param None + * + * @return None + */ +void ev_buf_reset(void); + + /** + * @brief Initialize the EV Buffer module + * + * @param None + * + * @return None + */ +void ev_buf_init(void); + + /** + * @brief Allocate an available buffer according to the requested size + * The allocated buffer will have only three kind of size, defined + * in @ref EV_BUFFER_CONSTANT + * + * @param size - The requested size + * + * @return Pointer to an allocated buffer. + * NULL means the there is no available buffer. + */ + +#if EV_BUFFER_DEBUG +#define ev_buf_allocate(size) my_ev_buf_allocate(size, __LINE__) +#else +u8 *ev_buf_allocate(u16 size); +#endif + + /** + * @brief Free the specified buffer + * + * @param pBuf - the pointer to the specified buffer to free. + * + * @return Status. + */ + +#if EV_BUFFER_DEBUG +#define ev_buf_free(pBuf) my_ev_buf_free(pBuf, __LINE__) +#else +buf_sts_t ev_buf_free(u8* pBuf); +#endif + + /** + * @brief Get the header of a buffer item + * + * @param pd - the pointer of a data, which is previously allocated + * + * @return Pointer of bufferItem + */ +ev_bufItem_t* ev_buf_getHead(u8* pd); + +/** + * @brief judge if the buffer is ev buffer + * + * @param the buffer adrress + * + * @return 1: if ev buffer; 0: others + */ +u8 is_ev_buf(void *arg); + +u16 ev_buf_getFreeMaxSize(void); +/** @} end of group EV_BUFFER_FUNCTIONS */ + +/** @} end of group EV_BUFFER */ + +/** @} end of group TELINK_COMMON_MODULE */ + + diff --git a/b91/b91m_ble_sdk/common/buf_pool1/mempool.c b/b91/b91m_ble_sdk/common/buf_pool1/mempool.c new file mode 100755 index 0000000..24eab05 --- /dev/null +++ b/b91/b91m_ble_sdk/common/buf_pool1/mempool.c @@ -0,0 +1,61 @@ +/******************************************************************************************************** + * @file mempool.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "mempool.h" +#include "utility.h" + +mem_pool_t* mempool_init(mem_pool_t* pool, void* mem, int itemsize, int itemcount) +{ + if (!pool || !mem) + return (0); + + pool->free_list = (mem_block_t*)mem; + + u32 block_size = (u32)(MEMPOOL_ITEMSIZE_2_BLOCKSIZE(itemsize)); + mem_block_t* tmp = (mem_block_t*)mem; + int i; + for(i = 0; i < itemcount - 1; ++i){ + tmp = tmp->next_block = (mem_block_t*)(((u32)tmp) + block_size); + } + tmp->next_block = 0; + return pool; +} + +mem_block_t* mempool_header(char* pd){ + return (mem_block_t*)(pd - OFFSETOF(mem_block_t, data)); +} + +void* mempool_alloc(mem_pool_t* pool) +{ + if(!pool->free_list) + return 0; + mem_block_t* tmp = pool->free_list; + pool->free_list = tmp->next_block; + return &tmp->data; +} + +void mempool_free(mem_pool_t* pool, void* p) +{ + mem_block_t* tmp = mempool_header((char*)p); + tmp->next_block = pool->free_list; + pool->free_list = tmp; +} diff --git a/b91/b91m_ble_sdk/common/buf_pool1/mempool.h b/b91/b91m_ble_sdk/common/buf_pool1/mempool.h new file mode 100755 index 0000000..34bf8af --- /dev/null +++ b/b91/b91m_ble_sdk/common/buf_pool1/mempool.h @@ -0,0 +1,50 @@ +/******************************************************************************************************** + * @file mempool.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "types.h" + +typedef struct mem_block_t +{ + struct mem_block_t* next_block; + char data[4]; // must 4 or 8 aligned, padding +}mem_block_t; + +typedef struct mem_pool_t +{ + mem_block_t* free_list; +}mem_pool_t; + +#define MEMPOOL_ALIGNMENT 4 +#define MEMPOOL_ITEMSIZE_2_BLOCKSIZE(s) ((s + (MEMPOOL_ALIGNMENT - 1)) & ~(MEMPOOL_ALIGNMENT-1)) + +#define MEMPOOL_DECLARE(pool_name, pool_mem, itemsize, itemcount) \ + mem_pool_t pool_name; \ + u8 pool_mem[MEMPOOL_ITEMSIZE_2_BLOCKSIZE(itemsize) * itemcount] _attribute_aligned_(4); + +mem_pool_t* mempool_init(mem_pool_t* pool, void* mem, int itemsize, int itemcount); +void* mempool_alloc(mem_pool_t* pool); +void mempool_free(mem_pool_t* pool, void* p); +mem_block_t* mempool_header(char* pd); + + diff --git a/b91/b91m_ble_sdk/common/buf_pool1/zb_buffer.c b/b91/b91m_ble_sdk/common/buf_pool1/zb_buffer.c new file mode 100755 index 0000000..ed08eef --- /dev/null +++ b/b91/b91m_ble_sdk/common/buf_pool1/zb_buffer.c @@ -0,0 +1,264 @@ +/******************************************************************************************************** + * @file zb_buffer.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +/*************************************************************************** +* * +* INSERT COPYRIGHT HERE! * +* * +**************************************************************************** +PURPOSE: Zigbee packet buffers pool +*/ +#include "common/compiler.h" +#include "zb_buffer.h" + +/*! \addtogroup buf */ +/*! @{ */ + + +/* + * the buffer for zigbee stack initilization + * + * */ +void tl_zbBufferInit(void){ + memset((u8 *)&g_mPool, 0, sizeof(zb_buf_pool_t)); + + zb_buf_t *p = g_mPool.head = &g_mPool.pool[0]; + + for(s32 i = 0; i < ZB_BUF_POOL_SIZE - 1; i++){ + p->next = (p + 1); + p++; + } + p->next = NULL; +} + + +/* + * allocate a buffer directly + * return success, if the pool has a empty buffer, + * if not, return failure + * + * */ +#if ZB_BUFFER_DEBUG +static _attribute_ram_code_ zb_buf_t *my_zb_buf_get(u16 line) +#else +static _attribute_ram_code_ zb_buf_t *zb_buf_get(void) +#endif +{ + zb_buf_t *buf = NULL; + + u8 r = irq_disable(); + if(g_mPool.usedNum < ZB_BUF_POOL_SIZE) + { + if((((u32)(g_mPool.head) < (u32)(&g_mPool.pool[0])) && (g_mPool.head != NULL)) || + ((u32)(g_mPool.head) > (u32)(&g_mPool.pool[ZB_BUF_POOL_SIZE - 1]))) { + //ZB_EXCEPTION_POST(SYS_EXCEPTTION_ZB_BUFFER_EXCEPTION); + } + + buf = g_mPool.head; + if(buf){ + g_mPool.head = buf->next; + buf->next = NULL; + memset(&buf->hdr, 0, sizeof(buf->hdr)); + memset(buf->buf, 0, ZB_BUF_SIZE); + g_mPool.usedNum++; + buf->hdr.used = 1; +#if ZB_BUFFER_DEBUG + u32 idx = buf->allocCnt % ZB_BUFF_DBG_NUM; + buf->allocInfo[idx].allocLine = line; +#endif + buf->allocCnt++; + }else{ + if(g_mPool.usedNum < ZB_BUF_POOL_SIZE){ + //ZB_EXCEPTION_POST(SYS_EXCEPTTION_ZB_BUFFER_EXCEPTION); + } + } + } + irq_restore(r); + + if(!buf){ + /* diagnostics packet buffer allocate failures */ + //g_sysDiags.packetBufferAllocateFailures++; + } + + return buf; +} + + +inline u8 *tl_phyRxBufTozbBuf(u8 *p){ + return (p - RX_ZBBUF_OFFSET); +} + +inline u8 *tl_zbBufToPhyRxBuf(u8 *p){ + return (p + RX_ZBBUF_OFFSET); +} + +/* + * allocate a buffer directly for ZB stack + * return success, if the pool has a empty buffer, + * if not, return failure + * + * */ +#if ZB_BUFFER_DEBUG +zb_buf_t *my_zb_buf_allocate(u16 line){ + return my_zb_buf_get(line); +} +_attribute_ram_code_ u8 *tl_getRxBuf(){ +#if 0 + if (g_mPool.usedNum > 8){ + return NULL; + + } +#endif + u8 *buf = (u8 *)my_zb_buf_get(90); + if(buf){ + return TL_INBUF_TO_RXBUF(buf); + } + return NULL; + +} +#else +_attribute_ram_code_ zb_buf_t *zb_buf_allocate(){ + return zb_buf_get(); +} + +_attribute_ram_code_ u8 *tl_getRxBuf(){ + u8 *buf = (u8 *)zb_buf_get(); + if(buf){ + return TL_INBUF_TO_RXBUF(buf); + } + return NULL; +} + +#endif + +/* + * free the buffer + * */ +volatile u32 T_zbBufDbg = 0; +volatile u32 T_zbBufFreeDbg = 0; +#if ZB_BUFFER_DEBUG +volatile u32 T_zbBufFreeDbgLine = 0; +volatile u32 T_zbBufFreeDbgIdx = 0; +volatile u32 T_zbBufFreeDbgIdx1 = 0; +u8 my_zb_buf_free(zb_buf_t *buf, u16 line) +#else +u8 zb_buf_free(zb_buf_t *buf) +#endif +{ + u8 r = irq_disable(); + + if(!is_zb_buf((void *)buf)){ + //ZB_EXCEPTION_POST(SYS_EXCEPTTION_ZB_BUFFER_EXCEPTION_FREE_OVERFLON); + } + +#if ZB_BUFFER_DEBUG + u32 idx = buf->freeCnt % ZB_BUFF_DBG_NUM; + T_zbBufFreeDbgLine = buf->allocInfo[idx].freeLine; + T_zbBufFreeDbgIdx1 = buf->allocCnt; + T_zbBufFreeDbgIdx = idx; + buf->allocInfo[idx].freeLine = line; + buf->allocInfo[idx].handler = buf->hdr.handle; + buf->allocInfo[idx].id = buf->hdr.id; + buf->allocInfo[idx].nlmeStatus = buf->hdr.resvHdr; + T_zbBufDbg = (u32)buf; +#endif + + buf->freeCnt++; + if(buf->hdr.macTxFifo == 1 || buf->freeCnt > buf->allocCnt || buf->hdr.used == 0){ + T_zbBufFreeDbg = (buf->hdr.macTxFifo << 24) | ((buf->freeCnt > buf->allocCnt) << 16) | buf->hdr.used ; + T_zbBufDbg = (u32)buf; + //ZB_EXCEPTION_POST(SYS_EXCEPTTION_ZB_BUFFER_EXCEPTION_FREE_MULIT); + } + + if((((u32)(g_mPool.head) < (u32)(&g_mPool.pool[0])) && (g_mPool.head != NULL)) || + ((u32)(g_mPool.head) > (u32)(&g_mPool.pool[ZB_BUF_POOL_SIZE - 1]))) { + //ZB_EXCEPTION_POST(SYS_EXCEPTTION_ZB_BUFFER_EXCEPTION); + } + + g_mPool.usedNum--; + buf->next = g_mPool.head; + g_mPool.head = buf; + + if((((u32)(g_mPool.head) < (u32)(&g_mPool.pool[0])) && (g_mPool.head != NULL)) || + ((u32)(g_mPool.head) > (u32)(&g_mPool.pool[ZB_BUF_POOL_SIZE - 1]))) { + //ZB_EXCEPTION_POST(SYS_EXCEPTTION_ZB_BUFFER_EXCEPTION); + } + buf->hdr.used = 0; + buf->hdr.handle = 0xff; + + irq_restore(r); + return SUCCESS; +} + + +void *tl_bufInitalloc(zb_buf_t *p, u8 size){ +#ifdef ZB_SECURITY + size += 8;//Extra 4 bytes for APS MIC and 4 bytes for NWK MIC +#endif + return (void *)((u8 *)p + ((ZB_BUF_SIZE - size) & (~0x03))); +} + +/* clear the buffer, some info set as 0 */ +void zb_buf_clear(zb_buf_t *p) +{ + u8 used = p->hdr.used; + + u8 r = irq_disable(); + memset(&p->hdr, 0, sizeof(p->hdr)); + p->hdr.used = used; + irq_restore(r); +} + +bool is_zb_buf(void *p){ + if(((u32)p >= (u32)(&g_mPool.pool[0])) && ((u32)p < (u32)((&g_mPool.pool[ZB_BUF_POOL_SIZE - 1]))+ZB_BUF_SIZE)){ + return 1; + } + return 0; +} + +#if ZB_BUFFER_DEBUG +volatile u8 T_zbbud_debug_start = 0; +typedef struct{ + u8 id; + u8 handle; + u16 allocateLine; +}zb_bufDbg_t; +zb_bufDbg_t g_zbBufDBG[ZB_BUF_POOL_NUM]; + +void zb_buf_debug_start(void){ + if(T_zbbud_debug_start){ + u8 cnt = 0; + T_zbbud_debug_start = 0; + for(s32 i = 0; i < ZB_BUF_POOL_SIZE - 1;i++){ + if(g_mPool.pool[i].hdr.used){ + g_zbBufDBG[cnt].handle = g_mPool.pool[i].hdr.handle; + g_zbBufDBG[cnt].id = g_mPool.pool[i].hdr.id; + //g_zbBufDBG[cnt].allocateLine = g_mPool.pool[i].allocLine; + cnt++; + } + } + } +} +#endif + + +/*! @} */ diff --git a/b91/b91m_ble_sdk/common/buf_pool1/zb_buffer.h b/b91/b91m_ble_sdk/common/buf_pool1/zb_buffer.h new file mode 100755 index 0000000..d53ab9f --- /dev/null +++ b/b91/b91m_ble_sdk/common/buf_pool1/zb_buffer.h @@ -0,0 +1,155 @@ +/******************************************************************************************************** + * @file zb_buffer.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef ZB_BUFPOOL_H +#define ZB_BUFPOOL_H 1 + +#include "tl_common.h" + +/*! \addtogroup buf */ +/*! @{ */ + +/** + Packet buffer header. + */ + +typedef struct{ + u8 id; //primitive id + u8 handle; + s8 rssi; + u8 used:1; + u8 macTxFifo:1; + u8 mgmtLeave:1; + u8 active:1; //only for mac command buffer + u8 pending:1; //only for endDev, if parent has pending data for me + u8 resvHdr:3; +}zb_buf_hdr_t;//4 + + +/** + Packet buffer + */ +#define ZB_BUFFER_DEBUG 0 + +#define TL_RXPRIMITIVEHDR 32 //To use the in buffer as RX buffer, needs to preallocate primitive fields + +#define ZB_BUF_SIZE (160 + TL_RXPRIMITIVEHDR) + +#ifndef ZB_BUF_POOL_NUM + #if defined(MCU_CORE_8258) || defined(MCU_CORE_8278) + #define ZB_BUF_POOL_NUM 36 + #else + #ifdef CHIP_8269 + #define ZB_BUF_POOL_NUM 36 + #else + #define ZB_BUF_POOL_NUM 12 + #endif + #endif +#endif + +typedef struct{ + u16 allocLine; + u16 freeLine; + u8 handler; + u8 nlmeStatus; + u8 id; + u8 resv; +}zb_buf_allocInfo_t; + +#if ZB_BUFFER_DEBUG +#define ZB_BUFF_DBG_NUM 16 +#endif + +typedef struct zb_buf_s{ + u8 buf[ZB_BUF_SIZE]; + zb_buf_hdr_t hdr; + struct zb_buf_s *next; + u32 allocCnt; + u32 freeCnt; +#if ZB_BUFFER_DEBUG + zb_buf_allocInfo_t allocInfo[ZB_BUFF_DBG_NUM]; +#endif +}zb_buf_t ; + +typedef struct{ + zb_buf_t *head; + u32 usedNum; +#if ZB_BUFFER_DEBUG + u32 rsv_fill[2]; +#endif + zb_buf_t pool[ZB_BUF_POOL_NUM]; //shall be allocated at the last field in the structure of the zb_buf_pool_t +} zb_buf_pool_t; + +extern u8 ZB_BUF_POOL_SIZE; +extern zb_buf_pool_t g_mPool; + +void *tl_bufInitalloc(zb_buf_t *p, u8 size); +#define TL_BUF_INITIAL_ALLOC(p, size, ptr, type) (ptr) = (type)tl_bufInitalloc((p), (size)) + +#define TL_COPY_BUF(dst, src) \ +do \ +{ \ + memcpy((dst), (src), ZB_BUF_SIZE + sizeof(zb_buf_hdr_t) - 1); \ +} while (0) + + +void zb_buf_clear(zb_buf_t *p); + +bool is_zb_buf(void *p); + +/* + * buffer(only used in zigbee stack) initialization + * + * */ +extern void tl_zbBufferInit(void); + +extern u8 *tl_phyRxBufTozbBuf(u8 *p); + +extern u8 *tl_zbBufToPhyRxBuf(u8 *p); + +#define TL_RXBUF_TO_INBUF(p) tl_phyRxBufTozbBuf(p) +#define TL_INBUF_TO_RXBUF(p) tl_zbBufToPhyRxBuf(p) + + +u8 *tl_getRxBuf(); + +#if ZB_BUFFER_DEBUG +#define zb_buf_allocate() my_zb_buf_allocate(__LINE__) +#else +zb_buf_t *zb_buf_allocate(); +#endif + + +#if ZB_BUFFER_DEBUG +#define zb_buf_free(x) my_zb_buf_free(x,__LINE__) +#else +u8 zb_buf_free(zb_buf_t *buf); +#endif + +#define ZB_BUF_FROM_REF(ref) (&g_mPool.pool[ref]) + +#define ZB_REF_FROM_BUF(p) (p - &g_mPool.pool[0]) + +extern u8 RX_ZBBUF_OFFSET; +/*! @} */ + +#endif /* ZB_BUFPOOL_H */ diff --git a/b91/b91m_ble_sdk/common/compiler.h b/b91/b91m_ble_sdk/common/compiler.h new file mode 100755 index 0000000..de08548 --- /dev/null +++ b/b91/b91m_ble_sdk/common/compiler.h @@ -0,0 +1,108 @@ +/******************************************************************************************************** + * @file compiler.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef COMPILER_H_ +#define COMPILER_H_ + +#define _attribute_noinline_ __attribute__((noinline)) + +#define _attribute_ram_code_sec_ __attribute__((section(".ram_code"))) +#define _attribute_ram_code_sec_noinline_ __attribute__((section(".ram_code"))) __attribute__((noinline)) + +#define _attribute_text_sec_ __attribute__((section(".text"))) + +#define _attribute_aes_data_sec_ __attribute__((section(".aes_data"))) + +#define _attribute_aligned_(s) __attribute__((aligned(s))) + +/// Pack a structure field +#define __PACKED __attribute__ ((__packed__)) + +/******************************* BLE Stack Use ******************************/ +#include "common/config/user_config.h" + +#define _attribute_packed_ __attribute__((packed)) +#define _attribute_session_(s) __attribute__((section(s))) +#define _attribute_custom_code_ _attribute_session_(".custom") volatile +#define _attribute_no_inline_ __attribute__((noinline)) +#define _inline_ inline +#define _attribute_data_dlm_ _attribute_session_(".dlm_data")//dlm:Data Local Memory + + + +#if (BLC_PM_DEEP_RETENTION_MODE_EN) + #define _attribute_data_retention_sec_ __attribute__((section(".retention_data"))) + #define _attribute_data_retention_ __attribute__((section(".retention_data"))) + #define _attribute_ble_data_retention_ __attribute__((section(".retention_data"))) +#else + #define _attribute_data_retention_sec_ + #define _attribute_data_retention_ + #define _attribute_ble_data_retention_ +#endif + +#define _attribute_ram_code_ __attribute__((section(".ram_code"))) __attribute__((noinline)) + +#define _attribute_text_code_ __attribute__((section(".text"))) + +/// define the static keyword for this compiler +#define __STATIC static + +/// define the force inlining attribute for this compiler +#define __INLINE static __attribute__((__always_inline__)) inline + +/// define the IRQ handler attribute for this compiler +#define __IRQ __attribute__ ((interrupt ("machine"), aligned(4))) + +/// define the BLE IRQ handler attribute for this compiler +#define __BTIRQ + +/// define the BLE IRQ handler attribute for this compiler +#define __BLEIRQ + +/// define the FIQ handler attribute for this compiler +#define __FIQ __attribute__((__interrupt__("FIQ"))) + +/// define size of an empty array (used to declare structure with an array size not defined) +#define __ARRAY_EMPTY + +/// Function returns struct in registers (4 in rvds, var with gnuarm). +/// With Gnuarm, feature depends on command line options and +/// impacts ALL functions returning 2-words max structs +/// (check -freg-struct-return and -mabi=xxx) +#define __VIR + +/// function has no side effect and return depends only on arguments +#define __PURE __attribute__((const)) + +/// Align instantiated lvalue or struct member on 4 bytes +#define __ALIGN4 __attribute__((aligned(4))) + +/// __MODULE__ comes from the RVDS compiler that supports it +#define __MODULE__ __BASE_FILE__ + + +/// Put a variable in a memory maintained during deep sleep +#define __LOWPOWER_SAVED + +#define ASSERT_ERR(x) + +#endif diff --git a/b91/b91m_ble_sdk/common/config/user_config.h b/b91/b91m_ble_sdk/common/config/user_config.h new file mode 100755 index 0000000..510ec15 --- /dev/null +++ b/b91/b91m_ble_sdk/common/config/user_config.h @@ -0,0 +1,26 @@ +/******************************************************************************************************** + * @file user_config.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "vendor/common/user_config.h" + diff --git a/b91/b91m_ble_sdk/common/macro_trick.h b/b91/b91m_ble_sdk/common/macro_trick.h new file mode 100755 index 0000000..c832aa9 --- /dev/null +++ b/b91/b91m_ble_sdk/common/macro_trick.h @@ -0,0 +1,79 @@ +/******************************************************************************************************** + * @file macro_trick.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef COMMON_MACRO_TRICK_H_ +#define COMMON_MACRO_TRICK_H_ + +#pragma once + +///////////////// variadic macro //////////////////////// + +#if 1 +// a little more complex version that works with GCC and visual studio + +/// http://stackoverflow.com/questions/9183993/msvc-variadic-macro-expansion +#define COUNT_ARGS_IMPL2(_1, _2, _3, _4, _5, _6, _7, _8 , _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N +#define COUNT_ARGS_IMPL(args) COUNT_ARGS_IMPL2 args +#define COUNT_ARGS(...) COUNT_ARGS_IMPL((__VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) + +#define MACRO_CHOOSE_HELPER2(base, count) base##count +#define MACRO_CHOOSE_HELPER1(base, count) MACRO_CHOOSE_HELPER2(base, count) +#define MACRO_CHOOSE_HELPER(base, count) MACRO_CHOOSE_HELPER1(base, count) + +#define MACRO_GLUE(x, y) x y +#define VARARG(base, ...) MACRO_GLUE(MACRO_CHOOSE_HELPER(base, COUNT_ARGS(__VA_ARGS__)),(__VA_ARGS__)) +// usage +/* + #define fun1(a) xxxx + #define fun2(a, b) xxxx + #define fun3(a, b, c) xxxx + + #define fun(...) VARARG(fun, __VA_ARGS__) + + int main(){ + fun(1); // calls fun1(1) + fun(1, 2); // calls fun2(1,2) + fun(1, 2, 3); // calls fun3(1,2,3) + } + +*/ + + +#else +// a concise version that only works with GCC + +/// http://stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments + +#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8 , _9, _10, N, ...) N +#define VA_NARGS(...) VA_NARGS_IMPL(X,##__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +#define VARARG_IMPL2(base, count, ...) base##count(__VA_ARGS__) +#define VARARG_IMPL(base, count, ...) VARARG_IMPL2(base, count, __VA_ARGS__) +#define VARARG(base, ...) VARARG_IMPL(base, VA_NARGS(__VA_ARGS__), __VA_ARGS__) + +#endif +// #define NUMARGS(...) (sizeof((int[]){__VA_ARGS__})/sizeof(int)) + +///////////////// end of variadic macro ////////////////////// + + + +#endif /* COMMON_MACRO_TRICK_H_ */ diff --git a/b91/b91m_ble_sdk/common/static_assert.h b/b91/b91m_ble_sdk/common/static_assert.h new file mode 100755 index 0000000..b54695b --- /dev/null +++ b/b91/b91m_ble_sdk/common/static_assert.h @@ -0,0 +1,42 @@ +/******************************************************************************************************** + * @file static_assert.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#pragma once + +// static assertion. evaluate at compile time. It is very useful like, STATIC_ASSERT(sizeof(a) == 5); + +// #define STATIC_ASSERT(expr) { char static_assertion[(expr) ? 1 : -1]; ((void) static_assertion); } // (void) array; to remove compiler unused variable warning + +// more complicated version canbe used anywhere in the source +#define STATIC_ASSERT_M(COND,MSG) typedef char static_assertion_##MSG[(!!(COND))*2-1] +// token pasting madness: +#define STATIC_ASSERT3(X,L) STATIC_ASSERT_M(X,static_assertion_at_line_##L) +#define STATIC_ASSERT2(X,L) STATIC_ASSERT3(X,L) + +#define STATIC_ASSERT(X) STATIC_ASSERT2(X,__LINE__) + +#define STATIC_ASSERT_POW2(expr) STATIC_ASSERT(!((expr) & ((expr)-1))) // assert expr is 2**N +#define STATIC_ASSERT_EVEN(expr) STATIC_ASSERT(!((expr) & 1)) +#define STATIC_ASSERT_ODD(expr) STATIC_ASSERT(((expr) & 1)) +#define STATIC_ASSERT_INT_DIV(a, b) STATIC_ASSERT((a) / (b) * (b) == (a)) + diff --git a/b91/b91m_ble_sdk/common/types.h b/b91/b91m_ble_sdk/common/types.h new file mode 100755 index 0000000..406efb8 --- /dev/null +++ b/b91/b91m_ble_sdk/common/types.h @@ -0,0 +1,99 @@ +/******************************************************************************************************** + * @file types.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include + + +typedef unsigned char u8 ; + +typedef signed char s8; + +typedef unsigned short u16; + +typedef signed short s16; + +typedef int s32; + +typedef unsigned int u32; + +typedef long long s64; + +typedef unsigned long long u64; + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef __cplusplus + +//typedef u8 bool; + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +//#define false FALSE +//#define true TRUE + +#endif + +// There is no way to directly recognise whether a typedef is defined +// http://stackoverflow.com/questions/3517174/how-to-check-if-a-datatype-is-defined-with-typedef +#ifdef __GNUC__ +//typedef u16 wchar_t; +#endif + +#ifndef WIN32 +typedef u32 size_t; +#endif + +#define U32_MAX ((u32)0xffffffff) +#define U16_MAX ((u16)0xffff) +#define U8_MAX ((u8)0xff) +#define U31_MAX ((u32)0x7fffffff) +#define U15_MAX ((u16)0x7fff) +#define U7_MAX ((u8)0x7f) + + +#ifdef WIN32 +# ifndef FALSE +# define FALSE 0 +# endif + +# ifndef TRUE +# define TRUE 1 +# endif +#endif + +#define SUCCESS 0x00 +#define FAILURE 0x01 + +typedef u32 UTCTime; +typedef u32 arg_t; +typedef u32 status_t; + + diff --git a/b91/b91m_ble_sdk/common/usb_dbg/SConscript b/b91/b91m_ble_sdk/common/usb_dbg/SConscript new file mode 100755 index 0000000..72fe398 --- /dev/null +++ b/b91/b91m_ble_sdk/common/usb_dbg/SConscript @@ -0,0 +1,19 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') +CPPPATH = [cwd] + +# remove no need file. +#if GetDepend('RT_USING_LWIP') == False: +# SrcRemove(src, 'stm32f2_eth.c') +#if GetDepend('RT_USING_DFS') == False: +# SrcRemove(src, 'sdio_sd.c') + +#remove other no use files +#SrcRemove(src, 'FM25Lx.c') +#SrcRemove(src, '24LCxx.c') + +group = DefineGroup('usb_dbg', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/b91/b91m_ble_sdk/common/usb_dbg/log_def_stack.h b/b91/b91m_ble_sdk/common/usb_dbg/log_def_stack.h new file mode 100755 index 0000000..a16307e --- /dev/null +++ b/b91/b91m_ble_sdk/common/usb_dbg/log_def_stack.h @@ -0,0 +1,95 @@ +/******************************************************************************************************** + * @file log_def_stack.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef _LOG_DEF_STACK_H_ +#define _LOG_DEF_STACK_H_ + +// event: 0 for time stamp; 1 reserved; eid2 - eid31 +#define SLEV_timestamp 0 +#define SLEV_reserved 1 +#define SLEV_slot 2 +#define SLEV_btrx 3 +#define SLEV_set_clkn_fcnt 4 +#define SLEV_rx_lmp 5 +#define SLEV_rx_acl 6 +#define SLEV_tx_tgl 7 +#define SLEV_host_conn_req 8 +#define SLEV_set_em 9 +#define SLEV_rx_end 10 +#define SLEV_tx_lmp 11 +#define SLEV_tx_acl 12 +#define SLEV_tx_lmp_full 13 +#define SLEV_tx_acl_full 14 +#define SLEV_tx_hci_full 15 +#define SLEV_sniff_slot_start 16 +#define SLEV_sniff_sub_slot_update 17 +#define SLEV_sniff_sub_start 18 +#define SLEV_sniff_transition 19 +#define SLEV_name_req 20 +#define SLEV_inq_timeout 21 +#define SLEV_page_timeout 22 +#define SLEV_pageresp_timeout 23 +#define SLEV_newconnect_timeout 24 + +// 1-bit data: 0/1 for hardware signal: PA4/PB1; bid2 - bid31 +#define SL01_TX_PA4 0 +#define SL01_RXSYNC_PB1 1 +#define SL01_ac_inq 2 +#define SL01_ac_inq_scan 3 +#define SL01_ac_page 4 +#define SL01_ac_page_scan 5 +#define SL01_ac_m_connect 6 +#define SL01_ac_s_connect 7 + +#define SL01_task_system_tick 8 +#define SL01_task_rx 9 +#define SL01_tx_tgl_level 10 +#define SL01_task_bt_ll_main 11 +#define SL01_task_test 12 +#define SL01_detach_timeout 13 +// 8-bit data: cid0 - cid63 +#define SL08_ac_state 0 +#define SL08_state_pending_slot 1 +#define SL08_rx_lmp_code 2 +#define SL08_rx_poll_fcnt 3 +#define SL08_rx_poll_offset 4 +#define SL08_rx_poll_rxbit 5 +#define SL08_lmp_esc4 6 +#define SL08_acl_tx_type 7 + +#define SL08_hci_wptr 8 +#define SL08_hci_rptr 9 +#define SL08_valid_range 10 +// 16-bit data: sid0 - sid63 +#define SL16_CLKN 0 +#define SL16_FCNT 1 +#define SL16_MCLK 2 +#define SL16_MCLKP 3 +#define SL16_RXBIT 4 +#define SL16_RxStat 5 +#define SL16_LNKCNTL 6 +#define SL16_acl_tx_size 7 +#define SL16_rx_acl_cid 8 +#define SL16_sniff_slot 9 +#define SL16_sniff_win 10 +#define SL16_sub_instant 11 +#endif diff --git a/b91/b91m_ble_sdk/common/usb_dbg/myudb.h b/b91/b91m_ble_sdk/common/usb_dbg/myudb.h new file mode 100755 index 0000000..1e9aba2 --- /dev/null +++ b/b91/b91m_ble_sdk/common/usb_dbg/myudb.h @@ -0,0 +1,149 @@ +/******************************************************************************************************** + * @file myudb.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef __MYUDB_H__ +#define __MYUDB_H__ +#pragma once + +#include "log_def_stack.h" +#include "common/config/user_config.h" + +/* Trace global enable macro */ +#ifndef VCD_EN +#define VCD_EN 0 +#endif +/* USB print log enable macro */ +#ifndef DUMP_STR_EN +#define DUMP_STR_EN 0 +#endif + + +#define SL_STACK_EN 0 + + +#if (DUMP_STR_EN) + #define my_usb_init(id, p_print) myudb_usb_init(id, p_print) + #define usb_send_str(s) usb_send_str_data(s, 0, 0) + #define usb_send_data(p,n) usb_send_str_data(0,p,n) + #define my_dump_str_data(en,s,p,n) if(en){usb_send_str_data(s,(u8*)(p),n);} + #define my_dump_str_u32s(en,s,d0,d1,d2,d3) if(en){usb_send_str_u32s(s,(u32)(d0),(u32)(d1),(u32)(d2),(u32)(d3));} + #define my_uart_send_str_data usb_send_str_data + #define my_uart_send_str_int usb_send_str_int + #define myudb_usb_handle_irq() udb_usb_handle_irq() +#else + #define my_usb_init(id, p_print) + #define usb_send_str(s) + #define usb_send_data(p,n) + #define my_dump_str_data(en,s,p,n) + #define my_dump_str_u32s(en,s,d0,d1,d2,d3) + #define my_uart_send_str_data + #define my_uart_send_str_int + #define myudb_usb_handle_irq() +#endif + + + +typedef int (*func_myudb_hci_cmd_cb_t) (unsigned char *, int); + +void myudb_register_hci_cb (void *p); +void myudb_register_hci_debug_cb (void *p); + +void myudb_usb_init(u16 id, void * p_print); + +void myudb_usb_bulkout_ready (); + +void udb_usb_handle_irq(void); + +void usb_send_status_pkt(u8 status, u8 buffer_num, u8 *pkt, u16 len); + +void myudb_capture_enable (int en); + +void usb_send_str_data (char *str, u8 *ph, int n); + +void usb_send_str_u32s (char *str, u32 d0, u32 d1, u32 d2, u32 d3); + +void usb_send_upper_tester_result (u8 err); + +#define my_irq_disable() u32 rie = core_interrupt_disable () +#define my_irq_restore() core_restore_interrupt(rie) +#define LOG_EVENT_TIMESTAMP 0 +#define LOG_DATA_B1_0 0 +#define LOG_DATA_B1_1 1 + +//#define get_systemtick() (clock_time()*3/2) +#define get_systemtick() stimer_get_tick() + +//#define log_uart(d) uart_send_byte_dma(0,d) +#define log_uart(d) reg_usb_ep8_dat=d + +#define DEBUG_PORT GPIO_PB2 +#define log_ref_gpio_h() gpio_set_high_level(DEBUG_PORT) +#define log_ref_gpio_l() gpio_set_low_level(DEBUG_PORT) + + +#define log_hw_ref() if(VCD_EN){my_irq_disable();log_ref_gpio_h();log_uart(0x20);int t=get_systemtick();log_uart(t);log_uart(t>>8);log_uart(t>>16);log_ref_gpio_l();my_irq_restore();} + +// 4-byte sync word: 00 00 00 00 +#define log_sync(en) if(VCD_EN && en) {my_irq_disable();log_uart(0);log_uart(0);log_uart(0);log_uart(0);my_irq_restore();} +//4-byte (001_id-5bits) id0: timestamp align with hardware gpio output; id1-31: user define +#define log_tick(en,id) if(VCD_EN && en) {my_irq_disable();log_uart(0x20|(id&31));int t=get_systemtick();log_uart(t);log_uart(t>>8);log_uart(t>>16);my_irq_restore();} + +//1-byte (000_id-5bits) +#define log_event(en,id) if(VCD_EN && en) {my_irq_disable();log_uart(0x00|(id&31));my_irq_restore();} + +//1-byte (01x_id-5bits) 1-bit data: id0 & id1 reserved for hardware +#define log_task(en,id,b) if(VCD_EN && en) {my_irq_disable();log_uart(((b)?0x60:0x40)|(id&31));int t=get_systemtick();log_uart(t);log_uart(t>>8);log_uart(t>>16);my_irq_restore();} + +//2-byte (10-id-6bits) 8-bit data +#define log_b8(en,id,d) if(VCD_EN && en) {my_irq_disable();log_uart(0x80|(id&63));log_uart(d);my_irq_restore();} + +//3-byte (11-id-6bits) 16-bit data +#define log_b16(en,id,d) if(VCD_EN && en) {my_irq_disable();log_uart(0xc0|(id&63));log_uart(d);log_uart((d)>>8);my_irq_restore();} + + + + +#define log_tick_irq(en,id) if(VCD_EN && en) {log_uart(0x20|(id));int t=get_systemtick();log_uart(t);log_uart(t>>8);log_uart(t>>16);} +#define log_tick_irq_2(en,id,t) if(VCD_EN && en) {log_uart(0x20|(id));log_uart(t);log_uart(t>>8);log_uart(t>>16);} + + +#define log_event_irq(en,id) if(VCD_EN && en) {log_uart(0x00|(id));} + + +#define log_task_irq(en,id,b) if(VCD_EN && en) {log_uart(((b)?0x60:0x40)|(id));int t=get_systemtick();log_uart(t);log_uart(t>>8);log_uart(t>>16);} + +#define log_task_begin_irq(en,id) if(VCD_EN && en) {log_uart(0x60|(id));int t=get_systemtick();log_uart(t);log_uart(t>>8);log_uart(t>>16);} +#define log_task_end_irq(en,id) if(VCD_EN && en) {log_uart(0x40|(id));int t=get_systemtick();log_uart(t);log_uart(t>>8);log_uart(t>>16);} + +#define log_task_begin_irq_2(en,id,t) if(VCD_EN && en) {log_uart(0x60|(id));log_uart(t);log_uart(t>>8);log_uart(t>>16);} +#define log_task_end_irq_2(en,id,t) if(VCD_EN && en) {log_uart(0x40|(id));log_uart(t);log_uart(t>>8);log_uart(t>>16);} + + + +#define log_b8_irq(en,id,d) if(VCD_EN && en) {log_uart(0x80|(id));log_uart(d);} + +#define log_b16_irq(en,id,d) if(VCD_EN && en) {log_uart(0xc0|(id));log_uart(d);log_uart((d)>>8);} + + + + +#endif diff --git a/b91/b91m_ble_sdk/common/usb_dbg/myudb_usb.c b/b91/b91m_ble_sdk/common/usb_dbg/myudb_usb.c new file mode 100755 index 0000000..aa383c3 --- /dev/null +++ b/b91/b91m_ble_sdk/common/usb_dbg/myudb_usb.c @@ -0,0 +1,694 @@ +/******************************************************************************************************** + * @file myudb_usb.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "drivers.h" +#include "myudb.h" +#include "myudb_usbdesc.h" +#include "common/utility.h" +#include + +#if (VCD_EN || DUMP_STR_EN) + + + +typedef struct myudb_cfg +{ + u16 id; + u16 response_len; + + u8* response; + u32 tick_sync; + + u8 stall; + u8 rptr; + u16 cmd_len; + +} myudb_cfg_t; + +myudb_cfg_t myudb = {0x120}; + +static USB_Request_Header_t control_request; + + + +my_fifo_t *myudb_print_fifo = 0; + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// USB device handling +//----------------------------------------------------------------------------------------- +enum { + MYUDB_USB_IRQ_SETUP_REQ = 0, + MYUDB_USB_IRQ_DATA_REQ, +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +//----------------------------------------------------------------------------------------- +void myudb_usb_send_response(void) { + u16 n; + if (myudb.response_len < 8) { + n = myudb.response_len; + } else { + n = 8; + } + myudb.response_len -= n; + usbhw_reset_ctrl_ep_ptr(); + while (n-- > 0) { + usbhw_write_ctrl_ep_data(*myudb.response); + ++myudb.response; + } +} + +void myudb_usb_prepare_desc_data(void) { + u8 value_l = (control_request.wValue) & 0xff; + u8 value_h = (control_request.wValue >> 8) & 0xff; + + myudb.response = 0; + myudb.response_len = 0; + + switch (value_h) { + + case DTYPE_Device: + myudb.response = myudb_usbdesc_get_device(); + myudb.response_len = sizeof(USB_Descriptor_Device_t); + break; + + case DTYPE_Configuration: + myudb.response = myudb_usbdesc_get_configuration(); + myudb.response_len = sizeof(MYUDB_USB_Descriptor_Configuration_t); + break; + + case DTYPE_String: + if (MYUDB_USB_STRING_LANGUAGE == value_l) { + myudb.response = myudb_usbdesc_get_language(); + myudb.response_len = sizeof(LANGUAGE_ID_ENG); + } else if (MYUDB_USB_STRING_VENDOR == value_l) { + myudb.response = myudb_usbdesc_get_vendor(); + myudb.response_len = sizeof (MYUDB_STRING_VENDOR); + } else if (MYUDB_USB_STRING_PRODUCT == value_l) { + myudb.response = myudb_usbdesc_get_product(); + myudb.response_len = sizeof(MYUDB_STRING_PRODUCT); + } else if (MYUDB_USB_STRING_SERIAL == value_l) { + myudb.response = myudb_usbdesc_get_serial(); + myudb.response_len = sizeof(MYUDB_STRING_SERIAL); + } else { + myudb.stall = 1; + } + break; + + default: + myudb.stall = 1; + break; + + } + + if (control_request.wLength < myudb.response_len) { + myudb.response_len = control_request.wLength; + } + + return; +} + +void myudb_usb_handle_in_class_intf_req() { + u8 property = control_request.bRequest; + switch (property) { + case 0x00: + usbhw_write_ctrl_ep_data(0x00); + break; + default: + myudb.stall = 1; + break; + } + +} + +void myudb_usb_handle_request(u8 data_request) { + u8 bmRequestType = control_request.bmRequestType; + u8 bRequest = control_request.bRequest; + + usbhw_reset_ctrl_ep_ptr(); + switch (bmRequestType) { + case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE): + if (REQ_GetDescriptor == bRequest) { + if (MYUDB_USB_IRQ_SETUP_REQ == data_request) { + myudb_usb_prepare_desc_data(); + } + myudb_usb_send_response(); + } + break; + case (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE): + myudb_usb_handle_in_class_intf_req(); + break; + case (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_INTERFACE): + if (MYUDB_USB_IRQ_SETUP_REQ == data_request) { + if (0xc0 == bRequest) { // Get board version + usbhw_reset_ctrl_ep_ptr(); + usbhw_write_ctrl_ep_data(myudb.id); + usbhw_write_ctrl_ep_data(myudb.id >> 8); + } + else + { + myudb.stall = 1; + } + } + break; + case (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_DEVICE): // 0xc0 + if (MYUDB_USB_IRQ_SETUP_REQ == data_request) { + if (0xc0 == bRequest) { // Get board version + usbhw_reset_ctrl_ep_ptr(); + usbhw_write_ctrl_ep_data(0x40); + usbhw_write_ctrl_ep_data(0x25); + usbhw_write_ctrl_ep_data(0x40); + usbhw_write_ctrl_ep_data(0x05); + usbhw_write_ctrl_ep_data(0x03); + usbhw_write_ctrl_ep_data(0x00); + usbhw_write_ctrl_ep_data(0x01); + usbhw_write_ctrl_ep_data(0x00); + } + else if (0xc6 == bRequest) { // + usbhw_reset_ctrl_ep_ptr(); + usbhw_write_ctrl_ep_data(0x04); + } + else + { + myudb.stall = 1; + } + } + break; + case (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | REQREC_DEVICE): // 0x40 + myudb.stall = 1; + break; + default: + myudb.stall = 1; + break; + } + + return; +} + +void myudb_usb_handle_ctl_ep_setup() { + usbhw_reset_ctrl_ep_ptr(); + control_request.bmRequestType = usbhw_read_ctrl_ep_data(); + control_request.bRequest = usbhw_read_ctrl_ep_data(); + control_request.wValue = usbhw_read_ctrl_ep_u16(); + control_request.wIndex = usbhw_read_ctrl_ep_u16(); + control_request.wLength = usbhw_read_ctrl_ep_u16(); + myudb.stall = 0; + myudb_usb_handle_request(MYUDB_USB_IRQ_SETUP_REQ); + if (myudb.stall) + usbhw_write_ctrl_ep_ctrl(FLD_EP_DAT_STALL); + else + usbhw_write_ctrl_ep_ctrl(FLD_EP_DAT_ACK); +} + +void myudb_usb_handle_ctl_ep_data(void) { + usbhw_reset_ctrl_ep_ptr(); + myudb.stall = 0; + myudb_usb_handle_request(MYUDB_USB_IRQ_DATA_REQ); + if (myudb.stall) + usbhw_write_ctrl_ep_ctrl(FLD_EP_DAT_STALL); + else + usbhw_write_ctrl_ep_ctrl(FLD_EP_DAT_ACK); +} + +void myudb_usb_handle_ctl_ep_status() { + if (myudb.stall) + usbhw_write_ctrl_ep_ctrl(FLD_EP_STA_STALL); + else + usbhw_write_ctrl_ep_ctrl(FLD_EP_STA_ACK); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +_attribute_ram_code_ int myudb_print_fifo_full (void) +{ + u8 n = myudb_print_fifo->wptr - myudb_print_fifo->rptr; + return n >= myudb_print_fifo->num; +} + +_attribute_ram_code_ void usb_send_status_pkt(u8 status, u8 buffer_num, u8 *pkt, u16 len) +{ +// if (myudb_print_fifo_full()) return; //skip if overflow + + u8 *p = myudb_print_fifo->p + (myudb_print_fifo->wptr & (myudb_print_fifo->num - 1)) * myudb_print_fifo->size; + if (len > 272) + { + len = 272; + } + *p++ = len + 2; + *p++ = (len + 2) >> 8; + p += 2; + *p++ = status; + *p++ = buffer_num; + while (len--) + { + *p++ = *pkt++; + } + myudb_print_fifo->wptr++; +} + +_attribute_ram_code_ void usb_send_str_data (char *str, u8 *ph, int n) +{ +// if (myudb_print_fifo_full()) return; //skip if overflow + u32 rie = core_interrupt_disable (); + u8 *ps = myudb_print_fifo->p + (myudb_print_fifo->wptr & (myudb_print_fifo->num - 1)) * myudb_print_fifo->size;; + u8 *pd = ps; + + int ns = str ? strlen (str) : 0; + if (ns > myudb_print_fifo->size - 12) + { + ns = myudb_print_fifo->size - 12; + n = 0; + } + if (n + ns > myudb_print_fifo->size - 12) + { + n = myudb_print_fifo->size - 12 - ns; + } + + int len = n + ns + 2 + 3; + *pd++ = len; + *pd++ = len >> 8; + *pd++ = 0; + *pd++ = 0; + *pd++ = 0x82; + *pd++ = 8; + + *pd++ = 0x22; + *pd++ = n; + *pd++ = n >> 8; + + while (n--) + { + *pd++ = *ph++; + } + while (ns--) + { + *pd++ = *str++; + } + myudb_print_fifo->wptr++; + core_restore_interrupt(rie); +} + +_attribute_ram_code_ void usb_send_str_u32s (char *str, u32 d0, u32 d1, u32 d2, u32 d3) +{ + u32 d[4]; + d[0] = d0; + d[1] = d1; + d[2] = d2; + d[3] = d3; + usb_send_str_data (str, (u8*)d, 16); +} + +_attribute_ram_code_ void myudb_to_usb() +{ + static u16 len = 0; + static u8 *p = 0; + + if(usbhw_is_ep_busy(MYUDB_EDP_IN_HCI)) return; + if (!p && (myudb_print_fifo->wptr != myudb_print_fifo->rptr)) //first packet + { + p = myudb_print_fifo->p + (myudb_print_fifo->rptr++ & (myudb_print_fifo->num - 1)) * myudb_print_fifo->size;; + //len = p[1] + 3; + len = p[0] + p[1] * 256; + p += 4; + } + if (p) + { + int n = len < 64 ? len : 64; + usbhw_reset_ep_ptr(MYUDB_EDP_IN_HCI); + for (int i=0; ip + (myudb_print_fifo->wptr & (myudb_print_fifo->num-1)) * myudb_print_fifo->size; + len = n + 2 + 1 + 1 + int_len; //str_len + '0x20' + symbol + int_len + *pd++ = len ; + *pd++ = len >> 8; + + + *pd++ = 0; + *pd++ = 0; + *pd++ = 0x82; + *pd++ = 8; + + *pd++ = 0x20; + while (n--) + { + *pd++ = *str++; + } + *pd++ = symbol; + while(int_len--) + { + *pd++ = *p++; + } + myudb_print_fifo->wptr++; + core_restore_interrupt(rie); + return len; +} + + +#define USB_ENDPOINT_BULK_OUT_FLAG (1 << (MYUDB_EDP_OUT_HCI & 7)) + +_attribute_ram_code_ int myudb_usb_get_packet (u8 *p) +{ + if (reg_usb_irq & USB_ENDPOINT_BULK_OUT_FLAG) + { + //clear interrupt flag + reg_usb_irq = USB_ENDPOINT_BULK_OUT_FLAG; + + // read data + int n = reg_usb_ep_ptr(MYUDB_EDP_OUT_HCI); + reg_usb_ep_ptr(MYUDB_EDP_OUT_HCI) = 0; + for (int i=0; i= 8) + { + usb_send_status_pkt (0x81, 8, p, 12); + rsp[0] = 0x29; + memcpy (rsp + 1, p + 1, 5); + int type = p[1]; + u32 adr = p[2] | (p[3] << 8) | (p[4] << 16) | (p[5] << 24); + int n = p[6] | (p[7] << 8); + if (n > 256) + { + n = 256; + } + + if (type == 0) + { + memcpy (rsp + 6, (void *)(adr | 0), n); + } + else if (type == 1) + { + for (int i=0; i 6) + { + usb_send_status_pkt (0x81, 8, p, 12); + rsp[0] = 0x2b; + memcpy (rsp + 1, p + 1, 16); + u8 type = p[1]; + u32 adr = p[2] | (p[3] << 8) | (p[4] << 16) | (p[5] << 24); + int n = len - 6; + + if (type == 0) //RAM + { + memcpy ((void *)adr, p + 6, n); + } + else if (type == 1) //Analog Register + { + for (int i=0; i 1) + nb += p[7] << 8; + if (n > 2) + nb += p[8] << 16; + if (n > 3) + nb += p[9] << 24; + + if (nb) + { + for (int i=0; irptr = myudb_print_fifo->wptr; + + //extern void hci_txfifo_set_rptr_reference (int idx); + //hci_txfifo_set_rptr_reference (1); + + ret = MYHCI_FW_DOWNLOAD; + } + usb_send_status_pkt (0x82, 8, rsp, 14); + } + else + { + ret = 1; + } + return ret; +} + +u8 buff_usb_cmd[320]; +_attribute_ram_code_ int myudb_hci_cmd_from_usb (void) +{ + fw_download = 0; + do + { + int n = myudb_usb_get_packet (buff_usb_cmd); + if (n) + { + int r = myudb_mem_cmd(buff_usb_cmd, n); + + if (r == MYHCI_FW_DOWNLOAD) + { + fw_download = MYHCI_FW_DOWNLOAD; + } + else if (0x11 == buff_usb_cmd[0] && myudb_hci_debug_cb && !fw_download) + { + myudb_hci_debug_cb (buff_usb_cmd, n); + } + else if (r && myudb_hci_cmd_cb && !fw_download) + { + myudb_hci_cmd_cb (buff_usb_cmd, n); + } + } + if (fw_download) + { + myudb_to_usb (); + } + } while (fw_download); + + return 0; +} + +///////////////////////////////////////////////////////////////////////// +void udb_usb_handle_irq(void) { + if(1){ // do nothing when in suspend. Maybe not unnecessary + u32 irq = usbhw_get_ctrl_ep_irq(); + if (irq & FLD_CTRL_EP_IRQ_SETUP) { + usbhw_clr_ctrl_ep_irq(FLD_CTRL_EP_IRQ_SETUP); + myudb_usb_handle_ctl_ep_setup(); + if (!myudb.tick_sync) + { + myudb.tick_sync = clock_time () | 1; + } + } + if (irq & FLD_CTRL_EP_IRQ_DATA) { + usbhw_clr_ctrl_ep_irq(FLD_CTRL_EP_IRQ_DATA); + myudb_usb_handle_ctl_ep_data(); + } + if (irq & FLD_CTRL_EP_IRQ_STA) { + usbhw_clr_ctrl_ep_irq(FLD_CTRL_EP_IRQ_STA); + myudb_usb_handle_ctl_ep_status(); + } + + if (reg_usb_irq_mask & FLD_USB_IRQ_RESET_O) + { + reg_usb_irq_mask |= FLD_USB_IRQ_RESET_O; //Clear USB reset flag + myudb_usb_bulkout_ready (); + } + myudb.stall = 0; + } + + myudb_to_usb (); + + myudb_hci_cmd_from_usb (); + + if (myudb.tick_sync && clock_time_exceed (myudb.tick_sync, 10000)) + { + myudb.tick_sync = clock_time () | 1; + log_sync (SL_STACK_EN); + } +} + +void myudb_usb_bulkout_ready () +{ + reg_usb_ep_ctrl (MYUDB_EDP_OUT_HCI) = FLD_EP_DAT_ACK; +} + +void myudb_usb_init(u16 id, void * p_print) +{ + if (!myudb_print_fifo) + { + myudb_print_fifo = p_print; + } + + + myudb_print_fifo->wptr = myudb_print_fifo->rptr = 0; + + memset (&myudb, 0, sizeof (myudb)); + + myudb.id = id; + //reg_usb_mask = BIT(7); //audio in interrupt enable + //reg_irq_mask |= FLD_IRQ_IRQ4_EN; + reg_usb_ep_max_size = (128 >> 2); + reg_usb_ep8_send_thre = 0x40; + reg_usb_ep8_send_max = 128 >> 3; + reg_usb_ep_buf_addr (MYUDB_EDP_IN_HCI) = 128; + reg_usb_ep_buf_addr (MYUDB_EDP_OUT_HCI) = 192; + reg_usb_ep_buf_addr (MYUDB_EDP_IN_VCD) = 0; + reg_usb_ep8_fifo_mode = 1; + reg_usb_mdev &= ~BIT(3); //vendor command: bRequest[7] = 0 + + usbhw_enable_manual_interrupt(FLD_CTRL_EP_AUTO_STD | FLD_CTRL_EP_AUTO_DESC); + + myudb_usb_bulkout_ready (); + usbhw_data_ep_ack(MYUDB_EDP_IN_HCI); //add log 1st log info +} + + + +_attribute_ram_code_ void usb_send_upper_tester_result (u8 err) +{ + u32 rie = core_interrupt_disable (); + u8 *ps = myudb_print_fifo->p + (myudb_print_fifo->wptr & (myudb_print_fifo->num - 1)) * myudb_print_fifo->size;; + + *((u32 *)ps) = 3; + u8 *pd = (ps + 4); + + *pd++ = 0x04; //HCI_TYPE_EVENT; + *pd++ = 0xF0; //HCI_EVT_HT_ERR_FLAG; + *pd++ = err; + + myudb_print_fifo->wptr++; + core_restore_interrupt(rie); +} + +#endif ///ending of #if(VCD_EN || DUMP_STR_EN) + diff --git a/b91/b91m_ble_sdk/common/usb_dbg/myudb_usbdesc.c b/b91/b91m_ble_sdk/common/usb_dbg/myudb_usbdesc.c new file mode 100755 index 0000000..78d1b1b --- /dev/null +++ b/b91/b91m_ble_sdk/common/usb_dbg/myudb_usbdesc.c @@ -0,0 +1,164 @@ +/******************************************************************************************************** + * @file myudb_usbdesc.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#if(1) + +#include "drivers.h" +#include "myudb.h" +#include "myudb_usbdesc.h" + +// request parameters +/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests + * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate + * via the language ID table available at USB.org what languages the device supports for its string descriptors. + */ +static const USB_Descriptor_String_t language_desc = { { + sizeof(USB_Descriptor_Header_t) + 2, DTYPE_String }, + { LANGUAGE_ID_ENG } }; + +/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable + * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device + * Descriptor. + */ +static const USB_Descriptor_String_t vendor_desc = { { sizeof(USB_Descriptor_Header_t) + + sizeof(MYUDB_STRING_VENDOR) - 2, DTYPE_String }, // Header + MYUDB_STRING_VENDOR }; + +/** Product descriptor string. This is a Unicode string containing the product's details in human readable form, + * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device + * Descriptor. + */ +static const USB_Descriptor_String_t product_desc = { { + sizeof(USB_Descriptor_Header_t) + sizeof(MYUDB_STRING_PRODUCT) - 2, + DTYPE_String }, // Header + MYUDB_STRING_PRODUCT }; + +/** Serial number string. This is a Unicode string containing the device's unique serial number, expressed as a + * series of uppercase hexadecimal digits. + */ +static const USB_Descriptor_String_t serial_desc = { { sizeof(USB_Descriptor_Header_t) + + sizeof(MYUDB_STRING_SERIAL) - 2, DTYPE_String }, // Header + MYUDB_STRING_SERIAL }; + + +static const USB_Descriptor_Device_t device_desc = { { + sizeof(USB_Descriptor_Device_t), DTYPE_Device }, // Header + 0x0200, // USBSpecification, USB 2.0 + USB_CSCP_NoDeviceClass, // Class + USB_CSCP_NoDeviceSubclass, // SubClass + USB_CSCP_NoDeviceProtocol, // Protocol + 8, // Endpoint0Size, Maximum Packet Size for Zero Endpoint. Valid Sizes are 8, 16, 32, 64 + MYUDB_ID_VENDOR, // VendorID + MYUDB_ID_PRODUCT, // ProductID + MYUDB_ID_VERSION/*0x0100*/, // .ReleaseNumber + MYUDB_USB_STRING_VENDOR, // .ManufacturerStrIndex + MYUDB_USB_STRING_PRODUCT, // .ProductStrIndex + 0, // .SerialNumStrIndex, iSerialNumber + 1 }; + +static const MYUDB_USB_Descriptor_Configuration_t + configuration_desc = { + { + {sizeof(USB_Descriptor_Configuration_Header_t), + DTYPE_Configuration }, // Length, type + sizeof(MYUDB_USB_Descriptor_Configuration_t), // TotalLength: variable + 2, // NumInterfaces + 1, // Configuration index + NO_DESCRIPTOR, // Configuration String + USB_CONFIG_ATTR_RESERVED, // Attributes + USB_CONFIG_POWER_MA(100) // MaxPower = 100mA + }, + // printer_interface + { { sizeof(USB_Descriptor_Interface_t), DTYPE_Interface }, + 0, 0, // AlternateSetting + 2, // bNumEndpoints + PRNT_CSCP_PrinterClass, // bInterfaceclass ->Printer + PRNT_CSCP_PrinterSubclass, // bInterfaceSubClass -> Control + PRNT_CSCP_BidirectionalProtocol,// bInterfaceProtocol + NO_DESCRIPTOR // iInterface, same as iProduct in USB_Descriptor_Device_t, or else not working + }, + // printer_in_endpoint + { { sizeof(USB_Descriptor_Endpoint_t), DTYPE_Endpoint }, // length, bDescriptorType + ENDPOINT_DIR_IN | MYUDB_EDP_IN_HCI, // endpoint id + EP_TYPE_BULK, // endpoint type + 0x0040, // wMaxPacketSize + 0 // bInterval + }, + // printer_out_endpoint + { { sizeof(USB_Descriptor_Endpoint_t), DTYPE_Endpoint }, // length, bDescriptorType + MYUDB_EDP_OUT_HCI, // endpoint id + EP_TYPE_BULK, // endpoint type + 0x0040, // wMaxPacketSize + 0 // polling bInterval. valid for iso or interrupt type + }, + + // printer_interface + { { sizeof(USB_Descriptor_Interface_t), DTYPE_Interface }, + 1, 0, // AlternateSetting + 2, // bNumEndpoints + PRNT_CSCP_PrinterClass, // bInterfaceclass ->Printer + PRNT_CSCP_PrinterSubclass, // bInterfaceSubClass -> Control + PRNT_CSCP_BidirectionalProtocol,// bInterfaceProtocol + NO_DESCRIPTOR // iInterface, same as iProduct in USB_Descriptor_Device_t, or else not working + }, + // printer_in_endpoint + { { sizeof(USB_Descriptor_Endpoint_t), DTYPE_Endpoint }, // length, bDescriptorType + ENDPOINT_DIR_IN | MYUDB_EDP_IN_VCD, // endpoint id + EP_TYPE_BULK, // endpoint type + 0x0040, // wMaxPacketSize + 0 // bInterval + }, + // printer_out_endpoint + { { sizeof(USB_Descriptor_Endpoint_t), DTYPE_Endpoint }, // length, bDescriptorType + MYUDB_EDP_OUT_VCD, // endpoint id + EP_TYPE_BULK, // endpoint type + 0x0040, // wMaxPacketSize + 0 // polling bInterval. valid for iso or interrupt type + }, + }; + +u8* myudb_usbdesc_get_language(void) { + return (u8*) (&language_desc); +} + +u8* myudb_usbdesc_get_vendor(void) { + return (u8*) (&vendor_desc); +} + +u8* myudb_usbdesc_get_product(void) { + return (u8*) (&product_desc); +} +u8* myudb_usbdesc_get_serial(void) { + return (u8*) (&serial_desc); +} + +u8* myudb_usbdesc_get_device(void) { + return (u8*) (&device_desc); +} + +u8* myudb_usbdesc_get_configuration(void) { + return (u8*) (&configuration_desc); +} + +#endif + + diff --git a/b91/b91m_ble_sdk/common/usb_dbg/myudb_usbdesc.h b/b91/b91m_ble_sdk/common/usb_dbg/myudb_usbdesc.h new file mode 100755 index 0000000..ae7f8af --- /dev/null +++ b/b91/b91m_ble_sdk/common/usb_dbg/myudb_usbdesc.h @@ -0,0 +1,920 @@ +/******************************************************************************************************** + * @file myudb_usbdesc.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "drivers.h" + +#ifdef MYUDB_DISABLE +#else +#define MYUDB_ID_VENDOR 0x248a // for report +#define MYUDB_ID_PRODUCT 0x9218 +#define MYUDB_ID_VERSION 0x0101 +#define MYUDB_STRING_VENDOR L"Telink" +#define MYUDB_STRING_PRODUCT L"HCI_VCD Dongle" +#define MYUDB_STRING_SERIAL L"TLSR9218" + + +//////////////////////////////////////////////////////// + +/* Public Interface - May be used in end-application: */ +/* Macros: */ + /** Mask for the request type parameter, to indicate the direction of the request data (Host to Device + * or Device to Host). The result of this mask should then be compared to the request direction masks. + * + * \see \c REQDIR_* macros for masks indicating the request data direction. + */ + #define CONTROL_REQTYPE_DIRECTION 0x80 + + /** Mask for the request type parameter, to indicate the type of request (Device, Class or Vendor + * Specific). The result of this mask should then be compared to the request type masks. + * + * \see \c REQTYPE_* macros for masks indicating the request type. + */ + #define CONTROL_REQTYPE_TYPE 0x60 + + /** Mask for the request type parameter, to indicate the recipient of the request (Device, Interface + * Endpoint or Other). The result of this mask should then be compared to the request recipient + * masks. + * + * \see \c REQREC_* macros for masks indicating the request recipient. + */ + #define CONTROL_REQTYPE_RECIPIENT 0x1F + + /** \name Control Request Data Direction Masks */ + //@{ + /** Request data direction mask, indicating that the request data will flow from host to device. + * + * \see \ref CONTROL_REQTYPE_DIRECTION macro. + */ + #define REQDIR_HOSTTODEVICE (0 << 7) + + /** Request data direction mask, indicating that the request data will flow from device to host. + * + * \see \ref CONTROL_REQTYPE_DIRECTION macro. + */ + #define REQDIR_DEVICETOHOST (1 << 7) + //@} + + /** \name Control Request Type Masks */ + //@{ + /** Request type mask, indicating that the request is a standard request. + * + * \see \ref CONTROL_REQTYPE_TYPE macro. + */ + #define REQTYPE_STANDARD (0 << 5) + + /** Request type mask, indicating that the request is a class-specific request. + * + * \see \ref CONTROL_REQTYPE_TYPE macro. + */ + #define REQTYPE_CLASS (1 << 5) + + /** Request type mask, indicating that the request is a vendor specific request. + * + * \see \ref CONTROL_REQTYPE_TYPE macro. + */ + #define REQTYPE_VENDOR (2 << 5) + //@} + + /** \name Control Request Recipient Masks */ + //@{ + /** Request recipient mask, indicating that the request is to be issued to the device as a whole. + * + * \see \ref CONTROL_REQTYPE_RECIPIENT macro. + */ + #define REQREC_DEVICE (0 << 0) + + /** Request recipient mask, indicating that the request is to be issued to an interface in the + * currently selected configuration. + * + * \see \ref CONTROL_REQTYPE_RECIPIENT macro. + */ + #define REQREC_INTERFACE (1 << 0) + + /** Request recipient mask, indicating that the request is to be issued to an endpoint in the + * currently selected configuration. + * + * \see \ref CONTROL_REQTYPE_RECIPIENT macro. + */ + #define REQREC_ENDPOINT (2 << 0) + + /** Request recipient mask, indicating that the request is to be issued to an unspecified element + * in the currently selected configuration. + * + * \see \ref CONTROL_REQTYPE_RECIPIENT macro. + */ + #define REQREC_OTHER (3 << 0) + //@} + +/* Type Defines: */ + /** \brief Standard USB Control Request + * + * Type define for a standard USB control request. + * + * \see The USB 2.0 specification for more information on standard control requests. + */ + typedef struct + { + u8 bmRequestType; /**< Type of the request. */ + u8 bRequest; /**< Request command code. */ + u16 wValue; /**< wValue parameter of the request. */ + u16 wIndex; /**< wIndex parameter of the request. */ + u16 wLength; /**< Length of the data to transfer in bytes. */ + }USB_Request_Header_t; + +/* Enums: */ + /** Enumeration for the various standard request commands. These commands are applicable when the + * request type is \ref REQTYPE_STANDARD (with the exception of \ref REQ_GetDescriptor, which is always + * handled regardless of the request type value). + * + * \see Chapter 9 of the USB 2.0 Specification. + */ + enum USB_Control_Request_t + { + REQ_GetStatus = 0, /**< Implemented in the library for device and endpoint recipients. Passed + * to the user application for other recipients via the + * \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + REQ_ClearFeature = 1, /**< Implemented in the library for device and endpoint recipients. Passed + * to the user application for other recipients via the + * \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + REQ_SetFeature = 3, /**< Implemented in the library for device and endpoint recipients. Passed + * to the user application for other recipients via the + * \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + REQ_SetAddress = 5, /**< Implemented in the library for the device recipient. Passed + * to the user application for other recipients via the + * \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + REQ_GetDescriptor = 6, /**< Implemented in the library for device and interface recipients. Passed to the + * user application for other recipients via the + * \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + REQ_SetDescriptor = 7, /**< Not implemented in the library, passed to the user application + * via the \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + REQ_GetConfiguration = 8, /**< Implemented in the library for the device recipient. Passed + * to the user application for other recipients via the + * \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + REQ_SetConfiguration = 9, /**< Implemented in the library for the device recipient. Passed + * to the user application for other recipients via the + * \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + REQ_GetInterface = 10, /**< Not implemented in the library, passed to the user application + * via the \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + REQ_SetInterface = 11, /**< Not implemented in the library, passed to the user application + * via the \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + REQ_SynchFrame = 12, /**< Not implemented in the library, passed to the user application + * via the \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + }; + + /** Feature Selector values for Set Feature and Clear Feature standard control requests directed to the device, interface + * and endpoint recipients. + */ + enum USB_Feature_Selectors_t + { + FEATURE_SEL_EndpointHalt = 0x00, /**< Feature selector for Clear Feature or Set Feature commands. When + * used in a Set Feature or Clear Feature request this indicates that an + * endpoint (whose address is given elsewhere in the request) should have + * its stall condition changed. + */ + FEATURE_SEL_DeviceRemoteWakeup = 0x01, /**< Feature selector for Device level Remote Wakeup enable set or clear. + * This feature can be controlled by the host on devices which indicate + * remote wakeup support in their descriptors to selectively disable or + * enable remote wakeup. + */ + FEATURE_SEL_TestMode = 0x02, /**< Feature selector for Test Mode features, used to test the USB controller + * to check for incorrect operation. + */ + }; + + #define FEATURE_SELFPOWERED_ENABLED (1 << 0) + #define FEATURE_REMOTE_WAKEUP_ENABLED (1 << 1) +//////////////////////////////////////////////////////// + + +/* Public Interface - May be used in end-application: */ +/* Macros: */ +/** Indicates that a given descriptor does not exist in the device. This can be used inside descriptors + * for string descriptor indexes, or may be use as a return value for GetDescriptor when the specified + * descriptor does not exist. + */ +#define NO_DESCRIPTOR 0 + +/** Macro to calculate the power value for the configuration descriptor, from a given number of milliamperes. + * + * \param[in] mA Maximum number of milliamps the device consumes when the given configuration is selected. + */ +#define USB_CONFIG_POWER_MA(mA) ((mA) >> 1) + +/** Macro to calculate the Unicode length of a string with a given number of Unicode characters. + * Should be used in string descriptor's headers for giving the string descriptor's byte length. + * + * \param[in] UnicodeChars Number of Unicode characters in the string text. + */ +#define USB_STRING_LEN(UnicodeChars) (sizeof(USB_Descriptor_Header_t) + ((UnicodeChars) << 1)) + +/** String language ID for the English language. Should be used in \ref USB_Descriptor_String_t descriptors + * to indicate that the English language is supported by the device in its string descriptors. + */ +#define LANGUAGE_ID_ENG 0x0409 + +/** \name USB Configuration Descriptor Attribute Masks */ +//@{ +/** Mask for the reserved bit in the Configuration Descriptor's \c ConfigAttributes field, which must be set on all + * devices for historial purposes. + */ +#define USB_CONFIG_ATTR_RESERVED 0x80 +/** Can be masked with other configuration descriptor attributes for a \ref USB_Descriptor_Configuration_Header_t + * descriptor's \c ConfigAttributes value to indicate that the specified configuration can draw its power + * from the device's own power source. + */ +#define USB_CONFIG_ATTR_SELFPOWERED 0x40 + +/** Can be masked with other configuration descriptor attributes for a \ref USB_Descriptor_Configuration_Header_t + * descriptor's \c ConfigAttributes value to indicate that the specified configuration supports the + * remote wakeup feature of the USB standard, allowing a suspended USB device to wake up the host upon + * request. + */ +#define USB_CONFIG_ATTR_REMOTEWAKEUP 0x20 +//@} + +/** \name Endpoint Descriptor Attribute Masks */ +//@{ +/** Can be masked with other endpoint descriptor attributes for a \ref USB_Descriptor_Endpoint_t descriptor's + * \c Attributes value to indicate that the specified endpoint is not synchronized. + * + * \see The USB specification for more details on the possible Endpoint attributes. + */ +#define ENDPOINT_ATTR_NO_SYNC (0 << 2) + +/** Can be masked with other endpoint descriptor attributes for a \ref USB_Descriptor_Endpoint_t descriptor's + * \c Attributes value to indicate that the specified endpoint is asynchronous. + * + * \see The USB specification for more details on the possible Endpoint attributes. + */ +#define ENDPOINT_ATTR_ASYNC (1 << 2) + +/** Can be masked with other endpoint descriptor attributes for a \ref USB_Descriptor_Endpoint_t descriptor's + * \c Attributes value to indicate that the specified endpoint is adaptive. + * + * \see The USB specification for more details on the possible Endpoint attributes. + */ +#define ENDPOINT_ATTR_ADAPTIVE (2 << 2) + +/** Can be masked with other endpoint descriptor attributes for a \ref USB_Descriptor_Endpoint_t descriptor's + * \c Attributes value to indicate that the specified endpoint is synchronized. + * + * \see The USB specification for more details on the possible Endpoint attributes. + */ +#define ENDPOINT_ATTR_SYNC (3 << 2) +//@} + +/** \name Endpoint Descriptor Usage Masks */ +//@{ +/** Can be masked with other endpoint descriptor attributes for a \ref USB_Descriptor_Endpoint_t descriptor's + * \c Attributes value to indicate that the specified endpoint is used for data transfers. + * + * \see The USB specification for more details on the possible Endpoint usage attributes. + */ +#define ENDPOINT_USAGE_DATA (0 << 4) + +/** Can be masked with other endpoint descriptor attributes for a \ref USB_Descriptor_Endpoint_t descriptor's + * \c Attributes value to indicate that the specified endpoint is used for feedback. + * + * \see The USB specification for more details on the possible Endpoint usage attributes. + */ +#define ENDPOINT_USAGE_FEEDBACK (1 << 4) + +/** Can be masked with other endpoint descriptor attributes for a \ref USB_Descriptor_Endpoint_t descriptor's + * \c Attributes value to indicate that the specified endpoint is used for implicit feedback. + * + * \see The USB specification for more details on the possible Endpoint usage attributes. + */ +#define ENDPOINT_USAGE_IMPLICIT_FEEDBACK (2 << 4) +//@} + +/* Enums: */ +/** Enum for the possible standard descriptor types, as given in each descriptor's header. */ +enum USB_DescriptorTypes_t +{ + DTYPE_Device = 0x01, /**< Indicates that the descriptor is a device descriptor. */ + DTYPE_Configuration = 0x02, /**< Indicates that the descriptor is a configuration descriptor. */ + DTYPE_String = 0x03, /**< Indicates that the descriptor is a string descriptor. */ + DTYPE_Interface = 0x04, /**< Indicates that the descriptor is an interface descriptor. */ + DTYPE_Endpoint = 0x05, /**< Indicates that the descriptor is an endpoint descriptor. */ + DTYPE_DeviceQualifier = 0x06, /**< Indicates that the descriptor is a device qualifier descriptor. */ + DTYPE_Other = 0x07, /**< Indicates that the descriptor is of other type. */ + DTYPE_InterfacePower = 0x08, /**< Indicates that the descriptor is an interface power descriptor. */ + DTYPE_InterfaceAssociation = 0x0B, /**< Indicates that the descriptor is an interface association descriptor. */ + DTYPE_CSInterface = 0x24, /**< Indicates that the descriptor is a class specific interface descriptor. */ + DTYPE_CSEndpoint = 0x25, /**< Indicates that the descriptor is a class specific endpoint descriptor. */ +}; + +/** Enum for possible Class, Subclass and Protocol values of device and interface descriptors. */ +enum USB_Descriptor_ClassSubclassProtocol_t +{ + USB_CSCP_NoDeviceClass = 0x00, /**< Descriptor Class value indicating that the device does not belong + * to a particular class at the device level. + */ + USB_CSCP_NoDeviceSubclass = 0x00, /**< Descriptor Subclass value indicating that the device does not belong + * to a particular subclass at the device level. + */ + USB_CSCP_NoDeviceProtocol = 0x00, /**< Descriptor Protocol value indicating that the device does not belong + * to a particular protocol at the device level. + */ + USB_CSCP_VendorSpecificClass = 0xFF, /**< Descriptor Class value indicating that the device/interface belongs + * to a vendor specific class. + */ + USB_CSCP_VendorSpecificSubclass = 0xFF, /**< Descriptor Subclass value indicating that the device/interface belongs + * to a vendor specific subclass. + */ + USB_CSCP_VendorSpecificProtocol = 0xFF, /**< Descriptor Protocol value indicating that the device/interface belongs + * to a vendor specific protocol. + */ + USB_CSCP_IADDeviceClass = 0xEF, /**< Descriptor Class value indicating that the device belongs to the + * Interface Association Descriptor class. + */ + USB_CSCP_IADDeviceSubclass = 0x02, /**< Descriptor Subclass value indicating that the device belongs to the + * Interface Association Descriptor subclass. + */ + USB_CSCP_IADDeviceProtocol = 0x01, /**< Descriptor Protocol value indicating that the device belongs to the + * Interface Association Descriptor protocol. + */ +}; + +/* Type Defines: */ +/** \brief Standard USB Descriptor Header (LUFA naming conventions). + * + * Type define for all descriptors' standard header, indicating the descriptor's length and type. This structure + * uses LUFA-specific element names to make each element's purpose clearer. + * + * \see \ref USB_StdDescriptor_Header_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ +typedef struct +{ + u8 Size; /**< Size of the descriptor, in bytes. */ + u8 Type; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ +}USB_Descriptor_Header_t; + +/** \brief Standard USB Descriptor Header (USB-IF naming conventions). + * + * Type define for all descriptors' standard header, indicating the descriptor's length and type. This structure + * uses the relevant standard's given element names to ensure compatibility with the standard. + * + * \see \ref USB_Descriptor_Header_t for the version of this type with non-standard LUFA specific element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ +typedef struct +{ + u8 bLength; /**< Size of the descriptor, in bytes. */ + u8 bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ +}USB_StdDescriptor_Header_t; + +/** \brief Standard USB Device Descriptor (LUFA naming conventions). + * + * Type define for a standard Device Descriptor. This structure uses LUFA-specific element names to make each + * element's purpose clearer. + * + * \see \ref USB_StdDescriptor_Device_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ +typedef struct +{ + USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */ + + u16 USBSpecification; /**< BCD of the supported USB specification. */ + u8 Class; /**< USB device class. */ + u8 SubClass; /**< USB device subclass. */ + u8 Protocol; /**< USB device protocol. */ + + u8 Endpoint0Size; /**< Size of the control (address 0) endpoint's bank in bytes. */ + + u16 VendorID; /**< Vendor ID for the USB product. */ + u16 ProductID; /**< Unique product ID for the USB product. */ + u16 ReleaseNumber; /**< Product release (version) number. */ + + u8 ManufacturerStrIndex; /**< String index for the manufacturer's name. The + * host will request this string via a separate + * control request for the string descriptor. + * + * \note If no string supplied, use \ref NO_DESCRIPTOR. + */ + u8 ProductStrIndex; /**< String index for the product name/details. + * + * \see ManufacturerStrIndex structure entry. + */ + u8 SerialNumStrIndex; /**< String index for the product's globally unique hexadecimal + * serial number, in uppercase Unicode ASCII. + * + * \note On some microcontroller models, there is an embedded serial number + * in the chip which can be used for the device serial number. + * To use this serial number, set this to USE_INTERNAL_SERIAL. + * On unsupported devices, this will evaluate to 0 and will cause + * the host to generate a pseudo-unique value for the device upon + * insertion. + * + * \see ManufacturerStrIndex structure entry. + */ + u8 NumberOfConfigurations; /**< Total number of configurations supported by + * the device. + */ +}USB_Descriptor_Device_t; + +/** \brief Standard USB Device Descriptor (USB-IF naming conventions). + * + * Type define for a standard Device Descriptor. This structure uses the relevant standard's given element names + * to ensure compatibility with the standard. + * + * \see \ref USB_Descriptor_Device_t for the version of this type with non-standard LUFA specific element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ +typedef struct +{ + u8 bLength; /**< Size of the descriptor, in bytes. */ + u8 bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + u16 bcdUSB; /**< BCD of the supported USB specification. */ + u8 bDeviceClass; /**< USB device class. */ + u8 bDeviceSubClass; /**< USB device subclass. */ + u8 bDeviceProtocol; /**< USB device protocol. */ + u8 bMaxPacketSize0; /**< Size of the control (address 0) endpoint's bank in bytes. */ + u16 idVendor; /**< Vendor ID for the USB product. */ + u16 idProduct; /**< Unique product ID for the USB product. */ + u16 bcdDevice; /**< Product release (version) number. */ + u8 iManufacturer; /**< String index for the manufacturer's name. The + * host will request this string via a separate + * control request for the string descriptor. + * + * \note If no string supplied, use \ref NO_DESCRIPTOR. + */ + u8 iProduct; /**< String index for the product name/details. + * + * \see ManufacturerStrIndex structure entry. + */ + u8 iSerialNumber; /**< String index for the product's globally unique hexadecimal + * serial number, in uppercase Unicode ASCII. + * + * \note On some microcontroller models, there is an embedded serial number + * in the chip which can be used for the device serial number. + * To use this serial number, set this to USE_INTERNAL_SERIAL. + * On unsupported devices, this will evaluate to 0 and will cause + * the host to generate a pseudo-unique value for the device upon + * insertion. + * + * \see ManufacturerStrIndex structure entry. + */ + u8 bNumConfigurations; /**< Total number of configurations supported by + * the device. + */ +}USB_StdDescriptor_Device_t; + +/** \brief Standard USB Device Qualifier Descriptor (LUFA naming conventions). + * + * Type define for a standard Device Qualifier Descriptor. This structure uses LUFA-specific element names + * to make each element's purpose clearer. + * + * \see \ref USB_StdDescriptor_DeviceQualifier_t for the version of this type with standard element names. + */ +typedef struct +{ + USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */ + + u16 USBSpecification; /**< BCD of the supported USB specification. */ + u8 Class; /**< USB device class. */ + u8 SubClass; /**< USB device subclass. */ + u8 Protocol; /**< USB device protocol. */ + + u8 Endpoint0Size; /**< Size of the control (address 0) endpoint's bank in bytes. */ + u8 NumberOfConfigurations; /**< Total number of configurations supported by + * the device. + */ + u8 Reserved; /**< Reserved for future use, must be 0. */ +}USB_Descriptor_DeviceQualifier_t; + +/** \brief Standard USB Device Qualifier Descriptor (USB-IF naming conventions). + * + * Type define for a standard Device Qualifier Descriptor. This structure uses the relevant standard's given element names + * to ensure compatibility with the standard. + * + * \see \ref USB_Descriptor_DeviceQualifier_t for the version of this type with non-standard LUFA specific element names. + */ +typedef struct +{ + u8 bLength; /**< Size of the descriptor, in bytes. */ + u8 bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + u16 bcdUSB; /**< BCD of the supported USB specification. */ + u8 bDeviceClass; /**< USB device class. */ + u8 bDeviceSubClass; /**< USB device subclass. */ + u8 bDeviceProtocol; /**< USB device protocol. */ + u8 bMaxPacketSize0; /**< Size of the control (address 0) endpoint's bank in bytes. */ + u8 bNumConfigurations; /**< Total number of configurations supported by + * the device. + */ + u8 bReserved; /**< Reserved for future use, must be 0. */ +}USB_StdDescriptor_DeviceQualifier_t; + +/** \brief Standard USB Configuration Descriptor (LUFA naming conventions). + * + * Type define for a standard Configuration Descriptor header. This structure uses LUFA-specific element names + * to make each element's purpose clearer. + * + * \see \ref USB_StdDescriptor_Configuration_Header_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ +typedef struct +{ + USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */ + + u16 TotalConfigurationSize; /**< Size of the configuration descriptor header, + * and all sub descriptors inside the configuration. + */ + u8 TotalInterfaces; /**< Total number of interfaces in the configuration. */ + + u8 ConfigurationNumber; /**< Configuration index of the current configuration. */ + u8 ConfigurationStrIndex; /**< Index of a string descriptor describing the configuration. */ + + u8 ConfigAttributes; /**< Configuration attributes, comprised of a mask of \c USB_CONFIG_ATTR_* masks. + * On all devices, this should include USB_CONFIG_ATTR_RESERVED at a minimum. + */ + + u8 MaxPowerConsumption; /**< Maximum power consumption of the device while in the + * current configuration, calculated by the \ref USB_CONFIG_POWER_MA() + * macro. + */ +}__attribute__((packed)) USB_Descriptor_Configuration_Header_t; + +/** \brief Standard USB Configuration Descriptor (USB-IF naming conventions). + * + * Type define for a standard Configuration Descriptor header. This structure uses the relevant standard's given element names + * to ensure compatibility with the standard. + * + * \see \ref USB_Descriptor_Device_t for the version of this type with non-standard LUFA specific element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ +typedef struct +{ + u8 bLength; /**< Size of the descriptor, in bytes. */ + u8 bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + u16 wTotalLength; /**< Size of the configuration descriptor header, + * and all sub descriptors inside the configuration. + */ + u8 bNumInterfaces; /**< Total number of interfaces in the configuration. */ + u8 bConfigurationValue; /**< Configuration index of the current configuration. */ + u8 iConfiguration; /**< Index of a string descriptor describing the configuration. */ + u8 bmAttributes; /**< Configuration attributes, comprised of a mask of \c USB_CONFIG_ATTR_* masks. + * On all devices, this should include USB_CONFIG_ATTR_RESERVED at a minimum. + */ + u8 bMaxPower; /**< Maximum power consumption of the device while in the + * current configuration, calculated by the \ref USB_CONFIG_POWER_MA() + * macro. + */ +}USB_StdDescriptor_Configuration_Header_t; + +/** \brief Standard USB Interface Descriptor (LUFA naming conventions). + * + * Type define for a standard Interface Descriptor. This structure uses LUFA-specific element names + * to make each element's purpose clearer. + * + * \see \ref USB_StdDescriptor_Interface_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ +typedef struct +{ + USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */ + + u8 InterfaceNumber; /**< Index of the interface in the current configuration. */ + u8 AlternateSetting; /**< Alternate setting for the interface number. The same + * interface number can have multiple alternate settings + * with different endpoint configurations, which can be + * selected by the host. + */ + u8 TotalEndpoints; /**< Total number of endpoints in the interface. */ + + u8 Class; /**< Interface class ID. */ + u8 SubClass; /**< Interface subclass ID. */ + u8 Protocol; /**< Interface protocol ID. */ + + u8 InterfaceStrIndex; /**< Index of the string descriptor describing the interface. */ +}__attribute__((packed))USB_Descriptor_Interface_t; + +/** \brief Standard USB Interface Descriptor (USB-IF naming conventions). + * + * Type define for a standard Interface Descriptor. This structure uses the relevant standard's given element names + * to ensure compatibility with the standard. + * + * \see \ref USB_Descriptor_Interface_t for the version of this type with non-standard LUFA specific element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ +typedef struct +{ + u8 bLength; /**< Size of the descriptor, in bytes. */ + u8 bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + u8 bInterfaceNumber; /**< Index of the interface in the current configuration. */ + u8 bAlternateSetting; /**< Alternate setting for the interface number. The same + * interface number can have multiple alternate settings + * with different endpoint configurations, which can be + * selected by the host. + */ + u8 bNumEndpoints; /**< Total number of endpoints in the interface. */ + u8 bInterfaceClass; /**< Interface class ID. */ + u8 bInterfaceSubClass; /**< Interface subclass ID. */ + u8 bInterfaceProtocol; /**< Interface protocol ID. */ + u8 iInterface; /**< Index of the string descriptor describing the + * interface. + */ +}USB_StdDescriptor_Interface_t; + +/** \brief Standard USB Interface Association Descriptor (LUFA naming conventions). + * + * Type define for a standard Interface Association Descriptor. This structure uses LUFA-specific element names + * to make each element's purpose clearer. + * + * This descriptor has been added as a supplement to the USB2.0 standard, in the ECN located at + * http://www.usb.org/developers/docs/InterfaceAssociationDescriptor_ecn.pdf. It allows composite + * devices with multiple interfaces related to the same function to have the multiple interfaces bound + * together at the point of enumeration, loading one generic driver for all the interfaces in the single + * function. Read the ECN for more information. + * + * \see \ref USB_StdDescriptor_Interface_Association_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ +typedef struct +{ + USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */ + + u8 FirstInterfaceIndex; /**< Index of the first associated interface. */ + u8 TotalInterfaces; /**< Total number of associated interfaces. */ + + u8 Class; /**< Interface class ID. */ + u8 SubClass; /**< Interface subclass ID. */ + u8 Protocol; /**< Interface protocol ID. */ + + u8 IADStrIndex; /**< Index of the string descriptor describing the + * interface association. + */ +}USB_Descriptor_Interface_Association_t; + +/** \brief Standard USB Interface Association Descriptor (USB-IF naming conventions). + * + * Type define for a standard Interface Association Descriptor. This structure uses the relevant standard's given + * element names to ensure compatibility with the standard. + * + * This descriptor has been added as a supplement to the USB2.0 standard, in the ECN located at + * http://www.usb.org/developers/docs/InterfaceAssociationDescriptor_ecn.pdf. It allows composite + * devices with multiple interfaces related to the same function to have the multiple interfaces bound + * together at the point of enumeration, loading one generic driver for all the interfaces in the single + * function. Read the ECN for more information. + * + * \see \ref USB_Descriptor_Interface_Association_t for the version of this type with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ +typedef struct +{ + u8 bLength; /**< Size of the descriptor, in bytes. */ + u8 bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + u8 bFirstInterface; /**< Index of the first associated interface. */ + u8 bInterfaceCount; /**< Total number of associated interfaces. */ + u8 bFunctionClass; /**< Interface class ID. */ + u8 bFunctionSubClass; /**< Interface subclass ID. */ + u8 bFunctionProtocol; /**< Interface protocol ID. */ + u8 iFunction; /**< Index of the string descriptor describing the + * interface association. + */ +}USB_StdDescriptor_Interface_Association_t; + +/** \brief Standard USB Endpoint Descriptor (LUFA naming conventions). + * + * Type define for a standard Endpoint Descriptor. This structure uses LUFA-specific element names + * to make each element's purpose clearer. + * + * \see \ref USB_StdDescriptor_Endpoint_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ +typedef struct +{ + USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */ + + u8 EndpointAddress; /**< Logical address of the endpoint within the device for the current + * configuration, including direction mask. + */ + u8 Attributes; /**< Endpoint attributes, comprised of a mask of the endpoint type (EP_TYPE_*) + * and attributes (ENDPOINT_ATTR_*) masks. + */ + u16 EndpointSize; /**< Size of the endpoint bank, in bytes. This indicates the maximum packet + * size that the endpoint can receive at a time. + */ + u8 PollingIntervalMS; /**< Polling interval in milliseconds for the endpoint if it is an INTERRUPT + * or ISOCHRONOUS type. + */ +}__attribute__((packed)) USB_Descriptor_Endpoint_t; + +/** \brief Standard USB Endpoint Descriptor (USB-IF naming conventions). + * + * Type define for a standard Endpoint Descriptor. This structure uses the relevant standard's given + * element names to ensure compatibility with the standard. + * + * \see \ref USB_Descriptor_Endpoint_t for the version of this type with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ +typedef struct +{ + u8 bLength; /**< Size of the descriptor, in bytes. */ + u8 bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a + * value given by the specific class. + */ + u8 bEndpointAddress; /**< Logical address of the endpoint within the device for the current + * configuration, including direction mask. + */ + u8 bmAttributes; /**< Endpoint attributes, comprised of a mask of the endpoint type (EP_TYPE_*) + * and attributes (ENDPOINT_ATTR_*) masks. + */ + u16 wMaxPacketSize; /**< Size of the endpoint bank, in bytes. This indicates the maximum packet size + * that the endpoint can receive at a time. + */ + u8 bInterval; /**< Polling interval in milliseconds for the endpoint if it is an INTERRUPT or + * ISOCHRONOUS type. + */ +}__attribute__((packed)) USB_StdDescriptor_Endpoint_t; + +/** \brief Standard USB String Descriptor (LUFA naming conventions). + * + * Type define for a standard string descriptor. Unlike other standard descriptors, the length + * of the descriptor for placement in the descriptor header must be determined by the \ref USB_STRING_LEN() + * macro rather than by the size of the descriptor structure, as the length is not fixed. + * + * This structure should also be used for string index 0, which contains the supported language IDs for + * the device as an array. + * + * This structure uses LUFA-specific element names to make each element's purpose clearer. + * + * \see \ref USB_StdDescriptor_String_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ +#ifndef __GNUC__ +#pragma warning(push) +#pragma warning(disable:4200) // none standard zero length array +#endif + +typedef struct +{ + USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */ + wchar_t UnicodeString[]; /**< String data, as unicode characters (alternatively, + * string language IDs). If normal ASCII characters are + * to be used, they must be added as an array of characters + * rather than a normal C string so that they are widened to + * Unicode size. + * + * Under GCC, strings prefixed with the "L" character (before + * the opening string quotation mark) are considered to be + * Unicode strings, and may be used instead of an explicit + * array of ASCII characters on little endian devices with + * UTF-16-LE \c wchar_t encoding. + */ +}USB_Descriptor_String_t; + +/** \brief Standard USB String Descriptor (USB-IF naming conventions). + * + * Type define for a standard string descriptor. Unlike other standard descriptors, the length + * of the descriptor for placement in the descriptor header must be determined by the \ref USB_STRING_LEN() + * macro rather than by the size of the descriptor structure, as the length is not fixed. + * + * This structure should also be used for string index 0, which contains the supported language IDs for + * the device as an array. + * + * This structure uses the relevant standard's given element names to ensure compatibility with the standard. + * + * \see \ref USB_Descriptor_String_t for the version of this type with with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ +typedef struct +{ + u8 bLength; /**< Size of the descriptor, in bytes. */ + u8 bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t + * or a value given by the specific class. + */ + wchar_t bString[]; /**< String data, as unicode characters (alternatively, string language IDs). + * If normal ASCII characters are to be used, they must be added as an array + * of characters rather than a normal C string so that they are widened to + * Unicode size. + * + * Under GCC, strings prefixed with the "L" character (before the opening string + * quotation mark) are considered to be Unicode strings, and may be used instead + * of an explicit array of ASCII characters. + */ +}USB_StdDescriptor_String_t; + +//////////////////////////////////////////////////////////////////////////////////////////////// +#if 1 + +#define MYUDB_EDP_IN_HCI 3 +#define MYUDB_EDP_OUT_HCI 5 +#define MYUDB_EDP_IN_VCD 8 +#define MYUDB_EDP_OUT_VCD 6 + +#else + +#define MYUDB_EDP_IN_HCI 8 +#define MYUDB_EDP_OUT_HCI 5 +#define MYUDB_EDP_IN_VCD 3 +#define MYUDB_EDP_OUT_VCD 6 + +#endif + +#define ENDPOINT_DIR_MASK BIT(7) +#define ENDPOINT_DIR_OUT 0 +#define ENDPOINT_DIR_IN BIT(7) +#define EP_TYPE_MASK 3 +#define EP_TYPE_CONTROL 0 +#define EP_TYPE_ISOCHRONOUS 1 +#define EP_TYPE_BULK 2 +#define EP_TYPE_INTERRUPT 3 + +enum PRNT_Descriptor_ClassSubclassProtocol_t +{ + PRNT_CSCP_PrinterClass = 0x07, + PRNT_CSCP_PrinterSubclass = 0x01, + PRNT_CSCP_BidirectionalProtocol = 0x02, +}; + +enum { + MYUDB_USB_STRING_LANGUAGE = 0, + MYUDB_USB_STRING_VENDOR, + MYUDB_USB_STRING_PRODUCT, + MYUDB_USB_STRING_SERIAL, +}; + +typedef struct { + USB_Descriptor_Configuration_Header_t Config; + USB_Descriptor_Interface_t intf0; + USB_Descriptor_Endpoint_t endpi0; + USB_Descriptor_Endpoint_t endpo0; + USB_Descriptor_Interface_t intf1; + USB_Descriptor_Endpoint_t endpi1; + USB_Descriptor_Endpoint_t endpo1; +} MYUDB_USB_Descriptor_Configuration_t; + +u8* myudb_usbdesc_get_language(void); +u8* myudb_usbdesc_get_vendor(void); +u8* myudb_usbdesc_get_product(void); +u8* myudb_usbdesc_get_serial(void); +u8* myudb_usbdesc_get_device(void); +u8* myudb_usbdesc_get_configuration(void); + +#endif diff --git a/b91/b91m_ble_sdk/common/utility.c b/b91/b91m_ble_sdk/common/utility.c new file mode 100755 index 0000000..2ac0a3a --- /dev/null +++ b/b91/b91m_ble_sdk/common/utility.c @@ -0,0 +1,155 @@ +/******************************************************************************************************** + * @file utility.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "tl_common.h" +#include "drivers.h" +#include "utility.h" + + +// general swap/endianess utils + +void swapN(unsigned char *p, int n) +{ + int i, c; + for (i=0; isize = s; + f->num = n; + f->wptr = 0; + f->rptr = 0; + f->p = p; +} + +u8* my_fifo_wptr (my_fifo_t *f) +{ + if (((f->wptr - f->rptr) & 255) < f->num) + { + return f->p + (f->wptr & (f->num-1)) * f->size; + } + return 0; +} + +u8* my_fifo_wptr_v2 (my_fifo_t *f) +{ + if (((f->wptr - f->rptr) & 255) < f->num - 3) //keep 3 fifo left for others evt + { + return f->p + (f->wptr & (f->num-1)) * f->size; + } + return 0; +} + +void my_fifo_next (my_fifo_t *f) +{ + f->wptr++; +} + +int my_fifo_push (my_fifo_t *f, u8 *p, int n) +{ + if (((f->wptr - f->rptr) & 255) >= f->num) + { + return -1; + } + + if (n >= f->size) + { + return -1; + } + u8 *pd = f->p + (f->wptr++ & (f->num-1)) * f->size; + *pd++ = n & 0xff; + *pd++ = (n >> 8) & 0xff; + memcpy (pd, p, n); + return 0; +} + +void my_fifo_pop (my_fifo_t *f) +{ + f->rptr++; +} + +u8 * my_fifo_get (my_fifo_t *f) +{ + if (f->rptr != f->wptr) + { + u8 *p = f->p + (f->rptr & (f->num-1)) * f->size; + return p; + } + return 0; +} + diff --git a/b91/b91m_ble_sdk/common/utility.h b/b91/b91m_ble_sdk/common/utility.h new file mode 100755 index 0000000..a09d158 --- /dev/null +++ b/b91/b91m_ble_sdk/common/utility.h @@ -0,0 +1,188 @@ +/******************************************************************************************************** + * @file utility.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once +#include "types.h" + +#define abs(a) (((a)>0)?((a)):(-(a))) + +#define cat2(i,j) i##j +#define cat3(i,j,k) i##j##k + +#ifndef min +#define min(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef max +#define max(a,b) ((a) > (b) ? (a): (b)) +#endif + +#ifndef min2 +#define min2(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef min3 +#define min3(a,b,c) min2(min2(a, b), c) +#endif + +#ifndef max2 +#define max2(a,b) ((a) > (b) ? (a): (b)) +#endif + +#ifndef max3 +#define max3(a,b,c) max2(max2(a, b), c) +#endif + +#define OFFSETOF(s, m) ((unsigned int) &((s *)0)->m) +#define ROUND_INT(x, r) (((x) + (r) - 1) / (r) * (r)) +#define ROUND_TO_POW2(x, r) (((x) + (r) - 1) & ~((r) - 1)) + +// direct memory access +#define U8_GET(addr) (*(volatile unsigned char *)(addr)) +#define U16_GET(addr) (*(volatile unsigned short *)(addr)) +#define U32_GET(addr) (*(volatile unsigned int *)(addr)) + +#define U8_SET(addr, v) (*(volatile unsigned char *)(addr) = (unsigned char)(v)) +#define U16_SET(addr, v) (*(volatile unsigned short *)(addr) = (unsigned short)(v)) +#define U32_SET(addr, v) (*(volatile unsigned int *)(addr) = (v)) + +#define U8_INC(addr) U8_GET(addr) += 1 +#define U16_INC(addr) U16_GET(addr) += 1 +#define U32_INC(addr) U32_GET(addr) += 1 + +#define U8_DEC(addr) U8_GET(addr) -= 1 +#define U16_DEC(addr) U16_GET(addr) -= 1 +#define U32_DEC(addr) U32_GET(addr) -= 1 + +#define U8_CPY(addr1,addr2) U8_SET(addr1, U8_GET(addr2)) +#define U16_CPY(addr1,addr2) U16_SET(addr1, U16_GET(addr2)) +#define U32_CPY(addr1,addr2) U32_SET(addr1, U32_GET(addr2)) + +#define MAKE_U16(h,l) ((unsigned short)(((h) << 8) | (l))) +#define MAKE_U24(a,b,c) ((unsigned int)(((a) << 16) | ((b) << 8) | (c))) +#define MAKE_U32(a,b,c,d) ((unsigned int)(((a) << 24) | ((b) << 16) | ((c) << 8) | (d))) + +#define BOUND(x, l, m) ((x) < (l) ? (l) : ((x) > (m) ? (m) : (x))) +#define SET_BOUND(x, l, m) ((x) = BOUND(x, l, m)) +#define BOUND_INC(x, m) do{++(x); (x) = (x) < (m) ? (x) :0;} while(0) +#define BOUND_INC_POW2(x, m) do{ \ + (x) = ((x)+1) & (m-1); \ + }while(0) + +#define IS_POWER_OF_2(x) (!(x & (x-1))) +#define IS_LITTLE_ENDIAN (*(unsigned short*)"\0\xff" > 0x100) +#define IS_4BYTE_ALIGN(x) (!(x & 3)) + +#define IMPLIES(x, y) (!(x) || (y)) + +// x > y ? 1 : (x ==y : 0 ? -1) +#define COMPARE(x, y) (((x) > (y)) - ((x) < (y))) +#define SIGN(x) COMPARE(x, 0) + +// better than xor swap: http://stackoverflow.com/questions/3912699/why-swap-with-xor-works-fine-in-c-but-in-java-doesnt-some-puzzle +#define SWAP(x, y, T) do { T tmp = (x); (x) = (y); (y) = tmp; } while(0) +#define SORT2(a, b, T) do { if ((a) > (b)) SWAP((a), (b), T); } while (0) + +#define foreach(i, n) for(int i = 0; i < (n); ++i) +#define foreach_range(i, s, e) for(int i = (s); i < (e); ++i) +#define foreach_arr(i, arr) for(int i = 0; i < ARRAY_SIZE(arr); ++i) + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a)) + +#define everyN(i, n) ++(i); (i)=((i) < N ? (i) : 0); if(0 == (i)) + +#define U16_HI(a) (((a) >> 8) & 0xFF) +#define U16_LO(a) ((a) & 0xFF) + +#define U32_BYTE0(a) ((a) & 0xFF) +#define U32_BYTE1(a) (((a) >> 8) & 0xFF) +#define U32_BYTE2(a) (((a) >> 16) & 0xFF) +#define U32_BYTE3(a) (((a) >> 24) & 0xFF) + + + +void swapN (unsigned char *p, int n); +void swapX(const u8 *src, u8 *dst, int len); + +void swap24(u8 dst[3], const u8 src[3]); +void swap32(u8 dst[4], const u8 src[4]); +void swap48(u8 dst[6], const u8 src[6]); +void swap56(u8 dst[7], const u8 src[7]); + +void swap64(u8 dst[8], const u8 src[8]); + +void swap128(u8 dst[16], const u8 src[16]); + +void flip_addr(u8 *dest, u8 *src); + +static inline u64 mul64_32x32(u32 u, u32 v) +{ +#if 0 //Eagle HW support this process + u32 u0, v0, w0; + u32 u1, v1, w1, w2, t; + u32 x, y; + + u0 = u & 0xFFFF; + u1 = u >> 16; + v0 = v & 0xFFFF; + v1 = v >> 16; + w0 = u0 * v0; + t = u1 * v0 + (w0 >> 16); + w1 = t & 0xFFFF; + w2 = t >> 16; + w1 = u0 * v1 + w1; + + //x is high 32 bits, y is low 32 bits + + x = u1 * v1 + w2 + (w1 >> 16); + y = u * v; + + + return(((u64)x << 32) | y); +#else + return (u64)u*v; +#endif +} + +typedef struct { + u32 size; + u16 num; + u8 wptr; + u8 rptr; + u8* p; +} my_fifo_t; + +void my_fifo_init (my_fifo_t *f, int s, u8 n, u8 *p); +u8* my_fifo_wptr (my_fifo_t *f); +u8* my_fifo_wptr_v2 (my_fifo_t *f); +void my_fifo_next (my_fifo_t *f); +int my_fifo_push (my_fifo_t *f, u8 *p, int n); +void my_fifo_pop (my_fifo_t *f); +u8 * my_fifo_get (my_fifo_t *f); + +#define MYFIFO_INIT(name,size,n) u8 name##_b[size * n]={0};my_fifo_t name = {size,n,0,0, name##_b} + +#define MYFIFO_INIT_IRAM(name,size,n) u8 name##_b[size * n]__attribute__((aligned(4)))/*={0}*/;my_fifo_t name = {size,n,0,0, name##_b} + + +#define DATA_LENGTH_ALLIGN4(n) ((n + 3) / 4 * 4) +#define DATA_LENGTH_ALLIGN16(n) ((n + 15) / 16 * 16) diff --git a/b91/b91m_ble_sdk/config.h b/b91/b91m_ble_sdk/config.h new file mode 100755 index 0000000..7f2c572 --- /dev/null +++ b/b91/b91m_ble_sdk/config.h @@ -0,0 +1,46 @@ +/******************************************************************************************************** + * @file config.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + + +#define CHIP_TYPE_9518 1 + + +#ifndef CHIP_TYPE +#define CHIP_TYPE CHIP_TYPE_9518 +#endif + + + + + + +#define MCU_CORE_9518 1 + + +#if(CHIP_TYPE == CHIP_TYPE_9518) + #define MCU_CORE_TYPE MCU_CORE_9518 +#endif + + + diff --git a/b91/b91m_ble_sdk/drivers.h b/b91/b91m_ble_sdk/drivers.h new file mode 100755 index 0000000..3eb6289 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers.h @@ -0,0 +1,29 @@ +/******************************************************************************************************** + * @file drivers.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "drivers/B91/driver_b91.h" +#include "drivers/B91/ext_driver/driver_ext.h" +#include "types.h" + +#include "common/assert.h" diff --git a/b91/b91m_ble_sdk/drivers/B91/adc.c b/b91/b91m_ble_sdk/drivers/B91/adc.c new file mode 100755 index 0000000..68c2d61 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/adc.c @@ -0,0 +1,362 @@ +/******************************************************************************************************** + * @file adc.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "adc.h" +#include "audio.h" +#include "compiler.h" + +_attribute_data_retention_sec_ unsigned short g_adc_vref = 1175; //default ADC ref voltage (unit:mV) +volatile unsigned char g_adc_pre_scale; +volatile unsigned char g_adc_vbat_divider; + +dma_chn_e adc_dma_chn; +dma_config_t adc_rx_dma_config= +{ + .dst_req_sel= 0, + .src_req_sel=DMA_REQ_AUDIO1_RX,//adc use the audio1 interface + .dst_addr_ctrl=DMA_ADDR_INCREMENT, + .src_addr_ctrl=DMA_ADDR_FIX, + .dstmode=DMA_NORMAL_MODE, + .srcmode=DMA_HANDSHAKE_MODE, + .dstwidth=DMA_CTR_WORD_WIDTH,//must word + .srcwidth=DMA_CTR_WORD_WIDTH,//must word + .src_burst_size=0,//must 0 + .read_num_en=0, + .priority=0, + .write_num_en=0, + .auto_en=0,//must 0 +}; +/** + * @brief This function serves to config adc_dma_chn channel. + * @param[in] chn - the DMA channel + * @return none + */ +void adc_set_dma_config(dma_chn_e chn) +{ + adc_dma_chn = chn; + dma_config(chn, &adc_rx_dma_config); + dma_clr_irq_mask(adc_dma_chn,TC_MASK|ERR_MASK|ABT_MASK); + dma_set_irq_mask(adc_dma_chn, TC_MASK); + + audio_data_fifo1_path_sel(SAR_ADC_DATA_IN_FIFO,OUT_NO_USE);//connect DMA and ADC by audio input fifo1. +} +/** + * @brief This function serves to start sample with adc DMA channel. + * @param[in] adc_data_buf - the address of data buffer + * @param[in] data_byte_len - the length of data size by byte + * @return none + */ +void adc_start_sample_dma(unsigned short *adc_data_buf,unsigned int data_byte_len) +{ + dma_set_address(adc_dma_chn,reg_fifo_buf_adr(1),(unsigned int)convert_ram_addr_cpu2bus(adc_data_buf)); + dma_set_size(adc_dma_chn,data_byte_len,DMA_WORD_WIDTH); + dma_chn_en(adc_dma_chn); + adc_fifo_enable(); +} +/** + * @brief This function serves to get adc DMA sample status. + * @return 0: the sample is in progress. + * !0: the sample is finished. + */ +unsigned char adc_get_sample_status_dma(void) +{ + return (dma_get_tc_irq_status(1<> 12, n_pin >> 12); +} +/** + * @brief This function serves to set the channel reference voltage. + * @param[in] v_ref - enum variable of ADC reference voltage. + * @return none + */ +void adc_set_ref_voltage(adc_ref_vol_e v_ref) +{ + analog_write_reg8(areg_adc_vref, v_ref); + if(v_ref == ADC_VREF_1P2V) + { + //Vref buffer bias current trimming: 150% + //Comparator preamp bias current trimming: 100% + analog_write_reg8(areg_ain_scale , (analog_read_reg8( areg_ain_scale )&(0xC0)) | 0x3d ); + g_adc_vref = 1175; + } + else if(v_ref == ADC_VREF_0P9V) + { + //Vref buffer bias current trimming: 100% + //Comparator preamp bias current trimming: 100% + analog_write_reg8( areg_ain_scale , (analog_read_reg8( areg_ain_scale )&(0xC0)) | 0x15 ); + g_adc_vref=900;// v_ref = ADC_VREF_0P9V, + } +} +/** + * @brief This function serves to set the sample frequency. + * @param[in] sample_freq - enum variable of ADC sample frequency. + * @return none + */ +void adc_set_sample_rate(adc_sample_freq_e sample_freq) +{ + switch(sample_freq) + { + case ADC_SAMPLE_FREQ_23K : + adc_set_state_length(1023, 15); + break; + case ADC_SAMPLE_FREQ_48K : + adc_set_state_length(490, 10); + break; + case ADC_SAMPLE_FREQ_96K : + adc_set_state_length(240, 10); + break; + } +} +/** + * @brief This function serves to set pre_scaling factor. + * @param[in] pre_scale - enum variable of ADC pre_scaling factor. + * @return none + */ +void adc_set_scale_factor(adc_pre_scale_e pre_scale) +{ + analog_write_reg8( areg_ain_scale , (analog_read_reg8( areg_ain_scale )&(~FLD_SEL_AIN_SCALE)) | (pre_scale<<6) ); + g_adc_pre_scale = 1<<(unsigned char)pre_scale; +} +/** + * @brief This function serves to select Vbat voltage division factor + * @param[in] vbat_div - enum variable of Vbat division factor. + * @return none + */ +void adc_set_vbat_divider(adc_vbat_div_e vbat_div) +{ + analog_write_reg8(areg_adc_vref_vbat_div, (analog_read_reg8(areg_adc_vref_vbat_div)&(~FLD_ADC_VREF_VBAT_DIV)) | (vbat_div<<2) ); + if(vbat_div) + { + g_adc_vbat_divider=5-vbat_div; + } + else + { + g_adc_vbat_divider=1; + } +} +/** + * @brief This function serves to ADC init. + * @param[in] v_ref - enum variable of ADC reference voltage. + * @param[in] pre_scale - enum variable of ADC pre_scaling factor. + * @param[in] sample_freq - enum variable of ADC sample frequency. + * @return none + * @attention Many features are configured in adc_init function. But some features + * such as adc_clk, resolution, tsample_cycle, we think better to set as default value, + * and user don't need to change them in most use cases. + */ +void adc_init(adc_ref_vol_e v_ref,adc_pre_scale_e pre_scale,adc_sample_freq_e sample_freq) +{ + adc_power_off();//power off sar adc + adc_reset();//reset whole digital adc module + adc_clk_en();//enable signal of 24M clock to sar adc + adc_set_clk(5);//default adc_clk 4M = 24M/(1+div), + adc_set_ref_voltage(v_ref);//set channel Vref + adc_set_scale_factor(pre_scale);//set Analog input pre-scaling + adc_set_sample_rate(sample_freq);//set sample frequency. + adc_set_resolution(ADC_RES14);//default adc_resolution set as 14bit ,BIT(13) is sign bit + adc_set_tsample_cycle(ADC_SAMPLE_CYC_6);//6 adc clocks for sample cycle + adc_set_m_chn_en();//enable adc channel. +} +/** + * @brief This function serves to ADC gpio sample init. + * @param[in] pin - adc_input_pin_def_e ADC input gpio pin + * @param[in] v_ref - enum variable of ADC reference voltage. + * @param[in] pre_scale - enum variable of ADC pre_scaling factor. + * @param[in] sample_freq - enum variable of ADC sample frequency. + * @return none + * @attention gpio voltage sample suggested initial setting are Vref = 1.2V, pre_scale = 1/8. + * 0.9V Vref pre_scale must be 1. + * The sampling range are as follows: + * Vref pre_scale sampling range + * 1.2V 1 0 ~ 1.1V (suggest) + * 1.2V 1/8 0 ~ 3.5V (suggest) + * 0.9V 1 0 ~ 0.8V + */ +void adc_gpio_sample_init(adc_input_pin_def_e pin,adc_ref_vol_e v_ref,adc_pre_scale_e pre_scale,adc_sample_freq_e sample_freq) +{ + adc_init(v_ref,pre_scale,sample_freq); + adc_set_vbat_divider(ADC_VBAT_DIV_OFF); + adc_pin_config(ADC_GPIO_MODE, pin); + adc_set_diff_input(pin >> 12, GND); +} +/** + * @brief This function servers to initialized ADC temperature sensor.When the reference voltage is set to 1.2V, and + * at the same time, the division factor is set to 1 the most accurate. + * @return none. + * @attention Temperature sensor suggested initial setting are Vref = 1.2V, pre_scale = 1. + * The user don't need to change it. + */ +void adc_temperature_sample_init(void) +{ + adc_init(ADC_VREF_1P2V, ADC_PRESCALE_1, ADC_SAMPLE_FREQ_96K); + adc_set_diff_input(ADC_TEMSENSORP_EE, ADC_TEMSENSORN_EE); + adc_set_vbat_divider(ADC_VBAT_DIV_OFF); + adc_temp_sensor_power_on(); +} + +/** + * @brief This function servers to set ADC configuration for ADC supply voltage sampling. + * @return none + * @attention battery voltage sample suggested initial setting are Vref = 1.2V, pre_scale = 1, vbat_div = 1/3. + * Which has higher accuracy, user don't need to change it. + * The battery voltage sample range is 1.8~3.5V, + * and must set sys_init with the mode for battery voltage less than 3.6V. + * For battery voltage > 3.6V, should take some external voltage divider. + */ +void adc_battery_voltage_sample_init(void) +{ + adc_init(ADC_VREF_1P2V, ADC_PRESCALE_1, ADC_SAMPLE_FREQ_96K); + adc_set_vbat_divider(ADC_VBAT_DIV_1F3); + adc_set_diff_input(ADC_VBAT, GND); +} +/** + * @brief This function serves to start adc sample and get raw adc sample code. + * @param[in] sample_buffer - pointer to the buffer adc sample code need to store. + * @param[in] sample_num - the number of adc sample code. + * @return none + */ +void adc_get_code_dma(unsigned short *sample_buffer, unsigned short sample_num) +{ + /******start adc sample********/ + adc_start_sample_dma((unsigned short *)sample_buffer, sample_num<<1); + /******wait for adc sample finish********/ + while(!adc_get_sample_status_dma()); + /******stop dma smaple********/ + adc_stop_sample_dma(); + /******clear adc sample finished status********/ + adc_clr_sample_status_dma();//must + /******get adc sample data and sort these data ********/ + for(int i=0;i valid data) + // = adc_code * Vref * adc_pre_scale / 0x2000 + // = adc_code * Vref * adc_pre_scale >>13 + return ((adc_code * g_adc_vbat_divider * g_adc_pre_scale * g_adc_vref)>>13); +} +/** + * @brief This function serves to calculate temperature from temperature sensor adc sample code. + * @param[in] adc_code - the temperature sensor adc sample code. + * @return adc_temp_value - the of temperature value. + * attention Temperature and adc_code are linearly related. We test four chips between -40~130 (Celsius) and got an average relationship: + * Temp = 564 - ((adc_code * 819)>>13),when Vref = 1.2V, pre_scale = 1. + */ +unsigned short adc_calculate_temperature(unsigned short adc_code) +{ + //////////////// adc sample data convert to temperature(Celsius) //////////////// + //adc_temp_value = 564 - ((adc_code * 819)>>13) + return 564 - ((adc_code * 819)>>13); +} + + diff --git a/b91/b91m_ble_sdk/drivers/B91/adc.h b/b91/b91m_ble_sdk/drivers/B91/adc.h new file mode 100755 index 0000000..6f915d6 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/adc.h @@ -0,0 +1,402 @@ +/******************************************************************************************************** + * @file adc.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +/** @page ADC + * + * Introduction + * =============== + * TLSRB91 supports hardware ADC function. + * + * API Reference + * =============== + * Header File: adc.h + */ +#pragma once + + +#include "dma.h" +#include "compiler.h" +#include "gpio.h" +#include "reg_include/register_b91.h" + +typedef enum{ + ADC_VREF_0P9V = 0x01, + ADC_VREF_1P2V = 0x02, +}adc_ref_vol_e; +typedef enum{ + ADC_VBAT_DIV_OFF = 0, + ADC_VBAT_DIV_1F3 = 0x02, +}adc_vbat_div_e; + +typedef enum { + NOINPUTN = 0, + ADC_GPIO_PB0N = 0x01, + ADC_GPIO_PB1N = 0x02, + ADC_GPIO_PB2N = 0x03, + ADC_GPIO_PB3N = 0x04, + ADC_GPIO_PB4N = 0x05, + ADC_GPIO_PB5N = 0x06, + ADC_GPIO_PB6N = 0x07, + ADC_GPIO_PB7N = 0x08, + ADC_GPIO_PD0N = 0x09, + ADC_GPIO_PD1N = 0x0a, + ADC_TEMSENSORN_EE = 0x0e, + GND = 0x0f, +}adc_input_nch_e; +typedef enum { + NOINPUTP = 0, + ADC_GPIO_PB0P = 0x01, + ADC_GPIO_PB1P = 0x02, + ADC_GPIO_PB2P = 0x03, + ADC_GPIO_PB3P = 0x04, + ADC_GPIO_PB4P = 0x05, + ADC_GPIO_PB5P = 0x06, + ADC_GPIO_PB6P = 0x07, + ADC_GPIO_PB7P = 0x08, + ADC_GPIO_PD0P = 0x09, + ADC_GPIO_PD1P = 0x0a, + ADC_TEMSENSORP_EE = 0x0e, + ADC_VBAT = 0x0f, +}adc_input_pch_e; +/** + * @brief adc input pin type + * | | | + * | :-------- | :----------- | + * | <15:12> | <11:0> | + * |adc channel| gpio pin | + */ +typedef enum{ + ADC_GPIO_PB0 = GPIO_PB0 | (0x1<<12), + ADC_GPIO_PB1 = GPIO_PB1 | (0x2<<12), + ADC_GPIO_PB2 = GPIO_PB2 | (0x3<<12), + ADC_GPIO_PB3 = GPIO_PB3 | (0x4<<12), + ADC_GPIO_PB4 = GPIO_PB4 | (0x5<<12), + ADC_GPIO_PB5 = GPIO_PB5 | (0x6<<12), + ADC_GPIO_PB6 = GPIO_PB6 | (0x7<<12), + ADC_GPIO_PB7 = GPIO_PB7 | (0x8<<12), + ADC_GPIO_PD0 = GPIO_PD0 | (0x9<<12), + ADC_GPIO_PD1 = GPIO_PD1 | (0xa<<12), +}adc_input_pin_def_e; +typedef enum{ + ADC_GPIO_MODE, + ADC_VBAT_MODE, +}adc_input_pin_mode_e; + +typedef enum{ + ADC_RES8 = 0, + ADC_RES10 = 0x01, + ADC_RES12 = 0x02, + ADC_RES14 = 0x03, +}adc_res_e; + +typedef enum{ + ADC_SAMPLE_CYC_3, + ADC_SAMPLE_CYC_6, + ADC_SAMPLE_CYC_9, + ADC_SAMPLE_CYC_12, + ADC_SAMPLE_CYC_15, + ADC_SAMPLE_CYC_18, + ADC_SAMPLE_CYC_21, + ADC_SAMPLE_CYC_24, + ADC_SAMPLE_CYC_27, + ADC_SAMPLE_CYC_30, + ADC_SAMPLE_CYC_33, + ADC_SAMPLE_CYC_36, + ADC_SAMPLE_CYC_39, + ADC_SAMPLE_CYC_42, + ADC_SAMPLE_CYC_45, + ADC_SAMPLE_CYC_48, +}adc_sample_cycle_e; + +typedef enum{ + ADC_SAMPLE_FREQ_23K, + ADC_SAMPLE_FREQ_48K, + ADC_SAMPLE_FREQ_96K, +}adc_sample_freq_e; + +typedef enum{ + ADC_MISC_CHN = BIT(2), +}adc_chn_e; + +typedef enum{ + ADC_PRESCALE_1 = 0x00, + ADC_PRESCALE_1F8 = 0x03, +}adc_pre_scale_e; +enum{ + ADC_MAX_STATE_NUM = 0x02, +}; + +/** + * @brief This function open sar_adc power. + * @return none. + */ +static inline void adc_power_on(void) +{ + analog_write_reg8 (areg_adc_pga_ctrl, (analog_read_reg8(areg_adc_pga_ctrl)&(~FLD_SAR_ADC_POWER_DOWN))); +} +/** + * @brief This function close sar_adc power. + * @return none + */ +static inline void adc_power_off(void) +{ + analog_write_reg8 (areg_adc_pga_ctrl, (analog_read_reg8(areg_adc_pga_ctrl)|FLD_SAR_ADC_POWER_DOWN)); +} +/** + * @brief This function reset adc module + * @return none + */ +static inline void adc_reset(void) +{ + reg_rst3 &= (~FLD_RST3_SARADC ); + reg_rst3 |=FLD_RST3_SARADC; +} +/** + * @brief This function serves to enable adc sample fifo. + * @return none + */ +static inline void adc_fifo_enable(void) +{ + reg_i2s_cfg2 &= (~FLD_AUDIO_FIFO1_RST); +} +/** + * @brief This function serves to disable adc sample fifo. + * @return none + */ +static inline void adc_fifo_disable(void) +{ + reg_i2s_cfg2 |= FLD_AUDIO_FIFO1_RST; +} +/** + * @brief This function enable adc source clock: Pad_24M + * @return none + */ +static inline void adc_clk_en(void) +{ + analog_write_reg8(areg_adc_clk_setting , analog_read_reg8(areg_adc_clk_setting ) | FLD_CLK_24M_TO_SAR_EN); +} +/** + * @brief This function disable adc source clock: Pad_24M + * @return none + */ +static inline void adc_clk_dis(void) +{ + analog_write_reg8(areg_adc_clk_setting , analog_read_reg8(areg_adc_clk_setting ) & (~FLD_CLK_24M_TO_SAR_EN)); +} +/** + * @brief This function sets adc sample clk. adc sample clk = 24M/(1+div) div: 0~7. + * @param[in] div - the divider of adc sample clock. + * @return none + */ +static inline void adc_set_clk(unsigned char div) +{ + analog_write_reg8(areg_adc_sample_clk_div, div); +} +/** + * @brief This function sets ADC input channel as misc channel. + * @return none + */ +static inline void adc_set_m_chn_en(void) +{ + analog_write_reg8(areg_adc_chn_en, FLD_ADC_CHN_EN_M | (ADC_MAX_STATE_NUM<<4) ); +} +/** + * @brief This function serves to set resolution. + * @param[in] res - enum variable of ADC resolution. + * @return none + */ +static inline void adc_set_resolution(adc_res_e res) +{ + analog_write_reg8(areg_adc_res_m, (analog_read_reg8(areg_adc_res_m)&(~FLD_ADC_RES_M)) | res); +} + +/** + * @brief This function serves to set ADC sample time(the number of adc clocks for sample cycles) for the misc channel. + * @param[in] sample_cycle - enum variable of adc sample cycles. + * @return none + */ +static inline void adc_set_tsample_cycle(adc_sample_cycle_e sample_cycle) +{ + //ana_ee<7:4> is reserved, so no need care its value + analog_write_reg8(areg_adc_tsmaple_m, sample_cycle); //optimize, <7:4> not cared +} +/** + * @brief This function open temperature sensor power. + * @return none + */ +static inline void adc_temp_sensor_power_on(void) +{ + analog_write_reg8(areg_temp_sensor_ctrl, (analog_read_reg8(areg_temp_sensor_ctrl)&(~FLD_TEMP_SENSOR_POWER_DOWN))); +} +/** + * @brief This function close temperature sensor power. + * @return none + */ +static inline void adc_temp_sensor_power_off(void) +{ + analog_write_reg8(areg_temp_sensor_ctrl, (analog_read_reg8(areg_temp_sensor_ctrl)|FLD_TEMP_SENSOR_POWER_DOWN)); +} +/** + * @brief This function serves to set input channel in differential_mode. + * @param[in] p_ain - enum variable of ADC analog positive input channel. + * @param[in] n_ain - enum variable of ADC analog negative input channel. + * @return none + */ +static inline void adc_set_diff_input(adc_input_pch_e p_ain, adc_input_nch_e n_ain) +{ + analog_write_reg8(areg_adc_res_m, analog_read_reg8(areg_adc_res_m) | FLD_ADC_EN_DIFF_CHN_M); + analog_write_reg8(areg_adc_ain_chn_misc, n_ain | p_ain<<4 ); +} +/** + * @brief This function serves to set state and capture_state length. + * @param[in] r_max_mc - Value of length of "capture" state for MISC channel. + * @param[in] r_max_s - Value of length of "set" state for MISC channel. + * @return none + */ +static inline void adc_set_state_length(unsigned short r_max_mc,unsigned char r_max_s) +{ + analog_write_reg8(areg_r_max_mc, r_max_mc); + analog_write_reg8(areg_r_max_s, ((r_max_mc>>8)<<6)| (r_max_s & FLD_R_MAX_S)); +} +/** + * @brief This function serves to config adc_dma_chn channel. + * @param[in] chn - the DMA channel + * @return none + */ +void adc_set_dma_config(dma_chn_e chn); +/** + * @brief This function serves to start sample with adc DMA channel. + * @param[in] adc_data_buf - the address of data buffer + * @param[in] data_byte_len - the length of data size by byte + * @return none + */ +void adc_start_sample_dma(unsigned short *adc_data_buf,unsigned int data_byte_len); +/** + * @brief This function is used to set IO port for ADC supply or ADC IO port voltage sampling. + * @param[in] mode - ADC gpio pin sample mode + * @param[in] pin - adc_input_pin_def_e ADC input gpio pin + * @return none + */ +void adc_pin_config(adc_input_pin_mode_e mode ,adc_input_pin_def_e pin); +/** + * @brief This function is used to set two IO port configuration and set it as input channel of ADC difference IO port voltage sampling. + * @param[in] p_pin - enum variable of ADC analog positive input IO. + * @param[in] n_pin - enum variable of ADC analog negative input IO. + * @return none + */ +void adc_set_diff_pin(adc_input_pin_def_e p_pin, adc_input_pin_def_e n_pin); +/** + * @brief This function serves to set the channel reference voltage. + * @param[in] v_ref - enum variable of ADC reference voltage. + * @return none + */ +void adc_set_ref_voltage(adc_ref_vol_e v_ref); +/** + * @brief This function serves to set the sample frequency. + * @param[in] sample_freq - enum variable of ADC sample frequency. + * @return none + */ +void adc_set_sample_rate(adc_sample_freq_e sample_freq); +/** + * @brief This function serves to set pre_scaling factor. + * @param[in] pre_scale - enum variable of ADC pre_scaling factor. + * @return none + */ +void adc_set_scale_factor(adc_pre_scale_e pre_scale); +/** + * @brief This function servers to initialized ADC temperature sensor.When the reference voltage is set to 1.2V, and + * at the same time, the division factor is set to 1 the most accurate. + * @return none. + * @attention Temperature sensor suggested initial setting are Vref = 1.2V, pre_scale = 1. + * The user don't need to change it. + */ +void adc_temperature_sample_init(void); +/** + * @brief This function serves to ADC gpio sample init. + * @param[in] pin - adc_input_pin_def_e ADC input gpio pin + * @param[in] v_ref - enum variable of ADC reference voltage. + * @param[in] pre_scale - enum variable of ADC pre_scaling factor. + * @param[in] sample_freq - enum variable of ADC sample frequency. + * @return none + * @attention gpio voltage sample suggested initial setting are Vref = 1.2V, pre_scale = 1/8. + * 0.9V Vref pre_scale must be 1. + * The sampling range are as follows: + * Vref pre_scale sampling range + * 1.2V 1 0 ~ 1.1V (suggest) + * 1.2V 1/8 0 ~ 3.5V (suggest) + * 0.9V 1 0 ~ 0.8V + */ +void adc_gpio_sample_init(adc_input_pin_def_e pin,adc_ref_vol_e v_ref,adc_pre_scale_e pre_scale,adc_sample_freq_e sample_freq); + +/** + * @brief This function servers to set ADC configuration for ADC supply voltage sampling. + * @return none + * @attention battery voltage sample suggested initial setting are Vref = 1.2V, pre_scale = 1, vbat_div = 1/3. + * Which has higher accuracy, user don't need to change it. + * The battery voltage sample range is 1.8~3.5V, + * and must set sys_init with the mode for battery voltage less than 3.6V. + * For battery voltage > 3.6V, should take some external voltage divider. + */ +void adc_battery_voltage_sample_init(void); +/** + * @brief This function serves to select Vbat voltage division factor + * @param[in] vbat_div - enum variable of Vbat division factor. + * @return none + */ +void adc_set_vbat_divider(adc_vbat_div_e vbat_div); +/** + * @brief This function serves to ADC init. + * @param[in] v_ref - enum variable of ADC reference voltage. + * @param[in] pre_scale - enum variable of ADC pre_scaling factor. + * @param[in] sample_freq - enum variable of ADC sample frequency. + * @return none + * @attention Many features are configured in adc_init function. But some features + * such as adc_clk, resolution, tsample_cycle, we think better to set as default value, + * and user don't need to change them in most use cases. + */ +void adc_init(adc_ref_vol_e v_ref,adc_pre_scale_e pre_scale,adc_sample_freq_e sample_freq); +/** + * @brief This function serves to start adc sample and get raw adc sample code. + * @param[in] sample_buffer - pointer to the buffer adc sample code need to store. + * @param[in] sample_num - the number of adc sample code. + * @return none + */ +void adc_get_code_dma(unsigned short *sample_buffer, unsigned short sample_num); +/** + * @brief This function serves to directly get an adc sample code from analog registers. + * @return adc_code - the adc sample code. + */ +unsigned short adc_get_code(void); +/** + * @brief This function serves to calculate voltage from adc sample code. + * @param[in] adc_code - the adc sample code. + * @return adc_vol_mv - the average value of adc voltage value. + */ +unsigned short adc_calculate_voltage(unsigned short adc_code); +/** + * @brief This function serves to calculate temperature from temperature sensor adc sample code. + * @param[in] adc_code - the temperature sensor adc sample code. + * @return adc_temp_value - the of temperature value. + * attention Temperature and adc_code are linearly related. We test four chips between -40~130 (Celsius) and got an average relationship: + * Temp = 564 - ((adc_code * 819)>>13),when Vref = 1.2V, pre_scale = 1. + */ +unsigned short adc_calculate_temperature(unsigned short adc_code); diff --git a/b91/b91m_ble_sdk/drivers/B91/aes.c b/b91/b91m_ble_sdk/drivers/B91/aes.c new file mode 100755 index 0000000..0e549c8 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/aes.c @@ -0,0 +1,158 @@ +/******************************************************************************************************** + * @file aes.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "aes.h" +#include "compiler.h" + +/********************************************************************************************************************** + * local constants * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * local macro * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * local data type * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * global variable * + *********************************************************************************************************************/ +_attribute_aes_data_sec_ unsigned int aes_data_buff[8]; +unsigned int aes_base_addr = 0xc0000000; +/********************************************************************************************************************** + * local variable * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * local function prototype * + *********************************************************************************************************************/ +/** + * @brief This function refer to wait aes encrypt/decrypt done. + * @return none. + */ +static inline void aes_wait_done(void); +/********************************************************************************************************************** + * global function implementation * + *********************************************************************************************************************/ +/** + * @brief This function refer to encrypt/decrypt to set key and data. AES module register must be used by word. + * All data need Little endian. + * @param[in] key - the key of encrypt/decrypt. + * @param[in] data - the data which to do encrypt/decrypt. + * @return none + */ +void aes_set_key_data(unsigned char *key, unsigned char* data) +{ + unsigned int temp; + reg_embase_addr = aes_base_addr; //set the embase addr + for (unsigned char i = 0; i < 4; i++) { + temp = key[16-(4*i)-4]<<24 | key[16-(4*i)-3]<<16 | key[16-(4*i)-2]<<8 | key[16-(4*i)-1]; + reg_aes_key(i) = temp; + temp = data[16-(4*i)-4]<<24 | data[16-(4*i)-3]<<16 | data[16-(4*i)-2]<<8 | data[16-(4*i)-1]; + aes_data_buff[i] = temp; + } + + reg_aes_ptr = (unsigned int)aes_data_buff; +} + +/** + * @brief This function refer to encrypt/decrypt to get result. AES module register must be used by word. + * @param[in] result - the result of encrypt/decrypt, Little endian. + * @return none. + */ +void aes_get_result(unsigned char *result) +{ + /* read out the result */ + unsigned char *ptr = (unsigned char *)&aes_data_buff[4]; + for (unsigned char i=0; i<16; i++) { + result[i] = ptr[15 - i]; + } +} + +/** + * @brief This function refer to encrypt. AES module register must be used by word, all data need big endian. + * @param[in] key - the key of encrypt. + * @param[in] plaintext - the plaintext of encrypt. + * @param[in] result - the result of encrypt. + * @return none + */ +int aes_encrypt(unsigned char *key, unsigned char* plaintext, unsigned char *result) +{ + + //set the key + aes_set_key_data(key, plaintext); + + aes_set_mode(AES_ENCRYPT_MODE); //cipher mode + + aes_wait_done(); + + aes_get_result(result); + + return 1; +} + +/** + * @brief This function refer to decrypt. AES module register must be used by word.all data need big endian. + * @param[in] key - the key of decrypt. + * @param[in] decrypttext - the text of decrypt. + * @param[in] result - the result of decrypt. + * @return none. + */ +int aes_decrypt(unsigned char *key, unsigned char* decrypttext, unsigned char *result) +{ + //set the key + aes_set_key_data(key, decrypttext); + + aes_set_mode(AES_DECRYPT_MODE); //decipher mode + + aes_wait_done(); + + aes_get_result(result); + + return 1; +} +/********************************************************************************************************************** + * local function implementation * + *********************************************************************************************************************/ +/** + * @brief This function refer to set the embase addr. + * @param[in] addr - the base addr of CEVA data. + * @return none. + */ +void aes_set_em_base_addr(unsigned int addr){ + aes_base_addr = addr; //set the embase addr +} + +/** + * @brief This function refer to wait aes crypt done. + * @return none. + */ +static inline void aes_wait_done(void) +{ + while(FLD_AES_START == (reg_aes_mode & FLD_AES_START)); +} + diff --git a/b91/b91m_ble_sdk/drivers/B91/aes.h b/b91/b91m_ble_sdk/drivers/B91/aes.h new file mode 100755 index 0000000..d0f39cc --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/aes.h @@ -0,0 +1,154 @@ +/******************************************************************************************************** + * @file aes.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +/** @page AES + * + * Introduction + * =============== + * TLSRB91 supports hardware AES function. + * + * API Reference + * =============== + * Header File: aes.h + */ +#ifndef _AES_H_ +#define _AES_H_ + +#include "compiler.h" +#include "./reg_include/aes_reg.h" + +/********************************************************************************************************************** + * global constants * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * global macro * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * global data type * + *********************************************************************************************************************/ +/** + * @brief AES mode. + */ +typedef enum{ + AES_ENCRYPT_MODE = 0, + AES_DECRYPT_MODE = 2, +}aes_mode_e; +/********************************************************************************************************************** + * global variable declaration * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * global function prototype * + *********************************************************************************************************************/ + /* @brief This function refer to encrypt. AES module register must be used by word. , all data need big endian. + * @param[in] key - the key of encrypt. + * @param[in] plaintext - the plaintext of encrypt. + * @param[in] result - the result of encrypt. + * @return none + */ +int aes_encrypt(unsigned char *key, unsigned char* plaintext, unsigned char *result); + +/** + * @brief This function refer to decrypt. AES module register must be used by word., all data need big endian. + * @param[in] key - the key of decrypt. + * @param[in] decrypttext - the decrypttext of decrypt. + * @param[in] result - the result of decrypt. + * @return none. + */ +int aes_decrypt(unsigned char *key, unsigned char* decrypttext, unsigned char *result); + +/** + * @brief This function refer to set the base addr of data which use in CEVA module + * @param[in] addr - the base addr of CEVA data. + * @return none. + */ +void aes_set_em_base_addr(unsigned int addr); + +/** + * @brief This function refer to encrypt/decrypt to set key and data. AES module register must be used by word. + * All data need Little endian. + * @param[in] key - the key of encrypt/decrypt. + * @param[in] data - the data which to do encrypt/decrypt. + * @return none + */ +void aes_set_key_data(unsigned char *key, unsigned char* data); + +/** + * @brief This function refer to encrypt/decrypt to get result. AES module register must be used by word. + * @param[in] result - the result of encrypt/decrypt. Little endian + * @return none. + */ +void aes_get_result(unsigned char *result); + +/** + * @brief This function refer to set aes mode. + * @param[in] mode - the irq mask. + * @return none. + */ +static inline void aes_set_mode(aes_mode_e mode) +{ + reg_aes_mode = (FLD_AES_START | mode); +} + +/** + * @brief This function refer to set aes irq mask. + * @param[in] mask - the irq mask. + * @return none. + */ +static inline void aes_set_irq_mask(aes_irq_e mask) +{ + reg_aes_irq_mask |= mask; +} + +/** + * @brief This function refer to clr aes irq mask. + * @param[in] mask - the irq mask. + * @return none. + */ +static inline void aes_clr_irq_mask(aes_irq_e mask) +{ + reg_aes_irq_mask &= (~mask); +} + +/** + * @brief This function refer to get aes irq status. + * @param[in] status - the irq status to get. + * @return none. + */ +static inline int aes_get_irq_status(aes_irq_e status) +{ + return (reg_aes_irq_status & status); +} + +/** + * @brief This function refer to clr aes irq status. + * @param[in] status - the irq status to clear. + * @return none. + */ +static inline void aes_clr_irq_status(aes_irq_e status) +{ + reg_aes_clr_irq_status = (status); +} + +#endif /* _AES_H_ */ diff --git a/b91/b91m_ble_sdk/drivers/B91/analog.c b/b91/b91m_ble_sdk/drivers/B91/analog.c new file mode 100755 index 0000000..638a936 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/analog.c @@ -0,0 +1,442 @@ +/******************************************************************************************************** + * @file analog.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "analog.h" +#include "compiler.h" +#include "plic.h" +#include "stimer.h" +/********************************************************************************************************************** + * local constants * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * local macro * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * local data type * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * global variable * + *********************************************************************************************************************/ + + + +dma_config_t analog_tx_dma_config={ + .dst_req_sel = DMA_REQ_ALGM_TX, /* < tx req */ + .src_req_sel = 0, + .dst_addr_ctrl = DMA_ADDR_FIX, + .src_addr_ctrl = DMA_ADDR_INCREMENT, /* < increment */ + .dstmode = DMA_HANDSHAKE_MODE, /* < handshake */ + .srcmode = DMA_NORMAL_MODE, + .dstwidth = DMA_CTR_WORD_WIDTH, + .srcwidth = DMA_CTR_WORD_WIDTH, + .src_burst_size = 0, /* < must 0 */ + .read_num_en = 0, + .priority = 0, + .write_num_en = 0, + .auto_en = 0, /* < must 0 */ +}; +dma_config_t analog_rx_dma_config={ + .dst_req_sel = 0,//tx req + .src_req_sel = DMA_REQ_ALGM_RX, + .dst_addr_ctrl = DMA_ADDR_INCREMENT, + .src_addr_ctrl = DMA_ADDR_FIX, + .dstmode = DMA_NORMAL_MODE, + .srcmode = DMA_HANDSHAKE_MODE, + .dstwidth = DMA_CTR_WORD_WIDTH, /* < must word */ + .srcwidth = DMA_CTR_WORD_WIDTH, /* < must word */ + .src_burst_size = 0, + .read_num_en = 0, + .priority = 0, + .write_num_en = 0, + .auto_en = 0,//must 0 +}; +/********************************************************************************************************************** + * local variable * + *********************************************************************************************************************/ +/********************************************************************************************************************** + * local function prototype * + *********************************************************************************************************************/ + + +/** + * @brief This function serves to judge whether analog write/read is busy . + * @return none. + */ +static inline void analog_wait(); +/********************************************************************************************************************** + * global function implementation * + *********************************************************************************************************************/ + + + + + +/** + * @brief This function serves to analog register read by byte. + * @param[in] addr - address need to be read. + * @return the result of read. + */ +unsigned char analog_read_reg8(unsigned char addr){ + unsigned int r=core_interrupt_disable(); + reg_ana_addr = addr; + reg_ana_len=0x1; + reg_ana_ctrl = FLD_ANA_CYC; + analog_wait(); + unsigned char data= reg_ana_data(0); + core_restore_interrupt(r); + return data; + +} + +/** + * @brief This function serves to analog register write by byte. + * @param[in] addr - address need to be write. + * @param[in] data - the value need to be write. + * @return none. + */ +void analog_write_reg8(unsigned char addr, unsigned char data){ + unsigned int r=core_interrupt_disable(); + reg_ana_addr = addr; + reg_ana_data(0) = data; + reg_ana_ctrl = (FLD_ANA_CYC | FLD_ANA_RW); + analog_wait(); + reg_ana_ctrl =0x00; + core_restore_interrupt(r); +} + +/** + * @brief This function serves to analog register write by halfword. + * @param[in] addr - address need to be write. + * @param[in] data - the value need to be write. + * @return none. + */ +void analog_write_reg16(unsigned char addr, unsigned short data) +{ + unsigned int r=core_interrupt_disable(); + reg_ana_addr = addr; + reg_ana_addr_data16 = data; + reg_ana_ctrl = (FLD_ANA_CYC | FLD_ANA_RW); + analog_wait(); + core_restore_interrupt(r); +} + +/** + * @brief This function serves to analog register read by halfword. + * @param[in] addr - address need to be read. + * @return the result of read. + */ +unsigned short analog_read_reg16(unsigned char addr) +{ + unsigned int r=core_interrupt_disable(); + reg_ana_len=2; + reg_ana_addr = addr; + reg_ana_ctrl = FLD_ANA_CYC; + analog_wait(); + unsigned short data=reg_ana_addr_data16; + core_restore_interrupt(r); + return data; +} + + + +/** + * @brief This function serves to analog register read by word. + * @param[in] addr - address need to be read. + * @return the result of read. + */ +unsigned int analog_read_reg32(unsigned char addr) +{ + unsigned int r=core_interrupt_disable(); + reg_ana_len = 4; + reg_ana_addr = addr; + reg_ana_ctrl = FLD_ANA_CYC; + analog_wait(); + unsigned int data=reg_ana_addr_data32; + core_restore_interrupt(r); + return data; +} + + +/** + * @brief This function serves to analog register write by word. + * @param[in] addr - address need to be write. + * @param[in] data - the value need to be write. + * @return none. + */ +void analog_write_reg32(unsigned char addr, unsigned int data) +{ + unsigned int r=core_interrupt_disable(); + reg_ana_addr = addr; + reg_ana_addr_data32 = data; + reg_ana_ctrl = (FLD_ANA_CYC | FLD_ANA_RW); + analog_wait(); + core_restore_interrupt(r); +} + +/** + * @brief This function serves to analog register write by word using dma. + * @param[in] chn - the dma channel. + * @param[in] addr - address need to be write. + * @param[in] pdat - the value need to be write. + * @return none. + */ +void analog_read_reg32_dma(dma_chn_e chn, unsigned char addr, void *pdat) +{ + unsigned int r=core_interrupt_disable(); + reg_ana_len = 0x04; + reg_ana_addr = addr; + reg_ana_ctrl = FLD_ANA_CYC; + reg_dma_src_addr(chn) = 0x80140184; + reg_dma_dst_addr(chn) = convert_ram_addr_cpu2bus(pdat); + dma_set_size(chn, 4, DMA_WORD_WIDTH); + analog_rx_dma_config.dstwidth = DMA_CTR_WORD_WIDTH; + analog_rx_dma_config.srcwidth = DMA_CTR_WORD_WIDTH; + dma_config(chn, &analog_rx_dma_config); + dma_chn_en(chn); + analog_wait(); + core_restore_interrupt(r); +} + +/** + * @brief This function serves to analog register write by word using dma. + * @param[in] chn - the dma channel. + * @param[in] addr - address need to be write. + * @param[in] data - the value need to be write. + * @return none. + */ +void analog_write_reg32_dma(dma_chn_e chn, unsigned char addr, void *pdat) +{ + unsigned int r=core_interrupt_disable(); + reg_ana_addr = addr; + reg_dma_src_addr(chn) = convert_ram_addr_cpu2bus(pdat); + reg_dma_dst_addr(chn) = 0x80140184; + dma_set_size(chn, 4, DMA_WORD_WIDTH); + analog_tx_dma_config.dstwidth = DMA_CTR_WORD_WIDTH; + analog_tx_dma_config.srcwidth = DMA_CTR_WORD_WIDTH; + dma_config(chn, &analog_tx_dma_config); + dma_chn_en(chn); + reg_ana_ctrl = FLD_ANA_CYC | FLD_ANA_RW; + analog_wait(); + core_restore_interrupt(r); +} + + + + + +/** + * @brief This function write buffer to analog register. + * @param[in] addr - address need to be write. + * @param[in] *buff - the buffer need to be write. + * @param[in] len - the length of buffer. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void analog_write_buff(unsigned char addr, unsigned char *buff, int len) +{ + unsigned char wr_idx = 0; + unsigned char len_t = len; + unsigned int r =core_interrupt_disable(); + reg_ana_len=len; + reg_ana_addr = addr; + + if(len_t <= 4) + { + while(len_t--) + reg_ana_data(wr_idx++) = *(buff++); + reg_ana_ctrl = FLD_ANA_CYC | FLD_ANA_RW; + } + else + { + len_t = 4; + while(len_t--) + reg_ana_data(wr_idx++) = *(buff++); + reg_ana_ctrl = FLD_ANA_CYC | FLD_ANA_RW; + len_t = len - 4; + wr_idx = 0; + while(len_t--) + { + reg_ana_data(wr_idx++) = *(buff++); + if(wr_idx == 4) + { + wr_idx = 0; + while((reg_ana_irq_sta & FLD_ANA_TXBUFF_IRQ) == 0);//tx_buf_irq + } + } + } + analog_wait();//busy + reg_ana_ctrl = 0x00; + core_restore_interrupt(r); +} + +/** + * @brief This function read data from analog register to buffer. + * @param[in] addr - address need to be read from. + * @param[in] *buff - the buffer need to be put data. + * @param[in] len - the length of read data. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void analog_read_buff(unsigned char addr, unsigned char *buff, int len) +{ + unsigned int r=core_interrupt_disable(); + unsigned char rd_idx = 0; + unsigned char len_t = len; + reg_ana_len=len; + reg_ana_addr = addr; + reg_ana_ctrl = FLD_ANA_CYC; + if (len_t > 4) + { + while((reg_ana_irq_sta & FLD_ANA_RXBUFF_IRQ) == 0);//rx_buf_irq + while(len_t--) + { + (*buff++) = reg_ana_data(rd_idx++); + if(rd_idx == 4) + { + rd_idx = 0; + if(len_t <= 4) + break; + else + while((reg_ana_irq_sta & FLD_ANA_RXBUFF_IRQ) == 0);//rx_buf_irq + } + } + } + analog_wait(); + while(len_t--) + (*buff++) = reg_ana_data(rd_idx++); + + reg_ana_ctrl = 0x00; + core_restore_interrupt(r); +} + +/** + * @brief This function write buffer to analog register by dma channel. + * @param[in] chn - the dma channel. + * @param[in] addr - address need to be write. + * @param[in] *pdat - the buffer need to be write. + * @param[in] len - the length of buffer. + * @return none. + */ +void analog_write_buff_dma(dma_chn_e chn, unsigned char addr, unsigned char * pdat, unsigned int len) +{ + unsigned int r=core_interrupt_disable(); + reg_ana_addr = addr; + reg_dma_src_addr(chn) = convert_ram_addr_cpu2bus(pdat); + reg_dma_dst_addr(chn) = 0x80140184; + dma_set_size(chn, len, DMA_WORD_WIDTH); + analog_tx_dma_config.dstwidth = DMA_CTR_WORD_WIDTH; + analog_tx_dma_config.srcwidth = DMA_CTR_WORD_WIDTH; + dma_config(chn, &analog_tx_dma_config); + dma_chn_en(chn); + reg_ana_ctrl = 0x60; + analog_wait(); + core_restore_interrupt(r); +} + +/** + * @brief This function write buffer to analog register by dma channel. + * @param[in] chn - the dma channel. + * @param[in] addr - address need to be read from. + * @param[in] *pdat - the buffer need to be put data. + * note: The size of array pdat must be a multiple of 4. + * For example, if you just need read 5 byte by dma, you should + * define the size of array pdat to be greater than 8 other than 5. + * Because the dma would return 4 byte data every time, 5 byte is + * not enough to store them. + * @param[in] len - the length of read data. + * @return none. + */ +void analog_read_buff_dma(dma_chn_e chn, unsigned char addr, unsigned char *pdat, unsigned int len) +{ + unsigned int r=core_interrupt_disable(); + reg_ana_len = len; + reg_ana_addr = addr; + + reg_dma_src_addr(chn) = 0x80140184; + reg_dma_dst_addr(chn) = convert_ram_addr_cpu2bus(pdat); + dma_set_size(chn, len, DMA_WORD_WIDTH); + analog_rx_dma_config.dstwidth = DMA_CTR_WORD_WIDTH; + analog_rx_dma_config.srcwidth = DMA_CTR_WORD_WIDTH; + dma_config(chn, &analog_rx_dma_config); + dma_chn_en(chn); + reg_ana_ctrl = FLD_ANA_CYC; + analog_wait(); + core_restore_interrupt(r); +} + +/** + * @brief This function write buffer to analog register by dma channel. + * @param[in] chn - the dma channel. + * @param[in] pdat - the buffer(addr & data) ptr need to be write, + * note: The array pdat should look like this, + * | pdat | | | + * | :------ | :----------| :---- | + * | pdat[0] | address | 0x3a | + * | pdat[1] | data | 0x11 | + * | pdat[2] | address | 0x3b | + * | pdat[3] | data | 0x22 | + * | ...... | | | + * It means write data 0x11 to address 0x3a, + * write data 0x22 to address 0x3b, + * ...... + * @param[in] len - the length of read data. + * @return none. + */ +void analog_write_addr_data_dma(dma_chn_e chn, void *pdat, int len) +{ + unsigned int r=core_interrupt_disable(); + + reg_dma_src_addr(chn) = convert_ram_addr_cpu2bus(pdat); + reg_dma_dst_addr(chn) = 0x80140184; + dma_set_size(chn, len, DMA_WORD_WIDTH); + analog_tx_dma_config.dstwidth = DMA_CTR_WORD_WIDTH; + analog_tx_dma_config.srcwidth = DMA_CTR_WORD_WIDTH; + dma_config(chn, &analog_tx_dma_config); + dma_chn_en(chn); + delay_us(1); + reg_ana_ctrl = FLD_ANA_RW; + reg_ana_dma_ctl = FLD_ANA_CYC1|FLD_ANA_DMA_EN; + delay_us(1); + while(!(reg_ana_sta & BIT(3))); + reg_ana_ctrl = 0x00; + reg_ana_dma_ctl = 0; + core_restore_interrupt(r); + +} + +/********************************************************************************************************************** + * local function implementation * + *********************************************************************************************************************/ +/** + * @brief This function serves to judge whether analog write/read is busy . + * @return none. + */ +static inline void analog_wait(){ + while(reg_ana_ctrl & FLD_ANA_BUSY){} +} + + + diff --git a/b91/b91m_ble_sdk/drivers/B91/analog.h b/b91/b91m_ble_sdk/drivers/B91/analog.h new file mode 100755 index 0000000..8f7f717 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/analog.h @@ -0,0 +1,184 @@ +/******************************************************************************************************** + * @file analog.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +/******************************* analog control registers: 0xb8 ******************************/ +/** @page ANALOG + * + * Introduction + * =============== + * TLSRB91 analog support dma and normal mode, in each mode, support byte/halfword/word/buffer write and read. + * + * API Reference + * =============== + * Header File: analog.h + */ +#pragma once + + +#include "dma.h" +#include "compiler.h" +#include "reg_include/register_b91.h" + +/********************************************************************************************************************** + * global constants * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * global macro * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * global data type * + *********************************************************************************************************************/ +/********************************************************************************************************************** + * global variable declaration * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * global function prototype * + *********************************************************************************************************************/ + +/** + * @brief This function serves to analog register read by byte. + * @param[in] addr - address need to be read. + * @return the result of read. + */ +_attribute_ram_code_sec_noinline_ unsigned char analog_read_reg8(unsigned char addr); + +/** + * @brief This function serves to analog register write by byte. + * @param[in] addr - address need to be write. + * @param[in] data - the value need to be write. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void analog_write_reg8(unsigned char addr, unsigned char data); + +/** + * @brief This function serves to analog register read by halfword. + * @param[in] addr - address need to be read. + * @return the result of read. + */ +unsigned short analog_read_reg16(unsigned char addr); + +/** + * @brief This function serves to analog register write by halfword. + * @param[in] addr - address need to be write. + * @param[in] data - the value need to be write. + * @return none. + */ +void analog_write_reg16(unsigned char addr, unsigned short data); + +/** + * @brief This function serves to analog register read by word. + * @param[in] addr - address need to be read. + * @return the result of read. + */ + unsigned int analog_read_reg32(unsigned char addr); + + /** + * @brief This function serves to analog register write by word. + * @param[in] addr - address need to be write. + * @param[in] data - the value need to be write. + * @return none. + */ +void analog_write_reg32(unsigned char addr, unsigned int data); +/** + * @brief This function serves to analog register read. + * @param[in] addr - address need to be read. + * @param[out] buff - the ptr of buffer to store the read data. + * @param[in] len - the length of read value. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void analog_read_buff(unsigned char addr, unsigned char *buff, int len); + +/** + * @brief This function serves to analog register write. + * @param[in] addr - address need to be write. + * @param[in] buff - the ptr of value need to be write. + * @param[in] len - the length of write value. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void analog_write_buff(unsigned char addr, unsigned char *buff, int len); + + +/** + * @brief This function serves to analog register write by word using dma. + * @param[in] chn - the dma channel. + * @param[in] addr - address need to be write. + * @param[in] pdat - the ptr of data need to be write. + * @return none. + */ +void analog_write_reg32_dma(dma_chn_e chn, unsigned char addr, void *pdat); + +/** + * @brief This function serves to analog register write by word using dma. + * @param[in] chn - the dma channel. + * @param[in] addr - address need to be read. + * @param[out] pdat - the buffer ptr to store read data. + * @return none. + */ +void analog_read_reg32_dma(dma_chn_e chn, unsigned char addr,void *pdat); + +/** + * @brief This function write buffer to analog register by dma channel. + * @param[in] chn - the dma channel. + * @param[in] addr - address need to be write. + * @param[in] pdat - the buffer ptr need to be write. + * @param[in] len - the length of buffer. + * @return none. + */ +void analog_write_buff_dma(dma_chn_e chn, unsigned char addr, unsigned char *pdat, unsigned int len); + +/** + * @brief This function write buffer to analog register by dma channel. + * @param[in] chn - the dma channel. + * @param[in] addr - address need to be read from. + * @param[out] pdat - the buffer ptr to store read data. + * note: The size of array pdat must be a multiple of 4. + * For example, if you just need read 5 byte by dma, you should + * define the size of array pdat to be greater than 8 other than 5. + * Because the dma would return 4 byte data every time, 5 byte is + * not enough to store them. + * @param[in] len - the length of read data. + * @return none. + */ +void analog_read_buff_dma(dma_chn_e chn, unsigned char addr, unsigned char *pdat, unsigned int len); + +/** + * @brief This function write buffer to analog register by dma channel. + * @param[in] chn - the dma channel. + * @param[in] pdat - the buffer(addr & data) ptr need to be write, + * note: The array pdat should look like this, + * | pdat | | | + * | :------ | :----------| :---- | + * | pdat[0] | address | 0x3a | + * | pdat[1] | data | 0x11 | + * | pdat[2] | address | 0x3b | + * | pdat[3] | data | 0x22 | + * | ...... | | | + * It means write data 0x11 to address 0x3a, + * write data 0x22 to address 0x3b, + * ...... + * @param[in] len - the length of read data. + * @return none. + */ +void analog_write_addr_data_dma(dma_chn_e chn, void *pdat, int len); diff --git a/b91/b91m_ble_sdk/drivers/B91/audio.c b/b91/b91m_ble_sdk/drivers/B91/audio.c new file mode 100755 index 0000000..ac28014 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/audio.c @@ -0,0 +1,1176 @@ +/******************************************************************************************************** + * @file audio.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "audio.h" +#include "clock.h" +#include "pwm.h" +#include "stimer.h" + + +unsigned char audio_rx_dma_chn; +unsigned char audio_tx_dma_chn; + +dma_chain_config_t g_audio_tx_dma_list_cfg; +dma_chain_config_t g_audio_rx_dma_list_cfg; + +aduio_i2s_codec_config_t audio_i2s_codec_config= +{ + .audio_in_mode =BIT_16_MONO, + .audio_out_mode =BIT_16_MONO_FIFO0, + .i2s_data_select =I2S_BIT_16_DATA, + .codec_data_select =CODEC_BIT_16_DATA, + .i2s_codec_m_s_mode =I2S_M_CODEC_S, + .i2s_data_invert_select =I2S_DATA_INVERT_DIS,//L channel default + .in_digital_gain =CODEC_IN_D_GAIN_0_DB, + .in_analog_gain =CODEC_IN_A_GAIN_8_DB, + .out_digital_gain =CODEC_OUT_D_GAIN_0_DB, + .out_analog_gain =CODEC_OUT_A_GAIN_6_DB, + .mic_input_mode_select =1,//0 single-ended input, 1 differential input +}; + +dma_config_t audio_dma_rx_config= +{ + .dst_req_sel= 0, + .src_req_sel=DMA_REQ_AUDIO0_RX,//rx req + .dst_addr_ctrl=DMA_ADDR_INCREMENT, + .src_addr_ctrl=DMA_ADDR_FIX, + .dstmode=DMA_NORMAL_MODE, + .srcmode=DMA_HANDSHAKE_MODE, + .dstwidth=DMA_CTR_WORD_WIDTH,//must word + .srcwidth=DMA_CTR_WORD_WIDTH,//must word + .src_burst_size=0,//must 0 + .read_num_en=0, + .priority=0, + .write_num_en=0, + .auto_en=0,//must 0 +}; + +dma_config_t audio_dma_tx_config= +{ + .dst_req_sel= DMA_REQ_AUDIO0_TX,//tx req + .src_req_sel=0, + .dst_addr_ctrl=DMA_ADDR_FIX, + .src_addr_ctrl=DMA_ADDR_INCREMENT,//increment + .dstmode=DMA_HANDSHAKE_MODE,//handshake + .srcmode=DMA_NORMAL_MODE, + .dstwidth=DMA_CTR_WORD_WIDTH,//must word + .srcwidth=DMA_CTR_WORD_WIDTH,//must word + .src_burst_size=0,//must 0 + .read_num_en=0, + .priority=0, + .write_num_en=0, + .auto_en=0,//must 0 +}; + + + +/** + * @brief This function serves to invert data between R channel and L channel. + * @param[in] en - I2S_DATA_INVERT_DIS: L channel (default); I2S_DATA_INVERT_EN: R channel. + * @return none + */ +void audio_set_mono_chn(audio_data_invert_e en) +{ + audio_i2s_codec_config.i2s_data_invert_select=en; +} + +/** + * @brief This function serves to set mic input mode. + * @param[in] input_mode - 0 single-ended input, 1 differential input. + * @return none + */ +void audio_set_codec_mic_input_mode (unsigned char input_mode) +{ + audio_i2s_codec_config.mic_input_mode_select=input_mode; +} + +/** + * @brief This function serves to set in path digital and analog gain . + * @param[in] d_gain - digital gain value + * @param[in] a_gain - analog gain value + * @return none + */ +void audio_set_codec_in_path_a_d_gain (codec_in_path_digital_gain_e d_gain,codec_in_path_analog_gain_e a_gain ) +{ + audio_i2s_codec_config.in_digital_gain=d_gain; + audio_i2s_codec_config.in_analog_gain=a_gain; +} + + +/** + * @brief This function serves to set out path digital and analog gain . + * @param[in] d_gain - digital gain value + * @param[in] a_gain - analog gain value + * @return none + */ + void audio_set_codec_out_path_a_d_gain (codec_out_path_digital_gain_e d_gain,codec_out_path_analog_gain_e a_gain) +{ + audio_i2s_codec_config.out_digital_gain=d_gain; + audio_i2s_codec_config.out_analog_gain=a_gain; +} + + + /** + * @brief This function serves to choose which is master to provide clock. + * @param[in] m_s - I2S_S_CODEC_M: i2s as slave ,codec as master; I2S_M_CODEC_S: i2s as master, codec as slave. + * @return none + */ +void audio_set_i2s_codec_m_s (i2s_codec_m_s_mode_e m_s) +{ + audio_i2s_codec_config.i2s_codec_m_s_mode=m_s; +} + +/** + * @brief This function serves to choose which is master to provide clock. + * @param[in] chn_wl: select word length and audio channel number + * @return none + */ +void aduio_set_chn_wl(audio_channel_wl_mode_e chn_wl) +{ + switch (chn_wl) + { + case MONO_BIT_16: + audio_i2s_codec_config.audio_in_mode=BIT_16_MONO; + audio_i2s_codec_config.audio_out_mode=BIT_16_MONO_FIFO0; + audio_i2s_codec_config.i2s_data_select=I2S_BIT_16_DATA; + audio_i2s_codec_config.codec_data_select=CODEC_BIT_16_DATA; + break; + + case MONO_BIT_20: + audio_i2s_codec_config.audio_in_mode=BIT_20_OR_24_MONO; + audio_i2s_codec_config.audio_out_mode=BIT_20_OR_24_MONO_FIFO0; + audio_i2s_codec_config.i2s_data_select=I2S_BIT_20_DATA; + audio_i2s_codec_config.codec_data_select=CODEC_BIT_20_DATA; + break; + + case MONO_BIT_24: + audio_i2s_codec_config.audio_in_mode=BIT_20_OR_24_MONO; + audio_i2s_codec_config.audio_out_mode=BIT_20_OR_24_MONO_FIFO0; + audio_i2s_codec_config.i2s_data_select=I2S_BIT_24_DATA; + audio_i2s_codec_config.codec_data_select=CODEC_BIT_24_DATA; + break; + + case STEREO_BIT_16: + audio_i2s_codec_config.audio_in_mode=BIT_16_STEREO; + audio_i2s_codec_config.audio_out_mode=BIT_16_STEREO_FIFO0; + audio_i2s_codec_config.i2s_data_select=I2S_BIT_16_DATA; + audio_i2s_codec_config.codec_data_select=CODEC_BIT_16_DATA; + break; + + case STEREO_BIT_20: + audio_i2s_codec_config.audio_in_mode=BIT_20_OR_24_STEREO; + audio_i2s_codec_config.audio_out_mode=BIT_20_OR_24_STEREO_FIFO0; + audio_i2s_codec_config.i2s_data_select=I2S_BIT_20_DATA; + audio_i2s_codec_config.codec_data_select=CODEC_BIT_20_DATA; + break; + + case STEREO_BIT_24: + audio_i2s_codec_config.audio_in_mode=BIT_20_OR_24_STEREO; + audio_i2s_codec_config.audio_out_mode=BIT_20_OR_24_STEREO_FIFO0; + audio_i2s_codec_config.i2s_data_select=I2S_BIT_24_DATA; + audio_i2s_codec_config.codec_data_select=CODEC_BIT_24_DATA; + break; + } + +} + + +/** + * @brief This function selects pin for i2s. + * @param[in] pin - the selected pin. + * @return none + */ +void audio_i2s_set_pin_mux(i2s_pin_e pin) +{ + + unsigned char val=0; + unsigned char start_bit = (BIT_LOW_BIT(pin & 0xff) %4 )<<1; + unsigned char mask =(unsigned char) ~BIT_RNG(start_bit , start_bit+1); + if(pin==I2S_BCK_PC3) + { + val = 0;//function 0 + } + else if((pin==I2S_ADC_LR_PC4)||(pin==I2S_ADC_DAT_PC5)||(pin==I2S_DAC_LR_PC6)||(pin==I2S_DAC_DAT_PC7)) + { + val = 1<<(start_bit);//function 1 + } + reg_gpio_func_mux(pin)=(reg_gpio_func_mux(pin)& mask)|val; + gpio_function_dis(pin); + +} + +/** + * @brief This function configures i2s pin. + * @param[in] none + * @return none + */ +void audio_i2s_set_pin(void) +{ + audio_i2s_set_pin_mux(I2S_BCK_PC3); + audio_i2s_set_pin_mux(I2S_ADC_LR_PC4); + audio_i2s_set_pin_mux(I2S_ADC_DAT_PC5); + audio_i2s_set_pin_mux(I2S_DAC_LR_PC6); + audio_i2s_set_pin_mux(I2S_DAC_DAT_PC7); +} + +/** + * @brief This function serves to set codec supply voltage + * @param[in] volt - the voltage of codec supply.A1 2.8V default,A0 1.8V default. + * @return none + * + */ +void audio_set_codec_supply (codec_volt_supply_e volt) +{ + + if(0xff==g_chip_version )//A0 1.8v default ( BIT(7) - 1: 2.8v 0: 1.8v ) + { + if(CODEC_2P8V==volt) + { + analog_write_reg8(0x02,analog_read_reg8(0x02)|BIT(7)); + } + + else if(CODEC_1P8V==volt) + { + analog_write_reg8(0x02,analog_read_reg8(0x02)&(~BIT(7))); + } + + } + + else //A1 2.8v default ( BIT(7) - 1: 1.8v 0: 2.8v ) + { + if(CODEC_1P8V==volt) + { + analog_write_reg8(0x02,analog_read_reg8(0x02)|BIT(7)); + } + + else if(CODEC_2P8V==volt) + { + analog_write_reg8(0x02,analog_read_reg8(0x02)&(~BIT(7))); + } + } +} + +/** + * @brief This function configures dmic pin. + * @param[in] pin_gp - the group of dmic pin + * @return none + */ +void audio_set_dmic_pin(dmic_pin_group_e pin_gp) +{ + if(pin_gp == DMIC_GROUPB_B2_DAT_B3_B4_CLK) + { + reg_gpio_pad_mul_sel=BIT(2); + reg_gpio_pb_fuc_h=reg_gpio_pb_fuc_h&(~BIT_RNG(0,1)); + reg_gpio_pb_fuc_l=(reg_gpio_pb_fuc_h&(~BIT_RNG(4,7)))|0x0f; + gpio_function_dis(GPIO_PB2|GPIO_PB3|GPIO_PB4); + } + else if(pin_gp == DMIC_GROUPC_C1_DAT_C2_C3_CLK) + { + reg_gpio_pad_mul_sel=BIT(0); + reg_gpio_pc_fuc_l=(reg_gpio_pc_fuc_l&(~BIT_RNG(2,7)))|((2<<2)|(2<<4)|(2<<6)); + gpio_function_dis(GPIO_PC1|GPIO_PC2|GPIO_PC3); + + } + else if(pin_gp == DMIC_GROUPD_D4_DAT_D5_D6_CLK)//can not use in A0 + { + reg_gpio_pd_fuc_h=(reg_gpio_pd_fuc_h&(~BIT_RNG(0,5)))|((1<<0)|(1<<2)|(1<<4)); + gpio_function_dis(GPIO_PD4|GPIO_PD5|GPIO_PD6); + } + else if(pin_gp == DMIC_B2_DAT_B3_CLK) + { + reg_gpio_pad_mul_sel=BIT(2); + reg_gpio_pb_fuc_l=(reg_gpio_pb_fuc_h&(~BIT_RNG(4,7)))|0x0f; + gpio_function_dis(GPIO_PB2|GPIO_PB3); + } + else if(pin_gp == DMIC_C1_DAT_C2_CLK) + { + reg_gpio_pad_mul_sel=BIT(0); + reg_gpio_pc_fuc_l=(reg_gpio_pc_fuc_l&(~BIT_RNG(2,5)))|((2<<2)|(2<<4)); + gpio_function_dis(GPIO_PC1|GPIO_PC2); + } + else if(pin_gp == DMIC_D4_DAT_D5_CLK)//can not use in A0 + { + reg_gpio_pd_fuc_h=(reg_gpio_pd_fuc_h&(~BIT_RNG(0,3)))|((1<<0)|(1<<2)); + gpio_function_dis(GPIO_PD4|GPIO_PD5); + } +} + + +/** + * @brief This function serves to enable rx_dma channel. + * @return none + */ + void audio_rx_dma_en(void) +{ + dma_chn_en(audio_rx_dma_chn); +} + + + /** + * @brief This function serves to disable rx_dma channel. + * @return none + */ + void audio_rx_dma_dis(void) + { + dma_chn_dis(audio_rx_dma_chn); + } + + + /** + * @brief This function serves to enable tx_dma channel. + * @return none + */ + void audio_tx_dma_en(void) +{ + dma_chn_en(audio_tx_dma_chn); +} + + + /** + * @brief This function serves to disable dis_dma channel. + * @return none + */ + void audio_tx_dma_dis(void) +{ + dma_chn_dis(audio_tx_dma_chn); +} + + /** + * @brief This function serves to config rx_dma channel. + * @param[in] chn - dma channel + * @param[in] dst_addr - the dma address of destination + * @param[in] data_len - the length of dma rx size by byte + * @param[in] head_of_list - the head address of dma llp. + * @return none + */ +void audio_rx_dma_config(dma_chn_e chn,unsigned short *dst_addr,unsigned int data_len,dma_chain_config_t *head_of_list) +{ + audio_rx_dma_chn=chn; + audio_set_rx_buff_len(data_len); + dma_config(audio_rx_dma_chn,&audio_dma_rx_config); + dma_set_address( chn,REG_AUDIO_AHB_BASE,(unsigned int)convert_ram_addr_cpu2bus(dst_addr)); + dma_set_size(chn,data_len,DMA_WORD_WIDTH); + reg_dma_llp(chn)=(unsigned int)convert_ram_addr_cpu2bus(head_of_list); + +} + +/** + * @brief This function serves to set rx dma chain transfer + * @param[in] rx_config - the head of list of llp_pointer. + * @param[in] llpointer - the next element of llp_pointer. + * @param[in] dst_addr -the dma address of destination. + * @param[in] data_len -the length of dma size by byte. + * @return none + */ +void audio_rx_dma_add_list_element(dma_chain_config_t *config_addr,dma_chain_config_t *llpointer ,unsigned short * dst_addr,unsigned int data_len) +{ + config_addr->dma_chain_ctl=reg_dma_ctrl(audio_rx_dma_chn)|BIT(0); + config_addr->dma_chain_src_addr=REG_AUDIO_AHB_BASE; + config_addr->dma_chain_dst_addr=(unsigned int)convert_ram_addr_cpu2bus(dst_addr); + config_addr->dma_chain_data_len=dma_cal_size(data_len,4); + config_addr->dma_chain_llp_ptr=(unsigned int)convert_ram_addr_cpu2bus(llpointer); +} + + +/** + * @brief This function serves to config tx_dma channel. + * @param[in] chn - dma channel + * @param[in] src_addr - the address of source + * @param[in] data_len - the length of dma rx size by byte + * @param[in] head_of_list - the head address of dma llp. + * @return none + */ +void audio_tx_dma_config(dma_chn_e chn,unsigned short * src_addr, unsigned int data_len,dma_chain_config_t * head_of_list) +{ + audio_tx_dma_chn=chn; + audio_set_tx_buff_len(data_len); + dma_config(audio_tx_dma_chn,&audio_dma_tx_config); + dma_set_address( chn,(unsigned int)convert_ram_addr_cpu2bus(src_addr),REG_AUDIO_AHB_BASE); + dma_set_size(chn,data_len,DMA_WORD_WIDTH); + reg_dma_llp(chn)=(unsigned int)convert_ram_addr_cpu2bus(head_of_list); +} + +/** + * @brief This function serves to set tx dma chain transfer + * @param[in] config_addr - the head of list of llp_pointer. + * @param[in] llpointer - the next element of llp_pointer. + * @param[in] src_addr - the address of source + * @param[in] data_len - the length of dma size by byte. + * @return none + */ +void audio_tx_dma_add_list_element(dma_chain_config_t *config_addr,dma_chain_config_t *llpointer ,unsigned short * src_addr,unsigned int data_len) +{ + config_addr->dma_chain_ctl=reg_dma_ctrl(audio_tx_dma_chn)|BIT(0); + config_addr->dma_chain_src_addr=(unsigned int)convert_ram_addr_cpu2bus(src_addr); + config_addr->dma_chain_dst_addr=REG_AUDIO_AHB_BASE; + config_addr->dma_chain_data_len=dma_cal_size(data_len,4); + config_addr->dma_chain_llp_ptr=(unsigned int)convert_ram_addr_cpu2bus(llpointer); +} + + +/** + * @brief This function serves to initialize audio by mc + * @param[in] flow_mode - select input out flow mode + * @param[in] rate - audio sampling rate. + * @param[in] channel_wl - word length and channel number. + * @return none + */ +void audio_init(audio_flow_mode_e flow_mode,audio_sample_rate_e rate,audio_channel_wl_mode_e channel_wl) +{ + aduio_set_chn_wl(channel_wl); + audio_set_codec_clk(1,16);//from ppl 192/16=12M + audio_mux_config(CODEC_I2S,audio_i2s_codec_config.audio_in_mode,audio_i2s_codec_config.audio_in_mode,audio_i2s_codec_config.audio_out_mode); + audio_i2s_config(I2S_I2S_MODE,audio_i2s_codec_config.i2s_data_select,audio_i2s_codec_config.i2s_codec_m_s_mode,audio_i2s_codec_config.i2s_data_invert_select); + audio_set_i2s_clock(rate,AUDIO_RATE_EQUAL,0); + audio_clk_en(1,1); + reg_audio_codec_vic_ctr=FLD_AUDIO_CODEC_SLEEP_ANALOG;//active analog sleep mode + while(!(reg_audio_codec_stat_ctr&FLD_AUDIO_CODEC_PON_ACK));//wait codec can be configed + if(flow_modeLINE_IN_TO_BUF) + { + audio_codec_dac_config(audio_i2s_codec_config.i2s_codec_m_s_mode,rate,audio_i2s_codec_config.codec_data_select,MCU_WREG); + } + while(!(reg_audio_codec_stat_ctr==(FLD_AUDIO_CODEC_ADC12_LOCKED|FLD_AUDIO_CODEC_DAC_LOCKED|FLD_AUDIO_CODEC_PON_ACK)));//wait codec adc/dac locked + + audio_data_fifo0_path_sel(I2S_DATA_IN_FIFO,I2S_OUT); +} + +/** + * @brief This function serves to read data from codec register. + * @param[in] addr: the address of codec register + * @return none + */ +unsigned char audio_i2c_codec_read(unsigned char addr) +{ + reg_i2c_data_buf(0)=addr<<1; + reg_i2c_len=0x01;//rx_len + reg_i2c_sct1=FLD_I2C_LS_ID|FLD_I2C_LS_ADDR|FLD_I2C_LS_START; + + while(i2c_master_busy()); //wait busy=0 + while(reg_i2c_mst & FLD_I2C_ACK_IN);//wait ack=0 + + reg_i2c_sct1=FLD_I2C_LS_ID|FLD_I2C_LS_DATAR|FLD_I2C_LS_START|FLD_I2C_LS_ID_R|FLD_I2C_LS_ACK; + while(i2c_master_busy()); //wait busy=0 + unsigned char rdat8= reg_i2c_data_buf(0); + reg_i2c_sct1=FLD_I2C_LS_STOP|FLD_I2C_LS_ID_R; + while(i2c_master_busy()); //wait busy=0 + return rdat8; +} + +/** + * @brief This function serves to write data to codec register. + * @param[in] addr: the address of codec register + * @return none + */ +void audio_i2c_codec_write(unsigned char addr ,unsigned char wdat) +{ + + reg_i2c_data_buf(0)=addr<<1; + reg_i2c_data_buf(1)=wdat; + reg_i2c_len=2;//tx_len + reg_i2c_sct1=FLD_I2C_LS_ID|FLD_I2C_LS_DATAW| FLD_I2C_LS_START| FLD_I2C_LS_STOP; + while(i2c_master_busy()); //wait busy=0 + while(reg_i2c_mst & FLD_I2C_ACK_IN);//wait ack=0 +} + +/** + * @brief This function serves to enable i2c master for codec i2c slave . + * @param[in] none. + * @return none. + */ +void audio_i2c_init(codec_type_e codec_type, i2c_sda_pin_e sda_pin,i2c_scl_pin_e scl_pin) +{ + i2c_master_init(); + i2c_set_master_clk((unsigned char)(sys_clk.pclk*1000*1000/(4*20000)));//set i2c frequency 400K. + //reg_i2c_sp=0x1e;//200k sys_clk.pclk=24M + if(codec_type==INNER_CODEC) + { + reg_audio_i2c_mode=0x05;//codec config by i2c + reg_i2c_id=(0x34<<1);//set i2c id + reg_audio_i2c_addr=0x34; + } + else if(codec_type==EXT_CODEC) + { + reg_i2c_id=0x34; + i2c_set_pin(sda_pin,scl_pin); + } +} + +/** + * @brief This function serves to initialize audio by i2c + * @param[in] flow_mode - select input out flow mode + * @param[in] rate - audio sampling rate. + * @param[in] channel_wl - word length and channel number. + * @return none + */ +void audio_init_i2c(audio_flow_mode_e flow_mode,audio_sample_rate_e rate,audio_channel_wl_mode_e channel_wl) +{ + aduio_set_chn_wl(channel_wl); + audio_set_codec_clk(1,16);////from ppl 192/16=12M + audio_mux_config(CODEC_I2S,audio_i2s_codec_config.audio_in_mode,audio_i2s_codec_config.audio_in_mode,audio_i2s_codec_config.audio_out_mode); + audio_i2s_config(I2S_I2S_MODE,audio_i2s_codec_config.i2s_data_select,audio_i2s_codec_config.i2s_codec_m_s_mode,audio_i2s_codec_config.i2s_data_invert_select); + audio_set_i2s_clock(rate,AUDIO_RATE_EQUAL,0); + audio_clk_en(1,1); + audio_i2c_init(INNER_CODEC,0,0); + audio_i2c_codec_write(addr_audio_codec_vic_ctr,FLD_AUDIO_CODEC_SLEEP_ANALOG);//active analog sleep mode + while(!(audio_i2c_codec_read(addr_audio_codec_stat_ctr)&FLD_AUDIO_CODEC_PON_ACK));//wait codec can be configed + if(flow_modeLINE_IN_TO_BUF) + { + audio_codec_dac_config(audio_i2s_codec_config.i2s_codec_m_s_mode,rate,audio_i2s_codec_config.codec_data_select,I2C_WREG); + } + while(!(audio_i2c_codec_read(addr_audio_codec_stat_ctr)==(FLD_AUDIO_CODEC_ADC12_LOCKED|FLD_AUDIO_CODEC_DAC_LOCKED|FLD_AUDIO_CODEC_PON_ACK)));//wait codec adc/dac locked + audio_data_fifo0_path_sel(I2S_DATA_IN_FIFO,I2S_OUT); +} + +/** + * @brief This function serves to config codec for dac. + * @param[in] mode - select i2s as master or slave + * @param[in] rate - audio sampling rate + * @param[in] data_select - codec dac word length + * @param[in] wreg_mode - mcu or i2c config codec + * @return none + */ +void audio_codec_dac_config(i2s_codec_m_s_mode_e mode,audio_sample_rate_e rate,codec_data_select_e data_select,codec_wreg_mode_e wreg_mode) +{ + + if(wreg_mode==MCU_WREG) + { + BM_SET(reg_audio_codec_dac_ctr,FLD_AUDIO_CODEC_DAC_SOFT_MUTE); //dac mute + if((audio_i2s_codec_config.audio_out_mode==BIT_16_MONO_FIFO0)||((audio_i2s_codec_config.audio_out_mode==BIT_20_OR_24_MONO_FIFO0))) + { + BM_CLR(reg_audio_codec_dac_ctr,FLD_AUDIO_CODEC_DAC_SB); //active DAC power + BM_SET(reg_audio_codec_dac_ctr,FLD_AUDIO_CODEC_DAC_LEFT_ONLY); //active left channel only + } + else + { + BM_CLR(reg_audio_codec_dac_ctr,FLD_AUDIO_CODEC_DAC_SB|FLD_AUDIO_CODEC_DAC_LEFT_ONLY);//active DAC power,active left and right channel + } + + BM_CLR(reg_audio_codec_vic_ctr,FLD_AUDIO_CODEC_SB|FLD_AUDIO_CODEC_SB_ANALOG|FLD_AUDIO_CODEC_SLEEP_ANALOG);//disable sleep mode ,disable sb_analog,disable global standby + + /* data word length ,interface master/slave selection, audio interface protocol selection ,active dac audio interface*/ + reg_audio_codec_dac_itf_ctr= MASK_VAL( FLD_AUDIO_CODEC_FORMAT, CODEC_I2S_MODE,\ + FLD_AUDIO_CODEC_DAC_ITF_SB, CODEC_ITF_AC, \ + FLD_AUDIO_CODEC_SLAVE, mode, \ + FLD_AUDIO_CODEC_WL, data_select); + + /*disable DAC digital gain coupling, Left channel DAC digital gain*/ + reg_audio_codec_dacl_gain=MASK_VAL(FLD_AUDIO_CODEC_DAC_LRGOD,0,\ + FLD_AUDIO_CODEC_DAC_GODL,audio_i2s_codec_config.out_digital_gain); + + reg_audio_codec_dacr_gain=MASK_VAL(FLD_AUDIO_CODEC_DAC_GODR,audio_i2s_codec_config.out_digital_gain); /*Right channel DAC digital gain*/ + + /*disable Headphone gain coupling, set Left channel HP amplifier gain*/ + reg_audio_codec_hpl_gain=MASK_VAL(FLD_AUDIO_CODEC_HPL_LRGO,0,\ + FLD_AUDIO_CODEC_HPL_GOL,audio_i2s_codec_config.out_analog_gain); + + reg_audio_codec_hpr_gain=MASK_VAL(FLD_AUDIO_CODEC_HPR_GOR, audio_i2s_codec_config.out_analog_gain); /* Right channel HP amplifier gain programming*/ + + reg_audio_codec_dac_freq_ctr=(FLD_AUDIO_CODEC_DAC_FREQ&(rate== AUDIO_ADC_16K_DAC_48K ? AUDIO_48K :rate)); + + BM_CLR(reg_audio_codec_dac_ctr,FLD_AUDIO_CODEC_DAC_SOFT_MUTE); /*dac mute*/ + } + + else if (wreg_mode==I2C_WREG) + { + /*active DAC power,active left and right channel,dac mute*/ + audio_i2c_codec_write(addr_audio_codec_dac_ctr,MASK_VAL( FLD_AUDIO_CODEC_DAC_SB, 0,\ + FLD_AUDIO_CODEC_DAC_LEFT_ONLY, 0, \ + FLD_AUDIO_CODEC_DAC_SOFT_MUTE, 1)); + + + /*disable sleep mode ,disable sb_analog,disable global standby*/ + audio_i2c_codec_write(addr_audio_codec_vic_ctr,MASK_VAL( FLD_AUDIO_CODEC_SB, 0,\ + FLD_AUDIO_CODEC_SB_ANALOG, 0, \ + FLD_AUDIO_CODEC_SLEEP_ANALOG, 0)); + + /*data word length ,interface master/slave selection, audio interface protocol selection ,active dac audio interface */ + audio_i2c_codec_write(addr_audio_codec_dac_itf_ctr,MASK_VAL( FLD_AUDIO_CODEC_FORMAT, CODEC_I2S_MODE,\ + FLD_AUDIO_CODEC_DAC_ITF_SB, CODEC_ITF_AC, \ + FLD_AUDIO_CODEC_SLAVE, mode, \ + FLD_AUDIO_CODEC_WL, data_select)); + + /* disable DAC digital gain coupling, Left channel DAC digital gain */ + audio_i2c_codec_write(addr_audio_codec_dacl_gain,MASK_VAL(FLD_AUDIO_CODEC_DAC_LRGOD,0,\ + FLD_AUDIO_CODEC_DAC_GODL,audio_i2s_codec_config.out_digital_gain)); + + + audio_i2c_codec_write(addr_audio_codec_dacr_gain,MASK_VAL(FLD_AUDIO_CODEC_DAC_GODR,audio_i2s_codec_config.out_digital_gain));/* Right channel DAC digital gain */ + + + /* disable Headphone gain coupling, set Left channel HP amplifier gain */ + audio_i2c_codec_write(addr_audio_codec_hpl_gain,MASK_VAL(FLD_AUDIO_CODEC_HPL_LRGO,0,\ + FLD_AUDIO_CODEC_HPL_GOL,audio_i2s_codec_config.out_analog_gain)); + + audio_i2c_codec_write(addr_audio_codec_hpr_gain,MASK_VAL(FLD_AUDIO_CODEC_HPR_GOR, audio_i2s_codec_config.out_analog_gain));/* Right channel HP amplifier gain programming*/ + + audio_i2c_codec_write(addr_audio_codec_dac_freq_ctr,(FLD_AUDIO_CODEC_DAC_FREQ&rate)); + + /*dac mute*/ + audio_i2c_codec_write(addr_audio_codec_dac_ctr,MASK_VAL( FLD_AUDIO_CODEC_DAC_SB, 0,\ + FLD_AUDIO_CODEC_DAC_LEFT_ONLY, 0, \ + FLD_AUDIO_CODEC_DAC_SOFT_MUTE, 0)); + } + +} + + + +/** + * @brief This function serves to config codec for adc. + * @param[in] mode - select i2s as master or slave + * @param[in] in_mode - line_in/amic/dmic input mode select + * @param[in] rate - audio sampling rate + * @param[in] data_select - codec adc word length + * @param[in] wreg_mode - mcu or i2c config codec + * @return none + */ +void audio_codec_adc_config(i2s_codec_m_s_mode_e mode,audio_input_mode_e in_mode,audio_sample_rate_e rate,codec_data_select_e data_select,codec_wreg_mode_e wreg_mode) +{ + + if(wreg_mode==MCU_WREG) + { + BM_SET(reg_audio_codec_adc12_ctr,FLD_AUDIO_CODEC_ADC12_SOFT_MUTE); /*adc mute*/ + if((audio_i2s_codec_config.audio_in_mode==BIT_16_MONO)||((audio_i2s_codec_config.audio_in_mode==BIT_20_OR_24_MONO))) + { + BM_CLR(reg_audio_codec_adc12_ctr,FLD_AUDIO_CODEC_ADC1_SB);/*active anc0 channel,mono .*/ + } + else + { + BM_CLR(reg_audio_codec_adc12_ctr,FLD_AUDIO_CODEC_ADC1_SB|FLD_AUDIO_CODEC_ADC2_SB);/*active adc0 and adc1 channel*/ + } + BM_CLR(reg_audio_codec_vic_ctr,FLD_AUDIO_CODEC_SB|FLD_AUDIO_CODEC_SB_ANALOG|FLD_AUDIO_CODEC_SLEEP_ANALOG);/*disable sleep mode ,disable sb_analog,disable global standby*/ + + if (in_mode==AMIC_INPUT) + { + /*Microphone 1 input selection ,Microphone biasing active,Single-ended input,MICBIAS1 output=2.08V,*/ + reg_audio_codec_mic1_ctr= MASK_VAL( FLD_AUDIO_CODEC_MIC1_SEL, 0,\ + FLD_AUDIO_CODEC_MICBIAS1_SB, 0, \ + FLD_AUDIO_CODEC_MIC_DIFF1, audio_i2s_codec_config.mic_input_mode_select,\ + FLD_AUDIO_CODEC_MICBIAS1_V, 0); + /*Microphone 2 input selection,Single-ended input*/ + reg_audio_codec_mic2_ctr= MASK_VAL( FLD_AUDIO_CODEC_MIC2_SEL, 0,\ + FLD_AUDIO_CODEC_MIC_DIFF2, audio_i2s_codec_config.mic_input_mode_select); + + /*enable wind noise filter mode3*/ + reg_audio_codec_adc_wnf_ctr = CODEC_ADC_WNF_MODE3; + + /*analog 0/4/8/12/16/20 dB boost gain*/ + reg_audio_codec_mic_l_R_gain= MASK_VAL( FLD_AUDIO_CODEC_AMIC_L_GAIN, audio_i2s_codec_config.in_analog_gain,\ + FLD_AUDIO_CODEC_AMIC_R_GAIN, audio_i2s_codec_config.in_analog_gain); + } + else if(in_mode==DMIC_INPUT) + { + reg_audio_dmic_12=MASK_VAL( FLD_AUDIO_CODEC_ADC_DMIC_SEL2, 1,\ + FLD_AUDIO_CODEC_ADC_DMIC_SEL1,1, \ + FLD_AUDIO_CODEC_DMIC2_SB,CODEC_ITF_AC,\ + FLD_AUDIO_CODEC_DMIC1_SB, CODEC_ITF_AC); + } + + else if(in_mode==LINE_INPUT) + { + /*analog 0/4/8/12/16/20 dB boost gain*/ + reg_audio_codec_mic_l_R_gain= MASK_VAL( FLD_AUDIO_CODEC_AMIC_L_GAIN, audio_i2s_codec_config.in_analog_gain,\ + FLD_AUDIO_CODEC_AMIC_R_GAIN, audio_i2s_codec_config.in_analog_gain); + } + + /*0db~43db 1db step ,digital programmable gain*/ + reg_audio_adc1_gain=MASK_VAL( FLD_AUDIO_CODEC_ADC_LRGID,1,\ + FLD_AUDIO_CODEC_ADC_GID1,audio_i2s_codec_config.in_digital_gain); + /*data word length ,interface master/slave selection, audio interface protocol selection */ + reg_audio_codec_adc_itf_ctr= MASK_VAL( FLD_AUDIO_CODEC_FORMAT, CODEC_I2S_MODE,\ + FLD_AUDIO_CODEC_SLAVE, mode, \ + FLD_AUDIO_CODEC_WL, data_select); + /*audio adc interface active*/ + BM_CLR(reg_audio_codec_adc2_ctr,FLD_AUDIO_CODEC_ADC12_SB); + + /* adc high pass filter active, set adc sample rate */ + reg_audio_codec_adc_freq_ctr=MASK_VAL( FLD_AUDIO_CODEC_ADC12_HPF_EN,1,\ + FLD_AUDIO_CODEC_ADC_FREQ,rate == AUDIO_ADC_16K_DAC_48K ? AUDIO_16K :rate); + + BM_CLR(reg_audio_codec_adc12_ctr,FLD_AUDIO_CODEC_ADC12_SOFT_MUTE);/*adc unmute*/ + } + + else if(wreg_mode==I2C_WREG) + { + + + /*active adc0 and adc1 channel, if mono only active adc1,adc mute*/ + audio_i2c_codec_write(addr_audio_codec_adc12_ctr,MASK_VAL( FLD_AUDIO_CODEC_ADC1_SB, 0,\ + FLD_AUDIO_CODEC_ADC2_SB, 0, \ + FLD_AUDIO_CODEC_ADC12_SOFT_MUTE, 1)); + + /*disable sleep mode ,disable sb_analog,disable global standby*/ + audio_i2c_codec_write(addr_audio_codec_vic_ctr,MASK_VAL( FLD_AUDIO_CODEC_SB, 0,\ + FLD_AUDIO_CODEC_SB_ANALOG, 0, \ + FLD_AUDIO_CODEC_SLEEP_ANALOG, 0)); + + + if (in_mode==AMIC_INPUT) + { + /*Microphone 1 input selection ,Microphone biasing active,Single-ended input,MICBIAS1 output=2.08V,*/ + audio_i2c_codec_write(addr_audio_codec_mic1_ctr,MASK_VAL( FLD_AUDIO_CODEC_MIC1_SEL, 0,\ + FLD_AUDIO_CODEC_MICBIAS1_SB, 0, \ + FLD_AUDIO_CODEC_MIC_DIFF1, 0,\ + FLD_AUDIO_CODEC_MICBIAS1_V, 0)); + + /*Microphone 2 input selection,Single-ended input*/ + audio_i2c_codec_write(addr_audio_codec_mic2_ctr,MASK_VAL( FLD_AUDIO_CODEC_MIC2_SEL, 0,\ + FLD_AUDIO_CODEC_MIC_DIFF2, 0)); + + /*analog 0/4/8/12/16/20 dB boost gain*/ + audio_i2c_codec_write(addr_audio_codec_mic_l_R_gain, MASK_VAL( FLD_AUDIO_CODEC_AMIC_L_GAIN, audio_i2s_codec_config.in_analog_gain,\ + FLD_AUDIO_CODEC_AMIC_R_GAIN, audio_i2s_codec_config.in_analog_gain)); + + } + else if(in_mode==DMIC_INPUT) + { + audio_i2c_codec_write(addr_audio_dmic_12,MASK_VAL( FLD_AUDIO_CODEC_ADC_DMIC_SEL2, 1,\ + FLD_AUDIO_CODEC_ADC_DMIC_SEL1,1, \ + FLD_AUDIO_CODEC_DMIC2_SB,CODEC_ITF_AC,\ + FLD_AUDIO_CODEC_DMIC1_SB, CODEC_ITF_AC)); + } + + else if(in_mode==LINE_INPUT) + { + /*analog 0/4/8/12/16/20 dB boost gain*/ + audio_i2c_codec_write(addr_audio_codec_mic_l_R_gain, MASK_VAL( FLD_AUDIO_CODEC_AMIC_L_GAIN, audio_i2s_codec_config.in_analog_gain,\ + FLD_AUDIO_CODEC_AMIC_R_GAIN, audio_i2s_codec_config.in_analog_gain)); + } + + /*0db~43db 1db step ,digital programmable gain*/ + audio_i2c_codec_write(addr_audio_adc1_gain,MASK_VAL( FLD_AUDIO_CODEC_ADC_LRGID,1,\ + FLD_AUDIO_CODEC_ADC_GID1,audio_i2s_codec_config.in_digital_gain)); + + + audio_i2c_codec_write(addr_audio_codec_adc_itf_ctr,MASK_VAL( FLD_AUDIO_CODEC_FORMAT, CODEC_I2S_MODE,\ + FLD_AUDIO_CODEC_SLAVE, mode, \ + FLD_AUDIO_CODEC_WL, data_select)); + + audio_i2c_codec_write(addr_audio_codec_adc2_ctr,~FLD_AUDIO_CODEC_ADC12_SB); /*audio adc interface active*/ + + + /* adc high pass filter active, set adc sample rate */ + audio_i2c_codec_write(addr_audio_codec_adc_freq_ctr,MASK_VAL( FLD_AUDIO_CODEC_ADC12_HPF_EN,1,\ + FLD_AUDIO_CODEC_ADC_FREQ,rate)); + + /*dac mute*/ + audio_i2c_codec_write(addr_audio_codec_adc12_ctr,MASK_VAL( FLD_AUDIO_CODEC_ADC1_SB, 0,\ + FLD_AUDIO_CODEC_ADC2_SB, 0, \ + FLD_AUDIO_CODEC_ADC12_SOFT_MUTE, 0)); + + } + + +} + + +/** + * @brief This function serves to set data path. + * @param[in] audio_flow - audio flow select + * @param[in] ain0_mode - fifo0 input mode select + * @param[in] ain1_mode - fifo1 input mode select + * @param[in] i2s_aout_mode - fifo output source select + * @return none + */ +void audio_mux_config(audio_flow_e audio_flow, audio_in_mode_e ain0_mode , audio_in_mode_e ain1_mode,audio_out_mode_e i2s_aout_mode) +{ + reg_audio_ctrl |= audio_flow; + reg_audio_tune= MASK_VAL( FLD_AUDIO_I2S_I2S_AIN0_COME, ain0_mode,\ + FLD_AUDIO_I2S_I2S_AIN1_COME, ain1_mode, \ + FLD_AUDIO_I2S_I2S_AOUT_COME, i2s_aout_mode); +} + + +/** + * @brief This function serves to config interface, word length, and m/s . + * @param[in] i2s_format - interface protocol + * @param[in] wl - audio data word length + * @param[in] m_s - select i2s as master or slave + * @param[in] en - 1 enable audio data invert , 0 disable audio data invert .for example in mono mode switch R and L channel data to fifo0 + * @return none + */ +void audio_i2s_config(i2s_mode_select_e i2s_format,i2s_data_select_e wl, i2s_codec_m_s_mode_e m_s , audio_data_invert_e en ) +{ + + reg_i2s_cfg = MASK_VAL( FLD_AUDIO_I2S_FORMAT, i2s_format,\ + FLD_AUDIO_I2S_WL, wl, \ + FLD_AUDIO_I2S_LRP, 0, \ + FLD_AUDIO_I2S_LRSWAP, en, \ + FLD_AUDIO_I2S_ADC_DCI_MS, m_s, \ + FLD_AUDIO_I2S_DAC_DCI_MS, m_s); +} + +/** + * @brief This function serves to set i2s clock and audio sampling rate when i2s as master. + * @param[in] audio_rate - audio sampling rate + * @param[in] match - the match of audio rate. + * @param[in] match_en - initial must 0, then change rate must 1 + * @return none + * @attention i2s clock divider from pll,sampling rate calculation is based on pll=192M,so pll must be 192M + */ +_attribute_ram_code_sec_noinline_ void audio_set_i2s_clock (audio_sample_rate_e audio_rate,audio_rate_match_e match,unsigned char match_en) +{ + reg_tx_wptr=0xffff;//enable tx_rptr + unsigned short tx_rptr_old; + switch(audio_rate) + { + case AUDIO_8K : + audio_set_i2s_clk(1,8);//set i2s clk 24M + audio_set_i2s_bclk(12);//24/(2*12) = 1M bclk + audio_set_lrclk(125,125); //bclk/125=8k + break; + + case AUDIO_16K: + audio_set_i2s_clk(1,8);//set i2s clk 24M + audio_set_i2s_bclk(6);//24/(2*6) = 2M bclk + audio_set_lrclk(125,125); //bclk/125=16k + break; + + case AUDIO_32K: + audio_set_i2s_clk(1,8);//set i2s clk 24M + audio_set_i2s_bclk(3);//24/(2*3) = 4M bclk + audio_set_lrclk(125,125); //bclk/125=32k + break; + + case AUDIO_ADC_16K_DAC_48K: + audio_set_i2s_clk(2,125);//i2s clk 3.072 M + audio_set_i2s_bclk(0);//3.072/1 = 3.072M bclk + audio_set_lrclk(192,64);//adc_lrclk=3.072/192=16K,dac_lrclk=3.072/64=48K + break; + + case AUDIO_48K: + if(match_en) + { + tx_rptr_old = reg_tx_rptr; + while(tx_rptr_old==reg_tx_rptr); + } + if(match==AUDIO_RATE_EQUAL)//48000 + { + audio_set_i2s_clk(2,125);//i2s clk 3.072 M + audio_set_i2s_bclk(0);//3.072/1 = 3.072M bclk + audio_set_lrclk(64,64);//bclk/64=48k + } + + else if(match==AUDIO_RATE_GT_L0)//48004 + { + audio_set_i2s_clk(3,169); + audio_set_i2s_bclk(0); + audio_set_lrclk(71,71); + } + + else if(match==AUDIO_RATE_GT_L1)//48012.0 + { + audio_set_i2s_clk(4,129); + audio_set_i2s_bclk(0); + audio_set_lrclk(124,124); + } + else if(match==AUDIO_RATE_LT_L0) + { + audio_set_i2s_clk(2,63);//47994.0 + audio_set_i2s_bclk(0); + audio_set_lrclk(127,127); + } + + else if(match==AUDIO_RATE_LT_L1) + { + audio_set_i2s_clk(4,165);//47985.0 + audio_set_i2s_bclk(0); + audio_set_lrclk(97,97); + } + break; + + case AUDIO_44EP1K: + if(match_en) + { + tx_rptr_old = reg_tx_rptr; + while(tx_rptr_old==reg_tx_rptr); + } + + if(match==AUDIO_RATE_EQUAL)//44099.9 + { + audio_set_i2s_clk(8,215); + audio_set_i2s_bclk(0); + audio_set_lrclk(162,162); + } + else if(match==AUDIO_RATE_GT_L0)//44110.2 + { + audio_set_i2s_clk(11,228); + audio_set_i2s_bclk(0); + audio_set_lrclk(210,210); + } + + else if(match==AUDIO_RATE_GT_L1)//44117.6 + { + audio_set_i2s_clk(5,170); + audio_set_i2s_bclk(0); + audio_set_lrclk(128,128); + } + + else if(match==AUDIO_RATE_LT_L0)//44094.4 + { + audio_set_i2s_clk(7,254); + audio_set_i2s_bclk(0); + audio_set_lrclk(120,120); + } + + else if(match==AUDIO_RATE_LT_L1)//44081.6 + { + audio_set_i2s_clk(9,245); + audio_set_i2s_bclk(0); + audio_set_lrclk(160,160); + } + break; + } + +} + + +/** + * @brief This function serves to set audio rx dma chain transfer. + * @param[in] chn - dma channel + * @param[in] in_buff - the pointer of rx_buff. + * @param[in] buff_size - the size of rx_buff. + * @return none + */ + void audio_rx_dma_chain_init (dma_chn_e chn,unsigned short * in_buff,unsigned int buff_size ) +{ + audio_rx_dma_config(chn,(unsigned short*)in_buff, buff_size, &g_audio_rx_dma_list_cfg); + audio_rx_dma_add_list_element(&g_audio_rx_dma_list_cfg, &g_audio_rx_dma_list_cfg,(unsigned short*)in_buff, buff_size); + audio_rx_dma_en(); +} + + /** + * @brief This function serves to initialize audio tx dma chain transfer. + * @param[in] chn - dma channel + * @param[in] out_buff - the pointer of tx_buff. + * @param[in] buff_size - the size of tx_buff. + * @return none + */ +void audio_tx_dma_chain_init (dma_chn_e chn,unsigned short * out_buff,unsigned int buff_size) +{ + audio_tx_dma_config(chn, (unsigned short*)out_buff, buff_size, &g_audio_tx_dma_list_cfg); + audio_tx_dma_add_list_element(&g_audio_tx_dma_list_cfg, &g_audio_tx_dma_list_cfg, (unsigned short*)out_buff, buff_size); + audio_tx_dma_en(); +} + + + + +#define WM8731_ANA_AUDIO_PATH_CTRL 0x08 //Analogue Audio Path Control +#define WM8731_DIG_AUDIO_PATH_CTRL 0x0a //Digital Audio Path Control +#define WM8731_POWER_DOWN_CTRL 0x0c //Power Down Control +#define WM8731_ST_LINE_VOL 0x00 //Set linmute volume +#define WM8731_ST_RINE_VOL 0x02 //Set rinmute volume +#define WM8731_DIG_AUDIO_INTERFACE_FORMAT 0x0e //Digital Audio Interface Format +#define WM8731_SAMPLING_CTRL 0x10 //Sampling Control +#define WM8731_ACTIVE_CTRL 0x12 //Active Control +#define WM8731_RESET_CTRL 0x1e //Reset Register + +unsigned char LineIn_To_I2S_CMD_TAB[9][2]={ {WM8731_RESET_CTRL, 0x00}, + {WM8731_ST_LINE_VOL, 0x10}, + {WM8731_ST_RINE_VOL, 0x10}, + {WM8731_ANA_AUDIO_PATH_CTRL, 0x13}, + {WM8731_DIG_AUDIO_PATH_CTRL, 0x00}, + {WM8731_POWER_DOWN_CTRL, 0x22}, + {WM8731_DIG_AUDIO_INTERFACE_FORMAT, 0x02}, + {WM8731_SAMPLING_CTRL, 0x19}, + {WM8731_ACTIVE_CTRL, 0x01}, + +}; + +/** + * @brief This function serves to set external codec by i2c + * @return none + */ +void audio_set_ext_codec(void) +{ + for (unsigned char i=0;i<9;i++) + { + audio_i2c_codec_write(LineIn_To_I2S_CMD_TAB[i][0]>>1,LineIn_To_I2S_CMD_TAB[i][1]); + } +} + + +/** + * @brief This function serves to set pwm0 as external codec mclk + * @param[in] pin - the pin of pwm0 + * @return none + */ +void pwm_set(pwm_pin_e pin) +{ + reg_pwm_enable=0; + reg_pwm0_enable=0;//off pwm0 + pwm_set_pin(pin); + pwm_set_clk((unsigned char) (sys_clk.pclk*1000*1000/24000000-1)); + //reg_pwm_clkdiv = 0;//set pwm clk equal pclk 24M + pwm_set_pwm0_mode(PWM_NORMAL_MODE); + pwm_set_tcmp(PWM0_ID,1); + pwm_set_tmax(PWM0_ID,2);//24M/2=12M pwm mclk to ext codec clk + pwm_start(PWM0_ID); + +} + + +/** + * @brief This function serves to initialize audio(external codec WM8731) by i2c. + * @param[in] pwm0_pin - the pin of pwm0 + * @param[in] sda_pin - the pin port selected as I2C sda pin port. + * @param[in] scl_pin - the pin port selected as I2C scl pin port. + * @return none + */ +void audio_i2s_init(pwm_pin_e pwm0_pin, i2c_sda_pin_e sda_pin,i2c_scl_pin_e scl_pin) +{ + pwm_set(pwm0_pin); + audio_i2s_set_pin(); + audio_i2c_init(EXT_CODEC,sda_pin,scl_pin); + aduio_set_chn_wl(MONO_BIT_16); + audio_mux_config(IO_I2S,BIT_16_MONO,BIT_16_MONO,BIT_16_MONO_FIFO0); + audio_i2s_config(I2S_I2S_MODE,I2S_BIT_16_DATA,I2S_M_CODEC_S,I2S_DATA_INVERT_DIS); + audio_set_i2s_clock(AUDIO_32K,AUDIO_RATE_EQUAL,0); + audio_clk_en(1,1); + audio_set_ext_codec(); + audio_data_fifo0_path_sel(I2S_DATA_IN_FIFO,I2S_OUT); + +} + +/** + * @brief This function serves to active soft mute dac and disable dma . + * @return none + */ + void audio_pause_out_path(void) +{ + BM_SET(reg_audio_codec_dac_ctr,FLD_AUDIO_CODEC_DAC_SOFT_MUTE);//dac mute + audio_tx_dma_dis(); +} + + /** + * @brief This function serves to inactive soft mute dac and enable dma after change_sample_rate. + * @return none + */ + void audio_resume_out_path(void) +{ + BM_CLR(reg_audio_codec_dac_ctr,FLD_AUDIO_CODEC_DAC_SOFT_MUTE);//dac unmute + audio_tx_dma_en(); +} +/** + * @brief This function serves to change sample rate for dac. + * @param[in] rate - the sample rate of dac + * @return none + */ +_attribute_ram_code_sec_ void audio_change_sample_rate (audio_sample_rate_e rate) +{ + audio_set_i2s_clock(rate, AUDIO_RATE_EQUAL,1); + reg_audio_codec_dac_freq_ctr=(FLD_AUDIO_CODEC_DAC_FREQ&rate); +} + + + +/** + * @brief This function serves to power down codec_dac. + * @return none + */ +void audio_codec_dac_power_down(void) +{ + BM_SET(reg_audio_codec_dac_ctr,FLD_AUDIO_CODEC_DAC_SOFT_MUTE); + delay_ms(10); + BM_SET(reg_audio_codec_dac_itf_ctr,FLD_AUDIO_CODEC_DAC_ITF_SB); + BM_SET(reg_audio_codec_dac_ctr,FLD_AUDIO_CODEC_DAC_SB); + delay_ms(1); + BM_SET(reg_audio_codec_vic_ctr,FLD_AUDIO_CODEC_SLEEP_ANALOG); + reg_audio_codec_vic_ctr= MASK_VAL( FLD_AUDIO_CODEC_SB, CODEC_ITF_PD,\ + FLD_AUDIO_CODEC_SB_ANALOG, CODEC_ITF_PD, \ + FLD_AUDIO_CODEC_SLEEP_ANALOG, CODEC_ITF_PD); + audio_tx_dma_dis(); + audio_clk_en(0,0); +} + +/** + * @brief This function serves to power on codec_dac. + * @return none + */ +void audio_codec_dac_power_on(void) +{ + audio_clk_en(1,1); + BM_SET(reg_audio_codec_vic_ctr,FLD_AUDIO_CODEC_SLEEP_ANALOG); + delay_ms(1); + BM_CLR(reg_audio_codec_dac_ctr,FLD_AUDIO_CODEC_DAC_SB); + BM_CLR(reg_audio_codec_dac_itf_ctr,FLD_AUDIO_CODEC_DAC_ITF_SB); + reg_audio_codec_vic_ctr= MASK_VAL( FLD_AUDIO_CODEC_SB, CODEC_ITF_AC,\ + FLD_AUDIO_CODEC_SB_ANALOG, CODEC_ITF_AC, \ + FLD_AUDIO_CODEC_SLEEP_ANALOG, CODEC_ITF_AC); + BM_CLR(reg_audio_codec_dac_ctr,FLD_AUDIO_CODEC_DAC_SOFT_MUTE);//un mute + audio_tx_dma_en(); + +} + +/** + * @brief This function serves to power down codec_adc. + * @return none + */ +void audio_codec_adc_power_down(void) +{ + BM_SET(reg_audio_codec_adc12_ctr,FLD_AUDIO_CODEC_ADC12_SOFT_MUTE); + delay_ms(10); + BM_SET(reg_audio_codec_adc2_ctr,FLD_AUDIO_CODEC_ADC12_SB); + BM_SET(reg_audio_codec_adc12_ctr,FLD_AUDIO_CODEC_ADC1_SB|FLD_AUDIO_CODEC_ADC2_SB); + + BM_SET(reg_audio_codec_vic_ctr,FLD_AUDIO_CODEC_SLEEP_ANALOG); + reg_audio_codec_vic_ctr= MASK_VAL( FLD_AUDIO_CODEC_SB, CODEC_ITF_PD,\ + FLD_AUDIO_CODEC_SB_ANALOG, CODEC_ITF_PD, \ + FLD_AUDIO_CODEC_SLEEP_ANALOG, CODEC_ITF_PD); + audio_rx_dma_dis(); + audio_clk_en(0,0); +} + + +/** + * @brief This function serves to power on codec_adc. + * @return none + */ +void audio_codec_adc_power_on(void) +{ + audio_clk_en(1,1); + BM_SET(reg_audio_codec_vic_ctr,FLD_AUDIO_CODEC_SLEEP_ANALOG); + delay_ms(1); + BM_CLR(reg_audio_codec_adc12_ctr,FLD_AUDIO_CODEC_ADC1_SB|FLD_AUDIO_CODEC_ADC2_SB); + BM_CLR(reg_audio_codec_adc2_ctr,FLD_AUDIO_CODEC_ADC12_SB); + reg_audio_codec_vic_ctr= MASK_VAL( FLD_AUDIO_CODEC_SB, CODEC_ITF_AC,\ + FLD_AUDIO_CODEC_SB_ANALOG, CODEC_ITF_AC, \ + FLD_AUDIO_CODEC_SLEEP_ANALOG, CODEC_ITF_AC); + BM_CLR(reg_audio_codec_adc12_ctr,FLD_AUDIO_CODEC_ADC12_SOFT_MUTE); + + audio_rx_dma_en(); + +} + + + + diff --git a/b91/b91m_ble_sdk/drivers/B91/audio.h b/b91/b91m_ble_sdk/drivers/B91/audio.h new file mode 100755 index 0000000..597c3ac --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/audio.h @@ -0,0 +1,875 @@ +/******************************************************************************************************** + * @file audio.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +/** @page AUDIO + * + * Introduction + * =============== + * audio module consists of 3 parts: audio code, audio in path , and audio out path. + * + * API Reference + * =============== + * Header File: audio.h + */ +#ifndef audio_H +#define audio_H + +#include "reg_include/register_b91.h" +#include "i2c.h" +#include "pwm.h" +#include "compiler.h" + +typedef enum{ + I2S_BCK_PC3 = GPIO_PC3, + I2S_ADC_LR_PC4 = GPIO_PC4, + I2S_ADC_DAT_PC5 = GPIO_PC5, + I2S_DAC_LR_PC6 = GPIO_PC6, + I2S_DAC_DAT_PC7 = GPIO_PC7, +}i2s_pin_e; + + +typedef enum{ + DMIC_B2_DAT_B3_CLK,//mono B3 clk1 + DMIC_C1_DAT_C2_CLK,//mono C2 clk1 + DMIC_D4_DAT_D5_CLK,//mono D5 clk1 + DMIC_GROUPB_B2_DAT_B3_B4_CLK, + DMIC_GROUPC_C1_DAT_C2_C3_CLK, + DMIC_GROUPD_D4_DAT_D5_D6_CLK, +}dmic_pin_group_e; + + +typedef enum{ + MIC_MODE, + SPK_MODE, + LOOP_MODE, +}audio_loop_mode_e; + + +typedef enum{ + CODEC_I2S , + IO_CODEC , + IO_I2S, +}audio_flow_e; + + +typedef enum{ + I2S_RJ_MODE , + I2S_LJ_MODE , + I2S_I2S_MODE, + I2S_DSP_MODE, +}i2s_mode_select_e; + +typedef enum{ + CODEC_PARALLEL_MODE , + CODEC_LJ_MODE , + CODEC_DSP_MODE, + CODEC_I2S_MODE, +}codec_mode_select_e; + + +typedef enum{ + CODEC_ITF_AC, + CODEC_ITF_PD, +}codec_interface_select_e; + +typedef enum{ + BIT_16_MONO, + BIT_20_OR_24_MONO , + BIT_16_STEREO, + BIT_20_OR_24_STEREO , +}audio_in_mode_e; + +typedef enum{ + BIT_16_MONO_FIFO0 , + BIT_20_OR_24_MONO_FIFO0 , + BIT_16_STEREO_FIFO0 , + BIT_20_OR_24_STEREO_FIFO0 , + BIT_16_MONO_FIFO1 , + BIT_20_OR_24_MONO_FIFO1 , + BIT_16_STEREO_FIFO0_AND_FIFO1 , + BIT_20_OR_24STEREO_FIFO0_AND_FIFO1 , + +}audio_out_mode_e; + +typedef enum{ + I2S_BIT_16_DATA, + I2S_BIT_20_DATA , + I2S_BIT_24_DATA, +}i2s_data_select_e; + +typedef enum{ + CODEC_BIT_16_DATA, + CODEC_BIT_20_DATA=2, + CODEC_BIT_24_DATA, +}codec_data_select_e; + + +typedef enum{ + MONO_BIT_16, + MONO_BIT_20, + MONO_BIT_24, + STEREO_BIT_16, + STEREO_BIT_20, + STEREO_BIT_24, +}audio_channel_wl_mode_e; + + +typedef enum{ + AUDIO_BIT_16_DATA, + AUDIO_BIT_20_DATA, + AUDIO_BIT_24_DATA, +}audio_wl_select_e; + +typedef enum{ + AUDIO_MONO, + AUDIO_STEREO, +}audio_channel_select_e; + + +typedef enum{ + I2S_S_CODEC_M, + I2S_M_CODEC_S, +}i2s_codec_m_s_mode_e; + +typedef enum{ + MCU_WREG, + I2C_WREG , +}codec_wreg_mode_e; + +typedef enum{ + I2S_DATA_INVERT_DIS, + I2S_DATA_INVERT_EN , +}audio_data_invert_e; + +typedef struct { + unsigned char audio_in_mode; + unsigned char audio_out_mode; + unsigned char i2s_data_select; + unsigned char codec_data_select; + unsigned char i2s_codec_m_s_mode; + unsigned char i2s_data_invert_select; + unsigned char in_digital_gain; + unsigned char in_analog_gain; + unsigned char out_digital_gain; + unsigned char out_analog_gain; + unsigned char mic_input_mode_select; +}aduio_i2s_codec_config_t; + + +typedef enum{ + I2S_DATA_IN_FIFO , + USB_DATA_IN_FIFO , + SAR_ADC_DATA_IN_FIFO, + IN_NO_USE, +}audio_mux_ain_e; + +typedef enum{ + I2S_OUT , + USB_IOS_OUT , + OUT_NO_USE=3, +}audio_mux_aout_e; + +/** + * define audio rate value. + */ +typedef enum{ + AUDIO_8K, + AUDIO_16K=3, + AUDIO_32K=6, + AUDIO_44EP1K, + AUDIO_48K, + AUDIO_ADC_16K_DAC_48K, +}audio_sample_rate_e; + +typedef enum{ + AMIC_INPUT, + DMIC_INPUT, + LINE_INPUT, +}audio_input_mode_e; + +typedef enum{ + AMIC_IN_TO_BUF, + DMIC_IN_TO_BUF, + LINE_IN_TO_BUF, + AMIC_IN_TO_BUF_TO_LINE_OUT, + DMIC_IN_TO_BUF_TO_LINE_OUT, + LINE_IN_TO_BUF_TO_LINE_OUT, + BUF_TO_LINE_OUT, +}audio_flow_mode_e; + + + +typedef enum{ + AUDIO_RATE_EQUAL, + AUDIO_RATE_GT_L0, + AUDIO_RATE_GT_L1, + AUDIO_RATE_LT_L0, + AUDIO_RATE_LT_L1, +}audio_rate_match_e; + + +/*[0,+43], 1 dB steps*/ +typedef enum{ + CODEC_IN_D_GAIN_0_DB=0, + CODEC_IN_D_GAIN_4_DB=4, + CODEC_IN_D_GAIN_8_DB=8, + CODEC_IN_D_GAIN_12_DB=12, + CODEC_IN_D_GAIN_16_DB=16, + CODEC_IN_D_GAIN_20_DB=20, + CODEC_IN_D_GAIN_43_DB=43, +}codec_in_path_digital_gain_e; + + +typedef enum{ + CODEC_IN_A_GAIN_0_DB, + CODEC_IN_A_GAIN_4_DB, + CODEC_IN_A_GAIN_8_DB, + CODEC_IN_A_GAIN_12_DB, + CODEC_IN_A_GAIN_16_DB, + CODEC_IN_A_GAIN_20_DB, +}codec_in_path_analog_gain_e; + + + +typedef enum{ + CODEC_OUT_D_GAIN_0_DB=0, + CODEC_OUT_D_GAIN_m1_DB, + CODEC_OUT_D_GAIN_m2_DB, + CODEC_OUT_D_GAIN_m3_DB, + CODEC_OUT_D_GAIN_m4_DB, + CODEC_OUT_D_GAIN_m5_DB, + CODEC_OUT_D_GAIN_m6_DB, + CODEC_OUT_D_GAIN_m7_DB, + CODEC_OUT_D_GAIN_m8_DB, + CODEC_OUT_D_GAIN_m9_DB, + CODEC_OUT_D_GAIN_m10_DB, + CODEC_OUT_D_GAIN_m11_DB, + CODEC_OUT_D_GAIN_m12_DB, + CODEC_OUT_D_GAIN_m13_DB, + CODEC_OUT_D_GAIN_m14_DB, + CODEC_OUT_D_GAIN_m15_DB, + CODEC_OUT_D_GAIN_m16_DB, + CODEC_OUT_D_GAIN_m17_DB, + CODEC_OUT_D_GAIN_m18_DB, + CODEC_OUT_D_GAIN_m19_DB, + CODEC_OUT_D_GAIN_m20_DB, + CODEC_OUT_D_GAIN_m21_DB, + CODEC_OUT_D_GAIN_m22_DB, + CODEC_OUT_D_GAIN_m23_DB, + CODEC_OUT_D_GAIN_m24_DB, + CODEC_OUT_D_GAIN_m25_DB, + CODEC_OUT_D_GAIN_m26_DB, + CODEC_OUT_D_GAIN_m27_DB, + CODEC_OUT_D_GAIN_m28_DB, + CODEC_OUT_D_GAIN_m29_DB, + CODEC_OUT_D_GAIN_m30_DB, + CODEC_OUT_D_GAIN_m31_DB=31, + + CODEC_OUT_D_GAIN_32_DB, + CODEC_OUT_D_GAIN_31_DB, + CODEC_OUT_D_GAIN_30_DB, + CODEC_OUT_D_GAIN_29_DB, + CODEC_OUT_D_GAIN_28_DB, + CODEC_OUT_D_GAIN_27_DB, + CODEC_OUT_D_GAIN_26_DB, + CODEC_OUT_D_GAIN_25_DB, + CODEC_OUT_D_GAIN_24_DB, + CODEC_OUT_D_GAIN_23_DB, + CODEC_OUT_D_GAIN_22_DB, + CODEC_OUT_D_GAIN_21_DB, + CODEC_OUT_D_GAIN_20_DB, + CODEC_OUT_D_GAIN_19_DB, + CODEC_OUT_D_GAIN_18_DB, + CODEC_OUT_D_GAIN_17_DB, + CODEC_OUT_D_GAIN_16_DB, + CODEC_OUT_D_GAIN_15_DB, + CODEC_OUT_D_GAIN_14_DB, + CODEC_OUT_D_GAIN_13_DB, + CODEC_OUT_D_GAIN_12_DB, + CODEC_OUT_D_GAIN_11_DB, + CODEC_OUT_D_GAIN_10_DB, + CODEC_OUT_D_GAIN_9_DB, + CODEC_OUT_D_GAIN_8_DB, + CODEC_OUT_D_GAIN_7_DB, + CODEC_OUT_D_GAIN_6_DB, + CODEC_OUT_D_GAIN_5_DB, + CODEC_OUT_D_GAIN_4_DB, + CODEC_OUT_D_GAIN_3_DB, + CODEC_OUT_D_GAIN_2_DB, + CODEC_OUT_D_GAIN_1_DB, +}codec_out_path_digital_gain_e; + + + +typedef enum{ + + CODEC_OUT_A_GAIN_12_DB, + CODEC_OUT_A_GAIN_11_DB, + CODEC_OUT_A_GAIN_10_DB, + CODEC_OUT_A_GAIN_9_DB, + CODEC_OUT_A_GAIN_8_DB, + CODEC_OUT_A_GAIN_7_DB, + CODEC_OUT_A_GAIN_6_DB, + CODEC_OUT_A_GAIN_5_DB, + CODEC_OUT_A_GAIN_4_DB, + CODEC_OUT_A_GAIN_3_DB, + CODEC_OUT_A_GAIN_2_DB, + CODEC_OUT_A_GAIN_1_DB, + CODEC_OUT_A_GAIN_0_DB, + CODEC_OUT_A_GAIN_m1_DB, + CODEC_OUT_A_GAIN_m2_DB, + CODEC_OUT_A_GAIN_m3_DB, + CODEC_OUT_A_GAIN_m4_DB, + CODEC_OUT_A_GAIN_m5_DB, + CODEC_OUT_A_GAIN_m6_DB, + CODEC_OUT_A_GAIN_m7_DB, + CODEC_OUT_A_GAIN_m8_DB, + CODEC_OUT_A_GAIN_m9_DB, + CODEC_OUT_A_GAIN_m10_DB, + CODEC_OUT_A_GAIN_m11_DB, + CODEC_OUT_A_GAIN_m12_DB, + CODEC_OUT_A_GAIN_m13_DB, + CODEC_OUT_A_GAIN_m14_DB, + CODEC_OUT_A_GAIN_m15_DB, + CODEC_OUT_A_GAIN_m16_DB, + CODEC_OUT_A_GAIN_m17_DB, + CODEC_OUT_A_GAIN_m18_DB, + CODEC_OUT_A_GAIN_m19_DB, +}codec_out_path_analog_gain_e; + + +/*The Wind Noise filter (WNF) is a programmable high pass filter feature enabling to reduce wind noise . +The wind noise filter is a 1st order filter. + Mode1 -3dB 59Hz +corner frequency Mode2 -3dB 117Hz + Mode3 -3dB 235Hz +*/ +typedef enum{ +CODEC_ADC_WNF_INACTIVE, +CODEC_ADC_WNF_MODE1, +CODEC_ADC_WNF_MODE2, +CODEC_ADC_WNF_MODE3, +}adc_wnf_mode_sel_e; + + + +typedef enum +{ + INNER_CODEC, + EXT_CODEC,//wm8731 +}codec_type_e; + + + + +typedef enum +{ + CODEC_1P8V, + CODEC_2P8V, +}codec_volt_supply_e; + + +/** + * @brief This function serves to set the clock of i2s + * @param[in] step - the dividing factor of step. + * @param[in] mod - the dividing factor of mod. + * @return none + */ +static inline void audio_set_i2s_clk(unsigned char step,unsigned char mod) +{ + reg_i2s_step = (step&FLD_I2S_STEP)|FLD_I2S_CLK_EN; + reg_i2s_mod = mod; +} + +/** + * @brief This function serves to set the clock of codec + * @param[in] step - the dividing factor of step. + * @param[in] mod - the dividing factor of mod. + * @return none + * @attention codec clock divider from pll,so pll must be 192M + */ +static inline void audio_set_codec_clk(unsigned char step,unsigned char mod) +{ + BM_CLR(reg_dmic_clk_set,BIT(0));//set dmic_div + reg_dmic_step = (step&FLD_DMIC_STEP)|FLD_DMIC_SEL; + reg_dmic_mod = mod; +} + + +/** + * @brief This function serves to set enable i2s clk + * @return none + */ +static inline void audio_i2s_clk_en(void) +{ + BM_SET(reg_i2s_step,FLD_I2S_CLK_EN); +} + +/** + * @brief This function serves to set disable i2s clk. + * @return none + */ +static inline void audio_i2s_clk_dis(void) +{ + BM_CLR(reg_i2s_step,FLD_I2S_CLK_EN); +} + + +/** + * @brief This function serves to set disable codec clk + * @return none + */ +static inline void audio_codec_clk_en(void) +{ + BM_SET(reg_dmic_step,FLD_DMIC_SEL); +} + + +/** + * @brief This function serves to set disable codec clk + * @return none + */ +static inline void audio_codec_clk_dis(void) +{ + BM_CLR(reg_dmic_step,FLD_DMIC_SEL); +} + + +/** + * @brief This function serves to set the bclk + * @param[in] div - bclk=i2s_clk/(div*2),if div=0,i2s_clk=bclk. + * @return none + */ +static inline void audio_set_i2s_bclk(unsigned char div) +{ + reg_pcm_clk_num=div&0x0f; +} + +/** + * @brief This function serves to set the lrclk divider. + * @param[in] adc_div - adc_lrclk=bclk/(adc_div) + * @param[in] dac_div - dac_lrclk=bclk/(dac_div) + * @return none + */ +static inline void audio_set_lrclk(unsigned short adc_div,unsigned short dac_div) +{ + reg_int_pcm_num=(adc_div-1); + reg_dec_pcm_num=(dac_div-1); +} + + + +/** + * @brief This function serves to set tx buff length, + * @param[in] len - the length of tx buff + * @return none + */ +static inline void audio_set_tx_buff_len(unsigned short len) +{ + reg_tx_max=((len)>>2)-1; +} + +/** + * @brief This function serves to set rx buff length, + * @param[in] len - the length of rx buff + * @return none + */ +static inline void audio_set_rx_buff_len(unsigned short len) +{ + reg_rx_max=((len)>>2)-1; +} + + +/** + * @brief This function serves to write codec register by mc. + * @param[in] addr - the address of codec register + * @param[in] data - Data to be written + * @return none + */ +static inline void audio_write_codec_reg(unsigned char addr,unsigned char data) +{ + write_reg8(REG_AUDIO_AHB_BASE+((0x80+addr)<<2), data); + +} + +/** + * @brief This function serves to read codec register by mc. + * @param[in] addr - the address of codec register + * @return data + */ +static inline unsigned char audio_read_codec_reg(unsigned char addr) +{ + return read_reg8(REG_AUDIO_AHB_BASE+((0x80+addr)<<2)); + +} + +/** + * @brief This function serves to tx fifo trigger number. + * @param[in] number - the number of dma trigger + * @return none + */ +static inline void audio_set_fifo_tx_trig_num(unsigned char number) +{ + reg_fifo_trig0 &=~FLD_AUDIO_FIFO_AOUT0_TRIG_NUM; + reg_fifo_trig0 |=(number&FLD_AUDIO_FIFO_AOUT0_TRIG_NUM); +} + +/** + * @brief This function serves to rx fifo trigger number. + * @param[in] number - the number of dma trigger + * @return none + */ +static inline void audio_set_fifo_rx_trig_num(unsigned char number) +{ + reg_fifo_trig0 &= ~FLD_AUDIO_FIFO_AIN0_TRIG_NUM; + reg_fifo_trig0 |=((number&0x0f)<<4); +} + +/** + * @brief This function serves to enable or disable i2s clk and codec mc clk . + * @param[in] i2s_clk_en - 1 enable : 0 disable + * @param[in] mc_clk_en - 1 enable : 0 disable + * @return none + */ +static inline void audio_clk_en(unsigned char i2s_clk_en,unsigned char mc_clk_en) +{ + reg_audio_en=MASK_VAL( FLD_AUDIO_I2S_CLK_EN, i2s_clk_en,\ + FLD_AUDIO_MC_CLK_EN, mc_clk_en); +} + + +/** + * @brief This function serves to get dma rx buff pointer. + * @param[in] chn - dma channel + * @return none + */ +static inline unsigned int audio_get_rx_dma_wptr (dma_chn_e chn) +{ + return convert_ram_addr_bus2cpu(reg_dma_dst_addr(chn)); +} + +/** + * @brief This function serves to get dma tx buff pointer. + * @param[in] chn - dma channel + * @return none + */ +static inline unsigned int audio_get_tx_dma_rptr (dma_chn_e chn) +{ + return convert_ram_addr_bus2cpu(reg_dma_src_addr(chn)); +} + + +/** + * @brief This function serves to invert data between R channel and L channel. + * @return none + */ +static inline void audio_invert_data_en(void) +{ + BM_SET(reg_i2s_cfg,FLD_AUDIO_I2S_LRSWAP); +} + +/** + * @brief This function serves to set fifo0 data path . + * @param[in] ain0_sel :fifo0 input source select + * @param[in] aout0_sel:fifo0 output source select + * @return none + */ +static inline void audio_data_fifo0_path_sel (audio_mux_ain_e ain0_sel, audio_mux_aout_e aout0_sel) +{ + reg_audio_sel = MASK_VAL( FLD_AUDIO_AIN0_SEL, ain0_sel,FLD_AUDIO_AOUT0_SEL, aout0_sel); +} + + +/** + * @brief This function serves to set fifo1 data path . + * @param[in] ain1_sel :fifo1 input source select + * @param[in] aout1_sel:fifo1 output source select + * @return none + */ +static inline void audio_data_fifo1_path_sel ( audio_mux_ain_e ain1_sel, audio_mux_aout_e aout1_sel) +{ + reg_audio_sel = MASK_VAL( FLD_AUDIO_AIN1_SEL, ain1_sel, FLD_AUDIO_AOUT1_SEL, aout1_sel); +} + + + +/** + * @brief This function serves to invert data between R channel and L channel. + * @return none + */ +static inline void audio_invert_data_dis(void) +{ + BM_CLR(reg_i2s_cfg,FLD_AUDIO_I2S_LRSWAP); +} + +/** + * @brief This function serves to set codec supply voltage + * @param[in] volt - the voltage of codec supply.A1 2.8V default,A0 1.8V default. + * @return none + * + */ +void audio_set_codec_supply (codec_volt_supply_e volt); + +/** + * @brief This function configures dmic pin. + * @param[in] pin_gp - the group of dmic pin + * @return none + */ +void audio_set_dmic_pin(dmic_pin_group_e pin_gp); + +/** + * @brief This function serves to set data path. + * @param[in] audio_flow - audio flow select + * @param[in] ain0_mode - fifo0 input mode select + * @param[in] ain1_mode - fifo1 input mode select + * @param[in] i2s_aout_mode - fifo output source select + * @return none + */ +void audio_mux_config(audio_flow_e audio_flow, audio_in_mode_e ain0_mode , audio_in_mode_e ain1_mode,audio_out_mode_e i2s_aout_mode); + + +/** + * @brief This function serves to config codec for dac. + * @param[in] mode - select i2s as master or slave + * @param[in] rate - audio sampling rate + * @param[in] data_select - codec dac word length + * @param[in] wreg_mode - mcu or i2c config codec + * @return none + */ +void audio_codec_dac_config(i2s_codec_m_s_mode_e mode,audio_sample_rate_e rate,codec_data_select_e data_select,codec_wreg_mode_e wreg_mode); + +/** + * @brief This function serves to config codec for adc. + * @param[in] mode - select i2s as master or slave + * @param[in] in_mode - line_in/amic/dmic input mode select + * @param[in] rate - audio sampling rate + * @param[in] data_select - codec adc word length + * @param[in] wreg_mode - mcu or i2c config codec + * @return none + */ +void audio_codec_adc_config(i2s_codec_m_s_mode_e mode,audio_input_mode_e in_mode,audio_sample_rate_e rate,codec_data_select_e data_select,codec_wreg_mode_e wreg_mode); + + + +/** + * @brief This function serves to config interface, word length, and m/s . + * @param[in] i2s_format - interface protocol + * @param[in] wl - audio data word length + * @param[in] m_s - select i2s as master or slave + * @param[in] en - 1 enable audio data invert , 0 disable audio data invert .for example in mono mode switch R and L channel data to fifo0 + * @return none + */ +void audio_i2s_config(i2s_mode_select_e i2s_format,i2s_data_select_e wl, i2s_codec_m_s_mode_e m_s , audio_data_invert_e en ); + +/** + * @brief This function serves to set i2s clock and audio sampling rate when i2s as master. + * @param[in] audio_rate - audio sampling rate + * @param[in] match - the match of audio rate. + * @param[in] match_en - initial must 0, then change rate must 1 + * @return none + * @attention i2s clock divider from pll,sampling rate calculation is based on pll=192M,so pll must be 192M + */ +_attribute_ram_code_sec_noinline_ void audio_set_i2s_clock (audio_sample_rate_e audio_rate,audio_rate_match_e match, unsigned char match_en); + +/** + * @brief This function serves to config rx_dma channel. + * @param[in] chn - dma channel + * @param[in] dst_addr - the dma address of destination + * @param[in] data_len - the length of dma rx size by byte + * @param[in] head_of_list - the head address of dma llp. + * @return none + */ +void audio_rx_dma_config(dma_chn_e chn,unsigned short * dst_addr,unsigned int data_len,dma_chain_config_t *head_of_list); + +/** + * @brief This function serves to set rx dma chain transfer + * @param[in] rx_config - the head of list of llp_pointer. + * @param[in] llpointer - the next element of llp_pointer. + * @param[in] dst_addr -the dma address of destination. + * @param[in] data_len -the length of dma size by byte. + * @return none + */ +void audio_rx_dma_add_list_element(dma_chain_config_t * rx_config,dma_chain_config_t *llpointer ,unsigned short * dst_addr,unsigned int data_len); + +/** + * @brief This function serves to config tx_dma channel. + * @param[in] chn - dma channel + * @param[in] src_addr - the address of source + * @param[in] data_len - the length of dma rx size by byte + * @param[in] head_of_list - the head address of dma llp. + * @return none + */ +void audio_tx_dma_config(dma_chn_e chn,unsigned short * src_addr, unsigned int data_len,dma_chain_config_t * head_of_list); + +/** + * @brief This function serves to set tx dma chain transfer + * @param[in] config_addr - the head of list of llp_pointer. + * @param[in] llpointer - the next element of llp_pointer. + * @param[in] src_addr - the address of source + * @param[in] data_len - the length of dma size by byte. + * @return none + */ +void audio_tx_dma_add_list_element(dma_chain_config_t *config_addr,dma_chain_config_t *llpointer ,unsigned short * src_addr,unsigned int data_len); + +/** + * @brief This function serves to enable rx_dma channel. + * @return none + */ +void audio_rx_dma_en(void); + +/** + * @brief This function serves to disable rx_dma channel. + * @return none + */ + void audio_rx_dma_dis(void); + +/** + * @brief This function serves to enable tx_dma channel. + * @return none + */ +void audio_tx_dma_en(void); + + +/** + * @brief This function serves to disable tx_dma channel. + * @return none + */ +void audio_tx_dma_dis(void); + + +/** + * @brief This function serves to initialize audio by mc + * @param[in] flow_mode - select input out flow mode + * @param[in] rate - audio sampling rate. + * @param[in] channel_wl - word length and channel number. + * @return none + */ +void audio_init(audio_flow_mode_e flow_mode,audio_sample_rate_e rate,audio_channel_wl_mode_e channel_wl); + + +/** + * @brief This function serves to initialize audio by i2c + * @param[in] flow_mode - select input out flow mode + * @param[in] rate - audio sampling rate. + * @param[in] channel_wl - word length and channel number. + * @return none + */ +void audio_init_i2c(audio_flow_mode_e flow_mode,audio_sample_rate_e rate,audio_channel_wl_mode_e channel_wl); + + +/** + * @brief This function serves to initialize audio(external codec WM8731) by i2c. + * @param[in] pwm0_pin - the pin of pwm0 + * @param[in] sda_pin - the pin port selected as I2C sda pin port. + * @param[in] scl_pin - the pin port selected as I2C scl pin port. + * @return none + */ +void audio_i2s_init(pwm_pin_e pwm0_pin, i2c_sda_pin_e sda_pin,i2c_scl_pin_e scl_pin); + +/** + * @brief This function serves to set audio rx dma chain transfer. + * @param[in] chn - dma channel + * @param[in] in_buff - the pointer of rx_buff. + * @param[in] buff_size - the size of rx_buff. + * @return none + */ +void audio_rx_dma_chain_init (dma_chn_e chn,unsigned short * in_buff,unsigned int buff_size ); + +/** + * @brief This function serves to initialize audio tx dma chain transfer. + * @param[in] chn - dma channel + * @param[in] out_buff - the pointer of tx_buff. + * @param[in] buff_size - the size of tx_buff. + * @return none + */ +void audio_tx_dma_chain_init (dma_chn_e chn,unsigned short * out_buff,unsigned int buff_size); + + +/** + * @brief This function serves to set in path digital and analog gain . + * @param[in] d_gain - digital gain value + * @param[in] a_gain - analog gain value + * @return none + */ +void audio_set_codec_in_path_a_d_gain (codec_in_path_digital_gain_e d_gain,codec_in_path_analog_gain_e a_gain ); + +/** + * @brief This function serves to set out path digital and analog gain . + * @param[in] d_gain - digital gain value + * @param[in] a_gain - analog gain value + * @return none + */ + void audio_set_codec_out_path_a_d_gain (codec_out_path_digital_gain_e d_gain,codec_out_path_analog_gain_e a_gain); + + /** + * @brief This function serves to choose which is master to provide clock. + * @param[in] m_s - I2S_S_CODEC_M: i2s as slave ,codec as master; I2S_M_CODEC_S: i2s as master, codec as slave. + * @return none + */ + void audio_set_i2s_codec_m_s (i2s_codec_m_s_mode_e m_s); + + + /** + * @brief This function serves to active soft mute dac and disable dma. + * @return none + */ + void audio_pause_out_path(void); + + + /** + * @brief This function serves to inactive soft mute dac and enable dma . + * @return none + */ + void audio_resume_out_path(void); + + /** + * @brief This function serves to change sample rate for dac. + * @param[in] rate - the sample rate of dac + * @return none + */ + _attribute_ram_code_sec_noinline_ void audio_change_sample_rate (audio_sample_rate_e rate); + + + /** + * @brief This function serves to power down codec_dac. + * @return none + */ +void audio_codec_dac_power_down(void); + + /** + * @brief This function serves to power on codec_dac. + * @return none + */ +void audio_codec_dac_power_on(void); + +/** + * @brief This function serves to power down codec_adc. + * @return none + */ +void audio_codec_adc_power_down(void); + +/** + * @brief This function serves to power on codec_adc. + * @return none + */ +void audio_codec_adc_power_on(void); +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/clock.c b/b91/b91m_ble_sdk/drivers/B91/clock.c new file mode 100755 index 0000000..f1e36c4 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/clock.c @@ -0,0 +1,319 @@ +/******************************************************************************************************** + * @file clock.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "clock.h" +#include "mspi.h" +#include "sys.h" +#include "stimer.h" +/********************************************************************************************************************** + * local constants * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * local macro * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * local data type * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * global variable * + *********************************************************************************************************************/ +sys_clk_t sys_clk = { + .pll_clk = 192, + .cclk = 24, + .hclk = 24, + .pclk = 24, + .mspi_clk = 24, +}; +_attribute_data_retention_sec_ unsigned char tl_24mrc_cal; +clk_32k_type_e g_clk_32k_src; +/********************************************************************************************************************** + * local variable * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * local function prototype * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * global function implementation * + *********************************************************************************************************************/ + + +/** + * @brief This function serves to set 32k clock source. + * @param[in] src - variable of 32k type. + * @return none. + */ +void clock_32k_init(clk_32k_type_e src) +{ + unsigned char sel_32k = analog_read_reg8(0x4e)&0x7f; + unsigned char power_32k = analog_read_reg8(0x05)&0xfc; + analog_write_reg8(0x4e, sel_32k|(src<<7)); + if(src) + { + analog_write_reg8(0x05, power_32k|0x1);//32k xtal + } + else + { + analog_write_reg8(0x05, power_32k|0x2);//32k rc + } + g_clk_32k_src = src; +} + +/** + * @brief This function serves to kick 32k xtal. + * @param[in] xtal_times - kick times. + * @return 1 success, 0 error. + */ +unsigned char clock_kick_32k_xtal(unsigned char xtal_times) +{ + int last_32k_tick; + int curr_32k_tick; + for(unsigned char i = 0; i< xtal_times; i++) + { + if(0xff == g_chip_version) + { + delay_ms(1000); + } + else //**Note that the clock is 24M crystal oscillator. PCLK is 24MHZ + { + //2.set PD0 as pwm output + unsigned char pwm_clk = read_reg8(0x1401d8);//**condition: PCLK is 24MHZ,PCLK = HCLK + write_reg8(0x1401d8,((pwm_clk & 0xfc) | 0x01));//PCLK = 12M + unsigned char reg_31e = read_reg8(0x14031e); //PD0 + write_reg8(0x14031e,reg_31e & 0xfe); + unsigned short reg_418 = read_reg16(0x140418); //pwm1 cmp + write_reg16(0x140418,0x01); + unsigned short reg_41a = read_reg16(0x14041a); //pwm1 max + write_reg16(0x14041a,0x02); + unsigned char reg_400 = read_reg8(0x140400); //pwm en + write_reg8(0x140400,0x02); + write_reg8(0x140402,0xb6); //12M/(0xb6 + 1)/2 = 32k + + //3.wait for PWM wake up Xtal + delay_ms(100); + + //4.Xtal 32k output + analog_write_reg8(0x03,0x4f); //<7:6>current select + + //5.Recover PD0 as Xtal pin + write_reg8(0x1401d8,pwm_clk); + write_reg8(0x14031e,reg_31e); + write_reg16(0x140418,reg_418); + write_reg16(0x14041a,reg_41a); + write_reg8(0x140400,reg_400); + } + + last_32k_tick = clock_get_32k_tick(); //clock_get_32k_tick() + delay_us(305); //for 32k tick accumulator, tick period: 30.5us, dly 10 ticks + curr_32k_tick = clock_get_32k_tick(); + if(last_32k_tick != curr_32k_tick) //clock_get_32k_tick() + { + return 1; //pwm kick 32k pad success + } + } + return 0; +} + +/** + * @brief This function performs to select 24M as the system clock source. + * 24M RC is inaccurate, and it is greatly affected by temperature, if need use it so real-time calibration is required + * The 24M RC needs to be calibrated before the pm_sleep_wakeup function, + * because this clock will be used to kick 24m xtal start after wake up, + * The more accurate this time, the faster the crystal will start.Calibration cycle depends on usage + * @return none. + */ +void clock_cal_24m_rc(void) +{ + analog_write_reg8(0xc8, 0x80); + + + analog_write_reg8(0x4f, analog_read_reg8(0x4f) | BIT(7) ); + + analog_write_reg8(0xc7, 0x0e); + analog_write_reg8(0xc7, 0x0f); + while((analog_read_reg8(0xcf) & 0x80) == 0); + unsigned char cap = analog_read_reg8(0xcb); + analog_write_reg8(0x52, cap); //write 24m cap into manual register + + analog_write_reg8(0x4f, analog_read_reg8(0x4f) & (~BIT(7)) ); + + analog_write_reg8(0xc7, 0x0e); + tl_24mrc_cal = analog_read_reg8(0x52); +} + +/** + * @brief This function performs to select 32K as the system clock source. + * @return none. + */ +void clock_cal_32k_rc(void) +{ + analog_write_reg8(0x4f, ((analog_read_reg8(0x4f) & 0x3f) | 0x40)); + analog_write_reg8(0xc6, 0xf6); + analog_write_reg8(0xc6, 0xf7); + while(0 == (analog_read_reg8(0xcf) & BIT(6))){}; + unsigned char res1 = analog_read_reg8(0xc9); //read 32k res[13:6] + analog_write_reg8(0x51, res1); //write 32k res[13:6] into manual register + unsigned char res2 = analog_read_reg8(0xca); //read 32k res[5:0] + analog_write_reg8(0x4f, (res2 | (analog_read_reg8(0x4f) & 0xc0))); //write 32k res[5:0] into manual register + analog_write_reg8(0xc6, 0xf6); + analog_write_reg8(0x4f, ((analog_read_reg8(0x4f) & 0x3f) | 0x00));//manual on +} + +/** + * @brief This function serves to set the 32k tick. + * @param tick - the value of to be set to 32k. + * @return none. + */ +void clock_set_32k_tick(unsigned int tick) +{ + reg_system_ctrl |= FLD_SYSTEM_32K_WR_EN;//r_32k_wr = 1; + while(reg_system_st & FLD_SYSTEM_RD_BUSY); + reg_system_timer_set_32k = tick; + + reg_system_st = FLD_SYSTEM_CMD_SYNC;//cmd_sync = 1,trig write + //delay 10us + __asm__("nop");__asm__("nop");__asm__("nop");__asm__("nop"); + __asm__("nop");__asm__("nop");__asm__("nop");__asm__("nop"); + __asm__("nop");__asm__("nop");__asm__("nop");__asm__("nop"); + __asm__("nop");__asm__("nop");__asm__("nop");__asm__("nop"); + while(reg_system_st & FLD_SYSTEM_CMD_SYNC);//wait wr_busy = 0 + +} + +/** + * @brief This function serves to get the 32k tick. + * @return none. + */ +unsigned int clock_get_32k_tick(void) +{ + unsigned int timer_32k_tick; + reg_system_st = FLD_SYSTEM_CLR_RD_DONE;//clr rd_done + while((reg_system_st & FLD_SYSTEM_CLR_RD_DONE) != 0);//wait rd_done = 0; + reg_system_ctrl &= ~FLD_SYSTEM_32K_WR_EN; //1:32k write mode; 0:32k read mode + while((reg_system_st & FLD_SYSTEM_CLR_RD_DONE) == 0);//wait rd_done = 1; + timer_32k_tick = reg_system_timer_read_32k; + reg_system_ctrl |= FLD_SYSTEM_32K_WR_EN; //1:32k write mode; 0:32k read mode + return timer_32k_tick; +} + +/** + * @brief This function use to select the system clock source. + * @param[in] pll - pll clock. + * @param[in] src - cclk source. + * @param[in] cclk_div - the cclk divide from pll.it is useless if src is not PAD_PLL_DIV. cclk max is 96M + * @param[in] hclk_div - the hclk divide from cclk.hclk max is 48M. + * @param[in] pclk_div - the pclk divide from hclk.pclk max is 24M.if hclk = 1/2 * cclk, the pclk can not be 1/4 of hclk. + * @param[in] mspi_clk_div - mspi_clk has two source. pll div and hclk.mspi max is 64M. + * @return none + */ +void clock_init(sys_pll_clk_e pll, + sys_clock_src_e src, + sys_pll_div_to_cclk_e cclk_div, + sys_cclk_div_to_hclk_e hclk_div, + sys_hclk_div_to_pclk_e pclk_div, + sys_pll_div_to_mspi_clk_e mspi_clk_div) +{ + + //pll clk + analog_write_reg8(0x80, (analog_read_reg8(0x80) & 0xe0) | ((pll >> 2) & 0x1f)); + analog_write_reg8(0x09, (analog_read_reg8(0x09) & 0xf3) | ((pll&0x03) << 2)); + sys_clk.pll_clk = (pll >> 8); + + //usb clock (192M/4 =48M) pll clock should be the multiple of 48, because USB clock is 48M. + write_reg8(0x1401fb, sys_clk.pll_clk/48); + + //wait for PLL stable + analog_write_reg8(0x81, (analog_read_reg8(0x81) | BIT(6))); + while(BIT(5) != (analog_read_reg8(0x88) & BIT(5))); + analog_write_reg8(0x81, (analog_read_reg8(0x81) & ~BIT(6))); + + //ensure mspi is not in busy status before change mspi clock + mspi_stop_xip(); + + //change mspi clock should be ram code. + if(CCLK_TO_MSPI_CLK == mspi_clk_div) + { + write_reg8(0x1401e8, read_reg8(0x1401e8) & 0x7f); //bit7 0 + } + else + { + write_reg8(0x1401e9, (read_reg8(0x1401e9) & 0x0f) | (mspi_clk_div<<4) ); + write_reg8(0x1401e8, read_reg8(0x1401e8) | BIT(7)); //if the div is odd, should set two times to ensure the correct sequence. + write_reg8(0x1401e8, read_reg8(0x1401e8) | BIT(7)); + sys_clk.mspi_clk = sys_clk.pll_clk / mspi_clk_div; + } + + //hclk and pclk should be set ahead of cclk, ensure the hclk and pclk not exceed the max clk(cclk max 96M, hclk max 48M, pclk max 24M) + if(CCLK_DIV1_TO_HCLK == hclk_div) + { + write_reg8(0x1401d8, read_reg8(0x1401d8) & ~BIT(2)); + } + else + { + write_reg8(0x1401d8, read_reg8(0x1401d8) | BIT(2)); + } + + //pclk can div1/div2/div4 from hclk. + if(HCLK_DIV1_TO_PCLK == pclk_div) + { + write_reg8(0x1401d8, read_reg8(0x1401d8) & 0xfc); + } + else + { + write_reg8(0x1401d8, (read_reg8(0x1401d8) & 0xfc) | (pclk_div/2)); + } + + //select cclk source(RC24M/PAD24M/PAD_PLL_DIV/PAD_PLL) + if(PAD_PLL_DIV == src) + { + write_reg8(0x1401e8, (read_reg8(0x1401e8) & 0xf0) | cclk_div); + sys_clk.cclk = sys_clk.pll_clk / cclk_div; + } + else if(PAD_PLL == src) + { + sys_clk.cclk = sys_clk.pll_clk; + } + else + { + sys_clk.cclk = 24; + } + write_reg8(0x1401e8, (read_reg8(0x1401e8) & 0x8f) | (src << 4)); + + //clk record. + sys_clk.hclk = sys_clk.cclk/hclk_div; + sys_clk.pclk = sys_clk.hclk / pclk_div; + if(CCLK_TO_MSPI_CLK == mspi_clk_div){ + sys_clk.mspi_clk = sys_clk.cclk; + } +} + + +/********************************************************************************************************************** + * local function implementation * + *********************************************************************************************************************/ diff --git a/b91/b91m_ble_sdk/drivers/B91/clock.h b/b91/b91m_ble_sdk/drivers/B91/clock.h new file mode 100755 index 0000000..795f227 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/clock.h @@ -0,0 +1,242 @@ +/******************************************************************************************************** + * @file clock.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +/** @page CLOCK + * + * Introduction + * =============== + * TLSRB91 clock setting. + * + * API Reference + * =============== + * Header File: clock.h + */ + +#ifndef CLOCK_H_ +#define CLOCK_H_ + +#include "reg_include/register_b91.h" +#include "compiler.h" + +/********************************************************************************************************************** + * global constants * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * global macro * + *********************************************************************************************************************/ +#define CCLK_16M_HCLK_16M_PCLK_16M clock_init(PLL_CLK_192M, PAD_PLL_DIV, PLL_DIV12_TO_CCLK, CCLK_DIV1_TO_HCLK, HCLK_DIV1_TO_PCLK, PLL_DIV4_TO_MSPI_CLK) +#define CCLK_24M_HCLK_24M_PCLK_24M clock_init(PLL_CLK_192M, PAD_PLL_DIV, PLL_DIV8_TO_CCLK, CCLK_DIV1_TO_HCLK, HCLK_DIV1_TO_PCLK, PLL_DIV4_TO_MSPI_CLK) +#define CCLK_32M_HCLK_32M_PCLK_16M clock_init(PLL_CLK_192M, PAD_PLL_DIV, PLL_DIV6_TO_CCLK, CCLK_DIV1_TO_HCLK, HCLK_DIV2_TO_PCLK, PLL_DIV4_TO_MSPI_CLK) +#define CCLK_48M_HCLK_48M_PCLK_24M clock_init(PLL_CLK_192M, PAD_PLL_DIV, PLL_DIV4_TO_CCLK, CCLK_DIV1_TO_HCLK, HCLK_DIV2_TO_PCLK, PLL_DIV4_TO_MSPI_CLK) + +/********************************************************************************************************************** + * global data type * + *********************************************************************************************************************/ + +/** + * @brief Define sys_clk struct. + */ +typedef struct { + unsigned short pll_clk; /**< pll clk */ + unsigned char cclk; /**< cpu clk */ + unsigned char hclk; /**< hclk */ + unsigned char pclk; /**< pclk */ + unsigned char mspi_clk; /**< mspi_clk */ +}sys_clk_t; + + +/** + * @brief system clock type + * | | | | + * | :-------- | :----------- | :------------ | + * | <1:0> | <6:2> | <15:8> | + * |ana_09<3:2>|analog_80<4:0>| clk | + */ +typedef enum{ + PLL_CLK_48M = (0 | (16 << 2) | (48 << 8)), + PLL_CLK_54M = (0 | (17 << 2) | (54 << 8)), + PLL_CLK_60M = (0 | (18 << 2) | (60 << 8)), + PLL_CLK_66M = (0 | (19 << 2) | (66 << 8)), + PLL_CLK_96M = (1 | (16 << 2) | (96 << 8)), + PLL_CLK_108M = (1 | (17 << 2) | (108 << 8)), + PLL_CLK_120M = (1 | (18 << 2) | (120 << 8)), + PLL_CLK_132M = (1 | (19 << 2) | (132 << 8)), + PLL_CLK_192M = (2 | (16 << 2) | (192 << 8)), + PLL_CLK_216M = (2 | (17 << 2) | (216 << 8)), + PLL_CLK_240M = (2 | (18 << 2) | (240 << 8)), + PLL_CLK_264M = (2 | (19 << 2) | (264 << 8)), +}sys_pll_clk_e; + +/** + * @brief system clock type. + */ +typedef enum{ + RC24M, + PAD24M, + PAD_PLL_DIV, + PAD_PLL, +}sys_clock_src_e; + +/** + * @brief 32K clock type. + */ +typedef enum{ + CLK_32K_RC =0, + CLK_32K_XTAL =1, +}clk_32k_type_e; + +/** + * @brief pll div to cclk. + */ +typedef enum{ + PLL_DIV2_TO_CCLK = 2, + PLL_DIV3_TO_CCLK = 3, + PLL_DIV4_TO_CCLK = 4, + PLL_DIV5_TO_CCLK = 5, + PLL_DIV6_TO_CCLK = 6, + PLL_DIV7_TO_CCLK = 7, + PLL_DIV8_TO_CCLK = 8, + PLL_DIV9_TO_CCLK = 9, + PLL_DIV10_TO_CCLK = 10, + PLL_DIV11_TO_CCLK = 11, + PLL_DIV12_TO_CCLK = 12, + PLL_DIV13_TO_CCLK = 13, + PLL_DIV14_TO_CCLK = 14, + PLL_DIV15_TO_CCLK = 15, +}sys_pll_div_to_cclk_e; + +/** + * @brief cclk/pll_div to mspi clk. + */ +typedef enum{ + CCLK_TO_MSPI_CLK = 1, + PLL_DIV2_TO_MSPI_CLK = 2, + PLL_DIV3_TO_MSPI_CLK = 3, + PLL_DIV4_TO_MSPI_CLK = 4, + PLL_DIV5_TO_MSPI_CLK = 5, + PLL_DIV6_TO_MSPI_CLK = 6, + PLL_DIV7_TO_MSPI_CLK = 7, + PLL_DIV8_TO_MSPI_CLK = 8, + PLL_DIV9_TO_MSPI_CLK = 9, + PLL_DIV10_TO_MSPI_CLK = 10, + PLL_DIV11_TO_MSPI_CLK = 11, + PLL_DIV12_TO_MSPI_CLK = 12, + PLL_DIV13_TO_MSPI_CLK = 13, + PLL_DIV14_TO_MSPI_CLK = 14, + PLL_DIV15_TO_MSPI_CLK = 15, +}sys_pll_div_to_mspi_clk_e; + +/** + * @brief hclk div to pclk. + */ +typedef enum{ + HCLK_DIV1_TO_PCLK = 1, + HCLK_DIV2_TO_PCLK = 2, + HCLK_DIV4_TO_PCLK = 4, +}sys_hclk_div_to_pclk_e; + +/** + * @brief cclk div to hclk. + */ +typedef enum{ + CCLK_DIV1_TO_HCLK = 1, + CCLK_DIV2_TO_HCLK = 2, /*< can not use in A0. if use reboot when hclk = 1/2cclk will cause problem */ +}sys_cclk_div_to_hclk_e; + +/** + * @brief Define rc_24M_cal enable/disable. + */ +typedef enum { + RC_24M_CAL_DISABLE=0, + RC_24M_CAL_ENABLE, + +}rc_24M_cal_e; + + +/********************************************************************************************************************** + * global variable declaration * + *********************************************************************************************************************/ +extern sys_clk_t sys_clk; +extern clk_32k_type_e g_clk_32k_src; + +/********************************************************************************************************************** + * global function prototype * + *********************************************************************************************************************/ + +/** + * @brief This function use to select the system clock source. + * @param[in] pll - pll clock. + * @param[in] src - cclk source. + * @param[in] cclk_div - the cclk divide from pll.it is useless if src is not PAD_PLL_DIV. cclk max is 96M + * @param[in] hclk_div - the hclk divide from cclk.hclk max is 48M. + * @param[in] pclk_div - the pclk divide from hclk.pclk max is 24M. + * @param[in] mspi_clk_div - mspi_clk has two source. pll div and hclk.mspi max is 64M. + * @return none + */ +_attribute_ram_code_sec_noinline_ void clock_init(sys_pll_clk_e pll, + sys_clock_src_e src, + sys_pll_div_to_cclk_e cclk_div, + sys_cclk_div_to_hclk_e hclk_div, + sys_hclk_div_to_pclk_e pclk_div, + sys_pll_div_to_mspi_clk_e mspi_clk_div); + +/** + * @brief This function serves to set 32k clock source. + * @param[in] src - variable of 32k type. + * @return none. + */ +void clock_32k_init(clk_32k_type_e src); + +/** + * @brief This function serves to kick 32k xtal. + * @param[in] xtal_times - kick times. + * @return 1 success, 0 error. + */ +unsigned char clock_kick_32k_xtal(unsigned char xtal_times); + +/** + * @brief This function performs to select 24M as the system clock source. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void clock_cal_24m_rc (void); + +/** + * @brief This function performs to select 32K as the system clock source. + * @return none. + */ +void clock_cal_32k_rc (void); + +/** + * @brief This function serves to get the 32k tick. + * @return none. + */ +_attribute_ram_code_sec_noinline_ unsigned int clock_get_32k_tick (void); + +/** + * @brief This function serves to set the 32k tick. + * @param tick - the value of to be set to 32k. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void clock_set_32k_tick(unsigned int tick); +#endif + diff --git a/b91/b91m_ble_sdk/drivers/B91/compatibility_pack/cmpt.h b/b91/b91m_ble_sdk/drivers/B91/compatibility_pack/cmpt.h new file mode 100755 index 0000000..5f62cb5 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/compatibility_pack/cmpt.h @@ -0,0 +1,112 @@ +/******************************************************************************************************** + * @file cmpt.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef DRIVERS_CMPT_H_ +#define DRIVERS_CMPT_H_ +#include "../gpio.h" +#include "../stimer.h" + +/********************************************************************************************************************** + * global constants * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * global macro * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * global data type * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * global variable declaration * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * global function prototype * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * gpio compatibility * + *********************************************************************************************************************/ + +/** + * @brief This function set the pin's output level. + * @param[in] pin - the pin needs to set its output level + * @param[in] value - value of the output level(1: high 0: low) + * @author BLE group . + * @return none + */ +#define gpio_write(pin,value) gpio_set_level(pin,value) + + +/** + * @brief This function enable the output function of a pin. + * @param[in] pin - the pin needs to set the output function(1: enable,0: disable) + * @author BLE group . + * @return none + */ +#define gpio_set_output_en(pin,value) gpio_set_output(pin,value) + + +/** + * @brief This function read the pin's input/output level. + * @param[in] pin - the pin needs to read its level + * @author BLE group . + * @return the pin's level(1: high 0: low) + */ +#define gpio_read(pin) gpio_get_level(pin) + + +/** + * @brief This function servers to enable gpio function. + * @param[in] pin - the selected pin. + * @author BLE group . + * @return none + */ +#define gpio_set_gpio_en(pin) gpio_function_en(pin) + +/** + * @brief This function set the input function of a pin. + * @param[in] pin - the pin needs to set the input function + * @param[in] value - enable or disable the pin's input function(1: enable,0: disable ) + * @author BLE group . + * @return none + */ +#define gpio_set_input_en(pin,value) gpio_set_input (pin,value) + + +/********************************************************************************************************************** + * stimer compatibility * + *********************************************************************************************************************/ + +/* + * @brief This function performs to get system timer tick. + * @return system timer tick value. + * @author BLE group . + */ +#define clock_time stimer_get_tick + + +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/core.h b/b91/b91m_ble_sdk/drivers/B91/core.h new file mode 100755 index 0000000..7350cf4 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/core.h @@ -0,0 +1,104 @@ +/******************************************************************************************************** + * @file core.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef CORE_H +#define CORE_H +#include "nds_intrinsic.h" +#include "sys.h" + +#define read_csr(reg) __nds__csrr(reg) +#define write_csr(reg, val) __nds__csrw(val, reg) +#define swap_csr(reg, val) __nds__csrrw(val, reg) +#define set_csr(reg, bit) __nds__csrrs(bit, reg) +#define clear_csr(reg, bit) __nds__csrrc(bit, reg) + +/* + * Inline nested interrupt entry/exit macros + */ +/* Svae/Restore macro */ +#define save_csr(r) long __##r = read_csr(r); +#define restore_csr(r) write_csr(r, __##r); +/* Support PowerBrake (Performance Throttling) feature */ + + +#define save_mxstatus() save_csr(NDS_MXSTATUS) +#define restore_mxstatus() restore_csr(NDS_MXSTATUS) + + /* Nested IRQ entry macro : Save CSRs and enable global interrupt. */ +#define core_save_nested_context() \ + save_csr(NDS_MEPC) \ + save_csr(NDS_MSTATUS) \ + save_mxstatus() \ + set_csr(NDS_MSTATUS, 1<<3); + +/* Nested IRQ exit macro : Restore CSRs */ +#define core_restore_nested_context() \ + clear_csr(NDS_MSTATUS, 1<<3); \ + restore_csr(NDS_MSTATUS) \ + restore_csr(NDS_MEPC) \ + restore_mxstatus() + +#define fence_iorw __nds__fence(FENCE_IORW,FENCE_IORW) + +typedef enum{ + FLD_FEATURE_PREEMPT_PRIORITY_INT_EN = BIT(0), + FLD_FEATURE_VECTOR_MODE_EN = BIT(1), +} +feature_e; + + +/** + * @brief Disable interrupts globally in the system.external, timer and software interrupts. + * @return r - the value of machine interrupt enable(MIE) register. + * @note this function must be used when the system wants to disable all the interrupt. + */ +static inline unsigned int core_interrupt_disable(void){ + + unsigned int r = read_csr (NDS_MIE); + clear_csr(NDS_MIE, BIT(3)| BIT(7)| BIT(11)); + return r; +} + + +/** + * @brief restore interrupts globally in the system. external,timer and software interrupts. + * @param[in] en - the value of machine interrupt enable(MIE) register before disable. + * @return 0 + * @note this function must be used when the system wants to restore all the interrupt. + */ +static inline unsigned int core_restore_interrupt(unsigned int en){ + + set_csr(NDS_MIE, en); + return 0; +} + +/** + * @brief enable interrupts globally in the system. + * @return none + */ +static inline void core_interrupt_enable(void) +{ + set_csr(NDS_MSTATUS,1<<3); + set_csr(NDS_MIE,1<<11 | 1 << 7 | 1 << 3); + +} +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/dma.h b/b91/b91m_ble_sdk/drivers/B91/dma.h new file mode 100755 index 0000000..e63f48b --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/dma.h @@ -0,0 +1,335 @@ +/******************************************************************************************************** + * @file dma.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +/** @page DMA + * + * Introduction + * =============== + * + * + * API Reference + * =============== + * Header File: dma.h + */ +#ifndef DMA_H_ +#define DMA_H_ +#include "reg_include/register_b91.h" + typedef enum{ + DMA0=0, + DMA1, + DMA2, + DMA3, + DMA4, + DMA5, + DMA6, + DMA7, +}dma_chn_e; + +typedef enum{ + DMA_CHN0_IRQ = BIT(0), + DMA_CHN1_IRQ = BIT(1), + DMA_CHN2_IRQ = BIT(2), + DMA_CHN3_IRQ = BIT(3), + DMA_CHN4_IRQ = BIT(4), + DMA_CHN5_IRQ = BIT(5), + DMA_CHN6_IRQ = BIT(6), + DMA_CHN7_IRQ = BIT(7), +}dma_irq_chn_e; + +typedef enum{ + DMA_REQ_SPI_AHB_TX=0, + DMA_REQ_SPI_AHB_RX, + DMA_REQ_UART0_TX, + DMA_REQ_UART0_RX, + DMA_REQ_SPI_APB_TX, + DMA_REQ_SPI_APB_RX, + DMA_REQ_I2C_TX, + DMA_REQ_I2C_RX, + DMA_REQ_ZB_TX, + DMA_REQ_ZB_RX, + DMA_REQ_PWM_TX, + DMA_REQ_RESERVED, + DMA_REQ_ALGM_TX, + DMA_REQ_ALGM_RX, + DMA_REQ_UART1_TX, + DMA_REQ_UART1_RX, + DMA_REQ_AUDIO0_TX, + DMA_REQ_AUDIO0_RX, + DMA_REQ_AUDIO1_TX, + DMA_REQ_AUDIO1_RX, + +}dma_req_sel_e; + +typedef enum{ + DMA_ADDR_INCREMENT=0, + DMA_ADDR_DECREMENT, + DMA_ADDR_FIX, +} +dma_addr_ctrl_e; + + +typedef enum{ + DMA_NORMAL_MODE=0, + DMA_HANDSHAKE_MODE, +} +dma_mode_e; + +typedef enum{ + DMA_CTR_BYTE_WIDTH=0, + DMA_CTR_HWORD_WIDTH, + DMA_CTR_WORD_WIDTH, +} +dma_ctr_width_e; + +typedef enum{ + DMA_BYTE_WIDTH=1, + DMA_HWORD_WIDTH=2, + DMA_WORD_WIDTH=4, +} +dma_transfer_width_e; + +typedef enum{ + TC_MASK = BIT(1), + ERR_MASK = BIT(2), + ABT_MASK = BIT(3), +}dma_irq_mask_e; + +typedef struct { + unsigned int dst_req_sel:5; /*DstReqSel :8:4 */ + unsigned int src_req_sel:5; /*SrcReqSel :13:9 */ + unsigned int dst_addr_ctrl:2;/*DstAddrCtrl :15:14 0:increment address 1: decrement address 2: fixed address */ + unsigned int src_addr_ctrl:2;/*SrcAddrCtrl :17:16 0:increment address 1: decrement address 2: fixed address */ + unsigned int dstmode:1; /*DstMode:18 0 normal mode 1 handshake*/ + unsigned int srcmode:1; /*SrcMode :19 0 normal mode 1 handshake*/ + unsigned int dstwidth:2; /*DstWidth :21:20 00:byte 01:hword 02:word*/ + unsigned int srcwidth:2; /*SrcWidth :23:22 00:byte 01:hword 02:word*/ + unsigned int src_burst_size:3; /*SrcBurstSize: 26:24*/ + unsigned int vacant_bit :1;/*vacant:27*/ + unsigned int read_num_en:1;/*Rnum_en :28*/ + unsigned int priority:1; /*Pri :29*/ + unsigned int write_num_en:1;/*wnum_en : 30*/ + unsigned int auto_en:1;/*/*auto_en : 31*/ +}dma_config_t; + + +typedef struct { + unsigned int dma_chain_ctl; + unsigned int dma_chain_src_addr; + unsigned int dma_chain_dst_addr; + unsigned int dma_chain_data_len; + unsigned int dma_chain_llp_ptr; +}dma_chain_config_t ; + + +/** + * @brief This function configures DMA control register. + * @param[in] chn - dma channel + * @param[in] config - the prt of dma_config that configured control register + * @return none + */ +static inline void dma_config(dma_chn_e chn ,dma_config_t *config) +{ + BM_CLR(reg_dma_ctrl(chn),BIT_RNG(4,31)); + reg_dma_ctrl(chn) |= (*(unsigned int*)config)<<4; +} + + +/** + * @brief This function servers to enable dma that selected channel. + * @param[in] chn - dma channel. + * @return none + */ +static inline void dma_chn_en(dma_chn_e chn) +{ + BM_SET(reg_dma_ctr0(chn),BIT(0)); +} + +/** + * @brief This function servers to disable dma that selected channel. + * @param[in] chn - dma channel. + * @return none + */ +static inline void dma_chn_dis(dma_chn_e chn) +{ + BM_CLR(reg_dma_ctr0(chn),BIT(0)); +} + +/** + * @brief This function servers to set dma irq mask. + * @param[in] chn - dma channel. + * @param[in] mask - dma irq mask. + * @return none + */ +static inline void dma_set_irq_mask(dma_chn_e chn,dma_irq_mask_e mask) +{ + reg_dma_ctr0(chn) = (reg_dma_ctr0(chn) | BIT_RNG(1,3)) & (~(mask)); +} + +/** + * @brief This function servers to clr dma irq mask. + * @param[in] chn - dma channel. + * @param[in] mask - dma irq mask. + * @return none + * attention the mask of dma tc/err/abt is enable default.we must disable when don'n use it. + */ +static inline void dma_clr_irq_mask(dma_chn_e chn,dma_irq_mask_e mask) +{ + reg_dma_ctr0(chn) |= (mask); +} + +/** + * @brief This function servers to get the terminal count irq status channel. + * @return the dma terminal count irq status channel. + */ +static inline unsigned char dma_get_tc_irq_status(dma_irq_chn_e tc_chn) +{ + return reg_dma_tc_isr&tc_chn; +} + + +/** + * @brief This function servers to clear the irq of terminal count status. + * @param[in] tc_chn -terminal count irq status channel. + * @return none + */ +static inline void dma_clr_tc_irq_status(dma_irq_chn_e tc_chn) +{ + reg_dma_tc_isr = tc_chn; +} + + +/** + * @brief This function servers to get the error irq status channel. + * @return the dma error irq status channel. + */ +static inline unsigned char dma_get_err_irq_status(dma_irq_chn_e err_chn) +{ + return reg_dma_err_isr&err_chn; +} + + +/** + * @brief This function servers to clear the abort status of channel. + * @param[in] err_chn -error status channel. + * @return none + */ +static inline void dma_clr_err_irq_status(dma_irq_chn_e err_chn) +{ + reg_dma_err_isr = err_chn; +} + + +/** + * @brief This function servers to get the abort status of channel. + * @return the dma abort irq status channel. + */ +static inline unsigned char dma_get_abt_irq_status(dma_irq_chn_e abt_chn) +{ + return reg_dma_abt_isr&abt_chn; +} + + +/** + * @brief This function servers to clear the abort status of channel. + * @param[in] abt_chn -abort irq status channel. + * @return none + */ +static inline void dma_clr_abt_irq_status(dma_irq_chn_e abt_chn) +{ + reg_dma_abt_isr = abt_chn; +} + +/** + * @brief this function set the DMA to tx/rx size byte. + * @param[in] chn - DMA channel + * @param[in] size_byte - the address of dma tx/rx size .The maximum transmission length of DMA is 0xFFFFFC bytes and cannot exceed this length. + * @param[in] byte_width - dma tx/rx width + * @return none + */ +static inline void dma_set_size(dma_chn_e chn,unsigned int size_byte,dma_transfer_width_e byte_width) +{ + reg_dma_size(chn) =((size_byte+byte_width-1)/byte_width)|( (size_byte % byte_width)<<22); +} + + +/** + * @brief this function calculate the DMA to tx/rx size byte. + * @param[in] size_byte - the address of dma tx/rx size + * @param[in] byte_width - dma tx/rx width + * @return none + */ +static inline unsigned int dma_cal_size(unsigned int size_byte,dma_transfer_width_e byte_width) +{ + return (((size_byte+byte_width-1)/byte_width)|( (size_byte % byte_width)<<22)); +} + + +/** + * @brief this function set source and destination address for DMA, + * src_address dst_address + * tx sram interface fifo. + * rx interface fifo sram + * @param[in] chn - DMA channel + * @param[in] src_addr - the address of source. + * @param[in] dst_addr - the address of destination. + * @return none + */ +static inline void dma_set_address(dma_chn_e chn,unsigned int src_addr,unsigned int dst_addr) +{ + reg_dma_src_addr(chn)=src_addr; + reg_dma_dst_addr(chn)=dst_addr; +} + + +/** + * @brief this function set source address for DMA, + * @param[in] chn - DMA channel + * @param[in] src_addr - the address of source. + * */ +static inline void dma_set_src_address(dma_chn_e chn,unsigned int src_addr) +{ + reg_dma_src_addr(chn)=src_addr; +} + +/** + * @brief this function set destination address for DMA, + * @param[in] chn - DMA channel + * @param[in] dst_addr - the address of destination. + * */ +static inline void dma_set_dst_address(dma_chn_e chn,unsigned int dst_addr) +{ + reg_dma_dst_addr(chn)=dst_addr; +} + + +/** + * @brief this function set reset DMA, + * @return none + */ +static inline void dma_reset(void) +{ + reg_rst1 &= ~(FLD_RST1_DMA); + reg_rst1 |= FLD_RST1_DMA; +} + + +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/driver_b91.h b/b91/b91m_ble_sdk/drivers/B91/driver_b91.h new file mode 100755 index 0000000..e9dc284 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/driver_b91.h @@ -0,0 +1,60 @@ +/******************************************************************************************************** + * @file driver_b91.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + + + +#include "audio.h" +#include "analog.h" +#include "dma.h" +#include "gpio.h" +#include "i2c.h" +#include "spi.h" +#include "pwm.h" +#include "pm.h" +#include "timer.h" +#include "flash.h" +#include "usbhw.h" +#include "watchdog.h" +#include "s7816.h" +#include "nds_intrinsic.h" +#include "mdec.h" + +#include "trng.h" +#include "npe.h" +#include "sys.h" +#include "pke.h" +#include "plic.h" +#include "uart.h" +#include "stimer.h" +#include "aes.h" + +#include "rf.h" + +#include "lpc.h" +#include "clock.h" +#include "emi.h" + +#include "mspi.h" +#include "adc.h" + diff --git a/b91/b91m_ble_sdk/drivers/B91/emi.c b/b91/b91m_ble_sdk/drivers/B91/emi.c new file mode 100755 index 0000000..b9a51eb --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/emi.c @@ -0,0 +1,497 @@ +/******************************************************************************************************** + * @file emi.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "emi.h" +#include "stimer.h" +/********************************************************************************************************************** + * local macro * + *********************************************************************************************************************/ +#define EMI_STATE0 0x1234 +#define EMI_STATE1 0x5678 +#define EMI_TX_FIFO_ADDR 0x14081c +#define EMI_TX_PKT_PAYLOAD 37 + +/********************************************************************************************************************** + * global constants * + *********************************************************************************************************************/ + +static unsigned char emi_rx_packet[128] __attribute__ ((aligned (4))); +static unsigned char emi_ble_tx_packet [48] __attribute__ ((aligned (4))) = {3,0,0,0,0,10}; +static unsigned char emi_zigbee_tx_packet[48] __attribute__ ((aligned (4))) = {19,0,0,0,20,0,0}; +static unsigned int s_emi_rx_cnt __attribute__ ((aligned (4))) = 0; +static unsigned int s_emi_rssibuf = 0; +static signed char s_emi_rssi = 0; +static unsigned int s_state0,s_state1; + +/********************************************************************************************************************** + * function implementation * + *********************************************************************************************************************/ + +/** + * @brief This function serves to set singletone power + * @param[in] level - the power level. + * @return none + */ +void rf_set_power_level_index_singletone (rf_power_level_e level) +{ + unsigned char value = 0; + + if(level&BIT(7)) + { + write_reg8(0x140e3c, (read_reg8(0x140e3c) & 0xbf) | ((0x01)<<6));// VANT + } + else + { + write_reg8(0x140e3c, (read_reg8(0x140e3c) & 0xbf)); + } + reg_rf_ll_ctrl0 = 0x55; // tx_en + delay_us(150); + + value = (unsigned char)level&0x3f; + write_reg8(0x140f78,read_reg8(0x140f78)|BIT(6)); // TX_PA_PWR_OW BIT6 set 1 + write_reg8(0x140f7c, (read_reg8(0x140f7c)&0x81)|(value<<1)); // TX_PA_PWR BIT1 t0 BIT6 set value +} + +extern unsigned char g_single_tong_freqoffset; + +/** + * @brief This function serves to set the TX singletone power and channel + * @param[in] power_level - the power level. + * @param[in] rf_chn - the channel. + * @return none + */ +void rf_emi_tx_single_tone(rf_power_level_e power_level,signed char rf_chn) +{ + g_single_tong_freqoffset = 1; + rf_mode_init(); + rf_set_zigbee_250K_mode(); + rf_set_chn(rf_chn); + rf_set_power_level_index_singletone(power_level); + rf_set_txmode(); + g_single_tong_freqoffset = 0; + +} + +/** + * @brief This function serves to stop emi/(close RF) + * @return none + */ +void rf_emi_stop(void) +{ + write_reg8(0x140f78, 0); + write_reg8(0x140f7c, 0);//TX_PA_PWR + rf_set_power_level_index (0); + rf_set_tx_rx_off(); +} + +/** + * @brief This function serves to set the CD mode correlation register + * @return none + */ +void rf_emi_tx_continue_setup(void) +{ + + write_reg8(0x140800,0x0a); + write_reg8(0x140808,0x00); // access code + + write_reg8(0x140801,0x80); // kick tx controller to wait data + s_state0 = EMI_STATE0; + s_state1 = EMI_STATE1; +} + +/** + * @brief This function serves to update the CD mode data + * @param[in] rf_mode - mode of RF. + * @param[in] power_level - power level of RF. + * @param[in] rf_chn - channel of RF. + * @param[in] pkt_type - The type of data sent. + * -#0:random + * -#1:0xf0 + * -#2:0x55 + * @return none + */ +void rf_emi_tx_continue_update_data(rf_mode_e rf_mode,rf_power_level_e power_level,signed char rf_chn,unsigned char pkt_type) +{ + rf_mode_init(); + switch(rf_mode) + { + case RF_MODE_BLE_1M_NO_PN: + rf_set_ble_1M_NO_PN_mode(); + break; + case RF_MODE_BLE_2M: + rf_set_ble_2M_NO_PN_mode(); + break; + case RF_MODE_LR_S2_500K: + rf_set_ble_500K_mode(); + break; + case RF_MODE_LR_S8_125K: + rf_set_ble_125K_mode(); + break; + case RF_MODE_ZIGBEE_250K: + rf_set_zigbee_250K_mode(); + break; + + default:break; + } + rf_pn_disable(); + rf_set_chn(rf_chn); + reg_rf_ll_ctrl0 = 0x45; // reset tx/rx state machine + rf_set_power_level_index_singletone (power_level); + rf_emi_tx_continue_setup(); + write_reg8(0x140808, pkt_type); // 0:pbrs9 1:0xf0 2:0x55 +} + +/** + * @brief This function serves to generate random number. + * @param[in] state - the old random number. + * @return the new random number + */ +unsigned int emi_pn_gen(unsigned int state) +{ + unsigned int feed = 0; + feed = (state&0x4000) >> 1; + state ^= feed; + state <<= 1; + state = (state&0xfffe) + ((state&0x8000)>>15); + return state; +} + +/** + * @brief This function serves to continue to run the CD mode + * @return none + */ +void rf_continue_mode_run(void) +{ + if(read_reg8(0x140808) == 1){ + write_reg32(EMI_TX_FIFO_ADDR, 0x0f0f0f0f); + }else if(read_reg8(0x140808)==2){ + write_reg32(EMI_TX_FIFO_ADDR, 0x55555555); + }else if(read_reg8(0x140808)==3){ + write_reg32(EMI_TX_FIFO_ADDR, read_reg32(0x140809)); + }else if(read_reg8(0x140808)==4){ + write_reg32(EMI_TX_FIFO_ADDR, 0); + }else if(read_reg8(0x140808)==5){ + write_reg32(EMI_TX_FIFO_ADDR, 0xffffffff); + }else{ + write_reg32(EMI_TX_FIFO_ADDR, (s_state0<<16)+s_state1); + s_state0 = emi_pn_gen(s_state0); + s_state1 = emi_pn_gen(s_state1); + } + + while(read_reg8(EMI_TX_FIFO_ADDR) & 0x1){ + } +} + +/** + * @brief This function serves to set rx mode and channel + * @param[in] mode - mode of RF. + * @param[in] rf_chn - the rx channel. + * @return none + */ +void rf_emi_rx_setup(rf_mode_e mode,signed char rf_chn) +{ + rf_mode_init(); + switch(mode) + { + case RF_MODE_BLE_1M_NO_PN: + rf_set_ble_1M_NO_PN_mode(); + break; + case RF_MODE_BLE_2M: + rf_set_ble_2M_NO_PN_mode(); + break; + case RF_MODE_LR_S2_500K: + rf_set_ble_500K_mode(); + break; + case RF_MODE_LR_S8_125K: + rf_set_ble_125K_mode(); + break; + case RF_MODE_ZIGBEE_250K: + rf_set_zigbee_250K_mode(); + break; + + default:break; + } + rf_set_rx_dma(emi_rx_packet,3,64); + rf_pn_disable(); + rf_set_chn(rf_chn);//set freq + if(mode != RF_MODE_ZIGBEE_250K) + rf_access_code_comm(EMI_ACCESS_CODE); //accesscode + rf_set_tx_rx_off(); + rf_set_rxmode(); + delay_us(150); + s_emi_rssi = 0; + s_emi_rssibuf = 0; + s_emi_rx_cnt = 0; +} + +/** + * @brief This function serves to update the number of receiving packet and the RSSI + * @return none + */ +void rf_emi_rx_loop(void) +{ + if(rf_get_irq_status(FLD_RF_IRQ_RX)) // rx irq + { + if((read_reg8(0x140840) & 0xf0) == 0) // crc err + { + s_emi_rssibuf += (read_reg8(0x140c5d)); + if(s_emi_rx_cnt) + { + if(s_emi_rssibuf != 0) + { + s_emi_rssibuf >>= 1; + } + } + s_emi_rssi = s_emi_rssibuf - 110; + s_emi_rx_cnt++; + } + rf_clr_irq_status(FLD_RF_IRQ_RX); // clr rx irq + write_reg8(0x140a00, 0x80); // stop cmd + } +} + +/** + * @brief This function serves to get the number of packets received + * @return the number of packets received + */ +unsigned int rf_emi_get_rxpkt_cnt(void) +{ + return s_emi_rx_cnt; +} + +/** + * @brief This function serves to get the RSSI of packets received + * @return the RSSI of packets received + */ +char rf_emi_get_rssi_avg(void) +{ + return s_emi_rssi; +} + + +/** + * @brief This function serves to generate random packets that need to be sent in burst mode + * @param[in] *p - the address of random packets. + * @param[in] n - the number of random packets. + * @return none + */ +void rf_phy_test_prbs9 (unsigned char *p, int n) +{ + unsigned short x = 0x1ff; + int i = 0; + int j = 0; + for ( i=0; i> 1) | (((x<<4) ^ (x<<8)) & 0x100); + } + *p++ = d; + } +} + +/** + * @brief This function serves to send packets in the burst mode + * @param[in] rf_mode - mode of RF. + * @param[in] pkt_type - The type of data sent. + * -#0:random + * -#1:0xf0 + * -#2:0x55 + * @return none + */ + +void rf_emi_tx_burst_loop(rf_mode_e rf_mode,unsigned char pkt_type) +{ + unsigned char rf_data_len = EMI_TX_PKT_PAYLOAD+1; + unsigned int rf_tx_dma_len = rf_tx_packet_dma_len(rf_data_len); + write_reg8(0x140a00, 0x80); // stop SM + rf_set_txmode(); + if((rf_mode==RF_MODE_BLE_1M_NO_PN)||(rf_mode==RF_MODE_BLE_2M))//ble + { + rf_data_len = EMI_TX_PKT_PAYLOAD+2; + rf_tx_dma_len = rf_tx_packet_dma_len(rf_data_len); + emi_ble_tx_packet[4]=0; + emi_ble_tx_packet[5]=EMI_TX_PKT_PAYLOAD; + emi_ble_tx_packet[3] = (rf_tx_dma_len >> 24)&0xff; + emi_ble_tx_packet[2] = (rf_tx_dma_len >> 16)&0xff; + emi_ble_tx_packet[1] = (rf_tx_dma_len >> 8)&0xff; + emi_ble_tx_packet[0] = rf_tx_dma_len&0xff; + rf_start_stx ((void *)emi_ble_tx_packet,read_reg32(0x140200) + 10); + while(!(rf_get_irq_status(FLD_RF_IRQ_TX))); + rf_clr_irq_status(FLD_RF_IRQ_TX); + + delay_ms(2); + if(pkt_type == 0) + rf_phy_test_prbs9(&emi_ble_tx_packet[6],37); + } + else if(rf_mode == RF_MODE_LR_S8_125K) + { + rf_data_len = EMI_TX_PKT_PAYLOAD+2; + rf_tx_dma_len = rf_tx_packet_dma_len(rf_data_len); + emi_ble_tx_packet[4]=0; + emi_ble_tx_packet[5]=EMI_TX_PKT_PAYLOAD; + emi_ble_tx_packet[3] = (rf_tx_dma_len >> 24)&0xff; + emi_ble_tx_packet[2] = (rf_tx_dma_len >> 16)&0xff; + emi_ble_tx_packet[1] = (rf_tx_dma_len >> 8)&0xff; + emi_ble_tx_packet[0] = rf_tx_dma_len&0xff; + rf_start_stx ((void *)emi_ble_tx_packet,read_reg32(0x140200) + 10); + while(!(rf_get_irq_status(FLD_RF_IRQ_TX))); + rf_clr_irq_status(FLD_RF_IRQ_TX); + + + delay_ms(2); + if(pkt_type == 0) + rf_phy_test_prbs9(&emi_ble_tx_packet[6],37); + } + else if(rf_mode == RF_MODE_LR_S2_500K) + { + rf_data_len = EMI_TX_PKT_PAYLOAD+2; + rf_tx_dma_len = rf_tx_packet_dma_len(rf_data_len); + emi_ble_tx_packet[4]=0; + emi_ble_tx_packet[5]=EMI_TX_PKT_PAYLOAD; + emi_ble_tx_packet[3] = (rf_tx_dma_len >> 24)&0xff; + emi_ble_tx_packet[2] = (rf_tx_dma_len >> 16)&0xff; + emi_ble_tx_packet[1] = (rf_tx_dma_len >> 8)&0xff; + emi_ble_tx_packet[0] = rf_tx_dma_len&0xff; + rf_start_stx ((void *)emi_ble_tx_packet,read_reg32(0x140200) + 10); + while(!(rf_get_irq_status(FLD_RF_IRQ_TX))); + rf_clr_irq_status(FLD_RF_IRQ_TX); + + + delay_ms(2); + if(pkt_type == 0) + rf_phy_test_prbs9(&emi_ble_tx_packet[6],37); + } + else if(rf_mode == RF_MODE_ZIGBEE_250K) + { + rf_data_len = EMI_TX_PKT_PAYLOAD+1; + rf_tx_dma_len = rf_tx_packet_dma_len(rf_data_len); + emi_zigbee_tx_packet[4]=EMI_TX_PKT_PAYLOAD+2; + emi_zigbee_tx_packet[3] = (rf_tx_dma_len >> 24)&0xff; + emi_zigbee_tx_packet[2] = (rf_tx_dma_len >> 16)&0xff; + emi_zigbee_tx_packet[1] = (rf_tx_dma_len >> 8)&0xff; + emi_zigbee_tx_packet[0] = rf_tx_dma_len&0xff; + rf_start_stx ((void *)emi_zigbee_tx_packet,read_reg32(0x140200) + 10); + while(!(rf_get_irq_status(FLD_RF_IRQ_TX))); + rf_clr_irq_status(FLD_RF_IRQ_TX); + + + delay_us(625*2); + if(pkt_type == 0) + rf_phy_test_prbs9(&emi_zigbee_tx_packet[5],37); + } +} + + +/** + * @brief This function serves to set the burst mode + * @param[in] rf_mode - mode of RF. + * @param[in] power_level - power level of RF. + * @param[in] rf_chn - channel of RF. + * @param[in] pkt_type - The type of data sent. + * -#0:random + * -#1:0xf0 + * -#2:0x55 + * @return none + */ +void rf_emi_tx_burst_setup(rf_mode_e rf_mode,rf_power_level_e power_level,signed char rf_chn,unsigned char pkt_type) +{ + unsigned char i = 0; + unsigned char tx_data = 0; + write_reg8(0x10083c,0x10); // print buffer size set + rf_set_tx_dma(2,128); + rf_set_chn(rf_chn); + rf_mode_init(); + switch(rf_mode) + { + case RF_MODE_BLE_1M_NO_PN: + rf_set_ble_1M_NO_PN_mode(); + break; + case RF_MODE_BLE_2M: + rf_set_ble_2M_NO_PN_mode(); + break; + case RF_MODE_LR_S2_500K: + rf_set_ble_500K_mode(); + break; + case RF_MODE_LR_S8_125K: + rf_set_ble_125K_mode(); + break; + case RF_MODE_ZIGBEE_250K: + rf_set_zigbee_250K_mode(); + break; + + default:break; + } + if(rf_mode != RF_MODE_ZIGBEE_250K) + rf_access_code_comm(EMI_ACCESS_CODE); //accesscode + + rf_pn_disable(); + rf_set_power_level (power_level); + if(pkt_type == 1) + { + tx_data = 0x0f; + } + else if(pkt_type == 2) + { + tx_data = 0x55; + } + + switch(rf_mode) + { + case RF_MODE_LR_S2_500K: + case RF_MODE_LR_S8_125K: + case RF_MODE_BLE_1M_NO_PN: + case RF_MODE_BLE_2M: + emi_ble_tx_packet[4] = pkt_type;//type + for(i = 0;i < 37;i++) + { + emi_ble_tx_packet[6+i]=tx_data; + } + break; + case RF_MODE_ZIGBEE_250K: + emi_zigbee_tx_packet[5] = pkt_type; // type + for(i = 0;i < 37;i++) + { + emi_zigbee_tx_packet[5 + i] = tx_data; + } + break; + + default: + break; + } + +} + +/** + * @brief This function serves to reset baseband + * @return none + */ +void rf_emi_reset_baseband(void) +{ + reg_rst3 &= (~FLD_RST3_ZB); // reset baseband + reg_rst3 |= (FLD_RST3_ZB); // clr baseband +} diff --git a/b91/b91m_ble_sdk/drivers/B91/emi.h b/b91/b91m_ble_sdk/drivers/B91/emi.h new file mode 100755 index 0000000..c37db12 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/emi.h @@ -0,0 +1,148 @@ +/******************************************************************************************************** + * @file emi.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef EMI_H_ +#define EMI_H_ + +#include "rf.h" + +/********************************************************************************************************************** + * global macro * + *********************************************************************************************************************/ +#define EMI_ACCESS_ADDR 0x140808 +#define EMI_ACCESS_CODE 0x29417671 + +/********************************************************************************************************************** + * function declaration * + *********************************************************************************************************************/ + +/** + * @brief This function serves to set singletone power and channel + * @param[in] power_level - the power level. + * @param[in] rf_chn - the channel. + * @return none + */ +void rf_emi_tx_single_tone(rf_power_level_e power_level,signed char rf_chn); + +/** + * @brief This function serves to set rx mode and channel + * @param[in] mode - mode of RF. + * @param[in] rf_chn - the rx channel. + * @return none + */ +void rf_emi_rx_setup(rf_mode_e mode,signed char rf_chn); + +/** + * @brief This function serves to update the number of receiving packet and the RSSI + * @return none + */ +void rf_emi_rx_loop(void); + +/** + * @brief This function serves to stop emi/(close RF) + * @return none + */ +void rf_emi_stop(void); + +/** + * @brief This function serves to get the number of packets received. + * @return the number of packets received. + */ +unsigned int rf_emi_get_rxpkt_cnt(void); + +/** + * @brief This function serves to get the RSSI of packets received + * @return the RSSI of packets received + */ +char rf_emi_get_rssi_avg(void); + + +/** + * @brief This function serves to set the CD mode correlation register + * @return none + */ +void rf_emi_tx_continue_setup(void); + +/** + * @brief This function serves to update the CD mode data. + * @param[in] rf_mode - mode of RF. + * @param[in] power_level - power level of RF. + * @param[in] rf_chn - channel of RF. + * @param[in] pkt_type - The type of data sent. + * -#0:random + * -#1:0xf0 + * -#2:0x55 + * @return none + */ +void rf_emi_tx_continue_update_data(rf_mode_e rf_mode,rf_power_level_e power_level,signed char rf_chn,unsigned char pkt_type); + +/** + * @brief This function serves to continue to run the CD mode + * @return none + */ +void rf_continue_mode_run(void); + +/** + * @brief This function serves to send packets in the burst mode + * @param[in] rf_mode - mode of RF. + * @param[in] pkt_type - The type of data sent. + * -#0:random + * -#1:0xf0 + * -#2:0x55 + * @return none + */ +void rf_emi_tx_burst_loop(rf_mode_e rf_mode,unsigned char pkt_type); + +/** + * @brief This function serves to set the burst mode + * @param[in] rf_mode - mode of RF. + * @param[in] power_level - power level of RF. + * @param[in] rf_chn - channel of RF. + * @param[in] pkt_type - The type of data sent. + * -#0:random + * -#1:0xf0 + * -#2:0x55 + * @return none + */ +void rf_emi_tx_burst_setup(rf_mode_e rf_mode,rf_power_level_e power_level,signed char rf_chn,unsigned char pkt_type); + +/** + * @brief This function serves to generate random packets that need to be sent in burst mode + * @param[in] *p - the address of random packets. + * @param[in] n - the number of random packets. + * @return none + */ +void rf_phy_test_prbs9 (unsigned char *p, int n); + +/** + * @brief This function serves to reset baseband. + * @return none + */ +void rf_emi_reset_baseband(void); + +/** + * @brief This function serves to generate random number. + * @param[in] state - the old random number. + * @return the new random number + */ +unsigned int emi_pn_gen(unsigned int state); +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/ext_driver/driver_ext.h b/b91/b91m_ble_sdk/drivers/B91/ext_driver/driver_ext.h new file mode 100755 index 0000000..42633a0 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/ext_driver/driver_ext.h @@ -0,0 +1,34 @@ +/******************************************************************************************************** + * @file driver_ext.h + * + * @brief This is the header file for B91 + * + * @author BLE Group + * @date 2020 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef DRIVERS_B91_EXT_DRIVER_DRIVER_EXT_H_ +#define DRIVERS_B91_EXT_DRIVER_DRIVER_EXT_H_ + + +#include "ext_rf.h" +#include "ext_pm.h" +#include "ext_gpio.h" +#include "ext_misc.h" +#include "software_pa.h" + + +#endif /* DRIVERS_B91_EXT_DRIVER_DRIVER_EXT_H_ */ diff --git a/b91/b91m_ble_sdk/drivers/B91/ext_driver/ext_gpio.c b/b91/b91m_ble_sdk/drivers/B91/ext_driver/ext_gpio.c new file mode 100755 index 0000000..9e310b0 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/ext_driver/ext_gpio.c @@ -0,0 +1,65 @@ +/******************************************************************************************************** + * @file ext_misc.c + * + * @brief This is the header file for B91 + * + * @author BLE Group + * @date 2020 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "ext_gpio.h" + + +/** + * @brief This function set a pin's pull-up/down resistor. + * @param[in] gpio - the pin needs to set its pull-up/down resistor + * @param[in] up_down - the type of the pull-up/down resistor + * @return none + */ +void gpio_setup_up_down_resistor(gpio_pin_e gpio, gpio_pull_type up_down) +{ + unsigned char r_val = up_down & 0x03; + + unsigned char base_ana_reg = 0x0e + ((gpio >> 8) << 1) + ( (gpio & 0xf0) ? 1 : 0 ); //group = gpio>>8; + unsigned char shift_num, mask_not; + + if(gpio & 0x11){ + shift_num = 0; + mask_not = 0xfc; + } + else if(gpio & 0x22){ + shift_num = 2; + mask_not = 0xf3; + } + else if(gpio & 0x44){ + shift_num = 4; + mask_not = 0xcf; + } + else if(gpio & 0x88){ + shift_num = 6; + mask_not = 0x3f; + } + else{ + return; + } + + if(GPIO_DP == gpio){ + //usb_dp_pullup_en (0); + } + + analog_write_reg8(base_ana_reg, (analog_read_reg8(base_ana_reg) & mask_not) | (r_val << shift_num)); +} + diff --git a/b91/b91m_ble_sdk/drivers/B91/ext_driver/ext_gpio.h b/b91/b91m_ble_sdk/drivers/B91/ext_driver/ext_gpio.h new file mode 100755 index 0000000..c0142ba --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/ext_driver/ext_gpio.h @@ -0,0 +1,89 @@ +/******************************************************************************************************** + * @file ext_misc.h + * + * @brief This is the header file for B91 + * + * @author BLE Group + * @date 2020 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#ifndef DRIVERS_B91_EXT_GPIO_H_ +#define DRIVERS_B91_EXT_GPIO_H_ + +#include "nds_intrinsic.h" +#include "compiler.h" + +#include "../analog.h" +#include "../dma.h" +#include "../gpio.h" +#include "../pm.h" +#include "../timer.h" +#include "../flash.h" +#include "../mdec.h" +#include "../trng.h" +#include "../sys.h" +#include "../plic.h" +#include "../stimer.h" +#include "../clock.h" +#include "../compatibility_pack/cmpt.h" + +/** + * @brief This function read a pin's cache from the buffer. + * @param[in] pin - the pin needs to read. + * @param[in] p - the buffer from which to read the pin's level. + * @return the state of the pin. + */ +static inline unsigned int gpio_read_cache(gpio_pin_e pin, unsigned char *p) +{ + return p[pin>>8] & (pin & 0xff); +} + +/** + * @brief This function read all the pins' input level. + * @param[out] p - the buffer used to store all the pins' input level + * @return none + */ +static inline void gpio_read_all(unsigned char *p) +{ + p[0] = REG_ADDR8(0x140300); + p[1] = REG_ADDR8(0x140308); + p[2] = REG_ADDR8(0x140310); + p[3] = REG_ADDR8(0x140318); + p[4] = REG_ADDR8(0x140320); +} + +/** + * @brief Define pull up or down types + */ +typedef enum { + PM_PIN_UP_DOWN_FLOAT = 0, + PM_PIN_PULLUP_1M = 1, + PM_PIN_PULLDOWN_100K = 2, + PM_PIN_PULLUP_10K = 3, +}gpio_pull_type; + +/** + * @brief This function set a pin's pull-up/down resistor. + * @param[in] gpio - the pin needs to set its pull-up/down resistor + * @param[in] up_down - the type of the pull-up/down resistor + * @return none + */ +void gpio_setup_up_down_resistor(gpio_pin_e gpio, gpio_pull_type up_down); + + + +#endif /* DRIVERS_B91_EXT_GPIO_H_ */ diff --git a/b91/b91m_ble_sdk/drivers/B91/ext_driver/ext_misc.h b/b91/b91m_ble_sdk/drivers/B91/ext_driver/ext_misc.h new file mode 100755 index 0000000..e823ff4 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/ext_driver/ext_misc.h @@ -0,0 +1,368 @@ +/******************************************************************************************************** + * @file ext_misc.h + * + * @brief This is the header file for B91 + * + * @author BLE Group + * @date 2020 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#ifndef DRIVERS_B91_EXT_MISC_H_ +#define DRIVERS_B91_EXT_MISC_H_ + +#include "nds_intrinsic.h" + +#include "../analog.h" +#include "../dma.h" +#include "../gpio.h" +#include "../pm.h" +#include "../timer.h" +#include "../flash.h" +#include "../mdec.h" +#include "../trng.h" +#include "../sys.h" +#include "../plic.h" +#include "../stimer.h" +#include "../clock.h" +#include "../uart.h" +#include "types.h" +#include "compiler.h" + +/* for debug */ +#define DBG_SRAM_ADDR 0x00014 + + +/* + * addr - only 0x00012 ~ 0x00021 can be used !!! */ +#define write_dbg32(addr, value) write_sram32(addr, value) + +#define write_log32(err_code) write_sram32(0x00014, err_code) + + + +/******************************* stimer_start ******************************************************************/ +#define SYSTICK_NUM_PER_US 16 +#define reg_system_tick_irq reg_system_irq_level + +typedef enum { + STIMER_IRQ_MASK = BIT(0), + STIMER_32K_CAL_IRQ_MASK = BIT(1), +}stimer_irq_mask_e; + +typedef enum { + FLD_IRQ_SYSTEM_TIMER = BIT(0), +}system_timer_irq_mask_e; + + +typedef enum { + STIMER_IRQ_CLR = BIT(0), + STIMER_32K_CAL_IRQ_CLR = BIT(1), +}stimer_irq_clr_e; + + +/** + * @brief This function serves to enable system timer interrupt. + * @return none + */ +static inline void systimer_irq_enable(void) +{ + reg_irq_src0 |= BIT(IRQ1_SYSTIMER); + //plic_interrupt_enable(IRQ1_SYSTIMER); +} + +/** + * @brief This function serves to disable system timer interrupt. + * @return none + */ +static inline void systimer_irq_disable(void) +{ + reg_irq_src0 &= ~BIT(IRQ1_SYSTIMER); + //plic_interrupt_disable(IRQ1_SYSTIMER); +} + +static inline void systimer_set_irq_mask(void) +{ + reg_system_irq_mask |= STIMER_IRQ_MASK; +} + +static inline void systimer_clr_irq_mask(void) +{ + reg_system_irq_mask &= (~STIMER_IRQ_MASK); +} + +static inline unsigned char systimer_get_irq_status(void) +{ + return reg_system_cal_irq & FLD_IRQ_SYSTEM_TIMER; +} + +static inline void systimer_clr_irq_status(void) +{ + reg_system_cal_irq = STIMER_IRQ_CLR; +} + +static inline void systimer_set_irq_capture(unsigned int tick) +{ + reg_system_irq_level = tick; +} + +static inline unsigned int systimer_get_irq_capture(void) +{ + return reg_system_irq_level; +} + +static inline int tick1_exceed_tick2(unsigned int tick1, unsigned int tick2) +{ + return (unsigned int)(tick1 - tick2) < BIT(30); +} +/******************************* stimer_end ********************************************************************/ + + + +/******************************* aes_start ******************************************************************/ +extern unsigned int aes_data_buff[8]; +/******************************* aes_end ********************************************************************/ + + + +/******************************* core_start ******************************************************************/ +#define irq_disable core_interrupt_disable +#define irq_enable core_interrupt_enable +#define irq_restore(en) core_restore_interrupt(en) +/******************************* core_end ********************************************************************/ + + + +/******************************* analog_start ******************************************************************/ +#define analog_write analog_write_reg8 +#define analog_read analog_read_reg8 + +/******************************* analog_end ********************************************************************/ + + + +/******************************* clock_start ******************************************************************/ +typedef enum{ + SYSCLK_16M = 16, + SYSCLK_24M = 24, + SYSCLK_32M = 32, + SYSCLK_48M = 48, + SYSCLK_64M = 64, +}sys_clk_fre_t; + +static inline unsigned char clock_get_system_clk() +{ + return sys_clk.cclk; +} +/******************************* clock_end ********************************************************************/ + + + +/******************************* trng_start ******************************************************************/ +#define rand trng_rand +#define random_generator_init trng_init + + +/** + * @brief This function performs to generate a series of random numbers + * @param[in] len - data length + * @param[out] data - data pointer + * @return none + **/ +void generateRandomNum(int len, unsigned char *data); + +/******************************* trng_end ********************************************************************/ + + + +/******************************* sys_start ******************************************************************/ +#define sleep_us(x) delay_us(x) +#define sleep_ms(x) delay_ms(x) + + +/******************************* sys_end ********************************************************************/ + + + +/******************************* dma_start ***************************************************************/ + + + +/** + * @brief ACL RX Data buffer length = maxRxOct + 21, then 16 Byte align + * maxRxOct + 21 = 4(DMA_len) + 2(BLE header) + maxRxOct + 4(MIC) + 3(CRC) + 8(ExtraInfor) + RX buffer size must be be 16*n, due to MCU design + */ +#define CAL_LL_ACL_RX_FIFO_SIZE(maxRxOct) (((maxRxOct+21) + 15) / 16 *16) + + +/** + * @brief ACL TX Data buffer length = maxTxOct + 10, then 16 Byte align + * maxTxOct + 10 = 4(DMA_len) + 2(BLE header) + maxTxOct + 4(MIC) + TX buffer size must be be 16*n, due to MCU design + */ +#define CAL_LL_ACL_TX_FIFO_SIZE(maxTxOct) (((maxTxOct+10) + 15) / 16 *16) + + +/*HCI TX RX buffer len = uart_fifo+ dma 4byte */ +#define HCI_FIFO_SIZE(n) (((n+2+4) + 15) / 16 *16) + + +/* + * @brief ISO RX Data buffer length = ISORxOct + 21, then 16 Byte align + * ISORxOct + 21 = 4(DMA_len) + 2(BLE header) + ISORxOct + 4(MIC) + 3(CRC) + 8(ExtraInfor) + * RX buffer size must be be 16*n, due to MCU design + */ +#define CAL_LL_ISO_RX_FIFO_SIZE(n) (((n + 21) + 15) / 16 * 16) + + +/* + * @brief ISO TX Data buffer length = ISOTxOct + 10, then 16 Byte align + * ISORxOct + 10 = 4(DMA_len) + 2(BLE header) + ISOTxOct + 4(MIC) + * TX buffer size must be be 16*n, due to MCU design + */ +#define CAL_LL_ISO_TX_FIFO_SIZE(n) (((n + 10) + 15) / 16 * 16) + + +/* +* DMA_LEN(4B)+Hdr(2B)+PLD(251B)+MIC(4B)+CRC(3B)+TLK_PKT_INFO(12B) +* **use 2B enough** +*/ +#define ISO_BIS_RX_PDU_SIZE_ALLIGN16(n) (((n + 25) + 15) / 16 * 16) //4+2+4+2+4+3+12 + +//12 = 4(struct bis_rx_pdu_tag *next) + 4(u32 payloadNum) + 4(u32 idealPldAnchorTick) in bis_rx_pdu_t +#define BIS_LL_RX_PDU_FIFO_SIZE(n) (CAL_LL_ISO_RX_FIFO_SIZE(n) + 12) + +/******************************* dma_end ********************************************************************/ + + + +/******************************* plic_start ******************************************************************/ +enum{//todo + FLD_IRQ_EXCEPTION_EN , + FLD_IRQ_SYSTIMER_EN, + FLD_IRQ_ALG_EN, + FLD_IRQ_TIMER1_EN, + FLD_IRQ_TIMER0_EN, + FLD_IRQ_DMA_EN, + FLD_IRQ_BMC_EN, + FLD_IRQ_USB_CTRL_EP_SETUP_EN, + FLD_IRQ_USB_CTRL_EP_DATA_EN, + FLD_IRQ_USB_CTRL_EP_STATUS_EN, + FLD_IRQ_USB_CTRL_EP_SETINF_EN, + FLD_IRQ_USB_ENDPOINT_EN, + FLD_IRQ_ZB_DM_EN, + FLD_IRQ_ZB_BLE_EN, + FLD_IRQ_ZB_BT_EN, + FLD_IRQ_ZB_RT_EN, + FLD_IRQ_PWM_EN, + FLD_IRQ_PKE_EN,//add + FLD_IRQ_UART1_EN, + FLD_IRQ_UART0_EN, + FLD_IRQ_DFIFO_EN, + FLD_IRQ_I2C_EN, + FLD_IRQ_SPI_APB_EN, + FLD_IRQ_USB_PWDN_EN, + FLD_IRQ_EN, + FLD_IRQ_GPIO2RISC0_EN, + FLD_IRQ_GPIO2RISC1_EN, + FLD_IRQ_SOFT_EN, + + FLD_IRQ_NPE_BUS0_EN, + FLD_IRQ_NPE_BUS1_EN, + FLD_IRQ_NPE_BUS2_EN, + FLD_IRQ_NPE_BUS3_EN, + FLD_IRQ_NPE_BUS4_EN, + + FLD_IRQ_USB_250US_EN, + FLD_IRQ_USB_RESET_EN, + FLD_IRQ_NPE_BUS7_EN, + FLD_IRQ_NPE_BUS8_EN, + + FLD_IRQ_NPE_BUS13_EN=42, + FLD_IRQ_NPE_BUS14_EN, + FLD_IRQ_NPE_BUS15_EN, + + FLD_IRQ_NPE_BUS17_EN=46, + + FLD_IRQ_NPE_BUS21_EN=50, + FLD_IRQ_NPE_BUS22_EN, + FLD_IRQ_NPE_BUS23_EN, + FLD_IRQ_NPE_BUS24_EN, + FLD_IRQ_NPE_BUS25_EN, + FLD_IRQ_NPE_BUS26_EN, + FLD_IRQ_NPE_BUS27_EN, + FLD_IRQ_NPE_BUS28_EN, + FLD_IRQ_NPE_BUS29_EN, + FLD_IRQ_NPE_BUS30_EN, + FLD_IRQ_NPE_BUS31_EN, + + FLD_IRQ_NPE_COMB_EN, + FLD_IRQ_PM_TM_EN, + FLD_IRQ_EOC_EN, + +}; + +/******************************* plic_end ********************************************************************/ + + + +/******************************* flash_start *****************************************************************/ +/** + * @brief flash capacity definition + * Call flash_read_mid function to get the size of flash capacity. + * Example is as follows: + * unsigned char temp_buf[4]; + * flash_read_mid(temp_buf); + * The value of temp_buf[2] reflects flash capacity. + */ +typedef enum { + FLASH_CAPACITY_64K = 0x10, + FLASH_CAPACITY_128K = 0x11, + FLASH_CAPACITY_256K = 0x12, + FLASH_CAPACITY_512K = 0x13, + FLASH_CAPACITY_1M = 0x14, + FLASH_CAPACITY_2M = 0x15, + FLASH_CAPACITY_4M = 0x16, + FLASH_CAPACITY_8M = 0x17, +} Flash_CapacityDef; +void flash_set_capacity(Flash_CapacityDef flash_cap); +Flash_CapacityDef flash_get_capacity(void); + +/******************************* flash_end *******************************************************************/ + + + +/******************************* usb_end *********************************************************************/ +#define reg_usb_irq REG_ADDR8(0x100839) +/******************************* usb_end *********************************************************************/ + + + +/******************************* core_start ******************************************************************/ +#define SUPPORT_PFT_ARCH 0 +/******************************* core_end ********************************************************************/ + + + +/******************************* uart_start ******************************************************************/ +_attribute_ram_code_ void uart_receive_dma_set(dma_chn_e chn, unsigned char * addr,unsigned int rev_size); + +void uart0_init(unsigned int baudrate); +/******************************* uart_end ********************************************************************/ + + +#endif /* DRIVERS_B91_EXT_MISC_H_ */ diff --git a/b91/b91m_ble_sdk/drivers/B91/ext_driver/ext_pm.h b/b91/b91m_ble_sdk/drivers/B91/ext_driver/ext_pm.h new file mode 100755 index 0000000..3597953 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/ext_driver/ext_pm.h @@ -0,0 +1,270 @@ +/******************************************************************************************************** + * @file ext_pm.h + * + * @brief This is the header file for B91 + * + * @author BLE Group + * @date 2020 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#ifndef DRIVERS_B91_DRIVER_EXT_EXT_PM_H_ +#define DRIVERS_B91_DRIVER_EXT_EXT_PM_H_ + +#include "../pm.h" +#include "types.h" + +#ifndef PM_32k_RC_CALIBRATION_ALGORITHM_EN +#define PM_32k_RC_CALIBRATION_ALGORITHM_EN 1 +#endif + + + + + + +/** + * @brief available wake-up source for customer + */ +typedef enum { + //not available wake-up source for customer + PM_TIM_RECOVER_START = BIT(14), + PM_TIM_RECOVER_END = BIT(15), +}pm_tim_recover_wakeup_src_e; + + + +typedef pm_sleep_mode_e SleepMode_TypeDef; +typedef pm_sleep_wakeup_src_e SleepWakeupSrc_TypeDef; + + +typedef int (*suspend_handler_t)(void); +typedef void (*check_32k_clk_handler_t)(void); +typedef unsigned int (*pm_get_32k_clk_handler_t)(void); +typedef int (*cpu_pm_handler_t)(SleepMode_TypeDef sleep_mode, SleepWakeupSrc_TypeDef wakeup_src, unsigned int wakeup_tick); +typedef unsigned int (*pm_tim_recover_handler_t)(unsigned int); + +extern cpu_pm_handler_t cpu_sleep_wakeup; +extern suspend_handler_t func_before_suspend; +extern check_32k_clk_handler_t pm_check_32k_clk_stable; +extern pm_get_32k_clk_handler_t pm_get_32k_tick; +extern pm_tim_recover_handler_t pm_tim_recover; + +/** + * @brief gpio wakeup level definition + */ +typedef enum{ + Level_Low=0, + Level_High =1, +}pm_gpio_wakeup_Level_e; + + +/** + * @brief deepsleep wakeup by external xtal + */ +typedef struct{ + unsigned char ext_cap_en; //24xtal cap + unsigned char pad32k_en; + unsigned char pm_enter_en; + unsigned char rsvd; +}misc_para_t; + +extern _attribute_aligned_(4) misc_para_t blt_miscParam; + +#define SYS_NEED_REINIT_EXT32K BIT(1) +#define WAKEUP_STATUS_TIMER_CORE ( WAKEUP_STATUS_TIMER | WAKEUP_STATUS_CORE) +#define WAKEUP_STATUS_TIMER_PAD ( WAKEUP_STATUS_TIMER | WAKEUP_STATUS_PAD) + + + +void bls_pm_registerFuncBeforeSuspend (suspend_handler_t func ); + +/** + * @brief analog register below can store infomation when MCU in deepsleep mode + * store your information in these ana_regs before deepsleep by calling analog_write function + * when MCU wakeup from deepsleep, read the information by by calling analog_read function + * Reset these analog registers only by power cycle + */ +#define DEEP_ANA_REG0 0x39 //initial value =0x00 +#define DEEP_ANA_REG1 0x3a //initial value =0x00 +#define DEEP_ANA_REG2 0x3b //initial value =0x00 +#define DEEP_ANA_REG3 0x3c //initial value =0x00 +#define DEEP_ANA_REG4 0x3d //initial value =0x00 +#define DEEP_ANA_REG5 0x3e //initial value =0x00 +#define DEEP_ANA_REG6 0x3f //initial value =0x0f + +/** + * @brief these analog register can store data in deepsleep mode or deepsleep with SRAM retention mode. + * Reset these analog registers by watchdog, chip reset, RESET Pin, power cycle + */ + +#define DEEP_ANA_REG7 0x38 //initial value =0xff + +//ana3e system used, user can not use +#define SYS_DEEP_ANA_REG PM_ANA_REG_POWER_ON_CLR_BUF0 + + +/** + * @brief This function serves to set the working mode of MCU based on 32k crystal,e.g. suspend mode, deepsleep mode, deepsleep with SRAM retention mode and shutdown mode. + * @param[in] sleep_mode - sleep mode type select. + * @param[in] wakeup_src - wake up source select. + * @param[in] wakeup_tick - the time of short sleep, which means MCU can sleep for less than 5 minutes. + * @return indicate whether the cpu is wake up successful. + */ +int cpu_sleep_wakeup_32k_rc(SleepMode_TypeDef sleep_mode, SleepWakeupSrc_TypeDef wakeup_src, unsigned int wakeup_tick); + +/** + * @brief This function serves to set the working mode of MCU based on 32k crystal,e.g. suspend mode, deepsleep mode, deepsleep with SRAM retention mode and shutdown mode. + * @param[in] sleep_mode - sleep mode type select. + * @param[in] wakeup_src - wake up source select. + * @param[in] wakeup_tick - the time of short sleep, which means MCU can sleep for less than 5 minutes. + * @return indicate whether the cpu is wake up successful. + */ +int cpu_sleep_wakeup_32k_xtal(SleepMode_TypeDef sleep_mode, SleepWakeupSrc_TypeDef wakeup_src, unsigned int wakeup_tick); + + +void pm_sleep_start(void); + + +/** + * @brief This function serves to reboot chip. + * @param none. + * @return none. + */ + +void start_reboot(void); + +/** + * @brief This function serves to recover system timer from tick of internal 32k RC. + * @param none. + * @return none. + */ +unsigned int pm_tim_recover_32k_rc(unsigned int now_tick_32k); + +/** + * @brief This function serves to recover system timer from tick of external 32k crystal. + * @param none. + * @return none. + */ +unsigned int pm_tim_recover_32k_xtal(unsigned int now_tick_32k); + +/** + * @brief This function serves to get the 32k tick. + * @param none + * @return tick of 32k . + */ +extern unsigned int get_32k_tick(void); + +unsigned int clock_get_digital_32k_tick(void); + +/** + * @brief This function serves to determine whether wake up source is internal 32k RC. + * @param[in] none. + * @return none. + */ +static inline void blc_pm_select_internal_32k_crystal(void) +{ + cpu_sleep_wakeup = cpu_sleep_wakeup_32k_rc; + pm_tim_recover = pm_tim_recover_32k_rc; + + blt_miscParam.pm_enter_en = 1; // allow enter pm, 32k rc does not need to wait for 32k clk to be stable +} + +extern void check_32k_clk_stable(void); + +/** + * @brief This function serves to determine whether wake up source is external 32k RC. + * @param[in] none. + * @return none. + */ +static inline void blc_pm_select_external_32k_crystal(void) +{ + cpu_sleep_wakeup = cpu_sleep_wakeup_32k_xtal; + pm_check_32k_clk_stable = check_32k_clk_stable; + pm_tim_recover = pm_tim_recover_32k_xtal; + pm_get_32k_tick = get_32k_tick; + blt_miscParam.pad32k_en = 1; // set '1': 32k clk src use external 32k crystal +} + + + + +/** + * @brief This function servers to wake up the cpu from sleep mode. + * @param[in] sleep_mode - sleep mode type select. + * @param[in] wakeup_src - wake up source select. + * @param[in] wakeup_tick - the time of sleep,unit is 31.25us,1ms = 32. + * @return indicate whether the cpu is wake up successful. + */ +int cpu_long_sleep_wakeup_32k_rc(SleepMode_TypeDef sleep_mode, SleepWakeupSrc_TypeDef wakeup_src, unsigned int wakeup_tick); + +/** + * @brief This function serves to determine whether mcu is waked up from deep retention. + * @param[in] none. + * @return 1- yes , 0- no. + */ +static inline int pm_is_MCU_deepRetentionWakeup(void) +{ + return (g_pm_status_info.mcu_status & MCU_STATUS_DEEPRET_BACK); +} + +/** + * @brief This function serves to determine whether mcu is waked up by pad. + * @param[in] none. + * @return 1- yes , 0- no. + */ +static inline int pm_is_deepPadWakeup(void) +{ + return g_pm_status_info.is_pad_wakeup; +} + +/** + * @brief This function serves to get the status of mcu. + * @param[in] none. + * @return mcu_status. + */ +static inline int pm_get_mcu_status(void) +{ + return g_pm_status_info.mcu_status; +} + +#define cpu_set_gpio_wakeup pm_set_gpio_wakeup + + +static inline unsigned int pm_get_latest_offset_cal_time(void) +{ + return pmcd.offset_cal_tick; +} + +/********************************** Internal APIs (not for user)***************************************************/ +extern unsigned char tl_24mrc_cal; +extern unsigned int g_pm_tick_32k_calib; +extern unsigned int g_pm_tick_cur; +extern unsigned int g_pm_tick_32k_cur; +extern unsigned char g_pm_long_suspend; +extern unsigned int g_pm_multi_addr; + +extern unsigned int g_sleep_32k_rc_cnt; +extern unsigned int g_sleep_stimer_tick; + +extern unsigned int ota_program_bootAddr; +extern unsigned int ota_program_offset; + + +#define PM_MIN_SLEEP_US 1500 //eagle + + +#endif /* DRIVERS_B91_DRIVER_EXT_EXT_PM_H_ */ diff --git a/b91/b91m_ble_sdk/drivers/B91/ext_driver/ext_rf.h b/b91/b91m_ble_sdk/drivers/B91/ext_driver/ext_rf.h new file mode 100755 index 0000000..d338629 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/ext_driver/ext_rf.h @@ -0,0 +1,366 @@ +/******************************************************************************************************** + * @file ext_rf.h + * + * @brief This is the header file for B91 + * + * @author BLE Group + * @date 2020 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#ifndef DRIVERS_B91_DRIVER_EXT_EXT_RF_H_ +#define DRIVERS_B91_DRIVER_EXT_EXT_RF_H_ + +#include "compiler.h" +#include "types.h" + +#define DMA_RFRX_LEN_HW_INFO 0 // 826x: 8 +#define DMA_RFRX_OFFSET_HEADER 4 // 826x: 12 +#define DMA_RFRX_OFFSET_RFLEN 5 // 826x: 13 +#define DMA_RFRX_OFFSET_DATA 6 // 826x: 14 + +#define DMA_RFRX_OFFSET_CRC24(p) (p[DMA_RFRX_OFFSET_RFLEN]+6) //data len:3 +#define DMA_RFRX_OFFSET_TIME_STAMP(p) (p[DMA_RFRX_OFFSET_RFLEN]+9) //data len:4 +#define DMA_RFRX_OFFSET_FREQ_OFFSET(p) (p[DMA_RFRX_OFFSET_RFLEN]+13) //data len:2 +#define DMA_RFRX_OFFSET_RSSI(p) (p[DMA_RFRX_OFFSET_RFLEN]+15) //data len:1, signed + +#define RF_BLE_RF_PAYLOAD_LENGTH_OK(p) (p[5] <= reg_rf_rxtmaxlen) +#define RF_BLE_RF_PACKET_CRC_OK(p) ((p[p[5]+5+11] & 0x01) == 0x0) +#define RF_BLE_PACKET_VALIDITY_CHECK(p) (RF_BLE_RF_PAYLOAD_LENGTH_OK(p) && RF_BLE_RF_PACKET_CRC_OK(p)) + + + +typedef enum { + RF_ACC_CODE_TRIGGER_AUTO = BIT(0), /**< auto trigger */ + RF_ACC_CODE_TRIGGER_MANU = BIT(1), /**< manual trigger */ +} rf_acc_trigger_mode; + + + + +extern signed char ble_txPowerLevel; + +_attribute_ram_code_ void ble_rf_set_rx_dma(unsigned char *buff, unsigned char fifo_byte_size); + +_attribute_ram_code_ void ble_rf_set_tx_dma(unsigned char fifo_dep, unsigned char fifo_byte_size); + +_attribute_ram_code_ void ble_tx_dma_config(void); + +_attribute_ram_code_ void ble_rx_dma_config(void); + +void rf_drv_ble_init(void); + +/** + * @brief This function serves to settle adjust for RF Tx.This function for adjust the differ time + * when rx_dly enable. + * @param txstl_us - adjust TX settle time. + * @return none + */ +static inline void rf_tx_settle_adjust(unsigned short txstl_us) +{ + REG_ADDR16(0x80140a04) = txstl_us; +} + +/** +* @brief This function serves to reset RF BaseBand +* @param[in] none. +* @return none. +*/ +static inline void rf_reset_baseband(void) +{ + REG_ADDR8(0x801404e3) = 0; //rf_reset_baseband,rf reg need re-setting + REG_ADDR8(0x801404e3) = BIT(0); //release reset signal +} + +/** + * @brief This function serves to set RF access code value. + * @param[in] ac - the address value. + * @return none + */ +static inline void rf_set_ble_access_code_value (unsigned int ac) +{ + write_reg32 (0x80140808, ac); +} + +/** + * @brief This function serves to set RF access code. + * @param[in] p - the address to access. + * @return none + */ +static inline void rf_set_ble_access_code (unsigned char *p) +{ + write_reg32 (0x80140808, p[3] | (p[2]<<8) | (p[1]<<16) | (p[0]<<24)); +} + +/** + * @brief This function serves to reset function for RF. + * @param none + * @return none + *******************need driver change + */ +static inline void reset_sn_nesn(void) +{ + REG_ADDR8(0x80140a01) = 0x01; +} + +/** + * @brief This function serves to set RF access code advantage. + * @param none. + * @return none. + */ +static inline void rf_set_ble_access_code_adv (void) +{ + write_reg32 (0x0140808, 0xd6be898e); +} + + +/** + * @brief This function serves to triggle accesscode in coded Phy mode. + * @param none. + * @return none. + */ +static inline void rf_trigle_codedPhy_accesscode(void) +{ + write_reg8(0x140c25,read_reg8(0x140c25)|0x01); +} + +/** + * @brief This function performs to enable RF Tx. + * @param[in] none. + * @return none. + */ +static inline void rf_ble_tx_on () +{ + write_reg8 (0x80140a02, 0x45 | BIT(4)); // TX enable +} + +/** + * @brief This function performs to done RF Tx. + * @param[in] none. + * @return none. + */ +static inline void rf_ble_tx_done () +{ + write_reg8 (0x80140a02, 0x45); +} + + +/** + * @brief This function serves to set RX first timeout value. + * @param[in] tm - timeout, unit: uS. + * @return none. + */ +static inline void rf_set_1st_rx_timeout(unsigned int tm) +{ + reg_rf_ll_rx_fst_timeout = tm; +} + + +/** + * @brief This function serves to set RX timeout value. + * @param[in] tm - timeout, unit: uS, range: 0 ~ 0xfff + * @return none. + */ +static inline void rf_ble_set_rx_timeout(u16 tm) +{ + reg_rf_rx_timeout = tm; +} + + + +typedef enum{ + FSM_BTX = 0x81, + FSM_BRX = 0x82, + FSM_STX = 0x85, + FSM_SRX = 0x86, + FSM_TX2RX = 0x87, + FSM_RX2TX = 0x88, +}fsm_mode_e; + + +/** + * @brief This function serves to RF trigger RF state machine. + * @param[in] mode - FSM mode. + * @param[in] tx_addr - DMA TX buffer, if not TX, must be "NULL" + * @param[in] tick - FAM Trigger tick. + * @return none. + */ +void rf_start_fsm(fsm_mode_e mode, void* tx_addr, unsigned int tick); + + +#define rf_set_ble_channel rf_set_ble_chn + + +/** + * @brief This function performs to switch PHY test mode. + * @param[in] mode - PHY mode + * @return none. + */ +void rf_switchPhyTestMode(rf_mode_e mode); + + + + + + + + + + +//TODO: merge into driver +#define STOP_RF_STATE_MACHINE ( REG_ADDR8(0x80140a00) = 0x80 ) +enum{ + FLD_RF_SN = BIT(0), +}; + + + +/** + * @brief This function serves to enable zb_rt interrupt source. + * @return none + */ +static inline void zb_rt_irq_enable(void) +{ + plic_interrupt_enable(IRQ15_ZB_RT); +} + + + + + +#if RF_RX_SHORT_MODE_EN//open rx dly +//TX settle time + + #define LL_SCAN_TX_SETTLE 63 + #define LL_SCANRSP_TX_SETTLE 78 //63+15=78 + + + //TODO: need debug + #define LL_TX_STL_TIFS_1M 63 + #define LL_TX_STL_TIFS_2M (LL_TX_STL_TIFS_1M + 24) + #define LL_TX_STL_TIFS_CODED (LL_TX_STL_TIFS_1M + 40) + + + #define LL_TX_STL_ADV_1M 84 + #define LL_TX_STL_ADV_2M 115 + #define LL_TX_STL_ADV_CODED 124 + + #define LL_SLAVE_TX_SETTLE 86 + #define LL_SLAVE_TX_STL_2M 117 + #define LL_SLAVE_TX_STL_CODED 125 + + #define LL_MASTER_TX_SETTLE 87 + #define LL_MASTER_TX_STL_2M 117 + #define LL_MASTER_TX_STL_CODED 125 + +#else// close rx dly + #error "add code here" +#endif + + +/* AD convert delay : timing cost on RF analog to digital convert signal process: + * Eagle 1M: 20uS 2M: 10uS; 500K(S2): 14uS 125K(S8): 14uS + * Jaguar 1M: 20uS 2M: 10uS; 500K(S2): 14uS 125K(S8): 14uS + */ +#define AD_CONVERT_DLY_1M 20 +#define AD_CONVERT_DLY_2M 10 +#define AD_CONVERT_DLY_CODED 14 + + +static inline void rf_ble_set_1m_phy(void) +{ + write_reg8(0x140e3d,0x61); + write_reg32(0x140e20,0x23200a16); + write_reg8(0x140c20,0xc4); + write_reg8(0x140c22,0x00); + write_reg8(0x140c4d,0x01); + write_reg8(0x140c4e,0x1e); + write_reg16(0x140c36,0x0eb7); + write_reg16(0x140c38,0x71c4); + write_reg8(0x140c73,0x01); + #if RF_RX_SHORT_MODE_EN + write_reg8(0x140c79,0x38); //default:0x00;RX_DIS_PDET_BLANK + #else + write_reg8(0x140c79,0x08); + #endif + write_reg16(0x140cc2,0x4b39); + write_reg32(0x140cc4,0x796e6256); + write_reg32(0x140800,0x4446081f); + write_reg16(0x140804,0x04f5); +} + + +static inline void rf_ble_set_2m_phy(void) +{ + write_reg8(0x140e3d,0x41); + write_reg32(0x140e20,0x26432a06); + write_reg8(0x140c20,0xc4); + write_reg8(0x140c22,0x01); + write_reg8(0x140c4d,0x01); + write_reg8(0x140c4e,0x1e); + write_reg16(0x140c36,0x0eb7); + write_reg16(0x140c38,0x71c4); + write_reg8(0x140c73,0x01); + #if RF_RX_SHORT_MODE_EN + write_reg8(0x140c79,0x30); //default:0x00;RX_DIS_PDET_BLANK + #else + write_reg8(0x140c79,0x00); + #endif + write_reg16(0x140cc2,0x4c3b); + write_reg32(0x140cc4,0x7a706458); + write_reg32(0x140800,0x4446081f); + write_reg16(0x140804,0x04e5); +} + + + + +static inline void rf_ble_set_coded_phy_common(void) +{ + write_reg8(0x140e3d,0x61); + write_reg32(0x140e20,0x23200a16); + write_reg8(0x140c20,0xc5); + write_reg8(0x140c22,0x00); + write_reg8(0x140c4d,0x01); + write_reg8(0x140c4e,0xf0); + write_reg16(0x140c38,0x7dc8); + write_reg8(0x140c73,0x21); + #if RF_RX_SHORT_MODE_EN + write_reg8(0x140c79,0x30); + #else + write_reg8(0x140c79,0x00); + #endif + write_reg16(0x140cc2,0x4836); + write_reg32(0x140cc4,0x796e6254); + write_reg32(0x140800,0x444a081f); +} + + +static inline void rf_ble_set_coded_phy_s2(void) +{ + write_reg16(0x140c36,0x0cee); + write_reg16(0x140804,0xa4f5); +} + + +static inline void rf_ble_set_coded_phy_s8(void) +{ + write_reg16(0x140c36,0x0cf6); + write_reg16(0x140804,0xb4f5); +} + + +#endif /* DRIVERS_B91_DRIVER_EXT_EXT_RF_H_ */ diff --git a/b91/b91m_ble_sdk/drivers/B91/ext_driver/software_pa.c b/b91/b91m_ble_sdk/drivers/B91/ext_driver/software_pa.c new file mode 100755 index 0000000..edc7f61 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/ext_driver/software_pa.c @@ -0,0 +1,70 @@ +/******************************************************************************************************** + * @file software_pa.h + * + * @brief This is the header file for B91 + * + * @author BLE Group + * @date 2020 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "compiler.h" +#include "software_pa.h" +#include "../gpio.h" + + +_attribute_data_retention_sec_ rf_pa_callback_t blc_rf_pa_cb = 0; + +_attribute_ram_code_ +void app_rf_pa_handler(int type) +{ +#if(PA_ENABLE) + if(type == PA_TYPE_TX_ON){ + gpio_set_output_en(PA_RXEN_PIN, 0); + gpio_write(PA_RXEN_PIN, 0); + gpio_set_output_en(PA_TXEN_PIN, 1); + gpio_write(PA_TXEN_PIN, 1); + } + else if(type == PA_TYPE_RX_ON){ + gpio_set_output_en(PA_TXEN_PIN, 0); + gpio_write(PA_TXEN_PIN, 0); + gpio_set_output_en(PA_RXEN_PIN, 1); + gpio_write(PA_RXEN_PIN, 1); + } + else{ + gpio_set_output_en(PA_RXEN_PIN, 0); + gpio_write(PA_RXEN_PIN, 0); + gpio_set_output_en(PA_TXEN_PIN, 0); + gpio_write(PA_TXEN_PIN, 0); + } +#endif +} + + +void rf_pa_init(void) +{ +#if(PA_ENABLE) + gpio_set_func(PA_TXEN_PIN, AS_GPIO); + gpio_set_output_en(PA_TXEN_PIN, 0); + gpio_write(PA_TXEN_PIN, 0); + + gpio_set_func(PA_RXEN_PIN, AS_GPIO); + gpio_set_output_en(PA_RXEN_PIN, 0); + gpio_write(PA_RXEN_PIN, 0); + + blc_rf_pa_cb = app_rf_pa_handler; +#endif +} + diff --git a/b91/b91m_ble_sdk/drivers/B91/ext_driver/software_pa.h b/b91/b91m_ble_sdk/drivers/B91/ext_driver/software_pa.h new file mode 100755 index 0000000..b0dd4f7 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/ext_driver/software_pa.h @@ -0,0 +1,59 @@ +/******************************************************************************************************** + * @file software_pa.h + * + * @brief This is the header file for B91 + * + * @author BLE Group + * @date 2020 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#ifndef BLT_PA_H_ +#define BLT_PA_H_ + +#include "../gpio.h" + + +#ifndef PA_ENABLE +#define PA_ENABLE 0 +#endif + + + +#ifndef PA_TXEN_PIN +#define PA_TXEN_PIN GPIO_PB2 +#endif + +#ifndef PA_RXEN_PIN +#define PA_RXEN_PIN GPIO_PB3 +#endif + + + +#define PA_TYPE_OFF 0 +#define PA_TYPE_TX_ON 1 +#define PA_TYPE_RX_ON 2 + + +typedef void (*rf_pa_callback_t)(int type); +extern rf_pa_callback_t blc_rf_pa_cb; + + + +void rf_pa_init(void); + + +#endif /* BLT_PA_H_ */ diff --git a/b91/b91m_ble_sdk/drivers/B91/flash.c b/b91/b91m_ble_sdk/drivers/B91/flash.c new file mode 100755 index 0000000..4bac631 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/flash.c @@ -0,0 +1,755 @@ +/******************************************************************************************************** + * @file flash.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "flash.h" +#include "mspi.h" +#include "plic.h" +#include "timer.h" +#include "sys.h" +#include "core.h" +#include "stimer.h" +#include "ext_driver/ext_misc.h" + +#define RAMCODE_OPTIMIZE_UNUSED_FLASH_API_NOT_IMPLEMENT 1 + +_attribute_data_retention_sec_ volatile unsigned char flash_cnt = 1; + +static preempt_config_t s_flash_preempt_config = +{ + .preempt_en =0, + .threshold =1, +}; + +/** + * @brief This function serves to set priority threshold. when the interrupt priority > Threshold flash process will disturb by interrupt. + * @param[in] preempt_en - 1 can disturb by interrupt, 0 can disturb by interrupt. + * @param[in] threshold - priority Threshold. + * @return none. + */ +void flash_plic_preempt_config(unsigned char preempt_en,unsigned char threshold) +{ + s_flash_preempt_config.preempt_en=preempt_en; + s_flash_preempt_config.threshold=threshold; +} + +/** + * @brief This function to determine whether the flash is busy.. + * @return 1:Indicates that the flash is busy. 0:Indicates that the flash is free + */ +static inline int flash_is_busy(void) +{ + return mspi_read() & 0x01; // the busy bit, pls check flash spec +} + +/** + * @brief This function serves to set flash write command.This function interface is only used internally by flash, + * and is currently included in the H file for compatibility with other SDKs. When using this interface, + * please ensure that you understand the precautions of flash before using it. + * @param[in] cmd - set command. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void flash_send_cmd(unsigned char cmd) +{ + mspi_high(); + CLOCK_DLY_10_CYC; + mspi_low(); + mspi_write(cmd); + mspi_wait(); +} + +/** + * @brief This function serves to send flash address. + * @param[in] addr - the flash address. + * @return none. + */ +_attribute_ram_code_sec_noinline_ static void flash_send_addr(unsigned int addr) +{ + mspi_write((unsigned char)(addr>>16)); + mspi_wait(); + mspi_write((unsigned char)(addr>>8)); + mspi_wait(); + mspi_write((unsigned char)(addr)); + mspi_wait(); +} + +/** + * @brief This function serves to wait flash done.(make this a asynchorous version). + * @return none. + */ +_attribute_ram_code_sec_noinline_ static void flash_wait_done(void) +{ + flash_send_cmd(FLASH_READ_STATUS_CMD); + + int i; + for(i = 0; i < 10000000; ++i){ + if(!flash_is_busy()){ + flash_cnt++; + break; + } + } + mspi_high(); +} + +/** + * @brief This function serves to erase a sector. + * @param[in] addr - the start address of the sector needs to erase. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void flash_erase_sector_ram(unsigned long addr) +{ +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 1; +#else + unsigned int r= core_interrupt_disable(); +#endif + mspi_stop_xip(); + flash_send_cmd(FLASH_WRITE_ENABLE_CMD); + flash_send_cmd(FLASH_SECT_ERASE_CMD); + flash_send_addr(addr); + mspi_high(); + flash_wait_done(); + CLOCK_DLY_5_CYC; +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 0; +#else + core_restore_interrupt(r); +#endif +} +_attribute_text_sec_ void flash_erase_sector(unsigned long addr) +{ + __asm__("csrci mmisc_ctl,8"); //disable BTB + flash_erase_sector_ram(addr); + __asm__("csrsi mmisc_ctl,8"); //enable BTB +} + +/** + * @brief This function writes the buffer's content to a page. + * @param[in] addr - the start address of the page. + * @param[in] len - the length(in byte) of content needs to write into the page. + * @param[in] buf - the start address of the content needs to write into. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void flash_write_page_ram(unsigned long addr, unsigned long len, unsigned char *buf) +{ +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 1; +#else + unsigned int r= core_interrupt_disable();//???irq_disable(); +#endif + mspi_stop_xip(); + flash_send_cmd(FLASH_WRITE_ENABLE_CMD); + flash_send_cmd(FLASH_WRITE_CMD); + flash_send_addr(addr); + + unsigned int i; + for(i = 0; i < len; ++i){ + mspi_write(buf[i]); /* write data */ + mspi_wait(); + } + mspi_high(); + flash_wait_done(); + CLOCK_DLY_5_CYC; + +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 0; +#else + core_restore_interrupt(r);//???irq_restore(r); +#endif +} +_attribute_text_sec_ void flash_write_page(unsigned long addr, unsigned long len, unsigned char *buf) +{ + unsigned int ns = PAGE_SIZE - (addr & 0xff); + int nw = 0; + + do{ + nw = len > ns ? ns : len; + __asm__("csrci mmisc_ctl,8"); //disable BTB + flash_write_page_ram(addr,nw,buf); + __asm__("csrsi mmisc_ctl,8"); //enable BTB + ns = PAGE_SIZE; + addr += nw; + buf += nw; + len -= nw; + }while(len > 0); +} + +/** + * @brief This function reads the content from a page to the buf. + * @param[in] addr - the start address of the page. + * @param[in] len - the length(in byte) of content needs to read out from the page. + * @param[out] buf - the start address of the buffer. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void flash_read_page_ram(unsigned long addr, unsigned long len, unsigned char *buf) +{ +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 1; +#else + unsigned int r= core_interrupt_disable();//???irq_disable(); +#endif + mspi_stop_xip(); + flash_send_cmd(FLASH_READ_CMD); + flash_send_addr(addr); + + mspi_write(0x00); /* dummy, to issue clock */ + mspi_wait(); + mspi_fm_rd_en(); /* auto mode, mspi_get() automatically triggers mspi_write(0x00) once. */ + mspi_wait(); + /* get data */ + for(unsigned int i = 0; i < len; ++i){ + *buf++ = mspi_get(); + mspi_wait(); + } + mspi_fm_rd_dis(); /* off read auto mode */ + mspi_high(); + CLOCK_DLY_5_CYC; +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 0; +#else + core_restore_interrupt(r);//???irq_restore(r); +#endif +} +_attribute_text_sec_ void flash_read_page(unsigned long addr, unsigned long len, unsigned char *buf) +{ + __asm__("csrci mmisc_ctl,8"); //disable BTB + flash_read_page_ram(addr,len,buf); + __asm__("csrsi mmisc_ctl,8"); //enable BTB +} + + + +/** + * @brief This function serves to erase a chip. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void flash_erase_chip_ram(void) +{ +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 1; +#else + unsigned int r= core_interrupt_disable(); +#endif + mspi_stop_xip(); + flash_send_cmd(FLASH_WRITE_ENABLE_CMD); + flash_send_cmd(FLASH_CHIP_ERASE_CMD); + mspi_high(); + flash_wait_done(); + CLOCK_DLY_5_CYC; +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 0; +#else + core_restore_interrupt(r); +#endif +} +_attribute_text_sec_ void flash_erase_chip(void) +{ + __asm__("csrci mmisc_ctl,8"); //disable BTB + flash_erase_chip_ram(); + __asm__("csrsi mmisc_ctl,8"); //enable BTB +} + +#if (!RAMCODE_OPTIMIZE_UNUSED_FLASH_API_NOT_IMPLEMENT) +/** + * @brief This function serves to erase a page(256 bytes). + * @param[in] addr - the start address of the page needs to erase. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void flash_erase_page_ram(unsigned int addr) +{ +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 1; +#else + unsigned int r= core_interrupt_disable(); +#endif + + mspi_stop_xip(); + flash_send_cmd(FLASH_WRITE_ENABLE_CMD); + flash_send_cmd(FLASH_PAGE_ERASE_CMD); + flash_send_addr(addr); + mspi_high(); + flash_wait_done(); + CLOCK_DLY_5_CYC; +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 0; +#else + core_restore_interrupt(r);//???irq_restore(r); +#endif +} +_attribute_text_sec_ void flash_erase_page(unsigned int addr) +{ + __asm__("csrci mmisc_ctl,8"); //disable BTB + flash_erase_page_ram(addr); + __asm__("csrsi mmisc_ctl,8"); //enable BTB +} + +/** + * @brief This function serves to erase a block(32k). + * @param[in] addr - the start address of the block needs to erase. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void flash_erase_32kblock_ram(unsigned int addr) +{ +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 1; +#else + unsigned int r= core_interrupt_disable(); +#endif + + mspi_stop_xip(); + flash_send_cmd(FLASH_WRITE_ENABLE_CMD); + flash_send_cmd(FLASH_32KBLK_ERASE_CMD); + flash_send_addr(addr); + mspi_high(); + flash_wait_done(); + CLOCK_DLY_5_CYC; +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 0; +#else + core_restore_interrupt(r);//???irq_restore(r); +#endif +} +_attribute_text_sec_ void flash_erase_32kblock(unsigned int addr) +{ + __asm__("csrci mmisc_ctl,8"); //disable BTB + flash_erase_32kblock_ram(addr); + __asm__("csrsi mmisc_ctl,8"); //enable BTB +} + +/** + * @brief This function serves to erase a block(64k). + * @param[in] addr - the start address of the block needs to erase. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void flash_erase_64kblock_ram(unsigned int addr) +{ +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 1; +#else + unsigned int r= core_interrupt_disable(); +#endif + + mspi_stop_xip(); + flash_send_cmd(FLASH_WRITE_ENABLE_CMD); + flash_send_cmd(FLASH_64KBLK_ERASE_CMD); + flash_send_addr(addr); + mspi_high(); + flash_wait_done(); + CLOCK_DLY_5_CYC; +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 0; +#else + core_restore_interrupt(r);//???irq_restore(r); +#endif +} +_attribute_text_sec_ void flash_erase_64kblock(unsigned int addr) +{ + __asm__("csrci mmisc_ctl,8"); //disable BTB + flash_erase_64kblock_ram(addr); + __asm__("csrsi mmisc_ctl,8"); //enable BTB +} + +/** + * @brief This function write the status of flash. + * @param[in] data - the value of status. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void flash_write_status_ram(unsigned short data) +{ +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 1; +#else + unsigned int r= core_interrupt_disable(); +#endif + mspi_stop_xip(); + flash_send_cmd(FLASH_WRITE_ENABLE_CMD); + flash_send_cmd(FLASH_WRITE_STATUS_CMD); + mspi_write((unsigned char)data); + mspi_wait(); + mspi_write((unsigned char)(data>>8)); + mspi_wait(); + mspi_high(); + flash_wait_done(); + mspi_high(); + CLOCK_DLY_5_CYC; +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 0; +#else + core_restore_interrupt(r);//???irq_restore(r); +#endif +} +_attribute_text_sec_ void flash_write_status(unsigned short data) +{ + __asm__("csrci mmisc_ctl,8"); //disable BTB + flash_write_status_ram(data); + __asm__("csrsi mmisc_ctl,8"); //enable BTB +} + +/** + * @brief This function reads the status of flash. + * @return the value of status. + */ +_attribute_ram_code_sec_noinline_ unsigned short flash_read_status_ram(void) +{ + unsigned short status = 0; +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 1; +#else + unsigned int r= core_interrupt_disable(); +#endif + + mspi_stop_xip(); + flash_send_cmd(FLASH_READ_STATUS_1_CMD); /* get high 8 bit status */ + status = (mspi_read()<<8); + mspi_high(); + flash_send_cmd(FLASH_READ_STATUS_CMD); /* get low 8 bit status */ + status |= mspi_read(); + mspi_high(); + CLOCK_DLY_5_CYC; + +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 0; +#else + core_restore_interrupt(r);//???irq_restore(r); +#endif + return status; +} +_attribute_text_sec_ unsigned short flash_read_status(void) +{ + __asm__("csrci mmisc_ctl,8"); //disable BTB + unsigned short status = flash_read_status_ram(); + __asm__("csrsi mmisc_ctl,8"); //enable BTB + return status; +} + +/** + * @brief Deep Power Down mode to put the device in the lowest consumption mode + * it can be used as an extra software protection mechanism,while the device + * is not in active use,since in the mode, all write,Program and Erase commands + * are ignored,except the Release from Deep Power-Down and Read Device ID(RDI) + * command.This release the device from this mode + * @return none. + */ +_attribute_ram_code_sec_noinline_ void flash_deep_powerdown_ram(void) +{ +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 1; +#else + unsigned int r= core_interrupt_disable(); +#endif + + mspi_stop_xip(); + flash_send_cmd(FLASH_POWER_DOWN); + mspi_high(); + delay_us(1); + CLOCK_DLY_5_CYC; + +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 0; +#else + core_restore_interrupt(r);//???irq_restore(r); +#endif +} +_attribute_text_sec_ void flash_deep_powerdown(void) +{ + __asm__("csrci mmisc_ctl,8"); //disable BTB + flash_deep_powerdown_ram(); + __asm__("csrsi mmisc_ctl,8"); //enable BTB +} + +/** + * @brief The Release from Power-Down or High Performance Mode/Device ID command is a + * Multi-purpose command.it can be used to release the device from the power-Down + * State or High Performance Mode or obtain the devices electronic identification + * (ID)number.Release from Power-Down will take the time duration of tRES1 before + * the device will resume normal operation and other command are accepted.The CS# + * pin must remain high during the tRES1(8us) time duration. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void flash_release_deep_powerdown_ram(void) +{ +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 1; +#else + unsigned int r= core_interrupt_disable(); +#endif + + mspi_stop_xip(); + flash_send_cmd(FLASH_POWER_DOWN_RELEASE); + mspi_high(); + flash_wait_done(); + mspi_high(); + CLOCK_DLY_5_CYC; + +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 0; +#else + core_restore_interrupt(r);//???irq_restore(r); +#endif +} +_attribute_text_sec_ void flash_release_deep_powerdown(void) +{ + __asm__("csrci mmisc_ctl,8"); //disable BTB + flash_release_deep_powerdown_ram(); + __asm__("csrsi mmisc_ctl,8"); //enable BTB +} + +#endif + +/** + * @brief This function serves to read MID of flash(MAC id). Before reading UID of flash, + * you must read MID of flash. and then you can look up the related table to select + * the idcmd and read UID of flash + * @param[in] buf - store MID of flash + * @return none. + */ +_attribute_ram_code_sec_noinline_ void flash_read_mid_ram(unsigned char *buf){ + + unsigned char j = 0; +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 1; +#else + unsigned int r= core_interrupt_disable(); +#endif + + mspi_stop_xip(); + flash_send_cmd(FLASH_GET_JEDEC_ID); + mspi_write(0x00); /* dummy, to issue clock */ + mspi_wait(); + mspi_fm_rd_en(); /* auto mode, mspi_get() automatically triggers mspi_write(0x00) once. */ + mspi_wait(); + + for(j = 0; j < 3; ++j){ + *buf++ = mspi_get(); + mspi_wait(); + } + mspi_fm_rd_dis(); /* off read auto mode */ + mspi_high(); + CLOCK_DLY_5_CYC; + +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 0; +#else + core_restore_interrupt(r);//???irq_restore(r); +#endif +} +_attribute_text_sec_ void flash_read_mid(unsigned char *buf){ + + __asm__("csrci mmisc_ctl,8"); //disable BTB + flash_read_mid_ram(buf); + __asm__("csrsi mmisc_ctl,8"); //enable BTB +} + +/** + * @brief This function serves to read UID of flash + * @param[in] idcmd - different flash vendor have different read-uid command. E.g: GD/PUYA:0x4B; XTX: 0x5A + * @param[in] buf - store UID of flash + * @return none. + */ +_attribute_ram_code_sec_noinline_ void flash_read_uid_ram(unsigned char idcmd,unsigned char *buf) +{ + unsigned char j = 0; +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 1; +#else + unsigned int r= core_interrupt_disable(); +#endif + + mspi_stop_xip(); + flash_send_cmd(idcmd); + if(idcmd==FLASH_GD_PUYA_READ_UID_CMD) //< GD/puya + { + flash_send_addr(0x00); + mspi_write(0x00); /* dummy, to issue clock */ + mspi_wait(); + } + else if (idcmd==FLASH_XTX_READ_UID_CMD) //< XTX + { + flash_send_addr(0x80); + mspi_write(0x00); /* dummy, to issue clock */ + mspi_wait(); + + } + mspi_write(0x00); /* dummy, to issue clock */ + mspi_wait(); + mspi_fm_rd_en(); /* auto mode, mspi_get() automatically triggers mspi_write(0x00) once. */ + mspi_wait(); + + for(j = 0; j < 16; ++j){ + *buf++ = mspi_get(); + mspi_wait(); + } + mspi_fm_rd_dis(); /* off read auto mode */ + mspi_high(); + CLOCK_DLY_5_CYC; + +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 0; +#else + core_restore_interrupt(r);//???irq_restore(r); +#endif +} +_attribute_text_sec_ void flash_read_uid(unsigned char idcmd,unsigned char *buf) +{ + __asm__("csrci mmisc_ctl,8"); //disable BTB + flash_read_uid_ram(idcmd,buf); + __asm__("csrsi mmisc_ctl,8"); //enable BTB +} + +/** + * @brief This function serves to read flash mid and uid,and check the correctness of mid and uid. + * @param[out] flash_mid - Flash Manufacturer ID + * @param[out] flash_uid - Flash Unique ID + * @return 0:error 1:ok + */ +_attribute_ram_code_sec_noinline_ int flash_read_mid_uid_with_check_ram( unsigned int *flash_mid ,unsigned char *flash_uid) +{ + unsigned char no_uid[16]={0x51,0x01,0x51,0x01,0x51,0x01,0x51,0x01,0x51,0x01,0x51,0x01,0x51,0x01,0x51,0x01}; + int i,f_cnt=0; + unsigned int mid; + + mspi_stop_xip(); + flash_read_mid((unsigned char*)&mid); + mid = mid&0xffff; + *flash_mid = mid; + // CMD MID + // GD25LD40C 0x4b 0x60c8 + // GD25LD05C 0x4b 0x60c8 + // P25Q40L 0x4b 0x6085 + // MD25D40DGIG 0x4b 0x4051 + if( (mid == 0x60C8) || (mid == 0x6085) ||(mid == 0x4051)){ + flash_read_uid(FLASH_GD_PUYA_READ_UID_CMD,(unsigned char *)flash_uid); + }else{ + return 0; + } + for(i=0;i<16;i++){ + if(flash_uid[i]==no_uid[i]){ + f_cnt++; + } + } + if(f_cnt==16){ //no uid flash + return 0; + + }else{ + return 1; + } + CLOCK_DLY_5_CYC; +} +_attribute_text_sec_ int flash_read_mid_uid_with_check( unsigned int *flash_mid ,unsigned char *flash_uid){ + + __asm__("csrci mmisc_ctl,8"); //disable BTB + int result = flash_read_mid_uid_with_check_ram(flash_mid,flash_uid); + __asm__("csrsi mmisc_ctl,8"); //enable BTB + return result; +} + + +#if (!RAMCODE_OPTIMIZE_UNUSED_FLASH_API_NOT_IMPLEMENT) +/** + * @brief This function serves to set the protection area of the flash. + * @param[in] type - flash type include Puya. + * @param[in] data - refer to Driver API Doc. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void flash_lock_ram(flash_type_e type , unsigned short data) +{ +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 1; +#else + unsigned int r= core_interrupt_disable(); +#endif + + mspi_stop_xip(); + flash_send_cmd(FLASH_WRITE_ENABLE_CMD); + flash_send_cmd(FLASH_WRITE_STATUS_CMD); + if(type == FLASH_TYPE_PUYA) + { + mspi_write((unsigned char)data); + mspi_wait(); + mspi_write((unsigned char)(data>>8));//16bit status + + } + mspi_wait(); + mspi_high(); + flash_wait_done(); + mspi_high(); + CLOCK_DLY_5_CYC; + +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 0; +#else + core_restore_interrupt(r);//???irq_restore(r); +#endif +} +_attribute_text_sec_ void flash_lock(flash_type_e type , unsigned short data) +{ + __asm__("csrci mmisc_ctl,8"); //disable BTB + flash_lock_ram(type,data); + __asm__("csrsi mmisc_ctl,8"); //enable BTB +} + +/** + * @brief This function serves to flash release protection. + * @param[in] type - flash type include Puya. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void flash_unlock_ram(flash_type_e type) +{ +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 1; +#else + unsigned int r= core_interrupt_disable(); +#endif + + mspi_stop_xip(); + flash_send_cmd(FLASH_WRITE_ENABLE_CMD); + flash_send_cmd(FLASH_WRITE_STATUS_CMD); + if(type == FLASH_TYPE_PUYA) + { + mspi_write(0); + mspi_wait(); + mspi_write(0);//16bit status + } + mspi_wait(); + mspi_high(); + flash_wait_done(); + mspi_high(); + CLOCK_DLY_5_CYC; +#if SUPPORT_PFT_ARCH + reg_irq_threshold = 0; +#else + core_restore_interrupt(r);//???irq_restore(r); +#endif +} +_attribute_text_sec_ void flash_unlock(flash_type_e type) +{ + __asm__("csrci mmisc_ctl,8"); //disable BTB + flash_unlock_ram(type); + __asm__("csrsi mmisc_ctl,8"); //enable BTB +} + +#endif + + + + + + diff --git a/b91/b91m_ble_sdk/drivers/B91/flash.h b/b91/b91m_ble_sdk/drivers/B91/flash.h new file mode 100755 index 0000000..f32885e --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/flash.h @@ -0,0 +1,232 @@ +/******************************************************************************************************** + * @file flash.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "mspi.h" +#include "compiler.h" + + +#define PAGE_SIZE 256 + +/** + * @brief flash command definition + */ +typedef enum +{ + FLASH_WRITE_STATUS_CMD = 0x01, + FLASH_WRITE_CMD = 0x02, + FLASH_READ_CMD = 0x03, + + FLASH_WRITE_DISABLE_CMD = 0x04, + FLASH_READ_STATUS_CMD = 0x05, + FLASH_WRITE_ENABLE_CMD = 0x06, + + FLASH_CHIP_ERASE_CMD = 0x60, //or 0xc7 + + FLASH_PES_CMD = 0x75, + FLASH_PER_CMD = 0x7A, + FLASH_QUAD_PAGE_PROGRAM_CMD = 0x32, + FLASH_READ_DEVICE_ID_CMD = 0x90, + + FLASH_FAST_READ_CMD = 0x0B, + FLASH_X2READ_CMD = 0xBB, + FLASH_DREAD_CMD = 0x3B, + FLASH_X4READ_CMD = 0xEB, + FLASH_QREAD_CMD = 0x6B, + + FLASH_SECT_ERASE_CMD = 0x20, //sector size = 4KBytes + FLASH_32KBLK_ERASE_CMD = 0x52, + FLASH_64KBLK_ERASE_CMD = 0xD8, + FLASH_GD_PUYA_READ_UID_CMD = 0x4B, //Flash Type = GD/PUYA + FLASH_XTX_READ_UID_CMD = 0x5A, //Flash Type = XTX + FLASH_PAGE_ERASE_CMD = 0x81, //caution: only P25Q40L support this function + + FLASH_POWER_DOWN = 0xB9, + FLASH_POWER_DOWN_RELEASE = 0xAB, + FLASH_GET_JEDEC_ID = 0x9F, + FLASH_READ_STATUS_1_CMD = 0x35, + + FLASH_VOLATILE_SR_WRITE_CMD = 0x50, + FLASH_SET_BURST_WITH_WRAP_CMD = 0x77, + FLASH_ENABLE_SO_TO_OUTPUT_CMD = 0x70, + FLASH_READ_DEVICE_ID_DUAL_CME = 0x92, + RLASH_READ_DEVICE_ID_QUAD_CMD = 0x94, + FLASH_ERASE_SECURITY_REGISTERS_CMD = 0x44, + FLASH_PROGRAM_SECURITY_REGISTERS_CMD = 0x42, + FLASH_READ_SECURITY_REGISTERS_CMD = 0x48, + FLASH_ENABLE_RESET_CMD = 0x99, + + FLASH_ENABLE_RESET = 0x66, + FLASH_DISABLE_SO_TO_OUTPUT = 0x80, +}flash_command_e; + +/** + * @brief flash type definition + */ +typedef enum{ + FLASH_TYPE_PUYA = 0, +}flash_type_e; + +/** + * @brief This function serves to erase a page(256 bytes). + * @param[in] addr - the start address of the page needs to erase. + * @return none. + */ +_attribute_text_sec_ void flash_erase_page(unsigned int addr); + +/** + * @brief This function serves to erase a sector. + * @param[in] addr - the start address of the sector needs to erase. + * @return none. + */ +_attribute_text_sec_ void flash_erase_sector(unsigned long addr); + +/** + * @brief This function serves to erase a block(32k). + * @param[in] addr - the start address of the block needs to erase. + * @return none. + */ +_attribute_text_sec_ void flash_erase_32kblock(unsigned int addr); + +/** + * @brief This function serves to erase a block(64k). + * @param[in] addr - the start address of the block needs to erase. + * @return none. + */ +_attribute_text_sec_ void flash_erase_64kblock(unsigned int addr); + +/** + * @brief This function serves to erase a chip. + * @return none. + */ +_attribute_text_sec_ void flash_erase_chip(void); + +/** + * @brief This function writes the buffer's content to a page. + * @param[in] addr - the start address of the page. + * @param[in] len - the length(in byte) of content needs to write into the page. + * @param[in] buf - the start address of the content needs to write into. + * @return none. + */ +_attribute_text_sec_ void flash_write_page(unsigned long addr, unsigned long len, unsigned char *buf); + +/** + * @brief This function reads the content from a page to the buf. + * @param[in] addr - the start address of the page. + * @param[in] len - the length(in byte) of content needs to read out from the page. + * @param[out] buf - the start address of the buffer. + * @return none. + */ +_attribute_text_sec_ void flash_read_page(unsigned long addr, unsigned long len, unsigned char *buf); + +/** + * @brief This function write the status of flash. + * @param[in] data - the value of status. + * @return none. + */ +_attribute_text_sec_ void flash_write_status(unsigned short data); + +/** + * @brief This function reads the status of flash. + * @return the value of status. + */ +_attribute_text_sec_ unsigned short flash_read_status(void); + +/** + * @brief Deep Power Down mode to put the device in the lowest consumption mode + * it can be used as an extra software protection mechanism,while the device + * is not in active use,since in the mode, all write,Program and Erase commands + * are ignored,except the Release from Deep Power-Down and Read Device ID(RDI) + * command.This release the device from this mode + * @return none. + */ +_attribute_text_sec_ void flash_deep_powerdown(void); + +/** + * @brief The Release from Power-Down or High Performance Mode/Device ID command is a + * Multi-purpose command.it can be used to release the device from the power-Down + * State or High Performance Mode or obtain the devices electronic identification + * (ID)number.Release from Power-Down will take the time duration of tRES1 before + * the device will resume normal operation and other command are accepted.The CS# + * pin must remain high during the tRES1(8us) time duration. + * @return none. + */ +_attribute_text_sec_ void flash_release_deep_powerdown(void); + +/** + * @brief This function serves to read MID of flash(MAC id). Before reading UID of flash, + * you must read MID of flash. and then you can look up the related table to select + * the idcmd and read UID of flash + * @param[in] buf - store MID of flash + * @return none. + */ +_attribute_text_sec_ void flash_read_mid(unsigned char *buf); + +/** + * @brief This function serves to read UID of flash + * @param[in] idcmd - different flash vendor have different read-uid command. E.g: GD/PUYA:0x4B; XTX: 0x5A + * @param[in] buf - store UID of flash + * @return none. + */ +_attribute_text_sec_ void flash_read_uid(unsigned char idcmd, unsigned char *buf); + +/** + * @brief This function serves to read flash mid and uid,and check the correctness of mid and uid. + * @param[out] flash_mid - Flash Manufacturer ID + * @param[out] flash_uid - Flash Unique ID + * @return 0:error 1:ok + */ +_attribute_text_sec_ int flash_read_mid_uid_with_check( unsigned int *flash_mid ,unsigned char *flash_uid); + +/** + * @brief This function serves to set the protection area of the flash. + * @param[in] type - flash type include Puya. + * @param[in] data - refer to Driver API Doc. + * @return none. + */ +_attribute_text_sec_ void flash_lock(flash_type_e type, unsigned short data); + +/** + * @brief This function serves to flash release protection. + * @param[in] type - flash type include Puya. + * @return none. + */ +_attribute_text_sec_ void flash_unlock(flash_type_e type); + +/** + * @brief This function serves to set priority threshold. when the interrupt priority > Threshold flash process will disturb by interrupt. + * @param[in] preempt_en - 1 can disturb by interrupt, 0 can disturb by interrupt. + * @param[in] threshold - priority Threshold. + * @return none. + */ +_attribute_text_sec_ void flash_plic_preempt_config(unsigned char preempt_en, unsigned char threshold); + +/** + * @brief This function serves to set flash write command.This function interface is only used internally by flash, + * and is currently included in the H file for compatibility with other SDKs. When using this interface, + * please ensure that you understand the precautions of flash before using it. + * @param[in] cmd - set command. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void flash_send_cmd(unsigned char cmd); + diff --git a/b91/b91m_ble_sdk/drivers/B91/gpio.c b/b91/b91m_ble_sdk/drivers/B91/gpio.c new file mode 100755 index 0000000..9f83e53 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/gpio.c @@ -0,0 +1,405 @@ +/******************************************************************************************************** + * @file gpio.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "gpio.h" + +/********************************************************************************************************************** + * local constants * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * local macro * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * local data type * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * global variable * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * local variable * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * local function prototype * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * global function implementation * + *********************************************************************************************************************/ + + + + +/** + * @brief This function enable the input function of a pin. + * @param[in] pin - the pin needs to set the input function. + * @return none. + */ +void gpio_input_en(gpio_pin_e pin) +{ + unsigned char bit = pin & 0xff; + unsigned short group = pin & 0xf00; + + if(group == GPIO_GROUPA || group == GPIO_GROUPB || group == GPIO_GROUPE) + { + BM_SET(reg_gpio_ie(pin), bit); + } + + else if(group == GPIO_GROUPC) + { + analog_write_reg8(areg_gpio_pc_ie, analog_read_reg8(areg_gpio_pc_ie)|bit); + } + + else if(group == GPIO_GROUPD) + { + analog_write_reg8(areg_gpio_pd_ie, analog_read_reg8(areg_gpio_pd_ie)|bit); + } +} + +/** + * @brief This function disable the input function of a pin. + * @param[in] pin - the pin needs to set the input function. + * @return none. + */ +void gpio_input_dis(gpio_pin_e pin) +{ + unsigned char bit = pin & 0xff; + unsigned short group = pin & 0xf00; + + if(group == GPIO_GROUPA || group == GPIO_GROUPB || group == GPIO_GROUPE) + { + BM_CLR(reg_gpio_ie(pin), bit); + } + + else if(group == GPIO_GROUPC) + { + analog_write_reg8(areg_gpio_pc_ie, analog_read_reg8(areg_gpio_pc_ie)&(~bit)); + } + + else if(group == GPIO_GROUPD) + { + analog_write_reg8(areg_gpio_pd_ie, analog_read_reg8(areg_gpio_pd_ie)&(~bit)); + } +} + +/** + * @brief This function set the input function of a pin. + * @param[in] pin - the pin needs to set the input function + * @param[in] value - enable or disable the pin's input function(1: enable,0: disable ) + * @return none + */ +void gpio_set_input(gpio_pin_e pin, unsigned char value) +{ + if(value) + { + gpio_input_en(pin); + } + else + { + gpio_input_dis(pin); + } +} + +/** + * @brief This function set the pin's driving strength at strong. + * @param[in] pin - the pin needs to set the driving strength + * @return none + */ + void gpio_ds_en(gpio_pin_e pin) +{ + unsigned char bit = pin & 0xff; + unsigned short group = pin & 0xf00; + if(group == GPIO_GROUPC) + {analog_write_reg8(areg_gpio_pc_ds, analog_read_reg8(areg_gpio_pc_ds)|bit);} + else if(group == GPIO_GROUPD) + {analog_write_reg8(areg_gpio_pd_ds, analog_read_reg8(areg_gpio_pd_ds)|bit);} + else + {BM_SET(reg_gpio_ds(pin), bit);} +} + + + /** + * @brief This function set the pin's driving strength. + * @param[in] pin - the pin needs to set the driving strength at poor. + * @return none + */ + void gpio_ds_dis(gpio_pin_e pin) + { + unsigned char bit = pin & 0xff; + unsigned short group = pin & 0xf00; + if(group == GPIO_GROUPC) + {analog_write_reg8(areg_gpio_pc_ds, analog_read_reg8(areg_gpio_pc_ds)&(~bit));} + else if(group == GPIO_GROUPD) + {analog_write_reg8(areg_gpio_pd_ds, analog_read_reg8(areg_gpio_pd_ds)&(~bit));} + else + {BM_CLR(reg_gpio_ds(pin), bit);} + } + + +/** + * @brief This function servers to set the specified GPIO as high resistor. + * @param[in] pin - select the specified GPIO + * @return none. + */ +void gpio_shutdown(gpio_pin_e pin) +{ + unsigned short group = pin & 0xf00; + unsigned char bit = pin & 0xff; + switch(group) + { + case GPIO_GROUPA: + reg_gpio_pa_oen |= bit;//disable output + reg_gpio_pa_out &= (~bit);//set low level + reg_gpio_pa_ie &= (~bit);//disable input + break; + case GPIO_GROUPB: + reg_gpio_pb_oen |= bit; + reg_gpio_pb_out &= (~bit); + reg_gpio_pb_ie &= (~bit); + break; + case GPIO_GROUPC: + reg_gpio_pc_oen |= bit; + reg_gpio_pc_out &= (~bit); + analog_write_reg8(areg_gpio_pc_ie, analog_read_reg8(areg_gpio_pc_ie) & (~bit)); + break; + case GPIO_GROUPD: + reg_gpio_pd_oen |= bit; + reg_gpio_pd_out &= (~bit); + analog_write_reg8(areg_gpio_pd_ie, analog_read_reg8(areg_gpio_pd_ie) & (~bit)); + break; + + case GPIO_GROUPE: + reg_gpio_pe_oen |= bit; + reg_gpio_pe_out &= (~bit); + reg_gpio_pe_ie &= (~bit); + break; + + case GPIO_ALL: + { + //as gpio + reg_gpio_pa_gpio = 0x7f; + reg_gpio_pb_gpio = 0xff; + reg_gpio_pc_gpio = 0xff; + reg_gpio_pd_gpio = 0xff; + reg_gpio_pe_gpio = 0xff; + + //output disable + reg_gpio_pa_oen = 0xff; + reg_gpio_pb_oen = 0xff; + reg_gpio_pc_oen = 0xff; + reg_gpio_pd_oen = 0xff; + reg_gpio_pe_oen = 0xff; + + //set low level + reg_gpio_pa_out = 0x00; + reg_gpio_pb_out = 0x00; + reg_gpio_pc_out = 0x00; + reg_gpio_pd_out = 0x00; + reg_gpio_pe_out = 0x00; + + //disable input + reg_gpio_pa_ie = 0x80; //SWS + reg_gpio_pb_ie = 0x00; + analog_write_reg8(areg_gpio_pc_ie, 0); + analog_write_reg8(areg_gpio_pd_ie, 0); + reg_gpio_pe_ie = 0x00; + } + } +} + + + +/** + * @brief This function set a pin's IRQ. + * @param[in] pin - the pin needs to enable its IRQ. + * @param[in] trigger_type - gpio interrupt type. + * 0: rising edge. + * 1: falling edge. + * 2: high level. + * 3: low level. + * @return none. + */ +void gpio_set_irq(gpio_pin_e pin, gpio_irq_trigger_type_e trigger_type) +{ + switch(trigger_type) + { + case INTR_RISING_EDGE: + BM_CLR(reg_gpio_pol(pin), pin & 0xff); + BM_CLR(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO); + break; + case INTR_FALLING_EDGE: + BM_SET(reg_gpio_pol(pin), pin & 0xff); + BM_CLR(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO); + break; + case INTR_HIGH_LEVEL: + BM_CLR(reg_gpio_pol(pin), pin & 0xff); + BM_SET(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO); + break; + case INTR_LOW_LEVEL: + BM_SET(reg_gpio_pol(pin), pin & 0xff); + BM_SET(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO); + break; + } + reg_gpio_irq_ctrl |= FLD_GPIO_CORE_INTERRUPT_EN; + reg_gpio_irq_clr = FLD_GPIO_IRQ_CLR;//must clear cause to unexpected interrupt. + BM_SET(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_MASK_GPIO); + +} + +/** + * @brief This function set a pin's IRQ_RISC0. + * @param[in] pin - the pin needs to enable its IRQ. + * @param[in] trigger_type - gpio interrupt type 0 rising edge 1 falling edge 2 high level 3 low level. + * @return none. + */ +void gpio_set_gpio2risc0_irq(gpio_pin_e pin, gpio_irq_trigger_type_e trigger_type) +{ + + switch(trigger_type) + { + case INTR_RISING_EDGE: + BM_CLR(reg_gpio_pol(pin), pin & 0xff); + BM_CLR(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO2RISC0); + break; + case INTR_FALLING_EDGE: + BM_SET(reg_gpio_pol(pin), pin & 0xff); + BM_CLR(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO2RISC0); + break; + case INTR_HIGH_LEVEL: + BM_CLR(reg_gpio_pol(pin), pin & 0xff); + BM_SET(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO2RISC0); + break; + case INTR_LOW_LEVEL: + BM_SET(reg_gpio_pol(pin), pin & 0xff); + BM_SET(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO2RISC0); + break; + } + reg_gpio_irq_clr = FLD_GPIO_IRQ_GPIO2RISC0_CLR;//must clear cause to unexpected interrupt. + BM_SET(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_MASK_GPIO2RISC0); + +} + +/** + * @brief This function set a pin's IRQ_RISC1. + * @param[in] pin - the pin needs to enable its IRQ. + * @param[in] trigger_type - gpio interrupt type 0 rising edge 1 falling edge 2 high level 3 low level + * @return none. + */ +void gpio_set_gpio2risc1_irq(gpio_pin_e pin, gpio_irq_trigger_type_e trigger_type) +{ + switch(trigger_type) + { + case INTR_RISING_EDGE: + BM_CLR(reg_gpio_pol(pin), pin & 0xff); + BM_CLR(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO2RISC1); + break; + case INTR_FALLING_EDGE: + BM_SET(reg_gpio_pol(pin), pin & 0xff); + BM_CLR(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO2RISC1); + break; + case INTR_HIGH_LEVEL: + BM_CLR(reg_gpio_pol(pin), pin & 0xff); + BM_SET(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO2RISC1); + break; + case INTR_LOW_LEVEL: + BM_SET(reg_gpio_pol(pin), pin & 0xff); + BM_SET(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO2RISC1); + break; + } + reg_gpio_irq_clr =FLD_GPIO_IRQ_GPIO2RISC1_CLR;//must clear cause to unexpected interrupt. + BM_SET(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_MASK_GPIO2RISC1); + +} + +/** + * @brief This function set a pin's pull-up/down resistor. + * @param[in] pin - the pin needs to set its pull-up/down resistor. + * @param[in] up_down_res - the type of the pull-up/down resistor. + * @return none. + */ +void gpio_set_up_down_res(gpio_pin_e pin, gpio_pull_type_e up_down_res) +{ + unsigned char r_val = up_down_res & 0x03; + + unsigned char base_ana_reg = 0x0e + ((pin >> 8) << 1) + ( (pin & 0xf0) ? 1 : 0 ); //group = gpio>>8; + unsigned char shift_num, mask_not; + + if(pin & 0x11){ + shift_num = 0; + mask_not = 0xfc; + } + else if(pin & 0x22){ + shift_num = 2; + mask_not = 0xf3; + } + else if(pin & 0x44){ + shift_num = 4; + mask_not = 0xcf; + } + else if(pin & 0x88){ + shift_num = 6; + mask_not = 0x3f; + } + else{ + return; + } + analog_write_reg8(base_ana_reg, (analog_read_reg8(base_ana_reg) & mask_not) | (r_val << shift_num)); +} + +/** + * @brief This function set pin's 30k pull-up registor. + * @param[in] pin - the pin needs to set its pull-up registor. + * @return none. + * @attention This function sets the digital pull-up, it will not work after entering low power consumption. + */ +void gpio_set_pullup_res_30k(gpio_pin_e pin) +{ + unsigned char bit = pin & 0xff; + unsigned short group = pin & 0xf00; + + if(group==GPIO_GROUPC) + { + analog_write_reg8(areg_gpio_pc_pe, analog_read_reg8(areg_gpio_pc_pe) | bit); + } + else if(group==GPIO_GROUPD) + { + analog_write_reg8(areg_gpio_pd_pe, analog_read_reg8(areg_gpio_pd_pe) | bit); + } + else + { + BM_SET(reg_gpio_oen(pin),bit); + BM_SET(reg_gpio_out(pin),bit); + } +} + + +/********************************************************************************************************************** + * local function implementation * + *********************************************************************************************************************/ + diff --git a/b91/b91m_ble_sdk/drivers/B91/gpio.h b/b91/b91m_ble_sdk/drivers/B91/gpio.h new file mode 100755 index 0000000..f7efd6d --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/gpio.h @@ -0,0 +1,496 @@ +/******************************************************************************************************** + * @file gpio.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +/** @page GPIO + * + * Introduction + * =============== + * B91 contain two six group gpio(A~F), total 44 gpio pin. + * + * API Reference + * =============== + * Header File: gpio.h + */ +#ifndef DRIVERS_GPIO_H_ +#define DRIVERS_GPIO_H_ + + +#include "analog.h" +#include "plic.h" +#include "reg_include/gpio_reg.h" +/********************************************************************************************************************** + * global constants * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * global macro * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * global data type * + *********************************************************************************************************************/ +/** + * @brief Define GPIO types + */ +typedef enum{ + GPIO_GROUPA = 0x000, + GPIO_GROUPB = 0x100, + GPIO_GROUPC = 0x200, + GPIO_GROUPD = 0x300, + GPIO_GROUPE = 0x400, + GPIO_GROUPF = 0x500, + GPIO_ALL = 0x600, + GPIO_PA0 = GPIO_GROUPA | BIT(0), + GPIO_PA1 = GPIO_GROUPA | BIT(1), + GPIO_PA2 = GPIO_GROUPA | BIT(2), + GPIO_PA3 = GPIO_GROUPA | BIT(3), + GPIO_PA4 = GPIO_GROUPA | BIT(4), + GPIO_PA5 = GPIO_GROUPA | BIT(5),GPIO_DM=GPIO_PA5, + GPIO_PA6 = GPIO_GROUPA | BIT(6),GPIO_DP=GPIO_PA6, + GPIO_PA7 = GPIO_GROUPA | BIT(7),GPIO_SWS=GPIO_PA7, + GPIOA_ALL = GPIO_GROUPA | 0x00ff, + + GPIO_PB0 = GPIO_GROUPB | BIT(0), + GPIO_PB1 = GPIO_GROUPB | BIT(1), + GPIO_PB2 = GPIO_GROUPB | BIT(2), + GPIO_PB3 = GPIO_GROUPB | BIT(3), + GPIO_PB4 = GPIO_GROUPB | BIT(4), + GPIO_PB5 = GPIO_GROUPB | BIT(5), + GPIO_PB6 = GPIO_GROUPB | BIT(6), + GPIO_PB7 = GPIO_GROUPB | BIT(7), + + GPIO_PC0 = GPIO_GROUPC | BIT(0), + GPIO_PC1 = GPIO_GROUPC | BIT(1), + GPIO_PC2 = GPIO_GROUPC | BIT(2), + GPIO_PC3 = GPIO_GROUPC | BIT(3), + GPIO_PC4 = GPIO_GROUPC | BIT(4), + GPIO_PC5 = GPIO_GROUPC | BIT(5), + GPIO_PC6 = GPIO_GROUPC | BIT(6), + GPIO_PC7 = GPIO_GROUPC | BIT(7), + GPIOC_ALL = GPIO_GROUPC | 0x00ff, + + GPIO_PD0 = GPIO_GROUPD | BIT(0), + GPIO_PD1 = GPIO_GROUPD | BIT(1), + GPIO_PD2 = GPIO_GROUPD | BIT(2), + GPIO_PD3 = GPIO_GROUPD | BIT(3), + GPIO_PD4 = GPIO_GROUPD | BIT(4), + GPIO_PD5 = GPIO_GROUPD | BIT(5), + GPIO_PD6 = GPIO_GROUPD | BIT(6), + GPIO_PD7 = GPIO_GROUPD | BIT(7), + + GPIO_PE0 = GPIO_GROUPE | BIT(0), + GPIO_PE1 = GPIO_GROUPE | BIT(1), + GPIO_PE2 = GPIO_GROUPE | BIT(2), + GPIO_PE3 = GPIO_GROUPE | BIT(3), + GPIO_PE4 = GPIO_GROUPE | BIT(4), + GPIO_PE5 = GPIO_GROUPE | BIT(5), + GPIO_PE6 = GPIO_GROUPE | BIT(6), + GPIO_PE7 = GPIO_GROUPE | BIT(7), + GPIOE_ALL = GPIO_GROUPE | 0x00ff, + + GPIO_PF0 = GPIO_GROUPF | BIT(0), + GPIO_PF1 = GPIO_GROUPF | BIT(1), + GPIO_PF2 = GPIO_GROUPF | BIT(2), + GPIO_PF3 = GPIO_GROUPF | BIT(3), + +}gpio_pin_e; + +/** + * @brief Define GPIO mux func + */ +typedef enum{ + AS_GPIO, + AS_MSPI, + + AS_SWS, + AS_SWM, + + AS_USB_DP, + AS_USB_DM, + + AS_TDI, + AS_TDO, + AS_TMS, + AS_TCK, + + + +}gpio_fuc_e; + + + +/** + * @brief Define rising/falling types + */ +typedef enum{ + POL_RISING = 0, + POL_FALLING = 1, +}gpio_pol_e; + + +/** + * @brief Define interrupt types + */ +typedef enum{ + INTR_RISING_EDGE=0, + INTR_FALLING_EDGE , + INTR_HIGH_LEVEL, + INTR_LOW_LEVEL, +} gpio_irq_trigger_type_e; + +/** + * @brief Define pull up or down types + */ +typedef enum { + GPIO_PIN_UP_DOWN_FLOAT = 0, + GPIO_PIN_PULLUP_1M = 1, + GPIO_PIN_PULLDOWN_100K = 2, + GPIO_PIN_PULLUP_10K = 3, +}gpio_pull_type_e; + + + + +/** + * @brief This function servers to enable gpio function. + * @param[in] pin - the selected pin. + * @return none. + */ +static inline void gpio_function_en(gpio_pin_e pin) +{ + unsigned char bit = pin & 0xff; + BM_SET(reg_gpio_func(pin), bit); +} + + +/** + * @brief This function servers to disable gpio function. + * @param[in] pin - the selected pin. + * @return none. + */ +static inline void gpio_function_dis(gpio_pin_e pin) +{ + unsigned char bit = pin & 0xff; + BM_CLR(reg_gpio_func(pin), bit); +} + + + +/** + * @brief This function set the pin's output high level. + * @param[in] pin - the pin needs to set its output level. + * @return none. + */ +static inline void gpio_set_high_level(gpio_pin_e pin) +{ + unsigned char bit = pin & 0xff; + BM_SET(reg_gpio_out(pin), bit); + +} + + +/** + * @brief This function set the pin's output low level. + * @param[in] pin - the pin needs to set its output level. + * @return none. + */ +static inline void gpio_set_low_level(gpio_pin_e pin) +{ + unsigned char bit = pin & 0xff; + BM_CLR(reg_gpio_out(pin), bit); + +} + +/** + * @brief This function set the pin's output level. + * @param[in] pin - the pin needs to set its output level + * @param[in] value - value of the output level(1: high 0: low) + * @return none + */ +static inline void gpio_set_level(gpio_pin_e pin, unsigned char value) +{ + if(value) + { + gpio_set_high_level(pin); + } + else + { + gpio_set_low_level(pin); + } +} + +/** + * @brief This function read the pin's input/output level. + * @param[in] pin - the pin needs to read its level. + * @return 1: the pin's level is high. + * 0: the pin's level is low. + */ +static inline _Bool gpio_get_level(gpio_pin_e pin) +{ + return BM_IS_SET(reg_gpio_in(pin), pin & 0xff); +} + + +/** + * @brief This function read all the pins' input level. + * @param[out] p - the buffer used to store all the pins' input level + * @return none + */ +static inline void gpio_get_level_all(unsigned char *p) +{ + p[0] = reg_gpio_pa_in; + p[1] = reg_gpio_pb_in; + p[2] = reg_gpio_pc_in; + p[3] = reg_gpio_pd_in; + p[4] = reg_gpio_pe_in; +} + + + +/** + * @brief This function set the pin toggle. + * @param[in] pin - the pin needs to toggle. + * @return none. + */ +static inline void gpio_toggle(gpio_pin_e pin) +{ + reg_gpio_out(pin) ^= (pin & 0xFF); +} + + + +/** + * @brief This function enable the output function of a pin. + * @param[in] pin - the pin needs to set the output function. + * @return none. + */ +static inline void gpio_output_en(gpio_pin_e pin) +{ + unsigned char bit = pin & 0xff; + BM_CLR(reg_gpio_oen(pin), bit); +} + +/** + * @brief This function disable the output function of a pin. + * @param[in] pin - the pin needs to set the output function. + * @return none. + */ +static inline void gpio_output_dis(gpio_pin_e pin) +{ + unsigned char bit = pin & 0xff; + BM_SET(reg_gpio_oen(pin), bit); +} + +/** + * @brief This function enable set output function of a pin. + * @param[in] pin - the pin needs to set the output function (1: enable,0: disable) + * @return none + */ +static inline void gpio_set_output(gpio_pin_e pin, unsigned char value) +{ + if(value) + { + gpio_output_en(pin); + } + else + { + gpio_output_dis(pin); + } + +} +/** + * @brief This function determines whether the output function of a pin is enabled. + * @param[in] pin - the pin needs to determine whether its output function is enabled. + * @return 1: the pin's output function is enabled. + * 0: the pin's output function is disabled. + */ +static inline _Bool gpio_is_output_en(gpio_pin_e pin) +{ + return !BM_IS_SET(reg_gpio_oen(pin), pin & 0xff); +} + + +/** + * @brief This function determines whether the input function of a pin is enabled. + * @param[in] pin - the pin needs to determine whether its input function is enabled(not include group_pc). + * @return 1: the pin's input function is enabled. + * 0: the pin's input function is disabled. + */ +static inline _Bool gpio_is_input_en(gpio_pin_e pin) +{ + return BM_IS_SET(reg_gpio_ie(pin), pin & 0xff); +} + +/** + * @brief This function serves to enable gpio irq function. + * @param[in] pin - the pin needs to enable its IRQ. + * @return none. + */ +static inline void gpio_irq_en(gpio_pin_e pin) +{ + BM_SET(reg_gpio_irq_en(pin), pin & 0xff); +} + +/** + * @brief This function serves to disable gpio irq function. + * @param[in] pin - the pin needs to disable its IRQ. + * @return none. + */ +static inline void gpio_irq_dis(gpio_pin_e pin) +{ + BM_CLR(reg_gpio_irq_en(pin), pin & 0xff); +} + +/** + * @brief This function serves to enable gpio risc0 irq function. + * @param[in] pin - the pin needs to enable its IRQ. + * @return none. + */ +static inline void gpio_gpio2risc0_irq_en(gpio_pin_e pin) +{ + BM_SET(reg_gpio_irq_risc0_en(pin), pin & 0xff); +} +/** + * @brief This function serves to disable gpio risc0 irq function. + * @param[in] pin - the pin needs to disable its IRQ. + * @return none. + */ +static inline void gpio_gpio2risc0_irq_dis(gpio_pin_e pin) +{ + BM_CLR(reg_gpio_irq_risc0_en(pin), pin & 0xff); +} +/** + * @brief This function serves to enable gpio risc1 irq function. + * @param[in] pin - the pin needs to enable its IRQ. + * @return none. + */ +static inline void gpio_gpio2risc1_irq_en(gpio_pin_e pin) +{ + BM_SET(reg_gpio_irq_risc1_en(pin), pin & 0xff); +} + +/** + * @brief This function serves to disable gpio risc1 irq function. + * @param[in] pin - the pin needs to disable its IRQ. + * @return none. + */ +static inline void gpio_gpio2risc1_irq_dis(gpio_pin_e pin) +{ + BM_CLR(reg_gpio_irq_risc1_en(pin), pin & 0xff); +} +/** + * @brief This function serves to clr gpio irq status. + * @param[in] status - the pin needs to disable its IRQ. + * @return none. + */ +static inline void gpio_clr_irq_status(gpio_irq_status_e status) +{ + reg_gpio_irq_clr=status; +} + +/** + * @brief This function set the pin's driving strength at strong. + * @param[in] pin - the pin needs to set the driving strength. + * @return none. + */ +void gpio_ds_en(gpio_pin_e pin); + + +/** + * @brief This function set the pin's driving strength. + * @param[in] pin - the pin needs to set the driving strength at poor. + * @return none. + */ + void gpio_ds_dis(gpio_pin_e pin); + + + + +void gpio_set_irq(gpio_pin_e pin, gpio_irq_trigger_type_e trigger_type); + +/** + * @brief This function set a pin's IRQ_RISC0. + * @param[in] pin - the pin needs to enable its IRQ. + * @param[in] trigger_type - gpio interrupt type 0 rising edge 1 falling edge 2 high level 3 low level + * @return none. + */ +void gpio_set_gpio2risc0_irq(gpio_pin_e pin, gpio_irq_trigger_type_e trigger_type); + +/** + * @brief This function set a pin's IRQ_RISC1. + * @param[in] pin - the pin needs to enable its IRQ. + * @param[in] trigger_type - gpio interrupt type 0 rising edge 1 falling edge 2 high level 3 low level + * @return none. + */ +void gpio_set_gpio2risc1_irq(gpio_pin_e pin, gpio_irq_trigger_type_e trigger_type); + + +/** + * @brief This function set the input function of a pin. + * @param[in] pin - the pin needs to set the input function. + * @return none. + */ +void gpio_input_en(gpio_pin_e pin); + +/** + * @brief This function disable the input function of a pin. + * @param[in] pin - the pin needs to set the input function. + * @return none. + */ +void gpio_input_dis(gpio_pin_e pin); + +/** + * @brief This function set the input function of a pin. + * @param[in] pin - the pin needs to set the input function + * @param[in] value - enable or disable the pin's input function(1: enable,0: disable ) + * @return none + */ +void gpio_set_input(gpio_pin_e pin, unsigned char value); +/** + * @brief This function servers to set the specified GPIO as high resistor. + * @param[in] pin - select the specified GPIO. + * @return none. + */ +void gpio_shutdown(gpio_pin_e pin); + +/** + * @brief This function set a pin's pull-up/down resistor. + * @param[in] pin - the pin needs to set its pull-up/down resistor. + * @param[in] up_down_res - the type of the pull-up/down resistor. + * @return none. + */ +void gpio_set_up_down_res(gpio_pin_e pin, gpio_pull_type_e up_down_res); + +/** + * @brief This function set pin's 30k pull-up registor. + * @param[in] pin - the pin needs to set its pull-up registor. + * @return none. + */ +void gpio_set_pullup_res_30k(gpio_pin_e pin); + + +#endif + + + + diff --git a/b91/b91m_ble_sdk/drivers/B91/gpio_default.h b/b91/b91m_ble_sdk/drivers/B91/gpio_default.h new file mode 100755 index 0000000..43eb0f2 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/gpio_default.h @@ -0,0 +1,1021 @@ +/******************************************************************************************************** + * @file gpio_default.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef DRIVERS_GPIO_DEFAULT_H_ +#define DRIVERS_GPIO_DEFAULT_H_ + +#include "compiler.h" +#include "gpio.h" +/********************************************************************************************************************** + * GPIO setting * + *********************************************************************************************************************/ +#ifndef PA0_INPUT_ENABLE +#define PA0_INPUT_ENABLE 0 +#endif +#ifndef PA1_INPUT_ENABLE +#define PA1_INPUT_ENABLE 0 +#endif +#ifndef PA2_INPUT_ENABLE +#define PA2_INPUT_ENABLE 0 +#endif +#ifndef PA3_INPUT_ENABLE +#define PA3_INPUT_ENABLE 0 +#endif +#ifndef PA4_INPUT_ENABLE +#define PA4_INPUT_ENABLE 0 +#endif +#ifndef PA5_INPUT_ENABLE +#define PA5_INPUT_ENABLE 0 //USB +#endif +#ifndef PA6_INPUT_ENABLE +#define PA6_INPUT_ENABLE 0 //USB +#endif +#ifndef PA7_INPUT_ENABLE +#define PA7_INPUT_ENABLE 1 //SWS +#endif +#ifndef PA0_OUTPUT_ENABLE +#define PA0_OUTPUT_ENABLE 0 +#endif +#ifndef PA1_OUTPUT_ENABLE +#define PA1_OUTPUT_ENABLE 0 +#endif +#ifndef PA2_OUTPUT_ENABLE +#define PA2_OUTPUT_ENABLE 0 +#endif +#ifndef PA3_OUTPUT_ENABLE +#define PA3_OUTPUT_ENABLE 0 +#endif +#ifndef PA4_OUTPUT_ENABLE +#define PA4_OUTPUT_ENABLE 0 +#endif +#ifndef PA5_OUTPUT_ENABLE +#define PA5_OUTPUT_ENABLE 0 +#endif +#ifndef PA6_OUTPUT_ENABLE +#define PA6_OUTPUT_ENABLE 0 +#endif +#ifndef PA7_OUTPUT_ENABLE +#define PA7_OUTPUT_ENABLE 0 +#endif +#ifndef PA0_DATA_STRENGTH +#define PA0_DATA_STRENGTH 1 +#endif +#ifndef PA1_DATA_STRENGTH +#define PA1_DATA_STRENGTH 1 +#endif +#ifndef PA2_DATA_STRENGTH +#define PA2_DATA_STRENGTH 1 +#endif +#ifndef PA3_DATA_STRENGTH +#define PA3_DATA_STRENGTH 1 +#endif +#ifndef PA4_DATA_STRENGTH +#define PA4_DATA_STRENGTH 1 +#endif +#ifndef PA5_DATA_STRENGTH +#define PA5_DATA_STRENGTH 1 +#endif +#ifndef PA6_DATA_STRENGTH +#define PA6_DATA_STRENGTH 1 +#endif +#ifndef PA7_DATA_STRENGTH +#define PA7_DATA_STRENGTH 1 +#endif +#ifndef PA0_DATA_OUT +#define PA0_DATA_OUT 0 +#endif +#ifndef PA1_DATA_OUT +#define PA1_DATA_OUT 0 +#endif +#ifndef PA2_DATA_OUT +#define PA2_DATA_OUT 0 +#endif +#ifndef PA3_DATA_OUT +#define PA3_DATA_OUT 0 +#endif +#ifndef PA4_DATA_OUT +#define PA4_DATA_OUT 0 +#endif +#ifndef PA5_DATA_OUT +#define PA5_DATA_OUT 0 +#endif +#ifndef PA6_DATA_OUT +#define PA6_DATA_OUT 0 +#endif +#ifndef PA7_DATA_OUT +#define PA7_DATA_OUT 0 +#endif +#ifndef PA0_FUNC +#define PA0_FUNC AS_GPIO +#endif +#ifndef PA1_FUNC +#define PA1_FUNC AS_GPIO +#endif +#ifndef PA2_FUNC +#define PA2_FUNC AS_GPIO +#endif +#ifndef PA3_FUNC +#define PA3_FUNC AS_GPIO +#endif +#ifndef PA4_FUNC +#define PA4_FUNC AS_GPIO +#endif +#ifndef PA5_FUNC +#define PA5_FUNC AS_GPIO +#endif +#ifndef PA6_FUNC +#define PA6_FUNC AS_GPIO +#endif +#ifndef PA7_FUNC +#define PA7_FUNC AS_SWS +#endif +#ifndef PULL_WAKEUP_SRC_PA0 +#define PULL_WAKEUP_SRC_PA0 0 +#endif +#ifndef PULL_WAKEUP_SRC_PA1 +#define PULL_WAKEUP_SRC_PA1 0 +#endif +#ifndef PULL_WAKEUP_SRC_PA2 +#define PULL_WAKEUP_SRC_PA2 0 +#endif +#ifndef PULL_WAKEUP_SRC_PA3 +#define PULL_WAKEUP_SRC_PA3 0 +#endif +#ifndef PULL_WAKEUP_SRC_PA4 +#define PULL_WAKEUP_SRC_PA4 0 +#endif +#ifndef PULL_WAKEUP_SRC_PA5 +#define PULL_WAKEUP_SRC_PA5 0 +#endif +#ifndef PULL_WAKEUP_SRC_PA6 +#define PULL_WAKEUP_SRC_PA6 0 +#endif +#ifndef PULL_WAKEUP_SRC_PA7 +#define PULL_WAKEUP_SRC_PA7 GPIO_PIN_PULLUP_1M //sws pullup +#endif + +////////////////////////////////////////////////// +#ifndef PB0_INPUT_ENABLE +#define PB0_INPUT_ENABLE 0 +#endif +#ifndef PB1_INPUT_ENABLE +#define PB1_INPUT_ENABLE 0 +#endif +#ifndef PB2_INPUT_ENABLE +#define PB2_INPUT_ENABLE 0 +#endif +#ifndef PB3_INPUT_ENABLE +#define PB3_INPUT_ENABLE 0 +#endif +#ifndef PB4_INPUT_ENABLE +#define PB4_INPUT_ENABLE 0 +#endif +#ifndef PB5_INPUT_ENABLE +#define PB5_INPUT_ENABLE 0 +#endif +#ifndef PB6_INPUT_ENABLE +#define PB6_INPUT_ENABLE 0 +#endif +#ifndef PB7_INPUT_ENABLE +#define PB7_INPUT_ENABLE 0 +#endif +#ifndef PB0_OUTPUT_ENABLE +#define PB0_OUTPUT_ENABLE 0 +#endif +#ifndef PB1_OUTPUT_ENABLE +#define PB1_OUTPUT_ENABLE 0 +#endif +#ifndef PB2_OUTPUT_ENABLE +#define PB2_OUTPUT_ENABLE 0 +#endif +#ifndef PB3_OUTPUT_ENABLE +#define PB3_OUTPUT_ENABLE 0 +#endif +#ifndef PB4_OUTPUT_ENABLE +#define PB4_OUTPUT_ENABLE 0 +#endif +#ifndef PB5_OUTPUT_ENABLE +#define PB5_OUTPUT_ENABLE 0 +#endif +#ifndef PB6_OUTPUT_ENABLE +#define PB6_OUTPUT_ENABLE 0 +#endif +#ifndef PB7_OUTPUT_ENABLE +#define PB7_OUTPUT_ENABLE 0 +#endif +#ifndef PB0_DATA_STRENGTH +#define PB0_DATA_STRENGTH 1 +#endif +#ifndef PB1_DATA_STRENGTH +#define PB1_DATA_STRENGTH 1 +#endif +#ifndef PB2_DATA_STRENGTH +#define PB2_DATA_STRENGTH 1 +#endif +#ifndef PB3_DATA_STRENGTH +#define PB3_DATA_STRENGTH 1 +#endif +#ifndef PB4_DATA_STRENGTH +#define PB4_DATA_STRENGTH 1 +#endif +#ifndef PB5_DATA_STRENGTH +#define PB5_DATA_STRENGTH 1 +#endif +#ifndef PB6_DATA_STRENGTH +#define PB6_DATA_STRENGTH 1 +#endif +#ifndef PB7_DATA_STRENGTH +#define PB7_DATA_STRENGTH 1 +#endif +#ifndef PB0_DATA_OUT +#define PB0_DATA_OUT 0 +#endif +#ifndef PB1_DATA_OUT +#define PB1_DATA_OUT 0 +#endif +#ifndef PB2_DATA_OUT +#define PB2_DATA_OUT 0 +#endif +#ifndef PB3_DATA_OUT +#define PB3_DATA_OUT 0 +#endif +#ifndef PB4_DATA_OUT +#define PB4_DATA_OUT 0 +#endif +#ifndef PB5_DATA_OUT +#define PB5_DATA_OUT 0 +#endif +#ifndef PB6_DATA_OUT +#define PB6_DATA_OUT 0 +#endif +#ifndef PB7_DATA_OUT +#define PB7_DATA_OUT 0 +#endif +#ifndef PB0_FUNC +#define PB0_FUNC AS_GPIO +#endif +#ifndef PB1_FUNC +#define PB1_FUNC AS_GPIO +#endif +#ifndef PB2_FUNC +#define PB2_FUNC AS_GPIO +#endif +#ifndef PB3_FUNC +#define PB3_FUNC AS_GPIO +#endif +#ifndef PB4_FUNC +#define PB4_FUNC AS_GPIO +#endif +#ifndef PB5_FUNC +#define PB5_FUNC AS_GPIO +#endif +#ifndef PB6_FUNC +#define PB6_FUNC AS_GPIO +#endif +#ifndef PB7_FUNC +#define PB7_FUNC AS_GPIO +#endif +#ifndef PULL_WAKEUP_SRC_PB0 +#define PULL_WAKEUP_SRC_PB0 0 +#endif +#ifndef PULL_WAKEUP_SRC_PB1 +#define PULL_WAKEUP_SRC_PB1 0 +#endif +#ifndef PULL_WAKEUP_SRC_PB2 +#define PULL_WAKEUP_SRC_PB2 0 +#endif +#ifndef PULL_WAKEUP_SRC_PB3 +#define PULL_WAKEUP_SRC_PB3 0 +#endif +#ifndef PULL_WAKEUP_SRC_PB4 +#define PULL_WAKEUP_SRC_PB4 0 +#endif +#ifndef PULL_WAKEUP_SRC_PB5 +#define PULL_WAKEUP_SRC_PB5 0 +#endif +#ifndef PULL_WAKEUP_SRC_PB6 +#define PULL_WAKEUP_SRC_PB6 0 +#endif +#ifndef PULL_WAKEUP_SRC_PB7 +#define PULL_WAKEUP_SRC_PB7 0 +#endif + +////////////////////////////////////////////////// +#ifndef PC0_INPUT_ENABLE +#define PC0_INPUT_ENABLE 0 +#endif +#ifndef PC1_INPUT_ENABLE +#define PC1_INPUT_ENABLE 0 +#endif +#ifndef PC2_INPUT_ENABLE +#define PC2_INPUT_ENABLE 0 +#endif +#ifndef PC3_INPUT_ENABLE +#define PC3_INPUT_ENABLE 0 +#endif +#ifndef PC4_INPUT_ENABLE +#define PC4_INPUT_ENABLE 0 +#endif +#ifndef PC5_INPUT_ENABLE +#define PC5_INPUT_ENABLE 0 +#endif +#ifndef PC6_INPUT_ENABLE +#define PC6_INPUT_ENABLE 0 +#endif +#ifndef PC7_INPUT_ENABLE +#define PC7_INPUT_ENABLE 0 +#endif +#ifndef PC0_OUTPUT_ENABLE +#define PC0_OUTPUT_ENABLE 0 +#endif +#ifndef PC1_OUTPUT_ENABLE +#define PC1_OUTPUT_ENABLE 0 +#endif +#ifndef PC2_OUTPUT_ENABLE +#define PC2_OUTPUT_ENABLE 0 +#endif +#ifndef PC3_OUTPUT_ENABLE +#define PC3_OUTPUT_ENABLE 0 +#endif +#ifndef PC4_OUTPUT_ENABLE +#define PC4_OUTPUT_ENABLE 0 +#endif +#ifndef PC5_OUTPUT_ENABLE +#define PC5_OUTPUT_ENABLE 0 +#endif +#ifndef PC6_OUTPUT_ENABLE +#define PC6_OUTPUT_ENABLE 0 +#endif +#ifndef PC7_OUTPUT_ENABLE +#define PC7_OUTPUT_ENABLE 0 +#endif +#ifndef PC0_DATA_STRENGTH +#define PC0_DATA_STRENGTH 1 +#endif +#ifndef PC1_DATA_STRENGTH +#define PC1_DATA_STRENGTH 1 +#endif +#ifndef PC2_DATA_STRENGTH +#define PC2_DATA_STRENGTH 1 +#endif +#ifndef PC3_DATA_STRENGTH +#define PC3_DATA_STRENGTH 1 +#endif +#ifndef PC4_DATA_STRENGTH +#define PC4_DATA_STRENGTH 1 +#endif +#ifndef PC5_DATA_STRENGTH +#define PC5_DATA_STRENGTH 1 +#endif +#ifndef PC6_DATA_STRENGTH +#define PC6_DATA_STRENGTH 1 +#endif +#ifndef PC7_DATA_STRENGTH +#define PC7_DATA_STRENGTH 1 +#endif +#ifndef PC0_DATA_OUT +#define PC0_DATA_OUT 0 +#endif +#ifndef PC1_DATA_OUT +#define PC1_DATA_OUT 0 +#endif +#ifndef PC2_DATA_OUT +#define PC2_DATA_OUT 0 +#endif +#ifndef PC3_DATA_OUT +#define PC3_DATA_OUT 0 +#endif +#ifndef PC4_DATA_OUT +#define PC4_DATA_OUT 0 +#endif +#ifndef PC5_DATA_OUT +#define PC5_DATA_OUT 0 +#endif +#ifndef PC6_DATA_OUT +#define PC6_DATA_OUT 0 +#endif +#ifndef PC7_DATA_OUT +#define PC7_DATA_OUT 0 +#endif +#ifndef PC0_FUNC +#define PC0_FUNC AS_GPIO +#endif +#ifndef PC1_FUNC +#define PC1_FUNC AS_GPIO +#endif +#ifndef PC2_FUNC +#define PC2_FUNC AS_GPIO +#endif +#ifndef PC3_FUNC +#define PC3_FUNC AS_GPIO +#endif +#ifndef PC4_FUNC +#define PC4_FUNC AS_GPIO +#endif +#ifndef PC5_FUNC +#define PC5_FUNC AS_GPIO +#endif +#ifndef PC6_FUNC +#define PC6_FUNC AS_GPIO +#endif +#ifndef PC7_FUNC +#define PC7_FUNC AS_GPIO +#endif +#ifndef PULL_WAKEUP_SRC_PC0 +#define PULL_WAKEUP_SRC_PC0 0 +#endif +#ifndef PULL_WAKEUP_SRC_PC1 +#define PULL_WAKEUP_SRC_PC1 0 +#endif +#ifndef PULL_WAKEUP_SRC_PC2 +#define PULL_WAKEUP_SRC_PC2 0 +#endif +#ifndef PULL_WAKEUP_SRC_PC3 +#define PULL_WAKEUP_SRC_PC3 0 +#endif +#ifndef PULL_WAKEUP_SRC_PC4 +#define PULL_WAKEUP_SRC_PC4 0 +#endif +#ifndef PULL_WAKEUP_SRC_PC5 +#define PULL_WAKEUP_SRC_PC5 0 +#endif +#ifndef PULL_WAKEUP_SRC_PC6 +#define PULL_WAKEUP_SRC_PC6 0 +#endif +#ifndef PULL_WAKEUP_SRC_PC7 +#define PULL_WAKEUP_SRC_PC7 0 +#endif + +////////////////////////////////////////////////// +#ifndef PD0_INPUT_ENABLE +#define PD0_INPUT_ENABLE 0 +#endif +#ifndef PD1_INPUT_ENABLE +#define PD1_INPUT_ENABLE 0 +#endif +#ifndef PD2_INPUT_ENABLE +#define PD2_INPUT_ENABLE 0 +#endif +#ifndef PD3_INPUT_ENABLE +#define PD3_INPUT_ENABLE 0 +#endif +#ifndef PD4_INPUT_ENABLE +#define PD4_INPUT_ENABLE 0 +#endif +#ifndef PD5_INPUT_ENABLE +#define PD5_INPUT_ENABLE 0 +#endif +#ifndef PD6_INPUT_ENABLE +#define PD6_INPUT_ENABLE 0 +#endif +#ifndef PD7_INPUT_ENABLE +#define PD7_INPUT_ENABLE 0 +#endif +#ifndef PD0_OUTPUT_ENABLE +#define PD0_OUTPUT_ENABLE 0 +#endif +#ifndef PD1_OUTPUT_ENABLE +#define PD1_OUTPUT_ENABLE 0 +#endif +#ifndef PD2_OUTPUT_ENABLE +#define PD2_OUTPUT_ENABLE 0 +#endif +#ifndef PD3_OUTPUT_ENABLE +#define PD3_OUTPUT_ENABLE 0 +#endif +#ifndef PD4_OUTPUT_ENABLE +#define PD4_OUTPUT_ENABLE 0 +#endif +#ifndef PD5_OUTPUT_ENABLE +#define PD5_OUTPUT_ENABLE 0 +#endif +#ifndef PD6_OUTPUT_ENABLE +#define PD6_OUTPUT_ENABLE 0 +#endif +#ifndef PD7_OUTPUT_ENABLE +#define PD7_OUTPUT_ENABLE 0 +#endif +#ifndef PD0_DATA_STRENGTH +#define PD0_DATA_STRENGTH 1 +#endif +#ifndef PD1_DATA_STRENGTH +#define PD1_DATA_STRENGTH 1 +#endif +#ifndef PD2_DATA_STRENGTH +#define PD2_DATA_STRENGTH 1 +#endif +#ifndef PD3_DATA_STRENGTH +#define PD3_DATA_STRENGTH 1 +#endif +#ifndef PD4_DATA_STRENGTH +#define PD4_DATA_STRENGTH 1 +#endif +#ifndef PD5_DATA_STRENGTH +#define PD5_DATA_STRENGTH 1 +#endif +#ifndef PD6_DATA_STRENGTH +#define PD6_DATA_STRENGTH 1 +#endif +#ifndef PD7_DATA_STRENGTH +#define PD7_DATA_STRENGTH 1 +#endif +#ifndef PD0_DATA_OUT +#define PD0_DATA_OUT 0 +#endif +#ifndef PD1_DATA_OUT +#define PD1_DATA_OUT 0 +#endif +#ifndef PD2_DATA_OUT +#define PD2_DATA_OUT 0 +#endif +#ifndef PD3_DATA_OUT +#define PD3_DATA_OUT 0 +#endif +#ifndef PD4_DATA_OUT +#define PD4_DATA_OUT 0 +#endif +#ifndef PD5_DATA_OUT +#define PD5_DATA_OUT 0 +#endif +#ifndef PD6_DATA_OUT +#define PD6_DATA_OUT 0 +#endif +#ifndef PD7_DATA_OUT +#define PD7_DATA_OUT 0 +#endif +#ifndef PD0_FUNC +#define PD0_FUNC AS_GPIO +#endif +#ifndef PD1_FUNC +#define PD1_FUNC AS_GPIO +#endif +#ifndef PD2_FUNC +#define PD2_FUNC AS_GPIO +#endif +#ifndef PD3_FUNC +#define PD3_FUNC AS_GPIO +#endif +#ifndef PD4_FUNC +#define PD4_FUNC AS_GPIO +#endif +#ifndef PD5_FUNC +#define PD5_FUNC AS_GPIO +#endif +#ifndef PD6_FUNC +#define PD6_FUNC AS_GPIO +#endif +#ifndef PD7_FUNC +#define PD7_FUNC AS_GPIO +#endif +#ifndef PULL_WAKEUP_SRC_PD0 +#define PULL_WAKEUP_SRC_PD0 0 +#endif +#ifndef PULL_WAKEUP_SRC_PD1 +#define PULL_WAKEUP_SRC_PD1 0 +#endif +#ifndef PULL_WAKEUP_SRC_PD2 +#define PULL_WAKEUP_SRC_PD2 0 +#endif +#ifndef PULL_WAKEUP_SRC_PD3 +#define PULL_WAKEUP_SRC_PD3 0 +#endif +#ifndef PULL_WAKEUP_SRC_PD4 +#define PULL_WAKEUP_SRC_PD4 0 +#endif +#ifndef PULL_WAKEUP_SRC_PD5 +#define PULL_WAKEUP_SRC_PD5 0 +#endif +#ifndef PULL_WAKEUP_SRC_PD6 +#define PULL_WAKEUP_SRC_PD6 0 +#endif +#ifndef PULL_WAKEUP_SRC_PD7 +#define PULL_WAKEUP_SRC_PD7 0 +#endif + +////////////////////////////////////////////////// +#ifndef PE0_INPUT_ENABLE +#define PE0_INPUT_ENABLE 0 +#endif +#ifndef PE1_INPUT_ENABLE +#define PE1_INPUT_ENABLE 0 +#endif +#ifndef PE2_INPUT_ENABLE +#define PE2_INPUT_ENABLE 0 +#endif +#ifndef PE3_INPUT_ENABLE +#define PE3_INPUT_ENABLE 0 +#endif +#ifndef PE4_INPUT_ENABLE +#define PE4_INPUT_ENABLE 0 +#endif +#ifndef PE5_INPUT_ENABLE +#define PE5_INPUT_ENABLE 0 +#endif +#ifndef PE6_INPUT_ENABLE +#define PE6_INPUT_ENABLE 1 +#endif +#ifndef PE7_INPUT_ENABLE +#define PE7_INPUT_ENABLE 1 +#endif + +#ifndef PE0_OUTPUT_ENABLE +#define PE0_OUTPUT_ENABLE 0 +#endif +#ifndef PE1_OUTPUT_ENABLE +#define PE1_OUTPUT_ENABLE 0 +#endif +#ifndef PE2_OUTPUT_ENABLE +#define PE2_OUTPUT_ENABLE 0 +#endif +#ifndef PE3_OUTPUT_ENABLE +#define PE3_OUTPUT_ENABLE 0 +#endif +#ifndef PE4_OUTPUT_ENABLE +#define PE4_OUTPUT_ENABLE 0 +#endif +#ifndef PE5_OUTPUT_ENABLE +#define PE5_OUTPUT_ENABLE 0 +#endif +#ifndef PE6_OUTPUT_ENABLE +#define PE6_OUTPUT_ENABLE 0 +#endif +#ifndef PE7_OUTPUT_ENABLE +#define PE7_OUTPUT_ENABLE 0 +#endif + +#ifndef PE0_DATA_STRENGTH +#define PE0_DATA_STRENGTH 1 +#endif +#ifndef PE1_DATA_STRENGTH +#define PE1_DATA_STRENGTH 1 +#endif +#ifndef PE2_DATA_STRENGTH +#define PE2_DATA_STRENGTH 1 +#endif +#ifndef PE3_DATA_STRENGTH +#define PE3_DATA_STRENGTH 1 +#endif +#ifndef PE4_DATA_STRENGTH +#define PE4_DATA_STRENGTH 1 +#endif +#ifndef PE5_DATA_STRENGTH +#define PE5_DATA_STRENGTH 1 +#endif +#ifndef PE6_DATA_STRENGTH +#define PE6_DATA_STRENGTH 1 +#endif +#ifndef PE7_DATA_STRENGTH +#define PE7_DATA_STRENGTH 1 +#endif + +#ifndef PE0_DATA_OUT +#define PE0_DATA_OUT 0 +#endif +#ifndef PE1_DATA_OUT +#define PE1_DATA_OUT 0 +#endif +#ifndef PE2_DATA_OUT +#define PE2_DATA_OUT 0 +#endif +#ifndef PE3_DATA_OUT +#define PE3_DATA_OUT 0 +#endif +#ifndef PE4_DATA_OUT +#define PE4_DATA_OUT 0 +#endif +#ifndef PE5_DATA_OUT +#define PE5_DATA_OUT 0 +#endif +#ifndef PE6_DATA_OUT +#define PE6_DATA_OUT 0 +#endif +#ifndef PE7_DATA_OUT +#define PE7_DATA_OUT 0 +#endif + +#ifndef PE0_FUNC +#define PE0_FUNC AS_GPIO +#endif +#ifndef PE1_FUNC +#define PE1_FUNC AS_GPIO +#endif +#ifndef PE2_FUNC +#define PE2_FUNC AS_GPIO +#endif +#ifndef PE3_FUNC +#define PE3_FUNC AS_GPIO +#endif +#ifndef PE4_FUNC +#define PE4_FUNC AS_GPIO +#endif +#ifndef PE5_FUNC +#define PE5_FUNC AS_GPIO +#endif +#ifndef PE6_FUNC +#define PE6_FUNC AS_TMS +#endif +#ifndef PE7_FUNC +#define PE7_FUNC AS_TCK +#endif +#ifndef PULL_WAKEUP_SRC_PE0 +#define PULL_WAKEUP_SRC_PE0 0 +#endif +#ifndef PULL_WAKEUP_SRC_PE1 +#define PULL_WAKEUP_SRC_PE1 0 +#endif +#ifndef PULL_WAKEUP_SRC_PE2 +#define PULL_WAKEUP_SRC_PE2 0 +#endif +#ifndef PULL_WAKEUP_SRC_PE3 +#define PULL_WAKEUP_SRC_PE3 0 +#endif +#ifndef PULL_WAKEUP_SRC_PE4 +#define PULL_WAKEUP_SRC_PE4 0 +#endif +#ifndef PULL_WAKEUP_SRC_PE5 +#define PULL_WAKEUP_SRC_PE5 0 +#endif +#ifndef PULL_WAKEUP_SRC_PE6 +#define PULL_WAKEUP_SRC_PE6 0 +#endif +#ifndef PULL_WAKEUP_SRC_PE7 +#define PULL_WAKEUP_SRC_PE7 0 +#endif +////////////////////////////////////////////////// +#ifndef PF0_INPUT_ENABLE +#define PF0_INPUT_ENABLE 1 //MSPI +#endif +#ifndef PF1_INPUT_ENABLE +#define PF1_INPUT_ENABLE 1 //MSPI +#endif +#ifndef PF2_INPUT_ENABLE +#define PF2_INPUT_ENABLE 1 //MSPI +#endif +#ifndef PF3_INPUT_ENABLE +#define PF3_INPUT_ENABLE 1 //MSPI +#endif +#ifndef PF4_INPUT_ENABLE +#define PF4_INPUT_ENABLE 1 //MSPI +#endif +#ifndef PF5_INPUT_ENABLE +#define PF5_INPUT_ENABLE 1 //MSPI +#endif +#ifndef PF0_OUTPUT_ENABLE +#define PF0_OUTPUT_ENABLE 0 +#endif +#ifndef PF1_OUTPUT_ENABLE +#define PF1_OUTPUT_ENABLE 0 +#endif +#ifndef PF2_OUTPUT_ENABLE +#define PF2_OUTPUT_ENABLE 0 +#endif +#ifndef PF3_OUTPUT_ENABLE +#define PF3_OUTPUT_ENABLE 0 +#endif +#ifndef PF4_OUTPUT_ENABLE +#define PF4_OUTPUT_ENABLE 0 +#endif +#ifndef PF5_OUTPUT_ENABLE +#define PF5_OUTPUT_ENABLE 0 +#endif + +#ifndef PF0_DATA_STRENGTH +#define PF0_DATA_STRENGTH 1 +#endif +#ifndef PF1_DATA_STRENGTH +#define PF1_DATA_STRENGTH 1 +#endif +#ifndef PF2_DATA_STRENGTH +#define PF2_DATA_STRENGTH 1 +#endif +#ifndef PF3_DATA_STRENGTH +#define PF3_DATA_STRENGTH 1 +#endif +#ifndef PF4_DATA_STRENGTH +#define PF4_DATA_STRENGTH 1 +#endif +#ifndef PF5_DATA_STRENGTH +#define PF5_DATA_STRENGTH 1 +#endif + +#ifndef PF0_DATA_OUT +#define PF0_DATA_OUT 0 +#endif +#ifndef PF1_DATA_OUT +#define PF1_DATA_OUT 0 +#endif +#ifndef PF2_DATA_OUT +#define PF2_DATA_OUT 0 +#endif +#ifndef PF3_DATA_OUT +#define PF3_DATA_OUT 0 +#endif +#ifndef PF4_DATA_OUT +#define PF4_DATA_OUT 0 +#endif +#ifndef PF5_DATA_OUT +#define PF5_DATA_OUT 0 +#endif + +#ifndef PF0_FUNC +#define PF0_FUNC AS_MSPI +#endif +#ifndef PF1_FUNC +#define PF1_FUNC AS_MSPI +#endif +#ifndef PF2_FUNC +#define PF2_FUNC AS_MSPI +#endif +#ifndef PF3_FUNC +#define PF3_FUNC AS_MSPI +#endif +#ifndef PF4_FUNC +#define PF4_FUNC AS_MSPI +#endif +#ifndef PF5_FUNC +#define PF5_FUNC AS_MSPI +#endif + +/** + * @brief This function servers to initiate pull up-down resistor of all gpio. + * @param[in] none + * @return none. + * @attention Processing methods of unused GPIO + * Set it to high resistance state and set it to open pull-up or pull-down resistance to + * let it be in the determined state.When GPIO uses internal pull-up or pull-down resistance, + * do not use pull-up or pull-down resistance on the board in the process of practical + * application because it may have the risk of electric leakage . + */ +static inline void gpio_analog_resistance_init(void) +{ + //A<3:0> + analog_write_reg8 (0x0e, PULL_WAKEUP_SRC_PA0 | + (PULL_WAKEUP_SRC_PA1<<2) | + (PULL_WAKEUP_SRC_PA2<<4) | + (PULL_WAKEUP_SRC_PA3<<6)); + //A<7:4> + analog_write_reg8 (0x0f, PULL_WAKEUP_SRC_PA4 | + (PULL_WAKEUP_SRC_PA5<<2) | + (PULL_WAKEUP_SRC_PA6<<4) | + (PULL_WAKEUP_SRC_PA7<<6)); + //B<3:0> + analog_write_reg8 (0x10, PULL_WAKEUP_SRC_PB0 | + (PULL_WAKEUP_SRC_PB1<<2) | + (PULL_WAKEUP_SRC_PB2<<4) | + (PULL_WAKEUP_SRC_PB3<<6)); + //B<7:4> + analog_write_reg8 (0x11, PULL_WAKEUP_SRC_PB4 | + (PULL_WAKEUP_SRC_PB5<<2) | + (PULL_WAKEUP_SRC_PB6<<4) | + (PULL_WAKEUP_SRC_PB7<<6)); + + //C<3:0> + analog_write_reg8 (0x12, PULL_WAKEUP_SRC_PC0 | + (PULL_WAKEUP_SRC_PC1<<2) | + (PULL_WAKEUP_SRC_PC2<<4) | + (PULL_WAKEUP_SRC_PC3<<6)); + //C<7:4> + analog_write_reg8 (0x13, PULL_WAKEUP_SRC_PC4 | + (PULL_WAKEUP_SRC_PC5<<2) | + (PULL_WAKEUP_SRC_PC6<<4) | + (PULL_WAKEUP_SRC_PC7<<6)); + + //D<3:0> + analog_write_reg8 (0x14, PULL_WAKEUP_SRC_PD0 | + (PULL_WAKEUP_SRC_PD1<<2) | + (PULL_WAKEUP_SRC_PD2<<4) | + (PULL_WAKEUP_SRC_PD3<<6)); + //D<7:4> + analog_write_reg8 (0x15, PULL_WAKEUP_SRC_PD4 | + (PULL_WAKEUP_SRC_PD5<<2) | + (PULL_WAKEUP_SRC_PD6<<4) | + (PULL_WAKEUP_SRC_PD7<<6)); + //E<3:0> + analog_write_reg8 (0x16, PULL_WAKEUP_SRC_PE0 | + (PULL_WAKEUP_SRC_PE1<<2) | + (PULL_WAKEUP_SRC_PE2<<4) | + (PULL_WAKEUP_SRC_PE3<<6)); + //E<7:4> + analog_write_reg8 (0x17, PULL_WAKEUP_SRC_PE4 | + (PULL_WAKEUP_SRC_PE5<<2) | + (PULL_WAKEUP_SRC_PE6<<4) | + (PULL_WAKEUP_SRC_PE7<<6)); +} + + +_attribute_ram_code_sec_ +static inline void gpio_init(int anaRes_init_en) +{ + //PA group + reg_gpio_pa_setting1 = + (PA0_INPUT_ENABLE<<8) | (PA1_INPUT_ENABLE<<9) | (PA2_INPUT_ENABLE<<10) | (PA3_INPUT_ENABLE<<11) | + (PA4_INPUT_ENABLE<<12) | (PA5_INPUT_ENABLE<<13) | (PA6_INPUT_ENABLE<<14) | (PA7_INPUT_ENABLE<<15) | + ((PA0_OUTPUT_ENABLE?0:1)<<16) | ((PA1_OUTPUT_ENABLE?0:1)<<17) | ((PA2_OUTPUT_ENABLE?0:1)<<18) | ((PA3_OUTPUT_ENABLE?0:1)<<19) | + ((PA4_OUTPUT_ENABLE?0:1)<<20) | ((PA5_OUTPUT_ENABLE?0:1)<<21) | ((PA6_OUTPUT_ENABLE?0:1)<<22) | ((PA7_OUTPUT_ENABLE?0:1)<<23) | + (PA0_DATA_OUT<<24) | (PA1_DATA_OUT<<25) | (PA2_DATA_OUT<<26) | (PA3_DATA_OUT<<27) | + (PA4_DATA_OUT<<28) | (PA5_DATA_OUT<<29) | (PA6_DATA_OUT<<30) | (PA7_DATA_OUT<<31) ; + reg_gpio_pa_setting2 = + (PA0_DATA_STRENGTH<<8) | (PA1_DATA_STRENGTH<<9)| (PA2_DATA_STRENGTH<<10) | (PA3_DATA_STRENGTH<<11) | + (PA4_DATA_STRENGTH<<12) | (PA5_DATA_STRENGTH<<13) | (PA6_DATA_STRENGTH<<14) | (PA7_DATA_STRENGTH<<15) | + (PA0_FUNC==AS_GPIO ? BIT(16):0) | (PA1_FUNC==AS_GPIO ? BIT(17):0)| (PA2_FUNC==AS_GPIO ? BIT(18):0)| (PA3_FUNC==AS_GPIO ? BIT(19):0) | + (PA4_FUNC==AS_GPIO ? BIT(20):0) | (PA5_FUNC==AS_GPIO ? BIT(21):0)| (PA6_FUNC==AS_GPIO ? BIT(22):0)| (PA7_FUNC==AS_GPIO ? BIT(23):0); + + //PB group + reg_gpio_pb_setting1 = + (PB0_INPUT_ENABLE<<8) | (PB1_INPUT_ENABLE<<9) | (PB2_INPUT_ENABLE<<10) | (PB3_INPUT_ENABLE<<11) | + (PB4_INPUT_ENABLE<<12) | (PB5_INPUT_ENABLE<<13) | (PB6_INPUT_ENABLE<<14) | (PB7_INPUT_ENABLE<<15) | + ((PB0_OUTPUT_ENABLE?0:1)<<16) | ((PB1_OUTPUT_ENABLE?0:1)<<17) | ((PB2_OUTPUT_ENABLE?0:1)<<18) | ((PB3_OUTPUT_ENABLE?0:1)<<19) | + ((PB4_OUTPUT_ENABLE?0:1)<<20) | ((PB5_OUTPUT_ENABLE?0:1)<<21) | ((PB6_OUTPUT_ENABLE?0:1)<<22) | ((PB7_OUTPUT_ENABLE?0:1)<<23) | + (PB0_DATA_OUT<<24) | (PB1_DATA_OUT<<25) | (PB2_DATA_OUT<<26) | (PB3_DATA_OUT<<27) | + (PB4_DATA_OUT<<28) | (PB5_DATA_OUT<<29) | (PB6_DATA_OUT<<30) | (PB7_DATA_OUT<<31) ; + reg_gpio_pb_setting2 = + (PB0_DATA_STRENGTH<<8) | (PB1_DATA_STRENGTH<<9)| (PB2_DATA_STRENGTH<<10) | (PB3_DATA_STRENGTH<<11) | + (PB4_DATA_STRENGTH<<12) | (PB5_DATA_STRENGTH<<13) | (PB6_DATA_STRENGTH<<14) | (PB7_DATA_STRENGTH<<15) | + (PB0_FUNC==AS_GPIO ? BIT(16):0) | (PB1_FUNC==AS_GPIO ? BIT(17):0)| (PB2_FUNC==AS_GPIO ? BIT(18):0)| (PB3_FUNC==AS_GPIO ? BIT(19):0) | + (PB4_FUNC==AS_GPIO ? BIT(20):0) | (PB5_FUNC==AS_GPIO ? BIT(21):0)| (PB6_FUNC==AS_GPIO ? BIT(22):0)| (PB7_FUNC==AS_GPIO ? BIT(23):0); + + //PC group + //ie + analog_write_reg8(areg_gpio_pc_ie, (PC0_INPUT_ENABLE<<0) | (PC1_INPUT_ENABLE<<1) | (PC2_INPUT_ENABLE<<2) | (PC3_INPUT_ENABLE<<3) | + (PC4_INPUT_ENABLE<<4) | (PC5_INPUT_ENABLE<<5) | (PC6_INPUT_ENABLE<<6) | (PC7_INPUT_ENABLE<<7) ); + + //oen + reg_gpio_pc_oen = + ((PC0_OUTPUT_ENABLE?0:1)<<0) | ((PC1_OUTPUT_ENABLE?0:1)<<1) | ((PC2_OUTPUT_ENABLE?0:1)<<2) | ((PC3_OUTPUT_ENABLE?0:1)<<3) | + ((PC4_OUTPUT_ENABLE?0:1)<<4) | ((PC5_OUTPUT_ENABLE?0:1)<<5) | ((PC6_OUTPUT_ENABLE?0:1)<<6) | ((PC7_OUTPUT_ENABLE?0:1)<<7); + //dataO + reg_gpio_pc_out = + (PC0_DATA_OUT<<0) | (PC1_DATA_OUT<<1) | (PC2_DATA_OUT<<2) | (PC3_DATA_OUT<<3) | + (PC4_DATA_OUT<<4) | (PC5_DATA_OUT<<5) | (PC6_DATA_OUT<<6) | (PC7_DATA_OUT<<7) ; + + //ds + analog_write_reg8(areg_gpio_pc_ds, (PC0_DATA_STRENGTH<<0) | (PC1_DATA_STRENGTH<<1) | (PC2_DATA_STRENGTH<<2) | (PC3_DATA_STRENGTH<<3) | + (PC4_DATA_STRENGTH<<4) | (PC5_DATA_STRENGTH<<5) | (PC6_DATA_STRENGTH<<6) | (PC7_DATA_STRENGTH<<7) ); + + reg_gpio_pc_gpio = + (PC0_FUNC==AS_GPIO ? BIT(0):0) | (PC1_FUNC==AS_GPIO ? BIT(1):0)| (PC2_FUNC==AS_GPIO ? BIT(2):0)| (PC3_FUNC==AS_GPIO ? BIT(3):0) | + (PC4_FUNC==AS_GPIO ? BIT(4):0) | (PC5_FUNC==AS_GPIO ? BIT(5):0)| (PC6_FUNC==AS_GPIO ? BIT(6):0)| (PC7_FUNC==AS_GPIO ? BIT(7):0); + + //PD group + //ie + analog_write_reg8(areg_gpio_pd_ie, (PD0_INPUT_ENABLE<<0) | (PD1_INPUT_ENABLE<<1) | (PD2_INPUT_ENABLE<<2) | (PD3_INPUT_ENABLE<<3) | + (PD4_INPUT_ENABLE<<4) | (PD5_INPUT_ENABLE<<5) | (PD6_INPUT_ENABLE<<6) | (PD7_INPUT_ENABLE<<7) ); + + //oen + reg_gpio_pd_oen = + ((PD0_OUTPUT_ENABLE?0:1)<<0) | ((PD1_OUTPUT_ENABLE?0:1)<<1) | ((PD2_OUTPUT_ENABLE?0:1)<<2) | ((PD3_OUTPUT_ENABLE?0:1)<<3) | + ((PD4_OUTPUT_ENABLE?0:1)<<4) | ((PD5_OUTPUT_ENABLE?0:1)<<5) | ((PD6_OUTPUT_ENABLE?0:1)<<6) | ((PD7_OUTPUT_ENABLE?0:1)<<7); + //dataO + reg_gpio_pd_out = + (PD0_DATA_OUT<<0) | (PD1_DATA_OUT<<1) | (PD2_DATA_OUT<<2) | (PD3_DATA_OUT<<3) | + (PD4_DATA_OUT<<4) | (PD5_DATA_OUT<<5) | (PD6_DATA_OUT<<6) | (PD7_DATA_OUT<<7) ; + + //ds + analog_write_reg8(areg_gpio_pd_ds, (PD0_DATA_STRENGTH<<0) | (PD1_DATA_STRENGTH<<1) | (PD2_DATA_STRENGTH<<2) | (PD3_DATA_STRENGTH<<3) | + (PD4_DATA_STRENGTH<<4) | (PD5_DATA_STRENGTH<<5) | (PD6_DATA_STRENGTH<<6) | (PD7_DATA_STRENGTH<<7) ); + + reg_gpio_pd_gpio = + (PD0_FUNC==AS_GPIO ? BIT(0):0) | (PD1_FUNC==AS_GPIO ? BIT(1):0)| (PD2_FUNC==AS_GPIO ? BIT(2):0)| (PD3_FUNC==AS_GPIO ? BIT(3):0) | + (PD4_FUNC==AS_GPIO ? BIT(4):0) | (PD5_FUNC==AS_GPIO ? BIT(5):0)| (PD6_FUNC==AS_GPIO ? BIT(6):0)| (PD7_FUNC==AS_GPIO ? BIT(7):0); + + //PE group + reg_gpio_pe_setting1 = + (PE0_INPUT_ENABLE<<8) | (PE1_INPUT_ENABLE<<9) | (PE2_INPUT_ENABLE<<10) | (PE3_INPUT_ENABLE<<11) | + (PE4_INPUT_ENABLE<<12) | (PE5_INPUT_ENABLE<<13)| (PE6_INPUT_ENABLE<<14) | (PE7_INPUT_ENABLE<<15) | + ((PE0_OUTPUT_ENABLE?0:1)<<16) | ((PE1_OUTPUT_ENABLE?0:1)<<17) | ((PE2_OUTPUT_ENABLE?0:1)<<18) | ((PE3_OUTPUT_ENABLE?0:1)<<19) | + ((PE4_OUTPUT_ENABLE?0:1)<<20) | ((PE5_OUTPUT_ENABLE?0:1)<<21) | ((PE6_OUTPUT_ENABLE?0:1)<<22) | ((PE7_OUTPUT_ENABLE?0:1)<<23) | + (PE0_DATA_OUT<<24) | (PE1_DATA_OUT<<25) | (PE2_DATA_OUT<<26) | (PE3_DATA_OUT<<27) | + (PE4_DATA_OUT<<28) | (PE5_DATA_OUT<<29) | (PE6_DATA_OUT<<30) | (PE7_DATA_OUT<<31) ; + reg_gpio_pe_setting2 = + (PE0_DATA_STRENGTH<<8) | (PE1_DATA_STRENGTH<<9) | (PE2_DATA_STRENGTH<<10) | (PE3_DATA_STRENGTH<<11) | + (PE4_DATA_STRENGTH<<12) | (PE5_DATA_STRENGTH<<13) | (PE6_DATA_STRENGTH<<14) | (PE7_DATA_STRENGTH<<15) | + (PE0_FUNC==AS_GPIO ? BIT(16):0) | (PE1_FUNC==AS_GPIO ? BIT(17):0)| (PE2_FUNC==AS_GPIO ? BIT(18):0)| (PE3_FUNC==AS_GPIO ? BIT(19):0) | + (PE4_FUNC==AS_GPIO ? BIT(20):0) | (PE5_FUNC==AS_GPIO ? BIT(21):0)| (PE6_FUNC==AS_GPIO ? BIT(22):0)| (PE7_FUNC==AS_GPIO ? BIT(23):0); + + if(anaRes_init_en) + { + gpio_analog_resistance_init(); + } +} + +#endif /* DRIVERS_GPIO_SETTING_H_ */ + diff --git a/b91/b91m_ble_sdk/drivers/B91/i2c.c b/b91/b91m_ble_sdk/drivers/B91/i2c.c new file mode 100755 index 0000000..cc2d552 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/i2c.c @@ -0,0 +1,481 @@ +/******************************************************************************************************** + * @file i2c.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "i2c.h" + +static unsigned char i2c_dma_tx_chn; +static unsigned char i2c_dma_rx_chn; + +dma_config_t i2c_tx_dma_config={ + .dst_req_sel= DMA_REQ_I2C_TX,//tx req + .src_req_sel=0, + .dst_addr_ctrl=DMA_ADDR_FIX, + .src_addr_ctrl=DMA_ADDR_INCREMENT,//increment + .dstmode=DMA_HANDSHAKE_MODE,//handshake + .srcmode=DMA_NORMAL_MODE, + .dstwidth=DMA_CTR_WORD_WIDTH,//must word + .srcwidth=DMA_CTR_WORD_WIDTH,//must word + .src_burst_size=0,//must 0 + .read_num_en=0, + .priority=0, + .write_num_en=0, + .auto_en=0,//must 0 + }; +dma_config_t i2c_rx_dma_config={ + .dst_req_sel= DMA_REQ_AUDIO0_TX, + .src_req_sel=DMA_REQ_I2C_RX, + .dst_addr_ctrl=DMA_ADDR_INCREMENT, + .src_addr_ctrl=DMA_ADDR_FIX, + .dstmode=DMA_NORMAL_MODE, + .srcmode=DMA_HANDSHAKE_MODE, + .dstwidth=DMA_CTR_WORD_WIDTH,//must word + .srcwidth=DMA_CTR_WORD_WIDTH,////must word + .src_burst_size=0, + .read_num_en=0, + .priority=0, + .write_num_en=0, + .auto_en=0,//must 0 +}; + + + +/* + * This parameter is 0x20 by default, that is, each write or read API opens the stop command. + * if g_i2c_stop_en=0x00,it means every write or read API will disable stop command. + */ +unsigned char g_i2c_stop_en=0x20; + + +/** + * @brief The function of this interface is equivalent to that after the user finishes calling the write or read interface, the stop signal is not sent, + * and then the write or read command is executed again. The driver defaults that every write or read API will send a stop command at the end + * @param[in] en - Input parameters.Decide whether to disable the stop function after each write or read interface + * @return none + */ +void i2c_master_send_stop(unsigned char en) +{ + if(en==1) + { + g_i2c_stop_en=0x20; + }else{ + g_i2c_stop_en=0x00; + } + +} + + +/** + * @brief This function selects a pin port for I2C interface. + * @param[in] sda_pin - the pin port selected as I2C sda pin port. + * @param[in] scl_pin - the pin port selected as I2C scl pin port. + * @return none + */ +void i2c_set_pin(i2c_sda_pin_e sda_pin,i2c_scl_pin_e scl_pin) +{ + + unsigned char val = 0; + unsigned char mask = 0xff; + + //disable sda_pin and scl_pin gpio function. + gpio_function_dis(scl_pin); + gpio_function_dis(sda_pin); + + //enable gpio as i2c sda function. + if(sda_pin == I2C_GPIO_SDA_B3) + { + mask= (unsigned char)~(BIT(7)|BIT(6)); + val = BIT(6); + } + else if(sda_pin == I2C_GPIO_SDA_C2) + { + mask = (unsigned char)~(BIT(5)|BIT(4)); + val = 0; + } + else if(sda_pin == I2C_GPIO_SDA_E2) + { + mask = (unsigned char)~(BIT(5)|BIT(4)); + val = 0; + } + else if(sda_pin == I2C_GPIO_SDA_E3) + { + mask = (unsigned char)~(BIT(7)|BIT(6)); + val = 0; + } + + reg_gpio_func_mux(sda_pin)=(reg_gpio_func_mux(sda_pin)& mask)|val; + + + //enable gpio as i2c scl function. + if(scl_pin == I2C_GPIO_SCL_B2) + { + mask= (unsigned char)~(BIT(5)|BIT(4)); + val = BIT(4); + } + else if(scl_pin == I2C_GPIO_SCL_C1) + { + mask = (unsigned char)~(BIT(3)|BIT(2)); + val = 0; + } + else if(scl_pin == I2C_GPIO_SCL_E0) + { + mask = (unsigned char)~(BIT(1)|BIT(0)); + val = 0; + } + else if(scl_pin == I2C_GPIO_SCL_E1) + { + mask = (unsigned char)~(BIT(3)|BIT(2)); + val = 0; + } + + reg_gpio_func_mux(scl_pin)=(reg_gpio_func_mux(scl_pin)& mask)|val; + + gpio_set_up_down_res(sda_pin, GPIO_PIN_PULLUP_10K); + gpio_set_up_down_res(scl_pin, GPIO_PIN_PULLUP_10K); + gpio_input_en(sda_pin);//enable sda input + gpio_input_en(scl_pin);//enable scl input +} + +/** + * @brief This function serves to enable i2c master function. + * @param[in] none. + * @return none. + */ +void i2c_master_init(void) +{ + reg_i2c_sct0 |= FLD_I2C_MASTER; //i2c master enable. +} + + + +/** + * @brief This function serves to set the i2c clock frequency.The i2c clock is consistent with the system clock. + * @param[in] clock - the division factor of I2C clock, + * I2C frequency = System_clock / (4*DivClock). + * @return none + */ +void i2c_set_master_clk(unsigned char clock) +{ + + //i2c frequency = system_clock/(4*clock) + reg_i2c_sp = clock; + + //set enable flag. + reg_clk_en0 |= FLD_CLK0_I2C_EN; +} + + +/** + * @brief This function serves to enable slave mode. + * @param[in] id - the id of slave device.it contains write or read bit,the laster bit is write or read bit. + * ID|0x01 indicate read. ID&0xfe indicate write. + * @return none + */ +void i2c_slave_init(unsigned char id) +{ + reg_i2c_sct0 &= (~FLD_I2C_MASTER); //enable slave mode. + + reg_i2c_id = id; //defaul eagle slave ID is 0x5a +} + + +/** + * @brief The function of this API is to ensure that the data can be successfully sent out. + * @param[in] id - to set the slave ID.for kite slave ID=0x5c,for eagle slave ID=0x5a. + * @param[in] data - The data to be sent, The first three bytes can be set as the RAM address of the slave. + * @param[in] len - This length is the total length, including both the length of the slave RAM address and the length of the data to be sent. + * @return 0 : the master receive NACK after sending out the id and then send stop. 1: the master sent the data successfully,(master does not detect NACK in data phase) + */ +unsigned char i2c_master_write(unsigned char id, unsigned char *data, unsigned char len) +{ + BM_SET(reg_i2c_status,FLD_I2C_TX_CLR);//clear index + //set i2c master write. + reg_i2c_data_buf(0)=id & (~FLD_I2C_WRITE_READ_BIT); //BIT(0):R:High W:Low; + reg_i2c_sct1 = (FLD_I2C_LS_ADDR | FLD_I2C_LS_START); + while(i2c_master_busy()); + if(reg_i2c_mst&FLD_I2C_ACK_IN) + { + reg_i2c_sct1 = (FLD_I2C_LS_STOP); + while(i2c_master_busy()); + return 0; + } + reg_i2c_len = len; + //write data + unsigned int cnt = 0; + while(cnt0) + { + data[cnt] = reg_i2c_data_buf(cnt % 4); + cnt++; + } + } + while(i2c_master_busy()); + return 1; +} + + +/** + * @brief This function serves to write data and restart read data. + * @param[in] id - to set the slave ID.for kite slave ID=0x5c,for eagle slave ID=0x5a. + * @param[in] wr_data - The data to be sent, The first three bytes can be set as the RAM address of the slave. + * @param[in] wr_len - This length is the total length, including both the length of the slave RAM address and the length of the data to be sent. + * @param[in] rd_data - Store the read data + * @param[in] rd_len - The total length of the data read back. + * @return 0 : the master receive NACK after sending out the id and then send stop. 1: the master receive the data successfully. + */ +unsigned char i2c_master_write_read(unsigned char id, unsigned char *wr_data, unsigned char wr_len, unsigned char *rd_data, unsigned char rd_len) +{ + BM_SET(reg_i2c_status,FLD_I2C_TX_CLR);//clear index + //set i2c master write. + reg_i2c_data_buf(0)=id & (~FLD_I2C_WRITE_READ_BIT); //BIT(0):R:High W:Low; + reg_i2c_sct1 = (FLD_I2C_LS_ADDR | FLD_I2C_LS_START); + while(i2c_master_busy()); + if(reg_i2c_mst&FLD_I2C_ACK_IN) + { + reg_i2c_sct1 = (FLD_I2C_LS_STOP); + while(i2c_master_busy()); + return 0; + } + reg_i2c_len = wr_len; + //write data + unsigned int cnt = 0; + while(cnt0) + { + rd_data[cnt] = reg_i2c_data_buf(cnt % 4); + cnt++; + } + } + while(i2c_master_busy()); + + return 1; +} + + +/** + * @brief The function of this API is just to write data to the i2c tx_fifo by DMA. + * @param[in] id - to set the slave ID.for kite slave ID=0x5c,for eagle slave ID=0x5a. + * @param[in] data - The data to be sent, The first three bytes represent the RAM address of the slave. + * @param[in] len - This length is the total length, including both the length of the slave RAM address and the length of the data to be sent. + * @return none. + */ +void i2c_master_write_dma(unsigned char id, unsigned char *data, unsigned char len) +{ + + //set id. + reg_i2c_id = (id & (~FLD_I2C_WRITE_READ_BIT)); //BIT(0):R:High W:Low + + dma_set_size(i2c_dma_tx_chn,len,DMA_WORD_WIDTH); + dma_set_address(i2c_dma_tx_chn,(unsigned int)convert_ram_addr_cpu2bus(data),reg_i2c_data_buf0_addr); + dma_chn_en(i2c_dma_tx_chn); + + reg_i2c_len = len; + reg_i2c_sct1 = (FLD_I2C_LS_ID|FLD_I2C_LS_START|FLD_I2C_LS_DATAW |g_i2c_stop_en); + +} + +/** + * @brief This function serves to read a packet of data from the specified address of slave device. + * @param[in] id - to set the slave ID.for kite slave ID=0x5c,for eagle slave ID=0x5a. + * @param[in] rx_data - Store the read data + * @param[in] len - The total length of the data read back. + * @return none. + */ +void i2c_master_read_dma(unsigned char id, unsigned char *rx_data, unsigned char len) +{ + + reg_i2c_sct0 |= FLD_I2C_RNCK_EN; //i2c rnck enable + + //set i2c master read. + reg_i2c_id = (id | FLD_I2C_WRITE_READ_BIT); //BIT(0):R:High W:Low + + dma_set_size(i2c_dma_rx_chn,len,DMA_WORD_WIDTH); + dma_set_address(i2c_dma_rx_chn,reg_i2c_data_buf0_addr,(unsigned int)convert_ram_addr_cpu2bus(rx_data)); + dma_chn_en(i2c_dma_rx_chn); + + reg_i2c_len = len; + reg_i2c_sct1 = ( FLD_I2C_LS_ID | FLD_I2C_LS_DATAR | FLD_I2C_LS_START | FLD_I2C_LS_ID_R | g_i2c_stop_en); + +} + +/** + * @brief This function serves to send a packet of data to master device.It will trigger after the master sends the read sequence. + * @param[in] data - the pointer of tx_buff. + * @param[in] len - The total length of the data . + * @return none. + */ +void i2c_slave_set_tx_dma( unsigned char *data, unsigned char len) +{ + dma_set_address(i2c_dma_tx_chn,(unsigned int)convert_ram_addr_cpu2bus(data),reg_i2c_data_buf0_addr); + dma_set_size(i2c_dma_tx_chn,len,DMA_WORD_WIDTH); + dma_chn_en(i2c_dma_tx_chn); +} + + +/** + * @brief This function serves to receive a packet of data from master device,It will trigger after the master sends the write sequence. + * @param[in] data - the pointer of rx_buff. + * @param[in] len - The total length of the data. + * @return none. + */ +void i2c_slave_set_rx_dma(unsigned char *data, unsigned char len) +{ + dma_set_address(i2c_dma_rx_chn,reg_i2c_data_buf0_addr,(unsigned int)convert_ram_addr_cpu2bus(data)); + dma_set_size(i2c_dma_rx_chn,len,DMA_WORD_WIDTH); + dma_chn_en(i2c_dma_rx_chn); +} + + +/** + * @brief This function serves to receive data . + * @param[in] data - the data need read. + * @param[in] len - The total length of the data + * @return none + */ +void i2c_slave_read(unsigned char* data , unsigned char len ) +{ + unsigned int cnt = 0; + while(cnt0) + { + data[cnt] = reg_i2c_data_buf(cnt % 4); + cnt++; + } + } +} + +/** + * @brief This function serves to receive uart data by byte with not DMA method. + * @param[in] data - the data need send. + * @param[in] len - The total length of the data. + * @return none + */ +void i2c_slave_write(unsigned char* data , unsigned char len) +{ + i2c_clr_fifo(I2C_TX_BUFF_CLR); + unsigned int cnt = 0; + while(cnt>4; +} + + +/** + * @brief The function of this API is to Get the number of bytes in rx_buffer. + * @return The actual number of bytes in rx_buffer. + */ +static inline unsigned char i2c_get_rx_buf_cnt(void) +{ + return (reg_i2c_buf_cnt & FLD_I2C_RX_BUFCNT); +} + + +/** + * @brief The function of this API is to set the number of bytes to triggered the receive interrupt. + * Its default value is 4. We recommend setting it to 1 or 4. + * @param[in] cnt - the interrupt trigger level. + * @return none + */ +static inline void i2c_rx_irq_trig_cnt(unsigned char cnt) +{ + reg_i2c_trig &= (~FLD_I2C_RX_IRQ_TRIG_LEV); + reg_i2c_trig |= cnt; +} + +/** + * @brief The function of this interface is equivalent to that after the user finishes calling the write or read interface, the stop signal is not sent, + * and then the write or read command is executed again. The driver defaults that every write or read API will send a stop command at the end + * @param[in] en - Input parameters.Decide whether to disable the stop function after each write or read interface + * @return none + */ +void i2c_master_send_stop(unsigned char en); + +/** + * @brief This function selects a pin port for I2C interface. + * @param[in] sda_pin - the pin port selected as I2C sda pin port. + * @param[in] scl_pin - the pin port selected as I2C scl pin port. + * @return none + */ +void i2c_set_pin(i2c_sda_pin_e sda_pin,i2c_scl_pin_e scl_pin); + + +/** + * @brief This function serves to enable i2c master function. + * @return none. + */ +void i2c_master_init(void); + + +/** + * @brief This function serves to enable i2c RX/TX/MASK_RX/MASK_TX interrupt function. + * @param[in] mask - to select Interrupt type. + * @return none + */ +static inline void i2c_set_irq_mask(i2c_irq_mask_e mask) +{ + reg_i2c_sct0 |= mask; +} + +/** + * @brief This function serves to disable i2c RX/TX/MASK_RX/MASK_TX interrupt function. + * @param[in] mask - to select Interrupt type. + * @return none + */ +static inline void i2c_clr_irq_mask(i2c_irq_mask_e mask) +{ + reg_i2c_sct0 &= (~mask); +} + + +/** + * @brief This function serves to get i2c interrupt status. + * @return none + * + */ +static inline unsigned char i2c_get_irq_status(i2c_irq_status_e status) +{ + return reg_i2c_irq_status&status; +} + + +/** + * @brief This function serves to clear i2c rx/tx fifo. + * @param[in] clr - to select Interrupt type. + * @return none + */ +static inline void i2c_clr_fifo(i2c_buff_clr_e clr) +{ + reg_i2c_status = clr; +} + +/** + * @brief This function serves to clear i2c irq status. + * @return none + */ +static inline void i2c_clr_irq_status(i2c_irq_clr_e status) +{ + reg_i2c_irq_status=status; +} + + + +/** + * @brief This function serves to enable slave mode. + * @param[in] id - the id of slave device.it contains write or read bit,the laster bit is write or read bit. + * ID|0x01 indicate read. ID&0xfe indicate write. + * @return none + */ +void i2c_slave_init(unsigned char id); + + +/** + * @brief The function of this API is to ensure that the data can be successfully sent out. + * @param[in] id - to set the slave ID.for kite slave ID=0x5c,for eagle slave ID=0x5a. + * @param[in] data - The data to be sent, The first three bytes can be set as the RAM address of the slave. + * @param[in] len - This length is the total length, including both the length of the slave RAM address and the length of the data to be sent. + * @return 0 : the master receive NACK after sending out the id and then send stop. 1: the master sent the data successfully,(master does not detect NACK in data phase) + */ +unsigned char i2c_master_write(unsigned char id, unsigned char *data, unsigned char len); + + +/** + * @brief This function serves to read a packet of data from the specified address of slave device + * @param[in] id - to set the slave ID.for kite slave ID=0x5c,for eagle slave ID=0x5a. + * @param[in] data - Store the read data + * @param[in] len - The total length of the data read back. + * @return 0 : the master receive NACK after sending out the id and then send stop. 1: the master receive the data successfully. + */ +unsigned char i2c_master_read(unsigned char id, unsigned char *data, unsigned char len); + + +/** + * @brief This function serves to write data and restart read data. + * @param[in] id - to set the slave ID.for kite slave ID=0x5c,for eagle slave ID=0x5a. + * @param[in] wr_data - The data to be sent, The first three bytes can be set as the RAM address of the slave. + * @param[in] wr_len - This length is the total length, including both the length of the slave RAM address and the length of the data to be sent. + * @param[in] rd_data - Store the read data + * @param[in] rd_len - The total length of the data read back. + * @return 0 : the master receive NACK after sending out the id and then send stop. 1: the master receive the data successfully. + */ +unsigned char i2c_master_write_read(unsigned char id, unsigned char *wr_data, unsigned char wr_len, unsigned char *rd_data, unsigned char rd_len); + +/** + * @brief The function of this API is just to write data to the i2c tx_fifo by DMA. + * @param[in] id - to set the slave ID.for kite slave ID=0x5c,for eagle slave ID=0x5a. + * @param[in] data - The data to be sent, The first three bytes represent the RAM address of the slave. + * @param[in] len - This length is the total length, including both the length of the slave RAM address and the length of the data to be sent. + * @return none. + */ +void i2c_master_write_dma(unsigned char id, unsigned char *data, unsigned char len); + + + +/** + * @brief This function serves to read a packet of data from the specified address of slave device. + * @param[in] id - to set the slave ID.for kite slave ID=0x5c,for eagle slave ID=0x5a. + * @param[in] data - Store the read data + * @param[in] len - The total length of the data read back. + * @return none. + */ +void i2c_master_read_dma(unsigned char id, unsigned char *data, unsigned char len); + + + + +/** + * @brief This function serves to send a packet of data to master device.It will trigger after the master sends the read sequence. + * @param[in] data - the pointer of tx_buff. + * @param[in] len - The total length of the data . + * @return none. + */ +void i2c_slave_set_tx_dma( unsigned char *data, unsigned char len); + + + +/** + * @brief This function serves to receive a packet of data from master device,It will trigger after the master sends the write sequence. + * @param[in] data - the pointer of rx_buff. + * @param[in] len - The total length of the data. + * @return none. + */ +void i2c_slave_set_rx_dma(unsigned char *data, unsigned char len); + + +/** + * @brief This function serves to receive data . + * @param[in] data - the data need read. + * @param[in] len - The total length of the data + * @return none + */ +void i2c_slave_read(unsigned char* data , unsigned char len ); + + +/** + * @brief This function serves to receive uart data by byte with not DMA method. + * @param[in] data - the data need send. + * @param[in] len - The total length of the data. + * @return none + */ +void i2c_slave_write(unsigned char* data , unsigned char len); + + +/** + * @brief This function serves to set the i2c clock frequency.The i2c clock is consistent with the system clock. + * Currently, the default system clock is 48M, and the i2c clock is also 48M. + * @param[in] clock - the division factor of I2C clock, + * I2C frequency = System_clock / (4*DivClock). + * @return none + */ +void i2c_set_master_clk(unsigned char clock); + +/** + * @brief This function serves to set i2c tx_dam channel and config dma tx default. + * @param[in] chn: dma channel. + * @return none + */ +void i2c_set_tx_dma_config(dma_chn_e chn); + +/** + * @brief This function serves to set i2c rx_dam channel and config dma rx default. + * @param[in] chn: dma channel. + * @return none + */ +void i2c_set_rx_dma_config(dma_chn_e chn); + + +#endif + + + + + + + + + + diff --git a/b91/b91m_ble_sdk/drivers/B91/lpc.c b/b91/b91m_ble_sdk/drivers/B91/lpc.c new file mode 100755 index 0000000..5a41306 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/lpc.c @@ -0,0 +1,45 @@ +/******************************************************************************************************** + * @file lpc.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "lpc.h" + +/** + * @brief This function selects input reference voltage for low power comparator. + * @param[in] mode - lower power comparator working mode includes normal mode and low power mode. + * @param[in] ref - selected input reference voltage. + * @return none. + */ +void lpc_set_input_ref(lpc_mode_e mode,lpc_reference_e ref) +{ + if(mode == LPC_LOWPOWER) + { + analog_write_reg8(0x0b,analog_read_reg8(0x0b)|0x08); + analog_write_reg8(0x0d,analog_read_reg8(0x0d)|0x80); + } + else if(mode == LPC_NORMAL) + { + analog_write_reg8(0x0b,analog_read_reg8(0x0b)&0xf7); + analog_write_reg8(0x0d,analog_read_reg8(0x0d)&0x7f); + } + analog_write_reg8(0x0d,(analog_read_reg8(0x0d)&0x8f)|(ref<<4)); +} + diff --git a/b91/b91m_ble_sdk/drivers/B91/lpc.h b/b91/b91m_ble_sdk/drivers/B91/lpc.h new file mode 100755 index 0000000..bb08f70 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/lpc.h @@ -0,0 +1,125 @@ +/******************************************************************************************************** + * @file lpc.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "analog.h" + +/** + * define input IO. + */ +typedef enum{ + LPC_INPUT_PB1 = 1, + LPC_INPUT_PB2 = 2, + LPC_INPUT_PB3 = 3, + LPC_INPUT_PB4 = 4, + LPC_INPUT_PB5 = 5, + LPC_INPUT_PB6 = 6, + LPC_INPUT_PB7 = 7, +}lpc_input_channel_e; + +/** + * define work mode. + */ +typedef enum{ + LPC_NORMAL = 0, + LPC_LOWPOWER, +}lpc_mode_e; + +/** + * define Reference voltage. + */ +typedef enum{ + LPC_REF_974MV = 1, + LPC_REF_923MV = 2, + LPC_REF_872MV = 3, + LPC_REF_820MV = 4, + LPC_REF_PB0 = 5, + LPC_REF_PB3 = 6, +}lpc_reference_e; + +/** + * define scale. + */ +typedef enum{ + LPC_SCALING_PER25 = 0, + LPC_SCALING_PER50 = 1, + LPC_SCALING_PER75 = 2, + LPC_SCALING_PER100 = 3, +}lpc_scaling_e; + +/** + * @brief This function servers to powers down low power comparator. + * @return none. + */ +static inline void lpc_power_down(void) +{ + analog_write_reg8(0x07,(analog_read_reg8(0x07))|0x08); +} + +/** + * @brief This function servers to power on low power comparator. + * @return none. + */ +static inline void lpc_power_on(void) +{ + analog_write_reg8(0x06,analog_read_reg8(0x06) & 0xfd); +} + +/** + * @brief This function selects input channel for low power comparator. + * @param[in] pin - selected input channel.Input derived from external PortB(PB<1>~PB<7>). + * @return none. + */ +static inline void lpc_set_input_chn(lpc_input_channel_e pin) +{ + analog_write_reg8(0x0d,(analog_read_reg8(0x0d) & 0xf8) | pin); +} + +/** + * @brief This function serves to set scaling_coefficient for low power comparator. + * @param[in] divider - selected scaling coefficient.(%25,%50,%75,%100) + * @return none. + */ +static inline void lpc_set_scaling_coeff(lpc_scaling_e divider) +{ + analog_write_reg8(0x0b,(analog_read_reg8(0x0b)&0xcf)|(divider<<4)); +} + +/** + * @brief This function serves to get the comparison results.if Vin>Vref 0x88[6]=0,else 0x88[6]=1. + * @return comparison results. + */ +static inline unsigned char lpc_get_result(void) +{ + return ((analog_read_reg8(0x88)&0x40)>>6); +} + +/** + * @brief This function selects input reference voltage for low power comparator. + * @param[in] mode - lower power comparator working mode includes normal mode and low power mode. + * @param[in] ref - selected input reference voltage. + * @return none. + */ +void lpc_set_input_ref(lpc_mode_e mode, lpc_reference_e ref); + + diff --git a/b91/b91m_ble_sdk/drivers/B91/mdec.c b/b91/b91m_ble_sdk/drivers/B91/mdec.c new file mode 100755 index 0000000..a959007 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/mdec.c @@ -0,0 +1,66 @@ +/******************************************************************************************************** + * @file mdec.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include"mdec.h" +#include "compiler.h" +#include "reg_include/mdec_reg.h" +#include "analog.h" +#include "clock.h" + +/** + * @brief This function is used to initialize the MDEC module,include clock setting and input IO select. + * @param[in] pin - mdec pin. + * In order to distinguish which pin the data is input from,only one input pin can be selected one time. + * @return none. + */ +void mdec_init(mdec_pin_e pin) +{ + analog_write_reg8(mdec_rst_addr,(analog_read_reg8(mdec_rst_addr) & (~FLD_CLS_MDEC)) | pin);//A0/B7/C4/D0/E0 +} + +/** + * @brief This function is used to read the receive data of MDEC module's IO. + * @param[out] dat - The array to store date. + * @return 1 decode success, 0 decode failure. + */ +unsigned char mdec_read_dat(unsigned char *dat) +{ + unsigned char m0,m1,m2,data_crc; + + dat[0]=analog_read_reg8(0x6a); + dat[1]=analog_read_reg8(0x6b); + dat[2]=analog_read_reg8(0x6c); + dat[3]=analog_read_reg8(0x6d); + dat[4]=analog_read_reg8(0x6e); + + m0= ((dat[0]>>5)<<4); + m1= dat[0]&0x07; + m2= m0+m1; + data_crc=(((m2+dat[1])^dat[2])+dat[3])^0xa5; + + if(data_crc==dat[4]){ + return 1; + } + return 0; +} + + diff --git a/b91/b91m_ble_sdk/drivers/B91/mdec.h b/b91/b91m_ble_sdk/drivers/B91/mdec.h new file mode 100755 index 0000000..b3c7db8 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/mdec.h @@ -0,0 +1,77 @@ +/******************************************************************************************************** + * @file mdec.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "analog.h" +#include "reg_include/mdec_reg.h" + +/** + * @brief This function servers to reset the MDEC module.When the system is wakeup by MDEC, you should + * to reset the MDEC module to clear the flag bit of MDEC wakeup. + * @return none. + */ +static inline void mdec_reset(void) +{ + analog_write_reg8(mdec_rst_addr,analog_read_reg8(mdec_rst_addr) | FLD_MDEC_RST); + analog_write_reg8(mdec_rst_addr,analog_read_reg8(mdec_rst_addr) & (~FLD_MDEC_RST)); +} + +/** + * @brief After all packet data are received, it can check whether packet transmission is finished. + * @param[in] status - the interrupt status to be obtained. + * @return irq status. + */ +static inline unsigned char mdec_get_irq_status(wakeup_status_e status) +{ + return (analog_read_reg8(reg_wakeup_status) & status); +} + +/** + * @brief This function serves to clear the wake mdec bit.After all packet + * data are received, corresponding flag bit will be set as 1. + * needed to manually clear this flag bit so as to avoid misjudgment. + * @param[in] status - the interrupt status that needs to be cleared. + * @return none. + */ +static inline void mdec_clr_irq_status(wakeup_status_e status) +{ + analog_write_reg8(reg_wakeup_status, (analog_read_reg8(reg_wakeup_status) | status)); +} + +/** + * @brief This function is used to initialize the MDEC module,include clock setting and input IO select. + * @param[in] pin - mdec pin. + * In order to distinguish which pin the data is input from,only one input pin can be selected one time. + * @return none. + */ +void mdec_init(mdec_pin_e pin); + +/** + * @brief This function is used to read the receive data of MDEC module's IO. + * @param[out] dat - The array to store date. + * @return 1 decode success, 0 decode failure. + */ +unsigned char mdec_read_dat(unsigned char *dat); + + + diff --git a/b91/b91m_ble_sdk/drivers/B91/mspi.h b/b91/b91m_ble_sdk/drivers/B91/mspi.h new file mode 100755 index 0000000..3195567 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/mspi.h @@ -0,0 +1,117 @@ +/******************************************************************************************************** + * @file mspi.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "compiler.h" +#include "gpio.h" +#include "reg_include/mspi_reg.h" + +/** + * @brief This function servers to set the spi wait. + * @return none. + */ +_attribute_ram_code_sec_ static inline void mspi_wait(void){ + while(reg_mspi_status & FLD_MSPI_BUSY); +} + +/** + * @brief This function servers to enable read triggle spi. + * @return none. + */ +_attribute_ram_code_sec_ static inline void mspi_fm_rd_en(void){ + reg_mspi_fm |= FLD_MSPI_RD_TRIG_EN; +} + +/** + * @brief This function servers to disable read triggle spi. + * @return none. + */ +_attribute_ram_code_sec_ static inline void mspi_fm_rd_dis(void){ + reg_mspi_fm &= ~FLD_MSPI_RD_TRIG_EN; +} + +/** + * @brief This function servers to set spi interface csn signal. + * @return none. + */ +_attribute_ram_code_sec_ static inline void mspi_high(void){ + reg_mspi_fm |= FLD_MSPI_CSN; +} + +/** + * @brief This function servers to clear spi interface csn signal. + * @return none. + */ +_attribute_ram_code_sec_ static inline void mspi_low(void){ + reg_mspi_fm &= ~FLD_MSPI_CSN; +} + +/** + * @brief This function servers to gets the spi data. + * @return the spi data. + */ +_attribute_ram_code_sec_ static inline unsigned char mspi_get(void){ + return reg_mspi_data; +} + +/** + * @brief This function servers to write the spi. + * @param[in] c - the char need to be write. + * @return none. + */ +_attribute_ram_code_sec_ static inline void mspi_write(unsigned char c){ + reg_mspi_data = c; +} + +/** + * @brief This function servers to control the write. + * @param[in] c - need to be write. + * @return none. + */ +_attribute_ram_code_sec_ static inline void mspi_fm_write(unsigned char c){ + reg_mspi_fm = c; +} + +/** + * @brief This function servers to spi read. + * @return read result. + */ +_attribute_ram_code_sec_ static inline unsigned char mspi_read(void){ + mspi_write(0); // dummy, issue clock + mspi_wait(); + return mspi_get(); +} + +/** + * @brief This function serves to Stop XIP operation before flash. + * @return none. + */ +_attribute_ram_code_sec_ static inline void mspi_stop_xip(void) +{ + mspi_wait(); //wait xip busy=0 + mspi_high(); //mspi_cn=1, stop xip read + while(gpio_get_level(GPIO_PF3) == 0); //wait cn=1 +} + + + diff --git a/b91/b91m_ble_sdk/drivers/B91/npe.c b/b91/b91m_ble_sdk/drivers/B91/npe.c new file mode 100755 index 0000000..72d036d --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/npe.c @@ -0,0 +1,46 @@ +/******************************************************************************************************** + * @file npe.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "npe.h" + + +/** +We don't know the meaning of the register, so let's them together + */ + +void npe_set_reg(void) +{ + reg_npe_0x84=0xffff; + reg_npe_0x74=0x03000000; + reg_npe_0x80=0x100; + reg_npe_0x40=0x100; + +} +/** +npe set config + */ +void npe_set_config(unsigned int desc_pointer ) +{ + reg_npe_0x6c=desc_pointer; + + npe_set_reg(); +} diff --git a/b91/b91m_ble_sdk/drivers/B91/npe.h b/b91/b91m_ble_sdk/drivers/B91/npe.h new file mode 100755 index 0000000..9d2481e --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/npe.h @@ -0,0 +1,30 @@ +/******************************************************************************************************** + * @file npe.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef NPE_H_ +#define NPE_H_ +#include "reg_include/npe_reg.h" + +void npe_set_reg(void); +void npe_set_config(unsigned int desc_pointer ); + +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/pke.c b/b91/b91m_ble_sdk/drivers/B91/pke.c new file mode 100755 index 0000000..2aeb676 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/pke.c @@ -0,0 +1,887 @@ +/******************************************************************************************************** + * @file pke.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "pke.h" +#include "string.h" + +/** + * @brief get real bit length of big number a of wordLen words. + * @param[in] a - the buffer a. + * @param[in] wordLen - the length of a. + * @return the real bit length of big number a of wordLen words. + */ +unsigned int valid_bits_get(const unsigned int *a, unsigned int wordLen) +{ + unsigned int i = 0; + unsigned int j = 0; + + if(0 == wordLen) + { + return 0; + } + + for (i = wordLen; i > 0; i--) + { + if (a[i - 1]) + { + break; + } + } + + if(0 == i) + { + return 0; + } + + for (j = 32; j > 0; j--) + { + if (a[i - 1] & (0x1 << (j - 1))) + { + break; + } + } + + return ((i - 1) << 5) + j; +} + +/** + * @brief get real word lenth of big number a of max_words words. + * @param[in] a - the buffer a. + * @param[in] max_words - the length of a. + * @return get real word lenth of big number a. + */ +unsigned int valid_words_get(unsigned int *a, unsigned int max_words) +{ + unsigned int i = 0; + + for (i = max_words; i > 0; i--) + { + if (a[i - 1]) + { + return i; + } + } + + return 0; +} + +/** + * @brief compare big integer a and b. + * @param[in] a - value. + * @param[in] aWordLen - the length of a. + * @param[in] b - value. + * @param[in] bWordLen - the length of b. + * @return 0:a=b, 1:a>b, -1: a bWordLen) + return 1; + if(aWordLen < bWordLen) + return -1; + + for(i=(aWordLen-1); i>=0; i--) + { + if(a[i] > b[i]) + return 1; + if(a[i] < b[i]) + return -1; + } + + return 0; +} + +/** + * @brief c = a - b. + * @param[in] a - integer a. + * @param[in] b - integer b. + * @param[in] wordLen - the length of a and b. + * @param[out] c - integer c = a - b. + * @return none. + */ +void sub_u32(unsigned int *a, unsigned int *b, unsigned int *c, unsigned int wordLen) +{ + unsigned int i, carry, temp; + + carry = 0; + for(i=0; i a[i] || c[i] > temp) + { + carry = 1; + } + else + { + carry = 0; + } + } +} + +/** + * @brief a = a/(2^n). + * @param[in] a - big integer a. + * @param[in] aWordLen - word length of a. + * @param[in] n - exponent of 2^n. + * @return word length of a = a/(2^n). + * @attention: 1. make sure aWordLen is real word length of a. + * 2. a may be 0, then aWordLen is 0, to make sure aWordLen-1 is available, so data + * type of aWordLen is int32_t, not uint32_t. + */ +unsigned int div2n_u32(unsigned int a[], signed int aWordLen, unsigned int n) +{ + signed int i; + unsigned int j; + + if(!aWordLen) + return 0; + + if(n <= 32) + { + for(i=0; i>= n; + a[i] |= (a[i+1]<<(32-n)); + } + a[i] >>= n; + + if(!a[i]) + return i; + return aWordLen; + } + else //general method + { + j = n>>5; + n &= 31; + for(i=0; i>n; + a[i] |= (a[i+j+1]<<(32-n)); + } + a[i] = a[i+j]>>n; + memset(a+aWordLen-j, 0, j<<2); + + if(!a[i]) + return i; + return aWordLen - j; + } +} + +/** + * @brief get result operand from specified addr. + * @param[in] baseaddr - the address. + * @param[in] data - the buffer data. + * @param[in] wordLen - the length of data. + * @return none. + */ +void pke_read_operand(unsigned int *baseaddr, unsigned int *data, unsigned int wordLen) +{ + unsigned int i; + + if(baseaddr != data) + { + for (i = 0; i < wordLen; i++) + { + data[i] = baseaddr[i]; + } + } +} + +/** + * @brief load operand to specified addr. + * @param[in] data - the buffer data. + * @param[in] wordLen - the length of data. + * @param[out] baseaddr - the address. + * @return none. + */ +void pke_load_operand(unsigned int *baseaddr, unsigned int *data, unsigned int wordLen) +{ + unsigned int i; + + if(baseaddr != data) + { + for (i = 0; i < wordLen; i++) + { + baseaddr[i] = data[i]; + } + for (i = wordLen; i < 9; i++) + { + baseaddr[i] = 0x00000000; + } + } +} + +/** + * @brief This function is to complete the calculation of the corresponding function of the PKE module. + * @param[in] addr - micro code. + * @param[in] cfg - pke exe cfg. + * @return 0 - normal stop. + * 1 - received a termination request(CTRL.STOP is high). + * 2 - no valid modulo inverse. + * 3 - point is not on the curve(CTRL.CMD:PVER). + * 4 - invalid microcode. + */ +unsigned char pke_opr_cal(pke_microcode_e addr, pke_exe_cfg_e cfg) +{ + pke_set_microcode(addr); + + if(0x00 != cfg) + pke_set_exe_cfg(cfg); + + pke_clr_irq_status(FLD_PKE_STAT_DONE); + + pke_opr_start(); + + while(!pke_get_irq_status(FLD_PKE_STAT_DONE)){} //0(in progress) 1(done)) + + return (pke_check_rt_code()); +} + +/** + * @brief load the pre-calculated mont parameters H(R^2 mod modulus) and + * n1( - modulus ^(-1) mod 2^w ). + * @param[in] H - R^2 mod modulus. + * @param[in] n1 - modulus ^(-1) mod 2^w, here w is 32 acutally. + * @param[in] wordLen - word length of modulus or H. + * @return: none. + */ +void pke_load_pre_calc_mont(unsigned int *H, unsigned int *n1, unsigned int wordLen) +{ + pke_set_operand_width(wordLen<<5); + + pke_load_operand((unsigned int *)reg_pke_a_ram(3), H, wordLen); + pke_load_operand((unsigned int *)reg_pke_b_ram(4), n1, 1); +} + +/** + * @brief calc h(R^2 mod modulus) and n1( - modulus ^(-1) mod 2^w ) for modmul, pointMul. etc. + * here w is bit width of word, i,e. 32. + * @param[in] modulus - input, modulus. + * @param[in] wordLen - input, word length of modulus or H. + * @return PKE_SUCCESS(success), other(error). + */ +unsigned char pke_calc_pre_mont(const unsigned int *modulus, unsigned int wordLen) +{ + unsigned char ret; + + pke_set_operand_width(wordLen<<5); + + pke_load_operand((unsigned int *)reg_pke_b_ram(3), (unsigned int *)modulus, wordLen); //B3 modulus + + ret = pke_opr_cal(PKE_MICROCODE_CAL_PRE_MON, 0x00); + + return ret; +} + +/** + * @brief ECCP curve point del point, Q=2P. + * @param[in] curve - ECCP_CURVE struct pointer. + * @param[in] Px - x coordinate of point P. + * @param[in] Py - y coordinate of point P. + * @param[out] Qx - x coordinate of point Q=2P. + * @param[out] Qy - y coordinate of point Q=2P. + * @return PKE_SUCCESS(success), other(error). + */ +unsigned char pke_eccp_point_del(eccp_curve_t *curve, unsigned int *Px, unsigned int *Py, + unsigned int *Qx, unsigned int *Qy) +{ + unsigned char ret; + unsigned int wordLen = (curve->eccp_p_bitLen + 31)>>5; + + pke_set_operand_width(curve->eccp_p_bitLen); + + pke_load_operand((unsigned int *)reg_pke_a_ram(0), Px, wordLen); //A0 Px + pke_load_operand((unsigned int *)reg_pke_a_ram(1), Py, wordLen); //A1 Py + pke_load_operand((unsigned int *)reg_pke_a_ram(5), curve->eccp_a, wordLen); //A5 a + pke_load_operand((unsigned int *)reg_pke_b_ram(3), curve->eccp_p, wordLen); //B3 p + + if((0 != curve->eccp_p_h) && (0 != curve->eccp_p_n1)) + { + pke_load_operand((unsigned int *)reg_pke_a_ram(3), curve->eccp_p_h, wordLen); //A3 p_h + pke_load_operand((unsigned int *)reg_pke_b_ram(4), curve->eccp_p_n1, 1); //B4 p_n1 + } + else + { + pke_opr_cal(PKE_MICROCODE_CAL_PRE_MON, 0x00); + } + + + ret = pke_opr_cal(PKE_MICROCODE_PDBL, PKE_EXE_CFG_ALL_NON_MONT); + if(ret) + { + return ret; + } + + pke_read_operand((unsigned int *)reg_pke_a_ram(0), Qx, wordLen); + if(Qy != 0) + { + pke_read_operand((unsigned int *)reg_pke_a_ram(1), Qy, wordLen); + } + + return ret; +} + +/** + * @brief ECCP curve point add, Q=P1+P2. + * @param[in] curve - eccp curve struct pointer. + * @param[in] P1x - x coordinate of point P1. + * @param[in] P1y - y coordinate of point P1. + * @param[in] P2x - x coordinate of point P2. + * @param[in] P2y - y coordinate of point P2. + * @param[out] Qx - x coordinate of point Q=P1+P2. + * @param[out] Qy - y coordinate of point Q=P1+P2. + * @return PKE_SUCCESS(success), other(error). + */ +unsigned char pke_eccp_point_add(eccp_curve_t *curve, unsigned int *P1x, unsigned int *P1y, unsigned int *P2x, unsigned int *P2y, + unsigned int *Qx, unsigned int *Qy) +{ + unsigned char ret; + unsigned int wordLen = (curve->eccp_p_bitLen + 31)>>5; + + pke_set_operand_width(curve->eccp_p_bitLen); + + pke_load_operand((unsigned int *)reg_pke_b_ram(0), P1x, wordLen); //B0 P1x + pke_load_operand((unsigned int *)reg_pke_b_ram(1), P1y, wordLen); //B1 P1y + pke_load_operand((unsigned int *)reg_pke_a_ram(0), P2x, wordLen); //A0 P2x + pke_load_operand((unsigned int *)reg_pke_a_ram(1), P2y, wordLen); //A1 P2y + pke_load_operand((unsigned int *)reg_pke_b_ram(3), curve->eccp_p, wordLen); //B3 p + + if((0 != curve->eccp_p_h) && (0 != curve->eccp_p_n1)) + { + pke_load_operand((unsigned int *)reg_pke_a_ram(3), curve->eccp_p_h, wordLen); //A3 p_h + pke_load_operand((unsigned int *)reg_pke_b_ram(4), curve->eccp_p_n1, 1); //B4 p_n1 + } + else + { + pke_opr_cal(PKE_MICROCODE_CAL_PRE_MON, 0x00); + } + + ret = pke_opr_cal(PKE_MICROCODE_PADD, PKE_EXE_CFG_ALL_NON_MONT); + if(ret) + { + return ret; + } + + pke_read_operand((unsigned int *)reg_pke_a_ram(0), Qx, wordLen); + pke_read_operand((unsigned int *)reg_pke_a_ram(1), Qy, wordLen); + + return ret; +} + +/** + * @brief check whether the input point P is on ECCP curve or not. + * @param[in] curve - ECCP_CURVE struct pointer. + * @param[in] Px - x coordinate of point P. + * @param[in] Py - y coordinate of point P. + * @return PKE_SUCCESS(success, on the curve), other(error or not on the curve). + */ +unsigned char pke_eccp_point_verify(eccp_curve_t *curve, unsigned int *Px, unsigned int *Py) +{ + signed int ret; + unsigned int wordLen = (curve->eccp_p_bitLen + 31)>>5; + + pke_set_operand_width(curve->eccp_p_bitLen); + + pke_load_operand((unsigned int *)reg_pke_b_ram(0), Px, wordLen); //B0 Px + pke_load_operand((unsigned int *)reg_pke_b_ram(1), Py, wordLen); //B1 Py + pke_load_operand((unsigned int *)reg_pke_a_ram(5), curve->eccp_a, wordLen); //A5 a + pke_load_operand((unsigned int *)reg_pke_a_ram(4), curve->eccp_b, wordLen); //A4 b + pke_load_operand((unsigned int *)reg_pke_b_ram(3), curve->eccp_p, wordLen); //B3 p + + if((0 != curve->eccp_p_h) && (0 != curve->eccp_p_n1)) + { + pke_load_operand((unsigned int *)reg_pke_a_ram(3), curve->eccp_p_h, wordLen); //A3 p_h + pke_load_operand((unsigned int *)reg_pke_b_ram(4), curve->eccp_p_n1, 1); //B4 p_n1 + } + else + { + pke_opr_cal(PKE_MICROCODE_CAL_PRE_MON, 0x00); + } + + ret = pke_opr_cal(PKE_MICROCODE_PVER, PKE_EXE_CFG_ALL_NON_MONT); + if(ret) + { + return ret; + } + + return PKE_SUCCESS; +} + +/** + * @brief ECCP curve point mul(random point), Q=[k]P. + * @param[in] curve - ECCP_CURVE struct pointer. + * @param[in] k - scalar. + * @param[in] Px - x coordinate of point P. + * @param[in] Py - y coordinate of point P. + * @param[out] Qx - x coordinate of point Q=[k]P. + * @param[out] Qy - y coordinate of point Q=[k]P. + * @return PKE_SUCCESS(success), other(error). + */ +unsigned char pke_eccp_point_mul(eccp_curve_t *curve, unsigned int *k, unsigned int *Px, unsigned int *Py, + unsigned int *Qx, unsigned int *Qy) +{ + unsigned char ret; + unsigned int wordLen = (curve->eccp_p_bitLen + 31)>>5; + + pke_set_operand_width(curve->eccp_p_bitLen); + + pke_load_operand((unsigned int *)reg_pke_b_ram(0), Px, wordLen); //B0 Px + pke_load_operand((unsigned int *)reg_pke_b_ram(1), Py, wordLen); //B1 Py + pke_load_operand((unsigned int *)reg_pke_a_ram(5), curve->eccp_a, wordLen); //A5 a + pke_load_operand((unsigned int *)reg_pke_a_ram(4), k, wordLen); //A4 k + pke_load_operand((unsigned int *)reg_pke_b_ram(3), curve->eccp_p, wordLen); //B3 p + + if((0 != curve->eccp_p_h) && (0 != curve->eccp_p_n1)) + { + pke_load_operand((unsigned int *)reg_pke_a_ram(3), curve->eccp_p_h, wordLen); //A3 p_h + pke_load_operand((unsigned int *)reg_pke_b_ram(4), curve->eccp_p_n1, 1); //B4 p_n1 + } + else + { + pke_opr_cal(PKE_MICROCODE_CAL_PRE_MON, 0x00); + } + + + ret = pke_opr_cal(PKE_MICROCODE_PMUL, PKE_EXE_CFG_ALL_NON_MONT); + if(ret) + { + return ret; + } + + pke_read_operand((unsigned int *)reg_pke_a_ram(0), Qx, wordLen); + if(Qy != 0) + { + pke_read_operand((unsigned int *)reg_pke_a_ram(1), Qy, wordLen); + } + + return ret; +} + +/** + * @brief out = a*b mod modulus. + * @param[in] modulus - modulus. + * @param[in] a - integer a. + * @param[in] b - integer b. + * @param[in] wordLen - word length of modulus, a, b. + * @param[out] out - out = a*b mod modulus. + * @return PKE_SUCCESS(success), other(error). + */ + unsigned char pke_mod_mul(const unsigned int *modulus, const unsigned int *a, const unsigned int *b, + unsigned int *out, unsigned int wordLen) + { + unsigned char ret; + + pke_set_operand_width(wordLen<<5); + + pke_load_operand((unsigned int *)(reg_pke_b_ram(3)), (unsigned int *)modulus, wordLen); //B3 modulus + pke_load_operand((unsigned int *)(reg_pke_a_ram(0)), (unsigned int *)a, wordLen); //A0 a + pke_load_operand((unsigned int *)(reg_pke_b_ram(0)), (unsigned int *)b, wordLen); //B0 b + + ret = pke_opr_cal(PKE_MICROCODE_MODMUL, PKE_EXE_CFG_ALL_NON_MONT); + if(ret) + { + return ret; + } + + pke_read_operand((unsigned int *)(reg_pke_a_ram(0)), out, wordLen); //A0 result + + return PKE_SUCCESS; +} + +/** + * @brief ainv = a^(-1) mod modulus. + * @param[in] modulus - modulus. + * @param[in] a - integer a. + * @param[in] modWordLen - word length of modulus, ainv. + * @param[in] aWordLen - word length of integer a. + * @param[out] ainv - ainv = a^(-1) mod modulus. + * @return: PKE_SUCCESS(success), other(inverse not exists or error). + */ + unsigned char pke_mod_inv(const unsigned int *modulus, const unsigned int *a, unsigned int *ainv, unsigned int modWordLen, + unsigned int aWordLen) + { + unsigned char ret; + + pke_set_operand_width(modWordLen<<5); + + + pke_load_operand((unsigned int *)(reg_pke_b_ram(3)), (unsigned int *)modulus, modWordLen); //B3 modulus + pke_load_operand((unsigned int *)(reg_pke_b_ram(0)), (unsigned int *)a, aWordLen); //B0 a + + ret = pke_opr_cal(PKE_MICROCODE_MODINV, 0x00); + if(ret) + { + return ret; + } + + pke_read_operand((unsigned int *)(reg_pke_a_ram(0)), (unsigned int *)ainv, modWordLen); //A0 ainv + + return PKE_SUCCESS; +} + +/** + * @brief out = (a+b) mod modulus. + * @param[in] modulus - modulus. + * @param[in] a - integer a. + * @param[in] b - integer b. + * @param[in] wordLen - word length of modulus, a, b. + * @param[out] out - out = a+b mod modulus. + * @return PKE_SUCCESS(success), other(error). + */ +unsigned char pke_mod_add(const unsigned int *modulus, const unsigned int *a, const unsigned int *b, + unsigned int *out, unsigned int wordLen) +{ + unsigned char ret; + + pke_set_operand_width(wordLen<<5); + + pke_load_operand((unsigned int *)(reg_pke_b_ram(3)), (unsigned int *)modulus, wordLen); //B3 modulus + pke_load_operand((unsigned int *)(reg_pke_a_ram(0)), (unsigned int *)a, wordLen); //A0 a + pke_load_operand((unsigned int *)(reg_pke_b_ram(0)), (unsigned int *)b, wordLen); //B0 b + + ret = pke_opr_cal(PKE_MICROCODE_MODADD, 0x00); + if(ret) + { + return ret; + } + + pke_read_operand((unsigned int *)(reg_pke_a_ram(0)), out, wordLen); //A0 result + + return PKE_SUCCESS; +} + +/** + * @brief out = (a-b) mod modulus. + * @param[in] modulus - input, modulus. + * @param[in] a - input, integer a. + * @param[in] b - input, integer b. + * @param[in] wordLen - input, word length of modulus, a, b. + * @param[out] out - output, out = a-b mod modulus. + * @return PKE_SUCCESS(success), other(error). + */ +unsigned char pke_mod_sub(const unsigned int *modulus, const unsigned int *a, const unsigned int *b, + unsigned int *out, unsigned int wordLen) +{ + unsigned char ret; + + pke_set_operand_width(wordLen<<5); + + pke_load_operand((unsigned int *)(reg_pke_b_ram(3)), (unsigned int *)modulus, wordLen); //B3 modulus + pke_load_operand((unsigned int *)(reg_pke_a_ram(0)), (unsigned int *)a, wordLen); //A0 a + pke_load_operand((unsigned int *)(reg_pke_b_ram(0)), (unsigned int *)b, wordLen); //B0 b + + ret = pke_opr_cal(PKE_MICROCODE_MODSUB, 0x00); + if(ret) + { + return ret; + } + + pke_read_operand((unsigned int *)(reg_pke_a_ram(0)), out, wordLen); //A0 result + + return PKE_SUCCESS; +} + +/** + * @brief c25519 point mul(random point), Q=[k]P. + * @param[in] curve - c25519 curve struct pointer. + * @param[in] k - scalar. + * @param[in] Pu - u coordinate of point P. + * @param[out] Qu - u coordinate of point Q=[k]P. + * @return PKE_SUCCESS(success), other(error). + */ +unsigned char pke_x25519_point_mul(mont_curve_t *curve, unsigned int *k, unsigned int *Pu, unsigned int *Qu) +{ + unsigned char ret; + unsigned int wordLen = (curve->mont_p_bitLen + 31)>>5; + + pke_set_operand_width(curve->mont_p_bitLen); + + pke_load_operand((unsigned int *)reg_pke_a_ram(0), Pu, wordLen); //A0 Pu + pke_load_operand((unsigned int *)reg_pke_b_ram(0), curve->mont_a24, wordLen); //B0 a24 + pke_load_operand((unsigned int *)reg_pke_a_ram(4), k, wordLen); //A4 k + pke_load_operand((unsigned int *)reg_pke_b_ram(3), curve->mont_p, wordLen); //B3 p + + if((NULL != curve->mont_p_h) && (NULL != curve->mont_p_n1)) + { + pke_load_operand((unsigned int *)reg_pke_a_ram(3), curve->mont_p_h, wordLen); //A3 p_h + pke_load_operand((unsigned int *)reg_pke_b_ram(4), curve->mont_p_n1, 1); //B4 p_n1 + } + else + { + pke_opr_cal(PKE_MICROCODE_CAL_PRE_MON, 0x00); + } + + + ret = pke_opr_cal(PKE_MICROCODE_C25519_PMUL, PKE_EXE_CFG_ALL_NON_MONT); + if(ret) + { + return ret; + } + + pke_read_operand((unsigned int *)reg_pke_a_ram(1), Qu, wordLen); + + return ret; +} + +/** + * @brief edwards25519 curve point mul(random point), Q=[k]P. + * @param[in] curve - edwards25519 curve struct pointer. + * @param[in] k - scalar. + * @param[in] Px - x coordinate of point P. + * @param[in] Py - y coordinate of point P. + * @param[out] Qx - x coordinate of point Q=[k]P. + * @param[out] Qy - y coordinate of point Q=[k]P. + * @return PKE_SUCCESS(success), other(error). + */ +unsigned char pke_ed25519_point_mul(edward_curve_t *curve, unsigned int *k, unsigned int *Px, unsigned int *Py, + unsigned int *Qx, unsigned int *Qy) +{ + unsigned char ret; + unsigned int wordLen = (curve->edward_p_bitLen + 31)>>5; + + pke_set_operand_width(curve->edward_p_bitLen); + + pke_load_operand((unsigned int *)reg_pke_a_ram(1), Px, wordLen); //A1 Px + pke_load_operand((unsigned int *)reg_pke_a_ram(2), Py, wordLen); //A2 Py + pke_load_operand((unsigned int *)reg_pke_b_ram(0), curve->edward_d, wordLen); //B0 d + pke_load_operand((unsigned int *)reg_pke_a_ram(0), k, wordLen); //A0 k + pke_load_operand((unsigned int *)reg_pke_b_ram(3), curve->edward_p, wordLen); //B3 p + + if((0 != curve->edward_p_h) && (0 != curve->edward_p_n1)) + { + pke_load_operand((unsigned int *)reg_pke_a_ram(3), curve->edward_p_h, wordLen); //A3 p_h + pke_load_operand((unsigned int *)reg_pke_b_ram(4), curve->edward_p_n1, 1); //B4 p_n1 + } + else + { + pke_opr_cal(PKE_MICROCODE_CAL_PRE_MON, 0x00); + } + + + ret = pke_opr_cal(PKE_MICROCODE_Ed25519_PMUL, PKE_EXE_CFG_ALL_NON_MONT); + if(ret) + { + return ret; + } + + pke_read_operand((unsigned int *)reg_pke_a_ram(1), Qx, wordLen); + if(Qy != 0) + { + pke_read_operand((unsigned int *)reg_pke_a_ram(2), Qy, wordLen); + } + + return ret; +} + +/** + * @brief edwards25519 point add, Q=P1+P2. + * @param[in] curve - edwards25519 curve struct pointer. + * @param[in] P1x - x coordinate of point P1. + * @param[in] P1y - y coordinate of point P1. + * @param[in] P2x - x coordinate of point P2. + * @param[in] P2y - y coordinate of point P2. + * @param[out] Qx - x coordinate of point Qx=P1x+P2x. + * @param[out] Qy - y coordinate of point Qy=P1y+P2y. + * @return PKE_SUCCESS(success), other(error). + */ +unsigned char pke_ed25519_point_add(edward_curve_t *curve, unsigned int *P1x, unsigned int *P1y, unsigned int *P2x, unsigned int *P2y, + unsigned int *Qx, unsigned int *Qy) +{ + unsigned char ret; + unsigned int wordLen = (curve->edward_p_bitLen + 31)>>5; + + pke_set_operand_width(curve->edward_p_bitLen); + + pke_load_operand((unsigned int *)reg_pke_a_ram(1), P1x, wordLen); //A1 P1x + pke_load_operand((unsigned int *)reg_pke_a_ram(2), P1y, wordLen); //A2 P1y + pke_load_operand((unsigned int *)reg_pke_b_ram(1), P2x, wordLen); //B1 P2x + pke_load_operand((unsigned int *)reg_pke_b_ram(2), P2y, wordLen); //B2 P2y + pke_load_operand((unsigned int *)reg_pke_b_ram(0), curve->edward_d, wordLen); //B0 d + pke_load_operand((unsigned int *)reg_pke_b_ram(3), curve->edward_p, wordLen); //B3 p + + if((0 != curve->edward_p_h) && (0 != curve->edward_p_n1)) + { + pke_load_operand((unsigned int *)reg_pke_a_ram(3), curve->edward_p_h, wordLen); //A3 p_h + pke_load_operand((unsigned int *)reg_pke_b_ram(4), curve->edward_p_n1, 1); //B4 p_n1 + } + else + { + pke_opr_cal(PKE_MICROCODE_CAL_PRE_MON, 0x00); + } + + ret = pke_opr_cal(PKE_MICROCODE_Ed25519_PADD, PKE_EXE_CFG_ALL_NON_MONT); + if(ret) + { + return ret; + } + + pke_read_operand((unsigned int *)reg_pke_a_ram(1), Qx, wordLen); + pke_read_operand((unsigned int *)reg_pke_a_ram(2), Qy, wordLen); + + return ret; +} + +/** + * @brief c = a mod b. + * @param[in] a - integer a. + * @param[in] b - integer b. + * @param[in] aWordLen - word length of a. + * @param[in] bWordLen - word length of b. + * @param[in] b_h - parameter b_h. + * @param[in] b_n1 - parameter b_n1. + * @param[out] c - c = a mod b. + * @return PKE_SUCCESS(success), other(error). + */ +unsigned char pke_mod(unsigned int *a, unsigned int aWordLen, unsigned int *b, unsigned int *b_h, unsigned int *b_n1, + unsigned int bWordLen, unsigned int *c) +{ + signed int ret; + unsigned int bitLen, tmpLen; + unsigned int *a_high, *a_low, *p; + + ret = big_integer_compare(a, aWordLen, b, bWordLen); + if(ret < 0) + { + aWordLen = valid_words_get(a, aWordLen); + memcpy(c, a, aWordLen<<2); + memset(c+aWordLen, 0, (bWordLen-aWordLen)<<2); + + return PKE_SUCCESS; + } + else if(0 == ret) + { + memset(c, 0, bWordLen<<2); + + return PKE_SUCCESS; + } + + bitLen = valid_bits_get(b, bWordLen) & 0x1F; + pke_set_operand_width(bWordLen<<5); + p = (unsigned int *)reg_pke_a_ram(1); + + //get a_high mod b + a_high = c; + if(bitLen) + { + tmpLen = aWordLen-bWordLen+1; + memcpy(p, a+bWordLen-1, tmpLen<<2); + div2n_u32(p, tmpLen, bitLen); + if(tmpLen < bWordLen) + { + memset(p+tmpLen, 0, (bWordLen-tmpLen)<<2); + } + + if(big_integer_compare(p, bWordLen, b, bWordLen) >= 0) + { + sub_u32(p, b, a_high, bWordLen); + } + else + { + memcpy(a_high, p, bWordLen<<2); + } + } + else + { + tmpLen = aWordLen - bWordLen; + if(big_integer_compare(a+bWordLen, tmpLen, b, bWordLen) > 0) + { + sub_u32(a+bWordLen, b, a_high, bWordLen); + } + else + { + memcpy(a_high, a+bWordLen, tmpLen<<2); + memset(a_high+tmpLen, 0, (bWordLen-tmpLen)<<2); + } + } + + if(0 == b_h && 0 == b_n1) + { + ret = pke_calc_pre_mont(b, bWordLen); + if(PKE_SUCCESS != ret) + { + return ret; + } + } + else + { + pke_load_pre_calc_mont(b_h, b_n1, bWordLen); + } + + //get 1000...000 mod b + memset(p, 0, bWordLen<<2); + if(bitLen) + { + p[bWordLen-1] = 1<<(bitLen); + } + sub_u32(p, b, (unsigned int *)reg_pke_b_ram(1), bWordLen); + + + //get a_high * 1000..000 mod b + pke_set_exe_cfg(PKE_EXE_CFG_ALL_NON_MONT); + pke_calc_pre_mont(b, bWordLen); + ret = pke_mod_mul(b, (unsigned int *)reg_pke_b_ram(1), a_high, (unsigned int *)reg_pke_b_ram(1), bWordLen); + if(PKE_SUCCESS != ret) + { + return ret; + } + + //get a_low mod b + if(bitLen) + { + a_low = c; + memcpy(p, a, bWordLen<<2); + p[bWordLen-1] &= ((1<<(bitLen))-1); + if(big_integer_compare(p, bWordLen, b, bWordLen) >= 0) + { + sub_u32(p, b, a_low, bWordLen); + } + else + { + memcpy(a_low, p, bWordLen<<2); + } + } + else + { + if(big_integer_compare(a, bWordLen, b, bWordLen) >= 0) + { + a_low = c; + sub_u32(a, b, a_low, bWordLen); + } + else + { + a_low = a; + } + } + + return pke_mod_add(b, a_low, (unsigned int *)reg_pke_b_ram(1), c, bWordLen); +} + + + + + diff --git a/b91/b91m_ble_sdk/drivers/B91/pke.h b/b91/b91m_ble_sdk/drivers/B91/pke.h new file mode 100755 index 0000000..fbd73ea --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/pke.h @@ -0,0 +1,439 @@ +/******************************************************************************************************** + * @file pke.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "reg_include/register_b91.h" + + + + +#define GET_WORD_LEN(bitLen) ((bitLen+31)/32) +#define GET_BYTE_LEN(bitLen) ((bitLen+7)/8) + +#define PKE_BASE (0X80110000) +#define reg_pke_a_ram(a) ((volatile unsigned long *)(PKE_BASE+0x0400+(a)*(0x24))) +#define reg_pke_b_ram(b) ((volatile unsigned long *)(PKE_BASE+0x1000+(b)*(0x24))) + +/********* oprand length *********/ +#define PKE_OPERAND_MAX_WORD_LEN (0x08) +#define PKE_OPERAND_MAX_BIT_LEN (0x100) +#define ECC_MAX_WORD_LEN PKE_OPERAND_MAX_WORD_LEN +#define ECC_MAX_BIT_LEN PKE_OPERAND_MAX_BIT_LEN + +#ifndef NULL +#define NULL 0 +#endif + +/** + * eccp curve + */ +typedef struct +{ + unsigned int eccp_p_bitLen; //bit length of prime p + unsigned int eccp_n_bitLen; //bit length of order n + unsigned int *eccp_p; + unsigned int *eccp_p_h; + unsigned int *eccp_p_n1; + unsigned int *eccp_a; + unsigned int *eccp_b; + unsigned int *eccp_Gx; + unsigned int *eccp_Gy; + unsigned int *eccp_n; + unsigned int *eccp_n_h; + unsigned int *eccp_n_n1; +}eccp_curve_t; + +/** + * mont curve + */ +typedef struct +{ + unsigned int mont_p_bitLen; //bit length of prime p + unsigned int *mont_p; + unsigned int *mont_p_h; + unsigned int *mont_p_n1; + unsigned int *mont_a24; + unsigned int *mont_u; + unsigned int *mont_v; + unsigned int *mont_n; + unsigned int *mont_n_h; + unsigned int *mont_n_n1; + unsigned int *mont_h; +}mont_curve_t; + +/** + * edward curve + */ +typedef struct +{ + unsigned int edward_p_bitLen; //bit length of prime p + unsigned int *edward_p; + unsigned int *edward_p_h; + unsigned int *edward_p_n1; + unsigned int *edward_d; + unsigned int *edward_Gx; + unsigned int *edward_Gy; + unsigned int *edward_n; + unsigned int *edward_n_h; + unsigned int *edward_n_n1; + unsigned int *edward_h; + +}edward_curve_t; + +/** + * pke return code + */ +typedef enum +{ + PKE_SUCCESS = 0, + PKE_ACTIVE_STOP, + PKE_MOD_INV_NOT_EXIST, + PKE_POINT_NOT_ON_CURVE, + PKE_INVALID_MICRO_CODE, + PKE_POINTOR_NULL, + PKE_INVALID_INPUT, +}pke_ret_code_e; + +/** + * pke exe cfg + */ +typedef enum{ + PKE_EXE_CFG_ALL_NON_MONT = 0x15, + PKE_EXE_CFG_ALL_MONT = 0x2A, +}pke_exe_cfg_e; + +/** + * pke micro code + */ +typedef enum{ + PKE_MICROCODE_PDBL = 0x04, + PKE_MICROCODE_PADD = 0x08, + PKE_MICROCODE_PVER = 0x0C, + PKE_MICROCODE_PMUL = 0x10, + PKE_MICROCODE_MODMUL = 0x18, + PKE_MICROCODE_MODINV = 0x1C, + PKE_MICROCODE_MODADD = 0x20, + PKE_MICROCODE_MODSUB = 0x24, + PKE_MICROCODE_CAL_PRE_MON = 0x28, + PKE_MICROCODE_C25519_PMUL = 0x34, + PKE_MICROCODE_Ed25519_PMUL = 0x38, + PKE_MICROCODE_Ed25519_PADD = 0x3C, + +}pke_microcode_e; + +/** + * @brief This function serves to get pke status. + * @param[in] status - the interrupt status to be obtained. + * @return pke status. + */ +static inline unsigned int pke_get_irq_status(pke_status_e status) +{ + return reg_pke_stat & status; +} + +/** + * @brief This function serves to clear pke status. + * @param[in] status - the interrupt status that needs to be cleared. + * @return none. + */ +static inline void pke_clr_irq_status(pke_status_e status) +{ + BM_CLR(reg_pke_stat, status); +} + +/** + * @brief This function serves to enable pke interrupt function. + * @param[in] mask - the irq mask. + * @return none. + */ +static inline void pke_set_irq_mask(pke_conf_e mask) +{ + BM_SET(reg_pke_conf, mask); +} + +/** + * @brief This function serves to disable PKE interrupt function. + * @param[in] mask - the irq mask. + * @return none. + */ +static inline void pke_clr_irq_mask(pke_conf_e mask) +{ + BM_CLR(reg_pke_conf, mask); +} + +/** + * @brief set operation micro code. + * @param[in] addr - pke micro code. + * @return none. + */ +static inline void pke_set_microcode(pke_microcode_e addr) +{ + reg_pke_mc_ptr = addr; +} + +/** + * @brief set exe config. + * @param[in] cfg - pke exe conf. + * @return none. + */ +static inline void pke_set_exe_cfg(pke_exe_cfg_e cfg) +{ + reg_pke_exe_conf = cfg; +} + +/** + * @brief start pke calculate. + * @return none. + */ +static inline void pke_opr_start(void) +{ + BM_SET(reg_pke_ctrl, FLD_PKE_CTRL_START); +} + +/** + * @brief This is used to indicate the reason when the pke stopped. + * @return 0 - normal stop. + * 1 - received a termination request(CTRL.STOP is high). + * 2 - no valid modulo inverse. + * 3 - point is not on the curve(CTRL.CMD:PVER). + * 4 - invalid microcode. + */ +static inline unsigned char pke_check_rt_code(void) +{ + return (unsigned char)(reg_pke_rt_code & FLD_PKE_RT_CODE_STOP_LOG); +} + +/** + * @brief set operand width please make sure 0 < bitLen <= 256. + * @param[in] bitLen - operand width. + * @return none. + */ +static inline void pke_set_operand_width(unsigned int bitLen) +{ + BM_CLR(reg_pke_conf, FLD_PKE_CONF_PARTIAL_RADIX); + BM_SET(reg_pke_conf, GET_WORD_LEN(bitLen)<<16); + BM_CLR(reg_pke_conf, FLD_PKE_CONF_BASE_RADIX); + BM_SET(reg_pke_conf, 2<<24); +} + +/** + * @brief compare big integer a and b. + * @param[in] a - value. + * @param[in] aWordLen - the length of a. + * @param[in] b - value. + * @param[in] bWordLen - the length of b. + * @return 0:a=b, 1:a>b, -1: a interrupt threshold,the function process will be disturb by interrupt. + * @return none +*/ +_attribute_ram_code_sec_noinline_ unsigned int plic_enter_critical_sec(unsigned char preempt_en ,unsigned char threshold) +{ + unsigned int r; + if(g_plic_preempt_en&&preempt_en) + { + plic_set_threshold(threshold); + r=0; + } + else + { + r = core_interrupt_disable(); + } + return r ; +} + +/** + * @brief This function serves to config plic when exit some function process such as flash. + * @param[in] preempt_en - 1 can disturb by interrupt, 0 can disturb by interrupt. + * @param[in] r - the value of mie register to restore. + * @return none +*/ +_attribute_ram_code_sec_noinline_ void plic_exit_critical_sec(unsigned char preempt_en ,unsigned int r) +{ + if (g_plic_preempt_en&&preempt_en) + { + plic_set_threshold(0); + } + else + { + core_restore_interrupt(r); + } +} + +/* + * FUNCTION DEFINITIONS + **************************************************************************************** + */ + + __attribute__((section(".ram_code"))) void default_irq_handler(void) +{ + +} +void stimer_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void analog_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void timer1_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void timer0_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void dma_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void bmc_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void usb_ctrl_ep_setup_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void usb_ctrl_ep_data_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void usb_ctrl_ep_status_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void usb_ctrl_ep_setinf_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void usb_endpoint_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void rf_dm_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void rf_ble_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void rf_bt_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void rf_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); + +void pwm_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void pke_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void uart1_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void uart0_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void audio_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); + +void i2c_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void hspi_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void pspi_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void usb_pwdn_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void gpio_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void gpio_risc0_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void gpio_risc1_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void soft_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); + +void npe_bus0_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void npe_bus1_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void npe_bus2_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void npe_bus3_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void npe_bus4_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void usb_250us_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void usb_reset_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); + +void npe_bus7_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void npe_bus8_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); + +void npe_bus13_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void npe_bus14_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); + +void npe_bus15_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void npe_bus17_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); + +void npe_bus21_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void npe_bus22_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void npe_bus23_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void npe_bus24_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void npe_bus25_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void npe_bus26_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void npe_bus27_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void npe_bus28_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); + +void npe_bus29_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void npe_bus30_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void npe_bus31_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void npe_comb_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void pm_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); +void eoc_irq_handler(void) __attribute__((weak, alias("default_irq_handler"))); + +typedef void (*func_isr_t) (void); +_attribute_ram_code_sec_ void plic_isr(func_isr_t func, irq_source_e src) +{ + +#if SUPPORT_PFT_ARCH + core_save_nested_context();//save csr and Enable interrupt enable + func ();//irq handler + core_restore_nested_context();// restore csr and disable interrupt enable + plic_interrupt_complete(src);//complete interrupt + fence_iorw;//fence instructio +#else + func ();//irq handler + plic_interrupt_complete(src);//complete interrupt +#endif +} + +/** + * @brief exception handler.this defines an exception handler to handle all the platform pre-defined exceptions. + * @return none + */ +_attribute_ram_code_sec_ __attribute__((weak)) void except_handler() +{ + while(1){ + /* Unhandled Trap */ + for(volatile unsigned int i = 0; i < 0xffff; i++) + { + __asm__("nop"); + } + } +} +_attribute_ram_code_sec_noinline_ void trap_entry(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void trap_entry(void) +{ + except_handler(); +} + +/** + * @brief system timer interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq1(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq1(void) +{ + plic_isr(stimer_irq_handler,IRQ1_SYSTIMER); +} + +/** + * @brief analog interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq2(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq2(void) +{ + plic_isr(analog_irq_handler,IRQ2_ALG); +} + + +/** + * @brief timer1 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq3(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq3(void) +{ + plic_isr(timer1_irq_handler,IRQ3_TIMER1); +} + +/** + * @brief timer0 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq4(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq4(void) +{ + plic_isr(timer0_irq_handler,IRQ4_TIMER0); +} + + +/** + * @brief dma interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq5(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq5(void) +{ + plic_isr(dma_irq_handler,IRQ5_DMA); +} + +/** + * @brief bmc interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq6(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq6(void) +{ +#if (!RAMCODE_OPTIMIZE_UNUSED_IRQ_NOT_IMPLEMENT) + plic_isr(bmc_irq_handler,IRQ6_BMC); +#endif +} + + +/** + * @brief usb control endpoint setup interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq7(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq7(void) +{ + plic_isr(usb_ctrl_ep_setup_irq_handler,IRQ7_USB_CTRL_EP_SETUP); +} + +/** + * @brief usb control endpoint data interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq8(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq8(void) +{ + plic_isr(usb_ctrl_ep_data_irq_handler,IRQ8_USB_CTRL_EP_DATA); +} + +/** + * @brief usb control endpoint status interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq9(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq9(void) +{ + plic_isr(usb_ctrl_ep_status_irq_handler,IRQ9_USB_CTRL_EP_STATUS); +} + + +/** + * @brief usb control endpoint setinf interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq10(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq10(void) +{ + plic_isr(usb_ctrl_ep_setinf_irq_handler,IRQ10_USB_CTRL_EP_SETINF); +} + +/** + * @brief usb endpoint interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq11(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq11(void) +{ + plic_isr(usb_endpoint_irq_handler,IRQ11_USB_ENDPOINT); +} + +/** + * @brief rf dual mode interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq12(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq12(void) +{ + plic_isr(rf_dm_irq_handler,IRQ12_ZB_DM); +} + +/** + * @brief rf ble interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq13(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq13(void) +{ +#if (!RAMCODE_OPTIMIZE_UNUSED_IRQ_NOT_IMPLEMENT) + plic_isr(rf_ble_irq_handler,IRQ13_ZB_BLE); +#endif +} + + +/** + * @brief rf BT interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq14(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq14(void) +{ +#if (!RAMCODE_OPTIMIZE_UNUSED_IRQ_NOT_IMPLEMENT) + plic_isr(rf_bt_irq_handler,IRQ14_ZB_BT); +#endif +} + +/** + * @brief telink rf interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq15(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq15(void) +{ + plic_isr(rf_irq_handler,IRQ15_ZB_RT); +} + + + +/** + * @brief pwm interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq16(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq16(void) +{ + plic_isr(pwm_irq_handler,IRQ16_PWM); +} + +/** + * @brief pke interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq17(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq17(void) +{ +#if (!RAMCODE_OPTIMIZE_UNUSED_IRQ_NOT_IMPLEMENT) + plic_isr(pke_irq_handler,IRQ17_PKE); +#endif +} + + + +/** + * @brief uart1 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq18(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq18(void) +{ + plic_isr(uart1_irq_handler,IRQ18_UART1); +} + + + +/** + * @brief uart0 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq19(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq19(void) +{ + plic_isr(uart0_irq_handler,IRQ19_UART0); +} + + +/** + * @brief audio interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq20(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq20(void) +{ + plic_isr(audio_irq_handler,IRQ20_DFIFO); +} + +/** + * @brief i2c interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq21(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq21(void) +{ + plic_isr(i2c_irq_handler,IRQ21_I2C); +} + + +/** + * @brief hspi interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq22(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq22(void) +{ + plic_isr(hspi_irq_handler,IRQ22_SPI_AHB); +} + + +/** + * @brief pspi interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq23(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq23(void) +{ + plic_isr(pspi_irq_handler,IRQ23_SPI_APB); + +} + +/** + * @brief usb power down interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq24(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq24(void) +{ + plic_isr(usb_pwdn_irq_handler,IRQ24_USB_PWDN); +} + +/** + * @brief gpio interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq25(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq25(void) +{ + plic_isr(gpio_irq_handler,IRQ25_GPIO); +} + +/** + * @brief gpio_risc0 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq26(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq26(void) +{ + plic_isr(gpio_risc0_irq_handler,IRQ26_GPIO2RISC0); +} + + +/** + * @brief gpio_risc1 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq27(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq27(void) +{ + plic_isr(gpio_risc1_irq_handler,IRQ27_GPIO2RISC1); +} + +/** + * @brief soft interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq28(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq28(void) +{ +#if (!RAMCODE_OPTIMIZE_UNUSED_IRQ_NOT_IMPLEMENT) + plic_isr(soft_irq_handler,IRQ28_SOFT); +#endif +} + +/** + * @brief npe bus0 interrupt handler. + * @return none + */ + +_attribute_ram_code_sec_noinline_ void entry_irq29(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq29(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus0_irq_handler,IRQ29_NPE_BUS0); +} +/** + * @brief npe bus1 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq30(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq30(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus1_irq_handler,IRQ30_NPE_BUS1); +} +/** + * @brief npe bus2 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq31(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq31(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus2_irq_handler,IRQ31_NPE_BUS2); +} +/** + * @brief npe bus3 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq32(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq32(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus3_irq_handler,IRQ32_NPE_BUS3); +} + +/** + * @brief npe bus4 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq33(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq33(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus4_irq_handler,IRQ33_NPE_BUS4); +} +/** + * @brief usb 250us interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq34(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq34(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(usb_250us_irq_handler,IRQ34_USB_250US); +} +/** + * @brief usb reset interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq35(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq35(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(usb_reset_irq_handler,IRQ35_USB_RESET); +} +/** + * @brief npe bus7 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq36(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq36(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus7_irq_handler,IRQ36_NPE_BUS7); +} +/** + * @brief npe bus8 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq37(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq37(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus8_irq_handler,IRQ37_NPE_BUS8); +} + + +_attribute_ram_code_sec_noinline_ void entry_irq38(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq38(void) +{ + +} +_attribute_ram_code_sec_noinline_ void entry_irq39(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq39(void) +{ + +} +_attribute_ram_code_sec_noinline_ void entry_irq40(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq40(void) +{ + +} +_attribute_ram_code_sec_noinline_ void entry_irq41(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq41(void) +{ + +} +/** + * @brief npe bus13 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq42(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq42(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus13_irq_handler,IRQ42_NPE_BUS13); +} +/** + * @brief npe bus14 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq43(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq43(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus14_irq_handler,IRQ43_NPE_BUS14); +} + +/** + * @brief npe bus15 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq44(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq44(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus15_irq_handler,IRQ44_NPE_BUS15); +} +_attribute_ram_code_sec_noinline_ void entry_irq45(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq45(void) +{ + +} +/** + * @brief npe bus17 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq46(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq46(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus17_irq_handler,IRQ46_NPE_BUS17); +} + + +_attribute_ram_code_sec_noinline_ void entry_irq47(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq47(void) +{ + +} + +_attribute_ram_code_sec_noinline_ void entry_irq48(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq48(void) +{ + +} + +_attribute_ram_code_sec_noinline_ void entry_irq49(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq49(void) +{ + +} +/** + * @brief npe bus21 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq50(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq50(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus21_irq_handler,IRQ50_NPE_BUS21); +} +/** + * @brief npe bus22 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq51(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq51(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus22_irq_handler,IRQ51_NPE_BUS22); +} +/** + * @brief npe bus23 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq52(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq52(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus23_irq_handler,IRQ52_NPE_BUS23); +} +/** + * @brief npe bus24 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq53(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq53(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus24_irq_handler,IRQ53_NPE_BUS24); +} +/** + * @brief npe bus25 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq54(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq54(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus25_irq_handler,IRQ54_NPE_BUS25); +} +/** + * @brief npe bus26 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq55(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq55(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus26_irq_handler,IRQ55_NPE_BUS26); +} +/** + * @brief npe bus27 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq56(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq56(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus27_irq_handler,IRQ56_NPE_BUS27); +} +/** + * @brief npe bus28 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq57(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq57(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus28_irq_handler,IRQ57_NPE_BUS28); +} +/** + * @brief npe bus29 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq58(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq58(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus29_irq_handler,IRQ58_NPE_BUS29); +} +/** + * @brief npe bus30 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq59(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq59(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus30_irq_handler,IRQ59_NPE_BUS30); +} +/** + * @brief npe bus31 interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq60(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq60(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_bus31_irq_handler,IRQ60_NPE_BUS31); +} +/** + * @brief npe comb interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq61(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq61(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(npe_comb_irq_handler,IRQ61_NPE_COMB); +} +/** + * @brief pm interrupt handler.An interrupt will be generated after wake-up + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq62(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq62(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(pm_irq_handler,IRQ62_PM_TM); +} +/** + * @brief eoc interrupt handler. + * @return none + */ +_attribute_ram_code_sec_noinline_ void entry_irq63(void) __attribute__ ((interrupt ("machine") , aligned(4))); +void entry_irq63(void) +{ + //disable unused interrupt modules to save ram_code +// plic_isr(eoc_irq_handler,IRQ63_EOC); +} + + + +/// @} DRIVERS diff --git a/b91/b91m_ble_sdk/drivers/B91/plic.h b/b91/b91m_ble_sdk/drivers/B91/plic.h new file mode 100755 index 0000000..7376b17 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/plic.h @@ -0,0 +1,249 @@ +/******************************************************************************************************** + * @file plic.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +/** @page PLIC + * + * Introduction + * =============== + * platform-level interrupt controller (PLIC) + * + * API Reference + * =============== + * Header File: plic.h + */ + +#ifndef INTERRUPT_H +#define INTERRUPT_H +#include "core.h" + +#include "reg_include/register_b91.h" +#include "compiler.h" + +typedef struct +{ + unsigned char preempt_en; + unsigned char threshold; +}preempt_config_t ; + + +extern unsigned char g_plic_preempt_en; + +typedef enum{ + IRQ0_EXCEPTION , + IRQ1_SYSTIMER, + IRQ2_ALG, + IRQ3_TIMER1, + IRQ4_TIMER0, + IRQ5_DMA, + IRQ6_BMC, + IRQ7_USB_CTRL_EP_SETUP, + IRQ8_USB_CTRL_EP_DATA, + IRQ9_USB_CTRL_EP_STATUS, + IRQ10_USB_CTRL_EP_SETINF, + IRQ11_USB_ENDPOINT, + IRQ12_ZB_DM, + IRQ13_ZB_BLE, + IRQ14_ZB_BT, + IRQ15_ZB_RT, + IRQ16_PWM, + IRQ17_PKE, + IRQ18_UART1, + IRQ19_UART0, + IRQ20_DFIFO, + IRQ21_I2C, + IRQ22_SPI_AHB, + IRQ23_SPI_APB, + IRQ24_USB_PWDN, + IRQ25_GPIO, + IRQ26_GPIO2RISC0, + IRQ27_GPIO2RISC1, + IRQ28_SOFT, + + IRQ29_NPE_BUS0, + IRQ30_NPE_BUS1, + IRQ31_NPE_BUS2, + IRQ32_NPE_BUS3, + IRQ33_NPE_BUS4, + + IRQ34_USB_250US, + IRQ35_USB_RESET, + IRQ36_NPE_BUS7, + IRQ37_NPE_BUS8, + + IRQ42_NPE_BUS13=42, + IRQ43_NPE_BUS14, + IRQ44_NPE_BUS15, + + IRQ46_NPE_BUS17=46, + + IRQ50_NPE_BUS21=50, + IRQ51_NPE_BUS22, + IRQ52_NPE_BUS23, + IRQ53_NPE_BUS24, + IRQ54_NPE_BUS25, + IRQ55_NPE_BUS26, + IRQ56_NPE_BUS27, + IRQ57_NPE_BUS28, + IRQ58_NPE_BUS29, + IRQ59_NPE_BUS30, + IRQ60_NPE_BUS31, + + IRQ61_NPE_COMB, + IRQ62_PM_TM, + IRQ63_EOC, + +} irq_source_e; + +typedef enum{ + IRQ_PRI_LEV0,//Never interrupt + IRQ_PRI_LEV1, + IRQ_PRI_LEV2, + IRQ_PRI_LEV3, +}irq_priority_e; + + +/** + * @brief This function serves to set plic feature. + * @param[in] feature - preemptive priority interrupt feature and the vector mode. + * @return none + */ +static inline void plic_set_feature (feature_e feature) +{ + reg_irq_feature = feature;//enable vectored in PLIC +} + +/** + * @brief This function serves to enable preemptive priority interrupt feature. + * @return none + */ +static inline void plic_preempt_feature_en (void) +{ + reg_irq_feature |= FLD_FEATURE_PREEMPT_PRIORITY_INT_EN; + g_plic_preempt_en=1; +} + +/** + * @brief This function serves to enable preemptive priority interrupt feature. + * @return none + */ +static inline void plic_preempt_feature_dis (void) +{ + reg_irq_feature &=(~ FLD_FEATURE_PREEMPT_PRIORITY_INT_EN); + g_plic_preempt_en=0; +} + + +/** + * @brief This function serves to set plic pending. + * @param[in] src - interrupt source. + * @return none + */ +static inline void plic_set_pending (irq_source_e src) +{ + reg_irq_pending(src)=BIT(src%32); +} + +/** + * @brief This function serves to set Priority Threshold,Only active interrupts with priorities strictly greater than the threshold will cause interrupt. + * @param[in] threshold - threshold level. + * @return none + */ +static inline void plic_set_threshold (unsigned char threshold) +{ + reg_irq_threshold=threshold; +} + +/** + * @brief This function serves to set preemptive priority level,The priority value 0 is reserved to mean "never interrupt". + * the larger the priority value, the higher the interrupt priority. + * @param[in] src- interrupt source. + * @param[in] priority- priority level. + * @return none + */ +static inline void plic_set_priority (irq_source_e src, irq_priority_e priority) +{ + reg_irq_src_priority(src)=priority; +} + + +/** + * @brief This function serves to enable plic interrupt source. + * @param[in] src - interrupt source. + * @return none + */ +static inline void plic_interrupt_enable(irq_source_e src) +{ + reg_irq_src(src) |= BIT(src%32); + +} + +/** + * @brief This function serves to disable plic interrupt source. + * @param[in] src - interrupt source. + * @return none + */ +static inline void plic_interrupt_disable(irq_source_e src) +{ + reg_irq_src(src) &= (~ BIT(src%32)); +} + +/** + * @brief This function serves to clear interrupt source has completed. + * @param[in] src - interrupt source. + * @return none + */ +static inline void plic_interrupt_complete(irq_source_e src) +{ + reg_irq_done = src; +} + +/** + * @brief This function serves to claim interrupt. + * @return it return the source id which interrupted in irq_source_e enum . + */ +static inline unsigned int plic_interrupt_claim(void) +{ + return reg_irq_done; +} + + + +/** + * @brief This function serves to config plic when enter some function process such as flash. + * @param[in] preempt_en - 1 can disturb by interrupt, 0 can't disturb by interrupt. + * @param[in] threshold - interrupt threshold.when the interrupt priority> interrupt threshold,the function process will be disturb by interrupt. + * @return none +*/ +_attribute_ram_code_sec_noinline_ unsigned int plic_enter_critical_sec(unsigned char preempt_en ,unsigned char threshold); + + + +/** + * @brief This function serves to config plic when exit some function process such as flash. + * @param[in] preempt_en - 1 can disturb by interrupt, 0 can disturb by interrupt. + * @param[in] r - the value of mie register to restore. + * @return none +*/ +_attribute_ram_code_sec_noinline_ void plic_exit_critical_sec(unsigned char preempt_en ,unsigned int r); + + +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/pm.h b/b91/b91m_ble_sdk/drivers/B91/pm.h new file mode 100755 index 0000000..36f1763 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/pm.h @@ -0,0 +1,299 @@ +/******************************************************************************************************** + * @file pm.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "reg_include/register_b91.h" +#include "compiler.h" +#include "gpio.h" +#include "clock.h" + +/******************************************************************************************************** + * internal + *******************************************************************************************************/ + +/******************************************************************************************************** + * This is currently included in the H file for compatibility with other SDKs. + *******************************************************************************************************/ + +//When the watchdog comes back, the Eagle chip does not clear 0x7f[0]. To avoid this problem, this macro definition is added. +#ifndef WDT_REBOOT_RESET_ANA7F_WORK_AROUND +#define WDT_REBOOT_RESET_ANA7F_WORK_AROUND 1 +#endif + +#ifndef SYS_TIMER_AUTO_MODE +#define SYS_TIMER_AUTO_MODE 1 +#endif + +/******************************************************************************************************** + * external + *******************************************************************************************************/ + + +/** + * @brief these analog register can store data in deepsleep mode or deepsleep with SRAM retention mode. + * Reset these analog registers by watchdog, chip reset, RESET Pin, power cycle + */ +#define PM_ANA_REG_WD_CLR_BUF0 0x38 // initial value 0xff. [Bit0] is already occupied. The customer cannot change! + +/** + * @brief analog register below can store infomation when MCU in deepsleep mode or deepsleep with SRAM retention mode. + * Reset these analog registers only by power cycle + */ +#define PM_ANA_REG_POWER_ON_CLR_BUF0 0x39 // initial value 0x00. [Bit0] is already occupied. The customer cannot change! +#define PM_ANA_REG_POWER_ON_CLR_BUF1 0x3a // initial value 0x00 +#define PM_ANA_REG_POWER_ON_CLR_BUF2 0x3b // initial value 0x00 +#define PM_ANA_REG_POWER_ON_CLR_BUF3 0x3c // initial value 0x00 +#define PM_ANA_REG_POWER_ON_CLR_BUF4 0x3d // initial value 0x00 +#define PM_ANA_REG_POWER_ON_CLR_BUF5 0x3e // initial value 0x00 +#define PM_ANA_REG_POWER_ON_CLR_BUF6 0x3f // initial value 0x0f + +/** + * @brief gpio wakeup level definition + */ +typedef enum{ + WAKEUP_LEVEL_LOW = 0, + WAKEUP_LEVEL_HIGH = 1, +}pm_gpio_wakeup_level_e; + +/** + * @brief wakeup tick type definition + */ +typedef enum { + PM_TICK_STIMER_16M = 0, + PM_TICK_32K = 1, +}pm_wakeup_tick_type_e; + +/** + * @brief suspend power weather to power down definition + */ +typedef enum { + PM_POWERON_BASEBAND = BIT(0), //weather to power on the BASEBAND before suspend. + PM_POWERON_USB = BIT(1), //weather to power on the USB before suspend. + PM_POWERON_NPE = BIT(2), //weather to power on the NPE before suspend. +}pm_suspend_power_cfg_e; + +/** + * @brief sleep mode. + */ +typedef enum { + //available mode for customer + SUSPEND_MODE = 0x00, //The A0 version of the suspend execution process is abnormal and the program restarts. + DEEPSLEEP_MODE = 0x30, //when use deep mode pad wakeup(low or high level), if the high(low) level always in + //the pad, system will not enter sleep and go to below of pm API, will reboot by core_6f = 0x20 + //deep retention also had this issue, but not to reboot. + DEEPSLEEP_MODE_RET_SRAM_LOW32K = 0x21, //for boot from sram + DEEPSLEEP_MODE_RET_SRAM_LOW64K = 0x03, //for boot from sram + //not available mode + DEEPSLEEP_RETENTION_FLAG = 0x0F, +}pm_sleep_mode_e; + +/** + * @brief available wake-up source for customer + */ +typedef enum { + PM_WAKEUP_PAD = BIT(3), + PM_WAKEUP_CORE = BIT(4), + PM_WAKEUP_TIMER = BIT(5), + PM_WAKEUP_COMPARATOR = BIT(6), + PM_WAKEUP_MDEC = BIT(7), +}pm_sleep_wakeup_src_e; + +/** + * @brief wakeup status + */ +typedef enum { + WAKEUP_STATUS_COMPARATOR = BIT(0), + WAKEUP_STATUS_TIMER = BIT(1), + WAKEUP_STATUS_CORE = BIT(2), + WAKEUP_STATUS_PAD = BIT(3), + WAKEUP_STATUS_MDEC = BIT(4), + + STATUS_GPIO_ERR_NO_ENTER_PM = BIT(7), + STATUS_ENTER_SUSPEND = BIT(30), +}pm_wakeup_status_e; + +/** + * @brief mcu status + */ +typedef enum{ + MCU_STATUS_POWER_ON = BIT(0), + MCU_STATUS_REBOOT_BACK = BIT(2), + MCU_STATUS_DEEPRET_BACK = BIT(3), + MCU_STATUS_DEEP_BACK = BIT(4), + MCU_STATUS_REBOOT_DEEP_BACK = BIT(5), //reboot + deep +}pm_mcu_status; + +/** + * @brief early wakeup time + */ +typedef struct { + unsigned short suspend_early_wakeup_time_us; /**< suspend_early_wakeup_time_us = deep_ret_r_delay_us + xtal_stable_time + early_time*/ + unsigned short deep_ret_early_wakeup_time_us; /**< deep_ret_early_wakeup_time_us = deep_ret_r_delay_us + early_time*/ + unsigned short deep_early_wakeup_time_us; /**< deep_early_wakeup_time_us = suspend_ret_r_delay_us*/ + unsigned short sleep_min_time_us; /**< sleep_min_time_us = suspend_early_wakeup_time_us + 200*/ +}pm_early_wakeup_time_us_s; + +/** + * @brief hardware delay time + */ +typedef struct { + unsigned short deep_r_delay_cycle ; /**< hardware delay time ,deep_ret_r_delay_us = deep_r_delay_cycle * 1/16k */ + unsigned short suspend_ret_r_delay_cycle ; /**< hardware delay time ,suspend_ret_r_delay_us = suspend_ret_r_delay_cycle * 1/16k */ + +}pm_r_delay_cycle_s; + +/** + * @brief deepsleep wakeup status + */ +typedef struct{ + unsigned char is_pad_wakeup; + unsigned char wakeup_src; //The pad pin occasionally wakes up abnormally in A0. The core wakeup flag will be incorrectly set in A0. + unsigned char mcu_status; + unsigned char rsvd; +}pm_status_info_s; + +/** + * @brief pm 32k rc calibration algorithm. + */ +typedef struct pm_clock_drift +{ + unsigned int ref_tick; + unsigned int ref_tick_32k; + int offset; + int offset_dc; +// int offset_cur; + unsigned int offset_cal_tick; + int tc; + int rc32; + int rc32_wakeup; + int rc32_rt; + int s0; + unsigned char calib; + unsigned char ref_no; + +} pm_clock_drift_t; + + +extern pm_clock_drift_t pmcd; +extern _attribute_aligned_(4) pm_status_info_s g_pm_status_info; +extern _attribute_data_retention_sec_ unsigned char g_pm_suspend_power_cfg; +extern _attribute_data_retention_sec_ unsigned char g_pm_vbat_v; + +/** + * @brief This function servers to set the match value for MDEC wakeup. + * @param[in] value - the MDEC match value for wakeup. + * @return none. + */ +static inline void pm_set_mdec_value_wakeup(unsigned char value) +{ + analog_write_reg8(mdec_ctrl,((analog_read_reg8(mdec_ctrl) & (~0x0f)) | value)); +} + +/** + * @brief This function serves to set baseband/usb/npe power on. + * @param[in] value - weather to power on the baseband/usb/npe. + * @return none. + */ +static inline void pm_set_suspend_power_cfg(pm_suspend_power_cfg_e value) +{ + g_pm_suspend_power_cfg &= (~value); +} + +/** + * @brief This function serves to get deep retention flag. + * @return 1 deep retention, 0 deep. + */ +static inline unsigned char pm_get_deep_retention_flag(void) +{ + return !(analog_read_reg8(0x7f) & BIT(0)); +} + +/** + * @brief This function serves to get wakeup source. + * @return wakeup source. + */ +static inline pm_wakeup_status_e pm_get_wakeup_src(void) +{ + return analog_read_reg8(0x64); +} + +/** + * @brief This function configures a GPIO pin as the wakeup pin. + * @param[in] pin - the pin needs to be configured as wakeup pin. + * @param[in] pol - the wakeup polarity of the pad pin(0: low-level wakeup, 1: high-level wakeup). + * @param[in] en - enable or disable the wakeup function for the pan pin(1: enable, 0: disable). + * @return none. + */ +void pm_set_gpio_wakeup (gpio_pin_e pin, pm_gpio_wakeup_level_e pol, int en); + +/** + * @brief This function configures pm wakeup time parameter. + * @param[in] param - pm wakeup time parameter. + * @return none. + */ +void pm_set_wakeup_time_param(pm_r_delay_cycle_s param); + +/** + * @brief this function servers to wait bbpll clock lock. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void pm_wait_bbpll_done(void); + +/** + * @brief This function serves to recover system timer. + * The code is placed in the ram code section, in order to shorten the time. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void pm_stimer_recover(void); + +/** + * @brief This function serves to set the working mode of MCU based on 32k crystal,e.g. suspend mode, deepsleep mode, deepsleep with SRAM retention mode and shutdown mode. + * @param[in] sleep_mode - sleep mode type select. + * @param[in] wakeup_src - wake up source select. + * A0 note: The reference current values under different configurations are as followsUnit (uA): + * | pad | 32k rc | 32k xtal | mdec | lpc | + * deep | 0.7 | 1.3 | 1.7 | 1.4 | 1.6 | + * deep ret 32k | 1.8 | 2.4 | 2.8 | 2.6 | 2.8 | + * deep ret 64k | 2.7 | 3.2 | 3.7 | 3.4 | 3.7 | + * A0 chip, the retention current will float up. + * @param[in] wakeup_tick_type - tick type select. For long timer sleep.currently only 16M is supported(PM_TICK_STIMER_16M). + * @param[in] wakeup_tick - the time of short sleep, which means MCU can sleep for less than 5 minutes. + * @return indicate whether the cpu is wake up successful. + */ +_attribute_ram_code_sec_noinline_ int pm_sleep_wakeup(pm_sleep_mode_e sleep_mode, pm_sleep_wakeup_src_e wakeup_src, pm_wakeup_tick_type_e wakeup_tick_type, unsigned int wakeup_tick); + +/** + * @brief Calculate the offset value based on the difference of 16M tick. + * @param[in] offset_tick - the 16M tick difference between the standard clock and the expected clock. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void pm_cal_32k_rc_offset (int offset_tick); + +void pm_ble_32k_rc_cal_reset(void); +void pm_ble_cal_32k_rc_offset (int, int); + +/** + * @brief When 32k rc sleeps, the calibration function is initialized. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void pm_32k_rc_offset_init(void); diff --git a/b91/b91m_ble_sdk/drivers/B91/pwm.c b/b91/b91m_ble_sdk/drivers/B91/pwm.c new file mode 100755 index 0000000..09a4563 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/pwm.c @@ -0,0 +1,140 @@ +/******************************************************************************************************** + * @file pwm.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "pwm.h" + + +dma_config_t pwm_tx_dma_config={ + .dst_req_sel= DMA_REQ_PWM_TX,//tx req + .src_req_sel=0, + .dst_addr_ctrl=DMA_ADDR_FIX, + .src_addr_ctrl=DMA_ADDR_INCREMENT,//increment + .dstmode=DMA_HANDSHAKE_MODE,//handshake + .srcmode=DMA_NORMAL_MODE, + .dstwidth=DMA_CTR_WORD_WIDTH,//must word + .srcwidth=DMA_CTR_WORD_WIDTH,//must word + .src_burst_size=0,//must 0 + .read_num_en=0, + .priority=0, + .write_num_en=0, + .auto_en=0, +}; + + +/** + * @brief This fuction servers to set pin as pwm0 + * @param[in] pin - selected pin + * @return none. + */ +void pwm_set_pin(pwm_pin_e pin) +{ + unsigned char val=0; + unsigned char start_bit = (BIT_LOW_BIT(pin & 0xff) %4 )<<1; + unsigned char mask =(unsigned char) ~BIT_RNG(start_bit , start_bit+1); + + if(pin==PWM_PWM2_PB7){ // Pad Function Mux:0 + val = 0; + BM_CLR(reg_gpio_pad_mul_sel, BIT(3)); + }else if((pin==PWM_PWM0_PB4) || (pin==PWM_PWM4_PD7) ||(pin==PWM_PWM2_N_PE6) ||(pin==PWM_PWM3_N_PE7)){ // Pad Function Mux:1 + val = 1<<(start_bit); + }else{ // Pad Function Mux:2 + val = 2<<(start_bit); + reg_gpio_pad_mul_sel|=BIT(0); + } + + reg_gpio_func_mux(pin)=(reg_gpio_func_mux(pin)& mask)|val; + gpio_function_dis(pin); +} + + +/** + * @brief This function servers to configure DMA channel and some configures. + * @param[in] chn - to select the DMA channel. + * @return none + */ +void pwm_set_dma_config(dma_chn_e chn) +{ + dma_config(chn,&pwm_tx_dma_config); +} + + +/** + * @brief This function servers to configure DMA channel address and length. + * @param[in] chn - to select the DMA channel. + * @param[in] buf_addr - the address where DMA need to get data from SRAM. + * @param[in] len - the length of data in SRAM. + * @return none + */ +void pwm_set_dma_buf(dma_chn_e chn,unsigned int buf_addr,unsigned int len) +{ + dma_set_address( chn,convert_ram_addr_cpu2bus(buf_addr),reg_pwm_data_buf_adr); + dma_set_size(chn,len,DMA_WORD_WIDTH); +} + + +/** + * @brief This function servers to enable DMA channel. + * @param[in] chn - to select the DMA channel. + * @return none + */ +void pwm_ir_dma_mode_start(dma_chn_e chn) +{ + dma_chn_en(chn); +} + + + +/** + * @brief This function servers to configure DMA head node. + * @param[in] chn - to select the DMA channel. + * @param[in] src_addr - to configure DMA source address. + * @param[in] data_len - to configure DMA length. + * @param[in] head_of_list - to configure the address of the next node configure. + * @return none + */ +void pwm_set_dma_chain_llp(dma_chn_e chn,unsigned short * src_addr, unsigned int data_len,dma_chain_config_t * head_of_list) +{ + dma_config(chn,&pwm_tx_dma_config); + dma_set_address( chn,convert_ram_addr_cpu2bus(src_addr),reg_pwm_data_buf_adr); + dma_set_size(chn,data_len,DMA_WORD_WIDTH); + reg_dma_llp(chn)=(unsigned int)convert_ram_addr_cpu2bus(head_of_list); +} + + +/** + * @brief This function servers to configure DMA cycle chain node. + * @param[in] chn - to select the DMA channel. + * @param[in] config_addr - to servers to configure the address of the current node. + * @param[in] llponit - to configure the address of the next node configure. + * @param[in] src_addr - to configure DMA source address. + * @param[in] data_len - to configure DMA length. + * @return none + */ +void pwm_set_tx_dma_add_list_element(dma_chn_e chn,dma_chain_config_t *config_addr,dma_chain_config_t *llponit ,unsigned short * src_addr,unsigned int data_len) +{ + config_addr->dma_chain_ctl= reg_dma_ctrl(chn)|BIT(0); + config_addr->dma_chain_src_addr=(unsigned int)convert_ram_addr_cpu2bus(src_addr); + config_addr->dma_chain_dst_addr=reg_pwm_data_buf_adr; + config_addr->dma_chain_data_len=dma_cal_size(data_len,DMA_WORD_WIDTH); + config_addr->dma_chain_llp_ptr=(unsigned int)convert_ram_addr_cpu2bus(llponit); +} + diff --git a/b91/b91m_ble_sdk/drivers/B91/pwm.h b/b91/b91m_ble_sdk/drivers/B91/pwm.h new file mode 100755 index 0000000..e6a40a3 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/pwm.h @@ -0,0 +1,542 @@ +/******************************************************************************************************** + * @file pwm.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef PWM_H_ +#define PWM_H_ +#include "gpio.h" +#include "dma.h" +#include "reg_include/register_b91.h" + +#define get_pwmid(gpio) ((gpio==PWM_PWM0_PB4) ? 0 : ( \ + (gpio==PWM_PWM0_PC0) ? 0 : ( \ + (gpio==PWM_PWM0_PE3) ? 0 : ( \ + (gpio==PWM_PWM0_N_PD0) ? 0 : ( \ + (gpio==PWM_PWM1_PB5) ? 1 : ( \ + (gpio==PWM_PWM1_PE1) ? 1 : ( \ + (gpio==PWM_PWM1_N_PD1) ? 1 : ( \ + (gpio==PWM_PWM2_PB7) ? 2 : ( \ + (gpio==PWM_PWM2_PE2) ? 2 : ( \ + (gpio==PWM_PWM2_N_PD2) ? 2 : ( \ + (gpio==PWM_PWM2_N_PE6) ? 2 : ( \ + (gpio==PWM_PWM3_PB1) ? 3 : ( \ + (gpio==PWM_PWM3_PE0) ? 3 : ( \ + (gpio==PWM_PWM3_N_PD3) ? 3 : ( \ + (gpio==PWM_PWM3_N_PE7) ? 3 : ( \ + (gpio==PWM_PWM4_PD7) ? 4 : ( \ + (gpio==PWM_PWM4_PE4) ? 4 : ( \ + (gpio==PWM_PWM4_N_PD4) ? 4 : ( \ + (gpio==PWM_PWM5_PB0) ? 5 : ( \ + (gpio==PWM_PWM5_PE5) ? 5 : ( \ + (gpio==PWM_PWM5_N_PD5) ? 5 : 0 \ + ))))))))))))))))))))) + +#define get_pwm_invert_val(gpio) ((gpio==PWM_PWM0_N_PD0) || \ + (gpio==PWM_PWM1_N_PD1) || \ + (gpio==PWM_PWM2_N_PD2) || \ + (gpio==PWM_PWM2_N_PE6) || \ + (gpio==PWM_PWM3_N_PD3) || \ + (gpio==PWM_PWM3_N_PE7) || \ + (gpio==PWM_PWM4_N_PD4) || \ + (gpio==PWM_PWM5_N_PD5)) + +/** + * @brief enum variable, the number of PWM channels supported + */ +typedef enum { + PWM0_ID = 0, + PWM1_ID, + PWM2_ID, + PWM3_ID, + PWM4_ID, + PWM5_ID, +}pwm_id_e; + + +/** + * @brief enum variable, represents the PWM mode. + */ +typedef enum{ + PWM_NORMAL_MODE = 0x00, + PWM_COUNT_MODE = 0x01, + PWM_IR_MODE = 0x03, + PWM_IR_FIFO_MODE = 0x07, + PWM_IR_DMA_FIFO_MODE = 0x0F, +}pwm_mode_e; + + +/** + * @brief enum variable, represents Selection of PWM pin. + */ +typedef enum{ + PWM_PWM0_PB4 = GPIO_PB4, + PWM_PWM0_PC0 = GPIO_PC0, + PWM_PWM0_PE3 = GPIO_PE3, + PWM_PWM0_N_PD0 = GPIO_PD0, + + PWM_PWM1_PB5 = GPIO_PB5, + PWM_PWM1_PE1 = GPIO_PE1, + PWM_PWM1_N_PD1 = GPIO_PD1, + + PWM_PWM2_PB7 = GPIO_PB7, + PWM_PWM2_PE2 = GPIO_PE2, + PWM_PWM2_N_PD2 = GPIO_PD2, + PWM_PWM2_N_PE6 = GPIO_PE6, + + PWM_PWM3_PB1 = GPIO_PB1, + PWM_PWM3_PE0 = GPIO_PE0, + PWM_PWM3_N_PD3 = GPIO_PD3, + PWM_PWM3_N_PE7 = GPIO_PE7, + + PWM_PWM4_PD7 = GPIO_PD7, + PWM_PWM4_PE4 = GPIO_PE4, + PWM_PWM4_N_PD4 = GPIO_PD4, + + PWM_PWM5_PB0 = GPIO_PB0, + PWM_PWM5_PE5 = GPIO_PE5, + PWM_PWM5_N_PD5 = GPIO_PD5, +}pwm_pin_e; + + + + +/** + * @brief Select the 32K clock source of pwm. + */ +typedef enum { + + PWM_CLOCK_32K_CHN_NONE = 0x00, + PWM_CLOCK_32K_CHN_PWM0 = 0x01, + PWM_CLOCK_32K_CHN_PWM1 = 0x02, + PWM_CLOCK_32K_CHN_PWM2 = 0x04, + PWM_CLOCK_32K_CHN_PWM3 = 0x08, + PWM_CLOCK_32K_CHN_PWM4 = 0x10, + PWM_CLOCK_32K_CHN_PWM5 = 0x20 + +}pwm_clk_32k_en_chn_e; + + + + + + +/** + * @brief This function servers to set pwm clock frequency, when pwm clock source is pclk. + * @param[in] pwm_clk_div - variable of the pwm clock. + * PWM frequency = System_clock / (pwm_clk_div+1). + * @return none. + */ +static inline void pwm_set_clk(unsigned char pwm_clk_div){ + + reg_pwm_clkdiv = pwm_clk_div; +} + +/** + * @brief This function servers to set pwm clock source is 32K. + * If you use 32K as the PWM clock source, you can work in suspend mode. + * but the 32K clock source cannot be divided and can only work in continuous mode and counting mode + * @param[in] pwm_32K_en_chn - This variable is used to select the specific PWM channel. + * @return none. + */ + +static inline void pwm_32k_chn_en(pwm_clk_32k_en_chn_e pwm_32K_en_chn){ + + reg_pwm_mode32k= pwm_32K_en_chn; + +} + + +/** + * @brief This fuction servers to set pin as pwm0 + * @param[in] pin - selected pin + * @return none. + */ +void pwm_set_pin(pwm_pin_e pin); + + + + +/** + * @brief This fuction servers to set pwm count status(CMP) time. + * @param[in] id - variable of enum to select the pwm number. + * @param[in] tcmp - variable of the CMP. + * @return none. + */ +static inline void pwm_set_tcmp(pwm_id_e id, unsigned short tcmp) +{ + reg_pwm_cmp(id) = tcmp; +} + + +/** + * @brief This fuction servers to set pwm cycle time. + * @param[in] id - variable of enum to select the pwm number. + * @param[in] tmax - variable of the cycle time. + * @return none. + */ +static inline void pwm_set_tmax(pwm_id_e id, unsigned short tmax){ + reg_pwm_max(id) = tmax; +} + + +/** + * @brief This fuction servers to start the pwm. + * @param[in] id - variable of enum to select the pwm number. + * @return none. + */ +static inline void pwm_start(pwm_id_e id){ + if(PWM0_ID == id){ + BM_SET(reg_pwm0_enable, BIT(0)); + } + else{ + BM_SET(reg_pwm_enable, BIT(id)); + } +} + + +/** + * @brief This fuction servers to stop the pwm. + * @param[in] id - variable of enum to select the pwm number. + * @return none. + */ +static inline void pwm_stop(pwm_id_e id){ + if(PWM0_ID == id){ + BM_CLR(reg_pwm0_enable, BIT(0)); + } + else{ + BM_CLR(reg_pwm_enable, BIT(id)); + } +} + + +/** + * @brief This fuction servers to revert the PWMx. + * @param[in] id - variable of enum to select the pwm number. + * @return none. + */ +static inline void pwm_invert_en(pwm_id_e id){ + reg_pwm_invert |= BIT(id); +} + + +/** + * @brief This fuction servers to disable the PWM revert function. + * @param[in] id - variable of enum to select the pwm number. + * @return none. + */ +static inline void pwm_invert_dis(pwm_id_e id){ + BM_CLR(reg_pwm_invert, BIT(id)); +} + + +/** + * @brief This fuction servers to revert the PWMx_N. + * @param[in] id - variable of enum to select the pwm number. + * @return none. + */ +static inline void pwm_n_invert_en(pwm_id_e id){ + reg_pwm_n_invert |= BIT(id); +} + + +/** + * @brief This fuction servers to disable the PWM revert function. + * @param[in] id - variable of enum to select the pwm number. + * @return none. + */ +static inline void pwm_n_invert_dis(pwm_id_e id){ + BM_CLR(reg_pwm_n_invert, BIT(id)); +} + + +/** + * @brief This fuction servers to enable the pwm polarity. + * @param[in] id - variable of enum to select the pwm number. + * @return none. + */ +static inline void pwm_set_polarity_en(pwm_id_e id){ + BM_SET(reg_pwm_pol, BIT(id)); +} + + +/** + * @brief This fuction servers to disable the pwm polarity. + * @param[in] id - variable of enum to select the pwm number. + * @return none. + */ +static inline void pwm_set_polarity_dis(pwm_id_e id){ + BM_CLR(reg_pwm_pol, BIT(id)); +} + + +/** + * @brief This fuction servers to enable the pwm interrupt. + * @param[in] mask - variable of enum to select the pwm interrupt source. + * @return none. + */ +static inline void pwm_set_irq_mask(pwm_irq_e mask){ + + if(mask==FLD_PWM0_IR_FIFO_IRQ) + { + BM_SET(reg_pwm_irq_mask(1), BIT(0)); + } + else + { + BM_SET(reg_pwm_irq_mask(0), mask); + } + +} + + +/** + * @brief This fuction servers to disable the pwm interrupt function. + * @param[in] mask - variable of enum to select the pwm interrupt source. + * @return none. + */ +static inline void pwm_clr_irq_mask(pwm_irq_e mask){ + + if(mask==FLD_PWM0_IR_FIFO_IRQ) + { + BM_SET(reg_pwm_irq_mask(1), BIT(0)); + } + else + { + BM_SET(reg_pwm_irq_mask(0), mask); + } + +} + + +/** + * @brief This fuction servers to get the pwm interrupt status. + * @param[in] status - variable of enum to select the pwm interrupt source. + * @return none. + */ +static inline unsigned char pwm_get_irq_status(pwm_irq_e status){ + + if(status==FLD_PWM0_IR_FIFO_IRQ) + { + return (reg_pwm_irq_sta(1) & BIT(0)); + } + else + { + return (reg_pwm_irq_sta(0) & status); + } + +} + + +/** + * @brief This fuction servers to clear the pwm interrupt.When a PWM interrupt occurs, the corresponding interrupt flag bit needs to be cleared manually. + * @param[in] status - variable of enum to select the pwm interrupt source. + * @return none. + */ +static inline void pwm_clr_irq_status(pwm_irq_e status){ + + if(status==FLD_PWM0_IR_FIFO_IRQ) + { + BM_SET(reg_pwm_irq_sta(1), BIT(0)); + } + else + { + BM_SET(reg_pwm_irq_sta(0), status); + } + +} + + +/** + * @brief This fuction servers to set pwm0 mode. + * @param[in] mode - variable of enum to indicates the pwm mode. + * @return none. + */ +static inline void pwm_set_pwm0_mode(pwm_mode_e mode){ + reg_pwm0_mode = mode; //only PWM0 has count/IR/fifo IR mode +} + + +/** + * @brief This fuction servers to set pwm cycle time & count status. + * @param[in] max_tick - variable of the cycle time. + * @param[in] cmp_tick - variable of the CMP. + * @return none. + */ +static inline void pwm_set_pwm0_tcmp_and_tmax_shadow(unsigned short max_tick, unsigned short cmp_tick) +{ + reg_pwm_tcmp0_shadow = cmp_tick; + reg_pwm_tmax0_shadow = max_tick; +} + + +/** + * @brief This fuction servers to set the pwm0 pulse number. + * @param[in] pulse_num - variable of the pwm pulse number.The maximum bits is 14bits. + * @return none. + */ +static inline void pwm_set_pwm0_pulse_num(unsigned short pulse_num){ + reg_pwm0_pulse_num0 = pulse_num; + reg_pwm0_pulse_num1 = pulse_num>>8; +} + + +/** + * @brief This fuction serves to set trigger level of interrupt for IR FiFo mode + * @param[in] trig_level - FIFO num int trigger level.When fifo numbers is less than this value.It's will take effect. + * @return none + */ +static inline void pwm_set_pwm0_ir_fifo_irq_trig_level(unsigned char trig_level) +{ + reg_pwm_ir_fifo_irq_trig_level = trig_level; +} + + +/** + * @brief This fuction serves to clear data in fifo. Only when pwm is in not active mode, + * it is possible to clear data in fifo. + * @return none + */ +static inline void pwm_clr_pwm0_ir_fifo(void) +{ + reg_pwm_ir_clr_fifo_data |= FLD_PWM0_IR_FIFO_CLR_DATA; +} + + +/** + * @brief This fuction serves to get the number of data in fifo. + * @return the number of data in fifo + */ +static inline unsigned char pwm_get_pwm0_ir_fifo_data_num(void)//????TODO +{ + return (reg_pwm_ir_fifo_data_status & FLD_PWM0_IR_FIFO_DATA_NUM); +} + + +/** + * @brief This fuction serves to determine whether data in fifo is empty. + * @return yes: 1 ,no: 0; + */ +static inline unsigned char pwm_get_pwm0_ir_fifo_is_empty(void) +{ + return (reg_pwm_ir_fifo_data_status & FLD_PWM0_IR_FIFO_EMPTY); +} + + +/** + * @brief This fuction serves to determine whether data in fifo is full. + * @return yes: 1 ,no: 0; + */ +static inline unsigned char pwm_get_pwm0_ir_fifo_is_full(void) +{ + return (reg_pwm_ir_fifo_data_status&FLD_PWM0_IR_FIFO_FULL); +} + + +/** + * @brief This fuction serves to config the pwm's dma wave form. + * @param[in] pulse_num - the number of pulse. + * @param[in] shadow_en - whether enable shadow mode. + * @param[in] carrier_en - must 1 or 0. + * @return none. + */ +static inline unsigned short pwm_cal_pwm0_ir_fifo_cfg_data(unsigned short pulse_num, unsigned char shadow_en, unsigned char carrier_en) +{ + return ( carrier_en<<15 | (shadow_en<<14) | (pulse_num & 0x3fff) ); +} + + +/** + * @brief This fuction serves to write data into FiFo + * @param[in] pulse_num - the number of pulse + * @param[in] use_shadow - determine whether the configuration of shadow cmp and shadow max is used + * 1: use shadow, 0: not use + * @param[in] carrier_en - enable sending carrier, 1: enable, 0: disable + * @return none + */ +static inline void pwm_set_pwm0_ir_fifo_cfg_data(unsigned short pulse_num, unsigned char use_shadow, unsigned char carrier_en) +{ + static unsigned char index=0; + unsigned short cfg_data = pwm_cal_pwm0_ir_fifo_cfg_data(pulse_num,use_shadow,carrier_en); + while(pwm_get_pwm0_ir_fifo_is_full()); + reg_pwm_ir_fifo_dat(index) = cfg_data; + index++; + index&=0x01; +} + + +/** + * @brief This function servers to configure DMA channel and some configures. + * @param[in] chn - to select the DMA channel. + * @return none + */ +void pwm_set_dma_config(dma_chn_e chn); + + +/** + * @brief This function servers to configure DMA channel address and length. + * @param[in] chn - to select the DMA channel. + * @param[in] buf_addr - the address where DMA need to get data from SRAM. + * @param[in] len - the length of data in SRAM. + * @return none + */ +void pwm_set_dma_buf(dma_chn_e chn,unsigned int buf_addr,unsigned int len); + + +/** + * @brief This function servers to enable DMA channel. + * @param[in] chn - to select the DMA channel. + * @return none + */ +void pwm_ir_dma_mode_start(dma_chn_e chn); + + + +/** + * @brief This function servers to configure DMA head node. + * @param[in] chn - to select the DMA channel. + * @param[in] src_addr - to configure DMA source address. + * @param[in] data_len - to configure DMA length. + * @param[in] head_of_list - to configure the address of the next node configure. + * @return none + */ +void pwm_set_dma_chain_llp(dma_chn_e chn,unsigned short * src_addr, unsigned int data_len,dma_chain_config_t * head_of_list); + + + + +/** + * @brief This function servers to configure DMA cycle chain node. + * @param[in] chn - to select the DMA channel. + * @param[in] config_addr - to servers to configure the address of the current node. + * @param[in] llponit - to configure the address of the next node configure. + * @param[in] src_addr - to configure DMA source address. + * @param[in] data_len - to configure DMA length. + * @return none + */ +void pwm_set_tx_dma_add_list_element(dma_chn_e chn,dma_chain_config_t *config_addr,dma_chain_config_t *llponit ,unsigned short * src_addr,unsigned int data_len); + + + +#endif + + + + + diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/adc_reg.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/adc_reg.h new file mode 100755 index 0000000..680fe35 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/adc_reg.h @@ -0,0 +1,94 @@ +/******************************************************************************************************** + * @file adc_reg.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef ADC_REG_H +#define ADC_REG_H +#include "../sys.h" + +#define areg_adc_clk_setting 0x82 +enum +{ + FLD_CLK_24M_TO_SAR_EN = BIT(6), +}; + +#define areg_adc_vref 0xea +enum{ + FLD_ADC_VREF_CHN_M = BIT_RNG(0,1), +}; +#define areg_adc_ain_chn_misc 0xeb +enum{ + FLD_ADC_AIN_NEGATIVE = BIT_RNG(0,3), + FLD_ADC_AIN_POSITIVE = BIT_RNG(4,7), +}; +#define areg_adc_res_m 0xec +enum{ + FLD_ADC_RES_M = BIT_RNG(0,1), + FLD_ADC_EN_DIFF_CHN_M = BIT(6), +}; +#define areg_adc_tsmaple_m 0xee +enum{ + FLD_ADC_TSAMPLE_CYCLE_CHN_M = BIT_RNG(0,3), +}; +#define areg_r_max_mc 0xef +enum{ + FLD_R_MAX_MC0 = BIT_RNG(0,7),//0xef<7:0> r_max_mc[7:0] +}; +#define areg_r_max_s 0xf1 +enum{ + FLD_R_MAX_S = BIT_RNG(0,3),//0xf1<3:0> r_max_s + FLD_R_MAX_MC1 = BIT_RNG(6,7),//0xf1<7:6> r_max_mc[9:8] +}; +#define areg_adc_chn_en 0xf2 +enum{ + FLD_ADC_CHN_EN_M = BIT(2), + FLD_ADC_MAX_SCNT = BIT_RNG(4,5), +}; +#define areg_adc_data_sample_control 0xf3 +enum{ + FLD_NOT_SAMPLE_ADC_DATA = BIT(0), +}; +#define areg_adc_sample_clk_div 0xf4 +enum{ + FLD_ADC_SAMPLE_CLK_DIV = BIT_RNG(0,2), +}; +#define areg_adc_misc_l 0xf7 +#define areg_adc_misc_h 0xf8 +#define areg_adc_vref_vbat_div 0xf9 +enum{ + FLD_ADC_VREF_VBAT_DIV = BIT_RNG(2,3), +}; +#define areg_ain_scale 0xfa +enum{ + FLD_ADC_ITRIM_PREAMP = BIT_RNG(0,1), + FLD_ADC_ITRIM_VREFBUF = BIT_RNG(2,3), + FLD_ADC_ITRIM_VCMBUF = BIT_RNG(4,5), + FLD_SEL_AIN_SCALE = BIT_RNG(6,7), +}; +#define areg_adc_pga_ctrl 0xfc +enum{ + FLD_SAR_ADC_POWER_DOWN = BIT(5), +}; +#define areg_temp_sensor_ctrl 0x00 +enum{ + FLD_TEMP_SENSOR_POWER_DOWN = BIT(4), +}; +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/aes_reg.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/aes_reg.h new file mode 100755 index 0000000..a256f0d --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/aes_reg.h @@ -0,0 +1,54 @@ +/******************************************************************************************************** + * @file aes_reg.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef _AES_REG_H_ +#define _AES_REG_H_ + +#include "../sys.h" + + +#define reg_aes_mode REG_ADDR32(0x1600b0) +enum{ + FLD_AES_START = BIT(0), + FLD_AES_MODE = BIT(1), /**< 0-ciher 1-deciher */ +}; + +#define reg_embase_addr REG_ADDR32(0x140b04) + +#define reg_aes_irq_mask REG_ADDR32(0x16000c) + +#define reg_aes_irq_status REG_ADDR32(0x160010) + +#define reg_aes_clr_irq_status REG_ADDR32(0x160018) +/** + * @brief Define AES IRQ + */ +typedef enum{ + FLD_CRYPT_IRQ = BIT(7), +}aes_irq_e; + + +#define reg_aes_key(v) REG_ADDR32(0x1600b4+(v*4)) + +#define reg_aes_ptr REG_ADDR32(0x1600c4) + +#endif /* _AES_REG_H_ */ diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/analog_reg.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/analog_reg.h new file mode 100755 index 0000000..9f1e9b7 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/analog_reg.h @@ -0,0 +1,65 @@ +/******************************************************************************************************** + * @file analog_reg.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef ANALOG_REG_H +#define ANALOG_REG_H +#include "../sys.h" +/******************************* alg registers: 140180 ******************************/ +#define ALG_BASE_ADDR 0x140180 +#define reg_ana_addr REG_ADDR8(ALG_BASE_ADDR) +#define reg_ana_ctrl REG_ADDR8(ALG_BASE_ADDR+0x02) +enum +{ + //FLD_ANA_TX_EN = BIT(0), + FLD_ANA_RX_EN = BIT(1), + FLD_ANA_MASKX_TX_DONE = BIT(2), + FLD_ANA_MASKX_RX_DONE = BIT(3), + FLD_ANA_CONTIU_ACC = BIT(4), + FLD_ANA_RW = BIT(5), /**< 1:write,0:read */ + FLD_ANA_CYC = BIT(6), + FLD_ANA_BUSY = BIT(7), +}; +#define reg_ana_len REG_ADDR8(ALG_BASE_ADDR+0x03) +#define reg_ana_data(n) REG_ADDR8(ALG_BASE_ADDR+0x04+(n)) +#define reg_ana_addr_data16 REG_ADDR16(ALG_BASE_ADDR+0x04) +#define reg_ana_addr_data32 REG_ADDR32(ALG_BASE_ADDR+0x04) + +#define reg_ana_sta REG_ADDR8(ALG_BASE_ADDR+0x09) +enum +{ + FLD_ANA_RX_DONE = BIT(7), +}; +#define reg_ana_irq_sta REG_ADDR8(ALG_BASE_ADDR+0x0a) +enum +{ + FLD_ANA_TXBUFF_IRQ = BIT(0), + FLD_ANA_RXBUFF_IRQ = BIT(1), +}; +#define reg_ana_dma_ctl REG_ADDR8(ALG_BASE_ADDR+0x0b) +enum +{ + FLD_ANA_CYC1 = BIT(0), + FLD_ANA_DMA_EN = BIT(1), + +}; + +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/audio_reg.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/audio_reg.h new file mode 100755 index 0000000..682a5db --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/audio_reg.h @@ -0,0 +1,376 @@ +/******************************************************************************************************** + * @file audio_reg.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef AUDIO_REG_H +#define AUDIO_REG_H +#include "../sys.h" + +#define REG_AUDIO_AHB_BASE 0x120000 +#define REG_CODEC_BASE_ADDR 0x120200 +#define REG_AUDIO_APB_BASE 0x140500 +#define reg_fifo_buf_adr(i) REG_AUDIO_AHB_BASE+(i)*0x40 +#define reg_audio_en REG_ADDR8(REG_AUDIO_APB_BASE+0x00) +enum +{ + FLD_AUDIO_I2S_CLK_EN = BIT(0), + FLD_AUDIO_CLK_DIV2 = BIT(1), + FLD_AUDIO_MC_CLK_EN = BIT(2), + FLD_AUDIO_MC_CLK_INV_O = BIT(3), +}; + +#define reg_i2s_cfg REG_ADDR8(REG_AUDIO_APB_BASE+0x01) +enum +{ + FLD_AUDIO_I2S_FORMAT = BIT_RNG(0,1), + FLD_AUDIO_I2S_WL = BIT_RNG(2,3), + FLD_AUDIO_I2S_LRP = BIT(4), + FLD_AUDIO_I2S_LRSWAP = BIT(5), + FLD_AUDIO_I2S_ADC_DCI_MS = BIT(6), + FLD_AUDIO_I2S_DAC_DCI_MS = BIT(7), +}; + +#define reg_i2s_cfg2 REG_ADDR8(REG_AUDIO_APB_BASE+0x02) + +enum +{ + FLD_AUDIO_FIFO1_RST = BIT(3), +}; +#define reg_audio_ctrl REG_ADDR8(REG_AUDIO_APB_BASE+0x03) +enum +{ + FLD_AUDIO_I2S_CMODE = BIT_RNG(0,1), + FLD_AUDIO_CODEC_I2S_SEL = BIT(2), + FLD_AUDIO_I2S_OUT_BIT_SEL = BIT(3), +}; + +#define reg_audio_tune REG_ADDR8(REG_AUDIO_APB_BASE+0x04) +enum +{ + FLD_AUDIO_I2S_I2S_AIN0_COME = BIT_RNG(0,1), + FLD_AUDIO_I2S_I2S_AIN1_COME = BIT_RNG(2,3), + FLD_AUDIO_I2S_I2S_AOUT_COME = BIT_RNG(4,6), +}; + + +#define reg_audio_sel REG_ADDR8(REG_AUDIO_APB_BASE+0x05) +enum +{ + FLD_AUDIO_AIN0_SEL = BIT_RNG(0,1), + FLD_AUDIO_AOUT0_SEL = BIT_RNG(2,3), + FLD_AUDIO_AIN1_SEL = BIT_RNG(4,5), + FLD_AUDIO_AOUT1_SEL = BIT_RNG(6,7), +}; + +#define reg_audio_i2c_addr REG_ADDR8(REG_AUDIO_APB_BASE+0x08) +#define reg_audio_i2c_mode REG_ADDR8(REG_AUDIO_APB_BASE+0x09) + +#define reg_fifo_trig0 REG_ADDR8(REG_AUDIO_APB_BASE+0x0a) + +#define reg_audio_ptr_set REG_ADDR8(REG_AUDIO_APB_BASE+0x10) +enum +{ + FLD_AUDIO_TX_PTR_SEL = BIT(0), + FLD_AUDIO_RX_PTR_SEL = BIT(4), +}; + +#define reg_audio_ptr_en REG_ADDR8(REG_AUDIO_APB_BASE+0x11) +enum +{ + FLD_AUDIO_TX_WPTR_PTR_EN = BIT(0), + FLD_AUDIO_TX_RPTR_PTR_EN = BIT(1), + FLD_AUDIO_RX_WPTR_PTR_EN = BIT(2), + FLD_AUDIO_RX_RPTR_PTR_EN = BIT(3), + +}; + +enum +{ + FLD_AUDIO_FIFO_AOUT0_TRIG_NUM = BIT_RNG(0,3), + FLD_AUDIO_FIFO_AIN0_TRIG_NUM = BIT_RNG(4,7), +}; + +#define fifo_trig1 REG_ADDR8(REG_AUDIO_APB_BASE+0x0b) + +enum +{ + FLD_AUDIO_FIFO_AOUT1_TRIG_NUM = BIT_RNG(0,3), + FLD_AUDIO_FIFO_AIN1_TRIG_NUM = BIT_RNG(4,7), +}; + +#define reg_tx_wptr REG_ADDR16(REG_AUDIO_APB_BASE+0x20) +#define reg_tx_rptr REG_ADDR16(REG_AUDIO_APB_BASE+0x22) + +#define reg_tx_max REG_ADDR16(REG_AUDIO_APB_BASE+0x26) + +#define reg_rx_rptr REG_ADDR16(REG_AUDIO_APB_BASE+0x2a) +#define reg_rx_wptr REG_ADDR16(REG_AUDIO_APB_BASE+0x28) + +#define reg_rx_max REG_ADDR16(REG_AUDIO_APB_BASE+0x2e) + +#define reg_th0_h1 REG_ADDR16(REG_AUDIO_APB_BASE+0x30)//tx +#define reg_th0_l1 REG_ADDR16(REG_AUDIO_APB_BASE+0x32)//tx + +#define reg_th0_h2 REG_ADDR16(REG_AUDIO_APB_BASE+0x38)//tx +#define reg_th0_l2 REG_ADDR16(REG_AUDIO_APB_BASE+0x3a)//tx + + +#define reg_th1_h1 REG_ADDR16(REG_AUDIO_APB_BASE+0x40)//rx +#define reg_th1_l1 REG_ADDR16(REG_AUDIO_APB_BASE+0x42)//rx + +#define reg_th1_h2 REG_ADDR16(REG_AUDIO_APB_BASE+0x48)//rx +#define reg_th1_l2 REG_ADDR16(REG_AUDIO_APB_BASE+0x4a)//rx + + + +#define reg_irq_fifo_state REG_ADDR8(REG_AUDIO_APB_BASE+0x5c) +typedef enum +{ + FLD_AUDIO_IRQ_TXFIFO_L_L1 = BIT(0), + FLD_AUDIO_IRQ_TXFIFO_H_L1 = BIT(1), + FLD_AUDIO_IRQ_TXFIFO_L_L2 = BIT(2), + FLD_AUDIO_IRQ_TXFIFO_H_L2 = BIT(3), + + FLD_AUDIO_IRQ_RXFIFO_L_L1 = BIT(4), + FLD_AUDIO_IRQ_RXFIFO_H_L1 = BIT(5), + FLD_AUDIO_IRQ_RXFIFO_L_L2 = BIT(6), + FLD_AUDIO_IRQ_RXFIFO_H_L2 = BIT(7), + +}audio_fifo_irq_status_type_e; + +#define reg_irq_fifo_mask REG_ADDR8(REG_AUDIO_APB_BASE+0x5d) + +typedef enum +{ + FLD_AUDIO_IRQ_TXFIFO_L_L1_EN = BIT(0), + FLD_AUDIO_IRQ_TXFIFO_H_L1_EN = BIT(1), + FLD_AUDIO_IRQ_TXFIFO_L_L2_EN = BIT(2), + FLD_AUDIO_IRQ_TXFIFO_H_L2_EN = BIT(3), + + FLD_AUDIO_IRQ_RXFIFO_L_L1_EN = BIT(4), + FLD_AUDIO_IRQ_RXFIFO_H_L1_EN = BIT(5), + FLD_AUDIO_IRQ_RXFIFO_L_L2_EN = BIT(6), + FLD_AUDIO_IRQ_RXFIFO_H_L2_EN = BIT(7), + +}audio_fifo_irq_mask_type_e; + + + +#define reg_irq_manual_en REG_ADDR8(REG_AUDIO_APB_BASE+0x5e) +enum +{ + FLD_AUDIO_IRQ_TXFIFO_L_L1_MAN_EN = BIT(0), + FLD_AUDIO_IRQ_TXFIFO_H_L1_MAN_EN = BIT(1), + FLD_AUDIO_IRQ_TXFIFO_L_L2_MAN_EN = BIT(2), + FLD_AUDIO_IRQ_TXFIFO_H_L2_MAN_EN = BIT(3), + + FLD_AUDIO_IRQ_RXFIFO_L_L1_MAN_EN = BIT(4), + FLD_AUDIO_IRQ_RXFIFO_H_L1_MAN_EN = BIT(5), + FLD_AUDIO_IRQ_RXFIFO_L_L2_MAN_EN = BIT(6), + FLD_AUDIO_IRQ_RXFIFO_H_L2_MAN_EN = BIT(7) + +}; + +#define reg_int_pcm_num REG_ADDR16(REG_AUDIO_APB_BASE+0x50) +#define reg_dec_pcm_num REG_ADDR16(REG_AUDIO_APB_BASE+0x52) + +#define reg_pcm_clk_num REG_ADDR8(REG_AUDIO_APB_BASE+0x54) + + + +#define reg_audio_codec_stat_ctr REG_ADDR8(REG_CODEC_BASE_ADDR+(0x00<<2)) +#define addr_audio_codec_stat_ctr 0x00 +enum +{ + FLD_AUDIO_CODEC_ADC12_LOCKED = BIT(3), + FLD_AUDIO_CODEC_DAC_LOCKED = BIT(4), + FLD_AUDIO_CODEC_PON_ACK = BIT(7), +}; + + +#define reg_audio_codec_vic_ctr REG_ADDR8(REG_CODEC_BASE_ADDR+(0x06<<2)) +#define addr_audio_codec_vic_ctr 0x06 +enum +{ + FLD_AUDIO_CODEC_SB = BIT(0), + FLD_AUDIO_CODEC_SB_ANALOG = BIT(1), + FLD_AUDIO_CODEC_SLEEP_ANALOG = BIT(2), +}; + + + +#define reg_audio_codec_dac_itf_ctr REG_ADDR8(REG_CODEC_BASE_ADDR+(0x08<<2)) +#define addr_audio_codec_dac_itf_ctr 0x08 + +#define reg_audio_codec_adc_itf_ctr REG_ADDR8(REG_CODEC_BASE_ADDR+(0x09<<2)) +#define addr_audio_codec_adc_itf_ctr 0x09 +enum +{ + FLD_AUDIO_CODEC_FORMAT = BIT_RNG(0,1), + FLD_AUDIO_CODEC_DAC_ITF_SB = BIT(4), + FLD_AUDIO_CODEC_SLAVE = BIT(5), + FLD_AUDIO_CODEC_WL = BIT_RNG(6,7), +}; + +#define reg_audio_codec_adc2_ctr REG_ADDR8(REG_CODEC_BASE_ADDR+(0x0a<<2)) +#define addr_audio_codec_adc2_ctr 0x0a +enum +{ + FLD_AUDIO_CODEC_ADC12_SB = BIT(0), +}; + +#define reg_audio_codec_dac_freq_ctr REG_ADDR8(REG_CODEC_BASE_ADDR+(0x0b<<2)) +#define addr_audio_codec_dac_freq_ctr 0x0b +enum +{ + FLD_AUDIO_CODEC_DAC_FREQ = BIT_RNG(0,3), +}; + +#define reg_audio_codec_adc_wnf_ctr REG_ADDR8(REG_CODEC_BASE_ADDR+(0x0e<<2)) +#define addr_audio_codec_adc_wnf_ctr 0x0e +enum +{ + FLD_AUDIO_CODEC_ADC12_WNF = BIT_RNG(0,1), +}; + + + +#define reg_audio_codec_adc_freq_ctr REG_ADDR8(REG_CODEC_BASE_ADDR+(0x0f<<2)) +#define addr_audio_codec_adc_freq_ctr 0x0f +enum +{ + FLD_AUDIO_CODEC_ADC_FREQ = BIT_RNG(0,3), + FLD_AUDIO_CODEC_ADC12_HPF_EN = BIT(4), +}; + + + +#define reg_audio_dmic_12 REG_ADDR8(REG_CODEC_BASE_ADDR+(0x10<<2)) +#define addr_audio_dmic_12 0x10 +enum +{ + FLD_AUDIO_CODEC_ADC_DMIC_SEL2 = BIT_RNG(0,1), + FLD_AUDIO_CODEC_ADC_DMIC_SEL1 = BIT_RNG(2,3), + FLD_AUDIO_CODEC_DMIC2_SB = BIT(6), + FLD_AUDIO_CODEC_DMIC1_SB = BIT(7), +}; + + +#define reg_audio_codec_hpl_gain REG_ADDR8(REG_CODEC_BASE_ADDR+(0x15<<2)) +#define addr_audio_codec_hpl_gain 0x15 + +enum +{ + FLD_AUDIO_CODEC_HPL_GOL = BIT_RNG(0,4), + FLD_AUDIO_CODEC_HPL_LRGO = BIT(7), +}; + +#define reg_audio_codec_hpr_gain REG_ADDR8(REG_CODEC_BASE_ADDR+(0x16<<2)) +#define addr_audio_codec_hpr_gain 0x16 +enum +{ + FLD_AUDIO_CODEC_HPR_GOR = BIT_RNG(0,4), +}; + + +#define reg_audio_codec_mic1_ctr REG_ADDR8(REG_CODEC_BASE_ADDR+(0x17<<2)) +#define addr_audio_codec_mic1_ctr 0x17 + +enum +{ + FLD_AUDIO_CODEC_MIC1_SEL = BIT(0), + FLD_AUDIO_CODEC_MICBIAS1_SB = BIT(5), + FLD_AUDIO_CODEC_MIC_DIFF1 = BIT(6), + FLD_AUDIO_CODEC_MICBIAS1_V = BIT(7), +}; + +#define reg_audio_codec_mic2_ctr REG_ADDR8(REG_CODEC_BASE_ADDR+(0x18<<2)) +#define addr_audio_codec_mic2_ctr 0x18 +enum +{ + FLD_AUDIO_CODEC_MIC2_SEL = BIT(0), + FLD_AUDIO_CODEC_MIC_DIFF2 = BIT(6), +}; + + + +#define reg_audio_codec_dacl_gain REG_ADDR8(REG_CODEC_BASE_ADDR+(0x2a<<2)) +#define addr_audio_codec_dacl_gain 0x2a +enum +{ + FLD_AUDIO_CODEC_DAC_GODL = BIT_RNG(0,5), + FLD_AUDIO_CODEC_DAC_LRGOD = BIT(7), +}; + +#define reg_audio_codec_dacr_gain REG_ADDR8(REG_CODEC_BASE_ADDR+(0x2b<<2)) +#define addr_audio_codec_dacr_gain 0x2b +enum +{ + FLD_AUDIO_CODEC_DAC_GODR = BIT_RNG(0,5), +}; + +#define reg_audio_codec_mic_l_R_gain REG_ADDR8(REG_CODEC_BASE_ADDR+(0x1f<<2)) +#define addr_audio_codec_mic_l_R_gain 0x1f +enum +{ + FLD_AUDIO_CODEC_AMIC_L_GAIN = BIT_RNG(0,2), + FLD_AUDIO_CODEC_AMIC_R_GAIN = BIT_RNG(3,5), +}; + + +#define reg_audio_codec_dac_ctr REG_ADDR8(REG_CODEC_BASE_ADDR+(0x23<<2)) +#define addr_audio_codec_dac_ctr 0x23 +enum +{ + FLD_AUDIO_CODEC_DAC_SB = BIT(4), + FLD_AUDIO_CODEC_DAC_LEFT_ONLY = BIT(5), + FLD_AUDIO_CODEC_DAC_SOFT_MUTE = BIT(7), +}; + + + +#define reg_audio_codec_adc12_ctr REG_ADDR8(REG_CODEC_BASE_ADDR+(0x24<<2)) +#define addr_audio_codec_adc12_ctr 0x24 +enum +{ + FLD_AUDIO_CODEC_ADC1_SB = BIT(4), + FLD_AUDIO_CODEC_ADC2_SB = BIT(5), + FLD_AUDIO_CODEC_ADC12_SOFT_MUTE = BIT(7), +}; + + +#define reg_audio_adc1_gain REG_ADDR8(REG_CODEC_BASE_ADDR+(0x2c<<2)) +#define addr_audio_adc1_gain 0x2c +enum +{ + FLD_AUDIO_CODEC_ADC_GID1 = BIT_RNG(0,5), + FLD_AUDIO_CODEC_ADC_LRGID = BIT(7), +}; + +#define reg_audio_adc2_gain REG_ADDR8(REG_CODEC_BASE_ADDR+(0x2d<<2)) +enum +{ + FLD_AUDIO_CODEC_ADC_GID2 = BIT_RNG(0,5), + +}; + + +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/dma_reg.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/dma_reg.h new file mode 100755 index 0000000..7cc9e01 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/dma_reg.h @@ -0,0 +1,132 @@ +/******************************************************************************************************** + * @file dma_reg.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef DMA_REG_H +#define DMA_REG_H +#include "../sys.h" +/******************************* dma registers: 0x100400 ******************************/ +#define reg_dma_id REG_ADDR32(0x100400) +#define reg_dma_cfg REG_ADDR32(0x100410) +//enum{ +// FLD_DMA_CHANNEL_NUM = BIT_RNG(0,3), +// FLD_DMA_FIFO_DEPTH = BIT_RNG(4,9), +// FLD_DMA_REQ_NUM = BIT_RNG(10,14), +// FLD_DMA_REQ_SYNC = BIT(30), +// FLD_DMA_CHANINXFR = BIT(31), +//}; +//in C99, FLD_DMA_CHANINXFR = BIT(31) is error +#define FLD_DMA_CHANNEL_NUM = BIT_RNG(0,3), +#define FLD_DMA_FIFO_DEPTH = BIT_RNG(4,9), +#define FLD_DMA_REQ_NUM = BIT_RNG(10,14), +#define FLD_DMA_REQ_SYNC = BIT(30), +#define FLD_DMA_CHANINXFR = BIT(31), + +#define reg_dma_ctrl(i) REG_ADDR32(( 0x00100444 +(i)*0x14)) + +enum{ + FLD_DMA_CHANNEL_ENABLE = BIT(0), + FLD_DMA_CHANNEL_TC_MASK = BIT(1), + FLD_DMA_CHANNEL_ERR_MASK = BIT(2), + FLD_DMA_CHANNEL_ABT_MASK = BIT(3), + FLD_DMA_CHANNEL_DST_REQ_SEL = BIT_RNG(4,8), + FLD_DMA_CHANNEL_SRC_REQ_SEL = BIT_RNG(9,13), + FLD_DMA_CHANNEL_DST_ADDR_CTRL = BIT_RNG(14,15), + FLD_DMA_CHANNEL_SRC_ADDR_CTRL = BIT_RNG(16,17), + FLD_DMA_CHANNEL_DST_MODE = BIT(18), + FLD_DMA_CHANNEL_SRC_MODE = BIT(19), + FLD_DMA_CHANNEL_DST_WIDTH = BIT_RNG(20,21), + FLD_DMA_CHANNEL_SRC_WIDTH = BIT_RNG(22,23), +}; + +#define reg_dma_ctr0(i) REG_ADDR8(( 0x00100444 +(i)*0x14)) + + +#define reg_dma_err_isr REG_ADDR8(0x100430) +#define reg_dma_abt_isr REG_ADDR8(0x100431) +#define reg_dma_tc_isr REG_ADDR8(0x100432) + +enum{ + FLD_DMA_CHANNEL0_IRQ = BIT(0), + FLD_DMA_CHANNEL1_IRQ = BIT(1), + FLD_DMA_CHANNEL2_IRQ = BIT(2), + FLD_DMA_CHANNEL3_IRQ = BIT(3), + FLD_DMA_CHANNEL4_IRQ = BIT(4), + FLD_DMA_CHANNEL5_IRQ = BIT(5), + FLD_DMA_CHANNEL6_IRQ = BIT(6), + FLD_DMA_CHANNEL7_IRQ = BIT(7), +}; + + + + + +#define reg_dma_ctr3(i) REG_ADDR8((0x00100447 +(i)*0x14)) + +enum{ + FLD_DMA_SRC_BURST_SIZE = BIT_RNG(0,2), + FLD_DMA_R_NUM_EN = BIT(4), + FLD_DMA_PRIORITY = BIT(5), + FLD_DMA_W_NUM_EN = BIT(6), + FLD_DMA_AUTO_ENABLE_EN = BIT(7), +}; + + + +#define reg_dma_src_addr(i) REG_ADDR32 (( 0x00100448 +(i)*0x14)) +#define reg_dma_dst_addr(i) REG_ADDR32 (( 0x0010044c +(i)*0x14)) +#define reg_dma_size(i) REG_ADDR32 (( 0x00100450 +(i)*0x14)) + +enum{ + FLD_DMA_TX_SIZE = BIT_RNG(0,21), + FLD_DMA_TX_SIZE_IDX = BIT_RNG(22,23), +}; + + + + +#define reg_dma_cr3_size(i) (*(volatile unsigned long*) ( 0x00100452 +(i)*0x14)) + +enum{ + FLD_DMA_TSR2_SIZE_IDX = BIT_RNG(6,7), +}; + +#define reg_dma_llp(i) REG_ADDR32 (( 0x00100454 +(i)*0x14)) + + +#define reg_dma_rx_wptr REG_ADDR8(0x801004f4) +#define reg_dma_tx_wptr REG_ADDR8(0x80100500) + +enum{ + FLD_DMA_WPTR_MASK = BIT_RNG(0,4), +}; + + +#define reg_dma_rx_rptr REG_ADDR8(0x801004f5) +#define reg_dma_tx_rptr REG_ADDR8(0x80100501) +enum{ + FLD_DMA_RPTR_MASK = BIT_RNG(0,4), + FLD_DMA_RPTR_SET = BIT(5), + FLD_DMA_RPTR_NEXT = BIT(6), + FLD_DMA_RPTR_CLR = BIT(7), +}; + +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/gpio_reg.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/gpio_reg.h new file mode 100755 index 0000000..86a3eb1 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/gpio_reg.h @@ -0,0 +1,170 @@ +/******************************************************************************************************** + * @file gpio_reg.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef GPIO_REG_H_ +#define GPIO_REG_H_ +#include "../sys.h" +/******************************* gpio registers: 0x140300 ******************************/ +//PA +#define reg_gpio_pa_setting1 REG_ADDR32(0x140300) +#define reg_gpio_pa_in REG_ADDR8(0x140300) +#define reg_gpio_pa_ie REG_ADDR8(0x140301) +#define reg_gpio_pa_oen REG_ADDR8(0x140302) +#define reg_gpio_pa_out REG_ADDR8(0x140303) + +#define reg_gpio_pa_setting2 REG_ADDR32(0x140304) +#define reg_gpio_pa_pol REG_ADDR8(0x140304) +#define reg_gpio_pa_ds REG_ADDR8(0x140305) +#define reg_gpio_pa_gpio REG_ADDR8(0x140306) +#define reg_gpio_pa_irq_en REG_ADDR8(0x140307) + +#define reg_gpio_pa_fs REG_ADDR16(0x140330) +#define reg_gpio_pa_fuc_l REG_ADDR8(0x140330) +#define reg_gpio_pa_fuc_h REG_ADDR8(0x140331) + +//PB +#define reg_gpio_pb_setting1 REG_ADDR32(0x140308) +#define reg_gpio_pb_in REG_ADDR8(0x140308) +#define reg_gpio_pb_ie REG_ADDR8(0x140309) +#define reg_gpio_pb_oen REG_ADDR8(0x14030a) +#define reg_gpio_pb_out REG_ADDR8(0x14030b) + +#define reg_gpio_pb_setting2 REG_ADDR32(0x14030c) +#define reg_gpio_pb_pol REG_ADDR8(0x14030c) +#define reg_gpio_pb_ds REG_ADDR8(0x14030d) +#define reg_gpio_pb_gpio REG_ADDR8(0x14030e) +#define reg_gpio_pb_irq_en REG_ADDR8(0x14030f) + +#define reg_gpio_pb_fs REG_ADDR16(0x140332) +#define reg_gpio_pb_fuc_l REG_ADDR8(0x140332) +#define reg_gpio_pb_fuc_h REG_ADDR8(0x140333) + +//PC +#define reg_gpio_pc_setting1 REG_ADDR32(0x140310) +#define reg_gpio_pc_in REG_ADDR8(0x140310) +#define areg_gpio_pc_ie 0xbd +#define areg_gpio_pc_pe 0xbe +#define reg_gpio_pc_oen REG_ADDR8(0x140312) +#define reg_gpio_pc_out REG_ADDR8(0x140313) + +#define reg_gpio_pc_setting2 REG_ADDR32(0x140314) +#define reg_gpio_pc_pol REG_ADDR8(0x140314) +#define areg_gpio_pc_ds 0xbf +#define reg_gpio_pc_gpio REG_ADDR8(0x140316) +#define reg_gpio_pc_irq_en REG_ADDR8(0x140317) + +#define reg_gpio_pc_fs REG_ADDR16(0x140334) +#define reg_gpio_pc_fuc_l REG_ADDR8(0x140334) +#define reg_gpio_pc_fuc_h REG_ADDR8(0x140335) + +//PD +#define reg_gpio_pd_setting1 REG_ADDR32(0x140318) +#define reg_gpio_pd_in REG_ADDR8(0x140318) +#define areg_gpio_pd_ie 0xc0 +#define areg_gpio_pd_pe 0xc1 +#define reg_gpio_pd_oen REG_ADDR8(0x14031a) +#define reg_gpio_pd_out REG_ADDR8(0x14031b) + +#define reg_gpio_pd_setting2 REG_ADDR32(0x14031c) +#define reg_gpio_pd_pol REG_ADDR8(0x14031c) +#define areg_gpio_pd_ds 0xc2 +#define reg_gpio_pd_gpio REG_ADDR8(0x14031e) +#define reg_gpio_pd_irq_en REG_ADDR8(0x14031f) + +#define reg_gpio_pd_fs REG_ADDR16(0x140336) +#define reg_gpio_pd_fuc_l REG_ADDR8(0x140336)//default 0xf0 +#define reg_gpio_pd_fuc_h REG_ADDR8(0x140337) + +//PE +#define reg_gpio_pe_setting1 REG_ADDR32(0x140320) +#define reg_gpio_pe_in REG_ADDR8(0x140320) +#define reg_gpio_pe_ie REG_ADDR8(0x140321) +#define reg_gpio_pe_oen REG_ADDR8(0x140322) +#define reg_gpio_pe_out REG_ADDR8(0x140323) + +#define reg_gpio_pe_setting2 REG_ADDR32(0x140324) +#define reg_gpio_pe_pol REG_ADDR8(0x140324) +#define reg_gpio_pe_ds REG_ADDR8(0x140325) +#define reg_gpio_pe_gpio REG_ADDR8(0x140326) +#define reg_gpio_pe_irq_en REG_ADDR8(0x140327) + +#define reg_gpio_pe_fs REG_ADDR16(0x140350) +#define reg_gpio_pe_fuc_l REG_ADDR8(0x140350) +#define reg_gpio_pe_fuc_h REG_ADDR8(0x140351) + +//PF +#define reg_gpio_pf_setting1 REG_ADDR32(0x140328) +#define reg_gpio_pf_in REG_ADDR8(0x140328) +#define reg_gpio_pf_ie REG_ADDR8(0x140329) +#define reg_gpio_pf_oen REG_ADDR8(0x14032a) +#define reg_gpio_pf_out REG_ADDR8(0x14032b) + +#define reg_gpio_pf_setting2 REG_ADDR32(0x14032c) +#define reg_gpio_pf_ds REG_ADDR8(0x14032d) +#define reg_gpio_pf_gpio REG_ADDR8(0x14032e) + +#define reg_gpio_pf_fs REG_ADDR16(0x140356) +#define reg_gpio_pf_fuc_l REG_ADDR8(0x140356) +#define reg_gpio_pf_fuc_h REG_ADDR8(0x140357) + +#define reg_gpio_in(i) REG_ADDR8(0x140300+((i>>8)<<3)) +#define reg_gpio_ie(i) REG_ADDR8(0x140301+((i>>8)<<3)) +#define reg_gpio_oen(i) REG_ADDR8(0x140302+((i>>8)<<3)) +#define reg_gpio_out(i) REG_ADDR8(0x140303+((i>>8)<<3)) +#define reg_gpio_pol(i) REG_ADDR8(0x140304+((i>>8)<<3)) +#define reg_gpio_ds(i) REG_ADDR8(0x140305+((i>>8)<<3)) + + +#define reg_gpio_func(i) REG_ADDR8(0x140306+((i>>8)<<3)) +#define reg_gpio_irq_en(i) REG_ADDR8(0x140307+((i>>8)<<3)) // reg_irq_mask: FLD_IRQ_GPIO_EN +#define reg_gpio_irq_risc0_en(i) REG_ADDR8(0x140338 + (i >> 8)) // reg_irq_mask: FLD_IRQ_GPIO_RISC0_EN +#define reg_gpio_irq_risc1_en(i) REG_ADDR8(0x140340 + (i >> 8)) // reg_irq_mask: FLD_IRQ_GPIO_RISC1_EN + +#define reg_gpio_func_mux(i) REG_ADDR8(0x140330 + (((i>>8)>3) ? 0x20 : ((i>>8)<<1) ) + ((i&0x0f0) ? 1 : 0 )) + + +#define reg_gpio_irq_risc_mask REG_ADDR8(0x140352) +enum{ + FLD_GPIO_IRQ_MASK_GPIO = BIT(0), + FLD_GPIO_IRQ_MASK_GPIO2RISC0 = BIT(1), + FLD_GPIO_IRQ_MASK_GPIO2RISC1 = BIT(2), + + FLD_GPIO_IRQ_LVL_GPIO = BIT(4), + FLD_GPIO_IRQ_LVL_GPIO2RISC0 = BIT(5), + FLD_GPIO_IRQ_LVL_GPIO2RISC1 = BIT(6), + +}; +#define reg_gpio_irq_ctrl REG_ADDR8(0x140353) +enum{ + FLD_GPIO_CORE_WAKEUP_EN = BIT(2), + FLD_GPIO_CORE_INTERRUPT_EN = BIT(3), +}; +#define reg_gpio_pad_mul_sel REG_ADDR8(0x140355) + +#define reg_gpio_irq_clr REG_ADDR8(0x140358) +typedef enum{ + FLD_GPIO_IRQ_CLR = BIT(0), + FLD_GPIO_IRQ_GPIO2RISC0_CLR = BIT(1), + FLD_GPIO_IRQ_GPIO2RISC1_CLR = BIT(2), +}gpio_irq_status_e; + +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/i2c_reg.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/i2c_reg.h new file mode 100755 index 0000000..bcd2769 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/i2c_reg.h @@ -0,0 +1,270 @@ +/******************************************************************************************************** + * @file i2c_reg.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef I2C_REG_H_ +#define I2C_REG_H_ +#include "../sys.h" +/******************************* i2c registers: 0x140280 ******************************/ + + +#define REG_I2C_BASE 0x140280 + + +#define reg_i2c_data_buf0_addr 0x80140288 + + +/** + * this register to configure I2C master clock speed,eagle i2c has default clock speed. + * for eagle i2c,its default clock resource is 24M, its default speed is 200K. + * user can configure this register to get other speed: i2c clock = i2c_system_clock/(4*DivClock) + * DivClock=0x80140280[7:0].max_value=0xff. + */ +#define reg_i2c_sp REG_ADDR8(REG_I2C_BASE) + + +/** + * this register to configure I2C ID. + * BIT[0] to set write or read bit:0=0 for write, bit:0=1 for read. + * BIT[7:1] for ID. + */ +#define reg_i2c_id REG_ADDR8(REG_I2C_BASE+0x01) +enum{ + FLD_I2C_WRITE_READ_BIT = BIT(0), + FLD_I2C_ID = BIT_RNG(1,7), +}; + + +/** + * this register is to configure i2c master + * BIT[0] means i2c bus whether busy. + * BIT[1] means that a start signal is coming, it is 1, and an end signal is coming it will be 0. + * BIT[2] Indicates the status of master send and receive,bit[2]=1,means have not ability to send or receivebit[2]=0,means have ability to send or receive. + * BIT_RNG[3:5] Indicate what state the i2c is in when it acts as master, BIT_RNG[3:5] defaule value is 0x06 it means master's state is IDLE. + * BIT_RNG[6:7] Indicate what state the i2c is in when it acts as slave. + */ +#define reg_i2c_mst REG_ADDR8(REG_I2C_BASE+0x02) +enum{ + FLD_I2C_MST_BUSY = BIT(0), + FLD_I2C_SCS_N = BIT(1), + FLD_I2C_ACK_IN = BIT(2), + FLD_I2C_MST_P = BIT_RNG(3,5), + FLD_I2C_SS = BIT_RNG(6,7), +}; + + +/** + * This shows the status control register of i2c + * BIT[0] i2c master enable. + * BIT[1] clk stretch enable: suspend transimission by pulling SCL down to low level,and continue transmission after SCL is pelesed to hign level. + * BIT[2] rx interrupt enable.RX is related to rx_irq_trig_lev function (this function is always present and does not need any setting to enable). + * fifo_data_cnt> = rx_irq_trig_lev generates an interrupt. + * BIT[3] tx interrupt enable.Related to tx_irq_trig_lev function,(This function is always present and does not require any setting to enable). + * fifo_data_cnt <= tx_irq_trig_lev, generate interrupt. + * BIT[4] tx_done.An interrupt is generated when one frame of data is sent. + * BIT[5] rx_done.An interrupt is generated when one frame of data is received. + * BIT[6] If the bit is set to 1, when the master reads, the hardware will automatically return ack / nak, no software processing is required. + * It is a new feature of eagle.Previously, software processed it through FLD_I2C_LS_ACK. Setting this bit to 0 will ack, and setting it to 1 will NAK. + * BIT[7] means,before master ack, delay sda data bus. + */ +#define reg_i2c_sct0 REG_ADDR8(REG_I2C_BASE+0x03) +typedef enum{ + FLD_I2C_MASTER = BIT(0), + FLD_I2C_R_CLK_STRETCH_EN = BIT(1), + FLD_I2C_RX_BUF_MASK = BIT(2), + FLD_I2C_TX_BUF_MASK = BIT(3), + FLD_I2C_TX_DONE_MASK = BIT(4), + FLD_I2C_RX_DONE_MASK = BIT(5), + FLD_I2C_RNCK_EN = BIT(6), + FLD_I2C_MANUAL_SDA_DELAY = BIT(7), +}i2c_mask_irq_type_e; + + + +/** + * This shows the status control register of i2c + * BIT[0] launch i2c ID cycle. + * BIT[1] launch i2c address cycle. + * BIT[2] launch data write cycle. + * BIT[3] launch data read cycle. + * BIT[4] launch start cycle. + * BIT[5] launch stop cycle. + * BIT[6] enable if BIT[6]=1,Its role is to convert the SDA from output to input, so that the master can accept the data sent by the slave when it reads. + * BIT[7] enable ACK in read command.When the master is reading, it needs to return to ack or nak. + * If it is in manual mode,when the master is reading, you need to configure this bit to determine whether it will ack. + * BIT[7] = 0,return ack. BIT[7] = 1,return nak. + */ +#define reg_i2c_sct1 REG_ADDR8(REG_I2C_BASE+0x04) +enum{ + FLD_I2C_LS_ID = BIT(0), + FLD_I2C_LS_ADDR = BIT(1), + FLD_I2C_LS_DATAW = BIT(2), + FLD_I2C_LS_DATAR = BIT(3), + FLD_I2C_LS_START = BIT(4), + FLD_I2C_LS_STOP = BIT(5), + FLD_I2C_LS_ID_R = BIT(6), + FLD_I2C_LS_ACK = BIT(7), +}; + + +/** + * This is the register that configures the i2c trigger interrupt + * BIT_RNG[0,3] to configure the interrupt trigger level of rx_status, for example BIT_RNG[0:3]=0x04,when rx 4bytes,will trigger interrupt. + * BIT_RNG[4,7] to configure the interrupt trigger level of tx_status, for example BIT_RNG[0:3]=0x04,when tx 4bytes,will trigger interrupt. + */ +#define reg_i2c_trig REG_ADDR8(REG_I2C_BASE+0x05) +enum{ + FLD_I2C_RX_IRQ_TRIG_LEV = BIT_RNG(0,3), + FLD_I2C_TX_IRQ_TRIG_LEV = BIT_RNG(4,7), +}; + + +//As a master, you need to configure this length for both sending and receiving, and the hardware needs to know what the length is. +#define reg_i2c_len REG_ADDR8(REG_I2C_BASE+0x06) + + +/** + * This register is to configure the slave stretch function. + * BIT[0] slave auto stretch clk eanble,open this function, use slave to receive data,when data buffer is full, scl bus will be low to stop receive data. + * BIT[1] slave manul stretch clk enable,open this function, use slave to receive data,when data buffer is full, scl bus will be low to stop receive data. + * BIT[2] clear slave stretch. + * BIT[6] in high speed mode,when open slave auto stretch clk function,Suddenly data came over, to meet the requirements of time setting. + * BIT[7] in fast speed mode,when open slave auto stretch clk function,Suddenly data came over, to meet the requirements of time setting. + */ +#define reg_i2c_slave_strech_en REG_ADDR8(REG_I2C_BASE+0x07) +enum{ + FLD_I2C_R_CLK_STRETCH_SEN = BIT(0), + FLD_I2C_R_MANUAL_STRETCH = BIT(1), + FLD_I2C_MANUAL_STRETCH_CLR = BIT(2), + FLD_I2C_R_HS_MODE = BIT(6), + FLD_I2C_R_FAST_MODE = BIT(7), +}; + +#define reg_i2c_data_buf(i) REG_ADDR8(( REG_I2C_BASE+0x08 +(i) )) +/** + * This register represents the data buffer of i2c. + * BIT_RNG[0,7] Buffer that stores one byte of data + */ +#define reg_i2c_data_buf0 REG_ADDR8(REG_I2C_BASE+0x08) +enum{ + FLD_I2C_BUF0 = BIT_RNG(0,7), +}; + + +/** + * This register represents the data buffer of i2c. + * BIT_RNG[0,7] Buffer that stores one byte of data + */ +#define reg_i2c_data_buf1 REG_ADDR8(REG_I2C_BASE+0x09) +enum{ + FLD_I2C_BUF1 = BIT_RNG(0,7), +}; + + +/** + * This register represents the data buffer of i2c. + * BIT_RNG[0,7] Buffer that stores one byte of data + */ +#define reg_i2c_data_buf2 REG_ADDR8(REG_I2C_BASE+0x0a) +enum{ + FLD_I2C_BUF2 = BIT_RNG(0,7), +}; + + +/** + * This register represents the data buffer of i2c. + * BIT_RNG[0,7] Buffer that stores one byte of data + */ +#define reg_i2c_data_buf3 REG_ADDR8(REG_I2C_BASE+0x0b) +enum{ + FLD_I2C_BUF3 = BIT_RNG(0,7), +}; + + +/** + * This register is used to configure the number of bytes in the i2c buffer + * BIT_RNG[0,3] rx_bufcnt is equivalent to a pointer to fifo, one in data plus one, one out data minus one. + * BIT_RNG[4,7] tx_bufcnt is equivalent to a pointer to fifo, one in data plus one, one out data minus one. + */ +#define reg_i2c_buf_cnt REG_ADDR8(REG_I2C_BASE+0x0c) +enum{ + FLD_I2C_RX_BUFCNT = BIT_RNG(0,3), + FLD_I2C_TX_BUFCNT = BIT_RNG(4,7), +}; + + +/** + * This register used to configure the status of i2c. + * BIT_RNG[0,2] rbcnt is the accumulation of this action read, fifo clear will clear. + * BIT[3] Indicates whether i2c is in an interrupted state. + * BIT_RNG[4,6] if configure BIT[6]=1,will manual clean rx_fifo. BIT[5,4] Indicates the number of bytes of tx_buffer. + * BIT[7] if configure BIT[7]=1,will manual clean tx_fifo. + */ +#define reg_i2c_status REG_ADDR8(REG_I2C_BASE+0x0d) +enum{ + FLD_I2C_RBCNT = BIT_RNG(0,2), + FLD_I2C_IRQ_O = BIT(3), + FLD_I2C_WBCNT = BIT_RNG(4,6), + FLD_I2C_RX_CLR = BIT(6), + FLD_I2C_TX_CLR = BIT(7), +}; + + + +/** + * This register is used to indicate the interrupt status of i2c. + * BIT[0] means Generate an interrupt after the transmission is completed. + * BIT[1] If there is data in tx_buffer, an interrupt will be generated. + * BIT[2] means Generate an interrupt after the receive is completed. + * BIT[3] If there is data in rx_buffer, an interrupt will be generated. + * BIT[4] Enable transmission function. + */ +#define reg_i2c_irq_status REG_ADDR8(REG_I2C_BASE+0x0e) +enum{ + FLD_I2C_TXDONE = BIT(0), + FLD_I2C_TX_BUF_IRQ = BIT(1), + FLD_I2C_RXDONE = BIT(2), + FLD_I2C_RX_BUF_IRQ = BIT(3), + FLD_I2C_TX_EN = BIT(4), +}; + + +//reg_i2c_rx_fifo_len is the number actually entered in the hardware fifo, it is an accumulated value, and fifo clear will clear. +#define reg_i2c_rx_fifo_len REG_ADDR8(REG_I2C_BASE+0x0f) +enum{ + FLD_I2C_RX_FIFO_LEN = BIT_RNG(0,7), +}; + + + + + +#endif + + + + + + + + + + diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/mdec_reg.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/mdec_reg.h new file mode 100755 index 0000000..fcdb486 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/mdec_reg.h @@ -0,0 +1,46 @@ +/******************************************************************************************************** + * @file mdec_reg.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "../sys.h" + +#define mdec_rst_addr 0x53 +typedef enum{ + FLD_SELE_PA0 = BIT(0), + FLD_SELE_PB7 = BIT(1), + FLD_SELE_PC4 = BIT(2), + FLD_SELE_PD0 = BIT(3), + FLD_SELE_PE0 = BIT(4), +}mdec_pin_e; +typedef enum{ + FLD_CLS_MDEC = BIT_RNG(0,4), + FLD_RSVD = BIT_RNG(5,6), + FLD_MDEC_RST = BIT(7), +}mdec_set_e; + +#define mdec_ctrl 0x54 + + + + + diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/mspi_reg.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/mspi_reg.h new file mode 100755 index 0000000..8698cbb --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/mspi_reg.h @@ -0,0 +1,73 @@ +/******************************************************************************************************** + * @file mspi_reg.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "../sys.h" + +/******************************* MSPI registers: 0x140100 ******************************/ +#define reg_mspi_data REG_ADDR8(0x140100) + +#define reg_mspi_fm REG_ADDR8(0x140101) +enum{ + FLD_MSPI_RD_TRIG_EN = BIT(0), + FLD_MSPI_RD_MODE = BIT(1), + FLD_MSPI_DATA_LINE = BIT_RNG(2,3), + FLD_MSPI_CSN = BIT(4), +}; + +#define reg_mspi_status REG_ADDR8(0x140102) +enum{ + FLD_MSPI_BUSY = BIT(0), +}; + +#define reg_mspi_fm1 REG_ADDR8(0x140103) +enum{ + FLD_MSPI_TIMEOUT_CNT = BIT_RNG(0,2), + FLD_MSPI_CS2SCL_CNT = BIT_RNG(3,4), + FLD_MSPI_CS2CS_CNT = BIT_RNG(5,7), +}; + +#define reg_mspi_set_l REG_ADDR8(0x140104) +enum{ + FLD_MSPI_MULTIBOOT_ADDR_OFFSET = BIT_RNG(0,2), +}; + +#define reg_mspi_set_h REG_ADDR8(0x140105) +enum{ + FLD_MSPI_PROGRAM_SPACE_SIZE = BIT_RNG(0,6), +}; + +#define reg_mspi_cmd_ahb REG_ADDR8(0x140106) +enum{ + FLD_MSPI_RD_CMD = BIT_RNG(0,7), +}; + +#define reg_mspi_fm_ahb REG_ADDR8(0x140107) +enum{ + FLD_MSPI_DUMMY = BIT_RNG(0,3), + FLD_MSPI_DAT_LINE = BIT_RNG(4,5), + FLD_MSPI_ADDR_LINE = BIT(6), + FLD_MSPI_CMD_LINE = BIT(7), +}; + + diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/npe_reg.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/npe_reg.h new file mode 100755 index 0000000..0432fe4 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/npe_reg.h @@ -0,0 +1,78 @@ +/******************************************************************************************************** + * @file npe_reg.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef NPE_REG_H +#define NPE_REG_H +#include "../sys.h" +#define NPE_BASE_ADDR 0x112000 +#define reg_npe_addr(addr) ((addr)-CPU_DLM_BASE+DLM_BASE) +#define reg_npe_0x40 REG_ADDR32(NPE_BASE_ADDR+0x40) +#define reg_npe_0x6c REG_ADDR32(NPE_BASE_ADDR+0x6c) +#define reg_npe_0x84 REG_ADDR32(NPE_BASE_ADDR+0x84) +#define reg_npe_0x74 REG_ADDR32(NPE_BASE_ADDR+0x74) +#define reg_npe_0x80 REG_ADDR32(NPE_BASE_ADDR+0x80) +#define reg_npe_0x84 REG_ADDR32(NPE_BASE_ADDR+0x84) + + +#define reg_npe_irq_0 REG_ADDR8(STIMER_BASE_ADDR+0x20) +enum{ + + FLD_IRQ_NPE_BUS0 = BIT(0), + FLD_IRQ_NPE_BUS1 = BIT(1), + FLD_IRQ_NPE_BUS2 = BIT(2), + FLD_IRQ_NPE_BUS3 = BIT(3), + FLD_IRQ_NPE_BUS4 = BIT(4), + FLD_IRQ_NPE_BUS7 = BIT(7), + +}; + +#define reg_npe_irq_1 REG_ADDR8(STIMER_BASE_ADDR+0x21) +enum{ + + FLD_IRQ_NPE_BUS8 = BIT(0), + FLD_IRQ_NPE_BUS13 = BIT(5), + FLD_IRQ_NPE_BUS14 = BIT(6), + FLD_IRQ_NPE_BUS15 = BIT(7), +}; + +#define reg_npe_irq_2 REG_ADDR8(STIMER_BASE_ADDR+0x22) +enum{ + + FLD_IRQ_NPE_BUS17 = BIT(1), + FLD_IRQ_NPE_BUS21 = BIT(5), + FLD_IRQ_NPE_BUS22 = BIT(6), + FLD_IRQ_NPE_BUS23 = BIT(7), +}; + +#define reg_npe_irq_3 REG_ADDR8(STIMER_BASE_ADDR+0x23) +enum{ + + FLD_IRQ_NPE_BUS24 = BIT(0), + FLD_IRQ_NPE_BUS25 = BIT(1), + FLD_IRQ_NPE_BUS26 = BIT(2), + FLD_IRQ_NPE_BUS27 = BIT(3), + FLD_IRQ_NPE_BUS28 = BIT(4), + FLD_IRQ_NPE_BUS29 = BIT(5), + FLD_IRQ_NPE_BUS30 = BIT(6), + FLD_IRQ_NPE_BUS31 = BIT(7), +}; +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/pke_reg.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/pke_reg.h new file mode 100755 index 0000000..83d300c --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/pke_reg.h @@ -0,0 +1,71 @@ +/******************************************************************************************************** + * @file pke_reg.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "../sys.h" + + + +/******************************* pke registers: 0x110000 ******************************/ + +#define REG_PKE_BASE 0x110000 + +#define reg_pke_ctrl REG_ADDR32(REG_PKE_BASE+0x00) +enum{ + FLD_PKE_CTRL_START = BIT(0), + FLD_PKE_CTRL_STOP = BIT(16), +}; + +#define reg_pke_conf REG_ADDR32(REG_PKE_BASE+0x04) +typedef enum{ + FLD_PKE_CONF_IRQ_EN = BIT(8), + FLD_PKE_CONF_PARTIAL_RADIX = BIT_RNG(16,23), + FLD_PKE_CONF_BASE_RADIX = BIT_RNG(24,26), +}pke_conf_e; + +#define reg_pke_mc_ptr REG_ADDR32(REG_PKE_BASE+0x10) + +#define reg_pke_stat REG_ADDR32(REG_PKE_BASE+0x20) +typedef enum{ + FLD_PKE_STAT_DONE = BIT(0), +}pke_status_e; + +#define reg_pke_rt_code REG_ADDR32(REG_PKE_BASE+0x24) +enum{ + FLD_PKE_RT_CODE_STOP_LOG = BIT_RNG(0,3), +}; + +#define reg_pke_exe_conf REG_ADDR32(REG_PKE_BASE+0x50) +enum{ + FLD_PKE_EXE_CONF_IAFF_R0 = BIT(0), + FLD_PKE_EXE_CONF_IMON_R0 = BIT(1), + FLD_PKE_EXE_CONF_IAFF_R1 = BIT(2), + FLD_PKE_EXE_CONF_IMON_R1 = BIT(3), + FLD_PKE_EXE_CONF_OAFF = BIT(4), + FLD_PKE_EXE_CONF_OMON = BIT(5), + FLD_PKE_EXE_CONF_ME_SCA_EN = BIT_RNG(8,9), +}; + + + + diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/plic_reg.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/plic_reg.h new file mode 100755 index 0000000..e11eca5 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/plic_reg.h @@ -0,0 +1,43 @@ +/******************************************************************************************************** + * @file plic_reg.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef INTERRUPT_REG_H +#define INTERRUPT_REG_H +#include "../sys.h" + + +/******************************* interrupt registers: ******************************/ +#define reg_irq_feature (*(volatile unsigned long*)(0 + (0xe4000000))) + +#define reg_irq_pending(i) (*(volatile unsigned long*)(0 + (0xe4001000+((i>31) ? 4 : 0)))) + +#define reg_irq_src0 (*(volatile unsigned long*)(0 + (0xe4002000))) +#define reg_irq_src1 (*(volatile unsigned long*)(0 + (0xe4002004))) + +#define reg_irq_src(i) (*(volatile unsigned long*)(0 + (0xe4002000+((i>31) ? 4 : 0) ))) + +#define reg_irq_threshold (*(volatile unsigned long*)(0 + (0xe4200000))) +#define reg_irq_done (*(volatile unsigned long*)(0 + (0xe4200004))) + +#define reg_irq_src_priority(i) (*(volatile unsigned long*)(0 + 0xe4000000+((i)<<2))) + +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/pwm_reg.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/pwm_reg.h new file mode 100755 index 0000000..eb810de --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/pwm_reg.h @@ -0,0 +1,306 @@ +/******************************************************************************************************** + * @file pwm_reg.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef PWM_REG_H +#define PWM_REG_H + +#include "../sys.h" + + + +/******************************* pwm registers: 0x140400 ******************************/ +#define reg_pwm_data_buf_adr 0x80140448 + + +/** + * Represents the base address register of the PWM + */ +#define REG_PWM_BASE 0x140400 + + +/** + * This register is used to enable PWM5 ~ PWM1 + */ +#define reg_pwm_enable REG_ADDR8(REG_PWM_BASE) +enum{ + FLD_PWM1_EN = BIT(1), + FLD_PWM2_EN = BIT(2), + FLD_PWM3_EN = BIT(3), + FLD_PWM4_EN = BIT(4), + FLD_PWM5_EN = BIT(5), +}; + + +/** + * This register is used to enable PWM0. + */ +#define reg_pwm0_enable REG_ADDR8(REG_PWM_BASE+0x01) +enum{ + FLD_PWM0_EN = BIT(0), +}; + + +/** + * This register is used to set the division factor of the PWM clock. + */ +#define reg_pwm_clkdiv REG_ADDR8(REG_PWM_BASE+0x02) + + +/** + * BIT[3:0] of this register is used to set the working mode of PWM0.Only PWM0 supports 5 modes. + */ +#define reg_pwm0_mode REG_ADDR8(REG_PWM_BASE+0x03) + + +/** + * This register is used to set the inversion of the output state of PWM5 ~ PWM0. + * PWM and PWM_N can be inverted independently + */ +#define reg_pwm_invert REG_ADDR8(REG_PWM_BASE+0x04) +enum{ + FLD_PWM0_OUT_INVERT = BIT(0), + FLD_PWM1_OUT_INVERT = BIT(1), + FLD_PWM2_OUT_INVERT = BIT(2), + FLD_PWM3_OUT_INVERT = BIT(3), + FLD_PWM4_OUT_INVERT = BIT(4), + FLD_PWM5_OUT_INVERT = BIT(5), +}; + + +/** + * This register is used to set the inversion of the output state of PWM5_N ~ PWM0_N. + * PWM and PWM_N can be inverted independently + */ +#define reg_pwm_n_invert REG_ADDR8(REG_PWM_BASE+0x05) +enum{ + FLD_PWM0_INV_OUT_INVERT = BIT(0), + FLD_PWM1_INV_OUT_INVERT = BIT(1), + FLD_PWM2_INV_OUT_INVERT = BIT(2), + FLD_PWM3_INV_OUT_INVERT = BIT(3), + FLD_PWM4_INV_OUT_INVERT = BIT(4), + FLD_PWM5_INV_OUT_INVERT = BIT(5), +}; + + +/* + * This register represents Signal frame polarity of PWM5~PWM0.By default, PWM outputs high level under Count status and low level under Remaining status. + * If the corresponding bit is set to 1, the high and low levels in different states will be reversed. + * BIT(0):pwm0 out low level first. ~BIT(0):pwm0 out high level first. + * BIT(1):pwm1 out low level first. ~BIT(1):pwm1 out high level first. + * BIT(2):pwm2 out low level first. ~BIT(2):pwm2 out high level first. + * BIT(3):pwm3 out low level first. ~BIT(3):pwm3 out high level first. + * BIT(4):pwm4 out low level first. ~BIT(4):pwm4 out high level first. + * BIT(5):pwm5 out low level first. ~BIT(5):pwm5 out high level first. + */ +#define reg_pwm_pol REG_ADDR8(REG_PWM_BASE+0x06) +enum{ + FLD_PWM0_FIRST_OUT_LEVEL = BIT(0), + FLD_PWM1_FIRST_OUT_LEVEL = BIT(1), + FLD_PWM2_FIRST_OUT_LEVEL = BIT(2), + FLD_PWM3_FIRST_OUT_LEVEL = BIT(3), + FLD_PWM4_FIRST_OUT_LEVEL = BIT(4), + FLD_PWM5_FIRST_OUT_LEVEL = BIT(5), +}; + + +/* + * This register represents 32K clock source with PWM5 ~ PWM0 enabled + * If the system has a 32K clock source, whether it is 32K_RC or 32K_Crystal, as long as the corresponding + * BIT of 0x140407 is configured, the corresponding PWM Channel can get 32K clock source. + */ +#define reg_pwm_mode32k REG_ADDR8(REG_PWM_BASE+0x07) +enum{ + FLD_PWM0_32K_ENABLE = BIT(0), + FLD_PWM1_32K_ENABLE = BIT(1), + FLD_PWM2_32K_ENABLE = BIT(2), + FLD_PWM3_32K_ENABLE = BIT(3), + FLD_PWM4_32K_ENABLE = BIT(4), + FLD_PWM5_32K_ENABLE = BIT(5), +}; + + +/** + * This register configures the length of the capture segment of PWM5 ~ PWM0. + * This value has a total of 16 bits, divided into lower 8 bits and higher 8 bits. + */ +#define reg_pwm_cmp(i) REG_ADDR16(REG_PWM_BASE+0x14 +(i << 2)) + + +/** + * This register is used to configure the period of the PWM waveform. There are 32 bits in total. + * The lower 16 bits indicate the length of the CMP segment. The higher 16 bits indicate the length of the MAX segment. + */ +#define reg_pwm_cycle(i) REG_ADDR32(REG_PWM_BASE+0x14 + (i << 2)) +//enum{ +// FLD_PWM_CMP = BIT_RNG(0,15), +// FLD_PWM_MAX = BIT_RNG(16,31), +//}; +// in C99 FLD_PWM_MAX = BIT_RNG(16,31) is error +#define FLD_PWM_CMP = BIT_RNG(0,15), +#define FLD_PWM_MAX = BIT_RNG(16,31), +/** + * This register configures the length of the max segment of PWM5 ~ PWM0. + * This value has a total of 16 bits, divided into lower 8 bits and higher 8 bits. + */ +#define reg_pwm_max(i) REG_ADDR16(REG_PWM_BASE+0x16 + (i << 2)) + + +/** + * When PWM0 is in count mode or ir mode, the total number of pulse_number is set by the following two registers. + */ +#define reg_pwm0_pulse_num0 REG_ADDR8(REG_PWM_BASE+0x2c)//0x2c[7:0] +#define reg_pwm0_pulse_num1 REG_ADDR8(REG_PWM_BASE+0x2d)//0x2d[5:0] + + +/** + * PWM interrupt mask or interrupt status + */ + +typedef enum{ + FLD_PWM0_PNUM_IRQ = BIT(0), + FLD_PWM0_IR_DMA_FIFO_IRQ = BIT(1), + FLD_PWM0_FRAME_DONE_IRQ = BIT(2), + FLD_PWM1_FRAME_DONE_IRQ = BIT(3), + FLD_PWM2_FRAME_DONE_IRQ = BIT(4), + FLD_PWM3_FRAME_DONE_IRQ = BIT(5), + FLD_PWM4_FRAME_DONE_IRQ = BIT(6), + FLD_PWM5_FRAME_DONE_IRQ = BIT(7), + + FLD_PWM0_IR_FIFO_IRQ = BIT(16), + +}pwm_irq_e; + +/** + * This register is used to configure the PWM interrupt function. + * BIT[0]:If this bit is set, an interrupt will be generated after a set of pulses has been sent. When this interrupt is enabled, you can capture an interrupt after a pulse is sent by detecting whether bit[0] of 0x140431 is set. + * BIT[1]:Enable ir dma fifo mode interrupt.This bit is usually used with 0x140431BIT[1]. + * BIT[2]:Enable pwm0 frame interrupt. + * BIT[3]:Enable pwm1 frame interrupt. + * BIT[4]:Enable pwm2 frame interrupt. + * BIT[5]:Enable pwm3 frame interrupt. + * BIT[6]:Enable pwm4 frame interrupt. + * BIT[7]:Enable pwm5 frame interrupt. + * BIT[16]:The Bit is to enable the mask_lvl(This level specifically indicates the number of bytes in the FIFO that can trigger an interrupt) interrupt. + */ +#define reg_pwm_irq_mask(i) REG_ADDR8(REG_PWM_BASE+0x30+i*2) + + +/** + * The bits in this register are used to indicate the various interrupt states of the PWM. + * BIT[0]:This bit is usually used with BIT[0] of 0x140430. If this bit is set to 1, it means that a pulse group of PWM has been sent.An interrupt was also generated. You can manually write 1 to clear the interrupt flag. + * BIT[1]:In ir dma fifo mode. If this is set 1 Indicates that a set of pulse of group has been sent. You can manually write 1 to clear the interrupt flag. + * BIT[2]:If this is set 1 Indicates that a signal frame interrupt has been generated. You can manually write 1 to clear the interrupt flag. + * BIT[3]:If this is set 1 Indicates that a signal frame interrupt has been generated. You can manually write 1 to clear the interrupt flag. + * BIT[4]:If this is set 1 Indicates that a signal frame interrupt has been generated. You can manually write 1 to clear the interrupt flag. + * BIT[5]:If this is set 1 Indicates that a signal frame interrupt has been generated. You can manually write 1 to clear the interrupt flag. + * BIT[6]:If this is set 1 Indicates that a signal frame interrupt has been generated. You can manually write 1 to clear the interrupt flag. + * BIT[7]:If this is set 1 Indicates that a signal frame interrupt has been generated. You can manually write 1 to clear the interrupt flag. + * BIT[16]:When the FIFO value is less than the set value, an interrupt is generated(The premise is that this interrupt has been enabled by register 0x140432 previous). + * The user can know whether this interrupt is generated by reading the status of this register.If BIT(16):1 Indicates that this interrupt has been generated. + */ +#define reg_pwm_irq_sta(i) REG_ADDR8(REG_PWM_BASE+0x31+i*2) + + +/** + * This register is used to count the number of PWM5~PWM0 pulses.The number of pulses of each PWM consists of 16 bits + */ +#define reg_pwm_cnt(i) REG_ADDR16(REG_PWM_BASE+0x34 +(i << 1)) + + +/** + * PWM0 pulse_cnt value BIT[7:0]. + */ +#define reg_pwm_ncnt_l REG_ADDR8(REG_PWM_BASE+0x40) + + +/** + * PWM0 pulse_cnt value BIT[15:8]. + */ +#define reg_pwm_ncnt_h REG_ADDR8(REG_PWM_BASE+0x41) + + +/** + * [7:0] bits 7-0 of PWM0's high time or low time(if pola[0]=1),if shadow bit(fifo data[14]) is 1 in ir fifo mode or dma fifo mode. + */ +#define reg_pwm_tcmp0_shadow REG_ADDR16(REG_PWM_BASE+0x44) + + +/** + * [15:8] bits 15-8 of PWM0's high time or low time(if pola[0]=1),if shadow bit(fifo data[14]) is 1 in ir fifo mode or dma fifo mode. + */ +#define reg_pwm_tmax0_shadow REG_ADDR16(REG_PWM_BASE+0x46) + + +/** + * PWM data fifo.0x140448~0x14044b. + */ +#define reg_pwm_ir_fifo_dat(i) REG_ADDR16(REG_PWM_BASE+0x48+i*2) + + +/** + * This register BIT[3:0] indicates the interrupt trigger level in ir_fifo mode. + * When fifo numbers is less than this value.It's will take effect. + */ +#define reg_pwm_ir_fifo_irq_trig_level REG_ADDR8(REG_PWM_BASE+0x4c) +enum{ + FLD_PWM0_FIFO_NUM_OF_TRIGGLE_LEVEL = BIT_RNG(0,3), +}; + + +/** + * This register indicates the fifo data status in. + * BIT[3:0]:Indicates the amount of data in the FIFO. + * BIT[4]:if BIT[4]=1,Indicates the data fifo is empty. + * BIT[5]:if BIT[5]=1,Indicates the data fifo is full. + */ +#define reg_pwm_ir_fifo_data_status REG_ADDR8(0x14044d) +enum{ + FLD_PWM0_IR_FIFO_DATA_NUM = BIT_RNG(0,3), + FLD_PWM0_IR_FIFO_EMPTY = BIT(4), + FLD_PWM0_IR_FIFO_FULL = BIT(5), +}; + + +/** + * This register can be configured to clear the data FIFO. + * BIT[0]:if BIT[0]=1,Indicates the data FIFO is clear. + */ +#define reg_pwm_ir_clr_fifo_data REG_ADDR8(0x14044e) +enum{ + FLD_PWM0_IR_FIFO_CLR_DATA = BIT(0), + +}; + + + + + +#endif + + + + + + + + + diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/register_b91.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/register_b91.h new file mode 100755 index 0000000..e0e8020 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/register_b91.h @@ -0,0 +1,47 @@ +/******************************************************************************************************** + * @file register_b91.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef REGISTER_B91_H +#define REGISTER_B91_H + +#include "gpio_reg.h" +#include "soc.h" +#include "analog_reg.h" +#include "audio_reg.h" +#include "timer_reg.h" +#include "dma_reg.h" +#include "usb_reg.h" +#include "pwm_reg.h" +#include "spi_reg.h" +#include "i2c_reg.h" +#include "mspi_reg.h" +#include "rf_reg.h" +#include "trng_reg.h" +#include "npe_reg.h" +#include "pke_reg.h" +#include "plic_reg.h" +#include "uart_reg.h" +#include "stimer_reg.h" +#include "aes_reg.h" +#include "adc_reg.h" +#include "mdec_reg.h" +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/rf_reg.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/rf_reg.h new file mode 100755 index 0000000..688d867 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/rf_reg.h @@ -0,0 +1,847 @@ +/******************************************************************************************************** + * @file rf_reg.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef RF_REG_H +#define RF_REG_H +#include "../sys.h" + +///******************************* RF ******************************/ +#define APBADDR 0x140000 +#define BBADDR APBADDR+0x800 //0x140800 +#define RADIOADDR APBADDR+0xe00 //0x140e00 +#define MODEMADDR APBADDR+0xc00 //0x140c00 +#define CHNADDR 0x100400 +#define APBRG_BASE 0x140000 +#define APBRG_APB_BASE (APBRG_BASE+0x0000) + + +#define REG_TL_RADIO_BASE_ADDR (APBRG_BASE+0x0e00) + + +#define reg_rf_bb_auto_ctrl REG_ADDR8(0x10050c) + +enum{ + FLD_RF_TX_MULTI_EN = BIT(0), + FLD_RF_RX_MULTI_EN = BIT(1), + FLD_RF_CH_0_RNUM_EN_BK = BIT(2), + FLD_RF_CH_1_RNUM_EN_BK = BIT(3), + FLD_RF_CH1_RX_ERR_EN = BIT(4), + FLD_RF_DMA_REQ_D1_EN = BIT(5), +}; +#define reg_rf_bb_tx_chn_dep REG_ADDR8(0x1004f3) +#define reg_rf_bb_tx_size REG_ADDR8(0x1004f2) + +#define reg_rf_dma_rx_wptr REG_ADDR8(0x001004f4) +#define reg_rf_dma_rx_rptr REG_ADDR8(0x001004f5) + +#define reg_rf_dma_tx_rptr(i) REG_ADDR8(0x00100501 + (i << 1)) +#define reg_rf_dma_tx_wptr(i) REG_ADDR8(0x00100500 + (i << 1)) + +#define reg_rf_bb_rx_size REG_ADDR8(CHNADDR+0xf6) + + + +#define reg_rf_rx_wptr_mask REG_ADDR8(CHNADDR+0x10d) + + + +//****************************** RF_Register_list ******************************/ +#define REG_BASEBAND_BASE_ADDR 0x0140800 + + +#define reg_rf_tx_mode1 REG_ADDR8(REG_BASEBAND_BASE_ADDR) +enum{ + FLD_RF_DMA_EN = BIT(0), + FLD_RF_CRC_EN = BIT(1), + FLD_RF_TX_FMT = BIT_RNG(2,3), + FLD_RF_TX_XOR_MODE = BIT(4), + FLD_RF_TX_TEST_DATA = BIT(5), + FLD_RF_TX_TEST_EN = BIT(6), + FLD_RF_BB_DEC = BIT(7), +}; + + +#define reg_rf_tx_mode2 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x01) +enum{ + FLD_RF_ZB_PN_EN = BIT(0), + FLD_RF_RESERVED0 = BIT_RNG(1,2), + FLD_RF_V_PN_EN = BIT(3), + FLD_RF_RESERVED1 = BIT_RNG(4,5), + FLD_RF_TX_OUT_PLR = BIT(6), +}; + + +#define reg_rf_preamble_trail REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x02) +enum{ + FLD_RF_PREAMBLE_LEN = BIT_RNG(0,4), + FLD_RF_TRAILER_LEN = BIT_RNG(5,7), +}; + + +#define reg_rf_bbdbg REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x03) +enum{ + FLD_RF_SLOW_EN = BIT(0), + FLD_RF_SLOW_SEL = BIT(1), + FLD_RF_XMODE_EN = BIT(2), + FLD_RF_REV_ORDER = BIT(3), + FLD_RF_TX_MODE = BIT(4), + FLD_RF_R_DBG_SEL0 = BIT(5), + FLD_RF_MODEM1M_PAT = BIT(6), + FLD_RF_R_DBG_SEL1 = BIT(7), +}; + + +#define reg_rf_format REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x04) +enum{ + FLD_RF_HEAD_MODE = BIT_RNG(0,1), + FLD_RF_CRC_MODE = BIT_RNG(2,3), + FLD_RF_BLE_1M = BIT(4), + FLD_RF_BLE_WT = BIT(5), + FLD_RF_TX_NOACK = BIT(6), + FLD_RF_PN_AUTO = BIT(7), +}; + + +//#define reg_rf_acclen REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x05) +#define reg_rf_acc_len REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x05) +enum{ + FLD_RF_ACC_LEN = BIT_RNG(0,2), + FLD_RF_LR_TX_SEL = BIT(4), + FLD_RF_BLE_LR = BIT(5), +}; + + + +#define reg_rf_sblen REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x06) + + +#define reg_rf_rxchn REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x07) +enum{ + FLD_RF_TEST_TXON = BIT(6), + FLD_RF_TEST_TXON_EN = BIT(7), +}; + +#define reg_rf_access_code REG_ADDR32(REG_BASEBAND_BASE_ADDR+0x08) +#define reg_rf_access_0 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x08) +#define reg_rf_access_1 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x09) +#define reg_rf_access_2 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x0a) +#define reg_rf_access_3 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x0b) +#define reg_rf_access_4 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x0c) + + +#define reg_rf_pn REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x0d) +enum{ + FLD_RF_PN_INIT = BIT_RNG(0,5), +}; + + +#define reg_rf_access_5 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x10) +#define reg_rf_access_6 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x11) +#define reg_rf_access_7 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x12) +#define reg_rf_access_8 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x13) +#define reg_rf_access_9 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x14) +#define reg_rf_access_10 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x18) +#define reg_rf_access_11 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x19) +#define reg_rf_access_12 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x1a) +#define reg_rf_access_13 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x1b) +#define reg_rf_access_code_base_pipe0 0x140808 +#define reg_rf_access_code_base_pipe2 0x140818 + +#define reg_rf_txfifo REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x1c) +enum{ + FLD_RF_TX_FIFO_FULL = BIT(0), + FLD_RF_TX_ACT_2D = BIT(1), +}; + + +#define reg_rf_rxgth1 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x21) +enum{ + FLD_RF_R_PILOT_LEN_O = BIT_RNG(0,3), + FLD_RF_R_ZB_SFD_O = BIT(4), + FLD_RF_R_PKTLEN_O = BIT(5), + FLD_RF_R_SN_LEN_O = BIT(6), + FLD_RF_R_LEN_0_EN_O = BIT(7), +}; + + +#define reg_rf_rxsfd0_num REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x22) +enum{ + FLD_RF_RXCHN_MAN_EN = BIT(3), + FLD_RF_RXCHN_MAN = BIT_RNG(4,6), +}; + + +#define reg_rf_crc_init0 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x24) +#define reg_rf_crc_init1 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x25) +#define reg_rf_crc_init2 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x26) + + +#define reg_rf_ctrl_0 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x27) +enum{ + FLD_RF_H1M_ODD = BIT(0), + FLD_RF_REV_ZB_SAMP = BIT(1), + FLD_RF_SFD_LAST_CHIP = BIT(2), +}; + + +#define reg_rf_rxmode REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x28) +enum{ + FLD_RF_RX_ENABLE = BIT(0), +}; + + +#define reg_rf_rxclk_on REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x2a) +enum{ + FLD_RF_CLKON_O = BIT_RNG(0,1), +}; + + +#define reg_rf_rxclk_auto REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x2b) +enum{ + FLD_RF_CLK_AUTO = BIT_RNG(0,1), +}; + + +#define reg_rf_rxdma_hs REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x2c) +enum{ + FLD_RF_RXDMA_HS = BIT(0), +}; + + +#define reg_rf_rxtcrcpkt REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x30) +enum{ + FLD_RF_FILTER_CRC_PKT = BIT(0), + FLD_RF_EN_TS_RX = BIT(2), + FLD_RF_EN_TS_TX = BIT(3), + FLD_RF_LEN_SET_O = BIT_RNG(4,5), +}; + + +#define reg_rf_rxtmaxlen REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x31) + + +#define reg_rf_rxlatf REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x33) +enum{ + FLD_RF_R_LATF_CNT_O = BIT_RNG(0,3), + FLD_RF_R_LATF_AT_END_O = BIT(4), +}; + + +#define reg_rf_bank_cnt REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x34) +enum{ + FLD_RF_BANK_CNT = BIT_RNG(0,2), +}; + + +#define reg_rf_rxsupp REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x38) +enum{ + FLD_RF_RX_SUPP_D_EN = BIT(0), + FLD_RF_RX_SUPP_A_EN = BIT(1), + FLD_RF_TX_SUPP_D_EN = BIT(2), + FLD_RF_TX_SUPP_A_EN = BIT(3), + FLD_RF_ANT_NUM = BIT_RNG(4,7), +}; + + +#define reg_rf_tx_antoffset REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x39) +#define reg_rf_rx_antoffset REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x3a) +#define reg_rf_samp_offset REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x3b) + + +#define reg_rf_man_ant_slot REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x3c) +enum{ + FLD_RF_ANT_SEL_MAN = BIT_RNG(0,2), + FLD_RF_ANT_SEL_MAN_EN = BIT(3), + FLD_RF_SLOT_1US_MAN_EN = BIT(4), + FLD_RF_SLOT_1US_MAN = BIT(5), + FLD_RF_ANT_PAT = BIT_RNG(6,7), +}; + + +#define reg_rf_sof_offset REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x3d) +enum{ + FLD_RF_ANT_SOF_OFFSET = BIT_RNG(0,1), + FLD_RF_SAMP_SOF_OFFSET = BIT_RNG(2,3), + FLD_RF_SUPP_MODE = BIT_RNG(4,6), +}; + + +#define reg_rf_mode_ctrl0 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x3e) +enum{ + FLD_RF_INTV_MODE = BIT_RNG(0,1), + FLD_RF_IQ_SAMP_EN = BIT(2), + FLD_RF_IQ_SAMP_INTERVAL = BIT_RNG(4,7), +}; + + +#define reg_rf_iq_samp_start REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x3f) + + +#define reg_rf_dec_err REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x40) +enum{ + FLD_RF_SS = BIT_RNG(0,2), + FLD_RF_PKT_DEC_ERR = BIT_RNG(4,7), +}; + +#define reg_rf_timestamp REG_ADDR32(REG_BASEBAND_BASE_ADDR+0x50) +#define reg_rf_tstamp0 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x50) +enum{ + FLD_RF_R_TSTAMP0 = BIT_RNG(0,7), +}; + + +#define reg_rf_tstamp1 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x51) +enum{ + FLD_RF_R_TSTAMP1 = BIT_RNG(0,7), +}; + + +#define reg_rf_tstamp2 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x52) +enum{ + FLD_RF_R_TSTAMP2 = BIT_RNG(0,7), +}; + + +#define reg_rf_tstamp3 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x53) +enum{ + FLD_RF_R_TSTAMP3 = BIT_RNG(0,7), +}; + + +#define reg_rf_ant_lut_0 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x68) +enum{ + FLD_RF_ANT_LUT0 = BIT_RNG(0,2), + FLD_RF_ANT_LUT1 = BIT_RNG(4,6), +}; + +#if 0 +#define reg_rf_ant_lut_1 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x69) +enum{ + FLD_RF_ANT_LUT0 = BIT_RNG(0,2), + FLD_RF_ANT_LUT1 = BIT_RNG(4,6), +}; + + +#define reg_rf_ant_lut_2 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x6a) +enum{ + FLD_RF_ANT_LUT0 = BIT_RNG(0,2), + FLD_RF_ANT_LUT1 = BIT_RNG(4,6), +}; + + +#define reg_rf_ant_lut_3 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x6b) +enum{ + FLD_RF_ANT_LUT0 = BIT_RNG(0,2), + FLD_RF_ANT_LUT1 = BIT_RNG(4,6), +}; + + +#define reg_rf_ant_lut_4 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x6c) +enum{ + FLD_RF_ANT_LUT0 = BIT_RNG(0,2), + FLD_RF_ANT_LUT1 = BIT_RNG(4,6), +}; + + +#define reg_rf_ant_lut_5 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x6d) +enum{ + FLD_RF_ANT_LUT0 = BIT_RNG(0,2), + FLD_RF_ANT_LUT1 = BIT_RNG(4,6), +}; + + +#define reg_rf_ant_lut_6 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x6e) +enum{ + FLD_RF_ANT_LUT0 = BIT_RNG(0,2), + FLD_RF_ANT_LUT1 = BIT_RNG(4,6), +}; + + +#define reg_rf_ant_lut_7 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x6f) +enum{ + FLD_RF_ANT_LUT0 = BIT_RNG(0,2), + FLD_RF_ANT_LUT1 = BIT_RNG(4,6), +}; +#endif + +#define reg_rf_rxdma_adr 0x140880 +#define reg_rf_rxdma_fifo0 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x80) +enum{ + FLD_RF_RXDMA_FIFO0 = BIT_RNG(0,7), +}; + + +#define reg_rf_rxdma_fifo1 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x81) +enum{ + FLD_RF_RXDMA_FIFO1 = BIT_RNG(0,7), +}; + + +#define reg_rf_rxdma_fifo2 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x82) +enum{ + FLD_RF_RXDMA_FIFO2 = BIT_RNG(0,7), +}; + + +#define reg_rf_rxdma_fifo3 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x83) +enum{ + FLD_RF_RXDMA_FIFO3 = BIT_RNG(0,7), +}; + +#define reg_rf_txdma_adr 0x140884 +#define reg_rf_txdma_fifo0 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x84) +enum{ + FLD_RF_TXDMA_FIFO0 = BIT_RNG(0,7), +}; + + +#define reg_rf_txdma_fifo1 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x85) +enum{ + FLD_RF_TXDMA_FIFO1 = BIT_RNG(0,7), +}; + + +#define reg_rf_txdma_fifo2 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x86) +enum{ + FLD_RF_TXDMA_FIFO2 = BIT_RNG(0,7), +}; + + +#define reg_rf_txdma_fifo3 REG_ADDR8(REG_BASEBAND_BASE_ADDR+0x87) +enum{ + FLD_RF_TXDMA_FIFO3 = BIT_RNG(0,7), +}; + + + +/** + * BB_LL + */ +#define REG_BB_LL_BASE_ADDR 0x0140a00 + + +#define reg_rf_ll_cmd REG_ADDR8(REG_BB_LL_BASE_ADDR) +enum{ + FLD_RF_R_CMD = BIT_RNG(0,3), + FLD_RF_R_STOP = 0, + FLD_RF_R_BTX = 1, + FLD_RF_R_BRX = 2, + FLD_RF_R_PTX = 3, + FLD_RF_R_PRX = 4, + FLD_RF_R_STX = 5, + FLD_RF_R_SRX = 6, + FLD_RF_R_STR = 7, + FLD_RF_R_SRT = 8, + FLD_RF_R_CMD_TRIG = BIT(7), +}; + + +#define reg_rf_ll_rest_pid REG_ADDR8(REG_BB_LL_BASE_ADDR+0x01) +enum{ + FLD_RF_R_RESET_PID_0 = BIT(0), + FLD_RF_R_RESET_PID_1 = BIT(1), + FLD_RF_R_RESET_PID_2 = BIT(2), + FLD_RF_R_RESET_PID_3 = BIT(3), + FLD_RF_R_RESET_PID_4 = BIT(4), + FLD_RF_R_RESET_PID_5 = BIT(5), +}; + + +#define reg_rf_ll_ctrl0 REG_ADDR8(REG_BB_LL_BASE_ADDR+0x02) +enum{ + FLD_RF_R_MD_EN = BIT(0), + FLD_RF_R_ID_EN = BIT(1), + FLD_RF_R_RX_NOACK_MAN = BIT(2), + FLD_RF_R_RX_NOACK_MAN_EN = BIT(3), + FLD_RF_R_TX_EN_MAN = BIT(4), + FLD_RF_R_RX_EN_MAN = BIT(5), + FLD_RF_R_TX_TRIQ_AUTO_EN = BIT(6), + FLD_RF_R_S_TX_TIMEOUT_EN = BIT(7), +}; + + +#define reg_rf_ll_ctrl_1 REG_ADDR8(REG_BB_LL_BASE_ADDR+0x03) + +enum{ + FLD_RF_FSM_TIMEOUT_EN = BIT(0), + FLD_RF_RX_FIRST_TIMEOUT_EN = BIT(1), + FLD_RF_RX_TIMEOUT_EN = BIT(2), + FLD_RF_CRC_2_EN = BIT(3), + + //BLE mode + FLD_RF_BRX_SN_INIT = BIT(4), + FLD_RF_BRX_NESN_INIT = BIT(5), + FLD_RF_BTX_SN_INIT = BIT(6), + FLD_RF_BTX_NESN_INIT = BIT(7), +}; + +#define FSM_TIMEOUT_ENABLE ( reg_rf_ll_ctrl_1 |= FLD_RF_FSM_TIMEOUT_EN ) +#define FSM_TIMEOUT_DISABLE ( reg_rf_ll_ctrl_1 &= (~FLD_RF_FSM_TIMEOUT_EN) ) + +#define reg_rf_ll_tx_stl REG_ADDR16(REG_BB_LL_BASE_ADDR+0x04) + +#define reg_rf_ll_tx_stl_l REG_ADDR8(REG_BB_LL_BASE_ADDR+0x04) + + +#define reg_rf_ll_tx_stl_h REG_ADDR8(REG_BB_LL_BASE_ADDR+0x05) +enum{ + FLD_RF_R_T_TXSTL_H = BIT_RNG(0,3), +}; + + +#define reg_rf_ll_rxwait_l REG_ADDR8(REG_BB_LL_BASE_ADDR+0x06) + + +#define reg_rf_ll_rxwait_h REG_ADDR8(REG_BB_LL_BASE_ADDR+0x07) +enum{ + FLD_RF_R_T_RXWAIT_H = BIT_RNG(0,3), +}; + + +#define reg_rf_ll_rx_l REG_ADDR8(REG_BB_LL_BASE_ADDR+0x0a) + +#define reg_rf_rx_timeout REG_ADDR16(REG_BB_LL_BASE_ADDR+0x0a) + +#define reg_rf_ll_rx_h REG_ADDR8(REG_BB_LL_BASE_ADDR+0x0b) +enum{ + FLD_RF_R_T_RX_H = BIT_RNG(0,3), +}; + + +#define reg_rf_ll_rxstl_l REG_ADDR8(REG_BB_LL_BASE_ADDR+0x0c) + + +#define reg_rf_ll_rxstl_h REG_ADDR8(REG_BB_LL_BASE_ADDR+0x0d) +enum{ + FLD_RF_R_T_RXSTL_H = BIT_RNG(0,3), +}; + + +#define reg_rf_ll_txwait_l REG_ADDR8(REG_BB_LL_BASE_ADDR+0x0e) + + +#define reg_rf_ll_txwait_h REG_ADDR8(REG_BB_LL_BASE_ADDR+0x0f) +enum{ + FLD_RF_R_T_TXWAIT_H = BIT_RNG(0,3), +}; + + +#define reg_rf_ll_ard_l REG_ADDR8(REG_BB_LL_BASE_ADDR+0x10) + + +#define reg_rf_ll_ard_h REG_ADDR8(REG_BB_LL_BASE_ADDR+0x11) +enum{ + FLD_RF_R_T_ARD_H = BIT_RNG(0,3), +}; + + +#define reg_rf_t_coex_t1 REG_ADDR8(REG_BB_LL_BASE_ADDR+0x12) +#define reg_rf_t_coex_t2 REG_ADDR8(REG_BB_LL_BASE_ADDR+0x13) +#define reg_rf_ll_max_reset_cnt REG_ADDR8(REG_BB_LL_BASE_ADDR+0x14) + + +#define reg_rf_ll_ctrl2 REG_ADDR8(REG_BB_LL_BASE_ADDR+0x15) +enum{ + FLD_RF_R_TXCHN_MAN = BIT_RNG(0,2), + FLD_RF_R_NOACK_RECNT_EN = BIT(3), + FLD_RF_R_TXCHN_MAN_EN = BIT(4), + FLD_RF_R_NOACK_REV_EN = BIT(5), + FLD_RF_R_RXIRQ_REPORT_ALL = BIT(6), + FLD_RF_R_REP_SN_PID_EN = BIT(7), +}; + + +#define reg_rf_ll_ctrl3 REG_ADDR8(REG_BB_LL_BASE_ADDR+0x16) +enum{ + FLD_RF_R_TX_EN_DLY_EN = BIT(0), + FLD_RF_R_PLL_RESET_EN = BIT(1), + FLD_RF_R_CMD_SCHDULE_EN = BIT(2), + FLD_RF_R_PLL_EN_MAN = BIT(3), + FLD_RF_R_T_TX_EN_DLY = BIT_RNG(4,7), +}; + + +#define reg_rf_ll_pll_reset REG_ADDR8(REG_BB_LL_BASE_ADDR+0x17) +#define reg_rf_ll_cmd_schedule REG_ADDR32(REG_BB_LL_BASE_ADDR+0x18) +#define reg_rf_ll_cmd_schedule0 REG_ADDR8(REG_BB_LL_BASE_ADDR+0x18) +#define reg_rf_ll_cmd_schedule1 REG_ADDR8(REG_BB_LL_BASE_ADDR+0x19) +#define reg_rf_ll_cmd_schedule2 REG_ADDR8(REG_BB_LL_BASE_ADDR+0x1a) +#define reg_rf_ll_cmd_schedule3 REG_ADDR8(REG_BB_LL_BASE_ADDR+0x1b) +#define reg_rf_ll_irq_mask_l REG_ADDR8(REG_BB_LL_BASE_ADDR+0x1c) +#define reg_rf_ll_irq_mask_h REG_ADDR8(REG_BB_LL_BASE_ADDR+0x1d) +#define reg_rf_irq_mask REG_ADDR16(REG_BB_LL_BASE_ADDR+0x1c) + + +#define reg_rf_ll_tx_id REG_ADDR8(REG_BB_LL_BASE_ADDR+0x1e) +enum{ + FLD_RF_R_TX_ID = BIT_RNG(0,6), +}; + + +#define reg_rf_ll_tx_committed REG_ADDR8(REG_BB_LL_BASE_ADDR+0x1f) +enum{ + FLD_RF_R_TX_COMMITTED = BIT_RNG(0,5), +}; + + + +#define reg_rf_irq_status REG_ADDR16(REG_BB_LL_BASE_ADDR+0x20) + +typedef enum{ + FLD_RF_IRQ_RX = BIT(0), + FLD_RF_IRQ_TX = BIT(1), + FLD_RF_IRQ_RX_TIMEOUT = BIT(2), + FLD_RF_IRQ_RX_FIFO_FULL = BIT(3), + FLD_RF_IRQ_RX_CRC_2 = BIT(4), + FLD_RF_IRQ_CMD_DONE = BIT(5), + FLD_RF_IRQ_FSM_TIMEOUT = BIT(6), + FLD_RF_IRQ_TX_RETRYCNT = BIT(7), + FLD_RF_IRQ_TX_DS = BIT(8), + FLD_RF_IRQ_RX_DR = BIT(9), + FLD_RF_IRQ_FIRST_TIMEOUT = BIT(10), + FLD_RF_IRQ_INVALID_PID = BIT(11), + FLD_RF_IRQ_STX_TIMEOUT = BIT(12), + FLD_RF_IRQ_WIFI_DENY = BIT(13), + FLD_RF_IRQ_SUPP_OF = BIT(14), + FLD_RF_IRQ_RXDMA_OF = BIT(15), + FLD_RF_IRQ_ALL = 0X1FFF, +}rf_irq_e; + + + +#define reg_rf_ll_pid_l REG_ADDR8(REG_BB_LL_BASE_ADDR+0x22) +enum{ + FLD_RF_PID0 = BIT_RNG(0,1), + FLD_RF_PID1 = BIT_RNG(2,3), + FLD_RF_PID2 = BIT_RNG(4,5), + FLD_RF_PID3 = BIT_RNG(6,7), +}; + + +#define reg_rf_ll_pid_h REG_ADDR8(REG_BB_LL_BASE_ADDR+0x23) +enum{ + FLD_RF_PID4 = BIT_RNG(0,1), + FLD_RF_PID5 = BIT_RNG(2,3), + FLD_RF_NESN = BIT(4), +}; + + +#define reg_rf_ll_2d_sclk REG_ADDR8(REG_BB_LL_BASE_ADDR+0x24) +typedef enum { + FLD_RF_STATE_MACHINE_IDLE = 0, /**< idle */ + FLD_RF_STATE_MACHINE_TX_SETTLE, /**< tx settle*/ + FLD_RF_STATE_MACHINE_TX, /**< tx */ + FLD_RF_STATE_MACHINE_RX_WAIT, /**< rx wait */ + FLD_RF_STATE_MACHINE_RX, /**< rx */ + FLD_RF_STATE_MACHINE_TX_WAIT, /**< tx wait */ +} state_machine_status_e; + + +#define reg_rf_ll_retry_cnt REG_ADDR8(REG_BB_LL_BASE_ADDR+0x25) +enum{ + FLD_RF_LL_RETRY_CNT = BIT_RNG(0,7), +}; + + +#define reg_rf_ll_cnt0 REG_ADDR8(REG_BB_LL_BASE_ADDR+0x26) +enum{ + FLD_RF_CRC_CNT = BIT_RNG(0,3), + FLD_RF_NAK_CNT = BIT_RNG(4,7), +}; + + +#define reg_rf_ll_cnt1 REG_ADDR8(REG_BB_LL_BASE_ADDR+0x27) +enum{ + FLD_RF_OLD_CNT = BIT_RNG(0,3), + FLD_RF_ID_CNT = BIT_RNG(4,7), +}; + +#define reg_rf_ll_rx_fst_timeout REG_ADDR32(REG_BB_LL_BASE_ADDR+0x28) +#define reg_rf_ll_rx_fst_l REG_ADDR8(REG_BB_LL_BASE_ADDR+0x28) +#define reg_rf_ll_rx_fst_m REG_ADDR8(REG_BB_LL_BASE_ADDR+0x29) +#define reg_rf_ll_rx_fst_h REG_ADDR8(REG_BB_LL_BASE_ADDR+0x2a) + +#define reg_rf_ll_fsm_timeout REG_ADDR32(REG_BB_LL_BASE_ADDR+0x2c) +#define reg_rf_ll_fsm_timeout_l REG_ADDR8(REG_BB_LL_BASE_ADDR+0x2c) +#define reg_rf_ll_fsm_timeout_m REG_ADDR8(REG_BB_LL_BASE_ADDR+0x2d) +#define reg_rf_ll_fsm_timeout_h REG_ADDR8(REG_BB_LL_BASE_ADDR+0x2e) + +#define reg_rf_fsm_timeout REG_ADDR32(0x80140a2c) + +#define reg_rf_coex_enable REG_ADDR8(REG_BB_LL_BASE_ADDR+0x30) +enum{ + FLD_RF_COEX_EN = BIT(0), + FLD_RF_COEX_WF_DN_POL = BIT(1), + FLD_RF_COEX_STATUS = BIT(2), + FLD_RF_COEX_TRX_POL = BIT(3), + FLD_RF_TRX_PRIO = BIT(4), + FLD_RF_TX_PRIO = BIT(5), + FLD_RF_RX_PRIO = BIT(6), +}; +#define CLEAR_ALL_RFIRQ_STATUS (reg_rf_irq_status = 0xffff) +#define REG_TL_MODEM_BASE_ADDR 0x140c00//140c00 + +#define reg_rf_modem_mode_cfg_rx1_0 REG_ADDR8(REG_TL_MODEM_BASE_ADDR+0x20) +enum +{ + FLD_RF_LR_MODE = BIT(0), + FLD_RF_BT_BLE_SEL_AUTO = BIT(1), + FLD_RF_BT_BLE_SEL_EN_RX = BIT(2), + FLD_RF_CONT_MODE = BIT(3), + FLD_RF_NTL_CV = BIT(4), + FLD_RF_RX_DATA_CLK_DBG = BIT(5), + FLD_RF_LR_TRIG_MODE = BIT(6), + FLD_RF_FDC_DBG_SEL = BIT(7), + +}; +#define reg_rf_modem_mode_ctrl_tx1_0 REG_ADDR8(REG_TL_MODEM_BASE_ADDR+0x22) +enum +{ + FLD_RF_BLE_MODEM_TX = BIT(0), +}; + +#define reg_rf_modem_rx_ctrl_0 REG_ADDR8(REG_TL_MODEM_BASE_ADDR+0x4c) +enum +{ + FLD_RF_RX_ACC_LNE = BIT_RNG(0,2), + FLD_RF_RX_CRC_EN = BIT(3), + FLD_RF_SFD0_NUM = BIT_RNG(4,6), +}; + +#define reg_rf_modem_sync_thre_ble REG_ADDR8(REG_TL_MODEM_BASE_ADDR+0x4e) + +#define reg_rf_agc_rssi_lat REG_ADDR8(REG_TL_MODEM_BASE_ADDR+0x5d) + +#define reg_rf_tx_tl_ctrl REG_ADDR8(REG_TL_MODEM_BASE_ADDR+0x9a) +enum +{ + FLD_RF_TX_TP_EN = BIT(0), + FLD_RF_TX_IQ_EN = BIT(1), + FLD_RF_TX_MPSK_EN = BIT(2), + FLD_RF_TX_TP_ALIGN = BIT(3), + +}; + +#define reg_rf_mode_cfg_rx1_0 REG_ADDR8(REG_TL_RADIO_BASE_ADDR+0x20) +enum +{ + FLD_RF_BW_CODE = BIT_RNG(1,3), + FLD_RF_SC_CODE = BIT(4), +}; + +#define reg_rf_mode_cfg_rx1_1 REG_ADDR8(REG_TL_RADIO_BASE_ADDR+0x21) +enum +{ + FLD_RF_MODE_VANT_RX = BIT(1), + FLD_RF_FE_RTRIM_RX = BIT_RNG(2,4), + FLD_RF_IF_FREQ = BIT_RNG(5,6), + +}; + +#define reg_rf_mode_cfg_tx1_0 REG_ADDR8(REG_TL_RADIO_BASE_ADDR+0x22) +enum +{ + FLD_RF_BLE_MODE_TX = BIT(0), + FLD_RF_VCO_TRIM_KVM = BIT_RNG(1,3), + FLD_RF_HPMC_EXP_DIFF_COUNT_L = BIT_RNG(4,7), +}; + +#define reg_rf_mode_cfg_tx1_1 REG_ADDR8(REG_TL_RADIO_BASE_ADDR+0x23) +enum +{ + FLD_RF_HPMC_EXP_DIFF_COUNT_H = BIT_RNG(0,4), + FLD_RF_DAC_TRIM_CFBK = BIT_RNG(5,6), + +}; + +#define reg_rf_mode_cfg_txrx_0 REG_ADDR8(REG_TL_RADIO_BASE_ADDR+0x26) +enum +{ + FLD_RF_DIS_CLK_DIG_O = BIT(0), + FLD_RF_VANT_PULLDN = BIT(1), + FLD_RF_GF_BT = BIT(2), + FLD_RF_LDO_ANT_TRIM = BIT_RNG(3,5), + FLD_RF_CBPF_TYPE = BIT(6), + FLD_RF_TX_PA_PWR_L = BIT(7), +}; + + +#define reg_rf_mode_cfg_txrx_1 REG_ADDR8(REG_TL_RADIO_BASE_ADDR+0x27) + +enum +{ + FLD_RF_TX_PA_PWR_H = BIT_RNG(0,4), +}; + +#define reg_rf_burst_cfg_txrx_0 REG_ADDR8(REG_TL_RADIO_BASE_ADDR+0x28) +enum +{ + FLD_RF_CHNL_NUM = BIT_RNG(0,7), +}; + +#define reg_rf_burst_cfg_txrx_1 REG_ADDR8(REG_TL_RADIO_BASE_ADDR+0x29) +enum +{ + FLD_RF_CH_NUMLL_SEL = BIT(0), + FLD_RF_TX_EN_PIF = BIT(1), + FLD_RF_RX_EN_PIF = BIT(2), + FLD_RF_RX_TIM_SRQ_SEL_TESQ = BIT(3), + FLD_RF_TX_TIM_SRQ_SEL_TESQ = BIT(4), + FLD_RF_FE_CTRIM = BIT_RNG(5,7), +}; + +#define reg_rf_mode_cfg_tx3_0 REG_ADDR8(REG_TL_RADIO_BASE_ADDR+0x3c) +enum +{ + FLD_RF_MODE_CFG_TX3 = BIT_RNG(0,5), + FLD_RF_MODE_VANT_TX_BLE = BIT(6), + FLD_RF_TX_IQ_MODE_EN_BLE = BIT(7), +}; + + + +#define reg_rf_mode_cfg_tx3_1 REG_ADDR8(REG_TL_RADIO_BASE_ADDR+0x3d) +enum +{ + FLD_RF_LDO_ANT_TRIM_BLE = BIT_RNG(0,2), + FLD_RF_BT_BLE_SEL_EN = BIT(3), + FLD_RF_TXC_PWR_SRL = BIT(4), + FLD_RF_BW_CODE_BLE = BIT_RNG(5,7), + +}; + +#define reg_rf_txrx_dbg3_0 REG_ADDR8(REG_TL_RADIO_BASE_ADDR+0x44) +enum +{ + FLD_RF_CHNL_FREQ_DIRECT = BIT(0), + FLD_RF_CHNL_FREQ_L = BIT_RNG(1,7), +}; + +#define reg_rf_txrx_dbg3_1 REG_ADDR8(REG_TL_RADIO_BASE_ADDR+0x45) +enum +{ + FLD_RF_CHNL_FREQ_H = BIT_RNG(0,5), + FLD_RF_DSN_DITHER_DISABLE = BIT(6), + FLD_RF_DSM_INT_MODE = BIT(7), +}; + +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/soc.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/soc.h new file mode 100755 index 0000000..6897eb0 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/soc.h @@ -0,0 +1,179 @@ +/******************************************************************************************************** + * @file soc.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "../sys.h" + +#define LM_BASE 0x80000000 + +#define ILM_BASE (LM_BASE + 0x40000000) +#define DLM_BASE (LM_BASE + 0x40200000) +#define CPU_ILM_BASE (0x00000000) +#define CPU_DLM_BASE (0x00080000) + +#define SC_BASE_ADDR 0x1401c0 +/******************************* reset registers: 1401e0 ******************************/ +#define reg_rst REG_ADDR32(0x1401e0) + +#define reg_rst0 REG_ADDR8(0x1401e0) +enum{ + FLD_RST0_HSPI = BIT(0), + FLD_RST0_I2C = BIT(1), + FLD_RST0_UART0 = BIT(2), + FLD_RST0_USB = BIT(3), + FLD_RST0_PWM = BIT(4), + //RSVD + FLD_RST0_UART1 = BIT(6), + FLD_RST0_SWIRE = BIT(7), +}; + + +#define reg_rst1 REG_ADDR8(0x1401e1) +enum{ + //RSVD + FLD_RST1_SYS_STIMER = BIT(1), + FLD_RST1_DMA = BIT(2), + FLD_RST1_ALGM = BIT(3), + FLD_RST1_PKE = BIT(4), + //RSVD + FLD_RST1_PSPI = BIT(6), + FLD_RST1_SPISLV = BIT(7), +}; + +#define reg_rst2 REG_ADDR8(0x1401e2) +enum{ + FLD_RST2_TIMER = BIT(0), + FLD_RST2_AUD = BIT(1), + FLD_RST2_TRNG = BIT(2), + //RSVD + FLD_RST2_MCU = BIT(4), + FLD_RST2_LM = BIT(5), + FLD_RST2_NPE = BIT(6), + //RSVD +}; + +#define reg_rst3 REG_ADDR8(0x1401e3) +enum{ + FLD_RST3_ZB = BIT(0), + FLD_RST3_MSTCLK = BIT(1), + FLD_RST3_LPCLK = BIT(2), + FLD_RST3_ZB_CRYPT = BIT(3), + FLD_RST3_MSPI = BIT(4), + FLD_RST3_CODEC = BIT(5), + FLD_RST3_SARADC = BIT(6), + FLD_RST3_ALG = BIT(7), +}; + +#define reg_clk_en REG_ADDR32(0x1401e4) + +#define reg_clk_en0 REG_ADDR8(0x1401e4) +enum{ + FLD_CLK0_HSPI_EN = BIT(0), + FLD_CLK0_I2C_EN = BIT(1), + FLD_CLK0_UART0_EN = BIT(2), + FLD_CLK0_USB_EN = BIT(3), + FLD_CLK0_PWM_EN = BIT(4), + FLD_CLK0_UART1_EN = BIT(6), + FLD_CLK0_SWIRE_EN = BIT(7), +}; + +#define reg_clk_en1 REG_ADDR8(0x1401e5) +enum{ + FLD_CLK1_SYS_TIMER_EN = BIT(1), + FLD_CLK1_ALGM_EN = BIT(3), + FLD_CLK1_PKE_EN = BIT(4), + FLD_CLK1_MACHINETIME_EN = BIT(5), + FLD_CLK1_PSPI_EN = BIT(6), + FLD_CLK1_SPISLV_EN = BIT(7), + +}; + +#define reg_clk_en2 REG_ADDR8(0x1401e6) +enum{ + FLD_CLK2_TIMER_EN = BIT(0), + FLD_CLK2_AUD_EN = BIT(1), + FLD_CLK2_TRNG_EN = BIT(2), + FLD_CLK2_MCU_EN = BIT(4), + + FLD_CLK2_NPE_EN = BIT(6), + FLD_CLK2_EOC_EN = BIT(7), +}; + +#define reg_clk_en3 REG_ADDR8(0x1401e7) +enum{ + FLD_CLK3_ZB_PCLK_EN = BIT(0), + FLD_CLK3_ZB_MSTCLK_EN = BIT(1), + FLD_CLK3_ZB_LPCLK_EN = BIT(2), +}; + +#define reg_clk_sel0 REG_ADDR8(0x1401e8) +enum{ + FLD_CLK_SCLK_DIV = BIT_RNG(0,3), + FLD_CLK_SCLK_SEL = BIT_RNG(4,6), + FLD_CLK_MSPI_CLK_SEL = BIT(7), +}; + +#define reg_clk_sel1 REG_ADDR8(0x1401e9) +enum{ + FLD_CLK_MSPI_DIV = BIT_RNG(4,7), +}; + +#define reg_i2s_step REG_ADDR8(SC_BASE_ADDR+0x2a) +enum{ + FLD_I2S_STEP = BIT_RNG(0,6), + FLD_I2S_CLK_EN = BIT(7), +}; + +#define reg_i2s_mod REG_ADDR8(SC_BASE_ADDR+0x2b) + + +#define reg_dmic_step REG_ADDR8(SC_BASE_ADDR+0x2c) +enum{ + FLD_DMIC_STEP = BIT_RNG(0,6), + FLD_DMIC_SEL = BIT(7), +}; + +#define reg_dmic_mod REG_ADDR8(SC_BASE_ADDR+0x2d) + +#define reg_wakeup_en REG_ADDR8(SC_BASE_ADDR+0x2e) +enum{ + FLD_USB_PWDN_I = BIT(0), + FLD_GPIO_WAKEUP_I = BIT(1), + FLD_USB_RESUME = BIT(2), + FLD_STANDBY_EX = BIT(3), +}; + +#define reg_dmic_clk_set REG_ADDR8(SC_BASE_ADDR+0x33) + + +#define reg_wakeup_status 0x64 +typedef enum{ + FLD_WKUP_CMP = BIT(0), + FLD_WKUP_TIMER = BIT(1), + FLD_WKUP_DIG = BIT(2), + FLD_WKUP_PAD = BIT(3), + FLD_WKUP_MDEC = BIT(4), + FLD_MDEC_RSVD = BIT_RNG(5,7), +}wakeup_status_e; + + diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/spi_reg.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/spi_reg.h new file mode 100755 index 0000000..5f6a0ff --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/spi_reg.h @@ -0,0 +1,392 @@ +/******************************************************************************************************** + * @file spi_reg.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef SPI_REG_H +#define SPI_REG_H + +#include "../sys.h" + +/******************************* hspi registers: 0x1FFFFC0 ******************************/ + + + +#define HSPI_BASE_ADDR 0x1FFFFC0 +#define PSPI_BASE_ADDR 0x140040 +#define BASE_ADDR_DIFF 0x1EBFF80 + +#define reg_hspi_data_buf_adr 0x1FFFFC8 +#define reg_hspi_xip_base_adr 0x1000000 +#define reg_spi_data_buf_adr(i) 0x140048+(i)*BASE_ADDR_DIFF +/** + * BIT[0:1] the minimum time between the edge of SPI_CS and the edges of SPI_CLK.the actual duration is (SPI_CLK_OUT/2)*(cs2sclk+1).master only + * BIT[2] set 3line mode ,MOSI is bi-directional signal in regular mode.master only + * BIT[3] transfer data with least significant bit first.1: LSB 0: MSB default. master/slave + * BIT[4] set dual io mode.master only + * BIT[5:6] set spi 4 mode. master/slave + * * * bit5: CPHA-SPI_CLK Phase,bit6: CPOL-SPI_CLK Polarity + * MODE0: CPHA = 0 , CPOL =0; + * MODE1: CPHA = 0 , CPOL =1; + * MODE2: CPHA = 1 , CPOL =0; + * MODE3: CPHA = 1, CPOL =1; + * BIT[7] set master/slave mode. 0 slave 1 master default.master/slave + */ +#define reg_spi_mode0(i) REG_ADDR8(PSPI_BASE_ADDR+(i)*BASE_ADDR_DIFF) +enum{ + FLD_SPI_CS2SCLK = BIT_RNG(0,1), + FLD_SPI_3LINE = BIT(2), + FLD_SPI_LSB = BIT(3), + FLD_SPI_DUAL = BIT(4), + FLD_SPI_MODE_WORK_MODE = BIT_RNG(5,6), + FLD_SPI_MASTER_MODE = BIT(7), +}; + +/*the clock freq ratio between the source_clock and spi_clock.master only + * spi_clock=source_clock/((spi_clk_div+1)*2) + * spi_clk_div=reg_hspi_mode1[7:0]. max_value=0xff,spi_clock==source_clock + */ +//#define reg_hspi_mode1 REG_ADDR8(HSPI_BASE_ADDR+0x01) +#define reg_spi_mode1(i) REG_ADDR8(PSPI_BASE_ADDR+0x01+(i)*BASE_ADDR_DIFF) + +/** + * BIT[0] set cmd format 0: single mode 1: the format of the cmd phase is the same as the data phase(Dual/Quad).master only + * BIT[1] set spi quad I/O mode. master only + * BIT[2] set the spi commnd phase enable.master only + * BIT[4:7] the minimum time that SPI CS should stay HIGH.the actual duration is (SPI_CLK period_out / 2)*(csht+1).default=2,master only + */ +#define reg_spi_mode2(i) REG_ADDR8(PSPI_BASE_ADDR+0x02+(i)*BASE_ADDR_DIFF) + + +enum{ + FLD_HSPI_CMD_FMT =BIT(0), + FLD_HSPI_QUAD =BIT(1), + FLD_SPI_CMD_EN =BIT(2), + FLD_SPI_HSPI_MODE2_RESERVED =BIT(3), + FLD_SPI_CSHT =BIT_RNG(4,7), +}; + +/** + * BIT[0:7] transfer count0 for write data.master only + */ +#define reg_spi_tx_cnt0(i) REG_ADDR8(PSPI_BASE_ADDR+0x03+(i)*BASE_ADDR_DIFF) + +/** + * BIT[0:7] transfer count1 for write data.master only + */ + +#define reg_spi_tx_cnt1(i) REG_ADDR8(PSPI_BASE_ADDR+0x12+(i)*(BASE_ADDR_DIFF-0x12+0x20)) +//#define reg_hspi_tx_cnt1 REG_ADDR8(HSPI_BASE_ADDR+0x20) +/** + * BIT[0:7] transfer count2 for write data.master only + */ + +#define reg_spi_tx_cnt2(i) REG_ADDR8(PSPI_BASE_ADDR+0x13+(i)*(BASE_ADDR_DIFF-0x13+0x21)) + +/** + * BIT[0:7] transfer count0 for read data.master only + */ +#define reg_spi_rx_cnt0(i) REG_ADDR8(PSPI_BASE_ADDR+0x04+(i)*BASE_ADDR_DIFF) + +/** + * BIT[0:7] transfer count1 for read data.master only + */ + +#define reg_spi_rx_cnt1(i) REG_ADDR8(PSPI_BASE_ADDR+0x10+(i)*(BASE_ADDR_DIFF-0x10+0x1e)) +/** + * BIT[0:7] transfer count2 for read data.master only + */ + +#define reg_spi_rx_cnt2(i) REG_ADDR8(PSPI_BASE_ADDR+0x11+(i)*(BASE_ADDR_DIFF-0x11+0x1f)) + + + +/** + * BIT[0:3] dummy data cnt, dummy is always single wire mode, dummy number = dummy_cnt + 1.master only + * BIT[4:7] the transfer mode.master only + * the transfer sequence could be: + * 0x0:write and read at the same time(must enbale CmdEn) + * 0x1:write only + * 0x2:read only(must enbale CmdEn) + * 0x3:write,read + * 0x4:read,write + * 0x5:write,dummy,read + * 0x6:read,dummy,write(must enbale CmdEn) + * 0x7:None Data(must enbale CmdEn) + * 0x8:Dummy,write + * 0x9:Dummy,read + * 0xa~0xf:reserved + */ +#define reg_spi_trans0(i) REG_ADDR8(PSPI_BASE_ADDR+0x05+(i)*BASE_ADDR_DIFF) + +enum{ + FLD_SPI_DUMMY_CNT = BIT_RNG(0,3), + FLD_SPI_TRANSMODE =BIT_RNG(4,7), +}; + + + +/** + * BIT[0:7] SPI Command.master only + */ + +#define reg_spi_trans1(i) REG_ADDR8(PSPI_BASE_ADDR+0x06+(i)*BASE_ADDR_DIFF) +enum{ + FLD_SPI_CMD_RESERVED =BIT(0), + FLD_SPI_CMD_TRANS_HWORD =BIT(1),//1 apb hword transfer + FLD_SPI_CMD_TRANS_WORD =BIT(2),//1 apb word transfer + FLD_SPI_CMD_RD_DUMMY_4CYCLE =BIT(3),// 0 8cycle 1 4cycle + FLD_SPI_CMD_ADDR_AUTO_INCREASE =BIT(4),// 0 AUTO incease + FLD_SPI_CMD_DATA_DUAL =BIT(5),// 0 Single 1 DuaL + FLD_SPI_CMD_ADDR_DUAL =BIT(6),// 0 Single 1 DuaL + FLD_SPI_CMD_RD_EN =BIT(7),// 0 write 1 read +}; + +/** + * BIT[0] enable the SPI Receive FIFO Overrun interrupt . slave only + * BIT[1] enable the SPI Transmit FIFO Underrun interrupt. slave only + * BIT[2] enable the SPI Receive FIFO Threshold interrupt.master/slave + * BIT[3] enable the SPI Transmit FIFO Threshold interrupt.master/slave + * BIT[4] enable the SPI Transmit end interrupt.master/slave + * BIT[5] enable slvCmdint.The slave command interrupt is triggered each byte command received (starting 8 bit) .slave only + * BIT[6] enable RX DMA + * BIT[7] enable TX DMA + */ + +#define reg_spi_trans2(i) REG_ADDR8(PSPI_BASE_ADDR+0x07+(i)*BASE_ADDR_DIFF) +enum{ + FLD_SPI_RXFIFO_OR_INT_EN =BIT(0), + FLD_SPI_TXFIFO_UR_INT_EN =BIT(1), + FLD_SPI_RXFIFO_INT_EN =BIT(2), + FLD_SPI_TXFIFO_INT_EN =BIT(3), + FLD_SPI_END_INT_EN =BIT(4), + FLD_SPI_SLV_CMD_EN =BIT(5), + FLD_SPI_RX_DMA_EN =BIT(6), + FLD_SPI_TX_DMA_EN =BIT(7), +}; + + +/** + * BIT[0:7] data0[7:0] to transmit or received. + */ + +#define reg_spi_wr_rd_data0(i) REG_ADDR8(PSPI_BASE_ADDR+0x08+(i)*BASE_ADDR_DIFF) +/** + * BIT[0:7] data1[7:0] to transmit or received. + */ + +#define reg_spi_wr_rd_data1(i) REG_ADDR8(PSPI_BASE_ADDR+0x09+(i)*BASE_ADDR_DIFF) +/** + * BIT[0:7] data2[7:0] to transmit or received. + */ +#define reg_spi_wr_rd_data2(i) REG_ADDR8(PSPI_BASE_ADDR+0x0a+(i)*BASE_ADDR_DIFF) + +/** + * BIT[0:7] data3[7:0] to transmit or received. + */ + +#define reg_spi_wr_rd_data3(i) REG_ADDR8(PSPI_BASE_ADDR+0x0b+(i)*BASE_ADDR_DIFF) + +#define reg_spi_wr_rd_data(i,j) REG_ADDR8(PSPI_BASE_ADDR+0x08+(j)+(i)*BASE_ADDR_DIFF) + + + +/** + * BIT[0:3] number of valid entries in the rxfifo. + * BIT[4:7] number of valid entries in the txfifo. + */ +#define reg_spi_fifo_num(i) REG_ADDR8(PSPI_BASE_ADDR+0x0c+(i)*BASE_ADDR_DIFF) + +enum{ + FLD_SPI_RXF_NUM = BIT_RNG(0,3), + FLD_SPI_TXF_NUM = BIT_RNG(4,7), +}; + +/** + * BIT[2] rxfifo reset,write 1 to reset. Spi clock must turn on. + * BIT[3] txfifo reset,write 1 to reset. Spi clock must turn on + * BIT[4] rxfifo full flag. + * BIT[5] rxfifo empty flag + * BIT[6] txfifo full flag. + * BIT[7] txfifo empty flag + */ +#define reg_spi_fifo_state(i) REG_ADDR8(PSPI_BASE_ADDR+0x0d+(i)*BASE_ADDR_DIFF) + +enum{ + FLD_SPI_FIFO_STA_RESERVED = BIT_RNG(0,1), + FLD_SPI_RXF_CLR =BIT(2), + FLD_SPI_TXF_CLR =BIT(3), + FLD_SPI_RXF_FULL =BIT(4), + FLD_SPI_RXF_EMPTY =BIT(5), + FLD_SPI_TXF_FULL =BIT(6), + FLD_SPI_TXF_EMPTY =BIT(7), +}; + +/** + * BIT[2] RX FIFO Overrun interrupt status. slave only + * BIT[3] TX FIFO Underrun interrupt status. slave only + * BIT[4] RX FIFO Threshold interrupt status.set 1 to clear. master/slave + * BIT[5] TX FIFO Threshold interrupt status.set 1 to clear. master/slave + * BIT[6] End of SPI Transfer interrupt status.set 1 to clear.master/slave + * BIT[7] Slave Command Interrupt status.set 1 to clear.slave only + */ +#define reg_spi_irq_state(i) REG_ADDR8(PSPI_BASE_ADDR + 0x0e +(i)*BASE_ADDR_DIFF) + +enum{ + FLD_SPI_STATE_RESERVED =BIT_RNG(0,1), + FLD_SPI_RXF_OR_INT =BIT(2), + FLD_SPI_TXF_UR_INT =BIT(3), + FLD_SPI_RXF_INT =BIT(4), + FLD_SPI_TXF_INT =BIT(5), + FLD_SPI_END_INT =BIT(6), + FLD_SPI_SLV_CMD_INT =BIT(7), +}; + +/** + * BIT[0] set this bit to indicate that spi as slave is ready for data transaction + * BIT[1] spi soft reset.high valid. + * BIT[4:6] fifo threshold. 0x4 default. + * BIT[7] SPI transfer status .1 is busy, 0 not busy. + */ +#define reg_spi_status(i) REG_ADDR8(PSPI_BASE_ADDR + 0x0f +(i)*BASE_ADDR_DIFF) +enum{ + FLD_HSPI_SLAVE_READY =BIT(0), + FLD_HSPI_SOFT_RESET =BIT(1), + FLD_HSPI_HSPI_STATUS_RESERVED =BIT_RNG(2,3), + FLD_HSPI_FIFO_THRES =BIT_RNG(4,6), + FLD_HSPI_BUSY =BIT(7), +}; + +/** + * BIT[0:7] hspi_addr0. + */ +#define reg_hspi_addr0 REG_ADDR8(HSPI_BASE_ADDR+0x10) + +/** + * BIT[0:7] hspi_addr1. + */ +#define reg_hspi_addr1 REG_ADDR8(HSPI_BASE_ADDR+0x11) + +/** + * BIT[0:7] hspi_addr2. + */ +#define reg_hspi_addr2 REG_ADDR8(HSPI_BASE_ADDR+0x12) + +/** + * BIT[0:7] hspi_addr3. + */ +#define reg_hspi_addr3 REG_ADDR8(HSPI_BASE_ADDR+0x13) + +#define reg_hspi_addr(i) REG_ADDR8(HSPI_BASE_ADDR+0x10+i) + +/** hspi_addr0~ hspi_addr3. + */ +#define reg_hspi_addr_32 REG_ADDR32(HSPI_BASE_ADDR+0x10) + + + +/** + * BIT[0] 1:enable addr phase, master only + * BIT[1] 0:single mode 1:the format of addr phase is the same as the data phase(Dual/Quad).master only + * BIT[2:3] address length.2'b00:1bye 2'b01:2bytes 2'b10:3bytes 2'b11:4bytes.master only + * BIT[4] enable xip. + * BIT[5] stop xip. + * BIT[6] xip mode 0:xip normal mode 1:xip sequential mode + * BIT[7] 0:xip timeout ,disable 1:xip timeout enable .default 1 + */ +#define reg_hspi_xip_ctrl REG_ADDR8(HSPI_BASE_ADDR+0x14) +enum{ + FLD_HSPI_ADDR_EN = BIT(0), + FLD_HSPI_ADDR_FMT = BIT(1), + FLD_HSPI_ADDR_LEN = BIT_RNG(2,3), + FLD_HSPI_XIP_ENABLE = BIT(4), + FLD_HSPI_XIP_STOP = BIT(5), + FLD_HSPI_XIP_MODE = BIT(6), + FLD_HSPI_XIP_TIMEOUT_MODE = BIT(7), +}; + + +/** + * BIT[0:7] write command used for xip + */ +#define reg_hspi_xip_wr_cmd REG_ADDR8(HSPI_BASE_ADDR+0x15) + +/** + * BIT[0:7] read command used for xip + */ +#define reg_hspi_xip_rd_cmd REG_ADDR8(HSPI_BASE_ADDR+0x16) + +/** + * BIT[0:7] Use this combined with xip_mode being xip sequential mode.default page boundary size is 32byte, 2^page_size. + */ +#define reg_hspi_page_size REG_ADDR8(HSPI_BASE_ADDR+0x17) + + +/** + * BIT[0:3] xip write mode .default 1, write trans mode is write only. + * BIT[4:7] xip read mode. default 2 ,read trans mode is read only. + */ +#define reg_hspi_xip_trans_mode REG_ADDR8(HSPI_BASE_ADDR+0x18) +enum{ + FLD_HSPI_XIP_WR_TRANS_MODE = BIT_RNG(0,3), + FLD_HSPI_XIP_RD_TRANS_MODE = BIT_RNG(4,7), +}; + +/** + * BIT[0:7] xip_addr_offset0. + */ +#define reg_hspi_xip_addr_offset0 REG_ADDR8(HSPI_BASE_ADDR+0x19) + +/** + * BIT[0:7] xip_addr_offset1. + */ +#define reg_hspi_xip_addr_offset1 REG_ADDR8(HSPI_BASE_ADDR+0x1a) + + +/** + * BIT[0:7] xip_addr_offset2. + */ +#define reg_hspi_xip_addr_offset2 REG_ADDR8(HSPI_BASE_ADDR+0x1b) + +/** + * BIT[0:7] xip_addr_offset3. + */ +#define reg_hspi_xip_addr_offset3 REG_ADDR8(HSPI_BASE_ADDR+0x1c) + + + +/** + * BIT[0:7] when XIP_TIMEOUT_MODE enable,timeout period=spi_clock_out_period*timeout_cnt + */ +#define reg_hspi_xip_timeout_cnt REG_ADDR8(HSPI_BASE_ADDR+0x1d) +/** + * BIT[0] 1:enable hspi 3line dcx (data/command selection), master only,for spi panel(LCD OLED ...) + * BIT[1] hspi 3line dcx (data/command selection). 0:command 1:data + * BIT[4:2] 2data_lane mode.3'b000:2data_lane close 3'b001:RGB565 3'b011:RGB666 3'b011:RGB888. + */ +#define reg_hspi_panel_ctrl REG_ADDR8(HSPI_BASE_ADDR+0x22) +enum{ + FLD_HSPI_PANEL_3LINE_DCX_EN = BIT(0), + FLD_HSPI_PANEL_3LINE_DCX = BIT(1), + FLD_HSPI_PANEL_2DATA_LANE = BIT_RNG(2,4), +}; + + +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/stimer_reg.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/stimer_reg.h new file mode 100755 index 0000000..45757ad --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/stimer_reg.h @@ -0,0 +1,82 @@ +/******************************************************************************************************** + * @file stimer_reg.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef STIMER_REG_H_ +#define STIMER_REG_H_ + +#include "../sys.h" +/******************************* sys clock registers: 0x140200 ******************************/ +#define STIMER_BASE_ADDR 0x140200 +#define reg_system_tick REG_ADDR32(STIMER_BASE_ADDR) + +#define reg_system_irq_level REG_ADDR32(STIMER_BASE_ADDR+0x4) + +#define reg_system_irq_mask REG_ADDR8(STIMER_BASE_ADDR+0x8) +enum{ + FLD_SYSTEM_IRQ_MASK = BIT_RNG(0,2), + FLD_SYSTEM_TRIG_PAST_EN = BIT(3), +}; + +#define reg_system_cal_irq REG_ADDR8(STIMER_BASE_ADDR+0x9) + +typedef enum{ + FLD_SYSTEM_IRQ = BIT(0), + FLD_SYSTEM_32K_IRQ = BIT(1), +}stimer_irq_e; + +#define reg_system_ctrl REG_ADDR8(STIMER_BASE_ADDR+0xa) +enum{ + FLD_SYSTEM_32K_WR_EN = BIT(0), + FLD_SYSTEM_TIMER_EN = BIT(1), + FLD_SYSTEM_TIMER_AUTO = BIT(2), + FLD_SYSTEM_32K_TRACK_EN = BIT(3), + FLD_SYSTEM_32K_CAL_MODE = BIT_RNG(4,7), + +}; + +#define reg_system_st REG_ADDR8(STIMER_BASE_ADDR+0xb) + +enum{ + + FLD_SYSTEM_CMD_STOP = BIT(1), + FLD_SYSTEM_CMD_SYNC = BIT(3), + FLD_SYSTEM_CLK_32K = BIT(4), + FLD_SYSTEM_CLR_RD_DONE = BIT(5), + FLD_SYSTEM_RD_BUSY = BIT(6), + FLD_SYSTEM_CMD_SET_DLY_DONE = BIT(7), + +}; + +#define reg_system_timer_set_32k REG_ADDR32(STIMER_BASE_ADDR+0xc) + +#define reg_system_timer_read_32k REG_ADDR32(STIMER_BASE_ADDR+0x10) + +#define reg_system_cal_latch_32k REG_ADDR32(STIMER_BASE_ADDR+0x14) + +#define reg_system_up_32k REG_ADDR32(STIMER_BASE_ADDR+0x18) +enum{ + + FLD_SYSTEM_UPDATE_UPON_32K = BIT(0), + FLD_SYSTEM_RUN_UPON_NXT_32K = BIT(1), +}; + +#endif /* STIMER_REG_H_ */ diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/timer_reg.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/timer_reg.h new file mode 100755 index 0000000..4205050 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/timer_reg.h @@ -0,0 +1,70 @@ +/******************************************************************************************************** + * @file timer_reg.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef TIMER_REG_H +#define TIMER_REG_H +#include "../sys.h" + +/******************************* timer registers: 0x140140 ******************************/ +#define reg_tmr_ctrl0 REG_ADDR8(0x140140) +#define reg_tmr_ctrl16 REG_ADDR16(0x140140) +#define reg_tmr_ctrl32 REG_ADDR32(0x140140) +enum{ + FLD_TMR0_MODE = BIT_RNG(0,1), + FLD_TMR0_EN = BIT(2), + FLD_TMR0_NOWRAP = BIT(3), + FLD_TMR1_MODE = BIT_RNG(4,5), + FLD_TMR1_EN = BIT(6), + FLD_TMR1_NOWRAP = BIT(7), +}; + +#define reg_tmr_ctrl2 REG_ADDR8(0x140142) + +enum{ + FLD_TMR_WD_EN = BIT(7), +}; + +#define reg_tmr_sta REG_ADDR8(0x140143) +enum{ + FLD_TMR_STA_TMR0 = BIT(0), + FLD_TMR_STA_TMR1 = BIT(1), + FLD_TMR_STA_WD = BIT(2), + FLD_TMR_WD_CNT_CLR = BIT(3), + FLD_TMR_SW_IRQ = BIT(7), +}; + +#define reg_tmr0_capt REG_ADDR32(0x140144) +#define reg_tmr1_capt REG_ADDR32(0x140148) +#define reg_tmr_capt(i) REG_ADDR32(0x140144 + ((i) << 2)) + +#define reg_wt_target0 REG_ADDR8(0x14014c)// always is 0x00 +#define reg_wt_target1 REG_ADDR8(0x14014d) +#define reg_wt_target2 REG_ADDR8(0x14014e) +#define reg_wt_target3 REG_ADDR8(0x14014f) +#define reg_wt_target REG_ADDR32(0x14014c) + + +#define reg_tmr0_tick REG_ADDR32(0X140150) +#define reg_tmr1_tick REG_ADDR32(0X140154) +#define reg_tmr_tick(i) REG_ADDR32(0X140150 + ((i) << 2)) + +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/trng_reg.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/trng_reg.h new file mode 100755 index 0000000..491d479 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/trng_reg.h @@ -0,0 +1,51 @@ +/******************************************************************************************************** + * @file trng_reg.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef TRNG_REG_H_ +#define TRNG_REG_H_ + +/******************************* trng registers: 101800 ******************************/ +#define REG_TRNG_BASE 0x101800 + + +#define reg_trng_cr0 REG_ADDR8(REG_TRNG_BASE) +enum{ + FLD_TRNG_CR0_RBGEN = BIT(0), + FLD_TRNG_CR0_ROSEN0 = BIT(1), + FLD_TRNG_CR0_ROSEN1 = BIT(2), + FLD_TRNG_CR0_ROSEN2 = BIT(3), + FLD_TRNG_CR0_ROSEN3 = BIT(4), +}; + +#define reg_trng_rtcr REG_ADDR32(REG_TRNG_BASE+0x04) +enum{ + FLD_TRNG_RTCR_MSEL = BIT(0), +}; + +#define reg_rbg_sr REG_ADDR8(REG_TRNG_BASE+0x08) +enum{ + FLD_RBG_SR_DRDY = BIT(0), +}; + +#define reg_rbg_dr REG_ADDR32(REG_TRNG_BASE+0x0c) + +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/uart_reg.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/uart_reg.h new file mode 100755 index 0000000..21c82e6 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/uart_reg.h @@ -0,0 +1,137 @@ +/******************************************************************************************************** + * @file uart_reg.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef UART_REG_H +#define UART_REG_H +#include "../sys.h" + +/******************************* uart0 registers: 0x140080 *******************************/ +/******************************* uart1 registers: 0x1400c0 ******************************/ +#define reg_uart_data_buf_adr(i) (0x140080+(i)*0x40) //uart(i) + +#define reg_uart_data_buf(i,j) REG_ADDR8(reg_uart_data_buf_adr(i)+(j)) //uart(i)_buf(j) +#define reg_uart_data_hword_buf(i,j) REG_ADDR16(reg_uart_data_buf_adr(i)+(j)*2) + +#define reg_uart_data_word_buf(i) REG_ADDR32(reg_uart_data_buf_adr(i)) //uart(i) + +#define reg_uart_clk_div(i) REG_ADDR16(0x140084+(i)*0x40) + +enum{ + FLD_UART_CLK_DIV = BIT_RNG(0,14), + FLD_UART_CLK_DIV_EN = BIT(15) +}; + +#define reg_uart_ctrl0(i) REG_ADDR8(0x140086+(i)*0x40) + +enum{ + FLD_UART_BPWC_O = BIT_RNG(0,3), + FLD_UART_MASK_RX_IRQ = BIT(6), + FLD_UART_MASK_TX_IRQ = BIT(7) +}; + +#define reg_uart_ctrl1(i) REG_ADDR8(0x140087+(i)*0x40) + +enum { + FLD_UART_TX_CTS_POLARITY = BIT(0), + FLD_UART_TX_CTS_ENABLE = BIT(1), + FLD_UART_PARITY_ENABLE = BIT(2), + FLD_UART_PARITY_POLARITY = BIT(3), //1:odd parity 0:even parity + FLD_UART_STOP_SEL = BIT_RNG(4,5), + FLD_UART_TTL_ENABLE = BIT(6), + FLD_UART_LOOPBACK_O = BIT(7), +}; + + +#define reg_uart_ctrl2(i) REG_ADDR16(0x140088+(i)*0x40) + +enum { + FLD_UART_RTS_TRIQ_LEV = BIT_RNG(0,3), + FLD_UART_RTS_POLARITY = BIT(4), + FLD_UART_RTS_MANUAL_V = BIT(5), + FLD_UART_RTS_MANUAL_M = BIT(6), + FLD_UART_RTS_EN = BIT(7), +}; + +#define reg_uart_ctrl3(i) REG_ADDR8(0x140089+(i)*0x40) + +enum { + FLD_UART_RX_IRQ_TRIQ_LEV = BIT_RNG(0,3), + FLD_UART_TX_IRQ_TRIQ_LEV = BIT_RNG(4,7), +}; +//////////////////////////////////////////////////// +#define reg_uart_rx_timeout0(i) REG_ADDR8(0x14008a+(i)*0x40) + +enum{ + FLD_UART_TIMEOUT_BW = BIT_RNG(0,7), +}; + +#define reg_uart_rx_timeout1(i) REG_ADDR8(0x14008b+0x40*(i)) + +enum{ + FLD_UART_TIMEOUT_MUL = BIT_RNG(0,1), + FLD_UART_MARK_RXDONE = BIT(2), + //rsvd BIT(4) + FLD_UART_P7816_EN = BIT(5), + FLD_UART_MASK_TXDONE = BIT(6), + FLD_UART_MASK_ERR_IRQ = BIT(7), +}; + + + +#define reg_uart_buf_cnt(i) REG_ADDR8(0x14008c+(i)*0x40) +enum{ + FLD_UART_RX_BUF_CNT = BIT_RNG(0,3), + FLD_UART_TX_BUF_CNT = BIT_RNG(4,7), +}; + +#define reg_uart_status1(i) REG_ADDR8(0x14008d+((i)*0x40)) +enum{ + FLD_UART_RBCNT = BIT_RNG(0,2), + FLD_UART_IRQ_O = BIT(3), + FLD_UART_WBCNT = BIT_RNG(4,6), //R + FLD_UART_CLEAR_RX = BIT(6), //Write 1 clear RX + FLD_UART_RX_ERR = BIT(7), //R + FLD_UART_CLEAR_TX = BIT(7), //Write 1 clear TX +}; + + +#define reg_uart_status2(i) REG_ADDR8((0x14008e) +(0x40*(i))) +enum{ + FLD_UART_TX_DONE = BIT(0),//only for dma default 1. + FLD_UART_TX_BUF_IRQ = BIT(1), + FLD_UART_RX_DONE = BIT(2), + FLD_UART_RX_BUF_IRQ = BIT(3), +}; + +//state machine use for IC debug +#define reg_uart_state(i) REG_ADDR8(0x14008f+0x40*(i)) +enum{ + FLD_UART_TSTATE_i = BIT_RNG(0,2),//only for dma default 1. + FLD_UART_RSTATE_i = BIT_RNG(4,7), +}; + +/******************************* 7816 registers: 0x1401f0 ******************************/ +#define reg_7816_clk_div REG_ADDR8(0x1401f0) +enum{ + FLD_7816_CLK_DIV = BIT_RNG(4,7), +}; +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/reg_include/usb_reg.h b/b91/b91m_ble_sdk/drivers/B91/reg_include/usb_reg.h new file mode 100755 index 0000000..c557d4b --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/reg_include/usb_reg.h @@ -0,0 +1,200 @@ +/******************************************************************************************************** + * @file usb_reg.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef USB_REG_H +#define USB_REG_H +#include "../sys.h" + +/******************************* usb registers: 0x100800 ******************************/ +#define reg_ctrl_ep_ptr REG_ADDR8(0x100800) +#define reg_ctrl_ep_dat REG_ADDR8(0x100801) +#define reg_ctrl_ep_ctrl REG_ADDR8(0x100802) +enum{ + FLD_EP_DAT_ACK = BIT(0), + FLD_EP_DAT_STALL = BIT(1), + FLD_EP_STA_ACK = BIT(2), + FLD_EP_STA_STALL = BIT(3), +}; + +#define reg_ctrl_ep_irq_sta REG_ADDR8(0x100803) +enum{ + FLD_CTRL_EP_IRQ_TRANS = BIT_RNG(0,3), + FLD_CTRL_EP_IRQ_SETUP = BIT(4), + FLD_CTRL_EP_IRQ_DATA = BIT(5), + FLD_CTRL_EP_IRQ_STA = BIT(6), + FLD_CTRL_EP_IRQ_INTF = BIT(7), +}; + +#define reg_ctrl_ep_irq_mode REG_ADDR8(0x100804) +enum{ + FLD_CTRL_EP_AUTO_ADDR = BIT(0), + FLD_CTRL_EP_AUTO_CFG = BIT(1), + FLD_CTRL_EP_AUTO_INTF = BIT(2), + FLD_CTRL_EP_AUTO_STA = BIT(3), + FLD_CTRL_EP_AUTO_SYN = BIT(4), + FLD_CTRL_EP_AUTO_DESC = BIT(5), + FLD_CTRL_EP_AUTO_FEAT = BIT(6), + FLD_CTRL_EP_AUTO_STD = BIT(7), +}; + +#define reg_usb_ctrl REG_ADDR8(0x100805) +enum{ + FLD_USB_CTRL_AUTO_CLK = BIT(0), + FLD_USB_CTRL_LOW_SPD = BIT(1), + FLD_USB_CTRL_LOW_JITT = BIT(2), + FLD_USB_CTRL_TST_MODE = BIT(3), +}; + +#define reg_usb_cycl_cali REG_ADDR16(0x100806) +#define reg_usb_cych_cali REG_ADDR16(0x100807) +#define reg_usb_mdev REG_ADDR8(0x10080a) +enum{ + FLD_USB_MDEV_SELF_PWR = BIT(0), + FLD_USB_MDEV_SUSP_STA = BIT(1), + FLD_USB_MDEV_WAKE_FEA = BIT(2), + FLD_USB_MDEV_VEND_CMD = BIT(3), + FLD_USB_MDEV_VEND_DIS = BIT(4), +}; + +#define reg_usb_host_conn REG_ADDR8(0x10080b) +#define reg_usb_sups_cyc_cali REG_ADDR8(0x10080c) +#define reg_usb_intf_alt REG_ADDR8(0x10080d) +#define reg_usb_edp_en REG_ADDR8(0x10080e) +typedef enum{ + FLD_USB_EDP8_EN = BIT(0), // printer + FLD_USB_EDP1_EN = BIT(1), // keyboard + FLD_USB_EDP2_EN = BIT(2), // mouse + FLD_USB_EDP3_EN = BIT(3), + FLD_USB_EDP4_EN = BIT(4), + FLD_USB_EDP5_EN = BIT(5), // printer + FLD_USB_EDP6_EN = BIT(6), // audio + FLD_USB_EDP7_EN = BIT(7), // audio +}usb_ep_en_e; + +#define reg_usb_irq_mask REG_ADDR8(0x10080f) +enum{ + FLD_USB_IRQ_RESET_MASK = BIT(0), + FLD_USB_IRQ_250US_MASK = BIT(1), + FLD_USB_IRQ_SUSPEND_MASK = BIT(2), + FLD_USB_IRQ_RESET_LVL = BIT(3), + FLD_USB_IRQ_250US_LVL = BIT(4), + FLD_USB_IRQ_RESET_O = BIT(5), + FLD_USB_IRQ_250US_O = BIT(6), + FLD_USB_IRQ_SUSPEND_O = BIT(7), +}; + +#define reg_usb_ep8123_ptr REG_ADDR32(0x100810) +#define reg_usb_ep8_ptr REG_ADDR8(0x100810) +#define reg_usb_ep1_ptr REG_ADDR8(0x100811) +#define reg_usb_ep2_ptr REG_ADDR8(0x100812) +#define reg_usb_ep3_ptr REG_ADDR8(0x100813) +#define reg_usb_ep4567_ptr REG_ADDR32(0x100814) +#define reg_usb_ep4_ptr REG_ADDR8(0x100814) +#define reg_usb_ep5_ptr REG_ADDR8(0x100815) +#define reg_usb_ep6_ptr REG_ADDR8(0x100816) +#define reg_usb_ep7_ptr REG_ADDR8(0x100817) +#define reg_usb_ep_ptr(i) REG_ADDR8(0x100810+((i) & 0x07)) + +#define reg_usb_ep8123_dat REG_ADDR32(0x100818) +#define reg_usb_ep8_dat REG_ADDR8(0x100818) +#define reg_usb_ep1_dat REG_ADDR8(0x100819) +#define reg_usb_ep2_dat REG_ADDR8(0x10081a) +#define reg_usb_ep3_dat REG_ADDR8(0x10081b) +#define reg_usb_ep4567_dat REG_ADDR32(0x10081c) +#define reg_usb_ep4_dat REG_ADDR8(0x10081c) +#define reg_usb_ep5_dat REG_ADDR8(0x10081d) +#define reg_usb_ep6_dat REG_ADDR8(0x10081e) +#define reg_usb_ep7_dat REG_ADDR8(0x10081f) +#define reg_usb_ep_dat(i) REG_ADDR8(0x100818+((i) & 0x07)) + +#define reg_usb_ep8_ctrl REG_ADDR8(0x100820) +#define reg_usb_ep1_ctrl REG_ADDR8(0x100821) +#define reg_usb_ep2_ctrl REG_ADDR8(0x100822) +#define reg_usb_ep3_ctrl REG_ADDR8(0x100823) +#define reg_usb_ep4_ctrl REG_ADDR8(0x100824) +#define reg_usb_ep5_ctrl REG_ADDR8(0x100825) +#define reg_usb_ep6_ctrl REG_ADDR8(0x100826) +#define reg_usb_ep7_ctrl REG_ADDR8(0x100827) +#define reg_usb_ep_ctrl(i) REG_ADDR8(0x100820+((i) & 0x07)) + +enum{ + FLD_USB_EP_BUSY = BIT(0), + FLD_USB_EP_STALL = BIT(1), + FLD_USB_EP_DAT0 = BIT(2), + FLD_USB_EP_DAT1 = BIT(3), + FLD_USB_EP_MONO = BIT(6), + FLD_USB_EP_EOF_ISO = BIT(7), +}; + +#define reg_usb_ep8123_buf_addr REG_ADDR32(0x100828) +#define reg_usb_ep8_buf_addr REG_ADDR8(0x100828) +#define reg_usb_ep1_buf_addr REG_ADDR8(0x100829) +#define reg_usb_ep2_buf_addr REG_ADDR8(0x10082a) +#define reg_usb_ep3_buf_addr REG_ADDR8(0x10082b) +#define reg_usb_ep4567_buf_addr REG_ADDR32(0x10082c) +#define reg_usb_ep4_buf_addr REG_ADDR8(0x10082c) +#define reg_usb_ep5_buf_addr REG_ADDR8(0x10082d) +#define reg_usb_ep6_buf_addr REG_ADDR8(0x10082e) +#define reg_usb_ep7_buf_addr REG_ADDR8(0x10082f) +#define reg_usb_ep_buf_addr(i) REG_ADDR8(0x100828+((i) & 0x07)) + + +#define reg_usb_ram_ctrl REG_ADDR8(0x100830) + +enum{ + FLD_USB_CEN_PWR_DN = BIT(0), + FLD_USB_CLK_PWR_DN = BIT(1), + FLD_USB_WEN_PWR_DN = BIT(3), + FLD_USB_CEN_FUNC = BIT(4), +}; + +#define reg_usb_iso_mode REG_ADDR8(0x100838) + +#define reg_usb_ep_irq_status REG_ADDR8(0x100839) +#define reg_usb_ep_irq_mask REG_ADDR8(0x10083a) +typedef enum{ + FLD_USB_EDP8_IRQ = BIT(0), + FLD_USB_EDP1_IRQ = BIT(1), + FLD_USB_EDP2_IRQ = BIT(2), + FLD_USB_EDP3_IRQ = BIT(3), + FLD_USB_EDP4_IRQ = BIT(4), + FLD_USB_EDP5_IRQ = BIT(5), + FLD_USB_EDP6_IRQ = BIT(6), + FLD_USB_EDP7_IRQ = BIT(7), +}usb_ep_irq_e ; + + +#define reg_usb_ep8_send_max REG_ADDR8(0x10083b) +#define reg_usb_ep8_send_thre REG_ADDR8(0x10083c) +#define reg_usb_ep8_fifo_mode REG_ADDR8(0x10083d) +enum{ + FLD_USB_ENP8_FIFO_MODE = BIT(0), + FLD_USB_ENP8_FULL_FLAG = BIT(1), +}; + +#define reg_usb_ep_max_size REG_ADDR8(0x10083e) +#define reg_usb_ep_tick REG_ADDR8(0x10083f) + +#define reg_usb_mic_dat0 REG_ADDR16(0x1800) +#define reg_usb_mic_dat1 REG_ADDR16(0x1802) + +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/rf.h b/b91/b91m_ble_sdk/drivers/B91/rf.h new file mode 100755 index 0000000..3660a59 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/rf.h @@ -0,0 +1,1031 @@ +/******************************************************************************************************** + * @file rf.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef RF_H +#define RF_H + +#include "gpio.h" +#include "sys.h" + +/********************************************************************************************************************** + * RF global macro * + *********************************************************************************************************************/ +/** + * @brief This define serve to calculate the DMA length of packet. + */ +#define rf_tx_packet_dma_len(rf_data_len) (((rf_data_len)+3)/4)|(((rf_data_len) % 4)<<22) + +/***********************************************************FOR BLE******************************************************/ +/** + * @brief Those setting of offset according to ble packet format, so this setting for ble only. + */ +#define RF_BLE_DMA_RFRX_LEN_HW_INFO 0 +#define RF_BLE_DMA_RFRX_OFFSET_HEADER 4 +#define RF_BLE_DMA_RFRX_OFFSET_RFLEN 5 +#define RF_BLE_DMA_RFRX_OFFSET_DATA 6 + +/** + * @brief According to the packet format find the information of packet through offset. + */ +#define rf_ble_dma_rx_offset_crc24(p) (p[RF_BLE_DMA_RFRX_OFFSET_RFLEN]+6) //data len:3 +#define rf_ble_dma_rx_offset_time_stamp(p) (p[RF_BLE_DMA_RFRX_OFFSET_RFLEN]+9) //data len:4 +#define rf_ble_dma_rx_offset_freq_offset(p) (p[RF_BLE_DMA_RFRX_OFFSET_RFLEN]+13) //data len:2 +#define rf_ble_dma_rx_offset_rssi(p) (p[RF_BLE_DMA_RFRX_OFFSET_RFLEN]+15) //data len:1, signed +#define rf_ble_packet_length_ok(p) (p[5] <= reg_rf_rxtmaxlen) //dma_len must 4 byte aligned +#define rf_ble_packet_crc_ok(p) ((p[(p[5]+5 + 11)] & 0x01) == 0x0) + +/** + * @brief This define for ble debug the effect of rx_dly. + * when this function turn on the time of rx_dly will shorten 6.3us, + */ +#define RF_RX_SHORT_MODE_EN 1//In order to debug whether the problem is caused by rx_dly. + +/******************************************************FOR ESB************************************************************/ + +/** + * @brief Those setting of offset according to private esb packet format, so this setting for ble only. + */ +#define RF_PRI_ESB_DMA_RFRX_OFFSET_RFLEN 4 + +/** + * @brief According to the packet format find the information of packet through offset. + */ + +#define rf_pri_esb_dma_rx_offset_crc(p) (p[RF_PRI_ESB_DMA_RFRX_OFFSET_RFLEN]+5) //data len:2 +#define rf_pri_esb_dma_rx_offset_time_stamp(p) (p[RF_PRI_ESB_DMA_RFRX_OFFSET_RFLEN]+7) //data len:4 +#define rf_pri_esb_dma_rx_offset_freq_offset(p) (p[RF_PRI_ESB_DMA_RFRX_OFFSET_RFLEN]+11) //data len:2 +#define rf_pri_esb_dma_rx_offset_rssi(p) (p[RF_PRI_ESB_DMA_RFRX_OFFSET_RFLEN]+13) //data len:1, signed +#define rf_pri_esb_packet_crc_ok(p) ((p[((p[4] & 0x3f) + 11+3)] & 0x01) == 0x00) + + +/******************************************************FOR ZIGBEE************************************************************/ + +/** + * @brief Those setting of offset according to zigbee packet format, so this setting for zigbee only. + */ + +#define RF_ZIGBEE_DMA_RFRX_OFFSET_RFLEN 4 + +/** + * @brief According to the packet format find the information of packet through offset. + */ + + +#define rf_zigbee_dma_rx_offset_crc(p) (p[RF_ZIGBEE_DMA_RFRX_OFFSET_RFLEN]+3) //data len:2 +#define rf_zigbee_dma_rx_offset_time_stamp(p) (p[RF_ZIGBEE_DMA_RFRX_OFFSET_RFLEN]+5) //data len:4 +#define rf_zigbee_dma_rx_offset_freq_offset(p) (p[RF_ZIGBEE_DMA_RFRX_OFFSET_RFLEN]+9) //data len:2 +#define rf_zigbee_dma_rx_offset_rssi(p) (p[RF_ZIGBEE_DMA_RFRX_OFFSET_RFLEN]+11) //data len:1, signed +#define rf_zigbee_packet_crc_ok(p) ((p[(p[4]+9+3)] & 0x51) == 0x0) +#define rf_zigbee_get_payload_len(p) (p[4]) +#define rf_zigbee_packet_length_ok(p) (1) +/** + * @brief According to different packet format find the crc check digit. + */ +#define rf_pri_sb_packet_crc_ok(p) ((p[(reg_rf_sblen & 0x3f)+4+9] & 0x01) == 0x00) +#define rf_hybee_packet_crc_ok(p) ((p[(p[4]+9+3)] & 0x51) == 0x0) + +#define rf_ant_packet_crc_ok(p) ((p[(reg_rf_sblen & 0x3f)+4+9] & 0x01) == 0x00) + +/********************************************************************************************************************** + * RF global data type * + *********************************************************************************************************************/ + +/** + * @brief select status of rf. + */ +typedef enum { + RF_MODE_TX = 0, /**< Tx mode */ + RF_MODE_RX = 1, /**< Rx mode */ + RF_MODE_AUTO=2, /**< Auto mode */ + RF_MODE_OFF =3 /**< TXRX OFF mode */ +} rf_status_e; + +/** + * @brief select RX_CYC2LNA and TX_CYC2PA pin; + */ + +typedef enum { + RF_RFFE_RX_PB1 = GPIO_PB1, /**< pb1 as rffe rx pin */ + RF_RFFE_RX_PD6 = GPIO_PD6, /**< pd6 as rffe rx pin */ + RF_RFFE_RX_PE4 = GPIO_PE4 /**< pe4 as rffe rx pin */ +} rf_lna_rx_pin_e; + + +typedef enum { + RF_RFFE_TX_PB0 = GPIO_PB0, /**< pb0 as rffe tx pin */ + RF_RFFE_TX_PB6 = GPIO_PB6, /**< pb6 as rffe tx pin */ + RF_RFFE_TX_PD7 = GPIO_PD7, /**< pd7 as rffe tx pin */ + RF_RFFE_TX_PE5 = GPIO_PE5 /**< pe5 as rffe tx pin */ +} rf_pa_tx_pin_e; + +/** + * @brief Define power list of RF. + */ +typedef enum { + /*VBAT*/ + RF_POWER_P9p11dBm = 63, /**< 9.1 dbm */ + RF_POWER_P8p57dBm = 45, /**< 8.6 dbm */ + RF_POWER_P8p05dBm = 35, /**< 8.1 dbm */ + RF_POWER_P7p45dBm = 27, /**< 7.5 dbm */ + RF_POWER_P6p98dBm = 23, /**< 7.0 dbm */ + RF_POWER_P5p68dBm = 18, /**< 6.0 dbm */ + /*VANT*/ + RF_POWER_P4p35dBm = BIT(7) | 63, /**< 4.4 dbm */ + RF_POWER_P3p83dBm = BIT(7) | 50, /**< 3.8 dbm */ + RF_POWER_P3p25dBm = BIT(7) | 41, /**< 3.3 dbm */ + RF_POWER_P2p79dBm = BIT(7) | 36, /**< 2.8 dbm */ + RF_POWER_P2p32dBm = BIT(7) | 32, /**< 2.3 dbm */ + RF_POWER_P1p72dBm = BIT(7) | 26, /**< 1.7 dbm */ + RF_POWER_P0p80dBm = BIT(7) | 22, /**< 0.8 dbm */ + RF_POWER_P0p01dBm = BIT(7) | 20, /**< 0.0 dbm */ + RF_POWER_N0p53dBm = BIT(7) | 18, /**< -0.5 dbm */ + RF_POWER_N1p37dBm = BIT(7) | 16, /**< -1.4 dbm */ + RF_POWER_N2p01dBm = BIT(7) | 14, /**< -2.0 dbm */ + RF_POWER_N3p37dBm = BIT(7) | 12, /**< -3.4 dbm */ + RF_POWER_N4p77dBm = BIT(7) | 10, /**< -4.8 dbm */ + RF_POWER_N6p54dBm = BIT(7) | 8, /**< -6.5 dbm */ + RF_POWER_N8p78dBm = BIT(7) | 6, /**< -8.8 dbm */ + RF_POWER_N12p06dBm = BIT(7) | 4, /**< -12.1 dbm */ + RF_POWER_N17p83dBm = BIT(7) | 2, /**< -17.8 dbm */ + RF_POWER_N23p54dBm = BIT(7) | 1, /**< -23.5 dbm */ + + RF_POWER_N30dBm = 0xff, /**< -30 dbm */ + RF_POWER_N50dBm = BIT(7) | 0, /**< -50 dbm */ + +} rf_power_level_e; + +/** + * @brief Define power index list of RF. + */ +typedef enum { + /*VBAT*/ + RF_POWER_INDEX_P9p11dBm, /**< power index of 9.1 dbm */ + RF_POWER_INDEX_P8p57dBm, /**< power index of 8.6 dbm */ + RF_POWER_INDEX_P8p05dBm, /**< power index of 8.1 dbm */ + RF_POWER_INDEX_P7p45dBm, /**< power index of 7.5 dbm */ + RF_POWER_INDEX_P6p98dBm, /**< power index of 7.0 dbm */ + RF_POWER_INDEX_P5p68dBm, /**< power index of 6.0 dbm */ + /*VANT*/ + RF_POWER_INDEX_P4p35dBm, /**< power index of 4.4 dbm */ + RF_POWER_INDEX_P3p83dBm, /**< power index of 3.8 dbm */ + RF_POWER_INDEX_P3p25dBm, /**< power index of 3.3 dbm */ RF_POWER_P3dBm = RF_POWER_INDEX_P3p25dBm, + RF_POWER_INDEX_P2p79dBm, /**< power index of 2.8 dbm */ + RF_POWER_INDEX_P2p32dBm, /**< power index of 2.3 dbm */ + RF_POWER_INDEX_P1p72dBm, /**< power index of 1.7 dbm */ + RF_POWER_INDEX_P0p80dBm, /**< power index of 0.8 dbm */ + RF_POWER_INDEX_P0p01dBm, /**< power index of 0.0 dbm */ RF_POWER_P0dBm = RF_POWER_INDEX_P0p01dBm, + RF_POWER_INDEX_N0p53dBm, /**< power index of -0.5 dbm */ + RF_POWER_INDEX_N1p37dBm, /**< power index of -1.4 dbm */ + RF_POWER_INDEX_N2p01dBm, /**< power index of -2.0 dbm */ + RF_POWER_INDEX_N3p37dBm, /**< power index of -3.4 dbm */ + RF_POWER_INDEX_N4p77dBm, /**< power index of -4.8 dbm */ + RF_POWER_INDEX_N6p54dBm, /**< power index of -6.5 dbm */ + RF_POWER_INDEX_N8p78dBm, /**< power index of -8.8 dbm */ + RF_POWER_INDEX_N12p06dBm, /**< power index of -12.1 dbm */ + RF_POWER_INDEX_N17p83dBm, /**< power index of -17.8 dbm */ + RF_POWER_INDEX_N23p54dBm, /**< power index of -23.5 dbm */ +} rf_power_level_index_e; + + + +/** + * @brief Define RF mode. + */ +typedef enum { + RF_MODE_BLE_2M = BIT(0), /**< ble 2m mode */ + RF_MODE_BLE_1M = BIT(1), /**< ble 1M mode */ + RF_MODE_BLE_1M_NO_PN = BIT(2), /**< ble 1M close pn mode */ + RF_MODE_ZIGBEE_250K = BIT(3), /**< zigbee 250K mode */ + RF_MODE_LR_S2_500K = BIT(4), /**< ble 500K mode */ + RF_MODE_LR_S8_125K = BIT(5), /**< ble 125K mode */ + RF_MODE_PRIVATE_250K = BIT(6), /**< private 250K mode */ + RF_MODE_PRIVATE_500K = BIT(7), /**< private 500K mode */ + RF_MODE_PRIVATE_1M = BIT(8), /**< private 1M mode */ + RF_MODE_PRIVATE_2M = BIT(9), /**< private 2M mode */ + RF_MODE_ANT = BIT(10), /**< ant mode */ + RF_MODE_BLE_2M_NO_PN = BIT(11), /**< ble 2M close pn mode */ + RF_MODE_HYBEE_1M = BIT(12), /**< hybee 1M mode */ + RF_MODE_HYBEE_2M = BIT(13), /**< hybee 2M mode */ + RF_MODE_HYBEE_500K = BIT(14), /**< hybee 500K mode */ +} rf_mode_e; + + + +/** + * @brief Define RF channel. + */ +typedef enum { + RF_CHANNEL_0 = BIT(0), /**< RF channel 0 */ + RF_CHANNEL_1 = BIT(1), /**< RF channel 1 */ + RF_CHANNEL_2 = BIT(2), /**< RF channel 2 */ + RF_CHANNEL_3 = BIT(3), /**< RF channel 3 */ + RF_CHANNEL_4 = BIT(4), /**< RF channel 4 */ + RF_CHANNEL_5 = BIT(5), /**< RF channel 5 */ + RF_CHANNEL_NONE = 0x00, /**< none RF channel*/ + RF_CHANNEL_ALL = 0x0f, /**< all RF channel */ +} rf_channel_e; + +/********************************************************************************************************************** + * RF global constants * + *********************************************************************************************************************/ +extern const rf_power_level_e rf_power_Level_list[30]; + + +/********************************************************************************************************************** + * RF function declaration * + *********************************************************************************************************************/ + + +/** + * @brief This function serves to judge the statue of RF receive. + * @return -#0:idle + * -#1:rx_busy + */ +static inline unsigned char rf_receiving_flag(void) +{ + //if the value of [2:0] of the reg_0x140840 isn't 0 , it means that the RF is in the receiving packet phase.(confirmed by junwen). + return ((read_reg8(0x140840)&0x07) > 1); +} + +/** + * @brief This function serve to judge whether it is in a certain state. + * @param[in] status - Option of rf state machine status. + * @return -#0:Not in parameter setting state + * -#1:In parameter setting state + */ +static inline unsigned short rf_get_state_machine_status(state_machine_status_e status) +{ + return status == read_reg8(0x140a24); +} +/** + * @brief This function serves to set the which irq enable. + * @param[in] mask - Options that need to be enabled. + * @return Yes: 1, NO: 0. + */ +static inline void rf_set_irq_mask(rf_irq_e mask) +{ + BM_SET(reg_rf_irq_mask,mask); +} + + +/** + * @brief This function serves to clear the TX/RX irq mask. + * @param[in] mask - RX/TX irq value. + * @return none. + */ +static inline void rf_clr_irq_mask(rf_irq_e mask) +{ + BM_CLR(reg_rf_irq_mask,mask); +} + + +/** + * @brief This function serves to judge whether it is in a certain state. + * @param[in] mask - RX/TX irq status. + * @return Yes: 1, NO: 0. + */ +static inline unsigned short rf_get_irq_status(rf_irq_e status) +{ + return ((unsigned short )BM_IS_SET(reg_rf_irq_status,status)); +} + + +/** + *@brief This function serves to clear the Tx/Rx finish flag bit. + * After all packet data are sent, corresponding Tx finish flag bit + * will be set as 1.By reading this flag bit, it can check whether + * packet transmission is finished. After the check, it is needed to + * manually clear this flag bit so as to avoid misjudgment. + *@return none. + */ +static inline void rf_clr_irq_status(rf_irq_e status) +{ + BM_SET(reg_rf_irq_status, status); +} + + +/** + * @brief This function serves to settle adjust for RF Tx.This function for adjust the differ time + * when rx_dly enable. + * @param[in] txstl_us - adjust TX settle time. + * @return none. + */ +static inline void rf_tx_settle_us(unsigned short txstl_us) +{ + REG_ADDR16(0x80140a04) = txstl_us; +} + + +/** + * @brief This function serves to set RF access code. + * @param[in] acc - the value of access code. + * @return none. + */ +static inline void rf_access_code_comm (unsigned int acc) +{ + reg_rf_access_code = acc; + //The following two lines of code are for trigger access code in S2,S8 mode.It has no effect on other modes. + write_reg8(0x140c25,read_reg8(0x140c25)|0x01); +} + + +/** + * @brief this function is to enable/disable each access_code channel for + * RF Rx terminal. + * @param[in] pipe - Bit0~bit5 correspond to channel 0~5, respectively. + * - #0:Disable. + * - #1:Enable. + * If "enable" is set as 0x3f (i.e. 00111111), + * all access_code channels (0~5) are enabled. + * @return none + */ +static inline void rf_rx_acc_code_pipe_en(rf_channel_e pipe) +{ + write_reg8(0x140c4d, (read_reg8(0x140c4d)&0xc0) | pipe); //rx_access_code_chn_en +} + + +/** + * @brief this function is to select access_code channel for RF tx terminal. + * @param[in] pipe - Bit0~bit2 the value correspond to channel 0~5, respectively. + * if value > 5 enable channel 5.And only 1 channel can be selected everytime. + * - #0:Disable. + * - #1:Enable. + * If "enable" is set as 0x7 (i.e. 0111), + * the access_code channel (5) is enabled. + * @return none + */ +static inline void rf_tx_acc_code_pipe_en(rf_channel_e pipe) +{ + write_reg8(0x140a15, (read_reg8(0x140a15)&0xf8) | pipe); //Tx_Channel_man[2:0] +} + + +/** + * @brief This function serves to reset RF Tx/Rx mode. + * @return none. + */ +static inline void rf_set_tx_rx_off(void) +{ + write_reg8 (0x80140a16, 0x29); + write_reg8 (0x80140828, 0x80); // rx disable + write_reg8 (0x80140a02, 0x45); // reset tx/rx state machine +} + + +/** + * @brief This function serves to turn off RF auto mode. + * @return none. + */ +static inline void rf_set_tx_rx_off_auto_mode(void) +{ + write_reg8 (0x80140a00, 0x80); +} + + +/** + * @brief This function serves to set CRC advantage. + * @return none. + */ +static inline void rf_set_ble_crc_adv (void) +{ + write_reg32 (0x80140824, 0x555555); +} + + +/** + * @brief This function serves to set CRC value for RF. + * @param[in] crc - CRC value. + * @return none. + */ +static inline void rf_set_ble_crc_value (unsigned int crc) +{ + write_reg32 (0x80140824, crc); +} + + +/** + * @brief This function serves to set the max length of rx packet.Use byte_len to limit what DMA + * moves out will not exceed the buffer size we define.And old chip do this through dma size. + * @param[in] byte_len - The longest of rx packet. + * @return none. + */ +static inline void rf_set_rx_maxlen(unsigned int byte_len) +{ + reg_rf_rxtmaxlen = byte_len; +} + + +/** + * @brief This function serve to rx dma fifo size. + * @param[in] fifo_byte_size - the size of each fifo. + * @return none + */ +static inline void rf_set_rx_dma_fifo_size(unsigned short fifo_byte_size) +{ + reg_rf_bb_rx_size = fifo_byte_size>>4; +} +/** + * @brief This function serve to set rx dma wptr. + * @param[in] wptr -rx_wptr_real=rx_wptr & mask:After receiving 4 packets,the address returns to original address.mask value must in (0x01,0x03,0x07,0x0f). + * @return none + */ +static inline void rf_set_rx_dma_fifo_num(unsigned char fifo_num) +{ + reg_rf_rx_wptr_mask = fifo_num; //rx_wptr_real=rx_wptr & mask:After receiving 4 packets,the address returns to original address.mask value must in (0x01,0x03,0x07,0x0f). +} + + +/** + * @brief This function serves to DMA rxFIFO address + * The function apply to the configuration of one rxFiFO when receiving packets, + * In this case,the rxFiFo address can be changed every time a packet is received + * Before setting, call the function "rf_set_rx_dma" to clear DMA fifo mask value(set 0) + * @param[in] rx_addr - The address store receive packet. + * @return none + */ +static inline void rf_set_rx_buffer(unsigned char *rx_addr) +{ + rx_addr += 4; + dma_set_dst_address(DMA1,convert_ram_addr_cpu2bus(rx_addr)); +} +/** + * @brief This function serve to set the number of tx dma fifo. + * @param[in] fifo_dep - the number of dma fifo is 2 to the power of fifo_dep. + * @return none + */ +static inline void rf_set_tx_dma_fifo_num(unsigned char fifo_num) +{ + reg_rf_bb_tx_chn_dep = fifo_num;//tx_chn_dep = 2^2 =4 (have 4 fifo) +} + +/** + * @brief This function serve to set the number of tx dma fifo. + * @param[in] fifo_byte_size - the size of each dma fifo. + * @return none + */ +static inline void rf_set_tx_dma_fifo_size(unsigned short fifo_byte_size) +{ + reg_rf_bb_tx_size = fifo_byte_size>>4;//tx_idx_addr = {tx_chn_adr*bb_tx_size,4'b0}// in this setting the max data in one dma buffer is 0x20<<4.And the The product of fifo_dep and bytesize cannot exceed 0xfff. +} +/** + * @brief This function serves to set RF tx settle time. + * @tx_stl_us tx settle time.The max value of this param is 0xfff; + * @return none. + */ +static inline void rf_set_tx_settle_time(unsigned short tx_stl_us ) +{ + tx_stl_us &= 0x0fff; + write_reg8(0x140a04, (read_reg8(0x140a04)& 0xf000) |tx_stl_us);//txxstl 112us +} +/** + * @brief This function serves to set RF tx settle time and rx settle time. + * @rx_stl_us rx settle time.The max value of this param is 0xfff; + * @return none. + */ +static inline void rf_set_rx_settle_time( unsigned short rx_stl_us ) +{ + rx_stl_us &= 0x0fff; + write_reg8(0x140a0c, (read_reg8(0x140a0c)& 0xf000) |rx_stl_us);//rxstl 85us +} + +/** + * @brief This function serve to get ptx wptr. + * @param[in] pipe_id - The number of tx fifo.0<= pipe_id <=5. + * @return The write pointer of the tx. + */ +static inline unsigned char rf_get_tx_wptr(unsigned char pipe_id) +{ + return reg_rf_dma_tx_wptr(pipe_id); +} + +/** + * @brief This function serve to update the wptr of tx terminal. + * @param[in] pipe_id - The number of pipe which need to update wptr. + * @param[in] wptr - The pointer of write in tx terminal. + * @return none + */ +static inline void rf_set_tx_wptr(unsigned char pipe_id,unsigned char wptr) +{ + reg_rf_dma_tx_wptr(pipe_id) = wptr; +} + + +/** + * @brief This function serve to clear the writer pointer of tx terminal. + * @param[in] pipe_id - The number of tx DMA.0<= pipe_id <=5. + * @return none. + */ +static inline void rf_clr_tx_wptr(unsigned char pipe_id) +{ + reg_rf_dma_tx_wptr(pipe_id) = 0; +} + +/** + * @brief This function serve to get ptx rptr. + * @param[in] pipe_id -The number of tx pipe.0<= pipe_id <=5. + * @return The read pointer of the tx. + */ +static inline unsigned char rf_get_tx_rptr(unsigned char pipe_id) +{ + return reg_rf_dma_tx_rptr(pipe_id); +} + + +/** + * @brief This function serve to clear read pointer of tx terminal. + * @param[in] pipe_id - The number of tx DMA.0<= pipe_id <=5. + * @return none. + */ +static inline void rf_clr_tx_rptr(unsigned char pipe_id) +{ + reg_rf_dma_tx_rptr(pipe_id) = 0x80; +} + +/** + * @brief This function serve to get the pointer of read in rx terminal. + * @return wptr - The pointer of rx_rptr. + */ +static inline unsigned char rf_get_rx_rptr(void) +{ + return reg_rf_dma_rx_rptr; +} + +/** + * @brief This function serve to clear read pointer of rx terminal. + * @return none. + */ +static inline void rf_clr_rx_rptr(void) +{ + write_reg8(0x1004f5, 0x80); //clear rptr +} + + +/** + * @brief This function serve to get the pointer of write in rx terminal. + * @return wptr - The pointer of rx_wptr. + */ +static inline unsigned char rf_get_rx_wptr(void) +{ + return reg_rf_dma_rx_wptr; +} + + +/** + * @brief This function serve to get ptx initial pid value. + * @return The value of ptx pid before update. + */ +static inline unsigned char rf_get_ptx_pid(void) +{ + return ((reg_rf_ll_ctrl_1 & 0xc0)>>6); +} + + +/** + * @brief This function serve to set the new ptx pid value. + * @param[in] pipe_id -The number of pipe.0<= pipe_id <=5. + * @return none + */ +static inline void rf_set_ptx_pid(unsigned char pipe_pid) +{ + reg_rf_ll_ctrl_1 |= (pipe_pid << 6); +} + + +/** + * @brief This function serves to initiate information of RF. + * @return none. + */ +void rf_mode_init(void); + + +/** + * @brief This function serves to set ble_1M mode of RF. + * @return none. + */ +void rf_set_ble_1M_mode(void); + + +/** + * @brief This function serves to set ble_1M_NO_PN mode of RF. + * @return none. + */ +void rf_set_ble_1M_NO_PN_mode(void); + + +/** + * @brief This function serves to set ble_2M mode of RF. + * @return none. + */ +void rf_set_ble_2M_mode(void); + + +/** + * @brief This function serves to set ble_2M_NO_PN mode of RF. + * @return none. + */ +void rf_set_ble_2M_NO_PN_mode(void); + + +/** + * @brief This function serves to set ble_500K mode of RF. + * @return none. + */ +void rf_set_ble_500K_mode(void); + + +/** + * @brief This function serves to set zigbee_125K mode of RF. + * @return none. + */ +void rf_set_ble_125K_mode(void); + + +/** + * @brief This function serves to set zigbee_250K mode of RF. + * @return none. + */ +void rf_set_zigbee_250K_mode(void); + + +/** + * @brief This function serves to set pri_250K mode of RF. + * @return none. + */ +void rf_set_pri_250K_mode(void); + + +/** + * @brief This function serves to set pri_500K mode of RF. + * @return none. + */ +void rf_set_pri_500K_mode(void); + + +/** + * @brief This function serves to set pri_1M mode of RF. + * @return none. + */ +void rf_set_pri_1M_mode(void); + + +/** + * @brief This function serves to set pri_2M mode of RF. + * @return none. + */ +void rf_set_pri_2M_mode(void); + + +/** + * @brief This function serves to set hybee_500K mode of RF. + * @return none. + */ +void rf_set_hybee_500K_mode(void); + + +/** + * @brief This function serves to set hybee_2M mode of RF. + * @return none. + */ +void rf_set_hybee_2M_mode(void); + + +/** + * @brief This function serves to set hybee_1M mode of RF. + * @return none. + */ +void rf_set_hybee_1M_mode(void); + + + + + +/** + * @brief This function serves to set ant mode of RF. + * @return none. + */ +void rf_set_ant_mode(void); + +/** + * @brief This function serves to set RF tx DMA setting. + * @param[in] none + * @return none. + */ +void rf_set_tx_dma_config(void); +/** + * @brief This function serves to set RF tx DMA setting. + * @param[in] fifo_depth - tx chn deep. + * @param[in] fifo_byte_size - tx_idx_addr = {tx_chn_adr*bb_tx_size,4'b0}. + * @return none. + */ +void rf_set_tx_dma(unsigned char fifo_depth,unsigned short fifo_byte_size); + + +/** + * @brief This function serves to rx dma setting. + * @param[in] buff - The buffer that store received packet. + * @param[in] wptr_mask - DMA fifo mask value (0~fif0_num-1). + * @param[in] fifo_byte_size - The length of one dma fifo. + * @return none. + */ +void rf_set_rx_dma(unsigned char *buff,unsigned char wptr_mask,unsigned short fifo_byte_size); + +/** + * @brief This function serve to rx dma config + * @param[in] none + * @return none + */ +void rf_set_rx_dma_config(void); + +/** + * @brief This function serves to trigger srx on. + * @param[in] tick - Trigger rx receive packet after tick delay. + * @return none. + */ +void rf_start_srx(unsigned int tick); + + +/** + * @brief This function serves to get rssi. + * @return rssi value. + */ +signed char rf_get_rssi(void); + + +/** + * @brief This function serves to set pin for RFFE of RF. + * @param[in] tx_pin - select pin as rffe to send. + * @param[in] rx_pin - select pin as rffe to receive. + * @return none. + */ +void rf_set_rffe_pin(rf_pa_tx_pin_e tx_pin, rf_lna_rx_pin_e rx_pin); + + + +/** + * @brief This function serves to set RF Tx mode. + * @return none. + */ +void rf_set_txmode(void); + + +/** + * @brief This function serves to set RF Tx packet address to DMA src_addr. + * @param[in] addr - The packet address which to send. + * @return none. + */ +_attribute_ram_code_sec_ void rf_tx_pkt(void* addr); + + +/** + * @brief This function serves to judge RF Tx/Rx state. + * @param[in] rf_status - Tx/Rx status. + * @param[in] rf_channel - This param serve to set frequency channel(2400+rf_channel) . + * @return Whether the setting is successful(-1:failed;else success). + */ +int rf_set_trx_state(rf_status_e rf_status, signed char rf_channel); + + +/** + * @brief This function serves to set rf channel for all mode.The actual channel set by this function is 2400+chn. + * @param[in] chn - That you want to set the channel as 2400+chn. + * @return none. + */ +void rf_set_chn(signed char chn); + + +/** + * @brief This function serves to set pri sb mode enable. + * @return none. + */ +void rf_private_sb_en(void); + + +/** + * @brief This function serves to set pri sb mode payload length. + * @param[in] pay_len - In private sb mode packet payload length. + * @return none. + */ +void rf_set_private_sb_len(int pay_len); + + +/** + * @brief This function serves to disable pn of ble mode. + * @return none. + */ +void rf_pn_disable(void); + + +/** + * @brief This function serves to get the right fifo packet. + * @param[in] fifo_num - The number of fifo set in dma. + * @param[in] fifo_dep - deepth of each fifo set in dma. + * @param[in] addr - address of rx packet. + * @return the next rx_packet address. + */ +unsigned char* rf_get_rx_packet_addr(int fifo_num,int fifo_dep,void* addr); + + +/** + * @brief This function serves to set RF power level. + * @param[in] level - The power level to set. + * @return none. + */ +void rf_set_power_level (rf_power_level_e level); + + +/** + * @brief This function serves to set RF power through select the level index. + * @param[in] idx - The index of power level which you want to set. + * @return none. + */ +void rf_set_power_level_index(rf_power_level_index_e idx); + + +/** + * @brief This function serves to close internal cap. + * @return none. + */ +void rf_turn_off_internal_cap(void); + + +/** + * @brief This function serves to update the value of internal cap. + * @param[in] value - The value of internal cap which you want to set. + * @return none. + */ +void rf_update_internal_cap(unsigned char value); + + +/** + * @brief This function serves to get RF status. + * @return RF Rx/Tx status. + */ +rf_status_e rf_get_trx_state(void); + + +/** + * @brief This function serve to change the length of preamble. + * @param[in] len -The value of preamble length.Set the register bit<0>~bit<4>. + * @return none + */ +void rf_set_preamble_len(unsigned char len); + +/** + * @brief This function serve to set the private ack enable,mainly used in prx/ptx. + * @param[in] rf_mode - Must be one of the private mode. + * @return none + */ +void rf_set_pri_tx_ack_en(rf_mode_e rf_mode); + + +/** + * @brief This function serve to set the length of access code. + * @param[in] byte_len - The value of access code length. + * @return none + */ +void rf_set_access_code_len(unsigned char byte_len); + +/** + * @brief This function serve to set access code.This function will first get the length of access code from register 0x140805 + * and then set access code in addr. + * @param[in] pipe_id -The number of pipe.0<= pipe_id <=5. + * @param[in] acc -The value access code + * @note For compatibility with previous versions the access code should be bit transformed by bit_swap(); + */ +void rf_set_pipe_access_code (unsigned int pipe_id, unsigned char *addr); + +/** + * @brief This function serves to set RF rx timeout. + * @param[in] timeout_us - rx_timeout after timeout_us us,The maximum of this param is 0xfff. + * @return none. + */ +void rf_set_rx_timeout(unsigned short timeout_us); + + +/** + * @brief This function serve to initial the ptx seeting. + * @return none. + */ +void rf_ptx_config(void); + +/** + * @brief This function serve to initial the prx seeting. + * @return none. + */ +void rf_prx_config(void); + +/** + * @brief This function serves to set RF ptx trigger. + * @param[in] addr - The address of tx_packet. + * @param[in] tick - Trigger ptx after (tick-current tick),If the difference is less than 0, trigger immediately. + * @return none. + */ +void rf_start_ptx (void* addr, unsigned int tick); + +/** + * @brief This function serves to set RF prx trigger. + * @param[in] tick - Trigger prx after (tick-current tick),If the difference is less than 0, trigger immediately. + * @return none. + */ +void rf_start_prx(unsigned int tick); + + +/** + * @brief This function to set retransmit and retransmit delay. + * @param[in] retry_times - Number of retransmit, 0: retransmit OFF + * @param[in] retry_delay - Retransmit delay time. + * @return none. + */ +void rf_set_ptx_retry(unsigned char retry_times, unsigned short retry_delay); + + +/** + * @brief This function serves to judge whether the FIFO is empty. + * @param pipe_id specify the pipe. + * @return TX FIFO empty bit. + * -#0 TX FIFO NOT empty. + * -#1 TX FIFO empty. + */ +unsigned char rf_is_rx_fifo_empty(unsigned char pipe_id); + + +/** + * @brief This function serves to RF trigger stx + * @param[in] addr - DMA tx buffer. + * @param[in] tick - Send after tick delay. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void rf_start_stx(void* addr, unsigned int tick); + + +/** + * @brief This function serves to RF trigger stx2rx + * @param[in] addr - DMA tx buffer. + * @param[in] tick - Send after tick delay. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void rf_start_stx2rx (void* addr, unsigned int tick); + + +/** + * @brief This function serves to set RF baseband channel.This function is suitable for ble open PN mode. + * @param[in] chn_num - Bluetooth channel set according to Bluetooth protocol standard. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void rf_set_ble_chn(signed char chn_num); + + + +/** + * @brief This function serves to set RF Rx manual on. + * @return none. + */ +_attribute_ram_code_sec_noinline_ void rf_set_rxmode(void); + + +/** + * @brief This function serves to start Rx of auto mode. In this mode, + * RF module stays in Rx status until a packet is received or it fails to receive packet when timeout expires. + * Timeout duration is set by the parameter "tick". + * The address to store received data is set by the function "addr". + * @param[in] addr - The address to store received data. + * @param[in] tick - It indicates timeout duration in Rx status.Max value: 0xffffff (16777215) + * @return none + */ +_attribute_ram_code_sec_noinline_ void rf_start_brx (void* addr, unsigned int tick); + + +/** + * @brief This function serves to start tx of auto mode. In this mode, + * RF module stays in tx status until a packet is sent or it fails to sent packet when timeout expires. + * Timeout duration is set by the parameter "tick". + * The address to store send data is set by the function "addr". + * @param[in] addr - The address to store send data. + * @param[in] tick - It indicates timeout duration in Rx status.Max value: 0xffffff (16777215) + * @return none + */ +_attribute_ram_code_sec_noinline_ void rf_start_btx (void* addr, unsigned int tick); + + + +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/s7816.c b/b91/b91m_ble_sdk/drivers/B91/s7816.c new file mode 100755 index 0000000..4b523b3 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/s7816.c @@ -0,0 +1,195 @@ +/******************************************************************************************************** + * @file s7816.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "s7816.h" +#include "dma.h" +#include "plic.h" + +volatile unsigned int s7816_rst_pin; +volatile unsigned int s7816_vcc_pin; +volatile unsigned int s7816_rtx_pin; +volatile unsigned char s7816_clock; +volatile int s7816_rst_time;//us +volatile int s7816_atr_time;//us +/** + * @brief This function is used to set the s7816 clock. + * @param[in] div - set the divider of clock of 7816 module. + * @return none. + * @note system clk is 24MHZ + * 7816clk: 0x60-4Mhz 0x40-6Mhz 0x20-12Mhz + * baudrate: 0x60-10752 0x40-16194 0x20-32388 + * the clk-pin is PA0 by default. + */ +void s7816_set_clk(unsigned char div) +{ + reg_7816_clk_div&=0x0f; + reg_7816_clk_div|=(unsigned char)div; +} + +/** + * @brief This function is used to set the rst-wait time of the s7816 module. + * @param[in] rst_time_us - set the s7816_rst_time. + * @param[in] atr_time_us - set the s7816_atr_time. + * @return none. + */ +void s7816_set_time(int rst_time_us,int atr_time_us) +{ + s7816_rst_time=rst_time_us; + s7816_atr_time=atr_time_us; +} +/** + * @brief This function is used to set the RST pin of s7816. + * @param[in] pin_7816_rst - the RST pin of s7816. + * @return none. + */ +void s7816_set_rst_pin(gpio_pin_e pin_7816_rst) +{ + s7816_rst_pin=pin_7816_rst; + gpio_function_en(pin_7816_rst); + gpio_output_en(pin_7816_rst); + gpio_input_dis(pin_7816_rst); + gpio_set_low_level(pin_7816_rst); +} + +/** + * @brief This function is used to set the VCC pin of s7816. + * @param[in] pin_7816_vcc - the VCC pin of s7816. + * @return none. + */ +void s7816_set_vcc_pin(gpio_pin_e pin_7816_vcc) +{ + s7816_vcc_pin=pin_7816_vcc; + gpio_function_en(pin_7816_vcc); + gpio_output_en(pin_7816_vcc); + gpio_input_dis(pin_7816_vcc); + gpio_set_low_level(pin_7816_vcc); +} + +/** + * @brief This function is used to initialize the s7816 module. + * @param[in] uart_num - UART0 or UART1. + * @param[in] clock - the clock of s7816. + * @param[in] f - the clock frequency regulator of s7816,372 by default. + * @param[in] d - the bitrate regulator of s7816,1 by default. + * @return none. + */ +void s7816_init(uart_num_e uart_num,s7816_clock_e clock,int f,int d) +{ + unsigned short div; + unsigned char bwpc; + s7816_clock=clock; + s7816_rst_time=40000/clock;//us + s7816_atr_time=40000/clock;//us + + int baud=clock*1000000*d/f; + if(clock==S7816_4MHZ) + { + s7816_set_clk(0x60); + } + else if(clock==S7816_6MHZ) + { + s7816_set_clk(0x40); + } + else if(clock==S7816_12MHZ) + { + s7816_set_clk(0x20); + } + uart_reset(uart_num); + uart_cal_div_and_bwpc(baud, 24*1000*1000, &div, &bwpc); + uart_init(uart_num, div, bwpc, UART_PARITY_EVEN, UART_STOP_BIT_ONE);//7816 protocol stipulate the parity bit should be even. +} + +/** + * @brief This function is used to set all the pin of s7816 module. + * @param[in] rst_pin - the rst pin of s7816. + * @param[in] vcc_pin - the vcc pin of s7816. + * @param[in] clk_pin - the clk pin of s7816. + * @param[in] trx_pin - the trx pin of s7816. + * @return none. + */ +void s7816_set_pin(gpio_pin_e rst_pin,gpio_pin_e vcc_pin,s7816_clk_pin_e clk_pin,s7816_rtx_pin_e rtx_pin) +{ + s7816_set_rst_pin(rst_pin); + s7816_rst_pin=rst_pin; + + s7816_set_vcc_pin(vcc_pin); + s7816_vcc_pin=vcc_pin; + + reg_gpio_func_mux(clk_pin)=(reg_gpio_func_mux(clk_pin)&(~BIT_RNG(0,1)))|BIT(0); + gpio_function_dis(clk_pin); + + s7816_rtx_pin=rtx_pin;//if the trx function set to early,it may trigger interrupt by accident.so we set the function in coldreset. +} + +/** + * @brief This function is used to active the IC card,set the trx pin and coldreset. + * @param[in] none. + * @return none. + */ +void s7816_coldreset() +{ + gpio_set_high_level(s7816_vcc_pin); + delay_us(20);//wait for the vcc stable. + reg_7816_clk_div|=BIT(7); //enable the 7816 clk,the pin is A0. + delay_us(s7816_rst_time); + s7816_set_rtx_pin(s7816_rtx_pin);// uart tx/rx pin set,if the trx pin set before this place,it may + gpio_set_high_level(s7816_rst_pin);//the IC card will return the initial ATR. + delay_us(s7816_atr_time); +} + +/** + * @brief This function is used to release the trigger. + * @param[in] none. + * @return none. + */ +void s7816_release_trig() +{ + gpio_set_low_level(s7816_rst_pin); + reg_7816_clk_div&=(BIT(7)-1); + gpio_set_low_level(s7816_vcc_pin); +} + +/** + * @brief This function is used to warmreset. + * @param[in] none. + * @return none. + * @note the warmreset is required after the IC-CARD active. + */ +void s7816_warmreset() +{ + gpio_set_low_level(s7816_rst_pin); + delay_us(s7816_rst_time); + gpio_set_high_level(s7816_rst_pin);//The IC card will return the initial ATR. + delay_us(s7816_atr_time); +} + +/** + * @brief This function is used to warmreset. + * @param[in] uart_num - UART0 or UART1. + * @param[in] tx_data - the data need to send. + * return none. + */ +void s7816_send_byte(uart_num_e uart_num, unsigned char tx_data) +{ + uart_send_byte(uart_num,tx_data); + uart_rtx_pin_tx_trig(uart_num); +} diff --git a/b91/b91m_ble_sdk/drivers/B91/s7816.h b/b91/b91m_ble_sdk/drivers/B91/s7816.h new file mode 100755 index 0000000..8be2da6 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/s7816.h @@ -0,0 +1,148 @@ +/******************************************************************************************************** + * @file s7816.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef S7816_H_ +#define S7816_H_ + +#include "gpio.h" +#include "uart.h" +#include "stimer.h" + +#define s7816_en(uart_num) uart_rtx_en(uart_num) +#define s7816_set_rtx_pin(s7816_trx_pin) uart_set_rtx_pin(s7816_trx_pin) + +/** + * @brief Define 7816 TRX pin. + */ +typedef enum{ + S7816_UART0_RTX_A4=GPIO_PA4, + S7816_UART0_RTX_B3=GPIO_PB3, + S7816_UART0_RTX_D3=GPIO_PD3, + + S7816_UART1_RTX_C7=GPIO_PC7, + S7816_UART1_RTX_D7=GPIO_PD7, + S7816_UART1_RTX_E2=GPIO_PE2, +}s7816_rtx_pin_e; + +/** + * @brief Define 7816 clock. + */ +typedef enum{ + S7816_4MHZ=4, + S7816_6MHZ=6, + S7816_12MHZ=12, +}s7816_clock_e; + +/** + * @brief Define 7816 clk pin. + */ +typedef enum{ + S7817_CLK_PA0=GPIO_PA0, +}s7816_clk_pin_e; + + +/** + * @brief This function is used to set the s7816 clock. + * @param[in] div - set the divider of clock of 7816 module. + * @return none. + * @note system clk is 24MHZ + * 7816clk: 0x60-4Mhz 0x40-6Mhz 0x20-12Mhz + * baudrate: 0x60-10752 0x40-16194 0x20-32388 + * the clk-pin is PA0 by default. + */ +extern void s7816_set_clk(unsigned char div); + + +/** + * @brief This function is used to initialize the s7816 module. + * @param[in] uart_num - UART0 or UART1. + * @param[in] clock - the clock of s7816. + * @param[in] f - the clock frequency conversion factor of s7816. + * @param[in] d - the bitrate regulator of s7816. + * @return none. + */ +extern void s7816_init(uart_num_e uart_num,s7816_clock_e clock,int f,int d); + +/** + * @brief This function is used to active the IC card,set the trx pin and coldreset. + * @param[in] none. + * @return none. + */ +extern void s7816_coldreset(); + +/** + * @brief This function is used to set all the pin of s7816 module. + * @param[in] rst_pin - the rst pin of s7816. + * @param[in] vcc_pin - the vcc pin of s7816. + * @param[in] clk_pin - the clk pin of s7816. + * @param[in] trx_pin - the trx pin of s7816. + * @return none. + */ +extern void s7816_set_pin(gpio_pin_e rst_pin,gpio_pin_e vcc_pin,s7816_clk_pin_e clk_pin,s7816_rtx_pin_e trx_pin); + +/** + * @brief This function is used to release the trigger + * @param[in] none. + * @return none. + */ +extern void s7816_release_trig(); + +/** + * @brief This function is used to set the RST pin of s7816. + * @param[in] pin_7816_rst - the RST pin of s7816. + * @return none. + */ +extern void s7816_set_rst_pin(gpio_pin_e pin_7816_rst); + +/** + * @brief This function is used to set the VCC pin of s7816. + * @param[in] pin_7816_vcc - the VCC pin of s7816. + * @return none. + */ +extern void s7816_set_vcc_pin(gpio_pin_e pin_7816_vcc); + +/** + * @brief This function is used to warmreset. + * @param[in] none. + * @return none. + * @note the warmreset is required after the IC-CARD active. + */ +extern void s7816_warmreset(); + +/** + * @brief This function is used to set the rst-wait time of the s7816 module. + * @param[in] rst_time_us - set the s7816_rst_time. + * @param[in] atr_time_us - set the s7816_atr_time. + * @return none. + */ +extern void s7816_set_time(int rst_time_us,int atr_time_us); + +/** + * @brief This function is used to warmreset. + * @param[in] uart_num - UART0 or UART1. + * @param[in] tx_data - the data need to send. + * return none. + */ +extern void s7816_send_byte(uart_num_e uart_num, unsigned char tx_data); + +#endif /* S7816_H_ */ + diff --git a/b91/b91m_ble_sdk/drivers/B91/spi.c b/b91/b91m_ble_sdk/drivers/B91/spi.c new file mode 100755 index 0000000..d5599a5 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/spi.c @@ -0,0 +1,990 @@ +/******************************************************************************************************** + * @file spi.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "spi.h" + +#include "timer.h" +#include "compiler.h" +static unsigned char s_hspi_tx_dma_chn; +static unsigned char s_hspi_rx_dma_chn; +static unsigned char s_pspi_tx_dma_chn; +static unsigned char s_pspi_rx_dma_chn; + +dma_config_t hspi_tx_dma_config = { + .dst_req_sel = DMA_REQ_SPI_AHB_TX,//tx req + .src_req_sel = 0, + .dst_addr_ctrl = DMA_ADDR_FIX, + .src_addr_ctrl = DMA_ADDR_INCREMENT,//increment + .dstmode = DMA_HANDSHAKE_MODE,//handshake + .srcmode = DMA_NORMAL_MODE, + .dstwidth = DMA_CTR_WORD_WIDTH,//must word + .srcwidth = DMA_CTR_WORD_WIDTH,//must word + .src_burst_size = 0,//must 0 + .read_num_en = 0, + .priority = 0, + .write_num_en = 0, + .auto_en = 0,//must 0 +}; + dma_config_t hspi_rx_dma_config = { + .dst_req_sel = 0,//tx req + .src_req_sel = DMA_REQ_SPI_AHB_RX, + .dst_addr_ctrl = DMA_ADDR_INCREMENT, + .src_addr_ctrl = DMA_ADDR_FIX, + .dstmode = DMA_NORMAL_MODE, + .srcmode = DMA_HANDSHAKE_MODE, + .dstwidth = DMA_CTR_WORD_WIDTH,//must word + .srcwidth = DMA_CTR_WORD_WIDTH,////must word + .src_burst_size = 0, + .read_num_en = 0, + .priority = 0, + .write_num_en = 0, + .auto_en = 0,//must 0 +}; + +dma_config_t pspi_tx_dma_config = { + .dst_req_sel = DMA_REQ_SPI_APB_TX,//tx req + .src_req_sel = 0, + .dst_addr_ctrl = DMA_ADDR_FIX, + .src_addr_ctrl = DMA_ADDR_INCREMENT,//increment + .dstmode = DMA_HANDSHAKE_MODE,//handshake + .srcmode = DMA_NORMAL_MODE, + .dstwidth = DMA_CTR_WORD_WIDTH,//must word + .srcwidth = DMA_CTR_WORD_WIDTH,//must word + .src_burst_size = 0,//must 0 + .read_num_en = 0, + .priority = 0, + .write_num_en = 0, + .auto_en = 0,//must 0 +}; + +dma_config_t pspi_rx_dma_config = { + .dst_req_sel = 0,//tx req + .src_req_sel = DMA_REQ_SPI_APB_RX, + .dst_addr_ctrl = DMA_ADDR_INCREMENT, + .src_addr_ctrl = DMA_ADDR_FIX, + .dstmode = DMA_NORMAL_MODE, + .srcmode = DMA_HANDSHAKE_MODE, + .dstwidth = DMA_CTR_WORD_WIDTH,//must word + .srcwidth = DMA_CTR_WORD_WIDTH,////must word + .src_burst_size = 0, + .read_num_en = 0, + .priority = 0, + .write_num_en = 0, + .auto_en = 0,//must 0 +}; + +/** + * @brief This function selects pin for hspi master or slave mode. + * @param[in] pin - the selected pin. + * @return none + */ +void hspi_set_pin_mux(hspi_pin_def_e pin) +{ + if (pin != HSPI_NONE_PIN) + { + unsigned char val = 0; + unsigned char start_bit = (BIT_LOW_BIT(pin & 0xff) % 4) << 1; + unsigned char mask = (unsigned char)~BIT_RNG(start_bit, start_bit + 1); + + if ((pin == HSPI_CLK_PB4_PIN) || (pin == HSPI_CSN_PB6_PIN) || (pin == HSPI_MOSI_IO0_PB3_PIN) || (pin == HSPI_MISO_IO1_PB2_PIN) || (pin == HSPI_WP_IO2_PB1_PIN) || (pin == HSPI_HOLD_IO3_PB0_PIN)) + { + val = 0;//function 0 + } + else if ((pin == HSPI_CLK_PA2_PIN) || (pin == HSPI_CSN_PA1_PIN) || (pin == HSPI_MOSI_IO0_PA4_PIN) || (pin == HSPI_MISO_IO1_PA3_PIN)) + { + val = 2 << (start_bit);//function 2 + reg_gpio_pad_mul_sel |= BIT(1); + } + reg_gpio_func_mux(pin) = (reg_gpio_func_mux(pin) & mask) | val; + gpio_function_dis(pin); + gpio_input_en(pin); + } +} + +/** + * @brief This function enable hspi csn pin. + * @param[in] pin - the csn pin. + * @return none + */ +void hspi_cs_pin_en(hspi_csn_pin_def_e pin) +{ + hspi_set_pin_mux(pin); +} + +/** + * @brief This function disable hspi csn pin. + * @param[in] pin - the csn pin. + * @return none + */ +void hspi_cs_pin_dis(hspi_csn_pin_def_e pin) +{ + gpio_function_en(pin); + gpio_set_high_level(pin); +} + +/** + * @brief This function change hspi csn pin. + * @param[in] next_csn_pin - the next csn pin. + * @return next_csn_pin - the next csn pin. + */ +hspi_csn_pin_def_e hspi_change_csn_pin(hspi_csn_pin_def_e next_csn_pin) +{ + if (next_csn_pin == HSPI_CSN_PB6) + { + hspi_cs_pin_dis(HSPI_CSN_PA1); + hspi_cs_pin_en(HSPI_CSN_PB6); + } + else if (next_csn_pin == HSPI_CSN_PA1) + { + hspi_cs_pin_dis(HSPI_CSN_PB6); + hspi_cs_pin_en(HSPI_CSN_PA1); + } + return next_csn_pin; +} + +/** + * @brief This function selects pin for pspi master or slave mode. + * @param[in] pin - the selected pin. + * @return none + */ +void pspi_set_pin_mux(pspi_pin_def_e pin) +{ + if (pin!= PSPI_NONE_PIN) + { + unsigned char val = 0; + unsigned char start_bit = (BIT_LOW_BIT(pin & 0xff) %4) << 1; + unsigned char mask = (unsigned char)~BIT_RNG(start_bit, start_bit + 1); + if ((pin == PSPI_CLK_PC5_PIN) || (pin == PSPI_CSN_PC4_PIN) || (pin == PSPI_MOSI_IO0_PC7_PIN) || (pin == PSPI_MISO_IO1_PC6_PIN)) + { + val = 0;//function 0 + } + + else if ((pin == PSPI_CLK_PB5_PIN) || (pin == PSPI_CLK_PD1_PIN) || (pin == PSPI_CSN_PC0_PIN) || (pin == PSPI_CSN_PD0_PIN) || (pin == PSPI_MOSI_IO0_PB7_PIN) || (pin == PSPI_MOSI_IO0_PD3_PIN) || (pin == PSPI_MISO_IO1_PB6_PIN) || (pin == PSPI_MISO_IO1_PD2_PIN)) + { + val = 1 << (start_bit);//function 1 + } + + reg_gpio_func_mux(pin) = (reg_gpio_func_mux(pin) & mask) | val; + gpio_function_dis(pin); + gpio_input_en(pin); + } +} +/** + * @brief This function enable pspi csn pin. + * @param[in] pin - the csn pin. + * @return none + */ +void pspi_cs_pin_en(pspi_csn_pin_def_e pin) +{ + pspi_set_pin_mux(pin); +} + +/** + * @brief This function disable pspi csn pin. + * @param[in] pin - the csn pin. + * @return none + */ +void pspi_cs_pin_dis(pspi_csn_pin_def_e pin) +{ + gpio_output_en(pin); + gpio_set_high_level(pin); + gpio_function_en(pin); + gpio_input_dis(pin); + +} + +/** + * @brief This function change pspi csn pin. + * @param[in] next_csn_pin - the next csn pin. + * @return next_csn_pin - the next csn pin. + */ +pspi_csn_pin_def_e pspi_change_csn_pin(pspi_csn_pin_def_e next_csn_pin) +{ + if (next_csn_pin == PSPI_CSN_PC4) + { + pspi_cs_pin_dis(PSPI_CSN_PC0); + pspi_cs_pin_dis(PSPI_CSN_PD0); + pspi_cs_pin_en(PSPI_CSN_PC4); + } + else if (next_csn_pin == PSPI_CSN_PC0) + { + pspi_cs_pin_dis(PSPI_CSN_PC4); + pspi_cs_pin_dis(PSPI_CSN_PD0); + pspi_cs_pin_en(PSPI_CSN_PC0); + } + else if (next_csn_pin == PSPI_CSN_PD0) + { + pspi_cs_pin_dis(PSPI_CSN_PC4); + pspi_cs_pin_dis(PSPI_CSN_PC0); + pspi_cs_pin_en(PSPI_CSN_PD0); + } + return next_csn_pin; +} +/** + * @brief This function configures hspi pin. + * @param[in] config - the pointer of pin config struct. + * @return none + */ +void hspi_set_pin(hspi_pin_config_t *config) +{ + hspi_set_pin_mux(config->hspi_csn_pin); + hspi_set_pin_mux(config->hspi_clk_pin); + hspi_set_pin_mux(config->hspi_mosi_io0_pin); + hspi_set_pin_mux(config->hspi_miso_io1_pin); + hspi_set_pin_mux(config->hspi_wp_io2_pin); + hspi_set_pin_mux(config->hspi_hold_io3_pin); +} + + + +/** + * @brief This function configures pspi pin. + * @param[in] config - the pointer of pin config struct. + * @return none + */ +void pspi_set_pin(pspi_pin_config_t *config) +{ + pspi_set_pin_mux(config->pspi_clk_pin); + pspi_set_pin_mux(config->pspi_csn_pin); + pspi_set_pin_mux(config->pspi_mosi_io0_pin); + pspi_set_pin_mux(config->pspi_miso_io1_pin); +} + +/** + * @brief This function selects pin for hspi master or slave. + * @return none + */ +void spi_slave_set_pin(void) +{ + reg_gpio_pa_fuc_l = (reg_gpio_pb_fuc_l & 0x03);//set PA1 as csn,PA2 as clk,PA3 as mosi_io0, + reg_gpio_pa_fuc_h = (reg_gpio_pb_fuc_l & 0xfc);//set PA4 slave miso_io1 + gpio_function_dis(GPIO_PA1 | GPIO_PA2 | GPIO_PA3 | GPIO_PA4); + gpio_input_en(GPIO_PA1 | GPIO_PA2 | GPIO_PA3 | GPIO_PA4); +} + +/** + * @brief This function configures the clock and working mode for SPI interface. + * @param[in] spi_sel - the spi module. + * @param[in] div_clock - the division factor for SPI module. + * spi_clock_out = ahb_clock / ((div_clock+1)*2) + * @param[in] mode - the selected working mode of SPI module. + * bit5:CPHA-Clock Polarity ; bit6:CPOL:CPHA-Clock Phase + * MODE0: CPHA = 0, CPOL = 0; + * MODE1: CPHA = 0, CPOL = 1; + * MODE2: CPHA = 1, CPOL = 0; + * MODE3: CPHA = 1, CPOL = 1; + * @return none + */ +void spi_master_init(spi_sel_e spi_sel, unsigned char div_clock, spi_mode_type_e mode) +{ + reg_spi_mode1(spi_sel) = div_clock; + reg_spi_mode0(spi_sel) |= FLD_SPI_MASTER_MODE;//master + reg_spi_mode0(spi_sel) &= (~FLD_SPI_MODE_WORK_MODE); // clear spi working mode + reg_spi_mode0(spi_sel) |= (mode << 5);// select SPI mode, support four modes +} + + +/** + * @brief This function configures the clock and working mode for SPI interface. + * @param[in] spi_sel - the spi module. + * @param[in] mode - the selected working mode of SPI module. + * bit5:CPHA-Clock Polarity ; bit6:CPOL:CPHA-Clock Phase + * MODE0: CPHA = 0, CPOL = 0; + * MODE1: CPHA = 0, CPOL = 1; + * MODE2: CPHA = 1, CPOL = 0; + * MODE3: CPHA = 1, CPOL = 1; + * @return none + * @note spi_clock_in (spi_slave_clock frequency)/3 + */ +void spi_slave_init(spi_sel_e spi_sel, spi_mode_type_e mode) +{ + reg_spi_mode0(spi_sel) &= (~FLD_SPI_MASTER_MODE);//slave + reg_spi_mode0(spi_sel) &= (~FLD_SPI_MODE_WORK_MODE); // clear spi working mode + reg_spi_mode0(spi_sel) |= (mode << 5);// select SPI mode, support four modes +} + +/** + * @brief This function servers to set dummy cycle cnt. + * @param[in] spi_sel - the spi module. + * @param[in] dummy_cnt - the cnt of dummy clock. + * @return none + */ +void spi_set_dummy_cnt(spi_sel_e spi_sel, unsigned char dummy_cnt) +{ + reg_spi_trans0(spi_sel) &= (~FLD_SPI_DUMMY_CNT); + reg_spi_trans0(spi_sel) |= (dummy_cnt - 1) & FLD_SPI_DUMMY_CNT; +} + +/** + * @brief This function servers to set spi transfer mode. + * @param[in] spi_sel - the spi module. + * @param[in] mode - transfer mode. + * @return none + */ +void spi_set_transmode(spi_sel_e spi_sel, spi_tans_mode_e mode) +{ + reg_spi_trans0(spi_sel) &= (~FLD_SPI_TRANSMODE); + reg_spi_trans0(spi_sel) |= (mode & 0xf) << 4; +} + +/** + * @brief This function servers to set normal mode. + * @param[in] spi_sel - the spi module. + * @return none + */ +void spi_set_normal_mode(spi_sel_e spi_sel) +{ + spi_dual_mode_dis(spi_sel); + spi_3line_mode_dis(spi_sel); + if (HSPI_MODULE == spi_sel) + { + hspi_quad_mode_dis(spi_sel); + } +} + +/** + * @brief This function servers to set dual mode. + * @param[in] spi_sel - the spi module. + * @return none + */ +void spi_set_dual_mode(spi_sel_e spi_sel) +{ + spi_dual_mode_en(spi_sel);//quad precede over dual + spi_3line_mode_dis(spi_sel); + if (HSPI_MODULE == spi_sel) + { + hspi_quad_mode_dis(spi_sel); + } +} + +/** + * @brief This function servers to set quad mode. + * @return none + */ +void hspi_set_quad_mode() +{ + hspi_quad_mode_en(); + spi_dual_mode_dis(HSPI_MODULE); + spi_3line_mode_dis(HSPI_MODULE); +} + +/** + * @brief This function servers to set 3line mode. + * @param[in] spi_sel - the spi module. + * @return none + */ +void spi_set_3line_mode(spi_sel_e spi_sel) +{ + /*must disable dual and quad*/ + spi_3line_mode_en(spi_sel); + spi_dual_mode_dis(spi_sel); + if (HSPI_MODULE == spi_sel) + { + hspi_quad_mode_dis(spi_sel); + } +} + +/** + * @brief This function servers to set hspi io mode. + * @param[in] spi_sel - the spi module. + * @param[in] mode - single/dual/quad /3line. + * @return none + */ +void spi_set_io_mode(spi_sel_e spi_sel, spi_io_mode_e mode) +{ + switch (mode) + { + case SPI_SINGLE_MODE: + spi_set_normal_mode(spi_sel); + break; + case SPI_DUAL_MODE: + spi_set_dual_mode(spi_sel); + break; + case HSPI_QUAD_MODE: + hspi_set_quad_mode(); + break; + case SPI_3_LINE_MODE: + spi_set_3line_mode(spi_sel); + break; + } +} + +/** + * @brief This function servers to config normal mode. + * @param[in] spi_sel - the spi module. + * @param[in] mode - nomal ,mode 3line. + * @return none + */ +void spi_master_config(spi_sel_e spi_sel, spi_nomal_3line_mode_e mode) +{ + spi_cmd_dis(spi_sel); + if (HSPI_MODULE == spi_sel) + { + hspi_addr_dis(); + } + spi_set_io_mode(spi_sel, mode); +} + +/** + * @brief This function servers to config hspi special mode. + * @param[in] config - the pointer of pin special config struct. + * @return none + */ +void hspi_master_config_plus(hspi_config_t *config) +{ + spi_set_io_mode(HSPI_MODULE, config->hspi_io_mode); + hspi_set_addr_len(config->hspi_addr_len); + spi_set_dummy_cnt(HSPI_MODULE, config->hspi_dummy_cnt); + + if (1 == config->hspi_cmd_en) + { + spi_cmd_en(HSPI_MODULE); + } + else if (0 == config->hspi_cmd_en) + { + spi_cmd_dis(HSPI_MODULE); + } + + if (1 == config->hspi_cmd_fmt_en) + { + hspi_cmd_fmt_en(); + } + else if (0 == config->hspi_cmd_fmt_en) + { + hspi_cmd_fmt_dis(); + } + + if (1 == config->hspi_addr_en) + { + hspi_addr_en(); + } + else if (0 == config->hspi_addr_en) + { + hspi_addr_dis(); + } + + if (1 == config->hspi_addr_fmt_en) + { + hspi_addr_fmt_en(); + } + else if (0 == config->hspi_addr_fmt_en) + { + hspi_addr_fmt_dis(); + } +} + +/** + * @brief This function servers to config pspi special mode. + * @param[in] config - the pointer of pin special config struct. + * @return none + */ +void pspi_master_config_plus(pspi_config_t *config) +{ + spi_set_io_mode(PSPI_MODULE, config->pspi_io_mode); + spi_set_dummy_cnt(PSPI_MODULE, config->pspi_dummy_cnt); + if (1 == config->pspi_cmd_en) + { + spi_cmd_en(PSPI_MODULE); + } + else if (0 == config->pspi_cmd_en) + { + spi_cmd_dis(PSPI_MODULE); + } +} + +/** + * @brief This function servers to set slave address hspi only. + * @param[in] addr - address of slave. + * @return none + */ +void hspi_set_address(unsigned int addr) +{ + reg_hspi_addr_32 = addr; +} + +/** + * @brief This function servers to write hspi fifo. + * @param[in] spi_sel - the spi module. + * @param[in] data - the pointer to the data for write. + * @param[in] len - write length. + * @return none + */ +void spi_write(spi_sel_e spi_sel, unsigned char *data, unsigned int len) +{ + for (unsigned int i = 0; i < len; i++) + { + while (reg_spi_fifo_state(spi_sel) & FLD_SPI_TXF_FULL); + reg_spi_wr_rd_data(spi_sel, i % 4) = data[i]; + } +} + + +/** + * @brief This function servers to read hspi fifo. + * @param[in] spi_sel - the spi module. + * @param[in] data - the pointer to the data for read. + * @param[in] len - write length. + * @return none + */ +void spi_read(spi_sel_e spi_sel, unsigned char *data, unsigned int len) +{ + for (unsigned int i = 0; i < len; i++) + { + while (reg_spi_fifo_state(spi_sel) & FLD_SPI_RXF_EMPTY); + data[i] = reg_spi_wr_rd_data(spi_sel, i % 4); + } +} + +/** + * @brief This function serves to normal write data in normal. + * @param[in] spi_sel - the spi module. + * @param[in] data - the pointer to the data for write. + * @param[in] len - write length. + * @return none + */ +void spi_master_write(spi_sel_e spi_sel, unsigned char *data, unsigned int len) +{ + spi_tx_fifo_clr(spi_sel); + spi_tx_cnt(spi_sel, len); + spi_set_transmode(spi_sel, SPI_MODE_WRITE_ONLY); + spi_set_cmd(spi_sel, 0x00);//when cmd disable that will not sent cmd,just trigger spi send . + spi_write(spi_sel, (unsigned char *)data, len); + while (spi_is_busy(spi_sel)); +} + +/** + * @brief This function serves to normal write and read data. + * @param[in] spi_sel - the spi module. + * @param[in] wr_data - the pointer to the data for write. + * @param[in] wr_len - write length. + * @param[in] rd_data - the pointer to the data for read. + * @param[in] rd_len - read length. + * @return none + */ +void spi_master_write_read(spi_sel_e spi_sel, unsigned char *wr_data, unsigned int wr_len, unsigned char *rd_data, unsigned int rd_len) +{ + spi_tx_fifo_clr(spi_sel); + spi_rx_fifo_clr(spi_sel); + spi_tx_cnt(spi_sel, wr_len); + spi_rx_cnt(spi_sel, rd_len); + spi_set_transmode(spi_sel, SPI_MODE_WRITE_READ); + spi_set_cmd(spi_sel, 0x00);//when cmd disable that will not sent cmd,just trigger spi send . + spi_write(spi_sel, (unsigned char *)wr_data, wr_len); + spi_read(spi_sel, (unsigned char *)rd_data, rd_len); + while (spi_is_busy(spi_sel)); +} + +/** + * @brief This function serves to single/dual/quad write to the SPI slave. + * @param[in] spi_sel - the spi module. + * @param[in] cmd - cmd one byte will first write. + * @param[in] addr - the address of slave. + * @param[in] data - pointer to the data need to write. + * @param[in] data_len - length in byte of the data need to write. + * @param[in] wr_mode - write mode.dummy or not dummy. + * @return none + */ +void spi_master_write_plus(spi_sel_e spi_sel, unsigned char cmd, unsigned int addr, unsigned char *data, unsigned int data_len, spi_wr_tans_mode_e wr_mode) +{ + spi_tx_fifo_clr(spi_sel); + if (HSPI_MODULE == spi_sel) + { + hspi_set_address(addr); + } + spi_set_transmode(spi_sel, wr_mode); + + spi_tx_cnt(spi_sel, data_len); + spi_set_cmd(spi_sel, cmd); + spi_write(spi_sel, (unsigned char *)data, data_len); + while (spi_is_busy(spi_sel)); +} + +/** + * @brief This function serves to single/dual/quad read from the SPI slave. + * @param[in] spi_sel - the spi module. + * @param[in] cmd - cmd one byte will first write. + * @param[in] addr - the address of slave. + * @param[in] data - pointer to the data need to read. + * @param[in] data_len - the length of data. + * @param[in] rd_mode - read mode.dummy or not dummy. + * @return none + */ +void spi_master_read_plus(spi_sel_e spi_sel, unsigned char cmd, unsigned int addr, unsigned char *data, unsigned int data_len, spi_rd_tans_mode_e rd_mode) +{ + spi_rx_fifo_clr(spi_sel); + if (HSPI_MODULE == spi_sel) + { + hspi_set_address(addr); + } + spi_set_transmode(spi_sel, rd_mode); + spi_rx_cnt(spi_sel, data_len); + spi_set_cmd(spi_sel, cmd); + spi_read(spi_sel, (unsigned char *)data, data_len); + while (spi_is_busy(spi_sel)); +} + +/** + * @brief This function serves to write address, then read data from the SPI slave. + * @param[in] spi_sel - the spi module. + * @param[in] cmd - cmd one byte will first write. + * @param[in] addrs - pointer to the address of slave. + * @param[in] addr_len - the length of address. + * @param[in] data - the pointer to the data for read. + * @param[in] data_len - read length. + * @param[in] wr_mode - write mode.dummy or not dummy. + * @return none + */ +void spi_master_write_read_plus(spi_sel_e spi_sel, unsigned char cmd, unsigned char *addrs, unsigned int addr_len, unsigned char *data, unsigned int data_len, spi_rd_tans_mode_e wr_mode) +{ + spi_tx_fifo_clr(spi_sel); + spi_rx_fifo_clr(spi_sel); + spi_tx_cnt(spi_sel, addr_len); + spi_rx_cnt(spi_sel, data_len); + spi_set_transmode(spi_sel, wr_mode); + + spi_set_cmd(spi_sel, cmd); + spi_write(spi_sel, (unsigned char *)addrs, addr_len); + spi_read(spi_sel, (unsigned char *)data, data_len); + while (spi_is_busy(spi_sel)); +} + +/** + * @brief This function serves to set tx_dam channel and config dma tx default. + * @param[in] chn - dma channel. + * @return none + */ +void hspi_set_tx_dma_config(dma_chn_e chn) +{ + s_hspi_tx_dma_chn = chn; + dma_config(chn, &hspi_tx_dma_config); + +} + +/** + * @brief This function serves to set rx_dam channel and config dma rx default. + * @param[in] chn - dma channel. + * @return none + */ +void hspi_set_rx_dma_config(dma_chn_e chn) +{ + s_hspi_rx_dma_chn = chn; + dma_config(chn, &hspi_rx_dma_config); +} + +/** + * @brief This function serves to set tx_dam channel and config dma tx default. + * @param[in] chn - dma channel. + * @return none + */ +void pspi_set_tx_dma_config(dma_chn_e chn) +{ + s_pspi_tx_dma_chn = chn; + dma_config(chn, &pspi_tx_dma_config); + +} + +/** + * @brief This function serves to set rx_dam channel and config dma rx default. + * @param[in] chn - dma channel. + * @return none + */ +void pspi_set_rx_dma_config(dma_chn_e chn) +{ + s_pspi_rx_dma_chn = chn; + dma_config(chn, &pspi_rx_dma_config); +} + +/** + * @brief this function set spi dma channel. + * @param[in] spi_dma_chn - dma channel. + * @param[in] src_addr - the address of source. + * @param[in] dst_addr - the address of destination. + * @param[in] len - the length of data. + * */ +void spi_set_dma(dma_chn_e spi_dma_chn, unsigned int src_addr, unsigned int dst_addr, unsigned int len) +{ + dma_set_address(spi_dma_chn, src_addr, dst_addr); + dma_set_size(spi_dma_chn, len, DMA_WORD_WIDTH); + dma_chn_en(spi_dma_chn); +} + +/** + * @brief this function set spi tx dma channel. + * @param[in] spi_sel - the spi module. + * @param[in] src_addr - the address of source. + * @param[in] len - the length of data. + * */ +void spi_set_tx_dma(spi_sel_e spi_sel, unsigned char* src_addr,unsigned int len) +{ + unsigned char tx_dma_chn; + if (HSPI_MODULE == spi_sel) + { + tx_dma_chn = s_hspi_tx_dma_chn; + } + else + { + tx_dma_chn = s_pspi_tx_dma_chn; + } + spi_rx_tx_irq_trig_cnt(spi_sel, 4);//recover trigger level to 4. + spi_tx_cnt(spi_sel,len); + dma_set_address(tx_dma_chn, (unsigned int)convert_ram_addr_cpu2bus(src_addr), reg_spi_data_buf_adr(spi_sel)); + dma_set_size(tx_dma_chn, len, DMA_WORD_WIDTH); + dma_chn_en(tx_dma_chn); +} + + +/** + * @brief this function set spi rx dma channel. + * @param[in] spi_sel - the spi module. + * @param[in] dst_addr - the address of destination. + * @param[in] len - the length of data. + * */ +void spi_set_rx_dma(spi_sel_e spi_sel, unsigned char* dst_addr,unsigned int len) +{ + unsigned char rx_dma_chn; + if (HSPI_MODULE == spi_sel) + { + rx_dma_chn = s_hspi_rx_dma_chn; + } + else + { + rx_dma_chn = s_pspi_rx_dma_chn; + } + spi_rx_tx_irq_trig_cnt(spi_sel, 5);//setting only for fixing the bug that slave receive number of bytes in multiples of 4 will fail. + dma_set_address(rx_dma_chn, reg_spi_data_buf_adr(spi_sel), (unsigned int)convert_ram_addr_cpu2bus(dst_addr)); + dma_set_size(rx_dma_chn, len, DMA_WORD_WIDTH); + dma_chn_en(rx_dma_chn); +} + + +/** + * @brief This function serves to normal write data by dma. + * @param[in] spi_sel - the spi module. + * @param[in] src_addr - the pointer to the data for write. + * @param[in] len - write length. + * @return none + */ +void spi_master_write_dma(spi_sel_e spi_sel, unsigned char *src_addr, unsigned int len) +{ + unsigned char tx_dma_chn; + spi_tx_fifo_clr(spi_sel); + spi_tx_dma_en(spi_sel); + spi_tx_cnt(spi_sel, len); + spi_set_transmode(spi_sel, SPI_MODE_WRITE_ONLY); + if (HSPI_MODULE == spi_sel) + { + tx_dma_chn = s_hspi_tx_dma_chn; + } + else + { + tx_dma_chn = s_pspi_tx_dma_chn; + } + spi_set_dma(tx_dma_chn, (unsigned int)convert_ram_addr_cpu2bus(src_addr), reg_spi_data_buf_adr(spi_sel), len); + spi_set_cmd(spi_sel, 0x00); +} + +/** + * @brief This function serves to normal write cmd and address, then read data by dma. + * @param[in] spi_sel - the spi module. + * @param[in] addr - the pointer to the cmd and address for write. + * @param[in] addr_len - write length. + * @param[in] data - the pointer to the data for read. + * @param[in] data_len - read length. + * @return none + */ +void spi_master_write_read_dma(spi_sel_e spi_sel, unsigned char *addr, unsigned int addr_len, unsigned char *data, unsigned int data_len) +{ + unsigned char tx_dma_chn, rx_dma_chn; + spi_tx_fifo_clr(spi_sel); + spi_rx_fifo_clr(spi_sel); + spi_tx_dma_en(spi_sel); + spi_rx_dma_en(spi_sel); + spi_tx_cnt(spi_sel, addr_len); + spi_rx_cnt(spi_sel, data_len); + spi_set_transmode(spi_sel, SPI_MODE_WRITE_READ); + if (HSPI_MODULE == spi_sel) + { + tx_dma_chn = s_hspi_tx_dma_chn; + rx_dma_chn = s_hspi_rx_dma_chn; + } + else + { + tx_dma_chn = s_pspi_tx_dma_chn; + rx_dma_chn = s_pspi_rx_dma_chn; + } + spi_set_dma(tx_dma_chn, (unsigned int)convert_ram_addr_cpu2bus(addr), reg_spi_data_buf_adr(spi_sel), addr_len); + spi_set_dma(rx_dma_chn, reg_spi_data_buf_adr(spi_sel), (unsigned int)convert_ram_addr_cpu2bus(data), data_len); + spi_set_cmd(spi_sel, 0x00);//when cmd disable that will not sent cmd,just trigger spi send . +} + +/** + * @brief This function serves to single/dual/quad write to the SPI slave by dma. + * @param[in] spi_sel - the spi module. + * @param[in] cmd - cmd one byte will first write. + * @param[in] addr - the address of slave. + * @param[in] data - pointer to the data need to write. + * @param[in] data_len - length in byte of the data need to write. + * @param[in] wr_mode - write mode.dummy or not dummy. + * @return none + */ +void spi_master_write_dma_plus(spi_sel_e spi_sel, unsigned char cmd, unsigned int addr, unsigned char *data, unsigned int data_len, spi_wr_tans_mode_e wr_mode) +{ + unsigned char tx_dma_chn; + spi_tx_fifo_clr(spi_sel); + spi_tx_dma_en(spi_sel); + spi_tx_cnt(spi_sel, data_len); + spi_set_transmode(spi_sel, wr_mode); + if (HSPI_MODULE == spi_sel) + { + tx_dma_chn = s_hspi_tx_dma_chn; + hspi_set_address(addr); + } + else + { + tx_dma_chn = s_pspi_tx_dma_chn; + } + spi_set_dma(tx_dma_chn, (unsigned int)convert_ram_addr_cpu2bus(data), reg_spi_data_buf_adr(spi_sel), data_len); + spi_set_cmd(spi_sel, cmd); +} + +/** + * @brief This function serves to single/dual/quad read from the SPI slave by dma. + * @param[in] spi_sel - the spi module. + * @param[in] cmd - cmd one byte will first write. + * @param[in] addr - the address of slave. + * @param[in] dst_addr - pointer to the buffer that will cache the reading out data. + * @param[in] data_len - length in byte of the data need to read. + * @param[in] rd_mode - read mode.dummy or not dummy. + * @return none + */ +void spi_master_read_dma_plus(spi_sel_e spi_sel, unsigned char cmd, unsigned int addr, unsigned char *dst_addr, unsigned int data_len, spi_rd_tans_mode_e rd_mode) +{ + unsigned char rx_dma_chn; + spi_rx_fifo_clr(spi_sel); + spi_rx_dma_en(spi_sel); + spi_set_transmode(spi_sel, rd_mode); + spi_rx_cnt(spi_sel, data_len); + if (HSPI_MODULE == spi_sel) + { + rx_dma_chn = s_hspi_rx_dma_chn; + hspi_set_address(addr); + } + else + { + rx_dma_chn = s_pspi_rx_dma_chn; + } + spi_set_dma(rx_dma_chn, reg_spi_data_buf_adr(spi_sel), (unsigned int)convert_ram_addr_cpu2bus(dst_addr), data_len); + spi_set_cmd(spi_sel, cmd); +} + +/** + * @brief This function serves to single/dual/quad write address and read from the SPI slave by dma. + * @param[in] spi_sel - the spi module. + * @param[in] cmd - cmd one byte will first write. + * @param[in] addr - the address of slave. + * @param[in] addr_len - the length of address. + * @param[in] rd_data - pointer to the buffer that will cache the reading out data. + * @param[in] rd_len - length in byte of the data need to read. + * @param[in] rd_mode - read mode.dummy or not dummy. + * @return none + */ +void spi_master_write_read_dma_plus(spi_sel_e spi_sel, unsigned char cmd, unsigned char *addr, unsigned int addr_len, unsigned char *dst_addr, unsigned int rd_len, spi_rd_tans_mode_e rd_mode) +{ + unsigned char tx_dma_chn, rx_dma_chn; + spi_tx_fifo_clr(spi_sel); + spi_rx_fifo_clr(spi_sel); + spi_tx_dma_en(spi_sel); + spi_rx_dma_en(spi_sel); + spi_tx_cnt(spi_sel,addr_len); + spi_rx_cnt(spi_sel, rd_len); + spi_set_transmode(spi_sel, rd_mode); + if (HSPI_MODULE == spi_sel) + { + tx_dma_chn = s_hspi_tx_dma_chn; + rx_dma_chn = s_hspi_rx_dma_chn; + } + else + { + tx_dma_chn = s_pspi_tx_dma_chn; + rx_dma_chn = s_pspi_rx_dma_chn; + } + spi_set_dma(tx_dma_chn, (unsigned int)convert_ram_addr_cpu2bus(addr), reg_spi_data_buf_adr(spi_sel), addr_len); + spi_set_dma(rx_dma_chn, reg_spi_data_buf_adr(spi_sel), (unsigned int)convert_ram_addr_cpu2bus(dst_addr), rd_len); + spi_set_cmd(spi_sel, cmd);//when cmd disable that will not sent cmd,just trigger spi send . +} + +/** + * @brief This function serves to single/dual (quad) write to the SPI slave by xip. + * @param[in] cmd - cmd one byte will first write. + * @param[in] addr_offset - offset of xip base address. + * @param[in] data - pointer to the data need to write. + * @param[in] data_len - length in byte of the data need to write. + * @param[in] wr_mode - write mode dummy or not dummy. + * @return none + */ +_attribute_ram_code_sec_noinline_ void hspi_master_write_xip(unsigned char cmd, unsigned int addr_offset, unsigned char *data, unsigned int data_len, spi_wr_tans_mode_e wr_mode) +{ + hspi_xip_write_transmode(wr_mode); + hspi_xip_addr_offset(addr_offset); + hspi_xip_set_wr_cmd(cmd); + for (unsigned int i = 0; i < data_len; i++) + { + write_reg8(reg_hspi_xip_base_adr + i, data[i]); + } +} + +/** + * @brief This function serves to single/dual (quad) read from the SPI slave by xip. + * @param[in] cmd - cmd one byte will first write. + * @param[in] addr_offset - offset of xip base address. + * @param[in] data - pointer to the data need to read. + * @param[in] data_len - length in byte of the data need to read. + * @param[in] rd_mode - read mode.dummy or not dummy. + * @return none + */ +_attribute_ram_code_sec_noinline_ void hspi_master_read_xip(unsigned char cmd, unsigned int addr_offset, unsigned char *data, unsigned int data_len, spi_rd_tans_mode_e rd_mode) +{ + hspi_xip_read_transmode(rd_mode); + hspi_xip_addr_offset(addr_offset); + hspi_xip_set_rd_cmd(cmd); + + for (unsigned int i = 0; i < data_len; i++) + { + data[i] = read_reg8(reg_hspi_xip_base_adr + i); + } +} + +/** + * @brief This function serves to a cmd and one data write to the SPI slave by xip. + * @param[in] cmd - cmd one byte will first write. + * @param[in] addr_offset - offset of xip base address. + * @param[in] data_in - data need to write. + * @param[in] wr_mode - write mode dummy or not dummy. + * @return none + */ +void hspi_master_write_xip_cmd_data(unsigned char cmd, unsigned int addr_offset, unsigned char data_in, spi_wr_tans_mode_e wr_mode) +{ + hspi_xip_write_transmode(wr_mode); + hspi_xip_addr_offset(addr_offset); + hspi_xip_set_wr_cmd(cmd); + write_reg8(reg_hspi_xip_base_adr, data_in); +} diff --git a/b91/b91m_ble_sdk/drivers/B91/spi.h b/b91/b91m_ble_sdk/drivers/B91/spi.h new file mode 100755 index 0000000..cddaec5 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/spi.h @@ -0,0 +1,1288 @@ +/******************************************************************************************************** + * @file spi.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef SPI_H +#define SPI_H + +#include "reg_include/register_b91.h" +#include "gpio.h" +#include "dma.h" +/** @page SPI + * + * Introduction + * =============== + * B91 supports two spi + * + * API Reference + * =============== + * Header File: spi.h + */ + +typedef enum{ + SPI_RXFIFO_OR_INT_EN =BIT(0), + SPI_TXFIFO_UR_INT_EN =BIT(1), + SPI_RXFIFO_INT_EN =BIT(2), + SPI_TXFIFO_INT_EN =BIT(3), + SPI_END_INT_EN =BIT(4), + SPI_SLV_CMD_EN =BIT(5), +}spi_irq_mask; + +typedef enum{ + SPI_RXF_OR_INT =BIT(2), + SPI_TXF_UR_INT =BIT(3), + SPI_RXF_INT =BIT(4), + SPI_TXF_INT =BIT(5), + SPI_END_INT =BIT(6), + SPI_SLV_CMD_INT =BIT(7), +}spi_irq_status_e; + +typedef enum{ + PSPI_MODULE = 0, + HSPI_MODULE = 1 , +}spi_sel_e; + +/** + * @brief Define the work mode. + */ +typedef enum{ + SPI_MODE0 = 0, + SPI_MODE2, + SPI_MODE1, + SPI_MODE3, +} spi_mode_type_e; + +/** + * @brief Define the mode for SPI io mode. + */ +typedef enum{ + SPI_SINGLE_MODE = 0, + SPI_DUAL_MODE = 1 , + HSPI_QUAD_MODE = 2, + SPI_3_LINE_MODE = 3 +} spi_io_mode_e; + +typedef enum{ + SPI_NOMAL = 0, + SPI_3LINE = 3, +} spi_nomal_3line_mode_e; + +typedef enum{ + PSPI_SINGLE = 0, + PSPI_DUAL = 1, + PSPI_3LINE = 3 +} pspi_single_dual_mode_e; + +typedef enum{ + HSPI_SINGLE = 0, + HSPI_DUAL = 1, + HSPI_QUAD = 2, + HSPI_3LINE = 3 +} hspi_single_dual_quad_mode_e; + + +/** + * @brief Define the SPI command & translate mode. + */ +typedef enum{ + SPI_MODE_WRITE_AND_READ = 0,//write and read at the same.must enbale CmdEn + SPI_MODE_WRITE_ONLY,//write + SPI_MODE_READ_ONLY,// read must enbale CmdEn + SPI_MODE_WRITE_READ,//write_ read + SPI_MODE_READ_WRITE,//read_write + SPI_MODE_WRITE_DUMMY_READ,//write_dummy_read + SPI_MODE_READ_DUMMY_WRITE,//read_ dummy_write must enbale CmdEn + SPI_MODE_NONE_DATA,//must enbale CmdEn + SPI_MODE_DUMMY_WRITE,//dummy_write + SPI_MODE_DUMMY_READ,//dummy_read + SPI_MODE_RESERVED, +}spi_tans_mode_e; + +typedef enum{ + SPI_MODE_WR_WRITE_ONLY = 1,//write + SPI_MODE_WR_DUMMY_WRITE = 8,//dummy_write +}spi_wr_tans_mode_e; + +typedef enum{ + SPI_MODE_RD_READ_ONLY = 2,//must enbale CmdEn + SPI_MODE_RD_DUMMY_READ = 9,//dummy_read +}spi_rd_tans_mode_e; + +typedef enum{ + SPI_MODE_WR_RD = 3,//must enbale CmdEn + SPI_MODE_WR_DUMMY_RD = 5,//write_dummy_read +}spi_wr_rd_tans_mode_e; + +typedef struct{ + hspi_single_dual_quad_mode_e hspi_io_mode;//set spi interface mode + unsigned char hspi_dummy_cnt;//set dummy cnt if tans_mode have dummy . + unsigned char hspi_cmd_en;//enable cmd phase + unsigned char hspi_addr_en;//enable address phase + unsigned char hspi_addr_len;//enable address phase + unsigned char hspi_cmd_fmt_en;//if cmd_en enable cmd fmt will follow the interface (dual/quad) + unsigned char hspi_addr_fmt_en;//if addr_en enable addr fmt will follow the interface (dual/quad) +}hspi_config_t; + +typedef struct{ + pspi_single_dual_mode_e pspi_io_mode;//set spi interface mode + unsigned char pspi_dummy_cnt;//set dummy cnt if tans_mode have dummy . + _Bool pspi_cmd_en;//enable cmd phase +}pspi_config_t; + + +typedef enum{ + SPI_SLAVE_WRITE_DATA_CMD = 0x00, + SPI_SLAVE_WRITE_DATA_DUAL_CMD = FLD_SPI_CMD_DATA_DUAL, + SPI_SLAVE_WRITE_ADDR_DUAL_CMD = FLD_SPI_CMD_ADDR_DUAL, + + SPI_SLAVE_WRITE_DATA_DUAL_4CYC_CMD = FLD_SPI_CMD_DATA_DUAL | FLD_SPI_CMD_RD_DUMMY_4CYCLE, + SPI_SLAVE_WRITE_ADDR_DUAL_4CYC_CMD = FLD_SPI_CMD_ADDR_DUAL | FLD_SPI_CMD_RD_DUMMY_4CYCLE, + SPI_SLAVE_WRITE_DATA_AND_ADDR_DUL_4CYC_CMD = FLD_SPI_CMD_ADDR_DUAL | FLD_SPI_CMD_DATA_DUAL | FLD_SPI_CMD_RD_DUMMY_4CYCLE, +}spi_slave_write_cmd_e; + +typedef enum{ + SPI_SLAVE_READ_DATA_CMD = FLD_SPI_CMD_RD_EN, + SPI_SLAVE_READ_DATA_DUAL_CMD = FLD_SPI_CMD_RD_EN | FLD_SPI_CMD_DATA_DUAL, + SPI_SLAVE_READ_ADDR_DUAL_CMD = FLD_SPI_CMD_RD_EN | FLD_SPI_CMD_ADDR_DUAL, + + SPI_SLAVE_READ_DATA_DUAL_4CYC_CMD = FLD_SPI_CMD_RD_EN | FLD_SPI_CMD_DATA_DUAL | FLD_SPI_CMD_RD_DUMMY_4CYCLE, + SPI_SLAVE_READ_ADDR_DUAL_4CYC_CMD = FLD_SPI_CMD_RD_EN | FLD_SPI_CMD_ADDR_DUAL | FLD_SPI_CMD_RD_DUMMY_4CYCLE, + + SPI_SLAVE_READ_DATA_AND_ADDR_DUL_4CYC_CMD = FLD_SPI_CMD_RD_EN | FLD_SPI_CMD_ADDR_DUAL | FLD_SPI_CMD_DATA_DUAL | FLD_SPI_CMD_RD_DUMMY_4CYCLE, + +}spi_slave_read_cmd_e; + +typedef enum{ + SPI_READ_STATUS_SINGLE_CMD = 0x05, + SPI_READ_STATUS_DUAL_CMD = 0x15, + HSPI_READ_STATUS_QUAD_CMD = 0x25, + SPI_READ_DATA_SINGLE_CMD = 0x0B, + SPI_READ_DATA_DUAL_CMD = 0x0C, + HSPI_READ_DATA_QUAD_CMD = 0x0E, + SPI_WRITE_DATA_SINGLE_CMD = 0x51, + SPI_WRITE_DATA_DUAL_CMD = 0x52, + HSPI_WRITE_DATA_QUAD_CMD = 0x54, +}pspi_hspi_cmd_e; +/** + * @brief Define APS1604M-3SQR QSPI PSRAM CMD. + */ +typedef enum{ + PSRAM_READ_CMD = 0x03, + PSRAM_FAST_READ_CMD = 0x0B, + PSRAM_FAST_READ_QUAD_CMD = 0xEB, + + PSRAM_WRITE_CMD = 0x02, + PSRAM_QUAD_WRITE_CMD = 0x38,// + PSRAM_WRAPPED_READ_CMD = 0x8B, + PSRAM_WRAPPED_WRITE_CMD = 0x82, + + PSRAM_MODE_RG_READ_CMD = 0xB5, + PSRAM_MODE_RG_WRITE_CMD = 0xB1, + + PSRAM_ENTER_QUAD_MODE_CMD = 0x35, + PSRAM_EXIT_QUAD_MODE_CMD = 0xF5, + + PSRAM_REST_ENABLE_CMD = 0x66, + PSRAM_REST_CMD = 0x99, + PSRAM_BURST_LENGTH_TOGGLE_CMD = 0xC0, + PSRAM_READ_ID_CMD = 0x95, + +}spi_xip_cmd_e; + +/** + * @brief Define panel 2data_lane_mode + */ +typedef enum{ + HSPI_2DATA_LANE_CLOSE = 0x00, + HSPI_2DATA_LANE_RGB565 = 0x01, + HSPI_2DATA_LANE_RGB666 = 0x03, + HSPI_2DATA_LANE_RGB888 = 0x07, +}hspi_panel_2data_lane_mode_e; + +/** + * @brief Define the SPI io. + */ +typedef enum{ + HSPI_CLK_PB4 = GPIO_PB4, + HSPI_CLK_PA2 = GPIO_PA2, +}hspi_clk_pin_def_e; + +typedef enum{ + HSPI_CSN_PB6 = GPIO_PB6, + HSPI_CSN_PA1 = GPIO_PA1, +}hspi_csn_pin_def_e; + +typedef enum{ + HSPI_MOSI_IO0_PB3 = GPIO_PB3, + HSPI_MOSI_IO0_PA4 = GPIO_PA4, +}hspi_mosi_io0_pin_def_e; + +typedef enum{ + HSPI_MISO_IO1_PB2 = GPIO_PB2, + HSPI_MISO_IO1_PA3 = GPIO_PA3, +}hspi_miso_io1_pin_def_e; + +typedef enum{ + HSPI_WP_IO2_PB1 = GPIO_PB1, +}hspi_wp_io2_pin_def_e; + +typedef enum{ + HSPI_HOLD_IO3_PB0 = GPIO_PB0, +}hspi_hold_io3_pin_def_e; + +typedef enum{ + HSPI_CLK_PB4_PIN = GPIO_PB4, + HSPI_CLK_PA2_PIN = GPIO_PA2, + + HSPI_CSN_PB6_PIN = GPIO_PB6, + HSPI_CSN_PA1_PIN = GPIO_PA1, + + HSPI_MOSI_IO0_PB3_PIN = GPIO_PB3, + HSPI_MOSI_IO0_PA4_PIN = GPIO_PA4, + + HSPI_MISO_IO1_PB2_PIN = GPIO_PB2, + HSPI_MISO_IO1_PA3_PIN = GPIO_PA3, + + HSPI_WP_IO2_PB1_PIN = GPIO_PB1, + HSPI_HOLD_IO3_PB0_PIN = GPIO_PB0, + HSPI_NONE_PIN = 0xfff, +}hspi_pin_def_e; + +typedef struct{ + hspi_clk_pin_def_e hspi_clk_pin; + hspi_csn_pin_def_e hspi_csn_pin; + hspi_mosi_io0_pin_def_e hspi_mosi_io0_pin; + hspi_miso_io1_pin_def_e hspi_miso_io1_pin; + hspi_wp_io2_pin_def_e hspi_wp_io2_pin; + hspi_hold_io3_pin_def_e hspi_hold_io3_pin; +}hspi_pin_config_t; + + +typedef enum{ + PSPI_CLK_PC5 = GPIO_PC5, + PSPI_CLK_PB5 = GPIO_PB5, + PSPI_CLK_PD1 = GPIO_PD1, +}pspi_clk_pin_def_e; + +typedef enum{ + PSPI_CSN_PC4 = GPIO_PC4, + PSPI_CSN_PC0 = GPIO_PC0, + PSPI_CSN_PD0 = GPIO_PD0, +}pspi_csn_pin_def_e; + +typedef enum{ + PSPI_MOSI_IO0_PC7 = GPIO_PC7, + PSPI_MOSI_IO0_PB7 = GPIO_PB7, + PSPI_MOSI_IO0_PD3 = GPIO_PD3, +}pspi_mosi_io0_pin_def_e; + +typedef enum{ + PSPI_MISO_IO1_PC6 = GPIO_PC6, + PSPI_MISO_IO1_PB6 = GPIO_PB6, + PSPI_MISO_IO1_PD2 = GPIO_PD2, +}pspi_miso_io1_pin_def_e; + +typedef enum{ + PSPI_CLK_PC5_PIN = GPIO_PC5, + PSPI_CLK_PB5_PIN = GPIO_PB5, + PSPI_CLK_PD1_PIN = GPIO_PD1, + + PSPI_CSN_PC4_PIN = GPIO_PC4, + PSPI_CSN_PC0_PIN = GPIO_PC0, + PSPI_CSN_PD0_PIN = GPIO_PD0, + + PSPI_MOSI_IO0_PC7_PIN = GPIO_PC7, + PSPI_MOSI_IO0_PB7_PIN = GPIO_PB7, + PSPI_MOSI_IO0_PD3_PIN = GPIO_PD3, + + PSPI_MISO_IO1_PC6_PIN = GPIO_PC6, + PSPI_MISO_IO1_PB6_PIN = GPIO_PB6, + PSPI_MISO_IO1_PD2_PIN = GPIO_PD2, + PSPI_NONE_PIN = 0xfff, +}pspi_pin_def_e; + +typedef struct{ + pspi_clk_pin_def_e pspi_clk_pin; + pspi_csn_pin_def_e pspi_csn_pin; + pspi_mosi_io0_pin_def_e pspi_mosi_io0_pin; + pspi_miso_io1_pin_def_e pspi_miso_io1_pin; +}pspi_pin_config_t; + + +/** + * @brief This function reset HSPI module. + * @return none + */ +static inline void hspi_reset(void) +{ + reg_rst0 &= (~FLD_RST0_HSPI); + reg_rst0 |= FLD_RST0_HSPI; +} +/** + * @brief This function reset PSPI module. + * @return none + */ +static inline void pspi_reset(void) +{ + reg_rst1 &= (~FLD_RST1_PSPI); + reg_rst1 |= FLD_RST1_PSPI; +} + +/** + * @brief This function get tx_fifo number. + * @param[in] spi_sel - the spi module. + * @return ntx_fifo - number that wait to be sent. + */ +static inline unsigned char spi_get_txfifo_num(spi_sel_e spi_sel) +{ + return (reg_spi_fifo_num(spi_sel) & FLD_SPI_TXF_NUM) >> 4; +} + +/** + * @brief This function get rx_fifo number. + * @param[in] spi_sel - the spi module. + * @return rx_fifo - num that have been received. + */ +static inline unsigned char spi_get_rxfifo_num(spi_sel_e spi_sel) +{ + return reg_spi_fifo_num(spi_sel) & FLD_SPI_RXF_NUM; +} + +/** + * @brief This function set SPI rx_cnt. + * @param[in] spi_sel - the spi module. + * @param[in] cnt - rx amount of data. + * @return none + */ +static inline void spi_rx_cnt(spi_sel_e spi_sel, unsigned int cnt) +{ + reg_spi_rx_cnt2(spi_sel) = ((cnt - 1) >> 16) & 0xff; + reg_spi_rx_cnt1(spi_sel) = ((cnt - 1) >> 8) & 0xff; + reg_spi_rx_cnt0(spi_sel) = (cnt - 1) & 0xff; + +} + +/** + * @brief This function set SPI tx_cnt. + * @param[in] spi_sel - the spi module. + * @param[in] cnt - tx amount of data. + * @return none + */ +static inline void spi_tx_cnt(spi_sel_e spi_sel, unsigned int cnt) +{ + reg_spi_tx_cnt2(spi_sel) = ((cnt - 1) >> 16) & 0xff; + reg_spi_tx_cnt1(spi_sel) = ((cnt - 1) >> 8) & 0xff; + reg_spi_tx_cnt0(spi_sel) = (cnt - 1) & 0xff; + +} + +/** + * @brief This function clear tx_fifo. + * @param[in] spi_sel - the spi module. + * @return none + */ +static inline void spi_tx_fifo_clr(spi_sel_e spi_sel) +{ + BM_SET(reg_spi_fifo_state(spi_sel), FLD_SPI_TXF_CLR); +} + +/** + * @brief This function clear rx_fifo. + * @param[in] spi_sel - the spi module. + * @return none + */ +static inline void spi_rx_fifo_clr(spi_sel_e spi_sel) +{ + BM_SET(reg_spi_fifo_state(spi_sel), FLD_SPI_RXF_CLR); +} + +/** + * @brief This function set hspi command content. + * @param[in] spi_sel - the spi module. + * @param[in] cmd - command content. + * @return none + */ +static inline void spi_set_cmd(spi_sel_e spi_sel, unsigned char cmd) +{ + reg_spi_trans1(spi_sel) = cmd; +} + +/** + * @brief This function servers to enable cmd which will sent a byte cmd. + * @param[in] spi_sel - the spi module. + * @return none + */ +static inline void spi_cmd_en(spi_sel_e spi_sel) +{ + BM_SET( reg_spi_mode2(spi_sel), FLD_SPI_CMD_EN); +} + +/** + * @brief This function servers to disable cmd which will not sent cmd. + * @param[in] spi_sel - the spi module. + * @return none + */ +static inline void spi_cmd_dis(spi_sel_e spi_sel) +{ + + BM_CLR(reg_spi_mode2(spi_sel), FLD_SPI_CMD_EN); +} + +/** + * @brief This function servers enable cmd format,the format of cmd phase is the same as the data phase(Dual/Quad). + * @return none + */ +static inline void hspi_cmd_fmt_en() +{ + BM_SET( reg_spi_mode2(HSPI_MODULE), FLD_HSPI_CMD_FMT); +} + +/** + * @brief This function servers disable cmd format. + * @return none + */ +static inline void hspi_cmd_fmt_dis() +{ + BM_CLR(reg_spi_mode2(HSPI_MODULE), FLD_HSPI_CMD_FMT); +} + +/** + * @brief This function servers to enable hspi quad mode. + * @return none + */ +static inline void hspi_quad_mode_en() +{ + BM_SET(reg_spi_mode2(HSPI_MODULE), FLD_HSPI_QUAD); +} + +/** + * @brief This function servers to disable hspi quad mode. + * @param[in] spi_sel - the spi module. + * @return none + */ +static inline void hspi_quad_mode_dis(spi_sel_e spi_sel) +{ + BM_CLR(reg_spi_mode2(spi_sel), FLD_HSPI_QUAD); +} + +/** + * @brief This function servers to enable hspi dual mode. + * @param[in] spi_sel - the spi module. + * @return none + */ +static inline void spi_dual_mode_en(spi_sel_e spi_sel) +{ + BM_SET(reg_spi_mode0(spi_sel), FLD_SPI_DUAL); +} + +/** + * @brief This function servers to disable hspi dual mode. + * @param[in] spi_sel - the spi module. + * @return none + */ +static inline void spi_dual_mode_dis(spi_sel_e spi_sel) +{ + BM_CLR(reg_spi_mode0(spi_sel), FLD_SPI_DUAL); +} + +/** + * @brief This function servers to enable hspi 3line mode. + * @param[in] spi_sel - the spi module. + * @return none + */ +static inline void spi_3line_mode_en(spi_sel_e spi_sel) +{ + BM_SET(reg_spi_mode0(spi_sel), FLD_SPI_3LINE); +} + +/** + * @brief This function servers to disable hspi 3line mode.. + * @param[in] spi_sel - the spi module. + * @return none + */ +static inline void spi_3line_mode_dis(spi_sel_e spi_sel) +{ + BM_CLR(reg_spi_mode0(spi_sel), FLD_SPI_3LINE); +} + +/** + * @brief This function to enable address format.the format of addr phase is the same as the data phase(Dual/Quad). + * @return none + */ +static inline void hspi_addr_fmt_en(void) +{ + BM_SET(reg_hspi_xip_ctrl, FLD_HSPI_ADDR_FMT); + +} + +/** + * @brief This function to disable address format. + * @return none + */ +static inline void hspi_addr_fmt_dis(void) +{ + BM_CLR( reg_hspi_xip_ctrl, FLD_HSPI_ADDR_FMT); + +} + +/** + * @brief This function to determine whether the bus is busy. + * @param[in] spi_sel - the spi module. + * @return 1:Indicates that the bus is busy. 0:Indicates that the bus is free. + */ +static inline _Bool spi_is_busy(spi_sel_e spi_sel) +{ + return reg_spi_status(spi_sel) & FLD_HSPI_BUSY; + +} + +/** + * @brief This function enable tx dma. + * @param[in] spi_sel - the spi module. + * @return none + */ +static inline void spi_tx_dma_en(spi_sel_e spi_sel) +{ + BM_SET(reg_spi_trans2(spi_sel), FLD_SPI_TX_DMA_EN); +} + +/** + * @brief This function disable tx dma. + * @param[in] spi_sel - the spi module. + * @return none + */ +static inline void spi_tx_dma_dis(spi_sel_e spi_sel) +{ + BM_CLR(reg_spi_trans2(spi_sel), FLD_SPI_TX_DMA_EN); +} + +/** + * @brief This function enable rx dma. + * @param[in] spi_sel - the spi module. + * @return none + */ +static inline void spi_rx_dma_en(spi_sel_e spi_sel) +{ + BM_SET(reg_spi_trans2(spi_sel), FLD_SPI_RX_DMA_EN); +} + +/** + * @brief This function disable rx dma. + * @param[in] spi_sel - the spi module. + * @return none + */ +static inline void spi_rx_dma_dis(spi_sel_e spi_sel) +{ + BM_CLR(reg_spi_trans2(spi_sel), FLD_SPI_RX_DMA_EN); +} + +/** + * @brief This function set xip write command content. + * @param[in] wr_cmd - write command content. + * @return none + */ +static inline void hspi_xip_set_wr_cmd(unsigned char wr_cmd) +{ + reg_hspi_xip_wr_cmd = wr_cmd; +} + +/** + * @brief This function set xip read command content. + * @param[in] rd_cmd - read command content. + * @return none + */ +static inline void hspi_xip_set_rd_cmd(unsigned char rd_cmd) +{ + + reg_hspi_xip_rd_cmd = rd_cmd; +} + +/** + * @brief This function set xip address offset. + * @param[in] addr_offset - the offset of data. + * @return none + */ +static inline void hspi_xip_addr_offset(unsigned int addr_offset) +{ + reg_hspi_xip_addr_offset0 = addr_offset & 0xff; + reg_hspi_xip_addr_offset1 = (addr_offset >> 8) & 0xff; + reg_hspi_xip_addr_offset2 = (addr_offset >> 16) & 0xff; + reg_hspi_xip_addr_offset3 = (addr_offset >> 24) & 0xff; +} + +/** + * @brief This function servers to set xip read transfer mode. + * @param[in] rd_mode - read mode in enum hspi_tans_mode_e. + * @return none + */ +static inline void hspi_xip_read_transmode(unsigned char rd_mode) +{ + reg_hspi_xip_trans_mode &= (~FLD_HSPI_XIP_RD_TRANS_MODE); + reg_hspi_xip_trans_mode |= (rd_mode & 0xf) << 4; +} + +/** + * @brief This function servers to set xip write transfer mode. + * @param[in] wr_mode - write mode in enum hspi_tans_mode_e. + * @return none + */ +static inline void hspi_xip_write_transmode(unsigned char wr_mode) +{ + reg_hspi_xip_trans_mode &= (~FLD_HSPI_XIP_WR_TRANS_MODE); + reg_hspi_xip_trans_mode |= wr_mode & FLD_HSPI_XIP_WR_TRANS_MODE; +} + +/** + * @brief This function enable address phase. + * @return none + */ +static inline void hspi_addr_en(void) +{ + BM_SET(reg_hspi_xip_ctrl, FLD_HSPI_ADDR_EN); +} + +/** + * @brief This function disable address phase. + * @return none + */ +static inline void hspi_addr_dis(void) +{ + BM_CLR(reg_hspi_xip_ctrl, FLD_HSPI_ADDR_EN); +} + +/** + * @brief This function servers to set hspi address length. + * @param[in] len - 2'b00:1bye 2'b01:2bytes 2'b10:3bytes 2'b11:4bytes + * @return none + */ +static inline void hspi_set_addr_len(unsigned char len) +{ + reg_hspi_xip_ctrl |= ((len - 1) & 0x3) << 2; +} + +/** + * @brief This function servers to enable xip sequential mode. + * @return none + */ +static inline void hspi_xip_seq_mode_en(void) +{ + BM_SET(reg_hspi_xip_ctrl, FLD_HSPI_XIP_MODE); +} + +/** + * @brief This function servers to disable xip sequential mode. + * @return none + */ +static inline void hspi_xip_seq_mode_dis(void) +{ + BM_CLR(reg_hspi_xip_ctrl, FLD_HSPI_XIP_MODE); +} + +/** + * @brief This function servers to enable xip. + * @return none + */ +static inline void hspi_xip_en(void) +{ + BM_SET(reg_hspi_xip_ctrl, FLD_HSPI_XIP_ENABLE); +} + +/** + * @brief This function servers to disable xip. + * @return none + */ +static inline void hspi_xip_dis(void) +{ + BM_CLR(reg_hspi_xip_ctrl, FLD_HSPI_XIP_ENABLE); +} + +/** + * @brief This function servers to stop xip. + * @return none + */ +static inline void hspi_xip_stop(void) +{ + BM_SET(reg_hspi_xip_ctrl, FLD_HSPI_XIP_STOP); +} + +/** + * @brief This function servers to enable xip timeout that set hight level. + * @return none + */ +static inline void hspi_xip_timeout_mode_en(void) +{ + BM_SET(reg_hspi_xip_ctrl, FLD_HSPI_XIP_TIMEOUT_MODE); +} + +/** + * @brief This function servers to disable xip timeout. + * @return none + */ +static inline void hspi_xip_timeout_mode_dis(void) +{ + BM_CLR(reg_hspi_xip_ctrl, FLD_HSPI_XIP_TIMEOUT_MODE); +} + +/** + * @brief This function servers to set xip timeout cnt,when two data frame intervals exceed spi_clock_out_period*timeout_cnt,cs will set high level. + * @param[in] cnt - xip timeout cnt. + * @return none + */ +static inline void hspi_xip_timeout_cnt(unsigned char cnt) +{ + reg_hspi_xip_timeout_cnt = cnt & 0xff; +} + +/** + * @brief This function servers to set page_size. + * @param[in] page_size_i - page boundary 2^page_size_i bytes. + * @return none + */ +static inline void hspi_xip_page_size(unsigned char page_size_i) +{ + reg_hspi_page_size = page_size_i; +} + +/** + * @brief This function servers to reply master slave is ready .When slave is ready, slave ready reply a byte data:0x5a. indicating that slave is ready for data transmission. + * @param[in] spi_sel - the spi module. + * @return none + */ +static inline void spi_slave_ready_en(spi_sel_e spi_sel) +{ + BM_SET(reg_spi_status(spi_sel), FLD_HSPI_SLAVE_READY); +} + +/** + * @brief This function servers to reply master slave is not ready.slave reply a byte data: 0x00.indicating that slave is not ready for data transmission. + * @param[in] spi_sel - the spi module. + * @return none + */ +static inline void spi_slave_ready_dis(spi_sel_e spi_sel) +{ + BM_CLR(reg_spi_status(spi_sel), FLD_HSPI_SLAVE_READY); +} + +/** + * @brief This function servers to read cmd from master for slave. + * @param[in] spi_sel - the spi module. + * @return cmd transferd by master. + */ +static inline unsigned char spi_slave_get_cmd(spi_sel_e spi_sel) +{ + return reg_spi_trans1(spi_sel); +} + +/** + * @brief The function of this API is to set the number of bytes to triggered the receive and transmit interrupt. + * Its default value is 4. recommend setting 4. + * @param[in] spi_sel - the spi module. + * @param[in] cnt - the interrupt trigger level. + * @return none + */ +static inline void spi_rx_tx_irq_trig_cnt(spi_sel_e spi_sel, unsigned char cnt) +{ + BM_CLR(reg_spi_status(spi_sel), FLD_HSPI_FIFO_THRES); + reg_spi_status(spi_sel) |= ((cnt & 7) << 4); +} + +/** + * @brief This function servers to get irq status. + * @param[in] spi_sel - the spi module. + * @param[in] status - the irq status. + * @return - the value of status is be set. + */ +static inline unsigned char spi_get_irq_status(spi_sel_e spi_sel,spi_irq_status_e status ) +{ + return reg_spi_irq_state(spi_sel)&status; +} + +/** + * @brief This function servers to clear irq status. + * @param[in] spi_sel - the spi module. + * @param[in] status - the irq status. + * @return none. + */ +static inline void spi_clr_irq_status(spi_sel_e spi_sel, spi_irq_status_e status) +{ + reg_spi_irq_state(spi_sel) = status; +} + +/** + * @brief This function servers to set irq mask. + * @param[in] spi_sel - the spi module. + * @param[in] mask - the irq mask. + * @return cmd - transferd by master. + */ +static inline void spi_set_irq_mask(spi_sel_e spi_sel, spi_irq_mask mask) +{ + BM_SET(reg_spi_trans2(spi_sel), mask); +} + +/** + * @brief This function servers to clear irq mask. + * @param[in] spi_sel - the spi module. + * @param[in] mask - the irq mask. + * @return cmd - transferd by master. + */ +static inline void spi_clr_irq_mask(spi_sel_e spi_sel, spi_irq_mask mask) +{ + BM_CLR(reg_spi_trans2(spi_sel), mask); +} + +/** + * @brief This function enable 3line_dcx module which is use for panel(lcd oled..). + * @return none + */ +static inline void hspi_3line_dcx_en(void) +{ + BM_SET(reg_hspi_panel_ctrl, FLD_HSPI_PANEL_3LINE_DCX_EN); +} + +/** + * @brief This function disable 3line_dcx module which is use for panel(lcd oled..). + * @return none + */ +static inline void hspi_3line_dcx_dis(void) +{ + BM_CLR(reg_hspi_panel_ctrl, FLD_HSPI_PANEL_3LINE_DCX_EN); +} + +/** + * @brief This function set 3line_dcx translate data. + * @return none + */ +static inline void hspi_set_3line_dcx_data(void) +{ + BM_SET(reg_hspi_panel_ctrl, FLD_HSPI_PANEL_3LINE_DCX); +} + +/** + * @brief This function set 3line_dcx translate command. + * @return none + */ +static inline void hspi_set_3line_dcx_cmd(void) +{ + BM_CLR(reg_hspi_panel_ctrl, FLD_HSPI_PANEL_3LINE_DCX); +} + +/** + * @brief This function set 2data_lane mode for panel. + * @return none + */ +static inline void hspi_set_panel_2data_lane_mode(hspi_panel_2data_lane_mode_e mode) +{ + reg_hspi_panel_ctrl &= (~FLD_HSPI_PANEL_2DATA_LANE); + reg_hspi_panel_ctrl |= (mode & 0xf) << 2; +} + +/** + * @brief This function selects pin for hspi master or slave. + * @return none + */ +void spi_slave_set_pin(void); +/** + * @brief This function configures hspi pin. + * @param[in] config - the pointer of pin config struct. + * @return none + */ +void hspi_set_pin(hspi_pin_config_t *config); + +/** + * @brief This function configures pspi pin. + * @param[in] config - the pointer of pin config struct. + * @return none + */ +void pspi_set_pin(pspi_pin_config_t *config); + +/** + * @brief This function enable hspi csn pin. + * @param[in] pin - the csn pin. + * @return none + */ +void hspi_cs_pin_en(hspi_csn_pin_def_e pin); + +/** + * @brief This function disable hspi csn pin. + * @param[in] pin - the csn pin. + * @return none + */ +void hspi_cs_pin_dis(hspi_csn_pin_def_e pin); + +/** + * @brief This function change hspi csn pin. + * @param[in] next_csn_pin - the next csn pin. + * @return next_csn_pin - the next csn pin. + */ +hspi_csn_pin_def_e hspi_change_csn_pin(hspi_csn_pin_def_e next_csn_pin); +/** + * @brief This function enable pspi csn pin. + * @param[in] pin - the csn pin. + * @return none + */ +void pspi_cs_pin_en(pspi_csn_pin_def_e pin); + +/** + * @brief This function disable pspi csn pin. + * @param[in] pin - the csn pin. + * @return none + */ +void pspi_cs_pin_dis(pspi_csn_pin_def_e pin); + +/** + * @brief This function change pspi csn pin. + * @param[in] next_csn_pin - the next csn pin. + * @return next_csn_pin - the next csn pin. + */ +pspi_csn_pin_def_e pspi_change_csn_pin(pspi_csn_pin_def_e next_csn_pin); +/** + * @brief This function configures the clock and working mode for SPI interface. + * @param[in] spi_sel - the spi module. + * @param[in] div_clock - the division factor for SPI module. + * spi_clock_out = ahb_clock / ((div_clock+1)*2) + * @param[in] mode - the selected working mode of SPI module. + * bit5:CPHA-Clock Polarity ; bit6:CPOL:CPHA-Clock Phase + * MODE0: CPHA = 0, CPOL = 0; + * MODE1: CPHA = 0, CPOL = 1; + * MODE2: CPHA = 1, CPOL = 0; + * MODE3: CPHA = 1, CPOL = 1; + * @return none + */ +void spi_master_init(spi_sel_e spi_sel, unsigned char div_clock, spi_mode_type_e mode); + +/** + * @brief This function configures the clock and working mode for SPI interface. + * @param[in] spi_sel - the spi module. + * @param[in] mode - the selected working mode of SPI module. + * bit5:CPHA-Clock Polarity ; bit6:CPOL:CPHA-Clock Phase + * MODE0: CPHA = 0, CPOL = 0; + * MODE1: CPHA = 0, CPOL = 1; + * MODE2: CPHA = 1, CPOL = 0; + * MODE3: CPHA = 1, CPOL = 1; + * @return none + * @note spi_clock_in (spi_slave_clock frequency)/3 + */ +void spi_slave_init(spi_sel_e spi_sel, spi_mode_type_e mode); + +/** + * @brief This function servers to set dummy cycle cnt. + * @param[in] spi_sel - the spi module. + * @param[in] dummy_cnt - the cnt of dummy clock. + * @return none + */ +void spi_set_dummy_cnt(spi_sel_e spi_sel, unsigned char dummy_cnt); + +/** + * @brief This function servers to set slave address hspi only. + * @param[in] addr - address of slave. + * @return none + */ +void hspi_set_address(unsigned int addr); + +/** + * @brief This function servers to set spi transfer mode. + * @param[in] spi_sel - the spi module. + * @param[in] mode - transfer mode. + * @return none + */ +void spi_set_transmode(spi_sel_e spi_sel, spi_tans_mode_e mode); + + +/** + * @brief This function servers to set normal mode. + * @param[in] spi_sel - the spi module. + * @return none + */ +void spi_set_normal_mode(spi_sel_e spi_sel); + +/** + * @brief This function servers to set dual mode. + * @param[in] spi_sel - the spi module. + * @return none + */ +void spi_set_dual_mode(spi_sel_e spi_sel); + +/** + * @brief This function servers to set quad mode. + * @return none + */ +void hspi_set_quad_mode(); + +/** + * @brief This function servers to set 3line mode. + * @param[in] spi_sel - the spi module. + * @return none + */ +void spi_set_3line_mode(spi_sel_e spi_sel); + +/** + * @brief This function servers to set hspi io mode. + * @param[in] spi_sel - the spi module. + * @param[in] mode - single/dual/quad /3line. + * @return none + */ +void spi_set_io_mode(spi_sel_e spi_sel, spi_io_mode_e mode); + +/** + * @brief This function servers to config normal mode. + * @param[in] spi_sel - the spi module. + * @param[in] mode - nomal ,mode 3line. + * @return none + */ +void spi_master_config(spi_sel_e spi_sel, spi_nomal_3line_mode_e mode); + +/** + * @brief This function servers to config hspi special mode. + * @param[in] config - the pointer of pin special config struct. + * @return none + */ +void hspi_master_config_plus(hspi_config_t *config); + +/** + * @brief This function servers to config pspi special mode. + * @param[in] config - the pointer of pin special config struct. + * @return none + */ +void pspi_master_config_plus(pspi_config_t *config); + +/** + * @brief This function servers to write hspi fifo. + * @param[in] spi_sel - the spi module. + * @param[in] data - the pointer to the data for write. + * @param[in] len - write length. + * @return none + */ +void spi_write(spi_sel_e spi_sel, unsigned char *data, unsigned int len); + +/** + * @brief This function servers to read hspi fifo. + * @param[in] spi_sel - the spi module. + * @param[in] data - the pointer to the data for read. + * @param[in] len - write length. + * @return none + */ +void spi_read(spi_sel_e spi_sel, unsigned char *data, unsigned int len); + +/** + * @brief This function serves to normal write data in normal. + * @param[in] spi_sel - the spi module. + * @param[in] data - the pointer to the data for write. + * @param[in] len - write length. + * @return none + */ +void spi_master_write(spi_sel_e spi_sel, unsigned char *data, unsigned int len); + +/** + * @brief This function serves to normal write and read data. + * @param[in] spi_sel - the spi module. + * @param[in] wr_data - the pointer to the data for write. + * @param[in] wr_len - write length. + * @param[in] rd_data - the pointer to the data for read. + * @param[in] rd_len - read length. + * @return none + */ +void spi_master_write_read(spi_sel_e spi_sel, unsigned char *wr_data, unsigned int wr_len, unsigned char *rd_data, unsigned int rd_len); + +/** + * @brief This function serves to single/dual/quad write to the SPI slave. + * @param[in] spi_sel - the spi module. + * @param[in] cmd - cmd one byte will first write. + * @param[in] addr - the address of slave. + * @param[in] data - pointer to the data need to write. + * @param[in] data_len - length in byte of the data need to write. + * @param[in] wr_mode - write mode.dummy or not dummy. + * @return none + */ +void spi_master_write_plus(spi_sel_e spi_sel, unsigned char cmd, unsigned int addr, unsigned char *data, unsigned int data_len, spi_wr_tans_mode_e wr_mode); + +/** + * @brief This function serves to single/dual/quad read from the SPI slave. + * @param[in] spi_sel - the spi module. + * @param[in] cmd - cmd one byte will first write. + * @param[in] addr - the address of slave. + * @param[in] data - pointer to the data need to read. + * @param[in] data_len - the length of data. + * @param[in] rd_mode - read mode.dummy or not dummy. + * @return none + */ +void spi_master_read_plus(spi_sel_e spi_sel, unsigned char cmd, unsigned int addr, unsigned char *data, unsigned int data_len, spi_rd_tans_mode_e rd_mode); + +/** + * @brief This function serves to write address, then read data from the SPI slave. + * @param[in] spi_sel - the spi module. + * @param[in] cmd - cmd one byte will first write. + * @param[in] addrs - pointer to the address of slave. + * @param[in] addr_len - the length of address. + * @param[in] data - the pointer to the data for read. + * @param[in] data_len - read length. + * @param[in] wr_mode - write mode.dummy or not dummy. + * @return none + */ +void spi_master_write_read_plus(spi_sel_e spi_sel, unsigned char cmd, unsigned char *addrs, unsigned int addr_len, unsigned char *data, unsigned int data_len, spi_rd_tans_mode_e wr_mode); + +/** + * @brief This function serves to set tx_dam channel and config dma tx default. + * @param[in] chn - dma channel. + * @return none + */ +void hspi_set_tx_dma_config(dma_chn_e chn); + +/** + * @brief This function serves to set rx_dam channel and config dma rx default. + * @param[in] chn - dma channel. + * @return none + */ +void hspi_set_rx_dma_config(dma_chn_e chn); + +/** + * @brief This function serves to set tx_dam channel and config dma tx default. + * @param[in] chn - dma channel. + * @return none + */ +void pspi_set_tx_dma_config(dma_chn_e chn); + +/** + * @brief This function serves to set rx_dam channel and config dma rx default. + * @param[in] chn - dma channel. + * @return none + */ +void pspi_set_rx_dma_config(dma_chn_e chn); + +/** + * @brief this function set spi dma channel. + * @param[in] spi_dma_chn - dma channel. + * @param[in] src_addr - the address of source. + * @param[in] dst_addr - the address of destination. + * @param[in] len - the length of data. + * */ +void spi_set_dma(dma_chn_e spi_dma_chn, unsigned int src_addr, unsigned int dst_addr, unsigned int len); + + + + +/** + * @brief this function set spi tx dma channel. + * @param[in] spi_sel - the spi module. + * @param[in] src_addr - the address of source. + * @param[in] len - the length of data. + * */ +_attribute_ram_code_sec_ void spi_set_tx_dma(spi_sel_e spi_sel, unsigned char* src_addr,unsigned int len); + + +/** + * @brief this function set spi rx dma channel. + * @param[in] spi_sel - the spi module. + * @param[in] dst_addr - the address of destination. + * @param[in] len - the length of data. + * */ +_attribute_ram_code_sec_ void spi_set_rx_dma(spi_sel_e spi_sel, unsigned char* dst_addr,unsigned int len); +/** + * @brief This function serves to normal write data by dma. + * @param[in] spi_sel - the spi module. + * @param[in] src_addr - the pointer to the data for write. + * @param[in] len - write length. + * @return none + */ +void spi_master_write_dma(spi_sel_e spi_sel, unsigned char *src_addr, unsigned int len); + +/** + * @brief This function serves to normal write cmd and address, then read data by dma. + * @param[in] spi_sel - the spi module. + * @param[in] addr - the pointer to the cmd and address for write. + * @param[in] addr_len - write length. + * @param[in] data - the pointer to the data for read. + * @param[in] data_len - read length. + * @return none + */ +void spi_master_write_read_dma(spi_sel_e spi_sel, unsigned char *addr, unsigned int addr_len, unsigned char *data, unsigned int data_len); + +/** + * @brief This function serves to single/dual/quad write to the SPI slave by dma. + * @param[in] spi_sel - the spi module. + * @param[in] cmd - cmd one byte will first write. + * @param[in] addr - the address of slave. + * @param[in] data - pointer to the data need to write. + * @param[in] data_len - length in byte of the data need to write. + * @param[in] wr_mode - write mode.dummy or not dummy. + * @return none + */ +void spi_master_write_dma_plus(spi_sel_e spi_sel, unsigned char cmd, unsigned int addr, unsigned char *data, unsigned int data_len, spi_wr_tans_mode_e wr_mode); + +/** + * @brief This function serves to single/dual/quad read from the SPI slave by dma. + * @param[in] spi_sel - the spi module. + * @param[in] cmd - cmd one byte will first write. + * @param[in] addr - the address of slave. + * @param[in] dst_addr - pointer to the buffer that will cache the reading out data. + * @param[in] data_len - length in byte of the data need to read. + * @param[in] rd_mode - read mode.dummy or not dummy. + * @return none + */ +void spi_master_read_dma_plus(spi_sel_e spi_sel, unsigned char cmd, unsigned int addr, unsigned char *dst_addr, unsigned int data_len, spi_rd_tans_mode_e rd_mode); + +/** + * @brief This function serves to single/dual/quad write address and read from the SPI slave by dma. + * @param[in] spi_sel - the spi module. + * @param[in] cmd - cmd one byte will first write. + * @param[in] addr - the address of slave. + * @param[in] addr_len - the length of address. + * @param[in] rd_data - pointer to the buffer that will cache the reading out data. + * @param[in] rd_len - length in byte of the data need to read. + * @param[in] rd_mode - read mode.dummy or not dummy. + * @return none + */ +void spi_master_write_read_dma_plus(spi_sel_e spi_sel, unsigned char cmd, unsigned char *addr, unsigned int addr_len, unsigned char *rd_data, unsigned int rd_len, spi_rd_tans_mode_e rd_mode); + +/** + * @brief This function serves to single/dual (quad) write to the SPI slave by xip. + * @param[in] cmd - cmd one byte will first write. + * @param[in] addr_offset - offset of xip base address. + * @param[in] data - pointer to the data need to write. + * @param[in] data_len - length in byte of the data need to write. + * @param[in] wr_mode - write mode dummy or not dummy. + * @return none + */ +void hspi_master_write_xip(unsigned char cmd, unsigned int addr_offset, unsigned char *data, unsigned int data_len, spi_wr_tans_mode_e wr_mode); + +/** + * @brief This function serves to single/dual (quad) read from the SPI slave by xip. + * @param[in] cmd - cmd one byte will first write. + * @param[in] addr_offset - offset of xip base address. + * @param[in] data - pointer to the data need to read. + * @param[in] data_len - length in byte of the data need to read. + * @param[in] rd_mode - read mode.dummy or not dummy. + * @return none + */ +void hspi_master_read_xip(unsigned char cmd, unsigned int addr_offset, unsigned char *data, unsigned int data_len, spi_rd_tans_mode_e rd_mode); + +/** + * @brief This function serves to a cmd and one data write to the SPI slave by xip. + * @param[in] cmd - cmd one byte will first write. + * @param[in] addr_offset - offset of xip base address. + * @param[in] data_in - data need to write. + * @param[in] wr_mode - write mode dummy or not dummy. + * @return none + */ +void hspi_master_write_xip_cmd_data(unsigned char cmd, unsigned int addr_offset, unsigned char data_in, spi_wr_tans_mode_e wr_mode); + +#endif + + diff --git a/b91/b91m_ble_sdk/drivers/B91/stimer.c b/b91/b91m_ble_sdk/drivers/B91/stimer.c new file mode 100755 index 0000000..f6f6f95 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/stimer.c @@ -0,0 +1,46 @@ +/******************************************************************************************************** + * @file stimer.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "stimer.h" +/** + * @brief This function performs to set delay time by us. + * @param[in] microsec - need to delay. + * @return none +*/ + void delay_us(unsigned int microsec) +{ + unsigned long t = stimer_get_tick(); + while(!clock_time_exceed(t, microsec)){ + } +} + +/* + * @brief This function performs to set delay time by ms. + * @param[in] millisec - need to delay. + * @return none +*/ + void delay_ms(unsigned int millisec) +{ + unsigned long t = stimer_get_tick(); + while(!clock_time_exceed(t, millisec*1000)){ + } +} diff --git a/b91/b91m_ble_sdk/drivers/B91/stimer.h b/b91/b91m_ble_sdk/drivers/B91/stimer.h new file mode 100755 index 0000000..1787a9f --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/stimer.h @@ -0,0 +1,184 @@ +/******************************************************************************************************** + * @file stimer.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +/** @page STIMER + * + * Introduction + * =============== + * TLSRB91 stimer use 16M clock count, have stimer irq. + * + * API Reference + * =============== + * Header File: uart.h + */ +#ifndef STIMER_H_ +#define STIMER_H_ +#include "compiler.h" +#include "reg_include/stimer_reg.h" + +/********************************************************************************************************************** + * global constants * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * global macro * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * global data type * + *********************************************************************************************************************/ +/********************************************************************************************************************** + * global variable declaration * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * global function prototype * + *********************************************************************************************************************/ +/** + * @brief define system clock tick per us/ms/s. + */ +enum{ + SYSTEM_TIMER_TICK_1US = 16, + SYSTEM_TIMER_TICK_1MS = 16000, + SYSTEM_TIMER_TICK_1S = 16000000, + + SYSTEM_TIMER_TICK_625US = 10000, //625*16 + SYSTEM_TIMER_TICK_1250US = 20000, //1250*16 +}; + + +/** + * @brief This function servers to set stimer irq mask. + * @param[in] mask - the irq mask. + * @return none. + */ +static inline void stimer_set_irq_mask(stimer_irq_e mask) +{ + reg_system_irq_mask |= mask; +} + +/** + * @brief This function servers to clear stimer irq mask. + * @param[in] mask - the irq mask. + * @return none. + */ +static inline void stimer_clr_irq_mask(stimer_irq_e mask) +{ + reg_system_irq_mask &= (~mask); +} + +/** + * @brief This function servers to clear stimer irq status. + * @param[in] status - the irq status. + * @return none. + */ +static inline void stimer_clr_irq_status(stimer_irq_e status) +{ + reg_system_cal_irq = (status); +} + +/** + * @brief This function servers to get stimer irq status. + * @param[in] status - the irq status. + * @return none. + */ +static inline unsigned char stimer_get_irq_status(stimer_irq_e status) +{ + return (reg_system_cal_irq & status); +} + +/** + * @brief This function servers to set tick irq capture. + * @param[in] tick - the value of irq tick. + * @return none. + */ +static inline void stimer_set_irq_capture(unsigned int tick) +{ + reg_system_irq_level = (tick); +} + +/** + * @brief This function servers to set stimer tick. + * @param[in] tick - the value of tick. + * @return none. + */ +static inline void stimer_set_tick(unsigned int tick) +{ + reg_system_tick = (tick); +} + +/** + * @brief This function servers to enable stimer. + * @return none. + */ +static inline void stimer_enable(void) +{ + reg_system_ctrl |= FLD_SYSTEM_TIMER_EN; +} + + +/** + * @brief This function servers to disable stimer. + * @return none. + */ +static inline void stimer_disable(void) +{ + reg_system_ctrl &= ~(FLD_SYSTEM_TIMER_EN); +} + +/* + * @brief This function performs to get system timer tick. + * @return system timer tick value. +**/ +static inline unsigned int stimer_get_tick(void) +{ + + return reg_system_tick; +} + +/** + * @brief This function serves to set timeout by us. + * @param[in] ref - reference tick of system timer . + * @param[in] us - count by us. + * @return true - timeout, false - not timeout + */ +static inline _Bool clock_time_exceed(unsigned int ref, unsigned int us) +{ + return ((unsigned int)(stimer_get_tick() - ref) > us * SYSTEM_TIMER_TICK_1US); +} +/** + * @brief This function performs to set delay time by us. + * @param[in] microsec - need to delay. + * @return none + */ +_attribute_ram_code_sec_noinline_ void delay_us(unsigned int microsec); + + +/** + * @brief This function performs to set delay time by ms. + * @param[in] millisec - need to delay. + * @return none + */ +_attribute_ram_code_sec_noinline_ void delay_ms(unsigned int millisec); + + +#endif /* STIMER_H_ */ diff --git a/b91/b91m_ble_sdk/drivers/B91/sys.c b/b91/b91m_ble_sdk/drivers/B91/sys.c new file mode 100755 index 0000000..5ef7d58 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/sys.c @@ -0,0 +1,166 @@ +/******************************************************************************************************** + * @file sys.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "sys.h" +#include "core.h" +#include "pm.h" +#include "compiler.h" +#include "analog.h" +#include "gpio.h" +#include "mspi.h" +#include "stimer.h" + + +unsigned int g_chip_version=0; + +extern void pm_update_status_info(void); + +#if 0 +/** + * @brief This function serves to initialize system. + * @param[in] power_mode - power mode(LDO/DCDC/LDO_DCDC) + * @param[in] vbat_v - vbat voltage type: 0 vbat may be greater than 3.6V, 1 vbat must be below 3.6V. + * @return none + */ +void sys_init(power_mode_e power_mode, vbat_type_e vbat_v) +{ + /** + * reset function will be cleared by set "1",which is different from the previous configuration. + * This setting turns off the TRNG and NPE modules in order to test power consumption.The current + * decrease about 3mA when those two modules be turn off.changed by zhiwei,confirmed by kaixin.20200828. + */ + reg_rst = 0xffbbffff; + reg_clk_en = 0xffbbffff; + + analog_write_reg8(0x8c,0x02); //<1>:reg_xo_en_clk_ana_ana=1 + analog_write_reg8(0x0a, power_mode);//poweron_dft: 0x90. + //<0-1>:pd_dcdc_ldo_sw, default:00, dcdc & bypass ldo status bits. + // dcdc_1p4 dcdc_1p8 ldo_1p4 ldo_1p8 + //00: N N Y Y + //01: Y N N Y + //10: Y N N N + //11: Y Y N N + analog_write_reg8(0x0b, 0x3b); //poweron_dft: 0x7b -> 0x3b. + //<6>:mscn_pullup_res_enb, default:1,->0 enable 1M pullup resistor for mscn PAD. + analog_write_reg8(0x05,analog_read_reg8(0x05) & (~BIT(3)));//poweron_dft: 0x02 -> 0x02. + //<3>:24M_xtl_pd, default:0,->0 Power up 24MHz XTL oscillator. + analog_write_reg8(0x06,analog_read_reg8(0x06) & ~(BIT(0) | vbat_v | BIT(6) | BIT(7)));//poweron_dft: 0xff -> 0x36 or 0x3e. + //<0>:pd_bbpll_ldo, default:1,->0 Power on ana LDO. + //<3>:pd_vbus_sw, default:1,->0 Power up of bypass switch. + //<6>:spd_ldo_pd, default:1,->0 Power up spd ldo. + //<7>:dig_ret_pd, default:1,->0 Power up retention ldo. + analog_write_reg8(0x01, 0x45); //poweron_dft: 0x44 -> 0x45. + //<0-2>:bbpll_ldo_trim, default:100,->101 measured 1.186V.The default value is sometimes crashes. + //<4-6>:ana_ldo_trim,1.0-1.4V default:100,->100 analog LDO output voltage trim: 1.2V + + write_csr(NDS_MILMB,0x01); + write_csr(NDS_MDLMB,0x80001); + + pm_update_status_info(); + g_pm_vbat_v = vbat_v>>3; + + //xo_ready check should be done after Xtal manual on_off, we put it here to save code running time, code running time between + //Xtal manual on_off and xo_ready check can be used as Xtal be stable timimg. + while( BIT(7) != (analog_read_reg8(0x88) & (BIT(7)))); //<7>: xo_ready_ana, R, aura xtl ready signal. + + //When bbpll_ldo_trim is set to the default voltage value, when doing high and low temperature stability tests,it is found that + //there is a crash.The current workaround is to set other voltage values to see if it is stable.If it fails,repeat the setting + //up to three times.The bbpll ldo trim must wait until 24M is stable.(add by weihua.zhang, confirmed by yi.bao and wenfeng 20200924) + pm_wait_bbpll_done(); + + if(g_pm_status_info.mcu_status == MCU_STATUS_DEEPRET_BACK) + { + pm_stimer_recover(); + }else{ +#if SYS_TIMER_AUTO_MODE + reg_system_ctrl |=(FLD_SYSTEM_TIMER_AUTO|FLD_SYSTEM_32K_TRACK_EN); //enable 32k track and stimer auto. + reg_system_tick = 0x01; //initial next tick is 1,kick system timer +#else + reg_system_ctrl |= FLD_SYSTEM_32K_TRACK_EN | FLD_SYSTEM_TIMER_EN; //enable 32k track and stimer. Wait for pll to stabilize before using stimer. +#endif + } + + g_chip_version = read_reg8(0x1401fd); + + //if clock src is PAD or PLL, and hclk = 1/2cclk, use reboot may cause problem, need deep to resolve(add by yi.bao, confirm by guangjun 20201016) + if(g_pm_status_info.mcu_status == MCU_STATUS_REBOOT_BACK) + { + //Use PM_ANA_REG_POWER_ON_CLR_BUF0 BIT(1) to represent the reboot+deep process, which is related to the function pm_update_status_info. + analog_write_reg8(PM_ANA_REG_POWER_ON_CLR_BUF0, analog_read_reg8(PM_ANA_REG_POWER_ON_CLR_BUF0) | BIT(1)); //(add by weihua.zhang, confirmed by yi.bao 20201222) + pm_sleep_wakeup(DEEPSLEEP_MODE, PM_WAKEUP_TIMER, PM_TICK_STIMER_16M, (stimer_get_tick() + 100*SYSTEM_TIMER_TICK_1MS)); + } + //**When testing AES_demo, it was found that the timing of baseband was wrong when it was powered on, which caused some of + //the registers of ceva to go wrong, which caused the program to run abnormally.(add by weihua.zhang, confirmed by junwen 20200819) + else if(0xff == g_chip_version) //A0 + { + if(g_pm_status_info.mcu_status == MCU_STATUS_POWER_ON) //power on + { + analog_write_reg8(0x7d, 0x80); //power on baseband + pm_sleep_wakeup(DEEPSLEEP_MODE, PM_WAKEUP_TIMER, PM_TICK_STIMER_16M, (stimer_get_tick() + 100*SYSTEM_TIMER_TICK_1MS)); + } + } + analog_write_reg8(0x7d, 0x80); //poweron_dft: 0x03 -> 0x80. + //<0>:pg_zb_en, default:1,->0 power on baseband. + //<1>:pg_usb_en, default:1,->0 power on usb. + //<2>:pg_npe_en, default:1,->0 power on npe. + //<7>:pg_clk_en, default:0,->1 enable change power sequence clk. +} +#endif +/** + * @brief This function performs a series of operations of writing digital or analog registers + * according to a command table + * @param[in] pt - pointer to a command table containing several writing commands + * @param[in] size - number of commands in the table + * @return number of commands are carried out + */ + +int write_reg_table(const tbl_cmd_set_t * pt, int size) +{ + int l=0; + + while (l=0x80000)?(((unsigned int)(addr))-0x80000+0xc0200000) : (((unsigned int)(addr)) + 0xc0000000))) +//#endif + +#define convert_ram_addr_bus2cpu(addr) (((((unsigned int)(addr)) >=0xc0200000)?(((unsigned int)(addr)) + 0x80000-0xc0200000) : (((unsigned int)(addr)) - 0xc0000000))) + +/********************************************************************************************************************** + * global data type * + *********************************************************************************************************************/ + +/** + * @brief Power type for different application + */ +typedef enum{ + LDO_1P4_LDO_1P8 = 0x00, /**< 1.4V-LDO & 1.8V-LDO mode */ + DCDC_1P4_LDO_1P8 = 0x01, /**< 1.4V-DCDC & 1.8V-LDO mode */ + DCDC_1P4_DCDC_1P8 = 0x03, /**< 1.4V-DCDC & 1.8V-DCDC mode */ +}power_mode_e; + +/** + * @brief The maximum voltage that the chip can withstand is 3.6V. + * When the vbat power supply voltage is lower than 3.6V, it is configured as VBAT_MAX_VALUE_LESS_THAN_3V6 mode, + * bypass is turned on, and the vbat voltage directly supplies power to the chip. + * When the vbat power supply voltage may be higher than 3.6V, it is configured as VBAT_MAX_VALUE_GREATER_THAN_3V6 mode, + * the bypass is closed, and the vbat voltage passes through an LDO to supply power to the chip. + */ +typedef enum{ + VBAT_MAX_VALUE_GREATER_THAN_3V6 = 0x00, /*VBAT may be greater than 3.6V. */ + VBAT_MAX_VALUE_LESS_THAN_3V6 = BIT(3), /*VBAT must be below 3.6V. */ +}vbat_type_e; + +/** + * @brief command table for special registers + */ +typedef struct tbl_cmd_set_t { + unsigned int adr; + unsigned char dat; + unsigned char cmd; +} tbl_cmd_set_t; + + +/********************************************************************************************************************** + * global variable declaration * + *********************************************************************************************************************/ + +extern unsigned int g_chip_version; + +/********************************************************************************************************************** + * global function prototype * + *********************************************************************************************************************/ +/** + * @brief This function reboot mcu. + * @return none + */ +static inline void sys_reboot(void) +{ + write_reg8(0x1401ef, 0x20); +} +/** + * @brief This function serves to initialize system. + * @param[in] power_mode - power mode(LDO/DCDC/LDO_DCDC) + * @param[in] vbat_v - vbat voltage type: 0 vbat may be greater than 3.6V, 1 vbat must be below 3.6V. + * @return none + */ +void sys_init(power_mode_e power_mode, vbat_type_e vbat_v); + +/** + * @brief This function performs a series of operations of writing digital or analog registers + * according to a command table + * @param[in] pt - pointer to a command table containing several writing commands + * @param[in] size - number of commands in the table + * @return number of commands are carried out + */ + +int write_reg_table(const tbl_cmd_set_t * pt, int size); + +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/timer.c b/b91/b91m_ble_sdk/drivers/B91/timer.c new file mode 100755 index 0000000..790a87d --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/timer.c @@ -0,0 +1,149 @@ +/******************************************************************************************************** + * @file timer.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "timer.h" +/********************************************************************************************************************** + * global function implementation * + *********************************************************************************************************************/ + +/** + * @brief the specifed timer start working. + * @param[in] type - select the timer to start. + * @return none + */ +void timer_start(timer_type_e type) +{ + switch(type) + { + case TIMER0: + reg_tmr_ctrl0 |= FLD_TMR0_EN; + break; + case TIMER1: + reg_tmr_ctrl0 |= FLD_TMR1_EN; + break; + default: + break; + } +} + +/** + * @brief the specifed timer stop working. + * @param[in] type - select the timer to stop. + * @return none + */ +void timer_stop(timer_type_e type) +{ + switch(type) + { + case TIMER0: + reg_tmr_ctrl0 &= (~FLD_TMR0_EN); + break; + case TIMER1: + reg_tmr_ctrl0 &= (~FLD_TMR1_EN); + break; + default: + break; + } +} + + + +/** + * @brief set mode, initial tick and capture of timer. + * @param[in] type - select the timer to start. + * @param[in] mode - select mode for timer. + * @param[in] init_tick - initial tick. + * @param[in] cap_tick - tick of capture. + * @return none + */ +void timer_set_mode(timer_type_e type, timer_mode_e mode) +{ + switch(type) + { + case TIMER0: + reg_tmr_sta = FLD_TMR_STA_TMR0; //clear irq status + reg_tmr_ctrl0 &= (~FLD_TMR0_MODE); + reg_tmr_ctrl0 |= mode; + break; + case TIMER1: + reg_tmr_sta = FLD_TMR_STA_TMR1; //clear irq status + reg_tmr_ctrl0 &= (~FLD_TMR1_MODE); + reg_tmr_ctrl0 |= (mode<<4); + break; + default: + break; + } + +} + +/** + * @brief initiate GPIO for gpio trigger and gpio width mode of timer. + * @param[in] type - select the timer to start. + * @param[in] pin - select pin for timer. + * @param[in] pol - select polarity for gpio trigger and gpio width + * @return none + */ +void timer_gpio_init(timer_type_e type, gpio_pin_e pin, gpio_pol_e pol ) +{ + gpio_function_en(pin); + gpio_output_dis(pin); //disable output + gpio_input_en(pin); //enable input + switch(type) + { + case TIMER0: + if(pol==POL_FALLING) + { + gpio_set_up_down_res(pin,GPIO_PIN_PULLUP_10K); + gpio_set_gpio2risc0_irq(pin,INTR_LOW_LEVEL); + gpio_gpio2risc0_irq_en(pin); + } + else if(pol==POL_RISING) + { + gpio_set_up_down_res(pin,GPIO_PIN_PULLDOWN_100K); + gpio_set_gpio2risc0_irq(pin,INTR_HIGH_LEVEL); + gpio_gpio2risc0_irq_en(pin); + } + break; + + case TIMER1: + if(pol==POL_FALLING) + { + gpio_set_up_down_res(pin,GPIO_PIN_PULLUP_10K); + gpio_set_gpio2risc1_irq(pin,INTR_LOW_LEVEL); + gpio_gpio2risc1_irq_en(pin); + } + else if(pol==POL_RISING) + { + gpio_set_up_down_res(pin,GPIO_PIN_PULLDOWN_100K); + gpio_set_gpio2risc1_irq(pin,INTR_HIGH_LEVEL); + gpio_gpio2risc1_irq_en(pin); + + } + break; + + default: + break; + } + +} + + diff --git a/b91/b91m_ble_sdk/drivers/B91/timer.h b/b91/b91m_ble_sdk/drivers/B91/timer.h new file mode 100755 index 0000000..e5087b0 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/timer.h @@ -0,0 +1,223 @@ +/******************************************************************************************************** + * @file timer.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +/** @page TIMER + * + * Introduction + * =============== + * B91 supports two timers: Timer0~ Timer1. The two timers all support four modes: + * - Mode 0 (System Clock Mode), + * - Mode 1 (GPIO Trigger Mode), + * - Mode 2 (GPIO Pulse Width Mode), + * - Mode 3 (Tick Mode), + * + * Timer 1 can also be configured as "watchdog" to monitor firmware running. + * + * API Reference + * =============== + * Header File: timer.h + */ +#ifndef TIMER_H_ +#define TIMER_H_ + +#include "analog.h" +#include "gpio.h" +#include "reg_include/register_b91.h" + + +/********************************************************************************************************************** + * global constants * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * global data type * + *********************************************************************************************************************/ +/** + * @brief Type of Timer + */ +typedef enum{ + TIMER0 =0, + TIMER1 =1, +}timer_type_e; + + +/** + * @brief Mode of Timer + */ +typedef enum{ + TIMER_MODE_SYSCLK =0, + TIMER_MODE_GPIO_TRIGGER =1, + TIMER_MODE_GPIO_WIDTH =2, + TIMER_MODE_TICK =3, +}timer_mode_e; + +typedef enum{ + TMR_STA_TMR0 = BIT(0), + TMR_STA_TMR1 = BIT(1), +}time_irq_e; + +/********************************************************************************************************************** + * global function prototype * + *********************************************************************************************************************/ + +/* + * @brief This function refer to get timer irq status. + * @param[in] status - variable of enum to select the timer interrupt source. + * @return the status of timer0/timer1. + */ +static inline unsigned char timer_get_irq_status(time_irq_e status) +{ + return reg_tmr_sta&status ; +} + +/* + * @brief This function refer to clr timer0 irq status. + * @param[in] status - variable of enum to select the timerinterrupt source. + * @return none + */ +static inline void timer_clr_irq_status(time_irq_e status) +{ + reg_tmr_sta= status; +} + + +/* + * @brief This function refer to get timer0 tick. + * @return none + */ +static inline unsigned int timer0_get_gpio_width(void) +{ + return reg_tmr0_tick; + +} + + +/* + * @brief This function refer to get timer1 tick. + * @return none + */ +static inline unsigned int timer1_get_gpio_width(void) +{ + return reg_tmr1_tick; + +} + + +/* + * @brief This function refer to set timer0 tick . + * @param[in] tick - the tick of timer0 + * @return none + */ +static inline void timer0_set_tick(unsigned int tick) +{ + reg_tmr0_tick = tick; +} + +/* + * @brief This function refer to get timer0 tick. + * @return none + */ +static inline unsigned int timer0_get_tick(void) +{ + return reg_tmr0_tick ; +} + + +/* + * @brief This function refer to set timer1 tick. + * @param[in] tick - the tick of timer1 + * @return none + */ +static inline void timer1_set_tick(unsigned int tick) +{ + reg_tmr1_tick = tick; +} + +/* + * @brief This function refer to get timer1 tick. + * @return none + */ +static inline unsigned int timer1_get_tick(void) +{ + return reg_tmr1_tick; +} + +/* + * @brief This function set to initial tick for timr0/timer1. + * @param[in] type - timer0/timer1. + * @param[in] init_tick - initial tick value. + * @return none + */ +static inline void timer_set_init_tick(timer_type_e type, unsigned int init_tick) +{ + reg_tmr_tick(type) = init_tick; +} +/* + * @brief This function set to capture tick for timr0/timer1. + * @param[in] type - timer0/timer1. + * @param[in] cap_tick - initial tick value. + * @return none + */ +static inline void timer_set_cap_tick(timer_type_e type, unsigned int cap_tick) +{ + reg_tmr_capt(type) = cap_tick; +} + + + +/** + * @brief the specifed timer start working. + * @param[in] type - select the timer to start. + * @return none + */ +void timer_start(timer_type_e type); + +/** + * @brief set mode, initial tick and capture of timer. + * @param[in] type - select the timer to start. + * @param[in] mode - select mode for timer. + * @return none + */ +void timer_set_mode(timer_type_e type, timer_mode_e mode); + +/** + * @brief initiate GPIO for gpio trigger and gpio width mode of timer. + * @param[in] type - select the timer to start. + * @param[in] pin - select pin for timer. + * @param[in] pol - select polarity for gpio trigger and gpio width + * @return none + */ +void timer_gpio_init(timer_type_e type, gpio_pin_e pin, gpio_pol_e pol ); + + + +/** + * @brief the specifed timer stop working. + * @param[in] type - select the timer to stop. + * @return none + */ +void timer_stop(timer_type_e type); + + + +#endif /* TIMER_H_ */ diff --git a/b91/b91m_ble_sdk/drivers/B91/trng.c b/b91/b91m_ble_sdk/drivers/B91/trng.c new file mode 100755 index 0000000..2fdca59 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/trng.c @@ -0,0 +1,102 @@ +/******************************************************************************************************** + * @file trng.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "trng.h" +#include "compiler.h" +/********************************************************************************************************************** + * local constants * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * local macro * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * local data type * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * global variable * + *********************************************************************************************************************/ + +_attribute_data_retention_sec_ unsigned int g_rnd_m_w = 0; +_attribute_data_retention_sec_ unsigned int g_rnd_m_z = 0; + +/********************************************************************************************************************** + * local variable * + *********************************************************************************************************************/ +/********************************************************************************************************************** + * local function prototype * + *********************************************************************************************************************/ +/********************************************************************************************************************** + * global function implementation * + *********************************************************************************************************************/ +/** + * @brief This function performs to get one random number.If chip in suspend TRNG module should be close. + * else its current will be larger. + * @return the value of one random number. + */ +void trng_init(void) +{ + //TRNG module Reset clear + reg_rst2 |= FLD_RST2_TRNG; + //turn on TRNG clock + reg_clk_en2 |= FLD_CLK2_TRNG_EN; + + reg_trng_cr0 &= ~(FLD_TRNG_CR0_RBGEN); //disable + reg_trng_rtcr = 0x00; //TCR_MSEL + reg_trng_cr0 |= (FLD_TRNG_CR0_RBGEN); //enable + + while(!(reg_rbg_sr & FLD_RBG_SR_DRDY)); + g_rnd_m_w = reg_rbg_dr; //get the random number + while(!(reg_rbg_sr & FLD_RBG_SR_DRDY)); + g_rnd_m_z = reg_rbg_dr; + + //Reset TRNG module + reg_rst2 &= (~FLD_RST2_TRNG); + //turn off TRNG module clock + reg_clk_en2 &= ~(FLD_CLK2_TRNG_EN); + + reg_trng_cr0 &= ~(FLD_TRNG_CR0_RBGEN | FLD_TRNG_CR0_ROSEN0 | FLD_TRNG_CR0_ROSEN1 \ + | FLD_TRNG_CR0_ROSEN2 | FLD_TRNG_CR0_ROSEN3); +} + +/** + * @brief This function performs to get one random number. + * @return the value of one random number. + */ +_attribute_ram_code_sec_noinline_ /*unsigned*/ int trng_rand(void) //16M clock, code in flash 23us, code in sram 4us +{ + + g_rnd_m_w = 18000 * (g_rnd_m_w & 0xffff) + (g_rnd_m_w >> 16); + g_rnd_m_z = 36969 * (g_rnd_m_z & 0xffff) + (g_rnd_m_z >> 16); + unsigned int result = (g_rnd_m_z << 16) + g_rnd_m_w; + + return (unsigned int)( result ^ stimer_get_tick() ); +} + /********************************************************************************************************************** + * local function implementation * + *********************************************************************************************************************/ + diff --git a/b91/b91m_ble_sdk/drivers/B91/trng.h b/b91/b91m_ble_sdk/drivers/B91/trng.h new file mode 100755 index 0000000..ad35731 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/trng.h @@ -0,0 +1,73 @@ +/******************************************************************************************************** + * @file trng.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +/** @page TRNG + * + * Introduction + * =============== + * TLSRB91 supports hardware trng. + * + * API Reference + * =============== + * Header File: trng.h + */ +#ifndef TRNG_H_ +#define TRNG_H_ + +#include "sys.h" +#include "stimer.h" +#include "reg_include/register_b91.h" + +/********************************************************************************************************************** + * global constants * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * global macro * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * global data type * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * global variable declaration * + *********************************************************************************************************************/ + +/********************************************************************************************************************** + * global function prototype * + *********************************************************************************************************************/ + +/** + * @brief This function performs to get one random number.If chip in suspend TRNG module should be close. + * else its current will be larger. + * @return none + **/ +void trng_init(void); + +/** + * @brief This function performs to get one random number. + * @return the value of one random number + **/ +/*unsigned*/ int trng_rand(void); + +#endif diff --git a/b91/b91m_ble_sdk/drivers/B91/uart.c b/b91/b91m_ble_sdk/drivers/B91/uart.c new file mode 100755 index 0000000..293d240 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/uart.c @@ -0,0 +1,771 @@ +/******************************************************************************************************** + * @file uart.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "uart.h" + +/********************************************************************************************************************** + * local constants * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * local macro * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * local data type * + *********************************************************************************************************************/ + + +/********************************************************************************************************************** + * global variable * + *********************************************************************************************************************/ +dma_config_t uart_tx_dma_config[2]={ + { .dst_req_sel = DMA_REQ_UART0_TX,//tx req + .src_req_sel = 0, + .dst_addr_ctrl = DMA_ADDR_FIX, + .src_addr_ctrl = DMA_ADDR_INCREMENT,//increment + .dstmode = DMA_HANDSHAKE_MODE,//handshake + .srcmode = DMA_NORMAL_MODE, + .dstwidth = DMA_CTR_WORD_WIDTH,//must be word + .srcwidth = DMA_CTR_WORD_WIDTH,//must be word + .src_burst_size = 0,//must be 0 + .read_num_en = 0, + .priority = 0, + .write_num_en = 0, + .auto_en = 0,//must be 0 + }, + { .dst_req_sel = DMA_REQ_UART1_TX,//tx req + .src_req_sel = 0, + .dst_addr_ctrl = DMA_ADDR_FIX, + .src_addr_ctrl = DMA_ADDR_INCREMENT,//increment + .dstmode = DMA_HANDSHAKE_MODE,//handshake + .srcmode = DMA_NORMAL_MODE, + .dstwidth = DMA_CTR_WORD_WIDTH,//must be word + .srcwidth = DMA_CTR_WORD_WIDTH,//must be word + .src_burst_size = 0,//must be 0 + .read_num_en = 0, + .priority = 0, + .write_num_en = 0, + .auto_en = 0,//must be 0 + } +}; +dma_config_t uart_rx_dma_config[2]={ + { .dst_req_sel = 0,//tx req + .src_req_sel = DMA_REQ_UART0_RX, + .dst_addr_ctrl = DMA_ADDR_INCREMENT, + .src_addr_ctrl = DMA_ADDR_FIX, + .dstmode = DMA_NORMAL_MODE, + .srcmode = DMA_HANDSHAKE_MODE, + .dstwidth = DMA_CTR_WORD_WIDTH,//must be word + .srcwidth = DMA_CTR_WORD_WIDTH,////must be word + .src_burst_size = 0, + .read_num_en = 0, + .priority = 0, + .write_num_en = 0, + .auto_en = 0,//must be 0 + }, + { .dst_req_sel = 0,//tx req + .src_req_sel = DMA_REQ_UART1_RX, + .dst_addr_ctrl = DMA_ADDR_INCREMENT, + .src_addr_ctrl = DMA_ADDR_FIX, + .dstmode = DMA_NORMAL_MODE, + .srcmode = DMA_HANDSHAKE_MODE, + .dstwidth = DMA_CTR_WORD_WIDTH,//must be word + .srcwidth = DMA_CTR_WORD_WIDTH,////must be word + .src_burst_size = 0, + .read_num_en = 0, + .priority = 0, + .write_num_en = 0, + .auto_en = 0,//must be 0 + } +}; +/********************************************************************************************************************** + * local variable * + *********************************************************************************************************************/ + static unsigned char uart_dma_tx_chn[2]; + static unsigned char uart_dma_rx_chn[2]; +/********************************************************************************************************************** + * local function prototype * + *********************************************************************************************************************/ + /** + * @brief This function is used to look for the prime.if the prime is finded,it will return 1, or return 0. + * @param[in] n - the calue to judge. + * @return 0 or 1 + */ + static unsigned char uart_is_prime(unsigned int n); + + /** + * @brief This function serves to set pin for UART fuction. + * @param tx_pin - To set TX pin. + * @param rx_pin - To set RX pin. + * @return none + */ +static void uart_set_fuc_pin(uart_tx_pin_e tx_pin,uart_rx_pin_e rx_pin); + +/********************************************************************************************************************** + * global function implementation * + *********************************************************************************************************************/ + +/** + * @brief This function initializes the UART module. + * @param[in] uart_num - UART0 or UART1. + * @param[in] div - uart clock divider. + * @param[in] bwpc - bitwidth, should be set to larger than 2. + * @param[in] parity - selected parity type for UART interface. + * @param[in] stop_bit - selected length of stop bit for UART interface. + * @return none + * @note sys_clk baudrate g_uart_div g_bwpc + * + * 16Mhz 9600 118 13 + * 19200 118 6 + * 115200 9 13 + * + * 24Mhz 9600 249 9 + * 19200 124 9 + * 115200 12 15 + * + * 32Mhz 9600 235 13 + * 19200 235 6 + * 115200 17 13 + * + * 48Mhz 9600 499 9 + * 19200 249 9 + * 115200 25 15 +*/ +void telink_b91_uart_init(uart_num_e uart_num,unsigned short div, unsigned char bwpc, uart_parity_e parity, uart_stop_bit_e stop_bit) +{ + reg_uart_ctrl0(uart_num) &= ~ (FLD_UART_BPWC_O); + reg_uart_ctrl0(uart_num) |= bwpc; //set bwpc + reg_uart_clk_div(uart_num) = (div | FLD_UART_CLK_DIV_EN); //set div_clock + + //parity config + if (parity) { + reg_uart_ctrl1(uart_num) |= FLD_UART_PARITY_ENABLE; //enable parity function + if (UART_PARITY_EVEN == parity) { + reg_uart_ctrl1(uart_num) &= (~FLD_UART_PARITY_POLARITY); //enable even parity + } + else if (UART_PARITY_ODD == parity) { + reg_uart_ctrl1(uart_num) |= FLD_UART_PARITY_POLARITY; //enable odd parity + } + } + else { + reg_uart_ctrl1(uart_num) &= (~FLD_UART_PARITY_ENABLE); //disable parity function + } + + //stop bit config + reg_uart_ctrl1(uart_num) &= (~FLD_UART_STOP_SEL); + reg_uart_ctrl1(uart_num) |= stop_bit; +} + +/*********************************************************** + * @brief This function serves to calculate the best bwpc(bit width) .i.e reg0x96. + * @param[in] baudrate - baut rate of UART. + * @param[in] pclk - system clock. + * @param[out] div - uart clock divider. + * @param[out] bwpc - bitwidth, should be set to larger than 2. + * @return none + * @note BaudRate*(div+1)*(bwpc+1) = system clock + * simplify the expression: div*bwpc = constant(z) + * bwpc range from 3 to 15.so loop and get the minimum one decimal point + */ +void uart_cal_div_and_bwpc(unsigned int baudrate, unsigned int pclk, unsigned short* div, unsigned char *bwpc) +{ + unsigned char i = 0, j= 0; + unsigned int primeInt = 0; + unsigned char primeDec = 0; + unsigned int D_intdec[13],D_int[13]; + unsigned char D_dec[13]; + + primeInt = pclk/baudrate; + primeDec = 10*pclk/baudrate - 10*primeInt; + + if(uart_is_prime(primeInt)){ // primeInt is prime + primeInt += 1; //+1 must be not prime. and primeInt must be larger than 2. + } + else{ + if(primeDec > 5){ // >5 + primeInt += 1; + if(uart_is_prime(primeInt)){ + primeInt -= 1; + } + } + } + + for(i=3;i<=15;i++){ + D_intdec[i-3] = (10*primeInt)/(i+1);////get the LSB + D_dec[i-3] = D_intdec[i-3] - 10*(D_intdec[i-3]/10);///get the decimal section + D_int[i-3] = D_intdec[i-3]/10;///get the integer section + } + + //find the max and min one decimation point + unsigned char position_min = 0,position_max = 0; + unsigned int min = 0xffffffff,max = 0x00; + for(j=0;j<13;j++){ + if((D_dec[j] <= min)&&(D_int[j] != 0x01)){ + min = D_dec[j]; + position_min = j; + } + if(D_dec[j]>=max){ + max = D_dec[j]; + position_max = j; + } + } + + if((D_dec[position_min]<5) && (D_dec[position_max]>=5)){ + if(D_dec[position_min]<(10-D_dec[position_max])){ + *bwpc = position_min + 3; + *div = D_int[position_min]-1; + } + else{ + *bwpc = position_max + 3; + *div = D_int[position_max]; + } + } + else if((D_dec[position_min]<5) && (D_dec[position_max]<5)){ + *bwpc = position_min + 3; + *div = D_int[position_min] - 1; + } + else{ + *bwpc = position_max + 3; + *div = D_int[position_max]; + } +} + +/** + * @brief This funtion serves to set r_rxtimeout. this setting is transfer one bytes need cycles base on uart_clk. + * For example, if transfer one bytes (1start bit+8bits data+1 priority bit+2stop bits) total 12 bits, + * this register setting should be (bpwc+1)*12. + * @param[in] uart_num - UART0 or UART1. + * @param[in] bwpc - bitwidth, should be set to larger than 2. + * @param[in] bit_cnt - bit number. + * @param[in] mul - mul. + * @return none + */ +void uart_set_dma_rx_timeout(uart_num_e uart_num,unsigned char bwpc, unsigned char bit_cnt, uart_timeout_mul_e mul) +{ + reg_uart_rx_timeout0(uart_num) = (bwpc+1) * bit_cnt; //one byte includes 12 bits at most + reg_uart_rx_timeout1(uart_num) &= (~FLD_UART_TIMEOUT_MUL); + reg_uart_rx_timeout1(uart_num) |= mul; //if over 2*(tmp_bwpc+1),one transaction end. +} + + unsigned char uart_tx_byte_index[2] = {0}; +/** + * @brief This function serves to send data by byte with not DMA method. + * @param[in] uart_num - UART0 or UART1. + * @param[in] tx_data - the data to be send. + * @return none + */ +void uart_send_byte(uart_num_e uart_num, unsigned char tx_data) +{ + while(uart_get_txfifo_num(uart_num)>7); + + reg_uart_data_buf(uart_num, uart_tx_byte_index[uart_num]) = tx_data; + uart_tx_byte_index[uart_num] ++; + (uart_tx_byte_index[uart_num]) &= 0x03; +} + +unsigned char uart_rx_byte_index[2]={0}; +/** + * @brief This function serves to receive uart data by byte with not DMA method. + * @param[in] uart_num - UART0 or UART1. + * @return none + */ +unsigned char uart_read_byte(uart_num_e uart_num) +{ + unsigned char rx_data = reg_uart_data_buf(uart_num, uart_rx_byte_index[uart_num]) ; + uart_rx_byte_index[uart_num]++; + uart_rx_byte_index[uart_num] &= 0x03 ; + return rx_data; +} + +/** + * @brief This function serves to judge if the transmission of uart is done. + * @param[in] uart_num - UART0 or UART1. + * @return return the tx status. + * - 0:tx is done 1:tx isn't done + */ +unsigned char uart_tx_is_busy(uart_num_e uart_num) +{ + return ( (reg_uart_status2(uart_num) & FLD_UART_TX_DONE) ? 0 : 1) ; +} + +/** + * @brief This function serves to send uart0 data by halfword with not DMA method. + * @param[in] uart_num - UART0 or UART1. + * @param[in] data - the data to be send. + * @return none + */ +void uart_send_hword(uart_num_e uart_num, unsigned short data) +{ + static unsigned char uart_tx_hword_index[2]={0}; + + while(uart_get_txfifo_num(uart_num)>6); + + reg_uart_data_hword_buf(uart_num, uart_tx_hword_index[uart_num]) = data; + uart_tx_hword_index[uart_num]++ ; + uart_tx_hword_index[uart_num] &= 0x01 ; +} + +/** + * @brief This function serves to send data by word with not DMA method. + * @param[in] uart_num - UART0 or UART1. + * @param[in] data - the data to be send. + * @return none + */ +void uart_send_word(uart_num_e uart_num, unsigned int data) +{ + while (uart_get_txfifo_num(uart_num)>4); + reg_uart_data_word_buf(uart_num) = data; + +} + +/** + * @brief This function serves to set the RTS pin's level manually. + * @param[in] uart_num - UART0 or UART1. + * @param[in] polarity - set the output of RTS pin(only for manual mode). + * @return none + */ +void uart_set_rts_level(uart_num_e uart_num, unsigned char polarity) +{ + if (polarity) { + reg_uart_ctrl2(uart_num) |= FLD_UART_RTS_MANUAL_V; + } + else { + reg_uart_ctrl2(uart_num) &= (~FLD_UART_RTS_MANUAL_V); + } +} + +/** + * @brief This function serves to set pin for UART0 cts function . + * @param[in] cts_pin -To set cts pin. + * @return none + */ +void uart_set_cts_pin(uart_cts_pin_e cts_pin) +{ + unsigned char val = 0; + unsigned char mask = 0xff; + if(cts_pin == UART0_CTS_PA1) + { + mask= (unsigned char)~(BIT(2)|BIT(3)); + val = BIT(2); + } + else if(cts_pin == UART0_CTS_PB6) + { + mask = (unsigned char)~(BIT(4)|BIT(5)); + val = BIT(5); + reg_gpio_pad_mul_sel|=BIT(0); + } + else if(cts_pin == UART0_CTS_PD0) + { + mask = (unsigned char)~(BIT(0)|BIT(1)); + val = 0; + } + else if(cts_pin == UART1_CTS_PC4) + { + mask= (unsigned char)~(BIT(0)|BIT(1)); + val = BIT(1); + reg_gpio_pad_mul_sel|=BIT(0); + } + else if(cts_pin == UART1_CTS_PD4) + { + mask = (unsigned char)~(BIT(0)|BIT(1)); + val = 0; + } + else if(cts_pin == UART1_CTS_PE1) + { + mask = (unsigned char)~(BIT(2)|BIT(3)); + val = BIT(2); + } + reg_gpio_func_mux(cts_pin)=(reg_gpio_func_mux(cts_pin)& mask)|val; + gpio_function_dis(cts_pin); +} + +/** + * @brief This function serves to set pin for UART0 rts function . + * @param[in] rts_pin - To set rts pin. + * @return none + */ +void uart_set_rts_pin(uart_rts_pin_e rts_pin) +{ + unsigned char val = 0; + unsigned char mask = 0xff; + if(rts_pin == UART0_RTS_PA2) + { + mask= (unsigned char)~(BIT(4)|BIT(5)); + val = BIT(4); + } + else if(rts_pin == UART0_RTS_PB4) + { + mask = (unsigned char)~(BIT(0)|BIT(1)); + val = BIT(1); + reg_gpio_pad_mul_sel|=BIT(0); + } + else if(rts_pin == UART0_RTS_PD1) + { + mask = (unsigned char)~(BIT(2)|BIT(3)); + val = 0; + } + else if(rts_pin == UART1_RTS_PC5) + { + mask= (unsigned char)~(BIT(2)|BIT(3)); + val = BIT(3); + reg_gpio_pad_mul_sel|=BIT(0); + } + else if(rts_pin == UART1_RTS_PD5) + { + mask = (unsigned char)~(BIT(2)|BIT(3)); + val = 0; + } + else if(rts_pin == UART1_RTS_PE3) + { + mask = (unsigned char)~(BIT(6)|BIT(7)); + val = BIT(6); + } + reg_gpio_func_mux(rts_pin)=(reg_gpio_func_mux(rts_pin)& mask)|val; + gpio_function_dis(rts_pin); +} + +/** +* @brief This function serves to select pin for UART module. +* @param[in] tx_pin - the pin to send data. +* @param[in] rx_pin - the pin to receive data. +* @return none +*/ +void uart_set_pin(uart_tx_pin_e tx_pin,uart_rx_pin_e rx_pin) +{ + gpio_set_up_down_res(tx_pin, GPIO_PIN_PULLUP_10K); + gpio_set_up_down_res(rx_pin, GPIO_PIN_PULLUP_10K); + uart_set_fuc_pin(tx_pin,rx_pin);//set tx and rx pin + gpio_input_en(tx_pin); + gpio_input_en(rx_pin); +} + +/** +* @brief This function serves to set rtx pin for UART module. +* @param[in] rx_pin - the rtx pin need to set. +* @return none +*/ +void uart_set_rtx_pin(uart_rx_pin_e rx_pin) +{ + unsigned char val = 0; + unsigned char mask = 0xff; + gpio_set_up_down_res(rx_pin, GPIO_PIN_PULLUP_10K); + if(rx_pin == UART0_RX_PA4) + { + mask= (unsigned char)~(BIT(1)|BIT(0)); + val = BIT(0); + } + else if(rx_pin == UART0_RX_PB3) + { + mask = (unsigned char)~(BIT(7)|BIT(6)); + val = BIT(7); + reg_gpio_pad_mul_sel|=BIT(0); + } + else if(rx_pin ==UART0_RX_PD3) + { + mask = (unsigned char)~(BIT(7)|BIT(6)); + val = 0; + } + else if(rx_pin == UART1_RX_PC7) + { + mask = (unsigned char)~(BIT(7)|BIT(6)); + val = BIT(7); + reg_gpio_pad_mul_sel|=BIT(0); + } + else if(rx_pin == UART1_RX_PD7) + { + mask = (unsigned char)~(BIT(7)|BIT(6)); + val = 0; + } + else if(rx_pin == UART1_RX_PE2) + { + mask = (unsigned char)~(BIT(5)|BIT(4)); + val = BIT(4); + } + reg_gpio_func_mux(rx_pin)=(reg_gpio_func_mux(rx_pin)& mask)|val; + gpio_input_en(rx_pin); + gpio_function_dis(rx_pin); +} + +/** +* @brief This function serves to send data with not DMA method. +* @param[in] uart_num - UART0 or UART1. +* @param[in] addr - pointer to the buffer containing data need to send. +* @param[in] len - NDMA transmission length. +* @return 1 +*/ +unsigned char uart_send(uart_num_e uart_num, unsigned char * addr, unsigned char len ) +{ + for(unsigned char i=0;i>4; +} + +/** + * @brief This function resets the UART module. + * @param[in] uart_num - UART0 or UART1. + * @return none + */ +static inline void uart_reset(uart_num_e uart_num) +{ + + reg_rst0 &= (~((uart_num)?FLD_RST0_UART1:FLD_RST0_UART0)); + reg_rst0 |= ((uart_num)?FLD_RST0_UART1:FLD_RST0_UART0); +} + +/** + * @brief This function enable the clock of UART module. + * @param[in] uart_num - UART0/UART1. + * @return none + */ +static inline void uart_clk_en(uart_num_e uart_num) +{ + reg_clk_en0 |= ((uart_num)?FLD_CLK0_UART1_EN:FLD_CLK0_UART0_EN); +} + +/** + * @brief This function initializes the UART module. + * @param[in] uart_num - UART0 or UART1. + * @param[in] div - uart clock divider. + * @param[in] bwpc - bitwidth, should be set to larger than 2. + * @param[in] parity - selected parity type for UART interface. + * @param[in] stop_bit - selected length of stop bit for UART interface. + * @return none + * @note sys_clk baudrate g_uart_div g_bwpc + * + * 16Mhz 9600 118 13 + * 19200 118 6 + * 115200 9 13 + * + * 24Mhz 9600 249 9 + * 19200 124 9 + * 115200 12 15 + * + * 32Mhz 9600 235 13 + * 19200 235 6 + * 115200 17 13 + * + * 48Mhz 9600 499 9 + * 19200 249 9 + * 115200 25 15 +*/ +extern void telink_b91_uart_init(uart_num_e uart_num,unsigned short div, unsigned char bwpc, uart_parity_e parity, uart_stop_bit_e stop_bit); + +/*********************************************************** + * @brief This function serves to calculate the best bwpc(bit width) .i.e reg0x96. + * @param[in] baudrate - baut rate of UART. + * @param[in] sysclk - system clock. + * @param[out] div - uart clock divider. + * @param[out] bwpc - bitwidth, should be set to larger than 2. + * @return none + * @note BaudRate*(div+1)*(bwpc+1) = system clock. + * simplify the expression: div*bwpc = constant(z). + * bwpc range from 3 to 15.so loop and get the minimum one decimal point. + */ +void uart_cal_div_and_bwpc(unsigned int baudrate, unsigned int sysclk, unsigned short* div, unsigned char *bwpc); + +/** + * @brief This funtion serves to set r_rxtimeout. this setting is transfer one bytes need cycles base on uart_clk. + * For example, if transfer one bytes (1start bit+8bits data+1 priority bit+2stop bits) total 12 bits, + * this register setting should be (bpwc+1)*12. + * @param[in] uart_num - UART0 or UART1. + * @param[in] bwpc - bitwidth, should be set to larger than 2. + * @param[in] bit_cnt - bit number. + * @param[in] mul - mul. + * @return none + */ +void uart_set_dma_rx_timeout(uart_num_e uart_num,unsigned char bwpc, unsigned char bit_cnt, uart_timeout_mul_e mul); + +/** + * @brief This function serves to config the number level setting the irq bit of status register. + * @param[in] uart_num - UART0 or UART1. + * @param[in] rx_level - receive level value. ie 0x140089[0,3]. + * @return none + */ +static inline void uart_rx_irq_trig_level(uart_num_e uart_num,unsigned char rx_level) +{ + reg_uart_ctrl3(uart_num) = (reg_uart_ctrl3(uart_num) & (~FLD_UART_RX_IRQ_TRIQ_LEV)) | (rx_level & 0x0f); +} + +/** + * @brief This function serves to config the number level setting the irq bit of status register. + * @param[in] uart_num - UART0 or UART1. + * @param[in] tx_level - transmit level value.ie 0x140089[4,7]. + * @return none + */ +static inline void uart_tx_irq_trig_level(uart_num_e uart_num,unsigned char tx_level) +{ + reg_uart_ctrl3(uart_num) = (reg_uart_ctrl3(uart_num) & (~FLD_UART_TX_IRQ_TRIQ_LEV)) | (tx_level << 4); +} + +/** + * @brief This function serves to send data by byte with not DMA method. + * @param[in] uart_num - UART0 or UART1. + * @param[in] tx_data - the data to be send. + * @return none + */ +void uart_send_byte(uart_num_e uart_num,unsigned char tx_data); + +/** + * @brief This function serves to receive uart data by byte with not DMA method. + * @param[in] uart_num - UART0 or UART1. + * @return none + */ +unsigned char uart_read_byte(uart_num_e uart_num); +/** + * @brief This function serves to judge if the transmission of uart is done. + * @param[in] uart_num - UART0 or UART1. + * @return return the tx status + * - 0:tx is done 1:tx isn't done + */ +unsigned char uart_tx_is_busy(uart_num_e uart_num); +/** + * @brief This function serves to send uart0 data by halfword with not DMA method. + * @param[in] uart_num - UART0 or UART1. + * @param[in] data - the data to be send. + * @return none + */ +void uart_send_hword(uart_num_e uart_num, unsigned short data); + +/** + * @brief This function serves to send uart0 data by word with not DMA method. + * @param[in] uart_num - UART0 or UART1. + * @param[in] data - the data to be send. + * @return none + */ +void uart_send_word(uart_num_e uart_num, unsigned int data); + + +/** + * @brief This function sets the RTS pin's level manually. + * @param[in] uart_num - UART0 or UART1. + * @param[in] polarity - set the output of RTS pin(only for manual mode). + * @return none + */ +void uart_set_rts_level(uart_num_e uart_num, unsigned char polarity); + +/** + * @brief This function serves to set pin for UART0 cts function . + * @param[in] cts_pin -To set cts pin. + * @return none + */ +void uart_set_cts_pin(uart_cts_pin_e cts_pin); + +/** + * @brief This function serves to set pin for UART0 rts function . + * @param[in] rts_pin - To set rts pin. + * @return none + */ +void uart_set_rts_pin(uart_rts_pin_e rts_pin); + +/** +* @brief This function serves to select pin for UART module. +* @param[in] tx_pin - the pin to send data. +* @param[in] rx_pin - the pin to receive data. +* @return none +*/ +void uart_set_pin(uart_tx_pin_e tx_pin,uart_rx_pin_e rx_pin); + +/** +* @brief This function serves to select pin for UART module. +* @param[in] rx_pin - the pin serves to send and receive data. +* @return none +*/ +void uart_set_rtx_pin(uart_rx_pin_e rx_pin); + + +/** + * @brief This function serves to send data by DMA, this function tell the DMA to get data from the RAM and start. + * @param[in] uart_num - UART0 or UART1. + * @param[in] addr - pointer to the buffer containing data need to send. + * @param[in] len - DMA transmission length.The maximum transmission length of DMA is 0xFFFFFC bytes, so dont'n over this length. + * @return 1 dma start send. + * 0 the length is error. + */ +unsigned char uart_send_dma(uart_num_e uart_num, unsigned char * addr, unsigned int len ); + +/** +* @brief This function serves to send data with not DMA method. +* @param[in] uart_num - UART0 or UART1. +* @param[in] addr - pointer to the buffer containing data need to send. +* @param[in] len - NDMA transmission length. +* @return 1 +*/ +unsigned char uart_send(uart_num_e uart_num, unsigned char * addr, unsigned char len ); + +/** + * @brief This function serves to receive data function by DMA, this function tell the DMA to get data from the uart data fifo. + * @param[in] uart_num - UART0 or UART1. + * @param[in] addr - pointer to the buffer receive data. + * @param[in] rev_size - the receive length of DMA.The maximum transmission length of DMA is 0xFFFFFC bytes, so dont'n over this length. + * @note The DMA version of A0 has some limitians. + * 1:The receive length should be greater or equal to the data you want to receive,then the data won't be lost. + * 2:You have to estimate the data-length that you want to receive.If the data length you set isn't the multiple + * of 4(the DMA carry 4-byte one time),like 5,it will carry 8 byte,while the last 3-byte data is random. + * The DMA version of A1 can receive any length of data,the rev_size is useless. + * @return none + */ +extern void uart_receive_dma(uart_num_e uart_num, unsigned char * addr,unsigned int rev_size); + +/** + * @brief This function serves to set uart tx_dam channel and config dma tx default. + * @param[in] uart_num - UART0 or UART1. + * @param[in] chn - dma channel. + * @return none + */ +extern void uart_set_tx_dma_config(uart_num_e uart_num, dma_chn_e chn); + +/** + * @brief This function serves to set uart rx_dam channel and config dma rx default. + * @param[in] uart_num - UART0 or UART1. + * @param[in] chn - dma channel. + * @return none + */ +extern void uart_set_rx_dma_config(uart_num_e uart_num, dma_chn_e chn); + +/** + * @brief This function serves to config the irq of uart tx and rx. + * @param[in] uart_num - UART0 or UART1. + * @param[in] mask - uart irq mask. + * @return none + */ +static inline void uart_set_irq_mask(uart_num_e uart_num,uart_irq_mask_e mask) +{ + if((mask & UART_RX_IRQ_MASK) || (mask & UART_TX_IRQ_MASK)) + { + reg_uart_ctrl0(uart_num) |= (((mask & UART_RX_IRQ_MASK)? 1:0) << 6) | (((mask & UART_TX_IRQ_MASK)? 1:0 )<< 7); + } + + if((mask & UART_RXDONE_MASK) || (mask & UART_TXDONE_MASK) || (mask & UART_ERR_IRQ_MASK)) + { + reg_uart_rx_timeout1(uart_num) |= (((mask & UART_RXDONE_MASK)? 1:0) << 2) | (((mask & UART_TXDONE_MASK) ? 1:0 )<< 6) | (((mask & UART_ERR_IRQ_MASK) ? 1:0 )<< 7); + } +} + +/** + * @brief This function serves to clear the irq of uart tx and rx. + * @param[in] uart_num - UART0 or UART1. + * @param[in] mask - uart irq mask. + * @return none + */ +static inline void uart_clr_irq_mask(uart_num_e uart_num,uart_irq_mask_e mask) +{ + if((mask & UART_RX_IRQ_MASK) || (mask & UART_TX_IRQ_MASK)) + { + reg_uart_ctrl0(uart_num) &= ~((((mask & UART_RX_IRQ_MASK)? 1:0)<< 6) | (((mask & UART_TX_IRQ_MASK)? 1:0) << 7)); + } + if((mask & UART_RXDONE_MASK) || (mask & UART_TXDONE_MASK) || (mask & UART_ERR_IRQ_MASK)){ + reg_uart_rx_timeout1(uart_num) &= ~((((mask & UART_RXDONE_MASK)? 1:0) << 2) | (((mask & UART_TXDONE_MASK)? 1:0)<< 6) | (((mask & UART_ERR_IRQ_MASK)? 1:0) << 7)); + } +} + + +/** + * @brief This function serves to get the irq status of uart tx and rx. + * @param[in] uart_num - UART0 or UART1. + * @param[in] status - uart irq mask. + * @return irq status + */ +static inline unsigned int uart_get_irq_status(uart_num_e uart_num,uart_irq_status_get_e status) +{ + if(status == UART_RX_ERR){ + return (reg_uart_status1(uart_num) & (status)); + } + else + { + return (reg_uart_status2(uart_num) & (status)); + } +} + + +/** + * @brief This function serves to clear the irq status of uart tx and rx. + * @param[in] uart_num - UART0 or UART1. + * @param[in] status - uart irq mask. + * @return none + */ +static inline void uart_clr_irq_status(uart_num_e uart_num,uart_irq_status_clr_e status) +{ + reg_uart_status1(uart_num) |= (status); +} + +/** + * @brief This function serves to set uart rts enable. + * @param[in] uart_num - UART0 or UART1. + * @return none + */ +static inline void uart_set_rts_en(uart_num_e uart_num) +{ + reg_uart_ctrl2(uart_num) |= FLD_UART_RTS_EN; //enable RTS function +} + +/** + * @brief This function serves to set uart rts disable. + * @param[in] uart_num - UART0 or UART1. + * @return none + */ +static inline void uart_set_rts_dis(uart_num_e uart_num) +{ + reg_uart_ctrl2(uart_num) &= (~FLD_UART_RTS_EN); //disable RTS function +} + +/** + * @brief This function serves to set uart cts enable. + * @param[in] uart_num - UART0 or UART1. + * @return none + */ +static inline void uart_set_cts_en(uart_num_e uart_num) +{ + reg_uart_ctrl1(uart_num) |= FLD_UART_TX_CTS_ENABLE; //enable CTS function +} + +/** + * @brief This function serves to set uart cts disable. + * @param[in] uart_num - UART0 or UART1. + * @return none + */ +static inline void uart_set_cts_dis(uart_num_e uart_num) +{ + reg_uart_ctrl1(uart_num) &= (~FLD_UART_TX_CTS_ENABLE); //disable CTS function +} + +/** + * @brief This function serves to configure UART hardware flow. Configure CTS. + * @param[in] uart_num - UART0 or UART1. + * @param[in] cts_pin - RTS pin select. + * @param[in] cts_parity - when CTS's input equals to select, tx will be stopped. + * @return none + */ +extern void uart_cts_config(uart_num_e uart_num,uart_cts_pin_e cts_pin,unsigned char cts_parity); + +/** + * @brief This function serves to configure UART hardware flow. Configure RTS. + * @param[in] uart_num - UART0 or UART1. + * @param[in] rts_pin - RTS pin select. + * @param[in] rts_parity - whether invert the output of RTS pin(only for auto mode). + * @param[in] auto_mode_en - set the mode of RTS(auto or manual). + * @return none + */ +extern void uart_rts_config(uart_num_e uart_num,uart_rts_pin_e rts_pin,unsigned char rts_parity,unsigned char auto_mode_en); + +/** + * @brief This function serves to set uart rts trig lexel in auto mode. + * @param[in] uart_num - UART0 or UART1. + * @param[in] level - threshold of trig RTS pin's level toggle(only for auto mode). + * @return none + */ +static inline void uart_rts_trig_level_auto_mode(uart_num_e uart_num,unsigned char level) +{ + reg_uart_ctrl2(uart_num) &= (~FLD_UART_RTS_TRIQ_LEV); + reg_uart_ctrl2(uart_num) |= (level & FLD_UART_RTS_TRIQ_LEV); +} + +/** + * @brief This function serves to set uart rts auto mode. + * @param[in] uart_num - UART0 or UART1. + * @return none + */ +static inline void uart_rts_auto_mode(uart_num_e uart_num) +{ + reg_uart_ctrl2(uart_num) &= (~FLD_UART_RTS_MANUAL_M); +} + +/** + * @brief This function serves to set uart rts manual mode. + * @param[in] uart_num - UART0 or UART1. + * @return none + */ +static inline void uart_rts_manual_mode(uart_num_e uart_num) +{ + reg_uart_ctrl2(uart_num) |= (FLD_UART_RTS_MANUAL_M); +} + + +/** + * @brief This function is used to set the 'uart_rx_byte_index' to 0. + * after wakeup from power-saving mode or reset uart, you must call this function before receiving the data. + * @param[in] uart_num + * @return none. + */ +static inline void uart_clr_rx_index(uart_num_e uart_num) +{ + uart_rx_byte_index[uart_num]=0; +} + +/** + * @brief This function is used to set the 'uart_tx_byte_index' to 0. + * after wakeup from power-saving mode or reset uart, you must call this function before sending the data. + * @param[in] uart_num + * @return none. + */ +static inline void uart_clr_tx_index(uart_num_e uart_num) +{ + uart_tx_byte_index[uart_num]=0; +} + +/** + * @brief This function is used to clr uart tx-done,which means set tx-done to 0 + * @param[in] uart_num + * @return none. + */ +static inline void uart_clr_tx_done(uart_num_e uart_num) +{ + reg_uart_state(uart_num) |=BIT(7); +} + +/** + * @brief This function is used to enable the rtx function of . + * @param[in] chn - UART0 or UART1. + * @return none. + */ +static inline void uart_rtx_en(uart_num_e chn) +{ + reg_uart_rx_timeout1(chn)|=FLD_UART_P7816_EN; +} + +#endif /* UART_H_ */ diff --git a/b91/b91m_ble_sdk/drivers/B91/usbhw.c b/b91/b91m_ble_sdk/drivers/B91/usbhw.c new file mode 100755 index 0000000..ceac066 --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/usbhw.c @@ -0,0 +1,82 @@ +/******************************************************************************************************** + * @file usbhw.c + * + * @brief This is the source file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "usbhw.h" +/** + * @brief This function disables the manual interrupt + * (Endpont8 is the alias of endpoint0) + * @param[in] m - the irq mode needs to set + * @return none + */ +void usbhw_disable_manual_interrupt(int m) { + BM_SET(reg_ctrl_ep_irq_mode, m); +} + +/** + * @brief This function enable the manual interrupt + * @param[in] m - the irq mode needs to set + * @return none + */ +void usbhw_enable_manual_interrupt(int m) { + BM_CLR(reg_ctrl_ep_irq_mode, m); +} + +/** + * @brief This function sends a bulk of data to host via the specified endpoint + * @param[in] ep - the number of the endpoint + * @param[in] data - pointer to the data need to send + * @param[in] len - length in byte of the data need to send + * @return none + */ +void usbhw_write_ep(unsigned int ep, unsigned char * data, int len) { + reg_usb_ep_ptr(ep) = 0; + + for(int i = 0; i < (len); ++i){ + reg_usb_ep_dat(ep) = data[i]; + } + reg_usb_ep_ctrl(ep) = FLD_EP_DAT_ACK; // ACK +} + +/** + * @brief This function sends two bytes data to host via the control endpoint + * (handy help function) + * @param[in] v - the two bytes data need to send + * @return none + */ +void usbhw_write_ctrl_ep_u16(unsigned short v){ + usbhw_write_ctrl_ep_data(v & 0xff); + usbhw_write_ctrl_ep_data(v >> 8); +} + +/** + * @brief This function reads two bytes data from host via the control endpoint + * @param none + * @return the two bytes data read from the control endpoint + */ +unsigned short usbhw_read_ctrl_ep_u16(void){ + unsigned short v = usbhw_read_ctrl_ep_data(); + return (usbhw_read_ctrl_ep_data() << 8) | v; +} + + + + diff --git a/b91/b91m_ble_sdk/drivers/B91/usbhw.h b/b91/b91m_ble_sdk/drivers/B91/usbhw.h new file mode 100755 index 0000000..cb175ae --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/usbhw.h @@ -0,0 +1,423 @@ +/******************************************************************************************************** + * @file usbhw.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +/** @page USBHW + * + * Introduction + * =============== + * USB hard ware . + * + * API Reference + * =============== + * Header File: usbhw.h + */ + +#pragma once + +#include "reg_include/register_b91.h" +#include "analog.h" +#include "gpio.h" + +typedef enum +{ + USB_IRQ_RESET_MASK =BIT(0), + USB_IRQ_250US_MASK =BIT(1), + USB_IRQ_SUSPEND_MASK =BIT(2), +}usb_irq_mask_e; + +typedef enum +{ + USB_IRQ_RESET_STATUS =BIT(5), + USB_IRQ_250US_STATUS =BIT(6), + USB_IRQ_SUSPEND_STATUS =BIT(7), +}usb_irq_status_e; + + + +/** + * @brief This function servers to set ed8 to fifo mode. + * @return none. + */ +static inline void usbhw_set_ep8_fifo_mode(void) { + BM_SET(reg_usb_ep8_fifo_mode,FLD_USB_ENP8_FIFO_MODE); +} + +/** + * @brief This function servers to reset the pointer of control Endpoint. + * @return none. + */ +static inline void usbhw_reset_ctrl_ep_ptr(void) { + reg_ctrl_ep_ptr = 0; +} + +/** + * @brief This function servers to get the irq status of control Endpoint. + * @return none. + */ +static inline unsigned int usbhw_get_ctrl_ep_irq(void) { + return reg_ctrl_ep_irq_sta; +} + +/** + * @brief This function servers to clear the irq status of control Endpoint. + * @param[in] ep - selected the Endpoint + * @return none. + */ +static inline void usbhw_clr_ctrl_ep_irq(int ep) { +#ifdef WIN32 + BM_CLR(reg_ctrl_ep_irq_sta, ep); +#else + reg_ctrl_ep_irq_sta = ep; +#endif +} + +/** + * @brief This function servers to set the value of control Endpoint. + * @param[in] data - the value of control Endpoint + * @return none. + */ +static inline void usbhw_write_ctrl_ep_ctrl(unsigned char data) { + reg_ctrl_ep_ctrl = data; +} + +/** + * @brief This function servers to read the data of control Endpoint. + * @return the value of control Endpoint data + */ +static inline unsigned char usbhw_read_ctrl_ep_data(void) { + return reg_ctrl_ep_dat; +} + +/** + * @brief This function servers to write the data of control Endpoint. + * @param[in] data - the data of control Endpoint to write + * @return none + */ +static inline void usbhw_write_ctrl_ep_data(unsigned char data) { + reg_ctrl_ep_dat = data; +} + +/** + * @brief This function servers to determine whether control Endpoint is busy. + * @return 1: busy; 0: not busy. + */ +static inline int usbhw_is_ctrl_ep_busy(void) { + return reg_ctrl_ep_irq_sta & FLD_USB_EP_BUSY; +} + + +/** + * @brief This function servers to reset the pointer of Endpoint. + * @param[in] ep - select the Endpoint + * @return none. + */ +static inline void usbhw_reset_ep_ptr(unsigned int ep) { + reg_usb_ep_ptr(ep) = 0; +} + +/** + * @brief This function servers to set the irq mask of Endpoint. + * @return none. + */ +static inline void usbhw_set_eps_irq_mask(usb_ep_irq_e mask) +{ + reg_usb_ep_irq_mask|=mask; + +} + +/** + * @brief This function servers to clr the irq mask of Endpoint. + * @return none. + */ +static inline void usbhw_clr_eps_irq_mask(usb_ep_irq_e mask) +{ + reg_usb_ep_irq_mask &=(~mask); + +} + +/** + * @brief This function servers to get the irq status of Endpoint. + * @return none. + */ +static inline unsigned int usbhw_get_eps_irq(void) { + return reg_usb_ep_irq_status; +} + +/** + * @brief This function servers to clear the irq status of Endpoint. + * @param[in] ep - selected the Endpoint + * @return none. + */ +static inline void usbhw_clr_eps_irq(int ep) { + reg_usb_ep_irq_status = ep; +} + +/** + * @brief This function servers to set usb irq mask. + * @param[in] mask -the irq mask of usb. + * @return none. + */ +static inline void usbhw_set_irq_mask( usb_irq_mask_e mask) +{ + reg_usb_irq_mask|=mask; +} + +/** + * @brief This function servers to clr usb irq mask. + * @param[in] mask -the irq mask of usb. + * @return none. + */ +static inline void usbhw_clr_irq_mask( usb_irq_mask_e mask) +{ + reg_usb_irq_mask &= (~mask); +} + +/** + * @brief This function servers to get usb irq status. + * @param[in] status -the irq status of usb. + * @return the status of irq. + */ +static inline unsigned char usbhw_get_irq_status(usb_irq_status_e status) +{ + return reg_usb_irq_mask&status; +} + +/** + * @brief This function servers to clr usb irq status. + * @param[in] status -the irq status of usb. + * @return none. + */ +static inline void usbhw_clr_irq_status(usb_irq_status_e status) +{ + reg_usb_irq_mask|=status; +} + + +/** + * @brief This function servers to enable Endpoint. + * @param[in] ep - selected the Endpoint + * @return none. + */ +static inline void usbhw_set_eps_en(usb_ep_en_e ep) +{ + reg_usb_edp_en= ep; +} + +/** + * @brief This function servers to enable Endpoint. + * @param[in] ep - selected the Endpoint + * @return none. + */ +static inline void usbhw_set_eps_dis(usb_ep_en_e ep) +{ + reg_usb_edp_en &=(~ ep); +} + +/** + * @brief This function servers to read the data of Endpoint. + * @param[in] ep - selected the Endpoint + * @return the value of Endpoint + */ +static inline unsigned char usbhw_read_ep_data(unsigned int ep) { + return reg_usb_ep_dat(ep); +} + +/** + * @brief This function servers to write the data of Endpoint. + * @param[in] ep - selected the Endpoint + * @param[in] data - the value of Endpoint + * @return none + */ +static inline void usbhw_write_ep_data(unsigned int ep, unsigned char data) { + reg_usb_ep_dat(ep) = data; +} + + + +/** + * @brief This function servers to enable the specified Endpoint. + * @param[in] ep - selected the Endpoint + * @param[in] en - 1:enable,0:disable + * @return none + */ +static inline void usbhw_set_ep_en(unsigned int ep, unsigned char en) { + if(en) + { + reg_usb_edp_en |= ep; + } + else + { + reg_usb_edp_en &= ~(ep); + } +} + +/** + * @brief This function servers to determine whether Endpoint is busy. + * @param[in] ep - selected the Endpoint + * @return 1: busy; 0: not busy. + */ +static inline unsigned int usbhw_is_ep_busy(unsigned int ep) { + return reg_usb_ep_ctrl(ep) & FLD_USB_EP_BUSY; +} + +/** + * @brief This function servers to set the specified data EndPoint to ack. + * @param[in] ep - select the data EndPoint. + * @return none. + */ +static inline void usbhw_data_ep_ack(unsigned int ep) { + reg_usb_ep_ctrl(ep) = FLD_USB_EP_BUSY; +} + +/** + * @brief This function servers to set the specified data EndPoint to stall. + * @param[in] ep - select the data EndPoint. + * @return none. + */ +static inline void usbhw_data_ep_stall(unsigned int ep) { + reg_usb_ep_ctrl(ep) = FLD_USB_EP_STALL; +} + + +/** + * @brief This function servers to set the threshold of printer. + * @param[in] th - set the threshold for printer + * @return none. + */ +static inline void usbhw_set_printer_threshold(unsigned char th) { + reg_usb_ep8_send_thre = th; +} + +enum { + USB_EDP_PRINTER_IN = 8, // default hw buf len = 64 + USB_EDP_MOUSE = 2, // default hw buf len = 8 + USB_EDP_KEYBOARD_IN = 1, // default hw buf len = 8 + USB_EDP_IN = 3, // default hw buf len = 16 + USB_EDP_AUDIO_IN = 4, // default hw buf len = 64 + USB_EDP_PRINTER_OUT = 5, // default hw buf len = 64 + USB_EDP_SPEAKER = 6, // default hw buf len = 16 + USB_EDP_MIC = 7, // default hw buf len = 16 + USB_EDP_MS_IN = USB_EDP_PRINTER_IN, // mass storage + USB_EDP_MS_OUT = USB_EDP_PRINTER_OUT, + USB_EDP_SOMATIC_IN = USB_EDP_AUDIO_IN, // when USB_SOMATIC_ENABLE, USB_EDP_PRINTER_OUT disable + USB_EDP_SOMATIC_OUT = USB_EDP_PRINTER_OUT, + USB_EDP_CDC_IN = 4, + USB_EDP_CDC_OUT = 5, +}; + +// #defined in the standard spec +enum { + USB_HID_AUDIO = 2, + USB_HID_MOUSE = 1, + USB_HID_KB_MEDIA = 3,// media + USB_HID_KB_SYS = 4,// system : power,sleep,wakeup + USB_HID_SOMATIC = 5,// somatic sensor, may have many report ids +}; + + +/** + * @brief This function disables the manual interrupt + * (Endpont8 is the alias of endpoint0) + * @param[in] m - the irq mode needs to set + * @return none + */ +void usbhw_disable_manual_interrupt(int m); + +/** + * @brief This function enable the manual interrupt + * @param[in] m - the irq mode needs to set + * @return none + */ +void usbhw_enable_manual_interrupt(int m); + +/** + * @brief This function sends a bulk of data to host via the specified endpoint + * @param[in] ep - the number of the endpoint + * @param[in] data - pointer to the data need to send + * @param[in] len - length in byte of the data need to send + * @return none + */ +void usbhw_write_ep(unsigned int ep, unsigned char * data, int len); + +/** + * @brief This function sends two bytes data to host via the control endpoint + * (handy help function) + * @param[in] v - the two bytes data need to send + * @return none + */ +void usbhw_write_ctrl_ep_u16(unsigned short v); + +/** + * @brief This function reads two bytes data from host via the control endpoint + * @return the two bytes data read from the control endpoint + */ +unsigned short usbhw_read_ctrl_ep_u16(void); + +/** + * @brief This function enables or disables the internal pull-up resistor of DP pin of USB interface + * @param[in] en - enables or disables the internal pull-up resistor(1: enable 0: disable) + * @return none + */ +static inline void usb_dp_pullup_en (int en) +{ + unsigned char dat = analog_read_reg8(0x0b); + if (en) { + dat = dat | BIT(7); + } + else + { + dat = dat & 0x7f ; + } + + analog_write_reg8 (0x0b, dat); +} + +/** + * @brief This function serves to power on or down USB module + * @param[in] en - 1: power on 0: power down + * @return none + */ +static inline void usb_power_on(unsigned char en) +{ + if(en) + { + analog_write_reg8(0x7d,analog_read_reg8(0x7d)&0xfd); + } + else + { + analog_write_reg8(0x7d,analog_read_reg8(0x7d)|0x02); + } +} + +/** + * @brief This function serves to set GPIO MUX function as DP and DM pin of USB + * @return none. + */ +static inline void usb_set_pin_en(void) +{ + reg_gpio_func_mux(GPIO_PA5)=reg_gpio_func_mux(GPIO_PA5)&(~BIT_RNG(2,3)); + gpio_function_dis(GPIO_PA5); + reg_gpio_func_mux(GPIO_PA6)=reg_gpio_func_mux(GPIO_PA6)&(~BIT_RNG(4,5)); + gpio_function_dis(GPIO_PA6); + gpio_input_en(GPIO_PA5|GPIO_PA6);//DP/DM must set input enable + usb_dp_pullup_en (1); +} diff --git a/b91/b91m_ble_sdk/drivers/B91/watchdog.h b/b91/b91m_ble_sdk/drivers/B91/watchdog.h new file mode 100755 index 0000000..0870b9b --- /dev/null +++ b/b91/b91m_ble_sdk/drivers/B91/watchdog.h @@ -0,0 +1,82 @@ +/******************************************************************************************************** + * @file watchdog.h + * + * @brief This is the header file for B91 + * + * @author Driver Group + * @date 2019 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef WATCHDOG_H_ +#define WATCHDOG_H_ +#include "analog.h" +#include "gpio.h" + +/** + * @brief start watchdog. + * @return none + */ +static inline void wd_start(void){ + + BM_SET(reg_tmr_ctrl2, FLD_TMR_WD_EN); +} + + +/** + * @brief stop watchdog. + * @return none + */ +static inline void wd_stop(void){ + BM_CLR(reg_tmr_ctrl2, FLD_TMR_WD_EN); +} + + +/** + * @brief clear watchdog. + * @return none + */ +static inline void wd_clear(void) +{ + reg_tmr_sta = FLD_TMR_STA_WD|FLD_TMR_WD_CNT_CLR; + +} + +/** + * @brief clear watchdog timer tick cnt. + * @return none + */ +static inline void wd_clear_cnt(void) +{ + reg_tmr_sta = FLD_TMR_WD_CNT_CLR; + +} + +/** + * @brief This function set the watchdog trigger time. + * Because the lower 8bit of the wd timer register will always be 0, there will be an error , + The time error = (0x00~0xff)/(APB clock frequency) + * @param[in] period_ms - The watchdog trigger time. Unit is millisecond + * @return none + * @attention The clock source of watchdog comes from pclk, when pclk changes it needs to be reconfigured. + */ +static inline void wd_set_interval_ms(unsigned int period_ms) +{ + static unsigned int tmp_period_ms = 0; + tmp_period_ms=period_ms*sys_clk.pclk*1000; + reg_wt_target=tmp_period_ms; +} + +#endif diff --git a/b91/b91m_ble_sdk/proj_lib/firmware_encrypt.h b/b91/b91m_ble_sdk/proj_lib/firmware_encrypt.h new file mode 100755 index 0000000..a803ccb --- /dev/null +++ b/b91/b91m_ble_sdk/proj_lib/firmware_encrypt.h @@ -0,0 +1,28 @@ +/******************************************************************************************************** + * @file firmware_encrypt.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef ENCRYPT_H_ +#define ENCRYPT_H_ + +void firmware_encrypt_based_on_uid(unsigned char* uid,unsigned char* ciphertext); + +#endif /* ENCRYPT_H_ */ diff --git a/b91/b91m_ble_sdk/proj_lib/liblt_9518.a b/b91/b91m_ble_sdk/proj_lib/liblt_9518.a new file mode 100755 index 0000000..534758c Binary files /dev/null and b/b91/b91m_ble_sdk/proj_lib/liblt_9518.a differ diff --git a/b91/b91m_ble_sdk/sdk_version.txt b/b91/b91m_ble_sdk/sdk_version.txt new file mode 100755 index 0000000..fadd198 --- /dev/null +++ b/b91/b91m_ble_sdk/sdk_version.txt @@ -0,0 +1,2 @@ +Telink BLE SDK_VERSION = +telink_b91_ble_sdk_beta_v4.0.1.0 diff --git a/b91/b91m_ble_sdk/stack/ble/ble.h b/b91/b91m_ble_sdk/stack/ble/ble.h new file mode 100755 index 0000000..df86acf --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/ble.h @@ -0,0 +1,50 @@ +/******************************************************************************************************** + * @file ble.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef BLE_H_ +#define BLE_H_ + + +#include "ble_config.h" +#include "ble_common.h" +#include "ble_format.h" + +#include "controller/ble_controller.h" +#include "host/ble_host.h" + +#include "hci/hci.h" +#include "hci/hci_const.h" +#include "hci/hci_cmd.h" +#include "hci/hci_event.h" + +#include "service/ota/ota.h" +#include "service/ota/ota_server.h" +#include "service/device_information.h" +#include "service/hids.h" +#include "service/uuid.h" + + + + + + +#endif /* BLE_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/ble_common.h b/b91/b91m_ble_sdk/stack/ble/ble_common.h new file mode 100755 index 0000000..05daeaf --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/ble_common.h @@ -0,0 +1,358 @@ +/******************************************************************************************************** + * @file ble_common.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef BLE_COMMON_H +#define BLE_COMMON_H + +#include "tl_common.h" + + + + + +typedef enum { + BLE_SUCCESS = 0, + +//// HCI Status, See the Core_v5.0(Vol 2/Part D/1.3 "list of Error Codes") for more information) + HCI_ERR_UNKNOWN_HCI_CMD = 0x01, + HCI_ERR_UNKNOWN_CONN_ID = 0x02, + HCI_ERR_HW_FAILURE = 0x03, + HCI_ERR_PAGE_TIMEOUT = 0x04, + HCI_ERR_AUTH_FAILURE = 0x05, + HCI_ERR_PIN_KEY_MISSING = 0x06, + HCI_ERR_MEM_CAP_EXCEEDED = 0x07, + HCI_ERR_CONN_TIMEOUT = 0x08, + HCI_ERR_CONN_LIMIT_EXCEEDED = 0x09, + HCI_ERR_SYNCH_CONN_LIMIT_EXCEEDED = 0x0A, + HCI_ERR_CONN_ALREADY_EXISTS = 0x0B, + HCI_ERR_CMD_DISALLOWED = 0x0C, + HCI_ERR_CONN_REJ_LIMITED_RESOURCES = 0x0D, + HCI_ERR_CONN_REJECTED_SECURITY_REASONS = 0x0E, + HCI_ERR_CONN_REJECTED_UNACCEPTABLE_BDADDR = 0x0F, + HCI_ERR_CONN_ACCEPT_TIMEOUT_EXCEEDED = 0x10, + HCI_ERR_UNSUPPORTED_FEATURE_PARAM_VALUE = 0x11, + HCI_ERR_INVALID_HCI_CMD_PARAMS = 0x12, + HCI_ERR_REMOTE_USER_TERM_CONN = 0x13, + HCI_ERR_REMOTE_DEVICE_TERM_CONN_LOW_RESOURCES = 0x14, + HCI_ERR_REMOTE_DEVICE_TERM_CONN_POWER_OFF = 0x15, + HCI_ERR_CONN_TERM_BY_LOCAL_HOST = 0x16, + HCI_ERR_REPEATED_ATTEMPTS = 0x17, + HCI_ERR_PAIRING_NOT_ALLOWED = 0x18, + HCI_ERR_UNKNOWN_LMP_PDU = 0x19, + HCI_ERR_UNSUPPORTED_REMOTE_FEATURE = 0x1A, + HCI_ERR_SCO_OFFSET_REJ = 0x1B, + HCI_ERR_SCO_INTERVAL_REJ = 0x1C, + HCI_ERR_SCO_AIR_MODE_REJ = 0x1D, + HCI_ERR_INVALID_LMP_PARAMS = 0x1E, + HCI_ERR_UNSPECIFIED_ERROR = 0x1F, + HCI_ERR_UNSUPPORTED_LMP_PARAM_VAL = 0x20, + HCI_ERR_ROLE_CHANGE_NOT_ALLOWED = 0x21, + HCI_ERR_LMP_LL_RESP_TIMEOUT = 0x22, + HCI_ERR_LMP_ERR_TRANSACTION_COLLISION = 0x23, + HCI_ERR_LMP_PDU_NOT_ALLOWED = 0x24, + HCI_ERR_ENCRYPT_MODE_NOT_ACCEPTABLE = 0x25, + HCI_ERR_LINK_KEY_CAN_NOT_BE_CHANGED = 0x26, + HCI_ERR_REQ_QOS_NOT_SUPPORTED = 0x27, + HCI_ERR_INSTANT_PASSED = 0x28, + HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED = 0x29, + HCI_ERR_DIFFERENT_TRANSACTION_COLLISION = 0x2A, + HCI_ERR_RESERVED1 = 0x2B, + HCI_ERR_QOS_UNACCEPTABLE_PARAM = 0x2C, + HCI_ERR_QOS_REJ = 0x2D, + HCI_ERR_CHAN_ASSESSMENT_NOT_SUPPORTED = 0x2E, + HCI_ERR_INSUFFICIENT_SECURITY = 0x2F, + HCI_ERR_PARAM_OUT_OF_MANDATORY_RANGE = 0x30, + HCI_ERR_RESERVED2 = 0x31, + HCI_ERR_ROLE_SWITCH_PENDING = 0x32, + HCI_ERR_RESERVED3 = 0x33, + HCI_ERR_RESERVED_SLOT_VIOLATION = 0x34, + HCI_ERR_ROLE_SWITCH_FAILED = 0x35, + HCI_ERR_EXTENDED_INQUIRY_RESP_TOO_LARGE = 0x36, + HCI_ERR_SIMPLE_PAIRING_NOT_SUPPORTED_BY_HOST = 0x37, + HCI_ERR_HOST_BUSY_PAIRING = 0x38, + HCI_ERR_CONN_REJ_NO_SUITABLE_CHAN_FOUND = 0x39, + HCI_ERR_CONTROLLER_BUSY = 0x3A, + HCI_ERR_UNACCEPTABLE_CONN_INTERVAL = 0x3B, + HCI_ERR_ADVERTISING_TIMEOUT = 0x3C, + HCI_ERR_CONN_TERM_MIC_FAILURE = 0x3D, + HCI_ERR_CONN_FAILED_TO_ESTABLISH = 0x3E, + HCI_ERR_MAC_CONN_FAILED = 0x3F, + HCI_ERR_COARSE_CLOCK_ADJUSTMENT_REJECT = 0x40, + HCI_ERR_TYPE0_SUBMAP_NOT_DEFINED = 0x41, + HCI_ERR_UNKNOWN_ADV_IDENTIFIER = 0x42, + HCI_ERR_LIMIT_REACHED = 0x43, + HCI_ERR_OP_CANCELLED_BY_HOST = 0x44, + HCI_ERR_PACKET_TOO_LONG = 0x45, + //DBG used only for CIS + HCI_ERR_CONN_TERM_CIS_MIC_FAILURE = 0xD3, + + + + +///////////////////////// TELINK define status ///////////////////////////// + + //LL status + LL_ERR_CONNECTION_NOT_ESTABLISH = 0x80, + LL_ERR_TX_FIFO_NOT_ENOUGH, + LL_ERR_ENCRYPTION_BUSY, + LL_ERR_CURRENT_STATE_NOT_SUPPORTED_THIS_CMD, + LL_ERR_INVALID_PARAMETER, + LL_ERR_UNKNOWN_OPCODE, + + LL_ERR_CIS_SYNC_FAIL, + LL_ERR_CIS_DISCONNECT, + + + //L2CAP status + L2CAP_ERR_INVALID_PARAMETER = 0x90, + L2CAP_ERR_INVALID_HANDLE, + L2CAP_ERR_INSUFFICIENT_RESOURCES, + L2CAP_ERR_PSM_NOT_REGISTER, + L2CAP_ERR_CONTROL_NOT_READY, + L2CAP_ERR_PSM_HAVE_ESTABLISH, + + //SMP status + SMP_ERR_INVALID_PARAMETER = 0xA0, + SMP_ERR_PAIRING_BUSY, + + //GATT status + GATT_ERR_INVALID_PARAMETER = 0xB0, + GATT_ERR_PREVIOUS_INDICATE_DATA_HAS_NOT_CONFIRMED, + GATT_ERR_SERVICE_DISCOVERY_TIEMOUT, + GATT_ERR_NOTIFY_INDICATION_NOT_PERMITTED, + GATT_ERR_DATA_PENDING_DUE_TO_SERVICE_DISCOVERY_BUSY, + GATT_ERR_DATA_LENGTH_EXCEED_MTU_SIZE, + + //GAP status + GAP_ERR_INVALID_PARAMETER = 0xC0, + //IAL + IAL_ERR_SDU_LEN_EXCEED_SDU_MAX, + IAL_ERR_LOSS_SDU_INTRVEL, + IAL_ERR_ISO_TX_FIFO_NOT_ENOUGH, + IAL_ERR_SDU_BUFF_INVALID, + IAL_ERR_EVENT_PASSED, + + //Service status + SERVICE_ERR_INVALID_PARAMETER = 0xD0, + + + //Application buffer check error code + LL_ACL_RX_BUF_NO_INIT = 0xE0, + LL_ACL_RX_BUF_PARAM_INVALID, + LL_ACL_RX_BUF_SIZE_NOT_MEET_MAX_RX_OCT, + LL_ACL_TX_BUF_NO_INIT, + LL_ACL_TX_BUF_PARAM_INVALID, + LL_ACL_TX_BUF_SIZE_MUL_NUM_EXCEED_4K, + LL_ACL_TX_BUF_SIZE_NOT_MEET_MAX_TX_OCT, + + LL_CIS_RX_BUF_NO_INIT, + LL_CIS_RX_BUF_PARAM_INVALID, + LL_CIS_TX_BUF_NO_INIT, + LL_CIS_TX_BUF_PARAM_INVALID, + LL_CIS_RX_EVT_BUF_NO_INIT, + LL_CIS_RX_EVT_BUF_PARAM_INVALID, + + LL_BIS_TX_BUF_NO_INIT, + LL_BIS_TX_BUF_PARAM_INVALID, + LL_BIS_RX_BUF_NO_INIT, + LL_BIS_RX_BUF_PARAM_INVALID, + LL_BIS_RX_PDU_INVALID, + LL_BIS_RX_PDU_EMPTY, + LL_BIS_RX_EVT_BUF_NO_INIT, + LL_BIS_RX_EVT_BUF_PARAM_INVALID, + + HCI_ACL_DATA_BUF_PARAM_INVALID, + HCI_ACL_DATA_BUF_SIZE_NOT_MEET_MAX_TX_OCT, + +} ble_sts_t; + + + + + + + + + + + +/////////////////////////////// BLE MAC ADDRESS ////////////////////////////////////////////// +#define BLE_ADDR_PUBLIC 0 +#define BLE_ADDR_RANDOM 1 +#define BLE_ADDR_INVALID 0xff +#define BLE_ADDR_LEN 6 + + +//Definition for BLE Common Address Type +/* + * + * |--public ..................................................... BLE_DEVICE_ADDRESS_PUBLIC + * | + * Address Type --| |-- random static ................................. BLE_DEVICE_ADDRESS_RANDOM_STATIC + * | | + * |--random --| + * | |-- non_resolvable private ... BLE_DEVICE_ADDRESS_NON_RESOLVABLE_PRIVATE + * |-- random private --| + * |-- resolvable private ....... BLE_DEVICE_ADDRESS_RESOLVABLE_PRIVATE + * + */ + +#define BLE_DEVICE_ADDRESS_PUBLIC 1 +#define BLE_DEVICE_ADDRESS_RANDOM_STATIC 2 +#define BLE_DEVICE_ADDRESS_NON_RESOLVABLE_PRIVATE 3 +#define BLE_DEVICE_ADDRESS_RESOLVABLE_PRIVATE 4 + + + +#define IS_PUBLIC_ADDR(Type, Addr) ( (Type)==BLE_ADDR_PUBLIC) ) +#define IS_RANDOM_STATIC_ADDR(Type, Addr) ( (Type)==BLE_ADDR_RANDOM && (Addr[5] & 0xC0) == 0xC0 ) +#define IS_NON_RESOLVABLE_PRIVATE_ADDR(Type, Addr) ( (Type)==BLE_ADDR_RANDOM && (Addr[5] & 0xC0) == 0x00 ) +#define IS_RESOLVABLE_PRIVATE_ADDR(Type, Addr) ( (Type)==BLE_ADDR_RANDOM && (Addr[5] & 0xC0) == 0x40 ) + + +#define MAC_MATCH8(md,ms) (md[0]==ms[0] && md[1]==ms[1] && md[2]==ms[2] && md[3]==ms[3] && md[4]==ms[4] && md[5]==ms[5]) +#define MAC_MATCH16(md,ms) (md[0]==ms[0] && md[1]==ms[1] && md[2]==ms[2]) +#define MAC_MATCH32(md,ms) (md[0]==ms[0] && md[1]==ms[1]) +///////////////////////////////////////////////////////////////////////////// + + + + +/******************************************** ATT ***************************************************************/ +/** + * @brief Definition for Attribute protocol PDUs + */ +typedef enum{ + ATT_OP_ERROR_RSP = 0x01, + ATT_OP_EXCHANGE_MTU_REQ = 0x02, + ATT_OP_EXCHANGE_MTU_RSP = 0x03, + ATT_OP_FIND_INFORMATION_REQ = 0x04, ATT_OP_FIND_INFO_REQ = 0x04, + ATT_OP_FIND_INFORMATION_RSP = 0x05, ATT_OP_FIND_INFO_RSP = 0x05, + ATT_OP_FIND_BY_TYPE_VALUE_REQ = 0x06, + ATT_OP_FIND_BY_TYPE_VALUE_RSP = 0x07, + ATT_OP_READ_BY_TYPE_REQ = 0x08, + ATT_OP_READ_BY_TYPE_RSP = 0x09, + ATT_OP_READ_REQ = 0x0A, + ATT_OP_READ_RSP = 0x0B, + ATT_OP_READ_BLOB_REQ = 0x0C, + ATT_OP_READ_BLOB_RSP = 0x0D, + ATT_OP_READ_MULTIPLE_REQ = 0x0E, ATT_OP_READ_MULTI_REQ = 0x0E, + ATT_OP_READ_MULTIPLE_RSP = 0x0F, + ATT_OP_READ_BY_GROUP_TYPE_REQ = 0x10, + ATT_OP_READ_BY_GROUP_TYPE_RSP = 0x11, + ATT_OP_WRITE_REQ = 0x12, + ATT_OP_WRITE_RSP = 0x13, + ATT_OP_PREPARE_WRITE_REQ = 0x16, + ATT_OP_PREPARE_WRITE_RSP = 0x17, + ATT_OP_EXECUTE_WRITE_REQ = 0x18, + ATT_OP_EXECUTE_WRITE_RSP = 0x19, + + ATT_OP_HANDLE_VALUE_NTF = 0x1B, ATT_OP_HANDLE_VALUE_NOTI = 0x1B, + ATT_OP_HANDLE_VALUE_IND = 0x1D, + ATT_OP_HANDLE_VALUE_CFM = 0x1E, + + ATT_OP_READ_MULTIPLE_VARIABLE_REQ = 0x20, //core_5.2 + ATT_OP_READ_MULTIPLE_VARIABLE_RSP = 0x21, //core_5.2 + ATT_OP_MULTIPLE_HANDLE_VALUE_NTF = 0x23, //core_5.2 + + ATT_OP_WRITE_CMD = 0x52, + ATT_OP_SIGNED_WRITE_CMD = 0xD2, +}att_pdu_type; + + + +/******************************************** GAP ***************************************************************/ + +// https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile/ +// EIR Data Type, Advertising Data Type (AD Type) and OOB Data Type Definitions + +typedef enum { + DT_FLAGS = 0x01, // Flag + DT_INCOMPLT_LIST_16BIT_SERVICE_UUID = 0x02, // Incomplete List of 16-bit Service Class UUIDs + DT_COMPLETE_LIST_16BIT_SERVICE_UUID = 0x03, // Complete List of 16-bit Service Class UUIDs + DT_INCOMPLT_LIST_32BIT_SERVICE_UUID = 0x04, // Incomplete List of 32-bit Service Class UUIDs + DT_COMPLETE_LIST_32BIT_SERVICE_UUID = 0x05, // Complete List of 32-bit Service Class UUIDs + DT_INCOMPLT_LIST_128BIT_SERVICE_UUID = 0x06, // Incomplete List of 128-bit Service Class UUIDs + DT_COMPLETE_LIST_128BIT_SERVICE_UUID = 0x07, // Complete List of 128-bit Service Class UUIDs + DT_SHORTENED_LOCAL_NAME = 0x08, // Shortened Local Name + DT_COMPLETE_LOCAL_NAME = 0x09, // Complete Local Name + DT_TX_POWER_LEVEL = 0x0A, // Tx Power Level + + DT_CLASS_OF_DEVICE = 0x0D, // Class of Device + + DT_APPEARANCE = 0x19, // Appearance + + DT_CHM_UPT_IND = 0x28, // Channel Map Update Indication + DT_BIGINFO = 0x2C, // BIGInfo + DT_BROADCAST_CODE = 0x2D, // Broadcast_Code + DT_3D_INFORMATION_DATA = 0x3D, // 3D Information Data + + DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF, // Manufacturer Specific Data +}data_type_t; + + + + + + + +/** + * @brief HCI ACL DATA buffer length = LE_ACL_Data_Packet_Length + 4, pkt_len is integer multiple of 4, so result is 4 Byte align + * 4 = 2(connHandle) + 1(PBFlag) + 1(length) + */ +#define CALCULATE_HCI_ACL_DATA_FIFO_SIZE(pkt_len) ((pkt_len) + 4) + + + +/** + * @brief 6 = header(2)+l2cap_len(2)+CID(2) + */ +#define CAL_MTU_BUFF_SIZE(n) (((n + 6) + 3)/4 * 4) + +/** + * @brief 12 = type(1) + len(1) + l2cap_len(2) + cid(2) + sud_len(2) + mic(4) + */ +#define L2CAP_ALLIGN4_KFRAM_DMA_BUFF(n) (((n + 12) + 3) / 4 * 4) + +// 7 = rf_packet_ll_data_t +#define CIS_PDU_ALLIGN4_TXBUFF(n) DATA_LENGTH_ALLIGN4((CAL_LL_ISO_TX_FIFO_SIZE(n) + DATA_LENGTH_ALLIGN4(CIS_TX_PDU_BUFFER_LENGTH -7))) + +#define CIS_PDU_ALLIGN4_RXBUFF(n) DATA_LENGTH_ALLIGN4(CAL_LL_ISO_RX_FIFO_SIZE(n) ) + +#define BIS_PDU_ALLIGN4_TXBUFF(n) DATA_LENGTH_ALLIGN4((CAL_LL_ISO_TX_FIFO_SIZE(n) + DATA_LENGTH_ALLIGN4(BIS_TX_PDU_BUFFER_LENGTH - 7))) + +#define BIS_PDU_ALLIGN4_RXBUFF(n) DATA_LENGTH_ALLIGN4(BIS_LL_RX_PDU_FIFO_SIZE(n)) + +#define IAL_SDU_ALLIGN4_BUFF(n) (((n + 16) + 3) / 4 * 4) + +#define HCI_ISO_ALLIGN4_BUFF(n) (((n + 4) + 3) / 4 * 4) //DMA len 4 + + + + + + + + + + +#endif diff --git a/b91/b91m_ble_sdk/stack/ble/ble_config.h b/b91/b91m_ble_sdk/stack/ble/ble_config.h new file mode 100755 index 0000000..993dcfe --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/ble_config.h @@ -0,0 +1,200 @@ +/******************************************************************************************************** + * @file ble_config.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +////////////////////////////////////////////////////////////////////////////// +/** + * @brief Definition for Device info + */ +#include "drivers.h" +#include "tl_common.h" + +#define BQB_TEST_EN 0 +//BQB Test +#if BQB_TEST_EN + #define BQB_TEST_PHY_EN 1 + #define BQB_TEST_CONN_UPD_EN 1 + #define BQB_TEST_CHN_MAP_EN 1 +#else + #define BQB_TEST_PHY_EN 0 + #define BQB_TEST_CONN_UPD_EN 0 + #define BQB_TEST_CHN_MAP_EN 0 +#endif + + +/////////////////// Feature //////////////////////////// +#ifndef LL_MULTI_SLAVE_MAC_ENABLE +#define LL_MULTI_SLAVE_MAC_ENABLE 0 +#endif + +////////////////////////////////////////////////////////////////////// +//note both the following two macro XXX_PRIVATE_XXX and XXX_NORMAL_XXX +//CAN NOT be set 1 at the same time.One is private,another is standard. +#ifndef LL_FEATURE_PRIVATE_BIS_SYNC_RECEIVER +#define LL_FEATURE_PRIVATE_BIS_SYNC_RECEIVER 0 +#endif + +#ifndef LL_FEATURE_NORMAL_BIS_SYNC_RECEIVER +#define LL_FEATURE_NORMAL_BIS_SYNC_RECEIVER 1 +#endif +////////////////////////////////////////////////////////////////////// + + +#if(MCU_CORE_TYPE == MCU_CORE_825x) + #define FIX_HW_CRC24_EN 1 + #define HW_ECDH_EN 0 +#elif(MCU_CORE_TYPE == MCU_CORE_827x) + #define FIX_HW_CRC24_EN 0 + #define HW_ECDH_EN 1 +#elif(MCU_CORE_TYPE == MCU_CORE_9518) + #define FIX_HW_CRC24_EN 0 + #define HW_ECDH_EN 1 +#else + #error "unsupported mcu type !" +#endif + +//conn param update/map update +#ifndef BLS_PROC_MASTER_UPDATE_REQ_IN_IRQ_ENABLE +#define BLS_PROC_MASTER_UPDATE_REQ_IN_IRQ_ENABLE 0 //TODO: +#endif + + +#ifndef LE_AUTHENTICATED_PAYLOAD_TIMEOUT_SUPPORT_EN +#define LE_AUTHENTICATED_PAYLOAD_TIMEOUT_SUPPORT_EN 0 +#endif + + +//Link layer feature enable flag default setting +#ifndef LL_FEATURE_SUPPORT_LE_DATA_LENGTH_EXTENSION +#define LL_FEATURE_SUPPORT_LE_DATA_LENGTH_EXTENSION 1 +#endif + +#ifndef LL_FEATURE_SUPPORT_LL_PRIVACY +#define LL_FEATURE_SUPPORT_LL_PRIVACY 0 //TODO: legAdv and slave role conn support now +#endif + +#ifndef LL_FEATURE_SUPPORT_LE_2M_PHY +#define LL_FEATURE_SUPPORT_LE_2M_PHY 1 +#endif + +#ifndef LL_FEATURE_SUPPORT_LE_CODED_PHY +#define LL_FEATURE_SUPPORT_LE_CODED_PHY 1 +#endif + +#ifndef LL_FEATURE_SUPPORT_LE_AOA_AOD +#define LL_FEATURE_SUPPORT_LE_AOA_AOD 0 +#endif + +#ifndef LL_FEATURE_SUPPORT_LE_EXTENDED_ADVERTISING +#define LL_FEATURE_SUPPORT_LE_EXTENDED_ADVERTISING 1 +#endif + +#ifndef LL_FEATURE_SUPPORT_LE_EXTENDED_SCANNING +#define LL_FEATURE_SUPPORT_LE_EXTENDED_SCANNING 1 +#endif + +#ifndef LL_FEATURE_SUPPORT_LE_EXTENDED_INITIATE +#define LL_FEATURE_SUPPORT_LE_EXTENDED_INITIATE 1 +#endif + +#ifndef LL_FEATURE_SUPPORT_LE_PERIODIC_ADVERTISING +#define LL_FEATURE_SUPPORT_LE_PERIODIC_ADVERTISING 1 +#endif + +#ifndef LL_FEATURE_SUPPORT_LE_PERIODIC_ADVERTISING_SYNC +#define LL_FEATURE_SUPPORT_LE_PERIODIC_ADVERTISING_SYNC 1 +#endif + +#ifndef LL_FEATURE_SUPPORT_CHANNEL_SELECTION_ALGORITHM2 +#define LL_FEATURE_SUPPORT_CHANNEL_SELECTION_ALGORITHM2 1 +#endif + + + + + + +//core_5.2 feature begin +#ifndef LL_FEATURE_SUPPORT_CONNECTED_ISOCHRONOUS_STREAM_MASTER +#define LL_FEATURE_SUPPORT_CONNECTED_ISOCHRONOUS_STREAM_MASTER 1 +#endif + +#ifndef LL_FEATURE_SUPPORT_CONNECTED_ISOCHRONOUS_STREAM_SLAVE +#define LL_FEATURE_SUPPORT_CONNECTED_ISOCHRONOUS_STREAM_SLAVE 1 +#endif + +#ifndef LL_FEATURE_SUPPORT_ISOCHRONOUS_BROADCASTER +#define LL_FEATURE_SUPPORT_ISOCHRONOUS_BROADCASTER 1 +#endif + +#ifndef LL_FEATURE_SUPPORT_SYNCHRONIZED_RECEIVER +#define LL_FEATURE_SUPPORT_SYNCHRONIZED_RECEIVER 1 +#endif + +#ifndef LL_FEATURE_SUPPORT_ISOCHRONOUS_CHANNELS +#define LL_FEATURE_SUPPORT_ISOCHRONOUS_CHANNELS 1 +#endif + +#ifndef LL_FEATURE_SUPPORT_ISOCHRONOUS_TEST_MODE +#define LL_FEATURE_SUPPORT_ISOCHRONOUS_TEST_MODE 1 +#endif +//core_5.2 feature end + + + +#ifndef BQB_LOWER_TESTER_ENABLE +#define BQB_LOWER_TESTER_ENABLE 0 +#endif + + + +#ifndef HCI_NEW_FIFO_FEATURE_ENABLE +#define HCI_NEW_FIFO_FEATURE_ENABLE 1 +#endif + + +#ifndef HCI_SEND_NUM_OF_CMP_AFT_ACK +#define HCI_SEND_NUM_OF_CMP_AFT_ACK 0 +#endif + + +#ifndef L2CAP_DATA_2_HCI_DATA_BUFFER_ENABLE +#define L2CAP_DATA_2_HCI_DATA_BUFFER_ENABLE 0 //just for debug +#endif + +#ifndef L2CAP_CREDIT_BASED_FLOW_CONTROL_MODE_EN +#define L2CAP_CREDIT_BASED_FLOW_CONTROL_MODE_EN 0 +#endif + + +#ifndef UPPER_TESTER_DBG_EN +#define UPPER_TESTER_DBG_EN 1 +#endif + +#ifndef UPPER_TESTER_HCI_LOG_EN +#define UPPER_TESTER_HCI_LOG_EN 1 +#endif + + + + diff --git a/b91/b91m_ble_sdk/stack/ble/ble_format.h b/b91/b91m_ble_sdk/stack/ble/ble_format.h new file mode 100755 index 0000000..9ad7ad0 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/ble_format.h @@ -0,0 +1,191 @@ +/******************************************************************************************************** + * @file ble_format.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef BLE_FORMAT_H +#define BLE_FORMAT_H + + +#include "stack/ble/ble_common.h" + + +typedef struct { + u8 llid :2; + u8 nesn :1; + u8 sn :1; + u8 md :1; + u8 rfu1 :3; + u8 rf_len; +}rf_acl_data_head_t; + + + +typedef struct { + u8 llid :2; + u8 nesn :1; + u8 sn :1; + u8 cie :1; + u8 rfu0 :1; + u8 npi :1; + u8 rfu1 :1; + u8 rf_len; +}rf_cis_data_hdr_t; + + + +typedef struct { + u8 llid :2; + u8 cssn :3; + u8 cstf :1; + u8 rfu0 :2; + u8 rf_len; +}rf_bis_data_hdr_t; + + + +typedef struct{ + u8 type; + u8 rf_len; + u8 opcode; + u8 cigId; + u8 cisId; + u8 phyM2S; + u8 phyS2M; + + u32 maxSduM2S :12; + u32 rfu0 :3; + u32 framed :1; + u32 maxSduS2M :12; + u32 rfu1 :4; + + u8 sduIntvlM2S[3]; //SDU_Interval_M_To_S(20 bits) + RFU(4 bits) + u8 sduIntvlS2M[3]; //SDU_Interval_S_To_M(20 bits) + RFU(4 bits) + + u16 maxPduM2S; + u16 maxPduS2M; + u8 nse; + u8 subIntvl[3]; //unit: uS + + u8 bnM2S:4; + u8 bnS2M:4; + u8 ftM2S; + u8 ftS2M; + u16 isoIntvl; //unit: 1.25 mS + + u8 cisOffsetMin[3]; + u8 cisOffsetMax[3]; + u16 connEventCnt; //similar to instant + +}rf_packet_ll_cis_req_t; + +typedef struct{ + u8 type; //RA(1)_TA(1)_RFU(2)_TYPE(4) + u8 rf_len; //LEN(6)_RFU(2) + u8 opcode; + u8 cisOffsetMin[3]; + u8 cisOffsetMax[3]; + u16 connEventCnt; +}rf_packet_ll_cis_rsp_t; + +typedef struct{ + u8 type; //RA(1)_TA(1)_RFU(2)_TYPE(4) + u8 rf_len; //LEN(6)_RFU(2) + u8 opcode; + u32 cisAccessAddr; //Access Address of the CIS + u8 cisOffset[3]; + u8 cigSyncDly[3]; + u8 cisSyncDly[3]; + u16 connEventCnt; +}rf_packet_ll_cis_ind_t; + +typedef struct{ + u8 type; + u8 rf_len; + u8 opcode; + u8 cig_id; + u8 cis_id; + u8 errorCode; +}rf_packet_ll_cis_terminate_t; + + + +typedef struct{ + union{ + rf_bis_data_hdr_t bisPduHdr; + rf_cis_data_hdr_t cisPduHdr; + rf_acl_data_head_t aclPduHdr; + struct{ + u8 type; + u8 rf_len; + }pduHdr; + }llPduHdr; /* LL PDU Header: 2 */ + u8 llPayload[1]; /* Max LL Payload length: 251 */ +}llPhysChnPdu_t; + +typedef struct{ + u32 dma_len; + llPhysChnPdu_t llPhysChnPdu; +}rf_packet_ll_data_t; + + + + + + + + +typedef struct{ + u8 type; + u8 rf_len; + u16 l2capLen; + u16 chanId; + u8 opcode; + u16 handle; + u8 dat[20]; +}rf_packet_att_t; + + +typedef struct{ + u8 type; + u8 rf_len; + u16 l2cap; + u16 chanid; + + u8 att; + u16 handle; + + u8 dat[20]; + +}rf_packet_att_data_t; + + + + + + + + + + + + + +#endif /* BLE_FORMAT_H */ diff --git a/b91/b91m_ble_sdk/stack/ble/bqb/bqb.h b/b91/b91m_ble_sdk/stack/ble/bqb/bqb.h new file mode 100755 index 0000000..91e621c --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/bqb/bqb.h @@ -0,0 +1,139 @@ +/******************************************************************************************************** + * @file bqb.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#ifndef STACK_BLE_BQB_BQB_H_ +#define STACK_BLE_BQB_BQB_H_ + + + +typedef int (*callback_testcase_t)(int, void*); + + + + +typedef enum { + + + TP_STATUS_ACL_CONN_PKT_MAX = 0, + TP_STATUS_CIS_CONN_PKT_MAX, + + + + TP_STATUS_CONN_UNKNOWN_RSP, + + TP_STATUS_CONNECTION_DATA_SEND, + + + TP_STATUS_ADV_PKT_MAX , + TP_STATUS_CONN_ESTABLISH , + TP_STATUS_CONN_TERMINATE , + + TP_STATUS_CONN_PARA_REQ , + TP_STATUS_CONN_PARA_UPDATE , + + TP_STATUS_CONNECTION_TIMEOUT , + TP_STATUS_CONNE_RCVD_L2CAP_DATA , + + TP_STATUS_CONN_MAP_REQ , + TP_STATUS_CONN_MAP_UPDATE , + TP_STATUS_CONN_DATA_LENGTH_EXCHANGE , + + TP_STATUS_CONN_BRX_MISS_END , + + TP_STATUS_L2CAP_DATA_IN_IRQ_RX , + + TP_STATUS_TERMINATE_IN_IRQ_RX , + TP_STATUS_BRX_START , + TP_STATUS_RECV_CERT_DATA , + TP_STATUS_PUSH_DATA_CRC_ERR , + TP_STATUS_PUSH_DATA_SN_ERR , + TP_STATUS_CONN_IN_IRQ_RX , + TP_STATUS_BRX_POST , + TP_STATUS_BRX_TX , + + + TP_STATUS_SCAN_HIT_MAX , + TP_STATUS_SCAN_RCVD_RSP , + TP_STATUS_SCAN_REQ_SENT , + TP_STATUS_CONN_HIT_MAX , + + TP_STATUS_CONN_RCVD_DAT , + TP_STATUS_CONN_REQ_SENT , + TP_STATUS_TIMEOUT , + TP_STATUS_CONNECTION_LOST , + TP_STATUS_CONN_PKT_MISSING , + TP_STATUS_CONNECTION_RETX_MAX , + + TP_STATUS_RCVD_NO_EMPTY_PKT , + TP_STATUS_CHN_MAP_FULL_USED , + + + TP_STATUS_CONN_PHY_UPDATE , + + TP_STATUS_CONNECTION_FEATURE_REQ , + + TP_STATUS_CONN_BTX_MIDDLE , + + + + + + + + + TP_STATUS_HCI_EVT_DISCONNECT = 0x80, + TP_STATUS_HCI_EVT_CONNECTION_COMPLETE, + TP_EVT_NUM_OF_COMPLETE_PACKETS, + TP_STATUS_HCI_EVT_LE_ADV_REPORT, + TP_STATUS_HCI_EVT_LE_CONNECTION_UPDATE_COMPLETE, + TP_STATUS_HCI_EVT_LE_READ_REMOTE_USED_FEATURES_COMPLET, + TP_STATUS_HCI_EVT_LE_LONG_TERM_KEY_REQUESTED, + TP_STATUS_HCI_EVT_LE_REMOTE_CONNECTION_PARAM_REQUEST, + TP_STATUS_HCI_EVT_LE_DATA_LENGTH_CHANGE, + TP_STATUS_HCI_EVT_LE_READ_LOCAL_P256_KEY_COMPLETE, + TP_STATUS_HCI_EVT_LE_GENERATE_DHKEY_COMPLETE, + TP_STATUS_HCI_EVT_LE_ENHANCED_CONNECTION_COMPLETE, + //... + TP_STATUS_HCI_EVT_LE_PHY_UPDATE_COMPLETE, + + TP_STATUS_HCI_EVT_LE_EXTENDED_ADVERTISING_REPORT, + TP_STATUS_HCI_EVT_LE_ADVERTISING_SET_TERMINATED , + + TP_STATUS_HCI_EVT_LE_CIS_ESTABLISHED, + TP_STATUS_HCI_EVT_LE_CIS_REQUESTED, + TP_STATUS_HCI_EVT_LE_CREATE_BIG_COMPLETE, + TP_STATUS_HCI_EVT_LE_BIG_SYNC_ESTABLILSHED, + TP_STATUS_HCI_EVT_LE_BIG_SYNC_LOST, + TP_EVT_UNKNOWN_PACKETS, + + + + TP_STATUS_INIT = 0x8000, +} tp_status_t; + + + + + + +#endif /* STACK_BLE_BQB_BQB_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/bqb/bqb_ll.h b/b91/b91m_ble_sdk/stack/ble/bqb/bqb_ll.h new file mode 100755 index 0000000..efc862b --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/bqb/bqb_ll.h @@ -0,0 +1,139 @@ +/******************************************************************************************************** + * @file bqb_ll.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef BQB_LL_H_ +#define BQB_LL_H_ + + +typedef struct { + + u16 testAclConnEvent_cnt; + u16 testAclConnEvent_numMax; + + u16 testCisConnEvent_cnt; + u16 testCisConnEvent_numMax; + + bool testAclConnPktMaxEnFlg; + bool testCisConnPktMaxEnFlg; + + + +} st_bqb_ll_t; + +extern st_bqb_ll_t bltBQB; + +extern u64 bqbIrqEvt_mask; + + + + + + +void tp_set_acl_conn_event_max(u16 m); +void tp_set_cis_conn_event_max(u16 m); + + + + + + + + + + +void test_case_function_register (char * testcase, callback_testcase_t func); +int exe_lower_tester_command (u8 *cmd); + + +void blc_bqb_ll_main_loop(void); + + + + + + + + + + + + + + + +void tp_set_adv_pkt_max (u16 m); +void tp_enable_advData_inrease(u8 en, s8 step); + +void tp_AdvAddress_companyId_exchange(void); +void tp_AdvAddress_companyAssignId_exchange(void); +void tp_AdvAddress_companyId_companyAssignId_mismatch(void); +//void tp_ScanRspAddress_companyId_exchange(void); +//void tp_ScanRspAddress_companyAssignId_exchange(void); +//void tp_ScanRspAddress_companyId_companyAssignId_mismatch(void); + + +void tp_enable_adv_scanRsp_Bad_CRC (u8 advBadCrc, u8 scanRspBadCrc ); + +void tp_set_conn_pkt_max (u32 m); + +void tp_flip_access_address (int n); +void tp_set_test_data (u8 type, u8 len, u8 d, int pkts); +void tp_set_manual_timeout (u32 timeout); +void tp_disable_more_data(u8 disable); +void tp_enbale_print_rcvd_data_connect(u8 en); +void tp_enbale_rcvd_l2cap_data_callback(u8 en); +void tp_disable_data_len_exchange(u8 en); +void tp_set_brx_missing_time(u32 time_ms); +void tp_set_brx_missing_delay_intervals(int interval_num); +void tp_enable_conn_pkt_Bad_CRC (u8 connBadCrc ); + + + +void tp_set_adv_pkt_max (u16 m); +void tp_disable_more_data(u8 disable); +void tp_set_conn_pkt_max(u32 m); +void tp_phy_req_col(u8 en); +void tp_phy_req_skip(u8 en); +void tp_phy_req_nochange(u8 en); +void tp_phy_no_common(u8 en); +void tp_set_test_data (u8 type, u8 len, u8 d, int pkts); +void tp_enbale_rcvd_l2cap_data_callback(u8 en); + + + + +void tp_set_test_pkt(u8 num); +void tp_SetPhyUpdate_Same(u8 en); +void tp_set_PhyUpdate_InsInPast(u8 en); +void tp_set_PhyReq_TO(u8 en); +void tp_set_DiffProc_ChnMap(u8 en); +void tp_set_DiffProc_ConUp(u8 en); +void tp_setRecv_no(u8 num); +void tp_set_PhyInd_TO(u8 en); +void tp_set_NoPhyReqChan(u8 en); +void tp_set_NoPhyRspChan(u8 en); + + + + + +#endif /* LL_BQB_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/bqb/ht_hci.h b/b91/b91m_ble_sdk/stack/ble/bqb/ht_hci.h new file mode 100755 index 0000000..815cabc --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/bqb/ht_hci.h @@ -0,0 +1,113 @@ +/******************************************************************************************************** + * @file ht_hci.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef STACK_BLE_BQB_BT_HCI_H_ +#define STACK_BLE_BQB_BT_HCI_H_ + + +#include "bqb.h" + +#include "stack/ble/hci/hci.h" +#include "stack/ble/hci/hci_const.h" +#include "stack/ble/hci/hci_cmd.h" +#include "stack/ble/hci/hci_event.h" + + + +typedef enum { + + + HT_ERR_EVT_TIMEOUT_START = 0x80, + HT_ERR_EVT_TIMEOUT_LE_CONNECTION_COMPLETE = HT_ERR_EVT_TIMEOUT_START + HCI_SUB_EVT_LE_CONNECTION_COMPLETE, + HT_ERR_EVT_TIMEOUT_LE_ADVERTISING_REPORT = HT_ERR_EVT_TIMEOUT_START + HCI_SUB_EVT_LE_ADVERTISING_REPORT, + HT_ERR_EVT_TIMEOUT_LE_CONNECTION_UPDATE_COMPLETE = HT_ERR_EVT_TIMEOUT_START + HCI_SUB_EVT_LE_CONNECTION_UPDATE_COMPLETE, + HT_ERR_EVT_TIMEOUT_LE_READ_REMOTE_USED_FEATURES_COMPLETE = HT_ERR_EVT_TIMEOUT_START + HCI_SUB_EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE, + + HT_ERR_EVT_TIMEOUT_LE_DATA_LENGTH_CHANGE = HT_ERR_EVT_TIMEOUT_START + HCI_SUB_EVT_LE_DATA_LENGTH_CHANGE, + HT_ERR_EVT_TIMEOUT_LE_PHY_UPDATE_COMPLETE = HT_ERR_EVT_TIMEOUT_START + HCI_SUB_EVT_LE_PHY_UPDATE_COMPLETE, + + + HT_ERR_EVT_TIMEOUT_DISCONNECTION_COMPLETE = HT_ERR_EVT_TIMEOUT_START + HCI_SUB_EVT_MAX + 0, + HT_ERR_EVT_TIMEOUT_NUM_OF_COMPLETE_PACKETS = HT_ERR_EVT_TIMEOUT_START + HCI_SUB_EVT_MAX + 1, + + + + HT_ERR_COMPLETE_EVT_TIMEOUT = 0xF0, + HT_ERR_STATUS_EVT_TIMEOUT = 0xF1, + HT_ERR_PARAM_LEN_ERR = 0xF2, + HT_ERR_OPCODE_ERR = 0xF3, + HT_ERR_UNEXPECT_STS = 0xF4, + + HOST_RX_FIFO_OVERFLOW = 0xF8, + CONTROLLER_RX_FIFO_OVERFLOW = 0xF9, +}ht_err_t; + + + + +extern hci_fifo_t host_hciTxfifo; +extern hci_fifo_t host_hciRxfifo; + + + +typedef int (*loop_func_t) (void); + + + + + + + + + +void ht_hci_init(void); + + +int blc_register_host_loop_func (void *p); +int blc_register_controller_loop_func (void *p); + + +int host_process_wait_hci_event (void); + +int host_hci_handler (u8 *p, int n); + + + + +ble_sts_t host_initHciTxFifo(u8 *pTxbuf, int fifo_size, int fifo_number); +ble_sts_t host_initHciRxFifo(u8 *pRxbuf, int fifo_size, int fifo_number); + +void host_register_hci_handler (void *prx, void *ptx); +int ht_hci_send_data (u32 h, u8 *para, int n); + + +void host_testcase_function_register (char * testcase, callback_testcase_t func); +int exe_upper_tester_command (u8 *cmd); + + + +void ht_reset_stack(void); + +int ht_set_test_result (int err_flag); + + +#endif /* STACK_BLE_BQB_BT_HCI_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/bqb/ht_hci_cmd.h b/b91/b91m_ble_sdk/stack/ble/bqb/ht_hci_cmd.h new file mode 100755 index 0000000..de86c16 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/bqb/ht_hci_cmd.h @@ -0,0 +1,332 @@ +/******************************************************************************************************** + * @file ht_hci_cmd.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef HT_HCI_CMD_H_ +#define HT_HCI_CMD_H_ + + + + + + + +/****************** Macro & Enumeration & Structure Definition for Stack, user can not use!!!! ******************/ + +typedef struct { + u8 hciType; + u8 ocf; + u8 ogf; + u8 paraLen; + u8 data[60]; +} hci_cmd_data_t; + +// Set ocf and ogf based opcodes +#define HCI_OPCODE(ogf, ocf) ((ocf) | ((ogf) << 10)) +// Obtain ogf and ocf from the opcode in the command +#define HCI_OGF(opcode) (((opcode) >> 10) & 0x003F) +#define HCI_OCF(opcode) ((opcode) & 0x03FF) + +/* + * Contains the following fields + * -> HCI Type (1) + * -> OGF & OCF (2) + * -> Parameter Len (1) + */ +#define HCI_CMD_HDR_LEN (4) + + //TODO:LEN +//--- OGF --- 0x01: Link Control Command +// -- OCF -- +#define HCI_INQUIRY_LEN 0x01 +#define HCI_DISCONNECT_LEN (3) +#define HCI_READ_REMOTE_NAME_REQ_LEN 0x19 +#define HCI_READ_REMOTE_VER_INFO_LEN 0x1D + + +//--- OGF --- 0x03: Controller & Baseband Commands +// -- OCF -- +#define HCI_SET_EVENT_MASK_LEN (8) +#define HCI_RESET_LEN (0) +#define HCI_SET_EVENT_FILTER_LEN 0x05 +#define HCI_WRITE_PIN_TYPE_LEN 0x0A +#define HCI_CREATE_NEW_UINT_KEY_LEN 0x0B +#define HCI_DELETE_STORED_LINK_KEY_LEN 0x12 +#define HCI_WRITE_LOCAL_NAME_LEN 0x13 +#define HCI_READ_LOCAL_NAME_LEN 0x14 +#define HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_LEN 0x16 +#define HCI_WRITE_PAGE_TIMEOUT_LEN 0x18 +#define HCI_WRITE_SCAN_ENABLE_LEN 0x1A +#define HCI_WRITE_PAGE_SCAN_ACTIVITY_LEN 0x1C +#define HCI_WRITE_INQUIRY_SCAN_ACTIVITY_LEN 0x1E +#define HCI_WRITE_AUTHENTICATION_ENABLE_LEN 0x20 +#define HCI_WRITE_CLASS_OF_DEVICE_LEN 0x24 +#define HCI_WRITE_VOICE_SETTING_LEN 0x26 +#define HCI_WRITE_NUM_BROADCAST_RETRANSMISSIONS_LEN 0x2A +#define HCI_WRITE_HOLD_MODE_ACTIVITY_LEN 0x2C +#define HCI_READ_TX_POWER_LEVEL_LEN 0x2D +#define HCI_SYNCHRONOUS_FLOW_CONTROL_ENABLE_LEN 0x2F +#define HCI_SET_CONTROLLER_TO_HOST_FLOW_CTRL_LEN 0x31 +#define HCI_HOST_BUF_SIZE_LEN 0x33 +#define HCI_HOST_NUM_OF_COMPLETE_PACKETS_LEN 0x35 +#define HCI_WRITE_CURRENT_IAC_LAP_LEN 0x3A +#define HCI_SET_AFH_HOST_CHN_CLASSIFICATION_LEN 0x3F +#define HCI_WRITE_INQUIRY_SCAN_TYPE_LEN 0x43 +#define HCI_WRITE_INQUIRY_MODE_LEN 0x45 +#define HCI_WRITE_PAGE_SCAN_TYPE_LEN 0x47 + + +//--- OGF --- 0x04: Informational Parameters +// -- OCF -- +#define HCI_READ_LOCAL_VER_INFO_LEN 0x01 +#define HCI_READ_LOCAL_SUPPORTED_CMDS_LEN 0x02 +#define HCI_READ_LOCAL_SUPPORTED_FEATURES_LEN 0x03 +#define HCI_READ_EXTENDED_LOCAL_SUPPORTED_FEATURES_LEN 0x04 +#define HCI_READ_BUFFER_SIZE_COMMAND_LEN 0x05 +#define HCI_READ_BD_ADDR_LEN (0) + + +//--- OGF --- 0x05: Status Parameters +// -- OCF -- +#define HCI_READ_RSSI_LEN 0x05 + + +//--- OGF --- 0x08: LE Controller Commands +// -- OCF -- +#define HCI_LE_SET_EVENT_MASK_LEN (8) +#define HCI_LE_READ_BUF_SIZE_LEN (0) +#define HCI_LE_READ_LOCAL_SUPPORTED_FEATURES_LEN 0x03 +#define HCI_LE_SET_RANDOM_ADDR_LEN (6) +#define HCI_LE_SET_ADVERTISE_PARAMETERS_LEN (15) +#define HCI_LE_READ_ADVERTISING_CHANNEL_TX_POWER_LEN 0x07 +//#define HCI_LE_SET_ADVERTISE_DATA_LEN +//#define HCI_LE_SET_SCAN_RSP_DATA_LEN +#define HCI_LE_SET_ADVERTISE_ENABLE_LEN (1) +#define HCI_LE_SET_SCAN_PARAMETERS_LEN (7) +#define HCI_LE_SET_SCAN_ENABLE_LEN (2) +#define HCI_LE_CREATE_CONNECTION_LEN (25) +#define HCI_LE_CREATE_CONNECTION_CANCEL_LEN 0x0E +#define HCI_LE_READ_WHITE_LIST_SIZE_LEN 0x0F +#define HCI_LE_CLEAR_WHITE_LIST_LEN (0) +#define HCI_LE_ADD_DEVICE_TO_WHITE_LIST_LEN (7) +#define HCI_LE_REMOVE_DEVICE_FROM_WL_LEN (7) +#define HCI_LE_CONNECTION_UPDATE_LEN 0x13 +#define HCI_LE_SET_HOST_CHANNEL_CLASSIFICATION_LEN 0x14 +#define HCI_LE_READ_CHANNEL_MAP_LEN 0x15 +#define HCI_LE_READ_REMOTE_USED_FEATURES_LEN 0x16 +#define HCI_LE_ENCRYPT_LEN 0x17 +#define HCI_LE_RANDOM_LEN 0x18 +#define HCI_LE_START_ENCRYPTION_LEN 0x19 +#define HCI_LE_LONG_TERM_KEY_REQUESTED_REPLY_LEN 0x1A +#define HCI_LE_LONG_TERM_KEY_REQUESTED_NEGATIVE_REPLY_LEN 0x1B +#define HCI_LE_READ_SUPPORTED_STATES_LEN 0x1C +#define HCI_LE_RECEIVER_TEST_LEN 0x1D +#define HCI_LE_TRANSMITTER_TEST_LEN 0x1E +#define HCI_LE_TEST_END_LEN 0x1F +//core_4.0 end +//core_4.2 begin +#define HCI_LE_REMOTE_CONNECTION_PARAM_REQ_REPLY_LEN 0x20 +#define HCI_LE_REMOTE_CONNECTION_PARAM_REQ_NEGATIVE_REPLY_LEN 0x21 +//core_4.1 end +//core_4.2 begin +#define HCI_LE_SET_DATA_LENGTH_LEN 0x22 +#define HCI_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH_LEN 0x23 +#define HCI_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH_LEN 0x24 +#define HCI_LE_READ_LOCAL_P256_PUBLIC_KEY_LEN 0x25 +#define HCI_LE_GENERATE_DHKEY_LEN 0x26 +#define HCI_LE_ADD_DEVICE_TO_RESOLVING_LIST_LEN 0x27 +#define HCI_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST_LEN 0x28 +#define HCI_LE_CLEAR_RESOLVING_LIST_LEN 0x29 +#define HCI_LE_READ_RESOLVING_LIST_SIZE_LEN 0x2A +#define HCI_LE_READ_PEER_RESOLVABLE_ADDRESS_LEN 0x2B +#define HCI_LE_READ_LOCAL_RESOLVABLE_ADDRESS_LEN 0x2C +#define HCI_LE_SET_ADDRESS_RESOLUTION_ENABLE_LEN 0x2D +#define HCI_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT_LEN 0x2E +#define HCI_LE_READ_MAX_DATA_LENGTH_LEN 0x2F +//core_4.2 end +//core_5.0 begin +#define HCI_LE_READ_PHY_LEN 0x30//LE Read PHY Command - [5] 7.8.47 +#define HCI_LE_SET_DEFAULT_PHY_LEN 0x31//LE Set Default PHY Command - [5] 7.8.48 +#define HCI_LE_SET_PHY_LEN 0x32//LE Set PHY Command - [5] 7.8.49 +#define HCI_LE_ENHANCED_RECEIVER_TEST_LEN 0x33//LE Enhanced Receiver Test Command - [5] 7.8.50 +#define HCI_LE_ENHANCED_TRANSMITTER_TEST_LEN 0x34//LE Enhanced Transmitter Test Command - [5] 7.8.51 +#define HCI_LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_LEN 0x35//LE Set Advertising Set Random Address Command - [5] 7.8.52 +#define HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_LEN 0x36//LE Set Extended Advertising Parameters Command - [5] 7.8.53 +#define HCI_LE_SET_EXTENDED_ADVERTISING_DATA_LEN 0x37//LE Set Extended Advertising Data Command - [5] 7.8.54 +#define HCI_LE_SET_EXTENDED_SCAN_RESPONSE_DATA_LEN 0x38//LE Set Extended Scan Response Data Command - [5] 7.8.55 +#define HCI_LE_SET_EXTENDED_ADVERTISING_ENABLE_LEN 0x39//LE Set Extended Advertising Enable Command - [5] 7.8.56 +#define HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_LEN 0x3A//LE Read Maximum Advertising Data Length Command - [5] 7.8.57 +#define HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS_LEN 0x3B//LE Read Number of Supported Advertising Sets Command - [5] 7.8.58 +#define HCI_LE_REMOVE_ADVERTISING_SET_LEN 0x3C//LE Remove Advertising Set Command - [5] 7.8.59 +#define HCI_LE_CLEAR_ADVERTISING_SETS_LEN 0x3D//LE Clear Advertising Sets Command - [5] 7.8.60 +#define HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_LEN 0x3E//LE Set Periodic Advertising Parameters Command - [5] 7.8.61 +#define HCI_LE_SET_PERIODIC_ADVERTISING_DATA_LEN 0x3F//LE Set Periodic Advertising Data Command - [5] 7.8.62 +#define HCI_LE_SET_PERIODIC_ADVERTISING_ENABLE_LEN 0x40//LE Set Periodic Advertising Enable Command - [5] 7.8.63 +#define HCI_LE_SET_EXTENDED_SCAN_PARAMETERS_LEN 0x41//LE Set Extended Scan Parameters Command - [5] 7.8.64 +#define HCI_LE_SET_EXTENDED_SCAN_ENABLE_LEN 0x42//LE Set Extended Scan Enable Command - [5] 7.8.65 +#define HCI_LE_EXTENDED_CREATE_CONNECTION_LEN 0x43//LE Extended Create Connection Command - [5] 7.8.66 +#define HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_LEN 0x44//LE Periodic Advertising Create Sync Command- [5] 7.8.67 +#define HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL_LEN 0x45//LE Periodic Advertising Create Sync Cancel Command - [5] 7.8.68 +#define HCI_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC_LEN 0x46//LE Periodic Advertising Terminate Sync Command - [5] 7.8.69 +#define HCI_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST_LEN 0x47//LE Add Device To Periodic Advertiser List Command - [5] 7.8.70 +#define HCI_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST_LEN 0x48//LE Remove Device From Periodic Advertiser List Command - [5] 7.8.71 +#define HCI_LE_CLEAR_PERIODIC_ADVERTISER_LIST_LEN 0x49//LE Clear Periodic Advertiser List Command - [5] 7.8.72 +#define HCI_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE_LEN 0x4A//LE Read Periodic Advertiser List Size Command - [5] 7.8.73 +#define HCI_LE_READ_TRANSMIT_POWER_LEN 0x4B//LE Read Transmit Power Command - [5] 7.8.74 +#define HCI_LE_READ_RF_PATH_COMPENSATION_LEN 0x4C//LE Read RF Path Compensation Command - [5] 7.8.75 +#define HCI_LE_WRITE_RF_PATH_COMPENSATION_LEN 0x4D//LE Write RF Path Compensation Command - [5] 7.8.76 +#define HCI_LE_SET_PRIVACY_MODE_LEN 0x4E//LE Set Privacy Mode Command - [5] 7.8.77 +//core_5.0 end +//core_5.1 begin +#define HCI_LE_RECEIVER_TEST_V3_LEN 0x4F //7.8.78 LE Receiver Test command [v3] +#define HCI_LE_TRANSMITTER_TEST_V3_LEN 0x50 //7.8.79 LE Transmitter Test command [v3] +#define HCI_LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS_LEN 0x51 //7.8.80 LE Set Connectionless CTE Transmit Parameters command +#define HCI_LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE_LEN 0x52 //7.8.81 LE Set Connectionless CTE Transmit Enable command +#define HCI_LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE_LEN 0x53 //7.8.82 LE Set Connectionless IQ Sampling Enable command +#define HCI_LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS_LEN 0x54 //7.8.83 LE Set Connection CTE Receive Parameters command +#define HCI_LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS_LEN 0x55 //7.8.84 LE Set Connection CTE Transmit Parameters command +#define HCI_LE_CONNECTION_REQUEST_ENABLE_LEN 0x56 //7.8.85 LE Connection CTE Request Enable command +#define HCI_LE_CONNECTION_RESPONSE_ENABLE_LEN 0x57 //7.8.86 LE Connection CTE Response Enable command +#define HCI_LE_READ_ANTENNA_INFORMATION_LEN 0x58 //7.8.87 LE Read Antenna Information command +#define HCI_LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE_LEN 0x59 //7.8.88 LE Set Periodic Advertising Receive Enable command +#define HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFOR_LEN 0x5A //7.8.89 LE Periodic Advertising Sync Transfer command +#define HCI_LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFOR_LEN 0x5B //7.8.90 LE Periodic Advertising Set Info Transfer command +#define HCI_LE_SET_PERIODIC_ADV_SYNC_TRANSFOR_PARAMETERS_LEN 0x5C //7.8.91 LE Set Periodic Advertising Sync Transfer Parameters command +#define HCI_LE_SET_DEFAULT_PERIODIC_ADV_SYNC_TRANSFOR_PARAMS_LEN 0x5D //7.8.92 LE Set Default Periodic Advertising Sync Transfer Parameters command +#define HCI_LE_GENERATE_DHKEY_V2_LEN 0x5E //7.8.93 LE Generate DHKey command [v2] +#define HCI_LE_MODIFY_SLEEP_CLOCK_ACCURACY_LEN 0x5F //7.8.94 LE Modify Sleep Clock Accuracy command +//core_5.1 end +//core_5.2 begin +#define HCI_LE_READ_ISO_TX_SYNC_LEN 0x61 //7.8.96 LE Read ISO TX Sync command +#define HCI_LE_SET_CIG_PARAMETERS_LEN (48) //7.8.97 LE Set CIG Parameters command +#define HCI_LE_SET_CIG_PARAMETERS_TEST_LEN (47) //7.8.98 LE Set CIG Parameters Test command +#define HCI_LE_CREATE_CIS_LEN (5) //7.8.99 LE Create CIS command +#define HCI_LE_REMOVE_CIG_LEN 0x65 //7.8.100 LE Remove CIG command +#define HCI_LE_ACCEPT_CIS_REQUEST_LEN (2) //7.8.101 LE Accept CIS Request command +#define HCI_LE_REJECT_CIS_REQUEST_LEN 0x67 //7.8.102 LE Reject CIS Request command +#define HCI_LE_CREATE_BIG_LEN 0x68 //7.8.103 LE Create BIG command +#define HCI_LE_CREATE_BIG_TEST_LEN 0x69 //7.8.104 LE Create BIG Test command +#define HCI_LE_TERMINATE_BIG_LEN 0x6A //7.8.105 LE Terminate BIG command +#define HCI_LE_BIG_CREATE_SYNC_LEN 0x6B //7.8.106 LE BIG Create Sync command +#define HCI_LE_BIG_TERMINATE_SYNC_LEN 0x6C //7.8.107 LE BIG Terminate Sync command +#define HCI_LE_REQUEST_PEER_SCA_LEN 0x6D //7.8.108 LE Request Peer SCA command +#define HCI_LE_SETUP_ISO_DATA_PATH_LEN 0x6E //7.8.109 LE Setup ISO Data Path command +#define HCI_LE_REMOVE_ISO_DARA_PATH_LEN 0x6F //7.8.110 LE Remove ISO Data Path command +#define HCI_LE_ISO_TRTANSMIT_TEST_LEN 0x70 //7.8.111 LE ISO Transmit Test command +#define HCI_LE_ISO_RECEIVE_TEST_LEN 0x71 //7.8.112 LE ISO Receive Test command +#define HCI_LE_ISO_READ_TEST_COUNTERS_LEN 0x72 //7.8.113 LE ISO Read Test Counters command +#define HCI_LE_ISO_TEST_END_LEN 0x73 //7.8.114 LE ISO Test End command +#define HCI_LE_SET_HOST_FEATURE_LEN (2) //7.8.115 LE Set Host Feature Command +#define HCI_LE_READ_ISO_LINK_QUALITY_LEN 0x75 //7.8.116 LE Read ISO Link Quality command +#define HCI_LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL_LEN 0x76 //7.8.117 LE Enhanced Read Transmit Power Level command +#define HCI_LE_READ_REMOTE_TRANSMIT_POWER_LEVEL_LEN 0x77 //7.8.118 LE Read Remote Transmit Power Level command +#define HCI_LE_SET_PATH_LOSS_REPORTING_PARAMETERS_LEN 0x78 //7.8.119 LE Set Path Loss Reporting Parameters command +#define HCI_LE_SET_PATH_LOSS_REPORTING_ENABLE_LEN 0x79 //7.8.120 LE Set Path Loss Reporting Enable command +#define HCI_LE_SET_TRANSMIT_POWER_REPORTING_ENABLE_LEN 0x7A //7.8.121 LE Set Transmit Power Reporting Enable command +//core_5.2 end + + +//--- OGF --- 0x3F: Vendor specific Commands +// -- OCF -- +#define HCI_TELINK_READ_REG_LEN 0x01 +#define HCI_TELINK_WRTIE_REG_LEN 0x02 +#define HCI_TELINK_SET_TX_PWR_LEN 0x03 +/************************** Macro & Enumeration & Structure Definition for Stack End ****************************/ + + + + + + + + +ble_sts_t ht_hci_disconnect (u16 connHandle, u8 reason); + +ble_sts_t ht_hci_setEventMask_cmd(u64 evtMask); +ble_sts_t ht_hci_reset(void); + +ble_sts_t ht_hci_readBDAddr(void); + + + + + +ble_sts_t ht_hci_le_setEventMask_cmd(u64 evtMask); +ble_sts_t ht_hci_le_readBufferSize_cmd(void); + +ble_sts_t ht_hci_le_setRandomAddr(u8 *randomAddr); +ble_sts_t ht_hci_setAdvParam( u16 intervalMin, u16 intervalMax, adv_type_t advType, own_addr_type_t ownAddrType, \ + u8 peerAddrType, u8 *peerAddr, adv_chn_map_t adv_channelMap, adv_fp_type_t advFilterPolicy); +ble_sts_t ht_hci_setAdvData(u8 *pAdvData, u8 advDataLen); +ble_sts_t ht_hci_setScanRspData(u8 *pScanRspData, u8 scanRspDataLen); +ble_sts_t ht_hci_setAdvEnable(adv_en_t adv_enable); + +ble_sts_t ht_hci_setScanParameter ( scan_type_t scan_type, u16 scan_interval, u16 scan_window, \ + own_addr_type_t ownAddrType, scan_fp_type_t scanFilter_policy); +ble_sts_t ht_hci_setScanEnable (scan_en_t scan_enable, dupFilter_en_t filter_duplicate); +ble_sts_t ht_hci_createConnection( u16 scan_interval, u16 scan_window, init_fp_t initiator_filter_policy, u8 adr_type, u8 *mac, u8 own_adr_type, \ + u16 conn_min, u16 conn_max, u16 conn_latency, u16 timeout, u16 ce_min, u16 ce_max); +ble_sts_t ht_hci_createConnectionCancel (void); + +ble_sts_t ht_hci_whiteList_readSize(void); +ble_sts_t ht_hci_whiteList_reset(void); +ble_sts_t ht_hci_whiteList_add(u8 type, u8 *addr); +ble_sts_t ht_hci_whiteList_delete(u8 type, u8 *addr); + + +ble_sts_t ht_hci_resolvingList_reset(void); + + + + + +ble_sts_t ht_hci_setExtScanParam ( own_addr_type_t ownAddrType, scan_fp_type_t scan_fp, scan_phy_t scan_phys, + scan_type_t scanType_0, scan_inter_t scanInter_0, scan_wind_t scanWindow_0, + scan_type_t scanType_1, scan_inter_t scanInter_1, scan_wind_t scanWindow_1); +ble_sts_t ht_hci_setExtScanEnable (scan_en_t extScan_en, dupe_fltr_en_t filter_duplicate, scan_durn_t duration, scan_period_t period); + + + + + + + +ble_sts_t ht_hci_setCigParamsTest(hci_le_setCigParamTest_cmdParam_t* pCmdParam, ble_sts_t exptHciRetSts); +ble_sts_t ht_hci_le_createCis(hci_le_CreateCisParams_t* pCisPara, ble_sts_t exptHciRetSts); +ble_sts_t ht_hci_le_acceptCisReq(u16 cisHandle, ble_sts_t exptHciRetSts); +ble_sts_t ht_hci_le_setHostFeature(u8 bitNum, u8 bitValue, ble_sts_t exptHciRetSts); + + + + + +ble_sts_t ht_hci_telinkVendorRebootMCU(void); +/************************************ User Interface End ********************************************************/ + + + + + + + + + +#endif /* HT_HCI_CMD_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ble_controller.h b/b91/b91m_ble_sdk/stack/ble/controller/ble_controller.h new file mode 100755 index 0000000..ecba5a2 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ble_controller.h @@ -0,0 +1,87 @@ +/******************************************************************************************************** + * @file ble_controller.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef BLE_CONTROLLER_H_ +#define BLE_CONTROLLER_H_ + + +#include "stack/ble/ble_config.h" +#include "stack/ble/ble_common.h" +#include "stack/ble/ble_format.h" + + +#include "stack/ble/hci/hci.h" +#include "stack/ble/hci/hci_const.h" +#include "stack/ble/hci/hci_cmd.h" +#include "stack/ble/hci/hci_event.h" + +#include "stack/ble/controller/ll/ll.h" +#include "stack/ble/controller/ll/ll_pm.h" + +#include "stack/ble/controller/ll/acl_conn/acl_conn.h" +#include "stack/ble/controller/ll/acl_conn/acl_slave.h" +#include "stack/ble/controller/ll/acl_conn/acl_master.h" + + +#include "stack/ble/controller/ll/adv/adv.h" +#include "stack/ble/controller/ll/adv/leg_adv.h" +#include "stack/ble/controller/ll/adv/ext_adv.h" + +#include "stack/ble/controller/ll/scan/scan.h" +#include "stack/ble/controller/ll/scan/leg_scan.h" +#include "stack/ble/controller/ll/scan/ext_scan.h" + + +#include "stack/ble/controller/ll/init/init.h" +#include "stack/ble/controller/ll/init/leg_init.h" +#include "stack/ble/controller/ll/init/ext_init.h" + + +#include "stack/ble/controller/ll/prdadv/pda.h" +#include "stack/ble/controller/ll/prdadv/prd_adv.h" +#include "stack/ble/controller/ll/prdadv/pda_sync.h" + + +#include "stack/ble/controller/ial/ial.h" +#include "stack/ble/controller/ll/iso/iso.h" + +#include "stack/ble/controller/ll/iso/bis.h" +#include "stack/ble/controller/ll/iso/bis_bcst.h" +#include "stack/ble/controller/ll/iso/bis_sync.h" +#include "stack/ble/controller/ll/iso/cis.h" +#include "stack/ble/controller/ll/iso/cis_master.h" +#include "stack/ble/controller/ll/iso/cis_slave.h" +#include "stack/ble/controller/ll/aoa_aod/aoa_aod.h" + + +#include "stack/ble/controller/whitelist/whitelist.h" +#include "stack/ble/controller/whitelist/resolvlist.h" + +#include "stack/ble/controller/csa/csa.h" + +#include "stack/ble/controller/phy/phy.h" +#include "stack/ble/controller/phy/phy_test.h" + +#include "algorithm/algorithm.h" + + +#endif /* BLE_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/csa/csa.h b/b91/b91m_ble_sdk/stack/ble/controller/csa/csa.h new file mode 100755 index 0000000..60e773e --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/csa/csa.h @@ -0,0 +1,39 @@ +/******************************************************************************************************** + * @file csa.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef CSA_H_ +#define CSA_H_ + + + + + +/** + * @brief this function is used to initialize channel selection algorithm #2 feature + * @param none + * @return none + */ +void blc_ll_initChannelSelectionAlgorithm_2_feature(void); + + + +#endif /* LL_CONN_CSA_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ial/ial.h b/b91/b91m_ble_sdk/stack/ble/controller/ial/ial.h new file mode 100755 index 0000000..66e20bb --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ial/ial.h @@ -0,0 +1,189 @@ +/******************************************************************************************************** + * @file ial.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef IAL_H_ +#define IAL_H_ + + + + +#include "stack/ble/controller/ll/iso/iso.h" + + + + +/* + * First fragment of sdu, data field + */ +#define HCI_ISO_PKT_HDR_HANDLE_LEN (2) +#define HCI_ISO_PKT_HDR_DATA_LEN (2) +#define HCI_ISO_LOAD_HDR_TIMESTAMP_LEN (4) +#define HCI_ISO_LOAD_HDR_PACKET_SN_LEN (2) +#define HCI_ISO_LOAD_SDU_LEN (2) + +#define HCI_ISO_PKT_HDR_LEN (HCI_ISO_PKT_HDR_HANDLE_LEN + HCI_ISO_PKT_HDR_DATA_LEN) + +#define HCI_ISO_LOAD_HDR_LEN_MAX (HCI_ISO_LOAD_HDR_TIMESTAMP_LEN + HCI_ISO_LOAD_HDR_PACKET_SN_LEN + HCI_ISO_LOAD_SDU_LEN) +#define HCI_ISO_LOAD_HDR_LEN_MIN (HCI_ISO_LOAD_HDR_PACKET_SN_LEN + HCI_ISO_LOAD_SDU_LEN) + + +#define ISO_FRAMED_SEGM_HEADER_LEN (2) +#define ISO_FRAMED_TIMEOFFSET_LEN (3) + + +/* + * HCI ISO data packet + */ +typedef struct{ + +//0 + u32 timestamp; + u16 offset; + u16 sn_offset; + + +//8 + u16 connHandle :12; + u16 pb :2; + u16 ts :1; + u16 RFU2 :1; +//10 + u16 iso_dl_len :14; //iso_data_load_length + u16 RFU3 :2; + + +//11 + u8 data[1]; + +}iso_data_packet_t; + + + + + + +/******************************* Macro & Enumeration & Structure Definition for Stack End ******************************/ + + + + + + +/******************************* Macro & Enumeration variables for User Begin ******************************************/ + + + +/******************************* Macro & Enumeration variables for User End ********************************************/ + + + + + + + + + + + + + + +/******************************* User Interface Begin *****************************************************************/ + +/** + * @brief This function is used to initialize the ISOAL module. + */ +void blc_ial_initSdu_module(void); + +/** + * @brief This function is used to initialize sdu buff. + * @param[in] rx_fifo + * @param[in] rx_fifo_size + * @param[in] rx_fifo_num + * @param[in] tx_fifo + * @param[in] tx_fifo_size + * @param[in] tx_fifo_num + */ +void blc_ial_initCisSduBuff(u8 *rx_fifo,u16 rx_fifo_size, u8 rx_fifo_num, u8 *tx_fifo,u16 tx_fifo_size, u8 tx_fifo_num); + +/** + * @brief This function is used to initialize cis sdu buff. + * @param[in] rx_fifo + * @param[in] rx_fifo_size + * @param[in] rx_fifo_num + * @param[in] tx_fifo + * @param[in] tx_fifo_size + * @param[in] tx_fifo_num + */ +void blc_ial_initBisSduBuff(u8 *rx_fifo,u16 rx_fifo_size, u8 rx_fifo_num, u8 *tx_fifo,u16 tx_fifo_size, u8 tx_fifo_num); + +/** + * @brief This function is used to pack HCI ISO data packet to SDU packet. + * @param[in] cis_connHandle - point to handle of cis. + * @param[in] pIsoData - point to hci ISO Data packet buff. + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_hci_packIsoData(u16 cis_connHandle, u8 *pIsoData); + +/** + * @brief This function is used to setup ISO Data Path. + * @param[in] refer to the structure 'hci_le_setupIsoDataPathCmdParams_t' + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_isoal_le_setupISODataPath_cmd(hci_le_setupIsoDataPathCmdParams_t *para); + +/** + * @brief This function is used to segmentation SDU to one Framed PDUs. + * @param[in] cis_connHandle + * @return Status - 0x00: command succeeded; IAL_ERR_SDU_LEN_EXCEED_SDU_MAX + * LL_ERR_INVALID_PARAMETER: command failed + */ +ble_sts_t blc_ial_splitCisSdu2FramedPdu(u16 cis_connHandle); + + +/** + * @brief This function is used to fragmentation SDU to one or more Unframed PDUs. + * @param[in] cis_connHandle + * @param[in] sdu point to sdu buff + * @return Status - 0x00: command succeeded; IAL_ERR_SDU_LEN_EXCEED_SDU_MAX + * LL_ERR_INVALID_PARAMETER: command failed + */ +ble_sts_t blc_ial_cis_splitSdu2UnframedPdu(u16 cisHandle, iso_data_packet_t *sdu); + + +/** + * @brief This function is used to fragmentation SDU to one or more Unframed PDUs. + * @param[in] bis_connHandle + * @param[in] sdu point to sdu buff + * @return Status - 0x00: command succeeded; IAL_ERR_SDU_LEN_EXCEED_SDU_MAX + * LL_ERR_INVALID_PARAMETER: command failed + */ +ble_sts_t blc_ial_bis_splitSdu2UnframedPdu(u16 bis_connHandle, iso_data_packet_t *sdu); + + +/******************************* User Interface End ******************************************************************/ + + + +#endif + + diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/acl_conn/acl_conn.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/acl_conn/acl_conn.h new file mode 100755 index 0000000..fbaf5f4 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/acl_conn/acl_conn.h @@ -0,0 +1,242 @@ +/******************************************************************************************************** + * @file acl_conn.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef ACL_CONN_H_ +#define ACL_CONN_H_ + + +/** + * @brief This function is used to get the current number of ACL connections. + * @param[in] none. + * @return The number of currently connected ACLs. + */ +int blc_ll_getCurrentConnectionNumber(void); //master + slave connection number + + +/** + * @brief This function is used to obtain the maximum number of connections that can be supported. + * @param[in] none. + * @return Maximum number of connections that can be supported. + */ +int blc_ll_getSupportedMaxConnNumber(void); + + +/** + * @brief This function is used to obtain the number of ACL connections of the Master role. + * @param[in] none. + * @return The number of currently connected master ACLs. + */ +int blc_ll_getCurrentMasterRoleNumber(void); //master role number + + +/** + * @brief This function is used to obtain the number of ACL connections of the Slave role. + * @param[in] none. + * @return The number of currently connected slave ACLs. + */ +int blc_ll_getCurrentSlaveRoleNumber(void); //slave role number + + +/** + * @brief This function is used to configure the number of master and slave connections that the protocol stack can support. + * @param[in] max_master_num - Number of master ACL connections supported. + * @param[in] max_slave_num - Number of slave ACL connections supported. + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_setMaxConnectionNumber(int max_master_num, int max_slave_num); + + +/** + * @brief This function is used to obtain the currently available TX FIFO numbers according to the ACL handle. + * @param[in] connHandle - ACL connection handle. + * @return available TX FIFO numbers + */ +u8 blc_ll_getTxFifoNumber (u16 connHandle); + + +/** + * @brief This function is used to disconnect the device with the specified ACL connection handle and specify the reason for the disconnection. + * @param[in] connHandle - ACL connection handle. + * @param[in] reason - Reason for disconnection.. + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_disconnect (u16 connHandle, u8 reason); + + +/** + * @brief This function is used to obtain the connection establishment time point corresponding to the current ACL connection handle. + * @param[in] connHandle - ACL connection handle. + * @param[in] reason - Reason for disconnection.. + * @return The connection establishment time point corresponding to the current ACL connection handle: Based on 16M system clock ticks. + */ +u32 blc_ll_getConnectionStartTick(u16 connHandle); + + +/** + * @brief This function is used to read remote version with the specified ACL connection handle. + * @param[in] connHandle - ACL connection handle. + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_readRemoteVersion(u16 connHandle); + + +/** + * @brief for user to initialize ACL connection module, this is must if user want use ACL master role or ACL slave role. + * @param none + * @return none + */ +void blc_ll_initAclConnection_module(void); + + + +/** + * @brief for user to initialize LinkLayer ACL connection RX FIFO. + * all connection will share the FIFO. + * @param[in] pRxbuf - RX FIFO buffer address. + * @param[in] fifo_size - RX FIFO size + * @param[in] fifo_number - RX FIFO number, can only be 4, 8, 16 or 32 + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_initAclConnRxFifo(u8 *pRxbuf, int fifo_size, int fifo_number); + + + +/** + * @brief for user to initialize master LinkLayer ACL connection TX FIFO. + * @param[in] pRxbuf - TX FIFO buffer address. + * @param[in] fifo_size - TX FIFO size + * @param[in] fifo_number - TX FIFO number, can only be 4, 8, 16 or 32 + * @param[in] conn_number - Number of supported master ACL connections + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_initAclConnMasterTxFifo(u8 *pTxbuf, int fifo_size, int fifo_number, int conn_number); + + +/** + * @brief for user to initialize slave LinkLayer ACL connection TX FIFO. + * @param[in] pRxbuf - TX FIFO buffer address. + * @param[in] fifo_size - TX FIFO size + * @param[in] fifo_number - TX FIFO number, can only be 4, 8, 16 or 32 + * @param[in] conn_number - Number of supported slave ACL connections + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_initAclConnSlaveTxFifo(u8 *pTxbuf, int fifo_size, int fifo_number, int conn_number); + + +/** + * @brief check ACL whether is in establish state. + * @param[in] connHandle - ACL connection handle. + * @return status, 0: connection not established(disconnection or connection complete but not established) + * 1: connection established state + */ +bool blc_ll_isAclConnEstablished(u16 connHandle); + + +/** + * @brief set ACL data length for Master and Slave. + * @param[in] maxRxOct - ACL max RX Oct. + * @param[in] maxTxOct_master - ACL master max TX Oct + * @param[in] maxTxOct_slave - ACL slave max TX Oct + * @return status, 0x00 : succeed + * other: failed + */ +ble_sts_t blc_ll_setAclConnMaxOctetsNumber(u8 maxRxOct, u8 maxTxOct_master, u8 maxTxOct_slave); + + +/** + * @brief This function is used to set ll_length_req pending timing after connection created + * @param[in] time_ms - pending timing, unit: ms + * @return none + */ +void blc_ll_setDataLengthReqSendingTime_after_connCreate(int time_ms); + + +/** + * @brief this function is used to set PHY type for connection + * @param[in] connHandle - Connection_Handle Range:0x0000 to 0x0EFF + * @param[in] all_phys - preference PHY for TX & RX + * @param[in] tx_phys - preference PHY for TX + * @param[in] rx_phys - preference PHY for RX + * @param[in] phy_options - LE coding indication prefer + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_setPhy ( u16 connHandle, le_phy_prefer_mask_t all_phys, + le_phy_prefer_type_t tx_phys, le_phy_prefer_type_t rx_phys, + le_ci_prefer_t phy_options); + + +/** + * @brief This function is used to set LE Coded PHY preference, S2 or S8, or no specific preference. + * @param[in] prefer_CI - Reference structure: hci_le_readPhyCmd_retParam_t. + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_setDefaultConnCodingIndication(le_ci_prefer_t prefer_CI); + + +/** + * @brief this function is used to allows the Host to specify its preferred values for the transmitter PHY and + * receiver PHY to be used for all subsequent connections over the LE transport. + * @param[in] all_phys - Reference structure: le_phy_prefer_mask_t: + * bit0: The Host has no preference among the transmitter PHYs supported by the Controller + * bit1: The Host has no preference among the receiver PHYs supported by the Controller + * All other bits: Reserved for future use + * @param[in] tx_phys - Reference structure: le_phy_prefer_mask_t: + * bit0: The Host prefers to use the LE 1M transmitter PHY (possibly among others) + * bit1: The Host prefers to use the LE 2M transmitter PHY (possibly among others) + * bit2: The Host prefers to use the LE Coded transmitter PHY (possibly among others) + * All other bits: Reserved for future use + * @param[in] rx_phys - Reference structure: le_phy_prefer_mask_t + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_setDefaultPhy(le_phy_prefer_mask_t all_phys, le_phy_prefer_type_t tx_phys, le_phy_prefer_type_t rx_phys); + + +/** + * @brief this function is used to read the current transmitter PHY and receiver PHY on the connection identified + * by the Connection_Handle. + * @param[in] connHandle - Connection_Handle Range:0x0000 to 0x0EFF + * @param[out] para - Reference structure: hci_le_readPhyCmd_retParam_t: + * Status - 0x00 HCI_LE_Read_PHY command succeeded; 0x01 to 0xFF: HCI_LE_Read_PHY command failed + * Connection_Handle - Connection_Handle Range:0x0000 to 0x0EFF + * TX_PHY - 1:LE 1M; 2: LE 2M; 3: LE Coded. + * RX_PHY - 1:LE 1M; 2: LE 2M; 3: LE Coded. + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_readPhy( u16 connHandle, hci_le_readPhyCmd_retParam_t *para); + +ble_sts_t blc_hci_le_readBufferSize_cmd(u8 *pData); +ble_sts_t blc_hci_le_getLocalSupportedFeatures(u8 *features); +ble_sts_t blc_hci_readSuggestedDefaultTxDataLength (u8 *tx, u8 *txtime); +ble_sts_t blc_hci_writeSuggestedDefaultTxDataLength (u16 tx, u16 txtime); +ble_sts_t blc_hci_readMaximumDataLength(hci_le_readMaxDataLengthCmd_retParam_t *para); + +#endif /* ACL_CONN_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/acl_conn/acl_master.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/acl_conn/acl_master.h new file mode 100755 index 0000000..d891548 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/acl_conn/acl_master.h @@ -0,0 +1,62 @@ +/******************************************************************************************************** + * @file acl_master.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef ACL_MASTER_H_ +#define ACL_MASTER_H_ + + + +/** + * @brief for user to initialize ACL connection master role. + * @param none + * @return none + */ +void blc_ll_initAclMasterRole_module(void); + + + +/** + * @brief for user to initialize LinkLayer ACL connection RX FIFO. + * all connection will share the FIFO. + * @param[in] conn_interval - Set connection interval, unit 1.25ms. + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_setAclMasterConnectionInterval(conn_inter_t conn_interval); + + +/** + * @brief this function is used to change the ACL connection parameters. + * @param[in] connHandle - Connection_Handle + * @param[in] conn_min - the minimum allowed connection interval. + * @param[in] conn_max - the maximum allowed connection interval. + * @param[in] conn_latency - the maximum allowed connection latency. + * @param[in] timeout - the link supervision timeout for the LE link. + * @param[in] ce_min - information parameters providing the Controller with a hint about the expected minimum length of the connection events. + * @param[in] ce_max - information parameters providing the Controller with a hint about the expected maximum length of the connection events. + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_updateConnection(u16 connHandle, conn_inter_t conn_min, conn_inter_t conn_max, u16 conn_latency, conn_tm_t timeout, u16 ce_min, u16 ce_max); + + +#endif /* ACL_MASTER_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/acl_conn/acl_slave.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/acl_conn/acl_slave.h new file mode 100755 index 0000000..161cc1f --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/acl_conn/acl_slave.h @@ -0,0 +1,41 @@ +/******************************************************************************************************** + * @file acl_slave.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef ACL_SLAVE_H_ +#define ACL_SLAVE_H_ + + + + + +/** + * @brief for user to initialize ACL connection slave role. + * @param none + * @return none + */ +void blc_ll_initAclSlaveRole_module(void); + + + + + +#endif /* ACL_SLAVE_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/adv/adv.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/adv/adv.h new file mode 100755 index 0000000..642c30c --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/adv/adv.h @@ -0,0 +1,57 @@ +/******************************************************************************************************** + * @file adv.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef ADV_H_ +#define ADV_H_ + + + +/** + * @brief Definition for ADV maximum random delay time + */ +typedef enum{ + MAX_DELAY_10MS = 512, + MAX_DELAY_5MS = 256, + MAX_DELAY_2P5MS = 128, + MAX_DELAY_0MS = 0, +}adv_max_delay_t; + + + + + +/** + * @brief Set Advertising Interval maximum random delay time. If not set, default value is 10mS according to BLE Spec. + * This API is mainly used for debug, to control adv_interval, this value will recover to 10mS if stack timing is limited + * //notice that: this API must used before API "blc_ll_setAdvParam" TODO SiHui + * @param max_delay - select one from enumeration variable "adv_max_delay_t" + * + * @return None + */ +void blc_ll_setMaxAdvDelay_for_AdvEvent(adv_max_delay_t max_delay); + + + + + + +#endif /* ADV_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/adv/ext_adv.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/adv/ext_adv.h new file mode 100755 index 0000000..a60841f --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/adv/ext_adv.h @@ -0,0 +1,233 @@ +/******************************************************************************************************** + * @file ext_adv.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef LL_EXT_ADV_H_ +#define LL_EXT_ADV_H_ + + +#include "stack/ble/hci/hci_cmd.h" + + +/* maximum number of advertising sets this SDK can support, periodic advertising is included. */ +#define ADV_SETS_NUMBER_MAX 4 + + +/* Note: user can't modify this value,and this value must 4 byte aligned + * if use BLUETOOTH_VER_5_2 this value is 680 other than 572 + */ +#define ADV_SET_PARAM_LENGTH 680//572 + + + +#if 0 +/* if use legacy ADV, primary ADV packet maximum length is 44 */ +#define MAX_LENGTH_PRIMARY_ADV_PKT_LEGACY 44 + +/* if use extended ADV, primary ADV packet maximum length is 28 */ +#define MAX_LENGTH_PRIMARY_ADV_PKT_EXTENDED 28 + +/* if not sure which kind of ADV will be used, use the bigger value is recommended. + * For example, when used as BLE Controller, BLE Host can use either legacy or extended ADV */ +#define MAX_LENGTH_PRIMARY_ADV_PKT 44 + + + +#define MAX_LENGTH_SECOND_ADV_PKT 264 //sizeof(rf_pkt_ext_adv_t) = 261 +#endif + + + + + + + + + + + + + + +/** + * @brief for user to initialize extended advertising module + * notice that: 1. only one module can be selected between legacy advertising module and extended advertising module + * 2. this API must be used before any other extended ADV initialization APIs. + * @param none + * @return none + */ +void blc_ll_initExtendedAdvertising_module(void); + +/** + * @brief for user to allocate single or multiple advertising sets buffer + * notice that: this API must used after "blc_ll_initExtendedAdvertising_module", + * and before any other extended ADV initialization APIs. + * @param[in] pBuff_advSets - global buffer allocated by application layer. + * @param[in] num_advSets - number of application adv_sets + * @return Status - 0x00: command succeeded; + * 0x12: num_advSets exceed maximum number of supported adv_sets. + */ +ble_sts_t blc_ll_initExtendedAdvSetBuffer(u8 *pBuff_advSets, int num_advSets); + +/** + * @brief initialize Advertising Data buffer for all adv_set + * @param[in] pExtAdvData - + * @param[in] max_len_advData - + * @return none + */ +void blc_ll_initExtAdvDataBuffer(u8 *pExtAdvData, int max_len_advData); + +/** + * @brief initialize Advertising Data buffer for specific adv_set. + * @param[in] adv_handle - Used to identify an advertising set + * @param[in] pExtAdvData - + * @param[in] max_len_advData - + * @return Status - 0x00: succeed. + * 0x12: adv_handle out of range. + */ +ble_sts_t blc_ll_initExtAdvDataBuffer_by_advHandle( u8 adv_handle, u8 *pExtAdvData, int max_len_advData); + +/** + * @brief initialize Scan Response Data Buffer for all adv_set + * @param[in] pScanRspData - + * @param[in] max_len_scanRspData - + * @return none + */ +void blc_ll_initExtScanRspDataBuffer(u8 *pScanRspData, int max_len_scanRspData); + +/** + * @brief initialize Scan Response Data Buffer buffer for specific adv_set. + * @param[in] adv_handle - Used to identify an advertising set + * @param[in] pScanRspData - + * @param[in] max_len_scanRspData - + * @return Status - 0x00: succeed. + * 0x12: adv_handle out of range. + */ +ble_sts_t blc_ll_initExtScanRspDataBuffer_by_advHandle(u8 adv_handle, u8 *pScanRspData, int max_len_scanRspData); + + + + + + + +/** + * @brief This function is used to set the advertising parameters + * @param[in] adv_handle - Used to identify an advertising set + * @param[in] adv_evt_prop - + * @param[in] pri_advInter_min & pri_advInter_max + * @param[in] + * @param[in] + * @param[in] + * @param[in] + * @return Status - 0x00: command succeeded; + * 0x12: 1. adv_handle out of range; + * 2. pri_advChnMap out of range + * 0x0C: advertising is enabled for the specified advertising set + */ +ble_sts_t blc_ll_setExtAdvParam( u8 adv_handle, advEvtProp_type_t adv_evt_prop, u32 pri_advInter_min, u32 pri_advInter_max, + adv_chn_map_t pri_advChnMap, own_addr_type_t ownAddrType, u8 peerAddrType, u8 *peerAddr, + adv_fp_type_t advFilterPolicy, tx_power_t adv_tx_pow, le_phy_type_t pri_adv_phy, u8 sec_adv_max_skip, + le_phy_type_t sec_adv_phy, u8 adv_sid, u8 scan_req_noti_en); + + + +/** + * @brief This function is used to set the data used in advertising PDU that have a data field + * notice that: setting legacy ADV data also use this API, data length can not exceed 31 + * @param[in] adv_handle - Used to identify an advertising set + * @param[in] *advData - + * @param[in] advData_len - + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_setExtAdvData (u8 adv_handle, int advData_len, u8 *advData); + + + + + + +/** + * @brief This function is used to provide scan response data used in scanning response PDUs. + * notice that: setting legacy scan response data also use this API, data length can not exceed 31 + * @param[in] adv_handle - Used to identify an advertising set + * @param[in] scanRspData_len - + * @param[in] *scanRspData - + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_setExtScanRspData(u8 adv_handle, int scanRspData_len, u8 *scanRspData); + + + + + +/** + * @brief This function is used to request the Controller to enable or disable one or more advertising sets using the + advertising sets identified by the adv_handle + * @param[in] enable - + * @param[in] adv_handle - Used to identify an advertising set + * @param[in] duration - the duration for which that advertising set is enabled + * Range: 0x0001 to 0xFFFF, Time = N * 10 ms, Time Range: 10 ms to 655,350 ms + * @param[in] max_extAdvEvt - Maximum number of extended advertising events the Controller shall + * attempt to send prior to terminating the extended advertising + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_setExtAdvEnable(adv_en_t enable, u8 adv_handle, u16 duration, u8 max_extAdvEvt); + + + +/** + * @brief This function is used by the Host to set the random device address specified by the Random_Address + parameter + * @param[in] adv_handle - Used to identify an advertising set + * @param[in] *rand_addr - Random Device Address + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_setAdvRandomAddr(u8 adv_handle, u8* rand_addr); + + + +/** + * @brief This function is is used to remove an advertising set from the Controller. + * @param[in] adv_handle - Used to identify an advertising set + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_removeAdvSet(u8 adv_handle); + + + +/** + * @brief This function is used to remove all existing advertising sets from the Controller. + * @param[in] none. + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_clearAdvSets(void); + + + + +//only for Debug +ble_sts_t blc_ll_setAuxAdvChnIdxByCustomers(u8 aux_chn); + + + + +#endif /* LL_EXT_ADV_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/adv/leg_adv.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/adv/leg_adv.h new file mode 100755 index 0000000..5fad001 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/adv/leg_adv.h @@ -0,0 +1,99 @@ +/******************************************************************************************************** + * @file leg_adv.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef LEG_ADV_H_ +#define LEG_ADV_H_ + + +/** + * @brief for user to initialize legacy advertising module + * notice that only one module can be selected between legacy advertising module and extended advertising module + * @param none + * @return none + */ +void blc_ll_initLegacyAdvertising_module(void); + + + +/** + * @brief set the data used in advertising packets that have a data field. + * @param[in] *data - advertising data buffer + * @param[in] len - The number of significant octets in the Advertising_Data. + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_setAdvData(u8 *data, u8 len); + + +/** + * @brief This function is used to provide data used in Scanning Packets that have a data field. + * @param[in] *data - Scan_Response_Data buffer + * @param[in] len - The number of significant octets in the Scan_Response_Data. + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_setScanRspData(u8 *data, u8 len); + + + +/** + * @brief This function is used to set the advertising parameters. + * @param[in] intervalMin - Minimum advertising interval(Time = N * 0.625 ms, Range: 0x0020 to 0x4000) + * @param[in] intervalMin - Maximum advertising interval(Time = N * 0.625 ms, Range: 0x0020 to 0x4000) + * @param[in] advType - Advertising_Type + * @param[in] ownAddrType - Own_Address_Type + * @param[in] peerAddrType - Peer_Address_Type + * @param[in] *peerAddr - Peer_Address + * @param[in] adv_channelMap - Advertising_Channel_Map + * @param[in] advFilterPolicy - Advertising_Filter_Policy + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_setAdvParam( adv_inter_t intervalMin, adv_inter_t intervalMax, adv_type_t advType, own_addr_type_t ownAddrType, \ + u8 peerAddrType, u8 *peerAddr, adv_chn_map_t adv_channelMap, adv_fp_type_t advFilterPolicy); + + +/** + * @brief This function is used to request the Controller to start or stop advertising. + * @param adv_enable - Advertising_Enable + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_setAdvEnable(adv_en_t adv_enable); + + + + + +/** + * @brief This function is used to set some other channel to replace advertising chn37/38/39. + * @param[in] chn0 - channel to replace channel 37 + * @param[in] chn1 - channel to replace channel 38 + * @param[in] chn2 - channel to replace channel 39 + * @return none + */ +void blc_ll_setAdvCustomedChannel (u8 chn0, u8 chn1, u8 chn2); + + + + + + + + +#endif /* LEG_ADV_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/aoa_aod/aoa_aod.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/aoa_aod/aoa_aod.h new file mode 100755 index 0000000..5b4e8e3 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/aoa_aod/aoa_aod.h @@ -0,0 +1,131 @@ +/******************************************************************************************************** + * @file aoa_aod.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#ifndef AOA_AOD_H_ +#define AOA_AOD_H_ + +#if (LL_FEATURE_EANBLE_LE_AOA_AOD) + +#define ANTENNA_MAX_NUM 0x07 //confirm with YeYang,our device can support 7 antennas. +//75;reference period only use 1 antenna; (160us-4-8)/2 = 74 antenna. so max 75 antennas +#define SWITCH_PATTERN_MAX_LEN 0x4b + +#define CTE_SET_PARAM_ADVHANDLE0_DONE_FLAG BIT(0) +#define CTE_SET_PARAM_ADVHANDLE1_DONE_FLAG BIT(1) +#define CTE_SET_PARAM_ADVHANDLE2_DONE_FLAG BIT(2) +#define CTE_SET_PARAM_ADVHANDLE3_DONE_FLAG BIT(3) ///now only support 4 adv set. +#define PRD_ADV_SET_PARAM_DONE_FLAG BIT(4) + + +#define CTE_SET_TRANSMIT_PARAM_CONNHANDLE0 BIT(0) /// +#define CTE_SET_TRANSMIT_PARAM_CONNHANDLE1 BIT(1) +#define CTE_SET_TRANSMIT_PARAM_CONNHANDLE2 BIT(2) +#define CTE_SET_TRANSMIT_PARAM_CONNHANDLE3 BIT(3) +#define CTE_SET_TRANSMIT_PARAM_CONNHANDLE4 BIT(4) +#define CTE_SET_TRANSMIT_PARAM_CONNHANDLE5 BIT(5) +#define CTE_SET_TRANSMIT_PARAM_CONNHANDLE6 BIT(6) +#define CTE_SET_TRANSMIT_PARAM_CONNHANDLE7 BIT(7) ///now support 8 connection device:4 master and 4 slave. + +#define CTE_SET_RECEIVE_PARAM_CONNHANDLE0 BIT(0) +#define CTE_SET_RECEIVE_PARAM_CONNHANDLE1 BIT(1) +#define CTE_SET_RECEIVE_PARAM_CONNHANDLE2 BIT(2) +#define CTE_SET_RECEIVE_PARAM_CONNHANDLE3 BIT(3) + +typedef struct{ + u8 AOA_type; + u8 AOD_type_1us; + u8 AOD_type_2us; + u8 rsvd; +}CTE_type_t; + + +enum{ + Antenna_ID0 = 0, + Antenna_ID1 = 1, + Antenna_ID2 = 2, + Antenna_ID3 = 3, + Antenna_ID4 = 4, + Antenna_ID5 = 5, + Antenna_ID6 = 6, +}; + +enum{ + AOD_1US_TRANSMIT = BIT(0), + AOD_1US_RECEIVE = BIT(1), + AOA_1US_SWITCH_SAMPLE = BIT(2), +}; + +enum{ + SWITCH_SAMPLE_SLOT_1US = 0x01, //confirm with YeYang, our device support 1us sample. + SWITCH_SAMPLE_SLOT_2US = 0x02, +}; + +enum{ + CTE_NOT_EXIST = 0x00, + CTE_TRANSMIT = 0x01, + CTE_RECEIVE = 0x02, +}; + + +typedef struct{ + //transmit and receive setting + u8 cte_switch_pattern_len; + u8 cte_swtich_pattern[SWITCH_PATTERN_MAX_LEN]; + + //transmit setting + u8 cte_len; + u8 cte_type; //for transmit. AOA/AOD_1US/AOD_2US + u8 cte_count; + u8 cte_transmit_en; + + //receive setting + u8 cte_slot_duration; //for receive; 1us/2us + u8 Max_Sampled_CTEs; //for receive; max CTE count per period adv interval. + u8 cte_sample_en; //sample enable + u8 cte_trsmitRev_flag; //transmit or receive flag. just for operate more convenient. + + u8 cte_req_en; + u8 cte_rsp_en; + u16 cte_req_intvl; + + u8 sequence_ctrl; + u8 rsvd[3]; +}switch_pattern_t; + +extern _attribute_data_retention_ _attribute_aligned_(4) switch_pattern_t cte_connLess_switchPattern[]; +extern _attribute_data_retention_ _attribute_aligned_(4) switch_pattern_t cte_conn_switchPattern[]; + + +ble_sts_t blc_hci_le_setConnectionless_CTETransmitParams(hci_le_setConnectionless_CTETransmitParam_t* connLessTxParams); +ble_sts_t blc_hci_le_setConnectionless_CTETransmit_Enable(hci_le_CTE_enable_type* connLessTxCtr); +ble_sts_t blc_hci_le_setConnectionless_IQsample_Enable(hci_le_setConnectionless_IQsampleEn_t* IQsampleEn); +ble_sts_t blc_hci_le_setConnection_CTEReceiveParams(hci_le_setConnection_CTERevParams_t* cteRevParam); +ble_sts_t blc_hci_le_setConnection_CTETransmitParams(hci_le_setConnection_CTETransmitParams_t* cteTransmitParams); +ble_sts_t blc_hci_le_connection_CTEReq_Enable(hci_le_cteReqEn_t* connCTEReqEn); +ble_sts_t blc_hci_le_connection_CTERsp_Enable(hci_le_cteRspEn_t* connCTERspEn); +ble_sts_t blc_hci_le_ReadAntennaInfor(u8* inforBuff); +bool blc_le_setAntennaInfor(cte_antenna_infor_t* antennaInfor); + +#endif ///#if (LL_FEATURE_EANBLE_LE_AOA_AOD) + +#endif ///AOA_AOD_H_ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/init/ext_init.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/init/ext_init.h new file mode 100755 index 0000000..ff10ed0 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/init/ext_init.h @@ -0,0 +1,82 @@ +/******************************************************************************************************** + * @file ext_init.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef EXT_INIT_H_ +#define EXT_INIT_H_ + + + +/** + * @brief for user to initialize extended initiating module + * notice that only one module can be selected between legacy initiating module and extended initiating module + * @param none + * @return none + */ +void blc_ll_initExtendedInitiating_module(void); + + + +/** + * @brief This function is used to create an ACL connection to a connectable advertiser. + * + * @param[in] filter_policy - used to determine whether the WhiteList is used. If the White List is not used, the Peer_Address_Type and the + Peer_Address parameters specify the address type and address of the advertising device to connect to. + * @param[in] ownAdr_type - indicates the type of address being used in the connection request packets. + * @param[in] peerAdrType - indicates the type of address used in the connectable advertisement sent by the peer. + * @param[in] *peerAddr - indicates the Peer's Public Device Address, Random (static) Device Address, Non-Resolvable Private Address, or + Resolvable Private Address depending on the Peer_Address_Type parameter. + * @param[in] init_phys - indicates the PHY(s) on which the advertising packets should be received on the primary advertising physical channel and + the PHYs for which connection parameters have been specified. + * + * Attention: + * scanInter_0/scanWindow_0/conn_min_0/conn_max_0/timeout_0 are only for 1M PHY. If 1M PHY is not supported, these parameters are ignored. + * scanInter_1/scanWindow_1/conn_min_1/conn_max_1/timeout_1 are only for 2M PHY. If 2M PHY is not supported, these parameters are ignored. + * scanInter_2/scanWindow_2/conn_min_2/conn_max_2/timeout_2 are only for Coded PHY. If Coded PHY is not supported, these parameters are ignored. + * + * @param[in] scanInter_0 - for 1M PHY: recommendations from the Host on how frequently (LE_Scan_Interval) the Controller should scan. + * @param[in] scanWindow_0 - for 1M PHY: recommendations from the Host on how long (LE_Scan_Window) the Controller should scan. + * @param[in] conn_min_0 - for 1M PHY: the minimum allowed connection interval. + * @param[in] conn_max_0 - for 1M PHY: the maximum allowed connection interval. + * @param[in] timeout_0 - for 1M PHY: Supervision timeout for the LE Link. + * @param[in] scanInter_1 - for 2M PHY: recommendations from the Host on how frequently (LE_Scan_Interval) the Controller should scan. + * @param[in] scanWindow_1 - for 2M PHY: recommendations from the Host on how long (LE_Scan_Window) the Controller should scan. + * @param[in] conn_min_1 - for 2M PHY: the minimum allowed connection interval. + * @param[in] conn_max_1 - for 2M PHY: the maximum allowed connection interval. + * @param[in] timeout_1 - for 2M PHY: Supervision timeout for the LE Link. + * @param[in] scanInter_2 - for Coded PHY: recommendations from the Host on how frequently (LE_Scan_Interval) the Controller should scan. + * @param[in] scanWindow_2 - for Coded PHY: recommendations from the Host on how long (LE_Scan_Window) the Controller should scan. + * @param[in] conn_min_2 - for Coded PHY: the minimum allowed connection interval. + * @param[in] conn_max_2 - for Coded PHY: the maximum allowed connection interval. + * @param[in] timeout_2 - for Coded PHY: Supervision timeout for the LE Link. + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_extended_createConnection ( init_fp_t filter_policy, own_addr_type_t ownAdrType, u8 peerAdrType, u8 *peerAddr, init_phy_t init_phys, + scan_inter_t scanInter_0, scan_wind_t scanWindow_0, conn_inter_t conn_min_0, conn_inter_t conn_max_0, conn_tm_t timeout_0, + scan_inter_t scanInter_1, scan_wind_t scanWindow_1, conn_inter_t conn_min_1, conn_inter_t conn_max_1, conn_tm_t timeout_1, + scan_inter_t scanInter_2, scan_wind_t scanWindow_2, conn_inter_t conn_min_2, conn_inter_t conn_max_2, conn_tm_t timeout_2 ); + + + + + + +#endif /* EXT_INIT_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/init/init.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/init/init.h new file mode 100755 index 0000000..86005b2 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/init/init.h @@ -0,0 +1,47 @@ +/******************************************************************************************************** + * @file init.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef INIT_H_ +#define INIT_H_ + + + +/** + * @brief This function is used to cancel the HCI_LE_Create_Connection or HCI_LE_Extended_Create_Connection commands. + * This command shall only be issued after the HCI_LE_Create_Connection or HCI_LE_Extended_Create_Connection commands have been issued. + * @param none + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_createConnectionCancel (void); + + +/** + * @brief This function is used to set the timeout of ACL connection establishment + * @param[in] timeout_ms - timeout of ACL connection establishment, unit: mS. If not set, default value is 4000 mS + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_setCreateConnectionTimeout (u32 timeout_ms); + + + + +#endif /* INIT_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/init/leg_init.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/init/leg_init.h new file mode 100755 index 0000000..9b7e9d1 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/init/leg_init.h @@ -0,0 +1,67 @@ +/******************************************************************************************************** + * @file leg_init.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef LLMS_INIT_H_ +#define LLMS_INIT_H_ + +#include "stack/ble/hci/hci_cmd.h" + + + +/** + * @brief for user to initialize legacy initiating module + * notice that only one module can be selected between legacy initiating module and extended initiating module + * @param none + * @return none + */ +void blc_ll_initLegacyInitiating_module(void); + +#define blc_ll_initInitiating_module blc_ll_initLegacyInitiating_module + +/** + * @brief This function is used to create an ACL connection to a connectable advertiser. + * @param[in] scan_interval - recommendations from the Host on how frequently (LE_Scan_Interval) the Controller should scan. + * @param[in] scan_window - recommendations from the Host on how long (LE_Scan_Window) the Controller should scan. + * @param[in] filter_policy - used to determine whether the White List is used. + * @param[in] adr_type - indicates the type of address used in the connectable advertisement sent by the peer. + * @param[in] *mac - indicates the Peer's Public Device Address. + * @param[in] own_adr_type - indicates the type of address being used in the connection request packets. + * @param[in] conn_min - the minimum allowed connection interval. + * @param[in] conn_max - the maximum allowed connection interval. + * @param[in] conn_latency - he maximum allowed connection latency + * @param[in] timeout - defines the link supervision timeout for the connection. + * @param[in] ce_min - informative parameters providing the Controller with the expected minimum length of the connection events. + * @param[in] ce_max - informative parameters providing the Controller with the expected maximum length of the connection events. + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_createConnection( scan_inter_t scanInter, scan_wind_t scanWindow, init_fp_t fp, u8 peerAdrType, u8 *peerAddr, own_addr_type_t ownAdrType, + conn_inter_t conn_min, conn_inter_t conn_max, u16 conn_latency, conn_tm_t timeout, u16 ce_min, u16 ce_max ); + + + + + + + + + +#endif /* LLMS_INIT_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/bis.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/bis.h new file mode 100755 index 0000000..ed75bec --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/bis.h @@ -0,0 +1,39 @@ +/******************************************************************************************************** + * @file bis.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef BIS_H_ +#define BIS_H_ + + +//Note: user can't modify this value,and this value must 4 byte aligned +#define BIS_PARAM_LENGTH (192) + + + +u32 blc_ll_getAvailBisNum(u8 role); +u32 blt_ll_bis_getAccessCode(u32 seedAccessCode, u8 bisSeq); +u32 blt_ll_bis_getSeedAccessAddr(void); + +ble_sts_t blc_ll_InitBisConnectionlessParameters(u8 *pBisPara, u8 bis_bcst_num, u8 bis_sync_num); + + +#endif diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/bis_bcst.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/bis_bcst.h new file mode 100755 index 0000000..33b1994 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/bis_bcst.h @@ -0,0 +1,79 @@ +/******************************************************************************************************** + * @file bis_bcst.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef BIS_BCST_H_ +#define BIS_BCST_H_ + +//Note: user can't modify this value,and this value must 4 byte aligned +#define BIG_BCST_PARAM_LENGTH (672) //4B aligned + + +/** + * @brief This function is used to initialize BIG broadcast module. + * @param none + * @return none + */ +void blc_ll_initBigBroadcast_module(void); + + +/** + * @brief + * @param none + * @return none + */ +ble_sts_t blc_ll_initBigBcstParameters(u8 *pBigBcstPara, u8 bigBcstNum); + + +/** + * @brief + * @param none + * @return none + */ +ble_sts_t blc_hci_le_createBigParams(hci_le_createBigParams_t* pCmdParam); + + +/** + * @brief + * @param none + * @return none + */ +ble_sts_t blc_hci_le_createBigParamsTest(hci_le_createBigParamsTest_t* pCmdParam); + + +/** + * @brief + * @param none + * @return none + */ +ble_sts_t blc_hci_le_terminateBig(hci_le_terminateBigParams_t* pCmdParam); //TODO: BIG BCST and BIG SYNC use common BIG CB + + +/** + * @brief Used to enable private ExtADV to send BIGINFO + * @param ExtADV handle + * @param If the BIS encrypted + * @return none + */ +void blc_ll_enPrivExtAdvForBigBcst(u8 extAdvHdl); + + +#endif /* BIS_BCST_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/bis_sync.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/bis_sync.h new file mode 100755 index 0000000..63881d1 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/bis_sync.h @@ -0,0 +1,93 @@ +/******************************************************************************************************** + * @file bis_sync.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2021.02 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef BIS_SYNC_H_ +#define BIS_SYNC_H_ + + +#define BIG_SYNC_PARAM_LENGTH (696) // Note: user can't modify this value,and this value must 4 byte aligned + + + +/** + * @brief This function is used to initialize BIG Synchronize module. + * @param none + * @return none + */ +void blc_ll_initBisSynchronize_module(void); + +/** + * @brief This function is used to initialize BIG Synchronize parameters. + * @param pointer to BIG Synchronize parameters buffer + * @return Number of BIG SYNC supported + */ +ble_sts_t blc_ll_initBigSyncParameters(u8 *pBigSyncPara, u8 bigSyncNum); + + +/** + * @brief + * @param none + * @return none + */ +ble_sts_t blc_hci_le_bigCreateSync(hci_le_bigCreateSyncParams_t* pCmdParam); + + +/** + * @brief + * @param none + * @return none + */ +ble_sts_t blc_hci_le_bigTerminateSync(u8 bigHandle, u8* pRetParam); + + +/** + * @brief Used to enable private LegScan to get BIGINFO for BIG SYNC + * @param none + * @return none + */ +void blc_ll_enPrivLegScanForBigBync(void); + + +/** + * @brief Used to enable scan to get BIGINFO for BIG SYNC + * @param none + * @return none + */ +void blc_ll_enScanForBigBync(void); + +/** + * @brief + * @param none + * @return none + */ +ble_sts_t blc_ll_bigCreateSync(u8 big_handle, u16 sync_handle, u8 enc, u8 broadcast_code[16], + u8 mse, u16 big_sync_timeout, u8 num_bis, u8 *bis); + +/** + * @brief + * @param none + * @return none + */ +ble_sts_t blc_ll_bigTerminateSync(u8 bigHandle); + + +#endif /* BIS_SYNC_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/cis.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/cis.h new file mode 100755 index 0000000..62763b5 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/cis.h @@ -0,0 +1,38 @@ +/******************************************************************************************************** + * @file cis.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef CIS_H_ +#define CIS_H_ + + + +//Note: user can't modify this value,and this value must 4 byte aligned +#define CIS_CONN_PARAM_LENGTH (344) + + + + +ble_sts_t blc_ll_initCisConnectionParameters( u8 *pCisConnPara, u32 master_cis_num, u32 slave_cis_num); + +_attribute_ram_code_ void irq_cis_conn_tx(void); + +#endif /* CIS_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/cis_master.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/cis_master.h new file mode 100755 index 0000000..866336c --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/cis_master.h @@ -0,0 +1,92 @@ +/******************************************************************************************************** + * @file cis_master.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef CIS_MASTER_H_ +#define CIS_MASTER_H_ + + + + +#define CIG_MST_PARAM_LEN (436) //Note: user can't modify this value,and this value must 4 byte aligned +#define CIG_ID_0 0 +#define CIG_ID_1 1 +#define CIG_ID_2 2 +#define CIG_ID_3 3 +#define CIG_ID_INVALID 0xFF + + + + +/** + * @brief for user to initialize CIS master module. + * @param none + * @return none + */ +void blc_ll_initCisMaster_module(void); + + +/** + * @brief + * @param none + * @return none + */ +void blc_ll_initCisMasterParameters( u8 *pCigPara, int cig_mst_num); + + +/** + * @brief + * @param + * @param + * @return ble_sts_t + */ +ble_sts_t blc_hci_le_setCigParams (hci_le_setCigParam_cmdParam_t* pCmdParam, hci_le_setCigParam_retParam_t* pRetParam); + + +/** + * @brief + * @param + * @param + * @return ble_sts_t + */ +ble_sts_t blc_hci_le_setCigParamsTest(hci_le_setCigParamTest_cmdParam_t* pCmdParam, hci_le_setCigParam_retParam_t* pRetParam); + + +/** + * @brief + * @param + * @param + * @return ble_sts_t + */ +ble_sts_t blc_hci_le_removeCig(u8 cigId, u8* pRetParamm); + + +/** + * @brief + * @param + * @param + * @return ble_sts_t + */ +ble_sts_t blc_hci_le_createCis(hci_le_CreateCisParams_t* pCisPara); + + + +#endif diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/cis_slave.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/cis_slave.h new file mode 100755 index 0000000..5902879 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/cis_slave.h @@ -0,0 +1,75 @@ +/******************************************************************************************************** + * @file cis_slave.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef CIS_SLAVE_H_ +#define CIS_SLAVE_H_ + +//#if (LL_FEATURE_ENABLE_CONNECTED_ISOCHRONOUS_STREAM_SLAVE) + + + + +#define CIG_SLV_PARAM_LEN (416) //Note: user can't modify this value,and this value must 4 byte aligned + + + + +/** + * @brief for user to initialize CIS slave module. + * @param none + * @return none + */ +void blc_ll_initCisSlave_module(void); + + +/** + * @brief + * @param + * @param + * @return ble_sts_t + */ +ble_sts_t blc_ll_initCisSlaveParameters( u8 *pCisSlavePara, int cis_slv_num); + + +/** + * @brief + * @param + * @param + * @return ble_sts_t + */ +ble_sts_t blc_hci_le_acceptCisReq(u16 cisHandle); + + +/** + * @brief + * @param + * @param + * @return ble_sts_t + */ +ble_sts_t blc_hci_le_rejectCisReq(u16 cisHandle, u8 reason, u8* pRetParam); + + + +#endif + + +//#endif /* CIS_MASTER_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/iso.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/iso.h new file mode 100755 index 0000000..0daf329 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/iso.h @@ -0,0 +1,95 @@ +/******************************************************************************************************** + * @file iso.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef ISO_H_ +#define ISO_H_ + +#define ISO_RX_EVENT_LENGTH (24) //Note: user can't modify this value,and this value must 4 byte aligned +#define CIS_TX_PDU_BUFFER_LENGTH (28) //Note: user can't modify this value,and this value must 4 byte aligned +#define BIS_TX_PDU_BUFFER_LENGTH (20) //Note: user can't modify this value,and this value must 4 byte aligned +/** + * @brief for user to initialize CIS ISO TX FIFO. + * @param[in] pRxbuf - TX FIFO buffer address(Tx buffer must concern all CISes). + * @param[in] fifo_size - TX FIFO size, size must be 4*n + * @param[in] fifo_number - TX FIFO number, can only be 4, 8, 16 or 32 + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_initCisTxFifo(u8 *pTxbuf, int fifo_size, int fifo_number); + + +/** + * @brief for user to initialize CIS ISO RX FIFO. + * @param[in] pRxbuf - RX FIFO buffer address. + * @param[in] fifo_size - RX FIFO size, size must be 4*n + * @param[in] fifo_number - RX FIFO number, can only be 4, 8, 16 or 32 + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_initCisRxFifo(u8 *pRxbuf, int fifo_size, int fifo_number); + + +/** + * @brief for user to initialize CIS RX EVT FIFO. + * @param[in] pRxbuf - RX FIFO buffer address. + * @param[in] fifo_size - RX FIFO size, size must be 4*n + * @param[in] fifo_number - RX FIFO number, can only be 4, 8, 16 or 32 + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_initCisRxEvtFifo(u8 *pRxbuf, int fifo_size, int fifo_number); + + +/** + * @brief for user to initialize BIS ISO TX FIFO. + * @param[in] pRxbuf - TX FIFO buffer address. + * @param[in] fifo_size - RX FIFO size + * @param[in] fifo_number - RX FIFO number, can only be 4, 8, 16 or 32 + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_initBisTxFifo(u8 *pTxbuf, int fifo_size, int fifo_number); + + +/** + * @brief for user to initialize BIS ISO RX FIFO. + * @param[in] pRxbuf - RX FIFO buffer address. + * @param[in] fifo_size - RX FIFO size + * @param[in] fifo_number - RX FIFO number, can only be 4, 8, 16 or 32 + * @return status, 0x00: succeed + * other: failed + */ +//ble_sts_t blc_ll_initBisRxFifo(u8 *pRxbuf, int fifo_size, int fifo_number); +ble_sts_t blc_ll_initBisRxFifo(u8 *pRxbuf, int full_size, int fifo_number, u8 bis_sync_num); + +/** + * @brief this function is used by the Host to enable LL feature of Isochronous channels, + * @param[in] en - 1:enable 0: disable. + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_setHostFeatureISOChannel_en(u8 en); + + +#endif + + diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/iso_test.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/iso_test.h new file mode 100755 index 0000000..dc4fadb --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/iso/iso_test.h @@ -0,0 +1,80 @@ +/******************************************************************************************************** + * @file iso_test.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#ifndef STACK_BLE_CONTROLLER_LL_ISO_ISO_TEST_H_ +#define STACK_BLE_CONTROLLER_LL_ISO_ISO_TEST_H_ + + +#define ISO_TESt_SUPPORT_MAX_NUM (2) + +typedef struct{ + u32 successCnt; + u32 missedCnt; + u32 failedCnt; + u32 lastPkt; +}iso_test_receive_infor_t; + +typedef struct{ + u32 send_pkt_cnt; + u32 isoTestSendTick; +}iso_test_trasmit_infor_t; + +typedef struct{ + + u8 occupy; + u8 isoTestMode; // 0: test mode disable, 1: transmit 2: receive + u8 isoTest_payload_type; + u8 rsvd1; + + union{ + iso_test_receive_infor_t recMode; + iso_test_trasmit_infor_t tranMode; + }; + +}iso_test_param_t; + +typedef enum{ + ISO_TEST_ZERO, + ISO_TEST_VARIABLE, + ISO_TEST_MAXIMUM, +}iso_test_payload_type_t; + +/** + * @brief This function is used to initialize LE ISO test mode. + * @param none + * @return none + */ +void blc_initIsoTestMode(void); + + +/** + * @brief This function is used to enter ISO test mode, only for testing purposes. + * @param *pCmdParam + * @return ble_sts_t + */ +ble_sts_t blc_hci_le_iso_transmit_test_cmd(hci_le_isoTransmitTestCmdParams_t *pCmdParam); + + +ble_sts_t blc_hci_le_iso_receive_test_cmd(hci_le_isoReceiveTestCmdParams_t *pCmdParam); + +#endif /* STACK_BLE_CONTROLLER_LL_ISO_ISO_TEST_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/ll.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/ll.h new file mode 100755 index 0000000..7d517c4 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/ll.h @@ -0,0 +1,185 @@ +/******************************************************************************************************** + * @file ll.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef LL_H_ +#define LL_H_ + + + +/** + * @brief Telink defined LinkLayer Event Callback + */ +typedef void (*blt_event_callback_t)(u8 e, u8 *p, int n); + + + + +typedef enum{ + BLT_EV_FLAG_ADV_DURATION_TIMEOUT = 0, + BLT_EV_FLAG_RX_DATA_ABANDOM, + BLT_EV_FLAG_GPIO_EARLY_WAKEUP, + BLT_EV_FLAG_SLEEP_ENTER, + BLT_EV_FLAG_SUSPEND_EXIT, + BLT_EV_FLAG_LL_REJECT_IND, + BLT_EV_MAX_NUM, +}blt_ev_flag_t; + + + + + + + +typedef enum{ + LL_FEATURE_ENABLE = 1, + LL_FEATURE_DISABLE = 0, +}ll_feature_value_t; + + + +/** + * @brief Telink defined LinkLayer Event callBack + * @param[in] e - event number, must use element of "blt_ev_flag_t" + * @param[in] p - callBack function + * @return none + */ +void blc_ll_registerTelinkControllerEventCallback (u8 e, blt_event_callback_t p); + +/** + * @brief irq_handler for BLE stack, process system tick interrupt and RF interrupt + * @param none + * @return none + */ +void blc_sdk_irq_handler(void); + +/** + * @brief main_loop for BLE stack, process data and event + * @param none + * @return none + */ +void blc_sdk_main_loop (void); + + + +/** + * @brief for user to initialize MCU + * @param none + * @return none + */ +void blc_ll_initBasicMCU (void); + + + +/** + * @brief for user to initialize link layer Standby state + * @param none + * @return none + */ +void blc_ll_initStandby_module (u8 *public_adr); + + +/** + * @brief this function is used to read MAC address + * @param[in] *addr - The address where the read value(MAC address) prepare to write. + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_readBDAddr(u8 *addr); + + +/** + * @brief this function is used to set the LE Random Device Address in the Controller + * @param[in] *randomAddr - Random Device Address + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_setRandomAddr(u8 *randomAddr); + + +/** + * @brief This function is used to check if the address's type is public + * @param[in] *addr - The address need to check. + * @return bool, 0x00: no public, 0x01: Public + */ +bool blc_ll_isValidPublicAddr(u8* addr); + + +/** + * @brief This function is used to check if the address's type is random + * @param[in] *addr - The address need to check. + * @return bool, 0x00: no random, 0x01: random + */ +bool blc_ll_isValidRandomAddr(u8* addr); + + +/** + * @brief This function is used to check if owner's address type is valid + * @param[in] ownAddrType - Owner address type. + * @param[in] randomAddr - If Owner's address type is Random, input Random address. + * @return bool, 0x00: invalid, 0x01: valid + */ +bool blc_ll_isValidOwnAddrByAddrType(u8 ownAddrType, u8* randomAddr); + + +/** + * @brief this function is used by the Host to specify a channel classification based on its local information, + * only the master role is valid. + * @param[in] bit_number - Bit position in the FeatureSet. + * @param[in] bit_value - refer to the struct "ll_feature_value_t". + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_hci_le_setHostFeature(u8 bit_number, ll_feature_value_t bit_value); + + +/** + * @brief this function is used check if any controller buffer initialized by application incorrect. + * attention: this function must be called at the end of BLE LinkLayer Initialization. + * @param none + * @return status, 0x00: succeed, no buffer error + * other: buffer error code + */ +ble_sts_t blc_controller_check_appBufferInitialization(void); + + + +/** + * @brief this function is used by the Host to specify a channel classification based on its local information, + * only the master role is valid. + * @param[in] *map - channel map + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_setHostChannel(u8 * chnMap); + + +/** + * @brief this function is used to reset module of all. + * @param none + * @return status, 0x00: succeed, no buffer error + * other: buffer error code + */ +ble_sts_t blc_hci_reset(void); +ble_sts_t blc_hci_le_getRemoteSupportedFeatures(u16 connHandle); +ble_sts_t blc_hci_le_readChannelMap(u16 connHandle, u8 *returnChannelMap); + +#endif /* LL_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/ll_pm.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/ll_pm.h new file mode 100755 index 0000000..a4674ba --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/ll_pm.h @@ -0,0 +1,141 @@ +/******************************************************************************************************** + * @file ll_pm.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef LL_PM_H_ +#define LL_PM_H_ + + + +/** + * @brief + */ +typedef enum { + PM_SLEEP_DISABLE = 0, + PM_SLEEP_LEG_ADV = BIT(0), + PM_SLEEP_LEG_SCAN = BIT(1), + PM_SLEEP_ACL_SLAVE = BIT(2), + PM_SLEEP_ACL_MASTER = BIT(3), +}sleep_mask_t; + + + +/** + * @brief + */ +/* DeepSleepRetention_Enable */ +typedef enum { + PM_DeepRetn_Disable = 0x00, + PM_DeepRetn_Enable = 0x01, +} deep_retn_en_t; + + +/** + * @brief for user to initialize low power mode + * @param none + * @return none + */ +void blc_ll_initPowerManagement_module(void); + + +/** + * @brief LinkLayer initialization after deepSleep retention wake_up + * @param none + * @return none + */ +void blc_ll_recoverDeepRetention(void); + + +/** + * @brief for user to set low power mode mask + * @param mask - low power mode mask + * @return none + */ +void blc_pm_setSleepMask (sleep_mask_t mask); + +/** + * @brief for user to enable or disable deepSleep retention function + * @param en - deepSleep retention enable, 1: enable; 0: disable + * @return none + */ +void blc_pm_setDeepsleepRetentionEnable (deep_retn_en_t en); + +/** + * @brief for user to set low power mode wake up source + * @param wakeup_src - low power mode wake_up source + * @return none + */ +void blc_pm_setWakeupSource (SleepMode_TypeDef wakeup_src); + + +/** + * @brief for user to get low power mode wake up time + * @param none + * @return bltPm.current_wakeup_tick + */ +u32 blc_pm_getWakeupSystemTick(void); + +/** + * @brief for user to set the threshold of sleep tick for entering deep retention mode + * @param thres_ms - the threshold of time for suspend or deepsleep retention + * @return none. + */ +void blc_pm_setDeepsleepRetentionThreshold(u32 thres_ms); + +/** + * @brief for user to set early wake up tick for deep retention mode + * @param earlyWakeup_us - early wake up tick for deep retention mode + * @return none. + */ +void blc_pm_setDeepsleepRetentionEarlyWakeupTiming(u32 earlyWakeup_us); + +/** + * @brief for user to set the type of deep retention mode + * @param sleep_type - the type of deep retention mode + * @return none. + */ +void blc_pm_setDeepsleepRetentionType(SleepMode_TypeDef sleep_type); + + + +/** + * @brief application wake up low power mode process callback function + */ +typedef void (*pm_appWakeupLowPower_callback_t)(int); + +/** + * @brief for user to set application wake up low power mode + * @param wakeup_tick - low power mode wake up time + * @param enable - low power mode application wake up enable + * @return none + */ +void blc_pm_setAppWakeupLowPower(u32 wakeup_tick, u8 enable); + +/** + * @brief for user to register the callback for application wake up low power mode process + * @param cb - the pointer of callback function + * @return none. + */ +void blc_pm_registerAppWakeupLowPowerCb(pm_appWakeupLowPower_callback_t cb); + + + +#endif /* LL_PM_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/prdadv/pda.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/prdadv/pda.h new file mode 100755 index 0000000..5936dbf --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/prdadv/pda.h @@ -0,0 +1,28 @@ +/******************************************************************************************************** + * @file pda.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef STACK_BLE_CONTROLLER_LL_PRDADV_PDA_H_ +#define STACK_BLE_CONTROLLER_LL_PRDADV_PDA_H_ + + + +#endif /* STACK_BLE_CONTROLLER_LL_PRDADV_PDA_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/prdadv/pda_sync.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/prdadv/pda_sync.h new file mode 100755 index 0000000..1c68a78 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/prdadv/pda_sync.h @@ -0,0 +1,108 @@ +/******************************************************************************************************** + * @file pda_sync.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#ifndef STACK_BLE_CONTROLLER_LL_PRDADV_PDA_SYNC_H_ +#define STACK_BLE_CONTROLLER_LL_PRDADV_PDA_SYNC_H_ + + +/** + * @brief for user to initialize periodic advertising synchronization module + * @param none + * @return none + */ +void blc_ll_initPeriodicAdvertisingSynchronization_module(void); + + +/** + * @brief this function is used to synchronize with a periodic advertising train from an advertiser and begin + receiving periodic advertising packets. + * @param[in] options - used to determine whether the Periodic Advertiser List is used and whether HCI_Periodic_Advertising_Report events + * for this periodic advertising train are initially enabled or disabled. + * @param[in] adv_sid - Advertising SID subfield in the ADI field used to identify the Periodic Advertising + * @param[in] adv_adrType - Advertiser Address Type + * @param[in] *adv_addr - Advertiser Address + * @param[in] skip - The maximum number of periodic advertising events that can be skipped after a successful receive + * @param[in] sync_timeout - Synchronization timeout for the periodic advertising train + * @param[in] sync_cte_type - + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_periodicAdvertisingCreateSync ( option_msk_t options, u8 adv_sid, u8 adv_adrType, u8 *adv_addr, u16 skip, sync_tm_t sync_timeout, u8 sync_cte_type); + +/** + * @brief This function is used to cancel the periodic advertising create sync command while it is pending. + * @param none + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_periodicAdvertisingCreateSyncCancel (void); + + + +/** + * @brief This function is used to stop reception of the periodic advertising train identified + * by the Sync_Handle parameter. + * @param[in] sync_handle - Sync_Handle identifying the periodic advertising train + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_periodicAdvertisingTerminateSync (u16 sync_handle); + +/** + * @brief This function is used to add an entry, consisting of a single device address and SID, + * to the Periodic Advertiser list stored in the Controller. + * @param[in] adv_adrType - Advertiser_Address_Type + * @param[in] *adv_addr - Advertiser_Address + * @param[in] adv_sid - Advertising_SID + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_addDeivceToPeriodicAdvertiserList (u8 adv_adrType, u8 *adv_addr, u8 adv_sid); + +/** + * @brief This function is used to remove one entry from the list of Periodic Advertisers + * stored in the Controller. + * @param[in] adv_adrType - Advertiser_Address_Type + * @param[in] *adv_addr - Advertiser_Address + * @param[in] adv_sid - Advertising_SID + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_removeDeivceFromPeriodicAdvertiserList (u8 adv_adrType, u8 *adv_addr, u8 adv_sid); + +/** + * @brief This function is used to remove all entries from the list of Periodic Advertisers. + * @param none + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_clearPeriodicAdvertiserList (void); + +/** + * @brief This function is used to read the total number of Periodic Advertiser list entries. + * @param[in] none + * @param[out] *perdAdvListSize - point to Periodic_Advertiser_List_Size + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_readPeriodicAdvertiserListSize (u8 *perdAdvListSize); + +ble_sts_t blc_hci_le_periodic_advertising_create_sync(hci_le_periodicAdvCreateSync_cmdParam_t* cmdPara); + + + + +#endif /* STACK_BLE_CONTROLLER_LL_PRDADV_PDA_SYNC_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/prdadv/prd_adv.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/prdadv/prd_adv.h new file mode 100755 index 0000000..3e3603d --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/prdadv/prd_adv.h @@ -0,0 +1,118 @@ +/******************************************************************************************************** + * @file prd_adv.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#ifndef STACK_BLE_CONTROLLER_LL_PRDADV_PRD_ADV_H_ +#define STACK_BLE_CONTROLLER_LL_PRDADV_PRD_ADV_H_ + + + + + + + + +/* maximum number of periodic advertising this SDK can support */ +#define PERIODIC_ADV_NUMBER_MAX 2 + + +#define PERD_ADV_PARAM_LENGTH (476) // Note: user can't modify this value,and this value must 4 byte aligned + + + +/** + * @brief for user to initialize periodic advertising module + * @param none + * @return none + */ +void blc_ll_initPeriodicAdvertising_module(void); + + +/** + * @brief for user to allocate periodic advertising parameters buffer + * notice that: this API must used after "blc_ll_initPeriodicAdvertising_module", + * and before any other periodic ADV initialization APIs. + * @param[in] pBuff - global buffer allocated by application layer. + * @param[in] num_periodic_adv - number of application adv_sets + * @return Status - 0x00: command succeeded; + * 0x12: num_periodic_adv exceed maximum number of supported periodic advertising. + */ +ble_sts_t blc_ll_initPeriodicAdvParamBuffer(u8 *pBuff, int num_periodic_adv); + +/** + * @brief This function is used by the Host to set the parameters for periodic advertising. + * @param[in] adv_handle - - Used to identify a periodic advertising train + * @param[in] advInter_min - Periodic_Advertising_Interval_Min(Range: 0x0006 to 0xFFFF, Time = N * 1.25 ms Time Range: 7.5 ms to 81.91875 s) + * @param[in] advInter_max - Periodic_Advertising_Interval_Max + * @param[in] property - Periodic_Advertising_Properties + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_setPeriodicAdvParam(adv_handle_t adv_handle, u16 advInter_min, u16 advInter_max, perd_adv_prop_t property); + +/** + * @brief initialize Periodic Advertising Data buffer for all adv_set + * @param[in] perdAdvData - + * @param[in] max_len_perdAdvData - + * @return none + */ +void blc_ll_initPeriodicAdvDataBuffer(u8 *perdAdvData, int max_len_perdAdvData); + +/** + * @brief initialize Periodic Advertising Data buffer for specific adv_set. + * notice that: + * @param[in] adv_handle - equal to adv_set index here. So if using single adv_set, adv_handle can only be 0x00; + * if using multiple adv_set, for example 3, adv_handle can be 0x00,0x01 and 0x02 + * @param[in] perdAdvData - + * @param[in] max_len_perdAdvData - + * @return Status - 0x00: succeed. + * 0x12: adv_handle out of range. + */ +ble_sts_t blc_ll_initPeriodicAdvDataBuffer_by_advHandle(u8 adv_handle, u8 *perdAdvData, int max_len_perdAdvData); + +/** + * @brief This function is used to set the data used in periodic advertising PDUs. + * @param[in] adv_handle - - equal to adv_set index here. + * @param[in] advData_len - + * @param[in] *advdata - + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_setPeriodicAdvData(adv_handle_t adv_handle, u16 advData_len, u8 *advdata); + + + +/** + * @brief This function is used to enable or disable the periodic advertising for the advertising + * set specified by the Advertising_Handle parameter + * @param[in] adv_enable - Advertising_Enable + * @param[in] adv_handle - Used to identify an advertising set. + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_setPeriodicAdvEnable(adv_en_t per_adv_enable, adv_handle_t adv_handle); + + + + + + + + +#endif /* STACK_BLE_CONTROLLER_LL_PRDADV_PRD_ADV_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/scan/ext_scan.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/scan/ext_scan.h new file mode 100755 index 0000000..7613c94 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/scan/ext_scan.h @@ -0,0 +1,96 @@ +/******************************************************************************************************** + * @file ext_scan.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef LL_SCAN_EXT_H_ +#define LL_SCAN_EXT_H_ + +#include "stack/ble/hci/hci_cmd.h" + + + + + + +/** + * @brief for user to initialize extended scanning module + * notice that only one module can be selected between legacy scanning module and extended scanning module + * @param none + * @return none + */ +void blc_ll_initExtendedScanning_module(void); + + + + + + + +/** + * @brief This function is used to set the extended scan parameters to be used on the advertising physical channels + * attention: when scan_phys is SCAN_PHY_1M, scanType_1 & scanInter_1 & scanWindow_1 are invalid parameters, + * when scan_phys is SCAN_PHY_CODED, scanType_0 & scanInter_0 & scanWindow_0 are invalid parameters, + * @param[in] ownAddrType - Own_Address_Type + * @param[in] scan_fp - Scanning_Filter_Policy + * @param[in] scan_phys - Scanning_PHYs, "SCAN_PHY_1M" or "SCAN_PHY_CODED" + * + * Attention: + * scanType_0/scanInter_0/scanWindow_0 are only for 1M PHY. If 1M PHY is not supported, these parameters are ignored. + * scanType_1/scanInter_1/scanWindow_1 are only for Coded PHY. If Coded PHY is not supported, these parameters are ignored. + * + * @param[in] scanType_0 - Scan_Type for 1M PHY, Passive Scanning or Active Scanning. + * @param[in] scanInter_0 - Scan_Interval for 1M PHY, Time interval from when the Controller started its last scan until it + begins the subsequent scan on the primary advertising physical channel. + * @param[in] scanWindow_0 - Duration of the scan on the primary advertising physical channel for 1M PHY + * + * @param[in] scanType_1 - Scan_Type for Coded PHY, Passive Scanning or Active Scanning. + * @param[in] scanInter_1 - Scan_Interval for Coded PHY, Time interval from when the Controller started its last scan until it + begins the subsequent scan on the primary advertising physical channel. + * @param[in] scanWindow_1 - Duration of the scan on the primary advertising physical channel for Coded PHY + * + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_setExtScanParam ( own_addr_type_t ownAddrType, scan_fp_type_t scan_fp, scan_phy_t scan_phys, + scan_type_t scanType_0, scan_inter_t scanInter_0, scan_wind_t scanWindow_0, + scan_type_t scanType_1, scan_inter_t scanInter_1, scan_wind_t scanWindow_1); + + + + + + + +/** + * @brief This function is used to enable or disable scanning. + * @param[in] extScan_en - 0x00: Scanning disabled; 0x01: Scanning enabled + * @param[in] filter_duplicate - Filter_Duplicates + * @param[in] duration - Scan duration + * @param[in] period - Time interval from when the Controller started its last Scan_Duration until it begins the + * subsequent Scan_Duration. + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_setExtScanEnable (scan_en_t extScan_en, dupe_fltr_en_t filter_duplicate, scan_durn_t duration, scan_period_t period); + + + + + +#endif /* LL_SCAN_EXT_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/scan/leg_scan.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/scan/leg_scan.h new file mode 100755 index 0000000..e9efb99 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/scan/leg_scan.h @@ -0,0 +1,74 @@ +/******************************************************************************************************** + * @file leg_scan.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef LLMS_SCAN_H_ +#define LLMS_SCAN_H_ + + +#include "stack/ble/hci/hci_cmd.h" + + +/** + * @brief for user to initialize legacy scanning module + * notice that only one module can be selected between legacy scanning module and extended scanning module + * @param none + * @return none + */ +void blc_ll_initLegacyScanning_module(void); + + + +/** + * @brief This function is used to set the scan parameters + * @param[in] scan_type - passive Scanning or active scanning. + * @param[in] scan_interval - time interval from when the Controller started its last LE scan until it begins the subsequent LE scan + * @param[in] scan_window - The duration of the LE scan. + * @param[in] ownAddrType - Own_Address_Type + * @param[in] scan_fp - Scanning_Filter_Policy + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_setScanParameter (scan_type_t scan_type, scan_inter_t scan_interval, scan_wind_t scan_window, own_addr_type_t ownAddrType, scan_fp_type_t scan_fp); + + + + + +/** + * @brief enable or disable legacy scanning. + * @param[in] scan_enable + * @param[in] filter_duplicate - controls whether the Link Layer should filter out + * duplicate advertising reports (Filtering_Enabled) to the Host, + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ll_setScanEnable (scan_en_t scan_enable, dupFilter_en_t filter_duplicate); + + +/** + * @brief This function is used to enable the private LegScan filter to filter specific private BIGInfo + * packets according to the SID value of the received ExtAdv packet + * @param[in] sid - The value of SID in the received ExtAdv packet + * @return none + */ +void blc_ll_enPrivLegScanFilterByExtAdvSid(u8 sid); + + +#endif /* LLMS_SCAN_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/ll/scan/scan.h b/b91/b91m_ble_sdk/stack/ble/controller/ll/scan/scan.h new file mode 100755 index 0000000..5cc77d2 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/ll/scan/scan.h @@ -0,0 +1,27 @@ +/******************************************************************************************************** + * @file scan.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef SCAN_H_ +#define SCAN_H_ + + +#endif /* SCAN_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/phy/phy.h b/b91/b91m_ble_sdk/stack/ble/controller/phy/phy.h new file mode 100755 index 0000000..14f5838 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/phy/phy.h @@ -0,0 +1,37 @@ +/******************************************************************************************************** + * @file phy.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef PHY_H_ +#define PHY_H_ + +#include "stack/ble/hci/hci_cmd.h" + + +/** + * @brief this function is used to initialize 2M/Coded PHY feature + * @param none + * @return none + */ +void blc_ll_init2MPhyCodedPhy_feature(void); + + +#endif /* PHY_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/phy/phy_test.h b/b91/b91m_ble_sdk/stack/ble/controller/phy/phy_test.h new file mode 100755 index 0000000..3ebebb8 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/phy/phy_test.h @@ -0,0 +1,97 @@ +/******************************************************************************************************** + * @file phy_test.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef PHY_TEST_H_ +#define PHY_TEST_H_ + +#include "tl_common.h" + +#ifndef PHYTEST_MODE_DISABLE +#define PHYTEST_MODE_DISABLE 0 +#endif + +#ifndef PHYTEST_MODE_THROUGH_2_WIRE_UART +#define PHYTEST_MODE_THROUGH_2_WIRE_UART 1 //Direct Test Mode through a 2-wire UART interface +#endif + +#ifndef PHYTEST_MODE_OVER_HCI_WITH_USB +#define PHYTEST_MODE_OVER_HCI_WITH_USB 2 //Direct Test Mode over HCI(UART hardware interface) +#endif + +#ifndef PHYTEST_MODE_OVER_HCI_WITH_UART +#define PHYTEST_MODE_OVER_HCI_WITH_UART 3 //Direct Test Mode over HCI(USB hardware interface) +#endif + + +#define BLC_PHYTEST_DISABLE 0 +#define BLC_PHYTEST_ENABLE 1 + + + + + + + + +/** + * @brief for user to initialize PHY test module + * @param none + * @return none + */ +void blc_phy_initPhyTest_module(void); + + +/** + * @brief for user to set PHY test enable or disable + * @param[in] en - 1: enable; 0:disable + * @return status: 0x00 command OK, no other rvalue + */ +ble_sts_t blc_phy_setPhyTestEnable (u8 en); + + +/** + * @brief for user to get PHY test status: enable or disable + * @param none + * @return 1: PHY test is enable; 0: PHY test is disable + */ +bool blc_phy_isPhyTestEnable(void); + + +/** + * @brief uart RX data process for PHY test 2 wire UART mode + * @param none + * @return always 0 + */ +int phy_test_2_wire_rx_from_uart (void); + + +/** + * @brief uart TX data process for PHY test 2 wire UART mode + * @param none + * @return always 0 + */ +int phy_test_2_wire_tx_to_uart (void); + + + + +#endif /* PHY_TEST_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/whitelist/resolvlist.h b/b91/b91m_ble_sdk/stack/ble/controller/whitelist/resolvlist.h new file mode 100755 index 0000000..37ca971 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/whitelist/resolvlist.h @@ -0,0 +1,133 @@ +/******************************************************************************************************** + * @file resolvlist.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef LL_RESOLVLIST_H_ +#define LL_RESOLVLIST_H_ + + +#include + + + + +/** + * @brief This function is used to initialize resolving list && RPA concerned parameters + * @param[in] none + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +void blc_ll_resolvListInit(void); + +/** + * @brief This function is used to reset resolving list + * @param[in] none + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t ll_resolvingList_reset(void); + + +/** + * @brief This function is used to add a device to resolving list + * @param[in] peerIdAddrType - device mac address type + * @param[in] peerIdAddr - device mac address + * @param[in] peer_irk - peer IRK pointer + * @param[in] local_irk - local IRK pointer + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t ll_resolvingList_add(u8 peerIdAddrType, u8 *peerIdAddr, u8 *peer_irk, u8 *local_irk); + + +/** + * @brief This function is used to delete a device from resolving list + * @param[in] peerIdAddrType - device mac address type + * @param[in] peerIdAddr - device mac address + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t ll_resolvingList_delete(u8 peerIdAddrType, u8 *peerIdAddr); + + +/** + * @brief This function is used to enable resolvinglist resolution + * @param[in] resolutionEn - 1: enable; 0:disable + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t ll_resolvingList_setAddrResolutionEnable (u8 resolutionEn); + + +/** + * @brief This function is used to get resolving list size + * @param[out] pointer to size + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t ll_resolvingList_getSize(u8 *Size); + + +/** + * @brief This function is used to get the current peer Resolvable Private + * Address being used for the corresponding peer Public and Random (static) Identity Address. + * @param[in] peerIdAddrType - Peer Identity Address Type + * @param[in] peerIdAddr - Peer Identity Address + * @param[out] peerResolvableAddr - Peer Resolvable Address + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t ll_resolvingList_getPeerResolvableAddr (u8 peerIdAddrType, u8* peerIdAddr, u8* peerResolvableAddr); + + +/** + * @brief This function is used to get the current local Resolvable Private + * Address being used for the corresponding peer Identity Address. + * @param[in] peerIdAddrType - Peer Identity Address Type + * @param[in] peerIdAddr - Peer Identity Address + * @param[out] LocalResolvableAddr - Local Resolvable Address + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t ll_resolvingList_getLocalResolvableAddr(u8 peerIdAddrType, u8* peerIdAddr, u8* LocalResolvableAddr); + + +/** + * @brief This function is used to enable resolution of Resolvable Private Addresses in the Controller. + * @param[in] resolutionEn - Address Resolution Enable/Disable + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t ll_resolvingList_setAddrResolutionEnable (u8 resolutionEn); + +/* + * @brief This function is used to set the length of time the controller uses a + * Resolvable Private Address before a new resolvable private address is + * generated and starts being used. This timeout applies to all addresses + * generated by the controller +* @param[in] timeout_s - RPA_Timeout: RPA_Timeout measured in seconds Range: 0x0001 to 0x0E10, Time range: 1 s to 1 hour + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + * */ +ble_sts_t ll_resolvingList_setResolvablePrivateAddrTimer (u16 timeout_s); + +/* + * @brief This function is used to allow the Host to specify the privacy mode to + * be used for a given entry on the resolving list. + * @param[in] peerIdAddrType - Peer Identity Address Type + * @param[in] peerIdAddr - Peer Identity Address + * @param[in] privMode - Privacy_Mode: Network/Device Privacy Mode + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + * */ +ble_sts_t ll_resolvingList_setPrivcyMode(u8 peerIdAddrType, u8* peerIdAddr, u8 privMode); + + +#endif /* LL_RESOLVLIST_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/controller/whitelist/whitelist.h b/b91/b91m_ble_sdk/stack/ble/controller/whitelist/whitelist.h new file mode 100755 index 0000000..b690e7d --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/controller/whitelist/whitelist.h @@ -0,0 +1,62 @@ +/******************************************************************************************************** + * @file whitelist.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef LL_WHITELIST_H_ +#define LL_WHITELIST_H_ + + + +/** + * @brief This function is used to reset whitelist + * @param[in] none + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t ll_whiteList_reset(void); + + +/** + * @brief This function is used to add a device form whitelist + * @param[in] type - device mac address type + * @param[in] addr - device mac address + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t ll_whiteList_add(u8 type, u8 *addr); + + +/** + * @brief This function is used to delete a device from whitelist + * @param[in] type - device mac address type + * @param[in] addr - device mac address + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t ll_whiteList_delete(u8 type, u8 *addr); + + +/** + * @brief This function is used to get whitelist size + * @param[out] pointer to size + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t ll_whiteList_readSize(u8 *returnPublicAddrListSize) ; + + +#endif /* LL_WHITELIST_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/debug.h b/b91/b91m_ble_sdk/stack/ble/debug.h new file mode 100755 index 0000000..a5948d6 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/debug.h @@ -0,0 +1,171 @@ +/******************************************************************************************************** + * @file debug.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef STACK_BLE_DEBUG_H_ +#define STACK_BLE_DEBUG_H_ + + + + +#ifndef DEBUG_PAIRING_ENCRYPTION +#define DEBUG_PAIRING_ENCRYPTION 0 +#endif + + +/* BLE rf irq timing && log enable */ +#ifndef BLE_IRQ_DBG_EN +#define BLE_IRQ_DBG_EN 0 +#endif + +/* BLE Tx fifo log enable */ +#ifndef TX_FIFO_DBG_EN +#define TX_FIFO_DBG_EN 0 +#endif + +/* BLE smp trans.. log enable */ +#ifndef SMP_DBG_EN +#define SMP_DBG_EN 0 +#endif + + +#ifndef TX_PUSH_DATA_LOG +#define TX_PUSH_DATA_LOG 0 +#endif + +#ifndef RX_L2CAP_DATA_LOG +#define RX_L2CAP_DATA_LOG 0 +#endif + + +#ifndef SCHE_DEBUG_DUMP_EN +#define SCHE_DEBUG_DUMP_EN 0 +#endif + +#ifndef SCHE_TIMING_DEBUG_EN +#define SCHE_TIMING_DEBUG_EN 0 +#endif + + +#ifndef DBG_BOUNDARY_RX +#define DBG_BOUNDARY_RX 0 +#endif + + +#ifndef DBG_LL_CTRL_LOG_EN +#define DBG_LL_CTRL_LOG_EN 0 +#endif + + +#ifndef DBG_DLE_DUMP_EN +#define DBG_DLE_DUMP_EN 0 +#endif + +#ifndef DBG_SCHE_TIMING_EN +#define DBG_SCHE_TIMING_EN 0 +#endif + + +#ifndef DBG_IAL_EN +#define DBG_IAL_EN 0 +#endif + +#ifndef DEB_CIG_MST_EN +#define DEB_CIG_MST_EN 0 +#endif + +#ifndef DEB_CIG_SLV_EN +#define DEB_CIG_SLV_EN 0 +#endif + +#ifndef DEB_BIG_BCST_EN +#define DEB_BIG_BCST_EN 0 +#endif + +#ifndef DEB_BIG_SYNC_EN +#define DEB_BIG_SYNC_EN 0 +#endif + +#ifndef DEB_ISO_TEST_EN +#define DEG_ISO_TEST_EN 1 +#endif + +#ifndef DEB_STRUCT_BUFFER_SIZE_CHECK +#define DEB_STRUCT_BUFFER_SIZE_CHECK 1 +#endif + + +#if (DBG_SLAVE_CONN_UPDATE) +#define SLET_upt_cmd_1 10 +#define SLET_upt_cmd_2 11 +#define SLET_upt_cmd_3 12 +#define SLET_upt_cmd_4 13 +#define SLET_upt_sync_1 20 +#define SLET_upt_sync_2 21 +#define SLET_upt_sync_3 22 +#define SLET_upt_sync_4 23 +#endif + +#if 0 +#define SLET_05_rx_crc 5 +#define SLET_06_rx_1st 6 +#define SLET_07_rx_new 7 +#define SLET_10_tx 10 +#define SLET_11_c_cmdone 11 +#define SLET_12_c_1stRxTmt 12 +#define SLET_13_c_rxTmt 13 +#define SLET_14_c_rxCrc2 14 +#endif + + + + + +#if 0 +#define SLEV_txFifo_push 17 +#define SLEV_txFifo_empty 18 +#define SLEV_txFifo_RX 19 +#define SLEV_txFifo_post 20 +#define SLEV_test_event 31 + +#define SL16_tf_hw_push 1 +#define SL16_tf_sw_push 2 +#define SL16_tf_hw_load1 3 +#define SL16_tf_sw_load1 4 +#define SL16_tf_hw_load2 5 +#define SL16_tf_sw_load2 6 +#define SL16_tf_hw_RX 7 +#define SL16_tf_sw_RX 8 +#define SL16_tf_hw_TX 9 +#define SL16_tf_sw_TX 10 +#define SL16_tf_hw_post 11 +#define SL16_tf_sw_post 12 +#define SL16_tf_save 13 + +#define SL16_seq_notify 15 +#define SL16_seq_write 16 +#define SL16_test_2B 17 +#endif + + + + +#endif /* STACK_BLE_DEBUG_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/hci/hci.h b/b91/b91m_ble_sdk/stack/ble/hci/hci.h new file mode 100755 index 0000000..1b5882b --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/hci/hci.h @@ -0,0 +1,296 @@ +/******************************************************************************************************** + * @file hci.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + + +#include "stack/ble/ble_common.h" + +typedef int (*blc_hci_rx_handler_t) (void); +typedef int (*blc_hci_tx_handler_t) (void); + + + +#define HCI_FLAG_EVENT_PHYTEST_2_WIRE_UART (1<<23) +#define HCI_FLAG_EVENT_TLK_MODULE (1<<24) +#define HCI_FLAG_EVENT_BT_STD (1<<25) //HCI event +#define HCI_FLAG_EVENT_STACK (1<<26) //not used now +#define HCI_FLAG_ACL_BT_STD (1<<27) +#define HCI_FLAG_BT_HCI_CMD (1<<28) //HCI command +#define HCI_FLAG_ISO_DATE_STD (1<<29) + +#define TLK_MODULE_EVENT_STATE_CHANGE 0x0730 +#define TLK_MODULE_EVENT_DATA_RECEIVED 0x0731 +#define TLK_MODULE_EVENT_DATA_SEND 0x0732 +#define TLK_MODULE_EVENT_BUFF_AVAILABLE 0x0733 + + + + +#define HCI_MAX_ACL_DATA_LEN 27 + +#define HCI_MAX_DATA_BUFFERS_SALVE 8 +#define HCI_MAX_DATA_BUFFERS_MASTER 8 + +#define HCI_ADV_REPORT_EVT_RSVD_FIFO 3 + +extern blc_hci_rx_handler_t blc_hci_rx_handler; +extern blc_hci_tx_handler_t blc_hci_tx_handler; + + + +extern my_fifo_t hci_tx_iso_fifo; + +typedef struct { + u32 size; + u8 num; + u8 mask; + u8 wptr; + u8 rptr; + u8* p; +}hci_fifo_t; + + +/** + * @brief Definition for HCI packet type & HCI packet indicator + */ +typedef enum{ + HCI_TYPE_CMD = 0x01, + HCI_TYPE_ACL_DATA = 0x02, + HCI_TYPE_SCO_DATA = 0x03, + HCI_TYPE_EVENT = 0x04, + HCI_TYPE_ISO_DATA = 0x05, //core_5.2 +} hci_type_t; + + +/** + * @brief Definition for HCI ACL Data packets Packet_Boundary_Flag + */ +typedef enum{ + HCI_FIRST_NAF_PACKET = 0x00, //LE Host to Controller + HCI_CONTINUING_PACKET = 0x01, //LE Host to Controller / Controller to Host + HCI_FIRST_AF_PACKET = 0x02, //LE Controller to Host +} acl_pb_flag_t; + + + + +/** + * @brief Definition for HCI ISO Data packets PB_Flag + */ +typedef enum{ + HCI_ISO_SDU_FIRST_FRAG = 0x00, //The ISO_Data_Load field contains the first fragment of a fragmented SDU + HCI_ISO_SDU_CONTINUE_FRAG = 0x01, //The ISO_Data_Load field contains a continuation fragment of an SDU + HCI_ISO_SDU_COMPLETE = 0x02, //The ISO_Data_Load field contains a complete SDU + HCI_ISO_SDU_LAST_FRAG = 0x03, //The ISO_Data_Load field contains the last fragment of an SDU. +} iso_pb_flag_t; + + + +/** + * @brief Definition for HCI ISO Data packets Packet_Status_Flag + */ +typedef enum{ + HCI_ISO_VALID_DATA = 0x00, //Valid data. The complete ISO_SDU was received correctly + HCI_ISO_POSSIBLE_INVALID_DATA = 0x01, //Possibly invalid data + HCI_ISO_LOST_DATA = 0x02, //Part(s) of the ISO_SDU were not received correctly. This is reported as "lost data" +} iso_ps_flag_t; + + + +// Controller event handler +typedef int (*hci_event_handler_t) (u32 h, u8 *para, int n); + +// Controller data handler +typedef int (*hci_data_handler_t) (u16 conn, u8 * p); + + + + +// hci event +extern u32 hci_eventMask; +extern u32 hci_le_eventMask; +extern u32 hci_le_eventMask_2; +extern hci_event_handler_t blc_hci_event_handler; +extern hci_data_handler_t blc_hci_data_handler; +extern hci_fifo_t bltHci_rxfifo; +extern hci_fifo_t bltHci_txfifo; + + + +/** + * @brief for user to initialize HCI TX FIFO. + * @param[in] pRxbuf - TX FIFO buffer address. + * @param[in] fifo_size - RX FIFO size + * @param[in] fifo_number - RX FIFO number, can only be 4, 8, 16 or 32 + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_initHciTxFifo(u8 *pTxbuf, int fifo_size, int fifo_number); + +/** + * @brief for user to initialize HCI RX FIFO. + * @param[in] pRxbuf - RX FIFO buffer address. + * @param[in] fifo_size - RX FIFO size + * @param[in] fifo_number - RX FIFO number, can only be 4, 8, 16 or 32 + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_initHciRxFifo(u8 *pRxbuf, int fifo_size, int fifo_number); + +/** + * @brief for user to initialize HCI RX ACL Data FIFO. + * @param[in] pRxbuf - RX FIFO buffer address (Attention: buffer size = fifo_size*fifo_num*conn_max_num). + * @param[in] fifo_size - RX FIFO size + * @param[in] fifo_number - RX FIFO number, can only be 4, 8, 16 or 32 + * @return status, 0x00: succeed + * other: failed + */ +ble_sts_t blc_ll_initHciAclDataFifo(u8 *pAclbuf, int fifo_size, int fifo_number); + + +/** + * @brief this function is used to get data by USB in RX mode for HCI Layer + * @param[in] none. + * @return 0 + */ +int blc_hci_rx_from_usb (void); + + +/** + * @brief this function is used to send data by USB in TX mode for HCI Layer + * @param[in] none. + * @return 0 + */ +int blc_hci_tx_to_usb (void); + + +/** + * @brief this function is used to process HCI data + * @param[in] *p - the pointer of HCI data + * @param[in] n - the length of HCI data + * @return 0 + */ +int blc_hci_handler (u8 *p, int n); + + +/** + * @brief this function is used to report HCI events + * @param[in] h - HCI Event type + * @param[in] *para - data pointer of event + * @param[in] n - data length of event + * @return none + */ +int blc_hci_send_event (u32 h, u8 *para, int n); + + +/** + * @brief this function is used to process HCI events + * @param[in] none. + * @return 0 + */ +int blc_hci_proc (void); + + +/** + * @brief this function is used to set HCI EVENT mask + * @param[in] evtMask - HCI EVENT mask + * @return 0 + */ +ble_sts_t blc_hci_setEventMask_cmd(u32 evtMask); //eventMask: BT/EDR + + +/** + * @brief this function is used to set HCI LE EVENT mask + * @param[in] evtMask - HCI LE EVENT mask(BIT<0-31>) + * @return 0 + */ +ble_sts_t blc_hci_le_setEventMask_cmd(u32 evtMask); //eventMask: LE event 0~31 + + +/** + * @brief this function is used to set HCI LE EVENT mask + * @param[in] evtMask - HCI LE EVENT mask(BIT<32-63>) + * @return 0 + */ +ble_sts_t blc_hci_le_setEventMask_2_cmd(u32 evtMask_2); //eventMask: LE event 32~63 + + +/** + * @brief This function is used to register the controller event processing callback + * @param[in] handler - hci_event_handler_t + * @return none. + */ +void blc_hci_registerControllerEventHandler (hci_event_handler_t handler); + + +/** + * @brief This function is used to register ACL data transmission to Host for processing callback function. + * @param[in] handler - hci_data_handler_t + * @return none. + */ +void blc_hci_registerControllerDataHandler (hci_data_handler_t handle); + + +/** + * @brief this function is used to register HCI TX or RX handler callback function + * @param[in] *prx - blc_hci_rx_handler + * @param[in] *ptx - blc_hci_tx_handler + * @return none. + */ +void blc_register_hci_handler (void *prx, void *ptx); + + +/** + * @brief this function is used to send ACL data to HOST + * @param[in] handle - connect handle + * @param[in] *p - the pointer of l2cap data + * @return 0 + */ +int blc_hci_sendACLData2Host (u16 handle, u8 *p); + +/** + * + */ +int blc_hci_getFreeTxFIFONum(void); +/** + * @brief this function is used to send data + * @param[in] h - HCI Event type + * @param[in] *para - data pointer of event + * @param[in] n - data length of event + * @return 0,-1 + */ +int blc_hci_send_data (u32 h, u8 *para, int n); + + +/** + * @brief This function is used to send ISO data from Controller to HOST. + * @param[in] h - HCI Event type + * @param[in] *iso_load - data pointer of the ISO load + * @param[in] data_load_len - data length of load + * @return 0,-1 + */ +int blc_hci_iso_send_data (u32 h, u8 *iso_load, int data_load_len); + + + + diff --git a/b91/b91m_ble_sdk/stack/ble/hci/hci_cmd.h b/b91/b91m_ble_sdk/stack/ble/hci/hci_cmd.h new file mode 100755 index 0000000..0ef544b --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/hci/hci_cmd.h @@ -0,0 +1,1248 @@ +/******************************************************************************************************** + * @file hci_cmd.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef HCI_CMD_H_ +#define HCI_CMD_H_ + + +#include "stack/ble/ble_format.h" + + + + +/** + * @brief Command Parameters for "7.1.6 Disconnect command" + */ +typedef struct { + u16 connection_handle; + u8 reason; +} hci_disconnect_cmdParam_t; + + + +/** + * @brief Return Parameters for "7.4.6 Read BD_ADDR command" + */ +typedef struct { + u8 status; + u8 bd_addr[6]; +} hci_readBdAddr_retParam_t; + + + + +/** + * @brief Return Parameters for "7.8.2 LE Read Buffer Size command" + */ +typedef struct { + u8 status; + u16 acl_data_pkt_len; // LE_ACL_Data_Packet_Length + u8 num_le_data_pkt; // Total_Num_LE_ACL_Data_Packets +} hci_le_readBufSize_v1_retParam_t; + + +/** + * @brief Command Parameters for "7.8.5 LE Set Advertising Parameters command" + */ +/* Advertising Parameters structure */ +typedef struct { + u16 intervalMin; // Minimum advertising interval for non-directed advertising, time = N * 0.625ms + u16 intervalMax; // Maximum advertising interval for non-directed advertising, time = N * 0.625ms + u8 advType; // Advertising + u8 ownAddrType; + u8 peerAddrType; + u8 peerAddr[6];//BLE_ADDR_LEN]; + u8 advChannelMap; + u8 advFilterPolicy; +} hci_le_setAdvParam_cmdParam_t; + + +/* Advertising_Interval, Time = N * 0.625 ms, + * Notice that these are just part of but not all Advertising_Interval value */ +typedef enum{ + ADV_INTERVAL_3_125MS = 5, + ADV_INTERVAL_3_75MS = 6, + ADV_INTERVAL_10MS = 16, + ADV_INTERVAL_15MS = 24, + ADV_INTERVAL_20MS = 32, + ADV_INTERVAL_25MS = 40, + ADV_INTERVAL_30MS = 48, + ADV_INTERVAL_35MS = 56, + ADV_INTERVAL_40MS = 64, + ADV_INTERVAL_45MS = 72, + ADV_INTERVAL_50MS = 80, + ADV_INTERVAL_60MS = 96, + ADV_INTERVAL_70MS = 112, + ADV_INTERVAL_80MS = 128, + ADV_INTERVAL_90MS = 144, + ADV_INTERVAL_100MS = 160, + ADV_INTERVAL_150MS = 240, + ADV_INTERVAL_195MS = 312, + ADV_INTERVAL_200MS = 320, + ADV_INTERVAL_250MS = 400, + ADV_INTERVAL_300MS = 480, + ADV_INTERVAL_350MS = 560, + ADV_INTERVAL_400MS = 640, + ADV_INTERVAL_450MS = 720, + ADV_INTERVAL_500MS = 800, + ADV_INTERVAL_600MS = 960, + ADV_INTERVAL_700MS = 1120, + ADV_INTERVAL_800MS = 1280, + ADV_INTERVAL_900MS = 1440, + ADV_INTERVAL_1S = 1600, + ADV_INTERVAL_1S5 = 2400, + ADV_INTERVAL_2S = 3200, + ADV_INTERVAL_1_28_S = 2048, + ADV_INTERVAL_10_24S = 16384, +}adv_inter_t; + + +/* Advertisement Type */ +typedef enum{ + ADV_TYPE_CONNECTABLE_UNDIRECTED = 0x00, // ADV_IND + ADV_TYPE_CONNECTABLE_DIRECTED_HIGH_DUTY = 0x01, // ADV_INDIRECT_IND (high duty cycle) + ADV_TYPE_SCANNABLE_UNDIRECTED = 0x02 , // ADV_SCAN_IND + ADV_TYPE_NONCONNECTABLE_UNDIRECTED = 0x03 , // ADV_NONCONN_IND + ADV_TYPE_CONNECTABLE_DIRECTED_LOW_DUTY = 0x04, // ADV_INDIRECT_IND (low duty cycle) +}adv_type_t; + +/* Own Address Type */ +typedef enum{ + OWN_ADDRESS_PUBLIC = 0, + OWN_ADDRESS_RANDOM = 1, + OWN_ADDRESS_RESOLVE_PRIVATE_PUBLIC = 2, + OWN_ADDRESS_RESOLVE_PRIVATE_RANDOM = 3, +}own_addr_type_t; + +/* Advertising_Channel_Map */ +typedef enum{ + BLT_ENABLE_ADV_37 = BIT(0), + BLT_ENABLE_ADV_38 = BIT(1), + BLT_ENABLE_ADV_39 = BIT(2), + BLT_ENABLE_ADV_ALL = (BLT_ENABLE_ADV_37 | BLT_ENABLE_ADV_38 | BLT_ENABLE_ADV_39), +}adv_chn_map_t; + +/* Advertising_Filter_Policy */ +typedef enum { + ADV_FP_ALLOW_SCAN_ANY_ALLOW_CONN_ANY = 0x00, // Process scan and connection requests from all devices + ADV_FP_ALLOW_SCAN_WL_ALLOW_CONN_ANY = 0x01, // Process connection requests from all devices and only scan requests from devices that are in the White List. + ADV_FP_ALLOW_SCAN_ANY_ALLOW_CONN_WL = 0x02, // Process scan requests from all devices and only connection requests from devices that are in the White List.. + ADV_FP_ALLOW_SCAN_WL_ALLOW_CONN_WL = 0x03, // Process scan and connection requests only from devices in the White List. + + ADV_FP_NONE = ADV_FP_ALLOW_SCAN_ANY_ALLOW_CONN_ANY, //adv filter policy set to zero, not use whitelist +} adv_fp_type_t; //adv_filterPolicy_type_t + + +#define ALLOW_SCAN_WL BIT(0) +#define ALLOW_CONN_WL BIT(1) + + + + +/** + * @brief Command Parameters for "7.8.9 LE Set Advertising Enable command" + */ +typedef enum { + BLC_ADV_DISABLE = 0x00, + BLC_ADV_ENABLE = 0x01, +} adv_en_t; + + + + +/** + * @brief Command Parameters for "7.8.10 LE Set Scan Parameters command" + */ +typedef enum { + SCAN_TYPE_PASSIVE = 0x00, + SCAN_TYPE_ACTIVE = 0x01, +} scan_type_t; + + +/* Scannning_Interval, Time = N * 0.625 ms, + * Notice that these are just part of but not all Scannning_Interval value */ +typedef enum{ + SCAN_INTERVAL_10MS = 16, + SCAN_INTERVAL_20MS = 32, + SCAN_INTERVAL_30MS = 48, + SCAN_INTERVAL_40MS = 64, + SCAN_INTERVAL_50MS = 80, + SCAN_INTERVAL_60MS = 96, + SCAN_INTERVAL_70MS = 112, + SCAN_INTERVAL_80MS = 128, + SCAN_INTERVAL_90MS = 144, + SCAN_INTERVAL_100MS = 160, + SCAN_INTERVAL_150MS = 240, + SCAN_INTERVAL_200MS = 320, + SCAN_INTERVAL_250MS = 400, + SCAN_INTERVAL_300MS = 480, + SCAN_INTERVAL_350MS = 560, + SCAN_INTERVAL_400MS = 640, + SCAN_INTERVAL_450MS = 720, + SCAN_INTERVAL_500MS = 800, + SCAN_INTERVAL_600MS = 960, + SCAN_INTERVAL_700MS = 1120, + SCAN_INTERVAL_800MS = 1280, + SCAN_INTERVAL_900MS = 1440, + SCAN_INTERVAL_1000MS = 1600, +}scan_inter_t; + +/* Scannning_Window, Time = N * 0.625 ms, + * Notice that these are just part of but not all Scannning_Window value */ +typedef enum{ + SCAN_WINDOW_10MS = 16, + SCAN_WINDOW_20MS = 32, + SCAN_WINDOW_30MS = 48, + SCAN_WINDOW_40MS = 64, + SCAN_WINDOW_50MS = 80, + SCAN_WINDOW_60MS = 96, + SCAN_WINDOW_70MS = 112, + SCAN_WINDOW_80MS = 128, + SCAN_WINDOW_90MS = 144, + SCAN_WINDOW_100MS = 160, + SCAN_WINDOW_150MS = 240, + SCAN_WINDOW_200MS = 320, + SCAN_WINDOW_250MS = 400, + SCAN_WINDOW_300MS = 480, + SCAN_WINDOW_350MS = 560, + SCAN_WINDOW_400MS = 640, + SCAN_WINDOW_450MS = 720, + SCAN_WINDOW_500MS = 800, + SCAN_WINDOW_600MS = 960, + SCAN_WINDOW_700MS = 1120, + SCAN_WINDOW_800MS = 1280, + SCAN_WINDOW_900MS = 1440, + SCAN_WINDOW_1000MS = 1600, +}scan_wind_t; + +/* Scanning_Filter_Policy */ +typedef enum { + SCAN_FP_ALLOW_ADV_ANY = 0x00, //except direct adv address not match + SCAN_FP_ALLOW_ADV_WL = 0x01, //except direct adv address not match + SCAN_FP_ALLOW_UNDIRECT_ADV = 0x02, //and direct adv address match initiator's resolvable private MAC + SCAN_FP_ALLOW_ADV_WL_DIRECT_ADV_MACTH = 0x03, //and direct adv address match initiator's resolvable private MAC + +} scan_fp_type_t; + + + +/** + * @brief Command Parameters for "7.8.11 LE Set Scan Enable command" + */ +/* LE_Scan_Enable */ +typedef enum { + BLC_SCAN_DISABLE = 0x00, + BLC_SCAN_ENABLE = 0x01, +} scan_en_t; + +/* Filter_Duplicates */ +typedef enum { + DUP_FILTER_DISABLE = 0x00, + DUP_FILTER_ENABLE = 0x01, +} dupFilter_en_t; + + + + +/** + * @brief Command Parameters for "7.8.12 LE Create Connection command" + */ +typedef struct{ + u16 scan_inter; + u16 scan_wind; + u8 fp; //init_filter_policy + u8 peerAddr_type; + u8 peer_addr[6]; + u8 ownAddr_type; + u16 conn_min; + u16 conn_max; + u16 connLatency; + u16 timeout; + u16 ceLen_min; + u16 ceLen_max; +} hci_le_createConn_cmdParam_t; + + + +/* Initiator_Filter_Policy */ +typedef enum { + INITIATE_FP_ADV_SPECIFY = 0x00, //connect ADV specified by host + INITIATE_FP_ADV_WL = 0x01, //connect ADV in whiteList +} init_fp_t; + + +/* Connection_Interval, Time = N * 1.25 ms, + * Notice that these are just part of but not all Connection_Interval value */ +typedef enum{ + CONN_INTERVAL_7P5MS = 6, + CONN_INTERVAL_8P75MS = 7, + CONN_INTERVAL_10MS = 8, + CONN_INTERVAL_11P25MS = 9, + CONN_INTERVAL_12P5MS = 10, + CONN_INTERVAL_13P75MS = 11, + CONN_INTERVAL_15MS = 12, + CONN_INTERVAL_16P25MS = 13, + CONN_INTERVAL_17P5MS = 14, + CONN_INTERVAL_18P75MS = 15, + CONN_INTERVAL_20MS = 16, + CONN_INTERVAL_21P25MS = 17, + CONN_INTERVAL_22P5MS = 18, + CONN_INTERVAL_23P75MS = 19, + CONN_INTERVAL_25MS = 20, + CONN_INTERVAL_26P25MS = 21, + CONN_INTERVAL_27P5MS = 22, + CONN_INTERVAL_28P75MS = 23, + CONN_INTERVAL_30MS = 24, + CONN_INTERVAL_31P25MS = 25, + CONN_INTERVAL_32P5MS = 26, + CONN_INTERVAL_33P75MS = 27, + CONN_INTERVAL_35MS = 28, + CONN_INTERVAL_36P25MS = 29, + CONN_INTERVAL_37P5MS = 30, + CONN_INTERVAL_38P75MS = 31, + CONN_INTERVAL_40MS = 32, + CONN_INTERVAL_41P25MS = 33, + CONN_INTERVAL_42P5MS = 34, + CONN_INTERVAL_43P75MS = 35, + CONN_INTERVAL_45MS = 36, + CONN_INTERVAL_46P25MS = 37, + CONN_INTERVAL_47P5MS = 38, + CONN_INTERVAL_48P75MS = 39, + CONN_INTERVAL_50MS = 40, + CONN_INTERVAL_55MS = 44, + CONN_INTERVAL_60MS = 48, + CONN_INTERVAL_62P5MS = 50, + CONN_INTERVAL_65MS = 52, + CONN_INTERVAL_70MS = 56, + CONN_INTERVAL_75MS = 60, + CONN_INTERVAL_80MS = 64, + CONN_INTERVAL_85MS = 68, + CONN_INTERVAL_90MS = 72, + CONN_INTERVAL_95MS = 78, + CONN_INTERVAL_100MS = 80, + CONN_INTERVAL_110MS = 88, + CONN_INTERVAL_120MS = 96, + CONN_INTERVAL_130MS = 104, + CONN_INTERVAL_140MS = 112, + CONN_INTERVAL_150MS = 120, + CONN_INTERVAL_160MS = 128, + CONN_INTERVAL_170MS = 136, + CONN_INTERVAL_180MS = 144, + CONN_INTERVAL_190MS = 152, + CONN_INTERVAL_200MS = 160, + CONN_INTERVAL_250MS = 200, + CONN_INTERVAL_300MS = 240, + CONN_INTERVAL_320MS = 256, +}conn_inter_t; + + +/* Supervision_Timeout, Time = N * 10 ms, + * Notice that these are just part of but not all Supervision_Timeout value */ +typedef enum{ + CONN_TIMEOUT_500MS = 50, + CONN_TIMEOUT_1S = 100, + CONN_TIMEOUT_1S5 = 150, + CONN_TIMEOUT_2S = 200, + CONN_TIMEOUT_2S5 = 250, + CONN_TIMEOUT_3S = 300, + CONN_TIMEOUT_3S5 = 350, + CONN_TIMEOUT_4S = 400, + CONN_TIMEOUT_4S5 = 450, + CONN_TIMEOUT_5S = 500, + CONN_TIMEOUT_6S = 600, + CONN_TIMEOUT_7S = 700, + CONN_TIMEOUT_8S = 800, + CONN_TIMEOUT_9S = 900, + CONN_TIMEOUT_10S = 1000, + CONN_TIMEOUT_15S = 1500, + CONN_TIMEOUT_20S = 2000, +}conn_tm_t; + + + +/** + * @brief Command Parameters for "7.8.16 LE Add Device To White List command" + */ +typedef struct{ + u8 adr_type; + u8 addr[6]; +} hci_le_addDeviceWhitelist_cmdParam_t; + +/** + * @brief Command Parameters for "7.8.17 LE Remove Device From White List command" + */ +typedef struct{ + u8 adr_type; + u8 addr[6]; +} hci_le_removeDeviceWhitelist_cmdParam_t; + + + +/** + * @brief Return Parameters for "7.8.46 LE Read Maximum Data Length command" + */ +typedef struct { + u8 status; + u16 support_max_tx_oct; + u16 support_max_tx_time; + u16 support_max_rx_oct; + u16 support_max_rx_time; +} hci_le_readMaxDataLengthCmd_retParam_t; + + + + + +/** + * @brief Return Parameters for "7.8.47 LE Read PHY command" + */ +typedef struct { + u8 status; + u8 handle[2]; + u8 tx_phy; + u8 rx_phy; +} hci_le_readPhyCmd_retParam_t; + + + +/** + * @brief Command Parameters for "7.8.48 LE Set Default PHY command" + */ + + +/** + * @brief Command Parameters for "7.8.49 LE Set PHY command" + */ + +typedef struct { + u16 connHandle; + u8 all_phys; + u8 tx_phys; + u8 rx_phys; + u16 phy_options; +} hci_le_setPhyCmd_param_t; + + + + +typedef enum { + BLE_PHY_1M = 0x01, + BLE_PHY_2M = 0x02, + BLE_PHY_CODED = 0x03, +} le_phy_type_t; + +typedef enum { + PHY_PREFER_1M = BIT(0), + PHY_PREFER_2M = BIT(1), + PHY_PREFER_CODED = BIT(2), +} le_phy_prefer_type_t; + +typedef enum { + PHY_TRX_PREFER = 0, //has preference among TX & RX PHYs + PHY_TX_NO_PREFER = BIT(0), //has no preference among TX PHYs + PHY_RX_NO_PREFER = BIT(1), //has no preference among RX PHYs + PHY_TRX_NO_PREFER = (BIT(0) | BIT(1)), //has no preference among TX & RX PHYs +} le_phy_prefer_mask_t; + +typedef enum { + CODED_PHY_PREFER_NONE = 0, + CODED_PHY_PREFER_S2 = 1, + CODED_PHY_PREFER_S8 = 2, +} le_ci_prefer_t; //LE coding indication prefer + + + + + + + +/** + * @brief Command Parameters for "7.8.53 LE Set Extended Advertising Parameters command" + */ +typedef struct { + u8 adv_handle; + u16 advEvt_props; + u8 pri_advIntMin[3]; + u8 pri_advIntMax[3]; + u8 pri_advChnMap; + u8 ownAddrType; + u8 peerAddrType; + u8 peerAddr[6]; + u8 advFilterPolicy; + u8 adv_tx_pow; + u8 pri_adv_phy; + u8 sec_adv_max_skip; + u8 sec_adv_phy; + u8 adv_sid; + u8 scan_req_noti_en; +}hci_le_setExtAdvParam_cmdParam_t; + +/* Advertising_Handle */ +typedef enum{ + ADV_HANDLE0 = 0x00, + ADV_HANDLE1 = 0x01, + ADV_HANDLE2 = 0x02, + ADV_HANDLE3 = 0x03, +}adv_handle_t; + + + +/* Advertising Event Properties mask*/ +typedef enum{ + ADVEVT_PROP_MASK_CONNECTABLE = BIT(0), + ADVEVT_PROP_MASK_SCANNABLE = BIT(1), + ADVEVT_PROP_MASK_DIRECTED = BIT(2), + ADVEVT_PROP_MASK_HD_DIRECTED = BIT(3), + ADVEVT_PROP_MASK_LEGACY = BIT(4), + ADVEVT_PROP_MASK_ANON_ADV = BIT(5), + ADVEVT_PROP_MASK_INC_TX_PWR = BIT(6), +}advEvtProp_mask_t; + + +#define ADVEVT_PROP_MASK_CONNECTABLE_SCANNABLE (0x0003) // ADVEVT_PROP_MASK_CONNECTABLE | ADVEVT_PROP_MASK_SCANNABLE +#define ADVEVT_PROP_MASK_LEGACY_SCANNABLE (0x0012) // ADVEVT_PROP_MASK_LEGACY | ADVEVT_PROP_MASK_SCANNABLE +#define ADVEVT_PROP_MASK_LEGACY_DIRECTED (0x0014) // ADVEVT_PROP_MASK_LEGACY | ADVEVT_PROP_MASK_DIRECTED +#define ADVEVT_PROP_MASK_LEGACY_HD_DIRECTED (0x0018) // ADVEVT_PROP_MASK_LEGACY | ADVEVT_PROP_MASK_HD_DIRECTED +#define ADVEVT_PROP_MASK_LEGACY_CONNECTABLE_SCANNABLE (0x0013) // ADVEVT_PROP_MASK_LEGACY | ADVEVT_PROP_MASK_CONNECTABLE | ADVEVT_PROP_MASK_SCANNABLE + + +/* Advertising Event Properties type*/ +typedef enum{ + ADV_EVT_PROP_LEGACY_CONNECTABLE_SCANNABLE_UNDIRECTED = 0x0013, // 0001 0011'b ADV_IND + ADV_EVT_PROP_LEGACY_CONNECTABLE_DIRECTED_LOW_DUTY = 0x0015, // 0001 0101'b ADV_DIRECT_IND(low duty cycle) + ADV_EVT_PROP_LEGACY_CONNECTABLE_DIRECTED_HIGH_DUTY = 0x001D, // 0001 1101'b ADV_DIRECT_IND(high duty cycle) + ADV_EVT_PROP_LEGACY_SCANNABLE_UNDIRECTED = 0x0012, // 0001 0010'b ADV_SCAN_IND + ADV_EVT_PROP_LEGACY_NON_CONNECTABLE_NON_SCANNABLE_UNDIRECTED = 0x0010, // 0001 0000'b ADV_NONCONN_IND + + + ADV_EVT_PROP_EXTENDED_NON_CONNECTABLE_NON_SCANNABLE_UNDIRECTED = 0x0000, // 0000 0000'b ADV_EXT_IND + AUX_ADV_IND/AUX_CHAIN_IND + ADV_EVT_PROP_EXTENDED_CONNECTABLE_UNDIRECTED = 0x0001, // 0000 0001'b ADV_EXT_IND + AUX_ADV_IND/AUX_CHAIN_IND + ADV_EVT_PROP_EXTENDED_SCANNABLE_UNDIRECTED = 0x0002, // 0000 0010'b ADV_EXT_IND + AUX_ADV_IND/AUX_CHAIN_IND + ADV_EVT_PROP_EXTENDED_NON_CONNECTABLE_NON_SCANNABLE_DIRECTED = 0x0004, // 0000 0100'b ADV_EXT_IND + AUX_ADV_IND/AUX_CHAIN_IND + ADV_EVT_PROP_EXTENDED_CONNECTABLE_DIRECTED = 0x0005, // 0000 0101'b ADV_EXT_IND + AUX_ADV_IND/AUX_CHAIN_IND + ADV_EVT_PROP_EXTENDED_SCANNABLE_DIRECTED = 0x0006, // 0000 0110'b ADV_EXT_IND + AUX_ADV_IND/AUX_CHAIN_IND + + + ADV_EVT_PROP_EXTENDED_MASK_ANONYMOUS_ADV = 0x0020, //if this mask on(only extended ADV event can mask it), anonymous advertising + ADV_EVT_PROP_EXTENDED_MASK_TX_POWER_INCLUDE = 0x0040, //if this mask on(only extended ADV event can mask it), TX power include + +}advEvtProp_type_t; + + + +/* Advertising_TX_Power */ +typedef enum { + TX_POWER_0dBm = 0, + TX_POWER_1dBm = 1, + TX_POWER_2dBm = 2, + TX_POWER_3dBm = 3, + TX_POWER_4dBm = 4, + TX_POWER_5dBm = 5, + TX_POWER_6dBm = 6, + TX_POWER_7dBm = 7, + TX_POWER_8dBm = 8, + TX_POWER_9dBm = 9, + TX_POWER_10dBm = 10, +} tx_power_t; + + + +/* Advertising_SID */ +typedef enum{ + ADV_SID_0 = 0x00, + ADV_SID_1 = 0x01, + ADV_SID_2 = 0x02, + ADV_SID_3 = 0x03, +}adv_sid_t; + + + + +/** + * @brief Command Parameters for "7.8.54 LE Set Extended Advertising Data command" + */ + +/* Operation */ +typedef enum { + DATA_OPER_INTER = 0x00, + DATA_OPER_FIRST = 0x01, + DATA_OPER_LAST = 0x02, + DATA_OPER_COMPLETE = 0x03, + DATA_OPER_UNCHANGEED = 0x04, +} data_oper_t; + + +/* Fragment_Preference */ +typedef enum { + DATA_FRAGM_ALLOWED = 0x00, + DATA_FRAGM_NONE_OR_MINIMIZE = 0x01, +} data_fragm_t; + + + + + +/** + * @brief Command Parameters for "7.8.56 LE Set Extended Advertising Enable command" + */ + +typedef struct{ + u8 adv_handle; + u16 duration; + u8 max_ext_adv_evts; +} extAdvEn_Cfg_t; + +typedef struct{ + u8 enable; + u8 num_sets; + extAdvEn_Cfg_t cisCfg[3]; // TSKNUM_EXT_ADV +} hci_le_setExtAdvEn_cmdParam_t; + + + +/** + * @brief Command Parameters for "7.8.61 LE Set Periodic Advertising Parameters command" + */ + +/* Periodic_adv_Interval, Time = N * 1.25 ms, + * Notice that these are just part of but not all Periodic_adv_Interval value */ +typedef enum{ + PERADV_INTERVAL_7P5MS = 6, + PERADV_INTERVAL_8P75MS = 7, + PERADV_INTERVAL_10MS = 8, + PERADV_INTERVAL_11P25MS = 9, + PERADV_INTERVAL_12P5MS = 10, + PERADV_INTERVAL_13P75MS = 11, + PERADV_INTERVAL_15MS = 12, + PERADV_INTERVAL_16P25MS = 13, + PERADV_INTERVAL_17P5MS = 14, + PERADV_INTERVAL_18P75MS = 15, + PERADV_INTERVAL_20MS = 16, + PERADV_INTERVAL_21P25MS = 17, + PERADV_INTERVAL_22P5MS = 18, + PERADV_INTERVAL_23P75MS = 19, + PERADV_INTERVAL_25MS = 20, + PERADV_INTERVAL_26P25MS = 21, + PERADV_INTERVAL_27P5MS = 22, + PERADV_INTERVAL_28P75MS = 23, + PERADV_INTERVAL_30MS = 24, + PERADV_INTERVAL_31P25MS = 25, + PERADV_INTERVAL_32P5MS = 26, + PERADV_INTERVAL_33P75MS = 27, + PERADV_INTERVAL_35MS = 28, + PERADV_INTERVAL_36P25MS = 29, + PERADV_INTERVAL_37P5MS = 30, + PERADV_INTERVAL_38P75MS = 31, + PERADV_INTERVAL_40MS = 32, + PERADV_INTERVAL_41P25MS = 33, + PERADV_INTERVAL_42P5MS = 34, + PERADV_INTERVAL_43P75MS = 35, + PERADV_INTERVAL_45MS = 36, + PERADV_INTERVAL_46P25MS = 37, + PERADV_INTERVAL_47P5MS = 38, + PERADV_INTERVAL_48P75MS = 39, + PERADV_INTERVAL_50MS = 40, + PERADV_INTERVAL_55MS = 44, + PERADV_INTERVAL_60MS = 48, + PERADV_INTERVAL_62P5MS = 50, + PERADV_INTERVAL_65MS = 52, + PERADV_INTERVAL_70MS = 56, + PERADV_INTERVAL_75MS = 60, + PERADV_INTERVAL_80MS = 64, + PERADV_INTERVAL_85MS = 68, + PERADV_INTERVAL_90MS = 72, + PERADV_INTERVAL_95MS = 78, + PERADV_INTERVAL_100MS = 80, + PERADV_INTERVAL_110MS = 88, + PERADV_INTERVAL_120MS = 96, + PERADV_INTERVAL_130MS = 104, + PERADV_INTERVAL_140MS = 112, + PERADV_INTERVAL_150MS = 120, + PERADV_INTERVAL_180MS = 144, + PERADV_INTERVAL_200MS = 160, + PERADV_INTERVAL_250MS = 200, + PERADV_INTERVAL_300MS = 240, + PERADV_INTERVAL_400MS = 320, + PERADV_INTERVAL_500MS = 400, + PERADV_INTERVAL_600MS = 480, + PERADV_INTERVAL_700MS = 560, + PERADV_INTERVAL_800MS = 640, + PERADV_INTERVAL_900MS = 720, + PERADV_INTERVAL_1S = 800, + PERADV_INTERVAL_1S2 = 960, + PERADV_INTERVAL_1S4 = 1120, + PERADV_INTERVAL_1S5 = 1200, + PERADV_INTERVAL_1S6 = 1280, + PERADV_INTERVAL_1S8 = 1440, + PERADV_INTERVAL_2S = 1600, + PERADV_INTERVAL_3S = 2400, + PERADV_INTERVAL_4S = 3200, + PERADV_INTERVAL_5S = 4000, + PERADV_INTERVAL_6S = 4800, + PERADV_INTERVAL_7S = 5600, + PERADV_INTERVAL_8S = 6400, + PERADV_INTERVAL_9S = 7200, + PERADV_INTERVAL_10S = 8000, +}periodic_adv_inter_t; + +typedef enum{ + + PERD_ADV_PROP_MASK_NONE = 0, + + PERD_ADV_PROP_MASK_TX_POWER_INCLUDE = BIT(6), + +}perd_adv_prop_t; + + + +/** + * @brief Command Parameters for "7.8.64 LE Set Extended Scan Parameters command" + */ +typedef struct{ + u8 scan_type; + u16 scan_interval; + u16 scan_window; +} ext_scan_cfg_t; + +typedef struct{ + u8 ownAddress_type; + u8 scan_filter_policy; + u8 scan_PHYs; + ext_scan_cfg_t scanCfg[2]; //at most 2 kind of PHY: 1M and Coded +} hci_le_setExtScanParam_cmdParam_t; + + +/* Scanning_PHYs */ +typedef enum { + SCAN_PHY_1M = BIT(0), + SCAN_PHY_CODED = BIT(2), + SCAN_PHY_1M_CODED = (SCAN_PHY_1M | SCAN_PHY_CODED), +} scan_phy_t; + + + + +/** + * @brief Command Parameters for "7.8.65 LE Set Extended Scan Enable command" + */ +typedef struct{ + u8 Enable; + u8 Filter_Duplicates; + u16 Duration; + u16 Period; +} hci_le_setExtScanEnable_cmdParam_t; + +/* Filter_Duplicates for Extended Scan*/ +typedef enum { + DUPE_FLTR_DISABLE = 0x00, + DUPE_FLTR_ENABLE = 0x01, + DUPE_FLTR_ENABLE_RST_PERIOD = 0x02, +} dupe_fltr_en_t; + + +/* Scan duration, Range: 0x0001 to 0xFFFF, Time = N * 10 ms, Time Range: 10 ms to 655.35 s, + * Notice that these are just part of but not all Scan duration value */ +typedef enum{ + SCAN_DURATION_CONTINUOUS = 0, + SCAN_DURATION_50MS = 5, + SCAN_DURATION_100MS = 10, + SCAN_DURATION_150MS = 15, + SCAN_DURATION_200MS = 20, + SCAN_DURATION_250MS = 25, + SCAN_DURATION_300MS = 30, + SCAN_DURATION_350MS = 35, + SCAN_DURATION_400MS = 40, + SCAN_DURATION_450MS = 45, + SCAN_DURATION_500MS = 50, + SCAN_DURATION_550MS = 55, + SCAN_DURATION_600MS = 60, + SCAN_DURATION_650MS = 65, + SCAN_DURATION_700MS = 70, + SCAN_DURATION_750MS = 75, + SCAN_DURATION_800MS = 80, + SCAN_DURATION_850MS = 85, + SCAN_DURATION_900MS = 90, + SCAN_DURATION_950MS = 96, + SCAN_DURATION_1S = 100, + SCAN_DURATION_1S2 = 120, + SCAN_DURATION_1S5 = 150, + SCAN_DURATION_1S6 = 160, + SCAN_DURATION_1S8 = 180, + SCAN_DURATION_2S = 200, + SCAN_DURATION_3S = 300, + SCAN_DURATION_4S = 400, + SCAN_DURATION_5S = 500, + SCAN_DURATION_6S = 600, + SCAN_DURATION_7S = 700, + SCAN_DURATION_8S = 800, + SCAN_DURATION_9S = 900, + SCAN_DURATION_10S = 1000, +}scan_durn_t; + +/* Scan period, Range: 0x0001 to 0xFFFF, Time = N * 1.28 sec, Time Range: 1.28 s to 83,884.8 s + * Notice that these are just part of but not all Scan period value */ +typedef enum{ + SCAN_WINDOW_CONTINUOUS = 0, + SCAN_WINDOW_1S28 = 1, + SCAN_WINDOW_2S56 = 2, + SCAN_WINDOW_3S84 = 3, + SCAN_WINDOW_5S12 = 4, + SCAN_WINDOW_6S4 = 5, + SCAN_WINDOW_7S68 = 6, + SCAN_WINDOW_8S92 = 7, + SCAN_WINDOW_10S24 = 8, + SCAN_WINDOW_11S52 = 9, + SCAN_WINDOW_12S8 = 10, +}scan_period_t; + + + +/** + * @brief Command Parameters for "7.8.66 LE Extended Create Connection command" + */ +typedef struct{ + u16 scan_inter; + u16 scan_wind; + u16 conn_min; + u16 conn_max; + u16 connLatency; + u16 timeout; + u16 ceLen_min; + u16 ceLen_max; +} ext_init_cfg_t; + +typedef struct{ + u8 fp; //init_filter_policy + u8 ownAddr_type; + u8 peerAddr_type; + u8 peer_addr[6]; + u8 init_PHYs; + ext_init_cfg_t initCfg[3]; +} hci_le_ext_createConn_cmdParam_t; + +#define EXT_CREATE_CONN_CMD_PARAM_MAX_LENGTH (10 + 16 * 3) //10 + sizeof(ext_init_cfg_t) * 3 + +/* Initiating_PHYs */ +typedef enum { + INIT_PHY_1M = BIT(0), + INIT_PHY_2M = BIT(1), //can not use this, at least one bit set for a PHY allowed for scanning on the primary advertising physical channel + INIT_PHY_CODED = BIT(2), + INIT_PHY_1M_2M = (INIT_PHY_1M | INIT_PHY_2M), + INIT_PHY_1M_CODED = (INIT_PHY_1M | INIT_PHY_CODED), + INIT_PHY_2M_CODED = (INIT_PHY_2M | INIT_PHY_CODED), + INIT_PHY_1M_2M_CODED = (INIT_PHY_1M | INIT_PHY_2M | INIT_PHY_1M_CODED), +} init_phy_t; + + + + + +/** + * @brief Command Parameters for "7.8.67 LE Periodic Advertising Create Sync command" + */ +typedef struct{ + u8 Options; + u8 Advertising_SID; + u8 Advertiser_Address_Type; + u8 Advertiser_Address[6]; + u16 Skip; + u16 Sync_Timeout; + u16 Sync_CTE_Type; +} hci_le_periodicAdvCreateSync_cmdParam_t; + +/** + * @brief Command Parameters for "7.8.80 LE Set Connectionless CTE Transmit Parameters command" + */ +typedef struct{ + u8 Advertising_Handle; + u8 CTE_length; + u8 CTE_type; + u8 CTE_count; + + u8 Switch_pattern_len; + u8 Antenna_IDs[1]; +}hci_le_setConnectionless_CTETransmitParam_t; + + +typedef struct{ + adv_handle_t adv_handle; + u8 CTE_enable; +}hci_le_CTE_enable_type; + +typedef struct{ + u16 Sync_Handle; + u8 Sampling_Enable; + u8 Slot_Duration; + + u8 Max_Sampled_CTEs; + u8 Switching_pattern_len; + u8 Antenna_IDs[1]; +}hci_le_setConnectionless_IQsampleEn_t; + + +typedef struct{ + u8 conn_handle; + u8 sampling_en; + u8 slot_duration; + u8 switch_pattern_len; + + u8 antenna_ids[1]; +}hci_le_setConnection_CTERevParams_t; + +typedef struct{ + u8 conn_handle; + u8 CTE_type; + u8 switching_pattern_len; + u8 antenna_IDs[1]; +}hci_le_setConnection_CTETransmitParams_t; + +typedef struct{ + u8 status; + u8 support_switch_sample_rate; + u8 antenna_num; + u8 max_switch_pattern_len; + + u8 max_cte_len; + +}cte_antenna_infor_t; + +typedef struct{ + u8 conn_handle; + u8 cte_req_en; + u16 cte_req_intvl; + + u8 req_cte_len; + u8 req_cte_type; +}hci_le_cteReqEn_t; + +typedef struct{ + u8 conn_handle; + u8 rsp_enable; +}hci_le_cteRspEn_t; + + +/* Options */ +typedef enum { + + /* BIT(0) + * 0: Use the adv_sid, adv_addr_type, and adv_address parameters to determine which advertiser to listen to. + * 1: Use the Periodic Advertiser List to determine which advertiser to listen to. */ + SYNC_ADV_SPECIFY = 0, + SYNC_ADV_FROM_LIST = BIT(0), + + /* BIT(1) + whether HCI_Periodic_Advertising_Report events for this periodic advertising train are initially enabled + 0: enabled + 1: disabled + */ + REPORTING_INITIALLY_EN = 0, + REPORTING_INITIALLY_DIS = BIT(1), + + /* BIT(2) ~ BIT(7) reserved */ +} option_msk_t; + + +/* Synchronization timeout, Time = N * 10 ms, + * Notice that these are just part of but not all Synchronization timeout value */ +typedef enum{ + SYNC_TIMEOUT_100MS = 10, + SYNC_TIMEOUT_200MS = 20, + SYNC_TIMEOUT_300MS = 30, + SYNC_TIMEOUT_400MS = 40, + SYNC_TIMEOUT_500MS = 50, + SYNC_TIMEOUT_1S = 100, + SYNC_TIMEOUT_1S5 = 150, + SYNC_TIMEOUT_2S = 200, + SYNC_TIMEOUT_2S5 = 250, + SYNC_TIMEOUT_3S = 300, + SYNC_TIMEOUT_3S5 = 350, + SYNC_TIMEOUT_4S = 400, + SYNC_TIMEOUT_4S5 = 450, + SYNC_TIMEOUT_5S = 500, + SYNC_TIMEOUT_6S = 600, + SYNC_TIMEOUT_7S = 700, + SYNC_TIMEOUT_8S = 800, + SYNC_TIMEOUT_9S = 900, + SYNC_TIMEOUT_10S = 1000, + SYNC_TIMEOUT_15S = 1500, + SYNC_TIMEOUT_20S = 2000, +}sync_tm_t; + + + + + +/** + * @brief Command Parameters for "7.8.97 LE Set CIG Parameters command" + */ +typedef struct { + u8 cig_id; + u8 sdu_int_m2s[3]; + u8 sdu_int_s2m[3]; + u8 sca; + u8 packing; + u8 framing; + u16 max_trans_lat_m2s; + u16 max_trans_lat_s2m; + u8 cis_count; + u8 restparam[1]; +} hci_le_setCigParam_cmdParam_t; + +typedef struct{ + u8 cis_id; + u8 nse; + u16 max_sdu_m2s; + u16 max_sdu_s2m; + u16 max_pdu_m2s; + u16 max_pdu_s2m; + u8 phy_m2s; + u8 phy_s2m; + u8 bn_m2s; + u8 bn_s2m; +} cigParamTest_cisCfg_t; + +/* Slaves_Clock_Accuracy */ +typedef enum { + PPM_251_500 = 0x00, + PPM_151_250 = 0x01, + PPM_101_150 = 0x02, + PPM_76_100 = 0x03, + PPM_51_75 = 0x04, + PPM_31_50 = 0x05, + PPM_21_30 = 0x06, + PPM_0_20 = 0x07, +} slv_clk_accuracy_t; + + +/* Packing */ +typedef enum { + PACK_SEQUENTIAL = 0x00, + PACK_INTERLEAVED = 0x01, +} packing_type_t; + +/* Framing */ +typedef enum { + UNFRAMED = 0x00, + FRAMED = 0x01, +} framing_t; + + + +/** + * @brief Command Parameters for "7.8.98 LE Set CIG Parameters Test command" + */ +typedef struct{ + u8 cig_id; + u8 sdu_int_m2s[3]; + u8 sdu_int_s2m[3]; + u8 ft_m2s; + u8 ft_s2m; + u16 iso_intvl; + u8 sca; + u8 packing; + u8 framing; + u8 cis_count; //15 B above + cigParamTest_cisCfg_t cisCfg[1]; //14 B for one CIS configuration +} hci_le_setCigParamTest_cmdParam_t; + + + +/** + * @brief Return Parameters for "LE Set CIG Parameters command" and "LE Set CIG Parameters Test command" + */ +typedef struct { + u8 status; + u8 cig_id; + u8 cis_count; + u16 cis_connHandle[1]; //not 4 byte aligned, but no problem +} hci_le_setCigParam_retParam_t; + + +/* ISO_Interval, Time = N * 1.25 ms, + * Notice that these are just part of but not all ISO_Interval value */ +typedef enum{ + ISO_INTERVAL_5MS = 4, + ISO_INTERVAL_6P75MS = 5, + ISO_INTERVAL_7P5MS = 6, + ISO_INTERVAL_8P75MS = 7, + ISO_INTERVAL_10MS = 8, + ISO_INTERVAL_11P25MS = 9, + ISO_INTERVAL_12P5MS = 10, + ISO_INTERVAL_15MS = 12, + ISO_INTERVAL_18P75MS = 15, + ISO_INTERVAL_20MS = 16, + ISO_INTERVAL_25MS = 20, + ISO_INTERVAL_27P5MS = 22, + ISO_INTERVAL_30MS = 24, + ISO_INTERVAL_31P25MS = 25, + ISO_INTERVAL_38P75MS = 31, + ISO_INTERVAL_40MS = 32, + ISO_INTERVAL_48P75MS = 39, + ISO_INTERVAL_50MS = 40, + ISO_INTERVAL_100MS = 80, +}iso_inter_t; + + + + +/** + * @brief Command Parameters for "7.8.99 LE Create CIS command" + */ +typedef struct +{ + u16 cis_handle; + u16 acl_handle; +} cisConnParams_t; + +typedef struct +{ + u8 cis_count; + cisConnParams_t cisConn[1]; +}hci_le_CreateCisParams_t; + + + +#if 0 +/** + * @brief Command Parameters for "7.8.102 LE Reject CIS Request command" + */ +typedef struct +{ + u16 cis_handle; + u8 reason; +} hci_le_rejectCisReqParams_t; +#endif + + + +/** + * @brief Command Parameters for "7.8.103 LE Create BIG command" + */ +typedef struct +{ + u8 big_handle; /* Used to identify the BIG */ + u8 adv_handle; /* Used to identify the periodic advertising train */ + u8 num_bis; /* Total number of BISes in the BIG */ + u8 sdu_intvl[3]; /* The interval, in microseconds, of BIS SDUs */ + u16 max_sdu; /* Maximum size of an SDU, in octets */ + u16 max_trans_lat; /* Maximum time, in milliseconds, for transmitting an SDU */ + u8 rtn; /* The maximum number of times that every BIS Data PDU should be retransmitted */ + u8 phy; /* The transmitter PHY of packets */ + packing_type_t packing;//type same as u8 + framing_t framing;//type same as u8 + u8 enc; /* Encryption flag */ + u8 broadcast_code[16]; /* The code used to derive the session key that is used to encrypt and decrypt BIS payloads */ +} hci_le_createBigParams_t; + + + + +/** + * @brief Command Parameters for "7.8.104 LE Create BIG Test command" + */ +typedef struct +{ + u8 big_handle; /* Used to identify the BIG */ + u8 adv_handle; /* Used to identify the periodic advertising train */ + u8 num_bis; /* Total number of BISes in the BIG */ + u8 sdu_intvl[3]; /* The interval, in microseconds, of periodic SDUs */ + u16 iso_intvl; /* The time between consecutive BIG anchor points, Time = N * 1.25 ms */ + u8 nse; /* The total number of subevents in each interval of each BIS in the BIG */ + u16 max_sdu; /* Maximum size of an SDU, in octets */ + u16 max_pdu; /* Maximum size, in octets, of payload */ + u8 phy; /* The transmitter PHY of packets, BIT(0): LE 1M; BIT(1): LE 2M; BIT(3): LE Coded PHY */ + u8 packing; + u8 framing; + u8 bn; /* The number of new payloads in each interval for each BIS */ + u8 irc; /* The number of times the scheduled payload(s) are transmitted in a given event*/ + u8 pto; /* Offset used for pre-transmissions */ + u8 enc; /* Encryption flag */ + u8 broadcast_code[16]; /* The code used to derive the session key that is used to encrypt and decrypt BIS payloads */ +} hci_le_createBigParamsTest_t; + + + + +/** + * @brief Command Parameters for "7.8.105 LE Terminate BIG command" + */ +typedef struct +{ + u8 big_handle; + u8 reason; +} hci_le_terminateBigParams_t; + + + + +typedef struct +{ + u8 big_handle; /* Used to identify the BIG */ + u16 sync_handle; /* Identifier of the periodic advertising train */ + u8 enc; /* Encryption flag */ + u8 broadcast_code[16]; /* The code used to derive the session key that is used to encrypt and decrypt BIS payloads */ + u8 mse; /* The Controller can schedule reception of any number of subevents up to NSE */ + u16 big_sync_timeout; /* Synchronization timeout for the BIG, Time = N*10 ms, Time Range: 100 ms to 163.84 s */ + u8 num_bis; /* Total number of BISes to synchronize */ + u8 bis[1]; /* List of indices of BISes */ +} hci_le_bigCreateSyncParams_t; + + + + +/** + * @brief Command Parameters for "7.8.109 LE Setup ISO Data Path command" + */ +typedef struct +{ + u16 conn_handle; + u8 data_path_direction; + u8 data_path_id; + u8 codec_id[5]; + + u32 controller_delay :24; + u32 codec_configration_length :8; + + u8 codec_config[1]; + +}hci_le_setupIsoDataPathCmdParams_t; + + +/** + * @brief Command Parameters for "7.8.111 LE ISO Transmit Test command" + */ +typedef struct +{ + u16 handle; + u8 payload_type; +}hci_le_isoTransmitTestCmdParams_t; + +/** + * @brief Command Parameters for "7.8.112 LE ISO Receive Test command" + */ +typedef struct +{ + u16 handle; + u8 payload_type; +}hci_le_isoReceiveTestCmdParams_t; + +#endif /* HCI_CMD_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/hci/hci_const.h b/b91/b91m_ble_sdk/stack/ble/hci/hci_const.h new file mode 100755 index 0000000..0cd30de --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/hci/hci_const.h @@ -0,0 +1,399 @@ +/******************************************************************************************************** + * @file hci_const.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#ifndef HCI_CONST_H_ +#define HCI_CONST_H_ + +/****HCI INFO****/ +#define HCI_VERSION 0x09 //Bluetooth Core Specification 5.0 +#define HCI_REVISION 0x0002 //Revision of the Current HCI in the BR/EDR Controller +#define HCI_LMP_VERSION 0x09 //Version of the Current LMP or PAL in the Controller, Bluetooth Core Specification 5.0 +#define HCI_MANUFACTURER_NAME VENDOR_ID //Manufacturer Name of the BR/EDR Controller +#define HCI_LMP_SUBVERSION 0x0001 //Subversion of the Current LMP or PAL in the Controller + +#define LMP_FEATURES 0x0000000000000000 + + + + +/****Events****/ +#define HCI_EVT_DISCONNECTION_COMPLETE 0x05 + +#define HCI_EVT_REMOTE_NAME_REQ_COMPLETE 0x07 +#define HCI_EVT_ENCRYPTION_CHANGE 0x08 +#define HCI_EVT_CHANGE_LINK_KEY_COMPLETE 0x09 +#define HCI_EVT_READ_REMOTE_VER_INFO_COMPLETE 0x0C +#define HCI_EVT_CMD_COMPLETE 0x0E +#define HCI_EVT_CMD_STATUS 0x0F +#define HCI_EVT_HW_ERROR 0x10 +#define HCI_EVT_NUM_OF_COMPLETE_PACKETS 0x13 +#define HCI_EVT_DATA_BUF_OVERFLOW 0x1A +#define HCI_EVT_ENCRYPTION_KEY_REFRESH 0x30 +#define HCI_EVT_LE_META 0x3E +#define HCI_EVT_HT_ERR_FLAG 0xF0 + +// LE Meta Event Codes +#define HCI_SUB_EVT_LE_CONNECTION_COMPLETE 0x01 //core_4.0 +#define HCI_SUB_EVT_LE_ADVERTISING_REPORT 0x02 //core_4.0 +#define HCI_SUB_EVT_LE_CONNECTION_UPDATE_COMPLETE 0x03 //core_4.0 +#define HCI_SUB_EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE 0x04 //core_4.0 +#define HCI_SUB_EVT_LE_LONG_TERM_KEY_REQUESTED 0x05 //core_4.0 +#define HCI_SUB_EVT_LE_REMOTE_CONNECTION_PARAM_REQUEST 0x06 //core_4.1 +#define HCI_SUB_EVT_LE_DATA_LENGTH_CHANGE 0x07 //core_4.2 +#define HCI_SUB_EVT_LE_READ_LOCAL_P256_KEY_COMPLETE 0x08 //core_4.2 +#define HCI_SUB_EVT_LE_GENERATE_DHKEY_COMPLETE 0x09 //core_4.2 +#define HCI_SUB_EVT_LE_ENHANCED_CONNECTION_COMPLETE 0x0A //core_4.2 +#define HCI_SUB_EVT_LE_DIRECT_ADVERTISE_REPORT 0x0B //core_4.2 + +#define HCI_SUB_EVT_LE_PHY_UPDATE_COMPLETE 0x0C //core_5.0 +#define HCI_SUB_EVT_LE_EXTENDED_ADVERTISING_REPORT 0x0D //core_5.0 - LE Extended Advertising Report Event - [5] 7.7.65.13 +#define HCI_SUB_EVT_LE_PERIODIC_ADVERTISING_SYNC_ESTABLISHED 0x0E //core_5.0 - LE Periodic Advertising Sync Established Event - [5] 7.7.65.14 +#define HCI_SUB_EVT_LE_PERIODIC_ADVERTISING_REPORT 0x0F //core_5.0 - LE Periodic Advertising Report Event- [5] 7.7.65.15 +#define HCI_SUB_EVT_LE_PERIODIC_ADVERTISING_SYNC_LOST 0x10 //core_5.0 - LE Periodic Advertising Sync Lost Event - [5] 7.7.65.16 +#define HCI_SUB_EVT_LE_SCAN_TIMEOUT 0x11 //core_5.0 - LE Scan Timeout Event - [5] 7.7.65.17 +#define HCI_SUB_EVT_LE_ADVERTISING_SET_TERMINATED 0x12 //core_5.0 - LE Advertising Set Terminated Event - [5]7.7.65.18 +#define HCI_SUB_EVT_LE_SCAN_REQUEST_RECEIVED 0x13 //core_5.0 - LE Scan Request Received Event - [5]7.7.65.19 +#define HCI_SUB_EVT_LE_CHANNEL_SELECTION_ALGORITHM 0x14 //core_5.0 - LE Channel Selection Algorithm Event - [5]7.7.65.20 + + +#define HCI_SUB_EVT_LE_CONNECTIONLESS_IQ_REPORT 0x15 //core_5.1 7.7.65.21 LE Connectionless IQ Report event +#define HCI_SUB_EVT_LE_CONNECTION_IQ_REPORT 0x16 //core_5.1 7.7.65.22 LE Connection IQ Report event +#define HCI_SUB_EVT_LE_CTE_REQUEST_FAILED 0x17 //core_5.1 7.7.65.23 LE CTE Request Failed event +#define HCI_SUB_EVT_LE_PERIODIC_ADVERTISING_SYNC_TRANSFOR_RECEIVED 0x18 //core_5.1 7.7.65.24 LE Periodic Advertising Sync Transfer Received event + + +#define HCI_SUB_EVT_LE_CIS_ESTABLISHED 0x19 //core_5.2 7.7.65.25 LE CIS Established event +#define HCI_SUB_EVT_LE_CIS_REQUESTED 0x1A //core_5.2 7.7.65.26 LE CIS Request event +#define HCI_SUB_EVT_LE_CREATE_BIG_COMPLETE 0x1B //core_5.2 7.7.65.27 LE Create BIG Complete event +#define HCI_SUB_EVT_LE_TERMINATE_BIG_COMPLETE 0x1C //core_5.2 7.7.65.28 LE Terminate BIG Complete event +#define HCI_SUB_EVT_LE_BIG_SYNC_ESTABLILSHED 0x1D //core_5.2 7.7.65.29 LE BIG Sync Established event +#define HCI_SUB_EVT_LE_BIG_SYNC_LOST 0x1E //core_5.2 7.7.65.30 LE BIG Sync Lost event +#define HCI_SUB_EVT_LE_REQUEST_PEER_SCA_COMPLETE 0x1F //core_5.2 7.7.65.31 LE Request Peer SCA Complete event +#define HCI_SUB_EVT_LE_PATH_LOSS_THRESHOLD 0x20 //core_5.2 7.7.65.32 LE Path Loss Threshold event +#define HCI_SUB_EVT_LE_TRANSMIT_POWER_REPORTING 0x21 //core_5.2 7.7.65.33 LE Transmit Power Reporting event +#define HCI_SUB_EVT_LE_BIGINFO_ADVERTISING_REPORT 0x22 //core_5.2 7.7.65.34 LE BIGInfo Advertising Report event +#define HCI_SUB_EVT_MAX 0x23 + + +#define HCI_SUB_EVT_LE_CONNECTION_ESTABLISH 0xFF //Telink private + + + + +//Event mask - last octet +#define HCI_EVT_MASK_NONE 0x0000000000 +#define HCI_EVT_MASK_INQUIRY_COMPLETE 0x0000000001 +#define HCI_EVT_MASK_INQUIRY_RESULT 0x0000000002 +#define HCI_EVT_MASK_CONNECTION_COMPELETE 0x0000000004 +#define HCI_EVT_MASK_CONNECTION_REQUEST 0x0000000008 +#define HCI_EVT_MASK_DISCONNECTION_COMPLETE 0x0000000010 // +#define HCI_EVT_MASK_AUTHENTICATION_COMPLETE 0x0000000020 +#define HCI_EVT_MASK_REMOTE_NAME_REQUEST_COMPLETE 0x0000000040 +#define HCI_EVT_MASK_ENCRYPTION_CHANGE 0x0000000080 +#define HCI_EVT_MASK_CHANGE_CONECTION_LINK_KEY_COMPLETE 0x0000000100 +#define HCI_EVT_MASK_MASTER_LINK_KEY_COMPLETE 0x0000000200 +#define HCI_EVT_MASK_READ_REMOTE_SUPPORTED_FEATURES_COMPLETE 0x0000000400 +#define HCI_EVT_MASK_READ_REMOTE_VERSION_INFORMATION_COMPLETE 0x0000000800 // + +#define HCI_EVT_MASK_DEFAULT HCI_EVT_MASK_DISCONNECTION_COMPLETE + + +// LE Event mask - last octet +#define HCI_LE_EVT_MASK_NONE 0x00000000 +#define HCI_LE_EVT_MASK_CONNECTION_COMPLETE 0x00000001 +#define HCI_LE_EVT_MASK_ADVERTISING_REPORT 0x00000002 +#define HCI_LE_EVT_MASK_CONNECTION_UPDATE_COMPLETE 0x00000004 +#define HCI_LE_EVT_MASK_READ_REMOTE_FEATURES_COMPLETE 0x00000008 +#define HCI_LE_EVT_MASK_LONG_TERM_KEY_REQUEST 0x00000010 +#define HCI_LE_EVT_MASK_REMOTE_CONNECTION_PARAM_REQUEST 0x00000020 +#define HCI_LE_EVT_MASK_DATA_LENGTH_CHANGE 0x00000040 +#define HCI_LE_EVT_MASK_READ_LOCAL_P256_PUBLIC_KEY_COMPLETE 0x00000080 +#define HCI_LE_EVT_MASK_GENERATE_DHKEY_COMPLETE 0x00000100 +#define HCI_LE_EVT_MASK_ENHANCED_CONNECTION_COMPLETE 0x00000200 +#define HCI_LE_EVT_MASK_DIRECT_ADVERTISING_REPORT 0x00000400 +#define HCI_LE_EVT_MASK_PHY_UPDATE_COMPLETE 0x00000800 // core5.0 +#define HCI_LE_EVT_MASK_EXTENDED_ADVERTISING_REPORT 0x00001000 // core5.0 +#define HCI_LE_EVT_MASK_PERIODIC_ADVERTISING_SYNC_ESTABLISHED 0x00002000 // core5.0 +#define HCI_LE_EVT_MASK_PERIODIC_ADVERTISING_REPORT 0x00004000 // core5.0 +#define HCI_LE_EVT_MASK_PERIODIC_ADVERTISING_SYNC_LOST 0x00008000 // core5.0 +#define HCI_LE_EVT_MASK_EXTENDED_SCAN_TIMEOUT 0x00010000 // core5.0 +#define HCI_LE_EVT_MASK_EXTENDED_ADVERTISING_SET_TERMINATED 0x00020000 // core5.0 +#define HCI_LE_EVT_MASK_SCAN_REQUEST_RECEIVED 0x00040000 // core5.0 +#define HCI_LE_EVT_MASK_CHANNEL_SELECTION_ALGORITHM 0x00080000 // core5.0 - bit19 + +#define HCI_LE_EVT_MASK_CONNECTIONLESS_IQ_REPORT 0x00100000 // core5.1 - bit20 +#define HCI_LE_EVT_MASK_CONNECTION_IQ_REPORTD 0x00200000 // core5.1 - bit21 +#define HCI_LE_EVT_MASK_CTE_REQUEST_FAILED 0x00400000 // core5.1 - bit22 +#define HCI_LE_EVT_MASK_PERIODIC_ADVERTISING_SYNC_TRANSFOR_RECEIVED 0x00800000 // core5.1 - bit23 + +#define HCI_LE_EVT_MASK_CIS_ESTABLISHED 0x01000000 // core5.2 - bit24 +#define HCI_LE_EVT_MASK_CIS_REQUESTED 0x02000000 // core5.2 - bit25 +#define HCI_LE_EVT_MASK_CREATE_BIG_COMPLETE 0x04000000 // core5.2 - bit26 +#define HCI_LE_EVT_MASK_TERMINATE_BIG_COMPLETE 0x08000000 // core5.2 - bit27 +#define HCI_LE_EVT_MASK_BIG_SYNC_ESTABLILSHED 0x10000000 // core5.2 - bit28 +#define HCI_LE_EVT_MASK_BIG_SYNC_LOST 0x20000000 // core5.2 - bit29 +#define HCI_LE_EVT_MASK_REQUEST_PEER_SCA_COMPLETE 0x40000000 // core5.2 - bit30 +#define HCI_LE_EVT_MASK_PATH_LOSS_THRESHOLD 0x80000000 // core5.2 - bit31 + +#define HCI_LE_EVT_MASK_2_TRANSMIT_POWER_REPORTING 0x00000001 // core5.2 - bit32 +#define HCI_LE_EVT_MASK_2_BIGINFO_ADVERTISING_REPORT 0x00000002 // core5.2 - bit33 + + + +#define HCI_LE_EVT_MASK_CONNECTION_ESTABLISH 0x80000000 //TODO + + + + + +#define HCI_LE_EVT_MASK_DEFAULT HCI_LE_EVT_MASK_NONE + + + + + +//Link Control Command +//-- OGF -- +#define HCI_CMD_LINK_CTRL_OPCODE_OGF 0x04 //0x01 <<2 = 0x04 +//-- OCF -- +#define HCI_CMD_INQUIRY 0x01 +#define HCI_CMD_DISCONNECT 0x06 +#define HCI_CMD_READ_REMOTE_NAME_REQ 0x19 +#define HCI_CMD_READ_REMOTE_VER_INFO 0x1D + + + +//Controller & Baseband Commands +//-- OGF -- +#define HCI_CMD_CBC_OPCODE_OGF 0x0C //0x03 <<2, controller & baseband control +//-- OCF -- +#define HCI_CMD_SET_EVENT_MASK 0x01 +#define HCI_CMD_RESET 0x03 +#define HCI_CMD_SET_EVENT_FILTER 0x05 +#define HCI_CMD_WRITE_PIN_TYPE 0x0A +#define HCI_CMD_CREATE_NEW_UINT_KEY 0x0B +#define HCI_CMD_DELETE_STORED_LINK_KEY 0x12 +#define HCI_CMD_WRITE_LOCAL_NAME 0x13 +#define HCI_CMD_READ_LOCAL_NAME 0x14 +#define HCI_CMD_WRITE_CONNECTION_ACCEPT_TIMEOUT 0x16 +#define HCI_CMD_WRITE_PAGE_TIMEOUT 0x18 +#define HCI_CMD_WRITE_SCAN_ENABLE 0x1A +#define HCI_CMD_WRITE_PAGE_SCAN_ACTIVITY 0x1C +#define HCI_CMD_WRITE_INQUIRY_SCAN_ACTIVITY 0x1E +#define HCI_CMD_WRITE_AUTHENTICATION_ENABLE 0x20 +#define HCI_CMD_WRITE_CLASS_OF_DEVICE 0x24 +#define HCI_CMD_WRITE_VOICE_SETTING 0x26 +#define HCI_CMD_WRITE_NUM_BROADCAST_RETRANSMISSIONS 0x2A +#define HCI_CMD_WRITE_HOLD_MODE_ACTIVITY 0x2C +#define HCI_CMD_READ_TX_POWER_LEVEL 0x2D +#define HCI_CMD_SYNCHRONOUS_FLOW_CONTROL_ENABLE 0x2F +#define HCI_CMD_SET_CONTROLLER_TO_HOST_FLOW_CTRL 0x31 +#define HCI_CMD_HOST_BUF_SIZE 0x33 +#define HCI_CMD_HOST_NUM_OF_COMPLETE_PACKETS 0x35 +#define HCI_CMD_WRITE_CURRENT_IAC_LAP 0x3A +#define HCI_CMD_SET_AFH_HOST_CHN_CLASSIFICATION 0x3F +#define HCI_CMD_WRITE_INQUIRY_SCAN_TYPE 0x43 +#define HCI_CMD_WRITE_INQUIRY_MODE 0x45 +#define HCI_CMD_WRITE_PAGE_SCAN_TYPE 0x47 +#define HCI_CMD_SET_EVT_MASK_PAGE_2 0x63 + +//Informational Parameters +//-- OGF -- +#define HCI_CMD_IP_OPCODE_OGF 0x10 //0x04 <<2, information parameter +//-- OCF -- +#define HCI_CMD_READ_LOCAL_VER_INFO 0x01 +#define HCI_CMD_READ_LOCAL_SUPPORTED_CMDS 0x02 +#define HCI_CMD_READ_LOCAL_SUPPORTED_FEATURES 0x03 +#define HCI_CMD_READ_EXTENDED_LOCAL_SUPPORTED_FEATURES 0x04 +#define HCI_CMD_READ_BUFFER_SIZE_COMMAND 0x05 +#define HCI_CMD_READ_BD_ADDR 0x09 + + + +// Status Parameters +//-- OGF -- +#define HCI_CMD_STATUS_PARAM_OPCODE_OGF 0x14 //0x05 <<2 +//-- OCF -- +#define HCI_CMD_READ_RSSI 0x05 + + + +#define HCI_EVT_CMDSTATUS(n,c,g,s) ((s) | (n<<8) | (c<<16) | (g<<24)) +#define HCI_EVT_CMD_COMPLETE_STATUS(n,c,g,s) ((n<<0) | (c<<8) | (g<<16) | (s<<24)) + + + + +// LE Controller Commands +//-- OGF -- +#define HCI_CMD_LE_OPCODE_OGF 0x20 //0x08 <<2 = 0x20 +//-- OCF -- +#define HCI_CMD_LE_SET_EVENT_MASK 0x01 +#define HCI_CMD_LE_READ_BUF_SIZE 0x02 +#define HCI_CMD_LE_READ_LOCAL_SUPPORTED_FEATURES 0x03 +#define HCI_CMD_LE_SET_RANDOM_ADDR 0x05 +#define HCI_CMD_LE_SET_ADVERTISE_PARAMETERS 0x06 +#define HCI_CMD_LE_READ_ADVERTISING_CHANNEL_TX_POWER 0x07 +#define HCI_CMD_LE_SET_ADVERTISE_DATA 0x08 +#define HCI_CMD_LE_SET_SCAN_RSP_DATA 0x09 +#define HCI_CMD_LE_SET_ADVERTISE_ENABLE 0x0A +#define HCI_CMD_LE_SET_SCAN_PARAMETERS 0x0B +#define HCI_CMD_LE_SET_SCAN_ENABLE 0x0C +#define HCI_CMD_LE_CREATE_CONNECTION 0x0D +#define HCI_CMD_LE_CREATE_CONNECTION_CANCEL 0x0E +#define HCI_CMD_LE_READ_WHITE_LIST_SIZE 0x0F +#define HCI_CMD_LE_CLEAR_WHITE_LIST 0x10 +#define HCI_CMD_LE_ADD_DEVICE_TO_WHITE_LIST 0x11 +#define HCI_CMD_LE_REMOVE_DEVICE_FROM_WL 0x12 +#define HCI_CMD_LE_CONNECTION_UPDATE 0x13 +#define HCI_CMD_LE_SET_HOST_CHANNEL_CLASSIFICATION 0x14 +#define HCI_CMD_LE_READ_CHANNEL_MAP 0x15 +#define HCI_CMD_LE_READ_REMOTE_USED_FEATURES 0x16 +#define HCI_CMD_LE_ENCRYPT 0x17 +#define HCI_CMD_LE_RANDOM 0x18 +#define HCI_CMD_LE_START_ENCRYPTION 0x19 +#define HCI_CMD_LE_LONG_TERM_KEY_REQUESTED_REPLY 0x1A +#define HCI_CMD_LE_LONG_TERM_KEY_REQUESTED_NEGATIVE_REPLY 0x1B +#define HCI_CMD_LE_READ_SUPPORTED_STATES 0x1C +#define HCI_CMD_LE_RECEIVER_TEST 0x1D +#define HCI_CMD_LE_TRANSMITTER_TEST 0x1E +#define HCI_CMD_LE_TEST_END 0x1F +//core_4.0 end +//core_4.1 begin +#define HCI_CMD_LE_REMOTE_CONNECTION_PARAM_REQ_REPLY 0x20 +#define HCI_CMD_LE_REMOTE_CONNECTION_PARAM_REQ_NEGATIVE_REPLY 0x21 +//core_4.1 end +//core_4.2 begin +#define HCI_CMD_LE_SET_DATA_LENGTH 0x22 +#define HCI_CMD_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH 0x23 +#define HCI_CMD_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH 0x24 +#define HCI_CMD_LE_READ_LOCAL_P256_PUBLIC_KEY 0x25 +#define HCI_CMD_LE_GENERATE_DHKEY 0x26 +#define HCI_CMD_LE_ADD_DEVICE_TO_RESOLVING_LIST 0x27 +#define HCI_CMD_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST 0x28 +#define HCI_CMD_LE_CLEAR_RESOLVING_LIST 0x29 +#define HCI_CMD_LE_READ_RESOLVING_LIST_SIZE 0x2A +#define HCI_CMD_LE_READ_PEER_RESOLVABLE_ADDRESS 0x2B +#define HCI_CMD_LE_READ_LOCAL_RESOLVABLE_ADDRESS 0x2C +#define HCI_CMD_LE_SET_ADDRESS_RESOLUTION_ENABLE 0x2D +#define HCI_CMD_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT 0x2E +#define HCI_CMD_LE_READ_MAX_DATA_LENGTH 0x2F +//core_4.2 end +//core_5.0 begin +#define HCI_CMD_LE_READ_PHY 0x30//LE Read PHY Command - [5] 7.8.47 +#define HCI_CMD_LE_SET_DEFAULT_PHY 0x31//LE Set Default PHY Command - [5] 7.8.48 +#define HCI_CMD_LE_SET_PHY 0x32//LE Set PHY Command - [5] 7.8.49 +#define HCI_CMD_LE_ENHANCED_RECEIVER_TEST 0x33//LE Enhanced Receiver Test Command - [5] 7.8.50 +#define HCI_CMD_LE_ENHANCED_TRANSMITTER_TEST 0x34//LE Enhanced Transmitter Test Command - [5] 7.8.51 +#define HCI_CMD_LE_SET_ADVERTISING_SET_RANDOM_ADDRESS 0x35//LE Set Advertising Set Random Address Command - [5] 7.8.52 +#define HCI_CMD_LE_SET_EXTENDED_ADVERTISING_PARAMETERS 0x36//LE Set Extended Advertising Parameters Command - [5] 7.8.53 +#define HCI_CMD_LE_SET_EXTENDED_ADVERTISING_DATA 0x37//LE Set Extended Advertising Data Command - [5] 7.8.54 +#define HCI_CMD_LE_SET_EXTENDED_SCAN_RESPONSE_DATA 0x38//LE Set Extended Scan Response Data Command - [5] 7.8.55 +#define HCI_CMD_LE_SET_EXTENDED_ADVERTISING_ENABLE 0x39//LE Set Extended Advertising Enable Command - [5] 7.8.56 +#define HCI_CMD_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH 0x3A//LE Read Maximum Advertising Data Length Command - [5] 7.8.57 +#define HCI_CMD_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS 0x3B//LE Read Number of Supported Advertising Sets Command - [5] 7.8.58 +#define HCI_CMD_LE_REMOVE_ADVERTISING_SET 0x3C//LE Remove Advertising Set Command - [5] 7.8.59 +#define HCI_CMD_LE_CLEAR_ADVERTISING_SETS 0x3D//LE Clear Advertising Sets Command - [5] 7.8.60 +#define HCI_CMD_LE_SET_PERIODIC_ADVERTISING_PARAMETERS 0x3E//LE Set Periodic Advertising Parameters Command - [5] 7.8.61 +#define HCI_CMD_LE_SET_PERIODIC_ADVERTISING_DATA 0x3F//LE Set Periodic Advertising Data Command - [5] 7.8.62 +#define HCI_CMD_LE_SET_PERIODIC_ADVERTISING_ENABLE 0x40//LE Set Periodic Advertising Enable Command - [5] 7.8.63 +#define HCI_CMD_LE_SET_EXTENDED_SCAN_PARAMETERS 0x41//LE Set Extended Scan Parameters Command - [5] 7.8.64 +#define HCI_CMD_LE_SET_EXTENDED_SCAN_ENABLE 0x42//LE Set Extended Scan Enable Command - [5] 7.8.65 +#define HCI_CMD_LE_EXTENDED_CREATE_CONNECTION 0x43//LE Extended Create Connection Command - [5] 7.8.66 +#define HCI_CMD_LE_PERIODIC_ADVERTISING_CREATE_SYNC 0x44//LE Periodic Advertising Create Sync Command- [5] 7.8.67 +#define HCI_CMD_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL 0x45//LE Periodic Advertising Create Sync Cancel Command - [5] 7.8.68 +#define HCI_CMD_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC 0x46//LE Periodic Advertising Terminate Sync Command - [5] 7.8.69 +#define HCI_CMD_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST 0x47//LE Add Device To Periodic Advertiser List Command - [5] 7.8.70 +#define HCI_CMD_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST 0x48//LE Remove Device From Periodic Advertiser List Command - [5] 7.8.71 +#define HCI_CMD_LE_CLEAR_PERIODIC_ADVERTISER_LIST 0x49//LE Clear Periodic Advertiser List Command - [5] 7.8.72 +#define HCI_CMD_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE 0x4A//LE Read Periodic Advertiser List Size Command - [5] 7.8.73 +#define HCI_CMD_LE_READ_TRANSMIT_POWER 0x4B//LE Read Transmit Power Command - [5] 7.8.74 +#define HCI_CMD_LE_READ_RF_PATH_COMPENSATION 0x4C//LE Read RF Path Compensation Command - [5] 7.8.75 +#define HCI_CMD_LE_WRITE_RF_PATH_COMPENSATION 0x4D//LE Write RF Path Compensation Command - [5] 7.8.76 +#define HCI_CMD_LE_SET_PRIVACY_MODE 0x4E//LE Set Privacy Mode Command - [5] 7.8.77 +//core_5.0 end + +//core_5.1 begin +#define HCI_CMD_LE_RECEIVER_TEST_V3 0x4F //7.8.78 LE Receiver Test command [v3] +#define HCI_CMD_LE_TRANSMITTER_TEST_V3 0x50 //7.8.79 LE Transmitter Test command [v3] +#define HCI_CMD_LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS 0x51 //7.8.80 LE Set Connectionless CTE Transmit Parameters command +#define HCI_CMD_LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE 0x52 //7.8.81 LE Set Connectionless CTE Transmit Enable command +#define HCI_CMD_LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE 0x53 //7.8.82 LE Set Connectionless IQ Sampling Enable command +#define HCI_CMD_LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS 0x54 //7.8.83 LE Set Connection CTE Receive Parameters command +#define HCI_CMD_LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS 0x55 //7.8.84 LE Set Connection CTE Transmit Parameters command +#define HCI_CMD_LE_CONNECTION_REQUEST_ENABLE 0x56 //7.8.85 LE Connection CTE Request Enable command +#define HCI_CMD_LE_CONNECTION_RESPONSE_ENABLE 0x57 //7.8.86 LE Connection CTE Response Enable command +#define HCI_CMD_LE_READ_ANTENNA_INFORMATION 0x58 //7.8.87 LE Read Antenna Information command +#define HCI_CMD_LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE 0x59 //7.8.88 LE Set Periodic Advertising Receive Enable command +#define HCI_CMD_LE_PERIODIC_ADVERTISING_SYNC_TRANSFOR 0x5A //7.8.89 LE Periodic Advertising Sync Transfer command +#define HCI_CMD_LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFOR 0x5B //7.8.90 LE Periodic Advertising Set Info Transfer command +#define HCI_CMD_LE_SET_PERIODIC_ADV_SYNC_TRANSFOR_PARAMETERS 0x5C //7.8.91 LE Set Periodic Advertising Sync Transfer Parameters command +#define HCI_CMD_LE_SET_DEFAULT_PERIODIC_ADV_SYNC_TRANSFOR_PARAMS 0x5D //7.8.92 LE Set Default Periodic Advertising Sync Transfer Parameters command +#define HCI_CMD_LE_GENERATE_DHKEY_V2 0x5E //7.8.93 LE Generate DHKey command [v2] +#define HCI_CMD_LE_MODIFY_SLEEP_CLOCK_ACCURACY 0x5F //7.8.94 LE Modify Sleep Clock Accuracy command +//core_5.1 end + +//core_5.2 begin +#define HCI_CMD_LE_READ_BUFFER_SIZE_V2 0x60 //7.8.2 LE Read Buffer Size command +#define HCI_CMD_LE_READ_ISO_TX_SYNC 0x61 //7.8.96 LE Read ISO TX Sync command +#define HCI_CMD_LE_SET_CIG_PARAMETERS 0x62 //7.8.97 LE Set CIG Parameters command +#define HCI_CMD_LE_SET_CIG_PARAMETERS_TEST 0x63 //7.8.98 LE Set CIG Parameters Test command +#define HCI_CMD_LE_CREATE_CIS 0x64 //7.8.99 LE Create CIS command +#define HCI_CMD_LE_REMOVE_CIG 0x65 //7.8.100 LE Remove CIG command +#define HCI_CMD_LE_ACCEPT_CIS_REQUEST 0x66 //7.8.101 LE Accept CIS Request command +#define HCI_CMD_LE_REJECT_CIS_REQUEST 0x67 //7.8.102 LE Reject CIS Request command +#define HCI_CMD_LE_CREATE_BIG 0x68 //7.8.103 LE Create BIG command +#define HCI_CMD_LE_CREATE_BIG_TEST 0x69 //7.8.104 LE Create BIG Test command +#define HCI_CMD_LE_TERMINATE_BIG 0x6A //7.8.105 LE Terminate BIG command +#define HCI_CMD_LE_BIG_CREATE_SYNC 0x6B //7.8.106 LE BIG Create Sync command +#define HCI_CMD_LE_BIG_TERMINATE_SYNC 0x6C //7.8.107 LE BIG Terminate Sync command +#define HCI_CMD_LE_REQUEST_PEER_SCA 0x6D //7.8.108 LE Request Peer SCA command +#define HCI_CMD_LE_SETUP_ISO_DATA_PATH 0x6E //7.8.109 LE Setup ISO Data Path command +#define HCI_CMD_LE_REMOVE_ISO_DARA_PATH 0x6F //7.8.110 LE Remove ISO Data Path command +#define HCI_CMD_LE_ISO_TRTANSMIT_TEST 0x70 //7.8.111 LE ISO Transmit Test command +#define HCI_CMD_LE_ISO_RECEIVE_TEST 0x71 //7.8.112 LE ISO Receive Test command +#define HCI_CMD_LE_ISO_READ_TEST_COUNTERS 0x72 //7.8.113 LE ISO Read Test Counters command +#define HCI_CMD_LE_ISO_TEST_END 0x73 //7.8.114 LE ISO Test End command +#define HCI_CMD_LE_SET_HOST_FEATURE 0x74 //7.8.115 LE Set Host Feature Command +#define HCI_CMD_LE_READ_ISO_LINK_QUALITY 0x75 //7.8.116 LE Read ISO Link Quality command +#define HCI_CMD_LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL 0x76 //7.8.117 LE Enhanced Read Transmit Power Level command +#define HCI_CMD_LE_READ_REMOTE_TRANSMIT_POWER_LEVEL 0x77 //7.8.118 LE Read Remote Transmit Power Level command +#define HCI_CMD_LE_SET_PATH_LOSS_REPORTING_PARAMETERS 0x78 //7.8.119 LE Set Path Loss Reporting Parameters command +#define HCI_CMD_LE_SET_PATH_LOSS_REPORTING_ENABLE 0x79 //7.8.120 LE Set Path Loss Reporting Enable command +#define HCI_CMD_LE_SET_TRANSMIT_POWER_REPORTING_ENABLE 0x7A //7.8.121 LE Set Transmit Power Reporting Enable command +//core_5.2 end + + +#define HCI_CMD_LINK_POLICY_OPCODE_OGF 0x08 //0x02<<2 = 0x08 +#define HCI_CMD_TEST_OPCODE_OGF 0x18 //0x06<<2 = 0x18 + +// Vendor specific Commands +//-- OGF -- +#define HCI_CMD_VENDOR_OPCODE_OGF 0xFC //0x3f <<2 = 0xFC +//-- OCF -- +#define HCI_TELINK_READ_REG 0x01 +#define HCI_TELINK_WRITE_REG 0x02 +#define HCI_TELINK_SET_TX_PWR 0x03 +#define HCI_TELINK_REBOOT_MCU 0x04 +#define HCI_TELINK_SET_RXTX_DATA_LEN 0x40 +#endif /* HCI_CONST_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/hci/hci_event.h b/b91/b91m_ble_sdk/stack/ble/hci/hci_event.h new file mode 100755 index 0000000..718d064 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/hci/hci_event.h @@ -0,0 +1,651 @@ +/******************************************************************************************************** + * @file hci_event.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef HCI_EVENT_H_ +#define HCI_EVENT_H_ + + +#include "stack/ble/ble_common.h" + + +/** + * @brief Definition for general HCI event packet + */ +typedef struct { + u8 type; + u8 eventCode; + u8 paraLen; + u8 parameters[1]; +} hci_event_t; + + +typedef struct { + u8 numHciCmds; + u8 opCode_OCF; + u8 opCode_OGF; + u8 returnParas[1]; +} hci_cmdCompleteEvt_evtParam_t; + + +typedef struct { + u8 status; + u8 numHciCmds; + u8 opCode_OCF; + u8 opCode_OGF; +} hci_cmdStatusEvt_evtParam_t; + +typedef struct{ + u16 connHandle; + u16 numOfCmpPkts; +}numCmpPktParamRet_t; + +typedef struct { + u8 numHandles; + numCmpPktParamRet_t retParams[1];//TODO +} hci_numOfCmpPktEvt_t; + +typedef struct{ + u8 status; + u16 connHandle; + u8 verNr; + u16 compId; + u16 subVerNr; +}hci_readRemVerInfoCmplEvt_t; + +typedef struct { + u8 type; + u8 eventCode; + u8 paraLen; + u8 subEventCode; + u8 parameters[1]; +} hci_le_metaEvt_t; + + + +/** + * @brief Event Parameters for "7.7.5 Disconnection Complete event" + */ +typedef struct { + u8 status; + u16 connHandle; + u8 reason; +} event_disconnection_t; + +typedef struct { + u8 status; + u16 connHandle; + u8 reason; +} hci_disconnectionCompleteEvt_t; + + + +/** + * @brief Event Parameters for "7.7.8 Encryption Change event" + */ +typedef struct { + u8 status; + u16 handle; + u8 enc_enable; +} event_enc_change_t; + +typedef struct { + u8 status; + u16 connHandle; + u8 encryption_enable; +} hci_le_encryptEnableEvt_t; + +/** + * @brief Event Parameters for "7.7.39 Encryption Key Refresh Complete event" + */ +typedef struct { + u8 status; + u16 handle; +} event_enc_refresh_t; + +typedef struct { + u8 status; + u16 connHandle; +} hci_le_encryptKeyRefreshEvt_t; + + + +/** + * @brief Event Parameters for "7.7.65.1 LE Connection Complete event" + */ +typedef struct { + u8 subEventCode; + u8 status; + u16 connHandle; + u8 role; + u8 peerAddrType; + u8 peerAddr[6]; + u16 connInterval; + u16 slaveLatency; + u16 supervisionTimeout; + u8 masterClkAccuracy; +} hci_le_connectionCompleteEvt_t; + + +/* ACL Connection Role */ +typedef enum { + LL_ROLE_MASTER = 0, + LL_ROLE_SLAVE = 1, +} acl_conection_role_t; + +/** + * @brief Event Parameters for "7.7.65.2 LE Advertising Report event" + */ +typedef struct { + u8 subcode; + u8 nreport; + u8 event_type; + u8 adr_type; + u8 mac[6]; + u8 len; + u8 data[1]; +} event_adv_report_t; + +/* Advertise report event type */ +typedef enum { + ADV_REPORT_EVENT_TYPE_ADV_IND = 0x00, + ADV_REPORT_EVENT_TYPE_DIRECT_IND = 0x01, + ADV_REPORT_EVENT_TYPE_SCAN_IND = 0x02, + ADV_REPORT_EVENT_TYPE_NONCONN_IND = 0x03, + ADV_REPORT_EVENT_TYPE_SCAN_RSP = 0x04, +} advReportEventType_t; + + + +/** + * @brief Event Parameters for "7.7.65.3 LE Connection Update Complete event" + */ +typedef struct { + u8 subEventCode; + u8 status; + u16 connHandle; + u16 connInterval; + u16 connLatency; + u16 supervisionTimeout; +} hci_le_connectionUpdateCompleteEvt_t; + + + +/** + * @brief Event Parameters for "7.7.65.4 LE Read Remote Features Complete event" + */ +#define LL_FEATURE_SIZE 8 +typedef struct { + u8 subEventCode; + u8 status; + u16 connHandle; + u8 feature[LL_FEATURE_SIZE]; +} hci_le_readRemoteFeaturesCompleteEvt_t; + + + +/** + * @brief Event Parameters for "7.7.65.5 LE Long Term Key Request event" + */ +typedef struct { + u8 subEventCode; + u16 connHandle; + u8 random[8]; + u16 ediv; +} hci_le_longTermKeyRequestEvt_t; + + + +/** + * @brief Event Parameters for "7.7.65.6 LE Remote Connection Parameter Request event" + */ +typedef struct { + u8 subEventCode; + u16 connHandle; + u16 IntervalMin; + u16 IntervalMax; + u16 latency; + u16 timeout; +} hci_le_remoteConnParamReqEvt_t; + + + +/** + * @brief Event Parameters for "7.7.65.7 LE Data Length Change event" + */ +typedef struct { + u8 subEventCode; + u16 connHandle; //no aligned, can not be used as pointer + u16 maxTxOct; + u16 maxTxtime; + u16 maxRxOct; + u16 maxRxtime; +} hci_le_dataLengthChangeEvt_t; + + + +/** + * @brief Event Parameters for "7.7.65.8 LE Read Local P-256 Public Key Complete event" + */ +typedef struct { + u8 subEventCode; + u8 status; + u8 localP256Key[64]; +} hci_le_readLocalP256KeyCompleteEvt_t; + + + +/** + * @brief Event Parameters for "7.7.65.9 LE Generate DHKey Complete event" + */ +typedef struct { + u8 subEventCode; + u8 status; + u8 DHKey[32]; +} hci_le_generateDHKeyCompleteEvt_t; + + + +/** + * @brief Event Parameters for "7.7.65.10 LE Enhanced Connection Complete event" + */ +typedef struct { + u8 subEventCode; + u8 status; + u16 connHandle; + u8 role; + u8 PeerAddrType; + u8 PeerAddr[6]; + u8 localRslvPrivAddr[6]; + u8 Peer_RslvPrivAddr[6]; + u16 connInterval; + u16 connLatency; + u16 superTimeout; + u8 masterClkAccuracy; +} hci_le_enhancedConnCompleteEvt_t; + + + +/** + * @brief Event Parameters for "7.7.65.12 LE PHY Update Complete event" + */ +typedef struct { + u8 subEventCode; + u8 status; + u16 connHandle; + u8 tx_phy; + u8 rx_phy; +} hci_le_phyUpdateCompleteEvt_t; + + + +/** + * @brief Event Parameters for "7.7.65.13 LE Extended Advertising Report event" + */ +typedef struct{ + u16 event_type; // 2 + u8 address_type; // 1 + u8 address[6]; // 6 + u8 primary_phy; // 1 + u8 secondary_phy; // 1 + u8 advertising_sid; // 1 + u8 tx_power; // 1 + u8 rssi; // 1 + u16 perd_adv_inter; // 2 Periodic_Advertising_Interval + u8 direct_address_type;// 1 + u8 direct_address[6]; // 6 + u8 data_length; // 1 + u8 data[1]; +} extAdvEvt_info_t; + +typedef struct{ + u8 sub_code; + u16 sync_handle; + u8 tx_power; + + u8 rssi; + u8 unused; + u8 data_status; + u8 data_len; + + u8 data[1]; +}le_periodAdvReportEvt_t; + +#define EXTADV_INFO_LENGTH 24 //byte number from "event_type" to "data_length" +#define EXTADV_RPT_DATA_LEN_MAX 229 //253 - 24 = 229 + +typedef struct{ + u8 subEventCode; + u8 num_reports; + u8 advEvtInfo[1]; +} hci_le_extAdvReportEvt_t; + + +/* Extended Advertising Report Event Event_Type mask*/ +typedef enum{ + EXTADV_RPT_EVT_MASK_CONNECTABLE = BIT(0), + EXTADV_RPT_EVT_MASK_SCANNABLE = BIT(1), + EXTADV_RPT_EVT_MASK_DIRECTED = BIT(2), + EXTADV_RPT_EVT_MASK_SCAN_RESPONSE = BIT(3), + EXTADV_RPT_EVT_MASK_LEGACY = BIT(4), + + EXTADV_RPT_DATA_COMPLETE = 0x00, + EXTADV_RPT_DATA_INCOMPLETE_MORE_TO_COME = 0x20, + EXTADV_RPT_DATA_INCOMPLETE_TRUNCATED = 0x40, + EXTADV_RPT_DATA_RFU = 0x60, + + EXTADV_RPT_EVTTYPE_MASK = 0x1F, + EXTADV_RPT_DATA_STATUS_MASK = 0x60, +}extAdvRptEvtMask_t; + + +/* Extended Advertising Report Event_Type */ +typedef enum{ + //Legacy + EXTADV_RPT_EVTTYPE_LEGACY_ADV_IND = 0x0013, // 0001 0011'b + EXTADV_RPT_EVTTYPE_LEGACY_ADV_DIRECT_IND = 0x0015, // 0001 0101'b + EXTADV_RPT_EVTTYPE_LEGACY_ADV_SCAN_IND = 0x0012, // 0001 0010'b + EXTADV_RPT_EVTTYPE_LEGACY_ADV_NONCONN_IND = 0x0010, // 0001 0000'b + EXTADV_RPT_EVTTYPE_LEGACY_SCAN_RSP_2_ADV_IND = 0x001B, // 0001 1011'b + EXTADV_RPT_EVTTYPE_LEGACY_SCAN_RSP_2_ADV_SCAN_IND = 0x001A, // 0001 1010'b + + //Extended + EXTADV_RPT_EVTTYPE_EXT_NON_CONN_NON_SCAN_UNDIRECTED = 0x0000, // Extended, Non_Connectable Non_Scannable Undirected + EXTADV_RPT_EVTTYPE_EXT_CONNECTABLE_UNDIRECTED = 0x0001, // Extended, Connectable Undirected + EXTADV_RPT_EVTTYPE_EXT_SCANNABLE_UNDIRECTED = 0x0002, // Extended, Scannable Undirected + EXTADV_RPT_EVTTYPE_EXT_NON_CONN_NON_SCAN_DIRECTED = 0x0004, // Extended, Non_Connectable Non_Scannable Directed + EXTADV_RPT_EVTTYPE_EXT_CONNECTABLE_DIRECTED = 0x0005, // Extended, Connectable Directed + EXTADV_RPT_EVTTYPE_EXT_SCANNABLE_DIRECTED = 0x0006, // Extended, Scannable Directed + EXTADV_RPT_EVTTYPE_EXT_SCAN_RESPONSE = 0x0008, // Extended, AUX_SCAN_RESPONSE +}extAdvRptEvtType_t; //extended advertising report event type + + + + +/* Address type */ +typedef enum{ + EXTADV_RPT_PUBLIC_DEVICE_ADDRESS = 0x00, + EXTADV_RPT_RANDOM_DEVICE_ADDRESS = 0x01, + EXTADV_RPT_PUBLIC_IDENTITY_ADDRESS = 0x02, + EXTADV_RPT_RANDOM_IDENTITY_ADDRESS = 0x03, + EXTADV_RPT_ANONYMOUS_ADV = 0xFF, +}ext_adv_adr_type_t; + + +#define PERIODIC_ADV_INTER_NO_PERIODIC_ADV 0 +#define SECONDARY_PHY_NO_PACKET_ON_SECONDARY_ADV_CHN 0 +#define ADVERTISING_SID_NO_ADI_FIELD 0xFF +#define TX_POWER_INFO_NOT_AVAILABLE 127 + + + +/** + * @brief Event Parameters for "7.7.65.14 LE Periodic Advertising Sync Established event" + */ +typedef struct { + u8 subEventCode; + u8 status; + u16 syncHandle; +// extadv_id_t adverting_id; + u8 advSID; + u8 advAddrType; + u8 advAddr[6]; + u8 advPHY; + u16 perdAdvItvl; + u8 advClkAccuracy; +}hci_le_periodicAdvSyncEstablishedEvt_t; + + +/** + * @brief Event Parameters for "7.7.65.15 LE Periodic Advertising Report event" + */ +typedef struct { + u8 subEventCode; + u16 syncHandle; + u8 txPower; + u8 RSSI; + u8 cteType; + u8 dataStatus; + u8 dataLength; // 0 to 247 Length of the Data field + u8 data[1]; +} hci_le_periodicAdvReportEvt_t; + + +/** + * @brief Event Parameters for "7.7.65.16 LE Periodic Advertising Sync Lost event" + */ +typedef struct { + u8 subEventCode; + u16 syncHandle; +} hci_le_periodicAdvSyncLostEvt_t; + + + +typedef struct { + //TODO +} hci_le_scanTimeoutEvt_t; + + + + +/** + * @brief Event Parameters for "7.7.65.18 LE Advertising Set Terminated event" + */ +typedef struct { + u8 subEventCode; + u8 status; + u8 advHandle; + u16 connHandle; + u8 num_compExtAdvEvt; +} hci_le_advSetTerminatedEvt_t; + + +/** + * @brief Event Parameters for "7.7.65.19 LE Scan Request Received event" + */ +typedef struct { + //TODO +} hci_le_scanReqRcvdEvt_t; + + +/** + * @brief Event Parameters for "7.7.65.20 LE Channel Selection Algorithm event" + */ +typedef struct { + u8 subEventCode; + u16 connHandle; + u8 channel_selection_algotihm; +} hci_le_chnSelectAlgorithmEvt_t; + + + + + + +/** + * @brief Event Parameters for "7.7.65.25 LE CIS Established event" + */ +typedef struct { + u8 subEventCode; + u8 status; + u16 cisHandle; + u8 cigSyncDly[3]; + u8 cisSyncDly[3]; + u8 transLaty_m2s[3]; + u8 transLaty_s2m[3]; + u8 phy_m2s; + u8 phy_s2m; + u8 nse; + u8 bn_m2s; + u8 bn_s2m; + u8 ft_m2s; + u8 ft_s2m; + u16 maxPDU_m2s; + u16 maxPDU_s2m; + u16 isoIntvl; +} hci_le_cisEstablishedEvt_t; + + +/** + * @brief Event Parameters for "7.7.65.26 LE CIS Request event" + */ +typedef struct { + u8 subEventCode; + u16 aclHandle; + u16 cisHandle; + u8 cigId; + u8 cisId; +} hci_le_cisReqEvt_t; + + +/** + * @brief Event Parameters for "7.7.65.27 LE Create BIG Complete event" + */ +typedef struct { + u8 subEventCode; + u8 status; + u8 bigHandle; + u8 bigSyncDly[3]; + u8 transLatyBig[3]; + u8 phy; + u8 nse; + u8 bn; + u8 pto; + u8 irc; + u16 maxPDU; + u16 isoIntvl; + u8 numBis; + u16 bisHandles[1];//LL_BIS_IN_PER_BIG_BCST_NUM_MAX]; +} hci_le_createBigCompleteEvt_t; + + + +/** + * @brief Event Parameters for "7.7.65.28 LE Terminate BIG Complete event" + */ +typedef struct { + u8 subEventCode; + u8 bigHandle; + u8 reason; +} hci_le_terminateBigCompleteEvt_t; + + +/** + * @brief Event Parameters for "7.7.65.20 LE Channel Selection Algorithm event" + */ +typedef struct { + u8 subEventCode; + u8 status; + u8 bigHandle; + u8 transLatyBig[3]; + u8 nse; + u8 bn; + u8 pto; + u8 irc; + u16 maxPDU; + u16 isoIntvl; + u8 numBis; + u16 bisHandles[1];//BIS_IN_PER_BIG_SYNC_NUM_MAX]; +} hci_le_bigSyncEstablishedEvt_t; + + +/** + * @brief Event Parameters for "7.7.65.29 LE BIG Sync Established event" + */ +typedef struct { + u8 subEventCode; + u8 bigHandle; + u8 reason; +} hci_le_bigSyncLostEvt_t; + + + +/** + * @brief Event Parameters for "7.7.65.30 LE BIG Sync Lost event" + */ + + +/** + * @brief Event Parameters for "7.7.65.34 LE BIGInfo Advertising Report event" + */ +typedef struct { + u8 subEventCode; + u16 syncHandle; + u8 numBis; + u8 nse; + u16 IsoItvl; //in units of 1.25 ms. + u8 bn; + u8 pto; + u8 irc; + u16 maxPdu; + u8 sduItvl[3]; + u16 maxSdu; + u8 phy; + u8 framing; + u8 enc; +} hci_le_bigInfoAdvReportEvt_t; + + +int hci_le_periodicAdvSyncEstablished_evt (u8 status, u16 syncHandle,u8 advSID, u8 advAddrType, u8 advAddress[6], u8 advPHY, + u16 perdAdvItvl, u8 advClkAccuracy); +//int hci_le_periodicAdvSyncEstablished_evt (u8 status, u16 syncHandle, extadv_id_t *pId, u8 advPHY, u16 perdAdvItvl, u8 advClkAccuracy); + +int hci_le_periodicAdvReport_evt (u8 subEventCode, u16 syncHandle, u8 txPower, u8 RSSI, u8 cteType,u8 dataStatus, u8 dataLength, + u8* data); +int hci_le_periodicAdvSyncLost_evt (u16 syncHandle); +int hci_le_cisEstablished_evt(u8 status, u16 cisHandle, u8 cigSyncDly[3], u8 cisSyncDly[3], u8 transLaty_m2s[3], u8 transLaty_s2m[3], u8 phy_m2s, + u8 phy_s2m, u8 nse, u8 bn_m2s, u8 bn_s2m, u8 ft_m2s, u8 ft_s2m, u16 maxPDU_m2s, u16 maxPDU_s2m, u16 isoIntvl ); +int hci_le_cisReq_evt(u16 aclHandle, u16 cisHandle, u8 cigId, u8 cisId); +int hci_le_createBigComplete_evt(u8 status, u8 bigHandle, u8 bigSyncDly[3], u8 transLatyBig[3], u8 phy, u8 nse, + u8 bn, u8 pto, u8 irc, u16 maxPDU, u16 isoIntvl, u8 numBis, u16* bisHandles); +int hci_le_terminateBigComplete_evt(u8 bigHandle, u8 reason); +int hci_le_bigSyncEstablished_evt(u8 staus, u8 bigHandle, u8 transLatyBig[3], u8 nse, u8 bn, u8 pto, u8 irc, + u16 maxPDU, u16 isoIntvl, u8 numBis, u16* bisHandles); +int hci_le_bigSyncLost_evt(u8 bigHandle, u8 reason); +int hci_le_BigInfoAdvReport_evt(u16 syncHandle, u8 numBis, u8 nse, u16 IsoItvl, u8 bn, u8 pto, u8 irc, + u16 maxPdu, u8 sduItvl[3], u16 maxSdu, u8 phy, u8 framing, u8 enc); +int hci_disconnectionComplete_evt(u8 status, u16 connHandle, u8 reason); +int hci_cmdComplete_evt(u8 numHciCmds, u8 opCode_ocf, u8 opCode_ogf, u8 paraLen, u8 *para, u8 *result); +void hci_cmdStatus_evt(u8 numHciCmds, u8 opCode_ocf, u8 opCode_ogf, u8 status, u8 *result); +int hci_le_connectionComplete_evt(u8 status, u16 connHandle, u8 role, u8 peerAddrType, u8 *peerAddr, + u16 connInterval, u16 slaveLatency, u16 supervisionTimeout, u8 masterClkAccuracy); +int hci_le_enhancedConnectionComplete_evt(u8 status, u16 connHandle, u8 role, u8 peerAddrType, u8 *peerAddr, u8 *loaclRpa, u8 *peerRpa, + u16 connInterval, u16 connLatency, u16 supervisionTimeout, u8 masterClkAccuracy); +int hci_le_connectionUpdateComplete_evt(u8 status, u16 connHandle, u16 connInterval, + u16 connLatency, u16 supervisionTimeout); +int hci_le_readRemoteFeaturesComplete_evt(u8 status, u16 connHandle, u8 * feature); +int hci_le_chennel_selection_algorithm_evt(u16 connhandle, u8 channel_selection_alg); +int hci_le_phyUpdateComplete_evt(u16 connhandle,u8 status, u8 new_phy); +int hci_le_data_len_update_evt(u16 connhandle,u16 effTxOctets, u16 effRxOctets, u16 maxtxtime, u16 maxrxtime); +int hci_le_longTermKeyRequest_evt(u16 connHandle, u8* random, u16 ediv, u8* result); +int hci_le_readLocalP256KeyComplete_evt(u8* localP256Key, u8 status); +int hci_le_generateDHKeyComplete_evt(u8* DHkey, u8 status); +int hci_le_encryptChange_evt(u16 connhandle, u8 encrypt_en); +int hci_le_encryptKeyRefresh_evt(u16 connhandle); +int hci_remoteNateReqComplete_evt (u8* bd_addr); + + +#endif /* HCI_EVENT_H_ */ + + + + + diff --git a/b91/b91m_ble_sdk/stack/ble/host/attr/att.h b/b91/b91m_ble_sdk/stack/ble/host/attr/att.h new file mode 100755 index 0000000..a4d56e4 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/host/attr/att.h @@ -0,0 +1,156 @@ +/******************************************************************************************************** + * @file att.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "tl_common.h" + + +/** @defgroup ATT_PERMISSIONS_BITMAPS GAP ATT Attribute Access Permissions Bit Fields + * @{ + * (See the Core_v5.0(Vol 3/Part C/10.3.1/Table 10.2) for more information) + */ +#define ATT_PERMISSIONS_AUTHOR 0x10 //Attribute access(Read & Write) requires Authorization +#define ATT_PERMISSIONS_ENCRYPT 0x20 //Attribute access(Read & Write) requires Encryption +#define ATT_PERMISSIONS_AUTHEN 0x40 //Attribute access(Read & Write) requires Authentication(MITM protection) +#define ATT_PERMISSIONS_SECURE_CONN 0x80 //Attribute access(Read & Write) requires Secure_Connection +#define ATT_PERMISSIONS_SECURITY (ATT_PERMISSIONS_AUTHOR | ATT_PERMISSIONS_ENCRYPT | ATT_PERMISSIONS_AUTHEN | ATT_PERMISSIONS_SECURE_CONN) + + +// user can choose permission below +#define ATT_PERMISSIONS_READ 0x01 //!< Attribute is Readable +#define ATT_PERMISSIONS_WRITE 0x02 //!< Attribute is Writable +#define ATT_PERMISSIONS_RDWR (ATT_PERMISSIONS_READ | ATT_PERMISSIONS_WRITE) //!< Attribute is Readable & Writable + +#define ATT_PERMISSIONS_ENCRYPT_READ (ATT_PERMISSIONS_READ | ATT_PERMISSIONS_ENCRYPT) //!< Read requires Encryption +#define ATT_PERMISSIONS_ENCRYPT_WRITE (ATT_PERMISSIONS_WRITE | ATT_PERMISSIONS_ENCRYPT) //!< Write requires Encryption +#define ATT_PERMISSIONS_ENCRYPT_RDWR (ATT_PERMISSIONS_RDWR | ATT_PERMISSIONS_ENCRYPT) //!< Read & Write requires Encryption + +#define ATT_PERMISSIONS_AUTHEN_READ (ATT_PERMISSIONS_READ | ATT_PERMISSIONS_ENCRYPT | ATT_PERMISSIONS_AUTHEN) //!< Read requires Authentication +#define ATT_PERMISSIONS_AUTHEN_WRITE (ATT_PERMISSIONS_WRITE | ATT_PERMISSIONS_ENCRYPT | ATT_PERMISSIONS_AUTHEN) //!< Write requires Authentication +#define ATT_PERMISSIONS_AUTHEN_RDWR (ATT_PERMISSIONS_RDWR | ATT_PERMISSIONS_ENCRYPT | ATT_PERMISSIONS_AUTHEN) //!< Read & Write requires Authentication + +#define ATT_PERMISSIONS_SECURE_CONN_READ (ATT_PERMISSIONS_READ | ATT_PERMISSIONS_SECURE_CONN | ATT_PERMISSIONS_ENCRYPT | ATT_PERMISSIONS_AUTHEN) //!< Read requires Secure_Connection +#define ATT_PERMISSIONS_SECURE_CONN_WRITE (ATT_PERMISSIONS_WRITE | ATT_PERMISSIONS_SECURE_CONN | ATT_PERMISSIONS_ENCRYPT | ATT_PERMISSIONS_AUTHEN) //!< Write requires Secure_Connection +#define ATT_PERMISSIONS_SECURE_CONN_RDWR (ATT_PERMISSIONS_RDWR | ATT_PERMISSIONS_SECURE_CONN | ATT_PERMISSIONS_ENCRYPT | ATT_PERMISSIONS_AUTHEN) //!< Read & Write requires Secure_Connection + + +#define ATT_PERMISSIONS_AUTHOR_READ (ATT_PERMISSIONS_READ | ATT_PERMISSIONS_AUTHOR) //!< Read requires Authorization +#define ATT_PERMISSIONS_AUTHOR_WRITE (ATT_PERMISSIONS_WRITE | ATT_PERMISSIONS_AUTHEN) //!< Write requires Authorization +#define ATT_PERMISSIONS_AUTHOR_RDWR (ATT_PERMISSIONS_RDWR | ATT_PERMISSIONS_AUTHOR) //!< Read & Write requires Authorization + +/** @} End GAP_ATT_PERMISSIONS_BITMAPS */ + + + +/** @ add to group GATT_Characteristic_Property GATT characteristic properties + * @{ + */ +#define CHAR_PROP_BROADCAST 0x01 //!< permit broadcasts of the Characteristic Value +#define CHAR_PROP_READ 0x02 //!< permit reads of the Characteristic Value +#define CHAR_PROP_WRITE_WITHOUT_RSP 0x04 //!< Permit writes of the Characteristic Value without response +#define CHAR_PROP_WRITE 0x08 //!< Permit writes of the Characteristic Value with response +#define CHAR_PROP_NOTIFY 0x10 //!< Permit notifications of a Characteristic Value without acknowledgement +#define CHAR_PROP_INDICATE 0x20 //!< Permit indications of a Characteristic Value with acknowledgement +#define CHAR_PROP_AUTHEN 0x40 //!< permit signed writes to the Characteristic Value +#define CHAR_PROP_EXTENDED 0x80 //!< additional characteristic properties are defined + +/** @} end of group GATT_Characteristic_Property */ + + + + +typedef int (*att_readwrite_callback_t)(u16 connHandle, void* p); + +typedef struct attribute +{ + u16 attNum; + u8 perm; + u8 uuidLen; + u32 attrLen; //4 bytes aligned + u8* uuid; + u8* pAttrValue; + att_readwrite_callback_t w; + att_readwrite_callback_t r; +} attribute_t; + + + + + + + +/******************************* User Interface Begin *****************************************************************/ + +/** + * @brief Register ATT table. + * @param[in] p - Pointer point to attribute table. + * @return[in] 0: success + * other: fail + */ +void bls_att_setAttributeTable (u8 *p); + +/** + * @brief This function is used to set prepare write buffer + * @param[in] *p - the pointer of buffer + * @param[in] len - the length of buffer + * @return none. + */ +void blc_att_setPrepareWriteBuffer(u8 *p, u16 len); + +/** + * @brief This function is used to set MTU req pending timing after connection created + * @param[in] time_ms - pending timing, unit: ms + * @return none + */ +void blc_att_setMtureqSendingTime_after_connCreate(int time_ms); +/** + * @brief This function is used to set RX MTU size in master + * @param[in] master_mtu_size - ATT MTU size + * @return[in] 0: success + * other: fail + */ +ble_sts_t blc_att_setMasterRxMTUSize(u16 master_mtu_size); + +/** + * @brief This function is used to set RX MTU size in slave + * @param[in] slave_mtu_size - ATT MTU size + * @return[in] 0: success + * other: fail + */ +ble_sts_t blc_att_setSlaveRxMTUSize(u16 slave_mtu_size); + +/** + * @brief Send MTU Size Exchange Request. + * @param[in] mtu_size - ATT MTU size + * @return[in] 0: success + * other: fail + */ +ble_sts_t blc_att_requestMtuSizeExchange (u16 connHandle, u16 mtu_size); + + +/******************************* User Interface End ******************************************************************/ + + + + + diff --git a/b91/b91m_ble_sdk/stack/ble/host/attr/eatt.h b/b91/b91m_ble_sdk/stack/ble/host/attr/eatt.h new file mode 100755 index 0000000..1f544df --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/host/attr/eatt.h @@ -0,0 +1,82 @@ +/******************************************************************************************************** + * @file eatt.h + * + * @brief for TLSR chips + * + * @author BLE Group + * @date Sep. 18, 2019 + * + * @par Copyright (c) Telink Semiconductor (Shanghai) Co., Ltd. + * All rights reserved. + * + * The information contained herein is confidential and proprietary property of Telink + * Semiconductor (Shanghai) Co., Ltd. and is available under the terms + * of Commercial License Agreement between Telink Semiconductor (Shanghai) + * Co., Ltd. and the licensee in separate contract or the terms described here-in. + * This heading MUST NOT be removed from this file. + * + * Licensees are granted free, non-transferable use of the information in this + * file under Mutual Non-Disclosure Agreement. NO WARRENTY of ANY KIND is provided. + * + *******************************************************************************************************/ +#ifndef GATT_H_ +#define GATT_H_ + + +#if (L2CAP_CREDIT_BASED_FLOW_CONTROL_MODE_EN) + + +#define BLC_EATT_NEED_LEN(sdu, cids, credits) + + +int blc_eatt_registerService(u8 srvCount, u8 chCount, u16 mtu, u16 mps, + u16 credits, u8 *pBuffer, blc_l2cap_coc_evtcb evtcb); +int blc_eatt_startService(u16 handle); +int blc_eatt_stopService(u16 handle); + +int blc_eatt_sendData(u16 handle, u16 scid, u8 *pHead, u8 headLen, u8 *pData, u16 dataLen, bool cidBusy); + + +int blc_eatt_sendErrorRsp(u16 connHandle, u16 scid, u8 errOpcode, u16 errHandle, u8 errReason); + +int blc_eatt_sendReadByTypeReq(u16 connHandle, u16 scid, u16 startAttHandle, + u16 endAttHandle, u8 *uuid, int uuidLen); +int blc_eatt_sendReadByTypeRsp(u16 connHandle, u16 scid, u8 typeLen, u8 dataLen, u8 *pData); + +int blc_eatt_sendReadByGroupTypeReq(u16 connHandle, u16 scid, u16 startAttHandle, + u16 endAttHandle, u8 *uuid, int uuidLen); +int blc_eatt_sendReadByGroupTypeRsp(u16 connHandle, u16 scid, u8 typeLen, u8 *pData, u16 datalen); + +int blc_eatt_sendFindInfoReq(u16 connHandle, u16 scid, u16 startAttHandle, u16 endAttHandle); +int blc_eatt_sendFindInfoRsp(u16 connHandle, u16 scid, u8 format, u8 dataLen, u8 *pData); + +int blc_eatt_sendFindByTypeReq(u16 connHandle, u16 scid, u16 startAttHandle, u16 endAttHandle, + u8 *pUuid, u8* pAttrValue, int valueLen); +int blc_eatt_sendFindByTypeRsp(u16 connHandle, u16 scid, u8 dataLen, u8 *pData); + +int blc_eatt_sendReadReq(u16 connHandle, u16 scid, u16 attHandle); +int blc_eatt_sendReadRsp(u16 connHandle, u16 scid, u8 dataLen, u8 *pData); +int blc_eatt_sendReadBlobReq(u16 connHandle, u16 scid, u16 attHandle, u16 offset); +int blc_eatt_sendReadBlobRsp(u16 connHandle, u16 scid, u8 dataLen, u8 *pData); + +int blc_eatt_sendReadMultipleReq(u16 connHandle, u16 scid, u8 numHandles, u16 *pHandle); +int blc_eatt_sendReadMultVarReq(u16 connHandle, u16 scid, u8 numHandles, u16 *pHandle); +int blc_eatt_sendReadMultVarRsp(u16 connHandle, u16 scid, u8 numVars, u16 *pVarLen); + +int blc_eatt_pushNotify(u16 connHandle, u16 scid, u16 attHandle, u16 dataLen, u8 *pData); +int blc_eatt_pushIndicate(u16 connHandle, u16 scid, u16 attHandle, u16 dataLen, u8 *pData); +int blc_eatt_sendWriteReq(u16 connHandle, u16 scid, u16 attHandle, u16 dataLen, u8 *pData); +int blc_eatt_sendWriteRsp(u16 connHandle, u16 scid); +int blc_eatt_sendWriteCmd(u16 connHandle, u16 scid, u16 attHandle, u16 dataLen, u8 *pData); +int blc_eatt_sendPrepareWriteReq(u16 connHandle, u16 scid, u16 attHandle, + u16 offset, u16 dataLen, u8 *pData); +int blc_eatt_sendPrepareWriteRsp(u16 connHandle, u16 scid, u16 attHandle, + u16 offset, u16 dataLen, u8 *pData); +int blc_eatt_sendExecuteWriteReq(u16 connHandle, u16 scid, u8 flag); +int blc_eatt_sendExecuteWriteRsp(u16 connHandle, u16 scid); + + + +#endif //#if (L2CAP_CREDIT_BASED_FLOW_CONTROL_MODE_EN) + +#endif //#ifndef GATT_H_ diff --git a/b91/b91m_ble_sdk/stack/ble/host/attr/gatt.h b/b91/b91m_ble_sdk/stack/ble/host/attr/gatt.h new file mode 100755 index 0000000..1229ebd --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/host/attr/gatt.h @@ -0,0 +1,137 @@ +/******************************************************************************************************** + * @file gatt.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef GATT_H_ +#define GATT_H_ + +/* GATT data handle call-back. */ +typedef int (*gatt_handler_t) (u16 conn, u8 * p); + +/** + * @brief Register GATT data handle call-back. + * @param[in] handler - + * @return none. + */ +void blc_gatt_register_data_handler(gatt_handler_t handler); + +/** + * @brief Send ATT Value Notify. + * @param[in] connHandle - connection handle. + * @param[in] attHandle - ATT handle. + * @param[in] p - Pointer point to application data buffer. + * @param[in] len - the length of data. + * @return none. + */ +ble_sts_t blc_gatt_pushHandleValueNotify (u16 connHandle, u16 attHandle, u8 *p, int len); + +/** + * @brief Send ATT Indicate. + * @param[in] connHandle - connection handle. + * @param[in] attHandle - ATT handle. + * @param[in] p - Pointer point to application data buffer. + * @param[in] len - the length of data. + * @return none. + */ +ble_sts_t blc_gatt_pushHandleValueIndicate(u16 connHandle, u16 attHandle, u8 *p, int len); + +/** + * @brief Send ATT Write Command. + * @param[in] connHandle - connection handle. + * @param[in] attHandle - ATT handle. + * @param[in] p - Pointer point to application data buffer. + * @param[in] len - the length of data. + * @return none. + */ +ble_sts_t blc_gatt_pushWriteCommand (u16 connHandle, u16 attHandle, u8 *p, int len); + +/** + * @brief Send ATT Write Request. + * @param[in] connHandle - connection handle. + * @param[in] attHandle - ATT handle. + * @param[in] p - Pointer point to application data buffer. + * @param[in] len - the length of data. + * @return none. + */ +ble_sts_t blc_gatt_pushWriteRequest (u16 connHandle, u16 attHandle, u8 *p, int len); + +/** + * @brief Send ATT Find Info Request. + * @param[in] connHandle - connection handle. + * @param[in] start_attHandle - the start of ATT handle. + * @param[in] end_attHandle - the end of ATT handle. + * @return none. + */ +ble_sts_t blc_gatt_pushFindInformationRequest(u16 connHandle, u16 start_attHandle, u16 end_attHandle); + +/** + * @brief Send ATT Find By Type Value Request. + * @param[in] connHandle - connection handle. + * @param[in] start_attHandle - the start of ATT handle. + * @param[in] end_attHandle - the end of ATT handle. + * @param[in] uuid - attribute type. + * @param[in] attr_value - Pointer point to value buffer. + * @param[in] len - the length of value. + * @return none. + */ +ble_sts_t blc_gatt_pushFindByTypeValueRequest(u16 connHandle, u16 start_attHandle, u16 end_attHandle, + u16 uuid, u8 *attr_value, int len); +/** + * @brief Send ATT Read By Type Request. + * @param[in] connHandle - connection handle. + * @param[in] start_attHandle - the start of ATT handle. + * @param[in] end_attHandle - the end of ATT handle. + * @param[in] uuid - attribute type. + * @param[in] uuid_len - the length of attribute type. + * @return none. + */ +ble_sts_t blc_gatt_pushReadByTypeRequest(u16 connHandle, u16 start_attHandle, u16 end_attHandle, u8 *uuid, int uuid_len); + +/** + * @brief Send ATT Read Request. + * @param[in] connHandle - connection handle. + * @param[in] attHandle - ATT handle. + * @return none. + */ +ble_sts_t blc_gatt_pushReadRequest(u16 connHandle, u16 attHandle); + +/** + * @brief Send ATT Read Blob Request. + * @param[in] connHandle - connection handle. + * @param[in] attHandle - ATT handle. + * @param[in] offset - ATT value offset. + * @return none. + */ +ble_sts_t blc_gatt_pushReadBlobRequest(u16 connHandle, u16 attHandle, u16 offset); + +/** + * @brief Send ATT Read By Group Type Request. + * @param[in] connHandle - connection handle. + * @param[in] start_attHandle - the start of ATT handle. + * @param[in] end_attHandle - the end of ATT handle. + * @param[in] uuid - Pointer point to attribute type. + * @param[in] uuid_len - the length of attribute type. + * @return none. + */ +ble_sts_t blc_gatt_pushReadByGroupTypeRequest(u16 connHandle, u16 start_attHandle, u16 end_attHandle, + u8 *uuid, int uuid_len); + +#endif /* GATT_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/host/ble_host.h b/b91/b91m_ble_sdk/stack/ble/host/ble_host.h new file mode 100755 index 0000000..65bf1f8 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/host/ble_host.h @@ -0,0 +1,46 @@ +/******************************************************************************************************** + * @file ble_host.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#ifndef STACK_BLE_HOST_BLE_HOST_H_ +#define STACK_BLE_HOST_BLE_HOST_H_ + +#include "stack/ble/ble_common.h" +#include "stack/ble/ble_format.h" + +#include "stack/ble/host/l2cap/l2cap.h" +#include "stack/ble/host/l2cap/l2cap_signal.h" + + +#include "stack/ble/host/attr/att.h" +#include "stack/ble/host/attr/gatt.h" + + +#include "stack/ble/host/smp/smp.h" +#include "stack/ble/host/smp/smp_storage.h" + +#include "stack/ble/host/gap/gap.h" +#include "stack/ble/host/gap/gap_event.h" + + + +#endif /* STACK_BLE_HOST_BLE_HOST_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/host/gap/gap.h b/b91/b91m_ble_sdk/stack/ble/host/gap/gap.h new file mode 100755 index 0000000..d58113c --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/host/gap/gap.h @@ -0,0 +1,92 @@ +/******************************************************************************************************** + * @file gap.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#include "tl_common.h" + + + +typedef enum { + Gap_Role_Broadcaster = 0, + Gap_Role_Observer = 1, + Gap_Role_Peripheral = 2, + Gap_Role_Central = 3, +}gap_role_t; + + + +#define GAP_ADTYPE_FLAGS 0x01 //!< Discovery Mode: @ref GAP_ADTYPE_FLAGS_MODES +#define GAP_ADTYPE_16BIT_INCOMPLETE 0x02 //!< Incomplete List of 16-bit Service Class UUIDs +#define GAP_ADTYPE_16BIT_COMPLETE 0x03 //!< Complete List of 16-bit Service Class UUIDs +#define GAP_ADTYPE_32BIT_INCOMPLETE 0x04 //!< Service: More 32-bit UUIDs available +#define GAP_ADTYPE_32BIT_COMPLETE 0x05 //!< Service: Complete list of 32-bit UUIDs +#define GAP_ADTYPE_128BIT_INCOMPLETE 0x06 //!< Service: More 128-bit UUIDs available +#define GAP_ADTYPE_128BIT_COMPLETE 0x07 //!< Service: Complete list of 128-bit UUIDs +#define GAP_ADTYPE_LOCAL_NAME_SHORT 0x08 //!< Shortened local name +#define GAP_ADTYPE_LOCAL_NAME_COMPLETE 0x09 //!< Complete local name +#define GAP_ADTYPE_TX_POWER_LEVEL 0x0A //!< TX Power Level: 0xXX: -127 to +127 dBm +#define GAP_ADTYPE_OOB_CLASS_OF_DEVICE 0x0D //!< Simple Pairing OOB Tag: Class of device (3 octets) +#define GAP_ADTYPE_OOB_SIMPLE_PAIRING_HASHC 0x0E //!< Simple Pairing OOB Tag: Simple Pairing Hash C (16 octets) +#define GAP_ADTYPE_OOB_SIMPLE_PAIRING_RANDR 0x0F //!< Simple Pairing OOB Tag: Simple Pairing Randomizer R (16 octets) +#define GAP_ADTYPE_DEVICE_ID 0x10 //!< Device ID Profile v1.3 or later +#define GAP_ADTYPE_SM_TK 0x10 //!< Security Manager TK Value +#define GAP_ADTYPE_SM_OOB_FLAG 0x11 //!< Secutiry Manager OOB Flags +#define GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE 0x12 //!< Min and Max values of the connection interval (2 octets Min, 2 octets Max) (0xFFFF indicates no conn interval min or max) +#define GAP_ADTYPE_SERVICES_LIST_16BIT 0x14 //!< Service Solicitation: list of 16-bit Service UUIDs +#define GAP_ADTYPE_SERVICES_LIST_32BIT 0x1F //!< Service Solicitation: list of 32-bit Service UUIDs +#define GAP_ADTYPE_SERVICES_LIST_128BIT 0x15 //!< Service Solicitation: list of 128-bit Service UUIDs +#define GAP_ADTYPE_SERVICE_DATA 0x16 //!< Service Data +#define GAP_ADTYPE_SERVICE_DATA_UUID_16BIT 0x16 //!< Service Data - 16-bit UUID +#define GAP_ADTYPE_SERVICE_DATA_UUID_32BIT 0x20 //!< Service Data - 32-bit UUID +#define GAP_ADTYPE_SERVICE_DATA_UUID_128BIT 0x21 //!< Service Data - 128-bit UUID +#define GAP_ADTYPE_TARGET_ADDR_PUBLIC 0x17 //!< Public Target Address +#define GAP_ADTYPE_TARGET_ADDR_RANDOM 0x18 //!< Random Target Address +#define GAP_ADTYPE_APPEARANCE 0x19 //!< Appearance +#define GAP_ADTYPE_ADVERTISING_INTERVAL 0x1A //!< Advertising Interval +#define GAP_ADTYPE_LE_BLUETOOTH_DEVICE_ADDR 0x1B //!< ​LE Bluetooth Device Address +#define GAP_ADTYPE_LE_ROLE 0x1C //!< LE Role +#define GAP_ADTYPE_SIMPLE_PAIRING_HASHC_256 0x1D //!< Simple Pairing Hash C-256 +#define GAP_ADTYPE_SIMPLE_PAIRING_RAND_R256 0x1E //!< Simple Pairing Randomizer R-256 +#define GAP_ADTYPE_3D_INFORMATION_DATA 0x3D //!< 3D Synchronization Profile, v1.0 or later +#define GAP_ADTYPE_MANUFACTURER_SPECIFIC 0xFF //!< Manufacturer Specific Data: first 2 octets contain the Company Identifier Code followed by the additional manufacturer specific data + +#define GAP_ADTYPE_LE_LIMITED_DISCOVERABLE_MODE_BIT 0x01 +#define GAP_ADTYPE_LE_GENERAL_DISCOVERABLE_MODE_BIT 0x02 +#define GAP_ADTYPE_LMP_BIT37_BIT 0x04 + +#define GAP_APPEARE_UNKNOWN 0x0000 //!< Unknown + + + + + + +/** + * @brief this function is used to initialize GAP + * @param none + * @return none + */ +void blc_gap_init(void); + + + diff --git a/b91/b91m_ble_sdk/stack/ble/host/gap/gap_event.h b/b91/b91m_ble_sdk/stack/ble/host/gap/gap_event.h new file mode 100755 index 0000000..6799998 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/host/gap/gap_event.h @@ -0,0 +1,398 @@ +/******************************************************************************************************** + * @file gap_event.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +/* + * gap_event.h + * + * Created on: 2018-12-5 + * Author: Administrator + */ + +#ifndef GAP_EVENT_H_ +#define GAP_EVENT_H_ + + + + + + + + + + +/***************************************** SMP message sequence and event chart ******************************************************* + + GAP_SMP EVENT +Situation 1: SMP Standard Pair | + Phase 1: Pairing Feature Exchange | + Phase 2: Encryption( STK/LTK Generation ) | + Phase 3: Key Distribution | + | + Master Slave | + | | | + | | | + ________|___________________________________________________________|_______ | + | | | + | Establish LL connection | | + |___________________________________________________________________________| | + | | | + | | | + | Phase 1: Pairing Feature Exchange | | + _______|___________________________________________________________|_______ | + | | | | | + | | (Optional)Security_Request | | | + | |<----------------------------------------------------------| | | + | | Pairing_Req | | + | |---------------------------------------------------------->|=======|=====>>> GAP_EVT_SMP_PAIRING_BEGIN + | | Pairing_Rsp | | + | |<----------------------------------------------------------| | | + | | ....... | | | + |_______|___________________________________________________________|_______| | + | | | + | | | + | Phase 2: Encryption | | + _______|___________________________________________________________|_______ | + | | | | | + | | LL_ENC_REQ | | | + | |---------------------------------------------------------->| | | + | | LL_ENC_RSP | | | + | |<----------------------------------------------------------| | | + | | LL_START_ENC_REQ | | | + | |<----------------------------------------------------------| | | + | | LL_START_ENC_RSP | | | + | |---------------------------------------------------------->| | | + | | LL_START_ENC_RSP | | + | |<----------------------------------------------------------|=======|=====>>> GAP_EVT_SMP_CONN_ENCRYPTION_DONE(re_connect = SMP_STANDARD_PAIR) + |_______|___________________________________________________________|_______| + | | | + | | | + | Phase 3: Key Distribution | | + _______|___________________________________________________________|_______ | + | | | | | + | | Key Distribution | | | + | |<----------------------------------------------------------| | | + | | Key Distribution | | | + | |<----------------------------------------------------------| | | + | | ....... | | | + | | | | | + | | Key Distribution | | | + | |---------------------------------------------------------->| | | + | | Key Distribution | | | + | |---------------------------------------------------------->| | | + | | ....... | | | + | | | | + | | All Key Distribution Finish |=======|=====>>> GAP_EVT_SMP_PAIRING_SUCCESS + | | |=======|=====>>> GAP_EVT_SMP_SECURITY_PROCESS_DONE(re_connect = SMP_STANDARD_PAIR) + |_______|___________________________________________________________|_______| + | + | + | + | +Situation 2: SMP Fast Connect | + Only 1 Phase: Encryption | + | + Master Slave | + | | | + | | | + ________|___________________________________________________________|_______ | + | | | + | Establish LL connection | | + |___________________________________________________________________________| | + | | | + | | | + | Phase 2: Encryption | | + _______|___________________________________________________________|_______ | + | | | | | + | | LL_ENC_REQ | | | + | |---------------------------------------------------------->| | | + | | LL_ENC_RSP | | | + | |<----------------------------------------------------------| | | + | | LL_START_ENC_REQ | | | + | |<----------------------------------------------------------| | | + | | LL_START_ENC_RSP | | | + | |---------------------------------------------------------->| | | + | | LL_START_ENC_RSP | | | + | |<----------------------------------------------------------|=======|=====>>> GAP_EVT_SMP_CONN_ENCRYPTION_DONE (re_connect = SMP_FAST_CONNECT) + | | |=======|=====>>> GAP_EVT_SMP_SECURITY_PROCESS_DONE(re_connect = SMP_FAST_CONNECT) + |_______|___________________________________________________________|_______| + + + *****************************************************************************************************************************/ + + +/** + * @brief GAP event type + */ +#define GAP_EVT_SMP_PAIRING_BEGIN 0 // Refer to SMP message sequence and event chart above +#define GAP_EVT_SMP_PAIRING_SUCCESS 1 // Refer to SMP message sequence and event chart above +#define GAP_EVT_SMP_PAIRING_FAIL 2 +#define GAP_EVT_SMP_CONN_ENCRYPTION_DONE 3 // Refer to SMP message sequence and event chart above +#define GAP_EVT_SMP_SECURITY_PROCESS_DONE 4 // Refer to SMP message sequence and event chart above + +#define GAP_EVT_SMP_TK_DISPALY 8 +#define GAP_EVT_SMP_TK_REQUEST_PASSKEY 9 +#define GAP_EVT_SMP_TK_REQUEST_OOB 10 +#define GAP_EVT_SMP_TK_NUMERIC_COMPARE 11 +#define GAP_EVT_SMP_BONDING_INFO_FULL 12 + + +#define GAP_EVT_ATT_EXCHANGE_MTU 16 +#define GAP_EVT_GATT_HANDLE_VLAUE_CONFIRM 17 + +#define GAP_EVT_L2CAP_CONN_PARAM_UPDATE_REQ 20 +#define GAP_EVT_L2CAP_CONN_PARAM_UPDATE_RSP 21 + +#if (L2CAP_CREDIT_BASED_FLOW_CONTROL_MODE_EN) +#define GAP_EVT_L2CAP_LE_CREDIT_BASED_CONNECT 22 +#define GAP_EVT_L2CAP_CREDIT_BASED_CONNECT 23 +#define GAP_EVT_L2CAP_CREDIT_BASED_RECONFIG 24 +#define GAP_EVT_L2CAP_FLOW_CONTROL_CREDIT 25 +#define GAP_EVT_L2CAP_DISCONNECT 26 +#define GAP_EVT_L2CAP_COC_DATA 27 +#endif + + +/** + * @brief GAP event mask + */ +#define GAP_EVT_MASK_NONE 0x00000000 +#define GAP_EVT_MASK_SMP_PAIRING_BEGIN (1<0) + * @param[in] pBuffer - A buffer to store data. You can use BLC_L2CAP_COC_MTU_NEEDLEN to calculate the required size. + * @param[in] evtCb - The callback of Event. + * @param[in] dataCb - The callback of RecvData. + * @return >=0: Number of services successfully registered; + * -1: Incorrect input parameter; + * -2: The resource is insufficient; + * -3: Unknown Error. + */ +int blc_l2cap_registerService(u16 spsm, u8 srvCount, u8 chCount, u16 mtu, u16 mps, + u16 credits, u8 *pBuffer, blc_l2cap_coc_evtcb evtCb, blc_l2cap_coc_datacb dataCb); +/** + * @brief Start the COC service. The interface automatically finds the relevant SPSM service, binds it to ConnHandle, and sends the start instruction packet. + * @param[in] aclHandle - The connection handle to be bound. + * @param[in] spsm - Simplified Protocol/Service Multiplexer. Refer to L2CAP_COC_PSM_ENUM. + * @param[in] method - Refer to L2CAP_COC_START_METHOD_ENUM. + * @return 0: success; + * -1: The AclHandle is not in a connected state; + * -2: There is no available service. + * -3: The service's state is error. (eg, Busy.) + * -4: There is no available channel. (This interface can be called multiple times so that all Channels are created.) + * -5: Failed to push data to Controller. + */ +int blc_l2cap_startService(u16 aclHandle, u16 spsm, u8 method); +/** + * @brief Stop the COC service. + * @param[in] aclHandle - The connection handle to be bound. + * @param[in] spsm - Simplified Protocol/Service Multiplexer. Refer to L2CAP_COC_PSM_ENUM. + * @return 0: success; + * -1: The Service is not started; + * -2: The Service's state is error. (eg, Busy.) + */ +int blc_l2cap_stopService(u16 aclHandle, u16 spsm); +/** + * @brief Disconnects the specified channel. Once disconnected, the user can also call "startService" to recreate it. + * @param[in] aclHandle - The connection handle. + * @param[in] scid - Source Channel ID. (local CID) + * @return 0: success; + * -1: The SCID is no available; + * -2: The Service is not started; + * -3: The Channel's state is error; + * -4: Failed to push data to Controller. + */ +int blc_l2cap_disconnScid(u16 aclHandle, u16 scid); + +/** + * @brief Reconfigure the MTU and MPS of the COC service. This interface can only be invoked when the service is idle. + * It is not stable at the moment, please use with caution! + * @param[in] aclHandle - The connection handle. + * @param[in] srvNum - Service ID. + * @param[in] mtu - Maximum Transmission Unit. + * @param[in] mps - Maximum PDU Payload Size. + * @return 0: success; + * -1: The srvNum is no available; + * -2: The Service's state is error; + * >0: Failed to push data to Controller. Refer to ble_sts_t. + */ +int blc_l2cap_reconfigService(u8 srvNum, u16 mtu, u16 mps); +/** + * @brief Get the SPSM of the corresponding service. + * @param[in] aclHandle - The connection handle. + * @param[in] srvNum - Service ID. + * @return SPSM. (0-fail) + */ +u16 blc_l2cap_getSpsmBySrvnum(u8 srvNum); +/** + * @brief Get the "SrvNum" by "ConnHandle" and "SPSM". + * @param[in] aclHandle - The connection handle. + * @param[in] spsm - Simplified Protocol/Service Multiplexer. Refer to L2CAP_COC_PSM_ENUM. + * @return SrvNum. (0-fail) + */ +u8 blc_l2cap_getSrvnumBySpsm(u16 aclHandle, u16 spsm); + + +/** + * @brief Sends data to the specified channel. + * @param[in] aclHandle - The connection handle. + * @param[in] scid - Source Channel ID. (local CID) + * @param[in] pHead - The first part of the data to be sent. + * @param[in] headLen - The length of the data's first part. + * @param[in] pData - The second part of the data to be sent. + * @param[in] dataLen - The length of the data's second part. + * @return 0: success; + * -1: The parameter is error. + * -2: The SCID is no available. + * >0: Failed to push data to Controller. Refer to ble_sts_t. + */ +int blc_l2cap_cocSendData(u16 aclHandle, u16 scid, u8 *pHead, u8 headLen, u8 *pData, u16 dataLen); + + + +#endif //#if (L2CAP_CREDIT_BASED_FLOW_CONTROL_MODE_EN) + +#endif /* L2CAP_COC_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/host/smp/smp.h b/b91/b91m_ble_sdk/stack/ble/host/smp/smp.h new file mode 100755 index 0000000..a16cbc6 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/host/smp/smp.h @@ -0,0 +1,311 @@ +/******************************************************************************************************** + * @file smp.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef BLE_SMP_H_ +#define BLE_SMP_H_ + +#include "stack/ble/ble_common.h" + + +/** @addtogroup SMP first pairing or connecting back definition + * @{ + */ +#define SMP_STANDARD_PAIR 0 +#define SMP_FAST_CONNECT 1 +/** @} end of group SMP first pairing or connecting back */ + + +/** @addtogroup SMP pairing fail reason definition + * @{ + */ +#define PAIRING_FAIL_REASON_PASSKEY_ENTRY 0x01 +#define PAIRING_FAIL_REASON_OOB_NOT_AVAILABLE 0x02 +#define PAIRING_FAIL_REASON_AUTH_REQUIRE 0x03 +#define PAIRING_FAIL_REASON_CONFIRM_FAILED 0x04 +#define PAIRING_FAIL_REASON_PAIRING_NOT_SUPPORTED 0x05 +#define PAIRING_FAIL_REASON_ENCRYPT_KEY_SIZE 0x06 +#define PAIRING_FAIL_REASON_CMD_NOT_SUPPORT 0x07 //-- core 4.2 +#define PAIRING_FAIL_REASON_UNSPECIFIED_REASON 0x08 +#define PAIRING_FAIL_REASON_REPEATED_ATTEMPT 0x09 +#define PAIRING_FAIL_REASON_INVAILD_PARAMETER 0x0A +#define PAIRING_FAIL_REASON_DHKEY_CHECK_FAIL 0x0B +#define PAIRING_FAIL_REASON_NUMUERIC_FAILED 0x0C +#define PAIRING_FAIL_REASON_BREDR_PAIRING 0x0D +#define PAIRING_FAIL_REASON_CROSS_TRANSKEY_NOT_ALLOW 0x0E +#define PAIRING_FAIL_REASON_PAIRING_TIEMOUT 0x80 //TLK defined +#define PAIRING_FAIL_REASON_CONN_DISCONNECT 0x81 //TLK defined +#define PAIRING_FAIL_REASON_SUPPORT_NC_ONLY 0x82 //TLK defined +/** @} end of group SMP pairing fail reasone */ + + +// "SecReq" refer to "security request" +typedef enum { + SecReq_NOT_SEND = 0, // do not send "security request" after link layer connection established + SecReq_IMM_SEND = BIT(0), //"IMM" refer to immediate, send "security request" immediately after link layer connection established + SecReq_PEND_SEND = BIT(1), //"PEND" refer to pending, pending "security request" for some time after link layer connection established, when pending time arrived. send it +}secReq_cfg; + + +// "PairReq" refer to "pairing request" +typedef enum { + PairReq_SEND_upon_SecReq = 0, // master send "pairing request" when received slave's "security request" + PairReq_AUTO_SEND = 1, // master send "pairing request" automatically, regardless of "security request" +}PairReq_cfg; + + +//See the Core_v5.0(Vol 3/Part C/10.2, Page 2067) for more information. +typedef enum { + LE_Security_Mode_1_Level_1 = BIT(0), No_Authentication_No_Encryption = BIT(0), No_Security = BIT(0), + LE_Security_Mode_1_Level_2 = BIT(1), Unauthenticated_Pairing_with_Encryption = BIT(1), + LE_Security_Mode_1_Level_3 = BIT(2), Authenticated_Pairing_with_Encryption = BIT(2), + LE_Security_Mode_1_Level_4 = BIT(3), Authenticated_LE_Secure_Connection_Pairing_with_Encryption = BIT(3), + + LE_Security_Mode_2_Level_1 = BIT(4), Unauthenticated_Pairing_with_Data_Signing = BIT(4), + LE_Security_Mode_2_Level_2 = BIT(5), Authenticated_Pairing_with_Data_Signing = BIT(5), + + LE_Security_Mode_1 = (LE_Security_Mode_1_Level_1 | LE_Security_Mode_1_Level_2 | LE_Security_Mode_1_Level_3 | LE_Security_Mode_1_Level_4) +}le_security_mode_level_t; + + +typedef enum { + non_debug_mode = 0, // ECDH distribute private/public key pairs + debug_mode = 1, // ECDH use debug mode private/public key pairs +} ecdh_keys_mode_t; + + +typedef enum { + Non_Bondable_Mode = 0, + Bondable_Mode = 1, +}bonding_mode_t; + + +//Pairing Methods select +//See the Core_v5.0(Vol 3/Part H/2.3) for more information. +typedef enum { + LE_Legacy_Pairing = 0, // BLE 4.0/4.2 + LE_Secure_Connection = 1, // BLE 4.2/5.0/5.1 +}pairing_methods_t; + + +typedef enum { + IO_CAPABILITY_UNKNOWN = 0xff, + IO_CAPABILITY_DISPLAY_ONLY = 0, + IO_CAPABILITY_DISPLAY_YES_NO = 1, + IO_CAPABILITY_KEYBOARD_ONLY = 2, + IO_CAPABILITY_NO_INPUT_NO_OUTPUT = 3, + IO_CAPABILITY_KEYBOARD_DISPLAY = 4, +} io_capability_t; + + +/** + * @brief This function is used to initialize each parameter configuration of SMP, including the initialization of the binding area FLASH. + * @param[in] none + * @return none + */ +void blc_smp_smpParamInit(void); + + +/** + * @brief This function is used to configure whether the slave sends a Security Request + * to the master immediately after the connection or after the connection is + * pending_ms milliseconds, or does not send the Security Request. + * @param[in] newConn_cfg - refer to "security request" + * @param[in] re_conn_cfg - refer to "security request" + * @param[in] pending_ms - Send a Security Request to the master after pending_ms milliseconds + * @return none. + */ +void blc_smp_configSecurityRequestSending( secReq_cfg newConn_cfg, secReq_cfg reConn_cfg, u16 pending_ms); + + +/** + * @brief This function is used to check whether active pairing or automatic connection back is required. + * @param[in] newConn_cfg - refer to "PairReq_cfg" + * @param[in] reConn_cfg - refer to "PairReq_cfg" + * @return none. + */ +void blc_smp_configPairingRequestSending( PairReq_cfg newConn_cfg, PairReq_cfg reConn_cfg); + + +/** + * @brief This function is used to set security level. + * @param[in] mode_level - The security level value can refer to the structure 'le_security_mode_level_t'. + * @return none. + */ +void blc_smp_setSecurityLevel(le_security_mode_level_t mode_level); +void blc_smp_setSecurityLevel_master(le_security_mode_level_t mode_level); +void blc_smp_setSecurityLevel_slave(le_security_mode_level_t mode_level); + +/** + * @brief This function is used to set pairing method. + * @param[in] method - The pairing method value can refer to the structure 'pairing_methods_t'. + * 0: LE legacy pairing; + * 1: LE secure connection + * @return none. + */ +void blc_smp_setPairingMethods(pairing_methods_t method); +void blc_smp_setPairingMethods_master(pairing_methods_t method); //select pairing methods +void blc_smp_setPairingMethods_slave (pairing_methods_t method); //select pairing methods + + +/** + * @brief This function is used to set device's IO capability. + * @param[in] ioCapablility - The IO capability's value can refer to the structure 'io_capability_t'. + * @return none. + */ +void blc_smp_setIoCapability(io_capability_t ioCapablility); +void blc_smp_setIoCapability_master(io_capability_t ioCapablility); +void blc_smp_setIoCapability_slave(io_capability_t ioCapablility); + + +/** + * @brief This function is used to set if enable OOB authentication. + * @param[in] OOB_en - 0: Disable OOB authentication; + * 1: Enable OOB authentication. + * @return none. + */ +void blc_smp_enableOobAuthentication(int OOB_en); +void blc_smp_enableOobAuthentication_master (int OOB_en); +void blc_smp_enableOobAuthentication_slave (int OOB_en); + + +/** + * @brief This function is used to set bonding mode. + * @param[in] mode - The bonding mode value can refer to the structure 'bonding_mode_t'. + * 0: non bondable mode; + * 1: bondable mode. + * @return none. + */ +void blc_smp_setBondingMode(bonding_mode_t mode); +void blc_smp_setBondingMode_master(bonding_mode_t mode); +void blc_smp_setBondingMode_slave(bonding_mode_t mode); + + +/** + * @brief This function is used to set if enable authentication MITM protection. + * @param[in] MITM_en - 0: Disable MITM protection; + * 1: Enable MITM protection. + * @return none. + */ +void blc_smp_enableAuthMITM(int MITM_en); +void blc_smp_enableAuthMITM_master(int MITM_en); +void blc_smp_enableAuthMITM_slave(int MITM_en); + + +/** + * @brief This function is used to set device's Keypress. + * @param[in] keyPress_en - 0: Disable Keypress; + * 1: Enable Keypress. + * @return none. + */ +void blc_smp_enableKeypress(int keyPress_en); +void blc_smp_enableKeypress_master(int keyPress_en); +void blc_smp_enableKeypress_slave(int keyPress_en); + + +/** + * @brief This function is used to set whether the device uses the ECDH DEBUG key. + * @param[in] mode - The ECDH key mode value can refer to the structure 'ecdh_keys_mode_t'. + * 0: non debug mode; + * 1: debug mode. + * @return none. + */ +void blc_smp_setEcdhDebugMode(ecdh_keys_mode_t mode); +void blc_smp_setEcdhDebugMode_master(ecdh_keys_mode_t mode); +void blc_smp_setEcdhDebugMode_slave(ecdh_keys_mode_t mode); + + +/** + * @brief This function is used to set device's security parameters. + * @param[in] mode - The bonding mode value can refer to the structure 'bonding_mode_t'. + * @param[in] MITM_en - 0: Disable MITM protection; 1: Enable MITM protection. + * @param[in] method - 0: LE_Legacy_Pairing; 1: LE_Secure_Connection. + * @param[in] OOB_en - 0: Disable OOB authentication; 1: Enable OOB authentication. + * @param[in] keyPress_en - 0: Disable Keypress; 1: Enable Keypress. + * @param[in] ioCapablility - The IO capability's value can refer to the structure 'io_capability_t'. + * @return none. + */ +void blc_smp_setSecurityParameters(bonding_mode_t mode, int MITM_en, pairing_methods_t method, int OOB_en, + int keyPress_en, io_capability_t ioCapablility); +void blc_smp_setSecurityParameters_master(bonding_mode_t bond_mode, int MITM_en, pairing_methods_t method, int OOB_en, + int keyPress_en,io_capability_t ioCapablility); +void blc_smp_setSecurityParameters_slave(bonding_mode_t bond_mode, int MITM_en, pairing_methods_t method, int OOB_en, + int keyPress_en,io_capability_t ioCapablility); + + +/** + * @brief This function is used to set TK by OOB method. + * param[in] connHandle - Current ACL connection handle. + * @param[in] oobData - TK's value, size: 16 byte. + * @return none. + */ +u8 blc_smp_setTK_by_OOB (u16 connHandle, u8 *oobData); //used for set oob data + + +/** + * @brief This function is used to set TK by passkey entry method. + * param[in] connHandle - Current ACL connection handle. + * @param[in] pinCodeInput - TK's value, input range [000000, 999999]. + * @return none. + */ +u8 blc_smp_setTK_by_PasskeyEntry (u16 connHandle, u32 pinCodeInput); + + +/** + * @brief This function is used to set numeric compare confirm YES or NO. + * param[in] connHandle - Current ACL connection handle. + * @param[in] YES_or_NO - 1: numeric compare confirm YES; + * 0: numeric compare confirm NO. + * @return none. + */ +void blc_smp_setNumericComparisonResult(u16 connHandle, bool YES_or_NO); //numeric compare confirm, 1: YES 0: NO + + +/** + * @brief This function is used to check if the pairing is busy. + * @param[in] connHandle - Current ACL connection handle. + * @return 1:is pair busy + * 0:isn't pair busy + */ +int blc_smp_isPairingBusy(u16 connHandle); + + +/** + * @brief This function is used to check whether the PinCode needs to be input. + * @param[in] connHandle - Current ACL connection handle. + * @return 1: Need to enter PinCode + * 0: No need to enter PinCode + */ +u8 blc_smp_isWaitingToSetPasskeyEntry(u16 connHandle); + + +/** + * @brief This function is used to check whether it is needed to confirm NC YES/NO. + * @param[in] connHandle - Current ACL connection handle. + * @return 1: Need to confirm NC YES/NO + * 0: No need to confirm NC YES/NO + */ +u8 blc_smp_isWaitingToCfmNumericComparison(u16 connHandle); + + + +#endif /* BLE_SMP_H_ */ + diff --git a/b91/b91m_ble_sdk/stack/ble/host/smp/smp_storage.h b/b91/b91m_ble_sdk/stack/ble/host/smp/smp_storage.h new file mode 100755 index 0000000..ee05def --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/host/smp/smp_storage.h @@ -0,0 +1,200 @@ +/******************************************************************************************************** + * @file smp_storage.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef SMP_STORAGE_H_ +#define SMP_STORAGE_H_ + + + + +/* + * Address resolution is not supported by default. After pairing and binding, we need to obtain the central Address Resolution + * feature value of the opposite end to determine whether the opposite end supports the address resolution function, and write + * the result to smp_bonding_flg. Currently, we leave it to the user to obtain this feature. + */ +#define IS_PEER_ADDR_RES_SUPPORT(peerAddrResSuppFlg) (!(peerAddrResSuppFlg & BIT(7))) + + +typedef enum { + Index_Update_by_Pairing_Order = 0, //default value + Index_Update_by_Connect_Order = 1, +} index_updateMethod_t; + + +/* + * smp parameter need save to flash. + */ +typedef struct { + //0x00 + u8 flag; + u8 role_dev_idx; //[7]:1 for master, 0 for slave; [2:0] slave device index + + // peer_addr_type & peer_addr must be together(SiHui 20200916), cause using flash read packed "type&address" in code + u8 peer_addr_type; //address used in link layer connection + u8 peer_addr[6]; + + u8 peer_id_adrType; //peer identity address information in key distribution, used to identify + u8 peer_id_addr[6]; + + //0x10 + u8 local_peer_ltk[16]; //slave: local_ltk; master: peer_ltk + + //0x20 + u8 encryt_key_size; + u8 local_id_adrType; + u8 local_id_addr[6]; + + u8 random[8]; //8 + + + //0x30 + u8 peer_irk[16]; + + //0x40 + u8 local_irk[16]; // local_csrk can be generated based on this key, to save flash area (delete this note at last, customers can not see it) + + //0x50 + u16 ediv; //2 + u8 rsvd[14]; //14 peer_csrk info address if needed(delete this note at last, customers can not see it) +}smp_param_save_t; + + + + +/** + * @brief This function is used to configure the bonding storage address and size. + * @param[in] address - SMP bonding storage start address. + * @param[in] size_byte - SMP bonding storage size(e.g.: 2*4096). + * @return none. + */ +void blc_smp_configPairingSecurityInfoStorageAddressAndSize (int address, int size_byte); //address and size must be 4K aligned + + +/** + * @brief This function is used to configure the number of master and slave devices that can be bound. + * @param[in] peer_slave_max - The number of slave devices that can be bound. + * @param[in] peer_master_max - The number of master devices that can be bound. + * @return none. + */ +void blc_smp_setBondingDeviceMaxNumber ( int peer_slave_max, int peer_master_max); + + +/** + * @brief This function is used to get the starting address of the current binding information storage area. + * @param[in] none. + * @return The starting address of the current binding information storage area. + */ +u32 blc_smp_getBondingInfoCurStartAddr(void); + + +//Search +// This API is for master only, to search if current slave device is already paired with master +/** + * @brief This function is used to obtain binding information according to the slave's address and address type. + * @param[in] peer_addr_type - Address type. + * @param[in] peer_addr - Address. + * @return 0: Failed to get binding information; + * others: FLASH address of the information area. + */ +u32 blc_smp_searchBondingSlaveDevice_by_PeerMacAddress( u8 peer_addr_type, u8* peer_addr); + +//Delete +/** + * @brief This function is used to delete binding information according to the peer device address and device address type. + * @param[in] peer_addr_type - Address type. + * @param[in] peer_addr - Address. + * @return 0: Failed to delete binding information; + * others: FLASH address of the deleted information area. + */ +int blc_smp_deleteBondingSlaveInfo_by_PeerMacAddress(u8 peer_addr_type, u8* peer_addr); + + +/** + * @brief This function is used to configure the storage order of binding information. + * @param[in] method - The storage order of binding info method value can refer to the structure 'index_updateMethod_t'. + * 0: Index update by pairing order; + * 1: Index update by connect order. + * @return none. + */ +void blc_smp_setBondingInfoIndexUpdateMethod(index_updateMethod_t method); + + +/** + * @brief This function is used to clear all binding information stored in the local FLASH. + * @param[in] none. + * @return none. + */ +void blc_smp_eraseAllBondingInfo(void); + + +/** + * @brief This function is used to check whether the bound storage area reaches the almost full warning threshold. + * @param[in] none. + * @return 0: The warning threshold is not reached. + * 1: The warning threshold is reached.. + */ +bool blc_smp_isBondingInfoStorageLowAlarmed(void); + + +/** + * @brief This function is used to load bonding information according to the peer device address and device address type. + * @param[in] isMaster - Is it a Master role: 0: slave role, others: master role. + * @param[in] slaveDevIdx - Address. + * @param[in] addr_type - Address type. + * @param[in] addr - Address. + * @param[out] smp_param_load - bonding information. + * @return 0: Failed to find the binding information; others: FLASH address of the bonding information area. + */ +u32 blc_smp_loadBondingInfoByAddr(u8 isMaster, u8 slaveDevIdx, u8 addr_type, u8* addr, smp_param_save_t* smp_param_load); + + +/** + * @brief This function is used to get the bonding information numbers. + * @param[in] isMaster - Is it a Master role: 0: slave role, others: master role. + * @param[in] slaveDevIdx - Address. + * @return 0: The number of bound devices is 0; others: Number of bound devices. + */ +u8 blc_smp_param_getCurrentBondingDeviceNumber(u8 isMasterRole, u8 slaveDevIdx); + + +/** + * @brief This function is used to load bonding information according to the index. + * @param[in] isMaster - Is it a Master role: 0: slave role, others: master role. + * @param[in] slaveDevIdx - Address. + * @param[in] index - bonding index. + * @param[out] smp_param_load - bonding information. + * @return 0: Failed to find the binding information; others: FLASH address of the bonding information area. + */ +u32 blc_smp_loadBondingInfoFromFlashByIndex(u8 isMaster, u8 slaveDevIdx, u8 index, smp_param_save_t* smp_param_load); + + +/** + * @brief This function is used to delete binding information according to the peer device address and device address type. + * @param[in] peer_addr_type - Address type. + * @param[in] peer_addr - Address. + * @return 0: Failed to delete binding information; + * others: FLASH address of the deleted information area. + */ +int blc_smp_setPeerAddrResSupportFlg(u32 flash_addr, u8 support); + + +#endif /* SMP_STORAGE_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_ascp.h b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_ascp.h new file mode 100755 index 0000000..2e15eb8 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_ascp.h @@ -0,0 +1,257 @@ +/******************************************************************************************************** + * @file audio_ascp.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef _AUDIO_BAP_H_ +#define _AUDIO_BAP_H_ + +#if (BLC_AUDIO_ASCP_ENABLE) + + + +typedef enum{ + BLT_AUDIO_ASCP_FLAG_NONE = 0x0000, + BLT_AUDIO_ASCP_FLAG_FIRST = 0x0001, + BLT_AUDIO_ASCP_FLAG_RASE = 0x0002, //Read Ase Attribute + BLT_AUDIO_ASCP_FLAG_CCC = 0x0004, +}BLT_AUDIO_ASCP_FLAGS_ENUM; + +typedef enum{ + BLT_AUDIO_ASE_STATE_IDLE = 0x00, + BLT_AUDIO_ASE_STATE_CODEC_CFG = 0x01, + BLT_AUDIO_ASE_STATE_QOS_CFG = 0x02, + BLT_AUDIO_ASE_STATE_ENABLING = 0x03, + BLT_AUDIO_ASE_STATE_STREAMING = 0x04, + BLT_AUDIO_ASE_STATE_DISABLING = 0x05, + BLT_AUDIO_ASE_STATE_RELEASING = 0x06, +}BLT_AUDIO_ASE_STATE_ENUM; +typedef enum{ + BLT_AUDIO_ASE_FLAG_NONE = 0x0000, + + BLT_AUDIOC_ASE_FLAG_ENABLE = 0x8000, + BLT_AUDIOC_ASE_FLAG_DISABLE = 0x4000, + BLT_AUDIOC_ASE_FLAG_SEND_WAIT = 0x2000, + BLT_AUDIOC_ASE_FLAG_SEND_CODEC = 0x1000, + BLT_AUDIOC_ASE_FLAG_SEND_QOS = 0x0800, + BLT_AUDIOC_ASE_FLAG_SEND_ENABLE = 0x0400, + BLT_AUDIOC_ASE_FLAG_SEND_DISABLE = 0x0200, + BLT_AUDIOC_ASE_FLAG_SEND_START = 0x0100, + BLT_AUDIOC_ASE_FLAG_SEND_STOP = 0x0080, + BLT_AUDIOC_ASE_FLAG_SEND_RELEASE = 0x0040, + BLT_AUDIOC_ASE_FLAG_SEND_UPDATE = 0x0020, + + BLT_AUDIOC_ASE_FLAG_ENABLE_MASK = BLT_AUDIOC_ASE_FLAG_SEND_CODEC|BLT_AUDIOC_ASE_FLAG_SEND_QOS + | BLT_AUDIOC_ASE_FLAG_SEND_ENABLE|BLT_AUDIOC_ASE_FLAG_SEND_START + | BLT_AUDIOC_ASE_FLAG_ENABLE, + BLT_AUDIOC_ASE_FLAG_DISABLE_MASK = BLT_AUDIOC_ASE_FLAG_SEND_DISABLE|BLT_AUDIOC_ASE_FLAG_SEND_STOP + | BLT_AUDIOC_ASE_FLAG_SEND_RELEASE|BLT_AUDIOC_ASE_FLAG_DISABLE, + + BLT_AUDIOC_ASE_FLAG_CREATE_CIS = 0x0010, + BLT_AUDIOC_ASE_FLAG_DESTORY_CIS = 0x0008, + BLT_AUDIOC_ASE_FLAG_CREATE_CIS_WAIT = 0x0004, + BLT_AUDIOC_ASE_FLAG_DESTORY_CIS_WAIT = 0x0002, + + BLT_AUDIOS_ASE_FLAG_NOTY_STATE = 0x0001, + +}BLT_AUDIO_ASE_FLAGS_ENUM; + +typedef enum{ + BLT_AUDIO_ASE_READY_NONE = 0x0000, + BLT_AUDIO_ASE_PARAM_READY = 0x8000, + BLT_AUDIO_ASE_CODEC_READY = 0x0001, +}BLT_AUDIO_ASE_READY_ENUM; + +typedef enum{ + BLT_AUDIO_ASCS_OPCODE_CONFIG_CODEC = 0x01, + BLT_AUDIO_ASCS_OPCODE_CONFIG_QOS = 0x02, + BLT_AUDIO_ASCS_OPCODE_CONFIG_ENABLE = 0x03, + BLT_AUDIO_ASCS_OPCODE_CONFIG_RECV_START = 0x04, + BLT_AUDIO_ASCS_OPCODE_CONFIG_DISABLE = 0x05, + BLT_AUDIO_ASCS_OPCODE_CONFIG_RECV_STOP = 0x06, + BLT_AUDIO_ASCS_OPCODE_CONFIG_UPDATE_METADATA = 0x07, + BLT_AUDIO_ASCS_OPCODE_CONFIG_RELEASE = 0x08, +}BLT_AUDIO_ASCS_OPCODE_ENUM; +typedef enum{ + BLT_AUDIO_ASCS_ERRCODE_NONE = 0x0000, + BLT_AUDIO_ASCS_ERRCODE_UNSUPPORTED_OPCODE = 0x0001, + BLT_AUDIO_ASCS_ERRCODE_TRUNCATED_OPERATION = 0x0002, + BLT_AUDIO_ASCS_ERRCODE_INVALID_ASE_ID = 0x0003, + BLT_AUDIO_ASCS_ERRCODE_INVALID_ASE_STATE = 0x0004, + BLT_AUDIO_ASCS_ERRCODE_UNSUPPORTED_CAPABILITY = 0x0005, // need ASCS_REASON_ENUM + BLT_AUDIO_ASCS_ERRCODE_UNSUPPORTED_CONFIG = 0x0006, // need ASCS_REASON_ENUM + BLT_AUDIO_ASCS_ERRCODE_REJECTED_CONFIG = 0x0007, // need ASCS_REASON_ENUM + BLT_AUDIO_ASCS_ERRCODE_INVALID_CONFIG = 0x0008, // need ASCS_REASON_ENUM + BLT_AUDIO_ASCS_ERRCODE_UNSUPPORTED_METADATA = 0x0009, // need Value of the Metadata Type field in error + BLT_AUDIO_ASCS_ERRCODE_REJECTED_METADATA = 0x000A, // need Value of the Metadata Type field in error + BLT_AUDIO_ASCS_ERRCODE_INVALID_METADATA = 0x000B, // need Value of the Metadata Type field in error + BLT_AUDIO_ASCS_ERRCODE_INSUFFICIENT_RESOURCE = 0x000C, + BLT_AUDIO_ASCS_ERRCODE_UNSPECIFIED_ERROR = 0x000D, +}BLT_AUDIO_ASCS_ERRCODE_ENUM; +typedef enum{ + BLT_AUDIO_ASCS_REASON_DIRECTION = 0x01, + BLT_AUDIO_ASCS_REASON_CODEC_ID = 0x02, + BLT_AUDIO_ASCS_REASON_CONFIG_LENGTH = 0x03, + BLT_AUDIO_ASCS_REASON_CONFIG = 0x04, + BLT_AUDIO_ASCS_REASON_SDU_INTERVAL = 0x05, + BLT_AUDIO_ASCS_REASON_FRAMING = 0x06, + BLT_AUDIO_ASCS_REASON_PHY = 0x07, + BLT_AUDIO_ASCS_REASON_SDU_SIZE = 0x08, + BLT_AUDIO_ASCS_REASON_RETRANS_NUMBER = 0x09, + BLT_AUDIO_ASCS_REASON_MAX_LATENCY = 0x0A, + BLT_AUDIO_ASCS_REASON_PRESENT_DELAY = 0x0B, + BLT_AUDIO_ASCS_REASON_METADATA_LENGTH = 0x0C, +}BLT_AUDIO_ASCS_REASON_ENUM; + + + + +typedef struct{ // 42Bytes + u8 direction; /*>8)) +#define BltAudioIsThisUUID2(uuid, value) BltAudioWord8ArrayIsEqual(uuid, value) + +#define BltAudioValueSplit2Array(Array, value) \ + (Array)[0] = (value) & 0xFF; \ + (Array)[1] = ((value) & 0xFF00) >> 8; +#define BltAudioValueSplit3Array(Array, value) \ + (Array)[0] = (value) & 0xFF; \ + (Array)[1] = ((value) & 0xFF00) >> 8; \ + (Array)[2] = ((value) & 0xFF0000) >> 16; +#define BltAudioValueSplit4Array(Array, value) \ + (Array)[0] = (value) & 0xFF; \ + (Array)[1] = ((value) & 0xFF00) >> 8; \ + (Array)[2] = ((value) & 0xFF0000) >> 16; \ + (Array)[3] = ((value) & 0xFF000000) >> 24; + +#define BltAudio2ArraySpellValue(value, Array) \ + (value) = (((u16)(Array)[1])<<8) | ((u16)(Array)[0]) +#define BltAudio3ArraySpellValue(value, Array) \ + (value) = (((u32)(Array)[2])<<16) | (((u32)(Array)[1])<<8) | ((u32)(Array)[0]) +#define BltAudio4ArraySpellValue(value, Array) \ + (value) = (((u32)(Array)[3])<<24) | (((u32)(Array)[2])<<16) | (((u32)(Array)[1])<<8) | ((u32)(Array)[0]) + + +#if BLC_AUDIO_DEBUG_ENABLE + #define CONSOLE_DBGID_FATA 0xD1 + #define CONSOLE_DBGID_ERROR 0xD2 + #define CONSOLE_DBGID_INFO 0xD3 + #define CONSOLE_DBGID_WARN 0xD4 + #define CONSOLE_DBGID_TRACE 0xD5 + + #define send_dbgmsg_fata(datalen, pData) blt_audio_sendDbgMsg(CONSOLE_DBGID_FATA, datalen, pData) + #define send_dbgmsg_error(datalen, pData) blt_audio_sendDbgMsg(CONSOLE_DBGID_ERROR, datalen, pData) + #define send_dbgmsg_info(datalen, pData) blt_audio_sendDbgMsg(CONSOLE_DBGID_INFO, datalen, pData) + #define send_dbgmsg_warn(datalen, pData) blt_audio_sendDbgMsg(CONSOLE_DBGID_WARN, datalen, pData) + #define send_dbgmsg_trace(datalen, pData) blt_audio_sendDbgMsg(CONSOLE_DBGID_TRACE, datalen, pData) + void blt_audio_sendDbgMsg(u8 dbgId, u8 datalen, u8 *pData); +#endif //BLC_AUDIO_DEBUG_ENABLE + + +typedef struct{ + u16 handle; + u8 uuidLen; + u8 dataLen; + u8 *pCCC; + u8 *pUuid; + u8 *pData; +}blt_audio_charParam_t; +typedef struct{ + u8 type; + u8 rf_len; + u16 l2capLen; + u16 chanId; + u8 opcode; + u8 handle[2]; + u8 value[1]; +}blt_audio_attNotify_t; +typedef struct{ + u8 type; + u8 rf_len; + u16 l2capLen; + u16 chanId; + u8 opcode; + u8 reqcode; + u8 handle[2]; + u8 errcode; +}blt_audio_attResp_t; +typedef struct{ + u8 type; + u8 rf_len; + u16 l2capLen; + u16 chanId; + u8 opcode; + u8 value[1]; +}blt_audio_attPkt_t; + +typedef struct{ + u8 type; + u8 rf_len; + u16 l2capLen; + u16 chanId; + u8 opcode; + u8 handle[2]; +}blt_audio_attReadReq_t; + +typedef struct{ + u8 type; + u8 rf_len; + u16 l2capLen; + u16 chanId; + u8 opcode; + u8 handle[2]; + u8 value[1]; +}blt_audio_attWriteReq_t; + + +static inline u8 blt_audio_getBitCount(u32 value) +{ + u8 count; + + count = 0; + while(value){ + count ++; + value &= (value-1); + } + + return count; +} + +u8 blt_audio_findNextChar(attribute_t *pServer, u8 *pOffset, blt_audio_charParam_t *pParam); +ble_sts_t blt_audio_pushHandleValue(u16 connHandle, u16 attHandle, u8 opcode, u8 *p, int len); +ble_sts_t blt_audio_pushReadRsp(u16 connHandle, u8 *p, int len); +ble_sts_t blt_audio_pushBlobReadRsp(u16 connHandle, u8 *p, int len); +ble_sts_t blt_audio_pushErrorRsp(u16 connHandle, u8 errOpcode, u16 errHandle, u8 errCode); +ble_sts_t blt_audio_pushWriteRsp(u16 connHandle); + +int blt_audio_sendEvent(blt_audio_handle_t *pHandle, u16 evtID, u16 dataLen, u8 *pData); + + +#endif //#if (BLC_AUDIO_PROFILE_EN) + +#endif //_AUDIO_COMMON_H_ + diff --git a/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_config.h b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_config.h new file mode 100755 index 0000000..89e5073 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_config.h @@ -0,0 +1,176 @@ +/******************************************************************************************************** + * @file audio_config.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef _AUDIO_CONFIG_H_ +#define _AUDIO_CONFIG_H_ + + +#define BLC_AUDIO_PROFILE_EN (1 && LE_AUDIO_ENABLE) + +#if (BLC_AUDIO_PROFILE_EN) + +#define BLC_AUDIO_DEBUG_ENABLE 1 + +#define BLC_AUDIO_SERVER_ENABLE 1 +#define BLC_AUDIO_CLIENT_ENABLE 1 + + +#define BLC_AUDIO_BSINK_ENABLE 1 +#define BLC_AUDIO_BSOURCE_ENABLE 1 +#define BLC_AUDIO_ASSISTANT_ENABLE 1 +#define BLC_AUDIO_DELEGATOR_ENABLE 1 + +//Assistant +//Delegator + +#if (!BLC_AUDIO_SERVER_ENABLE && !BLC_AUDIO_CLIENT_ENABLE) + #error "Server & Client must be supported one or more!" +#endif +#if BLC_AUDIO_SERVER_ENABLE + #define BLC_AUDIO_SERVER_COUNT 2 +#else + #define BLC_AUDIO_SERVER_COUNT 0 +#endif +#if BLC_AUDIO_SERVER_ENABLE + #define BLC_AUDIO_CLIENT_COUNT 2 +#else + #define BLC_AUDIO_CLIENT_COUNT 0 +#endif +#define BLC_AUDIO_HANDLE_COUNT (BLC_AUDIO_SERVER_COUNT+BLC_AUDIO_CLIENT_COUNT) + + +#define BLC_AUDIO_ROLE_SWICH_ENABLE 0 +#define BLC_AUDIO_MCP_TBP_RAAP_ROLE_SWICH_ENABLE 1 +#define BLC_AUDIO_OTP_ROLE_SWICH_ENABLE (1 && BLC_AUDIO_ROLE_SWICH_ENABLE) +#define BLC_AUDIO_MCP_ROLE_SWICH_ENABLE (1 && BLC_AUDIO_ROLE_SWICH_ENABLE) +#define BLC_AUDIO_TBP_ROLE_SWICH_ENABLE (1 && BLC_AUDIO_ROLE_SWICH_ENABLE) +#define BLC_AUDIO_RAAP_ROLE_SWICH_ENABLE (1 && BLC_AUDIO_ROLE_SWICH_ENABLE) +#define BLC_AUDIO_MCS_EXTEND_SUPPORT_ENABLE 1 +#define BLC_AUDIO_TBS_EXTEND_SUPPORT_ENABLE 1 +#define BLC_AUDIO_OTS_EXTEND_SUPPORT_ENABLE 1 + + +#define BLC_AUDIO_PACP_ENABLE 1 +#define BLC_AUDIO_ASCP_ENABLE 1 +#define BLC_AUDIO_BASP_ENABLE 0 +#define BLC_AUDIO_CSIP_ENABLE 1 +#define BLC_AUDIO_RAAP_ENABLE 1 +#define BLC_AUDIO_MICP_ENABLE 0 +#define BLC_AUDIO_VCP_ENABLE 1 +#define BLC_AUDIO_MCP_ENABLE 1 +#define BLC_AUDIO_TBP_ENABLE 1 +#define BLC_AUDIO_OTP_ENABLE (1 && BLC_AUDIO_MCP_ENABLE) + +#define BLC_AUDIO_AICS_ENABLE 1 +#define BLC_AUDIO_PACS_ENABLE (1 && BLC_AUDIO_PACP_ENABLE) +#define BLC_AUDIO_ASCS_ENABLE (1 && BLC_AUDIO_ASCP_ENABLE) +#define BLC_AUDIO_BASS_ENABLE (1 && BLC_AUDIO_BASP_ENABLE) +#define BLC_AUDIO_CSIS_ENABLE (1 && BLC_AUDIO_CSIP_ENABLE) +#define BLC_AUDIO_RAAS_ENABLE (1 && BLC_AUDIO_RAAP_ENABLE) +#define BLC_AUDIO_MICS_ENABLE (1 && BLC_AUDIO_MICP_ENABLE) +#define BLC_AUDIO_MICS_AICS_ENABLE (0 && (BLC_AUDIO_MICS_ENABLE && BLC_AUDIO_AICS_ENABLE)) +#define BLC_AUDIO_VCS_ENABLE (1 && BLC_AUDIO_VCP_ENABLE) +#define BLC_AUDIO_VCS_AICS_ENABLE (1 && (BLC_AUDIO_VCS_ENABLE && BLC_AUDIO_AICS_ENABLE)) +#define BLC_AUDIO_VOCS_ENABLE (1 && BLC_AUDIO_VCS_ENABLE) +#define BLC_AUDIO_MCS_ENABLE (1 && BLC_AUDIO_MCP_ENABLE) +#define BLC_AUDIO_TBS_ENABLE (1 && BLC_AUDIO_TBP_ENABLE) +#define BLC_AUDIO_OTS_ENABLE (1 && BLC_AUDIO_OTP_ENABLE) + + +#define BLC_AUDIO_CLIENT_SDP_ENABLE (1 && (BLC_AUDIO_CLIENT_ENABLE && (BLC_AUDIO_MCP_ENABLE || BLC_AUDIO_TBP_ENABLE || BLC_AUDIO_RAAP_ENABLE))) +#define BLC_AUDIO_SERVER_SDP_ENABLE (1 && BLC_AUDIO_SERVER_ENABLE) +#define BLC_AUDIO_EATT_ENABLE (0 && (BLC_AUDIO_CLIENT_SDP_ENABLE || BLC_AUDIO_SERVER_SDP_ENABLE)) +#define BLC_AUDIO_SDP_ENABLE (BLC_AUDIO_CLIENT_SDP_ENABLE || BLC_AUDIO_SERVER_SDP_ENABLE) + + + +#if (BLC_AUDIO_PACS_ENABLE == 0 && BLC_AUDIO_ASCS_ENABLE) + #error "You should enable PACS befor using ASCS!" +#endif + +#if (BLC_AUDIO_ASCS_ENABLE) + #define BLC_AUDIO_AES_COUNT 4 + #define BLC_AUDIO_ASE_PER_HANDLE 2 + #if (BLC_AUDIO_AES_COUNT == 0) + #error "Audio Ase Count should not be zero!" + #endif +#endif + +#if (BLC_AUDIO_AICS_ENABLE) + #if (BLC_AUDIO_MICS_AICS_ENABLE) + #define BLC_AUDIO_MICS_AICS_COUNT 1 + #endif + #if (BLC_AUDIO_VCS_AICS_ENABLE) + #define BLC_AUDIO_VCS_AICS_COUNT 1 + #endif + #define BLC_AUDIO_AICS_DESC_ENABLE 1 + #if (BLC_AUDIO_AICS_DESC_ENABLE) + #define BLC_AUDIO_AICS_DESC_SIZE 32 + #endif +#endif + +#if (BLC_AUDIO_VCP_ENABLE) + #define BLC_AUDIO_VCP_VOLUME_MAX 255 + #define BLC_AUDIO_VCP_VOLUME_STEP 10 +#endif +#if (BLC_AUDIO_VOCS_ENABLE) + #define BLC_AUDIO_VCS_VOCS_COUNT 2 + #define BLC_AUDIO_VOCS_DESC_ENABLE 1 + #if (BLC_AUDIO_VOCS_DESC_ENABLE) + #define BLC_AUDIO_VOCS_DESC_SIZE 32 + #endif +#endif + + + +#if (BLC_AUDIO_TBS_ENABLE) + #define BLC_AUDIO_TBS_CALL_COUNT 3 + #define BLC_AUDIO_TBS_URL_MAX_LEN 16 + #define BLC_AUDIO_TBS_NAME_MAX_LEN 16 +#endif + + +#if (BLC_AUDIO_ASCS_ENABLE) + #define BLC_AUDIO_CFG_INTERVAL_MIN 0x001D4C // 7.5ms // Range: 0x0000FF-0xFFFFF Units:us + #define BLC_AUDIO_CFG_INTERVAL_MAX 0x0186A0 // 100ms // Range: 0x0000FF-0xFFFFFF Units:us + #define BLC_AUDIO_CFG_INTERVAL_TYPE 0x003A98 // 15ms + #define BLC_AUDIO_CFG_FRAMING_SUPPORTED 0x03 // BIT(0)-Unframe, BIT(1)-frame + #define BLC_AUDIO_CFG_FRAMING_TYPE 0x00 // 0x00-Unframe, 0x01-frame ISOAL PDUs + #define BLC_AUDIO_CFG_PHY_SUPPORTED 0x03 // BIT(0)-1M, BIT(1)-2M, BIT(2)-Coded + #define BLC_AUDIO_CFG_PHY_TYPE 0x01 // BIT(0)-1M, BIT(1)-2M, BIT(2)-Coded + #define BLC_AUDIO_CFG_SDU_MAX 240 // Range: 0x0000-0x0FFF + //#define BLC_AUDIO_CFG_SDU_TYPE 240 // Range: 0x0000-0x0FFF + #define BLC_AUDIO_CFG_RETRANSMIT_NUM_MIN 0 + #define BLC_AUDIO_CFG_RETRANSMIT_NUM_MAX 15 + #define BLC_AUDIO_CFG_RETRANSMIT_NUM_TYPE 3 // Range: 0x00-0x0F + #define BLC_AUDIO_CFG_TRANSPORT_LATENCY_MAX 80 // Range: 0x0005-0x0FA0 Units:ms + //#define BLC_AUDIO_CFG_TRANSPORT_LATENCY_TYPE 40 + #define BLC_AUDIO_CFG_PRESENTATION_DELAY_MIN 0x002EE0 // 12ms // Range: 0x000000-0xFFFFFF, Units:us + #define BLC_AUDIO_CFG_PRESENTATION_DELAY_MAX 0x004E20 // 20ms // Range: 0x000000-0xFFFFFF, Units:us + #define BLC_AUDIO_CFG_PRESENTATION_DELAY_TYPE 0x003A98 // 15ms +#endif //BLC_AUDIO_ASCP_ENABLE + + + +#endif //BLC_AUDIO_PROFILE_EN + +#endif //_AUDIO_C ?I_' \ No newline at end of file diff --git a/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_csip.h b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_csip.h new file mode 100755 index 0000000..f49215e --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_csip.h @@ -0,0 +1,80 @@ +/******************************************************************************************************** + * @file audio_csip.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef _AUDIO_CSIP_H_ +#define _AUDIO_CSIP_H_ + +#if (BLC_AUDIO_CSIP_ENABLE) + +#define BLC_AUDIO_CSIP_LOCK_TIMEOUT_DEAFULT 60000000 // 60s + + +#define BLC_AUDIO_CSIP_LOCK 0x02 +#define BLC_AUDIO_CSIP_UNLOCK 0x01 + + +typedef enum{ + BLT_AUDIO_CSIP_FLAG_NONE = 0x00, + BLT_AUDIO_CSIP_FLAG_LOCK_TIMER = 0x02, + + BLT_AUDIO_CSIP_FLAG_NOTY_SIZE = 0x04, + BLT_AUDIO_CSIP_FLAG_NOTY_LOCK = 0x08, +}BLT_AUDIO_CSIP_FLAGS_ENUM; + +typedef enum{ + BLT_AUDIO_CSIP_ERRCODE_LOCK_DENIED = 0x80, //The lock cannot be granted because the server is already locked. + BLT_AUDIO_CSIP_ERRCODE_RELEASE_NOT_ACLLOWED = 0x81, + BLT_AUDIO_CSIP_ERRCODE_INVALID_LOCK_VALUE = 0x82, + BLT_AUDIO_CSIP_ERRCODE_OOB_SIRK_ONLY = 0x83, + BLT_AUDIO_CSIP_ERRCODE_LOCK_ALREADY_GRANTED = 0x84, //The client that made the request is the current owner of thelock. +}BLT_AUDIO_CSIP_ERRCODE_ENUM; + + +//readyEvt.size = pCsip->size; +// readyEvt.lock = pCsip->lock; +// readyEvt.rank = pCsip->rank; + +typedef enum{ + BLT_AUDIO_CSIP_SDP_FLAG_NONE = 0x00, + BLT_AUDIO_CSIP_SDP_FLAG_FIRST = 0x80, + BLT_AUDIO_CSIP_SDP_FLAG_SIRK = 0x01, + BLT_AUDIO_CSIP_SDP_FLAG_SIZE = 0x02, + BLT_AUDIO_CSIP_SDP_FLAG_RANK = 0x04, + BLT_AUDIO_CSIP_SDP_FLAG_LOCK = 0x08, +}BLT_AUDIO_CSIP_SDP_FLAGS_ENUM; + + +int blc_audio_csipAttRead(u16 connHandle, void* p); +int blc_audio_csipAttWrite(u16 connHandle, void* p); + +int blc_audio_csipSetLock(u16 connHandle, bool isLock); + +void blc_audio_csisSih(u8 sirk[16], u8 prand[3], u8 hash[3]); +void blc_audio_csisGeneratePsri(u8 sirk[16], u8 prand[3], u8 psri[6]); +bool blc_audio_csisPsriIsValid(u8 sirk[16], u8 psri[6]); + + + +#endif //#if (BLC_AUDIO_CSIP_ENABLE) + +#endif //_AUDIO_CSIP_H_ + diff --git a/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_define.h b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_define.h new file mode 100755 index 0000000..01bcfda --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_define.h @@ -0,0 +1,537 @@ +/******************************************************************************************************** + * @file audio_define.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef _AUDIO_DEFINE_H_ +#define _AUDIO_DEFINE_H_ + +#if (BLC_AUDIO_PROFILE_EN) + + +typedef enum{ + BLC_AUDIO_ROLE_CLIENT = 0x01, + BLC_AUDIO_ROLE_SERVER = 0x02, + + BLC_AUDIO_ROLE_BSINK = 0x06, + BLC_AUDIO_ROLE_BSOURCE = 0x07, + BLC_AUDIO_ROLE_ASSISTANT = 0x08, + BLC_AUDIO_ROLE_DELEGATOR = 0x09, +}BLC_AUDIO_ROLE_ENUM; + +typedef enum{ + BLC_AUDIO_STATE_DISCONN = 0x00, + BLC_AUDIO_STATE_CONNECT = 0x01, + BLC_AUDIO_STATE_RECONNECT = 0x02, +}BLC_AUDIO_STATE_ENUM; + +typedef enum{ + BLC_AUDIO_SUCCESS = 0x00, + BLC_AUDIO_EBUSY, + BLC_AUDIO_EFAIL, + BLC_AUDIO_EROLE, + BLC_AUDIO_EASEID, + BLC_AUDIO_EQUOTA, + BLC_AUDIO_EALIGN, + BLC_AUDIO_EPARAM, + BLC_AUDIO_EHANDLE, + BLC_AUDIO_EREPEAT, + BLC_AUDIO_ESTATUS, + BLC_AUDIO_ELENGTH, + BLC_AUDIO_ENOSUPP, //not supperted + BLC_AUDIO_ENOREADY, + BLC_AUDIO_ENOOBJECT, +}BLC_AUDIO_ERROR_ENUM; + + +typedef enum{ + BLC_AUDIO_SERVICE_PACS = 0, + BLC_AUDIO_SERVICE_ASCS, + BLC_AUDIO_SERVICE_CSIS, + BLC_AUDIO_SERVICE_RAAS, + BLC_AUDIO_SERVICE_MICS, + BLC_AUDIO_SERVICE_VCS, + BLC_AUDIO_SERVICE_MCS, + BLC_AUDIO_SERVICE_TBS, + BLC_AUDIO_SERVICE_OTS, + BLC_AUDIO_SERVICE_UNICAST_MAX, + + BLC_AUDIO_SERVICE_BASS = BLC_AUDIO_SERVICE_UNICAST_MAX, + BLC_AUDIO_SERVICE_MAX, +}BLC_AUDIO_SERVICE_ENUM; + +typedef enum{ + BLC_AUDIO_EVTID_NONE, + + //SDP + BLC_AUDIO_EVTID_SDP_OVER, + + ///ASCS Event + BLC_AUDIO_EVTID_ASE_ENABLE, + BLC_AUDIO_EVTID_ASE_UPDATE, + BLC_AUDIO_EVTID_ASE_DISABLE, + BLC_AUDIO_EVTID_ASE_RELEASE, + BLC_AUDIO_EVTID_RECV_START, //For Server and Client + BLC_AUDIO_EVTID_RECV_STOP, //For Server and Client + + //CSIS Event + BLC_AUDIO_EVTID_CSIS_READY, + + ///MICP Event + BLC_AUDIOC_EVTID_MICS_READY, //For Audio Client + BLC_AUDIO_EVTID_MICS_MUTE, //For Server and Client + BLC_AUDIO_EVTID_MICS_AICS_STATE, //For Server and Client + BLC_AUDIO_EVTID_MICS_AICS_STATUS, //For Server and Client + + ///VCS Event + BLC_AUDIOC_EVTID_VCS_READY, //For Audio Client + BLC_AUDIO_EVTID_VCS_STATE, //For Server and Client + BLC_AUDIO_EVTID_VCS_FLAG, //For Server and Client + BLC_AUDIO_EVTID_VCS_AICS_STATE, //For Server and Client + BLC_AUDIO_EVTID_VCS_VOCS_STATE, //For Server and Client + BLC_AUDIO_EVTID_VCS_AICS_STATUS, //For Server and Client + BLC_AUDIO_EVTID_VCS_VOCS_LOCATION, //For Server and Client + BLC_AUDIO_EVTID_VCS_VOCS_DESCRIBLE, //For Server and Client + BLC_AUDIO_EVTID_VCS_AICS_DESCRIBLE, //For Server and Client + + ///MCP Event + BLC_AUDIOS_EVTID_MCS_READY, //For server + BLC_AUDIOS_EVTID_MCS_STATE, //For Server + BLC_AUDIOS_EVTID_MCS_NOTY, //For Server + BLC_AUDIOC_EVTID_MCP_CTRL, //For Client + + ///PACP Event + BLC_AUDIOC_EVTID_PACS_READY, //For Audio Client + + ///ASCP Event + BLC_AUDIOC_EVTID_ASCS_READY, //For Audio Client + + //TBS Event + BLC_AUDIOS_EVTID_TBS_READY, + BLC_AUDIOS_EVTID_TBS_CALL_STATE, + + //OTS Event + BLC_AUDIOS_EVTID_OTS_READY, + + +}BLC_AUDIO_EVTID_ENUM; + + + + +// TODO: TBD +// PACS Service & Characteristic +#define SERVICE_UUID_PUBLISHED_AUDIO_CAPABILITIES 0x2310 //PACS +#define CHARACTERISTIC_UUID_PACS_SINK_PAC 0x2311 //Mandatory:Read; Optional:Notify +#define CHARACTERISTIC_UUID_PACS_SINK_AUDIO_LOCATION 0x2312 //Mandatory:Read; Optional:Notify,Write +#define CHARACTERISTIC_UUID_PACS_SOURCE_PAC 0x2313 //Mandatory:Read; Optional:Notify +#define CHARACTERISTIC_UUID_PACS_SOURCE_AUDIO_LOCATION 0x2314 //Mandatory:Read; Optional:Notify,Write +#define CHARACTERISTIC_UUID_PACS_AVAILABLE_AUDIO_CONTEXT 0x2315 //Mandatory:Read,Notify; Optional: +#define CHARACTERISTIC_UUID_PACS_SUPPORTED_AUDIO_CONTEXT 0x2316 //Mandatory:Read; Optional:Notify +// ASCS Service & Characteristic +#define SERVICE_UUID_AUDIO_STREAM_CONTROL 0x2320 +#define CHARACTERISTIC_UUID_ASCS_ASE 0x2321 //Read, Notify +#define CHARACTERISTIC_UUID_ASCS_ASE_CONTROL_PPOINT 0x2322 //WriteWithoutResponse, Notify +// BACS Service & Characteristic +#define SERVICE_UUID_BROADCAST_AUDIO_SCAN 0x2330 //PACS +// CSIS Service & Characteristic -- ok +#define SERVICE_UUID_COPRDINATED_SET_IDENTIFICATION 0x1846 +#define CHARACTERISTIC_UUID_CSIS_SIRK 0x2B84 //M Mandatory:Read; Optional:Notify +#define CHARACTERISTIC_UUID_CSIS_SIZE 0x2B85 //O Mandatory:Read; Optional:Notify +#define CHARACTERISTIC_UUID_CSIS_LOCK 0x2B86 //O Mandatory:Read,Write,Notify; Optional: +#define CHARACTERISTIC_UUID_CSIS_RANK 0x2B87 //O Mandatory:Read; Optional: +// RAAS Service & Characteristic +#define SERVICE_UUID_ROUTING_ACTIVE_AUDIO 0x2350 +#define CHARACTERISTIC_UUID_RAAS_SELECTABLE_ARE 0x2351 // Selectable Audio Route Endpoint List +#define CHARACTERISTIC_UUID_RAAS_CONFIGURED_ARE 0x2352 // Configured Audio Routes List +#define CHARACTERISTIC_UUID_RAAS_CONFIGURED_CONTENT 0x2353 // Configured Audio Routes Content Type List +#define CHARACTERISTIC_UUID_RAAS_MODIFY_ARC 0x2354 // Modify Audio Routing Control Point + +// AICS Service & Characteristic -- ok +#define SERVICE_UUID_AUDIO_INPUT_CONTROL 0x1843 //O +#define CHARACTERISTIC_UUID_AICS_INPUT_STATE 0x2B77 //M Mandatory:Read,Notify; Optional: +#define CHARACTERISTIC_UUID_AICS_GAIN_SETTING 0x2B78 //M Mandatory:Read; Optional: +#define CHARACTERISTIC_UUID_AICS_INPUT_TYPE 0x2B79 //M Mandatory:Read; Optional: +#define CHARACTERISTIC_UUID_AICS_INPUT_STATUS 0x2B7A //M Mandatory:Read,Notify; Optional: +#define CHARACTERISTIC_UUID_AICS_INPUT_CONTROL 0x2B7B //M Mandatory:Write; Optional: +#define CHARACTERISTIC_UUID_AICS_INPUT_DESCRIP 0x2B7C //M Mandatory:Read; Optional:Write Without Response, Notify + +// MICS Service & Characteristic -- ok +#define SERVICE_UUID_MICROPHONE_CONTROL 0x184D +#define CHARACTERISTIC_UUID_MICS_MUTE 0x2BC3 //M Mandatory:Read,Write,Notify; Optional: + +// VCS Service & Characteristic -- ok +#define SERVICE_UUID_VOLUME_CONTROL 0x1844 +#define CHARACTERISTIC_UUID_VCS_STATE 0x2B7D //Mandatory:Read,Notify; Optional: +#define CHARACTERISTIC_UUID_VCS_CONTROL_POINT 0x2B7E //Mandatory:Write; Optional: +#define CHARACTERISTIC_UUID_VCS_FLAGS 0x2B7F //Mandatory:Read,Notify; Optional: +// VOCS Service & Characteristic -- ok +#define SERVICE_UUID_VOLUME_OFFSET_CONTROL 0x1845 +#define CHARACTERISTIC_UUID_VOCS_STATE 0x2B80 +#define CHARACTERISTIC_UUID_VOCS_LOCATION 0x2B81 +#define CHARACTERISTIC_UUID_VOCS_CONTROL 0x2B82 +#define CHARACTERISTIC_UUID_VOCS_DESCRIPT 0x2B83 + +// MCS Service & Characteristic -- ok +#define SERVICE_UUID_MEDIA_CONTROL 0x1848 // Media Control Service +#define SERVICE_UUID_GENERIC_MEDIA_CONTROL 0x1849 // Generic Media Control Service +#define CHARACTERISTIC_UUID_MCS_PLAYER_NAME 0x2B93 // Media Player Name +#define CHARACTERISTIC_UUID_MCS_ICON_OBJECT_ID 0x2B94 // Media Player Icon Object ID +#define CHARACTERISTIC_UUID_MCS_ICON_URL 0x2B95 // Media Player Icon URL +#define CHARACTERISTIC_UUID_MCS_TRACK_CHANGED 0x2B96 // Track Changed +#define CHARACTERISTIC_UUID_MCS_TRACK_TITLE 0x2B97 // Track Title +#define CHARACTERISTIC_UUID_MCS_TRACK_DURATION 0x2B98 // Track Duration +#define CHARACTERISTIC_UUID_MCS_TRACK_POSITION 0x2B99 // Track Position +#define CHARACTERISTIC_UUID_MCS_PLAYBACK_SPEED 0x2B9A // Playback Speed +#define CHARACTERISTIC_UUID_MCS_SEEKING_SPEED 0x2B9B // Seeking Speed +#define CHARACTERISTIC_UUID_MCS_SEGMENTS_OBJECT_ID 0x2B9C // Current Track Segments Object ID +#define CHARACTERISTIC_UUID_MCS_CURRENT_OBJECT_ID 0x2B9D // Current Track Object ID +#define CHARACTERISTIC_UUID_MCS_NEXT_OBJECT_ID 0x2B9E // Next Track Object ID +#define CHARACTERISTIC_UUID_MCS_PARENT_GOUP_OBJECT_ID 0x2B9F // Parent Group Object ID +#define CHARACTERISTIC_UUID_MCS_CURRENT_GOUP_OBJECT_ID 0x2BA0 // Current Group Object ID +#define CHARACTERISTIC_UUID_MCS_PLAYING_ORDER 0x2BA1 // Playing Order +#define CHARACTERISTIC_UUID_MCS_PLAYING_ORDER_SUPPEORTED 0x2BA2 // Playing Order Supported +#define CHARACTERISTIC_UUID_MCS_MEDIA_STATE 0x2BA3 // Media State +#define CHARACTERISTIC_UUID_MCS_MEDIA_CONTROL_POINT 0x2BA4 // Media Control Point +#define CHARACTERISTIC_UUID_MCS_OPCODES_SUPPORTED 0x2BA5 // Media Control Point Opcodes Supported +#define CHARACTERISTIC_UUID_MCS_SEARCH_RESULTS_OBJECT_ID 0x2BA6 // Search Results Object ID +#define CHARACTERISTIC_UUID_MCS_SEARCH_CONTROL_POINT 0x2BA7 // Search Control Point +#define CHARACTERISTIC_UUID_MCS_CONTENT_CONTROL_ID 0x2BBA // Content Control ID (CCID) +// CCS Service & Characteristic +#define SERVICE_UUID_CALL_CONTROL 0x2430 + + +// TBS Service & Characteristic -- ok +#define SERVICE_UUID_TELEPHONE_BEARER 0x184B //Telephone Bearer Service +#define SERVICE_UUID_GENERIC_TELEPHONE_BEARER 0x184C //Generic Telephone Bearer Service +#define CHARACTERISTIC_UUID_TBS_PROVIDER_NAME 0x2BB3 //M Mandatory:Read, Notify; Optional: +#define CHARACTERISTIC_UUID_TBS_CALLER_IDENTIFIER 0x2BB4 //M Mandatory:Read; Optional: +#define CHARACTERISTIC_UUID_TBS_TECHNOLOGY 0x2BB5 //M Mandatory:Read, Notify; Optional: +#define CHARACTERISTIC_UUID_TBS_URI_LIST 0x2BB6 //M Mandatory:Read; Optional:Notify +#define CHARACTERISTIC_UUID_TBS_SIGNAL_STRENGTH 0x2BB7 //O Mandatory:Read, Notify; Optional: +#define CHARACTERISTIC_UUID_TBS_SIGNAL_REPORT_INTERVAL 0x2BB8 //O Mandatory:Read, Write, Write Without Response; Optional: +#define CHARACTERISTIC_UUID_TBS_CURRENT_CALL_LIST 0x2BB9 //M Mandatory:Read, Notify; Optional: +#define CHARACTERISTIC_UUID_TBS_CCID 0x2BBA //M Mandatory:Read; Optional: +#define CHARACTERISTIC_UUID_TBS_STATUS_FLAGS 0x2BBB //M Mandatory:Read, Notify; Optional: +#define CHARACTERISTIC_UUID_TBS_INCOMING_CALL_URI 0x2BBC //O Mandatory:Read, Notify; Optional: +#define CHARACTERISTIC_UUID_TBS_CALL_STATE 0x2BBD //M Mandatory:Read, Notify; Optional: +#define CHARACTERISTIC_UUID_TBS_CALL_CONTROL_POINT 0x2BBE //M Mandatory:Write, Write Without Response, Notify; Optional: +#define CHARACTERISTIC_UUID_TBS_CCP_OPTIONAL_OPCODES 0x2BBF //M Mandatory:Read; Optional: +#define CHARACTERISTIC_UUID_TBS_TERMINATIONO_REASON 0x2BC0 //M Mandatory:Notify; Optional: +#define CHARACTERISTIC_UUID_TBS_INCOMING_CALL 0x2BC1 //M Mandatory:Read, Notify; Optional: +#define CHARACTERISTIC_UUID_TBS_CALL_FREIENDLY_NAME 0x2BC2 //O Mandatory:Read, Notify; Optional: + +// OTS Service & Characteristic -- ok +#define SERVICE_UUID_OBJECT_TRANSFER 0x1825 //Object Transfer Service +#define CHARACTERISTIC_UUID_OTS_FEATURE 0x2ABD //M Mandatory:Read; Optional: +#define CHARACTERISTIC_UUID_OTS_OBJECT_NAME 0x2ABE //M Mandatory:Read; Optional:Write +#define CHARACTERISTIC_UUID_OTS_OBJECT_TYPE 0x2ABF //M Mandatory:Read; Optional: +#define CHARACTERISTIC_UUID_OTS_OBJECT_SIZE 0x2AC0 //M Mandatory:Read; Optional: +#define CHARACTERISTIC_UUID_OTS_OBJECT_FIRST_CREATED 0x2AC1 //O Mandatory:Read; Optional:Write +#define CHARACTERISTIC_UUID_OTS_OBJECT_LAST_CREATED 0x2AC2 //O Mandatory:Read; Optional:Write +#define CHARACTERISTIC_UUID_OTS_OBJECT_ID 0x2AC3 //O Mandatory:Read; Optional: +#define CHARACTERISTIC_UUID_OTS_OBJECT_PROPERTIES 0x2AC4 //M Mandatory:Read; Optional:Write +#define CHARACTERISTIC_UUID_OTS_OBJECT_ACTION_CONTROL_POINT 0x2AC5 //M Mandatory:Write,Indicate; Optional: +#define CHARACTERISTIC_UUID_OTS_OBJECT_LIST_CONTROL_POINT 0x2AC6 //O Mandatory:Write,Indicate; Optional: +#define CHARACTERISTIC_UUID_OTS_OBJECT_LIST_FILTER 0x2AC7 //O Mandatory:Read,Write; Optional: +#define CHARACTERISTIC_UUID_OTS_OBJECT_CHANGED 0x2AC8 //O Mandatory:Indicate; Optional: + + +///BAP +//////////////////////////////////////////////////////////////////// + +// Context Type +#define BLC_AUDIO_CONTEXT_TYPE_UNSPECIFIED BIT(0) // Unspecified. Matches any audio content. +#define BLC_AUDIO_CONTEXT_TYPE_CONVERSATIONAL BIT(1) // Conversation between humans as, for example, in telephony or video calls. +#define BLC_AUDIO_CONTEXT_TYPE_MEDIA BIT(2) // Media as, for example, in music, public radio, podcast or video soundtrack. +#define BLC_AUDIO_CONTEXT_TYPE_INSTRUCTIONAL BIT(3) // Instructional audio as, for example, in navigation, traffic announcements or user guidance +#define BLC_AUDIO_CONTEXT_TYPE_ATTENTION_SEEKING BIT(4) // Attention seeking audio as, for example, in beeps signalling arrival of a message or keyboard clicks. +#define BLC_AUDIO_CONTEXT_TYPE_IMMEDIATE_ALERT BIT(5) // Immediate alerts as, for example, in a low battery alarm, timer expiry or alarm clock. +#define BLC_AUDIO_CONTEXT_TYPE_MAN_MACHINE BIT(6) // Man machine communication as, for example, with voice recognition or virtual assistant. +#define BLC_AUDIO_CONTEXT_TYPE_EMERGENCY_ALERT BIT(7) // Emergency alerts as, for example, with fire alarms or other urgent alerts. +#define BLC_AUDIO_CONTEXT_TYPE_RINGTONE BIT(8) // Ringtone as in a call alert. +#define BLC_AUDIO_CONTEXT_TYPE_TV BIT(9) // Audio associated with a television program and/or with metadata conforming to the Bluetooth Broadcast TV profile. + +// Codec ID +#define BLC_AUDIO_CODECID_LC3 0x00000001 + +// Audio Codec_Specific_Capabilties parameters +#define BLC_AUDIO_CAPTYPE_SUP_SAMPLE_FREQUENCY 0x01 // Supported_Sampling_Frequencies +#define BLC_AUDIO_CAPTYPE_SUP_FRAME_DURATION 0x02 // Supported_Frame_Durations +#define BLC_AUDIO_CAPTYPE_SUP_CHANNELS_COUNTS 0x03 // Audio_Channel_Counts +#define BLC_AUDIO_CAPTYPE_SUP_FRAME_OCTETS 0x04 // Supported_Octets_Per_Codec_Frame + + +// Audio Codec_Specific_Configuration parameters +#define BLC_AUDIO_CAPTYPE_CFG_SAMPLE_FREQUENCY 0x01 // Sampling_Freqeuncy +#define BLC_AUDIO_CAPTYPE_CFG_FRAME_DURATION 0x02 // +#define BLC_AUDIO_CAPTYPE_CFG_CHANNELS_ALLOCATION 0x03 // Audio_Channel_Allocation +#define BLC_AUDIO_CAPTYPE_CFG_FRAME_OCTETS 0x04 // + +// Audio Meta Type +#define BLC_AUDIO_METATYPE_PREFERRED_CONTEXTS 0x01 // Preferred_Audio_Contexts +#define BLC_AUDIO_METATYPE_STREAMING_CONTEXTS 0x02 // Streaming_Audio_Contexts + +// Audio Direction +#define BLC_AUDIO_DIRECTION_SINK 0x01 //Server is Audio Sink +#define BLC_AUDIO_DIRECTION_SOURCE 0x02 //Server is Audio Source + +// Audio Support Location (bitfield, for PACS or ASCS) +#define BLC_AUDIO_LOCATION_FLAG_FL BIT(0) // Front Left +#define BLC_AUDIO_LOCATION_FLAG_FR BIT(1) // Front Right +#define BLC_AUDIO_LOCATION_FLAG_FC BIT(2) // Front Center +#define BLC_AUDIO_LOCATION_FLAG_LFE1 BIT(3) // Low Frequency Effects 1 +#define BLC_AUDIO_LOCATION_FLAG_BL BIT(4) // Back Left +#define BLC_AUDIO_LOCATION_FLAG_BR BIT(5) // Back Right +#define BLC_AUDIO_LOCATION_FLAG_FLc BIT(6) // Front Left of Center +#define BLC_AUDIO_LOCATION_FLAG_FRc BIT(7) // Front Right of Center +#define BLC_AUDIO_LOCATION_FLAG_BC BIT(8) // Back Center +#define BLC_AUDIO_LOCATION_FLAG_LFE2 BIT(9) // Low Frequency Effects 2 +#define BLC_AUDIO_LOCATION_FLAG_SiL BIT(10) // Side Left +#define BLC_AUDIO_LOCATION_FLAG_SiR BIT(11) // Side Right +#define BLC_AUDIO_LOCATION_FLAG_TpFL BIT(12) // Top Front Left +#define BLC_AUDIO_LOCATION_FLAG_TpFR BIT(13) // Top Front Right +#define BLC_AUDIO_LOCATION_FLAG_TpFC BIT(14) // Top Front Center +#define BLC_AUDIO_LOCATION_FLAG_TpC BIT(15) // Top Center +#define BLC_AUDIO_LOCATION_FLAG_TpBL BIT(16) // Top Back Left +#define BLC_AUDIO_LOCATION_FLAG_TpBR BIT(17) // Top Back Right +#define BLC_AUDIO_LOCATION_FLAG_TpSiL BIT(18) // Top Side Left +#define BLC_AUDIO_LOCATION_FLAG_TpSiR BIT(19) // Top Side Right +#define BLC_AUDIO_LOCATION_FLAG_TpBC BIT(20) // Top Back Center +#define BLC_AUDIO_LOCATION_FLAG_BtFC BIT(21) // Bottom Front Center +#define BLC_AUDIO_LOCATION_FLAG_BtFL BIT(22) // Bottom Front Left +#define BLC_AUDIO_LOCATION_FLAG_BtFR BIT(23) // Bottom Front Right +#define BLC_AUDIO_LOCATION_FLAG_FLw BIT(24) // Front Left Wide +#define BLC_AUDIO_LOCATION_FLAG_FRw BIT(25) // Front Right Wide +#define BLC_AUDIO_LOCATION_FLAG_LS BIT(26) // Left Surround +#define BLC_AUDIO_LOCATION_FLAG_RS BIT(27) // Right Surround + +// Audio Support Frame Frequency (bitfield, for PACS) +#define BLC_AUDIO_FREQUENCY_FLAG_8000 BIT(0) // 8000 Hz +#define BLC_AUDIO_FREQUENCY_FLAG_16000 BIT(1) // 16000 Hz +#define BLC_AUDIO_FREQUENCY_FLAG_24000 BIT(2) // 24000 Hz +#define BLC_AUDIO_FREQUENCY_FLAG_32000 BIT(3) // 32000 Hz +#define BLC_AUDIO_FREQUENCY_FLAG_44100 BIT(4) // 44100 Hz +#define BLC_AUDIO_FREQUENCY_FLAG_48000 BIT(5) // 48000 Hz +// Audio Frame Frequency (numbric, for ASCS) +#define BLC_AUDIO_FREQUENCY_CFG_8000 1 // 8000 Hz +#define BLC_AUDIO_FREQUENCY_CFG_16000 2 // 16000 Hz +#define BLC_AUDIO_FREQUENCY_CFG_24000 3 // 24000 Hz +#define BLC_AUDIO_FREQUENCY_CFG_32000 4 // 32000 Hz +#define BLC_AUDIO_FREQUENCY_CFG_44100 5 // 44100 Hz +#define BLC_AUDIO_FREQUENCY_CFG_48000 6 // 48000 Hz + +// Audio Support Frame Duration (bitfield, for PACS) +#define BLC_AUDIO_DURATION_FLAG_7_5 BIT(0) // +#define BLC_AUDIO_DURATION_FLAG_10 BIT(1) +#define BLC_AUDIO_DURATION_FLAG_7_5_PERFERRED BIT(4) +#define BLC_AUDIO_DURATION_FLAG_10_PERFERRED BIT(5) +// Audio Frame Duration (numbric, for ASCS) +#define BLC_AUDIO_DURATION_CFG_7_5 0 // +#define BLC_AUDIO_DURATION_CFG_10 1 + + +// Audio Channel +#define BLC_AUDIO_CHANNEL_COUNTS_1 BIT(0) +#define BLC_AUDIO_CHANNEL_COUNTS_2 BIT(1) +#define BLC_AUDIO_CHANNEL_COUNTS_3 BIT(2) +#define BLC_AUDIO_CHANNEL_COUNTS_4 BIT(3) +#define BLC_AUDIO_CHANNEL_COUNTS_5 BIT(4) +#define BLC_AUDIO_CHANNEL_COUNTS_6 BIT(5) +#define BLC_AUDIO_CHANNEL_COUNTS_7 BIT(6) +#define BLC_AUDIO_CHANNEL_COUNTS_8 BIT(7) + +// Audio PHY (bitfield, for ASCS) +#define BLC_AUDIO_PHY_FLAG_1M BIT(0) //LE 1M PHY preferred +#define BLC_AUDIO_PHY_FLAG_2M BIT(1) //LE 2M PHY preferred +#define BLC_AUDIO_PHY_FLAG_CODED BIT(2) //LE Coded PHY preferred + +// Audio Framing (bitfield, for ASCS) +#define BLC_AUDIO_FRAMING_UNFRAMED 0x00 //Unframed ISOAL PDUs preferred +#define BLC_AUDIO_FRAMING_FRAMED 0x01 //framed ISOAL PDUs preferred + + +// The Value Of Mute field +#define BLC_AUDIO_MUTE_NOT_MUTED 0x00 +#define BLC_AUDIO_MUTE_MUTED 0x01 +#define BLC_AUDIO_MUTE_DISABLED 0x02 + +// Gain Mode field +#define BLC_AUDIO_GAIN_MODE_MANUAL_ONLY 0x00 +#define BLC_AUDIO_GAIN_MODE_AUTOMATIC_ONLY 0x01 +#define BLC_AUDIO_GAIN_MODE_MANUAL 0x02 +#define BLC_AUDIO_GAIN_MODE_AUTOMATIC 0x03 + +// AICS Input State +#define BLC_AUDIO_INPUT_STATE_INACTIVE 0x00 +#define BLC_AUDIO_INPUT_STATE_ACTIVE 0x01 + +// TODO: Input Type TBD +// AICS Input Type +#define BLC_AUDIO_INPUT_TYPE_LOCAL 0x01 +#define BLC_AUDIO_INPUT_TYPE_ISOCHRONOUS_STREAM 0x02 +#define BLC_AUDIO_INPUT_TYPE_ANALOG_CONNECTOR 0x03 +#define BLC_AUDIO_INPUT_TYPE_DIGITAL_CONNECTOR 0x04 + + +// ASCS +#define BLC_AUDIO_CLOCK_ACCURACY_251_500PPM 0x00 +#define BLC_AUDIO_CLOCK_ACCURACY_151_250PPM 0x01 +#define BLC_AUDIO_CLOCK_ACCURACY_101_150PPM 0x02 +#define BLC_AUDIO_CLOCK_ACCURACY_76_100PPM 0x03 +#define BLC_AUDIO_CLOCK_ACCURACY_51_75PPM 0x04 +#define BLC_AUDIO_CLOCK_ACCURACY_31_50PPM 0x05 +#define BLC_AUDIO_CLOCK_ACCURACY_21_30PPM 0x06 +#define BLC_AUDIO_CLOCK_ACCURACY_0_20PPM 0x07 +#define BLC_AUDIO_CLOCK_ACCURACY_DEFAULT BLC_AUDIO_CLOCK_ACCURACY_76_100PPM +// ASCS +#define BLC_AUDIO_PACKING_SEQUENTIAL 0x00 +#define BLC_AUDIO_PACKING_INTERLEAVED 0x01 +#define BLC_AUDIO_PACKING_DEFAULT BLC_AUDIO_PACKING_SEQUENTIAL + + + +// MCP Media State +typedef enum{ + BLC_AUDIO_MCP_MEDIA_STATE_INACTIVE = 0x00, + BLC_AUDIO_MCP_MEDIA_STATE_PLAYING = 0x01, + BLC_AUDIO_MCP_MEDIA_STATE_PAUSED = 0x02, + BLC_AUDIO_MCP_MEDIA_STATE_SEEKING = 0x03, +}BLC_AUDIO_MCP_MEDIA_STATE_ENUM; +// MCP Supported Opcode +typedef enum{ + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_PLAY = 0x00000001, + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_PAUSE = 0x00000002, + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_FAST_REWIND = 0x00000004, + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_FAST_FORWARD = 0x00000008, + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_STOP = 0x00000010, + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_MOVE_RELATIVE = 0x00000020, + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_PREVIOUS_SEGMENT = 0x00000040, + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_NEXT_SEGMENT = 0x00000080, + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_FIRST_SEGMENT = 0x00000100, + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_LAST_SEGMENT = 0x00000200, + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_GOTO_SEGMENT = 0x00000400, + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_PREVIOUS_TRACK = 0x00000800, + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_NEXT_TRACK = 0x00001000, + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_FIRST_TRACK = 0x00002000, + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_LAST_TRACK = 0x00004000, + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_GOTO_TRACK = 0x00008000, + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_PRIVOUS_GROUP = 0x00010000, + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_NEXT_GROUP = 0x00020000, + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_FIRST_FROUP = 0x00040000, + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_LAST_GROUP = 0x00080000, + BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_GOTO_GROUP = 0x00100000, +}BLC_AUDIO_MCP_CP_SUPPORTED_OPCODE_ENUM; +// MCP Opcode for Control Point +typedef enum{ + BLC_AUDIO_MCP_OPCODE_NONE = 0x00, + BLC_AUDIO_MCP_OPCODE_PLAY = 0x01, + BLC_AUDIO_MCP_OPCODE_PAUSE = 0x02, + BLC_AUDIO_MCP_OPCODE_FAST_REWIND = 0x03, + BLC_AUDIO_MCP_OPCODE_FAST_FORWARD = 0x04, + BLC_AUDIO_MCP_OPCODE_STOP = 0x05, + BLC_AUDIO_MCP_OPCODE_MOVE_RELATIVE = 0x10, + BLC_AUDIO_MCP_OPCODE_PREVIOUS_SEGMENT = 0x20, + BLC_AUDIO_MCP_OPCODE_NEXT_SEGMENT = 0x21, + BLC_AUDIO_MCP_OPCODE_FIRST_SEGMENT = 0x22, + BLC_AUDIO_MCP_OPCODE_LAST_SEGMENT = 0x23, + BLC_AUDIO_MCP_OPCODE_GOTO_SEGMENT = 0x24, + BLC_AUDIO_MCP_OPCODE_PREVIOUS_TRACK = 0x30, + BLC_AUDIO_MCP_OPCODE_NEXT_TRACK = 0x31, + BLC_AUDIO_MCP_OPCODE_FIRST_TRACK = 0x32, + BLC_AUDIO_MCP_OPCODE_LAST_TRACK = 0x33, + BLC_AUDIO_MCP_OPCODE_GOTO_TRACK = 0x34, + BLC_AUDIO_MCP_OPCODE_PREVIOUS_GROUP = 0x40, + BLC_AUDIO_MCP_OPCODE_NEXT_GROUP = 0x41, + BLC_AUDIO_MCP_OPCODE_FIRST_GROUP = 0x42, + BLC_AUDIO_MCP_OPCODE_LAST_GROUP = 0x43, + BLC_AUDIO_MCP_OPCODE_GOTO_GROUP = 0x44, +}BLC_AUDIO_MCP_OPCODE_ENUM; + + + +// TBS Opcode for Control Point +typedef enum{ + BLC_AUDIO_TBP_OPCODE_ACCEPT = 0x00, + BLC_AUDIO_TBP_OPCODE_TERMINATE = 0x01, + BLC_AUDIO_TBP_OPCODE_LOCAL_HOLD = 0x02, + BLC_AUDIO_TBP_OPCODE_LOCAL_RETRIEVE = 0x03, + BLC_AUDIO_TBP_OPCODE_ORIGINATE = 0x04, + BLC_AUDIO_TBP_OPCODE_JOIN = 0x05, +}BLC_AUDIO_TBP_OPCODE_ENUM; +// TBS Call State +typedef enum{ + BLC_AUDIO_TBP_CALL_STATE_INCOMING = 0x00, + BLC_AUDIO_TBP_CALL_STATE_DIALING = 0x01, + BLC_AUDIO_TBP_CALL_STATE_ALERTING = 0x02, + BLC_AUDIO_TBP_CALL_STATE_ACTIVE = 0x03, + BLC_AUDIO_TBP_CALL_STATE_LOCAL_HELD = 0x04, + BLC_AUDIO_TBP_CALL_STATE_REMOTE_HELD = 0x05, + BLC_AUDIO_TBP_CALL_STATE_LOCAL_REMOTE_HELD = 0x06, +}BLC_AUDIO_TBP_CALL_STATE_ENUM; +// TBS Call Flags +typedef enum{ + BLC_AUDIO_TBP_CALL_FLAG_OUTCOMING = BIT(0), //Incoming/Outgoing: 0=Call is an incoming call; 1=Call is an outgoing call + BLC_AUDIO_TBP_CALL_FLAG_INCOMING = 0x00, + BLC_AUDIO_TBP_CALL_FLAG_WITHHELD_BY_SERVER = BIT(1), //Information withheld by server: 0=Not withheld; 1=Withheld + BLC_AUDIO_TBP_CALL_FLAG_NOT_WITHHELD_BY_SERVER = 0x00, + BLC_AUDIO_TBP_CALL_FLAG_WITHHELD_BY_NETWORK = BIT(2), //Information withheld by network: 0 = Provided by network; 1 = Withheld by network + BLC_AUDIO_TBP_CALL_FLAG_PROVIDED_BY_NETWORK = 0x00, +}BLC_AUDIO_TBP_CALL_FLAGS_ENUM; +// TBS Status Flags +typedef enum{ + BLC_AUDIO_TBP_STATUS_FLAG_INBAND_RINGTONE = BIT(0), //0=inband ringtone disabled; 1=inband ringtone enabled + BLC_AUDIO_TBP_STATUS_FLAG_SILENT_MODE = BIT(1), //0 = Server is not in silent mode; 1 = Server is in silent mode +}BLC_AUDIO_TBP_STATUS_FLAGS_ENUM; + + +// OTS Opcode for Action Control Point +typedef enum{ + BLC_AUDIO_OTP_OACP_OPCODE_CREATE = 0x01, + BLC_AUDIO_OTP_OACP_OPCODE_DELETE = 0x02, + BLC_AUDIO_OTP_OACP_OPCODE_CALC_CHECKSUM = 0x03, //Calculate Checksum + BLC_AUDIO_OTP_OACP_OPCODE_EXECUTE = 0x04, + BLC_AUDIO_OTP_OACP_OPCODE_READ = 0x05, + BLC_AUDIO_OTP_OACP_OPCODE_WRITE = 0x06, + BLC_AUDIO_OTP_OACP_OPCODE_ABORT = 0x07, + BLC_AUDIO_OTP_OACP_OPCODE_RSPCODE = 0x60, //Response Code +}BLC_AUDIO_OTP_OACP_OPCODE_ENUM; +// OTS Opcode for Action Control Point +typedef enum{ + BLC_AUDIO_OTP_OLCP_OPCODE_FIRST = 0x01, + BLC_AUDIO_OTP_OLCP_OPCODE_LAST = 0x02, + BLC_AUDIO_OTP_OLCP_OPCODE_PREVIOUS = 0x03, + BLC_AUDIO_OTP_OLCP_OPCODE_NEXT = 0x04, + BLC_AUDIO_OTP_OLCP_OPCODE_GOTO = 0x05, + BLC_AUDIO_OTP_OLCP_OPCODE_ORDER = 0x06, + BLC_AUDIO_OTP_OLCP_OPCODE_REQ_OBJNUMB = 0x07, + BLC_AUDIO_OTP_OLCP_OPCODE_CLEAR_MARKING = 0x08, + BLC_AUDIO_OTP_OLCP_OPCODE_RSPCODE = 0x70, +}BLC_AUDIO_OTP_OLCP_OPCODE_ENUM; + + + + + + + +#endif //#if (BLC_AUDIO_PROFILE_EN) + +#endif //_AUDIO_DEFINE_H_ diff --git a/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_handle.h b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_handle.h new file mode 100755 index 0000000..5babcc3 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_handle.h @@ -0,0 +1,48 @@ +/******************************************************************************************************** + * @file audio_handle.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef _AUDIO_HANDLE_H_ +#define _AUDIO_HANDLE_H_ + +#if (BLC_AUDIO_PROFILE_EN) + + + +int blt_audio_handleInit(void); + +blt_audio_handle_t *blt_audio_getHandle(u8 role); +void blt_audio_dropHandle(blt_audio_handle_t *pHandle); + +u16 blc_audio_getConnHandle(u16 cisHandle, u8 role); + +blt_audio_handle_t *blt_audio_findHandle(u16 connHandle); +blt_audio_client_t *blt_audio_findClient(u16 connHandle); +blt_audio_server_t *blt_audio_findServer(u16 connHandle); +blt_audio_handle_t *blt_audio_findHandleByRole(u16 connHandle, u8 role); +blt_audio_handle_t *blt_audio_findHandleByCisHandle(u16 cisHandle, u8 role); + + + +#endif //#if (BLC_AUDIO_PROFILE_EN) + +#endif //_AUDIO_HANDLE_H_ + diff --git a/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_inner.h b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_inner.h new file mode 100755 index 0000000..41c88aa --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_inner.h @@ -0,0 +1,627 @@ +/******************************************************************************************************** + * @file audio_inner.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef _AUDIO_INNER_H_ +#define _AUDIO_INNER_H_ + + +#if (BLC_AUDIO_PROFILE_EN) + + +#define BLT_AUDIO_SINK_AES_MAX 2 +#define BLT_AUDIO_SOURCE_AES_MAX 2 + + + +typedef enum{ + BLT_AUDIO_BUSY_NONE = 0x0000, + BLT_AUDIO_BUSY_PACP = BIT(BLC_AUDIO_SERVICE_PACS), + BLT_AUDIO_BUSY_ASCP = BIT(BLC_AUDIO_SERVICE_ASCS), + BLT_AUDIO_BUSY_BASP = BIT(BLC_AUDIO_SERVICE_BASS), + BLT_AUDIO_BUSY_CSIP = BIT(BLC_AUDIO_SERVICE_CSIS), + BLT_AUDIO_BUSY_RAAP = BIT(BLC_AUDIO_SERVICE_RAAS), + BLT_AUDIO_BUSY_MICP = BIT(BLC_AUDIO_SERVICE_MICS), + BLT_AUDIO_BUSY_VCP = BIT(BLC_AUDIO_SERVICE_VCS), + BLT_AUDIO_BUSY_MCP = BIT(BLC_AUDIO_SERVICE_MCS), + BLT_AUDIO_BUSY_TBP = BIT(BLC_AUDIO_SERVICE_TBS), + BLT_AUDIO_BUSY_OTP = BIT(BLC_AUDIO_SERVICE_OTS), + + BLT_AUDIO_BUSY_SDP = BIT(14), + BLT_AUDIO_BUSY_SDP_START = BIT(15), +}BLT_AUDIO_BUSY_ENUM; + +typedef enum{ + BLT_AUDIO_GFLAG_NONE = 0x0000, + BLT_AUDIO_GFLAG_PACS = BIT(0), + BLT_AUDIO_GFLAG_ASCS = BIT(1), + BLT_AUDIO_GFLAG_BACS = BIT(2), + BLT_AUDIO_GFLAG_CSIS = BIT(3), + BLT_AUDIO_GFLAG_RAAS = BIT(4), + BLT_AUDIO_GFLAG_MICS = BIT(5), + BLT_AUDIO_GFLAG_VCS = BIT(6), + BLT_AUDIO_GFLAG_MCS = BIT(7), + BLT_AUDIO_GFLAG_TBS = BIT(8), + BLT_AUDIO_GFLAG_OTS = BIT(9), +}BLT_AUDIO_GFLAGS_ENUM; + + + +#if (BLC_AUDIO_SDP_ENABLE) + +#define BLT_AUDIO_SDP_SRV_COUNT 8 +#define BLT_AUDIO_SDP_INC_COUNT 2 +#define BLT_AUDIO_SDP_CHAR_COUNT 12 +#define BLT_AUDIO_SDP_OTHR_COUNT 2 + +typedef struct blt_audio_srv_s blt_audio_srv_t; +typedef struct blt_audio_sdp_s blt_audio_sdp_t; +typedef void(*BlcAudioSdpFindServiceFunc)(blt_audio_sdp_t *pSdp, blt_audio_srv_t *pSrv); +typedef void(*BlcAudioSdpInitServiceFunc)(blt_audio_sdp_t *pSdp, blt_audio_srv_t *pSrv); +typedef void(*BlcAudioSdpLoopHandlerFunc)(blt_audio_sdp_t *pSdp, blt_audio_srv_t *pSrv); +typedef void(*BlcAudioSdpOverHandlerFunc)(blt_audio_sdp_t *pSdp, blt_audio_srv_t *pSrv); +typedef int(*BlcAudioSdpGattHandlerFunc)(blt_audio_sdp_t *pSdp, blt_audio_srv_t *pSrv, u8 *pkt); + +typedef struct{ + u16 sHandle; + u16 eHandle; + u16 srvUUID; +}blt_audio_inc_t; +typedef struct{ // 12Bytes + u16 charUUID; + u16 dHandle; //data handle + u16 othrUUID[BLT_AUDIO_SDP_OTHR_COUNT]; + u16 othrHandle[BLT_AUDIO_SDP_OTHR_COUNT]; +}blt_audio_char_t; +struct blt_audio_srv_s{ + u8 used; //Adapter to multi same ServiceUUID. + u8 mode; //Refer to BLT_AUDIO_CHAR_MODE_ENUM. + u8 flags; //Refer to BLT_AUDIO_SRV_FLAG_ENUM. + u8 curChar; // + u16 srvUUID; + u16 sHandle; + u16 eHandle; + u16 oHandle; + BlcAudioSdpFindServiceFunc findFunc; + BlcAudioSdpInitServiceFunc initFunc; + BlcAudioSdpLoopHandlerFunc loopFunc; + BlcAudioSdpOverHandlerFunc overFunc; + BlcAudioSdpGattHandlerFunc gattFunc; +}; +struct blt_audio_sdp_s{ + u8 start; + u8 flags; + u8 other; + u8 curSrv; + u16 handle; //Connect Handle + u16 sHandle; + u16 eHandle; + u16 oHandle; + u32 startTimer; + blt_audio_srv_t *servPtr[BLT_AUDIO_SDP_SRV_COUNT]; + blt_audio_inc_t includes[BLT_AUDIO_SDP_INC_COUNT]; + blt_audio_char_t charact[BLT_AUDIO_SDP_CHAR_COUNT]; //This will be Shared by multiple services +}; +#endif //#if (BLC_AUDIO_SDP_ENABLE) + + + +#if (BLC_AUDIO_AICS_ENABLE) +typedef struct{ + u16 flags; + u16 resv0; + u16 sHandle; + u16 eHandle; + u16 ctrlHandle; + u16 stateHandle; + u16 propeHandle; + u16 inputHandle; + u16 statusHandle; + u16 descHandle; + + u8 gainStateValue; + u8 gainStateMute; + u8 gainStateMode; + u8 gainStateCount; + + u8 gainPropeUnit; + u8 gainPropeMin; + u8 gainPropeMax; + u8 reserve1; + + u8 gainType; + u8 gainStatus; + u8 stateCCC; + u8 statusCCC; + + #if (BLC_AUDIO_AICS_DESC_ENABLE) + u32 descLen; + u8 desc[BLC_AUDIO_AICS_DESC_SIZE]; + #endif +}blt_audio_aics_t; +#endif //BLC_AUDIO_AICS_ENABLE +#if (BLC_AUDIO_VOCS_ENABLE) +typedef struct{ + u16 flags; + u16 reserve; + + u16 sHandle; + u16 eHandle; + + u16 stateHandle; + u16 ctrlHandle; + u16 locaHandle; + u16 descHandle; + + u8 counter; + u8 stateCCC; + u16 voffset; + + u32 location; + + #if (BLC_AUDIO_VOCS_DESC_ENABLE) + u32 descLen; + u8 desc[BLC_AUDIO_VOCS_DESC_SIZE]; + #endif +}blt_audio_vocs_t; +#endif //BLC_AUDIO_VOCS_ENABLE + +#if (BLC_AUDIO_PACP_ENABLE) +typedef struct{ + u16 flags; + u16 resv0; + u8 sinkPacLen; + u8 srcPacLen; + u16 avaHandle; + u16 srcLcaHandle; + u16 sinkLcaHandle; + u8 *pSrcPac; + u8 *pSrcLca; // source location + u8 *pSinkPac; + u8 *pSinkLca; // sink location + u8 *pAvaCtx; // avaliable Context + u8 *pSupCtx; // supported Context +}blt_audio_pacpCtrl_t; +#endif //#if (BLC_AUDIO_PACP_ENABLE) +#if (BLC_AUDIO_ASCP_ENABLE) +typedef struct{ // 36Bytes + // Profile Param 16Byte + u8 codecId[5]; + u8 direction; + u8 frequency; + u8 duration; + u16 context; // Metadata + u16 frameOcts; + u32 location; + + // Link Layer Param 16Bytes + u8 cigID; + u8 cisID; + u8 PHY; + u8 RTN; //Retransmission_Number + u16 maxSDU; + u16 latency; + u8 framing; + u8 resv000; + u8 delay[3]; + u8 interval[3]; +}blt_audio_aseParam_t; +typedef struct{ // 4Bytes + u16 attHandle; + u16 cisHandle; + u16 flags; //Refer to BLT_AUDIO_ASE_FLAGS_ENUM + u16 ready; + u8 aseID; + u8 state; //Refer to BLT_AUDIO_ASE_STATE_ENUM + u16 reserve; + u8 *pAseCCC; + blt_audio_aseParam_t param; +}blt_audio_ascpAse_t; +typedef struct{ + u8 flags; //For client, this is SdpExFlags. + u8 aseCount; + u16 ctrlHandle; + blt_audio_ascpAse_t ase[BLC_AUDIO_ASE_PER_HANDLE]; +}blt_audio_ascpCtrl_t; +#endif //#if (BLC_AUDIO_ASCP_ENABLE) + +#if (BLC_AUDIO_CSIP_ENABLE) +typedef struct{ + u8 flags; + u8 isInLock; //Is Inner Lock + u8 sdpFlags; + u8 reserve0; + u32 lockTimer; + u32 lockTimeout; //us + + u16 sirkHandle; + u16 sizeHandle; + u16 lockHandle; + u16 rankHandle; + + u8 size; + u8 lock; + u8 rank; + u8 lockCCC; + u8 SIRK[16]; +}blt_audio_csipCtrl_t; +#endif //#if (BLC_AUDIO_CSIP_ENABLE) +#if (BLC_AUDIO_MICP_ENABLE) +typedef struct{ + u16 flags; + u16 sdpFlags; + u8 aicsCount; + u8 sdpCount; + u8 muteCCC; + u8 muteValue; + u16 reserve01; + u16 muteHandle; + #if (BLC_AUDIO_MICS_AICS_ENABLE) + blt_audio_aics_t aics[BLC_AUDIO_MICS_AICS_COUNT]; + #endif +}blt_audio_micpCtrl_t; +#endif //#if (BLC_AUDIO_MICP_ENABLE) + +#if (BLC_AUDIO_VCP_ENABLE) +typedef struct{ + u16 flags; + u16 sdpFlags; + u8 sdpCount; + u8 aicsCount; + u8 vocsCount; + u8 flagCCC; + u8 flagValue; + u8 reserve00; + u16 statHandle; + u16 flagHandle; + u16 ctrlHandle; + struct{ + u8 mute; + u8 volume; + u8 counter; + u8 stateCCC; + }state; + #if (BLC_AUDIO_VCS_AICS_ENABLE) + blt_audio_aics_t aics[BLC_AUDIO_VCS_AICS_COUNT]; + #endif + #if (BLC_AUDIO_VOCS_ENABLE) + blt_audio_vocs_t vocs[BLC_AUDIO_VCS_VOCS_COUNT]; + #endif //BLC_AUDIO_VOCS_ENABLE +}blt_audio_vcpCtrl_t; +#endif //#if (BLC_AUDIO_VCP_ENABLE) + +#if (BLC_AUDIO_MCP_ENABLE) +typedef struct{ + u16 flags; + u8 enable; + u8 serial; + u8 isValid; + u8 cpOpcode; //Control Point Opcode + u8 resultCode; + u8 mediaState; + u8 trackIsStart; + u8 reserve000; + u16 playNameHandle; + u16 trackChangedHandle; + u16 trackTitleHandle; + u16 trackDurationHandle; + u16 trackPositionHandle; + u16 mediaStateHandle; + u16 mediaCtrlHandle; + u16 opcodesSuppHandle; + u16 CCIDHandle; + + u16 trackDurationValue; + u32 trackPositionValue; //Should be in [0,trackDurationValue] + + #if (BLC_AUDIO_MCS_EXTEND_SUPPORT_ENABLE) + u8 seekingSpeedValue; + u8 searchContrlStatus; + u16 seekingSpeedHandle; + u16 searchControlHandle; + u16 searchResultHandle; + u8 searchObjectID[6]; + #endif +}blt_audio_mcpCtrl_t; +#endif //BLC_AUDIO_MCP_ENABLE + + +//#define CHARACTERISTIC_UUID_TBS_PROVIDER_NAME //M Mandatory:Read, Notify; Optional: +//#define CHARACTERISTIC_UUID_TBS_CALLER_IDENTIFIER //M Mandatory:Read; Optional: +//#define CHARACTERISTIC_UUID_TBS_TECHNOLOGY //M Mandatory:Read, Notify; Optional: +//#define CHARACTERISTIC_UUID_TBS_URI_LIST //M Mandatory:Read; Optional:Notify +//#define CHARACTERISTIC_UUID_TBS_CURRENT_CALL_LIST //M Mandatory:Read, Notify; Optional: +//#define CHARACTERISTIC_UUID_TBS_CCID //M Mandatory:Read; Optional: +//#define CHARACTERISTIC_UUID_TBS_STATUS_FLAGS //M Mandatory:Read, Notify; Optional: +//#define CHARACTERISTIC_UUID_TBS_CALL_STATE //M Mandatory:Read, Notify; Optional: +//#define CHARACTERISTIC_UUID_TBS_CALL_CONTROL_POINT //M Mandatory:Write, Write Without Response, Notify; Optional: +//#define CHARACTERISTIC_UUID_TBS_CCP_OPTIONAL_OPCODES //M Mandatory:Read; Optional: +//#define CHARACTERISTIC_UUID_TBS_TERMINATIONO_REASON //M Mandatory:Notify; Optional: +//#define CHARACTERISTIC_UUID_TBS_INCOMING_CALL //M Mandatory:Read, Notify; Optional: + +#if (BLC_AUDIO_TBS_ENABLE) +typedef struct{ + u8 flags; + u8 index; + u8 state; + u8 callFlags; + u8 reserve001; + u8 termReason; + + u8 uriLen; + u8 nameLen; + u8 uri[BLC_AUDIO_TBS_URL_MAX_LEN]; + u8 name[BLC_AUDIO_TBS_NAME_MAX_LEN]; +}blt_audio_tbsCall_t; +typedef struct{ + u16 flags; + u8 cpOpcode; //Control Point Opcode + u8 callIndex; + u8 resultCode; + u8 callCount; + u16 reserve01; + u16 CCIDHandle; + u16 callCtrlHandle; + u16 inCallHandle; + u16 provNameHandle; + u16 callerIDHandle; + u16 callStateHandle; + u16 bearerTechHandle; + u16 CCPOpcodesHandle; + u16 termReasonHandle; + u16 curCallListHandle; + blt_audio_tbsCall_t call[BLC_AUDIO_TBS_CALL_COUNT]; + + #if (BLC_AUDIO_TBS_EXTEND_SUPPORT_ENABLE) + u8 signaleStrengthValue; + u8 provNameLength; + u8 bearerTechValue; + u8 reserver0002; + u16 statusFlagsValue; + u16 statusFlagsHandle; + + u8 provName[BLC_AUDIO_TBS_NAME_MAX_LEN]; + u16 inCallURIHandle; + u16 signaleStrengthHandle; + u16 signaleStrengthReportHandle; + u16 callFriendlyNameHandle; + #endif +}blt_audio_tbpCtrl_t; +#endif //BLC_AUDIO_TBS_ENABLE +#if (BLC_AUDIO_OTP_ENABLE) +//#define BLC_AUDIO_OTP_FEATURE_BUFFER_LEN 32 +//#define BLC_AUDIO_OTP_NAME_BUFFER_LEN 16 +//#define BLC_AUDIO_OTP_FILTER_BUFFER_LEN 32 +#define BLC_AUDIO_OTP_FEATURE_BUFFER_LEN 64 +#define BLC_AUDIO_OTP_NAME_BUFFER_LEN 64 +#define BLC_AUDIO_OTP_FILTER_BUFFER_LEN 64 +typedef struct{ + u16 flags; + + u8 oacpOpcode; + u8 oacpStatus; + + u16 featureHandle; + u16 objectNameHandle; + u16 objectTypeHandle; + u16 objectSizeHandle; + u16 objectPropertiesHandle; + u16 objectActionCPHandle; + + u8 featureLength; + u8 objectNameLength; + u16 objectTypeValue; + u32 objectSizeValue0; + u32 objectSizeValue1; + u32 objectPropertiesValue; + u8 featureValue[BLC_AUDIO_OTP_FEATURE_BUFFER_LEN]; + u8 objectNameValue[BLC_AUDIO_OTP_NAME_BUFFER_LEN]; + + #if (BLC_AUDIO_OTS_EXTEND_SUPPORT_ENABLE) + u16 firstCreatedHandle; + u16 lastCreatedHandle; + u16 objectIDHandle; + u16 objectListCPHandle; + u16 listFilterHandle; + u16 objectChangedHandle; + + u8 listFilterLength; + u8 reserve001; + u8 olcpOpcode; + u8 olcpStatus; + + u8 firstCreatedValue[8]; //Valid:7 + u8 lastCreatedValue[8]; //Valid:7 + u8 objectIDValue[8]; //Valid:6 + u8 listFilterValue[BLC_AUDIO_OTP_FILTER_BUFFER_LEN]; + #endif //BLC_AUDIO_OTS_EXTEND_SUPPORT_ENABLE + +}blt_audio_otpCtrl_t; +#endif //BLC_AUDIO_OTP_ENABLE + + +typedef struct{ + u8 role; //Refer to BLC_AUDIO_ROLE_ENUM + u8 conn; //True if used, false if not used + u16 busy; //Refer to BLT_AUDIO_BUSY_ENUM + u16 handle; //Connect Handle + u16 gFlags; //Global flags (this is not change). Refer to BLT_AUDIO_GFLAGS_ENUM + BlcAudioEventCB evtCB; + #if (BLC_AUDIO_PACP_ENABLE) + blt_audio_pacpCtrl_t pacp; + #endif + #if (BLC_AUDIO_ASCP_ENABLE) + blt_audio_ascpCtrl_t ascp; + #endif + #if (BLC_AUDIO_CSIP_ENABLE) + blt_audio_csipCtrl_t csip; + #endif + #if (BLC_AUDIO_MICP_ENABLE) + blt_audio_micpCtrl_t micp; + #endif + #if (BLC_AUDIO_VCP_ENABLE) + blt_audio_vcpCtrl_t vcp; + #endif + #if (BLC_AUDIO_MCP_ENABLE) + blt_audio_mcpCtrl_t mcp; + #endif + #if (BLC_AUDIO_TBS_ENABLE) + blt_audio_tbpCtrl_t tbp; + #endif + #if (BLC_AUDIO_OTS_ENABLE) + blt_audio_otpCtrl_t otp; + #endif + + #if (BLC_AUDIO_SERVER_SDP_ENABLE) + blt_audio_sdp_t sdp; + #if !(BLC_AUDIO_MCP_ROLE_SWICH_ENABLE) + #if (BLC_AUDIO_MCS_ENABLE) + blt_audio_srv_t mcsSrv; + #endif //BLC_AUDIO_MCS_ENABLE + #endif //BLC_AUDIO_MCP_ROLE_SWICH_ENABLE + #if !(BLC_AUDIO_TBP_ROLE_SWICH_ENABLE) + #if (BLC_AUDIO_TBS_ENABLE) + blt_audio_srv_t tbsSrv; + #endif //BLC_AUDIO_TBS_ENABLE + #endif //BLC_AUDIO_TBP_ROLE_SWICH_ENABLE + #if !(BLC_AUDIO_OTP_ROLE_SWICH_ENABLE) + #if (BLC_AUDIO_OTS_ENABLE) + blt_audio_srv_t otsSrv; + #endif //BLC_AUDIO_OTS_ENABLE + #endif //BLC_AUDIO_OTP_ROLE_SWICH_ENABLE + #endif +}blt_audio_server_t; + +typedef struct{ + u8 role; //Refer to BLC_AUDIO_ROLE_ENUM + u8 conn; //True if used, false if not used + u16 busy; //Refer to BLT_AUDIO_BUSY_ENUM + u16 handle; //Connect Handle + u16 gFlags; //Global flags. Refer to BLT_AUDIO_GFLAGS_ENUM + BlcAudioEventCB evtCB; + #if (BLC_AUDIO_PACP_ENABLE) + blt_audio_pacpCtrl_t pacp; + #endif + #if (BLC_AUDIO_ASCP_ENABLE) + blt_audio_ascpCtrl_t ascp; + #endif + #if (BLC_AUDIO_CSIP_ENABLE) + blt_audio_csipCtrl_t csip; + #endif + #if (BLC_AUDIO_MICP_ENABLE) + blt_audio_micpCtrl_t micp; + #endif + #if (BLC_AUDIO_VCP_ENABLE) + blt_audio_vcpCtrl_t vcp; + #endif + #if (BLC_AUDIO_MCP_ENABLE) + blt_audio_mcpCtrl_t mcp; + #endif + #if (BLC_AUDIO_TBS_ENABLE) + blt_audio_tbpCtrl_t tbp; + #endif + #if (BLC_AUDIO_OTS_ENABLE) + blt_audio_otpCtrl_t otp; + #endif + + #if (BLC_AUDIO_CLIENT_SDP_ENABLE) + blt_audio_sdp_t sdp; + #if (BLC_AUDIO_PACS_ENABLE) + blt_audio_srv_t pacsSrv; + #endif //BLC_AUDIO_PACS_ENABLE + #if (BLC_AUDIO_ASCS_ENABLE) + blt_audio_srv_t ascsSrv; + #endif //BLC_AUDIO_ASCS_ENABLE + #if (BLC_AUDIO_CSIS_ENABLE) + blt_audio_srv_t csisSrv; + #endif //BLC_AUDIO_CSIS_ENABLE + #if (BLC_AUDIO_MICS_ENABLE) + blt_audio_srv_t micsSrv; + #endif //BLC_AUDIO_CSIS_ENABLE + #if (BLC_AUDIO_VCS_ENABLE) + blt_audio_srv_t vcsSrv; + #endif //BLC_AUDIO_VCS_ENABLE + #if (BLC_AUDIO_MCP_ROLE_SWICH_ENABLE) + #if (BLC_AUDIO_MCS_ENABLE) + blt_audio_srv_t mcsSrv; + #endif //BLC_AUDIO_MCS_ENABLE + #endif + #if (BLC_AUDIO_TBP_ROLE_SWICH_ENABLE) + #if (BLC_AUDIO_TBS_ENABLE) + blt_audio_srv_t tbsSrv; + #endif //BLC_AUDIO_TBS_ENABLE + #endif + #if (BLC_AUDIO_OTP_ROLE_SWICH_ENABLE) + #if (BLC_AUDIO_OTS_ENABLE) + blt_audio_srv_t otsSrv; + #endif //BLC_AUDIO_OTS_ENABLE + #endif + #endif +}blt_audio_client_t; + +typedef struct{ + u8 role; //Refer to BLC_AUDIO_ROLE_ENUM + u8 conn; //True if used, false if not used + u16 busy; //Refer to BLT_AUDIO_BUSY_ENUM + u16 handle; //Connect Handle + u16 gFlags; //Global flags. Refer to BLT_AUDIO_GFLAGS_ENUM + BlcAudioEventCB evtCB; + #if (BLC_AUDIO_PACP_ENABLE) + blt_audio_pacpCtrl_t pacp; + #endif + #if (BLC_AUDIO_ASCP_ENABLE) + blt_audio_ascpCtrl_t ascp; + #endif + #if (BLC_AUDIO_CSIP_ENABLE) + blt_audio_csipCtrl_t csip; + #endif + #if (BLC_AUDIO_MICP_ENABLE) + blt_audio_micpCtrl_t micp; + #endif + #if (BLC_AUDIO_VCP_ENABLE) + blt_audio_vcpCtrl_t vcp; + #endif + #if (BLC_AUDIO_MCP_ENABLE) + blt_audio_mcpCtrl_t mcp; + #endif + #if (BLC_AUDIO_TBS_ENABLE) + blt_audio_tbpCtrl_t tbp; + #endif + #if (BLC_AUDIO_OTS_ENABLE) + blt_audio_otpCtrl_t otp; + #endif +}blt_audio_handle_t; + + + +typedef struct{ + int (*Init)(blt_audio_handle_t *pHandle); + int (*GattIn)(blt_audio_handle_t *pHandle, u8 *pPkt); + int (*SetServ)(blt_audio_handle_t *pHandle, attribute_t *pService); + void (*SetConn)(blt_audio_handle_t *pHandle, BLC_AUDIO_STATE_ENUM state); + void (*Process)(blt_audio_handle_t *pHandle); +}blt_audio_func_t; + + + +#endif //BLC_AUDIO_PROFILE_EN + +#endif //_AUDIO_INNER_H_ diff --git a/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_mcp.h b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_mcp.h new file mode 100755 index 0000000..584d7d8 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_mcp.h @@ -0,0 +1,100 @@ +/******************************************************************************************************** + * @file audio_mcp.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef _AUDIO_MCP_H_ +#define _AUDIO_MCP_H_ + +#if (BLC_AUDIO_MCP_ENABLE) + + + +#define BLT_AUDIO_MCP_TRACK_STEP 100 +#define BLT_AUDIO_MCP_TRACKS_IN_SINGLE_SEGMENT 5 +#define BLT_AUDIO_MCP_SEGMENT_MAX (0xFFFFFFFF/BLT_AUDIO_MCP_TRACKS_IN_SINGLE_SEGMENT) + +#define BLT_AUDIO_MCP_TRACKS_IN_SINGLE_GROUP 10 +#define BLT_AUDIO_MCP_GROUP_MAX (0xFFFFFFFF/BLT_AUDIO_MCP_TRACKS_IN_SINGLE_GROUP) + + +typedef enum{ + BLT_AUDIO_MCP_FLAG_NONE = 0x0000, + BLT_AUDIO_MCP_FLAG_NOTY_STATE = 0x0001, + BLT_AUDIO_MCP_FLAG_NOTY_CPRST = 0x0002, + BLT_AUDIO_MCP_FLAG_NOTY_TRACK_TITLE = 0x0010, + BLT_AUDIO_MCP_FLAG_NOTY_TRACK_CHANGED = 0x0020, + BLT_AUDIO_MCP_FLAG_NOTY_TRACK_DURATION = 0x0040, + BLT_AUDIO_MCP_FLAG_NOTY_TRACK_POSITION = 0x0080, + BLT_AUDIO_MCP_FLAG_NOTY_SEEKING_SPEED = 0x0100, + BLT_AUDIO_MCP_FLAG_NOTY_SEARCH_CONTROL = 0x0200, + BLT_AUDIO_MCP_FLAG_NOTY_SEARCH_OBJECT = 0x0400, +}BLT_AUDIO_MCP_FLAGS_ENUM; + +typedef enum{ + BLT_AUDIO_MCP_CP_ERRCODE_VALUE_CHANGED = 0x80, +}BLT_AUDIO_MCP_CP_ERRCODE_ENUM; + +typedef enum{ + BLT_AUDIO_MCP_CP_RSTCODE_SUCCESS = 0x01, + BLT_AUDIO_MCP_CP_RSTCODE_OPCODE_NOT_SUPPORTED = 0x02, + BLT_AUDIO_MCP_CP_RSTCODE_MEDIA_PLAYER_INACTIVE = 0x03, +}BLT_AUDIO_MCP_CP_RSTCODE_ENUM; + + + +int blc_audio_mcpAttRead(u16 connHandle, void* p); +int blc_audio_mcpAttWrite(u16 connHandle, void* p); + +int blc_audio_mcpEnable(u16 connHandle); +int blc_audio_mcpDisable(u16 connHandle); + +int blc_audio_mcpSetMediaState(u16 connHandle, u8 state, bool isNoty); +int blt_audio_mcpSetTrackPosition(u16 connHandle, u32 value, bool isNoty); + +int blc_audioMcpPlay(u16 connHandle); +int blc_audioMcpPause(u16 connHandle); +int blc_audioMcpFastRewind(u16 connHandle); +int blc_audioMcpFastForward(u16 connHandle); +int blc_audioMcpStop(u16 connHandle); +int blc_audioMcpMoveRelative(u16 connHandle, s32 offset); +int blc_audioMcpPreviousSegment(u16 connHandle); +int blc_audioMcpNextSegment(u16 connHandle); +int blc_audioMcpFirstSegment(u16 connHandle); +int blc_audioMcpLastSegment(u16 connHandle); +int blc_audioMcpGotoSegment(u16 connHandle, s32 number); +int blc_audioMcpPreviousTrack(u16 connHandle); +int blc_audioMcpNextTrack(u16 connHandle); +int blc_audioMcpFirstTrack(u16 connHandle); +int blc_audioMcpLastTrack(u16 connHandle); +int blc_audioMcpGotoTrack(u16 connHandle, s32 number); +int blc_audioMcpPreviousGroup(u16 connHandle); +int blc_audioMcpNextGroup(u16 connHandle); +int blc_audioMcpFirstGroup(u16 connHandle); +int blc_audioMcpLastGroup(u16 connHandle); +int blc_audioMcpGotoGroup(u16 connHandle, s32 number); +int blc_audio_mcpSendCtrl(u16 connHandle, u8 opcode, u8 *pData, u16 dataLen); + + + +#endif //#if (BLC_AUDIO_MCP_ENABLE) + +#endif //_AUDIO_MCP_H_ + diff --git a/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_micp.h b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_micp.h new file mode 100755 index 0000000..69dcd1f --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_micp.h @@ -0,0 +1,110 @@ +/******************************************************************************************************** + * @file audio_micp.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef _AUDIO_MICP_H_ +#define _AUDIO_MICP_H_ + +#if (BLC_AUDIO_MICP_ENABLE) + + + + +typedef enum{ + BLT_AUDIO_MICP_OPCODE_SET_GAIN = 0x01, + BLT_AUDIO_MICP_OPCODE_UNMUTE = 0x02, + BLT_AUDIO_MICP_OPCODE_MUTE = 0x03, + BLT_AUDIO_MICP_OPCODE_MANUAL_MODE = 0x04, + BLT_AUDIO_MICP_OPCODE_AUTOMATIC_MODE = 0x05, +}BLT_AUDIO_MICP_OPCODE_ENUM; + +typedef enum{ + BLT_AUDIO_MICP_ERRCODE_MUTE_DISABLED = 0x80, + BLT_AUDIO_MICP_ERRCODE_VALUE_OUT_OF_RANGE = 0x81, +}BLT_AUDIO_MICP_ERRCODE_ENUM; + +typedef enum{ + BLT_MICP_AICS_OPCODE_SET_GAIN_VALUE = 0x01, + BLT_MICP_AICS_OPCODE_UNMUTE = 0x02, + BLT_MICP_AICS_OPCODE_MUTE = 0x03, + BLT_MICP_AICS_OPCODE_MANU_GAIN_MODE = 0x04, + BLT_MICP_AICS_OPCODE_AUTO_GAIN_MODE = 0x05, +}BLT_MICP_AICS_OPCODE_ENUM; +typedef enum{ + BLT_MICP_AICS_ERRCODE_INVALID_CHANGE_COUNTER = 0x80, + BLT_MICP_AICS_ERRCODE_OPCODE_NOT_SUPPORTED = 0x81, + BLT_MICP_AICS_ERRCODE_MUTE_DISABLED = 0x82, + BLT_MICP_AICS_ERRCODE_VALUE_OUT_OF_RANGE = 0x83, + BLT_MICP_AICS_ERRCODE_MODE_CHANGE_NOT_ALLOWED = 0x84, +}BLT_MICP_AICS_ERRCODE_ENUM; + + +typedef enum{ + BLT_AUDIO_MICP_SDP_FLAG_NONE = 0x00, + BLT_AUDIO_MICP_SDP_FLAG_FIRST = 0x80, + BLT_AUDIO_MICP_SDP_FLAG_INIT = 0x40, + BLT_AUDIO_MICP_SDP_FLAG_AICS = 0x20, + BLT_AUDIO_MICP_SDP_FLAG_VOCS = 0x10, + BLT_AUDIO_MICP_SDP_FLAG_READY = 0x08, + + BLT_AUDIO_MICP_SDP_FLAG_PVAL = 0x04, + BLT_AUDIO_MICP_SDP_FLAG_SVAL = 0x02, +}BLT_AUDIO_MICP_SDP_FLAGS_ENUM; + +typedef enum{ + BLT_AUDIO_MICP_FLAG_NONE = 0x00, + BLT_AUDIO_MICP_FLAG_MUTE_CHANGE = 0x01, + BLT_AUDIO_MICP_FLAG_AICS_CHANGE = 0x02, +}BLT_AUDIO_MICP_FLAGS_ENUM; +typedef enum{ + BLT_AUDIO_MICP_AICS_FLAG_NONE = 0x00, + BLT_AUDIO_MICP_AICS_FLAG_STATE_CHANGE = 0x01, + BLT_AUDIO_MICP_AICS_FLAG_STATUS_CHANGE = 0x02, +}BLT_AUDIO_MICP_AICS_FLAGS_ENUM; + + + +int blc_audio_micpAttRead(u16 connHandle, void *p); +int blc_audio_micpAttWrite(u16 connHandle, void *p); + +int blc_audio_micpSetMute(u16 connHandle, u8 mute); + + +static int blt_audio_micpInit(blt_audio_handle_t *pHandle); +static int blt_audio_micpGattIn(blt_audio_handle_t *pHandle, u8 *pPkt); +static int blt_audio_micpSetServ(blt_audio_handle_t *pHandle, attribute_t *pService); +static void blt_audio_micpSetConn(blt_audio_handle_t *pHandle, BLC_AUDIO_STATE_ENUM state); +static void blt_audio_micpProcess(blt_audio_handle_t *pHandle); + +static int blt_audio_micpSetMicsServ(blt_audio_handle_t *pHandle, attribute_t *pService); +static int blt_audio_micpWriteMics(blt_audio_handle_t *pHandle, u8 dataLen, u8 *pData); +#if (BLC_AUDIO_MICS_AICS_ENABLE) +static int blt_audio_micpSetAicsServ(blt_audio_handle_t *pHandle, attribute_t *pService); +static int blt_audio_micpWriteAics(blt_audio_handle_t *pHandle, blt_audio_aics_t *pAics, u8 opcode, u8 dataLen, u8 *pData); +#endif + + + + +#endif //#if (BLC_AUDIO_MICP_ENABLE) + +#endif //_AUDIO_MICP_H_ + diff --git a/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_otp.h b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_otp.h new file mode 100755 index 0000000..70ccc77 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_otp.h @@ -0,0 +1,87 @@ +/******************************************************************************************************** + * @file audio_otp.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef _AUDIO_OTP_H_ +#define _AUDIO_OTP_H_ + +#if (BLC_AUDIO_OTP_ENABLE) + + +typedef enum{ + BLT_AUDIO_OTP_FLAG_NONE = 0x0000, + + BLT_AUDIO_OTP_FLAG_OACP_IND = 0x0001, + BLT_AUDIO_OTP_FLAG_OLCP_IND = 0x0002, + BLT_AUDIO_OTP_FLAG_OBJECT_CHANGED = 0x0004, +}BLT_AUDIO_OTP_FLAGS_ENUM; + +typedef enum{ + BLT_AUDIO_OTP_ERRCODE_WRITE_REJECTED = 0x80, //Write Request Rejected: An attempt was made to write a value that is invalid or not supported by this Server for a reason other than the attribute permissions. + BLT_AUDIO_OTP_ERRCODE_OBJECT_NOTSEL = 0x81, //Object Not Selected: An attempt was made to read or write to an Object Metadata characteristic while the Current Object was an Invalid Object + BLT_AUDIO_OTP_ERRCODE_LIMIT_EXCEEDED = 0x82, //Concurrency Limit Exceeded: The Server is unable to service the Read Request or Write Request because it exceeds the concurrency limit of the service. + BLT_AUDIO_OTP_ERRCODE_NAME_EXISTS = 0x83, //Object Name Already Exists: The requested object name was rejected because the name was already in use by an existing object on the Server. +}BLT_AUDIO_OTP_ERRCODE_ENUM; + +typedef enum{ + BLT_AUDIO_OTP_OACP_SUCCESS = 0x01, //Response for successful operation. + BLT_AUDIO_OTP_OACP_ERRCODE_OPCODE_NOT_SUPPORTED = 0x02, //Response if unsupported Op Code is received + BLT_AUDIO_OTP_OACP_ERRCODE_INVALID_PARAMETER = 0x03, //Response if Parameter received does not meet the requirements of the service. + BLT_AUDIO_OTP_OACP_ERRCODE_INSUFFICIENT_RESOURCES = 0x04, // + BLT_AUDIO_OTP_OACP_ERRCODE_INVALID_OBJECT = 0x05, //Response if the requested OACP procedure cannot be performed because the Current Object is an Invalid Object. + BLT_AUDIO_OTP_OACP_ERRCODE_CHANNEL_UNAVAILABLE = 0x06, //Response if the requested procedure could not be performed because an Object Transfer Channel was not available for use. + BLT_AUDIO_OTP_OACP_ERRCODE_UNSUPPORTED_TYPE = 0x07, //Response if the object type specified in the OACP procedure Type parameter is not supported by the Server. + BLT_AUDIO_OTP_OACP_ERRCODE_PROCEDURE_NOT_PERMITTED = 0x08, //Response if the requested procedure is not permitted according to the properties of the Current Object + BLT_AUDIO_OTP_OACP_ERRCODE_OBJECT_LOCKED = 0x09, //Response if the Current Object is temporarily locked by the Server. + BLT_AUDIO_OTP_OACP_ERRCODE_OPERATION_FAILED = 0x0A, //Response if the requested procedure failed for any reason other than those enumerated in this table. +}BLT_AUDIO_OTP_OACP_ERRCODE_ENUM; +typedef enum{ + BLT_AUDIO_OTP_OLCP_SUCCESS = 0x01, //Response for successful operation. + BLT_AUDIO_OTP_OLCP_ERRCODE_OPCODE_NOT_SUPPORTED = 0x02, //Response if unsupported Op Code is received. + BLT_AUDIO_OTP_OLCP_ERRCODE_INVALID_PARAMETER = 0x03, //Response if Parameter received does not meet the requirements of the service. + BLT_AUDIO_OTP_OLCP_ERRCODE_OPERATION_FAILED = 0x04, //Response if the requested procedure failed for a reason other than those enumerated below. + BLT_AUDIO_OTP_OLCP_ERRCODE_OUT_OF_BOUNDS = 0x05, //Response if the requested procedure attempted to select an object beyond the first object or beyond the last object in the current list. + BLT_AUDIO_OTP_OLCP_ERRCODE_TOO_MANY_OBJECS = 0x06, //Response if the requested procedure failed due to too many objects in the current list. + BLT_AUDIO_OTP_OLCP_ERRCODE_NO_OBJECT = 0x07, //Response if the requested procedure failed due to there being zero objects in the current list. + BLT_AUDIO_OTP_OLCP_ERRCODE_OBJID_NOT_FOUND = 0x08, //Response if the requested procedure failed due to there being no object with the requested Object ID. +}BLT_AUDIO_OTP_OLCP_ERRCODE_ENUM; + + +int blc_audio_otpAttRead(u16 connHandle, void* p); +int blc_audio_otpAttWrite(u16 connHandle, void* p); + +int blc_audio_otpSetObjectName(u16 connHandle, u8 *pName, u16 nameLen); +int blc_audio_otpSendActionCtrl(u16 connHandle, u8 opcode, u8 *pData, u8 dataLen); +int blc_audio_otpSendListCtrl(u16 connHandle, u8 opcode, u8 *pData, u8 dataLen); + + + +static int blt_audio_otpInit(blt_audio_handle_t *pHandle); +static int blt_audio_otpGattIn(blt_audio_handle_t *pHandle, u8 *pPkt); +static int blt_audio_otpSetServ(blt_audio_handle_t *pHandle, attribute_t *pService); +static void blt_audio_otpSetConn(blt_audio_handle_t *pHandle, BLC_AUDIO_STATE_ENUM state); +static void blt_audio_otpProcess(blt_audio_handle_t *pHandle); + + +#endif //#if (BLC_AUDIO_OTP_ENABLE) + +#endif //_AUDIO_OTP_H_ + diff --git a/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_pacp.h b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_pacp.h new file mode 100755 index 0000000..9bb3a81 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_pacp.h @@ -0,0 +1,67 @@ +/******************************************************************************************************** + * @file audio_pacp.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef _AUDIO_PACP_H_ +#define _AUDIO_PACP_H_ + +#if (BLC_AUDIO_PACS_ENABLE) + + +typedef enum{ + BLT_AUDIO_PACP_FLAG_NONE = 0x0000, + BLT_AUDIO_PACP_FLAG_CONTEXT_CHANGE = 0x0001, +}BLT_AUDIO_PACP_FLAGS_ENUM; + + +typedef enum{ + BLT_AUDIO_PACP_RECORD_TYPE_SINK = 0x00, + BLT_AUDIO_PACP_RECORD_TYPE_SOURCE = 0x01, +}BLT_PACP_RECORD_TYPE_ENUM; + + +typedef struct{ + u8 counts; + u8 duration; + u16 frequency; + u16 minOctets; + u16 maxOctets; + u16 preferredContext; +}blt_audio_pacpRecordParam_t; + +int blc_audio_pacpAttRead(u16 connHandle, void* p); +int blc_audio_pacpAttWrite(u16 connHandle, void* p); + + +u8 blt_audio_mallocContext(blt_audio_handle_t *pHandle, u8 type, u16 context); +u8 blt_audio_freeContext(blt_audio_handle_t *pHandle, u8 type, u16 context); + +u16 blt_audio_getAvalibleContext(blt_audio_handle_t *pHandle, u8 type); +void blt_audio_setAvalibleContext(blt_audio_handle_t *pHandle, u8 type, u16 context); + +u8 *blt_audio_getRecord(blt_audio_handle_t *pHandle, u8 type, u8 *pCodecId); +u8 blt_audio_getRecordParam(blt_audio_handle_t *pHandle, u8 type, u8 *pCodecId, blt_audio_pacpRecordParam_t *pParam); + + +#endif //#if (BLC_AUDIO_PACS_ENABLE) + +#endif //_AUDIO_PACP_H_ + diff --git a/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_raap.h b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_raap.h new file mode 100755 index 0000000..32bf4e1 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_raap.h @@ -0,0 +1,45 @@ +/******************************************************************************************************** + * @file audio_raap.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef _AUDIO_RAAP_H_ +#define _AUDIO_RAAP_H_ + +#if (BLC_AUDIO_RAAP_ENABLE) + + + +int blc_audio_raapAttRead(u16 connHandle, void* p); +int blc_audio_raapAttWrite(u16 connHandle, void* p); + + + + +static int blt_audio_raapInit(blt_audio_handle_t *pHandle); +static int blt_audio_raapGattIn(blt_audio_handle_t *pHandle, u8 *pPkt); +static int blt_audio_raapSetServ(blt_audio_handle_t *pHandle, attribute_t *pService); +static void blt_audio_raapSetConn(blt_audio_handle_t *pHandle, BLC_AUDIO_STATE_ENUM state); +static void blt_audio_raapProcess(blt_audio_handle_t *pHandle); + + +#endif //#if (BLC_AUDIO_RAAP_ENABLE) + +#endif //_AUDIO_RAAP_H_ diff --git a/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_sdp.h b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_sdp.h new file mode 100755 index 0000000..4a52d22 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_sdp.h @@ -0,0 +1,71 @@ +/******************************************************************************************************** + * @file audio_sdp.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef _AUDIO_SDP_H_ +#define _AUDIO_SDP_H_ + + +#if (BLC_AUDIO_SDP_ENABLE) + +typedef enum{ + BLT_AUDIO_SDP_FLAG_NONE = 0x00, + BLT_AUDIO_SDP_FLAG_WAIT = 0x80, + BLT_AUDIO_SDP_FLAG_SERACH_SERVICE = 0x01, + BLT_AUDIO_SDP_FLAG_INIT_SERVICE = 0x02, + BLT_AUDIO_SDP_FLAG_LOOP_SERVICE = 0x04, + + BLT_AUDIO_SDP_FLAG_DEFAULT = BLT_AUDIO_SDP_FLAG_SERACH_SERVICE | BLT_AUDIO_SDP_FLAG_INIT_SERVICE, +}BLT_AUDIO_SDP_FLAGS_ENUM; +typedef enum{ + BLT_AUDIO_SRV_FLAG_NONE = 0x00, + BLT_AUDIO_SRV_FLAG_WAIT = 0x80, + BLT_AUDIO_SRV_FLAG_AUTO = 0x40, //Auto do: SERACH_INCLUDE,SERACH_CHARACT,FIND_CHARACT,AUTO_ENABLE_CCC + BLT_AUDIO_SRV_FLAG_OTHR = 0x20, + BLT_AUDIO_SRV_FLAG_SERACH_INCLUDE = 0x01, + BLT_AUDIO_SRV_FLAG_SERACH_CHARACT = 0x02, + BLT_AUDIO_SRV_FLAG_FIND_CHARACT = 0x04, + BLT_AUDIO_SRV_FLAG_ENABLE_CCC = 0x08, + + BLT_AUDIO_SRV_FLAG_DEFAULT = BLT_AUDIO_SRV_FLAG_SERACH_CHARACT +| BLT_AUDIO_SRV_FLAG_FIND_CHARACT, +}BLT_AUDIO_SRV_FLAG_ENUM; + +typedef enum{ + BLT_AUDIO_CHAR_MODE_IDLE = 0x00,//Fill Character if idle + BLT_AUDIO_CHAR_MODE_UUID = 0x01,//Find Character by charUUID +}BLT_AUDIO_CHAR_MODE_ENUM; + + +int blt_audio_sdpRegServ(blt_audio_sdp_t *pSdp, blt_audio_srv_t *pServ); +int blt_audio_sdpClrServ(blt_audio_sdp_t *pSdp); + +bool blt_audio_sdpStart(blt_audio_sdp_t *pSdp, u16 connHandle); +void blt_audio_sdpStop(blt_audio_sdp_t *pSdp); + +void blt_audio_sdpHandler(blt_audio_sdp_t *pSdp); +int blt_audio_sdpGattHandler(blt_audio_sdp_t *pSdp, u8 *pkt); + + +#endif //#if (BLC_AUDIO_SDP_ENABLE) + +#endif //_AUDIO_SDP_H_ + diff --git a/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_struct.h b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_struct.h new file mode 100755 index 0000000..82981e1 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_struct.h @@ -0,0 +1,275 @@ +/******************************************************************************************************** + * @file audio_struct.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef _AUDIO_STRUCT_H_ +#define _AUDIO_STRUCT_H_ + +#if (BLC_AUDIO_PROFILE_EN) + +#if (BLC_AUDIO_ASCS_ENABLE) +typedef struct{ + u8 cigID; + u8 cisID; + u8 codecId[5]; + u8 direction; + u8 frequency; + u8 duration; + u16 context; // Metadata + u16 frameOcts; + u32 location; +}blc_audio_aseConfig_t; +#endif + +typedef int(*BlcAudioEventCB)(u16 connHandle, u16 evtID, u16 dataLen, u8 *pData); + + + +typedef struct{ + u8 aseID; + u8 reason; + u8 reserve; + u8 errorCode; //0-success, other-fail + u16 aclHandle; + u16 attHandle; +}blc_audio_aseEnableEvt_t; +typedef struct{ + u8 aseID; + u16 aclHandle; + u16 cisHandle; + u16 attHandle; + u16 context; +}blc_audio_aseUpdateEvt_t; +typedef struct{ + u8 aseID; + u16 aclHandle; + u16 cisHandle; + u16 attHandle; +}blc_audio_aseDisableEvt_t, blc_audio_aseReleaseEvt_t; +typedef struct{ + u8 aseID; + u16 aclHandle; + u16 cisHandle; + u16 attHandle; +}blc_audio_aseStartEvt_t, blc_audio_aseStopEvt_t; + +typedef struct{ + u16 aclHandle; + u16 attHandle; + u8 gainValue; + u8 gainMute; + u8 gainMode; + u8 gainCounter; +}blc_audio_aicsStateChangeEvt_t; +typedef struct{ + u16 aclHandle; + u16 attHandle; + u8 status; // 0-Inactive, 1-Active +}blc_audio_aicsStatusChangeEvt_t; +typedef struct{ + u16 aclHandle; + u16 attHandle; + u32 dataLen; + u8 *pData; +}blc_audio_aicsDescribleChangeEvt_t; + +typedef struct{ + u16 aclHandle; + u16 attHandle; + s16 voffset; + u8 counter; +}blc_audio_vocsStateChangeEvt_t; +typedef struct{ + u16 aclHandle; + u16 attHandle; + u32 location; +}blc_audio_vocpLocationChangeEvt_t; +typedef struct{ + u16 aclHandle; + u16 attHandle; + u32 dataLen; + u8 *pData; +}blc_audio_vocpDescribleChangeEvt_t; + + +typedef struct{ + u16 aclHandle; + u16 attHandle; + u8 mute; + u8 volume; +}blc_audio_vcpStateChangeEvt_t; +typedef struct{ + u16 aclHandle; + u16 attHandle; + u8 flag; +}blc_audio_vcpFlagChangeEvt_t; + + + + + +typedef struct{ + u8 numb; + u8 mute; + u8 volume; + u16 aclHandle; +}blc_audio_micVolumeChangeEvt_t; + + +typedef struct{ + u16 aclHandle; +}blc_audio_pacpServiceReadyEvt_t; + + +typedef struct{ + u16 aclHandle; + u16 ctlHandle; + u8 aseCount; + #if (BLC_AUDIO_ASCS_ENABLE) + u8 aseID[BLC_AUDIO_ASE_PER_HANDLE]; + u8 aseState[BLC_AUDIO_ASE_PER_HANDLE]; + #endif //#if (BLC_AUDIO_ASCS_ENABLE) +}blc_audio_ascpServiceReadyEvt_t; + + +typedef struct{ + u16 aclHandle; + u16 sirkHandle; + u16 sizeHandle; + u16 lockHandle; + u16 rankHandle; + u8 size; + u8 lock; + u8 rank; + u8 lockCCC; + u8 SIRK[16]; +}blc_audio_csipServiceReadyEvt_t; + + + +#if (BLC_AUDIO_MICS_ENABLE || BLC_AUDIO_VCS_ENABLE) +typedef struct{ + u16 ctrlHandle; + u16 stateHandle; + u16 propeHandle; + u16 inputHandle; + u16 statusHandle; + + u8 gainStateValue; + u8 gainStateMute; + u8 gainStateMode; + u8 gainStateCount; + u8 gainPropeUnit; + u8 gainPropeMin; + u8 gainPropeMax; + u8 gainType; + u8 gainStatus; +}blc_audio_aicsServiceReadyEvt_t; +#endif +typedef struct{ + u16 stateHandle; + u16 ctrlHandle; + u16 locaHandle; + u16 descHandle; + u16 voffset; + u8 counter; + u32 location; +}blc_audio_vocsServiceReadyEvt_t; + + +typedef struct{ + u16 aclHandle; + u16 muteHandle; + + u8 muteValue; + u8 aicsCount; + #if (BLC_AUDIO_VCS_AICS_ENABLE) + blc_audio_aicsServiceReadyEvt_t aics[BLC_AUDIO_VCS_AICS_COUNT]; + #endif +}blc_audio_micpServiceReadyEvt_t; +typedef struct{ + u16 aclHandle; + u16 muteHandle; + u8 muteValue; +}blc_audio_micpMuteChangeEvt_t; + + +typedef struct{ + u16 aclHandle; + u16 ctlHandle; + u16 statHandle; + u16 flagHandle; + + u8 mute; + u8 volume; + u8 counter; + u8 flagValue; + u8 aicsCount; + u8 vocsCount; + #if (BLC_AUDIO_VCS_AICS_ENABLE) + blc_audio_aicsServiceReadyEvt_t aics[BLC_AUDIO_VCS_AICS_COUNT]; + #endif + #if (BLC_AUDIO_VOCS_ENABLE) + blc_audio_vocsServiceReadyEvt_t vocs[BLC_AUDIO_VCS_VOCS_COUNT]; + #endif +}blc_audio_vcpServiceReadyEvt_t; + + +typedef struct{ + u16 aclHandle; + u16 cisHandle; +}blc_audio_mcpServiceReadyEvt_t; +typedef struct{ + u16 aclHandle; + u16 attHandle; + u8 opcode; //Refer to BLC_AUDIO_MCP_OPCODE_ENUM + u8 dataLen; + u8 *pData; +}blc_audio_mcpCtrlEvt_t; +typedef struct{ + u16 aclHandle; + u16 attHandle; + u8 state; //Refer to BLC_AUDIO_MEDIA_STATE_ENUM +}blc_audio_mcpStateEvt_t; + + +typedef struct{ + u16 CCIDHandle; + u16 inCallHandle; + u16 callCtrlHandle; + u16 provNameHandle; + u16 callerIDHandle; + u16 callStateHandle; + u16 bearerTechHandle; + u16 CCPOpcodesHandle; + u16 termReasonHandle; + u16 curCallListHandle; +}blc_audio_tbpServiceReadyEvt_t; +typedef struct{ + u8 index; + u8 state; + u8 callFlags; +}blc_audio_tbpCallStateEvt_t; + + +#endif //#if (BLC_AUDIO_PROFILE_EN) + +#endif // diff --git a/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_tbp.h b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_tbp.h new file mode 100755 index 0000000..cd9eb8e --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_tbp.h @@ -0,0 +1,102 @@ +/******************************************************************************************************** + * @file audio_tbs.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef _AUDIO_TBS_H_ +#define _AUDIO_TBS_H_ + +#if (BLC_AUDIO_TBS_ENABLE) + + +#define BLT_AUDIO_TBP_CALL_INVALID_STATE 0xFF + + +typedef enum{ + BLT_AUDIO_TBP_FLAG_NONE = 0x00, + BLT_AUDIO_TBP_FLAG_NOTY_STATE = 0x01, + BLT_AUDIO_TBP_FLAG_NOTY_CALL = 0x02, + BLT_AUDIO_TBP_FLAG_NOTY_CPRST = 0x04, + BLT_AUDIO_TBP_FLAG_NOTY_SIGNAL = 0x08, + BLT_AUDIO_TBP_FLAG_NOTY_PRNAME = 0x10, //Provide Name + BLT_AUDIO_TBP_FLAG_NOTY_BRTECH = 0x20, //Bearer Technology + BLT_AUDIO_TBP_FLAG_NOTY_STATUS = 0x40, //Status Flags +}BLT_AUDIO_TBP_FLAGS_ENUM; + +typedef enum{ + BLT_AUDIO_TBP_CALL_FLAG_NONE = 0x00, + BLT_AUDIO_TBP_CALL_FLAG_NOTY_STATE = 0x01, + BLT_AUDIO_TBP_CALL_FLAG_NOTY_ALL_STATE = 0x02, + BLT_AUDIO_TBP_CALL_FLAG_NOTY_INCALL = 0x04, + BLT_AUDIO_TBP_CALL_FLAG_NOTY_NAME = 0x08, + BLT_AUDIO_TBP_CALL_FLAG_NOTY_INCALL_URI = 0x10, + BLT_AUDIO_TBP_CALL_FLAG_NOTY_TERMINATION = 0x20, +}BLT_AUDIO_TBP_CALL_FLAGS_ENUM; + + +typedef enum{ + BLT_AUDIO_TBP_TERM_REASON_URI_ERROR = 0x00, + BLT_AUDIO_TBP_TERM_REASON_CALL_FAILED = 0x01, + BLT_AUDIO_TBP_TERM_REASON_REMOTE_ENDED_CALL = 0x02, + BLT_AUDIO_TBP_TERM_REASON_SERVER_ENDED_CALL = 0x03, + BLT_AUDIO_TBP_TERM_REASON_LINE_BUSY = 0x04, + BLT_AUDIO_TBP_TERM_REASON_NETWORK_CONGESTION = 0x05, + BLT_AUDIO_TBP_TERM_REASON_CLIENT_TERM_CALL = 0x06, + BLT_AUDIO_TBP_TERM_REASON_NO_SERVICE = 0x07, + BLT_AUDIO_TBP_TERM_REASON_NO_ANSWER = 0x08, + BLT_AUDIO_TBP_TERM_REASON_UNSPECIFIED = 0x09, +}BLT_AUDIO_TBP_TERM_REASON_ENUM; + +typedef enum{ + BLT_AUDIO_TBP_CP_RSTCODE_SUCCESS = 0x00, //The opcode write was successful. + BLT_AUDIO_TBP_CP_RSTCODE_OPCODE_NOT_SUPPORTED = 0x01, //An invalid opcode was used for the Call Control Point write. + BLT_AUDIO_TBP_CP_RSTCODE_OPERATION_NOT_POSSIBLE = 0x02, //The requested operation cannot be completed. + BLT_AUDIO_TBP_CP_RSTCODE_INVALID_CALL_INDEX = 0x03, //The Call Index used for the Call Control Point write is invalid. + BLT_AUDIO_TBP_CP_RSTCODE_STATE_MISMATCH = 0x04, //The opcode written to the Call Control Point was received when the current Call State for the Call Index was not in the expected state. + BLT_AUDIO_TBP_CP_RSTCODE_LACK_OF_RESOURCES = 0x05, //Lack of internal resources to complete the requested action. + BLT_AUDIO_TBP_CP_RSTCODE_INVALID_OUTGOING_URI = 0x06, //The Outgoing URI is incorrect or invalid when an Originate opcode is sent. +}BLT_AUDIO_TBP_CP_RSTCODE_ENUM; + + +int blc_audio_tbpAttRead(u16 connHandle, void* p); +int blc_audio_tbpAttWrite(u16 connHandle, void* p); + +int blc_audio_tbpEnable(u16 connHandle); +int blc_audio_tbpDisable(u16 connHandle); + +int blc_audio_tbpSendCtrl(u16 connHandle, u8 opcode, u8 *pData, u8 dataLen); + +int blc_audio_tbpAccept(u16 connHandle, u8 callIndex); +int blc_audio_tbpTerminal(u16 connHandle, u8 callIndex); +int blc_audio_tbpAlerting(u16 connHandle, u8 callIndex); +int blc_audio_tbpCallHold(u16 connHandle, u8 callIndex); +int blc_audio_tbpCallRetrieve(u16 connHandle, u8 callIndex); +int blc_audio_tbpAddIncomingCall(u16 connHandle, u8 *pURI, u8 URILen, u8 *pName, u8 nameLen); + +int blc_audio_tbpSetSignalStrength(u16 connHandle, u8 value); +int blc_audio_tbpSetProvideName(u16 connHandle, u8 *pName, u8 nameLen); +int blc_audio_tbpSetBearerTechnology(u16 connHandle, u8 value); +int blc_audio_tbpSetStatusFlags(u16 connHandle, u16 value); + + +#endif //#if (BLC_AUDIO_TBS_ENABLE) + +#endif + diff --git a/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_vcp.h b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_vcp.h new file mode 100755 index 0000000..6a81683 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/profile/audio/audio_vcp.h @@ -0,0 +1,145 @@ +/******************************************************************************************************** + * @file audio_vcp.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef _AUDIO_VCP_H_ +#define _AUDIO_VCP_H_ + +#if (BLC_AUDIO_VCP_ENABLE) + + + +typedef enum{ + BLT_VCP_OPCODE_RELATIVE_VOLUME_DOWN = 0x00, + BLT_VCP_OPCODE_RELATIVE_VOLUME_UP = 0x01, + BLT_VCP_OPCODE_UNMUTE_RELATIVE_VOLUME_DOWN = 0x02, + BLT_VCP_OPCODE_UNMUTE_RELATIVE_VOLUME_UP = 0x03, + BLT_VCP_OPCODE_SET_ABSOLUTE_VOLUME = 0x04, + BLT_VCP_OPCODE_UNMUTE = 0x05, + BLT_VCP_OPCODE_MUTE = 0x06, +}BLT_VCP_OPCODE_ENUM; +typedef enum{ + BLT_VCP_ERRCODE_INVALID_CHANGE_COUNTER = 0x80, + BLT_VCP_ERRCODE_OPCODE_NOT_SUPPORTED = 0x81, +}BLT_VCP_ERRCODE_ENUM; + +typedef enum{ + BLT_VCP_AICS_OPCODE_SET_GAIN_VALUE = 0x01, + BLT_VCP_AICS_OPCODE_UNMUTE = 0x02, + BLT_VCP_AICS_OPCODE_MUTE = 0x03, + BLT_VCP_AICS_OPCODE_MANU_GAIN_MODE = 0x04, + BLT_VCP_AICS_OPCODE_AUTO_GAIN_MODE = 0x05, +}BLT_VCP_AICS_OPCODE_ENUM; +typedef enum{ + BLT_VCP_AICS_ERRCODE_INVALID_CHANGE_COUNTER = 0x80, + BLT_VCP_AICS_ERRCODE_OPCODE_NOT_SUPPORTED = 0x81, + BLT_VCP_AICS_ERRCODE_MUTE_DISABLED = 0x82, + BLT_VCP_AICS_ERRCODE_VALUE_OUT_OF_RANGE = 0x83, + BLT_VCP_AICS_ERRCODE_MODE_CHANGE_NOT_ALLOWED = 0x84, +}BLT_VCP_AICS_ERRCODE_ENUM; + +typedef enum{ + BLT_VCP_VOCS_OPCODE_SET_VOLUME_OFFSET = 0x01, +}BLT_VCP_VOCS_OPCODE_ENUM; +typedef enum{ + BLT_VCP_VOCS_ERRCODE_INVALID_CHANGE_COUNTER = 0x80, + BLT_VCP_VOCS_ERRCODE_OPCODE_NOT_SUPPORTED = 0x81, + BLT_VCP_VOCS_ERRCODE_VALUE_OUT_OF_RANGE = 0x82, +}BLT_VCP_VOCS_ERRCODE_ENUM; + + +typedef enum{ + BLT_AUDIO_VCP_SDP_FLAG_NONE = 0x00, + BLT_AUDIO_VCP_SDP_FLAG_FIRST = 0x80, + BLT_AUDIO_VCP_SDP_FLAG_INIT = 0x40, + BLT_AUDIO_VCP_SDP_FLAG_AICS = 0x20, + BLT_AUDIO_VCP_SDP_FLAG_VOCS = 0x10, + BLT_AUDIO_VCP_SDP_FLAG_READY = 0x08, + + BLT_AUDIO_VCP_SDP_FLAG_PVAL = 0x04, + BLT_AUDIO_VCP_SDP_FLAG_SVAL = 0x02, +}BLT_AUDIO_VCP_SDP_FLAGS_ENUM; + +typedef enum{ + BLT_AUDIO_VCP_FLAG_NONE = 0x00, + BLT_AUDIO_VCP_FLAG_STATE_CHANGE = 0x01, + BLT_AUDIO_VCP_FLAG_FLAGS_CHANGE = 0x02, + BLT_AUDIO_VCP_FLAG_AICS_CHANGE = 0x04, + BLT_AUDIO_VCP_FLAG_VOCS_CHANGE = 0x08, +}BLT_AUDIO_VCP_FLAGS_ENUM; + +typedef enum{ + BLT_AUDIO_VCP_AICS_FLAG_NONE = 0x00, + BLT_AUDIO_VCP_AICS_FLAG_STATE_CHANGE = 0x01, + BLT_AUDIO_VCP_AICS_FLAG_STATUS_CHANGE = 0x02, + BLT_AUDIO_VCP_AICS_FLAG_DESC_CHANGE = 0x04, +}BLT_AUDIO_VCP_AICS_FLAGS_ENUM; +typedef enum{ + BLT_AUDIO_VCP_VOCS_FLAG_NONE = 0x00, + BLT_AUDIO_VCP_VOCS_FLAG_STATE_CHANGE = 0x01, + BLT_AUDIO_VCP_VOCS_FLAG_LOCA_CHANGE = 0x02, + BLT_AUDIO_VCP_VOCS_FLAG_DESC_CHANGE = 0x04, +}BLT_AUDIO_VCP_VOCS_FLAGS_ENUM; + + +int blc_audio_vcpAttRead(u16 connHandle, void* p); +int blc_audio_vcpAttWrite(u16 connHandle, void* p); +int blc_audio_vcpSetVolume(u16 connHandle, u8 volume); +int blc_audio_vcpSetMute(u16 connHandle, u8 mute); +int blc_audio_vcpSetCounter(u16 connHandle, u8 counter); +#if (BLC_AUDIO_VOCS_ENABLE) +int blc_audio_vcpVocsSetCounter(u16 connHandle, u8 counter, int num); +int blc_audio_vcpVocsSetAllCounter(u16 connHandle, u8 counter); +int blc_audio_vcpVocsSetLocation(u16 connHandle, u32 location, int num); +int blc_audio_vcpVocsSetDescrible(u16 connHandle, u8 *pDesc, u8 length, int num); +#if (BLC_AUDIO_VCS_AICS_ENABLE) +int blc_audio_vcpAicsSetCounter(u16 connHandle, u8 counter, int num); +int blc_audio_vcpAicsSetAllCounter(u16 connHandle, u8 counter); +int blc_audio_vcpAicsSetMute(u16 connHandle, u8 mute, int num); +int blc_audio_vcpAicsSetAllMute(u16 connHandle, u8 mute); +int blc_audio_vcpAicsSetGainMode(u16 connHandle, u8 gainMode, int num); +int blc_audio_vcpAicsSetAllGainMode(u16 connHandle, u8 gainMode); +int blc_audio_vcpAicsSetDescrible(u16 connHandle, u8 *pDesc, u8 length, int num); +#endif +#endif + + + +static int blt_audio_vcpInit(blt_audio_handle_t *pHandle); +static int blt_audio_vcpGattIn(blt_audio_handle_t *pHandle, u8 *pPkt); +static int blt_audio_vcpSetServ(blt_audio_handle_t *pHandle, attribute_t *pService); +static void blt_audio_vcpSetConn(blt_audio_handle_t *pHandle, BLC_AUDIO_STATE_ENUM state); +static void blt_audio_vcpProcess(blt_audio_handle_t *pHandle); + +static int blt_audio_vcpSetVcsServ(blt_audio_handle_t *pHandle, attribute_t *pService); +static int blt_audio_vcpWriteVcs(blt_audio_handle_t *pHandle, u8 opcode, u8 dataLen, u8 *pData); +#if (BLC_AUDIO_VCS_AICS_ENABLE) +static int blt_audio_vcpSetAicsServ(blt_audio_handle_t *pHandle, attribute_t *pService); +static int blt_audio_vcpWriteAics(blt_audio_handle_t *pHandle, blt_audio_aics_t *pAics, u8 opcode, u8 dataLen, u8 *pData); +#endif +#if (BLC_AUDIO_VOCS_ENABLE) +static int blt_audio_vcpSetVocsServ(blt_audio_handle_t *pHandle, attribute_t *pService); +static int blt_audio_vcpWriteVocs(blt_audio_handle_t *pHandle, blt_audio_vocs_t *pVocs, u8 opcode, u8 dataLen, u8 *pData); +#endif + +#endif //#if (BLC_AUDIO_VCP_ENABLE) + +#endif diff --git a/b91/b91m_ble_sdk/stack/ble/service/device_information.h b/b91/b91m_ble_sdk/stack/ble/service/device_information.h new file mode 100755 index 0000000..e6ba851 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/service/device_information.h @@ -0,0 +1,37 @@ +/******************************************************************************************************** + * @file device_information.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + + +/** + * @brief device_char_uuid Device Information Characteristic UUID + */ +#define CHARACTERISTIC_UUID_MANU_NAME_STRING 0x2A29 +#define CHARACTERISTIC_UUID_MODEL_NUM_STRING 0x2A24 +#define CHARACTERISTIC_UUID_SERIAL_NUM_STRING 0x2A25 +#define CHARACTERISTIC_UUID_HW_REVISION_STRING 0x2A27 +#define CHARACTERISTIC_UUID_FW_REVISION_STRING 0x2A26 +#define CHARACTERISTIC_UUID_SW_REVISION_STRING 0x2A28 +#define CHARACTERISTIC_UUID_SYSTEM_ID 0x2A23 +#define CHARACTERISTIC_UUID_IEEE_11073_CERT_LIST 0x2A2A +#define CHARACTERISTIC_UUID_PNP_ID 0x2A50 diff --git a/b91/b91m_ble_sdk/stack/ble/service/hids.h b/b91/b91m_ble_sdk/stack/ble/service/hids.h new file mode 100755 index 0000000..806b2d9 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/service/hids.h @@ -0,0 +1,80 @@ +/******************************************************************************************************** + * @file hids.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + + +/** + * @brief hids_uuid Hids Characteristic UUID + */ +#define CHARACTERISTIC_UUID_HID_BOOT_KEY_INPUT 0x2A22 //!< HID Boot Keyboard Input Report +#define CHARACTERISTIC_UUID_HID_BOOT_KEY_OUTPUT 0x2A32 //!< HID Boot Keyboard Output Report +#define CHARACTERISTIC_UUID_HID_BOOT_MOUSE_INPUT 0x2A33 //!< HID Boot Mouse Input Report +#define CHARACTERISTIC_UUID_HID_INFORMATION 0x2A4A //!< HID Information +#define CHARACTERISTIC_UUID_HID_REPORT_MAP 0x2A4B //!< HID Report Map +#define CHARACTERISTIC_UUID_HID_CONTROL_POINT 0x2A4C //!< HID Control Point +#define CHARACTERISTIC_UUID_HID_REPORT 0x2A4D //!< HID Report +#define CHARACTERISTIC_UUID_HID_PROTOCOL_MODE 0x2A4E //!< HID Protocol Mode + + +/** + * @brief HID Report ID + */ +#define HID_REPORT_ID_KEYBOARD_INPUT 1 //!< Keyboard input report ID +#define HID_REPORT_ID_CONSUME_CONTROL_INPUT 2 //!< Consumer Control input report ID +#define HID_REPORT_ID_MOUSE_INPUT 3 //!< Mouse input report ID +#define HID_REPORT_ID_GAMEPAD_INPUT 4 //!< Gamepad input report ID +#define HID_REPORT_ID_LED_OUT 0 //!< LED output report ID +#define HID_REPORT_ID_FEATURE 0 //!< Feature report ID + +#define HID_REPORT_ID_CTRL_VOICE 9 + +#define HID_REPORT_ID_AUDIO_FIRST_INPUT 10//250 +#define HID_REPORT_ID_AUDIO_SECND_INPUT 11//251 +#define HID_REPORT_ID_AUDIO_THIRD_INPUT 12//247 + + + +/** + * @brief HID Report type + */ + +#define HID_REPORT_TYPE_INPUT 1 +#define HID_REPORT_TYPE_OUTPUT 2 +#define HID_REPORT_TYPE_FEATURE 3 + + + +/** + * @brief Definition for HID protocol mode + */ +#define HID_PROTOCOL_MODE_BOOT 0 +#define HID_PROTOCOL_MODE_REPORT 1 +#define DFLT_HID_PROTOCOL_MODE HID_PROTOCOL_MODE_REPORT + + + +/** + * @brief Definition for HID information flags + */ +#define HID_FLAGS_REMOTE_WAKE 0x01 // RemoteWake +#define HID_FLAGS_NORMALLY_CONNECTABLE 0x02 // NormallyConnectable diff --git a/b91/b91m_ble_sdk/stack/ble/service/ota/ota.h b/b91/b91m_ble_sdk/stack/ble/service/ota/ota.h new file mode 100755 index 0000000..ec93560 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/service/ota/ota.h @@ -0,0 +1,157 @@ +/******************************************************************************************************** + * @file ota.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef OTA_H_ +#define OTA_H_ + + +/** + * @brief Legacy OTA command + */ +#define CMD_OTA_VERSION 0xFF00 //client -> server +#define CMD_OTA_START 0xFF01 //client -> server +#define CMD_OTA_END 0xFF02 //client -> server + +/** + * @brief Extended OTA command, optional + */ +#define CMD_OTA_START_EXT 0xFF03 //client -> server +#define CMD_OTA_FW_VERSION_REQ 0xFF04 //client -> server +#define CMD_OTA_FW_VERSION_RSP 0xFF05 //server -> client +#define CMD_OTA_RESULT 0xFF06 //server -> client + + + + +/** + * @brief Multiple boot address enumeration + */ +typedef enum{ + MULTI_BOOT_ADDR_0x20000 = 0x20000, //128 K + MULTI_BOOT_ADDR_0x40000 = 0x40000, //256 K + MULTI_BOOT_ADDR_0x80000 = 0x80000, //512 K +}multi_boot_addr_e; + + + +/** + * @brief OTA result + */ +enum{ + //0x00 + OTA_SUCCESS = 0, //success + OTA_DATA_PACKET_SEQ_ERR, //OTA data packet sequence number error: repeated OTA PDU or lost some OTA PDU + OTA_PACKET_INVALID, //invalid OTA packet: 1. invalid OTA command; 2. addr_index out of range; 3.not standard OTA PDU length + OTA_DATA_CRC_ERR, //packet PDU CRC err + + //0x04 + OTA_WRITE_FLASH_ERR, //write OTA data to flash ERR + OTA_DATA_UNCOMPLETE, //lost last one or more OTA PDU + OTA_FLOW_ERR, //peer device send OTA command or OTA data not in correct flow + OTA_FW_CHECK_ERR, //firmware CRC check error + + //0x08 + OTA_VERSION_COMPARE_ERR, //the version number to be update is lower than the current version + OTA_PDU_LEN_ERR, //PDU length error: not 16*n, or not equal to the value it declare in "CMD_OTA_START_EXT" packet + OTA_FIRMWARE_MARK_ERR, //firmware mark error: not generated by telink's BLE SDK + OTA_FW_SIZE_ERR, //firmware size error: no firmware_size; firmware size too small or too big + + //0x0C + OTA_DATA_PACKET_TIMEOUT, //time interval between two consequent packet exceed a value(user can adjust this value) + OTA_TIMEOUT, //OTA flow total timeout + OTA_FAIL_DUE_TO_CONNECTION_TERMIANTE, //OTA fail due to current connection terminate(maybe connection timeout or local/peer device terminate connection) +}; + + + + +/** + * @brief data structure of OTA command "CMD_OTA_START" + */ +typedef struct { + u16 ota_cmd; +} ota_start_t; + +/** + * @brief data structure of OTA command "CMD_OTA_START_EXT" + */ +typedef struct { + u16 ota_cmd; + u8 pdu_length; //must be: 16*n(n is in range of 1 ~ 15); pdu_length: 16,32,48,...240 + u8 version_compare; //0: no version compare; 1: only higher version can replace lower version +} ota_startExt_t; + + +/** + * @brief data structure of OTA command "CMD_OTA_END" + */ +typedef struct { + u16 ota_cmd; + u16 adr_index_max; + u16 adr_index_max_xor; +} ota_end_t; + + +/** + * @brief data structure of OTA command "CMD_OTA_RESULT" + */ +typedef struct { + u16 ota_cmd; + u8 result; +} ota_result_t; + + + +/** + * @brief data structure of OTA command "CMD_OTA_FW_VERSION_REQ" + */ +typedef struct { + u16 ota_cmd; + u16 version_num; + u8 version_compare; //1: only higher version can replace lower version +} ota_versionReq_t; + + +/** + * @brief data structure of OTA command "CMD_OTA_FW_VERSION_RSP" + */ +typedef struct { + u16 ota_cmd; + u16 version_num; + u8 version_accept; //1: accept firmware update; 0: reject firmware update(version compare enable, and compare result: fail) +} ota_versionRsp_t; + + + +typedef struct{ + u16 adr_index; + u8 data[16]; + u16 crc_16; +}ota_pdu16_t; + + +unsigned long crc32_half_cal(unsigned long crc, unsigned char* input, unsigned long* table, int len); +unsigned long crc32_cal(unsigned long crc, unsigned char* input, unsigned long* table, int len); + + + +#endif /* OTA_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/service/ota/ota_server.h b/b91/b91m_ble_sdk/stack/ble/service/ota/ota_server.h new file mode 100755 index 0000000..f6eca95 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/service/ota/ota_server.h @@ -0,0 +1,160 @@ +/******************************************************************************************************** + * @file ota_server.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#ifndef STACK_BLE_SERVICE_OTA_OTA_SERVER_H_ +#define STACK_BLE_SERVICE_OTA_OTA_SERVER_H_ + + + + +/** + * @brief OTA start command callback declaration + */ +typedef void (*ota_startCb_t)(void); + +/** + * @brief OTA version callback declaration + */ +typedef void (*ota_versionCb_t)(void); + +/** + * @brief OTA result indicate callback declaration + * @param[in] result - OTA result + */ +typedef void (*ota_resIndicateCb_t)(int result); + + + + + +/** + * @brief this function is used for user to initialize OTA server module. + * //attention: this API must called before any other OTA relative settings. + * @param none + * @return none + */ +void blc_ota_initOtaServer_module(void); + + + + + +/** + * @brief This function is used to set OTA new firmware storage address on Flash. + * note: this function must be called before "sys_init" or "cpu_wakeup_init". + * @param[in] firmware_size_k - set the firmware size. i.e. OTA erase flash size.note: unit is 1K(1024B) + * @param[in] new_fw_addr - new firmware storage address, 1.choose from multiple boot address + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ota_setFirmwareSizeAndBootAddress(int firmware_size_k, multi_boot_addr_e new_fw_addr); + + + + +/** + * @brief This function is used to set OTA firmware version number. + * if user use version compare to decide if OTA update, should use this API to set firmware version. + * @param[in] version_number - firmware version number + * @return none + */ +void blc_ota_setFirmwareVersionNumber(u16 version_number); + + + + + + + + + + +/** + * @brief This function is used to register OTA start command callback. + * when local device receive OTA command "CMD_OTA_START" and "CMD_OTA_START_EXT" form peer device, + * after checking all parameters are correct, local device will enter OTA update and trigger OTA start command callback. + * @param[in] cb - callback function + * @return none + */ +void blc_ota_registerOtaStartCmdCb(ota_startCb_t cb); + + + + + + +/** + * @brief This function is used to register OTA version command callback + * when local device receive OTA command "CMD_OTA_VERSION", trigger this callback. + * @param[in] cb - callback function + * @return none + */ +void blc_ota_registerOtaFirmwareVersionReqCb(ota_versionCb_t cb); + + + + + +/** + * @brief This function is used to register OTA result indication callback + * @param[in] cb - callback function + * @return none + */ +void blc_ota_registerOtaResultIndicationCb(ota_resIndicateCb_t cb); + + + + +/** + * @brief This function is used to set OTA whole process timeout value + * if not set, default value is 30 S + * @param[in] timeout_second - timeout value, unit: S, should in range of 4 ~ 250 + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ota_setOtaProcessTimeout(int timeout_second); + + + +/** + * @brief This function is used to set OTA packet interval timeout value + * if not set, default value is 5 S + * @param[in] timeout_ms - timeout value, unit: mS, should in range of 1 ~ 20 + * @return Status - 0x00: command succeeded; 0x01-0xFF: command failed + */ +ble_sts_t blc_ota_setOtaDataPacketTimeout(int timeout_second); + + + +/** + * @brief This function is used to write OTA data to flash + * @param[in] connHandle - ACL connection handle + * @return p - GATT data buffer pointer of write_req or write_cmd + */ +int otaWrite(u16 connHandle, void * p); + + + + + + + +#endif /* STACK_BLE_SERVICE_OTA_OTA_SERVER_H_ */ diff --git a/b91/b91m_ble_sdk/stack/ble/service/uuid.h b/b91/b91m_ble_sdk/stack/ble/service/uuid.h new file mode 100755 index 0000000..adeb2c9 --- /dev/null +++ b/b91/b91m_ble_sdk/stack/ble/service/uuid.h @@ -0,0 +1,117 @@ +/******************************************************************************************************** + * @file uuid.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef SERVICE_UUID_H_ +#define SERVICE_UUID_H_ + + +/** + * @brief GATT 16 bit UUID definition + */ +#define GATT_UUID_PRIMARY_SERVICE 0x2800 //!< Primary Service +#define GATT_UUID_SECONDARY_SERVICE 0x2801 //!< Secondary Service +#define GATT_UUID_INCLUDE 0x2802 //!< Include +#define GATT_UUID_CHARACTER 0x2803 //!< Characteristic +#define GATT_UUID_CHAR_EXT_PROPS 0x2900 //!< Characteristic Extended Properties +#define GATT_UUID_CHAR_USER_DESC 0x2901 //!< Characteristic User Description +#define GATT_UUID_CLIENT_CHAR_CFG 0x2902 //!< Client Characteristic Configuration +#define GATT_UUID_SERVER_CHAR_CFG 0x2903 //!< Server Characteristic Configuration +#define GATT_UUID_CHAR_PRESENT_FORMAT 0x2904 //!< Characteristic Present Format +#define GATT_UUID_CHAR_AGG_FORMAT 0x2905 //!< Characteristic Aggregate Format +#define GATT_UUID_VALID_RANGE 0x2906 //!< Valid Range +#define GATT_UUID_EXT_REPORT_REF 0x2907 //!< External Report Reference +#define GATT_UUID_REPORT_REF 0x2908 //!< Report Reference + +#define GATT_UUID_DEVICE_NAME 0x2a00 //!< Report Reference +#define GATT_UUID_APPEARANCE 0x2a01 +#define GATT_UUID_PERI_CONN_PARAM 0x2a04 +#define GATT_UUID_SERVICE_CHANGE 0x2a05 +#define GATT_UUID_BATTERY_LEVEL 0x2A19 +#define GATT_UUID_FIRMWARE_VER 0x2a26 //! +#include + + +#include "config.h" +#include "common/types.h" +#include "common/bit.h" +#include "common/static_assert.h" +#include "common/utility.h" +#include "common/usb_dbg/myudb.h" +#include "common/usb_dbg/log_def_stack.h" + + +#include "application/print/printf.h" + +#include "vendor/common/user_config.h" +#include "vendor/common/blt_common.h" +#include "vendor/common/blt_fw_sign.h" +#include "vendor/common/blt_led.h" +#include "vendor/common/blt_soft_timer.h" +#include "vendor/common/custom_pair.h" +#include "vendor/common/device_manage.h" +#include "vendor/common/simple_sdp.h" +#include "vendor/common/flash_fw_check.h" +#include "vendor/common/common_dbg.h" + +#include "gpio_default.h" + +#endif /* TL_COMMON_H_ */ diff --git a/b91/b91m_ble_sdk/vendor/common/app_common.h b/b91/b91m_ble_sdk/vendor/common/app_common.h new file mode 100755 index 0000000..4b2df21 --- /dev/null +++ b/b91/b91m_ble_sdk/vendor/common/app_common.h @@ -0,0 +1,44 @@ +/******************************************************************************************************** + * @file app_common.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#ifndef VENDOR_COMMON_APP_COMMON_H_ +#define VENDOR_COMMON_APP_COMMON_H_ + + +#include "blt_common.h" + +#include "device_manage.h" + +#include "simple_sdp.h" + +#include "custom_pair.h" + +#include "blt_fw_sign.h" + +#include "flash_fw_check.h" + +#include "blt_soft_timer.h" + +#include "common_dbg.h" + +#endif /* VENDOR_COMMON_APP_COMMON_H_ */ diff --git a/b91/b91m_ble_sdk/vendor/common/blt_common.c b/b91/b91m_ble_sdk/vendor/common/blt_common.c new file mode 100755 index 0000000..67d9873 --- /dev/null +++ b/b91/b91m_ble_sdk/vendor/common/blt_common.c @@ -0,0 +1,154 @@ +/******************************************************************************************************** + * @file blt_common.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "tl_common.h" +#include "drivers.h" +#include "blt_common.h" +#include "stack/ble/ble.h" + + +const u8 vendor_OtaUUID[16] = WRAPPING_BRACES(TELINK_SPP_DATA_OTA); + +#if (MCU_CORE_TYPE == MCU_CORE_9518) + /* default flash is 1M + * for 1M Flash, flash_sector_mac_address equals to 0xFF000 + * for 2M Flash, flash_sector_mac_address equals to 0x1FF000 */ + _attribute_ble_data_retention_ u32 flash_sector_mac_address = CFG_ADR_MAC_1M_FLASH; + _attribute_ble_data_retention_ u32 flash_sector_calibration = CFG_ADR_CALIBRATION_1M_FLASH; +#else + /* default flash is 512K + * for 512K Flash, flash_sector_mac_address equals to 0x76000 + * for 1M Flash, flash_sector_mac_address equals to 0xFF000 + * for 2M Flash, flash_sector_mac_address equals to 0x1FF000 */ + _attribute_ble_data_retention_ u32 flash_sector_mac_address = CFG_ADR_MAC_512K_FLASH; + _attribute_ble_data_retention_ u32 flash_sector_calibration = CFG_ADR_CALIBRATION_512K_FLASH; +#endif + + + + + +/** + * @brief This function can automatically recognize the flash size, + * and the system selects different customized sector according + * to different sizes. + * @param[in] none + * @return none + */ +_attribute_no_inline_ +void blc_readFlashSize_autoConfigCustomFlashSector(void) +{ + u8 temp_buf[4]; + flash_read_mid(temp_buf); + u8 flash_cap = temp_buf[2]; + + if(flash_cap == FLASH_CAPACITY_512K){ + flash_sector_mac_address = CFG_ADR_MAC_512K_FLASH; + flash_sector_calibration = CFG_ADR_CALIBRATION_512K_FLASH; + } + else if(flash_cap == FLASH_CAPACITY_1M){ + flash_sector_mac_address = CFG_ADR_MAC_1M_FLASH; + flash_sector_calibration = CFG_ADR_CALIBRATION_1M_FLASH; + } + else if(flash_cap == FLASH_CAPACITY_2M){ + flash_sector_mac_address = CFG_ADR_MAC_2M_FLASH; + flash_sector_calibration = CFG_ADR_CALIBRATION_2M_FLASH; + } + else{ + //This SDK do not support flash size other than 512K/1M/2M + //If code stop here, please check your Flash + while(1); + } + + flash_set_capacity(flash_cap); +} + + + + +/* + *Kite: VVWWXX38C1A4YYZZ + *Vulture: VVWWXXD119C4YYZZ + *Eagle: VVWWXX + * public_mac: + * Kite : VVWWXX 38C1A4 + * Vulture : VVWWXX D119C4 + * Eagle : VVWWXX + * random_static_mac: VVWWXXYYZZ C0 + */ +/** + * @brief This function is used to initialize the MAC address + * @param[in] flash_addr - flash address for MAC address + * @param[in] mac_public - public address + * @param[in] mac_random_static - random static MAC address + * @return none + */ +_attribute_no_inline_ +void blc_initMacAddress(int flash_addr, u8 *mac_public, u8 *mac_random_static) +{ + if(flash_sector_mac_address == 0){ + return; + } + + + u8 mac_read[8]; + flash_read_page(flash_addr, 8, mac_read); + + u8 value_rand[5]; + generateRandomNum(5, value_rand); + + u8 ff_six_byte[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + if ( memcmp(mac_read, ff_six_byte, 6) ) { + memcpy(mac_public, mac_read, 6); //copy public address from flash + } + else{ //no public address on flash + mac_public[0] = value_rand[0]; + mac_public[1] = value_rand[1]; + mac_public[2] = value_rand[2]; + mac_public[3] = 0x38; //company id: 0xA4C138 + mac_public[4] = 0xC1; + mac_public[5] = 0xA4; + + flash_write_page (flash_addr, 6, mac_public); + } + + + + + + mac_random_static[0] = mac_public[0]; + mac_random_static[1] = mac_public[1]; + mac_random_static[2] = mac_public[2]; + mac_random_static[5] = 0xC0; //for random static + + u16 high_2_byte = (mac_read[6] | mac_read[7]<<8); + if(high_2_byte != 0xFFFF){ + memcpy( (u8 *)(mac_random_static + 3), (u8 *)(mac_read + 6), 2); + } + else{ + mac_random_static[3] = value_rand[3]; + mac_random_static[4] = value_rand[4]; + + flash_write_page (flash_addr + 6, 2, (u8 *)(mac_random_static + 3) ); + } +} + diff --git a/b91/b91m_ble_sdk/vendor/common/blt_common.h b/b91/b91m_ble_sdk/vendor/common/blt_common.h new file mode 100755 index 0000000..ecf0c04 --- /dev/null +++ b/b91/b91m_ble_sdk/vendor/common/blt_common.h @@ -0,0 +1,288 @@ +/******************************************************************************************************** + * @file blt_common.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef BLT_COMMON_H_ +#define BLT_COMMON_H_ + +#include "drivers.h" +#include "vendor/common/user_config.h" + + + +/** + * @brief 512 K Flash MAC address and calibration data area + */ +#if (MCU_CORE_TYPE == MCU_CORE_9518) + #define CFG_ADR_MAC_512K_FLASH 0x7F000 + #define CFG_ADR_CALIBRATION_512K_FLASH 0x7E000 +#else + #define CFG_ADR_MAC_512K_FLASH 0x76000 + #define CFG_ADR_CALIBRATION_512K_FLASH 0x77000 +#endif + +/** + * @brief 1 M Flash MAC address and calibration data area + */ +#define CFG_ADR_MAC_1M_FLASH 0xFF000 +#define CFG_ADR_CALIBRATION_1M_FLASH 0xFE000 + +/** + * @brief 2 M Flash MAC address and calibration data area + */ +#define CFG_ADR_MAC_2M_FLASH 0x1FF000 +#define CFG_ADR_CALIBRATION_2M_FLASH 0x1FE000 + + + + + + + +/** + * @brief Flash size type supported by this SDK + */ +#define FLASH_SIZE_512K 0x80000 +#define FLASH_SIZE_1M 0x100000 +#define FLASH_SIZE_2M 0x200000 + + +/** + * @brief Flash size default configuration(user can change in app_config.h) + */ +#if (MCU_CORE_TYPE == MCU_CORE_9518) + #ifndef FLASH_SIZE_CONFIG + #define FLASH_SIZE_CONFIG FLASH_SIZE_1M + #endif +#else + #ifndef FLASH_SIZE_CONFIG + #define FLASH_SIZE_CONFIG FLASH_SIZE_512K + #endif +#endif + + + + +/** + * @brief Flash using area default Configuration, user can change some of them in app_config.h + * CFG_ADR_MAC: BLE MAC address stored in flash, can not change this value + * CFG_ADR_CALIBRATION: some calibration data stored in flash, can not change this value + * FLASH_ADR_SMP_PAIRING & FLASH_SMP_PAIRING_MAX_SIZE: + * If Slave or Master SMP enable, use 16K flash for SMP pairing information storage. + * First 8K is for normal use, second 8K is a backup to guarantee SMP information never lose. + * use API blc_smp_configPairingSecurityInfoStorageAddressAndSize(FLASH_ADR_SMP_PAIRING, FLASH_SMP_PAIRING_MAX_SIZE) + * to set the two value. + * FLASH_ADR_CUSTOM_PAIRING & FLASH_CUSTOM_PAIRING_MAX_SIZE: + * If master role is used but master SMP not used, use this flash area to store bonding slave information for custom pair. + * FLASH_SDP_ATT_ADRRESS & FLASH_SDP_ATT_MAX_SIZE + * If master role use service discovery, use this flash area to store some critical information of peer GATT server. + + */ +#if(FLASH_SIZE_CONFIG == FLASH_SIZE_512K) + + /* MAC and calibration data area */ + #define CFG_ADR_MAC CFG_ADR_MAC_512K_FLASH //can not change this value + #define CFG_ADR_CALIBRATION CFG_ADR_CALIBRATION_512K_FLASH //can not change this value + + #if (MCU_CORE_TYPE == MCU_CORE_9518) + //TODO + #else + /* SMP paring and key information area */ + #ifndef FLASH_ADR_SMP_PAIRING + #define FLASH_ADR_SMP_PAIRING 0x78000 + #endif + + #ifndef FLASH_SMP_PAIRING_MAX_SIZE + #define FLASH_SMP_PAIRING_MAX_SIZE (2*4096) //normal 8K + backup 8K = 16K + #endif + + + /* bonding slave information for custom pair area */ + #ifndef FLASH_ADR_CUSTOM_PAIRING + #define FLASH_ADR_CUSTOM_PAIRING 0x7C000 + #endif + + #ifndef FLASH_CUSTOM_PAIRING_MAX_SIZE + #define FLASH_CUSTOM_PAIRING_MAX_SIZE 4096 + #endif + + + /* bonding slave GATT service critical information area */ + #ifndef FLASH_SDP_ATT_ADRRESS + #define FLASH_SDP_ATT_ADRRESS 0x7D000 //for master: store peer slave device's ATT handle + #endif + + #ifndef FLASH_SDP_ATT_MAX_SIZE + #define FLASH_SDP_ATT_MAX_SIZE (2*4096) //8K flash for ATT HANLDE storage + #endif + #endif + +#elif(FLASH_SIZE_CONFIG == FLASH_SIZE_1M) + + /* MAC and calibration data area */ + #define CFG_ADR_MAC CFG_ADR_MAC_1M_FLASH //can not change this value + #define CFG_ADR_CALIBRATION CFG_ADR_CALIBRATION_1M_FLASH //can not change this value + + /* SMP paring and key information area */ + #ifndef FLASH_ADR_SMP_PAIRING + #define FLASH_ADR_SMP_PAIRING 0xFA000 + #endif + + #ifndef FLASH_SMP_PAIRING_MAX_SIZE + #define FLASH_SMP_PAIRING_MAX_SIZE (2*4096) //normal 8K + backup 8K = 16K + #endif + + + /* bonding slave information for custom pair area */ + #ifndef FLASH_ADR_CUSTOM_PAIRING + #define FLASH_ADR_CUSTOM_PAIRING 0xF8000 + #endif + + #ifndef FLASH_CUSTOM_PAIRING_MAX_SIZE + #define FLASH_CUSTOM_PAIRING_MAX_SIZE 4096 + #endif + + + /* bonding slave GATT service critical information area */ + #ifndef FLASH_SDP_ATT_ADRRESS + #define FLASH_SDP_ATT_ADRRESS 0xF6000 //for master: store peer slave device's ATT handle + #endif + + #ifndef FLASH_SDP_ATT_MAX_SIZE + #define FLASH_SDP_ATT_MAX_SIZE (2*4096) //8K flash for ATT HANLDE storage + #endif + +#elif(FLASH_SIZE_CONFIG == FLASH_SIZE_2M) +/* MAC and calibration data area */ + #define CFG_ADR_MAC CFG_ADR_MAC_2M_FLASH //can not change this value + #define CFG_ADR_CALIBRATION CFG_ADR_CALIBRATION_2M_FLASH //can not change this value + + /* SMP paring and key information area */ + #ifndef FLASH_ADR_SMP_PAIRING + #define FLASH_ADR_SMP_PAIRING 0x1FA000 + #endif + + #ifndef FLASH_SMP_PAIRING_MAX_SIZE + #define FLASH_SMP_PAIRING_MAX_SIZE (2*4096) //normal 8K + backup 8K = 16K + #endif + + + /* bonding slave information for custom pair area */ + #ifndef FLASH_ADR_CUSTOM_PAIRING + #define FLASH_ADR_CUSTOM_PAIRING 0x1F8000 + #endif + + #ifndef FLASH_CUSTOM_PAIRING_MAX_SIZE + #define FLASH_CUSTOM_PAIRING_MAX_SIZE 4096 + #endif + + + /* bonding slave GATT service critical information area */ + #ifndef FLASH_SDP_ATT_ADRRESS + #define FLASH_SDP_ATT_ADRRESS 0x1F6000 //for master: store peer slave device's ATT handle + #endif + + #ifndef FLASH_SDP_ATT_MAX_SIZE + #define FLASH_SDP_ATT_MAX_SIZE (2*4096) //8K flash for ATT HANLDE storage + #endif +#endif + + + + + +/** Calibration Information FLash Address Offset of CFG_ADR_CALIBRATION_xx_FLASH ***/ +#define CALIB_OFFSET_CAP_INFO 0x00 +#define CALIB_OFFSET_TP_INFO 0x40 + +#define CALIB_OFFSET_ADC_VREF 0xC0 + +#define CALIB_OFFSET_FIRMWARE_SIGNKEY 0x180 + + + + + + +extern const u8 vendor_OtaUUID[]; +extern u32 flash_sector_mac_address; +extern u32 flash_sector_calibration; + + + + +/** + * @brief This function is used to enable the external crystal capacitor + * @param[in] en - enable the external crystal capacitor + * @return none + */ +static inline void blc_app_setExternalCrystalCapEnable(u8 en) +{ + blt_miscParam.ext_cap_en = en; + analog_write(0x8a, analog_read(0x8a) | 0x80);//disable internal cap +} + + +/** + * @brief This function is used to load customized parameters from flash sector for application + * @param[in] none + * @return none + */ +static inline void blc_app_loadCustomizedParameters(void) +{ + if(!blt_miscParam.ext_cap_en) + { + //customize freq_offset adjust cap value, if not customized, default ana_81 is 0xd0 + //for 512K Flash, flash_sector_calibration equals to 0x77000 + //for 1M Flash, flash_sector_calibration equals to 0xFE000 + if(flash_sector_calibration){ + u8 cap_frqoft; + flash_read_page(flash_sector_calibration + CALIB_OFFSET_CAP_INFO, 1, &cap_frqoft); + + if( cap_frqoft != 0xff ){ + analog_write(0x8A, (analog_read(0x8A) & 0xc0)|(cap_frqoft & 0x3f)); + } + } + } +} + +/** + * @brief This function can automatically recognize the flash size, + * and the system selects different customized sector according + * to different sizes. + * @param[in] none + * @return none + */ +void blc_readFlashSize_autoConfigCustomFlashSector(void); + +/** + * @brief This function is used to initialize the MAC address + * @param[in] flash_addr - flash address for MAC address + * @param[in] mac_public - public address + * @param[in] mac_random_static - random static MAC address + * @return none + */ +void blc_initMacAddress(int flash_addr, u8 *mac_public, u8 *mac_random_static); + + + + +#endif /* BLT_COMMON_H_ */ diff --git a/b91/b91m_ble_sdk/vendor/common/blt_fw_sign.c b/b91/b91m_ble_sdk/vendor/common/blt_fw_sign.c new file mode 100755 index 0000000..efce70c --- /dev/null +++ b/b91/b91m_ble_sdk/vendor/common/blt_fw_sign.c @@ -0,0 +1,51 @@ +/******************************************************************************************************** + * @file blt_fw_sign.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "tl_common.h" +#include "drivers.h" +#include "blt_fw_sign.h" +#include "blt_common.h" +#include "proj_lib/firmware_encrypt.h" + +/** + * @brief This function is used to check digital signature of firmware + * @param[in] none + * @return none + */ +void blt_firmware_signature_check(void) +{ + unsigned int flash_mid; + unsigned char flash_uid[16]; + unsigned char signature_enc_key[16]; + int flag = flash_read_mid_uid_with_check(&flash_mid, flash_uid); + + if(flag==0){ //reading flash UID error + while(1); + } + + firmware_encrypt_based_on_uid (flash_uid, signature_enc_key); + + /* must using "0x20000000 | address" when reading flash data by address pointer */ + if(memcmp(signature_enc_key, (u8*)(FLASH_R_BASE_ADDR | (flash_sector_calibration + CALIB_OFFSET_FIRMWARE_SIGNKEY)), 16)){ //signature not match + while(1); //user can change the code here to stop firmware running + } +} diff --git a/b91/b91m_ble_sdk/vendor/common/blt_fw_sign.h b/b91/b91m_ble_sdk/vendor/common/blt_fw_sign.h new file mode 100755 index 0000000..623fc67 --- /dev/null +++ b/b91/b91m_ble_sdk/vendor/common/blt_fw_sign.h @@ -0,0 +1,35 @@ +/******************************************************************************************************** + * @file blt_fw_sign.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef BLT_FW_SIGN_H_ +#define BLT_FW_SIGN_H_ + +/** + * @brief This function is used to check digital signature of firmware + * @param[in] none + * @return none + */ +void blt_firmware_signature_check(void); + + + +#endif /* BLT_FW_SIGNATURE_H_ */ diff --git a/b91/b91m_ble_sdk/vendor/common/blt_led.c b/b91/b91m_ble_sdk/vendor/common/blt_led.c new file mode 100755 index 0000000..3f0cc86 --- /dev/null +++ b/b91/b91m_ble_sdk/vendor/common/blt_led.c @@ -0,0 +1,132 @@ +/******************************************************************************************************** + * @file blt_led.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "tl_common.h" +#include "drivers.h" +#include "blt_led.h" + + + +device_led_t device_led; + +/** + * @brief This function is used to control device led on or off + * @param[in] on - the status of led + * @return none + */ +void device_led_on_off(u8 on) +{ + gpio_write( device_led.gpio_led, on^device_led.polar ); + gpio_set_output_en(device_led.gpio_led, on); + device_led.isOn = on; +} + + +/** + * @brief This function is used to initialize device led setting + * @param[in] gpio - the GPIO corresponding to device led + * @param[in] polarity - 1 for high led on, 0 for low led on + * @return none + */ +void device_led_init(u32 gpio,u8 polarity){ //polarity: 1 for high led on, 0 for low led on + +#if (BLT_APP_LED_ENABLE) + device_led.gpio_led = gpio; + device_led.polar = !polarity; + gpio_write( gpio, !polarity ); +#endif +} + +/** + * @brief This function is used to create new led task + * @param[in] led_cfg - Configure the parameters for led event + * @return 0 - new led event priority not higher than the not ongoing one + * 1 - new led event created successfully + */ +int device_led_setup(led_cfg_t led_cfg) +{ +#if (BLT_APP_LED_ENABLE) + if( device_led.repeatCount && device_led.priority >= led_cfg.priority){ + return 0; //new led event priority not higher than the not ongoing one + } + else{ + device_led.onTime_ms = led_cfg.onTime_ms; + device_led.offTime_ms = led_cfg.offTime_ms; + device_led.repeatCount = led_cfg.repeatCount; + device_led.priority = led_cfg.priority; + + if(led_cfg.repeatCount == 0xff){ //for long on/long off + device_led.repeatCount = 0; + } + else{ //process one of on/off Time is zero situation + if(!device_led.onTime_ms){ //onTime is zero + device_led.offTime_ms *= device_led.repeatCount; + device_led.repeatCount = 1; + } + else if(!device_led.offTime_ms){ + device_led.onTime_ms *= device_led.repeatCount; + device_led.repeatCount = 1; + } + } + + device_led.startTick = clock_time(); + device_led_on_off(device_led.onTime_ms ? 1 : 0); + + return 1; + } +#else + return 0; +#endif +} + +/** + * @brief This function is used to manage led tasks + * @param[in] none + * @return none + */ +void led_proc(void) +{ +#if (BLT_APP_LED_ENABLE) + if(device_led.isOn){ + if(clock_time_exceed(device_led.startTick,device_led.onTime_ms*1000)){ + device_led_on_off(0); + if(device_led.offTime_ms){ //offTime not zero + device_led.startTick += device_led.onTime_ms*SYSTEM_TIMER_TICK_1MS; + } + else{ + device_led.repeatCount = 0; + } + } + } + else{ + if(clock_time_exceed(device_led.startTick,device_led.offTime_ms*1000)){ + if(--device_led.repeatCount){ + device_led_on_off(1); + device_led.startTick += device_led.offTime_ms*SYSTEM_TIMER_TICK_1MS; + } + } + } +#endif +} + + + diff --git a/b91/b91m_ble_sdk/vendor/common/blt_led.h b/b91/b91m_ble_sdk/vendor/common/blt_led.h new file mode 100755 index 0000000..c68e96d --- /dev/null +++ b/b91/b91m_ble_sdk/vendor/common/blt_led.h @@ -0,0 +1,107 @@ +/******************************************************************************************************** + * @file blt_led.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef BLT_LED_H_ +#define BLT_LED_H_ + +#include "tl_common.h" + + + +#ifndef BLT_APP_LED_ENABLE +#define BLT_APP_LED_ENABLE 0 +#endif + + +/** + * @brief Configure the parameters for led event + */ +typedef struct{ + unsigned short onTime_ms; + unsigned short offTime_ms; + + unsigned char repeatCount; //0xff special for long on(offTime_ms=0)/long off(onTime_ms=0) + unsigned char priority; //0x00 < 0x01 < 0x02 < 0x04 < 0x08 < 0x10 < 0x20 < 0x40 < 0x80 +} led_cfg_t; + +/** + * @brief the status of led event + */ +typedef struct { + unsigned char isOn; + unsigned char polar; + unsigned char repeatCount; + unsigned char priority; + + + unsigned short onTime_ms; + unsigned short offTime_ms; + + unsigned int gpio_led; + unsigned int startTick; +}device_led_t; + +extern device_led_t device_led; + +#define DEVICE_LED_BUSY (device_led.repeatCount) + +/** + * @brief This function is used to manage led tasks + * @param[in] none + * @return none + */ +extern void led_proc(void); + +/** + * @brief This function is used to initialize device led setting + * @param[in] gpio - the GPIO corresponding to device led + * @param[in] polarity - 1 for high led on, 0 for low led on + * @return none + */ +extern void device_led_init(u32 gpio,u8 polarity); + +/** + * @brief This function is used to create new led task + * @param[in] led_cfg - Configure the parameters for led event + * @return 0 - new led event priority not higher than the not ongoing one + * 1 - new led event created successfully + */ +int device_led_setup(led_cfg_t led_cfg); + +/** + * @brief This function is used to manage led tasks + * @param[in] none + * @return none + */ +static inline void device_led_process(void) +{ +#if (BLT_APP_LED_ENABLE) + if(DEVICE_LED_BUSY){ + led_proc(); + } +#endif +} + + + + +#endif /* BLT_LED_H_ */ diff --git a/b91/b91m_ble_sdk/vendor/common/blt_soft_timer.c b/b91/b91m_ble_sdk/vendor/common/blt_soft_timer.c new file mode 100755 index 0000000..f125457 --- /dev/null +++ b/b91/b91m_ble_sdk/vendor/common/blt_soft_timer.c @@ -0,0 +1,243 @@ +/******************************************************************************************************** + * @file blt_soft_timer.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "stack/ble/ble.h" +#include "tl_common.h" +#include "blt_soft_timer.h" + + + + +#if (BLT_SOFTWARE_TIMER_ENABLE) + + + + +_attribute_ble_data_retention_ blt_soft_timer_t blt_timer; + + +/** + * @brief This function is used to Sort the timers according + * to the time of the timed task, so as to trigger the + * timers in turn + * @param[in] none + * @return none + */ +int blt_soft_timer_sort(void) +{ + if(blt_timer.currentNum < 1 || blt_timer.currentNum > MAX_TIMER_NUM){ + return 0; + } + else{ + //BubbleSort + int n = blt_timer.currentNum; + u8 temp[sizeof(blt_time_event_t)]; + + for(int i=0;i= MAX_TIMER_NUM){ //timer full + return 0; + } + else{ + blt_timer.timer[blt_timer.currentNum].cb = func; + blt_timer.timer[blt_timer.currentNum].interval = interval_us * SYSTEM_TIMER_TICK_1US; + blt_timer.timer[blt_timer.currentNum].t = now + blt_timer.timer[blt_timer.currentNum].interval; + blt_timer.currentNum ++; + + blt_soft_timer_sort(); + + blc_pm_setAppWakeupLowPower(blt_timer.timer[0].t, 1); + + return 1; + } +} + + + +/** + * @brief Timer tasks are originally ordered. When deleting, it will + * be overwritten forward, so the order will not be destroyed + * and there is no need to reorder + * @param[in] index - the index for some software timer task + * @return 0 - delete fail + * other - delete successfully + */ +int blt_soft_timer_delete_by_index(u8 index) +{ + if(index >= blt_timer.currentNum){ + return 0; + } + + + for(int i=index; i t2 return 1 +#define TIME_COMPARE_BIG(t1,t2) ( (u32)((t1) - (t2)) < BIT(30) ) + + +#define BLT_TIMER_SAFE_MARGIN_PRE (SYSTEM_TIMER_TICK_1US<<7) //128 us +#define BLT_TIMER_SAFE_MARGIN_POST (SYSTEM_TIMER_TICK_1S<<2) // 4S + +/** + * @brief This function is used to check the current time is what the timer expects or not + * @param[in] t - the time is expired for setting + * @param[in] now - Current system clock time + * @return 0 - The current time isn't what the timer expects + * 1 - The current time is what the timer expects + */ +static int inline blt_is_timer_expired(u32 t, u32 now) { + return ((u32)(now + BLT_TIMER_SAFE_MARGIN_PRE - t) < BLT_TIMER_SAFE_MARGIN_POST); +} + + +/** + * @brief callback function for software timer task + */ +typedef int (*blt_timer_callback_t)(void); + + + + +typedef struct blt_time_event_t { + blt_timer_callback_t cb; + u32 t; + u32 interval; +} blt_time_event_t; + + +// timer table managemnt +typedef struct blt_soft_timer_t { + blt_time_event_t timer[MAX_TIMER_NUM]; //timer0 - timer3 + u8 currentNum; //total valid timer num +} blt_soft_timer_t; + + + + +//////////////////////// USER INTERFACE /////////////////////////////////// +//return 0 means Fail, others OK +/** + * @brief This function is used to add new software timer task + * @param[in] func - callback function for software timer task + * @param[in] interval_us - the interval for software timer task + * @return 0 - timer task is full, add fail + * 1 - create successfully + */ +int blt_soft_timer_add(blt_timer_callback_t func, u32 interval_us); + +/** + * @brief This function is used to delete timer tasks + * @param[in] func - callback function for software timer task + * @return 0 - delete fail + * 1 - delete successfully + */ +int blt_soft_timer_delete(blt_timer_callback_t func); + + + + +//////////////////////// SOFT TIMER MANAGEMENT INTERFACE /////////////////////////////////// + +/** + * @brief This function is used to register the call back for pm_appWakeupLowPowerCb + * @param[in] none + * @return none + */ +void blt_soft_timer_init(void); + +/** + * @brief This function is used to manage software timer tasks + * @param[in] type - the type for trigger + * @return none + */ +void blt_soft_timer_process(int type); + +/** + * @brief Timer tasks are originally ordered. When deleting, it will + * be overwritten forward, so the order will not be destroyed + * and there is no need to reorder + * @param[in] index - the index for some software timer task + * @return 0 - delete fail + * other - delete successfully + */ +int blt_soft_timer_delete_by_index(u8 index); + +/** + * @brief This function is used to check the current time is what the timer expects or not + * @param[in] e - callback function for software timer task + * @return none + */ +int is_timer_expired(blt_timer_callback_t *e); + + +#endif /* BLT_SOFT_TIMER_H_ */ diff --git a/b91/b91m_ble_sdk/vendor/common/common_dbg.c b/b91/b91m_ble_sdk/vendor/common/common_dbg.c new file mode 100755 index 0000000..2fec49d --- /dev/null +++ b/b91/b91m_ble_sdk/vendor/common/common_dbg.c @@ -0,0 +1,66 @@ +/******************************************************************************************************** + * @file common_dbg.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "tl_common.h" +#include "common_dbg.h" + + +#if (APP_DUMP_EN) + + + +MYFIFO_INIT_IRAM(print_fifo, 288, 32); + + + +void app_dmup_debug_init(void) +{ + my_usb_init(0x120, &print_fifo); + usb_set_pin_en (); +} + +#endif + + + + + +#if (UART_LOW_POWER_DEBUG_EN) + + +#define UART0_DMA_CHANNEL_TX DMA4 +#define UART0_BAUDRATE 1000000 //115200 + +int lp_uart_init = 0; //attention: can not be retention data !!! +void low_power_uart_debug_init(void) +{ +#if (UART_LOW_POWER_DEBUG_EN) + uart0_init(UART0_BAUDRATE); + uart_set_tx_dma_config(UART0, UART0_DMA_CHANNEL_TX); + uart_clr_tx_done(UART0); + dma_clr_irq_mask(UART0_DMA_CHANNEL_TX,TC_MASK|ABT_MASK|ERR_MASK); + + lp_uart_init = 1; +#endif +} + +#endif diff --git a/b91/b91m_ble_sdk/vendor/common/common_dbg.h b/b91/b91m_ble_sdk/vendor/common/common_dbg.h new file mode 100755 index 0000000..bfa525f --- /dev/null +++ b/b91/b91m_ble_sdk/vendor/common/common_dbg.h @@ -0,0 +1,71 @@ +/******************************************************************************************************** + * @file common_dbg.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef COMMON_DBG_H_ +#define COMMON_DBG_H_ + + + +#include "common/utility.h" +#include "vendor/common/user_config.h" + + +#ifndef APP_DUMP_EN +#define APP_DUMP_EN 0 +#endif + + +#if (APP_DUMP_EN) + +extern my_fifo_t print_fifo; +extern unsigned char print_fifo_b[]; + + + +void app_dmup_debug_init(void); + +#endif + + + + + + + +#ifndef UART_LOW_POWER_DEBUG_EN +#define UART_LOW_POWER_DEBUG_EN 0 +#endif + + + + +#if(UART_LOW_POWER_DEBUG_EN) + +extern int lp_uart_init; +void low_power_uart_debug_init(void); + +#endif + + + + +#endif /* COMMON_DBG_H_ */ diff --git a/b91/b91m_ble_sdk/vendor/common/custom_pair.c b/b91/b91m_ble_sdk/vendor/common/custom_pair.c new file mode 100755 index 0000000..1d6970a --- /dev/null +++ b/b91/b91m_ble_sdk/vendor/common/custom_pair.c @@ -0,0 +1,296 @@ +/******************************************************************************************************** + * @file custom_pair.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "tl_common.h" +#include "drivers.h" +#include "blt_common.h" +#include "custom_pair.h" + + + +/********************************************************************************** + // proc user PAIR and UNPAIR +**********************************************************************************/ + +man_pair_t blm_manPair; + +/* define pair slave max num, + if exceed this max num, two methods to process new slave pairing + method 1: overwrite the oldest one(telink demo use this method) + method 2: not allow pairing unless unfair happened */ +#define USER_PAIR_SLAVE_MAX_NUM 4 //telink demo use max 4, you can change this value + + +typedef struct { + u8 bond_mark; + u8 adr_type; + u8 address[6]; +} macAddr_t; + + +typedef struct { + u32 bond_flash_idx[USER_PAIR_SLAVE_MAX_NUM]; //mark paired slave mac address in flash + macAddr_t bond_device[USER_PAIR_SLAVE_MAX_NUM]; //macAddr_t alreay defined in ble stack + u8 curNum; +} user_salveMac_t; + + + +/* flash erase strategy: + never erase flash when dongle is working, for flash sector erase takes too much time(20-100 ms) + this will lead to timing err + so we only erase flash at initiation, and with mark 0x00 for no use symbol + */ + +#define ADR_BOND_MARK 0x5A +#define ADR_ERASE_MARK 0x00 +/* flash stored mac address struct: + every 8 bytes is a address area: first one is mark, second no use, third - eighth is 6 byte address + 0 1 2 - 7 + | mark | | mac_address | + mark = 0xff, current area is invalid, pair info end + mark = 0x01, current area is valid, load the following mac_address, + mark = 0x00, current area is invalid (previous valid address is erased) + */ + +int user_bond_slave_flash_cfg_idx; //new mac address stored flash idx + + +user_salveMac_t user_tbl_slaveMac; //slave mac bond table + +/** + * @brief Delete slave MAC by index. + * !!! Note: only internal use + * @param index + * @return none. + */ +void user_tbl_slave_mac_delete_by_index(int index) //remove the oldest adr in slave mac table +{ + //erase the oldest with ERASE_MARK + u8 delete_mark = ADR_ERASE_MARK; + flash_write_page (FLASH_ADR_CUSTOM_PAIRING + user_tbl_slaveMac.bond_flash_idx[index], 1, &delete_mark); + + for(int i=index; i= USER_PAIR_SLAVE_MAX_NUM){ //salve mac table is full + //slave mac max, telink use method 1: overwrite the oldest one + user_tbl_slave_mac_delete_by_index(0); //overwrite, delete index 0 (oldest) of table + add_new = 1; //add new + } + else{//slave mac table not full + add_new = 1; + } + + if(add_new){ + + user_bond_slave_flash_cfg_idx += 8; //inc flash idx to get the new 8 bytes area + + if( user_bond_slave_flash_cfg_idx >= FLASH_CUSTOM_PAIRING_MAX_SIZE ){ //pairing information exceed Flash sector 4K size + return 0; //add Fail + } + + user_tbl_slaveMac.bond_device[user_tbl_slaveMac.curNum].bond_mark = ADR_BOND_MARK; + user_tbl_slaveMac.bond_device[user_tbl_slaveMac.curNum].adr_type = adr_type; + memcpy(user_tbl_slaveMac.bond_device[user_tbl_slaveMac.curNum].address, adr, 6); + + flash_write_page (FLASH_ADR_CUSTOM_PAIRING + user_bond_slave_flash_cfg_idx, 8, (u8 *)&user_tbl_slaveMac.bond_device[user_tbl_slaveMac.curNum] ); + + user_tbl_slaveMac.bond_flash_idx[user_tbl_slaveMac.curNum] = user_bond_slave_flash_cfg_idx; //mark flash idx + user_tbl_slaveMac.curNum++; + + return 1; //add OK + } + + return 0; +} + +/** + * @brief search mac address in the bond slave mac table: + * when slave paired with dongle, add this addr to table + * re_poweron slave, dongle will search if this AdvA in slave adv pkt is in this table + * if in, it will connect slave directly + * this function must in ramcode + * @param[in] adr_type address type + * @param[in] adr Pointer point to address buffer. + * @return 0: invalid index + * others valid index + */ +int user_tbl_slave_mac_search(u8 adr_type, u8 * adr) +{ + for(int i=0; i< user_tbl_slaveMac.curNum; i++){ + if( user_tbl_slaveMac.bond_device[i].adr_type == adr_type && \ + !memcmp(user_tbl_slaveMac.bond_device[i].address ,adr, 6)){ //match + + return (i+1); //return index+1( 1 - USER_PAIR_SLAVE_MAX_NUM) + } + } + + return 0; +} + +/** + * @brief Delete bonding info. + * @param[in] adr_type address type + * @param[in] adr Pointer point to address buffer. + * @return 1: delete ok + * 0: no find + */ +int user_tbl_slave_mac_delete_by_adr(u8 adr_type, u8 *adr) //remove adr from slave mac table by adr +{ + for(int i=0;i>1) ) //max 2048/8 = 256,rest available sector is big enough, no need clean +#endif + { + return; + } + + adbg_flash_clean = 1; + + flash_erase_sector (FLASH_ADR_CUSTOM_PAIRING); + + user_bond_slave_flash_cfg_idx = -8; //init value for no bond slave mac + + //rewrite bond table at the beginning of 0x11000 + for(int i=0; i< user_tbl_slaveMac.curNum; i++){ + //u8 add_mark = ADR_BOND_MARK; + + user_bond_slave_flash_cfg_idx += 8; //inc flash idx to get the new 8 bytes area + flash_write_page (FLASH_ADR_CUSTOM_PAIRING + user_bond_slave_flash_cfg_idx, 8, (u8*)&user_tbl_slaveMac.bond_device[i] ); + + user_tbl_slaveMac.bond_flash_idx[i] = user_bond_slave_flash_cfg_idx; //update flash idx + } +} + +/** + * @brief initialize pair flash. + * @param none. + * @return none. + */ +void user_master_host_pairing_flash_init(void) +{ + u8 flag; + for (user_bond_slave_flash_cfg_idx=0; user_bond_slave_flash_cfg_idx<4096; user_bond_slave_flash_cfg_idx+=8) + { //traversing 8 bytes area in sector 0x11000 to find all the valid slave mac adr + flash_read_page(FLASH_ADR_CUSTOM_PAIRING + user_bond_slave_flash_cfg_idx, 1, &flag); + if( flag == ADR_BOND_MARK ){ //valid adr + if(user_tbl_slaveMac.curNum < USER_PAIR_SLAVE_MAX_NUM){ + user_tbl_slaveMac.bond_flash_idx[user_tbl_slaveMac.curNum] = user_bond_slave_flash_cfg_idx; + flash_read_page (FLASH_ADR_CUSTOM_PAIRING + user_bond_slave_flash_cfg_idx, 8, (u8 *)&user_tbl_slaveMac.bond_device[user_tbl_slaveMac.curNum] ); + user_tbl_slaveMac.curNum ++; + } + else{ //slave mac in flash more than max, we think it's code bug + irq_disable(); + while(1); + } + } + else if (flag == 0xff) //end + { + break; + } + } + + user_bond_slave_flash_cfg_idx -= 8; //back to the newest addr 8 bytes area flash ixd(if no valid addr, will be -8) + + user_bond_slave_flash_clean (); +} + +/** + * @brief Pair management initialization for master. + * @param none. + * @return none. + */ +void user_master_host_pairing_management_init(void) +{ + user_master_host_pairing_flash_init(); +} diff --git a/b91/b91m_ble_sdk/vendor/common/custom_pair.h b/b91/b91m_ble_sdk/vendor/common/custom_pair.h new file mode 100755 index 0000000..427e165 --- /dev/null +++ b/b91/b91m_ble_sdk/vendor/common/custom_pair.h @@ -0,0 +1,89 @@ +/******************************************************************************************************** + * @file custom_pair.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef BLM_PAIR_H_ +#define BLM_PAIR_H_ + +#include "vendor/common/user_config.h" + + + +/*! Pair parameter manager type */ +typedef struct{ + u8 manual_pair; + u8 mac_type; //address type + u8 mac[6]; + u32 pair_tick; +}man_pair_t; + +extern man_pair_t blm_manPair; + +/** + * @brief Pair management initialization for master. + * @param none. + * @return none. + */ +void user_master_host_pairing_management_init(void); + +/** + * @brief search mac address in the bond slave mac table: + * when slave paired with dongle, add this addr to table + * re_poweron slave, dongle will search if this AdvA in slave adv pkt is in this table + * if in, it will connect slave directly + * this function must in ramcode + * @param[in] adr_type address type + * @param[in] adr Pointer point to address buffer. + * @return 0: invalid index + * others valid index + */ +int user_tbl_slave_mac_search(u8 adr_type, u8 * adr); + +/** + * @brief Store bonding info to flash. + * @param[in] adr_type address type + * @param[in] adr Pointer point to address buffer. + * @return none. + */ +int user_tbl_slave_mac_add(u8 adr_type, u8 *adr); + + +/** + * @brief Delete bonding info. + * @param[in] adr_type address type + * @param[in] adr Pointer point to address buffer. + * @return 1: delete ok + * 0: no find + */ +int user_tbl_slave_mac_delete_by_adr(u8 adr_type, u8 *adr); + +/** + * @brief Delete all device bonding info. + * @param none. + * @return none. + */ +void user_tbl_slave_mac_delete_all(void); + + + + + +#endif /* APP_PAIR_H_ */ diff --git a/b91/b91m_ble_sdk/vendor/common/default_config.h b/b91/b91m_ble_sdk/vendor/common/default_config.h new file mode 100755 index 0000000..6c1e530 --- /dev/null +++ b/b91/b91m_ble_sdk/vendor/common/default_config.h @@ -0,0 +1,460 @@ +/******************************************************************************************************** + * @file default_config.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + + +#include "config.h" + +//////////// product Infomation ////////////////////////////// +#ifndef ID_VENDOR +#define ID_VENDOR 0x248a // for report +#endif +#ifndef ID_PRODUCT_BASE +#define ID_PRODUCT_BASE 0x8800 +#endif +#ifndef STRING_VENDOR +#define STRING_VENDOR L"Telink" +#endif +#ifndef STRING_PRODUCT +#define STRING_PRODUCT L"BLE 5.0" +#endif + +#ifndef STRING_SERIAL +#define STRING_SERIAL L"TLSR9518" +#endif + + +#ifndef PM_DEEPSLEEP_RETENTION_ENABLE +#define PM_DEEPSLEEP_RETENTION_ENABLE 0 +#endif + + +#if (PM_DEEPSLEEP_RETENTION_ENABLE) + #define BLC_PM_EN 1 + #define BLC_PM_DEEP_RETENTION_MODE_EN 1 +#endif + + +#ifndef BLC_PM_EN +#define BLC_PM_EN 0 +#endif + + +#ifndef BLC_PM_DEEP_RETENTION_MODE_EN +#define BLC_PM_DEEP_RETENTION_MODE_EN 0 +#endif + + + + + + +#if(APPLICATION_DONGLE) + #ifndef MODULE_MOUSE_ENABLE + #define MODULE_MOUSE_ENABLE 0 + #endif + #ifndef MODULE_KEYBOARD_ENABLE + #define MODULE_KEYBOARD_ENABLE 0 + #endif + #ifndef MODULE_MIC_ENABLE + #define MODULE_MIC_ENABLE 0 + #endif + #ifndef MODULE_SPEAKER_ENABLE + #define MODULE_SPEAKER_ENABLE 0 // device , not dongle + #endif + #ifndef MODULE_USB_ENABLE + #define MODULE_USB_ENABLE 1 + #endif +#else + #ifndef MODULE_MOUSE_ENABLE + #define MODULE_MOUSE_ENABLE 1 + #endif + #ifndef MODULE_KEYBOARD_ENABLE + #define MODULE_KEYBOARD_ENABLE 1 + #endif + + #ifndef MODULE_MIC_ENABLE + #define MODULE_MIC_ENABLE 0 + #endif + #ifndef MODULE_SPEAKER_ENABLE + #define MODULE_SPEAKER_ENABLE 0 // device , not dongle + #endif + + #ifndef MODULE_USB_ENABLE + #define MODULE_USB_ENABLE 0 + #endif +#endif + + + + + + + + +/////////////////// USB ///////////////////////////////// +#ifndef IRQ_USB_PWDN_ENABLE +#define IRQ_USB_PWDN_ENABLE 0 +#endif + + +#ifndef USB_PRINTER_ENABLE +#define USB_PRINTER_ENABLE 0 +#endif +#ifndef USB_SPEAKER_ENABLE +#define USB_SPEAKER_ENABLE 0 +#endif +#ifndef USB_MIC_ENABLE +#define USB_MIC_ENABLE 0 +#endif +#ifndef USB_MOUSE_ENABLE +#define USB_MOUSE_ENABLE 0 +#endif +#ifndef USB_KEYBOARD_ENABLE +#define USB_KEYBOARD_ENABLE 0 +#endif +#ifndef USB_SOMATIC_ENABLE +#define USB_SOMATIC_ENABLE 0 +#endif +#ifndef USB_CUSTOM_HID_REPORT +#define USB_CUSTOM_HID_REPORT 0 +#endif +#ifndef USB_AUDIO_441K_ENABLE +#define USB_AUDIO_441K_ENABLE 0 +#endif +#ifndef USB_MASS_STORAGE_ENABLE +#define USB_MASS_STORAGE_ENABLE 0 +#endif +#ifndef MIC_CHANNEL_COUNT +#define MIC_CHANNEL_COUNT 2 +#endif + +#ifndef USB_DESCRIPTER_CONFIGURATION_FOR_KM_DONGLE +#define USB_DESCRIPTER_CONFIGURATION_FOR_KM_DONGLE 0 +#endif + +#ifndef USB_ID_AND_STRING_CUSTOM +#define USB_ID_AND_STRING_CUSTOM 0 +#endif + +#define KEYBOARD_RESENT_MAX_CNT 3 +#define KEYBOARD_REPEAT_CHECK_TIME 300000 // in us +#define KEYBOARD_REPEAT_INTERVAL 100000 // in us +#define KEYBOARD_SCAN_INTERVAL 16000 // in us +#define MOUSE_SCAN_INTERVAL 8000 // in us +#define SOMATIC_SCAN_INTERVAL 8000 + +#define USB_KEYBOARD_POLL_INTERVAL 10 // in ms USB_KEYBOARD_POLL_INTERVAL < KEYBOARD_SCAN_INTERVAL to ensure PC no missing key +#define USB_MOUSE_POLL_INTERVAL 4 // in ms +#define USB_SOMATIC_POLL_INTERVAL 8 // in ms + +#define USB_KEYBOARD_RELEASE_TIMEOUT (450000) // in us +#define USB_MOUSE_RELEASE_TIMEOUT (200000) // in us +#define USB_SOMATIC_RELEASE_TIMEOUT (200000) // in us + + + + + + + +/* + * Default Link Layer Module Configuration + */ + +#ifndef LL_MODULE_LEGACY_ADVERTISING_ENABLE +#define LL_MODULE_LEGACY_ADVERTISING_ENABLE 0 +#endif + +#ifndef LL_MODULE_LEGACY_SCANNING_ENABLE +#define LL_MODULE_LEGACY_SCANNING_ENABLE 0 +#endif + +#ifndef LL_MODULE_LEGACY_INITIATING_ENABLE +#define LL_MODULE_LEGACY_ADVERTISING_ENABLE 0 +#endif + + +#ifndef LL_MODULE_EXTENDED_ADVERTISING_ENABLE +#define LL_MODULE_EXTENDED_ADVERTISING_ENABLE 0 +#endif + +#ifndef LL_MODULE_EXTENDED_SCANNING_ENABLE +#define LL_MODULE_EXTENDED_SCANNING_ENABLE 0 +#endif + +#ifndef LL_MODULE_EXTENDED_INITIATING_ENABLE +#define LL_MODULE_EXTENDED_INITIATING_ENABLE 0 +#endif + + +#ifndef LL_MODULE_PERIODIC_ADVERTISING_ENABLE +#define LL_MODULE_PERIODIC_ADVERTISING_ENABLE 0 +#endif + + + +#ifndef LL_MODULE_ACL_CONNECTION_ENABLE +#define LL_MODULE_ACL_CONNECTION_ENABLE 0 +#endif + +#ifndef LL_MODULE_ACL_MASTER_ROLE_ENABLE +#define LL_MODULE_ACL_MASTER_ROLE_ENABLE 0 +#endif + +#ifndef LL_MODULE_ACL_SLAVE_ROLE_ENABLE +#define LL_MODULE_ACL_SLAVE_ROLE_ENABLE 0 +#endif + + + +#ifndef LL_MODULE_CIS_MASTER_ROLE_ENABLE +#define LL_MODULE_CIS_MASTER_ROLE_ENABLE 0 +#endif + +#ifndef LL_MODULE_CIS_SLAVE_ROLE_ENABLE +#define LL_MODULE_CIS_SLAVE_ROLE_ENABLE 0 +#endif + + + + + + + +#ifndef DEBUG_GPIO_ENABLE +#define DEBUG_GPIO_ENABLE 0 +#endif + + + +#if (DEBUG_GPIO_ENABLE) + #ifdef GPIO_CHN0 + #define DBG_CHN0_LOW gpio_write(GPIO_CHN0, 0) + #define DBG_CHN0_HIGH gpio_write(GPIO_CHN0, 1) + #define DBG_CHN0_TOGGLE gpio_toggle(GPIO_CHN0) + #else + #define DBG_CHN0_LOW + #define DBG_CHN0_HIGH + #define DBG_CHN0_TOGGLE + #endif + + #ifdef GPIO_CHN1 + #define DBG_CHN1_LOW gpio_write(GPIO_CHN1, 0) + #define DBG_CHN1_HIGH gpio_write(GPIO_CHN1, 1) + #define DBG_CHN1_TOGGLE gpio_toggle(GPIO_CHN1) + #else + #define DBG_CHN1_LOW + #define DBG_CHN1_HIGH + #define DBG_CHN1_TOGGLE + #endif + + #ifdef GPIO_CHN2 + #define DBG_CHN2_LOW gpio_write(GPIO_CHN2, 0) + #define DBG_CHN2_HIGH gpio_write(GPIO_CHN2, 1) + #define DBG_CHN2_TOGGLE gpio_toggle(GPIO_CHN2) + #else + #define DBG_CHN2_LOW + #define DBG_CHN2_HIGH + #define DBG_CHN2_TOGGLE + #endif + + #ifdef GPIO_CHN3 + #define DBG_CHN3_LOW gpio_write(GPIO_CHN3, 0) + #define DBG_CHN3_HIGH gpio_write(GPIO_CHN3, 1) + #define DBG_CHN3_TOGGLE gpio_toggle(GPIO_CHN3) + #else + #define DBG_CHN3_LOW + #define DBG_CHN3_HIGH + #define DBG_CHN3_TOGGLE + #endif + + #ifdef GPIO_CHN4 + #define DBG_CHN4_LOW gpio_write(GPIO_CHN4, 0) + #define DBG_CHN4_HIGH gpio_write(GPIO_CHN4, 1) + #define DBG_CHN4_TOGGLE gpio_toggle(GPIO_CHN4) + #else + #define DBG_CHN4_LOW + #define DBG_CHN4_HIGH + #define DBG_CHN4_TOGGLE + #endif + + #ifdef GPIO_CHN5 + #define DBG_CHN5_LOW gpio_write(GPIO_CHN5, 0) + #define DBG_CHN5_HIGH gpio_write(GPIO_CHN5, 1) + #define DBG_CHN5_TOGGLE gpio_toggle(GPIO_CHN5) + #else + #define DBG_CHN5_LOW + #define DBG_CHN5_HIGH + #define DBG_CHN5_TOGGLE + #endif + + #ifdef GPIO_CHN6 + #define DBG_CHN6_LOW gpio_write(GPIO_CHN6, 0) + #define DBG_CHN6_HIGH gpio_write(GPIO_CHN6, 1) + #define DBG_CHN6_TOGGLE gpio_toggle(GPIO_CHN6) + #else + #define DBG_CHN6_LOW + #define DBG_CHN6_HIGH + #define DBG_CHN6_TOGGLE + #endif + + #ifdef GPIO_CHN7 + #define DBG_CHN7_LOW gpio_write(GPIO_CHN7, 0) + #define DBG_CHN7_HIGH gpio_write(GPIO_CHN7, 1) + #define DBG_CHN7_TOGGLE gpio_toggle(GPIO_CHN7) + #else + #define DBG_CHN7_LOW + #define DBG_CHN7_HIGH + #define DBG_CHN7_TOGGLE + #endif + + #ifdef GPIO_CHN8 + #define DBG_CHN8_LOW gpio_write(GPIO_CHN8, 0) + #define DBG_CHN8_HIGH gpio_write(GPIO_CHN8, 1) + #define DBG_CHN8_TOGGLE gpio_toggle(GPIO_CHN8) + #else + #define DBG_CHN8_LOW + #define DBG_CHN8_HIGH + #define DBG_CHN8_TOGGLE + #endif + + #ifdef GPIO_CHN9 + #define DBG_CHN9_LOW gpio_write(GPIO_CHN9, 0) + #define DBG_CHN9_HIGH gpio_write(GPIO_CHN9, 1) + #define DBG_CHN9_TOGGLE gpio_toggle(GPIO_CHN9) + #else + #define DBG_CHN9_LOW + #define DBG_CHN9_HIGH + #define DBG_CHN9_TOGGLE + #endif + + #ifdef GPIO_CHN10 + #define DBG_CHN10_LOW gpio_write(GPIO_CHN10, 0) + #define DBG_CHN10_HIGH gpio_write(GPIO_CHN10, 1) + #define DBG_CHN10_TOGGLE gpio_toggle(GPIO_CHN10) + #else + #define DBG_CHN10_LOW + #define DBG_CHN10_HIGH + #define DBG_CHN10_TOGGLE + #endif + + #ifdef GPIO_CHN11 + #define DBG_CHN11_LOW gpio_write(GPIO_CHN11, 0) + #define DBG_CHN11_HIGH gpio_write(GPIO_CHN11, 1) + #define DBG_CHN11_TOGGLE gpio_toggle(GPIO_CHN11) + #else + #define DBG_CHN11_LOW + #define DBG_CHN11_HIGH + #define DBG_CHN11_TOGGLE + #endif + + #ifdef GPIO_CHN12 + #define DBG_CHN12_LOW gpio_write(GPIO_CHN12, 0) + #define DBG_CHN12_HIGH gpio_write(GPIO_CHN12, 1) + #define DBG_CHN12_TOGGLE gpio_toggle(GPIO_CHN12) + #else + #define DBG_CHN12_LOW + #define DBG_CHN12_HIGH + #define DBG_CHN12_TOGGLE + #endif + + #ifdef GPIO_CHN13 + #define DBG_CHN13_LOW gpio_write(GPIO_CHN13, 0) + #define DBG_CHN13_HIGH gpio_write(GPIO_CHN13, 1) + #define DBG_CHN13_TOGGLE gpio_toggle(GPIO_CHN13) + #else + #define DBG_CHN13_LOW + #define DBG_CHN13_HIGH + #define DBG_CHN13_TOGGLE + #endif + + #ifdef GPIO_CHN14 + #define DBG_CHN14_LOW gpio_write(GPIO_CHN14, 0) + #define DBG_CHN14_HIGH gpio_write(GPIO_CHN14, 1) + #define DBG_CHN14_TOGGLE gpio_toggle(GPIO_CHN14) + #else + #define DBG_CHN14_LOW + #define DBG_CHN14_HIGH + #define DBG_CHN14_TOGGLE + #endif + + #ifdef GPIO_CHN15 + #define DBG_CHN15_LOW gpio_write(GPIO_CHN15, 0) + #define DBG_CHN15_HIGH gpio_write(GPIO_CHN15, 1) + #define DBG_CHN15_TOGGLE gpio_toggle(GPIO_CHN15) + #else + #define DBG_CHN15_LOW + #define DBG_CHN15_HIGH + #define DBG_CHN15_TOGGLE + #endif +#else + #define DBG_CHN0_LOW + #define DBG_CHN0_HIGH + #define DBG_CHN0_TOGGLE + #define DBG_CHN1_LOW + #define DBG_CHN1_HIGH + #define DBG_CHN1_TOGGLE + #define DBG_CHN2_LOW + #define DBG_CHN2_HIGH + #define DBG_CHN2_TOGGLE + #define DBG_CHN3_LOW + #define DBG_CHN3_HIGH + #define DBG_CHN3_TOGGLE + #define DBG_CHN4_LOW + #define DBG_CHN4_HIGH + #define DBG_CHN4_TOGGLE + #define DBG_CHN5_LOW + #define DBG_CHN5_HIGH + #define DBG_CHN5_TOGGLE + #define DBG_CHN6_LOW + #define DBG_CHN6_HIGH + #define DBG_CHN6_TOGGLE + #define DBG_CHN7_LOW + #define DBG_CHN7_HIGH + #define DBG_CHN7_TOGGLE + #define DBG_CHN8_LOW + #define DBG_CHN8_HIGH + #define DBG_CHN8_TOGGLE + #define DBG_CHN9_LOW + #define DBG_CHN9_HIGH + #define DBG_CHN9_TOGGLE + #define DBG_CHN10_LOW + #define DBG_CHN10_HIGH + #define DBG_CHN10_TOGGLE + #define DBG_CHN11_LOW + #define DBG_CHN11_HIGH + #define DBG_CHN11_TOGGLE + #define DBG_CHN12_LOW + #define DBG_CHN12_HIGH + #define DBG_CHN12_TOGGLE + #define DBG_CHN13_LOW + #define DBG_CHN13_HIGH + #define DBG_CHN13_TOGGLE + #define DBG_CHN14_LOW + #define DBG_CHN14_HIGH + #define DBG_CHN14_TOGGLE + #define DBG_CHN15_LOW + #define DBG_CHN15_HIGH + #define DBG_CHN15_TOGGLE +#endif diff --git a/b91/b91m_ble_sdk/vendor/common/device_manage.c b/b91/b91m_ble_sdk/vendor/common/device_manage.c new file mode 100755 index 0000000..753ef9b --- /dev/null +++ b/b91/b91m_ble_sdk/vendor/common/device_manage.c @@ -0,0 +1,404 @@ +/******************************************************************************************************** + * @file device_manage.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "tl_common.h" +#include "drivers.h" +#include "stack/ble/ble.h" + +#include "device_manage.h" + + + + +/* + * Used for store information of connected devices. + * + * 0 ~ (MASTER_MAX_NUM - 1) is for master, MASTER_MAX_NUM ~ (MASTER_MAX_NUM + SLAVE_MAX_NUM - 1) s for slave + * + * e.g. MASTER_MAX_NUM SLAVE_MAX_NUM master slave + * 0 1 none conn_dev_list[0] + * 0 2 none conn_dev_list[0..1] + * 0 3 none conn_dev_list[0..2] + * 0 4 none conn_dev_list[0..3] + * + * 1 0 conn_dev_list[0] none + * 1 1 conn_dev_list[0] conn_dev_list[1] + * 1 2 conn_dev_list[0] conn_dev_list[1..2] + * 1 3 conn_dev_list[0] conn_dev_list[1..3] + * 1 4 conn_dev_list[0] conn_dev_list[1..4] + * + * 2 0 conn_dev_list[0..1] none + * 2 1 conn_dev_list[0..1] conn_dev_list[2] + * 2 2 conn_dev_list[0..1] conn_dev_list[2..3] + * 2 3 conn_dev_list[0..1] conn_dev_list[2..4] + * 2 4 conn_dev_list[0..1] conn_dev_list[2..5] + * + * 3 0 conn_dev_list[0..2] none + * 3 1 conn_dev_list[0..2] conn_dev_list[3] + * 3 2 conn_dev_list[0..2] conn_dev_list[3..4] + * 3 3 conn_dev_list[0..2] conn_dev_list[3..5] + * 3 4 conn_dev_list[0..2] conn_dev_list[3..6] + * + * 4 0 conn_dev_list[0..3] none + * 4 1 conn_dev_list[0..3] conn_dev_list[4] + * 4 2 conn_dev_list[0..3] conn_dev_list[4..5] + * 4 3 conn_dev_list[0..3] conn_dev_list[4..6] + * 4 4 conn_dev_list[0..3] conn_dev_list[4..7] + */ +_attribute_ble_data_retention_ dev_char_info_t conn_dev_list[DEVICE_CHAR_INFO_MAX_NUM]; + + + +_attribute_ble_data_retention_ int conn_master_num = 0; //current master number in connection state +_attribute_ble_data_retention_ int conn_slave_num = 0; //current slave number in connection state + + + + + +/** + * @brief Used for add device information to conn_dev_list. + * @param[in] dev_char_info - Pointer point to data buffer. + * @return 0 ~ DEVICE_CHAR_INFO_MAX_NUM - 1: new connection index, insert success + * 0xFF: insert failed + */ +int dev_char_info_insert (dev_char_info_t* dev_char_info) +{ + int index = INVALID_CONN_IDX; + if( dev_char_info->conn_role == LL_ROLE_MASTER ){ //master + for(int i = 0; i < MASTER_MAX_NUM; i++){ + if(conn_dev_list[i].conn_state == 0){ + index = i; + conn_master_num ++; + break; + } + } + } + else if( dev_char_info->conn_role == LL_ROLE_SLAVE ){ //slave + for(int i = MASTER_MAX_NUM; i < MASTER_MAX_NUM + SLAVE_MAX_NUM; i++){ + if(conn_dev_list[i].conn_state == 0){ + index = i; + conn_slave_num ++; + break; + } + } + } + + + + if(index != INVALID_CONN_IDX){ + memcpy(&conn_dev_list[index], dev_char_info, sizeof(dev_char_info_t)); + conn_dev_list[index].conn_state = 1; + } + + return index; +} + + + +/** + * @brief Used for add device information to conn_dev_list. + * @param[in] pConnEvt - LE connection complete event data buffer address. + * @return 0 ~ DEVICE_CHAR_INFO_MAX_NUM - 1: new connection index, insert success + * 0xFF: insert failed + */ +int dev_char_info_insert_by_conn_event(hci_le_connectionCompleteEvt_t* pConnEvt) +{ + int index = INVALID_CONN_IDX; + if( pConnEvt->role == LL_ROLE_MASTER ){ //master + for(int i = 0; i < MASTER_MAX_NUM; i++){ + if(conn_dev_list[i].conn_state == 0){ + index = i; + conn_master_num ++; + break; + } + } + } + else if( pConnEvt->role == LL_ROLE_SLAVE ){ //slave + for(int i = MASTER_MAX_NUM; i < MASTER_MAX_NUM + SLAVE_MAX_NUM; i++){ + if(conn_dev_list[i].conn_state == 0){ + index = i; + conn_slave_num ++; + break; + } + } + } + + if(index != INVALID_CONN_IDX){ + memset(&conn_dev_list[index], 0, sizeof(dev_char_info_t)); + + conn_dev_list[index].conn_handle = pConnEvt->connHandle; + conn_dev_list[index].conn_role = pConnEvt->role; + conn_dev_list[index].conn_state = 1; + conn_dev_list[index].peer_adrType = pConnEvt->peerAddrType; + memcpy(conn_dev_list[index].peer_addr, pConnEvt->peerAddr, 6); + } + + return index; +} + + + + +/** + * @brief Used for add device information to conn_dev_list. + * @param[in] pConnEvt - LE enhanced connection complete event data buffer address. + * @return 0 ~ DEVICE_CHAR_INFO_MAX_NUM - 1: new connection index, insert success + * 0xFF: insert failed + */ +int dev_char_info_insert_by_enhanced_conn_event(hci_le_enhancedConnCompleteEvt_t* pConnEvt) +{ + int index = INVALID_CONN_IDX; + if( pConnEvt->role == LL_ROLE_MASTER ){ //master + for(int i = 0; i < MASTER_MAX_NUM; i++){ + if(conn_dev_list[i].conn_state == 0){ + index = i; + conn_master_num ++; + break; + } + } + } + else if( pConnEvt->role == LL_ROLE_SLAVE ){ //slave + for(int i = MASTER_MAX_NUM; i < MASTER_MAX_NUM + SLAVE_MAX_NUM; i++){ + if(conn_dev_list[i].conn_state == 0){ + index = i; + conn_slave_num ++; + break; + } + } + } + + if(index != INVALID_CONN_IDX){ + memset(&conn_dev_list[index], 0, sizeof(dev_char_info_t)); + + conn_dev_list[index].conn_handle = pConnEvt->connHandle; + conn_dev_list[index].conn_role = pConnEvt->role; + conn_dev_list[index].conn_state = 1; + conn_dev_list[index].peer_adrType = pConnEvt->PeerAddrType; + memcpy(conn_dev_list[index].peer_addr, pConnEvt->PeerAddr, 6); + } + + return index; +} + + + + +/** + * @brief Used for delete device information from conn_dev_list by connHandle + * @param[in] connhandle - connection handle. + * @return 0: success + * 1: no find + */ +int dev_char_info_delete_by_connhandle (u16 connhandle) +{ + foreach (i, DEVICE_CHAR_INFO_MAX_NUM) + { + if(conn_dev_list[i].conn_handle == connhandle && conn_dev_list[i].conn_state) //match + { + if(conn_dev_list[i].conn_role == LL_ROLE_MASTER){ //master + conn_master_num --; + } + else{ //slave + conn_slave_num --; + } + + memset(&conn_dev_list[i], 0, sizeof(dev_char_info_t)); + + return 0; + } + } + + return 1; //not find. +} + + +/** + * @brief Used for delete device information from conn_dev_list by peer mac_address + * @param[in] adr_type - peer address type. + * @param[in] addr - Pointer point to peer address. + * @return 0: success + * 1: no find + */ +int dev_char_info_delete_by_peer_mac_address (u8 adr_type, u8* addr) +{ + foreach (i, DEVICE_CHAR_INFO_MAX_NUM) + { + if(conn_dev_list[i].conn_state) + { + int mac_match = 0; + if( IS_RESOLVABLE_PRIVATE_ADDR(adr_type, addr) ){ + //TODO + } + else{ + if(adr_type == conn_dev_list[i].peer_adrType && (!memcmp (addr, conn_dev_list[i].peer_addr, 6)) ){ + mac_match = 1; + } + } + + //u16 connhandle = conn_dev_list[i].conn_handle; + + if(mac_match){ + if(conn_dev_list[i].conn_role == LL_ROLE_MASTER){ //master + conn_master_num --; + } + else{ //slave + conn_slave_num --; + } + + memset(&conn_dev_list[i], 0, sizeof(dev_char_info_t)); + + return 0; + } + + } + } + + return 1; //no find the peer device address. +} + + + + + + + +/** + * @brief Get device information by connection handle. + * @param[in] connhandle - connection handle. + * @return 0: no find + * !0: found + */ +dev_char_info_t* dev_char_info_search_by_connhandle (u16 connhandle) +{ + foreach (i, DEVICE_CHAR_INFO_MAX_NUM) + { + if(conn_dev_list[i].conn_handle == connhandle && conn_dev_list[i].conn_state) + { + return &conn_dev_list[i]; // find the peer device + } + } + + return 0; // no find the peer device +} + + + + +/** + * @brief Get device information by peer device address. + * @param[in] adr_type - peer address type. + * @param[in] addr - Pointer point to peer address. + * @return 0: no find + * !0: found + */ +dev_char_info_t* dev_char_info_search_by_peer_mac_address (u8 adr_type, u8* addr) +{ + foreach (i, DEVICE_CHAR_INFO_MAX_NUM) + { + + int mac_match = 0; + if( IS_RESOLVABLE_PRIVATE_ADDR(adr_type, addr) ){ + //TODO + } + else{ + if(adr_type == conn_dev_list[i].peer_adrType && (!memcmp (addr, conn_dev_list[i].peer_addr, 6)) ){ + mac_match = 1; + } + } + + if(mac_match){ + return &conn_dev_list[i]; // find the peer device + } + } + + return 0; // no find the peer device +} + + + + + +/** + * @brief Get device information by connection handle. + * @param[in] connhandle - connection handle. + * @return 0: no find + * !0: found + */ +bool dev_char_info_is_connection_state_by_conn_handle(u16 connhandle) +{ + foreach (i, DEVICE_CHAR_INFO_MAX_NUM) + { + if(conn_dev_list[i].conn_handle == connhandle && conn_dev_list[i].conn_state) + { + return TRUE; + } + } + + return FALSE; +} + + + +/** + * @brief Get ACL connection role by connection handle. + * @param[in] connhandle - connection handle. + * @return 0: LL_ROLE_MASTER + * 1: LL_ROLE_SLAVE + * 2: connection handle invalid + */ +int dev_char_get_conn_role_by_connhandle (u16 connhandle) +{ + foreach (i, DEVICE_CHAR_INFO_MAX_NUM) + { + if(conn_dev_list[i].conn_handle == connhandle && conn_dev_list[i].conn_state) + { + return conn_dev_list[i].conn_role; + } + } + + return 2; //no connection match +} + + + + +/** + * @brief Get ACL connection index by connection handle. + * @param[in] connhandle - connection handle. + * @return 0xFF: no connection index match + * others: connection index + */ +int dev_char_get_conn_index_by_connhandle (u16 connhandle) +{ + foreach (i, DEVICE_CHAR_INFO_MAX_NUM) + { + if(conn_dev_list[i].conn_handle == connhandle && conn_dev_list[i].conn_state) + { + return i; + } + } + + return INVALID_CONN_IDX; //no connection index match +} + + diff --git a/b91/b91m_ble_sdk/vendor/common/device_manage.h b/b91/b91m_ble_sdk/vendor/common/device_manage.h new file mode 100755 index 0000000..aa0d8d6 --- /dev/null +++ b/b91/b91m_ble_sdk/vendor/common/device_manage.h @@ -0,0 +1,198 @@ +/******************************************************************************************************** + * @file device_manage.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef APP_DEVICE_H_ +#define APP_DEVICE_H_ + + +#include "vendor/common/user_config.h" +#include "stack/ble/ble_common.h" +#include "stack/ble/hci/hci_event.h" + +#ifndef MASTER_MAX_NUM +#define MASTER_MAX_NUM 4 +#endif + +#ifndef SLAVE_MAX_NUM +#define SLAVE_MAX_NUM 4 +#endif + + + +#define INVALID_CONN_IDX 0xFF + + + +#define DEVICE_CHAR_INFO_MAX_NUM (MASTER_MAX_NUM + SLAVE_MAX_NUM) //4 master, 3 slave most + + + +#define CHAR_HANDLE_MAX 8 +/***************** connection character device information **************************** + * + * Demo master device char_handle(ATT handle) define as follows, assuming that peer device(BLE slave) is TELINK HID device + * char_handle[0] : MIC + * char_handle[1] : Speaker + * char_handle[2] : OTA + * char_handle[3] : Consume Report In + * char_handle[4] : Key Report In + * char_handle[5] : + * char_handle[6] : BLE Module, SPP Server to Client + * char_handle[7] : BLE Module, SPP Client to Server + *************************************************************************************/ + +typedef struct { + u8 id_adrType; //identity address type + u8 id_addr[6]; //identity address + u8 reserved; + u8 irk[16]; +} rpa_addr_t; + + + +//Attention: manual set 4 byte aligned +typedef struct +{ + u16 conn_handle; + u8 conn_role; // 0: master; 1: slave + u8 conn_state; // 1: connect; 0: disconnect + + u8 char_handle_valid; // 1: peer device's attHandle is available; 0: peer device's attHandle not available + u8 rsvd[3]; // for 4 Byte align + + u8 peer_adrType; + u8 peer_addr[6]; + u8 peer_RPA; //RPA: resolvable private address + + //rpa_addr_t *pPeer_RPA; //only when peer mac_address is RPA, this pointer is useful + + u16 char_handle[CHAR_HANDLE_MAX]; + +}dev_char_info_t; + + +extern dev_char_info_t conn_dev_list[]; + + +extern int conn_master_num; +extern int conn_slave_num; + +/** + * @brief Used for add device information to conn_dev_list. + * @param[in] dev_char_info - Pointer point to data buffer. + * @return 0 ~ DEVICE_CHAR_INFO_MAX_NUM - 1: new connection index, insert success + * 0xFF: insert failed + */ +int dev_char_info_insert (dev_char_info_t* dev_char_info); + + + +/** + * @brief Used for add device information to conn_dev_list. + * @param[in] pConnEvt - LE connection complete event data buffer address. + * @return 0 ~ DEVICE_CHAR_INFO_MAX_NUM - 1: new connection index, insert success + * 0xFF: insert failed + */ +int dev_char_info_insert_by_conn_event(hci_le_connectionCompleteEvt_t* pConnEvt); + + +/** + * @brief Used for add device information to conn_dev_list. + * @param[in] pConnEvt - LE enhanced connection complete event data buffer address. + * @return 0 ~ DEVICE_CHAR_INFO_MAX_NUM - 1: new connection index, insert success + * 0xFF: insert failed + */ +int dev_char_info_insert_by_enhanced_conn_event(hci_le_enhancedConnCompleteEvt_t* pConnEvt); + + +/** + * @brief Used for delete device information from conn_dev_list by connHandle + * @param[in] connhandle - connection handle. + * @return 0: success + * 1: no find + */ +int dev_char_info_delete_by_connhandle (u16 connhandle); + +/** + * @brief Used for delete device information from conn_dev_list by peer mac_address + * @param[in] adr_type - peer address type. + * @param[in] addr - Pointer point to peer address. + * @return 0: success + * 1: no find + */ +int dev_char_info_delete_by_peer_mac_address (u8 adr_type, u8* addr); + + +/** + * @brief Get device information by peer device address. + * @param[in] adr_type - peer address type. + * @param[in] addr - Pointer point to peer address. + * @return 0: no find + * !0: found + */ +dev_char_info_t* dev_char_info_search_by_peer_mac_address (u8 adr_type, u8* addr); + +/** + * @brief Get device information by connection handle. + * @param[in] connhandle - connection handle. + * @return 0: no find + * !0: found + */ +dev_char_info_t* dev_char_info_search_by_connhandle (u16 connhandle); + + + +/** + * @brief Used for judge if current device conn_handle + * @param[in] connhandle - connection handle. + * @return + */ +bool dev_char_info_is_connection_state_by_conn_handle(u16 connhandle); + + + +/** + * @brief Get ACL connection role by connection handle. + * @param[in] connhandle - connection handle. + * @return 0: LL_ROLE_MASTER + * 1: LL_ROLE_SLAVE + * 2: connection handle invalid + */ +int dev_char_get_conn_role_by_connhandle (u16 connhandle); + + + + + +/** + * @brief Get ACL connection index by connection handle. + * @param[in] connhandle - connection handle. + * @return 0xFF: no connection index match + * others: connection index + */ +int dev_char_get_conn_index_by_connhandle (u16 connhandle); + + + + + +#endif /* APP_DEVICE_H_ */ diff --git a/b91/b91m_ble_sdk/vendor/common/flash_fw_check.c b/b91/b91m_ble_sdk/vendor/common/flash_fw_check.c new file mode 100755 index 0000000..fe74bdc --- /dev/null +++ b/b91/b91m_ble_sdk/vendor/common/flash_fw_check.c @@ -0,0 +1,133 @@ +/******************************************************************************************************** + * @file flash_fw_check.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#if 1 +#include "tl_common.h" +#include "drivers.h" +#include "stack/ble/ble.h" +#include "flash_fw_check.h" + + + + +static const unsigned long fw_crc32_half_tbl[16] = { + 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, + 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, + 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c +}; + +#define FW_READ_SIZE 256 ///16 ///256 require more stack space + +u32 fw_crc_init = 0xFFFFFFFF; + +/*********************************** + * this function must be called after the function sys_init. + * sys_init will set the ota_program_offset value. + */ +/** + * @brief This function is used to check the firmware is ok or not + * @param[in] crc_init_value - the initial value of CRC + * @return 0 - CRC is check success + * 1 - CRC is check fail + */ +bool flash_fw_check( u32 crc_init_value ){ + + if(!crc_init_value){ + fw_crc_init = 0xFFFFFFFF; + }else{ + fw_crc_init = crc_init_value; + } + + /////find the real FW flash address + u32 fw_flashAddr; + if(!ota_program_offset){ ////zero, firmware is stored at flash 0x20000. + fw_flashAddr = ota_program_bootAddr; ///NOTE: this flash offset need to set according to OTA offset + }else{ ////note zero, firmware is stored at flash 0x00000. + fw_flashAddr = 0x00000; + } + + u32 fw_size; + flash_read_page( (fw_flashAddr+0x18), 4, (u8*)&fw_size); ///0x18 store bin size value + + u16 fw_Block; + u16 fw_remainSizeByte; + fw_Block = fw_size/FW_READ_SIZE; + fw_remainSizeByte = fw_size%FW_READ_SIZE; + + + int i = 0; + u8 fw_tmpdata[FW_READ_SIZE]; /// + u8 ota_dat[FW_READ_SIZE<<1]; + for(i=0; i < fw_Block; i++){ ///Telink bin must align 16 bytes. + + flash_read_page( (fw_flashAddr+i*FW_READ_SIZE), FW_READ_SIZE, fw_tmpdata); + + //FW_READ_SIZE byte OTA data32 half byteCRC + for(int i=0;i>4; + } + fw_crc_init = crc32_half_cal(fw_crc_init, ota_dat, (unsigned long* )fw_crc32_half_tbl, (FW_READ_SIZE<<1)); + } + + ////////////////////////////// + if(fw_remainSizeByte != 4){ + flash_read_page( (fw_flashAddr+fw_size -fw_remainSizeByte), (fw_remainSizeByte-4), fw_tmpdata); + for(int i=0;i<(fw_remainSizeByte-4);i++){ + ota_dat[i*2] = fw_tmpdata[i]&0x0f; + ota_dat[i*2+1] = fw_tmpdata[i]>>4; + } + fw_crc_init = crc32_half_cal(fw_crc_init, ota_dat, (unsigned long* )fw_crc32_half_tbl, ((fw_remainSizeByte-4)<<1)); + } + + ////////read crc value and compare + u32 fw_check_value; + flash_read_page( (fw_flashAddr+fw_size-4), 4, (u8*)&fw_check_value); + + if(fw_check_value != fw_crc_init){ + return 1; ///CRC check fail + } + + return 0; ///CRC check ok +} + +#endif + + + + + + + + + + + + + + + + + + + diff --git a/b91/b91m_ble_sdk/vendor/common/flash_fw_check.h b/b91/b91m_ble_sdk/vendor/common/flash_fw_check.h new file mode 100755 index 0000000..33f586b --- /dev/null +++ b/b91/b91m_ble_sdk/vendor/common/flash_fw_check.h @@ -0,0 +1,40 @@ +/******************************************************************************************************** + * @file flash_fw_check.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef _FLASH_FW_CHECK_H_ +#define _FLASH_FW_CHECK_H_ + + +#include "../../common/types.h" + + +/** + * @brief This function is used to check the firmware is ok or not + * @param[in] crc_init_value - the initial value of CRC + * @return 0 - CRC is check success + * 1 - CRC is check fail + */ +bool flash_fw_check( u32 crc_init_value ); + + + +#endif diff --git a/b91/b91m_ble_sdk/vendor/common/simple_sdp.c b/b91/b91m_ble_sdk/vendor/common/simple_sdp.c new file mode 100755 index 0000000..c91cd62 --- /dev/null +++ b/b91/b91m_ble_sdk/vendor/common/simple_sdp.c @@ -0,0 +1,565 @@ +/******************************************************************************************************** + * @file simple_sdp.c + * + * @brief This is the source file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#include "tl_common.h" +#include "drivers.h" +#include "stack/ble/ble.h" + +#include "simple_sdp.h" +#include "device_manage.h" +#include "blt_common.h" + +#if (BLE_MASTER_SIMPLE_SDP_ENABLE) + + +typedef struct{ + u8 type; + u8 rf_len; + u16 l2capLen; + u16 chanId; + u8 opcode; + u8 format; + u8 data[1]; // character_handle / property / value_handle / value +}ble_att_findInfoRsp_t; + + +int master_sdp_pending = 0; // SDP: service discovery + + +dev_char_info_t cur_sdp_device; //current connected device which is in SDP flow + + +main_service_t main_service = 0; + + +static const u8 my_OtaUUID[16] = WRAPPING_BRACES(TELINK_SPP_DATA_OTA); + + +ble_sts_t host_att_discoveryService (u16 handle, att_db_uuid16_t *p16, int n16, att_db_uuid128_t *p128, int n128); + + + +void simple_sdp_loop (void) +{ + if (main_service) + { + main_service (); + main_service = 0; + } +} + + + + +/** + * @brief SDP handler. + * !!! Note: This is a simple SDP processing implemented by telink. + * @param none. + * @return none. + */ +void app_service_discovery (void) +{ + att_db_uuid16_t db16[ATT_DB_UUID16_NUM]; + att_db_uuid128_t db128[ATT_DB_UUID128_NUM]; + memset (db16, 0, ATT_DB_UUID16_NUM * sizeof (att_db_uuid16_t)); + memset (db128, 0, ATT_DB_UUID128_NUM * sizeof (att_db_uuid128_t)); + + if ( master_sdp_pending && host_att_discoveryService (master_sdp_pending, db16, ATT_DB_UUID16_NUM, db128, ATT_DB_UUID128_NUM) == BLE_SUCCESS) // service discovery OK + { + cur_sdp_device.char_handle[2] = blm_att_findHandleOfUuid128 (db128, my_OtaUUID); //OTA + cur_sdp_device.char_handle[3] = blm_att_findHandleOfUuid16 (db16, CHARACTERISTIC_UUID_HID_REPORT, + HID_REPORT_ID_CONSUME_CONTROL_INPUT | (HID_REPORT_TYPE_INPUT<<8)); //consume report(media key report) + cur_sdp_device.char_handle[4] = blm_att_findHandleOfUuid16 (db16, CHARACTERISTIC_UUID_HID_REPORT, + HID_REPORT_ID_KEYBOARD_INPUT | (HID_REPORT_TYPE_INPUT<<8)); //normal key report + //cur_sdp_device.char_handle[6] = blm_att_findHandleOfUuid128 (db128, TelinkSppDataServer2ClientUUID); //BLE Module, SPP Server to Client + //cur_sdp_device.char_handle[7] = blm_att_findHandleOfUuid128 (db128, TelinkSppDataClient2ServerUUID); //BLE Module, SPP Client to Server + + /* add the peer device att_handle value to conn_dev_list after service discovery is correctly finished */ + dev_char_info_add_peer_att_handle(&cur_sdp_device); + + /* peer device att_handle value store in flash */ + dev_char_info_store_peer_att_handle(&cur_sdp_device); + + //my_dump_str_data(APP_DUMP_SDP_EN,"OTA handle", (u8*)&cur_sdp_device.char_handle[2], 2); + //my_dump_str_data(APP_DUMP_SDP_EN,"CMKEY handle", (u8*)&cur_sdp_device.char_handle[3], 2); + //my_dump_str_data(APP_DUMP_SDP_EN,"KBKEY handle", (u8*)&cur_sdp_device.char_handle[4], 2); + } + + master_sdp_pending = 0; //service discovery finish +} + +/** + * @brief This function is used to register SDP handler. + * @param[in] p - Pointer point to SDP handler. + * @return none. + */ +void app_register_service (void *p) +{ + main_service = p; +} + + + + + + + + + + +u8 *p_att_response = 0; + +volatile u32 host_att_req_busy = 0; + +/** + * @brief This function is used to process ATT packets related to SDP + * @param[in] connHandle - connection handle + * @param[in] p - Pointer point to ATT data buffer. + * @return + */ +int host_att_client_handler (u16 connHandle, u8 *p) +{ + ble_att_readByTypeRsp_t *p_rsp = (ble_att_readByTypeRsp_t *) p; + if (p_att_response) + { + if ((connHandle & 7) == (host_att_req_busy & 7) && p_rsp->chanId == 0x04 && + (p_rsp->opcode == 0x01 || p_rsp->opcode == ((host_att_req_busy >> 16) | 1))) + { + memcpy (p_att_response, p, 32); + host_att_req_busy = 0; + } + } + return 0; +} + +typedef int (*host_att_idle_func_t) (void); +host_att_idle_func_t host_att_idle_func = 0; + +/** + * @brief This function is used to register ble stack mainloop function. + * @param[in] p - Pointer point to ble stack mainloop function. + * @return + */ +int host_att_register_idle_func (void *p) +{ + if (host_att_idle_func) + return 1; + + host_att_idle_func = p; + return 0; +} + +int host_att_response () +{ + return host_att_req_busy == 0; +} + + +int host_att_service_wait_event (u16 handle, u8 *p, u32 timeout) +{ + host_att_req_busy = handle | (p[6] << 16); + p_att_response = p; + + u32 t = clock_time (); + while (!clock_time_exceed (t, timeout)) + { + if (host_att_response ()) + { + return 0; + } + if (host_att_idle_func) + { + if (host_att_idle_func ()) + { + break; + } + } + } + return 1; +} + +//Gaoqiu add ------------------------------------------------------------------ +int app_char_discovery(u8* reslut, u16 connHandle, u16 startAttHandle, u16 endAttHandle, u8*uuid, u8 uuidLen) +{ + blc_gatt_pushReadByTypeRequest(connHandle, startAttHandle, endAttHandle, uuid, uuidLen); + + return host_att_service_wait_event(connHandle, reslut, 1000000); +} + +int app_read_char_value(u8* reslut, u16 connHandle, u16 attHandle) +{ + blc_gatt_pushReadRequest(connHandle, attHandle); + + return host_att_service_wait_event(connHandle, reslut, 1000000); +} + +int app_find_char_info(u8* reslut, u16 connHandle, u16 startAttHandle, u16 endAttHandle) +{ + blc_gatt_pushFindInformationRequest(connHandle, startAttHandle, endAttHandle); + + return host_att_service_wait_event(connHandle, reslut, 1000000); +} + + +u16 blm_att_findHandleOfUuid16 (att_db_uuid16_t *p, u16 uuid, u16 ref) +{ + for (int i=0; inum; i++) + { + if (p[i].uuid == uuid && p[i].ref == ref) + { + return p[i].handle; + } + } + return 0; +} + +u16 blm_att_findHandleOfUuid128 (att_db_uuid128_t *p, const u8 * uuid) +{ + for (int i=0; inum; i++) + { + if (memcmp (p[i].uuid, uuid, 16) == 0) + { + return p[i].handle; + } + } + return 0; +} + + +ble_sts_t host_att_discoveryService (u16 handle, att_db_uuid16_t *p16, int n16, att_db_uuid128_t *p128, int n128) +{ + att_db_uuid16_t *ps16 = p16; + att_db_uuid128_t *ps128 = p128; + int i16 = 0; + int i128 = 0; + + ps16->num = 0; + ps128->num = 0; + + // char discovery: att_read_by_type + // hid discovery: att_find_info + u8 dat[32]; + u16 s = 1; + u16 uuid = GATT_UUID_CHARACTER; + do { + dat[6] = ATT_OP_READ_BY_TYPE_REQ; + if (app_char_discovery(dat, handle, s, 0xffff, (u8 *)&uuid, 2)) // 1s + { + return GATT_ERR_SERVICE_DISCOVERY_TIEMOUT; //timeout + } + + // process response data + ble_att_readByTypeRsp_t *p_rsp = (ble_att_readByTypeRsp_t *) dat; + if (p_rsp->opcode != ATT_OP_READ_BY_TYPE_RSP) + { + break; + } + + if (p_rsp->datalen == 21) //uuid128 + { + s = p_rsp->data[3] + p_rsp->data[4] * 256; + if (i128 < n128) + { + p128->property = p_rsp->data[2]; + p128->handle = s; + memcpy (p128->uuid, p_rsp->data + 5, 16); + i128++; + p128++; + } + } + else if (p_rsp->datalen == 7) //uuid16 + { + u8 *pd = p_rsp->data; + while (p_rsp->l2capLen > 7) + { + s = pd[3] + pd[4] * 256; + if (i16 < n16) + { + p16->property = pd[2]; + p16->handle = s; + p16->uuid = pd[5] | (pd[6] << 8); + p16->ref = 0; + i16 ++; + p16++; + } + p_rsp->l2capLen -= 7; + pd += 7; + } + } + } while (1); + + ps16->num = i16; + ps128->num = i128; + + //--------- use att_find_info to find the reference property for hid ---------- + p16 = ps16; + for (int i=0; iuuid == CHARACTERISTIC_UUID_HID_REPORT) //find reference + { + dat[6] = ATT_OP_FIND_INFORMATION_REQ; + if (app_find_char_info(dat, handle, p16->handle, 0xffff)) // 1s + { + return GATT_ERR_SERVICE_DISCOVERY_TIEMOUT; //timeout + } + + ble_att_findInfoRsp_t *p_rsp = (ble_att_findInfoRsp_t *) dat; + if (p_rsp->opcode == ATT_OP_FIND_INFO_RSP && p_rsp->format == 1) + { + int n = p_rsp->l2capLen - 2; + u8 *pd = p_rsp->data; + while (n > 0) + { + if ((pd[2]==U16_LO(GATT_UUID_CHARACTER) && pd[3]==U16_HI(GATT_UUID_CHARACTER)) || + (pd[2]==U16_LO(GATT_UUID_PRIMARY_SERVICE) && pd[3]==U16_HI(GATT_UUID_PRIMARY_SERVICE)) ) + { + break; + } + + if (pd[2]==U16_LO(GATT_UUID_REPORT_REF) && pd[3]==U16_HI(GATT_UUID_REPORT_REF)) + { + //----------- read attribute ---------------- + dat[6] = ATT_OP_READ_REQ; + if(app_read_char_value(dat, handle, pd[0])){ + return GATT_ERR_SERVICE_DISCOVERY_TIEMOUT; //timeout + } + + ble_att_readRsp_t *pr = (ble_att_readRsp_t *) dat; + if (pr->opcode == ATT_OP_READ_RSP) + { + p16->ref = pr->value[0] | (pr->value[1] << 8); + } + + break; + } + n -= 4; + pd += 4; + } + } + } //----- end for if CHARACTERISTIC_UUID_HID_REPORT + + p16++; + } + + return BLE_SUCCESS; +} + + + + + + + + + + + + + +/** + * @brief Used for add peer device service ATThandle. + * @param[in] dev_char_info - Pointer point to data buffer. + * @return 0: success + * 1: failed + */ +int dev_char_info_add_peer_att_handle (dev_char_info_t* dev_char_info) +{ + int i; + for(i=0; i< conn_master_num; i++){ + if( conn_dev_list[i].conn_handle == dev_char_info->conn_handle){ + break; + } + } + + if( i < conn_master_num){ + for(int j=0; jchar_handle[j]; + } + + conn_dev_list[i].char_handle_valid = 1; + + return 0; //success + } + else{ + return 1; //fail + } +} + + + + +/** + * @brief Use for store peer device att handle to flash. + * @param[in] dev_char_info Pointer point to peer device ATT handle info. + * @return 0: failed + * !0: return falsh address + */ +int dev_char_info_store_peer_att_handle(dev_char_info_t* pdev_char) +{ + u8 mark; + u32 current_flash_adr; + for(current_flash_adr = FLASH_SDP_ATT_ADRRESS; current_flash_adr < (FLASH_SDP_ATT_ADRRESS + FLASH_SDP_ATT_MAX_SIZE); current_flash_adr += sizeof(dev_att_t) ) + { + flash_read_page(current_flash_adr, 1, &mark); + + if( mark == U8_MAX){ + + flash_write_page( current_flash_adr + OFFSETOF(dev_att_t, adr_type), 7, (u8 *)&pdev_char->peer_adrType); // peer_adrType(1)+peer_addr(6) + +#if (PEER_SLAVE_USE_RPA_EN) + if( IS_RESOLVABLE_PRIVATE_ADDR(pdev_char->peer_adrType, pdev_char->peer_addr) ){ + //TODO, store irk to flash + } +#endif + +// char_handle[0] : MIC +// char_handle[1] : Speaker +// char_handle[2] : OTA +// char_handle[3] : Consume Report +// char_handle[4] : Key Report +// char_handle[5] : +// char_handle[6] : BLE Module, SPP Server to Client +// char_handle[7] : BLE Module, SPP Client to Server + flash_write_page( current_flash_adr + OFFSETOF(dev_att_t, char_handle) + 2*2, 2, (u8 *)&pdev_char->char_handle[2]); //save OTA att_handle + flash_write_page( current_flash_adr + OFFSETOF(dev_att_t, char_handle) + 3*2, 2, (u8 *)&pdev_char->char_handle[3]); //save Consume Report att_handle + flash_write_page( current_flash_adr + OFFSETOF(dev_att_t, char_handle) + 4*2, 2, (u8 *)&pdev_char->char_handle[4]); //save Key Report att_handle + + mark = ATT_BOND_MARK; + flash_write_page( current_flash_adr, 1, (u8 *)&mark); + + return current_flash_adr; //Store Success + } + } + + + + + + + return 0; //Store Fail +} + + +/** + * @brief Get peer device att handle info by peer address + * @param[in] adr_type address type + * @param[in] addr Pointer point to peer address buffer + * @param[out] dev_att Pointer point to dev_att_t + * @return 0: failed + * !0: return falsh address + */ +int dev_char_info_search_peer_att_handle_by_peer_mac(u8 adr_type, u8* addr, dev_att_t* pdev_att) +{ + + + u8 mark; + u32 current_flash_adr; + for(current_flash_adr = FLASH_SDP_ATT_ADRRESS; current_flash_adr < (FLASH_SDP_ATT_ADRRESS + FLASH_SDP_ATT_MAX_SIZE); current_flash_adr += sizeof(dev_att_t) ) + { + flash_read_page(current_flash_adr, 1, &mark); + + if(mark == U8_MAX){ + return 0; //Search Fail + } + else if(mark == ATT_ERASE_MARK){ + continue; //Search for next unit + } + else if( mark == ATT_BOND_MARK) + { + flash_read_page(current_flash_adr, sizeof(dev_att_t), (u8 *)pdev_att); + + int addr_match = 0; +#if (PEER_SLAVE_USE_RPA_EN) + if( IS_RESOLVABLE_PRIVATE_ADDR(pdev_att->adr_type, pdev_att->addr) ){ + //TODO, resolve address by irk + if(0){ + addr_match = 1; + } + + } + else +#endif + { + if( adr_type == pdev_att->adr_type && !memcmp(addr, pdev_att->addr, 6 )){ //match + addr_match = 1; + } + } + + if(addr_match){ + return current_flash_adr; + } + + + } + + + } + + return 0; //Search Fail + +} + +/** + * @brief Delete peer device att handle info by peer address + * @param[in] adr_type address type + * @param[in] addr Pointer point to peer address buffer + * @return 0: success + * 1: not find + */ +int dev_char_info_delete_peer_att_handle_by_peer_mac(u8 addrType, u8 *addr) +{ + dev_att_t dev_info; + + for(u32 cur_flash_addr = FLASH_SDP_ATT_ADRRESS; + cur_flash_addr < FLASH_SDP_ATT_ADRRESS + FLASH_SDP_ATT_MAX_SIZE; + cur_flash_addr += sizeof(dev_att_t)) + { + u8 flag; + flash_read_page(cur_flash_addr, 1, &flag); + + //have no device information + if(flag == 0xff) + return 1;//not find + + if(flag == ATT_BOND_MARK){ + //only read per device MAC address type and MAC address + flash_read_page(cur_flash_addr, 8, (u8*)&dev_info); + #if(PEER_SLAVE_USE_RPA_EN) + if(IS_RESOLVABLE_PRIVATE_ADDR(addrType, addr)){ + //todo: resolve private address using IRK + } + else + #endif + { + if(dev_info.adr_type == addrType && !memcmp(dev_info.addr, addr, 6)){ + u8 temp = ATT_ERASE_MARK; + flash_write_page(cur_flash_addr, 1, (u8*)&temp); + return 0;//find + } + } + } + } + return 1;//not find +} + + +#endif //end of BLE_MASTER_SIMPLE_SDP_ENABLE diff --git a/b91/b91m_ble_sdk/vendor/common/simple_sdp.h b/b91/b91m_ble_sdk/vendor/common/simple_sdp.h new file mode 100755 index 0000000..7b3c070 --- /dev/null +++ b/b91/b91m_ble_sdk/vendor/common/simple_sdp.h @@ -0,0 +1,201 @@ +/******************************************************************************************************** + * @file simple_sdp.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#ifndef SIMPLE_SDP_H_ +#define SIMPLE_SDP_H_ + +#include "vendor/common/user_config.h" +#include "tl_common.h" +#include "device_manage.h" + +#ifndef BLE_MASTER_SIMPLE_SDP_ENABLE +#define BLE_MASTER_SIMPLE_SDP_ENABLE 0 +#endif + + + +#if (BLE_MASTER_SIMPLE_SDP_ENABLE) + + +typedef void (*main_service_t) (void); +extern main_service_t main_service; + +extern int master_sdp_pending; +extern dev_char_info_t cur_sdp_device; + + +#define ATT_DB_UUID16_NUM 20 +#define ATT_DB_UUID128_NUM 8 + +typedef struct { + u8 num; + u8 property; + u16 handle; + u16 uuid; + u16 ref; +} att_db_uuid16_t; //8-byte + + +typedef struct { + u8 num; + u8 property; + u16 handle; + u8 uuid[16]; +} att_db_uuid128_t; //20-byte + + +typedef struct{ + u8 type; + u8 rf_len; + u16 l2capLen; + u16 chanId; + u8 opcode; + u8 datalen; + u8 data[1]; // character_handle / property / value_handle / value +}ble_att_readByTypeRsp_t; + + +typedef struct{ + u8 type; + u8 rf_len; + u16 l2capLen; + u16 chanId; + u8 opcode; + u8 value[22]; +}ble_att_readRsp_t; + + + + +#define ATT_BOND_MARK 0x5A +#define ATT_ERASE_MARK 0x00 + + +typedef struct{ + u8 flag; + u8 adr_type; + u8 addr[6]; + + u8 rsvd[8]; //very important: 16 byte aligned, to avoid different flash page write for a sequence data + +#if (PEER_SLAVE_USE_RPA_EN) + u8 irk[16]; //TODO: if peer device mac_adress is RPA(resolvable private address), IRK will be used +#endif + + u16 char_handle[CHAR_HANDLE_MAX]; +}dev_att_t; + + + + + +u16 blm_att_findHandleOfUuid16 (att_db_uuid16_t *p, u16 uuid, u16 ref); +u16 blm_att_findHandleOfUuid128 (att_db_uuid128_t *p, const u8 * uuid); + + + +/** + * @brief SDP handler. + * !!! Note: This is a simple SDP processing implemented by telink. + * @param none. + * @return none. + */ +void app_service_discovery (void); + +/** + * @brief This function is used to register SDP handler. + * @param[in] p - Pointer point to SDP handler. + * @return none. + */ +void app_register_service (void *p); + +/** + * @brief This function is used to process ATT packets related to SDP + * @param[in] connHandle - connection handle + * @param[in] p - Pointer point to ATT data buffer. + * @return no used + */ +int host_att_client_handler (u16 connHandle, u8 *p); + +/** + * @brief This function is used to register ble stack mainloop function. + * @param[in] p - Pointer point to ble stack mainloop function. + * @return + */ +int host_att_register_idle_func (void *p); + + +/** + * @brief SDP loop + * @param[in] none. + * @return none. + */ +void simple_sdp_loop (void); + + + + +/** + * @brief Used for add peer device service ATThandle. + * @param[in] dev_char_info - Pointer point to data buffer. + * @return 0: success + * 1: failed + */ +int dev_char_info_add_peer_att_handle (dev_char_info_t* dev_char_info); + +/** + * @brief Use for store peer device att handle to flash. + * @param[in] dev_char_info Pointer point to peer device ATT handle info. + * @return 0: failed + * !0: return falsh address + */ +int dev_char_info_store_peer_att_handle(dev_char_info_t* dev_char_info); + +/** + * @brief Get peer device att handle info by peer address + * @param[in] adr_type address type + * @param[in] addr Pointer point to peer address buffer + * @param[out] dev_att Pointer point to dev_att_t + * @return 0: failed + * !0: return falsh address + */ +int dev_char_info_search_peer_att_handle_by_peer_mac(u8 adr_type, u8* addr, dev_att_t * dev_att); + + +/** + * @brief Delete peer device att handle info by peer address + * @param[in] adr_type address type + * @param[in] addr Pointer point to peer address buffer + * @return 0: success + * 1: not find + */ +int dev_char_info_delete_peer_att_handle_by_peer_mac(u8 addrType, u8 *addr); + + + + + + + +#endif + +#endif /* SIMPLE_SDP_H_ */ diff --git a/b91/b91m_ble_sdk/vendor/common/user_config.h b/b91/b91m_ble_sdk/vendor/common/user_config.h new file mode 100755 index 0000000..b7243d1 --- /dev/null +++ b/b91/b91m_ble_sdk/vendor/common/user_config.h @@ -0,0 +1,50 @@ +/******************************************************************************************************** + * @file user_config.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 2020.06 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ +#pragma once + +#if (__PROJECT_B91_DEMO ) + #include +#elif(__PROJECT_B91_MASTER_DONGLE__) + #include "../B91_master_dongle/app_config.h" +#elif (__PROJECT_B91_FEATURE__) + #include "../B91_feature/app_config.h" +#elif (__PROJECT_B91_INTERNAL_TEST__ ) + #include "../B91_internal_test/app_config.h" +#elif (__PROJECT_B91_CIS_MASTER__ ) + #include "../vendor/audio_cis_mst/app_config.h" +#elif (__PROJECT_B91_CIS_SLAVE__ ) + #include "../vendor/audio_cis_slv/app_config.h" +#elif (__PROJECT_B91_AUDIO_BIS_BCST__ ) + #include "../vendor/audio_bis_bcst/app_config.h" +#elif (__PROJECT_B91_AUDIO_BIS_SYNC__ ) + #include "../vendor/audio_bis_sync/app_config.h" +#elif(__PROJECT_B91_HCI__) + #include "../B91_controller/app_config.h" +#elif(__PROJECT_B91_SLAVE) + #include "../B91_slave/app_config.h" +#elif(__PROJECT_B91_EXTERNAL) + #include +#else + #include "../common/default_config.h" +#endif + diff --git a/b91/hcs/device_info/device_info.hcs b/b91/hcs/device_info/device_info.hcs new file mode 100755 index 0000000..82be069 --- /dev/null +++ b/b91/hcs/device_info/device_info.hcs @@ -0,0 +1,34 @@ +root { + module = "telink,b91"; + device_info { + match_attr = "hdf_manager"; + template host { + hostName = ""; + priority = 100; + template device { + template deviceNode { + policy = 0; + priority = 100; + preload = 0; + permission = 0664; + moduleName = ""; + serviceName = ""; + deviceMatchAttr = ""; + } + } + } + platform :: host { + hostName = "platform_host"; + priority = 50; + device_gpio :: device { + device0 :: deviceNode { + policy = 0; + priority = 10; + moduleName = "TELINK_HDF_PLATFORM_GPIO"; + serviceName = "HDF_PLATFORM_GPIO"; + deviceMatchAttr = "telink_b91_gpio"; + } + } + } + } +} diff --git a/b91/hcs/gpio/gpio_config.hcs b/b91/hcs/gpio/gpio_config.hcs new file mode 100755 index 0000000..46c2a49 --- /dev/null +++ b/b91/hcs/gpio/gpio_config.hcs @@ -0,0 +1,9 @@ +root { + platform { + gpio_config { + match_attr = "telink_b91_gpio"; + pinMap = [12, 13, 14, 15, 16, 17, 18,19]; + pinNum = 8; + } + } +} diff --git a/b91/hcs/hdf.hcs b/b91/hcs/hdf.hcs new file mode 100755 index 0000000..7dea59e --- /dev/null +++ b/b91/hcs/hdf.hcs @@ -0,0 +1,2 @@ +#include "device_info/device_info.hcs" +#include "gpio/gpio_config.hcs" diff --git a/b91/hdf/BUILD.gn b/b91/hdf/BUILD.gn new file mode 100755 index 0000000..dd0c85d --- /dev/null +++ b/b91/hdf/BUILD.gn @@ -0,0 +1,26 @@ +# Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//drivers/adapter/khdf/liteos_m/hdf.gni") + +hdf_driver("b91_hdf") { + sources = [ + "gpio_telink.c" + ] + + configs += [ + "../:B91_config", + ] +} diff --git a/b91/hdf/gpio_telink.c b/b91/hdf/gpio_telink.c new file mode 100755 index 0000000..57af1fe --- /dev/null +++ b/b91/hdf/gpio_telink.c @@ -0,0 +1,439 @@ +/****************************************************************************** + * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *****************************************************************************/ + +#include "gpio/gpio_core.h" +#include "osal.h" +#include "device_resource_if.h" +#include "hdf_device_desc.h" + +#include + +#include + +#define GPIO_INDEX_MAX (sizeof(g_GpioIndexToActualPin) / sizeof(gpio_pin_e)) + +struct B91GpioCntlr { + struct GpioCntlr cntlr; + + uint8_t *pinReflectionMap; + + struct { + bool irq_enabled; + } *config; + + uint8_t pinNum; +}; + +static struct B91GpioCntlr g_B91GpioCntlr = { +}; + +static const gpio_pin_e g_GpioIndexToActualPin[] = +{ + GPIO_PA0, /* 0 */ + GPIO_PA1, /* 1 */ + GPIO_PA2, /* 2 */ + GPIO_PA3, /* 3 */ + GPIO_PA4, /* 4 */ + GPIO_PA5, /* 5 */ + GPIO_PA6, /* 6 */ + GPIO_PA7, /* 7 */ + + GPIO_PB0, /* 8 */ + GPIO_PB1, /* 9 */ + GPIO_PB2, /* 10 */ + GPIO_PB3, /* 11 */ + GPIO_PB4, /* 12 */ + GPIO_PB5, /* 13 */ + GPIO_PB6, /* 14 */ + GPIO_PB7, /* 15 */ + + GPIO_PC0, /* 16 */ + GPIO_PC1, /* 17 */ + GPIO_PC2, /* 18 */ + GPIO_PC3, /* 19 */ + GPIO_PC4, /* 20 */ + GPIO_PC5, /* 21 */ + GPIO_PC6, /* 22 */ + GPIO_PC7, /* 23 */ + + GPIO_PD0, /* 24 */ + GPIO_PD1, /* 25 */ + GPIO_PD2, /* 26 */ + GPIO_PD3, /* 27 */ + GPIO_PD4, /* 28 */ + GPIO_PD5, /* 29 */ + GPIO_PD6, /* 30 */ + GPIO_PD7, /* 31 */ + + GPIO_PE0, /* 32 */ + GPIO_PE1, /* 33 */ + GPIO_PE2, /* 34 */ + GPIO_PE3, /* 35 */ + GPIO_PE4, /* 36 */ + GPIO_PE5, /* 37 */ + GPIO_PE6, /* 38 */ + GPIO_PE7, /* 39 */ + + GPIO_PF0, /* 40 */ + GPIO_PF1, /* 41 */ + GPIO_PF2, /* 42 */ + GPIO_PF3, /* 43 */ +}; + +#define RETURN_ERR_IF_OUT_OF_RANGE(gpio) \ + if (gpio >= pB91GpioCntlr->pinNum) { \ + return HDF_ERR_INVALID_PARAM; \ + } \ + if (pB91GpioCntlr->pinReflectionMap[gpio] >= GPIO_INDEX_MAX) { \ + return HDF_ERR_INVALID_PARAM; \ + } + +static int32_t GpioDriverBind(struct HdfDeviceObject *device); +static int32_t GpioDriverInit(struct HdfDeviceObject *device); +static void GpioDriverRelease(struct HdfDeviceObject *device); + +struct HdfDriverEntry g_GpioDriverEntry = { + .moduleVersion = 1, + .moduleName = "TELINK_HDF_PLATFORM_GPIO", + .Bind = GpioDriverBind, + .Init = GpioDriverInit, + .Release = GpioDriverRelease, +}; + +HDF_INIT(g_GpioDriverEntry); + +static int32_t GpioDevWrite(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t val); +static int32_t GpioDevRead(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *val); +static int32_t GpioDevSetDir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t dir); +static int32_t GpioDevGetDir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *dir); +static int32_t GpioDevSetIrq(struct GpioCntlr *cntlr, uint16_t local, uint16_t mode); +static int32_t GpioDevEnableIrq(struct GpioCntlr *cntlr, uint16_t local); +static int32_t GpioDevDisableIrq(struct GpioCntlr *cntlr, uint16_t local); +static int32_t GpioDevUnsetIrq(struct GpioCntlr *cntlr, uint16_t local); + +/* GpioMethod Definitions */ +struct GpioMethod g_GpioCntlrMethod = { + .request = NULL, + .release = NULL, + .write = GpioDevWrite, + .read = GpioDevRead, + .setDir = GpioDevSetDir, + .getDir = GpioDevGetDir, + .toIrq = NULL, + .setIrq = GpioDevSetIrq, + .unsetIrq = GpioDevUnsetIrq, + .enableIrq = GpioDevEnableIrq, + .disableIrq = GpioDevDisableIrq, +}; + +_attribute_ram_code_ static void GpioIrqHandler(void) +{ + struct B91GpioCntlr *pB91GpioCntlr = &g_B91GpioCntlr; + + for (size_t i = 0; i < pB91GpioCntlr->pinNum; ++i) { + if (pB91GpioCntlr->config[i].irq_enabled) { + // TODO: Implement finding GPIO number which triggered IRQ + GpioCntlrIrqCallback(&pB91GpioCntlr->cntlr, i); + } + } + + gpio_clr_irq_status(FLD_GPIO_IRQ_CLR); +} + +static int32_t GetGpioDeviceResource(struct B91GpioCntlr *cntlr, const struct DeviceResourceNode *resourceNode) +{ + uint32_t pinIndex; + struct DeviceResourceIface *dri = NULL; + + dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (dri == NULL) { + HDF_LOGE("DeviceResourceIface is invalid!"); + return HDF_ERR_INVALID_OBJECT; + } + + if (dri->GetUint8(resourceNode, "pinNum", &cntlr->pinNum, 0) != HDF_SUCCESS) { + HDF_LOGE("Failed to read pinNum!"); + return HDF_FAILURE; + } + + cntlr->pinReflectionMap = (uint8_t *)OsalMemAlloc(sizeof(uint8_t) * cntlr->pinNum); + if (cntlr->pinReflectionMap == NULL) { + HDF_LOGE("%s: OsalMemAlloc error", __func__); + return HDF_ERR_MALLOC_FAIL; + } + + cntlr->config = OsalMemAlloc(sizeof(cntlr->config[0]) * cntlr->pinNum); + if (cntlr->config == NULL) { + HDF_LOGE("%s: OsalMemAlloc error", __func__); + return HDF_ERR_MALLOC_FAIL; + } + + for (uint32_t i = 0; i < cntlr->pinNum; i++) { + if (dri->GetUint32ArrayElem(resourceNode, "pinMap", i, &pinIndex, 0) != HDF_SUCCESS) { + HDF_LOGE("Failed to read pinMap!"); + return HDF_FAILURE; + } + + cntlr->pinReflectionMap[i] = pinIndex; + } + + return HDF_SUCCESS; +} + +static int32_t GpioDriverInit(struct HdfDeviceObject *device) +{ + int32_t ret; + struct B91GpioCntlr *pB91GpioCntlr = &g_B91GpioCntlr; + + HDF_LOGD("%s: Enter", __func__); + + if (device == NULL || device->property == NULL) { + HDF_LOGE("%s: device or property NULL!", __func__); + return HDF_ERR_INVALID_OBJECT; + } + + ret = GetGpioDeviceResource(pB91GpioCntlr, device->property); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: GetGpioDeviceResource failed: %ld", __func__, ret); + return ret; + } + + pB91GpioCntlr->cntlr.count = pB91GpioCntlr->pinNum; + pB91GpioCntlr->cntlr.priv = (void *)device->property; + pB91GpioCntlr->cntlr.ops = &g_GpioCntlrMethod; + + struct GpioCntlr *gpioCntlr = &pB91GpioCntlr->cntlr; + (void)PlatformDeviceBind(&gpioCntlr->device, device); + + ret = GpioCntlrAdd(&pB91GpioCntlr->cntlr); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: GpioCntlrAdd failed: %ld", __func__, ret); + return ret; + } + + B91IrqRegister(IRQ25_GPIO, (HWI_PROC_FUNC)GpioIrqHandler, 0); + plic_interrupt_enable(IRQ25_GPIO); + + HDF_LOGD("%s: dev service:%s init success!", __func__, HdfDeviceGetServiceName(device)); + return ret; +} + +static void GpioDriverRelease(struct HdfDeviceObject *device) +{ + struct GpioCntlr *gpioCntlr = NULL; + struct B91GpioCntlr *pB91GpioCntlr = &g_B91GpioCntlr; + + HDF_LOGD("%s: Enter", __func__); + + if (device == NULL) { + HDF_LOGE("%s: device is null!", __func__); + return; + } + + if (pB91GpioCntlr->pinReflectionMap) { + OsalMemFree(pB91GpioCntlr->pinReflectionMap); + pB91GpioCntlr->pinReflectionMap = NULL; + } + + gpioCntlr = GpioCntlrFromHdfDev(device); + if (gpioCntlr == NULL) { + HDF_LOGE("%s: no service bound!", __func__); + return; + } + GpioCntlrRemove(gpioCntlr); +} + +static int32_t GpioDriverBind(struct HdfDeviceObject *device) +{ + (void)device; + + return HDF_SUCCESS; +} + +static int32_t GpioDevWrite(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t val) +{ + (void)cntlr; + struct B91GpioCntlr *pB91GpioCntlr = &g_B91GpioCntlr; + + RETURN_ERR_IF_OUT_OF_RANGE(gpio); + + gpio_pin_e gpioPin = g_GpioIndexToActualPin[pB91GpioCntlr->pinReflectionMap[gpio]]; + HDF_LOGD("%s: %d - %d", __func__, gpioPin, val); + + if (val == GPIO_VAL_HIGH) { + gpio_set_level(gpioPin, 1); + } + else if (val == GPIO_VAL_LOW) { + gpio_set_level(gpioPin, 0); + } + else { + return HDF_ERR_NOT_SUPPORT; + } + + return HDF_SUCCESS; +} + +static int32_t GpioDevRead(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *val) +{ + (void)cntlr; + struct B91GpioCntlr *pB91GpioCntlr = &g_B91GpioCntlr; + + RETURN_ERR_IF_OUT_OF_RANGE(gpio); + + gpio_pin_e gpioPin = g_GpioIndexToActualPin[pB91GpioCntlr->pinReflectionMap[gpio]]; + HDF_LOGD("%s: %d", __func__, gpioPin); + + if (gpio_get_level(gpioPin) == 1) { + *val = GPIO_VAL_HIGH; + } + else { + *val = GPIO_VAL_LOW; + } + + return HDF_SUCCESS; +} + +static int32_t GpioDevSetDir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t dir) +{ + (void)cntlr; + struct B91GpioCntlr *pB91GpioCntlr = &g_B91GpioCntlr; + + RETURN_ERR_IF_OUT_OF_RANGE(gpio); + + gpio_pin_e gpioPin = g_GpioIndexToActualPin[pB91GpioCntlr->pinReflectionMap[gpio]]; + HDF_LOGD("%s: %d - %d", __func__, gpioPin, dir); + + if (dir == GPIO_DIR_OUT) { + gpio_function_en(gpioPin); + gpio_input_dis(gpioPin); + gpio_output_en(gpioPin); + } + else if (dir == GPIO_DIR_IN) { + gpio_function_en(gpioPin); + gpio_input_en(gpioPin); + gpio_output_dis(gpioPin); + } + else { + return HDF_ERR_NOT_SUPPORT; + } + + return HDF_SUCCESS; +} + +static int32_t GpioDevGetDir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *dir) +{ + (void)cntlr; + struct B91GpioCntlr *pB91GpioCntlr = &g_B91GpioCntlr; + + RETURN_ERR_IF_OUT_OF_RANGE(gpio); + + gpio_pin_e gpioPin = g_GpioIndexToActualPin[pB91GpioCntlr->pinReflectionMap[gpio]]; + HDF_LOGD("%s: %d", __func__, gpio); + + if (gpio_is_input_en(gpioPin)) { + *dir = GPIO_DIR_IN; + } + else if (gpio_is_output_en(gpioPin)) { + *dir = GPIO_DIR_OUT; + } + else { + *dir = GPIO_DIR_ERR; + } + + return HDF_SUCCESS; +} + +static int32_t GpioDevSetIrq(struct GpioCntlr *cntlr, uint16_t local, uint16_t mode) +{ + (void)cntlr; + struct B91GpioCntlr *pB91GpioCntlr = &g_B91GpioCntlr; + + RETURN_ERR_IF_OUT_OF_RANGE(local); + + gpio_pin_e gpioPin = g_GpioIndexToActualPin[pB91GpioCntlr->pinReflectionMap[local]]; + HDF_LOGD("%s: %d", __func__, local); + + switch (mode & 0x0F) + { + case GPIO_IRQ_TRIGGER_HIGH: { + gpio_set_irq(gpioPin, INTR_HIGH_LEVEL); + break; + } + case GPIO_IRQ_TRIGGER_LOW: { + gpio_set_irq(gpioPin, INTR_LOW_LEVEL); + break; + } + case GPIO_IRQ_TRIGGER_RISING: { + gpio_set_irq(gpioPin, INTR_RISING_EDGE); + break; + } + case GPIO_IRQ_TRIGGER_FALLING: { + gpio_set_irq(gpioPin, INTR_FALLING_EDGE); + break; + } + default: { + return HDF_ERR_BSP_PLT_API_ERR; + }; + } + + return HDF_SUCCESS; +} + +static int32_t GpioDevUnsetIrq(struct GpioCntlr *cntlr, uint16_t local) +{ + (void)cntlr; + struct B91GpioCntlr *pB91GpioCntlr = &g_B91GpioCntlr; + + RETURN_ERR_IF_OUT_OF_RANGE(local); + + return HDF_SUCCESS; +} + +static int32_t GpioDevEnableIrq(struct GpioCntlr *cntlr, uint16_t local) +{ + (void)cntlr; + struct B91GpioCntlr *pB91GpioCntlr = &g_B91GpioCntlr; + + RETURN_ERR_IF_OUT_OF_RANGE(local); + + gpio_pin_e gpioPin = g_GpioIndexToActualPin[pB91GpioCntlr->pinReflectionMap[local]]; + HDF_LOGD("%s: %d", __func__, local); + + gpio_irq_en(gpioPin); + + pB91GpioCntlr->config[local].irq_enabled = true; + + return HDF_SUCCESS; +} + +static int32_t GpioDevDisableIrq(struct GpioCntlr *cntlr, uint16_t local) +{ + (void)cntlr; + struct B91GpioCntlr *pB91GpioCntlr = &g_B91GpioCntlr; + + RETURN_ERR_IF_OUT_OF_RANGE(local); + + gpio_pin_e gpioPin = g_GpioIndexToActualPin[pB91GpioCntlr->pinReflectionMap[local]]; + HDF_LOGD("%s: %d", __func__, local); + + gpio_irq_dis(gpioPin); + + pB91GpioCntlr->config[local].irq_enabled = false; + + return HDF_SUCCESS; +} diff --git a/b91/liteos.ld b/b91/liteos.ld new file mode 100755 index 0000000..763312f --- /dev/null +++ b/b91/liteos.ld @@ -0,0 +1,276 @@ +/****************************************************************************** + * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *****************************************************************************/ + +MEMORY +{ + FLASH (rxai!w) : ORIGIN = 0x20000000, LENGTH = 1M + RAM_ILM (wxa) : ORIGIN = 0x00000000, LENGTH = 128K + RAM_DLM (wxa) : ORIGIN = 0x00080000, LENGTH = 128K +} + +ENTRY(reset_vector) +EXTERN(_b91_inject_start) + +SECTIONS +{ + PROVIDE (BIN_BEGIN = ORIGIN(FLASH)); + + PROVIDE(__text_start = .); + .entry.text : ALIGN(8) + { + KEEP(*(.entry.text)) + } > FLASH + + ._b91_inject_start ORIGIN(FLASH) + 0x18 : + { + KEEP(*(._b91_inject_start)) + } > FLASH + + .retention_data : ALIGN(8) + { + KEEP(*(.retention_data )) + . = .; + } > RAM_ILM AT > FLASH + + PROVIDE (_RETENTION_DATA_VMA_START = ADDR(.retention_data)); + PROVIDE (_RETENTION_DATA_LMA_START = LOADADDR(.retention_data)); + PROVIDE (_RETENTION_DATA_VMA_END = .); + + .ram_code : ALIGN(8) + { + KEEP(*(.ram_code )) + . = .; + } > RAM_ILM AT > FLASH + + PROVIDE (_RAMCODE_VMA_START = ADDR(.ram_code)); + PROVIDE (_RAMCODE_LMA_START = LOADADDR(.ram_code)); + PROVIDE (_RAMCODE_VMA_END = .); + + .text : ALIGN(8) + { + *(.text .stub .text.* .gnu.linkonce.t.* ) + *(.interrupt.text ) + *(.interrupt.text.* ) + *(.interrupt.HalTrapVector.text ) + KEEP(*(.text.*personality* )) + *(.text.unlikely .text.unlikely.*) + KEEP(*(.itcm.text)) + PROVIDE(__rodata_start = .); + *(.gnu.warning ) + *(.rodata .rodata.* .gnu.linkonce.r.* ) + PROVIDE(__rodata_end = .); + *(.gcc_except_table .gcc_except_table.*) + *(.eh_frame_hdr ) + . = ALIGN(0x20); + KEEP(*(.eh_frame )) + KEEP(*(.exec.itable)) + + KEEP (*(.init)) + KEEP (*(.fini)) + + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + + PROVIDE(_hdf_drivers_start = .); + KEEP(*(.hdf.driver)) + PROVIDE(_hdf_drivers_end = .); + + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + + } > FLASH AT > FLASH + + /* zInit code and data - will be freed after init */ + .zInit : ALIGN(8) + { + __zinitcall_bsp_start = .; + KEEP (*(.zinitcall.bsp0.init)) + KEEP (*(.zinitcall.bsp1.init)) + KEEP (*(.zinitcall.bsp2.init)) + KEEP (*(.zinitcall.bsp3.init)) + KEEP (*(.zinitcall.bsp4.init)) + __zinitcall_bsp_end = .; + __zinitcall_device_start = .; + KEEP (*(.zinitcall.device0.init)) + KEEP (*(.zinitcall.device1.init)) + KEEP (*(.zinitcall.device2.init)) + KEEP (*(.zinitcall.device3.init)) + KEEP (*(.zinitcall.device4.init)) + __zinitcall_device_end = .; + __zinitcall_core_start = .; + KEEP (*(.zinitcall.core0.init)) + KEEP (*(.zinitcall.core1.init)) + KEEP (*(.zinitcall.core2.init)) + KEEP (*(.zinitcall.core3.init)) + KEEP (*(.zinitcall.core4.init)) + __zinitcall_core_end = .; + __zinitcall_sys_service_start = .; + KEEP (*(.zinitcall.sys.service0.init)) + KEEP (*(.zinitcall.sys.service1.init)) + KEEP (*(.zinitcall.sys.service2.init)) + KEEP (*(.zinitcall.sys.service3.init)) + KEEP (*(.zinitcall.sys.service4.init)) + __zinitcall_sys_service_end = .; + __zinitcall_sys_feature_start = .; + KEEP (*(.zinitcall.sys.feature0.init)) + KEEP (*(.zinitcall.sys.feature1.init)) + KEEP (*(.zinitcall.sys.feature2.init)) + KEEP (*(.zinitcall.sys.feature3.init)) + KEEP (*(.zinitcall.sys.feature4.init)) + __zinitcall_sys_feature_end = .; + __zinitcall_run_start = .; + KEEP (*(.zinitcall.run0.init)) + KEEP (*(.zinitcall.run1.init)) + KEEP (*(.zinitcall.run2.init)) + KEEP (*(.zinitcall.run3.init)) + KEEP (*(.zinitcall.run4.init)) + __zinitcall_run_end = .; + __zinitcall_app_service_start = .; + KEEP (*(.zinitcall.app.service0.init)) + KEEP (*(.zinitcall.app.service1.init)) + KEEP (*(.zinitcall.app.service2.init)) + KEEP (*(.zinitcall.app.service3.init)) + KEEP (*(.zinitcall.app.service4.init)) + __zinitcall_app_service_end = .; + __zinitcall_app_feature_start = .; + KEEP (*(.zinitcall.app.feature0.init)) + KEEP (*(.zinitcall.app.feature1.init)) + KEEP (*(.zinitcall.app.feature2.init)) + KEEP (*(.zinitcall.app.feature3.init)) + KEEP (*(.zinitcall.app.feature4.init)) + __zinitcall_app_feature_end = .; + __zinitcall_test_start = .; + KEEP (*(.zinitcall.test0.init)) + KEEP (*(.zinitcall.test1.init)) + KEEP (*(.zinitcall.test2.init)) + KEEP (*(.zinitcall.test3.init)) + KEEP (*(.zinitcall.test4.init)) + __zinitcall_test_end = .; + __zinitcall_exit_start = .; + KEEP (*(.zinitcall.exit0.init)) + KEEP (*(.zinitcall.exit1.init)) + KEEP (*(.zinitcall.exit2.init)) + KEEP (*(.zinitcall.exit3.init)) + KEEP (*(.zinitcall.exit4.init)) + __zinitcall_exit_end = .; + } > FLASH AT > FLASH + + PROVIDE(__text_end = .); + + .data : ALIGN(8) + { + PROVIDE (__global_pointer$ = . + (4K / 2)); + . += 8; /* Workaround because linker don't use global pointer (GP) on extreme edge */ + *(.data .data.* .gnu.linkonce.d.* ) + KEEP(*( SORT (.liteos.table.*))); + KEEP(*(.gnu.linkonce.d.*personality* )) + SORT(CONSTRUCTORS) + *(.srodata.cst16 ) + *(.srodata.cst8 ) + *(.srodata.cst4 ) + *(.srodata.cst2 ) + *(.srodata .srodata.* ) + *(.sdata .sdata.* .gnu.linkonce.s.* ) + *(.sdata2 .sdata2.* .gnu.linkonce.s.* ) + } > RAM_DLM AT > FLASH + + PROVIDE(_DATA_VMA_START = ADDR(.data)); + PROVIDE(_DATA_LMA_START = LOADADDR(.data)); + PROVIDE(_DATA_VMA_END = .); + PROVIDE(__ram_data_start = _DATA_VMA_START); + PROVIDE(__ram_data_end = _DATA_VMA_END); + + .bss (NOLOAD) : ALIGN(8) + { + *(.dynsbss ) + *(.sbss .sbss.* .gnu.linkonce.sb.* ) + *(.scommon .scommon.* ) + *(.dynbss ) + *(.bss .bss.* .gnu.linkonce.b.* ) + *(COMMON ) + } > RAM_DLM + + PROVIDE (_BSS_VMA_START = ADDR(.bss)); + PROVIDE (_BSS_VMA_END = .); + PROVIDE(__bss_start = _BSS_VMA_START); + PROVIDE(__bss_end = _BSS_VMA_END); + + .noinit (NOLOAD) : ALIGN(16) + { + *(.noinit) + } > RAM_DLM + + .int_stack (NOLOAD) : ALIGN(0x1000) + { + __int_stack_start = .; + *(.int_stack); + __int_stack_end = .; + } > RAM_DLM + + . = ALIGN(8); + /* end is the starting address of the heap, the heap grows upward */ + _end = .; + _heap_end = ORIGIN(RAM_DLM) + LENGTH(RAM_DLM) - 1; + + .heap : ALIGN(1024) + { + PROVIDE (__los_heap_addr_start__ = .); + . = ORIGIN(RAM_ILM) + LENGTH(RAM_ILM); + PROVIDE (__los_heap_addr_end__ = . - 1); + PROVIDE (__los_heap_size__ = __los_heap_addr_end__ - __los_heap_addr_start__ + 1); + } > RAM_ILM + +/* PROVIDE (__los_heap_addr_start__ = .); + . = ORIGIN(RAM_DLM) + LENGTH(RAM_DLM); + PROVIDE (__los_heap_addr_end__ = . - 1); + PROVIDE (__los_heap_size__ = __los_heap_addr_end__ - __los_heap_addr_start__ + 1);*/ + + .BIN_END : + { + BIN_END = .; + } > FLASH + PROVIDE (BIN_SIZE = BIN_END - BIN_BEGIN); + + /* Remove information from the standard libraries 0x400 */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + *(.dummy) + } +} diff --git a/b91/liteos_m/BUILD.gn b/b91/liteos_m/BUILD.gn new file mode 100755 index 0000000..aeeab81 --- /dev/null +++ b/b91/liteos_m/BUILD.gn @@ -0,0 +1,64 @@ +# Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//kernel/liteos_m/liteos.gni") + +kernel_module("platform_main") { + sources = [ + "src/_stub.c", + "src/board_config.c", + "src/canary.c", + "src/littlefs_hal.c", + "src/main.c", + "src/riscv_irq.c", + "src/system.c", + "src/system_b91.c", + + "src/inject_start.S", + "src/reset_vector.S", + ] + + deps = [ + "//base/hiviewdfx/hilog_lite/frameworks/mini:hilog_lite", + "//base/hiviewdfx/hiview_lite", + ] + + include_dirs = [ + "//base/hiviewdfx/hilog_lite/frameworks/mini", + "//third_party/glib/glib/gnulib", + "//third_party/littlefs", + "//third_party/musl/porting/liteos_m/kernel/include", + "//kernel/liteos_m/components/fs", + "//kernel/liteos_m/components/fs/littlefs", + ] + + configs += [ + "../:B91_config", + ] + + if (!defined(defines)) { + defines = [] + } +} + +config("public") { + lib_dirs = [ "$root_out_dir/libs" ] + + ldflags = [ + "-z","muldefs", + "-Wl,--gc-sections", + "-Wl,-T" + rebase_path("../liteos.ld"), + ] +} diff --git a/b91/liteos_m/inc/b91_irq.h b/b91/liteos_m/inc/b91_irq.h new file mode 100755 index 0000000..4757fcf --- /dev/null +++ b/b91/liteos_m/inc/b91_irq.h @@ -0,0 +1,27 @@ +/****************************************************************************** + * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *****************************************************************************/ + +#ifndef _B91_IRQ_H +#define _B91_IRQ_H + +#include + +UINT32 B91IrqRegister(UINT32 irq_num, HWI_PROC_FUNC handler, HWI_ARG_T irqParam); +VOID B91IrqInit(VOID); + +#endif // _B91_IRQ_H diff --git a/b91/liteos_m/inc/system_b91.h b/b91/liteos_m/inc/system_b91.h new file mode 100755 index 0000000..4e94889 --- /dev/null +++ b/b91/liteos_m/inc/system_b91.h @@ -0,0 +1,26 @@ +/****************************************************************************** + * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *****************************************************************************/ + +#ifndef _SYSTEM_B91_H +#define _SYSTEM_B91_H + +#include + +VOID SystemInit(VOID); + +#endif /* _SYSTEM_B91_H */ diff --git a/b91/liteos_m/src/_stub.c b/b91/liteos_m/src/_stub.c new file mode 100755 index 0000000..d706a64 --- /dev/null +++ b/b91/liteos_m/src/_stub.c @@ -0,0 +1,21 @@ +/****************************************************************************** + * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *****************************************************************************/ + +void HAL_NVIC_SystemReset(void) +{ +} diff --git a/b91/liteos_m/src/board_config.c b/b91/liteos_m/src/board_config.c new file mode 100755 index 0000000..09affc9 --- /dev/null +++ b/b91/liteos_m/src/board_config.c @@ -0,0 +1,116 @@ +/****************************************************************************** + * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *****************************************************************************/ + +#include "los_compiler.h" + +#include +#include + +typedef void (*InitFunc)(void); + +extern UINT32 _ITB_BASE_; + +extern UINT32 _RETENTION_DATA_LMA_START[], _RETENTION_DATA_VMA_START[], _RETENTION_DATA_VMA_END[]; +extern UINT32 _RAMCODE_LMA_START[], _RAMCODE_VMA_START[], _RAMCODE_VMA_END[]; +extern UINT32 _DATA_LMA_START[], _DATA_VMA_START[], _DATA_VMA_END[]; +extern UINT32 _BSS_VMA_START[], _BSS_VMA_END[]; +extern UINT32 __int_stack_start[], __int_stack_end[]; + +extern InitFunc __preinit_array_start[] __attribute__((weak)); +extern InitFunc __preinit_array_end[] __attribute__((weak)); +extern InitFunc __init_array_start[] __attribute__((weak)); +extern InitFunc __init_array_end[] __attribute__((weak)); +extern InitFunc __fini_array_start[] __attribute__((weak)); +extern InitFunc __fini_array_end[] __attribute__((weak)); + +#define STACK_MAGIC UINT32_C(0xDEADBEEF) + +STATIC VOID BoardConfigInnerSafe(VOID); + +#ifdef __GNUC__ + #pragma GCC push_options + #pragma GCC optimize("-fno-stack-protector") +#endif /* __GNUC__ */ + +__attribute__((noinline)) STATIC VOID CopyBuf32(UINT32 *dst, const UINT32 *dstEnd, const UINT32 *src) +{ + while (dst < dstEnd) { + *dst++ = *src++; + } +} + +#define COPY_SEGMENT(_SEGNAME_) CopyBuf32((_SEGNAME_##_VMA_START), (_SEGNAME_##_VMA_END), (_SEGNAME_##_LMA_START)) + +__attribute__((used)) static void BoardConfigInner(void) +{ + for (UINT32 *p = _BSS_VMA_START; p < _BSS_VMA_END; ++p) { + *p = 0; + } + + COPY_SEGMENT(_RETENTION_DATA); + COPY_SEGMENT(_RAMCODE); + COPY_SEGMENT(_DATA); + + BoardConfigInnerSafe(); +} + +/* + * Use "naked" attribute to prevent stack usage before stack is initialized + */ +__attribute__((naked)) void BoardConfig(void) +{ +#ifdef __nds_execit + /* Initialize EXEC.IT table */ + __builtin_riscv_csrw((UINT32)&_ITB_BASE_, NDS_UITB); +#endif /* __nds_execit */ + + /* Enable I/D-Cache */ + UINT32 mcacheCtl = __builtin_riscv_csrr(NDS_MCACHE_CTL); + mcacheCtl |= 1; /* I-Cache */ + mcacheCtl |= 2; /* D-Cache */ + __builtin_riscv_csrw(mcacheCtl, NDS_MCACHE_CTL); + __asm__ volatile("fence.i"); + + for (UINT32 *p = __int_stack_start; p < __int_stack_end; ++p) { + *p = STACK_MAGIC; + } + + __asm__ volatile("j BoardConfigInner"); +} + +#ifdef __GNUC__ + #pragma GCC pop_options +#endif /* __GNUC__ */ + +/** + * @brief BoardConfigInnerSafe is safe part of BoardConfig without disabled stack protection + */ +STATIC VOID BoardConfigInnerSafe(VOID) +{ + for (InitFunc *f = __preinit_array_start; f < __preinit_array_end; ++f) { + (*f)(); + } + + for (InitFunc *f = __init_array_start; f < __init_array_end; ++f) { + (*f)(); + } + + for (InitFunc *f = __fini_array_start; f < __fini_array_end; ++f) { + (*f)(); + } +} diff --git a/b91/liteos_m/src/canary.c b/b91/liteos_m/src/canary.c new file mode 100755 index 0000000..b653dad --- /dev/null +++ b/b91/liteos_m/src/canary.c @@ -0,0 +1,67 @@ +/****************************************************************************** + * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *****************************************************************************/ + +#include + +#include + +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef __GNUC__ +/* stack protector */ +// UINTPTR __stack_chk_guard = 0x000a0dff; +extern UINTPTR __stack_chk_guard; + +STATIC UINT32 ArchGetTimerCnt(VOID) +{ + UINT32 cntpct; + cntpct = READ_CSR(0xB00); /* MCYCLE REG Address */ + return cntpct; +} + +/* + * If the SP compiling options:-fstack-protector-strong or -fstack-protector-all is enabled, + * We recommend to implement true random number generator function for __stack_chk_guard + * value to replace the function implementation template shown as below. + */ +#pragma GCC push_options +#pragma GCC optimize ("-fno-stack-protector") +LITE_OS_SEC_TEXT_INIT WEAK VOID ArchStackGuardInit(VOID) +{ + int rnd; + UINT32 seed; + + seed = ArchGetTimerCnt(); + srand(seed); + rnd = rand(); + __stack_chk_guard = (UINTPTR)rnd; +} +#pragma GCC pop_options +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/b91/liteos_m/src/inject_start.S b/b91/liteos_m/src/inject_start.S new file mode 100755 index 0000000..0ffbb1b --- /dev/null +++ b/b91/liteos_m/src/inject_start.S @@ -0,0 +1,27 @@ +/****************************************************************************** + * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *****************************************************************************/ + +.global _b91_inject_start +.section ._b91_inject_start, "a" +_b91_inject_start: + .org 0x08 + .word ('T'<<24 | 'L'<<16 | 'N'<<8 | 'K') + + .org 0x0e + .short (0x173B) /* DREAD: cmd:1x, addr:1x, data:2x, dummy:8 */ + .align 2 diff --git a/b91/liteos_m/src/littlefs_hal.c b/b91/liteos_m/src/littlefs_hal.c new file mode 100755 index 0000000..8b5de15 --- /dev/null +++ b/b91/liteos_m/src/littlefs_hal.c @@ -0,0 +1,127 @@ +/****************************************************************************** + * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *****************************************************************************/ + +#include +#include + +#include + +#include + +#include + +#define LITTLEFS_PATH "/littlefs/" + +#define LITTLEFS_PHYS_ADDR 0x60000 +#define LITTLEFS_PHYS_SIZE (16 * 1024) + +#define READ_SIZE 16 +#define PROG_SIZE 16 +#define BLOCK_SIZE 4096 +#define BLOCK_COUNT 32 +#define CACHE_SIZE 512 +#define LOOKAHEAD_SIZE 64 +#define BLOCK_CYCLES 500 + +#if defined(LFS_THREADSAFE) +static uint32_t g_lfsMutex; +#endif /* LFS_THREADSAFE */ + +static int LittlefsRead(const struct lfs_config *cfg, lfs_block_t block, + lfs_off_t off, void *buffer, lfs_size_t size) +{ + uint32_t addr = block * (cfg->block_size) + off; + + flash_read_page(LITTLEFS_PHYS_ADDR + addr, size, buffer); + + return LFS_ERR_OK; +} + +static int LittlefsProg(const struct lfs_config *cfg, lfs_block_t block, + lfs_off_t off, const void *buffer, lfs_size_t size) +{ + uint32_t addr = block * (cfg->block_size) + off; + + flash_write_page(LITTLEFS_PHYS_ADDR + addr, size, (unsigned char *)buffer); + + return LFS_ERR_OK; +} + +static int LittlefsErase(const struct lfs_config *cfg, lfs_block_t block) +{ + uint32_t addr = block * (cfg->block_size); + + flash_erase_sector(LITTLEFS_PHYS_ADDR + addr); + + return LFS_ERR_OK; +} + +static int LittlefsSync(const struct lfs_config *cfg) +{ + return LFS_ERR_OK; +} + +#if defined(LFS_THREADSAFE) +static int LittlefsLock(const struct lfs_config *conf) +{ + (void)conf; + (void)LOS_MuxPend(g_lfsMutex, LOS_WAIT_FOREVER); + return LFS_ERR_OK; +} + +static int LittlefsUnlock(const struct lfs_config *conf) +{ + (void)conf; + (void)LOS_MuxPost(g_lfsMutex); + return LFS_ERR_OK; +} +#endif /* LFS_THREADSAFE */ + +static struct lfs_config g_lfsConfig = { + // block device operations + .context = NULL, + .read = LittlefsRead, + .prog = LittlefsProg, + .erase = LittlefsErase, + .sync = LittlefsSync, +#if defined(LFS_THREADSAFE) + .lock = LittlefsLock, + .unlock = LittlefsUnlock, +#endif /* LFS_THREADSAFE */ + // block device configuration + .read_size = READ_SIZE, + .prog_size = PROG_SIZE, + .block_size = BLOCK_SIZE, + .block_count = BLOCK_COUNT, + .cache_size = CACHE_SIZE, + .lookahead_size = LOOKAHEAD_SIZE, + .block_cycles = BLOCK_CYCLES, +}; + +void LittlefsDriverInit(int needErase) +{ + (void)needErase; +} + +struct lfs_config *LittlefsConfigGet(void) +{ +#if defined(LFS_THREADSAFE) + (void)LOS_MuxCreate(&g_lfsMutex); +#endif /* LFS_THREADSAFE */ + return &g_lfsConfig; +} diff --git a/b91/liteos_m/src/main.c b/b91/liteos_m/src/main.c new file mode 100755 index 0000000..4fb2107 --- /dev/null +++ b/b91/liteos_m/src/main.c @@ -0,0 +1,309 @@ +/****************************************************************************** + * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include + +#include <../vendor/common/blt_common.h> + +#define DEBUG_UART_PORT UART0 +#define DEBUG_UART_PIN_TX UART0_TX_PB2 +#define DEBUG_UART_PIN_RX UART0_RX_PB3 +#define DEBUG_UART_PARITY UART_PARITY_NONE +#define DEBUG_UART_STOP_BITS UART_STOP_BIT_ONE +#define DEBUG_UART_BAUDRATE 921600 + +#define B91_SYSTEM_INIT_TASK_STACKSIZE (1024 * 32) +#define B91_SYSTEM_INIT_TASK_PRIO 7 +#define B91_SYSTEM_INIT_TASK_NAME "B91SystemInit" + +extern UserErrFunc g_userErrFunc; + +void OHOS_SystemInit(void); +struct lfs_config *LittlefsConfigGet(void); + +VOID HardwareInit(VOID) +{ + /* detect if MCU is wake_up from deep retention mode */ + int deepRetWakeUp = pm_is_MCU_deepRetentionWakeup(); //MCU deep retention wakeUp + + SystemInit(); + gpio_init(!deepRetWakeUp); +} + +STATIC VOID LittlefsInit(VOID) +{ +#define DIR_DATA "/data" +#define PAR_DATA 0 + + int res; + + printf("LittleFS_Init\r\n"); + + struct lfs_config *cfg = LittlefsConfigGet(); + + res = mount(PAR_DATA , DIR_DATA, "littlefs", 0, cfg); + printf("mount = %d\r\n", res); + + res = mkdir(DIR_DATA, 0777); + printf("mkdir = %d\r\n", res); +} + +STATIC VOID LittlefsTest(VOID) +{ +#define DIR_TEST "/data" +#define PAR_TEST 0 +#define TEST_FILE "/data/rw.sys.version" + + int res; + ssize_t fs_ret; + + printf("Littlefs Driver Test\n"); + struct lfs_config *cfg = LittlefsConfigGet(); + res = mount(PAR_TEST , DIR_TEST, "littlefs", 0, cfg); + printf("mount = %d\n", res); + + res = mkdir(DIR_TEST, 0777); + printf("mkdir = %d\n", res); + + uint32_t count = 0; + int fd = open(TEST_FILE, O_RDWR | O_CREAT); + printf("open = %d\n", fd); + + fs_ret = read(fd, &count, sizeof(count)); + printf("read = %ld\n", fs_ret); + printf("count = %lu\n", count); + count += 1; + + fs_ret = lseek(fd, 0, SEEK_SET); + printf("lseek = %ld\n", fs_ret); + + fs_ret = write(fd, &count, sizeof(count)); + printf("write = %ld\n", fs_ret); + + close(fd); + printf("close\n"); +} + +VOID IoTWatchDogKick(VOID) +{ +} + +STATIC VOID HdfGpioDriverTest(VOID) +{ + int32_t ret; + + ret = GpioSetDir(LED_BLUE_HDF, GPIO_DIR_OUT); + printf("GpioSetDir = %d\r\n", ret); + + while(1) { + GpioWrite(LED_BLUE_HDF, GPIO_VAL_LOW); + LOS_TaskDelay(500); + + GpioWrite(LED_BLUE_HDF, GPIO_VAL_HIGH); + LOS_TaskDelay(500); + } +} + +STATIC VOID B91SystemInit(VOID) +{ + OHOS_SystemInit(); + + LittlefsInit(); +} + +UINT32 LosAppInit(VOID) +{ + UINT32 ret = LOS_OK; + + B91IrqInit(); + + unsigned int taskID_ohos; + TSK_INIT_PARAM_S task_ohos = { 0 }; + + task_ohos.pfnTaskEntry = (TSK_ENTRY_FUNC)B91SystemInit; + task_ohos.uwStackSize = B91_SYSTEM_INIT_TASK_STACKSIZE; + task_ohos.pcName = B91_SYSTEM_INIT_TASK_NAME; + task_ohos.usTaskPrio = B91_SYSTEM_INIT_TASK_PRIO; + ret = LOS_TaskCreate(&taskID_ohos, &task_ohos); + if (ret != LOS_OK) { + printf("Create Task failed! ERROR: 0x%x\r\n", ret); + } + + return ret; +} + +__attribute__((weak)) void *_sbrk(ptrdiff_t incr) +{ + extern char _end[]; + extern char _heap_end[]; + static char *curbrk = _end; + + if ((curbrk + incr < _end) || (curbrk + incr > _heap_end)) { + return (void *)(-1); + } + + curbrk += incr; + return (void *)(curbrk - incr); +} + +VOID UsartInit(VOID) +{ + unsigned short div; + unsigned char bwpc; + + uart_set_pin(DEBUG_UART_PIN_TX, DEBUG_UART_PIN_RX); + uart_reset(DEBUG_UART_PORT); + uart_cal_div_and_bwpc(DEBUG_UART_BAUDRATE, sys_clk.pclk * 1000 * 1000, &div, &bwpc); + telink_b91_uart_init(DEBUG_UART_PORT, div, bwpc, DEBUG_UART_PARITY, DEBUG_UART_STOP_BITS); + uart_rx_irq_trig_level(DEBUG_UART_PORT, 1); +} + +int _write(int handle, char *data, int size) +{ + UNUSED(handle); + UNUSED(data); + UNUSED(size); + + int ret = 0; + + switch (handle) { + case STDOUT_FILENO: + case STDERR_FILENO: { + uart_send(UART0, (unsigned char *)data, size); + ret = size; + break; + } + default: { + break; + } + } + + return ret; +} + +static boolean hilog(const HiLogContent *hilogContent, uint32 len) +{ + UNUSED(len); + static char buf[256]; + int32 bytes = LogContentFmt(buf, sizeof(buf), (const uint8 *)hilogContent); + _write(STDOUT_FILENO, buf, bytes); + return TRUE; +} + +__attribute__((noreturn)) +void __assert_func(const char *file, int line, const char *func, const char *expr) +{ + printf("Assertion failed: %s (%s: %s: %d)\r\n", expr, file, func, line); + fflush(NULL); + abort(); +} + +STATIC VOID UserErrFuncImpl(CHAR *fileName, UINT32 lineNo, UINT32 errorNo, + UINT32 paraLen, VOID *para) +{ + printf("ERROR: \"/%s\" <<< line: %x err: %x para[%u]: ", fileName, lineNo, errorNo, paraLen); + + const u8 *pc = (const u8 *)para; + for (UINT32 i=0; i + +#include +#include + +#include +#include + +#include + +#include + +#define PLIC_IRQ_LIMIT 64 + +typedef VOID (*HwiProcFunc)(VOID *arg); + +VOID default_irq_handler(VOID); + +STATIC HWI_HANDLE_FORM_S irq_handlers[PLIC_IRQ_LIMIT] = { + [0 ... (PLIC_IRQ_LIMIT-1)] = {(HWI_PROC_FUNC)default_irq_handler, NULL, 0} +}; + +STATIC UINT32 EnableIrq(UINT32 hwiNum) +{ + if (hwiNum > OS_HWI_MAX_NUM) { + return OS_ERRNO_HWI_NUM_INVALID; + } + + UINT32 intSave = LOS_IntLock(); + if (hwiNum >= OS_RISCV_SYS_VECTOR_CNT) { + plic_interrupt_enable(hwiNum - OS_RISCV_SYS_VECTOR_CNT); + SET_CSR(mie, RISCV_MACH_EXT_IRQ); + } else { + UINT32 irq = hwiNum; + UINT32 mask = 1 << irq; + __asm__ volatile("csrs mie, %0" ::"r"(mask)); + } + + LOS_IntRestore(intSave); + return LOS_OK; +} + +VOID HalIrqEnable(UINT32 vector) +{ + (VOID)EnableIrq(vector); +} + +STATIC UINT32 DisableIrq(UINT32 hwiNum) +{ + if (hwiNum > OS_HWI_MAX_NUM) { + return OS_ERRNO_HWI_NUM_INVALID; + } + + UINT32 intSave = LOS_IntLock(); + if (hwiNum >= OS_RISCV_SYS_VECTOR_CNT) { + plic_interrupt_disable(hwiNum - OS_RISCV_SYS_VECTOR_CNT); + } else { + UINT32 irq = hwiNum; + UINT32 mask = 1 << irq; + __asm__ volatile("csrc mie, %0" ::"r"(mask)); + } + + LOS_IntRestore(intSave); + return LOS_OK; +} + +VOID HalIrqDisable(UINT32 vector) +{ + (VOID)DisableIrq(vector); +} + +VOID HalSetLocalInterPri(UINT32 interPriNum, UINT16 prior) +{ + plic_set_priority(interPriNum, prior); +} + +_attribute_ram_code_ void mext_irq_handler(void) +{ + unsigned int periph_irq = plic_interrupt_claim(); + + HWI_HANDLE_FORM_S *hwiForm = &irq_handlers[periph_irq]; + HwiProcFunc func = (HwiProcFunc)(hwiForm->pfnHook); + func(hwiForm->uwParam); + + plic_interrupt_complete(periph_irq); /* complete interrupt */ +} + +UINT32 B91IrqRegister(UINT32 irq_num, HWI_PROC_FUNC handler, HWI_ARG_T irqParam) +{ + if (irq_num >= PLIC_IRQ_LIMIT) { + return OS_ERRNO_HWI_NUM_INVALID; + } + + UINT32 intSave = LOS_IntLock(); + + if (NULL != handler) { + irq_handlers[irq_num].pfnHook = handler; + irq_handlers[irq_num].uwParam = (VOID *)irqParam; + } else { + irq_handlers[irq_num].pfnHook = (HWI_PROC_FUNC)default_irq_handler; + irq_handlers[irq_num].uwParam = NULL; + } + + LOS_IntRestore(intSave); + + return LOS_OK; +} + +VOID B91IrqInit(VOID) +{ + UINT32 ret = LOS_HwiCreate(RISCV_MACH_EXT_IRQ, OS_HWI_PRIO_LOWEST, 0, (HWI_PROC_FUNC)mext_irq_handler, 0); + if (ret != LOS_OK) { + printf("ret of LOS_HwiCreate(RISCV_MACH_EXT_IRQ) = %#x\r\n", ret); + } + + core_interrupt_enable(); +} diff --git a/b91/liteos_m/src/system.c b/b91/liteos_m/src/system.c new file mode 100755 index 0000000..86fc747 --- /dev/null +++ b/b91/liteos_m/src/system.c @@ -0,0 +1,39 @@ +/****************************************************************************** + * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *****************************************************************************/ + +#include +#include + +int access(const char *pathname, int mode) +{ + struct stat f_info; + + if (stat(pathname, &f_info) == 0) { + if (f_info.st_mode & S_IFDIR) { + return 0; + } else if (f_info.st_mode & S_IFREG) { + return 0; + } else { + return -1; + } + } else { + return -1; + } + + return 0; +} diff --git a/b91/liteos_m/src/system_b91.c b/b91/liteos_m/src/system_b91.c new file mode 100755 index 0000000..48bdc22 --- /dev/null +++ b/b91/liteos_m/src/system_b91.c @@ -0,0 +1,84 @@ +/****************************************************************************** + * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *****************************************************************************/ + +#include + +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Define 48 MHz and 96 MHz CCLK clock options (not present in HAL) */ +#define CCLK_64M_HCLK_32M_PCLK_16M \ + clock_init(PLL_CLK_192M, PAD_PLL_DIV, PLL_DIV3_TO_CCLK, \ + CCLK_DIV2_TO_HCLK, HCLK_DIV2_TO_PCLK, PLL_DIV4_TO_MSPI_CLK) + +#define CCLK_96M_HCLK_48M_PCLK_24M \ + clock_init(PLL_CLK_192M, PAD_PLL_DIV, PLL_DIV2_TO_CCLK, \ + CCLK_DIV2_TO_HCLK, HCLK_DIV2_TO_PCLK, PLL_DIV4_TO_MSPI_CLK) + +#if LOSCFG_TELINK_B91_CPU_FREQ == 16000000 +# define CLOCK_INIT CCLK_16M_HCLK_16M_PCLK_16M +#elif LOSCFG_TELINK_B91_CPU_FREQ == 24000000 +# define CLOCK_INIT CCLK_24M_HCLK_24M_PCLK_24M +#elif LOSCFG_TELINK_B91_CPU_FREQ == 32000000 +# define CLOCK_INIT CCLK_32M_HCLK_32M_PCLK_16M +#elif LOSCFG_TELINK_B91_CPU_FREQ == 48000000 +# define CLOCK_INIT CCLK_48M_HCLK_48M_PCLK_24M +#elif LOSCFG_TELINK_B91_CPU_FREQ == 64000000 +# define CLOCK_INIT CCLK_64M_HCLK_32M_PCLK_16M +#elif LOSCFG_TELINK_B91_CPU_FREQ == 96000000 +# define CLOCK_INIT CCLK_96M_HCLK_48M_PCLK_24M +#else /* LOSCFG_TELINK_B91_CPU_FREQ == 16000000 */ +# error Unsupported clock frequency. See LOSCFG_TELINK_B91_CPU_FREQ +#endif /* LOSCFG_TELINK_B91_CPU_FREQ == 16000000 */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#if defined(LOSCFG_POWER_MODE_LDO_1P4_LDO_1P8) +# define POWER_MODE LDO_1P4_LDO_1P8 +#elif defined(LOSCFG_POWER_MODE_DCDC_1P4_LDO_1P8) +# define POWER_MODE DCDC_1P4_LDO_1P8 +#elif defined(LOSCFG_POWER_MODE_DCDC_1P4_DCDC_1P8) +# define POWER_MODE DCDC_1P4_DCDC_1P8 +#else /* defined(LOSCFG_POWER_MODE_LDO_1P4_LDO_1P8) */ +# error Unsupported Power mode +#endif /* defined(LOSCFG_POWER_MODE_LDO_1P4_LDO_1P8) */ + +#if defined(LOSCFG_VBAT_TYPE_MAX_VALUE_GREATER_THAN_3V6) +# define VBAT_TYPE VBAT_MAX_VALUE_GREATER_THAN_3V6 +#elif defined(LOSCFG_VBAT_TYPE_MAX_VALUE_LESS_THAN_3V6) +# define VBAT_TYPE VBAT_MAX_VALUE_LESS_THAN_3V6 +#else /* defined(LOSCFG_VBAT_TYPE_MAX_VALUE_GREATER_THAN_3V6) */ +# error Unsupported VBat type +#endif /* defined(LOSCFG_VBAT_TYPE_MAX_VALUE_GREATER_THAN_3V6) */ + +VOID SystemInit(VOID) +{ + sys_init(POWER_MODE, VBAT_TYPE); + CLOCK_INIT; + + clock_32k_init(CLK_32K_RC); + clock_cal_32k_rc(); +} diff --git a/util/util.gni b/util/util.gni new file mode 100755 index 0000000..ac8c1d9 --- /dev/null +++ b/util/util.gni @@ -0,0 +1,119 @@ +# Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/lite/config/component/lite_component.gni") + +declare_args() { + disasm_unstripped_version = false +} + +template("binary") { + assert(defined(invoker.deps), + "Need sources in $target_name listing the idl files.") + + build_ext_component(target_name) { + deps = invoker.deps + + if (defined(invoker.source)) { + source = invoker.source + } else { + source = deps[0] + } + + print("ohos_build_type=${ohos_build_type}") + print("target_name = ${target_name}") + print(source) + print(compile_prefix) + + + elf = get_label_info(source, "name") + print("elf: ${elf} ") + print("target_out_dir: ${target_out_dir}") + print("root_out_dir: ${root_out_dir}") + print("name: ${name}") + out_dir = get_path_info(target_out_dir, "out_dir") + print("out_dir: ${out_dir}") + print("ohos_current_strip_command: ${ohos_current_strip_command}") + + if (defined(invoker.output)) { + bin = invoker.output + } else { + bin = elf + ".bin" + } + + print("bin: ${bin}") + + exec_path = rebase_path(root_out_dir + "/bin") + print("root_out_dir: ${root_out_dir}") + print("exec_path: ${exec_path}") + + if (disasm_unstripped_version && defined(ohos_current_strip_command) && ("" != ohos_current_strip_command)) { + unstripped_prefix = "/unstripped" + } else { + unstripped_prefix = "" + } + unstripped_prefix = rebase_path(root_out_dir + unstripped_prefix + "/bin", exec_path) + print("unstripped_prefix: ${unstripped_prefix}") + + objcopy = "${compile_prefix}objcopy$toolchain_cmd_suffix" + objdump = "${compile_prefix}objdump$toolchain_cmd_suffix" + + command = "$objcopy -O binary ${elf} ${bin}" + command += " && sh -c '$objdump -t $unstripped_prefix/$elf | sort > $elf.sym.sorted'" + command += " && sh -c '$objdump -xdSC $unstripped_prefix/$elf > $elf.S'" + print("command: \"$command\"") + } +} + +template("b91_firmware") { + executable("${target_name}_elf") { + forward_variables_from(invoker, "*") + + explicit_libs_full = [] + if (defined(explicit_libs)) { + foreach(lib, explicit_libs) { + explicit_libs_full += ["-l$lib"] + } + } + + if (!defined(ldflags)) { + ldflags = [] + } + + ldflags += [ + "-z","muldefs", + "-Wl,-Map=" + rebase_path("$root_out_dir/$target_name.map"), + "-L" + rebase_path("$root_out_dir/libs"), + ] + + ldflags += ["-Wl,--whole-archive"] + explicit_libs_full + ["-Wl,--no-whole-archive"] + + configs += [ + "//kernel/liteos_m:public", + "//kernel/liteos_m:los_config", + ] + + output_name = invoker.target_name + } + + binary("${target_name}_bin") { + deps = [":${invoker.target_name}_elf"] + source = invoker.target_name + } + + group(target_name) { + deps = [":${invoker.target_name}_bin"] + } +}