mirror of
https://github.com/openharmony/device_soc_telink.git
synced 2026-07-01 03:23:17 -04:00
@@ -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" ]
|
||||
}
|
||||
}
|
||||
Executable
+16
@@ -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"
|
||||
Executable
+16
@@ -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"
|
||||
Executable
+24
@@ -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
|
||||
Executable
+52
@@ -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",
|
||||
]
|
||||
}
|
||||
Executable
+19
@@ -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
|
||||
Executable
+25
@@ -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
|
||||
|
||||
Executable
+23
@@ -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
|
||||
|
||||
Executable
+23
@@ -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
|
||||
|
||||
Executable
+27
@@ -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 = []
|
||||
}
|
||||
Executable
+253
@@ -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 <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
Executable
+1242
File diff suppressed because it is too large
Load Diff
Executable
+82
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>B91_ble_multi_conn_sdk</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>?name?</key>
|
||||
<value></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.append_environment</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildArguments</key>
|
||||
<value></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildCommand</key>
|
||||
<value>make</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildLocation</key>
|
||||
<value>${workspace_loc:/Eagle_Driver_Demo}/9518_UART_DEMO</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
|
||||
<value>clean</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.contents</key>
|
||||
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
|
||||
<value>false</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.stopOnError</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
|
||||
<value>false</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
Executable
+44
@@ -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"]
|
||||
}
|
||||
Executable
+154
@@ -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);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Executable
+37
@@ -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_ */
|
||||
+166
@@ -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_ */
|
||||
|
||||
|
||||
|
||||
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
__build__/
|
||||
__pycache__
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
*.pyz
|
||||
*.egg-info/
|
||||
.DS_Store
|
||||
Executable
+40
@@ -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_ */
|
||||
Executable
+69
@@ -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_ */
|
||||
|
||||
|
||||
|
||||
|
||||
Executable
+77
@@ -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)) */
|
||||
|
||||
|
||||
Executable
+33
@@ -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
|
||||
|
||||
+55
@@ -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
|
||||
Executable
+107
@@ -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
|
||||
Executable
+141
@@ -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
|
||||
+68
@@ -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 <nds_math_types.h>
|
||||
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
|
||||
+21
@@ -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
|
||||
+223
@@ -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
|
||||
+12
@@ -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
|
||||
+44
@@ -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
|
||||
+369
@@ -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
|
||||
|
||||
Executable
+120
@@ -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
|
||||
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
#ifndef _ENCODER_FUNCTION_H
|
||||
#define _ENCODER_FUNCIION_H
|
||||
#include"../inc/lc3_enc.h"
|
||||
#if (ALG_LC3_ENABLE)
|
||||
#include<stdlib.h>
|
||||
//#include<stdio.h>
|
||||
#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
|
||||
|
||||
+190
@@ -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 <limits.h>
|
||||
#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 <alloca.h>
|
||||
#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
|
||||
+128
@@ -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 <xmmintrin.h>
|
||||
# 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 <sys/types.h>
|
||||
# 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
|
||||
+13
@@ -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
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
#ifndef FIXED_OP_H
|
||||
#define FIXED_OP_H
|
||||
|
||||
#include "../../../inc/config.h"
|
||||
#if (ALG_LC3_ENABLE)
|
||||
|
||||
#if __riscv
|
||||
#include <nds_intrinsic.h>
|
||||
#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
|
||||
+264
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
#ifndef _FUNC_ASM_H
|
||||
#define _FUNC_ASM_H
|
||||
|
||||
Word32 dprod_q15(Word16 *src1, Word16 *src2, Word32 size);
|
||||
|
||||
#endif
|
||||
+14
@@ -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
|
||||
+727
@@ -0,0 +1,727 @@
|
||||
#ifndef _INTRINSIC_H
|
||||
#define _INTRINSIC_H
|
||||
|
||||
#include "../inc/lc3_types.h"
|
||||
|
||||
#if (ALG_LC3_ENABLE)
|
||||
#ifdef ANDES_INTRINSIC
|
||||
#include <nds_intrinsic.h>
|
||||
#include <nds_utils_math.h>
|
||||
#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
|
||||
+16
@@ -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
|
||||
+16
@@ -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
|
||||
+18
@@ -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
|
||||
+18
@@ -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
|
||||
+15
@@ -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
|
||||
+15
@@ -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
|
||||
Executable
+284
@@ -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
|
||||
}
|
||||
|
||||
Executable
+100
@@ -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 <application/usbstd/HIDClassCommon.h>
|
||||
#include <application/usbstd/HIDReportData.h>
|
||||
#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
|
||||
|
||||
Executable
+115
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Executable
+321
@@ -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 */
|
||||
Executable
+70
@@ -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
|
||||
Executable
+30
@@ -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"
|
||||
|
||||
|
||||
|
||||
Executable
+366
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Executable
+70
@@ -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 <application/usbstd/HIDClassCommon.h>
|
||||
#include <application/usbstd/HIDReportData.h>
|
||||
#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
|
||||
|
||||
Executable
+130
@@ -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
|
||||
Executable
+152
@@ -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;i<new_data_num;i++)
|
||||
{
|
||||
// tmemcpy4((int*)(&mouse_dat_buff[usbmouse_wptr]), (int*)(&packet_mouse->data[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
|
||||
Executable
+45
@@ -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 <application/usbstd/HIDClassCommon.h>
|
||||
#include <application/usbstd/HIDReportData.h>
|
||||
#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
|
||||
+255
@@ -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);
|
||||
}
|
||||
|
||||
Executable
+506
@@ -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<len; i++) {
|
||||
|
||||
s16 di = ps[i];
|
||||
int step = steptbl[predict_idx];
|
||||
int diff = di - predict;
|
||||
|
||||
if (diff >=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<len; i++){//unit sample
|
||||
|
||||
s16 di = ps[i];
|
||||
int step = steptbl[predict_idx];
|
||||
int diff = di - predict;
|
||||
|
||||
if(diff >= 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<len; i++) {
|
||||
|
||||
s16 di = ps[i];
|
||||
int step = steptbl[predict_idx];
|
||||
int diff = di - predict;
|
||||
|
||||
if (diff >=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<len; i++) {
|
||||
|
||||
if (1) {
|
||||
int step = steptbl[predict_idx];
|
||||
|
||||
int diffq = step >> 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<len; i++){
|
||||
int step = steptbl[predict_idx];
|
||||
int diffq = step >> 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<len; i++) {
|
||||
|
||||
if (1) {
|
||||
int step = steptbl[predict_idx];
|
||||
|
||||
int diffq = step >> 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
|
||||
Executable
+29
@@ -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_ */
|
||||
+84
@@ -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_ */
|
||||
+47
@@ -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
|
||||
+555
@@ -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<nsample; i++)
|
||||
{
|
||||
//s = (*ps * coef[0])>>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<nsample; i++)
|
||||
{
|
||||
//s = (*ps * coef[0])>>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<TL_MIC_ADPCM_UNIT_SIZE*2; i++) {
|
||||
ps[i] = noise_supression (ps[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (IIR_FILTER_ENABLE)
|
||||
#if 0
|
||||
//step1: out of band voice 12bits EQ filter process
|
||||
voice_iir_OOB(ps, ps, LPF_FILTER_1, (TL_MIC_BUFFER_SIZE>>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<USB_ISO_IN_SIZE; i++)
|
||||
{
|
||||
reg_usb_ep7_dat = *ps;
|
||||
reg_usb_ep7_dat = *ps++ >> 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<USB_ISO_IN_SIZE * 2; i++)
|
||||
{
|
||||
reg_usb_ep7_dat = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i=0; i<USB_ISO_IN_SIZE * 2; i++)
|
||||
{
|
||||
reg_usb_ep7_dat = 0;
|
||||
}
|
||||
buffer_empty = 1;
|
||||
}
|
||||
reg_usb_ep7_ctrl = BIT(0); //ACK iso in
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
/********************************************************************************************************
|
||||
* @file tl_audio.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 TL_AUDIO_H_
|
||||
#define TL_AUDIO_H_
|
||||
|
||||
#include "tl_common.h"
|
||||
#include "audio_config.h"
|
||||
|
||||
|
||||
|
||||
#if (TL_AUDIO_MODE & RCU_PROJECT) //RCU
|
||||
#ifndef TL_NOISE_SUPRESSION_ENABLE
|
||||
#define TL_NOISE_SUPRESSION_ENABLE 0
|
||||
#endif
|
||||
|
||||
#ifndef IIR_FILTER_ENABLE
|
||||
#define IIR_FILTER_ENABLE 0
|
||||
#endif
|
||||
|
||||
#ifndef TL_MIC_PACKET_BUFFER_NUM
|
||||
#define TL_MIC_PACKET_BUFFER_NUM 4
|
||||
#endif
|
||||
|
||||
#ifndef MIC_SHORT_DEC_SIZE
|
||||
#define MIC_SHORT_DEC_SIZE 0
|
||||
#endif
|
||||
|
||||
#ifndef ADPCM_PACKET_LEN
|
||||
#define ADPCM_PACKET_LEN 0
|
||||
#endif
|
||||
|
||||
#ifndef TL_MIC_ADPCM_UNIT_SIZE
|
||||
#define TL_MIC_ADPCM_UNIT_SIZE 0
|
||||
#endif
|
||||
|
||||
#ifndef TL_MIC_BUFFER_SIZE
|
||||
#define TL_MIC_BUFFER_SIZE 0
|
||||
#endif
|
||||
|
||||
#if TL_MIC_BUFFER_SIZE
|
||||
s16 buffer_mic[TL_MIC_BUFFER_SIZE>>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_ */
|
||||
+509
@@ -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<ARRAY_SIZE(drive_pins); k++) {
|
||||
*pd++ = pressed_matrix[k];
|
||||
}
|
||||
matrix_wptr = (matrix_wptr + 1) & 7;
|
||||
if ( ((matrix_wptr - matrix_rptr) & 7) > 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;i<KB_REPEAT_KEY_NUM;i++){
|
||||
if(kb_event.keycode[0] == kb_map_repeat[i]){
|
||||
repeat_key.key_repeat_flg = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/********************************************************************************************************
|
||||
* @file keyboard.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"
|
||||
|
||||
#define KB_RETURN_KEY_MAX 6
|
||||
|
||||
#define KB_NUMLOCK_STATUS_INVALID BIT(7)
|
||||
#define KB_NUMLOCK_STATUS_POWERON BIT(15)
|
||||
|
||||
#define DEEPBACK_KEY_IDLE 0
|
||||
#define DEEPBACK_KEY_CACHE 1 //there is deepback key cached in kb_event_cache
|
||||
#define DEEPBACK_KEY_WAIT_RELEASE 2
|
||||
|
||||
|
||||
#ifndef KB_REPEAT_KEY_ENABLE
|
||||
#define KB_REPEAT_KEY_ENABLE 0
|
||||
#endif
|
||||
|
||||
#define KEY_NONE 0
|
||||
#define KEY_CHANGE 1
|
||||
#define KEY_SAME 2
|
||||
typedef struct{
|
||||
unsigned char key_change_flg;
|
||||
unsigned char key_repeat_flg;
|
||||
unsigned char keycode0;
|
||||
unsigned char keycode1;
|
||||
unsigned int key_change_tick;
|
||||
}repeatKey_t;
|
||||
|
||||
extern repeatKey_t repeat_key;
|
||||
|
||||
|
||||
typedef struct{
|
||||
unsigned char cnt;
|
||||
unsigned char ctrl_key;
|
||||
unsigned char keycode[KB_RETURN_KEY_MAX];
|
||||
//unsigned char padding[2]; // for 32 bit padding, if KB_RETURN_KEY_MAX change, this should be changed
|
||||
}kb_data_t;
|
||||
|
||||
extern kb_data_t kb_event;
|
||||
extern kb_data_t kb_event_cache;
|
||||
extern unsigned char deepback_key_state;
|
||||
extern unsigned int deepback_key_tick;
|
||||
|
||||
|
||||
#ifndef LONG_PRESS_KEY_POWER_OPTIMIZE
|
||||
#define LONG_PRESS_KEY_POWER_OPTIMIZE 0
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef STUCK_KEY_PROCESS_ENABLE
|
||||
#define STUCK_KEY_PROCESS_ENABLE 0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int kb_is_data_same(kb_data_t *a, kb_data_t *b);
|
||||
|
||||
static inline int kb_is_key_valid(kb_data_t *p){
|
||||
return (p->cnt || 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;
|
||||
}
|
||||
}
|
||||
Executable
+128
@@ -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 <stdarg.h>
|
||||
#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
|
||||
|
||||
|
||||
Executable
+51
@@ -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 <stdio.h>
|
||||
#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
|
||||
|
||||
Executable
+204
@@ -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_ */
|
||||
+353
@@ -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
|
||||
|
||||
+178
@@ -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
|
||||
+66
@@ -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 <application/usbstd/CDCClassCommon.h>
|
||||
#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
|
||||
+449
@@ -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
|
||||
|
||||
+58
@@ -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
|
||||
|
||||
|
||||
+110
@@ -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__)
|
||||
|
||||
@@ -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 <application/usbstd/stdDescriptors.h>
|
||||
#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
|
||||
@@ -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
|
||||
|
||||
+85
@@ -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
|
||||
|
||||
|
||||
|
||||
+67
@@ -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
|
||||
|
||||
+272
@@ -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
|
||||
|
||||
Executable
+872
@@ -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 <stdio.h>
|
||||
#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
|
||||
Executable
+80
@@ -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
|
||||
|
||||
+822
@@ -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 <application/usbstd/usbdesc.h>
|
||||
#include "tl_common.h"
|
||||
#include "drivers.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 "../app/usbsomatic_i.h"
|
||||
#endif
|
||||
|
||||
#if (USB_SPEAKER_ENABLE || USB_MIC_ENABLE)
|
||||
#include <application/app/usbaud_i.h>
|
||||
#endif
|
||||
|
||||
#if (USB_CDC_ENABLE)
|
||||
#include <application/app/usbcdc_i.h>
|
||||
#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
|
||||
+419
@@ -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 <application/usbstd/AudioClassCommon.h>
|
||||
#include <application/usbstd/CDCClassCommon.h>
|
||||
#include <application/usbstd/HIDClassCommon.h>
|
||||
#include <application/usbstd/PrinterClassCommon.h>
|
||||
#include <application/usbstd/USBController.h>
|
||||
|
||||
/* 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
|
||||
|
||||
+348
@@ -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: <<HID Usage Tables>> 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;
|
||||
Executable
+100
@@ -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");
|
||||
Executable
+107
@@ -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");
|
||||
Executable
+100
@@ -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");
|
||||
Executable
+475
@@ -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
|
||||
Executable
+485
@@ -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
|
||||
Executable
+81
@@ -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
|
||||
|
||||
|
||||
Executable
+241
@@ -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) & name##_MASK )
|
||||
|
||||
//! Get the value of bitfield \a name from \a y. Equivalent to (var=) y.name
|
||||
#define BFN_GET(y, name) ( ((y) & name##_MASK)>>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
|
||||
|
||||
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
Packetcraft's dynamic memory allocation
|
||||
Executable
+610
@@ -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 <buf_pool0/myBuf.h>
|
||||
#include <buf_pool0/myHeap.h>
|
||||
#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
|
||||
|
||||
Executable
+236
@@ -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 */
|
||||
Executable
+94
@@ -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;
|
||||
}
|
||||
Executable
+84
@@ -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
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user